feat: add start column and end column to position struct
This commit is contained in:
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 {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user