1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-14 14:24:10 +02:00

Show comptime emits as embedded sourceviews

This commit is contained in:
Brian Fiete 2022-04-16 06:27:54 -07:00
parent ee27f6fd02
commit 4d1e14a1c3
65 changed files with 3360 additions and 633 deletions

View file

@ -1205,10 +1205,21 @@ namespace IDE
linkLine.Append(" /ignore:4099");
}
int targetDotPos = targetPath.LastIndexOf('.');
if (targetDotPos != -1)
{
var writeEmitCmd = new IDEApp.WriteEmitCmd();
writeEmitCmd.mPath = new .(targetPath, 0, targetDotPos);
writeEmitCmd.mPath.Append("__emit.zip");
writeEmitCmd.mProjectName = new .(project.mProjectName);
gApp.mExecutionQueue.Add(writeEmitCmd);
}
var runCmd = gApp.QueueRun(linkerPath, linkLine, gApp.mInstallDir, .UTF16WithBom);
runCmd.mReference = new .(project.mProjectName);
runCmd.mEnvVars = new .() { (new String("VSLANG"), new String("1033")) };
runCmd.mOnlyIfNotFailed = true;
var tagetCompletedCmd = new IDEApp.TargetCompletedCmd(project);
tagetCompletedCmd.mOnlyIfNotFailed = true;
gApp.mExecutionQueue.Add(tagetCompletedCmd);

View file

@ -58,10 +58,10 @@ namespace IDE.Compiler
static extern bool BfCompiler_VerifyTypeName(void* bfCompiler, char8* typeName, int32 cursorPos);
[CallingConvention(.Stdcall), CLink]
static extern bool BfCompiler_ClassifySource(void* bfCompiler, void* bfPassInstance, void* bfParser, void* bfResolvePassData, void* char8Data);
static extern bool BfCompiler_ClassifySource(void* bfCompiler, void* bfPassInstance, void* bfResolvePassData);
[CallingConvention(.Stdcall), CLink]
static extern char8* BfCompiler_GetCollapseRegions(void* bfCompiler, void* bfParser);
static extern char8* BfCompiler_GetCollapseRegions(void* bfCompiler, void* bfParser, void* bfResolvePassData, char8* explicitEmitTypeNames);
[CallingConvention(.Stdcall), CLink]
static extern char8* BfCompiler_GetAutocompleteInfo(void* bfCompiler);
@ -135,6 +135,12 @@ namespace IDE.Compiler
[CallingConvention(.Stdcall), CLink]
static extern char8* BfCompiler_GetTypeInfo(void* bfCompiler, char8* typeName);
[CallingConvention(.Stdcall), CLink]
static extern char8* BfCompiler_GetGenericTypeInstances(void* bfCompiler, char8* typeName);
[CallingConvention(.Stdcall), CLink]
static extern int32 BfCompiler_GetTypeId(void* bfCompiler, char8* typeName);
[CallingConvention(.Stdcall), CLink]
static extern void BfCompiler_SetOptions(void* bfCompiler,
void* hotProject, int32 hotIdx, char8* targetTriple, char8* targetCPU, int32 toolsetType, int32 simdSetting, int32 allocStackCount, int32 maxWorkerThreads,
@ -149,6 +155,12 @@ namespace IDE.Compiler
[CallingConvention(.Stdcall), CLink]
static extern int32 BfCompiler_GetEmitSourceVersion(void* bfCompiler, char8* fileName);
[CallingConvention(.Stdcall), CLink]
static extern char8* BfCompiler_GetEmitLocation(void* bfCompiler, char8* typeName, int32 line, out int32 embedLine, out int32 embedLineChar);
[CallingConvention(.Stdcall), CLink]
static extern void BfCompiler_WriteEmitData(void* bfCompiler, char8* filePath, void* bfProject);
public enum HotTypeFlags
{
None = 0,
@ -260,18 +272,17 @@ namespace IDE.Compiler
BfCompiler_ClearResults(mNativeBfCompiler);
}
public bool ClassifySource(BfPassInstance bfPassInstance, BfParser parser, BfResolvePassData resolvePassData, EditWidgetContent.CharData[] char8Data)
public bool ClassifySource(BfPassInstance bfPassInstance, BfResolvePassData resolvePassData)
{
void* nativeResolvePassData = null;
if (resolvePassData != null)
nativeResolvePassData = resolvePassData.mNativeResolvePassData;
EditWidgetContent.CharData* char8DataPtr = (char8Data != null) ? char8Data.CArray() : null;
return BfCompiler_ClassifySource(mNativeBfCompiler, bfPassInstance.mNativeBfPassInstance, (parser != null) ? parser.mNativeBfParser : null, nativeResolvePassData, char8DataPtr);
return BfCompiler_ClassifySource(mNativeBfCompiler, bfPassInstance.mNativeBfPassInstance, nativeResolvePassData);
}
public void GetCollapseRegions(BfParser parser, String outData)
public void GetCollapseRegions(BfParser parser, BfResolvePassData resolvePassData, String explicitEmitTypeNames, String outData)
{
outData.Append(BfCompiler_GetCollapseRegions(mNativeBfCompiler, (parser != null) ? parser.mNativeBfParser : null));
outData.Append(BfCompiler_GetCollapseRegions(mNativeBfCompiler, (parser != null) ? parser.mNativeBfParser : null, resolvePassData.mNativeResolvePassData, explicitEmitTypeNames));
}
public bool VerifyTypeName(String typeName, int cursorPos)
@ -344,6 +355,15 @@ namespace IDE.Compiler
return BfCompiler_GetEmitSourceVersion(mNativeBfCompiler, fileName.ToScopeCStr!());
}
public void GetEmitLocation(StringView typeName, int line, String outFilePath, out int embedLine, out int embedLineChar)
{
int32 embedLine32;
int32 embedLineChar32;
outFilePath.Append(BfCompiler_GetEmitLocation(mNativeBfCompiler, typeName.ToScopeCStr!(), (.)line, out embedLine32, out embedLineChar32));
embedLine = embedLine32;
embedLineChar = embedLineChar32;
}
public void QueueSetPassInstance(BfPassInstance passInstance)
{
SetPassInstanceCommand command = new SetPassInstanceCommand();
@ -588,7 +608,7 @@ namespace IDE.Compiler
var resolvePassData = BfResolvePassData.Create(ResolveType.Classify);
// If we get canceled then try again after waiting a couple updates
if (!ClassifySource(passInstance, null, resolvePassData, null))
if (!ClassifySource(passInstance, resolvePassData))
QueueDeferredResolveAll();
UpdateRebuildFileWatches();
@ -808,11 +828,21 @@ namespace IDE.Compiler
outStr.Append(BfCompiler_GetTypeDefInfo(mNativeBfCompiler, typeDefName));
}
public void GetGenericTypeInstances(String typeName, String outStr)
{
outStr.Append(BfCompiler_GetGenericTypeInstances(mNativeBfCompiler, typeName));
}
public void GetTypeInfo(String typeDefName, String outStr)
{
outStr.Append(BfCompiler_GetTypeInfo(mNativeBfCompiler, typeDefName));
}
public int GetTypeId(String typeName)
{
return BfCompiler_GetTypeId(mNativeBfCompiler, typeName);
}
public void ClearBuildCache()
{
BfCompiler_ClearBuildCache(mNativeBfCompiler);
@ -943,5 +973,10 @@ namespace IDE.Compiler
dirChangedCommand.mDir.Set(str);
QueueCommand(dirChangedCommand);
}
public void WriteEmitData(String filePath, BfProject bfProject)
{
BfCompiler_WriteEmitData(mNativeBfCompiler, filePath, bfProject.mNativeBfProject);
}
}
}

View file

