| 2124 | } |
| 2125 | |
| 2126 | FunctionPtr makeClassConstructor ( Structure * baseClass, Function * method ) { |
| 2127 | // make a function |
| 2128 | auto func = new Function(); |
| 2129 | func->isTemplate = baseClass->isTemplate; |
| 2130 | func->generated = true; |
| 2131 | func->at = method->at; |
| 2132 | func->atDecl = method->at; |
| 2133 | func->name = baseClass->name; |
| 2134 | func->result = new TypeDecl(baseClass); |
| 2135 | func->isClassMethod = true; |
| 2136 | func->classParent = baseClass; |
| 2137 | DAS_ASSERT(func->classParent); |
| 2138 | if ( baseClass->macroInterface ) func->macroFunction = true; |
| 2139 | auto block = new ExprBlock(); |
| 2140 | block->at = func->at; |
| 2141 | func->body = block; |
| 2142 | for ( auto & arg : method->arguments ) { |
| 2143 | func->arguments.push_back(arg->clone()); |
| 2144 | } |
| 2145 | // lef self = [[Foo()]] |
| 2146 | auto makeT = new ExprMakeStruct(baseClass->at); |
| 2147 | makeT->alwaysSafe = true; |
| 2148 | makeT->at = func->at; |
| 2149 | makeT->useInitializer = true; |
| 2150 | makeT->nativeClassInitializer = true; |
| 2151 | makeT->makeType = new TypeDecl(baseClass); |
| 2152 | makeT->structs.push_back(new MakeStruct()); |
| 2153 | auto letS = new ExprLet(); |
| 2154 | letS->at = func->at; |
| 2155 | letS->atInit = func->at; |
| 2156 | letS->visibility = func->atDecl; |
| 2157 | letS->alwaysSafe = true; // this is due to local class variable |
| 2158 | auto argT = new TypeDecl(baseClass); |
| 2159 | argT->constant = false; |
| 2160 | auto argV = new Variable(); |
| 2161 | argV->name = "self"; |
| 2162 | argV->type = argT; |
| 2163 | argV->at = func->at; |
| 2164 | argV->generated = true; |
| 2165 | argV->capture_as_ref = true; |
| 2166 | argV->init = makeT; |
| 2167 | argV->init_via_move = true; |
| 2168 | letS->variables.push_back(argV); |
| 2169 | block->list.push_back(letS); |
| 2170 | // call Foo`Foo(self,args) |
| 2171 | auto cll = new ExprCall(func->at,baseClass->name+"`"+baseClass->name); |
| 2172 | cll->arguments.push_back(new ExprVar(func->at,"self")); |
| 2173 | for ( auto & arg : method->arguments ) { |
| 2174 | cll->arguments.push_back(new ExprVar(func->at,arg->name)); |
| 2175 | } |
| 2176 | block->list.push_back(cll); |
| 2177 | // return self |
| 2178 | auto selfV = new ExprVar(baseClass->at,"self"); |
| 2179 | selfV->at = func->at; |
| 2180 | auto returnDecl = new ExprReturn(baseClass->at,selfV); |
| 2181 | returnDecl->at = func->at; |
| 2182 | returnDecl->moveSemantics = true; |
| 2183 | block->list.push_back(returnDecl); |
no test coverage detected