From 7c12f739749ef141c89b680fd0b81440e95afbfd Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Sun, 26 Mar 2023 01:54:00 +0100 Subject: [PATCH] feat: add start column and end column to position struct --- internal/php7/lexer.go | 22 +++++++--- internal/php7/newline.go | 25 ------------ internal/php7/parser_test.go | 5 +++ internal/php8/lexer.go | 32 +++++++++++---- internal/php8/newline.go | 25 ------------ internal/php8/parser_php8_2_test.go | 2 +- internal/php8/parser_php8_test.go | 28 ++++++------- internal/php8/parser_test.go | 5 +++ internal/php8/scanner_php8_test.go | 16 ++++---- internal/position/newline.go | 41 +++++++++++++++++++ internal/position/newline_test.go | 56 +++++++++++++++++++++++++ internal/position/position.go | 59 ++++++++++++++++++++++----- internal/position/position_test.go | 47 +++++++++++++++++---- internal/tester/lexer_token_struct.go | 1 + internal/tester/parser_error.go | 1 + pkg/errors/error_test.go | 4 +- pkg/position/position.go | 47 ++++++++++++++++++++- pkg/visitor/dumper/dumper.go | 2 + pkg/visitor/dumper/dumper_test.go | 7 +++- 19 files changed, 316 insertions(+), 109 deletions(-) delete mode 100644 internal/php7/newline.go delete mode 100644 internal/php8/newline.go create mode 100644 internal/position/newline.go create mode 100644 internal/position/newline_test.go diff --git a/internal/php7/lexer.go b/internal/php7/lexer.go index e181311..c4991af 100644 --- a/internal/php7/lexer.go +++ b/internal/php7/lexer.go @@ -4,6 +4,7 @@ import ( "bytes" "strings" + pos "github.com/VKCOM/php-parser/internal/position" "github.com/VKCOM/php-parser/pkg/conf" "github.com/VKCOM/php-parser/pkg/errors" "github.com/VKCOM/php-parser/pkg/position" @@ -24,7 +25,7 @@ type Lexer struct { heredocLabel []byte tokenPool *token.Pool positionPool *position.Pool - newLines NewLines + newLines pos.NewLines } func NewLexer(data []byte, config conf.Config) *Lexer { @@ -38,7 +39,7 @@ func NewLexer(data []byte, config conf.Config) *Lexer { tokenPool: token.NewPool(position.DefaultBlockSize), positionPool: position.NewPool(token.DefaultBlockSize), - newLines: NewLines{make([]int, 0, 128)}, + newLines: pos.NewNewLines(), } initLexer(lex) @@ -49,10 +50,15 @@ func NewLexer(data []byte, config conf.Config) *Lexer { func (lex *Lexer) setTokenPosition(token *token.Token) { pos := lex.positionPool.Get() - pos.StartLine = lex.newLines.GetLine(lex.ts) - pos.EndLine = lex.newLines.GetLine(lex.te - 1) + sl, slb := lex.newLines.GetLine(lex.ts) + el, elb := lex.newLines.GetLine(lex.te - 1) + + pos.StartLine = sl + pos.EndLine = el pos.StartPos = lex.ts pos.EndPos = lex.te + pos.StartCol = lex.ts - slb + pos.EndCol = lex.te - elb token.Position = pos } @@ -232,11 +238,15 @@ func (lex *Lexer) error(msg string) { return } + sl, slb := lex.newLines.GetLine(lex.ts) + el, elb := lex.newLines.GetLine(lex.te - 1) pos := position.NewPosition( - lex.newLines.GetLine(lex.ts), - lex.newLines.GetLine(lex.te-1), + sl, + el, lex.ts, lex.te, + lex.ts-slb, + lex.te-elb, ) lex.errHandlerFunc(errors.NewError(msg, pos)) diff --git a/internal/php7/newline.go b/internal/php7/newline.go deleted file mode 100644 index e540c43..0000000 --- a/internal/php7/newline.go +++ /dev/null @@ -1,25 +0,0 @@ -package php7 - -type NewLines struct { - data []int -} - -func (nl *NewLines) Append(p int) { - if len(nl.data) == 0 || nl.data[len(nl.data)-1] < p { - nl.data = append(nl.data, p) - } -} - -func (nl *NewLines) GetLine(p int) int { - line := len(nl.data) + 1 - - for i := len(nl.data) - 1; i >= 0; i-- { - if p < nl.data[i] { - line = i + 1 - } else { - break - } - } - - return line -} diff --git a/internal/php7/parser_test.go b/internal/php7/parser_test.go index 980b373..c90eca2 100644 --- a/internal/php7/parser_test.go +++ b/internal/php7/parser_test.go @@ -14,6 +14,11 @@ import ( "github.com/VKCOM/php-parser/pkg/version" ) +func TestMain(m *testing.M) { + // Ignore StartCol and EndCol in equality checks, these tests were written before they were added. + position.CheckColEquality = false +} + func TestIdentifier(t *testing.T) { src := `= 0; i-- { - if p < nl.data[i] { - line = i + 1 - } else { - break - } - } - - return line -} diff --git a/internal/php8/parser_php8_2_test.go b/internal/php8/parser_php8_2_test.go index 3e24255..0629516 100644 --- a/internal/php8/parser_php8_2_test.go +++ b/internal/php8/parser_php8_2_test.go @@ -409,7 +409,7 @@ trait Foo { } ` - suite.Expected = `&ast.Root{ + suite.Expected = `&ast.Root{ Stmts: []ast.Vertex{ &ast.StmtTrait{ Name: &ast.Identifier{ diff --git a/internal/php8/parser_php8_test.go b/internal/php8/parser_php8_test.go index 1b6f3ab..413d598 100644 --- a/internal/php8/parser_php8_test.go +++ b/internal/php8/parser_php8_test.go @@ -1435,7 +1435,7 @@ func TestRealCastParserError(t *testing.T) { suite.Expected = []*errors.Error{ { Msg: "The (real) cast has been removed, use (float) instead", - Pos: position.NewPosition(2, 2, 7, 13), + Pos: position.NewPosition(2, 2, 7, 13, 1, 7), }, } @@ -1455,7 +1455,7 @@ func TestUnsetCastParserError(t *testing.T) { suite.Expected = []*errors.Error{ { Msg: "The (unset) cast is no longer supported", - Pos: position.NewPosition(2, 2, 7, 14), + Pos: position.NewPosition(2, 2, 7, 14, 1, 1), }, } @@ -1980,15 +1980,15 @@ new $a{10}; // Error suite.Expected = []*errors.Error{ { Msg: "Array and string offset access syntax with curly braces is no longer supported", - Pos: position.NewPosition(3, 3, 26, 27), + Pos: position.NewPosition(3, 3, 26, 27, 1, 1), }, { Msg: "Array and string offset access syntax with curly braces is no longer supported", - Pos: position.NewPosition(9, 9, 97, 98), + Pos: position.NewPosition(9, 9, 97, 98, 1, 1), }, { Msg: "Array and string offset access syntax with curly braces is no longer supported", - Pos: position.NewPosition(12, 12, 137, 138), + Pos: position.NewPosition(12, 12, 137, 138, 1, 1), }, } @@ -3020,19 +3020,19 @@ class Foo { suite.Expected = []*errors.Error{ { Msg: "syntax error: unexpected T_STATIC, expecting T_VARIABLE", - Pos: position.NewPosition(2, 2, 18, 24), + Pos: position.NewPosition(2, 2, 18, 24, 1, 1), }, { Msg: "syntax error: unexpected T_STATIC, expecting T_VARIABLE", - Pos: position.NewPosition(3, 3, 48, 54), + Pos: position.NewPosition(3, 3, 48, 54, 1, 1), }, { Msg: "syntax error: unexpected '|', expecting T_VARIABLE", - Pos: position.NewPosition(8, 8, 154, 155), + Pos: position.NewPosition(8, 8, 154, 155, 1, 1), }, { Msg: "syntax error: unexpected '}'", - Pos: position.NewPosition(10, 10, 182, 183), + Pos: position.NewPosition(10, 10, 182, 183, 1, 1), }, } @@ -3051,15 +3051,15 @@ function f(int|string|null $a) {} // ok suite.Expected = []*errors.Error{ { Msg: "syntax error: unexpected '|', expecting T_VARIABLE", - Pos: position.NewPosition(2, 2, 22, 23), + Pos: position.NewPosition(2, 2, 22, 23, 1, 1), }, { Msg: "syntax error: unexpected '('", - Pos: position.NewPosition(3, 3, 49, 50), + Pos: position.NewPosition(3, 3, 49, 50, 1, 1), }, { Msg: "syntax error: unexpected T_VARIABLE", - Pos: position.NewPosition(3, 3, 62, 64), + Pos: position.NewPosition(3, 3, 62, 64, 1, 1), }, } @@ -4537,7 +4537,7 @@ use \ Foo \ Boo; suite.Expected = []*errors.Error{ { Msg: "syntax error: unexpected T_NS_SEPARATOR", - Pos: position.NewPosition(2, 2, 11, 12), + Pos: position.NewPosition(2, 2, 11, 12, 1, 1), }, } @@ -4554,7 +4554,7 @@ function f(\Foo \ Boo $a) {} suite.Expected = []*errors.Error{ { Msg: "syntax error: unexpected T_NS_SEPARATOR, expecting T_VARIABLE", - Pos: position.NewPosition(2, 2, 23, 24), + Pos: position.NewPosition(2, 2, 23, 24, 1, 1), }, } diff --git a/internal/php8/parser_test.go b/internal/php8/parser_test.go index cf9d4b0..3e36157 100644 --- a/internal/php8/parser_test.go +++ b/internal/php8/parser_test.go @@ -14,6 +14,11 @@ import ( "github.com/VKCOM/php-parser/pkg/version" ) +func TestMain(m *testing.M) { + // Ignore StartCol and EndCol in equality checks, these tests were written before they were added. + position.CheckColEquality = false +} + func TestIdentifier(t *testing.T) { src := ` 0 { + lineStart = nl.data[len(nl.data)-1] + } + + for i := len(nl.data) - 1; i >= 0; i-- { + if p < nl.data[i] { + line = i + 1 + + if i-1 >= 0 { + lineStart = nl.data[i-1] + } else { + lineStart = 0 + } + } else { + break + } + } + + return line, lineStart +} diff --git a/internal/position/newline_test.go b/internal/position/newline_test.go new file mode 100644 index 0000000..ad602ca --- /dev/null +++ b/internal/position/newline_test.go @@ -0,0 +1,56 @@ +package position_test + +import ( + "strconv" + "testing" + + "github.com/VKCOM/php-parser/internal/position" + "gotest.tools/assert" +) + +func TestNewLine(t *testing.T) { + cases := []struct { + lines []int + pos int + expectedLine int + expectedBol int + }{ + { + lines: []int{}, + pos: 0, + expectedLine: 1, + expectedBol: 0, + }, + { + lines: []int{3, 10, 28}, + pos: 4, + expectedLine: 2, + expectedBol: 3, + }, + { + lines: []int{7}, + pos: 7, + expectedLine: 2, + expectedBol: 7, + }, + { + lines: []int{6, 8, 16, 18, 19, 21, 22}, + pos: 8, + expectedLine: 3, + expectedBol: 8, + }, + } + + for i, tt := range cases { + t.Run(strconv.Itoa(i), func(t *testing.T) { + nl := position.NewNewLines() + for _, l := range tt.lines { + nl.Append(l) + } + + line, bol := nl.GetLine(tt.pos) + assert.Equal(t, line, tt.expectedLine) + assert.Equal(t, bol, tt.expectedBol) + }) + } +} diff --git a/internal/position/position.go b/internal/position/position.go index 052428c..7a44a63 100644 --- a/internal/position/position.go +++ b/internal/position/position.go @@ -9,11 +9,13 @@ import ( type startPos struct { startLine int startPos int + startCol int } type endPos struct { endLine int endPos int + endCol int } type Builder struct { @@ -28,11 +30,11 @@ func NewBuilder() *Builder { func getListStartPos(l []ast.Vertex) startPos { if l == nil { - return startPos{-1, -1} + return startPos{-1, -1, -1} } if len(l) == 0 { - return startPos{-1, -1} + return startPos{-1, -1, -1} } return getNodeStartPos(l[0]) @@ -41,27 +43,29 @@ func getListStartPos(l []ast.Vertex) startPos { func getNodeStartPos(n ast.Vertex) startPos { sl := -1 sp := -1 + sc := -1 if n == nil { - return startPos{-1, -1} + return startPos{-1, -1, -1} } p := n.GetPosition() if p != nil { sl = p.StartLine sp = p.StartPos + sc = p.StartCol } - return startPos{sl, sp} + return startPos{sl, sp, sc} } func getListEndPos(l []ast.Vertex) endPos { if l == nil { - return endPos{-1, -1} + return endPos{-1, -1, -1} } if len(l) == 0 { - return endPos{-1, -1} + return endPos{-1, -1, -1} } return getNodeEndPos(l[len(l)-1]) @@ -70,18 +74,20 @@ func getListEndPos(l []ast.Vertex) endPos { func getNodeEndPos(n ast.Vertex) endPos { el := -1 ep := -1 + ec := -1 if n == nil { - return endPos{-1, -1} + return endPos{-1, -1, -1} } p := n.GetPosition() if p != nil { el = p.EndLine ep = p.EndPos + ec = p.EndCol } - return endPos{el, ep} + return endPos{el, ep, ec} } // NewNodeListPosition returns new Position @@ -92,6 +98,8 @@ func (b *Builder) NewNodeListPosition(list []ast.Vertex) *position.Position { pos.EndLine = getListEndPos(list).endLine pos.StartPos = getListStartPos(list).startPos pos.EndPos = getListEndPos(list).endPos + pos.StartCol = getListStartPos(list).startCol + pos.EndCol = getListEndPos(list).endCol return pos } @@ -104,6 +112,8 @@ func (b *Builder) NewNodePosition(n ast.Vertex) *position.Position { pos.EndLine = getNodeEndPos(n).endLine pos.StartPos = getNodeStartPos(n).startPos pos.EndPos = getNodeEndPos(n).endPos + pos.StartCol = getNodeStartPos(n).startCol + pos.EndCol = getNodeEndPos(n).endCol return pos } @@ -116,18 +126,25 @@ func (b *Builder) NewTokenPosition(t *token.Token) *position.Position { pos.EndLine = t.Position.EndLine pos.StartPos = t.Position.StartPos pos.EndPos = t.Position.EndPos + pos.StartCol = t.Position.StartCol + pos.EndCol = t.Position.EndCol return pos } // NewTokensPosition returns new Position -func (b *Builder) NewTokensPosition(startToken *token.Token, endToken *token.Token) *position.Position { +func (b *Builder) NewTokensPosition( + startToken *token.Token, + endToken *token.Token, +) *position.Position { pos := b.pool.Get() pos.StartLine = startToken.Position.StartLine pos.EndLine = endToken.Position.EndLine pos.StartPos = startToken.Position.StartPos pos.EndPos = endToken.Position.EndPos + pos.StartCol = endToken.Position.StartCol + pos.EndCol = endToken.Position.EndCol return pos } @@ -140,6 +157,8 @@ func (b *Builder) NewTokenNodePosition(t *token.Token, n ast.Vertex) *position.P pos.EndLine = getNodeEndPos(n).endLine pos.StartPos = t.Position.StartPos pos.EndPos = getNodeEndPos(n).endPos + pos.StartCol = t.Position.StartCol + pos.EndCol = getNodeEndPos(n).endCol return pos } @@ -152,6 +171,8 @@ func (b *Builder) NewNodeTokenPosition(n ast.Vertex, t *token.Token) *position.P pos.EndLine = t.Position.EndLine pos.StartPos = getNodeStartPos(n).startPos pos.EndPos = t.Position.EndPos + pos.StartCol = getNodeStartPos(n).startCol + pos.EndCol = t.Position.EndCol return pos } @@ -164,6 +185,8 @@ func (b *Builder) NewNodesPosition(startNode ast.Vertex, endNode ast.Vertex) *po pos.EndLine = getNodeEndPos(endNode).endLine pos.StartPos = getNodeStartPos(startNode).startPos pos.EndPos = getNodeEndPos(endNode).endPos + pos.StartCol = getNodeStartPos(startNode).startCol + pos.EndCol = getNodeEndPos(endNode).endCol return pos } @@ -176,6 +199,8 @@ func (b *Builder) NewNodeListTokenPosition(list []ast.Vertex, t *token.Token) *p pos.EndLine = t.Position.EndLine pos.StartPos = getListStartPos(list).startPos pos.EndPos = t.Position.EndPos + pos.StartCol = getListStartPos(list).startCol + pos.EndCol = t.Position.EndCol return pos } @@ -188,6 +213,8 @@ func (b *Builder) NewTokenNodeListPosition(t *token.Token, list []ast.Vertex) *p pos.EndLine = getListEndPos(list).endLine pos.StartPos = t.Position.StartPos pos.EndPos = getListEndPos(list).endPos + pos.StartCol = t.Position.StartCol + pos.EndCol = getListEndPos(list).endCol return pos } @@ -200,6 +227,8 @@ func (b *Builder) NewNodeNodeListPosition(n ast.Vertex, list []ast.Vertex) *posi pos.EndLine = getListEndPos(list).endLine pos.StartPos = getNodeStartPos(n).startPos pos.EndPos = getListEndPos(list).endPos + pos.StartCol = getNodeStartPos(n).startCol + pos.EndCol = getListEndPos(list).endCol return pos } @@ -212,12 +241,18 @@ func (b *Builder) NewNodeListNodePosition(list []ast.Vertex, n ast.Vertex) *posi pos.EndLine = getNodeEndPos(n).endLine pos.StartPos = getListStartPos(list).startPos pos.EndPos = getNodeEndPos(n).endPos + pos.StartCol = getListStartPos(list).startCol + pos.EndCol = getNodeEndPos(n).endCol return pos } // NewOptionalListTokensPosition returns new Position -func (b *Builder) NewOptionalListTokensPosition(list []ast.Vertex, t *token.Token, endToken *token.Token) *position.Position { +func (b *Builder) NewOptionalListTokensPosition( + list []ast.Vertex, + t *token.Token, + endToken *token.Token, +) *position.Position { pos := b.pool.Get() if list == nil { @@ -225,6 +260,8 @@ func (b *Builder) NewOptionalListTokensPosition(list []ast.Vertex, t *token.Toke pos.EndLine = endToken.Position.EndLine pos.StartPos = t.Position.StartPos pos.EndPos = endToken.Position.EndPos + pos.StartCol = t.Position.StartCol + pos.EndCol = endToken.Position.EndCol return pos } @@ -232,6 +269,8 @@ func (b *Builder) NewOptionalListTokensPosition(list []ast.Vertex, t *token.Toke pos.EndLine = endToken.Position.EndLine pos.StartPos = getListStartPos(list).startPos pos.EndPos = endToken.Position.EndPos + pos.StartCol = getListStartPos(list).startCol + pos.EndCol = endToken.Position.EndCol return pos } diff --git a/internal/position/position_test.go b/internal/position/position_test.go index e378bec..1dd0c51 100644 --- a/internal/position/position_test.go +++ b/internal/position/position_test.go @@ -1,9 +1,10 @@ package position_test import ( - "gotest.tools/assert" "testing" + "gotest.tools/assert" + builder "github.com/VKCOM/php-parser/internal/position" "github.com/VKCOM/php-parser/pkg/ast" "github.com/VKCOM/php-parser/pkg/position" @@ -18,12 +19,18 @@ func TestNewTokenPosition(t *testing.T) { EndLine: 1, StartPos: 0, EndPos: 3, + StartCol: 1, + EndCol: 2, }, } pos := builder.NewBuilder().NewTokenPosition(tkn) - assert.DeepEqual(t, &position.Position{StartLine: 1, EndLine: 1, EndPos: 3}, pos) + assert.DeepEqual( + t, + &position.Position{StartLine: 1, EndLine: 1, EndPos: 3, StartCol: 1, EndCol: 2}, + pos, + ) } func TestNewTokensPosition(t *testing.T) { @@ -365,7 +372,18 @@ func TestNewOptionalListTokensPosition2(t *testing.T) { func TestNilNodePos(t *testing.T) { pos := builder.NewBuilder().NewNodesPosition(nil, nil) - assert.DeepEqual(t, &position.Position{StartLine: -1, EndLine: -1, StartPos: -1, EndPos: -1}, pos) + assert.DeepEqual( + t, + &position.Position{ + StartLine: -1, + EndLine: -1, + StartPos: -1, + EndPos: -1, + StartCol: -1, + EndCol: -1, + }, + pos, + ) } func TestNilNodeListPos(t *testing.T) { @@ -380,7 +398,7 @@ func TestNilNodeListPos(t *testing.T) { pos := builder.NewBuilder().NewNodeNodeListPosition(n1, nil) - assert.DeepEqual(t, &position.Position{StartLine: 1, EndLine: -1, EndPos: -1}, pos) + assert.DeepEqual(t, &position.Position{StartLine: 1, EndLine: -1, EndPos: -1, EndCol: -1}, pos) } func TestNilNodeListTokenPos(t *testing.T) { @@ -396,7 +414,18 @@ func TestNilNodeListTokenPos(t *testing.T) { pos := builder.NewBuilder().NewNodeListTokenPosition(nil, tkn) - assert.DeepEqual(t, &position.Position{StartLine: -1, EndLine: 1, StartPos: -1, EndPos: 3}, pos) + assert.DeepEqual( + t, + &position.Position{ + StartLine: -1, + EndLine: 1, + StartPos: -1, + EndPos: 3, + StartCol: -1, + EndCol: 0, + }, + pos, + ) } func TestEmptyNodeListPos(t *testing.T) { @@ -411,7 +440,7 @@ func TestEmptyNodeListPos(t *testing.T) { pos := builder.NewBuilder().NewNodeNodeListPosition(n1, []ast.Vertex{}) - assert.DeepEqual(t, &position.Position{StartLine: 1, EndLine: -1, EndPos: -1}, pos) + assert.DeepEqual(t, &position.Position{StartLine: 1, EndLine: -1, EndPos: -1, EndCol: -1}, pos) } func TestEmptyNodeListTokenPos(t *testing.T) { @@ -427,5 +456,9 @@ func TestEmptyNodeListTokenPos(t *testing.T) { pos := builder.NewBuilder().NewNodeListTokenPosition([]ast.Vertex{}, tkn) - assert.DeepEqual(t, &position.Position{StartLine: -1, EndLine: 1, StartPos: -1, EndPos: 3}, pos) + assert.DeepEqual( + t, + &position.Position{StartLine: -1, EndLine: 1, StartPos: -1, EndPos: 3, StartCol: -1}, + pos, + ) } diff --git a/internal/tester/lexer_token_struct.go b/internal/tester/lexer_token_struct.go index 694f8b4..eda5a38 100644 --- a/internal/tester/lexer_token_struct.go +++ b/internal/tester/lexer_token_struct.go @@ -46,6 +46,7 @@ func (l *LexerTokenStructTestSuite) WithFreeFloating() { } func (l *LexerTokenStructTestSuite) Run() { + l.t.Helper() config := conf.Config{ Version: &l.Version, } diff --git a/internal/tester/parser_error.go b/internal/tester/parser_error.go index 6707ea3..d29a6dc 100644 --- a/internal/tester/parser_error.go +++ b/internal/tester/parser_error.go @@ -34,6 +34,7 @@ func (p *ParserErrorTestSuite) UsePHP8() { } func (p *ParserErrorTestSuite) Run() { + p.t.Helper() config := conf.Config{ Version: &p.Version, } diff --git a/pkg/errors/error_test.go b/pkg/errors/error_test.go index 8179396..fff8f72 100644 --- a/pkg/errors/error_test.go +++ b/pkg/errors/error_test.go @@ -10,7 +10,7 @@ import ( ) func TestConstructor(t *testing.T) { - pos := position.NewPosition(1, 2, 3, 4) + pos := position.NewPosition(1, 2, 3, 4, 1, 2) actual := errors.NewError("message", pos) @@ -23,7 +23,7 @@ func TestConstructor(t *testing.T) { } func TestPrint(t *testing.T) { - pos := position.NewPosition(1, 2, 3, 4) + pos := position.NewPosition(1, 2, 3, 4, 1, 2) Error := errors.NewError("message", pos) diff --git a/pkg/position/position.go b/pkg/position/position.go index ffe4746..b33a4fb 100644 --- a/pkg/position/position.go +++ b/pkg/position/position.go @@ -1,19 +1,64 @@ package position +// Tests that were written before the addition of StartCol and EndCol can set this to false, +// Which will not check if StartCol or EndCol are equal in the Equal function. +var CheckColEquality = true + // Position represents node position type Position struct { StartLine int EndLine int + StartCol int + EndCol int StartPos int EndPos int } // NewPosition Position constructor -func NewPosition(StartLine int, EndLine int, StartPos int, EndPos int) *Position { +func NewPosition( + StartLine int, + EndLine int, + StartPos int, + EndPos int, + StartCol int, + EndCol int, +) *Position { return &Position{ StartLine: StartLine, EndLine: EndLine, StartPos: StartPos, EndPos: EndPos, + StartCol: StartCol, + EndCol: EndCol, } } + +func (p Position) Equal(other Position) bool { + if p.StartLine != other.StartLine { + return false + } + + if p.StartPos != other.StartPos { + return false + } + + if p.EndLine != other.EndLine { + return false + } + + if p.EndPos != other.EndPos { + return false + } + + if CheckColEquality { + if p.StartCol != other.StartCol { + return false + } + + if p.EndCol != other.EndCol { + return false + } + } + + return true +} diff --git a/pkg/visitor/dumper/dumper.go b/pkg/visitor/dumper/dumper.go index cf6bcd6..c76f152 100644 --- a/pkg/visitor/dumper/dumper.go +++ b/pkg/visitor/dumper/dumper.go @@ -148,6 +148,8 @@ func (v *Dumper) dumpPosition(pos *position.Position) { v.print(v.indent, "StartLine: "+strconv.Itoa(pos.StartLine)+",\n") v.print(v.indent, "EndLine: "+strconv.Itoa(pos.EndLine)+",\n") + v.print(v.indent, "StartCol: "+strconv.Itoa(pos.StartCol)+",\n") + v.print(v.indent, "EndCol: "+strconv.Itoa(pos.EndCol)+",\n") v.print(v.indent, "StartPos: "+strconv.Itoa(pos.StartPos)+",\n") v.print(v.indent, "EndPos: "+strconv.Itoa(pos.EndPos)+",\n") diff --git a/pkg/visitor/dumper/dumper_test.go b/pkg/visitor/dumper/dumper_test.go index df28339..bcd9095 100644 --- a/pkg/visitor/dumper/dumper_test.go +++ b/pkg/visitor/dumper/dumper_test.go @@ -2,10 +2,11 @@ package dumper_test import ( "bytes" + "testing" + "github.com/VKCOM/php-parser/pkg/position" "github.com/VKCOM/php-parser/pkg/token" "github.com/VKCOM/php-parser/pkg/visitor/dumper" - "testing" "github.com/VKCOM/php-parser/pkg/ast" ) @@ -45,6 +46,8 @@ func TestDumper_root(t *testing.T) { Position: &position.Position{ StartLine: 1, EndLine: 2, + StartCol: 0, + EndCol: 0, StartPos: 3, EndPos: 4, }, @@ -60,6 +63,8 @@ func TestDumper_root(t *testing.T) { Position: &position.Position{ StartLine: 1, EndLine: 2, + StartCol: 0, + EndCol: 0, StartPos: 3, EndPos: 4, },