Optimize applies a sequence of optimizations to an Ast within a given environment. If issues are encountered, the Issues.Err() return value will be non-nil.
(env *Env, a *Ast)
| 74 | // |
| 75 | // If issues are encountered, the Issues.Err() return value will be non-nil. |
| 76 | func (opt *StaticOptimizer) Optimize(env *Env, a *Ast) (*Ast, *Issues) { |
| 77 | // Make a copy of the AST to be optimized. |
| 78 | optimized := ast.Copy(a.NativeRep()) |
| 79 | source := a.Source() |
| 80 | sourceInfo := optimized.SourceInfo() |
| 81 | if opt.sourceOverride != nil { |
| 82 | source = *opt.sourceOverride |
| 83 | sourceInfo = ast.NewSourceInfo(*opt.sourceOverride) |
| 84 | } |
| 85 | ids := newIDGenerator(ast.MaxID(a.NativeRep())) |
| 86 | |
| 87 | // Create the optimizer context, could be pooled in the future. |
| 88 | issues := NewIssues(common.NewErrors(source)) |
| 89 | baseFac := ast.NewExprFactory() |
| 90 | exprFac := &optimizerExprFactory{ |
| 91 | idGenerator: ids, |
| 92 | fac: baseFac, |
| 93 | sourceInfo: sourceInfo, |
| 94 | } |
| 95 | ctx := &OptimizerContext{ |
| 96 | optimizerExprFactory: exprFac, |
| 97 | Env: env, |
| 98 | Issues: issues, |
| 99 | } |
| 100 | |
| 101 | // Apply the optimizations sequentially. |
| 102 | for _, o := range opt.optimizers { |
| 103 | optimized = o.Optimize(ctx, optimized) |
| 104 | if issues.Err() != nil { |
| 105 | return nil, issues |
| 106 | } |
| 107 | // Normalize expression id metadata including coordination with macro call metadata. |
| 108 | freshIDGen := newIDGenerator(0) |
| 109 | info := optimized.SourceInfo() |
| 110 | expr := optimized.Expr() |
| 111 | normalizeIDs(freshIDGen.renumberStable, expr, info) |
| 112 | cleanupMacroRefs(expr, info) |
| 113 | |
| 114 | // Recheck the updated expression for any possible type-agreement or validation errors. |
| 115 | parsed := &Ast{ |
| 116 | source: source, |
| 117 | impl: ast.NewAST(expr, info)} |
| 118 | checked, iss := ctx.Check(parsed) |
| 119 | if iss.Err() != nil { |
| 120 | return nil, iss |
| 121 | } |
| 122 | optimized = checked.NativeRep() |
| 123 | } |
| 124 | |
| 125 | // Return the optimized result. |
| 126 | return &Ast{ |
| 127 | source: source, |
| 128 | impl: optimized, |
| 129 | }, nil |
| 130 | } |
| 131 | |
| 132 | // normalizeIDs ensures that the metadata present with an AST is reset in a manner such |
| 133 | // that the ids within the expression correspond to the ids within macros. |