MCPcopy Create free account
hub / github.com/GaijinEntertainment/daScript / countSuperCalls

Function countSuperCalls

src/ast/ast_lint.cpp:225–333  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

223 return false;
224 }
225 SuperCount countSuperCalls ( const ExpressionPtr & expr, const SuperChainMatch & chainCall ) {
226 if ( !expr ) return SuperCount::onlyFall(0, 0);
227 if ( expr->rtti_isCall() ) {
228 auto call = static_cast<ExprCall*>(expr);
229 if ( chainCall(call) ) {
230 return SuperCount::onlyFall(1, 1);
231 }
232 // JIT-mode rewrite of try/recover: ast_infer_type_op.cpp:1015 emits
233 // `builtin_try_recover(make_block(try), make_block(catch))` and the typer
234 // appends `context` + `at` (final arity = 4). Match the resolved function on
235 // its source module ($) to avoid colliding with any user shadow. Count super
236 // in the try block only; the recover block is fatal-panic-with-diagnostics,
237 // irrelevant to chain semantics (mirrors the direct ExprTryCatch handler below).
238 if ( call->func && call->func->module && call->func->module->name == "$"
239 && call->func->name == "builtin_try_recover"
240 && call->arguments.size() >= 2
241 && call->arguments[0]->rtti_isMakeBlock() ) {
242 auto mb = static_cast<ExprMakeBlock*>(call->arguments[0]);
243 return countSuperCalls(mb->block, chainCall);
244 }
245 return SuperCount::onlyFall(0, 0);
246 }
247 if ( expr->rtti_isReturn() ) {
248 // Early-exit at this point with the prefix accumulated so far; no super
249 // here, no fall-through. The caller (block walker) folds the prefix in.
250 return SuperCount::onlyExit(0, 0);
251 }
252 if ( expr->rtti_isBreak() || expr->rtti_isContinue() || expr->rtti_isGoto() ) {
253 // Don't escape the function — they stop block iteration (no fall-through) but
254 // contribute no function-level exit path.
255 return SuperCount::dead();
256 }
257 if ( expr->rtti_isBlock() ) {
258 auto blk = static_cast<ExprBlock*>(expr);
259 int prefix_lo = 0, prefix_hi = 0;
260 SuperCount out = SuperCount::onlyFall(0, 0); // exits accumulated as we go
261 out.hasExits = false;
262 bool fallenThrough = true;
263 for ( auto & be : blk->list ) {
264 auto sub = countSuperCalls(be, chainCall);
265 if ( sub.hasExits ) {
266 mergeExit(out, safeAdd(prefix_lo, sub.exitLo), safeAdd(prefix_hi, sub.exitHi));
267 }
268 if ( !sub.fallsThrough ) {
269 fallenThrough = false;
270 break;
271 }
272 prefix_lo = safeAdd(prefix_lo, sub.fallLo);
273 prefix_hi = safeAdd(prefix_hi, sub.fallHi);
274 }
275 out.fallsThrough = fallenThrough;
276 out.fallLo = prefix_lo;
277 out.fallHi = prefix_hi;
278 return out;
279 }
280 if ( expr->rtti_isIfThenElse() ) {
281 auto ite = static_cast<ExprIfThenElse*>(expr);
282 auto t = countSuperCalls(ite->if_true, chainCall);

Callers 1

visitMethod · 0.85

Calls 5

mergeExitFunction · 0.85
safeAddFunction · 0.85
safeMaxFunction · 0.85
subtreeHasSuperCallFunction · 0.85
sizeMethod · 0.45

Tested by

no test coverage detected