Quellcode durchsuchen

Improved emit marker resolve/build selection, emitted Go To Definition

Brian Fiete vor 3 Jahren
Ursprung
Commit
6ded6a37cc

+ 6 - 0
BeefLibs/Beefy2D/src/theme/dark/DarkEditWidget.bf

@@ -458,6 +458,12 @@ namespace Beefy.theme.dark
 			LineStartsChanged();
 		}
 
+		public override void ClearText()
+		{
+			mLineRange = null;
+			base.ClearText();
+		}
+
         public virtual float DrawText(Graphics g, String str, float x, float y, uint16 typeIdAndFlags)
         {
             using (g.PushColor(mTextColors[typeIdAndFlags & 0xFF]))

+ 67 - 17
IDE/src/IDEApp.bf

@@ -1504,6 +1504,11 @@ namespace IDE
 					useFileName = scope:: $"$Emit${useFileName.Substring("$Emit$Build$".Length)}";
 					compiler = mBfBuildCompiler;
 				}
+				else if (useFileName.StartsWith("$Emit$Resolve$"))
+				{
+					useFileName = scope:: $"$Emit${useFileName.Substring("$Emit$Resolve$".Length)}";
+					compiler = mBfResolveCompiler;
+				}
 
 				if (!compiler.IsPerformingBackgroundOperation())
 					compiler.GetEmitSource(useFileName, outBuffer);
@@ -7153,31 +7158,76 @@ namespace IDE
 					return null;
 				}
 
-				var itr = filePath.Split('$');
-				itr.GetNext();
-				itr.GetNext();
-				var typeName = itr.GetNext().Value;
-
-				mBfBuildCompiler.mBfSystem.Lock(0);
-				var embedFilePath = mBfBuildCompiler.GetEmitLocation(typeName, line, .. scope .(), var embedLine, var embedLineChar, var embedHash);
-				mBfBuildCompiler.mBfSystem.Unlock();
-
+				String embedFilePath;
 				bool isViewValid = true;
+				StringView typeName;
+				int embedLine;
+				int embedLineChar;
 
-				if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Resolve)
+				if (filePath.StartsWith("$Emit$Resolve$"))
 				{
-					mBfResolveCompiler.mBfSystem.Lock(0);
-					mBfResolveCompiler.GetEmitLocation(typeName, line, .. scope .(), var resolveLine, var resolveLineChar, var resolveHash);
-					mBfResolveCompiler.mBfSystem.Unlock();
-
-					if ((resolveLine != embedLine) || (resolveLineChar != embedLineChar) || (embedHash != resolveHash))
+					if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Resolve)
+					{
+						var itr = filePath.Split('$');
+						itr.GetNext();
+						itr.GetNext();
+						itr.GetNext();
+						typeName = itr.GetNext().Value;
+	
+						mBfResolveCompiler.mBfSystem.Lock(0);
+						embedFilePath = mBfResolveCompiler.GetEmitLocation(typeName, line, .. scope:: .(), out embedLine, out embedLineChar, var embedHash);
+						mBfResolveCompiler.mBfSystem.Unlock();
+						
+						useFilePath = scope:: $"$Emit${useFilePath.Substring("$Emit$Resolve$".Length)}";
+					}
+					else
+						isViewValid = false;
+				}
+				else if (filePath.StartsWith("$Emit$Build$"))
+				{
+					if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Build)
 					{
+						var itr = filePath.Split('$');
+						itr.GetNext();
+						itr.GetNext();
+						itr.GetNext();
+						typeName = itr.GetNext().Value;
+	
+						mBfBuildCompiler.mBfSystem.Lock(0);
+						embedFilePath = mBfBuildCompiler.GetEmitLocation(typeName, line, .. scope:: .(), out embedLine, out embedLineChar, var embedHash);
+						mBfBuildCompiler.mBfSystem.Unlock();
+						
+						useFilePath = scope:: $"$Emit${useFilePath.Substring("$Emit$Build$".Length)}";
+					}
+					else
 						isViewValid = false;
