1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338 |
- #include "BfAutoComplete.h"
- #include "BfParser.h"
- #include "BfExprEvaluator.h"
- #include "BfSourceClassifier.h"
- #include "BfResolvePass.h"
- #include "BfFixits.h"
- #pragma warning(disable:4996)
- using namespace llvm;
- USING_NS_BF;
- AutoCompleteBase::AutoCompleteBase()
- {
- mIsGetDefinition = false;
- mIsAutoComplete = true;
- mInsertStartIdx = -1;
- mInsertEndIdx = -1;
- }
- AutoCompleteBase::~AutoCompleteBase()
- {
- Clear();
- }
- AutoCompleteEntry* AutoCompleteBase::AddEntry(const AutoCompleteEntry& entry, const StringImpl& filter)
- {
- if (!DoesFilterMatch(entry.mDisplay, filter.c_str()))
- return NULL;
- return AddEntry(entry);
- }
- AutoCompleteEntry* AutoCompleteBase::AddEntry(const AutoCompleteEntry& entry)
- {
- if (mEntriesSet.mAllocSize == 0)
- {
- mEntriesSet.Reserve(128);
- }
- AutoCompleteEntry* insertedEntry = NULL;
- if (mEntriesSet.TryAdd(entry, &insertedEntry))
- {
- insertedEntry->mEntryType = entry.mEntryType;
- int size = (int)strlen(entry.mDisplay) + 1;
- insertedEntry->mDisplay = (char*)mAlloc.AllocBytes(size);
- memcpy((char*)insertedEntry->mDisplay, entry.mDisplay, size);
- }
- return insertedEntry;
- }
- bool AutoCompleteBase::DoesFilterMatch(const char* entry, const char* filter)
- {
- if (mIsGetDefinition)
- {
- int entryLen = (int)strlen(entry);
- if (entry[entryLen - 1] == '=')
- return (strncmp(filter, entry, entryLen - 1) == 0);
- return (strcmp(filter, entry) == 0);
- }
-
- if (!mIsAutoComplete)
- return false;
- if (filter[0] == 0)
- return true;
- int filterLen = (int)strlen(filter);
- int entryLen = (int)strlen(entry);
- bool hasUnderscore = false;
- bool checkInitials = filterLen > 1;
- for (int i = 0; i < (int)filterLen; i++)
- {
- char c = filter[i];
- if (c == '_')
- hasUnderscore = true;
- else if (islower((uint8)filter[i]))
- checkInitials = false;
- }
- if (hasUnderscore)
- return strnicmp(filter, entry, filterLen) == 0;
- char initialStr[256];
- char* initialStrP = initialStr;
- //String initialStr;
- bool prevWasUnderscore = false;
-
- for (int entryIdx = 0; entryIdx < entryLen; entryIdx++)
- {
- char entryC = entry[entryIdx];
- if (entryC == '_')
- {
- prevWasUnderscore = true;
- continue;
- }
- if ((entryIdx == 0) || (prevWasUnderscore) || (isupper((uint8)entryC) || (isdigit((uint8)entryC))))
- {
- if (strnicmp(filter, entry + entryIdx, filterLen) == 0)
- return true;
- if (checkInitials)
- *(initialStrP++) = entryC;
- }
- prevWasUnderscore = false;
- if (filterLen == 1)
- break; // Don't check inners for single-character case
- }
- if (!checkInitials)
- return false;
- *(initialStrP++) = 0;
- return strnicmp(filter, initialStr, filterLen) == 0;
- }
- void AutoCompleteBase::Clear()
- {
- //mEntries.clear();
- mAlloc.Clear();
- mEntriesSet.Clear();
- }
- //////////////////////////////////////////////////////////////////////////
- BfAutoComplete::BfAutoComplete(BfResolveType resolveType)
- {
- mResolveType = resolveType;
- mModule = NULL;
- mCompiler = NULL;
- mSystem = NULL;
- mIsCapturingMethodMatchInfo = false;
- mIgnoreFixits = false;
- mHasFriendSet = false;
- mUncertain = false;
- mMethodMatchInfo = NULL;
- mIsGetDefinition =
- (resolveType == BfResolveType_GetSymbolInfo) ||
- (resolveType == BfResolveType_GoToDefinition);
- mIsAutoComplete = (resolveType == BfResolveType_Autocomplete);
- mGetDefinitionNode = NULL;
- mShowAttributeProperties = NULL;
- mIdentifierUsed = NULL;
- //mReplaceMethodInstance = NULL;
- mReplaceLocalId = -1;
- mDefType = NULL;
- mDefField = NULL;
- mDefMethod = NULL;
- mDefProp = NULL;
- mDefMethodGenericParamIdx = -1;
- mDefTypeGenericParamIdx = -1;
- mCursorLineStart = -1;
- mCursorLineEnd = -1;
- }
- BfAutoComplete::~BfAutoComplete()
- {
- Clear();
- }
- void BfAutoComplete::SetModule(BfModule* module)
- {
- mModule = module;
- mCompiler = mModule->mCompiler;
- mSystem = mCompiler->mSystem;
- }
- void BfAutoComplete::Clear()
- {
- if (mMethodMatchInfo != NULL)
- {
- if (mMethodMatchInfo->mInstanceList.size() == 0)
- {
- delete mMethodMatchInfo;
- mMethodMatchInfo = NULL;
- }
- else
- {
- // Keep mBestIdx - for when we match but then backspace
- mMethodMatchInfo->mPrevBestIdx = mMethodMatchInfo->mBestIdx;
- mMethodMatchInfo->mMostParamsMatched = 0;
- mMethodMatchInfo->mHadExactMatch = false;
- mMethodMatchInfo->mInstanceList.Clear();
- mMethodMatchInfo->mSrcPositions.Clear();
- }
- }
-
- mInsertStartIdx = -1;
- mInsertEndIdx = -1;
- mIsCapturingMethodMatchInfo = false;
-
- AutoCompleteBase::Clear();
- }
- void BfAutoComplete::RemoveMethodMatchInfo()
- {
- mIsCapturingMethodMatchInfo = false;
- delete mMethodMatchInfo;
- mMethodMatchInfo = NULL;
- }
- void BfAutoComplete::ClearMethodMatchEntries()
- {
- mMethodMatchInfo->mInstanceList.Clear();
- }
- int BfAutoComplete::GetCursorIdx(BfAstNode* node)
- {
- if (node == NULL)
- return -1;
- if ((!mCompiler->mIsResolveOnly) || (!node->IsFromParser(mCompiler->mResolvePassData->mParser)))
- return -1;
- auto bfParser = node->GetSourceData()->ToParser();
- if ((bfParser->mParserFlags & ParserFlag_Autocomplete) == 0)
- return -1;
- return bfParser->mCursorIdx;
- }
- bool BfAutoComplete::IsAutocompleteNode(BfAstNode* node, int lengthAdd, int startAdd)
- {
- if (node == NULL)
- return false;
- if ((!mCompiler->mIsResolveOnly) || (!node->IsFromParser(mCompiler->mResolvePassData->mParser)))
- return false;
- auto bfParser = node->GetSourceData()->ToParser();
- if ((bfParser->mParserFlags & ParserFlag_Autocomplete) == 0)
- return false;
-
- //if (mCompiler->mResolvePassData->mResolveType != BfResolveType_Autocomplete)
- lengthAdd++;
- int cursorIdx = bfParser->mCursorCheckIdx;
- int nodeSrcStart = node->GetSrcStart();
- if ((cursorIdx < nodeSrcStart + startAdd) || (cursorIdx >= node->GetSrcEnd() + lengthAdd))
- return false;
- return true;
- }
- bool BfAutoComplete::IsAutocompleteNode(BfAstNode* startNode, BfAstNode* endNode, int lengthAdd, int startAdd)
- {
- if ((startNode == NULL) || (endNode == NULL))
- return false;
- if ((!mCompiler->mIsResolveOnly) || (!startNode->IsFromParser(mCompiler->mResolvePassData->mParser)))
- return false;
- auto bfParser = startNode->GetSourceData()->ToParser();
- if ((bfParser->mParserFlags & ParserFlag_Autocomplete) == 0)
- return false;
- //if (mCompiler->mResolvePassData->mResolveType != BfResolveType_Autocomplete)
- lengthAdd++;
- int cursorIdx = bfParser->mCursorCheckIdx;
- int nodeSrcStart = startNode->GetSrcStart();
- if ((cursorIdx < nodeSrcStart + startAdd) || (cursorIdx >= endNode->GetSrcEnd() + lengthAdd))
- return false;
- return true;
- }
- bool BfAutoComplete::IsAutocompleteLineNode(BfAstNode* node)
- {
- if (node == NULL)
- return false;
- if ((!mCompiler->mIsResolveOnly) || (!node->IsFromParser(mCompiler->mResolvePassData->mParser)))
- return false;
- auto bfParser = node->GetSourceData()->ToParser();
- if ((bfParser->mParserFlags & ParserFlag_Autocomplete) == 0)
- return false;
- int startAdd = 0;
-
- if (mCursorLineStart == -1)
- {
- auto nodeSource = node->GetSourceData();
- mCursorLineStart = bfParser->mCursorIdx;
- while (mCursorLineStart > 0)
- {
- if (nodeSource->mSrc[mCursorLineStart - 1] == '\n')
- break;
- mCursorLineStart--;
- }
- mCursorLineEnd = bfParser->mCursorIdx;
- while (mCursorLineEnd < nodeSource->mSrcLength)
- {
- if (nodeSource->mSrc[mCursorLineEnd] == '\n')
- break;
- mCursorLineEnd++;
- }
- }
- int srcStart = node->GetSrcStart();
- return (srcStart >= mCursorLineStart) && (srcStart <= mCursorLineEnd);
- }
- // The parser thought this was a type reference but it may not be
- BfTypedValue BfAutoComplete::LookupTypeRefOrIdentifier(BfAstNode* node, bool* isStatic, BfEvalExprFlags evalExprFlags, BfType* expectingType)
- {
- SetAndRestoreValue<bool> prevIgnoreClassifying(mModule->mIsInsideAutoComplete, true);
- if (auto typeRef = BfNodeDynCast<BfTypeReference>(node))
- {
- auto type = mModule->ResolveTypeRef(typeRef);
- if (type != NULL)
- {
- *isStatic = true;
- return BfTypedValue(type);
- }
- if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(typeRef))
- {
- BfExprEvaluator exprEvaluator(mModule);
- auto identifierResult = exprEvaluator.LookupIdentifier(namedTypeRef->mNameNode);
- if (identifierResult)
- return identifierResult;
- return exprEvaluator.GetResult(); // We need 'GetResult' to read property values
- }
- else if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef))
- {
- auto leftValue = LookupTypeRefOrIdentifier(qualifiedTypeRef->mLeft, isStatic);
- if (leftValue.mType)
- {
- if (leftValue.mType->IsPointer())
- {
- mModule->LoadValue(leftValue);
- leftValue.mType = leftValue.mType->GetUnderlyingType();
- leftValue.mKind = BfTypedValueKind_Addr;
- }
- if (auto rightNamedTypeRef = BfNodeDynCast<BfNamedTypeReference>(qualifiedTypeRef->mRight))
- {
- // This keeps the classifier from colorizing properties - this causes 'flashing' when we go back over this with a resolve pass
- // that wouldn't catch this
- SetAndRestoreValue<BfSourceClassifier*> prevClassifier(mModule->mCompiler->mResolvePassData->mSourceClassifier, NULL);
- BfExprEvaluator exprEvaluator(mModule);
- auto fieldResult = exprEvaluator.LookupField(qualifiedTypeRef->mRight, leftValue, rightNamedTypeRef->mNameNode->ToString());
- if (!fieldResult) // Was property?
- fieldResult = exprEvaluator.GetResult();
- *isStatic = false;
- return fieldResult;
- }
- }
- }
- }
- if (auto identifier = BfNodeDynCast<BfIdentifierNode>(node))
- {
- BfExprEvaluator exprEvaluator(mModule);
- auto identifierResult = exprEvaluator.LookupIdentifier(identifier, false, NULL);
- if (!identifierResult)
- identifierResult = exprEvaluator.GetResult();
- if (identifierResult)
- return identifierResult;
-
- if (auto qualifiedIdentifier = BfNodeDynCast<BfQualifiedNameNode>(node))
- {
- bool leftIsStatic = false;
- auto leftValue = LookupTypeRefOrIdentifier(qualifiedIdentifier->mLeft, &leftIsStatic);
- if (leftValue.mType)
- {
- auto findName = qualifiedIdentifier->mRight->ToString();
- if (findName == "base")
- {
- return BfTypedValue(leftValue);
- }
- BfExprEvaluator exprEvaluator(mModule);
- auto fieldResult = exprEvaluator.LookupField(node, leftValue, findName);
- if (fieldResult)
- return fieldResult;
- auto result = exprEvaluator.GetResult();
- if (result)
- return result;
- }
- }
- auto type = mModule->ResolveTypeRef(identifier, NULL);
- if (type != NULL)
- {
- *isStatic = true;
- return BfTypedValue(type);
- }
- }
- else if (auto memberRefExpr = BfNodeDynCast<BfMemberReferenceExpression>(node))
- {
- return mModule->CreateValueFromExpression(memberRefExpr, expectingType, evalExprFlags);
- }
- else if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(node))
- {
- // Don't pass BfEvalExprFlags_IgnoreNullConditional, since parenExprs end nullable chains and we actually
- // DO want the nullable at this point
- return mModule->CreateValueFromExpression(parenExpr);
- }
- else if (auto targetExpr = BfNodeDynCast<BfExpression>(node))
- {
- return mModule->CreateValueFromExpression(targetExpr, NULL, evalExprFlags);
- }
- return BfTypedValue();
-
- }
- void BfAutoComplete::SetDefinitionLocation(BfAstNode* astNode, bool force)
- {
- if (mIsGetDefinition)
- {
- if ((mGetDefinitionNode == NULL) || (force))
- mGetDefinitionNode = astNode;
- }
- }
- bool BfAutoComplete::IsAttribute(BfTypeInstance* typeInst)
- {
- auto checkTypeInst = typeInst;
- while (checkTypeInst != NULL)
- {
- if (checkTypeInst->mTypeDef == mModule->mCompiler->mAttributeTypeDef)
- return true;
- checkTypeInst = checkTypeInst->mBaseType;
- }
- return false;
- }
- void BfAutoComplete::AddMethod(BfMethodDeclaration* methodDecl, const StringImpl& methodName, const StringImpl& filter)
- {
- String replaceName;
- AutoCompleteEntry entry("method", methodName);
- if (methodDecl != NULL)
- {
- if (methodDecl->mMixinSpecifier != NULL)
- {
- replaceName = entry.mDisplay;
- replaceName += "!";
- entry.mDisplay = replaceName.c_str();
- entry.mEntryType = "mixin";
- }
- entry.mDocumentation = methodDecl->mDocumentation;
- }
- AddEntry(entry, filter);
- }
- void BfAutoComplete::AddTypeDef(BfTypeDef* typeDef, const StringImpl& filter, bool onlyAttribute)
- {
- StringT<64> name(typeDef->mName->ToString());
- if (name == "@")
- return;
- int gravePos = (int)name.IndexOf('`');
- if (gravePos != -1)
- name = name.Substring(0, gravePos) + "<>";
-
- if (onlyAttribute)
- {
- if ((mIsGetDefinition) && (name == filter + "Attribute"))
- {
- SetDefinitionLocation(typeDef->mTypeDeclaration->mNameNode);
- return;
- }
- if (!DoesFilterMatch(name.c_str(), filter.c_str()))
- return;
- auto type = mModule->ResolveTypeDef(typeDef, BfPopulateType_Declaration);
- if (type != NULL)
- {
- auto typeInst = type->ToTypeInstance();
- if (!IsAttribute(typeInst))
- return;
- }
- const char* attrStr = "Attribute";
- const int attrStrLen = (int)strlen(attrStr);
- if (((int)name.length() > attrStrLen) && ((int)name.length() - (int)attrStrLen >= filter.length()) && (strcmp(name.c_str() + (int)name.length() - attrStrLen, attrStr) == 0))
- {
- // Shorter name - remove "Attribute"
- name = name.Substring(0, name.length() - attrStrLen);
- }
- }
- AutoCompleteEntry* entryAdded = NULL;
- if (typeDef->mTypeCode == BfTypeCode_Object)
- entryAdded = AddEntry(AutoCompleteEntry("class", name, typeDef->mTypeDeclaration->mDocumentation), filter);
- else if (typeDef->mTypeCode == BfTypeCode_Interface)
- entryAdded = AddEntry(AutoCompleteEntry("interface", name, typeDef->mTypeDeclaration->mDocumentation), filter);
- else
- entryAdded = AddEntry(AutoCompleteEntry("valuetype", name, typeDef->mTypeDeclaration->mDocumentation), filter);
- if ((entryAdded != NULL) && (mIsGetDefinition))
- {
-
- }
- }
- bool BfAutoComplete::CheckProtection(BfProtection protection, bool allowProtected, bool allowPrivate)
- {
- return (mHasFriendSet) || (protection == BfProtection_Public) ||
- ((protection == BfProtection_Protected) && (allowProtected)) ||
- ((protection == BfProtection_Private) && (allowPrivate));
- }
- const char* BfAutoComplete::GetTypeName(BfType* type)
- {
- if (type != NULL)
- {
- if (type->IsPointer())
- return "pointer";
- if (type->IsObjectOrInterface())
- return "object";
- }
- return "value";
- }
- void BfAutoComplete::AddInnerTypes(BfTypeInstance* typeInst, const StringImpl& filter, bool allowProtected, bool allowPrivate)
- {
- for (auto innerType : typeInst->mTypeDef->mNestedTypes)
- {
- if (CheckProtection(innerType->mProtection, allowProtected, allowPrivate))
- AddTypeDef(innerType, filter);
- }
- allowPrivate = false;
- if (typeInst->mBaseType != NULL)
- AddInnerTypes(typeInst->mBaseType, filter, allowProtected, allowPrivate);
- }
- void BfAutoComplete::AddCurrentTypes(BfTypeInstance* typeInst, const StringImpl& filter, bool allowProtected, bool allowPrivate, bool onlyAttribute)
- {
- if (typeInst != mModule->mCurTypeInstance)
- AddTypeDef(typeInst->mTypeDef, filter, onlyAttribute);
- auto typeDef = typeInst->mTypeDef;
- for (auto nestedTypeDef : typeDef->mNestedTypes)
- {
- if (nestedTypeDef->mIsPartial)
- {
- nestedTypeDef = mSystem->GetCombinedPartial(nestedTypeDef);
- if (nestedTypeDef == NULL)
- continue;
- }
- if (CheckProtection(nestedTypeDef->mProtection, allowProtected, allowPrivate))
- AddTypeDef(nestedTypeDef, filter, onlyAttribute);
- }
- auto outerType = mModule->GetOuterType(typeInst);
- if (outerType != NULL)
- AddCurrentTypes(outerType, filter, allowProtected, allowPrivate, onlyAttribute);
- allowPrivate = false;
- auto baseType = mModule->GetBaseType(typeInst);
- if (baseType != NULL)
- AddCurrentTypes(baseType, filter, allowProtected, allowPrivate, onlyAttribute);
- }
- void BfAutoComplete::AddTypeMembers(BfTypeInstance* typeInst, bool addStatic, bool addNonStatic, const StringImpl& filter, BfTypeInstance* startType, bool allowInterfaces, bool allowImplicitThis)
- {
- bool isInterface = false;
-
- auto activeTypeDef = mModule->GetActiveTypeDef();
- #define CHECK_STATIC(staticVal) ((staticVal && addStatic) || (!staticVal && addNonStatic))
- mModule->PopulateType(typeInst, BfPopulateType_Data);
- BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None;
- for (auto& fieldInst : typeInst->mFieldInstances)
- {
- auto fieldDef = fieldInst.GetFieldDef();
- if (fieldDef == NULL)
- continue;
- if (fieldDef->mIsNoShow)
- continue;
- if ((CHECK_STATIC(fieldDef->mIsStatic)) &&
- ((mIsGetDefinition) || (mModule->CheckProtection(protectionCheckFlags, typeInst, fieldDef->mProtection, startType))))
- {
- if ((!typeInst->IsTypeMemberIncluded(fieldDef->mDeclaringType, activeTypeDef, mModule)) ||
- (!typeInst->IsTypeMemberAccessible(fieldDef->mDeclaringType, activeTypeDef)))
- continue;
-
- AutoCompleteEntry entry(GetTypeName(fieldInst.mResolvedType), fieldDef->mName, (fieldDef->mFieldDeclaration != NULL) ? fieldDef->mFieldDeclaration->mDocumentation : NULL);
- if ((AddEntry(entry, filter)) && (mIsGetDefinition))
- {
- if (mDefType == NULL)
- {
- mDefType = typeInst->mTypeDef;
- mDefField = fieldDef;
- if (fieldDef->mFieldDeclaration != NULL)
- SetDefinitionLocation(fieldDef->mFieldDeclaration->mNameNode);
- }
- }
- }
- }
- for (auto methodDef : typeInst->mTypeDef->mMethods)
- {
- if (methodDef->mIsOverride)
- continue;
- if (methodDef->mIsNoShow)
- continue;
- if (methodDef->mName.IsEmpty())
- continue;
- if (methodDef->mExplicitInterface != NULL)
- continue;
- if ((!typeInst->IsTypeMemberIncluded(methodDef->mDeclaringType, activeTypeDef, mModule)) ||
- (!typeInst->IsTypeMemberAccessible(methodDef->mDeclaringType, activeTypeDef)))
- continue;
- bool canUseMethod;
- canUseMethod = (methodDef->mMethodType == BfMethodType_Normal) || (methodDef->mMethodType == BfMethodType_Mixin);
- if (isInterface)
- {
- // Always allow
- canUseMethod &= addNonStatic;
- }
- else
- {
- canUseMethod &= (CHECK_STATIC(methodDef->mIsStatic) &&
- (mModule->CheckProtection(protectionCheckFlags, typeInst, methodDef->mProtection, startType)));
- }
- if (canUseMethod)
- {
- AddMethod(methodDef->GetMethodDeclaration(), methodDef->mName, filter);
- }
- }
- for (auto propDef : typeInst->mTypeDef->mProperties)
- {
- if (propDef->mIsNoShow)
- continue;
- if ((!typeInst->IsTypeMemberIncluded(propDef->mDeclaringType, activeTypeDef, mModule)) ||
- (!typeInst->IsTypeMemberAccessible(propDef->mDeclaringType, activeTypeDef)))
- continue;
- if ((CHECK_STATIC(propDef->mIsStatic)) && (mModule->CheckProtection(protectionCheckFlags, typeInst, propDef->mProtection, startType)))
- {
- if ((!allowInterfaces) && (propDef->HasExplicitInterface()))
- continue;
- if (propDef->mName == "[]")
- continue;
- BfCommentNode* documentation = NULL;
- if (propDef->mFieldDeclaration != NULL)
- documentation = propDef->mFieldDeclaration->mDocumentation;
- AutoCompleteEntry entry("property", propDef->mName, documentation);
- if ((AddEntry(entry, filter)) && (mIsGetDefinition) && (propDef->mFieldDeclaration != NULL))
- SetDefinitionLocation(propDef->mFieldDeclaration->mNameNode);
- }
- }
-
- if (allowInterfaces)
- {
- for (auto iface : typeInst->mInterfaces)
- AddTypeMembers(iface.mInterfaceType, addStatic, addNonStatic, filter, startType, false, allowImplicitThis);
- }
- if (typeInst->mBaseType != NULL)
- AddTypeMembers(typeInst->mBaseType, addStatic, addNonStatic, filter, startType, false, allowImplicitThis);
- else
- {
- if (typeInst->IsStruct())
- AddTypeMembers(mModule->mContext->mBfObjectType, addStatic, addNonStatic, filter, startType, false, allowImplicitThis);
- }
- if ((addStatic) && (allowImplicitThis))
- {
- auto outerType = mModule->GetOuterType(typeInst);
- if (outerType != NULL)
- {
- AddTypeMembers(outerType, true, false, filter, startType, false, allowImplicitThis);
- }
- }
- }
- void BfAutoComplete::AddSelfResultTypeMembers(BfTypeInstance* typeInst, BfTypeInstance* selfType, const StringImpl& filter, bool allowPrivate)
- {
- bool isInterface = false;
- bool allowProtected = allowPrivate;
- auto activeTypeDef = mModule->GetActiveTypeDef();
- mModule->PopulateType(typeInst, BfPopulateType_Data);
- for (auto& fieldInst : typeInst->mFieldInstances)
- {
- auto fieldDef = fieldInst.GetFieldDef();
- if (fieldDef == NULL)
- continue;
- if (fieldDef->mIsNoShow)
- continue;
-
- if ((fieldDef->mIsStatic) && (CheckProtection(fieldDef->mProtection, allowProtected, allowPrivate)))
- {
- if (!mModule->CanImplicitlyCast(BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), fieldInst.mResolvedType), selfType))
- continue;
- if ((!typeInst->IsTypeMemberIncluded(fieldDef->mDeclaringType, activeTypeDef, mModule)) ||
- (!typeInst->IsTypeMemberAccessible(fieldDef->mDeclaringType, activeTypeDef)))
- continue;
- AutoCompleteEntry entry(GetTypeName(fieldInst.mResolvedType), fieldDef->mName, fieldDef->mFieldDeclaration->mDocumentation);
- if ((AddEntry(entry, filter)) && (mIsGetDefinition))
- {
- if (mDefType == NULL)
- {
- mDefType = typeInst->mTypeDef;
- mDefField = fieldDef;
- if (fieldDef->mFieldDeclaration != NULL)
- SetDefinitionLocation(fieldDef->mFieldDeclaration->mNameNode);
- }
- }
- }
- }
- for (auto methodDef : typeInst->mTypeDef->mMethods)
- {
- if (methodDef->mIsOverride)
- continue;
- if (methodDef->mIsNoShow)
- continue;
- if (methodDef->mName.IsEmpty())
- continue;
- if (methodDef->mExplicitInterface != NULL)
- continue;
- if ((!typeInst->IsTypeMemberIncluded(methodDef->mDeclaringType, activeTypeDef, mModule)) ||
- (!typeInst->IsTypeMemberAccessible(methodDef->mDeclaringType, activeTypeDef)))
- continue;
- if (!methodDef->mIsStatic)
- continue;
- bool canUseMethod;
- canUseMethod = (methodDef->mMethodType == BfMethodType_Normal) || (methodDef->mMethodType == BfMethodType_Mixin);
- canUseMethod &= CheckProtection(methodDef->mProtection, allowProtected, allowPrivate);
-
- if (methodDef->mMethodType != BfMethodType_Normal)
- continue;
- auto methodInstance = mModule->GetRawMethodInstanceAtIdx(typeInst, methodDef->mIdx);
- if (methodInstance == NULL)
- continue;
- if (methodInstance->mReturnType->IsUnspecializedType())
- continue;
- if (!mModule->CanImplicitlyCast(BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), methodInstance->mReturnType), selfType))
- continue;
- if (canUseMethod)
- {
- if (auto methodDeclaration = methodDef->GetMethodDeclaration())
- {
- String replaceName;
- AutoCompleteEntry entry("method", methodDef->mName, methodDeclaration->mDocumentation);
- if ((AddEntry(entry, filter)) && (mIsGetDefinition))
- {
- }
- }
- }
- }
- for (auto propDef : typeInst->mTypeDef->mProperties)
- {
- if (propDef->mIsNoShow)
- continue;
- if ((!typeInst->IsTypeMemberIncluded(propDef->mDeclaringType, activeTypeDef, mModule)) ||
- (!typeInst->IsTypeMemberAccessible(propDef->mDeclaringType, activeTypeDef)))
- continue;
- if (!propDef->mIsStatic)
- continue;
- BfMethodDef* getMethod = NULL;
- for (auto methodDef : propDef->mMethods)
- {
- if (methodDef->mMethodType == BfMethodType_PropertyGetter)
- {
- getMethod = methodDef;
- break;
- }
- }
- if (getMethod == NULL)
- continue;
- auto methodInstance = mModule->GetRawMethodInstanceAtIdx(typeInst, getMethod->mIdx);
- if (methodInstance == NULL)
- continue;
- if (methodInstance->mReturnType != selfType)
- continue;
- if (CheckProtection(propDef->mProtection, allowProtected, allowPrivate))
- {
- if (propDef->HasExplicitInterface())
- continue;
- if (propDef->mName == "[]")
- continue;
- AutoCompleteEntry entry("property", propDef->mName, propDef->mFieldDeclaration->mDocumentation);
- if ((AddEntry(entry, filter)) && (mIsGetDefinition))
- SetDefinitionLocation(propDef->mFieldDeclaration->mNameNode);
- }
- }
-
- auto outerType = mModule->GetOuterType(typeInst);
- if (outerType != NULL)
- {
- AddSelfResultTypeMembers(outerType, selfType, filter, false);
- }
- }
- bool BfAutoComplete::InitAutocomplete(BfAstNode* dotNode, BfAstNode* nameNode, String& filter)
- {
- if (IsAutocompleteNode(nameNode))
- {
- auto bfParser = nameNode->GetSourceData()->ToParser();
- if (mIsGetDefinition)
- {
- mInsertStartIdx = nameNode->GetSrcStart();
- mInsertEndIdx = nameNode->GetSrcEnd();
- }
- else
- {
- mInsertStartIdx = dotNode->GetSrcEnd();
- mInsertEndIdx = std::min(bfParser->mCursorIdx + 1, nameNode->GetSrcEnd());
- }
- filter.Append(bfParser->mSrc + mInsertStartIdx, mInsertEndIdx - mInsertStartIdx);
- return true;
- }
- if ((dotNode != NULL) && (IsAutocompleteNode(dotNode, 0, 1)))
- {
- mInsertStartIdx = dotNode->GetSrcEnd();
- mInsertEndIdx = dotNode->GetSrcEnd();
- return true;
- }
- return false;
- }
- void BfAutoComplete::AddEnumTypeMembers(BfTypeInstance* typeInst, const StringImpl& filter, bool allowProtected, bool allowPrivate)
- {
- mModule->PopulateType(typeInst, BfPopulateType_Data);
- auto activeTypeDef = mModule->GetActiveTypeDef();
- for (auto& fieldInst : typeInst->mFieldInstances)
- {
- auto fieldDef = fieldInst.GetFieldDef();
- if ((fieldDef != NULL) && (fieldDef->mIsConst) &&
- ((fieldInst.mResolvedType == typeInst) || (fieldInst.mIsEnumPayloadCase)) &&
- (CheckProtection(fieldDef->mProtection, allowProtected, allowPrivate)))
- {
- if ((!typeInst->IsTypeMemberIncluded(fieldDef->mDeclaringType, activeTypeDef, mModule)) ||
- (!typeInst->IsTypeMemberAccessible(fieldDef->mDeclaringType, activeTypeDef)))
- continue;
- bool hasPayload = false;
- if ((fieldInst.mIsEnumPayloadCase) && (fieldInst.mResolvedType->IsTuple()))
- {
- auto payloadType = (BfTupleType*)fieldInst.mResolvedType;
- if (!payloadType->mFieldInstances.empty())
- hasPayload = true;
- }
- AutoCompleteEntry entry(hasPayload ? "payloadEnum" : "value", fieldDef->mName, fieldDef->mFieldDeclaration->mDocumentation);
- if ((AddEntry(entry, filter)) && (mIsGetDefinition))
- {
- mDefType = typeInst->mTypeDef;
- mDefField = fieldDef;
- if (fieldDef->mFieldDeclaration != NULL)
- SetDefinitionLocation(fieldDef->mFieldDeclaration->mNameNode);
- }
- }
- }
- }
- // bool BfAutoComplete::IsInExpression(BfAstNode* node)
- // {
- // if (mModule->mCurMethodInstance != NULL)
- // return true;
- // if (node == NULL)
- // return false;
- // if ((node->IsA<BfExpression>()) && (!node->IsA<BfIdentifierNode>()) && (!node->IsA<BfBlock>()))
- // return true;
- // return IsInExpression(node->mParent);
- // }
- void BfAutoComplete::AddTopLevelNamespaces(BfIdentifierNode* identifierNode)
- {
- String filter;
- if (identifierNode != NULL)
- {
- filter = identifierNode->ToString();
- mInsertStartIdx = identifierNode->GetSrcStart();
- mInsertEndIdx = identifierNode->GetSrcEnd();
- }
- BfProject* bfProject = NULL;
- if (mModule->mCurTypeInstance != NULL)
- bfProject = mModule->mCurTypeInstance->mTypeDef->mProject;
- else
- bfProject = mCompiler->mResolvePassData->mParser->mProject;
-
- auto _AddProjectNamespaces = [&](BfProject* project)
- {
- for (auto namespacePair : project->mNamespaces)
- {
- const BfAtomComposite& namespaceComposite = namespacePair.mKey;
- if (namespaceComposite.GetPartsCount() == 1)
- {
- AddEntry(AutoCompleteEntry("namespace", namespaceComposite.ToString()), filter);
- }
- }
- };
- if (bfProject != NULL)
- {
- for (int depIdx = -1; depIdx < (int) bfProject->mDependencies.size(); depIdx++)
- {
- BfProject* depProject = (depIdx == -1) ? bfProject : bfProject->mDependencies[depIdx];
- _AddProjectNamespaces(depProject);
- }
- }
- else
- {
- for (auto project : mSystem->mProjects)
- _AddProjectNamespaces(project);
- }
- }
- void BfAutoComplete::AddTopLevelTypes(BfIdentifierNode* identifierNode, bool onlyAttribute)
- {
- String filter;
-
- if (identifierNode != NULL)
- {
- filter = identifierNode->ToString();
- mInsertStartIdx = identifierNode->GetSrcStart();
- mInsertEndIdx = identifierNode->GetSrcEnd();
- }
- AddEntry(AutoCompleteEntry("token", "function"), filter);
- AddEntry(AutoCompleteEntry("token", "delegate"), filter);
-
- if (mModule->mCurTypeInstance != NULL)
- {
- if (!onlyAttribute)
- {
- auto activeTypeDef = mModule->GetActiveTypeDef();
- for (auto genericParam : activeTypeDef->mGenericParamDefs)
- AddEntry(AutoCompleteEntry("generic", genericParam->mName), filter);
- }
-
- AddCurrentTypes(mModule->mCurTypeInstance, filter, true, true, onlyAttribute);
- // Do inners
- // bool allowInnerPrivate = false;
- // auto checkTypeInst = mModule->mCurTypeInstance;
- // while (checkTypeInst != NULL)
- // {
- // auto checkTypeDef = checkTypeInst->mTypeDef;
- // for (auto nestedTypeDef : checkTypeDef->mNestedTypes)
- // {
- // if (CheckProtection(nestedTypeDef->mProtection, true, allowInnerPrivate))
- // AddTypeDef(nestedTypeDef, filter, onlyAttribute);
- // }
- //
- // checkTypeInst = mModule->GetOuterType(mModule->mCurTypeInstance);
- // if (checkTypeInst != NULL)
- // AddInnerTypes(checkTypeInst, filter, true, true);
- //
- // AddOuterTypes(checkTypeInst, filter, true, true);
- //
- // checkTypeInst = mModule->GetBaseType(checkTypeInst);
- // allowInnerPrivate = false;
- // }
- // allowInnerPrivate = true;
- // checkTypeInst = mModule->GetOuterType(mModule->mCurTypeInstance);
- // if (checkTypeInst != NULL)
- // AddInnerTypes(checkTypeInst, filter, true, true);
- //
- // AddOuterTypes(mModule->mCurTypeInstance, filter, true, true);
- }
- if (mModule->mCurMethodInstance != NULL)
- {
- if (!onlyAttribute)
- {
- for (auto genericParam : mModule->mCurMethodInstance->mMethodDef->mGenericParams)
- AddEntry(AutoCompleteEntry("generic", genericParam->mName), filter);
- }
- }
- if (!onlyAttribute)
- {
- BfTypeDef* showTypeDef = NULL;
- for (auto& systemTypeDefEntry : mModule->mSystem->mSystemTypeDefs)
- {
- auto systemTypeDef = systemTypeDefEntry.mValue;
- if ((systemTypeDef->mTypeCode == BfTypeCode_IntUnknown) || (systemTypeDef->mTypeCode == BfTypeCode_UIntUnknown))
- continue;
- if ((AddEntry(AutoCompleteEntry("valuetype", systemTypeDef->mName->mString.mPtr), filter)) && (mIsGetDefinition))
- showTypeDef = systemTypeDef;
- }
- if (showTypeDef != NULL)
- {
- auto showType = mModule->ResolveTypeDef(showTypeDef);
- BfTypeInstance* showTypeInst = NULL;
- if (showType->IsPrimitiveType())
- showTypeInst = mModule->GetWrappedStructType(showType);
- else
- showTypeInst = showType->ToTypeInstance();
- if (showTypeInst != NULL)
- SetDefinitionLocation(showTypeInst->mTypeDef->mTypeDeclaration->mNameNode);
- }
- }
- auto activeTypeDef = mModule->GetActiveTypeDef();
- if (activeTypeDef != NULL)
- {
- BfProject* curProject = activeTypeDef->mProject;
- if (mModule->mCurTypeInstance != NULL)
- {
- for (auto innerTypeDef : mModule->mCurTypeInstance->mTypeDef->mNestedTypes)
- {
- if (!mModule->mCurTypeInstance->IsTypeMemberAccessible(innerTypeDef, activeTypeDef))
- continue;
- AddTypeDef(innerTypeDef, filter, onlyAttribute);
- }
- }
- auto& namespaceSearch = activeTypeDef->mNamespaceSearch;
- String prevName;
- for (auto typeDef : mModule->mSystem->mTypeDefs)
- {
- if (typeDef->mIsPartial)
- continue;
- //TODO :Check protection
- if ((curProject != NULL) && (curProject->ContainsReference(typeDef->mProject)))
- {
- bool matches = false;
- if (typeDef->mOuterType == NULL)
- {
- if (((typeDef->mNamespace.IsEmpty()) ||
- (namespaceSearch.Contains(typeDef->mNamespace))))
- matches = true;
- }
- if (matches)
- {
- AddTypeDef(typeDef, filter, onlyAttribute);
- }
- }
- }
-
- // BfStaticSearch* staticSearch;
- // if (mModule->mCurTypeInstance->mStaticSearchMap.TryGetValue(activeTypeDef, &staticSearch))
- // {
- // for (auto typeInst : staticSearch->mStaticTypes)
- // {
- // AddTypeDef(typeInst->mTypeDef, filter, onlyAttribute);
- // }
- // }
- // else if (!activeTypeDef->mStaticSearch.IsEmpty())
- // {
- // BF_ASSERT(mModule->mCompiler->IsAutocomplete());
- // for (auto typeRef : activeTypeDef->mStaticSearch)
- // {
- // auto type = mModule->ResolveTypeRef(typeRef, NULL, BfPopulateType_Declaration);
- // if (type != NULL)
- // {
- // auto typeInst = type->ToTypeInstance();
- // if (typeInst != NULL)
- // AddTypeDef(typeInst->mTypeDef, filter, onlyAttribute);
- // }
- // }
- // }
- }
- else
- {
- BfProject* curProject = NULL;
- if (mModule->mCompiler->mResolvePassData->mParser != NULL)
- curProject = mModule->mCompiler->mResolvePassData->mParser->mProject;
- String prevName;
- for (auto typeDef : mModule->mSystem->mTypeDefs)
- {
- if (typeDef->mIsPartial)
- continue;
- //TODO :Check protection
- if ((curProject != NULL) && (curProject->ContainsReference(typeDef->mProject)))
- {
- bool matches = false;
- if (typeDef->mOuterType == NULL)
- {
- if (typeDef->mNamespace.IsEmpty())
- matches = true;
- }
- if (matches)
- {
- AddTypeDef(typeDef, filter, onlyAttribute);
- }
- }
- }
- }
- }
- void BfAutoComplete::CheckIdentifier(BfIdentifierNode* identifierNode, bool isInExpression, bool isUsingDirective)
- {
- if ((identifierNode != NULL) && (!IsAutocompleteNode(identifierNode)))
- return;
- mIdentifierUsed = identifierNode;
- if ((mModule->mParentNodeEntry != NULL) && (mModule->mCurMethodState != NULL))
- {
- if (auto binExpr = BfNodeDynCast<BfBinaryOperatorExpression>(mModule->mParentNodeEntry->mNode))
- {
- auto parentBlock = mModule->mCurMethodState->mCurScope->mAstBlock;
- if ((identifierNode == binExpr->mRight) && (binExpr->mOp == BfBinaryOp_Multiply) && (parentBlock != NULL))
- {
- // If we are the last identifier in a block then we MAY be a partially-typed variable declaration
- if (parentBlock->mChildArr.back() == binExpr)
- {
- mUncertain = true;
- }
- }
- }
- }
- //bool isUsingDirective = false;
- //bool isUsingDirective = (identifierNode != NULL) && (identifierNode->mParent != NULL) && (identifierNode->mParent->IsA<BfUsingDirective>());
- if (mCompiler->mResolvePassData->mSourceClassifier != NULL)
- {
- //TODO: Color around dots
- //mCompiler->mResolvePassData->mSourceClassifier->SetElementType(identifierNode, BfSourceElementType_Namespace);
- }
-
- if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(identifierNode))
- {
- CheckMemberReference(qualifiedNameNode->mLeft, qualifiedNameNode->mDot, qualifiedNameNode->mRight, false, NULL, isUsingDirective);
- return;
- }
- //bool isInExpression = true;
- // if (identifierNode != NULL)
- // isInExpression = IsInExpression(identifierNode);
-
- AddTopLevelNamespaces(identifierNode);
- if (isUsingDirective)
- return; // Only do namespaces
-
- AddTopLevelTypes(identifierNode);
- String filter;
- if (identifierNode != NULL)
- {
- filter = identifierNode->ToString();
- mInsertStartIdx = identifierNode->GetSrcStart();
- mInsertEndIdx = identifierNode->GetSrcEnd();
- }
- String addStr;
- if (mShowAttributeProperties != NULL)
- {
- auto showAttrTypeDef = mShowAttributeProperties->mTypeDef;
- for (auto prop : showAttrTypeDef->mProperties)
- {
- if ((AddEntry(AutoCompleteEntry("property", prop->mName + "=", prop->mFieldDeclaration->mDocumentation), filter)) && (mIsGetDefinition))
- {
- SetDefinitionLocation(prop->mFieldDeclaration->mNameNode);
- }
- }
- for (auto field : showAttrTypeDef->mFields)
- {
- if ((AddEntry(AutoCompleteEntry("field", field->mName + "=", field->mFieldDeclaration->mDocumentation), filter)) && (mIsGetDefinition))
- {
- SetDefinitionLocation(field->mFieldDeclaration->mNameNode);
- }
- }
- }
- if ((mModule->mContext->mCurTypeState != NULL) && (mModule->mContext->mCurTypeState->mTypeInstance != NULL))
- {
- BF_ASSERT(mModule->mCurTypeInstance == mModule->mContext->mCurTypeState->mTypeInstance);
- BfGlobalLookup globalLookup;
- globalLookup.mKind = BfGlobalLookup::Kind_All;
- mModule->PopulateGlobalContainersList(globalLookup);
- for (auto& globalContainer : mModule->mContext->mCurTypeState->mGlobalContainers)
- {
- AddTypeMembers(globalContainer.mTypeInst, true, false, filter, globalContainer.mTypeInst, true, true);
- }
- }
-
- //////////////////////////////////////////////////////////////////////////
- {
- auto activeTypeDef = mModule->GetActiveTypeDef();
- BfStaticSearch* staticSearch;
- if ((mModule->mCurTypeInstance != NULL) && (mModule->mCurTypeInstance->mStaticSearchMap.TryGetValue(activeTypeDef, &staticSearch)))
- {
- for (auto typeInst : staticSearch->mStaticTypes)
- {
- AddTypeMembers(typeInst, true, false, filter, typeInst, true, true);
- AddInnerTypes(typeInst, filter, false, false);
- }
- }
- else if ((activeTypeDef != NULL) && (!activeTypeDef->mStaticSearch.IsEmpty()))
- {
- BF_ASSERT(mModule->mCompiler->IsAutocomplete());
- for (auto typeRef : activeTypeDef->mStaticSearch)
- {
- auto type = mModule->ResolveTypeRef(typeRef, NULL, BfPopulateType_Declaration);
- if (type != NULL)
- {
- auto typeInst = type->ToTypeInstance();
- if (typeInst != NULL)
- {
- AddTypeMembers(typeInst, true, false, filter, typeInst, true, true);
- AddInnerTypes(typeInst, filter, false, false);
- }
- }
- }
- }
- }
- //////////////////////////////////////////////////////////////////////////
- BfMethodInstance* curMethodInstance = mModule->mCurMethodInstance;
- if (mModule->mCurMethodState != NULL)
- curMethodInstance = mModule->mCurMethodState->GetRootMethodState()->mMethodInstance;
- if (curMethodInstance != NULL)
- {
- if (!curMethodInstance->mMethodDef->mIsStatic)
- {
- if (mModule->mCurTypeInstance->IsObject())
- AddEntry(AutoCompleteEntry("object", "this"), filter);
- else
- AddEntry(AutoCompleteEntry("pointer", "this"), filter);
- AddTypeMembers(mModule->mCurTypeInstance, true, true, filter, mModule->mCurTypeInstance, mModule->mCurTypeInstance->IsInterface(), true);
- }
- else
- {
- AddTypeMembers(mModule->mCurTypeInstance, true, false, filter, mModule->mCurTypeInstance, mModule->mCurTypeInstance->IsInterface(), true);
- }
- if (mModule->mCurMethodState != NULL)
- {
- int varSkipCount = 0;
- StringT<128> wantName = filter;
- while (wantName.StartsWith("@"))
- {
- varSkipCount++;
- wantName.Remove(0);
- }
- if (varSkipCount > 0)
- {
- Dictionary<String, int> localCount;
- auto varMethodState = mModule->mCurMethodState;
- while (varMethodState != NULL)
- {
- for (int localIdx = (int)varMethodState->mLocals.size() - 1; localIdx >= 0; localIdx--)
- {
- auto local = varMethodState->mLocals[localIdx];
- int* findIdx = NULL;
- if (localCount.TryAdd(local->mName, NULL, &findIdx))
- {
- *findIdx = 0;
- }
- else
- {
- (*findIdx)++;
- }
- if (*findIdx == varSkipCount)
- {
- if ((AddEntry(AutoCompleteEntry(GetTypeName(local->mResolvedType), local->mName), wantName)) && (mIsGetDefinition))
- {
- }
- }
- }
- varMethodState = varMethodState->mPrevMethodState;
- if ((varMethodState == NULL) ||
- (varMethodState->mMixinState != NULL) ||
- ((varMethodState->mClosureState != NULL) && (!varMethodState->mClosureState->mCapturing)))
- break;
- }
- mInsertStartIdx += varSkipCount;
- }
- else
- {
- auto varMethodState = mModule->mCurMethodState;
- while (varMethodState != NULL)
- {
- for (auto& local : varMethodState->mLocals)
- {
- if ((AddEntry(AutoCompleteEntry(GetTypeName(local->mResolvedType), local->mName), wantName)) && (mIsGetDefinition))
- {
- }
- }
- varMethodState = varMethodState->mPrevMethodState;
- if ((varMethodState == NULL) ||
- (varMethodState->mMixinState != NULL) ||
- ((varMethodState->mClosureState != NULL) && (!varMethodState->mClosureState->mCapturing)))
- break;
- }
- }
- }
- }
- else if (mModule->mCurTypeInstance != NULL)
- {
- bool staticOnly = true;
- if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mTempKind == BfMethodState::TempKind_NonStatic))
- staticOnly = false;
- //BF_ASSERT(mModule->mCurTypeInstance->mResolvingConstField);
- AddTypeMembers(mModule->mCurTypeInstance, true, !staticOnly, filter, mModule->mCurTypeInstance, false, true);
- }
- auto checkMethodState = mModule->mCurMethodState;
- while (checkMethodState != NULL)
- {
- for (auto localMethod : checkMethodState->mLocalMethods)
- {
- //AddEntry(AutoCompleteEntry("method", localMethod->mMethodName, localMethod->mMethodDeclaration->mDocumentation), filter);
- AddMethod(localMethod->mMethodDeclaration, localMethod->mMethodName, filter);
- }
- checkMethodState = checkMethodState->mPrevMethodState;
- }
- if (isInExpression)
- {
- const char* tokens [] =
- {
- "alignof", "as", "asm", "base", "break", "case", "catch", "checked", "continue", "default", "defer",
- "delegate", "delete", "do", "else", "false", "finally",
- "fixed", "for", "function", "if", "implicit", "in", "internal", "is", "new", "mixin", "null",
- "out", "params", "ref", "rettype", "return",
- "sealed", "sizeof", "scope", "static", "strideof", "struct", "switch", /*"this",*/ "throw", "try", "true", "typeof", "unchecked",
- "using", "var", "virtual", "volatile", "where", "while",
- };
- for (int i = 0; i < sizeof(tokens) / sizeof(char*); i++)
- AddEntry(AutoCompleteEntry("token", tokens[i]), filter);
- if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mBreakData != NULL) && (mModule->mCurMethodState->mBreakData->mIRFallthroughBlock))
- {
- AddEntry(AutoCompleteEntry("token", "fallthrough"), filter);
- }
- }
- else
- {
- const char* tokens[] =
- {
- "abstract", "base", "class", "const",
- "delegate", "extern", "enum", "explicit", "extension", "function",
- "interface", "in", "internal", "mixin", "namespace", "new",
- "operator", "out", "override", "params", "private", "protected", "public", "readonly", "ref", "rettype", "return",
- "scope", "sealed", "static", "struct", "this", "typealias",
- "using", "virtual", "volatile", "T", "where"
- };
- for (int i = 0; i < sizeof(tokens)/sizeof(char*); i++)
- AddEntry(AutoCompleteEntry("token", tokens[i]), filter);
- }
-
- //if ((identifierNode != NULL) && ((mModule->mCurMethodInstance == NULL) || (BfNodeDynCast<BfExpression>(identifierNode->mParent) != NULL)))
- /*if ((identifierNode != NULL) && ((mModule->mCurMethodInstance == NULL) || (isInExpression)))
- {
- AddEntry(AutoCompleteEntry("token", "#if"), filter);
- AddEntry(AutoCompleteEntry("token", "#elif"), filter);
- AddEntry(AutoCompleteEntry("token", "#endif"), filter);
- }*/
-
- //OutputDebugStrF("Autocomplete: %s\n", str.c_str());
- }
- String BfAutoComplete::GetFilter(BfAstNode* node)
- {
- String filter = node->ToString();
- if (mIsGetDefinition)
- {
- mInsertEndIdx = node->GetSrcEnd();
- }
- else
- {
- // Only use member name up to cursor
- auto bfParser = node->GetSourceData()->ToParser();
- int cursorIdx = bfParser->mCursorIdx;
- filter = filter.Substring(0, BF_MIN(cursorIdx - node->GetSrcStart(), (int)filter.length()));
- mInsertEndIdx = cursorIdx;
- }
- return filter;
- }
- bool BfAutoComplete::CheckMemberReference(BfAstNode* target, BfAstNode* dotToken, BfAstNode* memberName, bool onlyShowTypes, BfType* expectingType, bool isUsingDirective, bool onlyAttribute)
- {
- BfAttributedIdentifierNode* attrIdentifier = NULL;
- bool isAutocompletingName = false;
- if ((attrIdentifier = BfNodeDynCast<BfAttributedIdentifierNode>(memberName)))
- {
- memberName = attrIdentifier->mIdentifier;
- if ((memberName == NULL) && (IsAutocompleteNode(attrIdentifier->mAttributes)))
- {
- auto bfParser = attrIdentifier->mAttributes->GetSourceData()->ToParser();
- int cursorIdx = bfParser->mCursorIdx;
- isAutocompletingName = cursorIdx == attrIdentifier->mAttributes->GetSrcEnd();
- }
- }
- if (memberName != NULL)
- isAutocompletingName = IsAutocompleteNode(dotToken, memberName, 0, 1);
- if ((IsAutocompleteNode(dotToken, 0, 1)) || (isAutocompletingName))
- {
- BfLogSys(mModule->mSystem, "Triggered autocomplete\n");
- bool isFriend = false;
-
- mInsertStartIdx = dotToken->GetSrcEnd();
- if (attrIdentifier != NULL)
- {
- BfAttributeState attributeState;
- attributeState.mTarget = (BfAttributeTargets)(BfAttributeTargets_MemberAccess);
- attributeState.mCustomAttributes = mModule->GetCustomAttributes(attrIdentifier->mAttributes, attributeState.mTarget);
- isFriend = (attributeState.mCustomAttributes != NULL) && (attributeState.mCustomAttributes->Contains(mModule->mCompiler->mFriendAttributeTypeDef));
- mInsertStartIdx = attrIdentifier->mAttributes->GetSrcEnd();
- }
-
- if (memberName != NULL)
- {
- //Member name MAY be incorrectly identified in cases like:
- // val._
- // OtherCall();
- int cursorIdx = GetCursorIdx(memberName);
- if ((cursorIdx != -1) && (cursorIdx >= memberName->GetSrcStart()))
- mInsertStartIdx = memberName->GetSrcStart();
- }
- SetAndRestoreValue<bool> prevFriendSet(mHasFriendSet, mHasFriendSet || isFriend);
- String filter;
- if ((memberName != NULL) && (IsAutocompleteNode(memberName)))
- {
- filter = GetFilter(memberName);
- }
- else if (mResolveType != BfResolveType_Autocomplete)
- mInsertStartIdx = -1; // Require a full span for everything but autocomplete
- SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
- bool isStatic = false;
- BfTypedValue targetValue = LookupTypeRefOrIdentifier(target, &isStatic, (BfEvalExprFlags)(BfEvalExprFlags_IgnoreNullConditional | BfEvalExprFlags_NoCast), expectingType);
- bool hadResults = false;
- bool doAsNamespace = true;
- if ((targetValue.mType) && (!isUsingDirective))
- {
- doAsNamespace = false;
- if (auto dotTokenNode = BfNodeDynCast<BfTokenNode>(dotToken))
- {
- if (dotTokenNode->GetToken() == BfToken_QuestionDot)
- {
- // ?. should look inside nullable types
- if (targetValue.mType->IsNullable())
- {
- BfGenericTypeInstance* nullableType = (BfGenericTypeInstance*)targetValue.mType->ToTypeInstance();
- targetValue = mModule->MakeAddressable(targetValue);
- BfIRValue valuePtr = mModule->mBfIRBuilder->CreateInBoundsGEP(targetValue.mValue, 0, 1); // mValue
- targetValue = BfTypedValue(valuePtr, nullableType->mTypeGenericArguments[0], true);
- }
- }
- }
- // Statics, inner types
- //bool isStatic = (targetValue.mValue == NULL) && (!targetValue.mType->IsValuelessType());
-
- auto checkType = targetValue.mType;
- if (checkType->IsGenericParam())
- {
- auto genericParamType = (BfGenericParamType*)checkType;
- auto genericParamInst = mModule->GetGenericParamInstance(genericParamType);
-
- for (auto interfaceConstraint : genericParamInst->mInterfaceConstraints)
- AddTypeMembers(interfaceConstraint, false, true, filter, interfaceConstraint, true, false);
- if (genericParamInst->mTypeConstraint != NULL)
- checkType = genericParamInst->mTypeConstraint;
- else
- checkType = mModule->mContext->mBfObjectType;
- }
- if (checkType->IsPointer())
- checkType = checkType->GetUnderlyingType();
- auto typeInst = checkType->ToTypeInstance();
- if ((typeInst == NULL) &&
- ((checkType->IsPrimitiveType()) || (checkType->IsSizedArray())))
- typeInst = mModule->GetWrappedStructType(checkType);
- if (typeInst != NULL)
- {
- if (typeInst->mTypeDef->IsGlobalsContainer())
- doAsNamespace = true; // Also list the types in this namespace
- bool allowPrivate = (mModule->mCurTypeInstance == typeInst) || (mModule->IsInnerType(mModule->mCurTypeInstance, typeInst));
- bool allowProtected = allowPrivate;
- if (isStatic)
- AddInnerTypes(typeInst, filter, allowProtected, allowPrivate);
- if (!onlyShowTypes)
- AddTypeMembers(typeInst, isStatic, !isStatic, filter, typeInst, false, false);
- if (typeInst->IsInterface())
- {
- AddTypeMembers(mModule->mContext->mBfObjectType, isStatic, !isStatic, filter, mModule->mContext->mBfObjectType, true, false);
- }
- }
- hadResults = true;
- }
- if (doAsNamespace) // Lookup namespaces
- {
- String targetStr = target->ToString();
- BfAtomComposite targetComposite;
- bool isValid = mSystem->ParseAtomComposite(targetStr, targetComposite);
- BfProject* bfProject = NULL;
- if (mModule->mCurTypeInstance != NULL)
- bfProject = mModule->mCurTypeInstance->mTypeDef->mProject;
- else
- bfProject = mCompiler->mResolvePassData->mParser->mProject;
- auto _CheckProject = [&](BfProject* project)
- {
- if ((isValid) && (project->mNamespaces.ContainsKey(targetComposite)))
- {
- for (auto namespacePair : project->mNamespaces)
- {
- const BfAtomComposite& namespaceComposite = namespacePair.mKey;
- if ((namespaceComposite.StartsWith(targetComposite)) && (namespaceComposite.GetPartsCount() > targetComposite.GetPartsCount()))
- {
- BfAtom* subNamespace = namespaceComposite.mParts[targetComposite.mSize];
- AutoCompleteEntry entry("namespace", subNamespace->mString.mPtr);
- AddEntry(entry, filter);
- }
- }
- if (!isUsingDirective)
- {
- BfTypeDef* curTypeDef = NULL;
- if (mModule->mCurTypeInstance != NULL)
- curTypeDef = mModule->mCurTypeInstance->mTypeDef;
- for (auto typeDef : mSystem->mTypeDefs)
- {
- if ((typeDef->mNamespace == targetComposite) && (typeDef->mOuterType == NULL) &&
- (!typeDef->mIsPartial) &&
- ((curTypeDef == NULL) || (curTypeDef->mProject->ContainsReference(typeDef->mProject))))
- {
- AddTypeDef(typeDef, filter, onlyAttribute);
- }
- }
- }
- hadResults = true;
- }
- };
- if (bfProject != NULL)
- {
- for (int depIdx = -1; depIdx < (int)bfProject->mDependencies.size(); depIdx++)
- {
- BfProject* depProject = (depIdx == -1) ? bfProject : bfProject->mDependencies[depIdx];
- _CheckProject(depProject);
- }
- }
- else
- {
- for (auto project : mSystem->mProjects)
- _CheckProject(project);
- }
- }
- return hadResults;
- }
- else
- {
- auto identifierNode = BfNodeDynCast<BfIdentifierNode>(target);
- if (identifierNode != NULL)
- CheckIdentifier(identifierNode);
- CheckTypeRef(BfNodeDynCast<BfTypeReference>(target), true, false, onlyAttribute);
- }
- return false;
- }
- void BfAutoComplete::CheckTypeRef(BfTypeReference* typeRef, bool mayBeIdentifier, bool isInExpression, bool onlyAttribute)
- {
- if ((typeRef == NULL) || (typeRef->IsTemporary()) || (!IsAutocompleteNode(typeRef)))
- return;
- if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef))
- {
- CheckTypeRef(genericTypeRef->mElementType, mayBeIdentifier, isInExpression, onlyAttribute);
- for (auto genericArg : genericTypeRef->mGenericArguments)
- CheckTypeRef(genericArg, false, isInExpression, false);
- return;
- }
- if (!onlyAttribute)
- {
- if (auto tupleTypeRef = BfNodeDynCast<BfTupleTypeRef>(typeRef))
- {
- for (auto fieldTypeRef : tupleTypeRef->mFieldTypes)
- CheckTypeRef(fieldTypeRef, false, isInExpression, false);
- return;
- }
- if (auto delegateTypeRef = BfNodeDynCast<BfDelegateTypeRef>(typeRef))
- {
- CheckTypeRef(delegateTypeRef->mReturnType, false, isInExpression);
- for (auto param : delegateTypeRef->mParams)
- {
- auto attributes = param->mAttributes;
- while (attributes != NULL)
- {
- if (attributes->mAttributeTypeRef != NULL)
- {
- CheckAttributeTypeRef(attributes->mAttributeTypeRef);
- }
- attributes = attributes->mNextAttribute;
- }
- CheckTypeRef(param->mTypeRef, false, isInExpression);
- }
- return;
- }
- if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(typeRef))
- {
- // "May be identifier" where pointer types could actually end up be multiplies, etc.
- CheckTypeRef(elementedTypeRef->mElementType, true, isInExpression);
- return;
- }
- }
- if (mayBeIdentifier)
- {
- if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(typeRef))
- {
- CheckIdentifier(namedTypeRef->mNameNode, isInExpression);
- return;
- }
- }
- if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef))
- {
- // Only consider the left side as an identifier if there's space after the dot. Consider this:
- // mVal.
- // Type a = null;
- // vs
- // mVal.Type a = null;
- // The first one is clearly a member reference being typed out even though it looks the same
- // to the parser except for the spacing
- if ((qualifiedTypeRef->mRight == NULL) || (qualifiedTypeRef->mDot->GetSrcEnd() < qualifiedTypeRef->mRight->GetSrcStart()))
- {
- BfAutoParentNodeEntry autoParentNodeEntry(mModule, qualifiedTypeRef);
- //CheckMemberReference(qualifiedTypeRef->mLeft, qualifiedTypeRef->mDot, NULL, !mayBeIdentifier, NULL, false, onlyAttribute);
- CheckMemberReference(qualifiedTypeRef->mLeft, qualifiedTypeRef->mDot, qualifiedTypeRef->mRight, !mayBeIdentifier, NULL, false, onlyAttribute);
- }
- else if (auto rightNamedTypeRef = BfNodeDynCast<BfNamedTypeReference>(qualifiedTypeRef->mRight))
- {
- BfAutoParentNodeEntry autoParentNodeEntry(mModule, qualifiedTypeRef);
- if (CheckMemberReference(qualifiedTypeRef->mLeft, qualifiedTypeRef->mDot, rightNamedTypeRef->mNameNode, false, NULL, false, onlyAttribute))
- return;
- }
- }
- if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(typeRef))
- {
- AddTopLevelNamespaces(namedTypeRef->mNameNode);
- AddTopLevelTypes(namedTypeRef->mNameNode, onlyAttribute);
- }
- }
- void BfAutoComplete::CheckAttributeTypeRef(BfTypeReference* typeRef)
- {
- if (!IsAutocompleteNode(typeRef))
- return;
- CheckTypeRef(typeRef, false, false, true);
- }
- void BfAutoComplete::CheckInvocation(BfAstNode* invocationNode, BfTokenNode* openParen, BfTokenNode* closeParen, const BfSizedArray<ASTREF(BfTokenNode*)>& commas)
- {
- if (!mIsAutoComplete)
- return;
- bool wasCapturingMethodMatchInfo = mIsCapturingMethodMatchInfo;
- mIsCapturingMethodMatchInfo = false;
- int lenAdd = 0;
- if (closeParen == NULL)
- {
- // Unterminated invocation expression - allow for space after last comma in param list
- lenAdd = 1;
- }
- else
- {
- // Ignore close paren
- lenAdd = -1;
- }
-
- if (!IsAutocompleteNode(invocationNode, lenAdd))
- return;
- if (openParen == NULL)
- {
- mModule->AssertErrorState();
- return;
- }
- auto bfParser = invocationNode->GetSourceData()->ToParser();
- if (bfParser == NULL)
- return;
- int cursorIdx = bfParser->mCursorIdx;
- BfAstNode* target = invocationNode;
- if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(invocationNode))
- {
- target = invocationExpr->mTarget;
- if (auto memberTarget = BfNodeDynCast<BfMemberReferenceExpression>(target))
- {
- if (memberTarget->mMemberName != NULL)
- target = memberTarget->mMemberName;
- }
- else if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(target))
- target = qualifiedTypeRef->mRight;
- else if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(target))
- target = qualifiedNameNode->mRight;
- if (auto attributedMember = BfNodeDynCast<BfAttributedIdentifierNode>(target))
- target = attributedMember->mIdentifier;
- }
- bool doCapture = (bfParser->mCursorIdx >= openParen->GetSrcStart());
- if (mIsGetDefinition)
- {
- doCapture |= (target != NULL) && (bfParser->mCursorIdx >= target->GetSrcStart());
- }
- if (doCapture)
- {
- mIsCapturingMethodMatchInfo = true;
- if (mMethodMatchInfo == NULL)
- mMethodMatchInfo = new MethodMatchInfo();
- else
- {
- if (wasCapturingMethodMatchInfo)
- {
- // We're actually in an inner invocation now
- delete mMethodMatchInfo;
- mMethodMatchInfo = new MethodMatchInfo();
- mMethodMatchInfo->mSrcPositions.Clear();
- }
- }
- mMethodMatchInfo->mInvocationSrcIdx = target->GetSrcStart();
- mMethodMatchInfo->mCurMethodInstance = mModule->mCurMethodInstance;
- mMethodMatchInfo->mCurTypeInstance = mModule->mCurTypeInstance;
- mMethodMatchInfo->mSrcPositions.Clear();
- mMethodMatchInfo->mSrcPositions.push_back(openParen->GetSrcStart());
- for (auto comma : commas)
- mMethodMatchInfo->mSrcPositions.push_back(comma->GetSrcStart());
- mMethodMatchInfo->mSrcPositions.push_back(invocationNode->GetSrcEnd() + lenAdd);
- }
- }
- void BfAutoComplete::CheckNode(BfAstNode* node)
- {
- if (!IsAutocompleteNode(node))
- return;
- if (auto identifer = BfNodeDynCast<BfIdentifierNode>(node))
- CheckIdentifier(identifer);
- if (auto typeRef = BfNodeDynCast<BfTypeReference>(node))
- CheckTypeRef(typeRef, true);
- if (auto memberRef = BfNodeDynCast<BfMemberReferenceExpression>(node))
- {
- if (memberRef->mTarget != NULL)
- CheckMemberReference(memberRef->mTarget, memberRef->mDotToken, memberRef->mMemberName);
- }
- }
- void BfAutoComplete::AddOverrides(const StringImpl& filter)
- {
- if (!mIsAutoComplete)
- return;
- auto activeTypeDef = mModule->GetActiveTypeDef();
- BfTypeInstance* curType = mModule->mCurTypeInstance;
- while (curType != NULL)
- {
- for (auto methodDef : curType->mTypeDef->mMethods)
- {
- if (methodDef->mIsNoShow)
- continue;
- if (curType == mModule->mCurTypeInstance)
- {
- // The "normal" case, and only case for types without extensions
- if (methodDef->mDeclaringType == activeTypeDef)
- continue;
- if ((methodDef->mDeclaringType->IsExtension()) && (methodDef->mDeclaringType->mProject == activeTypeDef->mProject))
- continue;
- if (!curType->IsTypeMemberAccessible(methodDef->mDeclaringType, activeTypeDef))
- continue;
- }
-
- auto& methodGroup = curType->mMethodInstanceGroups[methodDef->mIdx];
- if (methodGroup.mDefault == NULL)
- {
- continue;
- }
- auto methodInst = methodGroup.mDefault;
- if ((methodDef->mIsVirtual) && (!methodDef->mIsOverride))
- {
- if (methodDef->mMethodType == BfMethodType_Normal)
- {
- String methodPrefix;
- String methodName;
- String impString;
-
- bool isAbstract = methodDef->mIsAbstract;
- if (!isAbstract)
- {
- if (!methodInst->mReturnType->IsVoid())
- impString = "return ";
- impString += "base.";
- impString += methodDef->mName;
- impString += "(";
- }
- auto methodDeclaration = methodDef->GetMethodDeclaration();
- if (methodDeclaration->mProtectionSpecifier != NULL)
- methodPrefix += methodDeclaration->mProtectionSpecifier->ToString() + " ";
- methodPrefix += "override ";
- methodPrefix += mModule->TypeToString(methodInst->mReturnType, BfTypeNameFlag_ReduceName);
- methodPrefix += " ";
- methodName += methodDef->mName;
- methodName += "(";
- for (int paramIdx = 0; paramIdx < (int)methodInst->GetParamCount(); paramIdx++)
- {
- if (paramIdx > 0)
- {
- methodName += ", ";
- if (!isAbstract)
- impString += ", ";
- }
- methodName += mModule->TypeToString(methodInst->GetParamType(paramIdx), BfTypeNameFlag_ReduceName);
- methodName += " ";
- methodName += methodDef->mParams[paramIdx]->mName;
- if (!isAbstract)
- impString += methodDef->mParams[paramIdx]->mName;
- }
- methodName += ")";
- if (!isAbstract)
- impString += ");";
- AddEntry(AutoCompleteEntry("override", methodName + "\t" + methodPrefix + methodName + "\t" + impString, NULL), filter);
- }
- else if ((methodDef->mMethodType == BfMethodType_PropertyGetter) || (methodDef->mMethodType == BfMethodType_PropertySetter))
- {
- auto propDeclaration = methodDef->GetPropertyDeclaration();
- bool hasGet = propDeclaration->GetMethod("get") != NULL;
- bool hasSet = propDeclaration->GetMethod("set") != NULL;
- if ((methodDef->mMethodType == BfMethodType_PropertyGetter) || (!hasGet))
- {
- String propName;
- String impl;
- propDeclaration->mNameNode->ToString(propName);
- bool isAbstract = methodDef->mIsAbstract;
- if (propDeclaration->mProtectionSpecifier != NULL)
- impl += propDeclaration->mProtectionSpecifier->ToString() + " ";
- impl += "override ";
- impl += mModule->TypeToString(methodInst->mReturnType, BfTypeNameFlag_ReduceName);
- impl += " ";
- impl += propName;
- impl += "\t";
- if (hasGet)
- {
- impl += "get\t";
- if (!isAbstract)
- {
- impl += "return base.";
- impl += propName;
- impl += ";";
- }
- }
- if (hasSet)
- {
- if (hasGet)
- impl += "\b\r";
- impl += "set\t";
- if (!isAbstract)
- {
- impl += "base.";
- impl += propName;
- impl += " = value;";
- }
- }
- AddEntry(AutoCompleteEntry("override", propName + "\t" + impl, NULL), filter);
- }
- }
- }
- }
- if (curType->IsStruct())
- curType = mModule->mContext->mBfObjectType;
- else
- curType = curType->mBaseType;
- }
- }
- void BfAutoComplete::UpdateReplaceData()
- {
-
- }
- void BfAutoComplete::CheckMethod(BfMethodDeclaration* methodDeclaration, bool isLocalMethod)
- {
- if (/*(propertyDeclaration->mDefinitionBlock == NULL) &&*/ (methodDeclaration->mVirtualSpecifier != NULL) &&
- (methodDeclaration->mVirtualSpecifier->GetToken() == BfToken_Override))
- {
- auto bfParser = methodDeclaration->mVirtualSpecifier->GetSourceData()->ToParser();
- if (bfParser == NULL)
- return;
- int cursorIdx = bfParser->mCursorIdx;
- bool isInTypeRef = IsAutocompleteNode(methodDeclaration->mReturnType);
- bool isInNameNode = IsAutocompleteNode(methodDeclaration->mNameNode);
- if (((IsAutocompleteNode(methodDeclaration, 1)) && (cursorIdx == methodDeclaration->mVirtualSpecifier->GetSrcEnd())) ||
- (isInTypeRef) || (isInNameNode))
- {
- if (mIsAutoComplete)
- {
- mInsertStartIdx = methodDeclaration->GetSrcStart();
- mInsertEndIdx = methodDeclaration->GetSrcEnd();
- }
- String filter;
- if ((isInNameNode || isInTypeRef))
- {
- if (methodDeclaration->mNameNode != NULL)
- filter = methodDeclaration->mNameNode->ToString();
- else if (methodDeclaration->mReturnType != NULL)
- filter = methodDeclaration->mReturnType->ToString();
- }
- else if (methodDeclaration->mBody != NULL)
- {
- // We're just inside 'override' - we may be inserting a new method
- mInsertEndIdx = methodDeclaration->mVirtualSpecifier->GetSrcEnd();
- }
- AddOverrides(filter);
- }
- }
- if (methodDeclaration->mReturnType != NULL)
- CheckTypeRef(methodDeclaration->mReturnType, true, isLocalMethod);
- }
- void BfAutoComplete::CheckProperty(BfPropertyDeclaration* propertyDeclaration)
- {
- if (IsAutocompleteNode(propertyDeclaration->mNameNode))
- {
- mInsertStartIdx = propertyDeclaration->mNameNode->GetSrcStart();
- mInsertEndIdx = propertyDeclaration->mNameNode->GetSrcEnd();
- }
- if ((propertyDeclaration->mVirtualSpecifier != NULL) &&
- (propertyDeclaration->mVirtualSpecifier->GetToken() == BfToken_Override))
- {
- if (!mIsAutoComplete)
- return;
- auto bfParser = propertyDeclaration->mVirtualSpecifier->GetSourceData()->ToParser();
- if (bfParser == NULL)
- return;
- int cursorIdx = bfParser->mCursorIdx;
- bool isInTypeRef = IsAutocompleteNode(propertyDeclaration->mTypeRef);
- bool isInNameNode = IsAutocompleteNode(propertyDeclaration->mNameNode);
- if (((IsAutocompleteNode(propertyDeclaration, 1)) && (cursorIdx == propertyDeclaration->mVirtualSpecifier->GetSrcEnd())) ||
- (isInTypeRef) || (isInNameNode))
- {
- mInsertStartIdx = propertyDeclaration->mVirtualSpecifier->GetSrcStart();
- String filter;
- if ((isInNameNode || isInTypeRef))
- {
- BfAstNode* defNode = NULL;
- if (isInNameNode)
- defNode = propertyDeclaration->mNameNode;
- else if (isInTypeRef)
- defNode = propertyDeclaration->mTypeRef;
-
- filter = defNode->ToString();
- mInsertEndIdx = defNode->GetSrcEnd();
- }
- else if (propertyDeclaration->mTypeRef != NULL)
- {
- // We're just inside 'override' - we may be inserting a new method
- mInsertEndIdx = propertyDeclaration->mVirtualSpecifier->GetSrcEnd();
- }
- else
- {
- mInsertEndIdx = propertyDeclaration->mVirtualSpecifier->GetSrcEnd();
- }
- AddOverrides(filter);
- }
- }
- else
- {
- if (propertyDeclaration->mTypeRef != NULL)
- CheckTypeRef(propertyDeclaration->mTypeRef, true);
- }
- }
- void BfAutoComplete::CheckVarResolution(BfAstNode* varTypeRef, BfType* resolvedType)
- {
- if (IsAutocompleteNode(varTypeRef))
- {
- if ((resolvedType == NULL) || (resolvedType->IsVar()) || (resolvedType->IsLet()))
- return;
- if (mIsGetDefinition)
- {
- auto typeInst = resolvedType->ToTypeInstance();
- if (typeInst != NULL)
- {
- if (typeInst->mTypeDef->mTypeDeclaration != NULL)
- SetDefinitionLocation(typeInst->mTypeDef->mTypeDeclaration->mNameNode);
- }
- }
- if (mResolveType == BfResolveType_GetVarType)
- {
- mVarTypeName = mModule->TypeToString(resolvedType);
- }
- }
- }
- void BfAutoComplete::CheckLocalDef(BfIdentifierNode* identifierNode, BfLocalVariable* varDecl)
- {
- CheckLocalRef(identifierNode, varDecl);
- }
- void BfAutoComplete::CheckLocalRef(BfIdentifierNode* identifierNode, BfLocalVariable* varDecl)
- {
- if (mReplaceLocalId != -1)
- return;
- if (mResolveType == BfResolveType_GoToDefinition)
- {
- if (IsAutocompleteNode(identifierNode))
- {
- if (varDecl->mNameNode != NULL)
- SetDefinitionLocation(varDecl->mNameNode);
- }
- }
- else if (mResolveType == BfResolveType_GetSymbolInfo)
- {
- if ((IsAutocompleteNode(identifierNode)) &&
- ((!varDecl->mIsShadow) || (varDecl->mShadowedLocal != NULL)))
- {
- if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) &&
- (!mModule->mCurMethodState->mClosureState->mCapturing))
- {
- // For closures, only get locals during the 'capturing' stage
- return;
- }
- auto rootMethodInstance = mModule->mCurMethodState->GetRootMethodState()->mMethodInstance;
- if (rootMethodInstance == NULL)
- return;
-
- auto resolvePassData = mModule->mCompiler->mResolvePassData;
- mReplaceLocalId = varDecl->mLocalVarId;
- mDefType = mModule->mCurTypeInstance->mTypeDef;
- mDefMethod = rootMethodInstance->mMethodDef;
- if (mInsertStartIdx == -1)
- {
- mInsertStartIdx = identifierNode->GetSrcStart();
- mInsertEndIdx = identifierNode->GetSrcEnd();
- }
- }
- }
- }
- void BfAutoComplete::CheckFieldRef(BfIdentifierNode* identifierNode, BfFieldInstance* fieldInst)
- {
- if (mResolveType == BfResolveType_GetSymbolInfo)
- {
- if (mDefField != NULL)
- return;
- if (IsAutocompleteNode(identifierNode))
- {
- while (true)
- {
- if (auto qualifiedName = BfNodeDynCast<BfQualifiedNameNode>(identifierNode))
- {
- identifierNode = qualifiedName->mRight;
- if (!IsAutocompleteNode(identifierNode))
- return;
- }
- else
- break;
- }
- //mReplaceTypeDef = fieldInst->mOwner->mTypeDef;
- //mReplaceFieldDef = fieldInst->GetFieldDef();
- mDefType = fieldInst->mOwner->mTypeDef;
- mDefField = fieldInst->GetFieldDef();
- mInsertStartIdx = identifierNode->GetSrcStart();
- mInsertEndIdx = identifierNode->GetSrcEnd();
- }
- }
- }
- void BfAutoComplete::CheckLabel(BfIdentifierNode* identifierNode, BfAstNode* precedingNode)
- {
- String filter;
- if (identifierNode != NULL)
- {
- if (!IsAutocompleteNode(identifierNode))
- return;
- filter = identifierNode->ToString();
- mInsertStartIdx = identifierNode->GetSrcStart();
- mInsertEndIdx = identifierNode->GetSrcEnd();
- }
- else
- {
- if (precedingNode == NULL)
- return;
- int expectSpacing = 1;
- if (auto precedingToken = BfNodeDynCast<BfTokenNode>(precedingNode))
- if (precedingToken->GetToken() == BfToken_Colon)
- expectSpacing = 0;
- if (!IsAutocompleteNode(precedingNode, expectSpacing))
- return;
-
- auto bfParser = precedingNode->GetSourceData()->ToParser();
- if (bfParser->mCursorIdx != precedingNode->GetSrcEnd() + expectSpacing - 1)
- return;
- mInsertStartIdx = precedingNode->GetSrcEnd() + expectSpacing;
- mInsertEndIdx = mInsertStartIdx;
- }
- auto checkScope = mModule->mCurMethodState->mCurScope;
- while (checkScope != NULL)
- {
- if (!checkScope->mLabel.empty())
- AddEntry(AutoCompleteEntry("label", checkScope->mLabel), filter);
- checkScope = checkScope->mPrevScope;
- }
- }
- void BfAutoComplete::AddTypeInstanceEntry(BfTypeInstance* typeInst)
- {
- String bestTypeName = mModule->TypeToString(typeInst, BfTypeNameFlag_ReduceName);
- if (typeInst->IsValueType())
- AddEntry(AutoCompleteEntry("valuetype", bestTypeName));
- else
- AddEntry(AutoCompleteEntry("class", bestTypeName));
- mDefaultSelection = bestTypeName;
- }
- void BfAutoComplete::CheckDocumentation(AutoCompleteEntry* entry, BfCommentNode* documentation)
- {
-
- }
- void BfAutoComplete::CheckEmptyStart(BfAstNode* prevNode, BfType* type)
- {
- // Temporarily (?) removed?
- return;
- if (IsAutocompleteNode(prevNode, 2))
- {
- if (!type->IsEnum())
- return;
- int wantCursorIdx = prevNode->GetSrcEnd() - 1;
- String prevNodeString = prevNode->ToString();
- if (prevNodeString != "(")
- wantCursorIdx++;
- if (prevNode->GetSourceData()->ToParser()->mCursorIdx != wantCursorIdx)
- return;
-
- AddTypeInstanceEntry(type->ToTypeInstance());
- CheckIdentifier(NULL);
- mInsertStartIdx = wantCursorIdx + 1;
- mInsertEndIdx = mInsertStartIdx;
- }
- }
- bool BfAutoComplete::CheckFixit(BfAstNode* node)
- {
- if (mIgnoreFixits)
- return false;
- if (mCompiler->mResolvePassData->mResolveType != BfResolveType_GetFixits)
- return false;
- if (!IsAutocompleteLineNode(node))
- return false;
- if (mInsertStartIdx == -1)
- {
- mInsertStartIdx = node->GetSrcStart();
- mInsertEndIdx = node->GetSrcStart();
- }
- return true;
- }
- void BfAutoComplete::FixitAddMember(BfTypeInstance* typeInst, BfType* fieldType, const StringImpl& fieldName, bool isStatic, BfTypeInstance* referencedFrom)
- {
- if (typeInst == mModule->mContext->mBfObjectType)
- return;
- auto parser = typeInst->mTypeDef->mSource->ToParser();
- if (parser == NULL)
- return;
- String fullName = typeInst->mTypeDef->mFullName.ToString();
- String fieldStr;
- if (typeInst == referencedFrom)
- {
- // Implicitly private
- }
- else if ((referencedFrom != NULL) && (mModule->TypeIsSubTypeOf(referencedFrom, typeInst)))
- {
- fieldStr += "protected ";
- }
- else
- {
- fieldStr += "public ";
- }
- if (isStatic)
- fieldStr += "static ";
- if (fieldType != NULL)
- fieldStr += mModule->TypeToString(fieldType, BfTypeNameFlag_ReduceName);
- else
- fieldStr += "Object";
- fieldStr += " " + fieldName + ";";
- int fileLoc = typeInst->mTypeDef->mTypeDeclaration->GetSrcEnd();
- if (auto defineBlock = BfNodeDynCast<BfBlock>(typeInst->mTypeDef->mTypeDeclaration->mDefineNode))
- fileLoc = BfFixitFinder::FindLineStartAfter(defineBlock->mOpenBrace);
- if (!typeInst->mTypeDef->mFields.empty())
- {
- auto fieldDecl = typeInst->mTypeDef->mFields.back()->mFieldDeclaration;
- if (fieldDecl != NULL)
- {
- fileLoc = BfFixitFinder::FindLineStartAfter(fieldDecl);
- }
- }
- 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()));
- }
|