@ -29,29 +29,50 @@ namespace IDE.Compiler
public enum ResolveType
{
None,
Classify,
ClassifyFullRefresh,
Autocomplete,
Autocomplete_HighPri,
GoToDefinition,
GetSymbolInfo,
RenameSymbol,
ShowFileSymbolReferences,
GetNavigationData,
GetCurrentLocation,
GetFixits,
GetTypeDefList,
GetTypeDefInto,
GetResultString
case None,
Classify,
ClassifyFullRefresh,
Autocomplete,
Autocomplete_HighPri,
GoToDefinition,
GetSymbolInfo,
RenameSymbol,
ShowFileSymbolReferences,
GetNavigationData,
GetCurrentLocation,
GetFixits,
GetTypeDefList,
GetTypeDefInto,
GetResultString;
public bool IsClassify => (this == .Classify) || (this == .ClassifyFullRefresh);
}
public enum SourceEmbedKind
{
None,
Type,
Method
}
public class ResolveParams
{
public class Embed
{
public String mTypeName ~ delete _;
public int32 mRevision = -1;
public int32 mCursorIdx = -1;
public EditWidgetContent.CharData[] mCharData ~ delete _;
}
public ResolveType mResolveType;
public int32 mOverrideCursorPos = -1;
public bool mInDeferredList;
public EditWidgetContent.CharData[] mCharData ~ delete _;
public IdSpan mCharIdSpan ~ _.Dispose();
public BfParser mParser;
public int32 mLocalId = -1;
public String mReplaceStr ~ delete _;
public String mTypeDef ~ delete _;
@ -71,9 +92,7 @@ namespace IDE.Compiler
public WaitEvent mWaitEvent ~ delete _;
public BfPassInstance mPassInstance ~ delete _;
public EditWidgetContent.CharData[] mCharData ~ delete _;
public IdSpan mCharIdSpan ~ _.Dispose();
public BfParser mParser;
public List<Embed> mEmitEmbeds = new .() ~ DeleteContainerAndItems!(_);
public String mDocumentationName ~ delete _;
public bool mCancelled;
public int32 mTextVersion = -1;
@ -108,13 +127,16 @@ namespace IDE.Compiler
static extern void BfParser_SetNextRevision(void* bfParser, void* nextParser);
[CallingConvention(.Stdcall), CLink]
static extern bool BfParser_SetCursorIdx(void* bfParser, int32 cursorIdx);
static extern void BfParser_SetCursorIdx(void* bfParser, int32 cursorIdx);
[CallingConvention(.Stdcall), CLink]
static extern bool BfParser_SetAutocomplete(void* bfParser, int32 cursorIdx);
static extern void BfParser_SetAutocomplete(void* bfParser, int32 cursorIdx);
[CallingConvention(.Stdcall), CLink]
static extern void BfParser_SetEmbedKind(void* bfParser, SourceEmbedKind embedKind);
[CallingConvention(.Stdcall), CLink]
static extern bool BfParser_SetIsClassifying(void* bfParser);
static extern void BfParser_SetIsClassifying(void* bfParser);
[CallingConvention(.Stdcall), CLink]
static extern bool BfParser_Parse(void* bfParser, void* bfPassInstance, bool compatMode);
@ -140,6 +162,12 @@ namespace IDE.Compiler
[CallingConvention(.Stdcall), CLink]
static extern void BfParser_ClassifySource(void* bfParser, void* elementTypeArray, bool preserveFlags);
[CallingConvention(.Stdcall), CLink]
static extern void BfParser_CreateClassifier(void* bfParser, void* passInstance, void* resolvePassData, void* elementTypeArray);
[CallingConvention(.Stdcall), CLink]
static extern void BfParser_FinishClassifier(void* bfParser, void* resolvePassData);
[CallingConvention(.Stdcall), CLink]
static extern void BfParser_GenerateAutoCompletionFrom(void* bfParser, int32 srcPosition);
@ -168,11 +196,11 @@ namespace IDE.Compiler
mNativeBfParser = null;
}
public void SetSource(String data, String fileName)
public void SetSource(StringView data, String fileName)
{
Debug.Assert(!mIsUsed);
mIsUsed = true;
BfParser_SetSource(mNativeBfParser, data, (int32)data.Length, fileName);
BfParser_SetSource(mNativeBfParser, data.Ptr, (int32)data.Length, fileName);
}
public void SetCharIdData(ref IdSpan char8IdData)
@ -192,6 +220,11 @@ namespace IDE.Compiler
BfParser_SetAutocomplete(mNativeBfParser, (int32)cursorIdx);
}
public void SetEmbedKind(SourceEmbedKind embedKind)
{
BfParser_SetEmbedKind(mNativeBfParser, embedKind);
}
public void SetIsClassifying()
{
BfParser_SetIsClassifying(mNativeBfParser);
@ -247,6 +280,17 @@ namespace IDE.Compiler
BfParser_ClassifySource(mNativeBfParser, char8DataPtr, preserveFlags);
}
public void CreateClassifier(BfPassInstance passInstance, BfResolvePassData bfResolvePassData, EditWidgetContent.CharData[] charDataArr)
{
EditWidgetContent.CharData* charDataPtr = charDataArr.CArray();
BfParser_CreateClassifier(mNativeBfParser, passInstance.mNativeBfPassInstance, bfResolvePassData.mNativeResolvePassData, charDataPtr);
}
public void FinishClassifier(BfResolvePassData bfResolvePassData)
{
BfParser_FinishClassifier(mNativeBfParser, bfResolvePassData.mNativeResolvePassData);
}
public void SetNextRevision(BfParser nextRevision)
{
BfParser_SetNextRevision(mNativeBfParser, nextRevision.mNativeBfParser);

View file

@ -2,6 +2,7 @@ using System;
using System.Collections;
using System.Text;
using System.Threading.Tasks;
using Beefy.widgets;
namespace IDE.Compiler
{
@ -37,6 +38,12 @@ namespace IDE.Compiler
[CallingConvention(.Stdcall), CLink]
static extern void BfResolvePassData_SetDocumentationRequest(void* bfResolvePassData, char8* entryName);
[CallingConvention(.Stdcall), CLink]
static extern void BfResolvePassData_AddEmitEmbed(void* bfResolvePassData, char8* typeName, int32 cursorIdx);
[CallingConvention(.Stdcall), CLink]
static extern void* BfResolvePassData_GetEmitEmbedData(void* bfResolvePassData, char8* typeName, out int32 srcLength, out int32 revision);
//
//[CallingConvention(.Stdcall), CLink]
@ -100,5 +107,15 @@ namespace IDE.Compiler
resolvePassData.mNativeResolvePassData = BfParser.[Friend]BfParser_CreateResolvePassData(null, (int32)resolveType, doFuzzyAutoComplete);
return resolvePassData;
}
public void AddEmitEmbed(char8* typeName, int32 cursorIdx)
{
BfResolvePassData_AddEmitEmbed(mNativeResolvePassData, typeName, cursorIdx);
}
public EditWidgetContent.CharData* GetEmitEmbedData(char8* typeName, out int32 srcLength, out int32 revision)
{
return (.)BfResolvePassData_GetEmitEmbedData(mNativeResolvePassData, typeName, out srcLength, out revision);
}
}
}

View file

@ -372,6 +372,9 @@ namespace IDE.Debugger
[CallingConvention(.Stdcall),CLink]
static extern int Debugger_GetDbgAllocHeapSize();
[CallingConvention(.Stdcall), CLink]
static extern char8* Debugger_GetEmitSource(char8* fileName);
public String mRunningPath ~ delete _;
public bool mIsRunning;
public bool mIsRunningCompiled;
@ -382,8 +385,9 @@ namespace IDE.Debugger
public int32 mActiveCallStackIdx;
public Event<Action> mBreakpointsChangedDelegate ~ _.Dispose();
public Breakpoint mRunToCursorBreakpoint;
public int32 mDebugIdx;
bool IsRunning
public bool IsRunning
{
get
{
@ -391,6 +395,14 @@ namespace IDE.Debugger
}
}
public bool IsRunningUncompiled
{
get
{
return mIsRunning && !mIsRunningCompiled;
}
}
public this()
{
Debugger_Create();
@ -975,7 +987,14 @@ namespace IDE.Debugger
stackSize = stackSizeOut;
if (outFile != null)
{
outFile.Append(fileStrPtr);
if ((outFile.StartsWith("$Emit")) && (mIsRunningCompiled))
{
int dollarPos = outFile.IndexOf('$', 1);
outFile.Remove(5, dollarPos - 5);
}
}
if (outStackFrameInfo != null)
outStackFrameInfo.Append(locationStr);
}
@ -1224,5 +1243,14 @@ namespace IDE.Debugger
{
return Debugger_GetDbgAllocHeapSize();
}
public bool GetEmitSource(StringView fileName, String outText)
{
char8* str = Debugger_GetEmitSource(fileName.ToScopeCStr!());
if (str == null)
return false;
outText.Append(str);
return true;
}
}
}

View file