-						useFilePath = scope:: $"$Emit$Build${useFilePath.Substring("$Emit$".Length)}";
+				}
+				else
+				{
+					var itr = filePath.Split('$');
+					itr.GetNext();
+					itr.GetNext();
+					typeName = itr.GetNext().Value;
+
+					mBfBuildCompiler.mBfSystem.Lock(0);
+					embedFilePath = mBfBuildCompiler.GetEmitLocation(typeName, line, .. scope:: .(), out embedLine, out embedLineChar, var embedHash);
+					mBfBuildCompiler.mBfSystem.Unlock();
+
+					if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Resolve)
+					{
+						mBfResolveCompiler.mBfSystem.Lock(0);
+						mBfResolveCompiler.GetEmitLocation(typeName, line, scope .(), var resolveLine, var resolveLineChar, var resolveHash);
+						mBfResolveCompiler.mBfSystem.Unlock();
+
+						if ((resolveLine != embedLine) || (resolveLineChar != embedLineChar) || (embedHash != resolveHash))
+						{
+							isViewValid = false;
+							useFilePath = scope:: $"$Emit$Build${useFilePath.Substring("$Emit$".Length)}";
+						}
 					}
 				}
 
-				if ((!embedFilePath.IsEmpty) && (isViewValid))
+				if ((isViewValid) && (!embedFilePath.IsEmpty))
 				{
 					var sourceViewPanel = ShowSourceFile(scope .(embedFilePath), null, showTemp ? SourceShowType.Temp : SourceShowType.ShowExisting).panel;
 					if (sourceViewPanel == null)

+ 6 - 1
IDE/src/ui/RenameSymbolDialog.bf

@@ -244,7 +244,12 @@ namespace IDE.ui
 					if (mKind == .GoToDefinition)
 					{
 					    mSourceViewPanel.RecordHistoryLocation();
-					    var sourceViewPanel = gApp.ShowSourceFileLocation(scope .(filePath), -1, -1, line, lineChar, LocatorType.Smart, true);
+
+						var usePath = scope String(filePath);
+						if (usePath.StartsWith("$Emit$"))
+							usePath.Insert("$Emit$".Length, "Resolve$");
+
+					    var sourceViewPanel = gApp.ShowSourceFileLocation(usePath, -1, -1, line, lineChar, LocatorType.Smart, true);
 					    sourceViewPanel.RecordHistoryLocation(true);
 						Close();
 						return;

+ 14 - 2
IDE/src/ui/SourceEditWidgetContent.bf

@@ -1839,7 +1839,19 @@ namespace IDE.ui
                 int line;
                 int lineChar;
                 GetCursorLineChar(out line, out lineChar);
-                return IDEApp.sApp.mHistoryManager.CreateHistory(mSourceViewPanel, mSourceViewPanel.mFilePath, line, lineChar, ignoreIfClose);
+
+				String useFilePath = mSourceViewPanel.mFilePath;
+				if ((mSourceViewPanel.mFilePath.StartsWith("$Emit$")) &&
+					(!mSourceViewPanel.mFilePath.StartsWith("$Emit$Build$")) &&
+					(!mSourceViewPanel.mFilePath.StartsWith("$Emit$Resolve$")))
+				{
+					if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Resolve)
+						useFilePath = scope:: String("$Emit$Resolve$")..Append(mSourceViewPanel.mFilePath.Substring("$Emit$".Length));
+					else
+						useFilePath = scope:: String("$Emit$Build$")..Append(mSourceViewPanel.mFilePath.Substring("$Emit$".Length));
+				}
+
+                return IDEApp.sApp.mHistoryManager.CreateHistory(mSourceViewPanel, useFilePath, line, lineChar, ignoreIfClose);
             }
 			return null;
         }
@@ -6505,7 +6517,7 @@ namespace IDE.ui
 
 			var data = PreparedData;
 
-			if (resolveType != .None)
+			if ((resolveType != null) && (resolveType != .None))
 			{
 				data.ClearCollapse();
 			}

+ 46 - 14
IDE/src/ui/SourceViewPanel.bf

@@ -1493,6 +1493,10 @@ namespace IDE.ui
 					defer delete buildResolvePassData;
 					buildCollapseData = gApp.mBfBuildCompiler.GetCollapseRegions(buildParser, buildResolvePassData, explicitEmitTypeNames, .. scope:: .());
 				}
+				else
+				{
+					buildCollapseData = "";
+				}
 				gApp.mBfBuildSystem.Unlock();
 			}
 
@@ -2504,7 +2508,10 @@ namespace IDE.ui
             int32 prevLine = mEditWidget.Content.CursorLineAndColumn.mLine;
 			
             mEditWidget.Content.mSelection = null;
-            mEditWidget.Content.CursorTextPos = cursorIdx;
+
+			int wantCursorPos = Math.Min(mEditWidget.Content.mData.mTextLength - 1, cursorIdx);
+			if (wantCursorPos >= 0)
+            	mEditWidget.Content.CursorTextPos = wantCursorPos;
             mEditWidget.Content.CursorMoved();
             mEditWidget.Content.EnsureCursorVisible(true, true);
 			mEditWidget.Content.mCursorImplicitlyMoved = true;
