feat: add start column and end column to position struct
This commit is contained in:
parent
92019441d0
commit
7c12f73974
@ -4,6 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
pos "github.com/VKCOM/php-parser/internal/position"
|
||||||
"github.com/VKCOM/php-parser/pkg/conf"
|
"github.com/VKCOM/php-parser/pkg/conf"
|
||||||
"github.com/VKCOM/php-parser/pkg/errors"
|
"github.com/VKCOM/php-parser/pkg/errors"
|
||||||
"github.com/VKCOM/php-parser/pkg/position"
|
"github.com/VKCOM/php-parser/pkg/position"
|
||||||
@ -24,7 +25,7 @@ type Lexer struct {
|
|||||||
heredocLabel []byte
|
heredocLabel []byte
|
||||||
tokenPool *token.Pool
|
tokenPool *token.Pool
|
||||||
positionPool *position.Pool
|
positionPool *position.Pool
|
||||||
newLines NewLines
|
newLines pos.NewLines
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLexer(data []byte, config conf.Config) *Lexer {
|
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),
|
tokenPool: token.NewPool(position.DefaultBlockSize),
|
||||||
positionPool: position.NewPool(token.DefaultBlockSize),
|
positionPool: position.NewPool(token.DefaultBlockSize),
|
||||||
newLines: NewLines{make([]int, 0, 128)},
|
newLines: pos.NewNewLines(),
|
||||||
}
|
}
|
||||||
|
|
||||||
initLexer(lex)
|
initLexer(lex)
|
||||||
@ -49,10 +50,15 @@ func NewLexer(data []byte, config conf.Config) *Lexer {
|
|||||||
func (lex *Lexer) setTokenPosition(token *token.Token) {
|
func (lex *Lexer) setTokenPosition(token *token.Token) {
|
||||||
pos := lex.positionPool.Get()
|
pos := lex.positionPool.Get()
|
||||||
|
|
||||||
pos.StartLine = lex.newLines.GetLine(lex.ts)
|
sl, slb := lex.newLines.GetLine(lex.ts)
|
||||||
pos.EndLine = lex.newLines.GetLine(lex.te - 1)
|
el, elb := lex.newLines.GetLine(lex.te - 1)
|
||||||
|
|
||||||
|
pos.StartLine = sl
|
||||||
|
pos.EndLine = el
|
||||||
pos.StartPos = lex.ts
|
pos.StartPos = lex.ts
|
||||||
pos.EndPos = lex.te
|
pos.EndPos = lex.te
|
||||||
|
pos.StartCol = lex.ts - slb
|
||||||
|
pos.EndCol = lex.te - elb
|
||||||
|
|
||||||
token.Position = pos
|
token.Position = pos
|
||||||
}
|
}
|
||||||
@ -232,11 +238,15 @@ func (lex *Lexer) error(msg string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sl, slb := lex.newLines.GetLine(lex.ts)
|
||||||
|
el, elb := lex.newLines.GetLine(lex.te - 1)
|
||||||
pos := position.NewPosition(
|
pos := position.NewPosition(
|
||||||
lex.newLines.GetLine(lex.ts),
|
sl,
|
||||||
lex.newLines.GetLine(lex.te-1),
|
el,
|
||||||
lex.ts,
|
lex.ts,
|
||||||
lex.te,
|
lex.te,
|
||||||
|
lex.ts-slb,
|
||||||
|
lex.te-elb,
|
||||||
)
|
)
|
||||||
|
|
||||||
lex.errHandlerFunc(errors.NewError(msg, pos))
|
lex.errHandlerFunc(errors.NewError(msg, pos))
|
||||||
|
@ -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
|
|
||||||
}
|
|
@ -14,6 +14,11 @@ import (
|
|||||||
"github.com/VKCOM/php-parser/pkg/version"
|
"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) {
|
func TestIdentifier(t *testing.T) {
|
||||||
src := `<? $foo;`
|
src := `<? $foo;`
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
pos "github.com/VKCOM/php-parser/internal/position"
|
||||||
"github.com/VKCOM/php-parser/pkg/conf"
|
"github.com/VKCOM/php-parser/pkg/conf"
|
||||||
"github.com/VKCOM/php-parser/pkg/errors"
|
"github.com/VKCOM/php-parser/pkg/errors"
|
||||||
"github.com/VKCOM/php-parser/pkg/position"
|
"github.com/VKCOM/php-parser/pkg/position"
|
||||||
@ -16,7 +17,11 @@ type Lexer struct {
|
|||||||
phpVersion *version.Version
|
phpVersion *version.Version
|
||||||
errHandlerFunc func(*errors.Error)
|
errHandlerFunc func(*errors.Error)
|
||||||
|
|
||||||
p, pe, cs int
|
// p: current position being lexed/checked.
|
||||||
|
// pe: length in bytes of input.
|
||||||
|
p, pe, cs int
|
||||||
|
// ts: start position of the current token.
|
||||||
|
// te: end position of the current token.
|
||||||
ts, te, act int
|
ts, te, act int
|
||||||
stack []int
|
stack []int
|
||||||
top int
|
top int
|
||||||
@ -24,7 +29,7 @@ type Lexer struct {
|
|||||||
heredocLabel []byte
|
heredocLabel []byte
|
||||||
tokenPool *token.Pool
|
tokenPool *token.Pool
|
||||||
positionPool *position.Pool
|
positionPool *position.Pool
|
||||||
newLines NewLines
|
newLines pos.NewLines
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLexer(data []byte, config conf.Config) *Lexer {
|
func NewLexer(data []byte, config conf.Config) *Lexer {
|
||||||
@ -36,9 +41,9 @@ func NewLexer(data []byte, config conf.Config) *Lexer {
|
|||||||
pe: len(data),
|
pe: len(data),
|
||||||
stack: make([]int, 0),
|
stack: make([]int, 0),
|
||||||
|
|
||||||
tokenPool: token.NewPool(position.DefaultBlockSize),
|
tokenPool: token.NewPool(token.DefaultBlockSize),
|
||||||
positionPool: position.NewPool(token.DefaultBlockSize),
|
positionPool: position.NewPool(position.DefaultBlockSize),
|
||||||
newLines: NewLines{make([]int, 0, 128)},
|
newLines: pos.NewNewLines(),
|
||||||
}
|
}
|
||||||
|
|
||||||
initLexer(lex)
|
initLexer(lex)
|
||||||
@ -49,10 +54,15 @@ func NewLexer(data []byte, config conf.Config) *Lexer {
|
|||||||
func (lex *Lexer) setTokenPosition(token *token.Token) {
|
func (lex *Lexer) setTokenPosition(token *token.Token) {
|
||||||
pos := lex.positionPool.Get()
|
pos := lex.positionPool.Get()
|
||||||
|
|
||||||
pos.StartLine = lex.newLines.GetLine(lex.ts)
|
sl, slb := lex.newLines.GetLine(lex.ts)
|
||||||
pos.EndLine = lex.newLines.GetLine(lex.te - 1)
|
el, elb := lex.newLines.GetLine(lex.te - 1)
|
||||||
|
|
||||||
|
pos.StartLine = sl
|
||||||
|
pos.EndLine = el
|
||||||
pos.StartPos = lex.ts
|
pos.StartPos = lex.ts
|
||||||
pos.EndPos = lex.te
|
pos.EndPos = lex.te
|
||||||
|
pos.StartCol = lex.ts - slb
|
||||||
|
pos.EndCol = lex.te - elb
|
||||||
|
|
||||||
token.Position = pos
|
token.Position = pos
|
||||||
}
|
}
|
||||||
@ -249,11 +259,15 @@ func (lex *Lexer) error(msg string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sl, slb := lex.newLines.GetLine(lex.ts)
|
||||||
|
el, elb := lex.newLines.GetLine(lex.te - 1)
|
||||||
pos := position.NewPosition(
|
pos := position.NewPosition(
|
||||||
lex.newLines.GetLine(lex.ts),
|
sl,
|
||||||
lex.newLines.GetLine(lex.te-1),
|
el,
|
||||||
lex.ts,
|
lex.ts,
|
||||||
lex.te,
|
lex.te,
|
||||||
|
lex.ts-slb,
|
||||||
|
lex.te-elb,
|
||||||
)
|
)
|
||||||
|
|
||||||
lex.errHandlerFunc(errors.NewError(msg, pos))
|
lex.errHandlerFunc(errors.NewError(msg, pos))
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
package php8
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
@ -409,7 +409,7 @@ trait Foo {
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
suite.Expected = `&ast.Root{
|
suite.Expected = `&ast.Root{
|
||||||
Stmts: []ast.Vertex{
|
Stmts: []ast.Vertex{
|
||||||
&ast.StmtTrait{
|
&ast.StmtTrait{
|
||||||
Name: &ast.Identifier{
|
Name: &ast.Identifier{
|
||||||
|
@ -1435,7 +1435,7 @@ func TestRealCastParserError(t *testing.T) {
|
|||||||
suite.Expected = []*errors.Error{
|
suite.Expected = []*errors.Error{
|
||||||
{
|
{
|
||||||
Msg: "The (real) cast has been removed, use (float) instead",
|
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{
|
suite.Expected = []*errors.Error{
|
||||||
{
|
{
|
||||||
Msg: "The (unset) cast is no longer supported",
|
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{
|
suite.Expected = []*errors.Error{
|
||||||
{
|
{
|
||||||
Msg: "Array and string offset access syntax with curly braces is no longer supported",
|
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",
|
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",
|
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{
|
suite.Expected = []*errors.Error{
|
||||||
{
|
{
|
||||||
Msg: "syntax error: unexpected T_STATIC, expecting T_VARIABLE",
|
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",
|
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",
|
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 '}'",
|
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{
|
suite.Expected = []*errors.Error{
|
||||||
{
|
{
|
||||||
Msg: "syntax error: unexpected '|', expecting T_VARIABLE",
|
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 '('",
|
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",
|
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{
|
suite.Expected = []*errors.Error{
|
||||||
{
|
{
|
||||||
Msg: "syntax error: unexpected T_NS_SEPARATOR",
|
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{
|
suite.Expected = []*errors.Error{
|
||||||
{
|
{
|
||||||
Msg: "syntax error: unexpected T_NS_SEPARATOR, expecting T_VARIABLE",
|
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),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,11 @@ import (
|
|||||||
"github.com/VKCOM/php-parser/pkg/version"
|
"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) {
|
func TestIdentifier(t *testing.T) {
|
||||||
src := `<? $foo;`
|
src := `<? $foo;`
|
||||||
|
|
||||||
|
@ -366,40 +366,40 @@ $a;
|
|||||||
{
|
{
|
||||||
ID: php8.T_OPEN_TAG,
|
ID: php8.T_OPEN_TAG,
|
||||||
Value: []byte("<?php"),
|
Value: []byte("<?php"),
|
||||||
Position: &position.Position{StartLine: 1, EndLine: 1, EndPos: 5},
|
Position: &position.Position{StartLine: 1, EndLine: 1, EndPos: 5, StartCol: 0, EndCol: 5},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: php8.T_WHITESPACE,
|
ID: php8.T_WHITESPACE,
|
||||||
Value: []byte("\n"),
|
Value: []byte("\n"),
|
||||||
Position: &position.Position{StartLine: 1, EndLine: 1, StartPos: 5, EndPos: 6},
|
Position: &position.Position{StartLine: 1, EndLine: 1, StartPos: 5, EndPos: 6, StartCol: 5, EndCol: 6},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: php8.T_COMMENT,
|
ID: php8.T_COMMENT,
|
||||||
Value: []byte("#\n"),
|
Value: []byte("#\n"),
|
||||||
Position: &position.Position{StartLine: 2, EndLine: 2, StartPos: 6, EndPos: 8},
|
Position: &position.Position{StartLine: 2, EndLine: 2, StartPos: 6, EndPos: 8, StartCol: 0, EndCol: 2},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: php8.T_COMMENT,
|
ID: php8.T_COMMENT,
|
||||||
Value: []byte("# Hello\n"),
|
Value: []byte("# Hello\n"),
|
||||||
Position: &position.Position{StartLine: 3, EndLine: 3, StartPos: 8, EndPos: 16},
|
Position: &position.Position{StartLine: 3, EndLine: 3, StartPos: 8, EndPos: 16, StartCol: 0, EndCol: 8},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: php8.T_COMMENT,
|
ID: php8.T_COMMENT,
|
||||||
Value: []byte("#\n"),
|
Value: []byte("#\n"),
|
||||||
Position: &position.Position{StartLine: 4, EndLine: 4, StartPos: 16, EndPos: 18},
|
Position: &position.Position{StartLine: 4, EndLine: 4, StartPos: 16, EndPos: 18, StartCol: 0, EndCol: 2},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: php8.T_WHITESPACE,
|
ID: php8.T_WHITESPACE,
|
||||||
Value: []byte("\n"),
|
Value: []byte("\n"),
|
||||||
Position: &position.Position{StartLine: 5, EndLine: 5, StartPos: 18, EndPos: 19},
|
Position: &position.Position{StartLine: 5, EndLine: 5, StartPos: 18, EndPos: 19, StartCol: 0, EndCol: 1},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Position: &position.Position{StartLine: 6, EndLine: 6, StartPos: 19, EndPos: 21},
|
Position: &position.Position{StartLine: 6, EndLine: 6, StartPos: 19, EndPos: 21, StartCol: 0, EndCol: 2},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: ';',
|
ID: ';',
|
||||||
Value: []byte(";"),
|
Value: []byte(";"),
|
||||||
Position: &position.Position{StartLine: 6, EndLine: 6, StartPos: 21, EndPos: 22},
|
Position: &position.Position{StartLine: 6, EndLine: 6, StartPos: 21, EndPos: 22, StartCol: 2, EndCol: 3},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
suite.Run()
|
suite.Run()
|
||||||
|
41
internal/position/newline.go
Normal file
41
internal/position/newline.go
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package position
|
||||||
|
|
||||||
|
// NewLines wraps a slice of ints, each int is the beginning position of a line.
|
||||||
|
type NewLines struct {
|
||||||
|
data []int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewNewLines() NewLines {
|
||||||
|
return NewLines{make([]int, 0, 128)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (nl *NewLines) Append(p int) {
|
||||||
|
if len(nl.data) == 0 || nl.data[len(nl.data)-1] < p {
|
||||||
|
nl.data = append(nl.data, p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLine returns the line number, and beginning of the line.
|
||||||
|
func (nl *NewLines) GetLine(p int) (line int, lineStart int) {
|
||||||
|
line = len(nl.data) + 1
|
||||||
|
lineStart = 0
|
||||||
|
if len(nl.data) > 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
|
||||||
|
}
|
56
internal/position/newline_test.go
Normal file
56
internal/position/newline_test.go
Normal file
@ -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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -9,11 +9,13 @@ import (
|
|||||||
type startPos struct {
|
type startPos struct {
|
||||||
startLine int
|
startLine int
|
||||||
startPos int
|
startPos int
|
||||||
|
startCol int
|
||||||
}
|
}
|
||||||
|
|
||||||
type endPos struct {
|
type endPos struct {
|
||||||
endLine int
|
endLine int
|
||||||
endPos int
|
endPos int
|
||||||
|
endCol int
|
||||||
}
|
}
|
||||||
|
|
||||||
type Builder struct {
|
type Builder struct {
|
||||||
@ -28,11 +30,11 @@ func NewBuilder() *Builder {
|
|||||||
|
|
||||||
func getListStartPos(l []ast.Vertex) startPos {
|
func getListStartPos(l []ast.Vertex) startPos {
|
||||||
if l == nil {
|
if l == nil {
|
||||||
return startPos{-1, -1}
|
return startPos{-1, -1, -1}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(l) == 0 {
|
if len(l) == 0 {
|
||||||
return startPos{-1, -1}
|
return startPos{-1, -1, -1}
|
||||||
}
|
}
|
||||||
|
|
||||||
return getNodeStartPos(l[0])
|
return getNodeStartPos(l[0])
|
||||||
@ -41,27 +43,29 @@ func getListStartPos(l []ast.Vertex) startPos {
|
|||||||
func getNodeStartPos(n ast.Vertex) startPos {
|
func getNodeStartPos(n ast.Vertex) startPos {
|
||||||
sl := -1
|
sl := -1
|
||||||
sp := -1
|
sp := -1
|
||||||
|
sc := -1
|
||||||
|
|
||||||
if n == nil {
|
if n == nil {
|
||||||
return startPos{-1, -1}
|
return startPos{-1, -1, -1}
|
||||||
}
|
}
|
||||||
|
|
||||||
p := n.GetPosition()
|
p := n.GetPosition()
|
||||||
if p != nil {
|
if p != nil {
|
||||||
sl = p.StartLine
|
sl = p.StartLine
|
||||||
sp = p.StartPos
|
sp = p.StartPos
|
||||||
|
sc = p.StartCol
|
||||||
}
|
}
|
||||||
|
|
||||||
return startPos{sl, sp}
|
return startPos{sl, sp, sc}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getListEndPos(l []ast.Vertex) endPos {
|
func getListEndPos(l []ast.Vertex) endPos {
|
||||||
if l == nil {
|
if l == nil {
|
||||||
return endPos{-1, -1}
|
return endPos{-1, -1, -1}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(l) == 0 {
|
if len(l) == 0 {
|
||||||
return endPos{-1, -1}
|
return endPos{-1, -1, -1}
|
||||||
}
|
}
|
||||||
|
|
||||||
return getNodeEndPos(l[len(l)-1])
|
return getNodeEndPos(l[len(l)-1])
|
||||||
@ -70,18 +74,20 @@ func getListEndPos(l []ast.Vertex) endPos {
|
|||||||
func getNodeEndPos(n ast.Vertex) endPos {
|
func getNodeEndPos(n ast.Vertex) endPos {
|
||||||
el := -1
|
el := -1
|
||||||
ep := -1
|
ep := -1
|
||||||
|
ec := -1
|
||||||
|
|
||||||
if n == nil {
|
if n == nil {
|
||||||
return endPos{-1, -1}
|
return endPos{-1, -1, -1}
|
||||||
}
|
}
|
||||||
|
|
||||||
p := n.GetPosition()
|
p := n.GetPosition()
|
||||||
if p != nil {
|
if p != nil {
|
||||||
el = p.EndLine
|
el = p.EndLine
|
||||||
ep = p.EndPos
|
ep = p.EndPos
|
||||||
|
ec = p.EndCol
|
||||||
}
|
}
|
||||||
|
|
||||||
return endPos{el, ep}
|
return endPos{el, ep, ec}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewNodeListPosition returns new Position
|
// NewNodeListPosition returns new Position
|
||||||
@ -92,6 +98,8 @@ func (b *Builder) NewNodeListPosition(list []ast.Vertex) *position.Position {
|
|||||||
pos.EndLine = getListEndPos(list).endLine
|
pos.EndLine = getListEndPos(list).endLine
|
||||||
pos.StartPos = getListStartPos(list).startPos
|
pos.StartPos = getListStartPos(list).startPos
|
||||||
pos.EndPos = getListEndPos(list).endPos
|
pos.EndPos = getListEndPos(list).endPos
|
||||||
|
pos.StartCol = getListStartPos(list).startCol
|
||||||
|
pos.EndCol = getListEndPos(list).endCol
|
||||||
|
|
||||||
return pos
|
return pos
|
||||||
}
|
}
|
||||||
@ -104,6 +112,8 @@ func (b *Builder) NewNodePosition(n ast.Vertex) *position.Position {
|
|||||||
pos.EndLine = getNodeEndPos(n).endLine
|
pos.EndLine = getNodeEndPos(n).endLine
|
||||||
pos.StartPos = getNodeStartPos(n).startPos
|
pos.StartPos = getNodeStartPos(n).startPos
|
||||||
pos.EndPos = getNodeEndPos(n).endPos
|
pos.EndPos = getNodeEndPos(n).endPos
|
||||||
|
pos.StartCol = getNodeStartPos(n).startCol
|
||||||
|
pos.EndCol = getNodeEndPos(n).endCol
|
||||||
|
|
||||||
return pos
|
return pos
|
||||||
}
|
}
|
||||||
@ -116,18 +126,25 @@ func (b *Builder) NewTokenPosition(t *token.Token) *position.Position {
|
|||||||
pos.EndLine = t.Position.EndLine
|
pos.EndLine = t.Position.EndLine
|
||||||
pos.StartPos = t.Position.StartPos
|
pos.StartPos = t.Position.StartPos
|
||||||
pos.EndPos = t.Position.EndPos
|
pos.EndPos = t.Position.EndPos
|
||||||
|
pos.StartCol = t.Position.StartCol
|
||||||
|
pos.EndCol = t.Position.EndCol
|
||||||
|
|
||||||
return pos
|
return pos
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTokensPosition returns new Position
|
// 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 := b.pool.Get()
|
||||||
|
|
||||||
pos.StartLine = startToken.Position.StartLine
|
pos.StartLine = startToken.Position.StartLine
|
||||||
pos.EndLine = endToken.Position.EndLine
|
pos.EndLine = endToken.Position.EndLine
|
||||||
pos.StartPos = startToken.Position.StartPos
|
pos.StartPos = startToken.Position.StartPos
|
||||||
pos.EndPos = endToken.Position.EndPos
|
pos.EndPos = endToken.Position.EndPos
|
||||||
|
pos.StartCol = endToken.Position.StartCol
|
||||||
|
pos.EndCol = endToken.Position.EndCol
|
||||||
|
|
||||||
return pos
|
return pos
|
||||||
}
|
}
|
||||||
@ -140,6 +157,8 @@ func (b *Builder) NewTokenNodePosition(t *token.Token, n ast.Vertex) *position.P
|
|||||||
pos.EndLine = getNodeEndPos(n).endLine
|
pos.EndLine = getNodeEndPos(n).endLine
|
||||||
pos.StartPos = t.Position.StartPos
|
pos.StartPos = t.Position.StartPos
|
||||||
pos.EndPos = getNodeEndPos(n).endPos
|
pos.EndPos = getNodeEndPos(n).endPos
|
||||||
|
pos.StartCol = t.Position.StartCol
|
||||||
|
pos.EndCol = getNodeEndPos(n).endCol
|
||||||
|
|
||||||
return pos
|
return pos
|
||||||
}
|
}
|
||||||
@ -152,6 +171,8 @@ func (b *Builder) NewNodeTokenPosition(n ast.Vertex, t *token.Token) *position.P
|
|||||||
pos.EndLine = t.Position.EndLine
|
pos.EndLine = t.Position.EndLine
|
||||||
pos.StartPos = getNodeStartPos(n).startPos
|
pos.StartPos = getNodeStartPos(n).startPos
|
||||||
pos.EndPos = t.Position.EndPos
|
pos.EndPos = t.Position.EndPos
|
||||||
|
pos.StartCol = getNodeStartPos(n).startCol
|
||||||
|
pos.EndCol = t.Position.EndCol
|
||||||
|
|
||||||
return pos
|
return pos
|
||||||
}
|
}
|
||||||
@ -164,6 +185,8 @@ func (b *Builder) NewNodesPosition(startNode ast.Vertex, endNode ast.Vertex) *po
|
|||||||
pos.EndLine = getNodeEndPos(endNode).endLine
|
pos.EndLine = getNodeEndPos(endNode).endLine
|
||||||
pos.StartPos = getNodeStartPos(startNode).startPos
|
pos.StartPos = getNodeStartPos(startNode).startPos
|
||||||
pos.EndPos = getNodeEndPos(endNode).endPos
|
pos.EndPos = getNodeEndPos(endNode).endPos
|
||||||
|
pos.StartCol = getNodeStartPos(startNode).startCol
|
||||||
|
pos.EndCol = getNodeEndPos(endNode).endCol
|
||||||
|
|
||||||
return pos
|
return pos
|
||||||
}
|
}
|
||||||
@ -176,6 +199,8 @@ func (b *Builder) NewNodeListTokenPosition(list []ast.Vertex, t *token.Token) *p
|
|||||||
pos.EndLine = t.Position.EndLine
|
pos.EndLine = t.Position.EndLine
|
||||||
pos.StartPos = getListStartPos(list).startPos
|
pos.StartPos = getListStartPos(list).startPos
|
||||||
pos.EndPos = t.Position.EndPos
|
pos.EndPos = t.Position.EndPos
|
||||||
|
pos.StartCol = getListStartPos(list).startCol
|
||||||
|
pos.EndCol = t.Position.EndCol
|
||||||
|
|
||||||
return pos
|
return pos
|
||||||
}
|
}
|
||||||
@ -188,6 +213,8 @@ func (b *Builder) NewTokenNodeListPosition(t *token.Token, list []ast.Vertex) *p
|
|||||||
pos.EndLine = getListEndPos(list).endLine
|
pos.EndLine = getListEndPos(list).endLine
|
||||||
pos.StartPos = t.Position.StartPos
|
pos.StartPos = t.Position.StartPos
|
||||||
pos.EndPos = getListEndPos(list).endPos
|
pos.EndPos = getListEndPos(list).endPos
|
||||||
|
pos.StartCol = t.Position.StartCol
|
||||||
|
pos.EndCol = getListEndPos(list).endCol
|
||||||
|
|
||||||
return pos
|
return pos
|
||||||
}
|
}
|
||||||
@ -200,6 +227,8 @@ func (b *Builder) NewNodeNodeListPosition(n ast.Vertex, list []ast.Vertex) *posi
|
|||||||
pos.EndLine = getListEndPos(list).endLine
|
pos.EndLine = getListEndPos(list).endLine
|
||||||
pos.StartPos = getNodeStartPos(n).startPos
|
pos.StartPos = getNodeStartPos(n).startPos
|
||||||
pos.EndPos = getListEndPos(list).endPos
|
pos.EndPos = getListEndPos(list).endPos
|
||||||
|
pos.StartCol = getNodeStartPos(n).startCol
|
||||||
|
pos.EndCol = getListEndPos(list).endCol
|
||||||
|
|
||||||
return pos
|
return pos
|
||||||
}
|
}
|
||||||
@ -212,12 +241,18 @@ func (b *Builder) NewNodeListNodePosition(list []ast.Vertex, n ast.Vertex) *posi
|
|||||||
pos.EndLine = getNodeEndPos(n).endLine
|
pos.EndLine = getNodeEndPos(n).endLine
|
||||||
pos.StartPos = getListStartPos(list).startPos
|
pos.StartPos = getListStartPos(list).startPos
|
||||||
pos.EndPos = getNodeEndPos(n).endPos
|
pos.EndPos = getNodeEndPos(n).endPos
|
||||||
|
pos.StartCol = getListStartPos(list).startCol
|
||||||
|
pos.EndCol = getNodeEndPos(n).endCol
|
||||||
|
|
||||||
return pos
|
return pos
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewOptionalListTokensPosition returns new Position
|
// 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()
|
pos := b.pool.Get()
|
||||||
|
|
||||||
if list == nil {
|
if list == nil {
|
||||||
@ -225,6 +260,8 @@ func (b *Builder) NewOptionalListTokensPosition(list []ast.Vertex, t *token.Toke
|
|||||||
pos.EndLine = endToken.Position.EndLine
|
pos.EndLine = endToken.Position.EndLine
|
||||||
pos.StartPos = t.Position.StartPos
|
pos.StartPos = t.Position.StartPos
|
||||||
pos.EndPos = endToken.Position.EndPos
|
pos.EndPos = endToken.Position.EndPos
|
||||||
|
pos.StartCol = t.Position.StartCol
|
||||||
|
pos.EndCol = endToken.Position.EndCol
|
||||||
|
|
||||||
return pos
|
return pos
|
||||||
}
|
}
|
||||||
@ -232,6 +269,8 @@ func (b *Builder) NewOptionalListTokensPosition(list []ast.Vertex, t *token.Toke
|
|||||||
pos.EndLine = endToken.Position.EndLine
|
pos.EndLine = endToken.Position.EndLine
|
||||||
pos.StartPos = getListStartPos(list).startPos
|
pos.StartPos = getListStartPos(list).startPos
|
||||||
pos.EndPos = endToken.Position.EndPos
|
pos.EndPos = endToken.Position.EndPos
|
||||||
|
pos.StartCol = getListStartPos(list).startCol
|
||||||
|
pos.EndCol = endToken.Position.EndCol
|
||||||
|
|
||||||
return pos
|
return pos
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
package position_test
|
package position_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"gotest.tools/assert"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"gotest.tools/assert"
|
||||||
|
|
||||||
builder "github.com/VKCOM/php-parser/internal/position"
|
builder "github.com/VKCOM/php-parser/internal/position"
|
||||||
"github.com/VKCOM/php-parser/pkg/ast"
|
"github.com/VKCOM/php-parser/pkg/ast"
|
||||||
"github.com/VKCOM/php-parser/pkg/position"
|
"github.com/VKCOM/php-parser/pkg/position"
|
||||||
@ -18,12 +19,18 @@ func TestNewTokenPosition(t *testing.T) {
|
|||||||
EndLine: 1,
|
EndLine: 1,
|
||||||
StartPos: 0,
|
StartPos: 0,
|
||||||
EndPos: 3,
|
EndPos: 3,
|
||||||
|
StartCol: 1,
|
||||||
|
EndCol: 2,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pos := builder.NewBuilder().NewTokenPosition(tkn)
|
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) {
|
func TestNewTokensPosition(t *testing.T) {
|
||||||
@ -365,7 +372,18 @@ func TestNewOptionalListTokensPosition2(t *testing.T) {
|
|||||||
func TestNilNodePos(t *testing.T) {
|
func TestNilNodePos(t *testing.T) {
|
||||||
pos := builder.NewBuilder().NewNodesPosition(nil, nil)
|
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) {
|
func TestNilNodeListPos(t *testing.T) {
|
||||||
@ -380,7 +398,7 @@ func TestNilNodeListPos(t *testing.T) {
|
|||||||
|
|
||||||
pos := builder.NewBuilder().NewNodeNodeListPosition(n1, nil)
|
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) {
|
func TestNilNodeListTokenPos(t *testing.T) {
|
||||||
@ -396,7 +414,18 @@ func TestNilNodeListTokenPos(t *testing.T) {
|
|||||||
|
|
||||||
pos := builder.NewBuilder().NewNodeListTokenPosition(nil, tkn)
|
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) {
|
func TestEmptyNodeListPos(t *testing.T) {
|
||||||
@ -411,7 +440,7 @@ func TestEmptyNodeListPos(t *testing.T) {
|
|||||||
|
|
||||||
pos := builder.NewBuilder().NewNodeNodeListPosition(n1, []ast.Vertex{})
|
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) {
|
func TestEmptyNodeListTokenPos(t *testing.T) {
|
||||||
@ -427,5 +456,9 @@ func TestEmptyNodeListTokenPos(t *testing.T) {
|
|||||||
|
|
||||||
pos := builder.NewBuilder().NewNodeListTokenPosition([]ast.Vertex{}, tkn)
|
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,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@ func (l *LexerTokenStructTestSuite) WithFreeFloating() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *LexerTokenStructTestSuite) Run() {
|
func (l *LexerTokenStructTestSuite) Run() {
|
||||||
|
l.t.Helper()
|
||||||
config := conf.Config{
|
config := conf.Config{
|
||||||
Version: &l.Version,
|
Version: &l.Version,
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ func (p *ParserErrorTestSuite) UsePHP8() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *ParserErrorTestSuite) Run() {
|
func (p *ParserErrorTestSuite) Run() {
|
||||||
|
p.t.Helper()
|
||||||
config := conf.Config{
|
config := conf.Config{
|
||||||
Version: &p.Version,
|
Version: &p.Version,
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestConstructor(t *testing.T) {
|
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)
|
actual := errors.NewError("message", pos)
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ func TestConstructor(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPrint(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)
|
Error := errors.NewError("message", pos)
|
||||||
|
|
||||||
|
@ -1,19 +1,64 @@
|
|||||||
package position
|
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
|
// Position represents node position
|
||||||
type Position struct {
|
type Position struct {
|
||||||
StartLine int
|
StartLine int
|
||||||
EndLine int
|
EndLine int
|
||||||
|
StartCol int
|
||||||
|
EndCol int
|
||||||
StartPos int
|
StartPos int
|
||||||
EndPos int
|
EndPos int
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPosition Position constructor
|
// 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{
|
return &Position{
|
||||||
StartLine: StartLine,
|
StartLine: StartLine,
|
||||||
EndLine: EndLine,
|
EndLine: EndLine,
|
||||||
StartPos: StartPos,
|
StartPos: StartPos,
|
||||||
EndPos: EndPos,
|
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
|
||||||
|
}
|
||||||
|
@ -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, "StartLine: "+strconv.Itoa(pos.StartLine)+",\n")
|
||||||
v.print(v.indent, "EndLine: "+strconv.Itoa(pos.EndLine)+",\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, "StartPos: "+strconv.Itoa(pos.StartPos)+",\n")
|
||||||
v.print(v.indent, "EndPos: "+strconv.Itoa(pos.EndPos)+",\n")
|
v.print(v.indent, "EndPos: "+strconv.Itoa(pos.EndPos)+",\n")
|
||||||
|
|
||||||
|
@ -2,10 +2,11 @@ package dumper_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"github.com/VKCOM/php-parser/pkg/position"
|
"github.com/VKCOM/php-parser/pkg/position"
|
||||||
"github.com/VKCOM/php-parser/pkg/token"
|
"github.com/VKCOM/php-parser/pkg/token"
|
||||||
"github.com/VKCOM/php-parser/pkg/visitor/dumper"
|
"github.com/VKCOM/php-parser/pkg/visitor/dumper"
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/VKCOM/php-parser/pkg/ast"
|
"github.com/VKCOM/php-parser/pkg/ast"
|
||||||
)
|
)
|
||||||
@ -45,6 +46,8 @@ func TestDumper_root(t *testing.T) {
|
|||||||
Position: &position.Position{
|
Position: &position.Position{
|
||||||
StartLine: 1,
|
StartLine: 1,
|
||||||
EndLine: 2,
|
EndLine: 2,
|
||||||
|
StartCol: 0,
|
||||||
|
EndCol: 0,
|
||||||
StartPos: 3,
|
StartPos: 3,
|
||||||
EndPos: 4,
|
EndPos: 4,
|
||||||
},
|
},
|
||||||
@ -60,6 +63,8 @@ func TestDumper_root(t *testing.T) {
|
|||||||
Position: &position.Position{
|
Position: &position.Position{
|
||||||
StartLine: 1,
|
StartLine: 1,
|
||||||
EndLine: 2,
|
EndLine: 2,
|
||||||
|
StartCol: 0,
|
||||||
|
EndCol: 0,
|
||||||
StartPos: 3,
|
StartPos: 3,
|
||||||
EndPos: 4,
|
EndPos: 4,
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user