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

Function makeConstructor

src/ast/ast_generate.cpp:313–396  ·  view source on GitHub ↗

return [[t()]] -- or, for a class derived from a parent with a user ctor, emit the let-self / call Parent`Parent(self) / return self chain body.

Source from the content-addressed store, hash-verified

311 // return [[t()]] -- or, for a class derived from a parent with a user ctor,
312 // emit the let-self / call Parent`Parent(self) / return self chain body.
313 FunctionPtr makeConstructor ( Structure * str, bool isPrivate ) {
314 auto fn = new Function();
315 fn->generated = true;
316 fn->privateFunction = isPrivate;
317 fn->name = str->name;
318 fn->at = fn->atDecl = str->at;
319 fn->result = new TypeDecl(str);
320 if ( str->isClass ) {
321 fn->isClassMethod = true;
322 fn->classParent = str;
323 DAS_ASSERT(fn->classParent);
324 }
325 if ( str->macroInterface ) fn->macroFunction = true;
326 auto block = new ExprBlock();
327 block->at = str->at;
328 // For a synth ctor of a class whose ancestor chain has a user ctor, emit a
329 // chain body that calls the deepest USER ctor directly -- but only when
330 // (a) the class itself has no user ctor (true implicit-default case)
331 // AND (b) the chain target has a 0-arg-callable user ctor we can reach.
332 // Otherwise fall through to the plain field-init body. The latter preserves
333 // the long-standing `new Class(field=val)` named-init idiom for classes
334 // with user ctors. The lint catches missing super in the user's own ctor,
335 // which is the only path that actually runs invariants.
336 Structure * chainTarget = nullptr;
337 if ( !str->hasUserConstructor() ) {
338 auto * cand = findChainCtorAncestor(str);
339 if ( cand && cand->hasUserDefaultConstructor() ) {
340 chainTarget = cand;
341 }
342 }
343 if ( chainTarget ) {
344 // let self = [[Derived()]]
345 auto makeT = new ExprMakeStruct(str->at);
346 makeT->alwaysSafe = true;
347 makeT->useInitializer = true;
348 makeT->nativeClassInitializer = true;
349 makeT->makeType = new TypeDecl(str);
350 makeT->structs.push_back(new MakeStruct());
351 auto letS = new ExprLet();
352 letS->at = str->at;
353 letS->atInit = str->at;
354 letS->visibility = str->at;
355 letS->alwaysSafe = true; // local class variable
356 auto argT = new TypeDecl(str);
357 argT->constant = false;
358 auto argV = new Variable();
359 argV->name = "self";
360 argV->type = argT;
361 argV->at = str->at;
362 argV->generated = true;
363 argV->capture_as_ref = true;
364 argV->init = makeT;
365 argV->init_via_move = true;
366 letS->variables.push_back(argV);
367 block->list.push_back(letS);
368 // call ChainTarget`ChainTarget(self) -- closest ancestor with user ctor
369 auto cll = new ExprCall(str->at, chainTarget->name + "`" + chainTarget->name);
370 cll->arguments.push_back(new ExprVar(str->at, "self"));

Callers 1

tryMakeStructureCtorMethod · 0.85

Calls 5

findChainCtorAncestorFunction · 0.85
verifyGeneratedFunction · 0.85
hasUserConstructorMethod · 0.80
push_backMethod · 0.45

Tested by

no test coverage detected