feat: add start column and end column to position struct

This commit is contained in:
Laytan Laats
2023-03-26 01:54:00 +01:00
parent 92019441d0
commit 7c12f73974
19 changed files with 316 additions and 109 deletions

View 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
}

View 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)
})
}
}

View File

@@ -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
}

View File

@@ -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,
)
}