rewritePresenceExpr converts the inlined expression, when it occurs within a has() macro, to type-safe expression appropriate for the inlined type, if possible. If the rewrite is not possible an error is reported at the inline expression site.
(ctx *OptimizerContext, prev, inlined ast.Expr, inlinedType *Type)
| 152 | // |
| 153 | // If the rewrite is not possible an error is reported at the inline expression site. |
| 154 | func (opt *inliningOptimizer) rewritePresenceExpr(ctx *OptimizerContext, prev, inlined ast.Expr, inlinedType *Type) { |
| 155 | // If the input inlined expression is not a select expression it won't work with the has() |
| 156 | // macro. Attempt to rewrite the presence test in terms of the typed input, otherwise error. |
| 157 | if inlined.Kind() == ast.SelectKind { |
| 158 | presenceTest, hasMacro := ctx.NewHasMacro(prev.ID(), inlined) |
| 159 | ctx.UpdateExpr(prev, presenceTest) |
| 160 | ctx.SetMacroCall(prev.ID(), hasMacro) |
| 161 | return |
| 162 | } |
| 163 | |
| 164 | ctx.ClearMacroCall(prev.ID()) |
| 165 | if inlinedType.IsAssignableType(NullType) { |
| 166 | ctx.UpdateExpr(prev, |
| 167 | ctx.NewCall(operators.NotEquals, |
| 168 | inlined, |
| 169 | ctx.NewLiteral(types.NullValue), |
| 170 | )) |
| 171 | return |
| 172 | } |
| 173 | if inlinedType.HasTrait(traits.SizerType) { |
| 174 | ctx.UpdateExpr(prev, |
| 175 | ctx.NewCall(operators.NotEquals, |
| 176 | ctx.NewMemberCall(overloads.Size, inlined), |
| 177 | ctx.NewLiteral(types.IntZero), |
| 178 | )) |
| 179 | return |
| 180 | } |
| 181 | if zeroValExpr, ok := zeroValueExpr(ctx, inlinedType); ok { |
| 182 | ctx.UpdateExpr(prev, |
| 183 | ctx.NewCall(operators.NotEquals, |
| 184 | inlined, zeroValExpr)) |
| 185 | return |
| 186 | } |
| 187 | ctx.ReportErrorAtID(prev.ID(), "unable to inline expression type %v into presence test", inlinedType) |
| 188 | } |
| 189 | |
| 190 | // zeroValueExpr creates an expression representing the empty or zero value for the given type |
| 191 | // Note: bytes, lists, maps, and strings are supported via the `SizerType` trait. |
no test coverage detected