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 package node
import "fmt"
type Node interface { type Node interface {
Positioner Positioner
Attributes() map[string]interface{} Attributes() map[string]interface{}
@ -14,4 +16,10 @@ type Positioner interface {
type Position struct { type Position struct {
StartLine int StartLine int
EndLine 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] 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 startln := l.lineNumber
var prev byte var prev byte
@ -105,5 +105,5 @@ func (l *lexer) handleNewLine(tokenBytes []byte) ([]byte, int, int) {
l.lineNumber++ 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: alt_if_stmt_without_else:
T_IF '(' expr ')' ':' inner_statement_list 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 | 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) $$ = $1.(stmt.AltIf).AddElseIf(_elseIf)
} }
; ;
alt_if_stmt: 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 ';' | 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)) stmts := stmt.NewStmtList($4).SetPosition(NewNodeListPosition($4))
$$ = $1.(stmt.AltIf).SetElse(_else).SetPosition(NewAltIfPosition($1.Position().StartLine, $6)) _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" "github.com/z7zmey/php-parser/token"
) )
func getListPosStartLine(l []node.Node) int { type startPos struct {
startLine := -1 startLine int
startPos int
}
type endPos struct {
endLine int
endPos int
}
func getListStartPos(l []node.Node) startPos {
if l == nil { if l == nil {
return startLine return startPos{-1, -1}
} }
if len(l) == 0 { if len(l) == 0 {
return startLine return startPos{-1, -1}
} }
return getNodePosStartLine(l[0]) return getNodeStartPos(l[0])
} }
func getNodePosStartLine(n node.Node) int { func getNodeStartPos(n node.Node) startPos {
startLine := -1 sl := -1
sp := -1
if n == nil { if n == nil {
return startLine return startPos{-1, -1}
} }
p := n.Position() p := n.Position()
if p != nil { if p != nil {
startLine = p.StartLine sl = p.StartLine
sp = p.StartPos
} }
return startLine return startPos{sl, sp}
} }
func getListPosEndLine(l []node.Node) int { func getListEndPos(l []node.Node) endPos {
endLine := -1
if l == nil { if l == nil {
return endLine return endPos{-1, -1}
} }
if len(l) == 0 { 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 { func getNodeEndPos(n node.Node) endPos {
endLine := -1 el := -1
ep := -1
if n == nil { if n == nil {
return endLine return endPos{-1, -1}
} }
p := n.Position() p := n.Position()
if p != nil { 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 { 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 { 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 { 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 { func NewTokensPosition(startToken token.Token, endToken token.Token) *node.Position {
return &node.Position{startToken.StartLine, EndToken.EndLine} return &node.Position{
startToken.StartLine,
endToken.EndLine,
startToken.StartPos,
endToken.EndPos,
}
} }
func NewTokenNodePosition(t token.Token, n node.Node) *node.Position { 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 { 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 { 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 { 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 { 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 { 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 { func NewOptionalListTokensPosition(list []node.Node, t token.Token, endToken token.Token) *node.Position {
if list == nil { if list == nil {
return &node.Position{t.StartLine, endToken.EndLine} return &node.Position{
t.StartLine,
endToken.EndLine,
t.StartPos,
endToken.EndPos,
}
} else { } 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 Value string
StartLine int StartLine int
EndLine int EndLine int
StartPos int
EndPos int
} }
func NewToken(value []byte, startLine int, endLine int) Token { func NewToken(value []byte, startLine int, endLine int, startPos int, endPos int) Token {
return Token{string(value), startLine, endLine} return Token{string(value), startLine, endLine, startPos, endPos}
} }
func (t Token) String() string { func (t Token) String() string {