diff --git a/comment/comment.go b/comment/comment.go index c8713f2..3aa4958 100644 --- a/comment/comment.go +++ b/comment/comment.go @@ -1,17 +1,28 @@ package comment +import ( + "github.com/z7zmey/php-parser/position" +) + // Comment aggrigates information about comment /** type Comment struct { - value string + 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 +} diff --git a/comment/comment_test.go b/comment/comment_test.go index 27980e9..c9389e2 100644 --- a/comment/comment_test.go +++ b/comment/comment_test.go @@ -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") + } +} diff --git a/position/builder.go b/parser/position_builder.go similarity index 78% rename from position/builder.go rename to parser/position_builder.go index 1a98c2f..9f9260e 100644 --- a/position/builder.go +++ b/parser/position_builder.go @@ -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, diff --git a/position/position_test.go b/parser/position_builder_test.go similarity index 93% rename from position/position_test.go rename to parser/position_builder_test.go index 01f1985..6166967 100644 --- a/position/position_test.go +++ b/parser/position_builder_test.go @@ -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) diff --git a/php5/parser.go b/php5/parser.go index 03a6f22..fd8fce3 100644 --- a/php5/parser.go +++ b/php5/parser.go @@ -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, } diff --git a/php7/parser.go b/php7/parser.go index 9c3b34b..4529c35 100644 --- a/php7/parser.go +++ b/php7/parser.go @@ -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, } diff --git a/position/position.go b/position/position.go index f619e7b..0ca3c80 100644 --- a/position/position.go +++ b/position/position.go @@ -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) } diff --git a/scanner/lexer.go b/scanner/lexer.go index e415f8e..999f009 100644 --- a/scanner/lexer.go +++ b/scanner/lexer.go @@ -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) } diff --git a/scanner/scanner_test.go b/scanner/scanner_test.go index b63afb5..3195757 100644 --- a/scanner/scanner_test.go +++ b/scanner/scanner_test.go @@ -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 := ` 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") diff --git a/scanner/token_test.go b/scanner/token_test.go index 9864882..2993267 100644 --- a/scanner/token_test.go +++ b/scanner/token_test.go @@ -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)