php2go/parseutil/MutatingWalker.go

1087 lines
26 KiB
Go

package parseutil
import (
"errors"
"fmt"
"reflect"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/node/expr"
"github.com/z7zmey/php-parser/node/expr/assign"
"github.com/z7zmey/php-parser/node/expr/binary"
"github.com/z7zmey/php-parser/node/expr/cast"
"github.com/z7zmey/php-parser/node/name"
"github.com/z7zmey/php-parser/node/scalar"
"github.com/z7zmey/php-parser/node/stmt"
)
func MutatingWalkerNoop(n *node.Node) error { return nil }
var (
ErrDoNotWalkDeeper = errors.New("ErrDoNotWalkDeeper")
)
// MutatingWalker walks the AST by pointer to interface.
// This allows for modification of interior AST nodes while walking, unlike the
// upstream php-parser.Walker() interface that walks by value.
type MutatingWalker struct {
EnterNode func(n *node.Node) error
LeaveNode func(n *node.Node) error
}
//
func (mw MutatingWalker) walkEach(pNodes ...*node.Node) error {
for _, pNode := range pNodes {
err := mw.walkSingle(pNode)
if err != nil {
return err
}
}
return nil
}
func (mw MutatingWalker) walkSlice(arr []node.Node) error {
for idx, _ := range arr {
err := mw.walkSingle(&arr[idx])
if err != nil {
return err
}
}
return nil
}
func (mw MutatingWalker) walkSingle(n *node.Node) error {
err := mw.EnterNode(n)
if err != nil {
if err == ErrDoNotWalkDeeper {
return nil
}
return err
}
if *n == nil || reflect.ValueOf(*n).IsNil() {
// don't enter it
} else {
err = switchExhaustive(mw, n)
if err != nil {
return err
}
}
err = mw.LeaveNode(n)
if err != nil {
return err
}
return nil
}
// node
func (mw MutatingWalker) handleNodeRoot(n *node.Root) error {
return mw.walkSlice(n.Stmts)
}
func (mw MutatingWalker) handleNodeIdentifier(n *node.Identifier) error {
return nil
}
func (mw MutatingWalker) handleNodeParameter(n *node.Parameter) error {
return mw.walkEach(&n.DefaultValue, &n.Variable, &n.VariableType)
}
func (mw MutatingWalker) handleNodeNullable(n *node.Nullable) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleNodeArgument(n *node.Argument) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleNodeArgumentList(n *node.ArgumentList) error {
return mw.walkSlice(n.Arguments)
}
// name
func (mw MutatingWalker) handleNameNamePart(n *name.NamePart) error {
return nil
}
func (mw MutatingWalker) handleNameName(n *name.Name) error {
return mw.walkSlice(n.Parts)
}
func (mw MutatingWalker) handleNameFullyQualified(n *name.FullyQualified) error {
return mw.walkSlice(n.Parts)
}
func (mw MutatingWalker) handleNameRelative(n *name.Relative) error {
return mw.walkSlice(n.Parts)
}
// scalar
func (mw MutatingWalker) handleScalarLnumber(n *scalar.Lnumber) error {
return nil
}
func (mw MutatingWalker) handleScalarDnumber(n *scalar.Dnumber) error {
return nil
}
func (mw MutatingWalker) handleScalarString(n *scalar.String) error {
return nil
}
func (mw MutatingWalker) handleScalarEncapsedStringPart(n *scalar.EncapsedStringPart) error {
return nil
}
func (mw MutatingWalker) handleScalarEncapsed(n *scalar.Encapsed) error {
return mw.walkSlice(n.Parts)
}
func (mw MutatingWalker) handleScalarHeredoc(n *scalar.Heredoc) error {
return mw.walkSlice(n.Parts)
}
func (mw MutatingWalker) handleScalarMagicConstant(n *scalar.MagicConstant) error {
return nil
}
// assign
func (mw MutatingWalker) handleAssign(n *assign.Assign) error {
return mw.walkEach(&n.Variable, &n.Expression)
}
func (mw MutatingWalker) handleAssignReference(n *assign.Reference) error {
return mw.walkEach(&n.Variable, &n.Expression)
}
func (mw MutatingWalker) handleAssignBitwiseAnd(n *assign.BitwiseAnd) error {
return mw.walkEach(&n.Variable, &n.Expression)
}
func (mw MutatingWalker) handleAssignBitwiseOr(n *assign.BitwiseOr) error {
return mw.walkEach(&n.Variable, &n.Expression)
}
func (mw MutatingWalker) handleAssignBitwiseXor(n *assign.BitwiseXor) error {
return mw.walkEach(&n.Variable, &n.Expression)
}
func (mw MutatingWalker) handleAssignCoalesce(n *assign.Coalesce) error {
return mw.walkEach(&n.Variable, &n.Expression)
}
func (mw MutatingWalker) handleAssignConcat(n *assign.Concat) error {
return mw.walkEach(&n.Variable, &n.Expression)
}
func (mw MutatingWalker) handleAssignDiv(n *assign.Div) error {
return mw.walkEach(&n.Variable, &n.Expression)
}
func (mw MutatingWalker) handleAssignMinus(n *assign.Minus) error {
return mw.walkEach(&n.Variable, &n.Expression)
}
func (mw MutatingWalker) handleAssignMod(n *assign.Mod) error {
return mw.walkEach(&n.Variable, &n.Expression)
}
func (mw MutatingWalker) handleAssignMul(n *assign.Mul) error {
return mw.walkEach(&n.Variable, &n.Expression)
}
func (mw MutatingWalker) handleAssignPlus(n *assign.Plus) error {
return mw.walkEach(&n.Variable, &n.Expression)
}
func (mw MutatingWalker) handleAssignPow(n *assign.Pow) error {
return mw.walkEach(&n.Variable, &n.Expression)
}
func (mw MutatingWalker) handleAssignShiftLeft(n *assign.ShiftLeft) error {
return mw.walkEach(&n.Variable, &n.Expression)
}
func (mw MutatingWalker) handleAssignShiftRight(n *assign.ShiftRight) error {
return mw.walkEach(&n.Variable, &n.Expression)
}
// binary
func (mw MutatingWalker) handleBinaryBitwiseAnd(n *binary.BitwiseAnd) error {
return mw.walkEach(&n.Left, &n.Right)
}
func (mw MutatingWalker) handleBinaryBitwiseOr(n *binary.BitwiseOr) error {
return mw.walkEach(&n.Left, &n.Right)
}
func (mw MutatingWalker) handleBinaryBitwiseXor(n *binary.BitwiseXor) error {
return mw.walkEach(&n.Left, &n.Right)
}
func (mw MutatingWalker) handleBinaryBooleanAnd(n *binary.BooleanAnd) error {
return mw.walkEach(&n.Left, &n.Right)
}
func (mw MutatingWalker) handleBinaryBooleanOr(n *binary.BooleanOr) error {
return mw.walkEach(&n.Left, &n.Right)
}
func (mw MutatingWalker) handleBinaryCoalesce(n *binary.Coalesce) error {
return mw.walkEach(&n.Left, &n.Right)
}
func (mw MutatingWalker) handleBinaryConcat(n *binary.Concat) error {
return mw.walkEach(&n.Left, &n.Right)
}
func (mw MutatingWalker) handleBinaryDiv(n *binary.Div) error {
return mw.walkEach(&n.Left, &n.Right)
}
func (mw MutatingWalker) handleBinaryEqual(n *binary.Equal) error {
return mw.walkEach(&n.Left, &n.Right)
}
func (mw MutatingWalker) handleBinaryGreaterOrEqual(n *binary.GreaterOrEqual) error {
return mw.walkEach(&n.Left, &n.Right)
}
func (mw MutatingWalker) handleBinaryGreater(n *binary.Greater) error {
return mw.walkEach(&n.Left, &n.Right)
}
func (mw MutatingWalker) handleBinaryIdentical(n *binary.Identical) error {
return mw.walkEach(&n.Left, &n.Right)
}
func (mw MutatingWalker) handleBinaryLogicalAnd(n *binary.LogicalAnd) error {
return mw.walkEach(&n.Left, &n.Right)
}
func (mw MutatingWalker) handleBinaryLogicalOr(n *binary.LogicalOr) error {
return mw.walkEach(&n.Left, &n.Right)
}
func (mw MutatingWalker) handleBinaryLogicalXor(n *binary.LogicalXor) error {
return mw.walkEach(&n.Left, &n.Right)
}
func (mw MutatingWalker) handleBinaryMinus(n *binary.Minus) error {
return mw.walkEach(&n.Left, &n.Right)
}
func (mw MutatingWalker) handleBinaryMod(n *binary.Mod) error {
return mw.walkEach(&n.Left, &n.Right)
}
func (mw MutatingWalker) handleBinaryMul(n *binary.Mul) error {
return mw.walkEach(&n.Left, &n.Right)
}
func (mw MutatingWalker) handleBinaryNotEqual(n *binary.NotEqual) error {
return mw.walkEach(&n.Left, &n.Right)
}
func (mw MutatingWalker) handleBinaryNotIdentical(n *binary.NotIdentical) error {
return mw.walkEach(&n.Left, &n.Right)
}
func (mw MutatingWalker) handleBinaryPlus(n *binary.Plus) error {
return mw.walkEach(&n.Left, &n.Right)
}
func (mw MutatingWalker) handleBinaryPow(n *binary.Pow) error {
return mw.walkEach(&n.Left, &n.Right)
}
func (mw MutatingWalker) handleBinaryShiftLeft(n *binary.ShiftLeft) error {
return mw.walkEach(&n.Left, &n.Right)
}
func (mw MutatingWalker) handleBinaryShiftRight(n *binary.ShiftRight) error {
return mw.walkEach(&n.Left, &n.Right)
}
func (mw MutatingWalker) handleBinarySmallerOrEqual(n *binary.SmallerOrEqual) error {
return mw.walkEach(&n.Left, &n.Right)
}
func (mw MutatingWalker) handleBinarySmaller(n *binary.Smaller) error {
return mw.walkEach(&n.Left, &n.Right)
}
func (mw MutatingWalker) handleBinarySpaceship(n *binary.Spaceship) error {
return mw.walkEach(&n.Left, &n.Right)
}
// cast
func (mw MutatingWalker) handleCastArray(n *cast.Array) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleCastBool(n *cast.Bool) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleCastDouble(n *cast.Double) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleCastInt(n *cast.Int) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleCastObject(n *cast.Object) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleCastString(n *cast.String) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleCastUnset(n *cast.Unset) error {
return mw.walkSingle(&n.Expr)
}
// expr
func (mw MutatingWalker) handleExprArrayDimFetch(n *expr.ArrayDimFetch) error {
return mw.walkEach(&n.Dim, &n.Variable)
}
func (mw MutatingWalker) handleExprArrayItem(n *expr.ArrayItem) error {
return mw.walkEach(&n.Key, &n.Val)
}
func (mw MutatingWalker) handleExprArray(n *expr.Array) error {
return mw.walkSlice(n.Items)
}
func (mw MutatingWalker) handleExprArrowFunction(n *expr.ArrowFunction) error {
err := mw.walkSlice(n.Params)
if err != nil {
return err
}
return mw.walkEach(&n.Expr, &n.ReturnType)
}
func (mw MutatingWalker) handleExprBitwiseNot(n *expr.BitwiseNot) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleExprBooleanNot(n *expr.BooleanNot) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleExprClassConstFetch(n *expr.ClassConstFetch) error {
return mw.walkEach(&n.Class, &n.ConstantName)
}
func (mw MutatingWalker) handleExprClone(n *expr.Clone) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleExprClosureUse(n *expr.ClosureUse) error {
return mw.walkSlice(n.Uses)
}
func (mw MutatingWalker) handleExprClosure(n *expr.Closure) error {
err := mw.walkSlice(n.Params)
if err != nil {
return err
}
err = mw.walkSlice(n.Stmts)
if err != nil {
return err
}
// n.ClosureUse is not boxed as a node.Node
// Box it, and then reinstate it after we have handled all *node.Node types
var boxedClosureUse node.Node = n.ClosureUse
err = mw.walkEach(&boxedClosureUse, &n.ReturnType)
if err != nil {
return err
}
cu, ok := boxedClosureUse.(*expr.ClosureUse)
if !ok {
return fmt.Errorf("illegal modification from '*expr.ClosureUse' to incompatible type '%t'", boxedClosureUse)
}
n.ClosureUse = cu // reinstate
// Done
return nil
}
func (mw MutatingWalker) handleExprConstFetch(n *expr.ConstFetch) error {
return mw.walkSingle(&n.Constant)
}
func (mw MutatingWalker) handleExprEmpty(n *expr.Empty) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleExprErrorSuppress(n *expr.ErrorSuppress) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleExprEval(n *expr.Eval) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleExprExit(n *expr.Exit) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleExprFunctionCall(n *expr.FunctionCall) error {
var boxedArgumentList node.Node = n.ArgumentList
err := mw.walkEach(&boxedArgumentList, &n.Function)
if err != nil {
return err
}
al, ok := boxedArgumentList.(*node.ArgumentList)
if !ok {
return fmt.Errorf("illegal modification from '*node.ArgumentList' to incompatible type '%t'", boxedArgumentList)
}
n.ArgumentList = al // reinstate
return nil
}
func (mw MutatingWalker) handleExprInclude(n *expr.Include) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleExprIncludeOnce(n *expr.IncludeOnce) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleExprInstanceOf(n *expr.InstanceOf) error {
return mw.walkEach(&n.Class, &n.Expr)
}
func (mw MutatingWalker) handleExprIsset(n *expr.Isset) error {
return mw.walkSlice(n.Variables)
}
func (mw MutatingWalker) handleExprList(n *expr.List) error {
return mw.walkSlice(n.Items)
}
func (mw MutatingWalker) handleExprMethodCall(n *expr.MethodCall) error {
var boxedArgumentList node.Node = n.ArgumentList
err := mw.walkEach(&boxedArgumentList, &n.Method, &n.Variable)
if err != nil {
return err
}
al, ok := boxedArgumentList.(*node.ArgumentList)
if !ok {
return fmt.Errorf("illegal modification from '*node.ArgumentList' to incompatible type '%t'", boxedArgumentList)
}
n.ArgumentList = al // reinstate
return nil
}
func (mw MutatingWalker) handleExprNew(n *expr.New) error {
var boxedArgumentList node.Node = n.ArgumentList
err := mw.walkEach(&boxedArgumentList, &n.Class)
if err != nil {
return err
}
al, ok := boxedArgumentList.(*node.ArgumentList)
if !ok {
return fmt.Errorf("illegal modification from '*node.ArgumentList' to incompatible type '%t'", boxedArgumentList)
}
n.ArgumentList = al // reinstate
return nil
}
func (mw MutatingWalker) handleExprPostDec(n *expr.PostDec) error {
return mw.walkSingle(&n.Variable)
}
func (mw MutatingWalker) handleExprPostInc(n *expr.PostInc) error {
return mw.walkSingle(&n.Variable)
}
func (mw MutatingWalker) handleExprPreDec(n *expr.PreDec) error {
return mw.walkSingle(&n.Variable)
}
func (mw MutatingWalker) handleExprPreInc(n *expr.PreInc) error {
return mw.walkSingle(&n.Variable)
}
func (mw MutatingWalker) handleExprPrint(n *expr.Print) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleExprPropertyFetch(n *expr.PropertyFetch) error {
return mw.walkEach(&n.Property, &n.Variable)
}
func (mw MutatingWalker) handleExprReference(n *expr.Reference) error {
return mw.walkSingle(&n.Variable)
}
func (mw MutatingWalker) handleExprRequire(n *expr.Require) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleExprRequireOnce(n *expr.RequireOnce) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleExprShellExec(n *expr.ShellExec) error {
return mw.walkSlice(n.Parts)
}
func (mw MutatingWalker) handleExprShortArray(n *expr.ShortArray) error {
return mw.walkSlice(n.Items)
}
func (mw MutatingWalker) handleExprShortList(n *expr.ShortList) error {
return mw.walkSlice(n.Items)
}
func (mw MutatingWalker) handleExprStaticCall(n *expr.StaticCall) error {
var boxedArgumentList node.Node = n.ArgumentList
err := mw.walkEach(&boxedArgumentList, &n.Call, &n.Class)
if err != nil {
return err
}
al, ok := boxedArgumentList.(*node.ArgumentList)
if !ok {
return fmt.Errorf("illegal modification from '*node.ArgumentList' to incompatible type '%t'", boxedArgumentList)
}
n.ArgumentList = al // reinstate
return nil
}
func (mw MutatingWalker) handleExprStaticPropertyFetch(n *expr.StaticPropertyFetch) error {
return mw.walkEach(&n.Class, &n.Property)
}
func (mw MutatingWalker) handleExprTernary(n *expr.Ternary) error {
return mw.walkEach(&n.Condition, &n.IfTrue, &n.IfFalse)
}
func (mw MutatingWalker) handleExprUnaryMinus(n *expr.UnaryMinus) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleExprUnaryPlus(n *expr.UnaryPlus) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleExprVariable(n *expr.Variable) error {
return mw.walkSingle(&n.VarName)
}
func (mw MutatingWalker) handleExprYieldFrom(n *expr.YieldFrom) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleExprYield(n *expr.Yield) error {
return mw.walkEach(&n.Key, &n.Value)
}
// stmt
func (mw MutatingWalker) handleStmtAltElse(n *stmt.AltElse) error {
return mw.walkSingle(&n.Stmt)
}
func (mw MutatingWalker) handleStmtAltElseIf(n *stmt.AltElseIf) error {
return mw.walkEach(&n.Cond, &n.Stmt)
}
func (mw MutatingWalker) handleStmtAltFor(n *stmt.AltFor) error {
err := mw.walkSlice(n.Cond)
if err != nil {
return err
}
err = mw.walkSlice(n.Init)
if err != nil {
return err
}
err = mw.walkSlice(n.Loop)
if err != nil {
return err
}
return mw.walkSingle(&n.Stmt)
}
func (mw MutatingWalker) handleStmtAltForeach(n *stmt.AltForeach) error {
return mw.walkEach(&n.Expr, &n.Key, &n.Stmt, &n.Variable)
}
func (mw MutatingWalker) handleStmtAltIf(n *stmt.AltIf) error {
err := mw.walkSlice(n.ElseIf)
if err != nil {
return err
}
return mw.walkEach(&n.Cond, &n.Else, &n.Stmt)
}
func (mw MutatingWalker) handleStmtAltSwitch(n *stmt.AltSwitch) error {
var boxedCaseList node.Node = n.CaseList
err := mw.walkEach(&boxedCaseList, &n.Cond)
if err != nil {
return err
}
cl, ok := boxedCaseList.(*stmt.CaseList)
if !ok {
return fmt.Errorf("illegal modification from '*stmt.CaseList' to incompatible type '%t'", boxedCaseList)
}
n.CaseList = cl // reinstate
return nil
}
func (mw MutatingWalker) handleStmtAltWhile(n *stmt.AltWhile) error {
return mw.walkEach(&n.Cond, &n.Stmt)
}
func (mw MutatingWalker) handleStmtBreak(n *stmt.Break) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleStmtCase(n *stmt.Case) error {
err := mw.walkSlice(n.Stmts)
if err != nil {
return err
}
return mw.walkSingle(&n.Cond)
}
func (mw MutatingWalker) handleStmtCaseList(n *stmt.CaseList) error {
return mw.walkSlice(n.Cases)
}
func (mw MutatingWalker) handleStmtCatch(n *stmt.Catch) error {
err := mw.walkSlice(n.Types)
if err != nil {
return err
}
err = mw.walkSingle(&n.Variable)
if err != nil {
return err
}
return mw.walkSlice(n.Stmts)
}
func (mw MutatingWalker) handleStmtClass(n *stmt.Class) error {
var (
boxedArgumentList node.Node = n.ArgumentList
boxedClassExtends node.Node = n.Extends
boxedClassImplements node.Node = n.Implements
)
err := mw.walkEach(&n.ClassName, &boxedArgumentList, &boxedClassExtends, &boxedClassImplements)
if err != nil {
return err
}
al, ok := boxedArgumentList.(*node.ArgumentList)
if !ok {
return fmt.Errorf("illegal modification from '*node.ArgumentList' to incompatible type '%t'", boxedArgumentList)
}
n.ArgumentList = al // reinstate
ce, ok := boxedClassExtends.(*stmt.ClassExtends)
if !ok {
return fmt.Errorf("illegal modification from '*stmt.ClassExtends' to incompatible type '%t'", boxedClassExtends)
}
n.Extends = ce // reinstate
ci, ok := boxedClassImplements.(*stmt.ClassImplements)
if !ok {
return fmt.Errorf("illegal modification from '*stmt.ClassImplements' to incompatible type '%t'", boxedClassImplements)
}
n.Implements = ci // reinstate
//
err = mw.walkSlice(n.Modifiers)
if err != nil {
return err
}
return mw.walkSlice(n.Stmts)
}
func (mw MutatingWalker) handleStmtClassExtends(n *stmt.ClassExtends) error {
return mw.walkSingle(&n.ClassName)
}
func (mw MutatingWalker) handleStmtClassImplements(n *stmt.ClassImplements) error {
return mw.walkSlice(n.InterfaceNames)
}
func (mw MutatingWalker) handleStmtClassMethod(n *stmt.ClassMethod) error {
err := mw.walkEach(&n.MethodName, &n.ReturnType)
if err != nil {
return err
}
err = mw.walkSlice(n.Modifiers)
if err != nil {
return err
}
err = mw.walkSlice(n.Params)
if err != nil {
return err
}
return mw.walkSingle(&n.Stmt) // we could have embedded it in the leading walkEach, but, try and keep the ordering a little bit
}
func (mw MutatingWalker) handleStmtClassConstList(n *stmt.ClassConstList) error {
err := mw.walkSlice(n.Modifiers)
if err != nil {
return err
}
return mw.walkSlice(n.Consts)
}
func (mw MutatingWalker) handleStmtConstList(n *stmt.ConstList) error {
return mw.walkSlice(n.Consts)
}
func (mw MutatingWalker) handleStmtConstant(n *stmt.Constant) error {
return mw.walkEach(&n.ConstantName, &n.Expr)
}
func (mw MutatingWalker) handleStmtContinue(n *stmt.Continue) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleStmtDeclare(n *stmt.Declare) error {
err := mw.walkSlice(n.Consts)
if err != nil {
return err
}
return mw.walkSingle(&n.Stmt)
}
func (mw MutatingWalker) handleStmtDefault(n *stmt.Default) error {
return mw.walkSlice(n.Stmts)
}
func (mw MutatingWalker) handleStmtDo(n *stmt.Do) error {
return mw.walkEach(&n.Stmt, &n.Cond)
}
func (mw MutatingWalker) handleStmtEcho(n *stmt.Echo) error {
return mw.walkSlice(n.Exprs)
}
func (mw MutatingWalker) handleStmtElseIf(n *stmt.ElseIf) error {
return mw.walkEach(&n.Cond, &n.Stmt)
}
func (mw MutatingWalker) handleStmtElse(n *stmt.Else) error {
return mw.walkEach(&n.Stmt)
}
func (mw MutatingWalker) handleStmtExpression(n *stmt.Expression) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleStmtFinally(n *stmt.Finally) error {
return mw.walkSlice(n.Stmts)
}
func (mw MutatingWalker) handleStmtFor(n *stmt.For) error {
err := mw.walkSlice(n.Cond)
if err != nil {
return err
}
err = mw.walkSlice(n.Init)
if err != nil {
return err
}
err = mw.walkSlice(n.Loop)
if err != nil {
return err
}
return mw.walkSingle(&n.Stmt)
}
func (mw MutatingWalker) handleStmtForeach(n *stmt.Foreach) error {
return mw.walkEach(&n.Expr, &n.Key, &n.Stmt, &n.Variable)
}
func (mw MutatingWalker) handleStmtFunction(n *stmt.Function) error {
err := mw.walkEach(&n.FunctionName, &n.ReturnType)
if err != nil {
return err
}
err = mw.walkSlice(n.Params)
if err != nil {
return err
}
return mw.walkSlice(n.Stmts)
}
func (mw MutatingWalker) handleStmtGlobal(n *stmt.Global) error {
return mw.walkSlice(n.Vars)
}
func (mw MutatingWalker) handleStmtGoto(n *stmt.Goto) error {
return mw.walkSingle(&n.Label)
}
func (mw MutatingWalker) handleStmtGroupUse(n *stmt.GroupUse) error {
err := mw.walkEach(&n.Prefix, &n.UseType)
if err != nil {
return err
}
return mw.walkSlice(n.UseList)
}
func (mw MutatingWalker) handleStmtHaltCompiler(n *stmt.HaltCompiler) error {
return nil
}
func (mw MutatingWalker) handleStmtIf(n *stmt.If) error {
err := mw.walkEach(&n.Cond, &n.Stmt)
if err != nil {
return err
}
err = mw.walkSlice(n.ElseIf)
if err != nil {
return err
}
return mw.walkSingle(&n.Else)
}
func (mw MutatingWalker) handleStmtInlineHtml(n *stmt.InlineHtml) error {
return nil
}
func (mw MutatingWalker) handleStmtInterface(n *stmt.Interface) error {
var boxedInterfaceExtends node.Node = n.Extends
err := mw.walkEach(&n.InterfaceName, &boxedInterfaceExtends)
if err != nil {
return err
}
ie, ok := boxedInterfaceExtends.(*stmt.InterfaceExtends)
if !ok {
return fmt.Errorf("illegal modification from '*stmt.InterfaceExtends' to incompatible type '%t'", boxedInterfaceExtends)
}
n.Extends = ie // reinstate
//
return mw.walkSlice(n.Stmts)
}
func (mw MutatingWalker) handleStmtInterfaceExtends(n *stmt.InterfaceExtends) error {
return mw.walkSlice(n.InterfaceNames)
}
func (mw MutatingWalker) handleStmtLabel(n *stmt.Label) error {
return mw.walkSingle(&n.LabelName)
}
func (mw MutatingWalker) handleStmtNamespace(n *stmt.Namespace) error {
err := mw.walkSingle(&n.NamespaceName)
if err != nil {
return err
}
return mw.walkSlice(n.Stmts)
}
func (mw MutatingWalker) handleStmtNop(n *stmt.Nop) error {
return nil
}
func (mw MutatingWalker) handleStmtPropertyList(n *stmt.PropertyList) error {
err := mw.walkSlice(n.Modifiers)
if err != nil {
return err
}
err = mw.walkSingle(&n.Type)
if err != nil {
return err
}
return mw.walkSlice(n.Properties)
}
func (mw MutatingWalker) handleStmtProperty(n *stmt.Property) error {
return mw.walkEach(&n.Expr, &n.Variable)
}
func (mw MutatingWalker) handleStmtReturn(n *stmt.Return) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleStmtStaticVar(n *stmt.StaticVar) error {
return mw.walkEach(&n.Variable, &n.Expr)
}
func (mw MutatingWalker) handleStmtStatic(n *stmt.Static) error {
return mw.walkSlice(n.Vars)
}
func (mw MutatingWalker) handleStmtStmtList(n *stmt.StmtList) error {
for i, _ := range n.Stmts {
mw.walkSingle(&n.Stmts[i])
}
return nil
}
func (mw MutatingWalker) handleStmtSwitch(n *stmt.Switch) error {
var boxedCaseList node.Node = n.CaseList
err := mw.walkEach(&boxedCaseList, &n.Cond)
if err != nil {
return err
}
cl, ok := boxedCaseList.(*stmt.CaseList)
if !ok {
return fmt.Errorf("illegal modification from '*stmt.CaseList' to incompatible type '%t'", boxedCaseList)
}
n.CaseList = cl // reinstate
return nil
}
func (mw MutatingWalker) handleStmtThrow(n *stmt.Throw) error {
return mw.walkSingle(&n.Expr)
}
func (mw MutatingWalker) handleStmtTraitAdaptationList(n *stmt.TraitAdaptationList) error {
return mw.walkSlice(n.Adaptations)
}
func (mw MutatingWalker) handleStmtTraitMethodRef(n *stmt.TraitMethodRef) error {
return mw.walkEach(&n.Method, &n.Trait)
}
func (mw MutatingWalker) handleStmtTraitUseAlias(n *stmt.TraitUseAlias) error {
return mw.walkEach(&n.Alias, &n.Modifier, &n.Ref)
}
func (mw MutatingWalker) handleStmtTraitUsePrecedence(n *stmt.TraitUsePrecedence) error {
err := mw.walkSlice(n.Insteadof)
if err != nil {
return err
}
return mw.walkSingle(&n.Ref)
}
func (mw MutatingWalker) handleStmtTraitUse(n *stmt.TraitUse) error {
err := mw.walkSingle(&n.TraitAdaptationList)
if err != nil {
return err
}
return mw.walkSlice(n.Traits)
}
func (mw MutatingWalker) handleStmtTrait(n *stmt.Trait) error {
err := mw.walkSingle(&n.TraitName)
if err != nil {
return err
}
return mw.walkSlice(n.Stmts)
}
func (mw MutatingWalker) handleStmtTry(n *stmt.Try) error {
err := mw.walkSlice(n.Stmts)
if err != nil {
return err
}
err = mw.walkSlice(n.Catches)
if err != nil {
return err
}
return mw.walkSingle(&n.Finally)
}
func (mw MutatingWalker) handleStmtUnset(n *stmt.Unset) error {
return mw.walkSlice(n.Vars)
}
func (mw MutatingWalker) handleStmtUseList(n *stmt.UseList) error {
err := mw.walkSlice(n.Uses)
if err != nil {
return err
}
return mw.walkSingle(&n.UseType)
}
func (mw MutatingWalker) handleStmtUse(n *stmt.Use) error {
return mw.walkEach(&n.Alias, &n.Use, &n.UseType)
}
func (mw MutatingWalker) handleStmtWhile(n *stmt.While) error {
return mw.walkEach(&n.Cond, &n.Stmt)
}
var _ Exhaustive = MutatingWalker{} // interface assertion
//
func (mw MutatingWalker) Walk(n *node.Node) error {
return mw.walkSingle(n)
}