@@ -6288,15 +6295,15 @@ namespace IDE.ui
 										emitEmbedView.mGenericMethodCombo?.mEditWidget.SetFocus();
 								}
 
-								var sourceViewPanel = emitEmbedView.mSourceViewPanel;
+								var firstSourceViewPanel = emitEmbedView.mSourceViewPanel;
 
-								var embedEWC = sourceViewPanel.mEditWidget.mEditWidgetContent;
+								var firstEmbedEWC = firstSourceViewPanel.mEditWidget.mEditWidgetContent;
 
-								var prevCursorLineAndColumn = embedEWC.CursorLineAndColumn;
+								var prevCursorLineAndColumn = firstEmbedEWC.CursorLineAndColumn;
 
-								var editData = sourceViewPanel.mEditWidget.mEditWidgetContent.mData;
+								var editData = firstSourceViewPanel.mEditWidget.mEditWidgetContent.mData;
 								if (editData.mTextLength == 0)
-									DeleteAndNullify!(sourceViewPanel.mTrackedTextElementViewList);
+									DeleteAndNullify!(firstSourceViewPanel.mTrackedTextElementViewList);
 
 								delete editData.mText;
 								editData.mText = embed.mCharData;
@@ -6307,15 +6314,23 @@ namespace IDE.ui
 								editData.mNextCharId = 0;
 								editData.mTextIdData.Insert(0, editData.mTextLength, ref editData.mNextCharId);
 
-								sourceViewPanel.mEditWidget.mEditWidgetContent.ContentChanged();
-								// We have a full classify now, FastClassify will just mess it up
-								sourceViewPanel.mSkipFastClassify = true; 
+								firstSourceViewPanel.mEmitRevision = embed.mRevision;
+								firstSourceViewPanel.InjectErrors(resolveResult.mPassInstance, editData.mText, editData.mTextIdData, false, true);
+
+								for (var user in editData.mUsers)
+								{
+									if (var embedEWC = user as SourceEditWidgetContent)
+									{
+										var sourceViewPanel = embedEWC.mSourceViewPanel;
+
+										sourceViewPanel.mEditWidget.mEditWidgetContent.ContentChanged();
+										// We have a full classify now, FastClassify will just mess it up
+										sourceViewPanel.mSkipFastClassify = true; 
 
-								if (prevCursorLineAndColumn.mLine >= embedEWC.GetLineCount())
-									embedEWC.CursorLineAndColumn = .(embedEWC.GetLineCount() - 1, prevCursorLineAndColumn.mColumn);
-								
-								sourceViewPanel.mEmitRevision = embed.mRevision;
-								sourceViewPanel.InjectErrors(resolveResult.mPassInstance, editData.mText, editData.mTextIdData, false, true);
+										if (prevCursorLineAndColumn.mLine >= firstEmbedEWC.GetLineCount())
+											embedEWC.CursorLineAndColumn = .(firstEmbedEWC.GetLineCount() - 1, prevCursorLineAndColumn.mColumn);
+									}
+								}
 							}
 						}
 					}
@@ -6868,11 +6883,14 @@ namespace IDE.ui
 					{
 						if (mQueuedCollapseData.mBuildData != null)
 						{
+							bool foundData = false;
+
 							using (gApp.mMonitor.Enter())
 							{                
 							    var projectSourceCompileInstance = gApp.mWorkspace.GetProjectSourceCompileInstance(projectSource, gApp.mWorkspace.HotCompileIdx);
 								if (projectSourceCompileInstance != null)
 								{
+									foundData = true;
 									ewc.ParseCollapseRegions(mQueuedCollapseData.mBuildData, mQueuedCollapseData.mTextVersion, ref projectSourceCompileInstance.mSourceCharIdData, null);
 
 									HashSet<EditWidgetContent.Data> dataLoaded = scope .();
@@ -6894,6 +6912,20 @@ namespace IDE.ui
 									}
 								}
 							}
+
+							if (!foundData)
+							{
+								for (var embed in ewc.mEmbeds.Values)
+								{
+									if (var emitEmbed = embed as SourceEditWidgetContent.EmitEmbed)
+									{
+										if (emitEmbed.mView != null)
+										{
+											emitEmbed.mView.mSourceViewPanel.mEditWidget.mEditWidgetContent.ClearText();
+										}
+									}
+								}
+							}
 						}
 					}
 					

