BfDefBuilder.cpp 86 KB

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