From 5271f5e2fd8a4633ec5baa028c9433637593862a Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Mon, 2 May 2022 07:48:29 -0700 Subject: [PATCH] Improvements to emit markers on emits only in specialized types --- IDE/src/Compiler/BfCompiler.bf | 39 ++++++- IDE/src/Compiler/BfResolvePassData.bf | 4 + IDE/src/Compiler/CompilerBase.bf | 15 ++- IDE/src/IDEApp.bf | 13 ++- IDE/src/ui/SourceEditWidgetContent.bf | 137 +++++++++++++++++++++-- IDE/src/ui/SourceViewPanel.bf | 106 ++++++++++++++---- IDEHelper/Compiler/BfCompiler.cpp | 23 ++-- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 53 ++++++++- IDEHelper/Compiler/BfResolvePass.cpp | 1 + IDEHelper/Compiler/BfResolvePass.h | 1 + IDEHelper/Compiler/BfStmtEvaluator.cpp | 5 - IDEHelper/Compiler/BfSystem.cpp | 5 + IDEHelper/Compiler/CeMachine.cpp | 6 +- IDEHelper/Compiler/CeMachine.h | 2 + 14 files changed, 342 insertions(+), 68 deletions(-) diff --git a/IDE/src/Compiler/BfCompiler.bf b/IDE/src/Compiler/BfCompiler.bf index 35bd121f..d433ec8a 100644 --- a/IDE/src/Compiler/BfCompiler.bf +++ b/IDE/src/Compiler/BfCompiler.bf @@ -221,6 +221,12 @@ namespace IDE.Compiler class RefreshViewCommand : Command { + public ViewRefreshKind mRefreshKind; + + public this(ViewRefreshKind refreshKind) + { + mRefreshKind = refreshKind; + } } class SetWorkspaceOptionsCommand : Command @@ -237,6 +243,7 @@ namespace IDE.Compiler public void* mNativeBfCompiler; public bool mIsResolveOnly; + public bool mWantsResolveAllCollapseRefresh; public BfSystem mBfSystem; bool mWantsRemoveOldData; public Dictionary mRebuildWatchingFiles = new .() ~ delete _; @@ -392,9 +399,9 @@ namespace IDE.Compiler QueueCommand(command); } - public void QueueRefreshViewCommand() + public void QueueRefreshViewCommand(ViewRefreshKind viewRefreshKind = .FullRefresh) { - QueueCommand(new RefreshViewCommand()); + QueueCommand(new RefreshViewCommand(viewRefreshKind)); } public void QueueSetWorkspaceOptions(Project hotProject, int32 hotIdx) @@ -608,8 +615,31 @@ namespace IDE.Compiler var resolvePassData = BfResolvePassData.Create(ResolveType.Classify); // If we get canceled then try again after waiting a couple updates - if (!ClassifySource(passInstance, resolvePassData)) + + bool wantsCollapseRefresh = false; + + if (ClassifySource(passInstance, resolvePassData)) + { + Debug.WriteLine($"ClassifySource success {mWantsResolveAllCollapseRefresh} {resolvePassData.HadEmits}"); + + if (mWantsResolveAllCollapseRefresh) + { + mWantsResolveAllCollapseRefresh = false; + wantsCollapseRefresh = true; + } + } + else + { + Debug.WriteLine($"ClassifySource partial {resolvePassData.HadEmits}"); QueueDeferredResolveAll(); + } + + if (resolvePassData.HadEmits) + wantsCollapseRefresh = true; + + if (wantsCollapseRefresh) + QueueRefreshViewCommand(.Collapse); + UpdateRebuildFileWatches(); delete resolvePassData; @@ -632,7 +662,8 @@ namespace IDE.Compiler if (command is RefreshViewCommand) { - mWantsActiveViewRefresh = true; + var refreshViewCommand = (RefreshViewCommand)command; + mWantsActiveViewRefresh = Math.Max(mWantsActiveViewRefresh, refreshViewCommand.mRefreshKind); } if (var dirChangedCommand = command as RebuildFileChangedCommand) diff --git a/IDE/src/Compiler/BfResolvePassData.bf b/IDE/src/Compiler/BfResolvePassData.bf index 3860ef4f..24356abb 100644 --- a/IDE/src/Compiler/BfResolvePassData.bf +++ b/IDE/src/Compiler/BfResolvePassData.bf @@ -44,12 +44,16 @@ namespace IDE.Compiler [CallingConvention(.Stdcall), CLink] static extern void* BfResolvePassData_GetEmitEmbedData(void* bfResolvePassData, char8* typeName, out int32 srcLength, out int32 revision); + [CallingConvention(.Stdcall), CLink] + static extern bool BfResolvePassData_GetHadEmits(void* bfResolvePassData); + // //[CallingConvention(.Stdcall), CLink] //static extern void* BfParser_CreateResolvePassData(void* bfSystem, int32 resolveType); public void* mNativeResolvePassData; + public bool HadEmits => BfResolvePassData_GetHadEmits(mNativeResolvePassData); public ~this() { diff --git a/IDE/src/Compiler/CompilerBase.bf b/IDE/src/Compiler/CompilerBase.bf index e975ce8e..5f4411e9 100644 --- a/IDE/src/Compiler/CompilerBase.bf +++ b/IDE/src/Compiler/CompilerBase.bf @@ -13,9 +13,16 @@ namespace IDE.Compiler { public abstract class CompilerBase : CommandQueueManager { - public int32 mResolveAllWait; + public enum ViewRefreshKind + { + None, + Collapse, + FullRefresh + } + + public int32 mResolveAllWait; protected List mQueuedOutput = new List() ~ DeleteContainerAndItems!(_); - public bool mWantsActiveViewRefresh; + public ViewRefreshKind mWantsActiveViewRefresh; public volatile int32 mThreadYieldCount = 0; // Whether our thread wants to be yielded to, and for how many ticks @@ -157,10 +164,10 @@ namespace IDE.Compiler { CheckThreadDone(); - if (mWantsActiveViewRefresh) + if (mWantsActiveViewRefresh != .None) { IDEApp.sApp.RefreshVisibleViews(); - mWantsActiveViewRefresh = false; + mWantsActiveViewRefresh = .None; } if (mThreadYieldCount > 0) diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf index f1b3e570..5a7b1bfe 100644 --- a/IDE/src/IDEApp.bf +++ b/IDE/src/IDEApp.bf @@ -1372,12 +1372,17 @@ namespace IDE return activePanel as TextPanel; } - public void RefreshVisibleViews(SourceViewPanel excludeSourceViewPanel = null) + public void RefreshVisibleViews(SourceViewPanel excludeSourceViewPanel = null, CompilerBase.ViewRefreshKind viewRefreshKind = .FullRefresh) { WithSourceViewPanels(scope (sourceViewPanel) => { - if ((sourceViewPanel.mParent != null) && (sourceViewPanel != excludeSourceViewPanel)) - sourceViewPanel.QueueFullRefresh(true); + if ((sourceViewPanel.mParent != null) && (sourceViewPanel != excludeSourceViewPanel)) + { + if (viewRefreshKind ==.Collapse) + sourceViewPanel.QueueFullRefresh(true); + else + sourceViewPanel.QueueCollapseRefresh(); + } }); } @@ -9459,7 +9464,7 @@ namespace IDE } mBfResolveCompiler.QueueDeferredResolveAll(); - mBfResolveCompiler.QueueRefreshViewCommand(); + mBfResolveCompiler.QueueRefreshViewCommand(.FullRefresh); return; } diff --git a/IDE/src/ui/SourceEditWidgetContent.bf b/IDE/src/ui/SourceEditWidgetContent.bf index 5ccb9e55..be884a07 100644 --- a/IDE/src/ui/SourceEditWidgetContent.bf +++ b/IDE/src/ui/SourceEditWidgetContent.bf @@ -203,7 +203,7 @@ namespace IDE.ui public SourceViewPanel mSourceViewPanel; public DarkComboBox mGenericTypeCombo; public DarkComboBox mGenericMethodCombo; - public String mGenericTypeFilter; + public String mGenericTypeFilter ~ delete _; public float mWantHeight; public float? mMouseDownY; public float? mDownWantHeight; @@ -268,14 +268,15 @@ namespace IDE.ui if (mIgnoreChange) return; - var editWidget = (EditWidget)theEvent.mSender; - var searchText = scope String(); - editWidget.GetText(searchText); - searchText.Trim(); + if (mGenericTypeFilter == null) + mGenericTypeFilter = new .(); + else + mGenericTypeFilter.Clear(); - mGenericTypeFilter = searchText; + var editWidget = (EditWidget)theEvent.mSender; + editWidget.GetText(mGenericTypeFilter); + mGenericTypeFilter.Trim(); mGenericTypeCombo.ShowDropdown(); - mGenericTypeFilter = null; } void EditKeyDownHandler(KeyDownEvent evt) @@ -293,6 +294,7 @@ namespace IDE.ui typeName = explicitTypeName; } + DeleteAndNullify!(mGenericTypeFilter); mIgnoreChange = true; int colonPos = typeName.IndexOf(':'); if (colonPos != -1) @@ -305,7 +307,7 @@ namespace IDE.ui void PopulateTypeData(Menu menu) { List findStrs = null; - if (mGenericTypeFilter != null) + if ((mGenericTypeFilter != null) && (!mGenericTypeFilter.IsWhiteSpace)) findStrs = scope:: List(mGenericTypeFilter.Split(' ')); using (mMonitor.Enter()) @@ -561,6 +563,7 @@ namespace IDE.ui case Type = 'T'; case UsingNamespaces = 'U'; case Unknown = '?'; + case HasUncertainEmits = '~'; case Emit = 'e'; case EmitAddType = '+'; @@ -597,6 +600,9 @@ namespace IDE.ui public int32 mAnchorIdx; public int32 mStartLine; public int32 mEndLine; + public bool mOnlyInResolveAll; + public bool mIncludedInClassify; + public bool mIncludedInResolveAll; public int32 mAnchorId; } @@ -613,7 +619,18 @@ namespace IDE.ui public void Clear() { + ClearCollapse(); + ClearEmit(); + } + + public void ClearCollapse() + { + mCollapseData.Clear(); + } + + public void ClearEmit() + { mEmitData.Clear(); ClearAndDeleteItems(mTypeNames); } @@ -6264,22 +6281,76 @@ namespace IDE.ui RehupLineCoords(); } - public void ParseCollapseRegions(String collapseText, int32 textVersion, ref IdSpan idSpan) + public void ParseCollapseRegions(String collapseText, int32 textVersion, ref IdSpan idSpan, ResolveType resolveType) { + /*if (resolveType == .None) + return;*/ + IdSpan.LookupContext lookupCtx = scope .(idSpan); var data = PreparedData; - data.Clear(); + if (resolveType != .None) + { + data.ClearCollapse(); + } + + List typeNameIdxMap = scope .(); + Dictionary typeNameMap = scope .(); + Dictionary emitAnchorIds = scope .(); + + bool hasUncertainEmits = false; + bool emitInitialized = false; + + void CheckInitEmit() + { + if (emitInitialized) + return; + emitInitialized = true; + if ((hasUncertainEmits) || (resolveType == .None)) + { + // Leave emits alone + for (var typeName in data.mTypeNames) + typeNameMap[typeName] = (.)@typeName.Index; + for (var emitData in ref data.mEmitData) + { + emitAnchorIds[emitData.mAnchorId] = (.)@emitData.Index; + if (resolveType == .None) + emitData.mIncludedInResolveAll = false; + else + emitData.mIncludedInClassify = false; + } + return; + } + + hasUncertainEmits = false; + data.ClearEmit(); + } for (var line in collapseText.Split('\n', .RemoveEmptyEntries)) { SourceEditWidgetContent.CollapseEntry.Kind kind = (.)line[0]; line.RemoveFromStart(1); + if (kind == .HasUncertainEmits) + { + hasUncertainEmits = true; + continue; + } + + if ((kind == .EmitAddType) || (kind.IsEmit)) + { + CheckInitEmit(); + } + if (kind == .EmitAddType) { - data.mTypeNames.Add(new String(line)); + if (typeNameMap.TryAdd(line, var keyPtr, var valuePtr)) + { + data.mTypeNames.Add(new String(line)); + *valuePtr = (.)data.mTypeNames.Count - 1; + } + typeNameIdxMap.Add(*valuePtr); continue; } @@ -6288,15 +6359,40 @@ namespace IDE.ui { EmitData emitData; emitData.mKind = kind; - emitData.mTypeNameIdx = int32.Parse(itr.GetNext().Value); + int typeNameIdx = int32.Parse(itr.GetNext().Value); + emitData.mTypeNameIdx = typeNameIdxMap[typeNameIdx]; emitData.mAnchorIdx = int32.Parse(itr.GetNext().Value); emitData.mStartLine = int32.Parse(itr.GetNext().Value); emitData.mEndLine = int32.Parse(itr.GetNext().Value); emitData.mAnchorId = lookupCtx.GetIdAtIndex(emitData.mAnchorIdx); + emitData.mOnlyInResolveAll = resolveType == .None; + emitData.mIncludedInClassify = resolveType != .None; + emitData.mIncludedInResolveAll = resolveType == .None; + + if (emitAnchorIds.TryGetValue(emitData.mAnchorId, var idx)) + { + var curEmitData = ref data.mEmitData[idx]; + + if (resolveType == .None) + { + curEmitData.mIncludedInResolveAll = true; + } + else + { + emitData.mIncludedInClassify |= curEmitData.mIncludedInClassify; + curEmitData = emitData; + } + + continue; + } + data.mEmitData.Add(emitData); continue; } + if (resolveType == .None) + continue; + CollapseData collapseData; collapseData.mAnchorIdx = int32.Parse(itr.GetNext().Value); @@ -6322,6 +6418,23 @@ namespace IDE.ui data.mCollapseData.Add(collapseData); } + CheckInitEmit(); + + for (var emitData in ref data.mEmitData) + { + if (((emitData.mOnlyInResolveAll) && (!emitData.mIncludedInResolveAll)) || + ((!emitData.mOnlyInResolveAll) && (!emitData.mIncludedInClassify))) + { + @emitData.RemoveFast(); + continue; + } + + if ((emitData.mOnlyInResolveAll) && (!emitData.mIncludedInClassify)) + { + gApp.mBfResolveCompiler.mWantsResolveAllCollapseRefresh = true; + } + } + data.mCollapseParseRevision++; data.mCollapseTextVersionId = textVersion; } diff --git a/IDE/src/ui/SourceViewPanel.bf b/IDE/src/ui/SourceViewPanel.bf index dc3df107..c879e122 100644 --- a/IDE/src/ui/SourceViewPanel.bf +++ b/IDE/src/ui/SourceViewPanel.bf @@ -369,6 +369,7 @@ namespace IDE.ui public String mData = new .() ~ delete _; public int32 mTextVersion; public IdSpan mCharIdSpan ~ _.Dispose(); + public ResolveType mResolveType; } class QueuedEmitShowData @@ -424,6 +425,7 @@ namespace IDE.ui bool mWantsFastClassify; bool mWantsFullClassify; // This triggers a classify bool mWantsFullRefresh; // If mWantsFullClassify is set, mWantsFullRefresh makes the whole thing refresh + bool mWantsCollapseRefresh; bool mRefireMouseOverAfterRefresh; bool mWantsBackgroundAutocomplete; QueuedAutoComplete mQueuedAutoComplete ~ delete _; @@ -636,7 +638,6 @@ namespace IDE.ui AddWidget(mNavigationBar); } } - public ~this() { if (mInPostRemoveUpdatePanels) @@ -889,6 +890,11 @@ namespace IDE.ui //mDidClangSource = false; } + public void QueueCollapseRefresh() + { + mWantsCollapseRefresh = true; + } + public override bool EscapeHandler() { if (IDEApp.sApp.mSymbolReferenceHelper != null) @@ -1174,7 +1180,7 @@ namespace IDE.ui useResolveType = ResolveType.Autocomplete; } - bool doBackground = (useResolveType == ResolveType.Classify) || (useResolveType == ResolveType.ClassifyFullRefresh); + bool doBackground = (useResolveType == .Classify) || (useResolveType == .ClassifyFullRefresh); if (mAsyncAutocomplete) { if ((useResolveType == .Autocomplete) || (useResolveType == .GetCurrentLocation) || (useResolveType == .GetSymbolInfo) || @@ -1438,6 +1444,31 @@ namespace IDE.ui bfSystem.Unlock(); } + public void DoRefreshCollapse(BfParser parser, int32 textVersion, IdSpan charIdSpan) + { + var bfCompiler = BfResolveCompiler; + + String explicitEmitTypeNames = scope .(); + for (var explicitType in mExplicitEmitTypes) + { + explicitEmitTypeNames.Append(explicitType); + explicitEmitTypeNames.Append("\n"); + } + + var resolvePassData = parser.CreateResolvePassData(.None); + defer delete resolvePassData; + + var collapseData = bfCompiler.GetCollapseRegions(parser, resolvePassData, explicitEmitTypeNames, .. scope .()); + using (mMonitor.Enter()) + { + DeleteAndNullify!(mQueuedCollapseData); + mQueuedCollapseData = new .(); + mQueuedCollapseData.mData.Set(collapseData); + mQueuedCollapseData.mTextVersion = textVersion; + mQueuedCollapseData.mCharIdSpan = charIdSpan; + } + } + public void DoFullClassify(ResolveParams resolveParams) { var bfCompiler = BfResolveCompiler; @@ -1457,7 +1488,7 @@ namespace IDE.ui public void DoFastClassify() { - if (!mIsSourceCode) + if ((!mIsSourceCode) || (mEmbedKind != .None)) return; //Debug.WriteLine("DoFastClassify"); @@ -1911,7 +1942,8 @@ namespace IDE.ui var bfCompiler = BfResolveCompiler; //var compiler = ResolveCompiler; - bool isBackground = (resolveType == .Classify) || (resolveType == .ClassifyFullRefresh) || (resolveType == .GetResultString) || (resolveType == .GoToDefinition); + bool isBackground = (resolveType == .Classify) || (resolveType == .ClassifyFullRefresh) || + (resolveType == .GetResultString) || (resolveType == .GoToDefinition); bool fullRefresh = resolveType == ResolveType.ClassifyFullRefresh; if (!isBackground) @@ -2112,7 +2144,7 @@ namespace IDE.ui bfSystem.Lock(0); } - if (!isFastClassify) + if (!isFastClassify) parser.BuildDefs(passInstance, resolvePassData, fullRefresh); // For Fixits we do want to parse the whole file but we need the cursorIdx bound still to @@ -2142,11 +2174,6 @@ namespace IDE.ui { parser.CreateClassifier(passInstance, resolvePassData, charData); - if (resolveType == .ClassifyFullRefresh) - { - NOP!(); - } - if (resolveParams != null) { for (var emitEmbedData in resolveParams.mEmitEmbeds) @@ -2157,7 +2184,7 @@ namespace IDE.ui if (bfCompiler.ClassifySource(passInstance, resolvePassData)) { - if ((resolveType == ResolveType.Classify) || (resolveType == ResolveType.ClassifyFullRefresh)) + if ((resolveType == .Classify) || (resolveType == .ClassifyFullRefresh)) { String explicitEmitTypeNames = scope .(); for (var explicitType in mExplicitEmitTypes) @@ -2166,14 +2193,23 @@ namespace IDE.ui explicitEmitTypeNames.Append("\n"); } - var collapseData = bfCompiler.GetCollapseRegions(parser, resolvePassData, explicitEmitTypeNames, .. scope .()); - using (mMonitor.Enter()) + bool allowCollapseData = resolveType == .ClassifyFullRefresh; + if (allowCollapseData) { - DeleteAndNullify!(mQueuedCollapseData); - mQueuedCollapseData = new .(); - mQueuedCollapseData.mData.Set(collapseData); - mQueuedCollapseData.mTextVersion = resolveParams.mTextVersion; - mQueuedCollapseData.mCharIdSpan = resolveParams.mCharIdSpan.Duplicate(); + var collapseData = bfCompiler.GetCollapseRegions(parser, resolvePassData, explicitEmitTypeNames, .. scope .()); + using (mMonitor.Enter()) + { + DeleteAndNullify!(mQueuedCollapseData); + mQueuedCollapseData = new .(); + mQueuedCollapseData.mData.Set(collapseData); + mQueuedCollapseData.mTextVersion = resolveParams.mTextVersion; + mQueuedCollapseData.mCharIdSpan = resolveParams.mCharIdSpan.Duplicate(); + mQueuedCollapseData.mResolveType = resolveType; + } + } + else + { + QueueFullRefresh(false); } } @@ -6445,11 +6481,39 @@ namespace IDE.ui if (Classify(mWantsFullRefresh ? ResolveType.ClassifyFullRefresh : ResolveType.Classify)) { mWantsFullClassify = false; - mWantsFullRefresh = false; + mWantsFullRefresh = false; + mWantsCollapseRefresh = false; } canDoBackground = false; } } + else if (mWantsCollapseRefresh) + { + if (!compiler.IsPerformingBackgroundOperation()) + { + bfSystem?.Log("SourceViewPanel handling mWantsCollapseRefresh"); + mWantsCollapseRefresh = false; + /*Classify(.GetCollapse);*/ + + if ((projectSource != null) && (mIsBeefSource)) + do + { + var bfProject = bfSystem.GetBfProject(projectSource.mProject); + if (bfProject.mDisabled) + break; + + var bfParser = bfSystem.FindParser(projectSource); + if (bfParser == null) + break; + + var data = mEditWidget.mEditWidgetContent.mData; + compiler.DoBackground(new () => + { + DoRefreshCollapse(bfParser, data.mCurTextVersionId, data.mTextIdData.Duplicate()); + }); + } + } + } else if (mWantsParserCleanup) { if (!compiler.IsPerformingBackgroundOperation()) @@ -6734,7 +6798,7 @@ namespace IDE.ui using (mMonitor.Enter()) { if (mQueuedCollapseData != null) - ewc.ParseCollapseRegions(mQueuedCollapseData.mData, mQueuedCollapseData.mTextVersion, ref mQueuedCollapseData.mCharIdSpan); + ewc.ParseCollapseRegions(mQueuedCollapseData.mData, mQueuedCollapseData.mTextVersion, ref mQueuedCollapseData.mCharIdSpan, mQueuedCollapseData.mResolveType); DeleteAndNullify!(mQueuedCollapseData); } @@ -6967,7 +7031,7 @@ namespace IDE.ui } else { - mNavigationBar.mVisible = false; + mNavigationBar?.mVisible = false; } // Always leave enough to read the first 3 lines diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index 192276f2..eb076579 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -7199,16 +7199,13 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) bool didWork = false; UpdateDependencyMap(mOptions.mCompileOnDemandKind != BfCompileOnDemandKind_ResolveUnused, didWork); - - if (mOptions.mCompileOnDemandKind != BfCompileOnDemandKind_AlwaysInclude) + + // If UpdateDependencyMap caused methods to be reified, then we need to run PopulateReified again- + // because those methods may be virtual and we need to reify overrides (for example). + // We use the DoWorkLoop result to determine if there were actually any changes from UpdateDependencyMap + if (didWork) { - // If UpdateDependencyMap caused methods to be reified, then we need to run PopulateReified again- - // because those methods may be virtual and we need to reify overrides (for example). - // We use the DoWorkLoop result to determine if there were actually any changes from UpdateDependencyMap - if (didWork) - { - PopulateReified(); - } + PopulateReified(); } } @@ -9814,6 +9811,8 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo }; Dictionary> emitLocMap; + bool mayHaveMissedEmits = false; + for (auto type : bfCompiler->mContext->mResolvedTypes) { auto typeInst = type->ToTypeInstance(); @@ -9825,6 +9824,12 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo if (typeInst->mCeTypeInfo == NULL) continue; + if ((typeInst->mCeTypeInfo->mMayHaveUniqueEmitLocations) && (!mayHaveMissedEmits)) + { + outString += "~\n"; + mayHaveMissedEmits = true; + } + for (auto& kv : typeInst->mCeTypeInfo->mEmitSourceMap) { int partialIdx = (int)(kv.mKey >> 32); diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index e81b43a6..6a5f3ddd 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -2091,6 +2091,9 @@ void BfModule::SetTypeOptions(BfTypeInstance* typeInstance) BfCEParseContext BfModule::CEEmitParse(BfTypeInstance* typeInstance, BfTypeDef* declaringType, const StringImpl& src, BfAstNode* refNode, BfCeTypeEmitSourceKind emitSourceKind) { + if (mCompiler->mResolvePassData != NULL) + mCompiler->mResolvePassData->mHadEmits = true; + BfCEParseContext ceParseContext; ceParseContext.mFailIdx = mCompiler->mPassInstance->mFailedIdx; ceParseContext.mWarnIdx = mCompiler->mPassInstance->mWarnIdx; @@ -2114,10 +2117,20 @@ BfCEParseContext BfModule::CEEmitParse(BfTypeInstance* typeInstance, BfTypeDef* } else { - ceTypeInfo->mEmitSourceMap.TryAdd(emitSourceMapKey, NULL, &ceEmitSource); + if (ceTypeInfo->mEmitSourceMap.TryAdd(emitSourceMapKey, NULL, &ceEmitSource)) + { + if (typeInstance->IsSpecializedType()) + { + auto unspecializedType = GetUnspecializedTypeInstance(typeInstance); + if ((unspecializedType->mCeTypeInfo == NULL) || (!unspecializedType->mCeTypeInfo->mEmitSourceMap.ContainsKey(emitSourceMapKey))) + ceTypeInfo->mMayHaveUniqueEmitLocations = true; + } + } ceEmitSource->mKind = emitSourceKind; } + BfLogSysM("CEEmitParse type %p ceTypeInfo %p\n", typeInstance, ceTypeInfo); + int emitSrcStart = 0; BfEmitEmbedEntry* emitEmbedEntry = NULL; @@ -4748,6 +4761,8 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy { if (typeInstance->mCeTypeInfo->mNext != NULL) { + BfLogSysM("Type %p injecting next ceTypeInfo %p into ceTypeInfo %p\n", typeInstance, typeInstance->mCeTypeInfo->mNext, typeInstance->mCeTypeInfo); + auto ceInfo = typeInstance->mCeTypeInfo->mNext; HashContext hashCtx; @@ -5799,7 +5814,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) ambiguityContext.mTypeInstance = typeInstance; ambiguityContext.mModule = this; ambiguityContext.mIsProjectSpecific = false; - + bool wantsOnDemandMethods = false; //TODO: Testing having interface methods be "on demand"... //if (!typeInstance->IsInterface()) @@ -5825,6 +5840,36 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) if (TypeIsSubTypeOf(typeInstance, mCompiler->mAttributeTypeDef)) wantsOnDemandMethods = false; + if ((mCompiler->mResolvePassData != NULL) && (!mCompiler->mResolvePassData->mEmitEmbedEntries.IsEmpty()) && (typeInstance->IsSpecializedType())) + { + bool isCurrentEntry = false; + + auto _CheckEntry = [&](BfTypeDef* typeDef) + { + auto parser = typeDef->mTypeDeclaration->GetParser(); + if (parser != NULL) + if (mCompiler->mResolvePassData->GetSourceClassifier(parser) != NULL) + isCurrentEntry = true; + }; + + _CheckEntry(typeInstance->mTypeDef); + for (auto& partial : typeInstance->mTypeDef->mPartials) + _CheckEntry(partial); + + if (isCurrentEntry) + { + String typeName; + typeName += typeInstance->mTypeDef->mProject->mName; + typeName += ":"; + typeName += TypeToString(typeInstance, BfTypeNameFlags_None); + + if (mCompiler->mResolvePassData->mEmitEmbedEntries.ContainsKey(typeName)) + { + wantsOnDemandMethods = false; + } + } + } + //bool allDeclsRequired = (mIsReified) && (mCompiler->mOptions.mEmitDebugInfo) && (); bool allDeclsRequired = false; //if ((mIsReified) && (mCompiler->mOptions.mEmitDebugInfo) && (!mCompiler->mWantsDeferMethodDecls)) @@ -10210,9 +10255,9 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula auto directStrTypeRef = BfNodeDynCastExact(typeRef); if (((namedTypeRef != NULL) && (namedTypeRef->mNameNode != NULL)) || (directStrTypeRef != NULL)) { - StringT<128> findName; + StringView findName; if (namedTypeRef != NULL) - namedTypeRef->mNameNode->ToString(findName); + findName = namedTypeRef->mNameNode->ToStringView(); else findName = directStrTypeRef->mTypeName; if (findName == "Self") diff --git a/IDEHelper/Compiler/BfResolvePass.cpp b/IDEHelper/Compiler/BfResolvePass.cpp index aa3cdcc5..5474cd2d 100644 --- a/IDEHelper/Compiler/BfResolvePass.cpp +++ b/IDEHelper/Compiler/BfResolvePass.cpp @@ -21,6 +21,7 @@ BfResolvePassData::BfResolvePassData() mResolveType = BfResolveType_None; mIsClassifying = false; mHasCursorIdx = false; + mHadEmits = false; } BfResolvePassData::~BfResolvePassData() diff --git a/IDEHelper/Compiler/BfResolvePass.h b/IDEHelper/Compiler/BfResolvePass.h index f41c6b31..66dc4639 100644 --- a/IDEHelper/Compiler/BfResolvePass.h +++ b/IDEHelper/Compiler/BfResolvePass.h @@ -83,6 +83,7 @@ public: int mSymbolTypeGenericParamIdx; bool mIsClassifying; bool mHasCursorIdx; + bool mHadEmits; typedef Dictionary FoundSymbolReferencesParserDataMap; FoundSymbolReferencesParserDataMap mFoundSymbolReferencesParserData; diff --git a/IDEHelper/Compiler/BfStmtEvaluator.cpp b/IDEHelper/Compiler/BfStmtEvaluator.cpp index c0a987c6..a64458ed 100644 --- a/IDEHelper/Compiler/BfStmtEvaluator.cpp +++ b/IDEHelper/Compiler/BfStmtEvaluator.cpp @@ -1766,11 +1766,6 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD _CheckConst(); - if (isStatic) - { - NOP; - } - if ((initValue.mKind == BfTypedValueKind_TempAddr) && (!initHandled)) { BF_ASSERT(initValue.IsAddr()); diff --git a/IDEHelper/Compiler/BfSystem.cpp b/IDEHelper/Compiler/BfSystem.cpp index 5748d449..366d5c30 100644 --- a/IDEHelper/Compiler/BfSystem.cpp +++ b/IDEHelper/Compiler/BfSystem.cpp @@ -4013,6 +4013,11 @@ BF_EXPORT void* BfResolvePassData_GetEmitEmbedData(BfResolvePassData* resolvePas return emitEmbedEntry->mParser->mSourceClassifier->mCharData; } +BF_EXPORT bool BfResolvePassData_GetHadEmits(BfResolvePassData* resolvePassData) +{ + return resolvePassData->mHadEmits; +} + BF_EXPORT BfParser* BF_CALLTYPE BfSystem_CreateParser(BfSystem* bfSystem, BfProject* bfProject) { return bfSystem->CreateParser(bfProject); diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index bdf8a93c..283be9bd 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -3286,11 +3286,7 @@ void CeBuilder::Build() } if (mCeFunction->mGenError.IsEmpty()) - mCeFunction->mFailed = false; - else - { - NOP; - } + mCeFunction->mFailed = false; mCeFunction->mFrameSize = mFrameSize; } diff --git a/IDEHelper/Compiler/CeMachine.h b/IDEHelper/Compiler/CeMachine.h index fd6d6938..eb106bea 100644 --- a/IDEHelper/Compiler/CeMachine.h +++ b/IDEHelper/Compiler/CeMachine.h @@ -1012,12 +1012,14 @@ public: Dictionary mRebuildMap; Val128 mHash; bool mFailed; + bool mMayHaveUniqueEmitLocations; BfCeTypeInfo* mNext; public: BfCeTypeInfo() { mFailed = false; + mMayHaveUniqueEmitLocations = false; mNext = NULL; } };