BfDefBuilder.cpp 88 KB

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