handle node position in file

This commit is contained in:
vadim 2018-01-05 13:01:14 +02:00
parent dac789d601
commit c99f15a646
6 changed files with 419 additions and 339 deletions

View File

@ -1,5 +1,7 @@
package node
import "fmt"
type Node interface {
Positioner
Attributes() map[string]interface{}
@ -14,4 +16,10 @@ type Positioner interface {
type Position struct {
StartLine int
EndLine int
StartPos int
EndPos int
}
func (p Position) String() string {
return fmt.Sprintf("Pos{Line: %d-%d Pos: %d-%d}", p.StartLine, p.EndLine, p.StartPos, p.EndPos)
}

View File

@ -87,7 +87,7 @@ func (l *lexer) getCurrentState() int {
return l.stateStack[len(l.stateStack)-1]
}
func (l *lexer) handleNewLine(tokenBytes []byte) ([]byte, int, int) {
func (l *lexer) handleNewLine(tokenBytes []byte) ([]byte, int, int, int, int) {
startln := l.lineNumber
var prev byte
@ -105,5 +105,5 @@ func (l *lexer) handleNewLine(tokenBytes []byte) ([]byte, int, int) {
l.lineNumber++
}
return tokenBytes, startln, l.lineNumber
return tokenBytes, startln, l.lineNumber, int(l.First.Pos()), int(l.Prev.Pos())
}

File diff suppressed because it is too large Load Diff

View File

@ -634,21 +634,27 @@ if_stmt:
alt_if_stmt_without_else:
T_IF '(' expr ')' ':' inner_statement_list
{
$$ = stmt.NewAltIf($3, stmt.NewStmtList($6).SetPosition(NewNodeListPosition($6))).SetPosition(NewAltIfStartPosition($1))
stmts := stmt.NewStmtList($6).SetPosition(NewNodeListPosition($6))
$$ = stmt.NewAltIf($3, stmts).SetPosition(NewTokenNodeListPosition($1, $6))
}
| alt_if_stmt_without_else T_ELSEIF '(' expr ')' ':' inner_statement_list
{
_elseIf := stmt.NewAltElseIf($4, stmt.NewStmtList($7).SetPosition(NewNodeListPosition($7))).SetPosition(NewTokenNodeListPosition($2, $7))
stmts := stmt.NewStmtList($7).SetPosition(NewNodeListPosition($7))
_elseIf := stmt.NewAltElseIf($4, stmts).SetPosition(NewTokenNodeListPosition($2, $7))
$$ = $1.(stmt.AltIf).AddElseIf(_elseIf)
}
;
alt_if_stmt:
alt_if_stmt_without_else T_ENDIF ';' { $$ = $1.SetPosition(NewAltIfPosition($1.Position().StartLine, $3)) }
alt_if_stmt_without_else T_ENDIF ';'
{
$$ = $1.SetPosition(NewNodeTokenPosition($1, $3))
}
| alt_if_stmt_without_else T_ELSE ':' inner_statement_list T_ENDIF ';'
{
_else := stmt.NewAltElse(stmt.NewStmtList($4).SetPosition(NewNodeListPosition($4))).SetPosition(NewTokenNodeListPosition($2, $4))
$$ = $1.(stmt.AltIf).SetElse(_else).SetPosition(NewAltIfPosition($1.Position().StartLine, $6))
stmts := stmt.NewStmtList($4).SetPosition(NewNodeListPosition($4))
_else := stmt.NewAltElse(stmts).SetPosition(NewTokenNodeListPosition($2, $4))
$$ = $1.(stmt.AltIf).SetElse(_else).SetPosition(NewNodeTokenPosition($1, $6))
}
;

View File

@ -5,117 +5,178 @@ import (
"github.com/z7zmey/php-parser/token"
)
func getListPosStartLine(l []node.Node) int {
startLine := -1
type startPos struct {
startLine int
startPos int
}
type endPos struct {
endLine int
endPos int
}
func getListStartPos(l []node.Node) startPos {
if l == nil {
return startLine
return startPos{-1, -1}
}
if len(l) == 0 {
return startLine
return startPos{-1, -1}
}
return getNodePosStartLine(l[0])
return getNodeStartPos(l[0])
}
func getNodePosStartLine(n node.Node) int {
startLine := -1
func getNodeStartPos(n node.Node) startPos {
sl := -1
sp := -1
if n == nil {
return startLine
return startPos{-1, -1}
}
p := n.Position()
if p != nil {
startLine = p.StartLine
sl = p.StartLine
sp = p.StartPos
}
return startLine
return startPos{sl, sp}
}
func getListPosEndLine(l []node.Node) int {
endLine := -1
func getListEndPos(l []node.Node) endPos {
if l == nil {
return endLine
return endPos{-1, -1}
}
if len(l) == 0 {
return endLine
return endPos{-1, -1}
}
return getNodePosEndLine(l[len(l)-1])
return getNodeEndPos(l[len(l)-1])
}
func getNodePosEndLine(n node.Node) int {
endLine := -1
func getNodeEndPos(n node.Node) endPos {
el := -1
ep := -1
if n == nil {
return endLine
return endPos{-1, -1}
}
p := n.Position()
if p != nil {
endLine = p.EndLine
el = p.EndLine
ep = p.EndPos
}
return endLine
return endPos{el, ep}
}
func NewNodeListPosition(list []node.Node) *node.Position {
return &node.Position{getListPosStartLine(list), getListPosEndLine(list)}
return &node.Position{
getListStartPos(list).startLine,
getListEndPos(list).endLine,
getListStartPos(list).startPos,
getListEndPos(list).endPos,
}
}
func NewNodePosition(n node.Node) *node.Position {
return &node.Position{getNodePosStartLine(n), getNodePosEndLine(n)}
return &node.Position{
getNodeStartPos(n).startLine,
getNodeEndPos(n).endLine,
getNodeStartPos(n).startPos,
getNodeEndPos(n).endPos,
}
}
func NewTokenPosition(t token.Token) *node.Position {
return &node.Position{t.StartLine, t.EndLine}
return &node.Position{
t.StartLine,
t.EndLine,
t.StartPos,
t.EndPos,
}
}
func NewTokensPosition(startToken token.Token, EndToken token.Token) *node.Position {
return &node.Position{startToken.StartLine, EndToken.EndLine}
func NewTokensPosition(startToken token.Token, endToken token.Token) *node.Position {
return &node.Position{
startToken.StartLine,
endToken.EndLine,
startToken.StartPos,
endToken.EndPos,
}
}
func NewTokenNodePosition(t token.Token, n node.Node) *node.Position {
return &node.Position{t.StartLine, getNodePosEndLine(n)}
return &node.Position{
t.StartLine,
getNodeEndPos(n).endLine,
t.StartPos,
getNodeEndPos(n).endPos,
}
}
func NewNodeTokenPosition(n node.Node, t token.Token) *node.Position {
return &node.Position{getNodePosStartLine(n), t.EndLine}
return &node.Position{
getNodeStartPos(n).startLine,
t.EndLine,
getNodeStartPos(n).startPos,
t.EndPos,
}
}
func NewNodesPosition(startNode node.Node, endNode node.Node) *node.Position {
return &node.Position{getNodePosStartLine(startNode), getNodePosEndLine(endNode)}
return &node.Position{
getNodeStartPos(startNode).startLine,
getNodeEndPos(endNode).endLine,
getNodeStartPos(startNode).startPos,
getNodeEndPos(endNode).endPos,
}
}
func NewNodeListTokenPosition(list []node.Node, t token.Token) *node.Position {
return &node.Position{getListPosStartLine(list), t.EndLine}
return &node.Position{
getListStartPos(list).startLine,
t.EndLine,
getListStartPos(list).startPos,
t.EndPos,
}
}
func NewTokenNodeListPosition(t token.Token, list []node.Node) *node.Position {
return &node.Position{t.StartLine, getListPosEndLine(list)}
return &node.Position{
t.StartLine,
getListEndPos(list).endLine,
t.StartPos,
getListEndPos(list).endPos,
}
}
func NewNodeNodeListPosition(n node.Node, list []node.Node) *node.Position {
return &node.Position{getNodePosStartLine(n), getListPosEndLine(list)}
return &node.Position{
getNodeStartPos(n).startLine,
getListEndPos(list).endLine,
getNodeStartPos(n).startPos,
getListEndPos(list).endPos,
}
}
func NewOptionalListTokensPosition(list []node.Node, t token.Token, endToken token.Token) *node.Position {
if list == nil {
return &node.Position{t.StartLine, endToken.EndLine}
return &node.Position{
t.StartLine,
endToken.EndLine,
t.StartPos,
endToken.EndPos,
}
} else {
return &node.Position{getListPosStartLine(list), endToken.EndLine}
return &node.Position{
getListStartPos(list).startLine,
endToken.EndLine,
getListStartPos(list).startPos,
endToken.EndPos,
}
}
}
// AltIf Positions
func NewAltIfStartPosition(startToken token.Token) *node.Position {
return &node.Position{startToken.StartLine, -1}
}
func NewAltIfPosition(startLine int, EndToken token.Token) *node.Position {
return &node.Position{startLine, EndToken.EndLine}
}

View File

@ -10,10 +10,12 @@ type Token struct {
Value string
StartLine int
EndLine int
StartPos int
EndPos int
}
func NewToken(value []byte, startLine int, endLine int) Token {
return Token{string(value), startLine, endLine}
func NewToken(value []byte, startLine int, endLine int, startPos int, endPos int) Token {
return Token{string(value), startLine, endLine, startPos, endPos}
}
func (t Token) String() string {