MCPcopy Create free account
hub / github.com/cel-expr/cel-cpp / IsConstExpr

Function IsConstExpr

eval/compiler/constant_folding.cc:107–175  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

105};
106
107IsConst IsConstExpr(const Expr& expr, const Resolver& resolver) {
108 switch (expr.kind_case()) {
109 case ExprKindCase::kConstant:
110 return IsConst::kConditional;
111 case ExprKindCase::kIdentExpr:
112 return IsConst::kNonConst;
113 case ExprKindCase::kComprehensionExpr:
114 // Not yet supported, need to identify whether range and
115 // iter vars are compatible with const folding.
116 return IsConst::kNonConst;
117 case ExprKindCase::kStructExpr:
118 return IsConst::kNonConst;
119 case ExprKindCase::kMapExpr:
120 // Empty maps are rare and not currently supported as they may eventually
121 // have similar issues to empty list when used within comprehensions or
122 // macros.
123 if (expr.map_expr().entries().empty()) {
124 return IsConst::kNonConst;
125 }
126 return IsConst::kConditional;
127 case ExprKindCase::kListExpr:
128 if (expr.list_expr().elements().empty()) {
129 // Don't fold for empty list to allow comprehension
130 // list append optimization.
131 return IsConst::kNonConst;
132 }
133 return IsConst::kConditional;
134 case ExprKindCase::kSelectExpr:
135 return IsConst::kConditional;
136 case ExprKindCase::kCallExpr: {
137 const auto& call = expr.call_expr();
138 // Short Circuiting operators not yet supported.
139 if (call.function() == kAnd || call.function() == kOr ||
140 call.function() == kTernary) {
141 return IsConst::kNonConst;
142 }
143 // For now we skip constant folding for cel.@block. We do not yet setup
144 // slots. When we enable constant folding for comprehensions (like
145 // cel.bind), we can address cel.@block.
146 if (call.function() == "cel.@block") {
147 return IsConst::kNonConst;
148 }
149
150 int arg_len = call.args().size() + (call.has_target() ? 1 : 0);
151 // Check for any lazy overloads (activation dependant)
152 if (!resolver
153 .FindLazyOverloads(call.function(), call.has_target(), arg_len)
154 .empty()) {
155 return IsConst::kNonConst;
156 }
157
158 auto overloads =
159 resolver.FindOverloads(call.function(), call.has_target(), arg_len);
160 // Check for any contextual overloads. If there are any, we cowardly
161 // avoid constant folding instead of trying to check if one of the
162 // overloads would be safe to use.
163 for (const auto& overload : overloads) {
164 if (overload.descriptor.is_contextual()) {

Callers 1

OnPreVisitMethod · 0.85

Calls 8

kind_caseMethod · 0.80
argsMethod · 0.80
has_targetMethod · 0.80
is_contextualMethod · 0.80
emptyMethod · 0.45
sizeMethod · 0.45
FindLazyOverloadsMethod · 0.45
FindOverloadsMethod · 0.45

Tested by

no test coverage detected