BfDefBuilder.cpp 76 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343
  1. #include "BeefySysLib/util/AllocDebug.h"
  2. #include "BfDefBuilder.h"
  3. #include "BeefySysLib/util/Hash.h"
  4. #include "BfParser.h"
  5. #include "BfResolvePass.h"
  6. #include "BeefySysLib/util/PerfTimer.h"
  7. #include "BeefySysLib/util/BeefPerf.h"
  8. #include "BfUtil.h"
  9. USING_NS_BF;
  10. static void HashNode(HashContext& ctx, BfAstNode* astNode)
  11. {
  12. // Add a separator marker so two nodes hashed back-to-back won't mix
  13. uint8 marker = 0;
  14. ctx.Mixin(&marker, 1);
  15. if (astNode == NULL)
  16. return;
  17. ctx.Mixin(astNode->GetSourceData()->mSrc + astNode->GetSrcStart(), astNode->GetSrcLength());
  18. }
  19. static void HashNode(HashContext& ctx, BfAstNode* astNode, BfAstNode* endNode)
  20. {
  21. // Add a separator marker so two nodes hashed back-to-back won't mix
  22. uint8 marker = 0;
  23. ctx.Mixin(&marker, 1);
  24. if (endNode == NULL)
  25. {
  26. HashNode(ctx, astNode);
  27. return;
  28. }
  29. ctx.Mixin(astNode->GetSourceData()->mSrc + astNode->GetSrcStart(), endNode->GetSrcStart() - astNode->GetSrcStart());
  30. }
  31. static Val128 HashNode(BfAstNode* astNode)
  32. {
  33. if (astNode == NULL)
  34. return Val128();
  35. return Hash128(astNode->GetSourceData()->mSrc + astNode->GetSrcStart(), astNode->GetSrcLength());
  36. }
  37. static Val128 HashNode(BfAstNode* astNode, BfAstNode* endNode)
  38. {
  39. if (endNode == NULL)
  40. return HashNode(astNode);
  41. return Hash128(astNode->GetSourceData()->mSrc + astNode->GetSrcStart(), endNode->GetSrcStart() - astNode->GetSrcStart());
  42. }
  43. static Val128 HashString(const StringImpl& str, const Val128& seed = Val128())
  44. {
  45. return Hash128(str.c_str(), (int)str.length(), seed);
  46. }
  47. BfDefBuilder::BfDefBuilder(BfSystem* bfSystem)
  48. {
  49. mPassInstance = NULL;
  50. mSystem = bfSystem;
  51. mCurTypeDef = NULL;
  52. mCurActualTypeDef = NULL;
  53. mFullRefresh = false;
  54. mResolvePassData = NULL;
  55. mCurSource = NULL;
  56. mFullHashCtx = NULL;
  57. mSignatureHashCtx = NULL;
  58. }
  59. BfDefBuilder::~BfDefBuilder()
  60. {
  61. for (auto& usingNamespace : mNamespaceSearch)
  62. mSystem->ReleaseAtomComposite(usingNamespace);
  63. }
  64. void BfDefBuilder::Process(BfPassInstance* passInstance, BfSource* bfSource, bool fullRefresh)
  65. {
  66. BF_ASSERT((mSystem->mCurSystemLockThreadId == 0) || (mSystem->mCurSystemLockThreadId == BfpThread_GetCurrentId()));
  67. String fileName;
  68. BfParser* parser = bfSource->ToParser();
  69. if (parser != NULL)
  70. fileName = parser->mFileName;
  71. BP_ZONE_F("BfDefBuilder::Process %s", fileName.c_str());
  72. BfLogSys(parser->mSystem, "DefBuilder::Process parser %p\n", parser);
  73. if (mResolvePassData == NULL)
  74. mSystem->mNeedsTypesHandledByCompiler = true;
  75. mPassInstance = passInstance;
  76. bool isAutocomplete = false;
  77. if ((mResolvePassData != NULL) && (mResolvePassData->mAutoComplete != NULL))
  78. {
  79. mCurSource = bfSource;
  80. Visit(bfSource->mRootNode);
  81. mCurSource = NULL;
  82. mPassInstance = NULL;
  83. return;
  84. }
  85. mFullRefresh = fullRefresh;
  86. if (bfSource->mPrevRevision != NULL)
  87. {
  88. for (auto typeDef : bfSource->mPrevRevision->mTypeDefs)
  89. {
  90. BF_ASSERT((typeDef->mDefState >= BfTypeDef::DefState_New) && (typeDef->mDefState < BfTypeDef::DefState_Deleted));
  91. typeDef->mDefState = BfTypeDef::DefState_AwaitingNewVersion;
  92. }
  93. }
  94. {
  95. BP_ZONE("RootNode");
  96. if (bfSource->mRootNode != NULL)
  97. {
  98. mCurSource = bfSource;
  99. Visit(bfSource->mRootNode);
  100. mCurSource = NULL;
  101. }
  102. }
  103. if (bfSource->mPrevRevision != NULL)
  104. {
  105. for (auto typeDef : bfSource->mPrevRevision->mTypeDefs)
  106. {
  107. if (!typeDef->mIsCombinedPartial)
  108. {
  109. if (typeDef->mDefState == BfTypeDef::DefState_AwaitingNewVersion)
  110. {
  111. BfLogSys(parser->mSystem, "DefBuilder::Process deleting typeDef %p\n", typeDef);
  112. typeDef->mName->mAtomUpdateIdx = ++mSystem->mAtomUpdateIdx;
  113. typeDef->mDefState = BfTypeDef::DefState_Deleted;
  114. mSystem->mTypeMapVersion++;
  115. }
  116. }
  117. }
  118. }
  119. mPassInstance = NULL;
  120. }
  121. void BfDefBuilder::Visit(BfIdentifierNode* identifier)
  122. {
  123. if (mResolvePassData != NULL)
  124. mResolvePassData->mExteriorAutocompleteCheckNodes.push_back(identifier);
  125. }
  126. // We need to be aware of the startNode because the reducer adds specifiers like 'static' and 'public' AFTER the method has
  127. // already been handled, so we need to ignore that space while determining if we're "inside" this method or not during
  128. // autocompletion
  129. bool BfDefBuilder::WantsNode(BfAstNode* wholeNode, BfAstNode* startNode, int addLen)
  130. {
  131. if ((mResolvePassData == NULL) || (mResolvePassData->mParser->mCursorIdx == -1))
  132. return true;
  133. // We need to get all nodes when we get fixits because the cursor could be either before or after fields with
  134. // warnings, but still on the correct line
  135. //if (mResolvePassData->mResolveType == BfResolveType_GetFixits)
  136. //return true;
  137. addLen++;
  138. if ((mResolvePassData->mParser->mCursorIdx >= wholeNode->GetSrcStart()) && (mResolvePassData->mParser->mCursorIdx < wholeNode->GetSrcEnd() + addLen))
  139. {
  140. if ((startNode == NULL) || (mResolvePassData->mParser->mCursorIdx >= startNode->GetSrcStart()))
  141. return true;
  142. }
  143. return false;
  144. }
  145. static int sGenericParamIdx = 0;
  146. void BfDefBuilder::ParseGenericParams(BfGenericParamsDeclaration* genericParamsDecl, BfGenericConstraintsDeclaration* genericConstraints, Array<BfGenericParamDef*>& genericParams, Array<BfExternalConstraintDef>* externConstraintDefs, int outerGenericSize, bool isInGeneric)
  147. {
  148. if (genericParamsDecl != NULL)
  149. {
  150. int startIdx = (int)genericParams.size();
  151. for (int genericParamIdx = 0; genericParamIdx < (int)genericParamsDecl->mGenericParams.size(); genericParamIdx++)
  152. {
  153. BfIdentifierNode* genericParamNode = genericParamsDecl->mGenericParams[genericParamIdx];
  154. String name = genericParamNode->ToString();
  155. for (int checkParamsIdx = startIdx; checkParamsIdx < (int)genericParams.size(); checkParamsIdx++)
  156. {
  157. if (genericParams[checkParamsIdx]->mName == name)
  158. {
  159. Fail("Duplicate generic param name", genericParamNode);
  160. }
  161. }
  162. auto checkTypeDef = mCurTypeDef;
  163. while (checkTypeDef != NULL)
  164. {
  165. if (&genericParams != &checkTypeDef->mGenericParamDefs)
  166. {
  167. for (int checkParamsIdx = 0; checkParamsIdx < (int)checkTypeDef->mGenericParamDefs.size(); checkParamsIdx++)
  168. {
  169. if (checkTypeDef->mGenericParamDefs[checkParamsIdx]->mName == name)
  170. {
  171. mPassInstance->Warn(0, "Generic param name has same name as generic param from outer type", genericParamNode);
  172. }
  173. }
  174. }
  175. checkTypeDef = checkTypeDef->mOuterType;
  176. }
  177. auto genericParamDef = new BfGenericParamDef();
  178. genericParamDef->mName = name;
  179. genericParamDef->mNameNodes.Add(genericParamNode);
  180. genericParamDef->mGenericParamFlags = BfGenericParamFlag_None;
  181. genericParams.push_back(genericParamDef);
  182. }
  183. }
  184. if (genericConstraints == NULL)
  185. return;
  186. for (BfAstNode* genericConstraintNode : genericConstraints->mGenericConstraints)
  187. {
  188. auto genericConstraint = BfNodeDynCast<BfGenericConstraint>(genericConstraintNode);
  189. if (genericConstraint == NULL)
  190. continue;
  191. if (genericConstraint->mTypeRef == NULL)
  192. continue;
  193. BfIdentifierNode* nameNode = NULL;
  194. BfGenericParamDef* genericParamDef = NULL;
  195. if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(genericConstraint->mTypeRef))
  196. {
  197. nameNode = namedTypeRef->mNameNode;
  198. String findName = nameNode->ToString();
  199. for (int genericParamIdx = outerGenericSize; genericParamIdx < (int)genericParams.size(); genericParamIdx++)
  200. {
  201. auto checkGenericParam = genericParams[genericParamIdx];
  202. if (checkGenericParam->mName == findName)
  203. genericParamDef = checkGenericParam;
  204. }
  205. }
  206. BfConstraintDef* constraintDef = genericParamDef;
  207. if (genericParamDef == NULL)
  208. {
  209. if (externConstraintDefs == NULL)
  210. {
  211. Fail("Cannot find generic parameter in constraint", genericConstraint->mTypeRef);
  212. if (genericParams.IsEmpty())
  213. continue;
  214. genericParamDef = genericParams[0];
  215. constraintDef = genericParamDef;
  216. }
  217. else
  218. {
  219. if (!isInGeneric)
  220. Fail("Constraints cannot be specified for non-generics", genericConstraint);
  221. externConstraintDefs->Add(BfExternalConstraintDef());
  222. BfExternalConstraintDef* externConstraintDef = &externConstraintDefs->back();
  223. externConstraintDef->mTypeRef = genericConstraint->mTypeRef;
  224. constraintDef = externConstraintDef;
  225. }
  226. }
  227. if (genericParamDef != NULL)
  228. genericParamDef->mNameNodes.Add(nameNode);
  229. for (BfAstNode* constraintNode : genericConstraint->mConstraintTypes)
  230. {
  231. String name;
  232. if ((constraintNode->IsA<BfNamedTypeReference>()) || (constraintNode->IsA<BfTokenNode>()))
  233. {
  234. name = constraintNode->ToString();
  235. }
  236. else if (auto tokenPairNode = BfNodeDynCast<BfTokenPairNode>(constraintNode))
  237. {
  238. name = tokenPairNode->mLeft->ToString() + tokenPairNode->mRight->ToString();
  239. }
  240. bool hasEquals = (genericConstraint->mColonToken != NULL) && (genericConstraint->mColonToken->mToken == BfToken_AssignEquals);
  241. if (!name.empty())
  242. {
  243. if ((name == "class") || (name == "struct") || (name == "struct*") || (name == "const") || (name == "var") || (name == "interface") || (name == "enum"))
  244. {
  245. int prevFlags = constraintDef->mGenericParamFlags &
  246. (BfGenericParamFlag_Class | BfGenericParamFlag_Struct | BfGenericParamFlag_StructPtr | BfGenericParamFlag_Interface | BfGenericParamFlag_Enum);
  247. if (prevFlags != 0)
  248. {
  249. String prevFlagName;
  250. if (prevFlags & BfGenericParamFlag_Class)
  251. prevFlagName = "class";
  252. else if (prevFlags & BfGenericParamFlag_Struct)
  253. prevFlagName = "struct";
  254. else if (prevFlags & BfGenericParamFlag_StructPtr)
  255. prevFlagName = "struct*";
  256. else if (prevFlags & BfGenericParamFlag_Enum)
  257. prevFlagName = "enum";
  258. else // interface
  259. prevFlagName = "interface";
  260. if (prevFlagName == name)
  261. Fail(StrFormat("Cannot specify '%s' twice", prevFlagName.c_str()), constraintNode);
  262. else
  263. Fail(StrFormat("Cannot specify both '%s' and '%s'", prevFlagName.c_str(), name.c_str()), constraintNode);
  264. return;
  265. }
  266. if (name == "class")
  267. constraintDef->mGenericParamFlags = (BfGenericParamFlags)(constraintDef->mGenericParamFlags | BfGenericParamFlag_Class);
  268. else if (name == "struct")
  269. constraintDef->mGenericParamFlags = (BfGenericParamFlags)(constraintDef->mGenericParamFlags | BfGenericParamFlag_Struct);
  270. else if (name == "struct*")
  271. constraintDef->mGenericParamFlags = (BfGenericParamFlags)(constraintDef->mGenericParamFlags | BfGenericParamFlag_StructPtr);
  272. else if (name == "const")
  273. constraintDef->mGenericParamFlags = (BfGenericParamFlags)(constraintDef->mGenericParamFlags | BfGenericParamFlag_Const);
  274. else if (name == "interface")
  275. constraintDef->mGenericParamFlags = (BfGenericParamFlags)(constraintDef->mGenericParamFlags | BfGenericParamFlag_Interface);
  276. else if (name == "enum")
  277. constraintDef->mGenericParamFlags = (BfGenericParamFlags)(constraintDef->mGenericParamFlags | BfGenericParamFlag_Enum);
  278. else //if (name == "var")
  279. constraintDef->mGenericParamFlags = (BfGenericParamFlags)(constraintDef->mGenericParamFlags | BfGenericParamFlag_Var);
  280. continue;
  281. }
  282. else if (name == "new")
  283. {
  284. constraintDef->mGenericParamFlags = (BfGenericParamFlags)(constraintDef->mGenericParamFlags | BfGenericParamFlag_New);
  285. continue;
  286. }
  287. else if (name == "delete")
  288. {
  289. constraintDef->mGenericParamFlags = (BfGenericParamFlags)(constraintDef->mGenericParamFlags | BfGenericParamFlag_Delete);
  290. continue;
  291. }
  292. }
  293. if (auto genericOpConstraint = BfNodeDynCast<BfGenericOperatorConstraint>(constraintNode))
  294. {
  295. // Ok
  296. }
  297. else
  298. {
  299. auto constraintType = BfNodeDynCast<BfTypeReference>(constraintNode);
  300. if (constraintType == NULL)
  301. {
  302. Fail("Invalid constraint", constraintNode);
  303. return;
  304. }
  305. }
  306. if (hasEquals)
  307. {
  308. if (constraintDef->mConstraints.IsEmpty())
  309. {
  310. constraintDef->mGenericParamFlags = (BfGenericParamFlags)(constraintDef->mGenericParamFlags | BfGenericParamFlag_Equals);
  311. }
  312. else
  313. {
  314. Fail("Type assignment must be the first constraint", genericConstraint->mColonToken);
  315. }
  316. }
  317. constraintDef->mConstraints.Add(constraintNode);
  318. }
  319. }
  320. }
  321. BfProtection BfDefBuilder::GetProtection(BfAstNode* protectionNode)
  322. {
  323. if (auto tokenPair = BfNodeDynCast<BfTokenPairNode>(protectionNode))
  324. {
  325. return BfProtection_ProtectedInternal;
  326. }
  327. else if (auto protectionToken = BfNodeDynCast<BfTokenNode>(protectionNode))
  328. {
  329. if (protectionToken->GetToken() == BfToken_Public)
  330. return BfProtection_Public;
  331. if (protectionToken->GetToken() == BfToken_Protected)
  332. return BfProtection_Protected;
  333. if (protectionToken->GetToken() == BfToken_Internal)
  334. return BfProtection_Internal;
  335. return BfProtection_Private;
  336. }
  337. if (mCurTypeDef->mTypeCode == BfTypeCode_Interface)
  338. return BfProtection_Public;
  339. else
  340. return BfProtection_Private;
  341. }
  342. void BfDefBuilder::Visit(BfConstructorDeclaration* ctorDeclaration)
  343. {
  344. if (!WantsNode(ctorDeclaration, NULL))
  345. return;
  346. Visit((BfMethodDeclaration*)ctorDeclaration);
  347. }
  348. BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaration, BfMethodDef* outerMethodDef)
  349. {
  350. BfMethodDef* methodDef;
  351. if (auto operatorDecl = BfNodeDynCast<BfOperatorDeclaration>(methodDeclaration))
  352. {
  353. auto operatorDef = new BfOperatorDef();
  354. operatorDef->mOperatorDeclaration = operatorDecl;
  355. operatorDef->mIsOperator = true;
  356. methodDef = operatorDef;
  357. }
  358. else
  359. methodDef = new BfMethodDef();
  360. methodDef->mDeclaringType = mCurTypeDef;
  361. methodDef->mMethodDeclaration = methodDeclaration;
  362. methodDef->mExplicitInterface = methodDeclaration->mExplicitInterface;
  363. methodDef->mReturnTypeRef = methodDeclaration->mReturnType;
  364. methodDef->mProtection = GetProtection(methodDeclaration->mProtectionSpecifier);
  365. methodDef->mIsReadOnly = methodDeclaration->mReadOnlySpecifier != NULL;
  366. methodDef->mIsStatic = methodDeclaration->mStaticSpecifier != NULL;
  367. methodDef->mIsVirtual = methodDeclaration->mVirtualSpecifier != NULL;
  368. methodDef->mIsPartial = methodDeclaration->mPartialSpecifier != NULL;
  369. methodDef->mIsNew = methodDeclaration->mNewSpecifier != NULL;
  370. methodDef->mIsMutating = methodDeclaration->mMutSpecifier != NULL;
  371. methodDef->mIsExtern = methodDeclaration->mExternSpecifier != NULL;
  372. methodDef->mBody = methodDeclaration->mBody;
  373. if ((methodDeclaration->mThisToken != NULL) && (!methodDeclaration->mParams.IsEmpty()))
  374. methodDef->mMethodType = BfMethodType_Extension;
  375. HashContext signatureHashCtx;
  376. HashNode(signatureHashCtx, methodDeclaration, methodDef->mBody);
  377. //methodDef->mSignatureHash = signatureHashCtx.Finish128();
  378. if (mSignatureHashCtx != NULL)
  379. HashNode(*mSignatureHashCtx, methodDeclaration, methodDef->mBody);
  380. HashContext fullHash;
  381. HashNode(fullHash, methodDeclaration);
  382. methodDef->mFullHash = fullHash.Finish128();
  383. if (methodDeclaration->mVirtualSpecifier != NULL)
  384. {
  385. methodDef->mIsOverride = methodDeclaration->mVirtualSpecifier->GetToken() == BfToken_Override;
  386. methodDef->mIsAbstract = methodDeclaration->mVirtualSpecifier->GetToken() == BfToken_Abstract;
  387. if (methodDef->mIsOverride)
  388. mCurTypeDef->mHasOverrideMethods = true;
  389. if (methodDeclaration->mVirtualSpecifier->GetToken() == BfToken_Concrete)
  390. {
  391. methodDef->mIsConcrete = true;
  392. methodDef->mIsVirtual = false;
  393. }
  394. if (mCurTypeDef->mTypeCode == BfTypeCode_Interface)
  395. {
  396. if ((methodDef->mIsConcrete) && (!mCurTypeDef->mIsConcrete))
  397. Fail("Only interfaces declared as 'concrete' can be declare methods as 'concrete'. Consider adding 'concrete' to the interface declaration.", methodDeclaration->mVirtualSpecifier);
  398. //if (!methodDef->mIsConcrete)
  399. //Fail(StrFormat("Interfaces methods cannot be declared as '%s'", methodDeclaration->mVirtualSpecifier->ToString().c_str()), methodDeclaration->mVirtualSpecifier);
  400. }
  401. else
  402. {
  403. if (methodDef->mIsConcrete)
  404. Fail("Only interfaces methods can be declared as 'concrete'", methodDeclaration->mVirtualSpecifier);
  405. }
  406. if (methodDef->mIsAbstract)
  407. {
  408. if ((!mCurTypeDef->mIsAbstract) && (mCurTypeDef->mTypeCode != BfTypeCode_Interface))
  409. Fail("Method is abstract but it is contained in non-abstract class", methodDeclaration);
  410. if (methodDeclaration->mBody != NULL)
  411. Fail("Abstract method cannot declare a body", methodDeclaration);
  412. }
  413. }
  414. else
  415. {
  416. methodDef->mIsOverride = false;
  417. methodDef->mIsAbstract = false;
  418. }
  419. if (mCurTypeDef->mTypeCode == BfTypeCode_Interface)
  420. {
  421. if ((!methodDef->mIsConcrete) && (!methodDef->mIsStatic) && (!methodDef->mGenericParams.empty()) && (methodDef->mProtection == BfProtection_Public))
  422. methodDef->mIsVirtual = true;
  423. }
  424. if (auto ctorDeclaration = BfNodeDynCast<BfConstructorDeclaration>(methodDeclaration))
  425. {
  426. methodDef->mIsMutating = true;
  427. if (methodDeclaration->mOpenParen != NULL)
  428. {
  429. methodDef->mMethodType = BfMethodType_Ctor;
  430. if (methodDef->mIsStatic)
  431. methodDef->mName = "__BfStaticCtor";
  432. else
  433. methodDef->mName = "__BfCtor";
  434. }
  435. else
  436. {
  437. methodDef->mMethodType = BfMethodType_Init;
  438. methodDef->mName = "__BfInit";
  439. }
  440. }
  441. else if (methodDeclaration->IsA<BfDestructorDeclaration>())
  442. {
  443. methodDef->mMethodType = BfMethodType_Dtor;
  444. if (methodDef->mIsStatic)
  445. methodDef->mName = "__BfStaticDtor";
  446. else
  447. {
  448. mCurTypeDef->mDtorDef = methodDef;
  449. methodDef->mName = "~this";
  450. if (!methodDef->mIsVirtual)
  451. {
  452. methodDef->mIsVirtual = true;
  453. methodDef->mIsOverride = true;
  454. }
  455. }
  456. }
  457. else if (auto operatorDecl = BfNodeDynCast<BfOperatorDeclaration>(methodDeclaration))
  458. {
  459. methodDef->mMethodType = BfMethodType_Operator;
  460. /*if (propertyDecl->mStaticSpecifier == NULL)
  461. {
  462. Fail("Operators must be declared as static", methodDeclaration);
  463. }*/
  464. String declError;
  465. if (methodDef->mProtection != BfProtection_Public)
  466. {
  467. declError = "'public'";
  468. methodDef->mProtection = BfProtection_Public; // Fix it
  469. }
  470. if (operatorDecl->mAssignOp != BfAssignmentOp_None)
  471. {
  472. if (methodDef->mIsStatic)
  473. {
  474. Fail("Assignment operator must not be declared 'static'", operatorDecl->mStaticSpecifier);
  475. }
  476. }
  477. else
  478. {
  479. if (!methodDef->mIsStatic)
  480. {
  481. if ((operatorDecl->mUnaryOp != BfUnaryOp_Increment) && (operatorDecl->mUnaryOp != BfUnaryOp_Decrement))
  482. {
  483. if (!declError.empty())
  484. declError += " and ";
  485. declError += "'static'";
  486. methodDef->mIsStatic = true; // Fix it
  487. }
  488. }
  489. }
  490. if (!declError.empty())
  491. {
  492. Fail(StrFormat("Operator must be declared %s", declError.c_str()), operatorDecl->mOperatorToken);
  493. }
  494. }
  495. else if ((mCurTypeDef->mIsDelegate) || (mCurTypeDef->mIsFunction))
  496. {
  497. methodDef->mName = "Invoke";
  498. methodDef->mMethodType = BfMethodType_Normal;
  499. methodDef->mProtection = BfProtection_Public;
  500. methodDef->mIsStatic = mCurTypeDef->mIsFunction;
  501. auto attributes = mCurTypeDef->mTypeDeclaration->mAttributes;
  502. while (attributes != NULL)
  503. {
  504. if (attributes->mAttributeTypeRef != NULL)
  505. {
  506. auto typeRefName = attributes->mAttributeTypeRef->ToString();
  507. if (typeRefName == "StdCall")
  508. methodDef->mCallingConvention = BfCallingConvention_Stdcall;
  509. }
  510. attributes = attributes->mNextAttribute;
  511. }
  512. }
  513. else if (methodDeclaration->mMixinSpecifier != NULL)
  514. {
  515. if (methodDeclaration->mNameNode != NULL)
  516. methodDef->mName = methodDeclaration->mNameNode->ToString();
  517. methodDef->mMethodType = BfMethodType_Mixin;
  518. }
  519. else
  520. {
  521. if (methodDeclaration->mNameNode != NULL)
  522. methodDef->mName = methodDeclaration->mNameNode->ToString();
  523. methodDef->mMethodType = BfMethodType_Normal;
  524. if ((methodDeclaration->mThisToken != NULL) && (!methodDeclaration->mParams.IsEmpty()))
  525. {
  526. methodDef->mMethodType = BfMethodType_Extension;
  527. mCurTypeDef->mHasExtensionMethods = true;
  528. }
  529. }
  530. if (outerMethodDef != NULL)
  531. {
  532. for (auto genericParam : outerMethodDef->mGenericParams)
  533. {
  534. auto* copiedGenericParamDef = new BfGenericParamDef();
  535. *copiedGenericParamDef = *genericParam;
  536. methodDef->mGenericParams.Add(copiedGenericParamDef);
  537. }
  538. }
  539. int outerGenericSize = 0;
  540. if (outerMethodDef != NULL)
  541. outerGenericSize = (int)outerMethodDef->mGenericParams.size();
  542. if ((methodDef->mMethodType == BfMethodType_Normal) ||
  543. (methodDef->mMethodType == BfMethodType_Operator) ||
  544. (methodDef->mMethodType == BfMethodType_Mixin) ||
  545. (methodDef->mMethodType == BfMethodType_Extension))
  546. {
  547. bool isGeneric = (methodDeclaration->mGenericParams != NULL) || (!mCurTypeDef->mGenericParamDefs.IsEmpty());
  548. ParseGenericParams(methodDeclaration->mGenericParams, methodDeclaration->mGenericConstraintsDeclaration, methodDef->mGenericParams, &methodDef->mExternalConstraints, outerGenericSize, isGeneric);
  549. }
  550. else
  551. {
  552. if (methodDeclaration->mGenericParams != NULL)
  553. Fail("Generic parameters are only allowed on normal methods", methodDeclaration->mGenericParams);
  554. if (methodDeclaration->mGenericConstraintsDeclaration != NULL)
  555. Fail("Generic constraints are only allowed on normal methods", methodDeclaration->mGenericConstraintsDeclaration);
  556. }
  557. bool didDefaultsError = false;
  558. bool hadParams = false;
  559. bool hasDefault = false;
  560. for (int paramIdx = 0; paramIdx < (int)methodDeclaration->mParams.size(); paramIdx++)
  561. {
  562. BfParameterDeclaration* paramDecl = methodDeclaration->mParams[paramIdx];
  563. auto paramDef = new BfParameterDef();
  564. paramDef->mParamDeclaration = paramDecl;
  565. if (paramDecl->mNameNode != NULL)
  566. paramDef->mName = paramDecl->mNameNode->ToString();
  567. paramDef->mTypeRef = paramDecl->mTypeRef;
  568. paramDef->mMethodGenericParamIdx = mSystem->GetGenericParamIdx(methodDef->mGenericParams, paramDef->mTypeRef);
  569. if (paramDecl->mModToken == NULL)
  570. paramDef->mParamKind = BfParamKind_Normal;
  571. else //
  572. paramDef->mParamKind = BfParamKind_Params;
  573. if ((mCurTypeDef->mIsFunction) && (paramIdx == 0) && (paramDef->mName == "this"))
  574. {
  575. paramDef->mParamKind = BfParamKind_ExplicitThis;
  576. methodDef->mIsStatic = false;
  577. }
  578. if (auto dotTypeRef = BfNodeDynCast<BfDotTypeReference>(paramDef->mTypeRef))
  579. {
  580. if (dotTypeRef->mDotToken->mToken == BfToken_DotDotDot)
  581. {
  582. if (paramIdx == (int)methodDeclaration->mParams.size() - 1)
  583. paramDef->mParamKind = BfParamKind_VarArgs;
  584. else
  585. Fail("Varargs specifier must be the last parameter", methodDef->mParams[paramIdx - 1]->mParamDeclaration);
  586. }
  587. }
  588. if (paramDef->mParamDeclaration != NULL)
  589. {
  590. if (paramDef->mParamKind == BfParamKind_Params)
  591. {
  592. hadParams = true;
  593. }
  594. else if (hadParams)
  595. {
  596. methodDef->mParams[paramIdx - 1]->mParamKind = BfParamKind_Normal;
  597. hadParams = false;
  598. Fail("Params parameter must be the last parameter", methodDef->mParams[paramIdx - 1]->mParamDeclaration);
  599. }
  600. if (paramDef->mParamDeclaration->mInitializer != NULL)
  601. hasDefault = true;
  602. else if ((hasDefault) && (paramDef->mParamKind != BfParamKind_Params))
  603. {
  604. if (!didDefaultsError)
  605. Fail("Optional parameters must appear after all required parameters", methodDef->mParams[paramIdx - 1]->mParamDeclaration);
  606. didDefaultsError = true;
  607. }
  608. }
  609. methodDef->mParams.push_back(paramDef);
  610. }
  611. if ((mCurTypeDef->mIsFunction) && (!methodDef->mParams.IsEmpty()) && (methodDef->mParams[0]->mName == "this"))
  612. {
  613. methodDef->mIsStatic = false;
  614. methodDef->mHasExplicitThis = true;
  615. methodDef->mParams[0]->mParamKind = BfParamKind_ExplicitThis;
  616. if (auto refTypeRef = BfNodeDynCast<BfRefTypeRef>(methodDef->mParams[0]->mTypeRef))
  617. {
  618. if (refTypeRef->mRefToken->mToken != BfToken_Mut)
  619. {
  620. Fail("Only 'mut' is allowed here", refTypeRef->mRefToken);
  621. }
  622. methodDef->mIsMutating = true;
  623. }
  624. }
  625. ParseAttributes(methodDeclaration->mAttributes, methodDef);
  626. return methodDef;
  627. }
  628. BfError* BfDefBuilder::Fail(const StringImpl& errorStr, BfAstNode* refNode)
  629. {
  630. auto error = mPassInstance->Fail(errorStr, refNode);
  631. if (error != NULL)
  632. error->mProject = mCurSource->mProject;
  633. return error;
  634. }
  635. void BfDefBuilder::Visit(BfMethodDeclaration* methodDeclaration)
  636. {
  637. if (mCurTypeDef == NULL)
  638. {
  639. return;
  640. }
  641. int addLen = 0;
  642. if ((methodDeclaration->mNameNode == NULL) && (methodDeclaration->mBody == NULL))
  643. addLen = 1;
  644. mSystem->CheckLockYield();
  645. bool wantsBody = true;
  646. BfAstNode* startNode = methodDeclaration->mReturnType;
  647. if (startNode == NULL)
  648. startNode = methodDeclaration->mMixinSpecifier;
  649. if (startNode == NULL)
  650. {
  651. if (auto ctorDecl = BfNodeDynCast<BfConstructorDeclaration>(methodDeclaration))
  652. startNode = ctorDecl->mThisToken;
  653. else if (auto ctorDecl = BfNodeDynCast<BfDestructorDeclaration>(methodDeclaration))
  654. startNode = ctorDecl->mTildeToken;
  655. }
  656. if (startNode == NULL)
  657. startNode = methodDeclaration->mOpenParen;
  658. if (!WantsNode(methodDeclaration, startNode, addLen))
  659. {
  660. if (!WantsNode(methodDeclaration, NULL, addLen))
  661. return;
  662. wantsBody = false;
  663. }
  664. auto methodDef = CreateMethodDef(methodDeclaration);
  665. methodDef->mWantsBody = wantsBody;
  666. if (methodDef->mMethodType == BfMethodType_Operator)
  667. mCurTypeDef->mOperators.push_back((BfOperatorDef*)methodDef);
  668. mCurTypeDef->mMethods.push_back(methodDef);
  669. if (methodDef->mCommutableKind == BfCommutableKind_Forward)
  670. {
  671. auto revMethodDef = CreateMethodDef(methodDeclaration);
  672. revMethodDef->mWantsBody = wantsBody;
  673. if (revMethodDef->mMethodType == BfMethodType_Operator)
  674. mCurTypeDef->mOperators.push_back((BfOperatorDef*)revMethodDef);
  675. if (revMethodDef->mParams.size() >= 2)
  676. {
  677. BF_SWAP(revMethodDef->mParams[0], revMethodDef->mParams[1]);
  678. }
  679. revMethodDef->mCommutableKind = BfCommutableKind_Reverse;
  680. mCurTypeDef->mMethods.push_back(revMethodDef);
  681. }
  682. }
  683. void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfMethodDef* methodDef)
  684. {
  685. while (attributes != NULL)
  686. {
  687. if (attributes->mAttributeTypeRef != NULL)
  688. {
  689. auto typeRefName = attributes->mAttributeTypeRef->ToString();
  690. if (typeRefName == "CLink")
  691. methodDef->mCLink = true;
  692. else if (typeRefName == "StdCall")
  693. methodDef->mCallingConvention = BfCallingConvention_Stdcall;
  694. else if (typeRefName == "CVarArgs")
  695. methodDef->mCallingConvention = BfCallingConvention_CVarArgs;
  696. else if (typeRefName == "Inline")
  697. methodDef->mAlwaysInline = true;
  698. else if (typeRefName == "AllowAppend")
  699. methodDef->mHasAppend = true;
  700. else if (typeRefName == "Checked")
  701. methodDef->mCheckedKind = BfCheckedKind_Checked;
  702. else if (typeRefName == "Unchecked")
  703. methodDef->mCheckedKind = BfCheckedKind_Unchecked;
  704. else if (typeRefName == "Export")
  705. {
  706. mCurTypeDef->mIsAlwaysInclude = true;
  707. methodDef->mImportKind = BfImportKind_Export;
  708. }
  709. else if (typeRefName == "Import")
  710. {
  711. methodDef ->mImportKind = BfImportKind_Import_Unknown;
  712. if (!attributes->mArguments.IsEmpty())
  713. {
  714. if (auto literalExpr = BfNodeDynCast<BfLiteralExpression>(attributes->mArguments[0]))
  715. {
  716. if (literalExpr->mValue.mTypeCode == BfTypeCode_CharPtr)
  717. {
  718. String filePath = *literalExpr->mValue.mString;
  719. methodDef->mImportKind = BfMethodDef::GetImportKindFromPath(filePath);
  720. }
  721. }
  722. }
  723. }
  724. else if (typeRefName == "NoReturn")
  725. methodDef->mIsNoReturn = true;
  726. else if (typeRefName == "SkipCall")
  727. methodDef->mIsSkipCall = true;
  728. else if (typeRefName == "ConstEval")
  729. methodDef->mIsConstEval = true;
  730. else if (typeRefName == "NoShow")
  731. methodDef->mIsNoShow = true;
  732. else if (typeRefName == "NoDiscard")
  733. methodDef->mIsNoDiscard = true;
  734. else if (typeRefName == "NoSplat")
  735. methodDef->mIsNoSplat = true;
  736. else if (typeRefName == "Commutable")
  737. {
  738. if (methodDef->mParams.size() != 2)
  739. {
  740. Fail("Commutable attributes can only be applied to methods with two arguments", attributes->mAttributeTypeRef);
  741. }
  742. else
  743. {
  744. if (methodDef->mIsOperator)
  745. methodDef->mCommutableKind = BfCommutableKind_Operator;
  746. else
  747. methodDef->mCommutableKind = BfCommutableKind_Forward;
  748. }
  749. }
  750. }
  751. attributes = attributes->mNextAttribute;
  752. }
  753. }
  754. void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfTypeDef* typeDef)
  755. {
  756. while (attributes != NULL)
  757. {
  758. if (attributes->mAttributeTypeRef != NULL)
  759. {
  760. auto typeRefName = attributes->mAttributeTypeRef->ToString();
  761. if (typeRefName == "AlwaysInclude")
  762. typeDef->mIsAlwaysInclude = true;
  763. else if (typeRefName == "NoDiscard")
  764. typeDef->mIsNoDiscard = true;
  765. }
  766. attributes = attributes->mNextAttribute;
  767. }
  768. }
  769. void BfDefBuilder::Visit(BfPropertyDeclaration* propertyDeclaration)
  770. {
  771. int addLen = 0;
  772. if (propertyDeclaration->mTypeRef == NULL)
  773. addLen = 1;
  774. bool wantsBody = true;
  775. if (!WantsNode(propertyDeclaration, propertyDeclaration->mTypeRef, addLen))
  776. {
  777. if (!WantsNode(propertyDeclaration, NULL, addLen))
  778. return;
  779. // The cursor is inside some exterior specifiers, don't process body
  780. wantsBody = false;
  781. }
  782. if (propertyDeclaration->mConstSpecifier != NULL)
  783. {
  784. Fail("Const properties are not allowed", propertyDeclaration->mConstSpecifier);
  785. }
  786. HashNode(*mSignatureHashCtx, propertyDeclaration, propertyDeclaration->mDefinitionBlock);
  787. BfPropertyDef* propertyDef = new BfPropertyDef();
  788. mCurTypeDef->mProperties.push_back(propertyDef);
  789. propertyDef->mProtection = GetProtection(propertyDeclaration->mProtectionSpecifier);
  790. propertyDef->mIdx = (int)mCurTypeDef->mProperties.size() - 1;
  791. propertyDef->mIsConst = false;
  792. propertyDef->mIsStatic = propertyDeclaration->mStaticSpecifier != NULL;
  793. propertyDef->mIsReadOnly = propertyDeclaration->mReadOnlySpecifier != NULL;
  794. if (propertyDeclaration->mNameNode != NULL)
  795. propertyDef->mName = propertyDeclaration->mNameNode->ToString();
  796. else if (propertyDeclaration->IsA<BfIndexerDeclaration>())
  797. {
  798. propertyDef->mName = "[]";
  799. }
  800. propertyDef->mTypeRef = propertyDeclaration->mTypeRef;
  801. propertyDef->mInitializer = NULL;
  802. propertyDef->mFieldDeclaration = propertyDeclaration;
  803. propertyDef->mDeclaringType = mCurTypeDef;
  804. if (auto varType = BfNodeDynCast<BfLetTypeReference>(propertyDef->mTypeRef))
  805. propertyDef->mIsReadOnly = true;
  806. //HashNode(*mSignatureHashCtx, propertyDeclaration, propertyDeclaration->mDefinitionBlock);
  807. //mCurTypeDef->mSignatureHash = HashNode(propertyDeclaration, propertyDeclaration->mDefinitionBlock, mCurTypeDef->mSignatureHash);
  808. if (propertyDeclaration->mDefinitionBlock == NULL) // To differentiate between autocompleting partial property if it transitions to a field
  809. {
  810. //mCurTypeDef->mSignatureHash = HashString("nullprop", mCurTypeDef->mSignatureHash);
  811. mSignatureHashCtx->MixinStr("nullprop");
  812. }
  813. auto indexerDeclaration = BfNodeDynCast<BfIndexerDeclaration>(propertyDeclaration);
  814. bool isAbstract = false;
  815. if (propertyDeclaration->mVirtualSpecifier != NULL)
  816. isAbstract = propertyDeclaration->mVirtualSpecifier->GetToken() == BfToken_Abstract;
  817. bool needsAutoProperty = mCurTypeDef->HasAutoProperty(propertyDeclaration);
  818. if (needsAutoProperty)
  819. {
  820. BfFieldDef* fieldDef = new BfFieldDef();
  821. fieldDef->mDeclaringType = mCurTypeDef;
  822. fieldDef->mFieldDeclaration = propertyDeclaration;
  823. fieldDef->mProtection = BfProtection_Hidden;
  824. fieldDef->mIsStatic = propertyDef->mIsStatic;
  825. fieldDef->mTypeRef = propertyDef->mTypeRef;
  826. if (auto refTypeRef = BfNodeDynCast<BfRefTypeRef>(fieldDef->mTypeRef))
  827. fieldDef->mTypeRef = refTypeRef->mElementType;
  828. fieldDef->mName = mCurTypeDef->GetAutoPropertyName(propertyDeclaration);
  829. fieldDef->mIdx = (int)mCurTypeDef->mFields.size();
  830. mCurTypeDef->mFields.push_back(fieldDef);
  831. mCurTypeDef->mSignatureHash = HashString(fieldDef->mName, mCurTypeDef->mSignatureHash);
  832. }
  833. for (auto methodDeclaration : propertyDeclaration->mMethods)
  834. {
  835. HashNode(*mSignatureHashCtx, methodDeclaration->mAttributes);
  836. HashNode(*mSignatureHashCtx, methodDeclaration->mProtectionSpecifier);
  837. HashNode(*mSignatureHashCtx, methodDeclaration->mNameNode);
  838. HashNode(*mSignatureHashCtx, methodDeclaration->mMutSpecifier);
  839. if (!wantsBody)
  840. continue;
  841. if (!WantsNode(methodDeclaration))
  842. continue;
  843. auto methodDef = new BfMethodDef();
  844. mCurTypeDef->mMethods.push_back(methodDef);
  845. methodDef->mDeclaringType = mCurTypeDef;
  846. methodDef->mMethodDeclaration = methodDeclaration;
  847. methodDef->mProtection = propertyDef->mProtection;
  848. methodDef->mWantsBody = (methodDeclaration->mBody != NULL) && (WantsNode(methodDeclaration->mBody));
  849. if (methodDeclaration->mProtectionSpecifier != NULL)
  850. {
  851. BfProtection newProtection = GetProtection(methodDeclaration->mProtectionSpecifier);
  852. if (newProtection > methodDef->mProtection)
  853. Fail(StrFormat("the accessibility modifier of the 'get' accessor must be more restrictive than the property or indexer '%s'", propertyDef->mName.c_str()),
  854. methodDeclaration->mProtectionSpecifier);
  855. methodDef->mProtection = newProtection;
  856. }
  857. methodDef->mIsMutating = methodDeclaration->mMutSpecifier != NULL;
  858. methodDef->mIsAbstract = isAbstract;
  859. methodDef->mIsStatic = propertyDef->mIsStatic;
  860. methodDef->mIsVirtual = propertyDeclaration->mVirtualSpecifier != NULL;
  861. methodDef->mIsExtern = propertyDeclaration->mExternSpecifier != NULL;
  862. methodDef->mMethodDeclaration = methodDeclaration;
  863. methodDef->mExplicitInterface = propertyDeclaration->mExplicitInterface;
  864. HashContext propHashCtx;
  865. HashNode(propHashCtx, methodDeclaration->mNameNode);
  866. HashNode(propHashCtx, methodDeclaration->mAttributes);
  867. HashNode(propHashCtx, methodDeclaration->mProtectionSpecifier);
  868. HashNode(propHashCtx, methodDeclaration->mMutSpecifier);
  869. HashNode(propHashCtx, propertyDeclaration, propertyDeclaration->mDefinitionBlock);
  870. //methodDef->mSignatureHash = propHashCtx.Finish128();
  871. methodDef->mFullHash = HashNode(propertyDeclaration);
  872. if (propertyDeclaration->mVirtualSpecifier != NULL)
  873. methodDef->mIsOverride = propertyDeclaration->mVirtualSpecifier->GetToken() == BfToken_Override;
  874. else
  875. methodDef->mIsOverride = false;
  876. methodDef->mIsNew = propertyDeclaration->mNewSpecifier != NULL;
  877. if (indexerDeclaration != NULL)
  878. {
  879. for (int paramIdx = 0; paramIdx < (int)indexerDeclaration->mParams.size(); paramIdx++)
  880. {
  881. auto paramDef = new BfParameterDef();
  882. BfParameterDeclaration* paramDecl = indexerDeclaration->mParams[paramIdx];
  883. paramDef->mParamDeclaration = paramDecl;
  884. paramDef->mName = paramDecl->mNameNode->ToString();
  885. paramDef->mTypeRef = paramDecl->mTypeRef;
  886. paramDef->mMethodGenericParamIdx = mSystem->GetGenericParamIdx(methodDef->mGenericParams, paramDef->mTypeRef);
  887. methodDef->mParams.push_back(paramDef);
  888. }
  889. }
  890. String methodName;
  891. if (auto propExprBody = BfNodeDynCast<BfPropertyBodyExpression>(propertyDeclaration->mDefinitionBlock))
  892. {
  893. methodName = "get";
  894. ParseAttributes(propertyDeclaration->mAttributes, methodDef);
  895. }
  896. else if ((methodDeclaration != NULL) && (methodDeclaration->mNameNode != NULL))
  897. methodName = methodDeclaration->mNameNode->ToString();
  898. if (methodName == "get")
  899. {
  900. methodDef->mName = "get__";
  901. if (propertyDeclaration->mNameNode != NULL)
  902. methodDef->mName += propertyDeclaration->mNameNode->ToString();
  903. methodDef->mReturnTypeRef = propertyDeclaration->mTypeRef;
  904. methodDef->mMethodType = BfMethodType_PropertyGetter;
  905. if (propertyDeclaration->mReadOnlySpecifier != NULL)
  906. methodDef->mIsReadOnly = true;
  907. propertyDef->mMethods.Add(methodDef);
  908. }
  909. else if (methodName == "set")
  910. {
  911. methodDef->mName = "set__";
  912. if (propertyDeclaration->mNameNode != NULL)
  913. methodDef->mName += propertyDeclaration->mNameNode->ToString();
  914. methodDef->mMethodType = BfMethodType_PropertySetter;
  915. if (BfNodeDynCast<BfTokenNode>(methodDeclaration->mBody) != NULL)
  916. methodDef->mIsMutating = true; // Don't require "set mut;", just "set;"
  917. auto paramDef = new BfParameterDef();
  918. paramDef->mName = "value";
  919. if (auto refTypeRef = BfNodeDynCast<BfRefTypeRef>(propertyDeclaration->mTypeRef))
  920. paramDef->mTypeRef = refTypeRef->mElementType;
  921. else
  922. paramDef->mTypeRef = propertyDeclaration->mTypeRef;
  923. methodDef->mParams.push_back(paramDef);
  924. propertyDef->mMethods.Add(methodDef);
  925. }
  926. else
  927. {
  928. // Parse had an error, leave this block as an unnamed method
  929. }
  930. methodDef->mBody = methodDeclaration->mBody;
  931. ParseAttributes(methodDeclaration->mAttributes, methodDef);
  932. }
  933. }
  934. void BfDefBuilder::Visit(BfFieldDeclaration* fieldDeclaration)
  935. {
  936. mSystem->CheckLockYield();
  937. int endingAdd = 1;// Add '1' for autocompletion of 'new' initializer
  938. if (!WantsNode(fieldDeclaration, NULL, endingAdd))
  939. {
  940. return;
  941. }
  942. // This check is a bit of a hack to determine the difference between a "MemberType mMember" and a proper case entry of "mMember(TupleType)"
  943. bool isEnumEntryDecl = fieldDeclaration->IsA<BfEnumEntryDeclaration>();
  944. auto fieldDef = new BfFieldDef();
  945. mCurTypeDef->mFields.push_back(fieldDef);
  946. fieldDef->mFieldDeclaration = fieldDeclaration;
  947. fieldDef->mDeclaringType = mCurTypeDef;
  948. if (fieldDeclaration->mNameNode != NULL)
  949. fieldDef->mName = fieldDeclaration->mNameNode->ToString();
  950. fieldDef->mProtection = GetProtection(fieldDeclaration->mProtectionSpecifier);
  951. if (isEnumEntryDecl)
  952. fieldDef->mProtection = BfProtection_Public;
  953. fieldDef->mIsReadOnly = fieldDeclaration->mReadOnlySpecifier != NULL;
  954. fieldDef->mIsInline = (fieldDeclaration->mReadOnlySpecifier != NULL) && (fieldDeclaration->mReadOnlySpecifier->GetToken() == BfToken_Inline);
  955. fieldDef->mIsExtern = (fieldDeclaration->mExternSpecifier != NULL);
  956. fieldDef->mIsConst = (fieldDeclaration->mConstSpecifier != NULL) || (isEnumEntryDecl);
  957. fieldDef->mIsStatic = (fieldDeclaration->mStaticSpecifier != NULL) || fieldDef->mIsConst;
  958. fieldDef->mIsVolatile = (fieldDeclaration->mVolatileSpecifier != NULL);
  959. fieldDef->mTypeRef = fieldDeclaration->mTypeRef;
  960. if (auto varType = BfNodeDynCast<BfLetTypeReference>(fieldDef->mTypeRef))
  961. fieldDef->mIsReadOnly = true;
  962. if ((mCurTypeDef->mTypeCode == BfTypeCode_Enum) && (fieldDef->mTypeRef != NULL) && (!fieldDef->mIsStatic))
  963. {
  964. // This check is a bit of a hack to determine the difference between a "MemberType mMember" and a proper case entry of "mMember(TupleType)"
  965. if (!isEnumEntryDecl)
  966. {
  967. Fail("Non-static field declarations are not allowed in enums", fieldDeclaration);
  968. }
  969. }
  970. fieldDef->mIdx = (int)mCurTypeDef->mFields.size() - 1;
  971. fieldDef->mInitializer = fieldDeclaration->mInitializer;
  972. //mCurTypeDef->mSignatureHash = HashNode(fieldDeclaration, mCurTypeDef->mSignatureHash);
  973. HashNode(*mSignatureHashCtx, fieldDeclaration);
  974. }
  975. void BfDefBuilder::Visit(BfEnumCaseDeclaration* enumCaseDeclaration)
  976. {
  977. // Using `enumCaseDeclaration->mCaseToken` breaks attribute autocompletion
  978. //if (!WantsNode(enumCaseDeclaration, enumCaseDeclaration->mCaseToken, 0))
  979. if (!WantsNode(enumCaseDeclaration))
  980. {
  981. return;
  982. }
  983. for (int entryIdx = 0; entryIdx < (int)enumCaseDeclaration->mEntries.size(); entryIdx++)
  984. {
  985. auto caseEntry = enumCaseDeclaration->mEntries[entryIdx];
  986. Visit(caseEntry);
  987. }
  988. }
  989. BfFieldDef* BfDefBuilder::AddField(BfTypeDef* typeDef, BfTypeReference* fieldType, const StringImpl& fieldName)
  990. {
  991. BfFieldDef* fieldDef = new BfFieldDef();
  992. fieldDef->mDeclaringType = typeDef;
  993. fieldDef->mTypeRef = fieldType;
  994. fieldDef->mName = fieldName;
  995. fieldDef->mIdx = (int)typeDef->mFields.size();
  996. typeDef->mFields.push_back(fieldDef);
  997. return fieldDef;
  998. }
  999. BfMethodDef* BfDefBuilder::AddMethod(BfTypeDef* typeDef, BfMethodType methodType, BfProtection protection, bool isStatic, const StringImpl& name)
  1000. {
  1001. BF_ASSERT(typeDef->mTypeCode != BfTypeCode_TypeAlias);
  1002. auto methodDef = new BfMethodDef();
  1003. methodDef->mIdx = (int)typeDef->mMethods.size();
  1004. typeDef->mMethods.push_back(methodDef);
  1005. methodDef->mDeclaringType = typeDef;
  1006. methodDef->mMethodType = methodType;
  1007. if (name.empty())
  1008. {
  1009. if (methodType == BfMethodType_Ctor)
  1010. {
  1011. if (isStatic)
  1012. methodDef->mName = "__BfStaticCtor";
  1013. else
  1014. methodDef->mName = "__BfCtor";
  1015. }
  1016. else if (methodType == BfMethodType_CtorNoBody)
  1017. {
  1018. methodDef->mName = "__BfCtorNoBody";
  1019. methodDef->mIsNoReflect = true;
  1020. }
  1021. else if (methodType == BfMethodType_CtorClear)
  1022. {
  1023. methodDef->mName = "__BfCtorClear";
  1024. methodDef->mIsNoReflect = true;
  1025. }
  1026. else if (methodType == BfMethodType_Init)
  1027. {
  1028. methodDef->mName = "__BfInit";
  1029. }
  1030. else if (methodType == BfMethodType_Dtor)
  1031. {
  1032. if (isStatic)
  1033. {
  1034. methodDef->mName = "__BfStaticDtor";
  1035. }
  1036. else
  1037. {
  1038. methodDef->mName = "~this";
  1039. methodDef->mIsVirtual = true;
  1040. methodDef->mIsOverride = true;
  1041. BF_ASSERT(typeDef->mDtorDef == NULL);
  1042. typeDef->mDtorDef = methodDef;
  1043. }
  1044. }
  1045. else
  1046. {
  1047. BF_FATAL("Method name expected");
  1048. }
  1049. }
  1050. else
  1051. methodDef->mName = name;
  1052. methodDef->mProtection = protection;
  1053. methodDef->mIsStatic = isStatic;
  1054. return methodDef;
  1055. }
  1056. BfMethodDef* BfDefBuilder::AddDtor(BfTypeDef* typeDef)
  1057. {
  1058. auto methodDef = new BfMethodDef();
  1059. typeDef->mMethods.push_back(methodDef);
  1060. methodDef->mDeclaringType = typeDef;
  1061. methodDef->mName = "~this";
  1062. methodDef->mProtection = BfProtection_Public;
  1063. methodDef->mMethodType = BfMethodType_Dtor;
  1064. methodDef->mIsVirtual = true;
  1065. methodDef->mIsOverride = true;
  1066. BF_ASSERT(typeDef->mDtorDef == NULL);
  1067. typeDef->mDtorDef = methodDef;
  1068. return methodDef;
  1069. }
  1070. void BfDefBuilder::AddDynamicCastMethods(BfTypeDef* typeDef)
  1071. {
  1072. //
  1073. {
  1074. auto methodDef = new BfMethodDef();
  1075. methodDef->mIdx = (int)typeDef->mMethods.size();
  1076. typeDef->mMethods.push_back(methodDef);
  1077. methodDef->mDeclaringType = typeDef;
  1078. methodDef->mName = BF_METHODNAME_DYNAMICCAST;
  1079. methodDef->mProtection = BfProtection_Protected;
  1080. methodDef->mIsStatic = false;
  1081. methodDef->mMethodType = BfMethodType_Normal;
  1082. methodDef->mIsVirtual = true;
  1083. methodDef->mIsOverride = true;
  1084. auto paramDef = new BfParameterDef();
  1085. paramDef->mName = "id";
  1086. paramDef->mTypeRef = typeDef->mSystem->mDirectInt32TypeRef;
  1087. methodDef->mParams.push_back(paramDef);
  1088. methodDef->mReturnTypeRef = typeDef->mSystem->mDirectObjectTypeRef;
  1089. methodDef->mIsNoReflect = true;
  1090. }
  1091. //
  1092. {
  1093. auto methodDef = new BfMethodDef();
  1094. methodDef->mIdx = (int)typeDef->mMethods.size();
  1095. typeDef->mMethods.push_back(methodDef);
  1096. methodDef->mDeclaringType = typeDef;
  1097. methodDef->mName = BF_METHODNAME_DYNAMICCAST_INTERFACE;
  1098. methodDef->mProtection = BfProtection_Protected;
  1099. methodDef->mIsStatic = false;
  1100. methodDef->mMethodType = BfMethodType_Normal;
  1101. methodDef->mIsVirtual = true;
  1102. methodDef->mIsOverride = true;
  1103. auto paramDef = new BfParameterDef();
  1104. paramDef->mName = "id";
  1105. paramDef->mTypeRef = typeDef->mSystem->mDirectInt32TypeRef;
  1106. methodDef->mParams.push_back(paramDef);
  1107. methodDef->mReturnTypeRef = typeDef->mSystem->mDirectObjectTypeRef;
  1108. methodDef->mIsNoReflect = true;
  1109. }
  1110. }
  1111. void BfDefBuilder::AddParam(BfMethodDef* methodDef, BfTypeReference* typeRef, const StringImpl& paramName)
  1112. {
  1113. auto paramDef = new BfParameterDef();
  1114. paramDef->mName = paramName;
  1115. paramDef->mTypeRef = typeRef;
  1116. methodDef->mParams.push_back(paramDef);
  1117. }
  1118. void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
  1119. {
  1120. BF_ASSERT(typeDeclaration->GetSourceData() == mCurSource->mSourceData);
  1121. if ((typeDeclaration->mTypeNode != NULL) && (typeDeclaration->mNameNode == NULL))
  1122. return;
  1123. /*if (typeDeclaration->mNameNode != NULL)
  1124. OutputDebugStrF("Decl: %s\n", typeDeclaration->mNameNode->ToString().c_str());*/
  1125. bool isAutoCompleteTempType = false;
  1126. if (mResolvePassData != NULL)
  1127. {
  1128. isAutoCompleteTempType = (mResolvePassData->mAutoComplete != NULL);
  1129. int cursorIdx = mResolvePassData->mParser->mCursorIdx;
  1130. if (typeDeclaration->Contains(cursorIdx, 1, 0))
  1131. {
  1132. // Within bounds
  1133. }
  1134. else if (cursorIdx != -1)
  1135. return;
  1136. }
  1137. int curLine = 0;
  1138. int curColumn = 0;
  1139. auto bfParser = mCurSource->ToParser();
  1140. if (bfParser != NULL)
  1141. {
  1142. int srcStart = typeDeclaration->GetSrcStart();
  1143. auto* jumpEntry = bfParser->mJumpTable + (srcStart / PARSER_JUMPTABLE_DIVIDE);
  1144. if (jumpEntry->mCharIdx > srcStart)
  1145. jumpEntry--;
  1146. curLine = jumpEntry->mLineNum;
  1147. int curSrcPos = jumpEntry->mCharIdx;
  1148. curColumn = 0;
  1149. while (curSrcPos < srcStart)
  1150. {
  1151. if (bfParser->mSrc[curSrcPos] == '\n')
  1152. {
  1153. curLine++;
  1154. curColumn = 0;
  1155. }
  1156. else
  1157. curColumn++;
  1158. curSrcPos++;
  1159. }
  1160. }
  1161. auto outerTypeDef = mCurTypeDef;
  1162. auto actualOuterTypeDef = mCurActualTypeDef;
  1163. while ((outerTypeDef != NULL) && (outerTypeDef->IsGlobalsContainer()))
  1164. outerTypeDef = outerTypeDef->mOuterType;
  1165. while ((actualOuterTypeDef != NULL) && (actualOuterTypeDef->IsGlobalsContainer()))
  1166. actualOuterTypeDef = actualOuterTypeDef->mOuterType;
  1167. SetAndRestoreValue<BfTypeDef*> prevTypeDef(mCurTypeDef, new BfTypeDef());
  1168. SetAndRestoreValue<BfTypeDef*> prevActualTypeDef(mCurActualTypeDef, mCurTypeDef);
  1169. mCurTypeDef->mSystem = mSystem;
  1170. mCurTypeDef->mProject = mCurSource->mProject;
  1171. mCurTypeDef->mNamespace = mNamespace;
  1172. mSystem->AddNamespaceUsage(mCurTypeDef->mNamespace, mCurTypeDef->mProject);
  1173. if (typeDeclaration->mTypeNode == NULL)
  1174. {
  1175. mCurTypeDef->mIsPartial = true;
  1176. mCurTypeDef->mIsExplicitPartial = true;
  1177. }
  1178. if (typeDeclaration->mNameNode == NULL)
  1179. {
  1180. // Global
  1181. mCurTypeDef->mName = mSystem->mGlobalsAtom;
  1182. mCurTypeDef->mName->Ref();
  1183. BF_ASSERT(mCurTypeDef->mSystem != NULL);
  1184. }
  1185. else
  1186. {
  1187. mCurTypeDef->mName = mSystem->GetAtom(typeDeclaration->mNameNode->ToString());
  1188. if (mCurTypeDef->mName->mIsSystemType)
  1189. {
  1190. Fail(StrFormat("Type name '%s' is reserved", typeDeclaration->mNameNode->ToString().c_str()), typeDeclaration->mNameNode);
  1191. }
  1192. }
  1193. BfLogSys(mCurSource->mSystem, "DefBuilder %p %p TypeDecl:%s\n", mCurTypeDef, mCurSource, mCurTypeDef->mName->ToString().mPtr);
  1194. mCurTypeDef->mProtection = (outerTypeDef == NULL) ? BfProtection_Public : BfProtection_Private;
  1195. if (typeDeclaration->mProtectionSpecifier != NULL)
  1196. {
  1197. if ((outerTypeDef == NULL) && (typeDeclaration->mProtectionSpecifier->GetToken() != BfToken_Public))
  1198. {
  1199. //CS1527
  1200. Fail("Elements defined in a namespace cannot be explicitly declared as private or protected", typeDeclaration->mProtectionSpecifier);
  1201. }
  1202. else
  1203. {
  1204. mCurTypeDef->mProtection = GetProtection(typeDeclaration->mProtectionSpecifier);
  1205. }
  1206. }
  1207. if (typeDeclaration->mAttributes != NULL)
  1208. ParseAttributes(typeDeclaration->mAttributes, mCurTypeDef);
  1209. for (auto& baseClass : typeDeclaration->mBaseClasses)
  1210. mCurTypeDef->mBaseTypes.push_back(baseClass);
  1211. HashContext fullHashCtx;
  1212. HashContext signatureHashCtx;
  1213. SetAndRestoreValue<HashContext*> prevFullHashCtx(mFullHashCtx, &fullHashCtx);
  1214. SetAndRestoreValue<HashContext*> prevSignatureHashCtx(mSignatureHashCtx, &signatureHashCtx);
  1215. if (bfParser != NULL)
  1216. {
  1217. mFullHashCtx->MixinStr(bfParser->mFileName);
  1218. mFullHashCtx->Mixin(bfParser->mParserData->mMD5Hash);
  1219. }
  1220. HashNode(*mSignatureHashCtx, typeDeclaration->mTypeNode);
  1221. for (auto& baseClassNode : typeDeclaration->mBaseClasses)
  1222. HashNode(*mSignatureHashCtx, baseClassNode);
  1223. HashNode(*mSignatureHashCtx, typeDeclaration->mAttributes);
  1224. HashNode(*mSignatureHashCtx, typeDeclaration->mAbstractSpecifier);
  1225. HashNode(*mSignatureHashCtx, typeDeclaration->mSealedSpecifier);
  1226. HashNode(*mSignatureHashCtx, typeDeclaration->mProtectionSpecifier);
  1227. HashNode(*mSignatureHashCtx, typeDeclaration->mPartialSpecifier);
  1228. HashNode(*mSignatureHashCtx, typeDeclaration->mNameNode);
  1229. HashNode(*mSignatureHashCtx, typeDeclaration->mGenericParams);
  1230. HashNode(*mSignatureHashCtx, typeDeclaration->mGenericConstraintsDeclaration);
  1231. HashNode(*mFullHashCtx, typeDeclaration);
  1232. // Allow internal preprocessor flags to change a full hash change
  1233. if (bfParser != NULL)
  1234. {
  1235. // Note- we insert strings from these HashSets in bucket-order, which is stable
  1236. // for the same insertion order, but is not truly order independent. Shouldn't matter.
  1237. fullHashCtx.Mixin(bfParser->mParserData->mDefines_Def.size());
  1238. for (auto& defStr : bfParser->mParserData->mDefines_Def)
  1239. fullHashCtx.MixinStr(defStr);
  1240. fullHashCtx.Mixin(bfParser->mParserData->mDefines_NoDef.size());
  1241. for (auto& defStr : bfParser->mParserData->mDefines_NoDef)
  1242. fullHashCtx.MixinStr(defStr);
  1243. }
  1244. // We need to hash the position of the declaration in the file so we can rebuild the debug info with revised line numbers
  1245. int hashPos[2] = { curLine, curColumn };
  1246. mFullHashCtx->Mixin(hashPos);
  1247. if (mSystem->mIsResolveOnly)
  1248. {
  1249. // We need to have the correct source index for renames and such
  1250. fullHashCtx.Mixin(typeDeclaration->GetSrcStart());
  1251. }
  1252. if (auto typeAliasDeclaration = BfNodeDynCast<BfTypeAliasDeclaration>(typeDeclaration))
  1253. {
  1254. HashNode(*mSignatureHashCtx, typeAliasDeclaration->mAliasToType);
  1255. }
  1256. //TODO:
  1257. //int randomCrap = rand();
  1258. //HASH128_MIXIN(mCurTypeDef->mFullHash, randomCrap);
  1259. // To cause a type rebuild when we change pragma settings or #if resolves
  1260. //mCurTypeDef->mFullHash = Hash128(&typeDeclaration->mParser->mStateHash, sizeof(Val128), mCurTypeDef->mFullHash);
  1261. //BfParser* bfParser = typeDeclaration->mParser;
  1262. // Hash in ignored warnings that occur before our type declaration
  1263. std::set<int> ignoredWarningSet;
  1264. auto warningItr = bfParser->mParserData->mWarningEnabledChanges.begin();
  1265. while (warningItr != bfParser->mParserData->mWarningEnabledChanges.end())
  1266. {
  1267. int srcIdx = warningItr->mKey;
  1268. if (srcIdx >= typeDeclaration->GetSrcStart())
  1269. break;
  1270. auto& warningEntry = warningItr->mValue;
  1271. if (!warningEntry.mEnable)
  1272. {
  1273. ignoredWarningSet.insert(warningEntry.mWarningNumber);
  1274. }
  1275. else
  1276. {
  1277. auto setItr = ignoredWarningSet.find(warningEntry.mWarningNumber);
  1278. if (setItr != ignoredWarningSet.end())
  1279. ignoredWarningSet.erase(setItr);
  1280. }
  1281. ++warningItr;
  1282. }
  1283. for (auto ignoredWarning : ignoredWarningSet)
  1284. {
  1285. mFullHashCtx->Mixin(ignoredWarning);
  1286. }
  1287. // Hash in relative mPreprocessorIgnoredSectionStarts positions that occur within the type declaration
  1288. auto ignoredSectionItr = bfParser->mPreprocessorIgnoredSectionStarts.upper_bound(typeDeclaration->GetSrcStart());
  1289. while (ignoredSectionItr != bfParser->mPreprocessorIgnoredSectionStarts.end())
  1290. {
  1291. int srcIdx = *ignoredSectionItr;
  1292. if (srcIdx >= typeDeclaration->GetSrcEnd())
  1293. break;
  1294. int relSrcIdx = srcIdx - typeDeclaration->GetSrcStart();
  1295. mFullHashCtx->Mixin(relSrcIdx);
  1296. ++ignoredSectionItr;
  1297. }
  1298. SizedArray<BfAtom*, 6> expandedName;
  1299. if (mCurTypeDef->mName != mSystem->mGlobalsAtom)
  1300. expandedName.push_back(mCurTypeDef->mName);
  1301. // Expanded name should container outer namespace parts
  1302. if (outerTypeDef != NULL)
  1303. {
  1304. mCurTypeDef->mNestDepth = outerTypeDef->mNestDepth + 1;
  1305. mCurTypeDef->mNamespaceSearch = outerTypeDef->mNamespaceSearch;
  1306. mCurTypeDef->mStaticSearch = outerTypeDef->mStaticSearch;
  1307. mCurTypeDef->mInternalAccessSet = outerTypeDef->mInternalAccessSet;
  1308. for (auto outerGenericParamDef : outerTypeDef->mGenericParamDefs)
  1309. {
  1310. BfGenericParamDef* copiedGenericParamDef = new BfGenericParamDef();
  1311. *copiedGenericParamDef = *outerGenericParamDef;
  1312. mCurTypeDef->mGenericParamDefs.Add(copiedGenericParamDef);
  1313. }
  1314. BfTypeDef* parentType = outerTypeDef;
  1315. while (parentType != NULL)
  1316. {
  1317. expandedName.Insert(0, parentType->mNameEx);
  1318. parentType = parentType->mOuterType;
  1319. }
  1320. }
  1321. else
  1322. {
  1323. BF_ASSERT(mCurTypeDef->mNamespaceSearch.size() == 0);
  1324. mCurTypeDef->mNamespaceSearch = mNamespaceSearch;
  1325. mCurTypeDef->mStaticSearch = mStaticSearch;
  1326. mCurTypeDef->mInternalAccessSet = mInternalAccessSet;
  1327. }
  1328. // We need to mix the namespace search into the signature hash because it can change how type references are resolved
  1329. for (auto& usingName : mCurTypeDef->mNamespaceSearch)
  1330. {
  1331. mSystem->RefAtomComposite(usingName);
  1332. mSignatureHashCtx->MixinStr(usingName.ToString());
  1333. }
  1334. for (auto& usingName : mCurTypeDef->mStaticSearch)
  1335. HashNode(*mSignatureHashCtx, usingName);
  1336. for (auto& usingName : mCurTypeDef->mInternalAccessSet)
  1337. HashNode(*mSignatureHashCtx, usingName);
  1338. if ((typeDeclaration->mPartialSpecifier != NULL) && (!isAutoCompleteTempType))
  1339. {
  1340. mCurTypeDef->mIsExplicitPartial = true;
  1341. mCurTypeDef->mIsPartial = true;
  1342. }
  1343. bool isExtension = false;
  1344. if ((typeDeclaration->mTypeNode != NULL) && (typeDeclaration->mTypeNode->GetToken() == BfToken_Extension))
  1345. {
  1346. mCurTypeDef->mIsPartial = true;
  1347. isExtension = true;
  1348. }
  1349. BfAtomComposite fullName;
  1350. if (!expandedName.IsEmpty())
  1351. fullName.Set(mCurTypeDef->mNamespace.mParts, mCurTypeDef->mNamespace.mSize, &expandedName[0], (int)expandedName.size());
  1352. else
  1353. fullName = mCurTypeDef->mNamespace;
  1354. String fullNameStr = fullName.ToString();
  1355. mCurTypeDef->mHash = 0xBEEF123; // Salt the hash
  1356. for (char c : fullNameStr)
  1357. mCurTypeDef->mHash = ((mCurTypeDef->mHash ^ c) << 4) - mCurTypeDef->mHash;
  1358. mCurTypeDef->mFullName = fullName;
  1359. BfTypeDef* prevRevisionTypeDef = NULL;
  1360. BfTypeDef* otherDefinitionTypeDef = NULL;
  1361. int numGenericParams = 0;
  1362. if (typeDeclaration->mGenericParams != NULL)
  1363. numGenericParams = (int)typeDeclaration->mGenericParams->mGenericParams.size();
  1364. if (outerTypeDef != NULL)
  1365. numGenericParams += (int)outerTypeDef->mGenericParamDefs.size();
  1366. mCurTypeDef->mSource = mCurSource;
  1367. mCurTypeDef->mSource->mRefCount++;
  1368. mCurTypeDef->mTypeDeclaration = typeDeclaration;
  1369. mCurTypeDef->mIsAbstract = (typeDeclaration->mAbstractSpecifier != NULL) && (typeDeclaration->mAbstractSpecifier->GetToken() == BfToken_Abstract);
  1370. mCurTypeDef->mIsConcrete = (typeDeclaration->mAbstractSpecifier != NULL) && (typeDeclaration->mAbstractSpecifier->GetToken() == BfToken_Concrete);
  1371. mCurTypeDef->mIsStatic = typeDeclaration->mStaticSpecifier != NULL;
  1372. mCurTypeDef->mIsDelegate = false;
  1373. mCurTypeDef->mIsFunction = false;
  1374. BfToken typeToken = BfToken_None;
  1375. if (typeDeclaration->mTypeNode != NULL)
  1376. typeToken = typeDeclaration->mTypeNode->GetToken();
  1377. if (typeDeclaration->mTypeNode == NULL)
  1378. {
  1379. // Globals
  1380. mCurTypeDef->mTypeCode = BfTypeCode_Struct;
  1381. }
  1382. else if (typeToken == BfToken_Class)
  1383. {
  1384. mCurTypeDef->mTypeCode = BfTypeCode_Object;
  1385. }
  1386. else if (typeToken == BfToken_Delegate)
  1387. {
  1388. mCurTypeDef->mTypeCode = BfTypeCode_Object;
  1389. mCurTypeDef->mIsDelegate = true;
  1390. }
  1391. else if (typeToken == BfToken_Function)
  1392. {
  1393. mCurTypeDef->mTypeCode = BfTypeCode_Struct;
  1394. mCurTypeDef->mIsFunction = true;
  1395. }
  1396. else if (typeToken == BfToken_Interface)
  1397. {
  1398. mCurTypeDef->mTypeCode = BfTypeCode_Interface;
  1399. }
  1400. else if (typeToken == BfToken_Enum)
  1401. {
  1402. mCurTypeDef->mTypeCode = BfTypeCode_Enum;
  1403. }
  1404. else if (typeToken == BfToken_TypeAlias)
  1405. {
  1406. mCurTypeDef->mTypeCode = BfTypeCode_TypeAlias;
  1407. }
  1408. else if (typeToken == BfToken_Struct)
  1409. mCurTypeDef->mTypeCode = BfTypeCode_Struct;
  1410. else if (typeToken == BfToken_Extension)
  1411. mCurTypeDef->mTypeCode = BfTypeCode_Extension;
  1412. else
  1413. BF_FATAL("Unknown type token");
  1414. if (mCurTypeDef->mIsStatic)
  1415. {
  1416. if ((mCurTypeDef->mTypeCode != BfTypeCode_Object) &&
  1417. (mCurTypeDef->mTypeCode != BfTypeCode_Struct))
  1418. {
  1419. mPassInstance->Warn(0, StrFormat("Types declared as '%s' cannot be 'static'", BfTokenToString(typeToken)).c_str(), typeDeclaration->mStaticSpecifier);
  1420. mCurTypeDef->mIsStatic = false;
  1421. }
  1422. }
  1423. if (mCurTypeDef->mIsAbstract)
  1424. {
  1425. if (mCurTypeDef->mTypeCode != BfTypeCode_Object)
  1426. {
  1427. mPassInstance->Warn(0, StrFormat("Types declared as '%s' cannot be 'abstract'", BfTokenToString(typeToken)).c_str(), typeDeclaration->mAbstractSpecifier);
  1428. mCurTypeDef->mIsAbstract = false;
  1429. }
  1430. }
  1431. if (mCurTypeDef->mIsConcrete)
  1432. {
  1433. if (mCurTypeDef->mTypeCode != BfTypeCode_Interface)
  1434. {
  1435. mPassInstance->Warn(0, StrFormat("Types declared as '%s' cannot be 'concrete'", BfTokenToString(typeToken)).c_str(), typeDeclaration->mAbstractSpecifier);
  1436. mCurTypeDef->mIsConcrete = false;
  1437. }
  1438. }
  1439. if (!isAutoCompleteTempType)
  1440. {
  1441. BfTypeDef* prevDef = NULL;
  1442. auto itr = mSystem->mTypeDefs.TryGet(fullName);
  1443. while (itr)
  1444. {
  1445. BfTypeDef* checkTypeDef = *itr;
  1446. if (checkTypeDef->mDefState == BfTypeDef::DefState_Deleted)
  1447. {
  1448. itr.MoveToNextHashMatch();
  1449. continue;
  1450. }
  1451. if ((checkTypeDef->NameEquals(mCurTypeDef)) &&
  1452. (checkTypeDef->mGenericParamDefs.size() == numGenericParams) &&
  1453. (mCurTypeDef->mProject == checkTypeDef->mProject))
  1454. {
  1455. if (checkTypeDef->mIsCombinedPartial)
  1456. {
  1457. // Ignore
  1458. }
  1459. else
  1460. {
  1461. if (checkTypeDef->mDefState == BfTypeDef::DefState_AwaitingNewVersion)
  1462. {
  1463. // We don't allow "new revision" semantics if the 'isExtension' state changes, or
  1464. // if the outer type did not use "new revision" semantics (for isExtension change on itself or other outer type)
  1465. bool isCompatible = (isExtension == (checkTypeDef->mTypeCode == BfTypeCode_Extension)) &&
  1466. (checkTypeDef->mTypeCode == mCurTypeDef->mTypeCode) &&
  1467. (checkTypeDef->mIsDelegate == mCurTypeDef->mIsDelegate) &&
  1468. (checkTypeDef->mIsFunction == mCurTypeDef->mIsFunction) &&
  1469. (checkTypeDef->mOuterType == actualOuterTypeDef);
  1470. if (isCompatible)
  1471. {
  1472. if (prevRevisionTypeDef == NULL)
  1473. {
  1474. prevRevisionTypeDef = checkTypeDef;
  1475. prevDef = checkTypeDef;
  1476. }
  1477. }
  1478. }
  1479. else
  1480. {
  1481. //otherDefinitionTypeDef = prevRevisionTypeDef;
  1482. }
  1483. }
  1484. }
  1485. itr.MoveToNextHashMatch();
  1486. }
  1487. bool doInsertNew = true;
  1488. if (prevRevisionTypeDef != NULL)
  1489. {
  1490. mCurTypeDef->mIsNextRevision = true;
  1491. bfParser->mTypeDefs.Add(prevRevisionTypeDef);
  1492. if (prevRevisionTypeDef->mDefState == BfTypeDef::DefState_AwaitingNewVersion)
  1493. {
  1494. delete prevRevisionTypeDef->mNextRevision;
  1495. prevRevisionTypeDef->mNextRevision = mCurTypeDef;
  1496. BF_ASSERT(mCurTypeDef->mSystem != NULL);
  1497. mCurActualTypeDef = prevRevisionTypeDef;
  1498. doInsertNew = false;
  1499. }
  1500. else
  1501. {
  1502. if (prevRevisionTypeDef->mNextRevision != NULL)
  1503. prevRevisionTypeDef = prevRevisionTypeDef->mNextRevision;
  1504. prevRevisionTypeDef = NULL;
  1505. }
  1506. }
  1507. else
  1508. {
  1509. mSystem->TrackName(mCurTypeDef);
  1510. bfParser->mTypeDefs.Add(mCurTypeDef);
  1511. }
  1512. if (doInsertNew)
  1513. {
  1514. mSystem->mTypeDefs.Add(mCurTypeDef);
  1515. mSystem->mTypeMapVersion++;
  1516. }
  1517. }
  1518. else
  1519. {
  1520. mCurTypeDef->mIsNextRevision = true; // We don't track name
  1521. mResolvePassData->mAutoCompleteTempTypes.push_back(mCurTypeDef);
  1522. }
  1523. // Insert name into there
  1524. mCurTypeDef->mOuterType = actualOuterTypeDef;
  1525. //dottedName = mCurTypeDef->mName;
  1526. if ((outerTypeDef != NULL) && (!isAutoCompleteTempType))
  1527. {
  1528. outerTypeDef->mNestedTypes.push_back(mCurActualTypeDef);
  1529. }
  1530. BfLogSysM("Creating TypeDef %p Hash:%d from TypeDecl: %p Source: %p ResolvePass: %d AutoComplete:%d\n", mCurTypeDef, mSystem->mTypeDefs.GetHash(mCurTypeDef), typeDeclaration,
  1531. typeDeclaration->GetSourceData(), mResolvePassData != NULL, isAutoCompleteTempType);
  1532. int outerGenericSize = 0;
  1533. if (mCurTypeDef->mOuterType != NULL)
  1534. outerGenericSize = (int)mCurTypeDef->mOuterType->mGenericParamDefs.size();
  1535. bool isGeneric = (outerGenericSize != 0) || (typeDeclaration->mGenericParams != NULL);
  1536. ParseGenericParams(typeDeclaration->mGenericParams, typeDeclaration->mGenericConstraintsDeclaration, mCurTypeDef->mGenericParamDefs, &mCurTypeDef->mExternalConstraints, outerGenericSize, isGeneric);
  1537. BF_ASSERT(mCurTypeDef->mNameEx == NULL);
  1538. if (mCurTypeDef->mGenericParamDefs.size() != 0)
  1539. {
  1540. mCurTypeDef->mNameEx = mSystem->GetAtom(StrFormat("%s`%d", mCurTypeDef->mName->mString.mPtr, numGenericParams));
  1541. }
  1542. else
  1543. {
  1544. mCurTypeDef->mNameEx = mCurTypeDef->mName;
  1545. mCurTypeDef->mNameEx->mRefCount++;
  1546. }
  1547. if (!fullName.IsEmpty())
  1548. {
  1549. if (mCurTypeDef->IsGlobalsContainer())
  1550. {
  1551. mCurTypeDef->mFullNameEx.Set(fullName.mParts, fullName.mSize, &mCurTypeDef->mNameEx, 1);
  1552. }
  1553. else
  1554. {
  1555. mCurTypeDef->mFullNameEx = fullName;
  1556. mCurTypeDef->mFullNameEx.mParts[mCurTypeDef->mFullNameEx.mSize - 1] = mCurTypeDef->mNameEx;
  1557. }
  1558. }
  1559. if (auto defineBlock = BfNodeDynCast<BfBlock>(typeDeclaration->mDefineNode))
  1560. {
  1561. for (auto& member : *defineBlock)
  1562. {
  1563. VisitChildNoRef(member);
  1564. }
  1565. }
  1566. else if (auto defineTokenNode = BfNodeDynCast<BfTokenNode>(typeDeclaration->mDefineNode))
  1567. {
  1568. if (defineTokenNode->GetToken() == BfToken_Semicolon)
  1569. {
  1570. mCurTypeDef->mIsOpaque = true;
  1571. }
  1572. }
  1573. FinishTypeDef(mCurTypeDef->mTypeCode == BfTypeCode_Enum);
  1574. // Map methods into the correct index from previous revision
  1575. if (prevRevisionTypeDef != NULL)
  1576. {
  1577. BF_ASSERT(mCurTypeDef->mTypeCode == prevRevisionTypeDef->mTypeCode);
  1578. if ((mCurTypeDef->mFullHash == prevRevisionTypeDef->mFullHash) && (!mFullRefresh))
  1579. {
  1580. BfLogSys(bfParser->mSystem, "DefBuilder deleting typeDef with no changes %p\n", prevRevisionTypeDef);
  1581. prevRevisionTypeDef->mDefState = BfTypeDef::DefState_Defined;
  1582. BF_ASSERT(prevRevisionTypeDef->mNextRevision == mCurTypeDef);
  1583. prevRevisionTypeDef->mNextRevision = NULL;
  1584. delete mCurTypeDef;
  1585. mCurTypeDef = NULL;
  1586. }
  1587. else if (mCurTypeDef->mSignatureHash != prevRevisionTypeDef->mSignatureHash)
  1588. prevRevisionTypeDef->mDefState = BfTypeDef::DefState_Signature_Changed;
  1589. else if (mCurTypeDef->mInlineHash != prevRevisionTypeDef->mInlineHash)
  1590. prevRevisionTypeDef->mDefState = BfTypeDef::DefState_InlinedInternals_Changed;
  1591. else
  1592. prevRevisionTypeDef->mDefState = BfTypeDef::DefState_Internals_Changed;
  1593. }
  1594. // There's a new type with this name...
  1595. if ((prevRevisionTypeDef == NULL) && (!isAutoCompleteTempType))
  1596. {
  1597. mCurTypeDef->mName->mAtomUpdateIdx = ++mSystem->mAtomUpdateIdx;
  1598. }
  1599. }
  1600. void BfDefBuilder::FinishTypeDef(bool wantsToString)
  1601. {
  1602. auto bfSource = mCurTypeDef->mSource;
  1603. bool isAlias = mCurTypeDef->mTypeCode == BfTypeCode_TypeAlias;
  1604. bool hasCtor = false;
  1605. bool needsDefaultCtor = (mCurTypeDef->mTypeCode != BfTypeCode_Interface) && (!mCurTypeDef->mIsStatic) && (!isAlias);
  1606. bool hasDefaultCtor = false;
  1607. bool hasStaticCtor = false;
  1608. bool hasDtor = false;
  1609. bool hasStaticDtor = false;
  1610. bool hasMarkMethod = false;
  1611. bool hasStaticMarkMethod = false;
  1612. bool hasDynamicCastMethod = false;
  1613. bool hasToStringMethod = false;
  1614. bool needsEqualsMethod = ((mCurTypeDef->mTypeCode == BfTypeCode_Struct) || (mCurTypeDef->mTypeCode == BfTypeCode_Enum)) && (!mCurTypeDef->mIsStatic);
  1615. bool hasEqualsMethod = false;
  1616. bool needsStaticInit = false;
  1617. for (int methodIdx = 0; methodIdx < (int)mCurTypeDef->mMethods.size(); methodIdx++)
  1618. {
  1619. auto method = mCurTypeDef->mMethods[methodIdx];
  1620. if (method->mMethodType == BfMethodType_Ctor)
  1621. {
  1622. if (method->mIsStatic)
  1623. {
  1624. if (hasStaticCtor)
  1625. {
  1626. Fail("Only one static constructor is allowed", method->mMethodDeclaration);
  1627. method->mIsStatic = false;
  1628. }
  1629. if (method->mParams.size() != 0)
  1630. {
  1631. Fail("Static constructor cannot declare parameters", method->mMethodDeclaration);
  1632. method->mIsStatic = false;
  1633. }
  1634. if (method->mName == BF_METHODNAME_MARKMEMBERS_STATIC)
  1635. hasStaticMarkMethod = true;
  1636. hasStaticCtor = true;
  1637. }
  1638. else
  1639. {
  1640. hasCtor = true;
  1641. if (method->mParams.size() == 0)
  1642. hasDefaultCtor = true;
  1643. auto ctorDeclaration = (BfConstructorDeclaration*)method->mMethodDeclaration;
  1644. if (method->mHasAppend)
  1645. {
  1646. mCurTypeDef->mHasAppendCtor = true;
  1647. auto methodDef = new BfMethodDef();
  1648. mCurTypeDef->mMethods.Insert(methodIdx + 1, methodDef);
  1649. methodDef->mDeclaringType = mCurTypeDef;
  1650. methodDef->mName = BF_METHODNAME_CALCAPPEND;
  1651. methodDef->mProtection = BfProtection_Public;
  1652. methodDef->mMethodType = BfMethodType_CtorCalcAppend;
  1653. methodDef->mIsMutating = method->mIsMutating;
  1654. methodDef->mMethodDeclaration = method->mMethodDeclaration;
  1655. methodDef->mReturnTypeRef = mSystem->mDirectIntTypeRef;
  1656. methodDef->mIsStatic = true;
  1657. methodDef->mBody = method->mBody;
  1658. for (auto param : method->mParams)
  1659. {
  1660. BfParameterDef* newParam = new BfParameterDef();
  1661. newParam->mName = param->mName;
  1662. newParam->mTypeRef = param->mTypeRef;
  1663. newParam->mMethodGenericParamIdx = param->mMethodGenericParamIdx;
  1664. methodDef->mParams.push_back(newParam);
  1665. }
  1666. // Insert a 'appendIdx'
  1667. BfParameterDef* newParam = new BfParameterDef();
  1668. newParam->mName = "appendIdx";
  1669. newParam->mTypeRef = mSystem->mDirectRefIntTypeRef;
  1670. newParam->mParamKind = BfParamKind_AppendIdx;
  1671. method->mParams.Insert(0, newParam);
  1672. }
  1673. }
  1674. }
  1675. else if (method->mMethodType == BfMethodType_Dtor)
  1676. {
  1677. if (method->mIsStatic)
  1678. {
  1679. if (hasStaticDtor)
  1680. {
  1681. Fail("Only one static constructor is allowed", method->mMethodDeclaration);
  1682. method->mIsStatic = false;
  1683. }
  1684. hasStaticDtor = true;
  1685. }
  1686. else
  1687. {
  1688. if (hasDtor)
  1689. {
  1690. Fail("Only one destructor is allowed", method->mMethodDeclaration);
  1691. method->mIsStatic = false;
  1692. }
  1693. hasDtor = true;
  1694. }
  1695. if (method->mParams.size() != 0)
  1696. Fail("Destructors cannot declare parameters", method->GetMethodDeclaration()->mParams[0]);
  1697. }
  1698. else if (method->mMethodType == BfMethodType_Normal)
  1699. {
  1700. if (method->mIsStatic)
  1701. {
  1702. if (method->mName == BF_METHODNAME_MARKMEMBERS_STATIC)
  1703. hasStaticMarkMethod = true;
  1704. }
  1705. else
  1706. {
  1707. if (method->mName == BF_METHODNAME_MARKMEMBERS)
  1708. hasMarkMethod = true;
  1709. if (method->mName == BF_METHODNAME_DYNAMICCAST)
  1710. hasDynamicCastMethod = true;
  1711. if (method->mName == BF_METHODNAME_TO_STRING)
  1712. hasToStringMethod = true;
  1713. }
  1714. }
  1715. else if ((method->mMethodType == BfMethodType_Operator) &&
  1716. (method->mIsStatic) &&
  1717. (method->mParams.size() == 2))
  1718. {
  1719. if (auto operatorDecl = BfNodeDynCast<BfOperatorDeclaration>(method->mMethodDeclaration))
  1720. {
  1721. if (operatorDecl->mBinOp == BfBinaryOp_Equality)
  1722. {
  1723. // This is a conservative check. It's okay to add a system-defined equals method even if we don't need it.
  1724. if ((method->mParams[0]->mTypeRef->ToString() == mCurTypeDef->mName->ToString()) &&
  1725. (method->mParams[1]->mTypeRef->ToString() == mCurTypeDef->mName->ToString()))
  1726. {
  1727. hasEqualsMethod = true;
  1728. }
  1729. }
  1730. }
  1731. }
  1732. if ((method->mImportKind == BfImportKind_Import_Dynamic) || (method->mImportKind == BfImportKind_Import_Unknown))
  1733. needsStaticInit = true;
  1734. }
  1735. if (mCurTypeDef->IsExtension())
  1736. needsDefaultCtor = false;
  1737. bool needsDtor = false;
  1738. bool needsStaticDtor = false;
  1739. bool hasStaticField = false;
  1740. bool hasNonStaticField = false;
  1741. bool hasThreadStatics = false;
  1742. for (auto field : mCurTypeDef->mFields)
  1743. {
  1744. if (field->mIsStatic)
  1745. {
  1746. // Resolve-only compiler wants to visit const initializers in a static ctor method, but we don't
  1747. // want to create it for the actual binary
  1748. if ((!field->mIsConst) || (mSystem->mIsResolveOnly))
  1749. {
  1750. hasStaticField = true;
  1751. if (field->mFieldDeclaration != NULL)
  1752. {
  1753. if (field->mFieldDeclaration->mInitializer != NULL)
  1754. {
  1755. needsStaticInit = true;
  1756. }
  1757. if (field->mFieldDeclaration->mFieldDtor != NULL)
  1758. needsStaticDtor = true;
  1759. }
  1760. }
  1761. if (field->mFieldDeclaration != NULL)
  1762. {
  1763. auto attributes = field->mFieldDeclaration->mAttributes;
  1764. while (attributes != NULL)
  1765. {
  1766. if (attributes->mAttributeTypeRef != NULL)
  1767. {
  1768. auto typeRefName = attributes->mAttributeTypeRef->ToString();
  1769. if (typeRefName == "ThreadStatic")
  1770. hasThreadStatics = true;
  1771. }
  1772. attributes = attributes->mNextAttribute;
  1773. }
  1774. }
  1775. }
  1776. else
  1777. {
  1778. hasNonStaticField = true;
  1779. if (field->mInitializer != NULL)
  1780. needsDefaultCtor = true;
  1781. if ((field->mFieldDeclaration != NULL) && (field->mFieldDeclaration->mFieldDtor != NULL))
  1782. needsDtor = true;
  1783. }
  1784. }
  1785. bool needsDynamicCastMethod = !hasDynamicCastMethod;
  1786. if (mCurTypeDef->mIsFunction)
  1787. {
  1788. wantsToString = false;
  1789. needsEqualsMethod = false;
  1790. needsDefaultCtor = false;
  1791. needsDynamicCastMethod = false;
  1792. }
  1793. if ((mCurTypeDef->mTypeCode == BfTypeCode_Object) && (!mCurTypeDef->mIsStatic))
  1794. {
  1795. auto methodDef = AddMethod(mCurTypeDef, BfMethodType_CtorClear, BfProtection_Private, false, "");
  1796. methodDef->mIsMutating = true;
  1797. }
  1798. if ((needsDtor) && (!hasDtor))
  1799. {
  1800. auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Dtor, BfProtection_Public, false, "");
  1801. BF_ASSERT(mCurTypeDef->mDtorDef == methodDef);
  1802. }
  1803. if ((needsStaticDtor) && (!hasStaticDtor))
  1804. {
  1805. auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Dtor, BfProtection_Public, true, "");
  1806. }
  1807. if ((needsStaticInit) && (!hasStaticCtor))
  1808. {
  1809. auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Ctor, BfProtection_Public, true, "");
  1810. }
  1811. bool makeCtorPrivate = hasCtor;
  1812. if (mCurTypeDef->mTypeCode == BfTypeCode_TypeAlias)
  1813. needsDefaultCtor = false;
  1814. if (mCurTypeDef->mTypeCode == BfTypeCode_Extension)
  1815. needsDefaultCtor = false;
  1816. if ((needsDefaultCtor) && ((!hasDefaultCtor)))
  1817. {
  1818. BfProtection prot = hasCtor ? BfProtection_Hidden : BfProtection_Public;
  1819. if (mCurTypeDef->mName == mSystem->mEmptyAtom)
  1820. prot = BfProtection_Hidden;
  1821. // Create default constructor. If it's the only constructor then make it public,
  1822. // otherwise make it private so we can still internally use it but the user can't
  1823. auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Ctor, prot, false, "");
  1824. methodDef->mIsMutating = true;
  1825. }
  1826. bool isAutocomplete = false;
  1827. if ((mResolvePassData != NULL) && (mResolvePassData->mAutoComplete != NULL))
  1828. isAutocomplete = true;
  1829. //TODO: Don't do this for the autocomplete pass
  1830. if ((needsDynamicCastMethod) && (mCurTypeDef->mTypeCode != BfTypeCode_Interface) && (mCurTypeDef->mTypeCode != BfTypeCode_Extension) &&
  1831. (!mCurTypeDef->mIsStatic) && (!isAutocomplete) && (!isAlias))
  1832. {
  1833. AddDynamicCastMethods(mCurTypeDef);
  1834. }
  1835. bool isPayloadEnum = false;
  1836. if (mCurTypeDef->mTypeCode == BfTypeCode_Enum)
  1837. {
  1838. for (auto fieldDef : mCurTypeDef->mFields)
  1839. {
  1840. if (auto enumEntryDecl = BfNodeDynCast<BfEnumEntryDeclaration>(fieldDef->mFieldDeclaration))
  1841. {
  1842. if (enumEntryDecl->mTypeRef != NULL)
  1843. isPayloadEnum = true;
  1844. }
  1845. }
  1846. }
  1847. if (isPayloadEnum)
  1848. hasNonStaticField = true;
  1849. if (mCurTypeDef->mTypeCode != BfTypeCode_Interface)
  1850. {
  1851. if ((hasStaticField) && (!hasStaticMarkMethod))
  1852. {
  1853. auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Normal, BfProtection_Protected, true, BF_METHODNAME_MARKMEMBERS_STATIC);
  1854. methodDef->mIsNoReflect = true;
  1855. }
  1856. if (hasThreadStatics)
  1857. {
  1858. auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Normal, BfProtection_Protected, true, BF_METHODNAME_FIND_TLS_MEMBERS);
  1859. methodDef->mIsNoReflect = true;
  1860. }
  1861. if ((hasNonStaticField) && (!hasMarkMethod))
  1862. {
  1863. auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Normal, BfProtection_Protected, false, BF_METHODNAME_MARKMEMBERS);
  1864. methodDef->mIsVirtual = true;
  1865. methodDef->mIsOverride = true;
  1866. methodDef->mIsNoReflect = true;
  1867. methodDef->mCallingConvention = BfCallingConvention_Cdecl;
  1868. mCurTypeDef->mHasOverrideMethods = true;
  1869. }
  1870. }
  1871. if (hasToStringMethod)
  1872. wantsToString = false;
  1873. if ((mCurTypeDef->mTypeCode == BfTypeCode_Enum) && (!isPayloadEnum))
  1874. {
  1875. auto methodDef = new BfMethodDef();
  1876. mCurTypeDef->mMethods.push_back(methodDef);
  1877. methodDef->mDeclaringType = mCurTypeDef;
  1878. methodDef->mName = BF_METHODNAME_ENUM_HASFLAG;
  1879. methodDef->mReturnTypeRef = mSystem->mDirectBoolTypeRef;
  1880. methodDef->mProtection = BfProtection_Public;
  1881. AddParam(methodDef, mSystem->mDirectSelfTypeRef, "checkEnum");
  1882. // Underlying
  1883. {
  1884. auto methodDef = new BfMethodDef();
  1885. mCurTypeDef->mMethods.push_back(methodDef);
  1886. methodDef->mDeclaringType = mCurTypeDef;
  1887. methodDef->mName = BF_METHODNAME_ENUM_GETUNDERLYING;
  1888. methodDef->mReturnTypeRef = mSystem->mDirectSelfBaseTypeRef;
  1889. methodDef->mMethodType = BfMethodType_PropertyGetter;
  1890. methodDef->mProtection = BfProtection_Public;
  1891. auto propDef = new BfPropertyDef();
  1892. mCurTypeDef->mProperties.Add(propDef);
  1893. propDef->mTypeRef = mSystem->mDirectSelfBaseTypeRef;
  1894. propDef->mDeclaringType = mCurTypeDef;
  1895. propDef->mName = "Underlying";
  1896. propDef->mMethods.Add(methodDef);
  1897. propDef->mProtection = BfProtection_Public;
  1898. }
  1899. // UnderlyingRef
  1900. {
  1901. auto methodDef = new BfMethodDef();
  1902. mCurTypeDef->mMethods.push_back(methodDef);
  1903. methodDef->mDeclaringType = mCurTypeDef;
  1904. methodDef->mIsMutating = true;
  1905. methodDef->mName = BF_METHODNAME_ENUM_GETUNDERLYINGREF;
  1906. methodDef->mReturnTypeRef = mSystem->mDirectRefSelfBaseTypeRef;
  1907. methodDef->mMethodType = BfMethodType_PropertyGetter;
  1908. methodDef->mProtection = BfProtection_Public;
  1909. auto propDef = new BfPropertyDef();
  1910. mCurTypeDef->mProperties.Add(propDef);
  1911. propDef->mTypeRef = mSystem->mDirectRefSelfBaseTypeRef;
  1912. propDef->mDeclaringType = mCurTypeDef;
  1913. propDef->mName = "UnderlyingRef";
  1914. propDef->mMethods.Add(methodDef);
  1915. propDef->mProtection = BfProtection_Public;
  1916. }
  1917. }
  1918. if (wantsToString)
  1919. {
  1920. auto methodDef = new BfMethodDef();
  1921. mCurTypeDef->mMethods.push_back(methodDef);
  1922. methodDef->mDeclaringType = mCurTypeDef;
  1923. methodDef->mName = BF_METHODNAME_TO_STRING;
  1924. methodDef->mReturnTypeRef = mSystem->mDirectVoidTypeRef;
  1925. methodDef->mProtection = BfProtection_Public;
  1926. methodDef->mIsOverride = true;
  1927. methodDef->mIsVirtual = true;
  1928. AddParam(methodDef, mSystem->mDirectStringTypeRef, "outStr");
  1929. mCurTypeDef->mHasOverrideMethods = true;
  1930. }
  1931. if ((needsEqualsMethod) && (!hasEqualsMethod))
  1932. {
  1933. auto methodDef = new BfMethodDef();
  1934. mCurTypeDef->mMethods.push_back(methodDef);
  1935. methodDef->mDeclaringType = mCurTypeDef;
  1936. methodDef->mName = BF_METHODNAME_DEFAULT_EQUALS;
  1937. methodDef->mReturnTypeRef = mSystem->mDirectBoolTypeRef;
  1938. methodDef->mProtection = BfProtection_Private;
  1939. methodDef->mIsStatic = true;
  1940. AddParam(methodDef, mSystem->mDirectSelfTypeRef, "lhs");
  1941. AddParam(methodDef, mSystem->mDirectSelfTypeRef, "rhs");
  1942. }
  1943. if (needsEqualsMethod)
  1944. {
  1945. auto methodDef = new BfMethodDef();
  1946. mCurTypeDef->mMethods.push_back(methodDef);
  1947. methodDef->mDeclaringType = mCurTypeDef;
  1948. methodDef->mName = BF_METHODNAME_DEFAULT_STRICT_EQUALS;
  1949. methodDef->mReturnTypeRef = mSystem->mDirectBoolTypeRef;
  1950. methodDef->mProtection = BfProtection_Private;
  1951. methodDef->mIsStatic = true;
  1952. AddParam(methodDef, mSystem->mDirectSelfTypeRef, "lhs");
  1953. AddParam(methodDef, mSystem->mDirectSelfTypeRef, "rhs");
  1954. }
  1955. HashContext inlineHashCtx;
  1956. if (mCurSource != NULL)
  1957. {
  1958. auto bfParser = mCurSource->ToParser();
  1959. if (bfParser != NULL)
  1960. inlineHashCtx.MixinStr(bfParser->mFileName);
  1961. }
  1962. //for (auto methodDef : mCurTypeDef->mMethods)
  1963. for (int methodIdx = 0; methodIdx < (int)mCurTypeDef->mMethods.size(); methodIdx++)
  1964. {
  1965. // Add in name so the hand-created methods can be compared by hash
  1966. auto methodDef = mCurTypeDef->mMethods[methodIdx];
  1967. methodDef->mIdx = methodIdx;
  1968. methodDef->mFullHash = HashString(methodDef->mName, methodDef->mFullHash);
  1969. if (mSignatureHashCtx != NULL)
  1970. mSignatureHashCtx->MixinStr(methodDef->mName);
  1971. if ((methodDef->mAlwaysInline) ||
  1972. (methodDef->mHasAppend) ||
  1973. (methodDef->mMethodType == BfMethodType_Mixin))
  1974. inlineHashCtx.Mixin(methodDef->mFullHash);
  1975. if (mFullRefresh)
  1976. methodDef->mCodeChanged = true;
  1977. }
  1978. mCurTypeDef->mInlineHash = inlineHashCtx.Finish128();
  1979. if (mSignatureHashCtx != NULL)
  1980. {
  1981. mCurTypeDef->mSignatureHash = mSignatureHashCtx->Finish128();
  1982. // We need to hash the signature in here because the preprocessor settings
  1983. // may change so the text is the same but the signature changes
  1984. // so fullHash needs to change too
  1985. mFullHashCtx->Mixin(mCurTypeDef->mSignatureHash);
  1986. }
  1987. if (mFullHashCtx != NULL)
  1988. mCurTypeDef->mFullHash = mFullHashCtx->Finish128();
  1989. }
  1990. void BfDefBuilder::Visit(BfUsingDirective* usingDirective)
  1991. {
  1992. if (usingDirective->mNamespace == NULL)
  1993. {
  1994. BF_ASSERT(mPassInstance->HasFailed());
  1995. return;
  1996. }
  1997. if (mResolvePassData != NULL)
  1998. mResolvePassData->mExteriorAutocompleteCheckNodes.push_back(usingDirective);
  1999. String usingString = usingDirective->mNamespace->ToString();
  2000. BfAtomComposite usingComposite;
  2001. mSystem->ParseAtomComposite(usingString, usingComposite, true);
  2002. if (!mNamespaceSearch.Contains(usingComposite))
  2003. mNamespaceSearch.Insert(0, usingComposite);
  2004. else
  2005. mSystem->ReleaseAtomComposite(usingComposite);
  2006. }
  2007. void BfDefBuilder::Visit(BfUsingModDirective* usingDirective)
  2008. {
  2009. if (mResolvePassData != NULL)
  2010. mResolvePassData->mExteriorAutocompleteCheckNodes.push_back(usingDirective);
  2011. if (usingDirective->mModToken->mToken == BfToken_Internal)
  2012. {
  2013. if (usingDirective->mTypeRef != NULL)
  2014. mInternalAccessSet.Add(usingDirective->mTypeRef);
  2015. }
  2016. else if (usingDirective->mTypeRef != NULL)
  2017. mStaticSearch.Add(usingDirective->mTypeRef);
  2018. }
  2019. void BfDefBuilder::Visit(BfNamespaceDeclaration* namespaceDeclaration)
  2020. {
  2021. BfAtomComposite prevNamespace = mNamespace;
  2022. int prevNamespaceSearchCount = (int)mNamespaceSearch.size();
  2023. if (namespaceDeclaration->mNameNode == NULL)
  2024. return;
  2025. String namespaceLeft = namespaceDeclaration->mNameNode->ToString();
  2026. while (true)
  2027. {
  2028. int dotIdx = (int)namespaceLeft.IndexOf('.');
  2029. if (dotIdx == -1)
  2030. {
  2031. BfAtom* namespaceAtom = mSystem->GetAtom(namespaceLeft);
  2032. mNamespace.Set(mNamespace.mParts, mNamespace.mSize, &namespaceAtom, 1);
  2033. if (!mNamespaceSearch.Contains(mNamespace))
  2034. {
  2035. mSystem->RefAtomComposite(mNamespace);
  2036. mNamespaceSearch.Insert(0, mNamespace);
  2037. }
  2038. mSystem->ReleaseAtom(namespaceAtom);
  2039. break;
  2040. }
  2041. BfAtom* namespaceAtom = mSystem->GetAtom(namespaceLeft.Substring(0, dotIdx));
  2042. mNamespace.Set(mNamespace.mParts, mNamespace.mSize, &namespaceAtom, 1);
  2043. namespaceLeft = namespaceLeft.Substring(dotIdx + 1);
  2044. if (!mNamespaceSearch.Contains(mNamespace))
  2045. {
  2046. mSystem->RefAtomComposite(mNamespace);
  2047. mNamespaceSearch.Insert(0, mNamespace);
  2048. }
  2049. mSystem->ReleaseAtom(namespaceAtom);
  2050. }
  2051. VisitChild(namespaceDeclaration->mBlock);
  2052. while ((int)mNamespaceSearch.size() > prevNamespaceSearchCount)
  2053. {
  2054. BfAtomComposite& atomComposite = mNamespaceSearch[0];
  2055. mSystem->ReleaseAtomComposite(atomComposite);
  2056. mNamespaceSearch.RemoveAt(0);
  2057. }
  2058. mNamespace = prevNamespace;
  2059. }
  2060. void BfDefBuilder::Visit(BfBlock* block)
  2061. {
  2062. VisitMembers(block);
  2063. }
  2064. void BfDefBuilder::Visit(BfRootNode* rootNode)
  2065. {
  2066. VisitMembers(rootNode);
  2067. }