+ 2 - 0
IDEHelper/Compiler/BfAutoComplete.cpp

@@ -3155,6 +3155,8 @@ bool BfAutoComplete::CheckFixit(BfAstNode* node)
 {
 	if (mIgnoreFixits)
 		return false;
+	if (mModule == NULL)
+		return false;
 	if (mCompiler->mResolvePassData->mResolveType != BfResolveType_GetFixits)
 		return false;
 	if (!IsAutocompleteLineNode(node))

+ 38 - 4
IDEHelper/Compiler/BfContext.cpp

@@ -592,6 +592,8 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods)
 
 				auto owner = methodInstance->mMethodInstanceGroup->mOwner;
 
+				auto autoComplete = mCompiler->GetAutoComplete();
+
 				BF_ASSERT(!module->mAwaitingFinish);
 				if ((resolveParser != NULL) && (methodInstance->mMethodDef->mDeclaringType != NULL) && (methodInstance->mMethodDef->mDeclaringType->GetDefinition()->mSource != resolveParser))
 				{
@@ -599,6 +601,39 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods)
 					if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mHasCursorIdx))
 					{
 						auto parser = methodInstance->mMethodDef->mDeclaringType->GetLastSource()->ToParser();
+
+						if ((parser != NULL) && (autoComplete != NULL) && (autoComplete->mModule == NULL))
+						{
+							bool emitHasCursor = false;
+							for (auto& checkEntry : mCompiler->mResolvePassData->mEmitEmbedEntries)
+							{
+								if (checkEntry.mValue.mCursorIdx >= 0)
+									emitHasCursor = true;
+							}
+
+							if (emitHasCursor)
+							{
+								// Go To Definition in an emit mixin?
+								BfParser** foundParserPtr = NULL;
+								if (mCompiler->mResolvePassData->mCompatParserMap.TryAdd(parser, NULL, &foundParserPtr))
+								{
+									*foundParserPtr = NULL;
+									for (auto checkParser : mCompiler->mResolvePassData->mParsers)
+									{
+										if ((checkParser->mFileName == parser->mFileName) && (checkParser->mOrigSrcLength == parser->mOrigSrcLength) &&
+											(memcmp(checkParser->mSrc, parser->mSrc, checkParser->mOrigSrcLength) == 0))
+										{
+											*foundParserPtr = checkParser;
+										}
+									}
+								}
+
+								auto* compatParser = *foundParserPtr;
+								if (compatParser != NULL)
+									allow = true;
+							}
+						}
+
 						if ((parser != NULL) && (parser->mCursorIdx >= 0))
 							allow = true;
 					}
@@ -616,13 +651,12 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods)
 				{
 					if (!mCompiler->mIsResolveOnly)
 						BF_ASSERT(!methodInstance->mIsReified || methodInstance->mDeclModule->mIsModuleMutable);
-
-					auto autoComplete = mCompiler->GetAutoComplete();
+					
 					if ((autoComplete != NULL) && (autoComplete->mModule == NULL))
 					{
-						autoComplete->mModule = methodInstance->mDeclModule;
+						autoComplete->SetModule(methodInstance->mDeclModule);
 						ProcessMethod(methodInstance);
-						autoComplete->mModule = NULL;
+						autoComplete->SetModule(NULL);
 					}
 					else
 						ProcessMethod(methodInstance);

+ 9 - 0
IDEHelper/Compiler/BfExprEvaluator.cpp

@@ -6232,6 +6232,15 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
 				((autoComplete->mResolveType != BfResolveType_Autocomplete) &&
 				(autoComplete->mResolveType != BfResolveType_Autocomplete_HighPri) &&
 				(autoComplete->mResolveType != BfResolveType_GetResultString));
+
+			for (auto& entry : mModule->mCompiler->mResolvePassData->mEmitEmbedEntries)
+			{
+				if (entry.mValue.mCursorIdx >= 0)
+				{
+					// Needed for Go To Definition in Compiler.Mixin
+					wantQuickEval = false;
+				}
+			}			
 		}
 
 		if (wantQuickEval)

+ 5 - 4
IDEHelper/Compiler/BfModule.cpp

@@ -11509,6 +11509,7 @@ void BfModule::ClearConstData()
 	mStringCharPtrPool.Clear();
 	mStringPoolRefs.Clear();
 	mUnreifiedStringPoolRefs.Clear();
+	mStaticFieldRefs.Clear();
 }
 
 BfTypedValue BfModule::GetTypedValueFromConstant(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType)
