save comment position

This commit is contained in:
z7zmey 2018-04-15 21:39:26 +03:00
parent c2f938e55c
commit 781a55659b
10 changed files with 114 additions and 61 deletions

View File

@ -1,17 +1,28 @@
package comment
import (
"github.com/z7zmey/php-parser/position"
)
// Comment aggrigates information about comment /**
type Comment struct {
value string
position *position.Position
}
// NewComment - Comment constructor
func NewComment(value string) *Comment {
func NewComment(value string, pos *position.Position) *Comment {
return &Comment{
value,
pos,
}
}
func (c *Comment) String() string {
return c.value
}
// Position returns comment position
func (c *Comment) Position() *position.Position {
return c.position
}

View File

@ -3,6 +3,8 @@ package comment_test
import (
"testing"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/comment"
"github.com/z7zmey/php-parser/node"
)
@ -11,8 +13,8 @@ func TestComments(t *testing.T) {
n := node.NewIdentifier("test")
commentGroup := []*comment.Comment{
comment.NewComment("/** hello world */"),
comment.NewComment("// hello world"),
comment.NewComment("/** hello world */", nil),
comment.NewComment("// hello world", nil),
}
comments := comment.Comments{}
@ -25,3 +27,15 @@ func TestComments(t *testing.T) {
t.Errorf("expected and actual are not equal\n")
}
}
func TestCommentPos(t *testing.T) {
expected := position.NewPosition(0, 0, 0, 0)
comment := comment.NewComment("/** hello world */", expected)
actual := comment.Position()
if expected != actual {
t.Errorf("expected and actual are not equal\n")
}
}

View File

@ -1,13 +1,14 @@
package position
package parser
import (
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/scanner"
)
// Builder provide functions to constuct positions
type Builder struct {
Positions *Positions
Positions *position.Positions
}
type startPos struct {
@ -79,8 +80,8 @@ func (b *Builder) getNodeEndPos(n node.Node) endPos {
}
// NewNodeListPosition returns new Position
func (b *Builder) NewNodeListPosition(list []node.Node) *Position {
return &Position{
func (b *Builder) NewNodeListPosition(list []node.Node) *position.Position {
return &position.Position{
b.getListStartPos(list).startLine,
b.getListEndPos(list).endLine,
b.getListStartPos(list).startPos,
@ -89,8 +90,8 @@ func (b *Builder) NewNodeListPosition(list []node.Node) *Position {
}
// NewNodePosition returns new Position
func (b *Builder) NewNodePosition(n node.Node) *Position {
return &Position{
func (b *Builder) NewNodePosition(n node.Node) *position.Position {
return &position.Position{
b.getNodeStartPos(n).startLine,
b.getNodeEndPos(n).endLine,
b.getNodeStartPos(n).startPos,
@ -99,8 +100,8 @@ func (b *Builder) NewNodePosition(n node.Node) *Position {
}
// NewTokenPosition returns new Position
func (b *Builder) NewTokenPosition(t scanner.Token) *Position {
return &Position{
func (b *Builder) NewTokenPosition(t scanner.Token) *position.Position {
return &position.Position{
t.StartLine,
t.EndLine,
t.StartPos,
@ -109,8 +110,8 @@ func (b *Builder) NewTokenPosition(t scanner.Token) *Position {
}
// NewTokensPosition returns new Position
func (b *Builder) NewTokensPosition(startToken scanner.Token, endToken scanner.Token) *Position {
return &Position{
func (b *Builder) NewTokensPosition(startToken scanner.Token, endToken scanner.Token) *position.Position {
return &position.Position{
startToken.StartLine,
endToken.EndLine,
startToken.StartPos,
@ -119,8 +120,8 @@ func (b *Builder) NewTokensPosition(startToken scanner.Token, endToken scanner.T
}
// NewTokenNodePosition returns new Position
func (b *Builder) NewTokenNodePosition(t scanner.Token, n node.Node) *Position {
return &Position{
func (b *Builder) NewTokenNodePosition(t scanner.Token, n node.Node) *position.Position {
return &position.Position{
t.StartLine,
b.getNodeEndPos(n).endLine,
t.StartPos,
@ -129,8 +130,8 @@ func (b *Builder) NewTokenNodePosition(t scanner.Token, n node.Node) *Position {
}
// NewNodeTokenPosition returns new Position
func (b *Builder) NewNodeTokenPosition(n node.Node, t scanner.Token) *Position {
return &Position{
func (b *Builder) NewNodeTokenPosition(n node.Node, t scanner.Token) *position.Position {
return &position.Position{
b.getNodeStartPos(n).startLine,
t.EndLine,
b.getNodeStartPos(n).startPos,
@ -139,8 +140,8 @@ func (b *Builder) NewNodeTokenPosition(n node.Node, t scanner.Token) *Position {
}
// NewNodesPosition returns new Position
func (b *Builder) NewNodesPosition(startNode node.Node, endNode node.Node) *Position {
return &Position{
func (b *Builder) NewNodesPosition(startNode node.Node, endNode node.Node) *position.Position {
return &position.Position{
b.getNodeStartPos(startNode).startLine,
b.getNodeEndPos(endNode).endLine,
b.getNodeStartPos(startNode).startPos,
@ -149,8 +150,8 @@ func (b *Builder) NewNodesPosition(startNode node.Node, endNode node.Node) *Posi
}
// NewNodeListTokenPosition returns new Position
func (b *Builder) NewNodeListTokenPosition(list []node.Node, t scanner.Token) *Position {
return &Position{
func (b *Builder) NewNodeListTokenPosition(list []node.Node, t scanner.Token) *position.Position {
return &position.Position{
b.getListStartPos(list).startLine,
t.EndLine,
b.getListStartPos(list).startPos,
@ -159,8 +160,8 @@ func (b *Builder) NewNodeListTokenPosition(list []node.Node, t scanner.Token) *P
}
// NewTokenNodeListPosition returns new Position
func (b *Builder) NewTokenNodeListPosition(t scanner.Token, list []node.Node) *Position {
return &Position{
func (b *Builder) NewTokenNodeListPosition(t scanner.Token, list []node.Node) *position.Position {
return &position.Position{
t.StartLine,
b.getListEndPos(list).endLine,
t.StartPos,
@ -169,8 +170,8 @@ func (b *Builder) NewTokenNodeListPosition(t scanner.Token, list []node.Node) *P
}
// NewNodeNodeListPosition returns new Position
func (b *Builder) NewNodeNodeListPosition(n node.Node, list []node.Node) *Position {
return &Position{
func (b *Builder) NewNodeNodeListPosition(n node.Node, list []node.Node) *position.Position {
return &position.Position{
b.getNodeStartPos(n).startLine,
b.getListEndPos(list).endLine,
b.getNodeStartPos(n).startPos,
@ -179,9 +180,9 @@ func (b *Builder) NewNodeNodeListPosition(n node.Node, list []node.Node) *Positi
}
// NewOptionalListTokensPosition returns new Position
func (b *Builder) NewOptionalListTokensPosition(list []node.Node, t scanner.Token, endToken scanner.Token) *Position {
func (b *Builder) NewOptionalListTokensPosition(list []node.Node, t scanner.Token, endToken scanner.Token) *position.Position {
if list == nil {
return &Position{
return &position.Position{
t.StartLine,
endToken.EndLine,
t.StartPos,
@ -189,7 +190,7 @@ func (b *Builder) NewOptionalListTokensPosition(list []node.Node, t scanner.Toke
}
}
return &Position{
return &position.Position{
b.getListStartPos(list).startLine,
endToken.EndLine,
b.getListStartPos(list).startPos,

View File

@ -1,16 +1,17 @@
package position_test
package parser_test
import (
"testing"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/parser"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/scanner"
)
func TestNewTokenPosition(t *testing.T) {
builder := position.Builder{}
builder := parser.Builder{}
tkn := scanner.NewToken([]byte(`foo`), 1, 1, 0, 3)
@ -22,7 +23,7 @@ func TestNewTokenPosition(t *testing.T) {
}
func TestNewTokensPosition(t *testing.T) {
builder := position.Builder{}
builder := parser.Builder{}
token1 := scanner.NewToken([]byte(`foo`), 1, 1, 0, 3)
token2 := scanner.NewToken([]byte(`foo`), 2, 2, 4, 6)
@ -45,7 +46,7 @@ func TestNewNodePosition(t *testing.T) {
EndPos: 3,
})
builder := position.Builder{
builder := parser.Builder{
Positions: p,
}
@ -68,7 +69,7 @@ func TestNewTokenNodePosition(t *testing.T) {
EndPos: 12,
})
builder := position.Builder{
builder := parser.Builder{
Positions: p,
}
@ -91,7 +92,7 @@ func TestNewNodeTokenPosition(t *testing.T) {
EndPos: 9,
})
builder := position.Builder{
builder := parser.Builder{
Positions: p,
}
@ -106,7 +107,7 @@ func TestNewNodeListPosition(t *testing.T) {
n1 := node.NewIdentifier("test node")
n2 := node.NewIdentifier("test node")
builder := position.Builder{
builder := parser.Builder{
Positions: &position.Positions{
n1: &position.Position{
StartLine: 1,
@ -134,7 +135,7 @@ func TestNewNodesPosition(t *testing.T) {
n1 := node.NewIdentifier("test node")
n2 := node.NewIdentifier("test node")
builder := position.Builder{
builder := parser.Builder{
Positions: &position.Positions{
n1: &position.Position{
StartLine: 1,
@ -163,7 +164,7 @@ func TestNewNodeListTokenPosition(t *testing.T) {
n2 := node.NewIdentifier("test node")
tkn := scanner.NewToken([]byte(`foo`), 3, 3, 20, 22)
builder := position.Builder{
builder := parser.Builder{
Positions: &position.Positions{
n1: &position.Position{
StartLine: 1,
@ -192,7 +193,7 @@ func TestNewTokenNodeListPosition(t *testing.T) {
n1 := node.NewIdentifier("test node")
n2 := node.NewIdentifier("test node")
builder := position.Builder{
builder := parser.Builder{
Positions: &position.Positions{
n1: &position.Position{
StartLine: 2,
@ -221,7 +222,7 @@ func TestNewNodeNodeListPosition(t *testing.T) {
n2 := node.NewIdentifier("test node")
n3 := node.NewIdentifier("test node")
builder := position.Builder{
builder := parser.Builder{
Positions: &position.Positions{
n1: &position.Position{
StartLine: 1,
@ -252,7 +253,7 @@ func TestNewNodeNodeListPosition(t *testing.T) {
}
func TestNewOptionalListTokensPosition(t *testing.T) {
builder := position.Builder{}
builder := parser.Builder{}
token1 := scanner.NewToken([]byte(`foo`), 1, 1, 0, 3)
token2 := scanner.NewToken([]byte(`foo`), 2, 2, 4, 6)
@ -269,7 +270,7 @@ func TestNewOptionalListTokensPosition2(t *testing.T) {
n2 := node.NewIdentifier("test node")
n3 := node.NewIdentifier("test node")
builder := position.Builder{
builder := parser.Builder{
Positions: &position.Positions{
n1: &position.Position{
StartLine: 1,
@ -303,7 +304,7 @@ func TestNewOptionalListTokensPosition2(t *testing.T) {
}
func TestNilNodePos(t *testing.T) {
builder := position.Builder{}
builder := parser.Builder{}
pos := builder.NewNodesPosition(nil, nil)
@ -315,7 +316,7 @@ func TestNilNodePos(t *testing.T) {
func TestNilNodeListPos(t *testing.T) {
n1 := node.NewIdentifier("test node")
builder := position.Builder{
builder := parser.Builder{
Positions: &position.Positions{
n1: &position.Position{
StartLine: 1,
@ -336,7 +337,7 @@ func TestNilNodeListPos(t *testing.T) {
func TestNilNodeListTokenPos(t *testing.T) {
token1 := scanner.NewToken([]byte(`foo`), 1, 1, 0, 3)
builder := position.Builder{}
builder := parser.Builder{}
pos := builder.NewNodeListTokenPosition(nil, token1)
@ -348,7 +349,7 @@ func TestNilNodeListTokenPos(t *testing.T) {
func TestEmptyNodeListPos(t *testing.T) {
n1 := node.NewIdentifier("test node")
builder := position.Builder{
builder := parser.Builder{
Positions: &position.Positions{
n1: &position.Position{
StartLine: 1,
@ -369,7 +370,7 @@ func TestEmptyNodeListPos(t *testing.T) {
func TestEmptyNodeListTokenPos(t *testing.T) {
token1 := scanner.NewToken([]byte(`foo`), 1, 1, 0, 3)
builder := position.Builder{}
builder := parser.Builder{}
pos := builder.NewNodeListTokenPosition([]node.Node{}, token1)

View File

@ -6,6 +6,7 @@ import (
"github.com/z7zmey/php-parser/comment"
"github.com/z7zmey/php-parser/errors"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/parser"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/scanner"
)
@ -19,7 +20,7 @@ type Parser struct {
*scanner.Lexer
path string
lastToken *scanner.Token
positionBuilder *position.Builder
positionBuilder *parser.Builder
errors []*errors.Error
rootNode node.Node
comments comment.Comments
@ -63,7 +64,7 @@ func (l *Parser) Parse() int {
l.rootNode = nil
l.comments = comment.Comments{}
l.positions = position.Positions{}
l.positionBuilder = &position.Builder{
l.positionBuilder = &parser.Builder{
Positions: &l.positions,
}

View File

@ -6,6 +6,7 @@ import (
"github.com/z7zmey/php-parser/comment"
"github.com/z7zmey/php-parser/errors"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/parser"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/scanner"
)
@ -19,7 +20,7 @@ type Parser struct {
*scanner.Lexer
path string
lastToken *scanner.Token
positionBuilder *position.Builder
positionBuilder *parser.Builder
errors []*errors.Error
rootNode node.Node
comments comment.Comments
@ -63,7 +64,7 @@ func (l *Parser) Parse() int {
l.rootNode = nil
l.comments = comment.Comments{}
l.positions = position.Positions{}
l.positionBuilder = &position.Builder{
l.positionBuilder = &parser.Builder{
Positions: &l.positions,
}

View File

@ -14,6 +14,16 @@ type Position struct {
EndPos int
}
// NewPosition Position constructor
func NewPosition(StartLine int, EndLine int, StartPos int, EndPos int) *Position {
return &Position{
StartLine: StartLine,
EndLine: EndLine,
StartPos: StartPos,
EndPos: EndPos,
}
}
func (p Position) String() string {
return fmt.Sprintf("Pos{Line: %d-%d Pos: %d-%d}", p.StartLine, p.EndLine, p.StartPos, p.EndPos)
}

View File

@ -8,6 +8,8 @@ import (
"io"
"unicode"
"github.com/z7zmey/php-parser/position"
"github.com/cznic/golex/lex"
"github.com/z7zmey/php-parser/comment"
)
@ -521,7 +523,17 @@ func (l *Lexer) newToken(chars []lex.Char) Token {
}
func (l *Lexer) addComment(chars []lex.Char) {
c := comment.NewComment(string(l.charsToBytes(chars)))
firstChar := chars[0]
lastChar := chars[len(chars)-1]
pos := position.NewPosition(
l.File.Line(firstChar.Pos()),
l.File.Line(lastChar.Pos()),
int(firstChar.Pos()),
int(lastChar.Pos()),
)
c := comment.NewComment(string(l.charsToBytes(chars)), pos)
l.Comments = append(l.Comments, c)
}

View File

@ -5,6 +5,8 @@ import (
"reflect"
"testing"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/comment"
"github.com/z7zmey/php-parser/scanner"
@ -873,7 +875,7 @@ func TestCommentEnd(t *testing.T) {
src := `<?php //test`
expected := []*comment.Comment{
comment.NewComment("//test"),
comment.NewComment("//test", position.NewPosition(1, 1, 7, 12)),
}
lexer := scanner.NewLexer(bytes.NewBufferString(src), "test.php")
@ -890,7 +892,7 @@ func TestCommentNewLine(t *testing.T) {
src := "<?php //test\n$a"
expected := []*comment.Comment{
comment.NewComment("//test\n"),
comment.NewComment("//test\n", position.NewPosition(1, 1, 7, 13)),
}
lexer := scanner.NewLexer(bytes.NewBufferString(src), "test.php")
@ -907,7 +909,7 @@ func TestCommentNewLine1(t *testing.T) {
src := "<?php //test\r$a"
expected := []*comment.Comment{
comment.NewComment("//test\r"),
comment.NewComment("//test\r", position.NewPosition(1, 1, 7, 13)),
}
lexer := scanner.NewLexer(bytes.NewBufferString(src), "test.php")
@ -924,7 +926,7 @@ func TestCommentNewLine2(t *testing.T) {
src := "<?php #test\r\n$a"
expected := []*comment.Comment{
comment.NewComment("#test\r\n"),
comment.NewComment("#test\r\n", position.NewPosition(1, 1, 7, 13)),
}
lexer := scanner.NewLexer(bytes.NewBufferString(src), "test.php")
@ -942,7 +944,7 @@ func TestCommentWithPhpEndTag(t *testing.T) {
//test?> test`
expected := []*comment.Comment{
comment.NewComment("//test"),
comment.NewComment("//test", position.NewPosition(2, 2, 8, 13)),
}
lexer := scanner.NewLexer(bytes.NewBufferString(src), "test.php")
@ -960,7 +962,7 @@ func TestInlineComment(t *testing.T) {
/*test*/`
expected := []*comment.Comment{
comment.NewComment("/*test*/"),
comment.NewComment("/*test*/", position.NewPosition(2, 2, 8, 15)),
}
lexer := scanner.NewLexer(bytes.NewBufferString(src), "test.php")
@ -978,7 +980,7 @@ func TestEmptyInlineComment(t *testing.T) {
/**/`
expected := []*comment.Comment{
comment.NewComment("/**/"),
comment.NewComment("/**/", position.NewPosition(2, 2, 8, 11)),
}
lexer := scanner.NewLexer(bytes.NewBufferString(src), "test.php")
@ -996,7 +998,7 @@ func TestEmptyInlineComment2(t *testing.T) {
/***/`
expected := []*comment.Comment{
comment.NewComment("/***/"),
comment.NewComment("/***/", position.NewPosition(2, 2, 8, 12)),
}
lexer := scanner.NewLexer(bytes.NewBufferString(src), "test.php")

View File

@ -13,7 +13,7 @@ func TestToken(t *testing.T) {
tkn := scanner.NewToken([]byte(`foo`), 1, 1, 0, 3)
c := []*comment.Comment{
comment.NewComment("test comment"),
comment.NewComment("test comment", nil),
}
tkn.SetComments(c)