BfAutoComplete.cpp 68 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338
  1. #include "BfAutoComplete.h"
  2. #include "BfParser.h"
  3. #include "BfExprEvaluator.h"
  4. #include "BfSourceClassifier.h"
  5. #include "BfResolvePass.h"
  6. #include "BfFixits.h"
  7. #pragma warning(disable:4996)
  8. using namespace llvm;
  9. USING_NS_BF;
  10. AutoCompleteBase::AutoCompleteBase()
  11. {
  12. mIsGetDefinition = false;
  13. mIsAutoComplete = true;
  14. mInsertStartIdx = -1;
  15. mInsertEndIdx = -1;
  16. }
  17. AutoCompleteBase::~AutoCompleteBase()
  18. {
  19. Clear();
  20. }
  21. AutoCompleteEntry* AutoCompleteBase::AddEntry(const AutoCompleteEntry& entry, const StringImpl& filter)
  22. {
  23. if (!DoesFilterMatch(entry.mDisplay, filter.c_str()))
  24. return NULL;
  25. return AddEntry(entry);
  26. }
  27. AutoCompleteEntry* AutoCompleteBase::AddEntry(const AutoCompleteEntry& entry)
  28. {
  29. if (mEntriesSet.mAllocSize == 0)
  30. {
  31. mEntriesSet.Reserve(128);
  32. }
  33. AutoCompleteEntry* insertedEntry = NULL;
  34. if (mEntriesSet.TryAdd(entry, &insertedEntry))
  35. {
  36. insertedEntry->mEntryType = entry.mEntryType;
  37. int size = (int)strlen(entry.mDisplay) + 1;
  38. insertedEntry->mDisplay = (char*)mAlloc.AllocBytes(size);
  39. memcpy((char*)insertedEntry->mDisplay, entry.mDisplay, size);
  40. }
  41. return insertedEntry;
  42. }
  43. bool AutoCompleteBase::DoesFilterMatch(const char* entry, const char* filter)
  44. {
  45. if (mIsGetDefinition)
  46. {
  47. int entryLen = (int)strlen(entry);
  48. if (entry[entryLen - 1] == '=')
  49. return (strncmp(filter, entry, entryLen - 1) == 0);
  50. return (strcmp(filter, entry) == 0);
  51. }
  52. if (!mIsAutoComplete)
  53. return false;
  54. if (filter[0] == 0)
  55. return true;
  56. int filterLen = (int)strlen(filter);
  57. int entryLen = (int)strlen(entry);
  58. bool hasUnderscore = false;
  59. bool checkInitials = filterLen > 1;
  60. for (int i = 0; i < (int)filterLen; i++)
  61. {
  62. char c = filter[i];
  63. if (c == '_')
  64. hasUnderscore = true;
  65. else if (islower((uint8)filter[i]))
  66. checkInitials = false;
  67. }
  68. if (hasUnderscore)
  69. return strnicmp(filter, entry, filterLen) == 0;
  70. char initialStr[256];
  71. char* initialStrP = initialStr;
  72. //String initialStr;
  73. bool prevWasUnderscore = false;
  74. for (int entryIdx = 0; entryIdx < entryLen; entryIdx++)
  75. {
  76. char entryC = entry[entryIdx];
  77. if (entryC == '_')
  78. {
  79. prevWasUnderscore = true;
  80. continue;
  81. }
  82. if ((entryIdx == 0) || (prevWasUnderscore) || (isupper((uint8)entryC) || (isdigit((uint8)entryC))))
  83. {
  84. if (strnicmp(filter, entry + entryIdx, filterLen) == 0)
  85. return true;
  86. if (checkInitials)
  87. *(initialStrP++) = entryC;
  88. }
  89. prevWasUnderscore = false;
  90. if (filterLen == 1)
  91. break; // Don't check inners for single-character case
  92. }
  93. if (!checkInitials)
  94. return false;
  95. *(initialStrP++) = 0;
  96. return strnicmp(filter, initialStr, filterLen) == 0;
  97. }
  98. void AutoCompleteBase::Clear()
  99. {
  100. //mEntries.clear();
  101. mAlloc.Clear();
  102. mEntriesSet.Clear();
  103. }
  104. //////////////////////////////////////////////////////////////////////////
  105. BfAutoComplete::BfAutoComplete(BfResolveType resolveType)
  106. {
  107. mResolveType = resolveType;
  108. mModule = NULL;
  109. mCompiler = NULL;
  110. mSystem = NULL;
  111. mIsCapturingMethodMatchInfo = false;
  112. mIgnoreFixits = false;
  113. mHasFriendSet = false;
  114. mUncertain = false;
  115. mMethodMatchInfo = NULL;
  116. mIsGetDefinition =
  117. (resolveType == BfResolveType_GetSymbolInfo) ||
  118. (resolveType == BfResolveType_GoToDefinition);
  119. mIsAutoComplete = (resolveType == BfResolveType_Autocomplete);
  120. mGetDefinitionNode = NULL;
  121. mShowAttributeProperties = NULL;
  122. mIdentifierUsed = NULL;
  123. //mReplaceMethodInstance = NULL;
  124. mReplaceLocalId = -1;
  125. mDefType = NULL;
  126. mDefField = NULL;
  127. mDefMethod = NULL;
  128. mDefProp = NULL;
  129. mDefMethodGenericParamIdx = -1;
  130. mDefTypeGenericParamIdx = -1;
  131. mCursorLineStart = -1;
  132. mCursorLineEnd = -1;
  133. }
  134. BfAutoComplete::~BfAutoComplete()
  135. {
  136. Clear();
  137. }
  138. void BfAutoComplete::SetModule(BfModule* module)
  139. {
  140. mModule = module;
  141. mCompiler = mModule->mCompiler;
  142. mSystem = mCompiler->mSystem;
  143. }
  144. void BfAutoComplete::Clear()
  145. {
  146. if (mMethodMatchInfo != NULL)
  147. {
  148. if (mMethodMatchInfo->mInstanceList.size() == 0)
  149. {
  150. delete mMethodMatchInfo;
  151. mMethodMatchInfo = NULL;
  152. }
  153. else
  154. {
  155. // Keep mBestIdx - for when we match but then backspace
  156. mMethodMatchInfo->mPrevBestIdx = mMethodMatchInfo->mBestIdx;
  157. mMethodMatchInfo->mMostParamsMatched = 0;
  158. mMethodMatchInfo->mHadExactMatch = false;
  159. mMethodMatchInfo->mInstanceList.Clear();
  160. mMethodMatchInfo->mSrcPositions.Clear();
  161. }
  162. }
  163. mInsertStartIdx = -1;
  164. mInsertEndIdx = -1;
  165. mIsCapturingMethodMatchInfo = false;
  166. AutoCompleteBase::Clear();
  167. }
  168. void BfAutoComplete::RemoveMethodMatchInfo()
  169. {
  170. mIsCapturingMethodMatchInfo = false;
  171. delete mMethodMatchInfo;
  172. mMethodMatchInfo = NULL;
  173. }
  174. void BfAutoComplete::ClearMethodMatchEntries()
  175. {
  176. mMethodMatchInfo->mInstanceList.Clear();
  177. }
  178. int BfAutoComplete::GetCursorIdx(BfAstNode* node)
  179. {
  180. if (node == NULL)
  181. return -1;
  182. if ((!mCompiler->mIsResolveOnly) || (!node->IsFromParser(mCompiler->mResolvePassData->mParser)))
  183. return -1;
  184. auto bfParser = node->GetSourceData()->ToParser();
  185. if ((bfParser->mParserFlags & ParserFlag_Autocomplete) == 0)
  186. return -1;
  187. return bfParser->mCursorIdx;
  188. }
  189. bool BfAutoComplete::IsAutocompleteNode(BfAstNode* node, int lengthAdd, int startAdd)
  190. {
  191. if (node == NULL)
  192. return false;
  193. if ((!mCompiler->mIsResolveOnly) || (!node->IsFromParser(mCompiler->mResolvePassData->mParser)))
  194. return false;
  195. auto bfParser = node->GetSourceData()->ToParser();
  196. if ((bfParser->mParserFlags & ParserFlag_Autocomplete) == 0)
  197. return false;
  198. //if (mCompiler->mResolvePassData->mResolveType != BfResolveType_Autocomplete)
  199. lengthAdd++;
  200. int cursorIdx = bfParser->mCursorCheckIdx;
  201. int nodeSrcStart = node->GetSrcStart();
  202. if ((cursorIdx < nodeSrcStart + startAdd) || (cursorIdx >= node->GetSrcEnd() + lengthAdd))
  203. return false;
  204. return true;
  205. }
  206. bool BfAutoComplete::IsAutocompleteNode(BfAstNode* startNode, BfAstNode* endNode, int lengthAdd, int startAdd)
  207. {
  208. if ((startNode == NULL) || (endNode == NULL))
  209. return false;
  210. if ((!mCompiler->mIsResolveOnly) || (!startNode->IsFromParser(mCompiler->mResolvePassData->mParser)))
  211. return false;
  212. auto bfParser = startNode->GetSourceData()->ToParser();
  213. if ((bfParser->mParserFlags & ParserFlag_Autocomplete) == 0)
  214. return false;
  215. //if (mCompiler->mResolvePassData->mResolveType != BfResolveType_Autocomplete)
  216. lengthAdd++;
  217. int cursorIdx = bfParser->mCursorCheckIdx;
  218. int nodeSrcStart = startNode->GetSrcStart();
  219. if ((cursorIdx < nodeSrcStart + startAdd) || (cursorIdx >= endNode->GetSrcEnd() + lengthAdd))
  220. return false;
  221. return true;
  222. }
  223. bool BfAutoComplete::IsAutocompleteLineNode(BfAstNode* node)
  224. {
  225. if (node == NULL)
  226. return false;
  227. if ((!mCompiler->mIsResolveOnly) || (!node->IsFromParser(mCompiler->mResolvePassData->mParser)))
  228. return false;
  229. auto bfParser = node->GetSourceData()->ToParser();
  230. if ((bfParser->mParserFlags & ParserFlag_Autocomplete) == 0)
  231. return false;
  232. int startAdd = 0;
  233. if (mCursorLineStart == -1)
  234. {
  235. auto nodeSource = node->GetSourceData();
  236. mCursorLineStart = bfParser->mCursorIdx;
  237. while (mCursorLineStart > 0)
  238. {
  239. if (nodeSource->mSrc[mCursorLineStart - 1] == '\n')
  240. break;
  241. mCursorLineStart--;
  242. }
  243. mCursorLineEnd = bfParser->mCursorIdx;
  244. while (mCursorLineEnd < nodeSource->mSrcLength)
  245. {
  246. if (nodeSource->mSrc[mCursorLineEnd] == '\n')
  247. break;
  248. mCursorLineEnd++;
  249. }
  250. }
  251. int srcStart = node->GetSrcStart();
  252. return (srcStart >= mCursorLineStart) && (srcStart <= mCursorLineEnd);
  253. }
  254. // The parser thought this was a type reference but it may not be
  255. BfTypedValue BfAutoComplete::LookupTypeRefOrIdentifier(BfAstNode* node, bool* isStatic, BfEvalExprFlags evalExprFlags, BfType* expectingType)
  256. {
  257. SetAndRestoreValue<bool> prevIgnoreClassifying(mModule->mIsInsideAutoComplete, true);
  258. if (auto typeRef = BfNodeDynCast<BfTypeReference>(node))
  259. {
  260. auto type = mModule->ResolveTypeRef(typeRef);
  261. if (type != NULL)
  262. {
  263. *isStatic = true;
  264. return BfTypedValue(type);
  265. }
  266. if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(typeRef))
  267. {
  268. BfExprEvaluator exprEvaluator(mModule);
  269. auto identifierResult = exprEvaluator.LookupIdentifier(namedTypeRef->mNameNode);
  270. if (identifierResult)
  271. return identifierResult;
  272. return exprEvaluator.GetResult(); // We need 'GetResult' to read property values
  273. }
  274. else if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef))
  275. {
  276. auto leftValue = LookupTypeRefOrIdentifier(qualifiedTypeRef->mLeft, isStatic);
  277. if (leftValue.mType)
  278. {
  279. if (leftValue.mType->IsPointer())
  280. {
  281. mModule->LoadValue(leftValue);
  282. leftValue.mType = leftValue.mType->GetUnderlyingType();
  283. leftValue.mKind = BfTypedValueKind_Addr;
  284. }
  285. if (auto rightNamedTypeRef = BfNodeDynCast<BfNamedTypeReference>(qualifiedTypeRef->mRight))
  286. {
  287. // This keeps the classifier from colorizing properties - this causes 'flashing' when we go back over this with a resolve pass
  288. // that wouldn't catch this
  289. SetAndRestoreValue<BfSourceClassifier*> prevClassifier(mModule->mCompiler->mResolvePassData->mSourceClassifier, NULL);
  290. BfExprEvaluator exprEvaluator(mModule);
  291. auto fieldResult = exprEvaluator.LookupField(qualifiedTypeRef->mRight, leftValue, rightNamedTypeRef->mNameNode->ToString());
  292. if (!fieldResult) // Was property?
  293. fieldResult = exprEvaluator.GetResult();
  294. *isStatic = false;
  295. return fieldResult;
  296. }
  297. }
  298. }
  299. }
  300. if (auto identifier = BfNodeDynCast<BfIdentifierNode>(node))
  301. {
  302. BfExprEvaluator exprEvaluator(mModule);
  303. auto identifierResult = exprEvaluator.LookupIdentifier(identifier, false, NULL);
  304. if (!identifierResult)
  305. identifierResult = exprEvaluator.GetResult();
  306. if (identifierResult)
  307. return identifierResult;
  308. if (auto qualifiedIdentifier = BfNodeDynCast<BfQualifiedNameNode>(node))
  309. {
  310. bool leftIsStatic = false;
  311. auto leftValue = LookupTypeRefOrIdentifier(qualifiedIdentifier->mLeft, &leftIsStatic);
  312. if (leftValue.mType)
  313. {
  314. auto findName = qualifiedIdentifier->mRight->ToString();
  315. if (findName == "base")
  316. {
  317. return BfTypedValue(leftValue);
  318. }
  319. BfExprEvaluator exprEvaluator(mModule);
  320. auto fieldResult = exprEvaluator.LookupField(node, leftValue, findName);
  321. if (fieldResult)
  322. return fieldResult;
  323. auto result = exprEvaluator.GetResult();
  324. if (result)
  325. return result;
  326. }
  327. }
  328. auto type = mModule->ResolveTypeRef(identifier, NULL);
  329. if (type != NULL)
  330. {
  331. *isStatic = true;
  332. return BfTypedValue(type);
  333. }
  334. }
  335. else if (auto memberRefExpr = BfNodeDynCast<BfMemberReferenceExpression>(node))
  336. {
  337. return mModule->CreateValueFromExpression(memberRefExpr, expectingType, evalExprFlags);
  338. }
  339. else if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(node))
  340. {
  341. // Don't pass BfEvalExprFlags_IgnoreNullConditional, since parenExprs end nullable chains and we actually
  342. // DO want the nullable at this point
  343. return mModule->CreateValueFromExpression(parenExpr);
  344. }
  345. else if (auto targetExpr = BfNodeDynCast<BfExpression>(node))
  346. {
  347. return mModule->CreateValueFromExpression(targetExpr, NULL, evalExprFlags);
  348. }
  349. return BfTypedValue();
  350. }
  351. void BfAutoComplete::SetDefinitionLocation(BfAstNode* astNode, bool force)
  352. {
  353. if (mIsGetDefinition)
  354. {
  355. if ((mGetDefinitionNode == NULL) || (force))
  356. mGetDefinitionNode = astNode;
  357. }
  358. }
  359. bool BfAutoComplete::IsAttribute(BfTypeInstance* typeInst)
  360. {
  361. auto checkTypeInst = typeInst;
  362. while (checkTypeInst != NULL)
  363. {
  364. if (checkTypeInst->mTypeDef == mModule->mCompiler->mAttributeTypeDef)
  365. return true;
  366. checkTypeInst = checkTypeInst->mBaseType;
  367. }
  368. return false;
  369. }
  370. void BfAutoComplete::AddMethod(BfMethodDeclaration* methodDecl, const StringImpl& methodName, const StringImpl& filter)
  371. {
  372. String replaceName;
  373. AutoCompleteEntry entry("method", methodName);
  374. if (methodDecl != NULL)
  375. {
  376. if (methodDecl->mMixinSpecifier != NULL)
  377. {
  378. replaceName = entry.mDisplay;
  379. replaceName += "!";
  380. entry.mDisplay = replaceName.c_str();
  381. entry.mEntryType = "mixin";
  382. }
  383. entry.mDocumentation = methodDecl->mDocumentation;
  384. }
  385. AddEntry(entry, filter);
  386. }
  387. void BfAutoComplete::AddTypeDef(BfTypeDef* typeDef, const StringImpl& filter, bool onlyAttribute)
  388. {
  389. StringT<64> name(typeDef->mName->ToString());
  390. if (name == "@")
  391. return;
  392. int gravePos = (int)name.IndexOf('`');
  393. if (gravePos != -1)
  394. name = name.Substring(0, gravePos) + "<>";
  395. if (onlyAttribute)
  396. {
  397. if ((mIsGetDefinition) && (name == filter + "Attribute"))
  398. {
  399. SetDefinitionLocation(typeDef->mTypeDeclaration->mNameNode);
  400. return;
  401. }
  402. if (!DoesFilterMatch(name.c_str(), filter.c_str()))
  403. return;
  404. auto type = mModule->ResolveTypeDef(typeDef, BfPopulateType_Declaration);
  405. if (type != NULL)
  406. {
  407. auto typeInst = type->ToTypeInstance();
  408. if (!IsAttribute(typeInst))
  409. return;
  410. }
  411. const char* attrStr = "Attribute";
  412. const int attrStrLen = (int)strlen(attrStr);
  413. if (((int)name.length() > attrStrLen) && ((int)name.length() - (int)attrStrLen >= filter.length()) && (strcmp(name.c_str() + (int)name.length() - attrStrLen, attrStr) == 0))
  414. {
  415. // Shorter name - remove "Attribute"
  416. name = name.Substring(0, name.length() - attrStrLen);
  417. }
  418. }
  419. AutoCompleteEntry* entryAdded = NULL;
  420. if (typeDef->mTypeCode == BfTypeCode_Object)
  421. entryAdded = AddEntry(AutoCompleteEntry("class", name, typeDef->mTypeDeclaration->mDocumentation), filter);
  422. else if (typeDef->mTypeCode == BfTypeCode_Interface)
  423. entryAdded = AddEntry(AutoCompleteEntry("interface", name, typeDef->mTypeDeclaration->mDocumentation), filter);
  424. else
  425. entryAdded = AddEntry(AutoCompleteEntry("valuetype", name, typeDef->mTypeDeclaration->mDocumentation), filter);
  426. if ((entryAdded != NULL) && (mIsGetDefinition))
  427. {
  428. }
  429. }
  430. bool BfAutoComplete::CheckProtection(BfProtection protection, bool allowProtected, bool allowPrivate)
  431. {
  432. return (mHasFriendSet) || (protection == BfProtection_Public) ||
  433. ((protection == BfProtection_Protected) && (allowProtected)) ||
  434. ((protection == BfProtection_Private) && (allowPrivate));
  435. }
  436. const char* BfAutoComplete::GetTypeName(BfType* type)
  437. {
  438. if (type != NULL)
  439. {
  440. if (type->IsPointer())
  441. return "pointer";
  442. if (type->IsObjectOrInterface())
  443. return "object";
  444. }
  445. return "value";
  446. }
  447. void BfAutoComplete::AddInnerTypes(BfTypeInstance* typeInst, const StringImpl& filter, bool allowProtected, bool allowPrivate)
  448. {
  449. for (auto innerType : typeInst->mTypeDef->mNestedTypes)
  450. {
  451. if (CheckProtection(innerType->mProtection, allowProtected, allowPrivate))
  452. AddTypeDef(innerType, filter);
  453. }
  454. allowPrivate = false;
  455. if (typeInst->mBaseType != NULL)
  456. AddInnerTypes(typeInst->mBaseType, filter, allowProtected, allowPrivate);
  457. }
  458. void BfAutoComplete::AddCurrentTypes(BfTypeInstance* typeInst, const StringImpl& filter, bool allowProtected, bool allowPrivate, bool onlyAttribute)
  459. {
  460. if (typeInst != mModule->mCurTypeInstance)
  461. AddTypeDef(typeInst->mTypeDef, filter, onlyAttribute);
  462. auto typeDef = typeInst->mTypeDef;
  463. for (auto nestedTypeDef : typeDef->mNestedTypes)
  464. {
  465. if (nestedTypeDef->mIsPartial)
  466. {
  467. nestedTypeDef = mSystem->GetCombinedPartial(nestedTypeDef);
  468. if (nestedTypeDef == NULL)
  469. continue;
  470. }
  471. if (CheckProtection(nestedTypeDef->mProtection, allowProtected, allowPrivate))
  472. AddTypeDef(nestedTypeDef, filter, onlyAttribute);
  473. }
  474. auto outerType = mModule->GetOuterType(typeInst);
  475. if (outerType != NULL)
  476. AddCurrentTypes(outerType, filter, allowProtected, allowPrivate, onlyAttribute);
  477. allowPrivate = false;
  478. auto baseType = mModule->GetBaseType(typeInst);
  479. if (baseType != NULL)
  480. AddCurrentTypes(baseType, filter, allowProtected, allowPrivate, onlyAttribute);
  481. }
  482. void BfAutoComplete::AddTypeMembers(BfTypeInstance* typeInst, bool addStatic, bool addNonStatic, const StringImpl& filter, BfTypeInstance* startType, bool allowInterfaces, bool allowImplicitThis)
  483. {
  484. bool isInterface = false;
  485. auto activeTypeDef = mModule->GetActiveTypeDef();
  486. #define CHECK_STATIC(staticVal) ((staticVal && addStatic) || (!staticVal && addNonStatic))
  487. mModule->PopulateType(typeInst, BfPopulateType_Data);
  488. BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None;
  489. for (auto& fieldInst : typeInst->mFieldInstances)
  490. {
  491. auto fieldDef = fieldInst.GetFieldDef();
  492. if (fieldDef == NULL)
  493. continue;
  494. if (fieldDef->mIsNoShow)
  495. continue;
  496. if ((CHECK_STATIC(fieldDef->mIsStatic)) &&
  497. ((mIsGetDefinition) || (mModule->CheckProtection(protectionCheckFlags, typeInst, fieldDef->mProtection, startType))))
  498. {
  499. if ((!typeInst->IsTypeMemberIncluded(fieldDef->mDeclaringType, activeTypeDef, mModule)) ||
  500. (!typeInst->IsTypeMemberAccessible(fieldDef->mDeclaringType, activeTypeDef)))
  501. continue;
  502. AutoCompleteEntry entry(GetTypeName(fieldInst.mResolvedType), fieldDef->mName, (fieldDef->mFieldDeclaration != NULL) ? fieldDef->mFieldDeclaration->mDocumentation : NULL);
  503. if ((AddEntry(entry, filter)) && (mIsGetDefinition))
  504. {
  505. if (mDefType == NULL)
  506. {
  507. mDefType = typeInst->mTypeDef;
  508. mDefField = fieldDef;
  509. if (fieldDef->mFieldDeclaration != NULL)
  510. SetDefinitionLocation(fieldDef->mFieldDeclaration->mNameNode);
  511. }
  512. }
  513. }
  514. }
  515. for (auto methodDef : typeInst->mTypeDef->mMethods)
  516. {
  517. if (methodDef->mIsOverride)
  518. continue;
  519. if (methodDef->mIsNoShow)
  520. continue;
  521. if (methodDef->mName.IsEmpty())
  522. continue;
  523. if (methodDef->mExplicitInterface != NULL)
  524. continue;
  525. if ((!typeInst->IsTypeMemberIncluded(methodDef->mDeclaringType, activeTypeDef, mModule)) ||
  526. (!typeInst->IsTypeMemberAccessible(methodDef->mDeclaringType, activeTypeDef)))
  527. continue;
  528. bool canUseMethod;
  529. canUseMethod = (methodDef->mMethodType == BfMethodType_Normal) || (methodDef->mMethodType == BfMethodType_Mixin);
  530. if (isInterface)
  531. {
  532. // Always allow
  533. canUseMethod &= addNonStatic;
  534. }
  535. else
  536. {
  537. canUseMethod &= (CHECK_STATIC(methodDef->mIsStatic) &&
  538. (mModule->CheckProtection(protectionCheckFlags, typeInst, methodDef->mProtection, startType)));
  539. }
  540. if (canUseMethod)
  541. {
  542. AddMethod(methodDef->GetMethodDeclaration(), methodDef->mName, filter);
  543. }
  544. }
  545. for (auto propDef : typeInst->mTypeDef->mProperties)
  546. {
  547. if (propDef->mIsNoShow)
  548. continue;
  549. if ((!typeInst->IsTypeMemberIncluded(propDef->mDeclaringType, activeTypeDef, mModule)) ||
  550. (!typeInst->IsTypeMemberAccessible(propDef->mDeclaringType, activeTypeDef)))
  551. continue;
  552. if ((CHECK_STATIC(propDef->mIsStatic)) && (mModule->CheckProtection(protectionCheckFlags, typeInst, propDef->mProtection, startType)))
  553. {
  554. if ((!allowInterfaces) && (propDef->HasExplicitInterface()))
  555. continue;
  556. if (propDef->mName == "[]")
  557. continue;
  558. BfCommentNode* documentation = NULL;
  559. if (propDef->mFieldDeclaration != NULL)
  560. documentation = propDef->mFieldDeclaration->mDocumentation;
  561. AutoCompleteEntry entry("property", propDef->mName, documentation);
  562. if ((AddEntry(entry, filter)) && (mIsGetDefinition) && (propDef->mFieldDeclaration != NULL))
  563. SetDefinitionLocation(propDef->mFieldDeclaration->mNameNode);
  564. }
  565. }
  566. if (allowInterfaces)
  567. {
  568. for (auto iface : typeInst->mInterfaces)
  569. AddTypeMembers(iface.mInterfaceType, addStatic, addNonStatic, filter, startType, false, allowImplicitThis);
  570. }
  571. if (typeInst->mBaseType != NULL)
  572. AddTypeMembers(typeInst->mBaseType, addStatic, addNonStatic, filter, startType, false, allowImplicitThis);
  573. else
  574. {
  575. if (typeInst->IsStruct())
  576. AddTypeMembers(mModule->mContext->mBfObjectType, addStatic, addNonStatic, filter, startType, false, allowImplicitThis);
  577. }
  578. if ((addStatic) && (allowImplicitThis))
  579. {
  580. auto outerType = mModule->GetOuterType(typeInst);
  581. if (outerType != NULL)
  582. {
  583. AddTypeMembers(outerType, true, false, filter, startType, false, allowImplicitThis);
  584. }
  585. }
  586. }
  587. void BfAutoComplete::AddSelfResultTypeMembers(BfTypeInstance* typeInst, BfTypeInstance* selfType, const StringImpl& filter, bool allowPrivate)
  588. {
  589. bool isInterface = false;
  590. bool allowProtected = allowPrivate;
  591. auto activeTypeDef = mModule->GetActiveTypeDef();
  592. mModule->PopulateType(typeInst, BfPopulateType_Data);
  593. for (auto& fieldInst : typeInst->mFieldInstances)
  594. {
  595. auto fieldDef = fieldInst.GetFieldDef();
  596. if (fieldDef == NULL)
  597. continue;
  598. if (fieldDef->mIsNoShow)
  599. continue;
  600. if ((fieldDef->mIsStatic) && (CheckProtection(fieldDef->mProtection, allowProtected, allowPrivate)))
  601. {
  602. if (!mModule->CanImplicitlyCast(BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), fieldInst.mResolvedType), selfType))
  603. continue;
  604. if ((!typeInst->IsTypeMemberIncluded(fieldDef->mDeclaringType, activeTypeDef, mModule)) ||
  605. (!typeInst->IsTypeMemberAccessible(fieldDef->mDeclaringType, activeTypeDef)))
  606. continue;
  607. AutoCompleteEntry entry(GetTypeName(fieldInst.mResolvedType), fieldDef->mName, fieldDef->mFieldDeclaration->mDocumentation);
  608. if ((AddEntry(entry, filter)) && (mIsGetDefinition))
  609. {
  610. if (mDefType == NULL)
  611. {
  612. mDefType = typeInst->mTypeDef;
  613. mDefField = fieldDef;
  614. if (fieldDef->mFieldDeclaration != NULL)
  615. SetDefinitionLocation(fieldDef->mFieldDeclaration->mNameNode);
  616. }
  617. }
  618. }
  619. }
  620. for (auto methodDef : typeInst->mTypeDef->mMethods)
  621. {
  622. if (methodDef->mIsOverride)
  623. continue;
  624. if (methodDef->mIsNoShow)
  625. continue;
  626. if (methodDef->mName.IsEmpty())
  627. continue;
  628. if (methodDef->mExplicitInterface != NULL)
  629. continue;
  630. if ((!typeInst->IsTypeMemberIncluded(methodDef->mDeclaringType, activeTypeDef, mModule)) ||
  631. (!typeInst->IsTypeMemberAccessible(methodDef->mDeclaringType, activeTypeDef)))
  632. continue;
  633. if (!methodDef->mIsStatic)
  634. continue;
  635. bool canUseMethod;
  636. canUseMethod = (methodDef->mMethodType == BfMethodType_Normal) || (methodDef->mMethodType == BfMethodType_Mixin);
  637. canUseMethod &= CheckProtection(methodDef->mProtection, allowProtected, allowPrivate);
  638. if (methodDef->mMethodType != BfMethodType_Normal)
  639. continue;
  640. auto methodInstance = mModule->GetRawMethodInstanceAtIdx(typeInst, methodDef->mIdx);
  641. if (methodInstance == NULL)
  642. continue;
  643. if (methodInstance->mReturnType->IsUnspecializedType())
  644. continue;
  645. if (!mModule->CanImplicitlyCast(BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), methodInstance->mReturnType), selfType))
  646. continue;
  647. if (canUseMethod)
  648. {
  649. if (auto methodDeclaration = methodDef->GetMethodDeclaration())
  650. {
  651. String replaceName;
  652. AutoCompleteEntry entry("method", methodDef->mName, methodDeclaration->mDocumentation);
  653. if ((AddEntry(entry, filter)) && (mIsGetDefinition))
  654. {
  655. }
  656. }
  657. }
  658. }
  659. for (auto propDef : typeInst->mTypeDef->mProperties)
  660. {
  661. if (propDef->mIsNoShow)
  662. continue;
  663. if ((!typeInst->IsTypeMemberIncluded(propDef->mDeclaringType, activeTypeDef, mModule)) ||
  664. (!typeInst->IsTypeMemberAccessible(propDef->mDeclaringType, activeTypeDef)))
  665. continue;
  666. if (!propDef->mIsStatic)
  667. continue;
  668. BfMethodDef* getMethod = NULL;
  669. for (auto methodDef : propDef->mMethods)
  670. {
  671. if (methodDef->mMethodType == BfMethodType_PropertyGetter)
  672. {
  673. getMethod = methodDef;
  674. break;
  675. }
  676. }
  677. if (getMethod == NULL)
  678. continue;
  679. auto methodInstance = mModule->GetRawMethodInstanceAtIdx(typeInst, getMethod->mIdx);
  680. if (methodInstance == NULL)
  681. continue;
  682. if (methodInstance->mReturnType != selfType)
  683. continue;
  684. if (CheckProtection(propDef->mProtection, allowProtected, allowPrivate))
  685. {
  686. if (propDef->HasExplicitInterface())
  687. continue;
  688. if (propDef->mName == "[]")
  689. continue;
  690. AutoCompleteEntry entry("property", propDef->mName, propDef->mFieldDeclaration->mDocumentation);
  691. if ((AddEntry(entry, filter)) && (mIsGetDefinition))
  692. SetDefinitionLocation(propDef->mFieldDeclaration->mNameNode);
  693. }
  694. }
  695. auto outerType = mModule->GetOuterType(typeInst);
  696. if (outerType != NULL)
  697. {
  698. AddSelfResultTypeMembers(outerType, selfType, filter, false);
  699. }
  700. }
  701. bool BfAutoComplete::InitAutocomplete(BfAstNode* dotNode, BfAstNode* nameNode, String& filter)
  702. {
  703. if (IsAutocompleteNode(nameNode))
  704. {
  705. auto bfParser = nameNode->GetSourceData()->ToParser();
  706. if (mIsGetDefinition)
  707. {
  708. mInsertStartIdx = nameNode->GetSrcStart();
  709. mInsertEndIdx = nameNode->GetSrcEnd();
  710. }
  711. else
  712. {
  713. mInsertStartIdx = dotNode->GetSrcEnd();
  714. mInsertEndIdx = std::min(bfParser->mCursorIdx + 1, nameNode->GetSrcEnd());
  715. }
  716. filter.Append(bfParser->mSrc + mInsertStartIdx, mInsertEndIdx - mInsertStartIdx);
  717. return true;
  718. }
  719. if ((dotNode != NULL) && (IsAutocompleteNode(dotNode, 0, 1)))
  720. {
  721. mInsertStartIdx = dotNode->GetSrcEnd();
  722. mInsertEndIdx = dotNode->GetSrcEnd();
  723. return true;
  724. }
  725. return false;
  726. }
  727. void BfAutoComplete::AddEnumTypeMembers(BfTypeInstance* typeInst, const StringImpl& filter, bool allowProtected, bool allowPrivate)
  728. {
  729. mModule->PopulateType(typeInst, BfPopulateType_Data);
  730. auto activeTypeDef = mModule->GetActiveTypeDef();
  731. for (auto& fieldInst : typeInst->mFieldInstances)
  732. {
  733. auto fieldDef = fieldInst.GetFieldDef();
  734. if ((fieldDef != NULL) && (fieldDef->mIsConst) &&
  735. ((fieldInst.mResolvedType == typeInst) || (fieldInst.mIsEnumPayloadCase)) &&
  736. (CheckProtection(fieldDef->mProtection, allowProtected, allowPrivate)))
  737. {
  738. if ((!typeInst->IsTypeMemberIncluded(fieldDef->mDeclaringType, activeTypeDef, mModule)) ||
  739. (!typeInst->IsTypeMemberAccessible(fieldDef->mDeclaringType, activeTypeDef)))
  740. continue;
  741. bool hasPayload = false;
  742. if ((fieldInst.mIsEnumPayloadCase) && (fieldInst.mResolvedType->IsTuple()))
  743. {
  744. auto payloadType = (BfTupleType*)fieldInst.mResolvedType;
  745. if (!payloadType->mFieldInstances.empty())
  746. hasPayload = true;
  747. }
  748. AutoCompleteEntry entry(hasPayload ? "payloadEnum" : "value", fieldDef->mName, fieldDef->mFieldDeclaration->mDocumentation);
  749. if ((AddEntry(entry, filter)) && (mIsGetDefinition))
  750. {
  751. mDefType = typeInst->mTypeDef;
  752. mDefField = fieldDef;
  753. if (fieldDef->mFieldDeclaration != NULL)
  754. SetDefinitionLocation(fieldDef->mFieldDeclaration->mNameNode);
  755. }
  756. }
  757. }
  758. }
  759. // bool BfAutoComplete::IsInExpression(BfAstNode* node)
  760. // {
  761. // if (mModule->mCurMethodInstance != NULL)
  762. // return true;
  763. // if (node == NULL)
  764. // return false;
  765. // if ((node->IsA<BfExpression>()) && (!node->IsA<BfIdentifierNode>()) && (!node->IsA<BfBlock>()))
  766. // return true;
  767. // return IsInExpression(node->mParent);
  768. // }
  769. void BfAutoComplete::AddTopLevelNamespaces(BfIdentifierNode* identifierNode)
  770. {
  771. String filter;
  772. if (identifierNode != NULL)
  773. {
  774. filter = identifierNode->ToString();
  775. mInsertStartIdx = identifierNode->GetSrcStart();
  776. mInsertEndIdx = identifierNode->GetSrcEnd();
  777. }
  778. BfProject* bfProject = NULL;
  779. if (mModule->mCurTypeInstance != NULL)
  780. bfProject = mModule->mCurTypeInstance->mTypeDef->mProject;
  781. else
  782. bfProject = mCompiler->mResolvePassData->mParser->mProject;
  783. auto _AddProjectNamespaces = [&](BfProject* project)
  784. {
  785. for (auto namespacePair : project->mNamespaces)
  786. {
  787. const BfAtomComposite& namespaceComposite = namespacePair.mKey;
  788. if (namespaceComposite.GetPartsCount() == 1)
  789. {
  790. AddEntry(AutoCompleteEntry("namespace", namespaceComposite.ToString()), filter);
  791. }
  792. }
  793. };
  794. if (bfProject != NULL)
  795. {
  796. for (int depIdx = -1; depIdx < (int) bfProject->mDependencies.size(); depIdx++)
  797. {
  798. BfProject* depProject = (depIdx == -1) ? bfProject : bfProject->mDependencies[depIdx];
  799. _AddProjectNamespaces(depProject);
  800. }
  801. }
  802. else
  803. {
  804. for (auto project : mSystem->mProjects)
  805. _AddProjectNamespaces(project);
  806. }
  807. }
  808. void BfAutoComplete::AddTopLevelTypes(BfIdentifierNode* identifierNode, bool onlyAttribute)
  809. {
  810. String filter;
  811. if (identifierNode != NULL)
  812. {
  813. filter = identifierNode->ToString();
  814. mInsertStartIdx = identifierNode->GetSrcStart();
  815. mInsertEndIdx = identifierNode->GetSrcEnd();
  816. }
  817. AddEntry(AutoCompleteEntry("token", "function"), filter);
  818. AddEntry(AutoCompleteEntry("token", "delegate"), filter);
  819. if (mModule->mCurTypeInstance != NULL)
  820. {
  821. if (!onlyAttribute)
  822. {
  823. auto activeTypeDef = mModule->GetActiveTypeDef();
  824. for (auto genericParam : activeTypeDef->mGenericParamDefs)
  825. AddEntry(AutoCompleteEntry("generic", genericParam->mName), filter);
  826. }
  827. AddCurrentTypes(mModule->mCurTypeInstance, filter, true, true, onlyAttribute);
  828. // Do inners
  829. // bool allowInnerPrivate = false;
  830. // auto checkTypeInst = mModule->mCurTypeInstance;
  831. // while (checkTypeInst != NULL)
  832. // {
  833. // auto checkTypeDef = checkTypeInst->mTypeDef;
  834. // for (auto nestedTypeDef : checkTypeDef->mNestedTypes)
  835. // {
  836. // if (CheckProtection(nestedTypeDef->mProtection, true, allowInnerPrivate))
  837. // AddTypeDef(nestedTypeDef, filter, onlyAttribute);
  838. // }
  839. //
  840. // checkTypeInst = mModule->GetOuterType(mModule->mCurTypeInstance);
  841. // if (checkTypeInst != NULL)
  842. // AddInnerTypes(checkTypeInst, filter, true, true);
  843. //
  844. // AddOuterTypes(checkTypeInst, filter, true, true);
  845. //
  846. // checkTypeInst = mModule->GetBaseType(checkTypeInst);
  847. // allowInnerPrivate = false;
  848. // }
  849. // allowInnerPrivate = true;
  850. // checkTypeInst = mModule->GetOuterType(mModule->mCurTypeInstance);
  851. // if (checkTypeInst != NULL)
  852. // AddInnerTypes(checkTypeInst, filter, true, true);
  853. //
  854. // AddOuterTypes(mModule->mCurTypeInstance, filter, true, true);
  855. }
  856. if (mModule->mCurMethodInstance != NULL)
  857. {
  858. if (!onlyAttribute)
  859. {
  860. for (auto genericParam : mModule->mCurMethodInstance->mMethodDef->mGenericParams)
  861. AddEntry(AutoCompleteEntry("generic", genericParam->mName), filter);
  862. }
  863. }
  864. if (!onlyAttribute)
  865. {
  866. BfTypeDef* showTypeDef = NULL;
  867. for (auto& systemTypeDefEntry : mModule->mSystem->mSystemTypeDefs)
  868. {
  869. auto systemTypeDef = systemTypeDefEntry.mValue;
  870. if ((systemTypeDef->mTypeCode == BfTypeCode_IntUnknown) || (systemTypeDef->mTypeCode == BfTypeCode_UIntUnknown))
  871. continue;
  872. if ((AddEntry(AutoCompleteEntry("valuetype", systemTypeDef->mName->mString.mPtr), filter)) && (mIsGetDefinition))
  873. showTypeDef = systemTypeDef;
  874. }
  875. if (showTypeDef != NULL)
  876. {
  877. auto showType = mModule->ResolveTypeDef(showTypeDef);
  878. BfTypeInstance* showTypeInst = NULL;
  879. if (showType->IsPrimitiveType())
  880. showTypeInst = mModule->GetWrappedStructType(showType);
  881. else
  882. showTypeInst = showType->ToTypeInstance();
  883. if (showTypeInst != NULL)
  884. SetDefinitionLocation(showTypeInst->mTypeDef->mTypeDeclaration->mNameNode);
  885. }
  886. }
  887. auto activeTypeDef = mModule->GetActiveTypeDef();
  888. if (activeTypeDef != NULL)
  889. {
  890. BfProject* curProject = activeTypeDef->mProject;
  891. if (mModule->mCurTypeInstance != NULL)
  892. {
  893. for (auto innerTypeDef : mModule->mCurTypeInstance->mTypeDef->mNestedTypes)
  894. {
  895. if (!mModule->mCurTypeInstance->IsTypeMemberAccessible(innerTypeDef, activeTypeDef))
  896. continue;
  897. AddTypeDef(innerTypeDef, filter, onlyAttribute);
  898. }
  899. }
  900. auto& namespaceSearch = activeTypeDef->mNamespaceSearch;
  901. String prevName;
  902. for (auto typeDef : mModule->mSystem->mTypeDefs)
  903. {
  904. if (typeDef->mIsPartial)
  905. continue;
  906. //TODO :Check protection
  907. if ((curProject != NULL) && (curProject->ContainsReference(typeDef->mProject)))
  908. {
  909. bool matches = false;
  910. if (typeDef->mOuterType == NULL)
  911. {
  912. if (((typeDef->mNamespace.IsEmpty()) ||
  913. (namespaceSearch.Contains(typeDef->mNamespace))))
  914. matches = true;
  915. }
  916. if (matches)
  917. {
  918. AddTypeDef(typeDef, filter, onlyAttribute);
  919. }
  920. }
  921. }
  922. // BfStaticSearch* staticSearch;
  923. // if (mModule->mCurTypeInstance->mStaticSearchMap.TryGetValue(activeTypeDef, &staticSearch))
  924. // {
  925. // for (auto typeInst : staticSearch->mStaticTypes)
  926. // {
  927. // AddTypeDef(typeInst->mTypeDef, filter, onlyAttribute);
  928. // }
  929. // }
  930. // else if (!activeTypeDef->mStaticSearch.IsEmpty())
  931. // {
  932. // BF_ASSERT(mModule->mCompiler->IsAutocomplete());
  933. // for (auto typeRef : activeTypeDef->mStaticSearch)
  934. // {
  935. // auto type = mModule->ResolveTypeRef(typeRef, NULL, BfPopulateType_Declaration);
  936. // if (type != NULL)
  937. // {
  938. // auto typeInst = type->ToTypeInstance();
  939. // if (typeInst != NULL)
  940. // AddTypeDef(typeInst->mTypeDef, filter, onlyAttribute);
  941. // }
  942. // }
  943. // }
  944. }
  945. else
  946. {
  947. BfProject* curProject = NULL;
  948. if (mModule->mCompiler->mResolvePassData->mParser != NULL)
  949. curProject = mModule->mCompiler->mResolvePassData->mParser->mProject;
  950. String prevName;
  951. for (auto typeDef : mModule->mSystem->mTypeDefs)
  952. {
  953. if (typeDef->mIsPartial)
  954. continue;
  955. //TODO :Check protection
  956. if ((curProject != NULL) && (curProject->ContainsReference(typeDef->mProject)))
  957. {
  958. bool matches = false;
  959. if (typeDef->mOuterType == NULL)
  960. {
  961. if (typeDef->mNamespace.IsEmpty())
  962. matches = true;
  963. }
  964. if (matches)
  965. {
  966. AddTypeDef(typeDef, filter, onlyAttribute);
  967. }
  968. }
  969. }
  970. }
  971. }
  972. void BfAutoComplete::CheckIdentifier(BfIdentifierNode* identifierNode, bool isInExpression, bool isUsingDirective)
  973. {
  974. if ((identifierNode != NULL) && (!IsAutocompleteNode(identifierNode)))
  975. return;
  976. mIdentifierUsed = identifierNode;
  977. if ((mModule->mParentNodeEntry != NULL) && (mModule->mCurMethodState != NULL))
  978. {
  979. if (auto binExpr = BfNodeDynCast<BfBinaryOperatorExpression>(mModule->mParentNodeEntry->mNode))
  980. {
  981. auto parentBlock = mModule->mCurMethodState->mCurScope->mAstBlock;
  982. if ((identifierNode == binExpr->mRight) && (binExpr->mOp == BfBinaryOp_Multiply) && (parentBlock != NULL))
  983. {
  984. // If we are the last identifier in a block then we MAY be a partially-typed variable declaration
  985. if (parentBlock->mChildArr.back() == binExpr)
  986. {
  987. mUncertain = true;
  988. }
  989. }
  990. }
  991. }
  992. //bool isUsingDirective = false;
  993. //bool isUsingDirective = (identifierNode != NULL) && (identifierNode->mParent != NULL) && (identifierNode->mParent->IsA<BfUsingDirective>());
  994. if (mCompiler->mResolvePassData->mSourceClassifier != NULL)
  995. {
  996. //TODO: Color around dots
  997. //mCompiler->mResolvePassData->mSourceClassifier->SetElementType(identifierNode, BfSourceElementType_Namespace);
  998. }
  999. if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(identifierNode))
  1000. {
  1001. CheckMemberReference(qualifiedNameNode->mLeft, qualifiedNameNode->mDot, qualifiedNameNode->mRight, false, NULL, isUsingDirective);
  1002. return;
  1003. }
  1004. //bool isInExpression = true;
  1005. // if (identifierNode != NULL)
  1006. // isInExpression = IsInExpression(identifierNode);
  1007. AddTopLevelNamespaces(identifierNode);
  1008. if (isUsingDirective)
  1009. return; // Only do namespaces
  1010. AddTopLevelTypes(identifierNode);
  1011. String filter;
  1012. if (identifierNode != NULL)
  1013. {
  1014. filter = identifierNode->ToString();
  1015. mInsertStartIdx = identifierNode->GetSrcStart();
  1016. mInsertEndIdx = identifierNode->GetSrcEnd();
  1017. }
  1018. String addStr;
  1019. if (mShowAttributeProperties != NULL)
  1020. {
  1021. auto showAttrTypeDef = mShowAttributeProperties->mTypeDef;
  1022. for (auto prop : showAttrTypeDef->mProperties)
  1023. {
  1024. if ((AddEntry(AutoCompleteEntry("property", prop->mName + "=", prop->mFieldDeclaration->mDocumentation), filter)) && (mIsGetDefinition))
  1025. {
  1026. SetDefinitionLocation(prop->mFieldDeclaration->mNameNode);
  1027. }
  1028. }
  1029. for (auto field : showAttrTypeDef->mFields)
  1030. {
  1031. if ((AddEntry(AutoCompleteEntry("field", field->mName + "=", field->mFieldDeclaration->mDocumentation), filter)) && (mIsGetDefinition))
  1032. {
  1033. SetDefinitionLocation(field->mFieldDeclaration->mNameNode);
  1034. }
  1035. }
  1036. }
  1037. if ((mModule->mContext->mCurTypeState != NULL) && (mModule->mContext->mCurTypeState->mTypeInstance != NULL))
  1038. {
  1039. BF_ASSERT(mModule->mCurTypeInstance == mModule->mContext->mCurTypeState->mTypeInstance);
  1040. BfGlobalLookup globalLookup;
  1041. globalLookup.mKind = BfGlobalLookup::Kind_All;
  1042. mModule->PopulateGlobalContainersList(globalLookup);
  1043. for (auto& globalContainer : mModule->mContext->mCurTypeState->mGlobalContainers)
  1044. {
  1045. AddTypeMembers(globalContainer.mTypeInst, true, false, filter, globalContainer.mTypeInst, true, true);
  1046. }
  1047. }
  1048. //////////////////////////////////////////////////////////////////////////
  1049. {
  1050. auto activeTypeDef = mModule->GetActiveTypeDef();
  1051. BfStaticSearch* staticSearch;
  1052. if ((mModule->mCurTypeInstance != NULL) && (mModule->mCurTypeInstance->mStaticSearchMap.TryGetValue(activeTypeDef, &staticSearch)))
  1053. {
  1054. for (auto typeInst : staticSearch->mStaticTypes)
  1055. {
  1056. AddTypeMembers(typeInst, true, false, filter, typeInst, true, true);
  1057. AddInnerTypes(typeInst, filter, false, false);
  1058. }
  1059. }
  1060. else if ((activeTypeDef != NULL) && (!activeTypeDef->mStaticSearch.IsEmpty()))
  1061. {
  1062. BF_ASSERT(mModule->mCompiler->IsAutocomplete());
  1063. for (auto typeRef : activeTypeDef->mStaticSearch)
  1064. {
  1065. auto type = mModule->ResolveTypeRef(typeRef, NULL, BfPopulateType_Declaration);
  1066. if (type != NULL)
  1067. {
  1068. auto typeInst = type->ToTypeInstance();
  1069. if (typeInst != NULL)
  1070. {
  1071. AddTypeMembers(typeInst, true, false, filter, typeInst, true, true);
  1072. AddInnerTypes(typeInst, filter, false, false);
  1073. }
  1074. }
  1075. }
  1076. }
  1077. }
  1078. //////////////////////////////////////////////////////////////////////////
  1079. BfMethodInstance* curMethodInstance = mModule->mCurMethodInstance;
  1080. if (mModule->mCurMethodState != NULL)
  1081. curMethodInstance = mModule->mCurMethodState->GetRootMethodState()->mMethodInstance;
  1082. if (curMethodInstance != NULL)
  1083. {
  1084. if (!curMethodInstance->mMethodDef->mIsStatic)
  1085. {
  1086. if (mModule->mCurTypeInstance->IsObject())
  1087. AddEntry(AutoCompleteEntry("object", "this"), filter);
  1088. else
  1089. AddEntry(AutoCompleteEntry("pointer", "this"), filter);
  1090. AddTypeMembers(mModule->mCurTypeInstance, true, true, filter, mModule->mCurTypeInstance, mModule->mCurTypeInstance->IsInterface(), true);
  1091. }
  1092. else
  1093. {
  1094. AddTypeMembers(mModule->mCurTypeInstance, true, false, filter, mModule->mCurTypeInstance, mModule->mCurTypeInstance->IsInterface(), true);
  1095. }
  1096. if (mModule->mCurMethodState != NULL)
  1097. {
  1098. int varSkipCount = 0;
  1099. StringT<128> wantName = filter;
  1100. while (wantName.StartsWith("@"))
  1101. {
  1102. varSkipCount++;
  1103. wantName.Remove(0);
  1104. }
  1105. if (varSkipCount > 0)
  1106. {
  1107. Dictionary<String, int> localCount;
  1108. auto varMethodState = mModule->mCurMethodState;
  1109. while (varMethodState != NULL)
  1110. {
  1111. for (int localIdx = (int)varMethodState->mLocals.size() - 1; localIdx >= 0; localIdx--)
  1112. {
  1113. auto local = varMethodState->mLocals[localIdx];
  1114. int* findIdx = NULL;
  1115. if (localCount.TryAdd(local->mName, NULL, &findIdx))
  1116. {
  1117. *findIdx = 0;
  1118. }
  1119. else
  1120. {
  1121. (*findIdx)++;
  1122. }
  1123. if (*findIdx == varSkipCount)
  1124. {
  1125. if ((AddEntry(AutoCompleteEntry(GetTypeName(local->mResolvedType), local->mName), wantName)) && (mIsGetDefinition))
  1126. {
  1127. }
  1128. }
  1129. }
  1130. varMethodState = varMethodState->mPrevMethodState;
  1131. if ((varMethodState == NULL) ||
  1132. (varMethodState->mMixinState != NULL) ||
  1133. ((varMethodState->mClosureState != NULL) && (!varMethodState->mClosureState->mCapturing)))
  1134. break;
  1135. }
  1136. mInsertStartIdx += varSkipCount;
  1137. }
  1138. else
  1139. {
  1140. auto varMethodState = mModule->mCurMethodState;
  1141. while (varMethodState != NULL)
  1142. {
  1143. for (auto& local : varMethodState->mLocals)
  1144. {
  1145. if ((AddEntry(AutoCompleteEntry(GetTypeName(local->mResolvedType), local->mName), wantName)) && (mIsGetDefinition))
  1146. {
  1147. }
  1148. }
  1149. varMethodState = varMethodState->mPrevMethodState;
  1150. if ((varMethodState == NULL) ||
  1151. (varMethodState->mMixinState != NULL) ||
  1152. ((varMethodState->mClosureState != NULL) && (!varMethodState->mClosureState->mCapturing)))
  1153. break;
  1154. }
  1155. }
  1156. }
  1157. }
  1158. else if (mModule->mCurTypeInstance != NULL)
  1159. {
  1160. bool staticOnly = true;
  1161. if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mTempKind == BfMethodState::TempKind_NonStatic))
  1162. staticOnly = false;
  1163. //BF_ASSERT(mModule->mCurTypeInstance->mResolvingConstField);
  1164. AddTypeMembers(mModule->mCurTypeInstance, true, !staticOnly, filter, mModule->mCurTypeInstance, false, true);
  1165. }
  1166. auto checkMethodState = mModule->mCurMethodState;
  1167. while (checkMethodState != NULL)
  1168. {
  1169. for (auto localMethod : checkMethodState->mLocalMethods)
  1170. {
  1171. //AddEntry(AutoCompleteEntry("method", localMethod->mMethodName, localMethod->mMethodDeclaration->mDocumentation), filter);
  1172. AddMethod(localMethod->mMethodDeclaration, localMethod->mMethodName, filter);
  1173. }
  1174. checkMethodState = checkMethodState->mPrevMethodState;
  1175. }
  1176. if (isInExpression)
  1177. {
  1178. const char* tokens [] =
  1179. {
  1180. "alignof", "as", "asm", "base", "break", "case", "catch", "checked", "continue", "default", "defer",
  1181. "delegate", "delete", "do", "else", "false", "finally",
  1182. "fixed", "for", "function", "if", "implicit", "in", "internal", "is", "new", "mixin", "null",
  1183. "out", "params", "ref", "rettype", "return",
  1184. "sealed", "sizeof", "scope", "static", "strideof", "struct", "switch", /*"this",*/ "throw", "try", "true", "typeof", "unchecked",
  1185. "using", "var", "virtual", "volatile", "where", "while",
  1186. };
  1187. for (int i = 0; i < sizeof(tokens) / sizeof(char*); i++)
  1188. AddEntry(AutoCompleteEntry("token", tokens[i]), filter);
  1189. if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mBreakData != NULL) && (mModule->mCurMethodState->mBreakData->mIRFallthroughBlock))
  1190. {
  1191. AddEntry(AutoCompleteEntry("token", "fallthrough"), filter);
  1192. }
  1193. }
  1194. else
  1195. {
  1196. const char* tokens[] =
  1197. {
  1198. "abstract", "base", "class", "const",
  1199. "delegate", "extern", "enum", "explicit", "extension", "function",
  1200. "interface", "in", "internal", "mixin", "namespace", "new",
  1201. "operator", "out", "override", "params", "private", "protected", "public", "readonly", "ref", "rettype", "return",
  1202. "scope", "sealed", "static", "struct", "this", "typealias",
  1203. "using", "virtual", "volatile", "T", "where"
  1204. };
  1205. for (int i = 0; i < sizeof(tokens)/sizeof(char*); i++)
  1206. AddEntry(AutoCompleteEntry("token", tokens[i]), filter);
  1207. }
  1208. //if ((identifierNode != NULL) && ((mModule->mCurMethodInstance == NULL) || (BfNodeDynCast<BfExpression>(identifierNode->mParent) != NULL)))
  1209. /*if ((identifierNode != NULL) && ((mModule->mCurMethodInstance == NULL) || (isInExpression)))
  1210. {
  1211. AddEntry(AutoCompleteEntry("token", "#if"), filter);
  1212. AddEntry(AutoCompleteEntry("token", "#elif"), filter);
  1213. AddEntry(AutoCompleteEntry("token", "#endif"), filter);
  1214. }*/
  1215. //OutputDebugStrF("Autocomplete: %s\n", str.c_str());
  1216. }
  1217. String BfAutoComplete::GetFilter(BfAstNode* node)
  1218. {
  1219. String filter = node->ToString();
  1220. if (mIsGetDefinition)
  1221. {
  1222. mInsertEndIdx = node->GetSrcEnd();
  1223. }
  1224. else
  1225. {
  1226. // Only use member name up to cursor
  1227. auto bfParser = node->GetSourceData()->ToParser();
  1228. int cursorIdx = bfParser->mCursorIdx;
  1229. filter = filter.Substring(0, BF_MIN(cursorIdx - node->GetSrcStart(), (int)filter.length()));
  1230. mInsertEndIdx = cursorIdx;
  1231. }
  1232. return filter;
  1233. }
  1234. bool BfAutoComplete::CheckMemberReference(BfAstNode* target, BfAstNode* dotToken, BfAstNode* memberName, bool onlyShowTypes, BfType* expectingType, bool isUsingDirective, bool onlyAttribute)
  1235. {
  1236. BfAttributedIdentifierNode* attrIdentifier = NULL;
  1237. bool isAutocompletingName = false;
  1238. if ((attrIdentifier = BfNodeDynCast<BfAttributedIdentifierNode>(memberName)))
  1239. {
  1240. memberName = attrIdentifier->mIdentifier;
  1241. if ((memberName == NULL) && (IsAutocompleteNode(attrIdentifier->mAttributes)))
  1242. {
  1243. auto bfParser = attrIdentifier->mAttributes->GetSourceData()->ToParser();
  1244. int cursorIdx = bfParser->mCursorIdx;
  1245. isAutocompletingName = cursorIdx == attrIdentifier->mAttributes->GetSrcEnd();
  1246. }
  1247. }
  1248. if (memberName != NULL)
  1249. isAutocompletingName = IsAutocompleteNode(dotToken, memberName, 0, 1);
  1250. if ((IsAutocompleteNode(dotToken, 0, 1)) || (isAutocompletingName))
  1251. {
  1252. BfLogSys(mModule->mSystem, "Triggered autocomplete\n");
  1253. bool isFriend = false;
  1254. mInsertStartIdx = dotToken->GetSrcEnd();
  1255. if (attrIdentifier != NULL)
  1256. {
  1257. BfAttributeState attributeState;
  1258. attributeState.mTarget = (BfAttributeTargets)(BfAttributeTargets_MemberAccess);
  1259. attributeState.mCustomAttributes = mModule->GetCustomAttributes(attrIdentifier->mAttributes, attributeState.mTarget);
  1260. isFriend = (attributeState.mCustomAttributes != NULL) && (attributeState.mCustomAttributes->Contains(mModule->mCompiler->mFriendAttributeTypeDef));
  1261. mInsertStartIdx = attrIdentifier->mAttributes->GetSrcEnd();
  1262. }
  1263. if (memberName != NULL)
  1264. {
  1265. //Member name MAY be incorrectly identified in cases like:
  1266. // val._
  1267. // OtherCall();
  1268. int cursorIdx = GetCursorIdx(memberName);
  1269. if ((cursorIdx != -1) && (cursorIdx >= memberName->GetSrcStart()))
  1270. mInsertStartIdx = memberName->GetSrcStart();
  1271. }
  1272. SetAndRestoreValue<bool> prevFriendSet(mHasFriendSet, mHasFriendSet || isFriend);
  1273. String filter;
  1274. if ((memberName != NULL) && (IsAutocompleteNode(memberName)))
  1275. {
  1276. filter = GetFilter(memberName);
  1277. }
  1278. else if (mResolveType != BfResolveType_Autocomplete)
  1279. mInsertStartIdx = -1; // Require a full span for everything but autocomplete
  1280. SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
  1281. bool isStatic = false;
  1282. BfTypedValue targetValue = LookupTypeRefOrIdentifier(target, &isStatic, (BfEvalExprFlags)(BfEvalExprFlags_IgnoreNullConditional | BfEvalExprFlags_NoCast), expectingType);
  1283. bool hadResults = false;
  1284. bool doAsNamespace = true;
  1285. if ((targetValue.mType) && (!isUsingDirective))
  1286. {
  1287. doAsNamespace = false;
  1288. if (auto dotTokenNode = BfNodeDynCast<BfTokenNode>(dotToken))
  1289. {
  1290. if (dotTokenNode->GetToken() == BfToken_QuestionDot)
  1291. {
  1292. // ?. should look inside nullable types
  1293. if (targetValue.mType->IsNullable())
  1294. {
  1295. BfGenericTypeInstance* nullableType = (BfGenericTypeInstance*)targetValue.mType->ToTypeInstance();
  1296. targetValue = mModule->MakeAddressable(targetValue);
  1297. BfIRValue valuePtr = mModule->mBfIRBuilder->CreateInBoundsGEP(targetValue.mValue, 0, 1); // mValue
  1298. targetValue = BfTypedValue(valuePtr, nullableType->mTypeGenericArguments[0], true);
  1299. }
  1300. }
  1301. }
  1302. // Statics, inner types
  1303. //bool isStatic = (targetValue.mValue == NULL) && (!targetValue.mType->IsValuelessType());
  1304. auto checkType = targetValue.mType;
  1305. if (checkType->IsGenericParam())
  1306. {
  1307. auto genericParamType = (BfGenericParamType*)checkType;
  1308. auto genericParamInst = mModule->GetGenericParamInstance(genericParamType);
  1309. for (auto interfaceConstraint : genericParamInst->mInterfaceConstraints)
  1310. AddTypeMembers(interfaceConstraint, false, true, filter, interfaceConstraint, true, false);
  1311. if (genericParamInst->mTypeConstraint != NULL)
  1312. checkType = genericParamInst->mTypeConstraint;
  1313. else
  1314. checkType = mModule->mContext->mBfObjectType;
  1315. }
  1316. if (checkType->IsPointer())
  1317. checkType = checkType->GetUnderlyingType();
  1318. auto typeInst = checkType->ToTypeInstance();
  1319. if ((typeInst == NULL) &&
  1320. ((checkType->IsPrimitiveType()) || (checkType->IsSizedArray())))
  1321. typeInst = mModule->GetWrappedStructType(checkType);
  1322. if (typeInst != NULL)
  1323. {
  1324. if (typeInst->mTypeDef->IsGlobalsContainer())
  1325. doAsNamespace = true; // Also list the types in this namespace
  1326. bool allowPrivate = (mModule->mCurTypeInstance == typeInst) || (mModule->IsInnerType(mModule->mCurTypeInstance, typeInst));
  1327. bool allowProtected = allowPrivate;
  1328. if (isStatic)
  1329. AddInnerTypes(typeInst, filter, allowProtected, allowPrivate);
  1330. if (!onlyShowTypes)
  1331. AddTypeMembers(typeInst, isStatic, !isStatic, filter, typeInst, false, false);
  1332. if (typeInst->IsInterface())
  1333. {
  1334. AddTypeMembers(mModule->mContext->mBfObjectType, isStatic, !isStatic, filter, mModule->mContext->mBfObjectType, true, false);
  1335. }
  1336. }
  1337. hadResults = true;
  1338. }
  1339. if (doAsNamespace) // Lookup namespaces
  1340. {
  1341. String targetStr = target->ToString();
  1342. BfAtomComposite targetComposite;
  1343. bool isValid = mSystem->ParseAtomComposite(targetStr, targetComposite);
  1344. BfProject* bfProject = NULL;
  1345. if (mModule->mCurTypeInstance != NULL)
  1346. bfProject = mModule->mCurTypeInstance->mTypeDef->mProject;
  1347. else
  1348. bfProject = mCompiler->mResolvePassData->mParser->mProject;
  1349. auto _CheckProject = [&](BfProject* project)
  1350. {
  1351. if ((isValid) && (project->mNamespaces.ContainsKey(targetComposite)))
  1352. {
  1353. for (auto namespacePair : project->mNamespaces)
  1354. {
  1355. const BfAtomComposite& namespaceComposite = namespacePair.mKey;
  1356. if ((namespaceComposite.StartsWith(targetComposite)) && (namespaceComposite.GetPartsCount() > targetComposite.GetPartsCount()))
  1357. {
  1358. BfAtom* subNamespace = namespaceComposite.mParts[targetComposite.mSize];
  1359. AutoCompleteEntry entry("namespace", subNamespace->mString.mPtr);
  1360. AddEntry(entry, filter);
  1361. }
  1362. }
  1363. if (!isUsingDirective)
  1364. {
  1365. BfTypeDef* curTypeDef = NULL;
  1366. if (mModule->mCurTypeInstance != NULL)
  1367. curTypeDef = mModule->mCurTypeInstance->mTypeDef;
  1368. for (auto typeDef : mSystem->mTypeDefs)
  1369. {
  1370. if ((typeDef->mNamespace == targetComposite) && (typeDef->mOuterType == NULL) &&
  1371. (!typeDef->mIsPartial) &&
  1372. ((curTypeDef == NULL) || (curTypeDef->mProject->ContainsReference(typeDef->mProject))))
  1373. {
  1374. AddTypeDef(typeDef, filter, onlyAttribute);
  1375. }
  1376. }
  1377. }
  1378. hadResults = true;
  1379. }
  1380. };
  1381. if (bfProject != NULL)
  1382. {
  1383. for (int depIdx = -1; depIdx < (int)bfProject->mDependencies.size(); depIdx++)
  1384. {
  1385. BfProject* depProject = (depIdx == -1) ? bfProject : bfProject->mDependencies[depIdx];
  1386. _CheckProject(depProject);
  1387. }
  1388. }
  1389. else
  1390. {
  1391. for (auto project : mSystem->mProjects)
  1392. _CheckProject(project);
  1393. }
  1394. }
  1395. return hadResults;
  1396. }
  1397. else
  1398. {
  1399. auto identifierNode = BfNodeDynCast<BfIdentifierNode>(target);
  1400. if (identifierNode != NULL)
  1401. CheckIdentifier(identifierNode);
  1402. CheckTypeRef(BfNodeDynCast<BfTypeReference>(target), true, false, onlyAttribute);
  1403. }
  1404. return false;
  1405. }
  1406. void BfAutoComplete::CheckTypeRef(BfTypeReference* typeRef, bool mayBeIdentifier, bool isInExpression, bool onlyAttribute)
  1407. {
  1408. if ((typeRef == NULL) || (typeRef->IsTemporary()) || (!IsAutocompleteNode(typeRef)))
  1409. return;
  1410. if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef))
  1411. {
  1412. CheckTypeRef(genericTypeRef->mElementType, mayBeIdentifier, isInExpression, onlyAttribute);
  1413. for (auto genericArg : genericTypeRef->mGenericArguments)
  1414. CheckTypeRef(genericArg, false, isInExpression, false);
  1415. return;
  1416. }
  1417. if (!onlyAttribute)
  1418. {
  1419. if (auto tupleTypeRef = BfNodeDynCast<BfTupleTypeRef>(typeRef))
  1420. {
  1421. for (auto fieldTypeRef : tupleTypeRef->mFieldTypes)
  1422. CheckTypeRef(fieldTypeRef, false, isInExpression, false);
  1423. return;
  1424. }
  1425. if (auto delegateTypeRef = BfNodeDynCast<BfDelegateTypeRef>(typeRef))
  1426. {
  1427. CheckTypeRef(delegateTypeRef->mReturnType, false, isInExpression);
  1428. for (auto param : delegateTypeRef->mParams)
  1429. {
  1430. auto attributes = param->mAttributes;
  1431. while (attributes != NULL)
  1432. {
  1433. if (attributes->mAttributeTypeRef != NULL)
  1434. {
  1435. CheckAttributeTypeRef(attributes->mAttributeTypeRef);
  1436. }
  1437. attributes = attributes->mNextAttribute;
  1438. }
  1439. CheckTypeRef(param->mTypeRef, false, isInExpression);
  1440. }
  1441. return;
  1442. }
  1443. if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(typeRef))
  1444. {
  1445. // "May be identifier" where pointer types could actually end up be multiplies, etc.
  1446. CheckTypeRef(elementedTypeRef->mElementType, true, isInExpression);
  1447. return;
  1448. }
  1449. }
  1450. if (mayBeIdentifier)
  1451. {
  1452. if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(typeRef))
  1453. {
  1454. CheckIdentifier(namedTypeRef->mNameNode, isInExpression);
  1455. return;
  1456. }
  1457. }
  1458. if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef))
  1459. {
  1460. // Only consider the left side as an identifier if there's space after the dot. Consider this:
  1461. // mVal.
  1462. // Type a = null;
  1463. // vs
  1464. // mVal.Type a = null;
  1465. // The first one is clearly a member reference being typed out even though it looks the same
  1466. // to the parser except for the spacing
  1467. if ((qualifiedTypeRef->mRight == NULL) || (qualifiedTypeRef->mDot->GetSrcEnd() < qualifiedTypeRef->mRight->GetSrcStart()))
  1468. {
  1469. BfAutoParentNodeEntry autoParentNodeEntry(mModule, qualifiedTypeRef);
  1470. //CheckMemberReference(qualifiedTypeRef->mLeft, qualifiedTypeRef->mDot, NULL, !mayBeIdentifier, NULL, false, onlyAttribute);
  1471. CheckMemberReference(qualifiedTypeRef->mLeft, qualifiedTypeRef->mDot, qualifiedTypeRef->mRight, !mayBeIdentifier, NULL, false, onlyAttribute);
  1472. }
  1473. else if (auto rightNamedTypeRef = BfNodeDynCast<BfNamedTypeReference>(qualifiedTypeRef->mRight))
  1474. {
  1475. BfAutoParentNodeEntry autoParentNodeEntry(mModule, qualifiedTypeRef);
  1476. if (CheckMemberReference(qualifiedTypeRef->mLeft, qualifiedTypeRef->mDot, rightNamedTypeRef->mNameNode, false, NULL, false, onlyAttribute))
  1477. return;
  1478. }
  1479. }
  1480. if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(typeRef))
  1481. {
  1482. AddTopLevelNamespaces(namedTypeRef->mNameNode);
  1483. AddTopLevelTypes(namedTypeRef->mNameNode, onlyAttribute);
  1484. }
  1485. }
  1486. void BfAutoComplete::CheckAttributeTypeRef(BfTypeReference* typeRef)
  1487. {
  1488. if (!IsAutocompleteNode(typeRef))
  1489. return;
  1490. CheckTypeRef(typeRef, false, false, true);
  1491. }
  1492. void BfAutoComplete::CheckInvocation(BfAstNode* invocationNode, BfTokenNode* openParen, BfTokenNode* closeParen, const BfSizedArray<ASTREF(BfTokenNode*)>& commas)
  1493. {
  1494. if (!mIsAutoComplete)
  1495. return;
  1496. bool wasCapturingMethodMatchInfo = mIsCapturingMethodMatchInfo;
  1497. mIsCapturingMethodMatchInfo = false;
  1498. int lenAdd = 0;
  1499. if (closeParen == NULL)
  1500. {
  1501. // Unterminated invocation expression - allow for space after last comma in param list
  1502. lenAdd = 1;
  1503. }
  1504. else
  1505. {
  1506. // Ignore close paren
  1507. lenAdd = -1;
  1508. }
  1509. if (!IsAutocompleteNode(invocationNode, lenAdd))
  1510. return;
  1511. if (openParen == NULL)
  1512. {
  1513. mModule->AssertErrorState();
  1514. return;
  1515. }
  1516. auto bfParser = invocationNode->GetSourceData()->ToParser();
  1517. if (bfParser == NULL)
  1518. return;
  1519. int cursorIdx = bfParser->mCursorIdx;
  1520. BfAstNode* target = invocationNode;
  1521. if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(invocationNode))
  1522. {
  1523. target = invocationExpr->mTarget;
  1524. if (auto memberTarget = BfNodeDynCast<BfMemberReferenceExpression>(target))
  1525. {
  1526. if (memberTarget->mMemberName != NULL)
  1527. target = memberTarget->mMemberName;
  1528. }
  1529. else if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(target))
  1530. target = qualifiedTypeRef->mRight;
  1531. else if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(target))
  1532. target = qualifiedNameNode->mRight;
  1533. if (auto attributedMember = BfNodeDynCast<BfAttributedIdentifierNode>(target))
  1534. target = attributedMember->mIdentifier;
  1535. }
  1536. bool doCapture = (bfParser->mCursorIdx >= openParen->GetSrcStart());
  1537. if (mIsGetDefinition)
  1538. {
  1539. doCapture |= (target != NULL) && (bfParser->mCursorIdx >= target->GetSrcStart());
  1540. }
  1541. if (doCapture)
  1542. {
  1543. mIsCapturingMethodMatchInfo = true;
  1544. if (mMethodMatchInfo == NULL)
  1545. mMethodMatchInfo = new MethodMatchInfo();
  1546. else
  1547. {
  1548. if (wasCapturingMethodMatchInfo)
  1549. {
  1550. // We're actually in an inner invocation now
  1551. delete mMethodMatchInfo;
  1552. mMethodMatchInfo = new MethodMatchInfo();
  1553. mMethodMatchInfo->mSrcPositions.Clear();
  1554. }
  1555. }
  1556. mMethodMatchInfo->mInvocationSrcIdx = target->GetSrcStart();
  1557. mMethodMatchInfo->mCurMethodInstance = mModule->mCurMethodInstance;
  1558. mMethodMatchInfo->mCurTypeInstance = mModule->mCurTypeInstance;
  1559. mMethodMatchInfo->mSrcPositions.Clear();
  1560. mMethodMatchInfo->mSrcPositions.push_back(openParen->GetSrcStart());
  1561. for (auto comma : commas)
  1562. mMethodMatchInfo->mSrcPositions.push_back(comma->GetSrcStart());
  1563. mMethodMatchInfo->mSrcPositions.push_back(invocationNode->GetSrcEnd() + lenAdd);
  1564. }
  1565. }
  1566. void BfAutoComplete::CheckNode(BfAstNode* node)
  1567. {
  1568. if (!IsAutocompleteNode(node))
  1569. return;
  1570. if (auto identifer = BfNodeDynCast<BfIdentifierNode>(node))
  1571. CheckIdentifier(identifer);
  1572. if (auto typeRef = BfNodeDynCast<BfTypeReference>(node))
  1573. CheckTypeRef(typeRef, true);
  1574. if (auto memberRef = BfNodeDynCast<BfMemberReferenceExpression>(node))
  1575. {
  1576. if (memberRef->mTarget != NULL)
  1577. CheckMemberReference(memberRef->mTarget, memberRef->mDotToken, memberRef->mMemberName);
  1578. }
  1579. }
  1580. void BfAutoComplete::AddOverrides(const StringImpl& filter)
  1581. {
  1582. if (!mIsAutoComplete)
  1583. return;
  1584. auto activeTypeDef = mModule->GetActiveTypeDef();
  1585. BfTypeInstance* curType = mModule->mCurTypeInstance;
  1586. while (curType != NULL)
  1587. {
  1588. for (auto methodDef : curType->mTypeDef->mMethods)
  1589. {
  1590. if (methodDef->mIsNoShow)
  1591. continue;
  1592. if (curType == mModule->mCurTypeInstance)
  1593. {
  1594. // The "normal" case, and only case for types without extensions
  1595. if (methodDef->mDeclaringType == activeTypeDef)
  1596. continue;
  1597. if ((methodDef->mDeclaringType->IsExtension()) && (methodDef->mDeclaringType->mProject == activeTypeDef->mProject))
  1598. continue;
  1599. if (!curType->IsTypeMemberAccessible(methodDef->mDeclaringType, activeTypeDef))
  1600. continue;
  1601. }
  1602. auto& methodGroup = curType->mMethodInstanceGroups[methodDef->mIdx];
  1603. if (methodGroup.mDefault == NULL)
  1604. {
  1605. continue;
  1606. }
  1607. auto methodInst = methodGroup.mDefault;
  1608. if ((methodDef->mIsVirtual) && (!methodDef->mIsOverride))
  1609. {
  1610. if (methodDef->mMethodType == BfMethodType_Normal)
  1611. {
  1612. String methodPrefix;
  1613. String methodName;
  1614. String impString;
  1615. bool isAbstract = methodDef->mIsAbstract;
  1616. if (!isAbstract)
  1617. {
  1618. if (!methodInst->mReturnType->IsVoid())
  1619. impString = "return ";
  1620. impString += "base.";
  1621. impString += methodDef->mName;
  1622. impString += "(";
  1623. }
  1624. auto methodDeclaration = methodDef->GetMethodDeclaration();
  1625. if (methodDeclaration->mProtectionSpecifier != NULL)
  1626. methodPrefix += methodDeclaration->mProtectionSpecifier->ToString() + " ";
  1627. methodPrefix += "override ";
  1628. methodPrefix += mModule->TypeToString(methodInst->mReturnType, BfTypeNameFlag_ReduceName);
  1629. methodPrefix += " ";
  1630. methodName += methodDef->mName;
  1631. methodName += "(";
  1632. for (int paramIdx = 0; paramIdx < (int)methodInst->GetParamCount(); paramIdx++)
  1633. {
  1634. if (paramIdx > 0)
  1635. {
  1636. methodName += ", ";
  1637. if (!isAbstract)
  1638. impString += ", ";
  1639. }
  1640. methodName += mModule->TypeToString(methodInst->GetParamType(paramIdx), BfTypeNameFlag_ReduceName);
  1641. methodName += " ";
  1642. methodName += methodDef->mParams[paramIdx]->mName;
  1643. if (!isAbstract)
  1644. impString += methodDef->mParams[paramIdx]->mName;
  1645. }
  1646. methodName += ")";
  1647. if (!isAbstract)
  1648. impString += ");";
  1649. AddEntry(AutoCompleteEntry("override", methodName + "\t" + methodPrefix + methodName + "\t" + impString, NULL), filter);
  1650. }
  1651. else if ((methodDef->mMethodType == BfMethodType_PropertyGetter) || (methodDef->mMethodType == BfMethodType_PropertySetter))
  1652. {
  1653. auto propDeclaration = methodDef->GetPropertyDeclaration();
  1654. bool hasGet = propDeclaration->GetMethod("get") != NULL;
  1655. bool hasSet = propDeclaration->GetMethod("set") != NULL;
  1656. if ((methodDef->mMethodType == BfMethodType_PropertyGetter) || (!hasGet))
  1657. {
  1658. String propName;
  1659. String impl;
  1660. propDeclaration->mNameNode->ToString(propName);
  1661. bool isAbstract = methodDef->mIsAbstract;
  1662. if (propDeclaration->mProtectionSpecifier != NULL)
  1663. impl += propDeclaration->mProtectionSpecifier->ToString() + " ";
  1664. impl += "override ";
  1665. impl += mModule->TypeToString(methodInst->mReturnType, BfTypeNameFlag_ReduceName);
  1666. impl += " ";
  1667. impl += propName;
  1668. impl += "\t";
  1669. if (hasGet)
  1670. {
  1671. impl += "get\t";
  1672. if (!isAbstract)
  1673. {
  1674. impl += "return base.";
  1675. impl += propName;
  1676. impl += ";";
  1677. }
  1678. }
  1679. if (hasSet)
  1680. {
  1681. if (hasGet)
  1682. impl += "\b\r";
  1683. impl += "set\t";
  1684. if (!isAbstract)
  1685. {
  1686. impl += "base.";
  1687. impl += propName;
  1688. impl += " = value;";
  1689. }
  1690. }
  1691. AddEntry(AutoCompleteEntry("override", propName + "\t" + impl, NULL), filter);
  1692. }
  1693. }
  1694. }
  1695. }
  1696. if (curType->IsStruct())
  1697. curType = mModule->mContext->mBfObjectType;
  1698. else
  1699. curType = curType->mBaseType;
  1700. }
  1701. }
  1702. void BfAutoComplete::UpdateReplaceData()
  1703. {
  1704. }
  1705. void BfAutoComplete::CheckMethod(BfMethodDeclaration* methodDeclaration, bool isLocalMethod)
  1706. {
  1707. if (/*(propertyDeclaration->mDefinitionBlock == NULL) &&*/ (methodDeclaration->mVirtualSpecifier != NULL) &&
  1708. (methodDeclaration->mVirtualSpecifier->GetToken() == BfToken_Override))
  1709. {
  1710. auto bfParser = methodDeclaration->mVirtualSpecifier->GetSourceData()->ToParser();
  1711. if (bfParser == NULL)
  1712. return;
  1713. int cursorIdx = bfParser->mCursorIdx;
  1714. bool isInTypeRef = IsAutocompleteNode(methodDeclaration->mReturnType);
  1715. bool isInNameNode = IsAutocompleteNode(methodDeclaration->mNameNode);
  1716. if (((IsAutocompleteNode(methodDeclaration, 1)) && (cursorIdx == methodDeclaration->mVirtualSpecifier->GetSrcEnd())) ||
  1717. (isInTypeRef) || (isInNameNode))
  1718. {
  1719. if (mIsAutoComplete)
  1720. {
  1721. mInsertStartIdx = methodDeclaration->GetSrcStart();
  1722. mInsertEndIdx = methodDeclaration->GetSrcEnd();
  1723. }
  1724. String filter;
  1725. if ((isInNameNode || isInTypeRef))
  1726. {
  1727. if (methodDeclaration->mNameNode != NULL)
  1728. filter = methodDeclaration->mNameNode->ToString();
  1729. else if (methodDeclaration->mReturnType != NULL)
  1730. filter = methodDeclaration->mReturnType->ToString();
  1731. }
  1732. else if (methodDeclaration->mBody != NULL)
  1733. {
  1734. // We're just inside 'override' - we may be inserting a new method
  1735. mInsertEndIdx = methodDeclaration->mVirtualSpecifier->GetSrcEnd();
  1736. }
  1737. AddOverrides(filter);
  1738. }
  1739. }
  1740. if (methodDeclaration->mReturnType != NULL)
  1741. CheckTypeRef(methodDeclaration->mReturnType, true, isLocalMethod);
  1742. }
  1743. void BfAutoComplete::CheckProperty(BfPropertyDeclaration* propertyDeclaration)
  1744. {
  1745. if (IsAutocompleteNode(propertyDeclaration->mNameNode))
  1746. {
  1747. mInsertStartIdx = propertyDeclaration->mNameNode->GetSrcStart();
  1748. mInsertEndIdx = propertyDeclaration->mNameNode->GetSrcEnd();
  1749. }
  1750. if ((propertyDeclaration->mVirtualSpecifier != NULL) &&
  1751. (propertyDeclaration->mVirtualSpecifier->GetToken() == BfToken_Override))
  1752. {
  1753. if (!mIsAutoComplete)
  1754. return;
  1755. auto bfParser = propertyDeclaration->mVirtualSpecifier->GetSourceData()->ToParser();
  1756. if (bfParser == NULL)
  1757. return;
  1758. int cursorIdx = bfParser->mCursorIdx;
  1759. bool isInTypeRef = IsAutocompleteNode(propertyDeclaration->mTypeRef);
  1760. bool isInNameNode = IsAutocompleteNode(propertyDeclaration->mNameNode);
  1761. if (((IsAutocompleteNode(propertyDeclaration, 1)) && (cursorIdx == propertyDeclaration->mVirtualSpecifier->GetSrcEnd())) ||
  1762. (isInTypeRef) || (isInNameNode))
  1763. {
  1764. mInsertStartIdx = propertyDeclaration->mVirtualSpecifier->GetSrcStart();
  1765. String filter;
  1766. if ((isInNameNode || isInTypeRef))
  1767. {
  1768. BfAstNode* defNode = NULL;
  1769. if (isInNameNode)
  1770. defNode = propertyDeclaration->mNameNode;
  1771. else if (isInTypeRef)
  1772. defNode = propertyDeclaration->mTypeRef;
  1773. filter = defNode->ToString();
  1774. mInsertEndIdx = defNode->GetSrcEnd();
  1775. }
  1776. else if (propertyDeclaration->mTypeRef != NULL)
  1777. {
  1778. // We're just inside 'override' - we may be inserting a new method
  1779. mInsertEndIdx = propertyDeclaration->mVirtualSpecifier->GetSrcEnd();
  1780. }
  1781. else
  1782. {
  1783. mInsertEndIdx = propertyDeclaration->mVirtualSpecifier->GetSrcEnd();
  1784. }
  1785. AddOverrides(filter);
  1786. }
  1787. }
  1788. else
  1789. {
  1790. if (propertyDeclaration->mTypeRef != NULL)
  1791. CheckTypeRef(propertyDeclaration->mTypeRef, true);
  1792. }
  1793. }
  1794. void BfAutoComplete::CheckVarResolution(BfAstNode* varTypeRef, BfType* resolvedType)
  1795. {
  1796. if (IsAutocompleteNode(varTypeRef))
  1797. {
  1798. if ((resolvedType == NULL) || (resolvedType->IsVar()) || (resolvedType->IsLet()))
  1799. return;
  1800. if (mIsGetDefinition)
  1801. {
  1802. auto typeInst = resolvedType->ToTypeInstance();
  1803. if (typeInst != NULL)
  1804. {
  1805. if (typeInst->mTypeDef->mTypeDeclaration != NULL)
  1806. SetDefinitionLocation(typeInst->mTypeDef->mTypeDeclaration->mNameNode);
  1807. }
  1808. }
  1809. if (mResolveType == BfResolveType_GetVarType)
  1810. {
  1811. mVarTypeName = mModule->TypeToString(resolvedType);
  1812. }
  1813. }
  1814. }
  1815. void BfAutoComplete::CheckLocalDef(BfIdentifierNode* identifierNode, BfLocalVariable* varDecl)
  1816. {
  1817. CheckLocalRef(identifierNode, varDecl);
  1818. }
  1819. void BfAutoComplete::CheckLocalRef(BfIdentifierNode* identifierNode, BfLocalVariable* varDecl)
  1820. {
  1821. if (mReplaceLocalId != -1)
  1822. return;
  1823. if (mResolveType == BfResolveType_GoToDefinition)
  1824. {
  1825. if (IsAutocompleteNode(identifierNode))
  1826. {
  1827. if (varDecl->mNameNode != NULL)
  1828. SetDefinitionLocation(varDecl->mNameNode);
  1829. }
  1830. }
  1831. else if (mResolveType == BfResolveType_GetSymbolInfo)
  1832. {
  1833. if ((IsAutocompleteNode(identifierNode)) &&
  1834. ((!varDecl->mIsShadow) || (varDecl->mShadowedLocal != NULL)))
  1835. {
  1836. if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) &&
  1837. (!mModule->mCurMethodState->mClosureState->mCapturing))
  1838. {
  1839. // For closures, only get locals during the 'capturing' stage
  1840. return;
  1841. }
  1842. auto rootMethodInstance = mModule->mCurMethodState->GetRootMethodState()->mMethodInstance;
  1843. if (rootMethodInstance == NULL)
  1844. return;
  1845. auto resolvePassData = mModule->mCompiler->mResolvePassData;
  1846. mReplaceLocalId = varDecl->mLocalVarId;
  1847. mDefType = mModule->mCurTypeInstance->mTypeDef;
  1848. mDefMethod = rootMethodInstance->mMethodDef;
  1849. if (mInsertStartIdx == -1)
  1850. {
  1851. mInsertStartIdx = identifierNode->GetSrcStart();
  1852. mInsertEndIdx = identifierNode->GetSrcEnd();
  1853. }
  1854. }
  1855. }
  1856. }
  1857. void BfAutoComplete::CheckFieldRef(BfIdentifierNode* identifierNode, BfFieldInstance* fieldInst)
  1858. {
  1859. if (mResolveType == BfResolveType_GetSymbolInfo)
  1860. {
  1861. if (mDefField != NULL)
  1862. return;
  1863. if (IsAutocompleteNode(identifierNode))
  1864. {
  1865. while (true)
  1866. {
  1867. if (auto qualifiedName = BfNodeDynCast<BfQualifiedNameNode>(identifierNode))
  1868. {
  1869. identifierNode = qualifiedName->mRight;
  1870. if (!IsAutocompleteNode(identifierNode))
  1871. return;
  1872. }
  1873. else
  1874. break;
  1875. }
  1876. //mReplaceTypeDef = fieldInst->mOwner->mTypeDef;
  1877. //mReplaceFieldDef = fieldInst->GetFieldDef();
  1878. mDefType = fieldInst->mOwner->mTypeDef;
  1879. mDefField = fieldInst->GetFieldDef();
  1880. mInsertStartIdx = identifierNode->GetSrcStart();
  1881. mInsertEndIdx = identifierNode->GetSrcEnd();
  1882. }
  1883. }
  1884. }
  1885. void BfAutoComplete::CheckLabel(BfIdentifierNode* identifierNode, BfAstNode* precedingNode)
  1886. {
  1887. String filter;
  1888. if (identifierNode != NULL)
  1889. {
  1890. if (!IsAutocompleteNode(identifierNode))
  1891. return;
  1892. filter = identifierNode->ToString();
  1893. mInsertStartIdx = identifierNode->GetSrcStart();
  1894. mInsertEndIdx = identifierNode->GetSrcEnd();
  1895. }
  1896. else
  1897. {
  1898. if (precedingNode == NULL)
  1899. return;
  1900. int expectSpacing = 1;
  1901. if (auto precedingToken = BfNodeDynCast<BfTokenNode>(precedingNode))
  1902. if (precedingToken->GetToken() == BfToken_Colon)
  1903. expectSpacing = 0;
  1904. if (!IsAutocompleteNode(precedingNode, expectSpacing))
  1905. return;
  1906. auto bfParser = precedingNode->GetSourceData()->ToParser();
  1907. if (bfParser->mCursorIdx != precedingNode->GetSrcEnd() + expectSpacing - 1)
  1908. return;
  1909. mInsertStartIdx = precedingNode->GetSrcEnd() + expectSpacing;
  1910. mInsertEndIdx = mInsertStartIdx;
  1911. }
  1912. auto checkScope = mModule->mCurMethodState->mCurScope;
  1913. while (checkScope != NULL)
  1914. {
  1915. if (!checkScope->mLabel.empty())
  1916. AddEntry(AutoCompleteEntry("label", checkScope->mLabel), filter);
  1917. checkScope = checkScope->mPrevScope;
  1918. }
  1919. }
  1920. void BfAutoComplete::AddTypeInstanceEntry(BfTypeInstance* typeInst)
  1921. {
  1922. String bestTypeName = mModule->TypeToString(typeInst, BfTypeNameFlag_ReduceName);
  1923. if (typeInst->IsValueType())
  1924. AddEntry(AutoCompleteEntry("valuetype", bestTypeName));
  1925. else
  1926. AddEntry(AutoCompleteEntry("class", bestTypeName));
  1927. mDefaultSelection = bestTypeName;
  1928. }
  1929. void BfAutoComplete::CheckDocumentation(AutoCompleteEntry* entry, BfCommentNode* documentation)
  1930. {
  1931. }
  1932. void BfAutoComplete::CheckEmptyStart(BfAstNode* prevNode, BfType* type)
  1933. {
  1934. // Temporarily (?) removed?
  1935. return;
  1936. if (IsAutocompleteNode(prevNode, 2))
  1937. {
  1938. if (!type->IsEnum())
  1939. return;
  1940. int wantCursorIdx = prevNode->GetSrcEnd() - 1;
  1941. String prevNodeString = prevNode->ToString();
  1942. if (prevNodeString != "(")
  1943. wantCursorIdx++;
  1944. if (prevNode->GetSourceData()->ToParser()->mCursorIdx != wantCursorIdx)
  1945. return;
  1946. AddTypeInstanceEntry(type->ToTypeInstance());
  1947. CheckIdentifier(NULL);
  1948. mInsertStartIdx = wantCursorIdx + 1;
  1949. mInsertEndIdx = mInsertStartIdx;
  1950. }
  1951. }
  1952. bool BfAutoComplete::CheckFixit(BfAstNode* node)
  1953. {
  1954. if (mIgnoreFixits)
  1955. return false;
  1956. if (mCompiler->mResolvePassData->mResolveType != BfResolveType_GetFixits)
  1957. return false;
  1958. if (!IsAutocompleteLineNode(node))
  1959. return false;
  1960. if (mInsertStartIdx == -1)
  1961. {
  1962. mInsertStartIdx = node->GetSrcStart();
  1963. mInsertEndIdx = node->GetSrcStart();
  1964. }
  1965. return true;
  1966. }
  1967. void BfAutoComplete::FixitAddMember(BfTypeInstance* typeInst, BfType* fieldType, const StringImpl& fieldName, bool isStatic, BfTypeInstance* referencedFrom)
  1968. {
  1969. if (typeInst == mModule->mContext->mBfObjectType)
  1970. return;
  1971. auto parser = typeInst->mTypeDef->mSource->ToParser();
  1972. if (parser == NULL)
  1973. return;
  1974. String fullName = typeInst->mTypeDef->mFullName.ToString();
  1975. String fieldStr;
  1976. if (typeInst == referencedFrom)
  1977. {
  1978. // Implicitly private
  1979. }
  1980. else if ((referencedFrom != NULL) && (mModule->TypeIsSubTypeOf(referencedFrom, typeInst)))
  1981. {
  1982. fieldStr += "protected ";
  1983. }
  1984. else
  1985. {
  1986. fieldStr += "public ";
  1987. }
  1988. if (isStatic)
  1989. fieldStr += "static ";
  1990. if (fieldType != NULL)
  1991. fieldStr += mModule->TypeToString(fieldType, BfTypeNameFlag_ReduceName);
  1992. else
  1993. fieldStr += "Object";
  1994. fieldStr += " " + fieldName + ";";
  1995. int fileLoc = typeInst->mTypeDef->mTypeDeclaration->GetSrcEnd();
  1996. if (auto defineBlock = BfNodeDynCast<BfBlock>(typeInst->mTypeDef->mTypeDeclaration->mDefineNode))
  1997. fileLoc = BfFixitFinder::FindLineStartAfter(defineBlock->mOpenBrace);
  1998. if (!typeInst->mTypeDef->mFields.empty())
  1999. {
  2000. auto fieldDecl = typeInst->mTypeDef->mFields.back()->mFieldDeclaration;
  2001. if (fieldDecl != NULL)
  2002. {
  2003. fileLoc = BfFixitFinder::FindLineStartAfter(fieldDecl);
  2004. }
  2005. }
  2006. AddEntry(AutoCompleteEntry("fixit", StrFormat("Create field '%s' in '%s'\taddField|%s|%d||%s", fieldName.c_str(), fullName.c_str(), parser->mFileName.c_str(), fileLoc, fieldStr.c_str()).c_str()));
  2007. }