@@ -14860,11 +14861,11 @@ BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance)
 		}
 	}	
 
-	if ((mIsScratchModule) && (mCompiler->mIsResolveOnly))
-	{
+	if ((mIsScratchModule) && (mCompiler->mIsResolveOnly) && (!fieldInstance->mOwner->IsInstanceOf(mCompiler->mCompilerTypeDef)))
+	{		
 		// Just fake it for the extern and unspecialized modules
-		// We can't do this for compilation because unreified methods with default params need to get acutal global variable refs
-		return BfTypedValue(mBfIRBuilder->CreateConstNull(), fieldInstance->GetResolvedType(), true);
+		// We can't do this for compilation because unreified methods with default params need to get actual global variable refs
+		return BfTypedValue(mBfIRBuilder->CreateConstNull(), fieldInstance->GetResolvedType(), true);	
 	}
 	
 	BfIRValue* globalValuePtr = NULL;

+ 2 - 2
IDEHelper/Compiler/BfModuleTypeUtils.cpp

@@ -2378,8 +2378,8 @@ void BfModule::UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeIn
 	if (emitParser->mSourceClassifier != NULL)
 	{
 		emitParser->mSourceClassifier->VisitChild(emitParser->mRootNode);
-		emitParser->mSourceClassifier->VisitChild(emitParser->mSidechannelRootNode);
-		emitParser->mSourceClassifier->VisitChild(emitParser->mErrorRootNode);
+		emitParser->mSourceClassifier->DeferNodes(emitParser->mSidechannelRootNode);
+		emitParser->mSourceClassifier->DeferNodes(emitParser->mErrorRootNode);
 	}
 
 	if (typeInstance->mTypeDef->mEmitParent != NULL)

+ 1 - 0
IDEHelper/Compiler/BfResolvePass.h

@@ -64,6 +64,7 @@ public:
 	BfResolveType mResolveType;
 
 	Array<BfParser*> mParsers;
+	Dictionary<BfParser*, BfParser*> mCompatParserMap;
 	BfAutoComplete* mAutoComplete;
 	Array<BfTypeDef*> mAutoCompleteTempTypes; // Contains multiple values when we have nested types
 	Dictionary<BfTypeDef*, BfStaticSearch> mStaticSearchMap;

+ 13 - 0
IDEHelper/Compiler/BfSourceClassifier.cpp

@@ -694,6 +694,19 @@ void BfSourceClassifier::MarkSkipped(BfAstNode* node)
 	MarkSkipped(node->GetSrcStart(), node->GetSrcEnd());
 }
 
+void BfSourceClassifier::DeferNodes(BfBlock* block)
+{
+	for (auto child : *block)
+		mDeferredNodes.Add(child);
+}
+
+void BfSourceClassifier::FlushDeferredNodes()
+{
+	for (auto node : mDeferredNodes)
+		VisitChild(node);
+	mDeferredNodes.Clear();
+}
+
 void BfSourceClassifier::Visit(BfTypeAliasDeclaration* typeDeclaration)
 {
 	if (typeDeclaration->mIgnoreDeclaration)

+ 3 - 0
IDEHelper/Compiler/BfSourceClassifier.h

@@ -70,6 +70,7 @@ public:
 	BfAstNode* mPrevNode;
 	BfAstNode* mCurMember;
 	BfLocalMethodDeclaration* mCurLocalMethodDeclaration;
+	Array<BfAstNode*> mDeferredNodes;
 
 public:
 	void HandleLeafNode(BfAstNode* node);
@@ -86,6 +87,8 @@ public:
 	void Handle(BfTypeDeclaration* typeDeclaration);
 	void MarkSkipped(int startPos, int endPos);
 	void MarkSkipped(BfAstNode* node);
+	void DeferNodes(BfBlock* block);
+	void FlushDeferredNodes();
 
 public:
 	BfSourceClassifier(BfParser* bfParser, CharData* charData);

+ 4 - 0
IDEHelper/Compiler/BfSystem.cpp

@@ -4075,6 +4075,10 @@ BF_EXPORT void* BfResolvePassData_GetEmitEmbedData(BfResolvePassData* resolvePas
 		return NULL;
 	*revision = emitEmbedEntry->mRevision;
 	*charCount = emitEmbedEntry->mParser->mSrcLength;
+
+	auto emitParser = emitEmbedEntry->mParser;
+	emitParser->mSourceClassifier->FlushDeferredNodes();	
+
 	return emitEmbedEntry->mParser->mSourceClassifier->mCharData;
 }