php-parser/pkg/ast/traverser/dfs.go
2020-05-10 08:17:24 +03:00

492 lines
15 KiB
Go

package traverser
import "github.com/z7zmey/php-parser/pkg/ast"
type DFS struct {
visitor ast.Visitor
}
func NewDFS(visitor ast.Visitor) *DFS {
return &DFS{
visitor: visitor,
}
}
func (t *DFS) Traverse(n ast.Vertex) {
if n == nil {
return
}
if !t.visitor.EnterNode(n) {
return
}
switch nn := n.(type) {
case *ast.Root:
t.traverseArray("Stmts", nn.Stmts)
case *ast.Nullable:
t.traverseSingle("Expr", nn.Expr)
case *ast.Parameter:
t.traverseSingle("Type", nn.Type)
t.traverseSingle("Var", nn.Var)
t.traverseSingle("DefaultValue", nn.DefaultValue)
case *ast.Identifier:
case *ast.ArgumentList:
t.traverseArray("Arguments", nn.Arguments)
case *ast.Argument:
t.traverseSingle("Expr", nn.Expr)
case *ast.StmtAltElse:
t.traverseSingle("Stmt", nn.Stmt)
case *ast.StmtAltElseIf:
t.traverseSingle("Cond", nn.Cond)
t.traverseSingle("Stmt", nn.Stmt)
case *ast.StmtAltFor:
t.traverseArray("Init", nn.Init)
t.traverseArray("Cond", nn.Cond)
t.traverseArray("Loop", nn.Loop)
t.traverseSingle("Stmt", nn.Stmt)
case *ast.StmtAltForeach:
t.traverseSingle("Expr", nn.Expr)
t.traverseSingle("Key", nn.Key)
t.traverseSingle("Var", nn.Var)
t.traverseSingle("Stmt", nn.Stmt)
case *ast.StmtAltIf:
t.traverseSingle("Cond", nn.Cond)
t.traverseSingle("Stmt", nn.Stmt)
t.traverseArray("ElseIf", nn.ElseIf)
t.traverseSingle("Else", nn.Else)
case *ast.StmtAltSwitch:
t.traverseSingle("Cond", nn.Cond)
t.traverseSingle("CaseList", nn.CaseList)
case *ast.StmtAltWhile:
t.traverseSingle("Cond", nn.Cond)
t.traverseSingle("Stmt", nn.Stmt)
case *ast.StmtBreak:
t.traverseSingle("Expr", nn.Expr)
case *ast.StmtCase:
t.traverseSingle("Cond", nn.Cond)
t.traverseArray("Stmts", nn.Stmts)
case *ast.StmtCaseList:
t.traverseArray("Cases", nn.Cases)
case *ast.StmtCatch:
t.traverseArray("Types", nn.Types)
t.traverseSingle("Var", nn.Var)
t.traverseArray("Stmts", nn.Stmts)
case *ast.StmtClass:
t.traverseSingle("ClassName", nn.ClassName)
t.traverseArray("Modifiers", nn.Modifiers)
t.traverseArray("Stmts", nn.Stmts)
case *ast.StmtClassConstList:
t.traverseArray("Modifiers", nn.Modifiers)
t.traverseArray("Consts", nn.Consts)
case *ast.StmtClassExtends:
t.traverseSingle("ClassName", nn.ClassName)
case *ast.StmtClassImplements:
t.traverseArray("InterfaceNames", nn.InterfaceNames)
case *ast.StmtClassMethod:
t.traverseSingle("MethodName", nn.MethodName)
t.traverseArray("Modifiers", nn.Modifiers)
t.traverseArray("Params", nn.Params)
t.traverseSingle("ReturnType", nn.ReturnType)
t.traverseSingle("Stmt", nn.Stmt)
case *ast.StmtConstList:
t.traverseArray("Consts", nn.Consts)
case *ast.StmtConstant:
t.traverseSingle("ConstantName", nn.ConstantName)
t.traverseSingle("Expr", nn.Expr)
case *ast.StmtContinue:
t.traverseSingle("Expr", nn.Expr)
case *ast.StmtDeclare:
t.traverseArray("Consts", nn.Consts)
t.traverseSingle("Stmt", nn.Stmt)
case *ast.StmtDefault:
t.traverseArray("Stmts", nn.Stmts)
case *ast.StmtDo:
t.traverseSingle("Stmt", nn.Stmt)
t.traverseSingle("Cond", nn.Cond)
case *ast.StmtEcho:
t.traverseArray("Exprs", nn.Exprs)
case *ast.StmtElse:
t.traverseSingle("Stmt", nn.Stmt)
case *ast.StmtElseIf:
t.traverseSingle("Cond", nn.Cond)
t.traverseSingle("Stmt", nn.Stmt)
case *ast.StmtExpression:
t.traverseSingle("Expr", nn.Expr)
case *ast.StmtFinally:
t.traverseArray("Stmts", nn.Stmts)
case *ast.StmtFor:
t.traverseArray("Init", nn.Init)
t.traverseArray("Cond", nn.Cond)
t.traverseArray("Loop", nn.Loop)
t.traverseSingle("Stmt", nn.Stmt)
case *ast.StmtForeach:
t.traverseSingle("Expr", nn.Expr)
t.traverseSingle("Key", nn.Key)
t.traverseSingle("Var", nn.Var)
t.traverseSingle("Stmt", nn.Stmt)
case *ast.StmtFunction:
t.traverseSingle("FunctionName", nn.FunctionName)
t.traverseArray("Params", nn.Params)
t.traverseSingle("ReturnType", nn.ReturnType)
t.traverseArray("Stmts", nn.Stmts)
case *ast.StmtGlobal:
t.traverseArray("Vars", nn.Vars)
case *ast.StmtGoto:
t.traverseSingle("Label", nn.Label)
case *ast.StmtGroupUse:
t.traverseSingle("UseType", nn.UseType)
t.traverseSingle("Prefix", nn.Prefix)
t.traverseArray("UseList", nn.UseList)
case *ast.StmtHaltCompiler:
case *ast.StmtIf:
t.traverseSingle("Cond", nn.Cond)
t.traverseSingle("Stmt", nn.Stmt)
t.traverseArray("ElseIf", nn.ElseIf)
t.traverseSingle("Else", nn.Else)
case *ast.StmtInlineHtml:
case *ast.StmtInterface:
t.traverseSingle("InterfaceName", nn.InterfaceName)
t.traverseArray("Stmts", nn.Stmts)
case *ast.StmtInterfaceExtends:
t.traverseArray("InterfaceNames", nn.InterfaceNames)
case *ast.StmtLabel:
t.traverseSingle("LabelName", nn.LabelName)
case *ast.StmtNamespace:
t.traverseSingle("NamespaceName", nn.NamespaceName)
t.traverseArray("Stmts", nn.Stmts)
case *ast.StmtNop:
case *ast.StmtProperty:
t.traverseSingle("Var", nn.Var)
t.traverseSingle("Expr", nn.Expr)
case *ast.StmtPropertyList:
t.traverseArray("Modifiers", nn.Modifiers)
t.traverseSingle("Type", nn.Type)
t.traverseArray("Properties", nn.Properties)
case *ast.StmtReturn:
t.traverseSingle("Expr", nn.Expr)
case *ast.StmtStatic:
t.traverseArray("Vars", nn.Vars)
case *ast.StmtStaticVar:
t.traverseSingle("Var", nn.Var)
t.traverseSingle("Expr", nn.Expr)
case *ast.StmtStmtList:
t.traverseArray("Stmts", nn.Stmts)
case *ast.StmtSwitch:
t.traverseSingle("Cond", nn.Cond)
case *ast.StmtThrow:
t.traverseSingle("Expr", nn.Expr)
case *ast.StmtTrait:
t.traverseSingle("TraitName", nn.TraitName)
t.traverseArray("Stmts", nn.Stmts)
case *ast.StmtTraitAdaptationList:
t.traverseArray("Adaptations", nn.Adaptations)
case *ast.StmtTraitMethodRef:
t.traverseSingle("Trait", nn.Trait)
t.traverseSingle("Method", nn.Method)
case *ast.StmtTraitUse:
t.traverseArray("Traits", nn.Traits)
t.traverseSingle("TraitAdaptationList", nn.TraitAdaptationList)
case *ast.StmtTraitUseAlias:
t.traverseSingle("Ref", nn.Ref)
t.traverseSingle("Modifier", nn.Modifier)
t.traverseSingle("Alias", nn.Alias)
case *ast.StmtTraitUsePrecedence:
t.traverseSingle("Ref", nn.Ref)
t.traverseArray("Insteadof", nn.Insteadof)
case *ast.StmtTry:
t.traverseArray("Stmts", nn.Stmts)
t.traverseArray("Catches", nn.Catches)
t.traverseSingle("Finally", nn.Finally)
case *ast.StmtUnset:
t.traverseArray("Vars", nn.Vars)
case *ast.StmtUse:
t.traverseSingle("UseType", nn.UseType)
t.traverseSingle("Use", nn.Use)
t.traverseSingle("Alias", nn.Alias)
case *ast.StmtUseList:
t.traverseSingle("UseType", nn.UseType)
t.traverseArray("Uses", nn.Uses)
case *ast.StmtWhile:
t.traverseSingle("Cond", nn.Cond)
t.traverseSingle("Stmt", nn.Stmt)
case *ast.ExprArray:
t.traverseArray("Items", nn.Items)
case *ast.ExprArrayDimFetch:
t.traverseSingle("Var", nn.Var)
t.traverseSingle("Dim", nn.Dim)
case *ast.ExprArrayItem:
t.traverseSingle("Key", nn.Key)
t.traverseSingle("Val", nn.Val)
case *ast.ExprArrowFunction:
t.traverseArray("Params", nn.Params)
t.traverseSingle("ReturnType", nn.ReturnType)
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprBitwiseNot:
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprBooleanNot:
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprClassConstFetch:
t.traverseSingle("Class", nn.Class)
t.traverseSingle("ConstantName", nn.ConstantName)
case *ast.ExprClone:
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprClosure:
t.traverseArray("Params", nn.Params)
t.traverseSingle("ClosureUse", nn.ClosureUse)
t.traverseSingle("ReturnType", nn.ReturnType)
t.traverseArray("Stmts", nn.Stmts)
case *ast.ExprClosureUse:
t.traverseArray("Uses", nn.Uses)
case *ast.ExprConstFetch:
t.traverseSingle("Const", nn.Const)
case *ast.ExprEmpty:
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprErrorSuppress:
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprEval:
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprExit:
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprFunctionCall:
t.traverseSingle("Function", nn.Function)
t.traverseSingle("ArgumentList", nn.ArgumentList)
case *ast.ExprInclude:
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprIncludeOnce:
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprInstanceOf:
t.traverseSingle("Expr", nn.Expr)
t.traverseSingle("Class", nn.Class)
case *ast.ExprIsset:
t.traverseArray("Vars", nn.Vars)
case *ast.ExprList:
t.traverseArray("Items", nn.Items)
case *ast.ExprMethodCall:
t.traverseSingle("Var", nn.Var)
t.traverseSingle("Method", nn.Method)
case *ast.ExprNew:
t.traverseSingle("Class", nn.Class)
case *ast.ExprPostDec:
t.traverseSingle("Var", nn.Var)
case *ast.ExprPostInc:
t.traverseSingle("Var", nn.Var)
case *ast.ExprPreDec:
t.traverseSingle("Var", nn.Var)
case *ast.ExprPreInc:
t.traverseSingle("Var", nn.Var)
case *ast.ExprPrint:
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprPropertyFetch:
t.traverseSingle("Var", nn.Var)
t.traverseSingle("Property", nn.Property)
case *ast.ExprReference:
t.traverseSingle("Var", nn.Var)
case *ast.ExprRequire:
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprRequireOnce:
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprShellExec:
t.traverseArray("Parts", nn.Parts)
case *ast.ExprShortArray:
t.traverseArray("Items", nn.Items)
case *ast.ExprShortList:
t.traverseArray("Items", nn.Items)
case *ast.ExprStaticCall:
t.traverseSingle("Class", nn.Class)
t.traverseSingle("Call", nn.Call)
t.traverseSingle("ArgumentList", nn.ArgumentList)
case *ast.ExprStaticPropertyFetch:
t.traverseSingle("Class", nn.Class)
t.traverseSingle("Property", nn.Property)
case *ast.ExprTernary:
t.traverseSingle("Condition", nn.Condition)
t.traverseSingle("IfTrue", nn.IfTrue)
t.traverseSingle("IfFalse", nn.IfFalse)
case *ast.ExprUnaryMinus:
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprUnaryPlus:
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprVariable:
t.traverseSingle("VarName", nn.VarName)
case *ast.ExprYield:
t.traverseSingle("Key", nn.Key)
t.traverseSingle("Value", nn.Value)
case *ast.ExprYieldFrom:
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprAssign:
t.traverseSingle("Var", nn.Var)
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprAssignReference:
t.traverseSingle("Var", nn.Var)
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprAssignBitwiseAnd:
t.traverseSingle("Var", nn.Var)
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprAssignBitwiseOr:
t.traverseSingle("Var", nn.Var)
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprAssignBitwiseXor:
t.traverseSingle("Var", nn.Var)
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprAssignCoalesce:
t.traverseSingle("Var", nn.Var)
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprAssignConcat:
t.traverseSingle("Var", nn.Var)
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprAssignDiv:
t.traverseSingle("Var", nn.Var)
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprAssignMinus:
t.traverseSingle("Var", nn.Var)
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprAssignMod:
t.traverseSingle("Var", nn.Var)
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprAssignMul:
t.traverseSingle("Var", nn.Var)
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprAssignPlus:
t.traverseSingle("Var", nn.Var)
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprAssignPow:
t.traverseSingle("Var", nn.Var)
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprAssignShiftLeft:
t.traverseSingle("Var", nn.Var)
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprAssignShiftRight:
t.traverseSingle("Var", nn.Var)
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprBinaryBitwiseAnd:
t.traverseSingle("Left", nn.Left)
t.traverseSingle("Right", nn.Right)
case *ast.ExprBinaryBitwiseOr:
t.traverseSingle("Left", nn.Left)
t.traverseSingle("Right", nn.Right)
case *ast.ExprBinaryBitwiseXor:
t.traverseSingle("Left", nn.Left)
t.traverseSingle("Right", nn.Right)
case *ast.ExprBinaryBooleanAnd:
t.traverseSingle("Left", nn.Left)
t.traverseSingle("Right", nn.Right)
case *ast.ExprBinaryBooleanOr:
t.traverseSingle("Left", nn.Left)
t.traverseSingle("Right", nn.Right)
case *ast.ExprBinaryCoalesce:
t.traverseSingle("Left", nn.Left)
t.traverseSingle("Right", nn.Right)
case *ast.ExprBinaryConcat:
t.traverseSingle("Left", nn.Left)
t.traverseSingle("Right", nn.Right)
case *ast.ExprBinaryDiv:
t.traverseSingle("Left", nn.Left)
t.traverseSingle("Right", nn.Right)
case *ast.ExprBinaryEqual:
t.traverseSingle("Left", nn.Left)
t.traverseSingle("Right", nn.Right)
case *ast.ExprBinaryGreater:
t.traverseSingle("Left", nn.Left)
t.traverseSingle("Right", nn.Right)
case *ast.ExprBinaryGreaterOrEqual:
t.traverseSingle("Left", nn.Left)
t.traverseSingle("Right", nn.Right)
case *ast.ExprBinaryIdentical:
t.traverseSingle("Left", nn.Left)
t.traverseSingle("Right", nn.Right)
case *ast.ExprBinaryLogicalAnd:
t.traverseSingle("Left", nn.Left)
t.traverseSingle("Right", nn.Right)
case *ast.ExprBinaryLogicalOr:
t.traverseSingle("Left", nn.Left)
t.traverseSingle("Right", nn.Right)
case *ast.ExprBinaryLogicalXor:
t.traverseSingle("Left", nn.Left)
t.traverseSingle("Right", nn.Right)
case *ast.ExprBinaryMinus:
t.traverseSingle("Left", nn.Left)
t.traverseSingle("Right", nn.Right)
case *ast.ExprBinaryMod:
t.traverseSingle("Left", nn.Left)
t.traverseSingle("Right", nn.Right)
case *ast.ExprBinaryMul:
t.traverseSingle("Left", nn.Left)
t.traverseSingle("Right", nn.Right)
case *ast.ExprBinaryNotEqual:
t.traverseSingle("Left", nn.Left)
t.traverseSingle("Right", nn.Right)
case *ast.ExprBinaryNotIdentical:
t.traverseSingle("Left", nn.Left)
t.traverseSingle("Right", nn.Right)
case *ast.ExprBinaryPlus:
t.traverseSingle("Left", nn.Left)
t.traverseSingle("Right", nn.Right)
case *ast.ExprBinaryPow:
t.traverseSingle("Left", nn.Left)
t.traverseSingle("Right", nn.Right)
case *ast.ExprBinaryShiftLeft:
t.traverseSingle("Left", nn.Left)
t.traverseSingle("Right", nn.Right)
case *ast.ExprBinaryShiftRight:
t.traverseSingle("Left", nn.Left)
t.traverseSingle("Right", nn.Right)
case *ast.ExprBinarySmaller:
t.traverseSingle("Left", nn.Left)
t.traverseSingle("Right", nn.Right)
case *ast.ExprBinarySmallerOrEqual:
t.traverseSingle("Left", nn.Left)
t.traverseSingle("Right", nn.Right)
case *ast.ExprBinarySpaceship:
t.traverseSingle("Left", nn.Left)
t.traverseSingle("Right", nn.Right)
case *ast.ExprCastArray:
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprCastBool:
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprCastDouble:
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprCastInt:
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprCastObject:
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprCastString:
t.traverseSingle("Expr", nn.Expr)
case *ast.ExprCastUnset:
t.traverseSingle("Expr", nn.Expr)
case *ast.ScalarDnumber:
case *ast.ScalarEncapsed:
t.traverseArray("Parts", nn.Parts)
case *ast.ScalarEncapsedStringPart:
case *ast.ScalarHeredoc:
t.traverseArray("Parts", nn.Parts)
case *ast.ScalarLnumber:
case *ast.ScalarMagicConstant:
case *ast.ScalarString:
}
t.visitor.LeaveNode(n)
}
func (t *DFS) traverseSingle(key string, n ast.Vertex) {
if n == nil {
return
}
t.visitor.Enter(key, true)
t.Traverse(n)
t.visitor.Leave(key, true)
}
func (t *DFS) traverseArray(key string, nn []ast.Vertex) {
if nn == nil {
return
}
t.visitor.Enter(key, false)
for _, c := range nn {
t.Traverse(c)
}
t.visitor.Leave(key, false)
}