@ -380,6 +380,12 @@ namespace IDE
public bool mOnlyIfNotFailed;
}
public class WriteEmitCmd : ExecutionCmd
{
public String mProjectName ~ delete _;
public String mPath ~ delete _;
}
public class BuildCompletedCmd : ExecutionCmd
{
public Stopwatch mStopwatch ~ delete _;
@ -524,6 +530,18 @@ namespace IDE
private int32 mStepCount;
private int32 mNoDebugMessagesTick;
public class DeferredShowSource
{
public String mFilePath ~ delete _;
public int32 mShowHotIdx;
public int32 mRefHotIdx;
public int32 mLine;
public int32 mColumn;
public LocatorType mHilitePosition;
public bool mShowTemp;
}
public DeferredShowSource mDeferredShowSource ~ delete _;
public bool IsCompiling
{
get
@ -1335,7 +1353,7 @@ namespace IDE
return false;
}
public SourceViewPanel GetActiveSourceViewPanel(bool includeLastActive = false)
public SourceViewPanel GetActiveSourceViewPanel(bool includeLastActive = false, bool includeEmbeds = false)
{
if (mRunningTestScript)
return mLastActiveSourceViewPanel;
@ -1343,10 +1361,12 @@ namespace IDE
var activePanel = GetActiveDocumentPanel();
var sourceViewPanel = activePanel as SourceViewPanel;
if (sourceViewPanel != null)
return sourceViewPanel.GetActivePanel();
sourceViewPanel = sourceViewPanel.GetActivePanel();
if ((mLastActiveSourceViewPanel != null) && (includeLastActive))
return mLastActiveSourceViewPanel.GetActivePanel();
return null;
sourceViewPanel = mLastActiveSourceViewPanel.GetActivePanel();
if ((sourceViewPanel != null) && (includeEmbeds))
sourceViewPanel = sourceViewPanel.GetFocusedEmbeddedView();
return sourceViewPanel;
}
public TextPanel GetActiveTextPanel()
@ -1461,21 +1481,20 @@ namespace IDE
}
}
BfCompiler compiler = null;
if (fileName.Contains("$EmitR$"))
compiler = mBfResolveCompiler;
else if (fileName.Contains("$Emit$"))
compiler = mBfBuildCompiler;
if (compiler != null)
if (fileName.StartsWith("$Emit$"))
{
if (compiler.GetEmitSource(fileName, outBuffer))
{
if (onPreFilter != null)
onPreFilter();
BfCompiler compiler = mBfResolveCompiler;
if (!compiler.IsPerformingBackgroundOperation())
compiler.GetEmitSource(fileName, outBuffer);
if (onPreFilter != null)
onPreFilter();
return .Ok;
}
else if (fileName.StartsWith("$Emit"))
{
if (mDebugger.GetEmitSource(fileName, outBuffer))
return .Ok;
}
}
return Utils.LoadTextFile(fileName, outBuffer, autoRetry, onPreFilter);
@ -4152,7 +4171,7 @@ namespace IDE
public void GoToDefinition(bool force)
{
var sourceViewPanel = GetActiveSourceViewPanel();
var sourceViewPanel = GetActiveSourceViewPanel(false, true);
if (sourceViewPanel != null)
{
if (!force)
@ -4188,7 +4207,7 @@ namespace IDE
}
else
#endif
{
/*{
ResolveParams resolveParams = scope ResolveParams();
sourceViewPanel.Classify(ResolveType.GoToDefinition, resolveParams);
if (resolveParams.mOutFileName != null)
@ -4204,7 +4223,7 @@ namespace IDE
{
Fail("Unable to locate definition");
}
else
else*/
{
sourceViewPanel.ShowSymbolReferenceHelper(.GoToDefinition);
}
@ -4629,6 +4648,7 @@ namespace IDE
if (var sourceViewPanel = documentPanel as SourceViewPanel)
{
sourceViewPanel = sourceViewPanel.GetFocusedEmbeddedView();
sourceViewPanel.ToggleBreakpointAtCursor(setKind, setFlags, bindToThread ? gApp.mDebugger.GetActiveThread() : -1);
}
else if (var disassemblyPanel = documentPanel as DisassemblyPanel)
@ -6483,9 +6503,10 @@ namespace IDE
public (SourceViewPanel panel, TabbedView.TabButton tabButton) ShowSourceFile(String filePath, ProjectSource projectSource = null, SourceShowType showType = SourceShowType.ShowExisting, bool setFocus = true)
{
DeleteAndNullify!(mDeferredShowSource);
//TODO: PUT BACK!
//return null;
#unwarn
String useFilePath = filePath;
var useProjectSource = projectSource;
@ -6604,6 +6625,8 @@ namespace IDE
else
success = sourceViewPanel.Show(useFilePath, !mInitialized);
sourceViewPanel.mEmitRevision = emitRevision;
if (emitRevision != -1)
sourceViewPanel.mEditWidget.mEditWidgetContent.mIsReadOnly = true;
if (!success)
{
@ -7051,9 +7074,76 @@ namespace IDE
public SourceViewPanel ShowSourceFileLocation(String filePath, int showHotIdx, int refHotIdx, int line, int column, LocatorType hilitePosition, bool showTemp = false)
{
var sourceViewPanel = ShowSourceFile(filePath, null, showTemp ? SourceShowType.Temp : SourceShowType.ShowExisting).panel;
if (filePath.StartsWith("$Emit$"))
{
var compiler = mBfResolveCompiler;
if (compiler.IsPerformingBackgroundOperation())
{
DeleteAndNullify!(mDeferredShowSource);
mDeferredShowSource = new DeferredShowSource()
{
mFilePath = new .(filePath),
mShowHotIdx = (.)showHotIdx,
mRefHotIdx = (.)refHotIdx,
mLine = (.)line,
mColumn = (.)column,
mHilitePosition = hilitePosition,
mShowTemp = showTemp
};
return null;
}
var itr = filePath.Split('$');
itr.GetNext();
itr.GetNext();
var typeName = itr.GetNext().Value;
//var compiler = (kindStr == "Emit") ? mBfBuildCompiler : mBfResolveCompiler;
compiler.mBfSystem.Lock(0);
var embedFilePath = compiler.GetEmitLocation(typeName, line, .. scope .(), var embedLine, var embedLineChar);
compiler.mBfSystem.Unlock();
if (!embedFilePath.IsEmpty)
{
var sourceViewPanel = ShowSourceFile(scope .(embedFilePath), null, showTemp ? SourceShowType.Temp : SourceShowType.ShowExisting).panel;
if (sourceViewPanel == null)
return null;
var sewc = sourceViewPanel.mEditWidget.mEditWidgetContent as SourceEditWidgetContent;
var data = sewc.mData as SourceEditWidgetContent.Data;
QueuedEmitShowData emitShowData = new .();
emitShowData.mPrevCollapseParseRevision = data.mCollapseParseRevision;
emitShowData.mTypeName = new .(typeName);
emitShowData.mLine = (.)line;
emitShowData.mColumn = (.)column;
DeleteAndNullify!(sourceViewPanel.[Friend]mQueuedEmitShowData);
sourceViewPanel.[Friend]mQueuedEmitShowData = emitShowData;
//sourceViewPanel.ShowHotFileIdx(showHotIdx);
sourceViewPanel.ShowFileLocation(refHotIdx, embedLine, embedLineChar, .None);
//sourceViewPanel.QueueFullRefresh(false);
//sourceViewPanel.mBackgroundDelay = 1; // Don't immediately perform the full classify
if (typeName.Contains('<'))
{
if (sourceViewPanel.AddExplicitEmitType(typeName))
sourceViewPanel.QueueFullRefresh(false);
}
if (!sourceViewPanel.[Friend]mWantsFullRefresh)
sourceViewPanel.UpdateQueuedEmitShowData();
return sourceViewPanel;
}
}
var (sourceViewPanel, tabButton) = ShowSourceFile(filePath, null, showTemp ? SourceShowType.Temp : SourceShowType.ShowExisting);
if (sourceViewPanel == null)
return null;
if (((filePath.StartsWith("$")) && (var svTabButton = tabButton as SourceViewTabButton)))
svTabButton.mIsTemp = true;
sourceViewPanel.ShowHotFileIdx(showHotIdx);
sourceViewPanel.ShowFileLocation(refHotIdx, Math.Max(0, line), Math.Max(0, column), hilitePosition);
return sourceViewPanel;
@ -7155,6 +7245,10 @@ namespace IDE
checkForOldFileInfo = true;
}
}
else if (filePath.StartsWith("$Emit"))
{
// Check this later
}
else
{
if (!File.Exists(filePath))
@ -7207,6 +7301,12 @@ namespace IDE
ShowCallstack();
}
if (filePath.StartsWith("$"))
{
ShowSourceFileLocation(filePath, hotIdx, hotIdx, line, column, .Smart);
return;
}
var (sourceViewPanel, tabButton) = ShowSourceFile(filePath, null, SourceShowType.ShowExisting, setFocus);
if (sourceViewPanel != null)
{
@ -7957,6 +8057,8 @@ namespace IDE
public static bool IsBeefFile(String fileName)
{
if (fileName.StartsWith('$'))
return true;
return fileName.EndsWith(".cs", StringComparison.OrdinalIgnoreCase) || fileName.EndsWith(".bf", StringComparison.OrdinalIgnoreCase);
}
@ -7971,6 +8073,8 @@ namespace IDE
public static bool IsSourceCode(String fileName)
{
if (fileName.StartsWith('$'))
return true;
return fileName.EndsWith(".cs", StringComparison.OrdinalIgnoreCase) || fileName.EndsWith(".bf", StringComparison.OrdinalIgnoreCase) ||
fileName.EndsWith(".h", StringComparison.OrdinalIgnoreCase) || fileName.EndsWith(".cpp", StringComparison.OrdinalIgnoreCase) ||
fileName.EndsWith(".c", StringComparison.OrdinalIgnoreCase) || fileName.EndsWith(".cc", StringComparison.OrdinalIgnoreCase) ||
@ -8775,6 +8879,30 @@ namespace IDE
// Already handled
(void)scriptCmd;
}
else if (var writeEmitCmd = next as WriteEmitCmd)
{
String projectName = new String(writeEmitCmd.mProjectName);
String filePath = new String(writeEmitCmd.mPath);
mBfBuildCompiler.DoBackground(new () =>
{
if (var project = mWorkspace.FindProject(projectName))
{
var bfProject = mBfBuildSystem.GetBfProject(project);
if (bfProject != null)
{
mBfBuildSystem.Lock(0);
mBfBuildCompiler.WriteEmitData(filePath, bfProject);
mBfBuildSystem.Unlock();
}
}
}
~
{
delete projectName;
delete filePath;
});
}
else
{
Runtime.FatalError("Unknown command");
@ -10758,49 +10886,49 @@ namespace IDE
return;
}
bool hasTempFiles = false;
WithTabs(scope [&] (tabButton) =>
{
if (var svTabButton = tabButton as SourceViewTabButton)
{
if (svTabButton.mIsTemp)
hasTempFiles = true;
}
});
if (hasTempFiles)
{
var dialog = ThemeFactory.mDefault.CreateDialog("Close Temp Files",
"Do you want to close temporary files opened from the debugger?");
dialog.mDefaultButton = dialog.AddButton("Yes", new (evt) =>
{
List<SourceViewTabButton> closeTabs = scope .();
WithTabs(scope [&] (tabButton) =>
{
if (var svTabButton = tabButton as SourceViewTabButton)
{
if (svTabButton.mIsTemp)
closeTabs.Add(svTabButton);
}
});
for (var tab in closeTabs)
{
CloseDocument(tab.mContent);
}
});
dialog.AddButton("No", new (evt) =>
{
});
dialog.PopupWindow(GetActiveWindow());
}
if (mCrashDumpPath != null)
{
DeleteAndNullify!(mCrashDumpPath);
mDebugger.Detach();
mDebugger.mIsRunning = false;
mExecutionPaused = false;
bool hasTempFiles = false;
WithTabs(scope [&] (tabButton) =>
{
if (var svTabButton = tabButton as SourceViewTabButton)
{
if (svTabButton.mIsTemp)
hasTempFiles = true;
}
});
if (hasTempFiles)
{
var dialog = ThemeFactory.mDefault.CreateDialog("Close Temp Files",
"Do you want to close temporary files referenced in the dump file?");
dialog.mDefaultButton = dialog.AddButton("Yes", new (evt) =>
{
List<SourceViewTabButton> closeTabs = scope .();
WithTabs(scope [&] (tabButton) =>
{
if (var svTabButton = tabButton as SourceViewTabButton)
{
if (svTabButton.mIsTemp)
closeTabs.Add(svTabButton);
}
});
for (var tab in closeTabs)
{
CloseDocument(tab.mContent);
}
});
dialog.AddButton("No", new (evt) =>
{
});
dialog.PopupWindow(GetActiveWindow());
}
}
if (mDebugger.mIsRunning)
@ -11349,6 +11477,7 @@ namespace IDE
CheckDebugVisualizers();
mDebugger.mIsRunning = true;
mDebugger.mDebugIdx++;
WithSourceViewPanels(scope (sourceView) =>
{
sourceView.RehupAlias();
@ -11407,6 +11536,7 @@ namespace IDE
CheckDebugVisualizers();
mDebugger.mIsRunning = true;
mDebugger.mDebugIdx++;
mDebugger.RehupBreakpoints(true);
mDebugger.Run();
mIsAttachPendingSourceShow = true;
@ -11866,6 +11996,7 @@ namespace IDE
if (mDebugger.OpenMiniDump(mCrashDumpPath))
{
mDebugger.mIsRunning = true;
mDebugger.mDebugIdx++;
mExecutionPaused = false; // Make this false so we can detect a Pause immediately
mIsAttachPendingSourceShow = true;
}
@ -14015,6 +14146,15 @@ namespace IDE
if (IDEApp.sApp.mSpellChecker != null)
IDEApp.sApp.mSpellChecker.CheckThreadDone();
if ((mDeferredShowSource != null) && (mBfResolveCompiler?.IsPerformingBackgroundOperation() == false))
{
var deferredShowSource = mDeferredShowSource;
mDeferredShowSource = null;
defer delete deferredShowSource;
ShowSourceFileLocation(deferredShowSource.mFilePath, deferredShowSource.mShowHotIdx, deferredShowSource.mRefHotIdx,
deferredShowSource.mLine, deferredShowSource.mColumn, deferredShowSource.mHilitePosition, deferredShowSource.mShowTemp);
}
///
//TODO: REMOVE
//mDebugger.InitiateHotResolve(.ActiveMethods | .Allocations);

View file

@ -17,6 +17,48 @@ namespace IDE
public const char8 cNativeSlash = Path.DirectorySeparatorChar;
public const char8 cOtherSlash = Path.AltDirectorySeparatorChar;
public static bool GenericEquals(StringView lhs, StringView rhs)
{
void SkipGeneric(StringView str, ref int i)
{
int depth = 0;
while (i < str.Length)
{
char8 c = str[i++];
if (c == '<')
depth++;
if (c == '>')
{
if (--depth == 0)
return;
}
}
}
int li = 0;
int ri = 0;
while ((li < lhs.Length) && (ri < rhs.Length))
{
char8 lc = lhs[li];
char8 rc = rhs[ri];
if (lc != rc)
return false;
if (lc == '<')
{
SkipGeneric(lhs, ref li);
SkipGeneric(rhs, ref ri);
continue;
}
li++;
ri++;
}
return (li == lhs.Length) && (ri == rhs.Length);
}
public static void AppendWithOptionalQuotes(String targetStr, StringView srcFileName)
{
bool hasSpace = srcFileName.Contains(' ');

View file

@ -627,6 +627,7 @@ namespace IDE
gApp.mDebugger.RehupBreakpoints(true);
gApp.mDebugger.Run();
gApp.mDebugger.mIsRunning = true;
gApp.mDebugger.mDebugIdx++;
}
mTestInstance.mThread.Start(false);

View file

@ -584,6 +584,13 @@ namespace IDE
{
if (inRelPath.IsEmpty)
return;
if (inRelPath.StartsWith('$'))
{
outAbsPath.Append(inRelPath);
return;
}
Path.GetAbsolutePath(inRelPath, mDir, outAbsPath);
}

View file

@ -75,13 +75,14 @@ namespace IDE.ui
mErrorLV.AddColumn(40, "Line");
mErrorLV.mOnItemMouseDown.Add(new (item, x, y, btnNum, btnCount) =>
{
ListViewItemMouseDown(item, x, y, btnNum, btnCount);
if ((btnNum == 0) && (btnCount == 2))
{
let mainItem = (ErrorsListViewItem)item.GetSubItem(0);
mainItem.Goto();
}
ListViewItemMouseDown(item, x, y, btnNum, btnCount);
//mErrorLV.GetRoot().SelectItemExclusively()
});
//let newItem = mErrorLV.GetRoot().CreateChildItem();

View file

@ -206,7 +206,11 @@ namespace IDE.ui
if ((errLine != -1) && (errLineChar != -1) && (filePath != null))
{
if ((!filePath.Contains('\\')) && (!filePath.Contains('/')) && (!filePath.Contains('.')))
if (filePath.StartsWith("$Emit"))
{
// Is good
}
else if ((!filePath.Contains('\\')) && (!filePath.Contains('/')) && (!filePath.Contains('.')))
return false;
IDEApp.sApp.CheckProjectRelativePath(filePath);

View file

@ -277,8 +277,6 @@ namespace IDE.ui
public void FindAll(bool doSelect = true)
{
Debug.WriteLine($"FindAll({doSelect})");
mIsShowingMatches = true;
mFoundMatches = false;
@ -305,8 +303,6 @@ namespace IDE.ui
}
mCurFindIdx = curFindIdx;
mCurFindCount = 0;
Debug.WriteLine($"FindAll CurFindIdx{mCurFindIdx} CurFindStart:{mCurFindStart}");
}
public void ShowCurrentSelection()

View file

@ -135,7 +135,7 @@ namespace IDE.ui
mVertPos = sourceViewPanel.mEditWidget.mVertPos.mDest;
mAwaitingGetSymbolInfo = true;
CheckGetSymbolInfo(kind == .ShowFileReferences);
CheckGetSymbolInfo((kind == .ShowFileReferences) || (kind == .GoToDefinition));
}
@ -153,6 +153,9 @@ namespace IDE.ui
if (!mAwaitingGetSymbolInfo)
return true;
if (gApp.mBfResolveCompiler.IsPerformingBackgroundOperationHi())
return false;
if (!force)
{
if (!gApp.mBfResolveCompiler.HasResolvedAll())
@ -160,7 +163,7 @@ namespace IDE.ui
}
mAwaitingGetSymbolInfo = false;
mSourceViewPanel.Classify(.GetSymbolInfo);
mSourceViewPanel.Classify((mKind == .GoToDefinition) ? .GoToDefinition : .GetSymbolInfo);
mInitialized = true;
mGettingSymbolInfo = true;
return true;
@ -231,9 +234,21 @@ namespace IDE.ui
mResolveParams.mNamespace = new String(lineDataItr.GetNext().Get());
foundSymbol = true;
case "defLoc":
StringView filePath = lineDataItr.GetNext().Get();
int32 line = int32.Parse(lineDataItr.GetNext().Value);
int32 lineChar = int32.Parse(lineDataItr.GetNext().Value);
if (mKind == .GoToDefinition)
{
mSourceViewPanel.RecordHistoryLocation();
var sourceViewPanel = gApp.ShowSourceFileLocation(scope .(filePath), -1, -1, line, lineChar, LocatorType.Smart, true);
sourceViewPanel.RecordHistoryLocation(true);
Close();
return;
}
if (mKind == .Rename)
{
StringView filePath = lineDataItr.GetNext().Get();
let editData = gApp.GetEditData(scope String(filePath), false, false);
if (editData != null)
{
@ -260,6 +275,12 @@ namespace IDE.ui
}
}
if (mKind == .GoToDefinition)
{
gApp.Fail("Unable to locate definition");
Close();
}
if ((!foundSymbol) || (foundStr == null))
{
if ((mKind == .Rename) || (mKind == .FindAllReferences))
@ -829,13 +850,22 @@ namespace IDE.ui
{
base.Update();
if ((mUpdatingProjectSources == null) && (mUpdateCnt > 30) && (gApp.mUpdateCnt % 4 == 0))
MarkDirty();
if (mAwaitingGetSymbolInfo)
{
if (!CheckGetSymbolInfo(false))
return;
}
if (mKind == .GoToDefinition)
{
if (gApp.mBfResolveCompiler.HasResolvedAll())
/*if (gApp.mBfResolveCompiler.HasResolvedAll())
{
Close();
gApp.GoToDefinition(true);
}
}*/
if (mSourceViewPanel.EditWidget.Content.CursorTextPos != mCursorPos)
{
@ -845,12 +875,6 @@ namespace IDE.ui
return;
}
if (mAwaitingGetSymbolInfo)
{
if (!CheckGetSymbolInfo(false))
return;
}
if (mStartingWork)
return;
@ -899,7 +923,7 @@ namespace IDE.ui
mClosed = true;
mSourceViewPanel.CancelResolve(.GetSymbolInfo);
mSourceViewPanel.CancelResolve((mKind == .GoToDefinition) ? .GoToDefinition : .GetSymbolInfo);
if (mBackgroundKind != .None)
{
gApp.mBfResolveCompiler.CancelBackground();
@ -921,6 +945,12 @@ namespace IDE.ui
if (mKind == Kind.ShowFileReferences)
return;
if ((mKind == .GoToDefinition) && (mUpdateCnt < 40))
{
// Reduce "flashing" for very fast finds
return;
}
int symCount = 0;
int readOnlyRefCount = 0;
int lockedFileCount = 0;
@ -993,7 +1023,7 @@ namespace IDE.ui
}
}
if ((mUpdatingProjectSources == null) && (mUpdateCnt > 30))
if ((mUpdatingProjectSources == null) && (mUpdateCnt > 30))
IDEUtils.DrawWait(g, mWidth / 2, mHeight / 2 + 4, mUpdateCnt);
}

View file

@ -13,6 +13,7 @@ using Beefy.utils;
using IDE.Debugger;
using IDE.Compiler;
using Beefy.geom;
using Beefy.events;
namespace IDE.ui
{
@ -180,19 +181,393 @@ namespace IDE.ui
}
}
public class EmitEmbed : DarkEditWidgetContent.Embed
{
public class View : Widget
{
public class GenericTypeEntry
{
public String mTypeName ~ delete _;
}
public enum WorkState
{
Idle,
Queued,
Performing,
Done
}
public EmitEmbed mEmitEmbed;
public String mTypeName ~ delete _;
public SourceViewPanel mSourceViewPanel;
public DarkComboBox mGenericTypeCombo;
public DarkComboBox mGenericMethodCombo;
public String mGenericTypeFilter;
public float mWantHeight;
public float? mMouseDownY;
public float? mDownWantHeight;
public float MinHeight => (mGenericTypeCombo != null) ? GS!(96+25) : GS!(96);
public float MaxAutoHeight => GS!(364);
public float HeightAdd => (mGenericTypeCombo != null) ? GS!(28+25) : GS!(28);
public int32 mCollapseParseRevision;
public List<GenericTypeEntry> mGenericTypeData = new .() ~ DeleteContainerAndItems!(_);
public Monitor mMonitor = new .() ~ delete _;
public WorkState mTypeWorkState;
public bool mAwaitingLoad;
bool mIgnoreChange = false;
public this(EmitEmbed emitEmbed)
{
mTypeName = new .(emitEmbed.mTypeName);
mEmitEmbed = emitEmbed;
mSourceViewPanel = new SourceViewPanel((emitEmbed.mEmitKind == .Method) ? .Method : .Type);
mSourceViewPanel.mEmbedParent = mEmitEmbed.mEditWidgetContent.mSourceViewPanel;
var emitPath = scope $"$Emit${emitEmbed.mTypeName}";
mSourceViewPanel.Show(emitPath, false, null);
mSourceViewPanel.mEditWidget.mEditWidgetContent.mIsReadOnly = true;
mSourceViewPanel.mEmitRevision = emitEmbed.mRevision;
AddWidget(mSourceViewPanel);
mSourceViewPanel.mEditWidget.mOnGotFocus.Add(new (val1) =>
{
if (mGenericTypeCombo != null)
UpdateGenericTypeCombo();
});
mSourceViewPanel.mEditWidget.mHorzScrollbar.mAllowMouseWheel = false;
mSourceViewPanel.mEditWidget.mVertScrollbar.mAllowMouseWheel = false;
var sewc = mSourceViewPanel.mEditWidget.mEditWidgetContent as SourceEditWidgetContent;
sewc.mLineRange = Range(emitEmbed.mStartLine, emitEmbed.mEndLine);
sewc.mAllowMaximalScroll = false;
mSourceViewPanel.mEditWidget.UpdateScrollbars();
mClipGfx = true;
if (mTypeName.Contains('<'))
{
mGenericTypeCombo = new DarkComboBox();
mGenericTypeCombo.mFocusDropdown = false;
mGenericTypeCombo.mLabelAlign = .Left;
mGenericTypeCombo.MakeEditable();
UpdateGenericTypeCombo();
mGenericTypeCombo.mPopulateMenuAction.Add(new => PopulateTypeData);
AddWidget(mGenericTypeCombo);
mGenericTypeCombo.mEditWidget.mOnContentChanged.Add(new => GenericTypeEditChanged);
mGenericTypeCombo.mEditWidget.mOnKeyDown.Add(new => EditKeyDownHandler);
mGenericTypeCombo.mEditWidget.mOnGotFocus.Add(new (widget) => mGenericTypeCombo.mEditWidget.mEditWidgetContent.SelectAll());
}
}
private void GenericTypeEditChanged(EditEvent theEvent)
{
if (mIgnoreChange)
return;
var editWidget = (EditWidget)theEvent.mSender;
var searchText = scope String();
editWidget.GetText(searchText);
searchText.Trim();
mGenericTypeFilter = searchText;
mGenericTypeCombo.ShowDropdown();
mGenericTypeFilter = null;
}
void EditKeyDownHandler(KeyDownEvent evt)
{
if (evt.mKeyCode == KeyCode.Escape)
mEmitEmbed.mEditWidgetContent.mSourceViewPanel.FocusEdit();
}
void UpdateGenericTypeCombo()
{
var typeName = mEmitEmbed.mTypeName;
for (var explicitTypeName in mEmitEmbed.mEditWidgetContent.mSourceViewPanel.[Friend]mExplicitEmitTypes)
{
if (IDEUtils.GenericEquals(typeName, explicitTypeName))
typeName = explicitTypeName;
}
mIgnoreChange = true;
int colonPos = typeName.IndexOf(':');
if (colonPos != -1)
mGenericTypeCombo.Label = typeName.Substring(colonPos + 1);
else
mGenericTypeCombo.Label = typeName;
mIgnoreChange = false;
}
void PopulateTypeData(Menu menu)
{
List<StringView> findStrs = null;
if (mGenericTypeFilter != null)
findStrs = scope:: List<StringView>(mGenericTypeFilter.Split(' '));
using (mMonitor.Enter())
{
EntryLoop: for (var entry in mGenericTypeData)
{
StringView useName = entry.mTypeName;
int colonPos = useName.IndexOf(':');
if (colonPos != -1)
useName.RemoveFromStart(colonPos + 1);
if (findStrs != null)
{
for (let findStr in findStrs)
{
if (useName.IndexOf(findStr, true) == -1)
continue EntryLoop;
}
}
var item = menu.AddItem(useName);
var origName = new String(entry.mTypeName);
item.mOnMenuItemSelected.Add(new (menu) =>
{
mEmitEmbed.mEditWidgetContent.mSourceViewPanel.AddExplicitEmitType(origName);
mEmitEmbed.mEditWidgetContent.mSourceViewPanel.QueueFullRefresh(false);
UpdateGenericTypeCombo();
mGenericTypeCombo.mEditWidget.SetFocus();
}
~
{
delete origName;
});
}
}
if ((mTypeWorkState == .Idle) && (mCollapseParseRevision != mEmitEmbed.mEditWidgetContent.mCollapseParseRevision))
{
mCollapseParseRevision = mEmitEmbed.mEditWidgetContent.mCollapseParseRevision;
mTypeWorkState = .Queued;
}
/*menu.AddItem("Abc");
menu.AddItem("Def");*/
}
public override void Update()
{
base.Update();
using (mMonitor.Enter())
{
if ((mTypeWorkState == .Queued) && (gApp?.mBfResolveCompiler.IsPerformingBackgroundOperation() == false))
{
mTypeWorkState = .Performing;
gApp.mBfResolveCompiler.DoBackground(new => GetGenericTypes);
}
if (mTypeWorkState == .Done)
{
mGenericTypeCombo.ShowDropdown();
mGenericTypeCombo.SelectFromLabel();
mTypeWorkState = .Idle;
}
}
mAwaitingLoad = false;
for (var explicitTypeName in mEmitEmbed.mEditWidgetContent.mSourceViewPanel.[Friend]mExplicitEmitTypes)
{
if ((IDEUtils.GenericEquals(mTypeName, explicitTypeName)) && (mTypeName != explicitTypeName))
mAwaitingLoad = true;
}
if (mSourceViewPanel.mEditWidget.mEditWidgetContent.mData.mTextLength == 0)
mAwaitingLoad = true;
if ((mAwaitingLoad) && (gApp.mUpdateCnt % 4 == 0))
MarkDirty();
}
public void GetGenericTypes()
{
gApp.mBfResolveSystem.Lock(0);
var genericTypeNames = gApp.mBfResolveCompiler.GetGenericTypeInstances(mTypeName, .. scope .());
gApp.mBfResolveSystem.Unlock();
using (mMonitor.Enter())
{
mGenericTypeData.ClearAndDeleteItems();
mTypeWorkState = .Done;
for (var genericTypeName in genericTypeNames.Split('\n', .RemoveEmptyEntries))
{
GenericTypeEntry entry = new .();
entry.mTypeName = new .(genericTypeName);
mGenericTypeData.Add(entry);
mGenericTypeData.Sort(scope (lhs, rhs) => lhs.mTypeName <=> rhs.mTypeName);
}
}
}
public override void DrawAll(Graphics g)
{
base.DrawAll(g);
if (mAwaitingLoad)
{
var rect = mSourceViewPanel.mEditWidget.GetRect();
mSourceViewPanel.mEditWidget.SelfToOtherTranslate(this, 0, 0, out rect.mX, out rect.mY);
using (g.PushColor(Color.Mult(gApp.mSettings.mUISettings.mColors.mWindow, 0x60FFFFFF)))
{
g.FillRect(rect.mX, rect.mY, rect.mWidth, rect.mHeight);
}
IDEUtils.DrawWait(g, rect.mX + rect.mWidth / 2, rect.mY + rect.mHeight / 2, mUpdateCnt);
}
}
public override void Resize(float x, float y, float width, float height)
{
base.Resize(x, y, width, height);
float curY = GS!(2);
if (mGenericTypeCombo != null)
{
mGenericTypeCombo.Resize(GS!(38), curY, Math.Max(0, width - GS!(38)), GS!(22));
curY += GS!(25);
}
mSourceViewPanel.Resize(0, curY, width, Math.Max(0, height - curY - GS!(7)));
}
public void SizeTo(float x, float y, float width, float height)
{
Resize(x, y, width, height + GS!(3));
}
public override void RehupScale(float oldScale, float newScale)
{
base.RehupScale(oldScale, newScale);
mWantHeight = mWantHeight * newScale / oldScale;
}
public override void MouseDown(float x, float y, int32 btn, int32 btnCount)
{
base.MouseDown(x, y, btn, btnCount);
if (btn == 0)
{
mMouseDownY = y;
mDownWantHeight = mWantHeight;
}
}
public override void MouseUp(float x, float y, int32 btn)
{
base.MouseUp(x, y, btn);
if (btn == 0)
{
mMouseDownY = null;
mDownWantHeight = null;
}
}
public override void MouseMove(float x, float y)
{
base.MouseMove(x, y);
if (mMouseDownY != null)
{
mWantHeight = Math.Max(MinHeight, mDownWantHeight.Value + y - mMouseDownY.Value);
mEmitEmbed.mEditWidgetContent.RehupLineCoords();
}
if (y > mHeight - GS!(6))
gApp.SetCursor(.SizeNS);
}
public override void MouseLeave()
{
base.MouseLeave();
gApp.SetCursor(.Pointer);
}
}
public SourceEditWidgetContent mEditWidgetContent;
public SourceEditWidgetContent.CollapseData.Kind mEmitKind;
public String mTypeName;
public bool mIsOpen;
public float mOpenPct;
public int32 mAnchorId;
public int32 mCollapseIndex;
public int32 mRevision;
public int32 mPartialIdx;
public int32 mStartLine;
public int32 mEndLine;
public View mView;
public ~this()
{
if (mView != null)
{
mView.RemoveSelf();
delete mView;
}
}
public override float GetWidth(bool hideLine)
{
return GS!(42);
}
public override void Draw(Graphics g, Rect rect, bool hideLine)
{
if (rect.mHeight >= DarkTheme.sDarkTheme.mSmallBoldFont.GetLineSpacing())
g.SetFont(DarkTheme.sDarkTheme.mSmallBoldFont);
using (g.PushColor(0x20FFFFFF))
{
g.FillRect(rect.mX, rect.mY, rect.mWidth, rect.mHeight);
}
if ((mEditWidgetContent.mSelection != null) && (mCollapseIndex < mEditWidgetContent.mOrderedCollapseEntries.Count))
{
var collapseEntry = mEditWidgetContent.mOrderedCollapseEntries[mCollapseIndex];
int32 startIdx = mEditWidgetContent.mData.mLineStarts[collapseEntry.mStartLine];
if ((mEditWidgetContent.mSelection.Value.MinPos <= collapseEntry.mEndIdx) && (mEditWidgetContent.mSelection.Value.MaxPos >= startIdx))
{
using (g.PushColor(mEditWidgetContent.GetSelectionColor(0)))
g.FillRect(rect.mX, rect.mY, rect.mWidth, rect.mHeight);
}
}
using (g.PushColor(0x48FFFFFF))
{
g.OutlineRect(rect.mX, rect.mY, rect.mWidth, rect.mHeight);
}
var summaryString = "Emit";
g.DrawString(summaryString, rect.mX, rect.mY + (int)((rect.mHeight - g.mFont.GetLineSpacing()) * 0.5f), .Centered, rect.mWidth);
}
}
public struct CollapseData
{
public enum Kind : char8
{
Zero = 0,
Comment = 'C',
Method = 'M',
Namespace = 'N',
Property = 'P',
Region = 'R',
Type = 'T',
UsingNamespaces = 'U',
Unknown = '?'
case Zero = 0;
case Comment = 'C';
case Method = 'M';
case Namespace = 'N';
case Property = 'P';
case Region = 'R';
case Type = 'T';
case UsingNamespaces = 'U';
case Unknown = '?';
case EmitInType = 't';
case EmitInMethod = 'm';
case EmitAddType = '+';
public bool IsEmit => (this == .EmitInType) || (this == .EmitInMethod);
}
public Kind mKind;
@ -218,6 +593,19 @@ namespace IDE.ui
public bool mDeleted;
}
public struct EmitData
{
public SourceEditWidgetContent.CollapseEntry.Kind mKind;
public int32 mTypeNameIdx;
public int32 mRevision;
public int32 mPartialIdx;
public int32 mAnchorIdx;
public int32 mStartLine;
public int32 mEndLine;
public int32 mAnchorId;
}
public class Data : DarkEditWidgetContent.Data
{
public List<PersistentTextPosition> mPersistentTextPositions = new List<PersistentTextPosition>() ~ DeleteContainerAndItems!(_);
@ -225,6 +613,19 @@ namespace IDE.ui
public int32 mCollapseParseRevision;
public int32 mCollapseTextVersionId;
public List<CollapseData> mCollapseData = new .() ~ delete _;
public List<EmitData> mEmitData = new .() ~ delete _;
public List<String> mTypeNames = new .() ~ DeleteContainerAndItems!(_);
public void Clear()
{
mCollapseData.Clear();
mEmitData.Clear();
ClearAndDeleteItems(mTypeNames);
}
public ~this()
{
}
}
struct QueuedTextEntry
@ -327,6 +728,7 @@ namespace IDE.ui
HilitePairedCharState mHilitePairedCharState = .NeedToRecalculate;
public Dictionary<int32, CollapseEntry> mCollapseMap = new .() ~ delete _;
public List<CollapseEntry*> mOrderedCollapseEntries = new .() ~ delete _;
public List<String> mCollapseTypeNames = new .() ~ DeleteContainerAndItems!(_);
public int32 mCollapseParseRevision;
public int32 mCollapseTextVersionId;
public bool mCollapseNeedsUpdate;
@ -421,6 +823,12 @@ namespace IDE.ui
String curText = scope String();
mEditWidget.GetText(curText);
if (curText == text)
{
// No change
return true;
}
char8* diffCmdsPtr = BfDiff_DiffText(curText, text);
String diffCmds = scope String();
diffCmds.Append(diffCmdsPtr);
@ -4538,15 +4946,20 @@ namespace IDE.ui
public override void MouseDown(float x, float y, int32 btn, int32 btnCount)
{
int line = GetLineAt(y);
if (mEmbeds.GetValue(line) case .Ok(let embed))
if (mEmbeds.GetValue((.)line) case .Ok(let embed))
{
Rect embedRect = GetEmbedRect(line, embed);
if (embedRect.Contains(x, y))
{
if ((btn == 0) && (btnCount == 2))
if ((btn == 0) && (btnCount % 2 == 0))
{
if (var collapseSummary = embed as SourceEditWidgetContent.CollapseSummary)
SetCollapseOpen(collapseSummary.mCollapseIndex, true);
else if (var emitEmbed = embed as EmitEmbed)
{
emitEmbed.mIsOpen = !emitEmbed.mIsOpen;
mCollapseNeedsUpdate = true;
}
}
return;
}
@ -5047,10 +5460,23 @@ namespace IDE.ui
if (mLineCoordJumpTable == null)
mLineCoordJumpTable = new .();
if (data.mLineStarts == null)
return;
mLineCoords.Clear();
mLineCoords.GrowUnitialized(data.mLineStarts.Count);
mLineCoordJumpTable.Clear();
List<(int32 line, EmitEmbed emitEmbed)> orderedEmitEmbeds = scope .();
for (var entry in mEmbeds)
{
if (var emitEmbed = entry.value as EmitEmbed)
{
orderedEmitEmbeds.Add((entry.key, emitEmbed));
}
}
orderedEmitEmbeds.Sort(scope (lhs, rhs) => lhs.line <=> rhs.line);
float fontHeight = mFont.GetLineSpacing();
int prevJumpIdx = -1;
float jumpCoordSpacing = GetJumpCoordSpacing();
@ -5067,6 +5493,7 @@ namespace IDE.ui
int32 curAnimLineIdx = 0;
bool inAnim = false;
int checkOpenIdx = 0;
int orderedEmebedIdx = 0;
for (int line < data.mLineStarts.Count)
{
@ -5129,6 +5556,28 @@ namespace IDE.ui
lineHeight = 0;
}
if ((orderedEmebedIdx < orderedEmitEmbeds.Count) && (line == orderedEmitEmbeds[orderedEmebedIdx].line))
{
var emitEmbed = orderedEmitEmbeds[orderedEmebedIdx++].emitEmbed;
if (lineHeight == 0)
{
if (emitEmbed.mView != null)
emitEmbed.mView.SetVisible(false);
}
else if (emitEmbed.mView != null)
{
if (emitEmbed.mView.mWantHeight == 0)
{
emitEmbed.mView.mWantHeight = Math.Clamp((emitEmbed.mEndLine - emitEmbed.mStartLine) * gApp.mCodeFont.GetLineSpacing() + emitEmbed.mView.HeightAdd,
emitEmbed.mView.MinHeight, emitEmbed.mView.MaxAutoHeight);
}
float height = emitEmbed.mView.mWantHeight * emitEmbed.mOpenPct;
emitEmbed.mView.SizeTo(GS!(0), (float)curY + lineHeight, mParent.mWidth, height);
lineHeight += height;
}
}
mLineCoords[line] = (float)curY;
int jumpIdx = (.)(curY / jumpCoordSpacing);
@ -5200,13 +5649,88 @@ namespace IDE.ui
{
mCollapseParseRevision = data.mCollapseParseRevision;
mCollapseTextVersionId = data.mCollapseTextVersionId;
mCollapseTypeNames.ClearAndDeleteItems();
for (var name in data.mTypeNames)
mCollapseTypeNames.Add(new .(name));
Dictionary<int, EmitEmbed> emitEmbedMap = scope .(64);
for (var embed in mEmbeds.Values)
{
if (var emitEmbed = embed as SourceEditWidgetContent.EmitEmbed)
{
emitEmbedMap[emitEmbed.mAnchorId] = emitEmbed;
}
}
for (var emitData in ref data.mEmitData)
{
GetLineCharAtIdx(emitData.mAnchorIdx, var line, var lineChar);
SourceEditWidgetContent.EmitEmbed emitEmbed = null;
if (emitEmbedMap.GetAndRemove(emitData.mAnchorId) case .Ok((?, out emitEmbed)))
{
if (line != emitEmbed.mLine)
{
mEmbeds.Remove(emitEmbed.mLine);
emitEmbed.mLine = (.)line;
mEmbeds[(.)line] = emitEmbed;
}
}
else if (mEmbeds.TryAdd((.)line, var keyPtr, var valuePtr))
{
emitEmbed = new .();
*valuePtr = emitEmbed;
}
else
{
emitEmbed = *valuePtr as SourceEditWidgetContent.EmitEmbed;
}
if (emitEmbed == null)
continue;
emitEmbed.mLine = (.)line;
emitEmbed.mAnchorId = emitData.mAnchorId;
emitEmbed.mEmitKind = emitData.mKind;
emitEmbed.mTypeName = mCollapseTypeNames[emitData.mTypeNameIdx];
emitEmbed.mRevision = emitData.mRevision;
emitEmbed.mPartialIdx = emitData.mPartialIdx;
if (emitEmbed.mView != null)
{
Range range = .(emitData.mStartLine, emitData.mEndLine);
var ew = emitEmbed.mView.mSourceViewPanel.mEditWidget;
var ewc = ew.mEditWidgetContent as DarkEditWidgetContent;
if (ewc.mLineRange != range)
{
ewc.mLineRange = range;
ew.UpdateScrollbars();
}
}
emitEmbed.mStartLine = emitData.mStartLine;
emitEmbed.mEndLine = emitData.mEndLine;
emitEmbed.mEditWidgetContent = this;
emitEmbed.mCollapseIndex = (.)emitData.mAnchorIdx;
emitEmbed.mKind = .LineEnd;
}
for (var emitEmbed in emitEmbedMap.Values)
{
mCollapseNeedsUpdate = true;
mEmbeds.Remove(emitEmbed.mLine);
delete emitEmbed;
}
for (var collapseData in ref data.mCollapseData)
{
if (mCollapseMap.TryAdd(collapseData.mAnchorId, ?, var entry))
{
*entry = .();
}
int32 prevAnchorLine = entry.mAnchorLine;
Internal.MemCpy(entry, &collapseData, sizeof(CollapseData));
entry.mPrevAnchorLine = entry.mAnchorLine;
entry.mPrevAnchorLine = prevAnchorLine;
entry.mParseRevision = mCollapseParseRevision;
entry.mDeleted = false;
}
@ -5216,7 +5740,10 @@ namespace IDE.ui
if (entry.mParseRevision != data.mCollapseParseRevision)
{
if (mEmbeds.GetAndRemove(entry.mAnchorLine) case .Ok(let val))
delete val.value;
{
if (val.value is CollapseSummary)
delete val.value;
}
@entry.Remove();
}
}
@ -5236,23 +5763,31 @@ namespace IDE.ui
if (entry.mDeleted)
{
if (mEmbeds.GetAndRemove(entry.mAnchorIdx) case .Ok(let val))
delete val.value;
{
if (val.value is CollapseSummary)
delete val.value;
}
continue;
}
if ((entry.mPrevAnchorLine != -1) && (entry.mPrevAnchorLine != entry.mAnchorLine))
{
if (mEmbeds.GetAndRemove(entry.mPrevAnchorLine) case .Ok(let val))
if (!mEmbeds.TryGetValue(entry.mPrevAnchorLine, let val))
continue;
if (!(val is CollapseSummary))
continue;
mEmbeds.Remove(entry.mPrevAnchorLine);
if (mEmbeds.TryAdd(entry.mAnchorLine, var keyPtr, var valuePtr))
{
if (!mEmbeds.TryAdd(entry.mAnchorLine, var keyPtr, var valuePtr))
{
if (var collapseSummary = val.value as SourceEditWidgetContent.CollapseSummary)
collapseSummary.mCollapseIndex = (.)@entry.Index;
*valuePtr = val.value;
}
else
delete val.value;
}
if (var collapseSummary = val as SourceEditWidgetContent.CollapseSummary)
collapseSummary.mCollapseIndex = (.)@entry.Index;
val.mLine = entry.mAnchorLine;
*valuePtr = val;
}
else
delete val;
}
}
@ -5432,6 +5967,20 @@ namespace IDE.ui
}
}
public override void Resize(float x, float y, float width, float height)
{
base.Resize(x, y, width, height);
for (var embed in mEmbeds.Values)
{
if (var emitEmbed = embed as EmitEmbed)
{
if (emitEmbed.mView != null)
emitEmbed.mView.Resize(emitEmbed.mView.mX, emitEmbed.mView.mY, mParent.mWidth - emitEmbed.mView.mX, emitEmbed.mView.mHeight);
}
}
}
public void CollapseToggle()
{
CollapseEntry* foundEntry = null;
@ -5560,10 +6109,13 @@ namespace IDE.ui
{
if (mEmbeds.GetValue(entry.mAnchorLine) case .Ok(let embed))
{
if ((embed.mKind == .HideLine) || (embed.mKind == .LineEnd))
if (embed is CollapseSummary)
{
delete embed;
mEmbeds.Remove(entry.mAnchorLine);
if ((embed.mKind == .HideLine) || (embed.mKind == .LineEnd))
{
delete embed;
mEmbeds.Remove(entry.mAnchorLine);
}
}
}
}
@ -5591,6 +6143,7 @@ namespace IDE.ui
}
}
public void RefreshCollapseRegion(SourceEditWidgetContent.CollapseEntry* entry, int32 prevAnchorLine, bool failed)
{
if (failed)
@ -5605,7 +6158,10 @@ namespace IDE.ui
if (mEmbeds.GetAndRemove(prevAnchorLine) case .Ok(let val))
{
if (mEmbeds.TryAdd(entry.mAnchorLine, var keyPtr, var valuePtr))
{
val.value.mLine = entry.mAnchorLine;
*valuePtr = val.value;
}
else
delete val.value;
}
@ -5685,14 +6241,34 @@ namespace IDE.ui
var data = PreparedData;
data.mCollapseData.Clear();
data.Clear();
for (var line in collapseText.Split('\n', .RemoveEmptyEntries))
{
SourceEditWidgetContent.CollapseEntry.Kind kind = (.)line[0];
line.RemoveFromStart(1);
if (kind == .EmitAddType)
{
data.mTypeNames.Add(new String(line));
continue;
}
var itr = line.Split(',');
if (kind.IsEmit)
{
EmitData emitData;
emitData.mKind = kind;
emitData.mTypeNameIdx = int32.Parse(itr.GetNext().Value);
emitData.mRevision = int32.Parse(itr.GetNext().Value);
emitData.mPartialIdx = int32.Parse(itr.GetNext().Value);
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);
data.mEmitData.Add(emitData);
continue;
}
CollapseData collapseData;
@ -5730,6 +6306,7 @@ namespace IDE.ui
if (mEmbeds.TryAdd(entry.mAnchorLine, var keyPtr, var valuePtr))
{
SourceEditWidgetContent.CollapseSummary collapseSummary = new .();
collapseSummary.mLine = entry.mAnchorLine;
collapseSummary.mEditWidgetContent = this;
collapseSummary.mCollapseIndex = (.)collapseIdx;
collapseSummary.mKind = .HideLine;
@ -5774,11 +6351,20 @@ namespace IDE.ui
if (mEmbeds.TryAdd(entry.mAnchorLine, var keyPtr, var valuePtr))
{
SourceEditWidgetContent.CollapseSummary collapseSummary = new .();
collapseSummary.mLine = entry.mAnchorLine;
collapseSummary.mEditWidgetContent = this;
collapseSummary.mCollapseIndex = (.)collapseIdx;
collapseSummary.mKind = .LineEnd;
*valuePtr = collapseSummary;
}
else
{
if (var emitEntry = *valuePtr as EmitEmbed)
{
emitEntry.mIsOpen = false;
mCollapseNeedsUpdate = true;
}
}
}
}
@ -5830,8 +6416,44 @@ namespace IDE.ui
if (animIdx == -1)
{
RehupLineCoords();
mCollapseNeedsUpdate = false;
for (var embed in mEmbeds.Values)
{
if (var emitEmbed = embed as EmitEmbed)
{
if (emitEmbed.mIsOpen)
{
emitEmbed.mOpenPct = Math.Min(1.0f, emitEmbed.mOpenPct + 0.1f);
if (emitEmbed.mOpenPct != 1.0f)
mCollapseNeedsUpdate = true;
if (emitEmbed.mView == null)
{
mSourceViewPanel.QueueFullRefresh(false);
emitEmbed.mView = new SourceEditWidgetContent.EmitEmbed.View(emitEmbed);
AddWidget(emitEmbed.mView);
}
}
else
{
emitEmbed.mOpenPct = Math.Max(0.0f, emitEmbed.mOpenPct - 0.1f);
if (emitEmbed.mOpenPct == 0.0f)
{
if (emitEmbed.mView != null)
{
emitEmbed.mView.RemoveSelf();
DeleteAndNullify!(emitEmbed.mView);
}
}
else
mCollapseNeedsUpdate = true;
}
}
}
RehupLineCoords();
return;
}
@ -5915,6 +6537,5 @@ namespace IDE.ui
RehupLineCoords(animIdx, animLines);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -408,6 +408,8 @@ namespace IDE.ui
{
DrawStatusBox("Loading Projects");
}
else if (gApp.mDeferredShowSource != null)
DrawStatusBox("Queued Showing Source");
else
mStatusBoxUpdateCnt = -1;