buildMacroCallArg iterates the expression and returns a new expression where all macros have been replaced by their IDs in MacroCalls
(expr ast.Expr)
| 191 | // buildMacroCallArg iterates the expression and returns a new expression |
| 192 | // where all macros have been replaced by their IDs in MacroCalls |
| 193 | func (p *parserHelper) buildMacroCallArg(expr ast.Expr) ast.Expr { |
| 194 | if _, found := p.sourceInfo.GetMacroCall(expr.ID()); found { |
| 195 | return p.exprFactory.NewUnspecifiedExpr(expr.ID()) |
| 196 | } |
| 197 | |
| 198 | switch expr.Kind() { |
| 199 | case ast.CallKind: |
| 200 | // Iterate the AST from `expr` recursively looking for macros. Because we are at most |
| 201 | // starting from the top level macro, this recursion is bounded by the size of the AST. This |
| 202 | // means that the depth check on the AST during parsing will catch recursion overflows |
| 203 | // before we get to here. |
| 204 | call := expr.AsCall() |
| 205 | macroArgs := make([]ast.Expr, len(call.Args())) |
| 206 | for index, arg := range call.Args() { |
| 207 | macroArgs[index] = p.buildMacroCallArg(arg) |
| 208 | } |
| 209 | if !call.IsMemberFunction() { |
| 210 | return p.exprFactory.NewCall(expr.ID(), call.FunctionName(), macroArgs...) |
| 211 | } |
| 212 | macroTarget := p.buildMacroCallArg(call.Target()) |
| 213 | return p.exprFactory.NewMemberCall(expr.ID(), call.FunctionName(), macroTarget, macroArgs...) |
| 214 | case ast.ListKind: |
| 215 | list := expr.AsList() |
| 216 | macroListArgs := make([]ast.Expr, list.Size()) |
| 217 | for i, elem := range list.Elements() { |
| 218 | macroListArgs[i] = p.buildMacroCallArg(elem) |
| 219 | } |
| 220 | return p.exprFactory.NewList(expr.ID(), macroListArgs, list.OptionalIndices()) |
| 221 | } |
| 222 | return expr |
| 223 | } |
| 224 | |
| 225 | // addMacroCall adds the macro the the MacroCalls map in source info. If a macro has args/subargs/target |
| 226 | // that are macros, their ID will be stored instead for later self-lookups. |
no test coverage detected