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

Added error/warning panel, region support

This commit is contained in:
Brian Fiete 2020-01-06 13:49:35 -08:00
parent c63edcbf87
commit 8970ebcd93
33 changed files with 454 additions and 130 deletions

View file

@ -179,6 +179,8 @@ namespace Beefy.theme.dark
ThreadBreakpointUnbound, ThreadBreakpointUnbound,
Search, Search,
CheckIndeterminate, CheckIndeterminate,
CodeError,
CodeWarning,
COUNT COUNT
}; };

View file

@ -78,7 +78,7 @@ namespace Beefy.widgets
{ {
if (mIsFocused != value) if (mIsFocused != value)
{ {
Selected = true; Selected = value;
mIsFocused = value; mIsFocused = value;
if (mListView.mOnFocusChanged.HasListeners) if (mListView.mOnFocusChanged.HasListeners)
mListView.mOnFocusChanged(this); mListView.mOnFocusChanged(this);

View file

@ -25,7 +25,7 @@ OtherLinkFlags = ""
TargetDirectory = "$(WorkspaceDir)/dist" TargetDirectory = "$(WorkspaceDir)/dist"
TargetName = "BeefIDE_d" TargetName = "BeefIDE_d"
OtherLinkFlags = "$(LinkFlags) Comdlg32.lib kernel32.lib user32.lib advapi32.lib shell32.lib IDEHelper64_d.lib" OtherLinkFlags = "$(LinkFlags) Comdlg32.lib kernel32.lib user32.lib advapi32.lib shell32.lib IDEHelper64_d.lib"
DebugCommandArguments = "-proddir=C:\\proj\\CycloBuddy" DebugCommandArguments = "-proddir=c:\\beef\\idehelper\\tests"
DebugWorkingDirectory = "c:\\Beef\\IDE\\Tests\\EmptyTest" DebugWorkingDirectory = "c:\\Beef\\IDE\\Tests\\EmptyTest"
EnvironmentVars = ["_NO_DEBUG_HEAP=1"] EnvironmentVars = ["_NO_DEBUG_HEAP=1"]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Before After
Before After

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Before After
Before After

Binary file not shown.

View file

@ -73,7 +73,7 @@ BeefLibType = "Static"
[Configs.Test.Win64] [Configs.Test.Win64]
CLibType = "Static" CLibType = "Static"
BeefLibType = "Static" BeefLibType = "DynamicDebug"
[Configs.Test.WinFart] [Configs.Test.WinFart]
BuildKind = "Normal" BuildKind = "Normal"
@ -88,8 +88,6 @@ BuildKind = "StaticLib"
BuildKind = "StaticLib" BuildKind = "StaticLib"
RelocType = "PIC" RelocType = "PIC"
[ProjectFolder]
[[ProjectFolder.Items]] [[ProjectFolder.Items]]
Type = "Source" Type = "Source"
Path = "../../../temp/test.txt" Path = "../../../temp/test.txt"
@ -98,3 +96,7 @@ Path = "../../../temp/test.txt"
Type = "Folder" Type = "Folder"
Path = "../../../temp/borf" Path = "../../../temp/borf"
AutoInclude = true AutoInclude = true
[[ProjectFolder.Items]]
Type = "Source"
Path = "../../../temp/test.bf"

View file

@ -8,6 +8,7 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Threading; using System.Threading;
#region EnumA Crapsos
[AllowDuplicates] [AllowDuplicates]
enum EnumA enum EnumA
{ {
@ -18,12 +19,35 @@ enum EnumA
Zoop = 1 Zoop = 1
} }
struct StructA
{
public int mA;
public int mB;
}
#region Blurg
struct Blurg struct Blurg
{ {
static mixin MixA(var sa2)
{
sa2.mA++;
}
static mixin MixB(mut StructA sa2)
{
sa2.mA++;
}
static void MethodA(mut StructA sa)
{
MixA!(sa);
//MixB!(mut sa);
}
public static int32 Hey() public static int32 Hey()
{ {
int a = 123; StructA sa = .();
int* aPtr = &a; sa.mA = 123
return (int32)123; return (int32)123;
} }

View file

@ -135,7 +135,7 @@ namespace IDE
{ {
mScriptManager = new .(); mScriptManager = new .();
mScriptManager.mProjectName = new String(project.mProjectName); mScriptManager.mProjectName = new String(project.mProjectName);
mScriptManager.mAllowCompiling = true; mScriptManager.mIsBuildScript = true;
mScriptManager.mSoftFail = true; mScriptManager.mSoftFail = true;
mScriptManager.mVerbosity = gApp.mVerbosity; mScriptManager.mVerbosity = gApp.mVerbosity;
didCommands = true; didCommands = true;

View file

@ -250,6 +250,8 @@ namespace IDE
Add("Show Class View", new => gApp.ShowClassViewPanel); Add("Show Class View", new => gApp.ShowClassViewPanel);
Add("Show Current", new => gApp.Cmd_ShowCurrent); Add("Show Current", new => gApp.Cmd_ShowCurrent);
Add("Show Disassembly", new => gApp.[Friend]ShowDisassemblyAtStack); Add("Show Disassembly", new => gApp.[Friend]ShowDisassemblyAtStack);
Add("Show Errors", new => gApp.[Friend]ShowErrors);
Add("Show Error Next", new => gApp.ShowErrorNext);
Add("Show File Externally", new => gApp.Cmd_ShowFileExternally); Add("Show File Externally", new => gApp.Cmd_ShowFileExternally);
Add("Show Find Results", new => gApp.ShowFindResults); Add("Show Find Results", new => gApp.ShowFindResults);
Add("Show Fixit", new => gApp.Cmd_ShowFixit); Add("Show Fixit", new => gApp.Cmd_ShowFixit);

View file

@ -8,6 +8,7 @@ using Beefy.widgets;
using Beefy; using Beefy;
using Beefy.utils; using Beefy.utils;
using IDE.Util; using IDE.Util;
using IDE.ui;
namespace IDE.Compiler namespace IDE.Compiler
{ {
@ -295,6 +296,8 @@ namespace IDE.Compiler
protected override void DoProcessQueue() protected override void DoProcessQueue()
{ {
BfPassInstance.PassKind passKind = .None;
BfPassInstance passInstance = null; BfPassInstance passInstance = null;
bool didPassInstanceAlloc = false; bool didPassInstanceAlloc = false;
@ -312,6 +315,23 @@ namespace IDE.Compiler
command = mCommandQueue[0]; command = mCommandQueue[0];
} }
bool commandProcessed = true;
defer
{
if (commandProcessed)
{
using (mMonitor.Enter())
{
delete command;
if (!mShuttingDown)
{
var poppedCmd = mCommandQueue.PopFront();
Debug.Assert(poppedCmd == command);
}
}
}
}
if (command is SetPassInstanceCommand) if (command is SetPassInstanceCommand)
{ {
var setPassInstanceCommand = (SetPassInstanceCommand)command; var setPassInstanceCommand = (SetPassInstanceCommand)command;
@ -345,9 +365,12 @@ namespace IDE.Compiler
var projectSource = projectSourceCommand.mProjectSource; var projectSource = projectSourceCommand.mProjectSource;
if (projectSource.mIncludeKind != .Ignore) if (projectSource.mIncludeKind != .Ignore)
{ {
BfProject bfProject = null;
using (projectSource.mProject.mMonitor.Enter()) using (projectSource.mProject.mMonitor.Enter())
{ {
projectSourceCommand.mProjectSource.GetFullImportPath(sourceFilePath); projectSourceCommand.mProjectSource.GetFullImportPath(sourceFilePath);
bfProject = mBfSystem.GetBfProject(projectSource.mProject);
} }
bool canMoveSourceString = true; bool canMoveSourceString = true;
@ -389,10 +412,15 @@ namespace IDE.Compiler
else else
bfParser.SetSource("", sourceFilePath); bfParser.SetSource("", sourceFilePath);
bfParser.SetCharIdData(ref char8IdData); bfParser.SetCharIdData(ref char8IdData);
//passInstance.SetProject(bfProject);
worked &= bfParser.Parse(passInstance, false); worked &= bfParser.Parse(passInstance, false);
worked &= bfParser.Reduce(passInstance); worked &= bfParser.Reduce(passInstance);
//passInstance.SetProject(bfProject);
worked &= bfParser.BuildDefs(passInstance, null, false); worked &= bfParser.BuildDefs(passInstance, null, false);
passKind = .Parse;
// Do this to make sure we re-trigger errors in parse/reduce/builddefs // Do this to make sure we re-trigger errors in parse/reduce/builddefs
if (!worked) if (!worked)
projectSource.HasChangedSinceLastCompile = true; projectSource.HasChangedSinceLastCompile = true;
@ -402,6 +430,15 @@ namespace IDE.Compiler
if (command is ProjectSourceRemovedCommand) if (command is ProjectSourceRemovedCommand)
{ {
var fileRemovedCommand = (ProjectSourceRemovedCommand)command; var fileRemovedCommand = (ProjectSourceRemovedCommand)command;
let projectSource = fileRemovedCommand.mProjectSource;
using (projectSource.mProject.mMonitor.Enter())
{
String sourceFilePath = scope String();
projectSource.GetFullImportPath(sourceFilePath);
gApp.mErrorsPanel.ClearParserErrors(sourceFilePath);
}
var bfParser = mBfSystem.FileRemoved(fileRemovedCommand.mProjectSource); var bfParser = mBfSystem.FileRemoved(fileRemovedCommand.mProjectSource);
if (bfParser != null) if (bfParser != null)
{ {
@ -421,13 +458,24 @@ namespace IDE.Compiler
if (command is ResolveAllCommand) if (command is ResolveAllCommand)
{ {
if (passKind != .None)
{
commandProcessed = false;
break;
}
var resolvePassData = BfResolvePassData.Create(ResolveType.Classify); var resolvePassData = BfResolvePassData.Create(ResolveType.Classify);
// If we get canceled then try again after waiting a couple updates // If we get canceled then try again after waiting a couple updates
if (!ClassifySource(passInstance, null, resolvePassData, null)) if (!ClassifySource(passInstance, null, resolvePassData, null))
QueueDeferredResolveAll(); QueueDeferredResolveAll();
delete resolvePassData; delete resolvePassData;
mBfSystem.RemoveOldParsers(); mBfSystem.RemoveOldParsers();
mBfSystem.RemoveOldData(); mBfSystem.RemoveOldData();
passKind = .Classify;
// End after resolveAll
break;
} }
if (command is SetWorkspaceOptionsCommand) if (command is SetWorkspaceOptionsCommand)
@ -444,22 +492,16 @@ namespace IDE.Compiler
{ {
mWantsActiveViewRefresh = true; mWantsActiveViewRefresh = true;
} }
using (mMonitor.Enter())
{
delete command;
if (!mShuttingDown)
{
var poppedCmd = mCommandQueue.PopFront();
Debug.Assert(poppedCmd == command);
}
}
} }
mBfSystem.Unlock(); mBfSystem.Unlock();
if (didPassInstanceAlloc) if (didPassInstanceAlloc)
delete passInstance; {
if ((passKind != .None) && (mIsResolveOnly))
gApp.mErrorsPanel.ProcessPassInstance(passInstance, passKind);
delete passInstance;
}
} }
void HandleOptions(BfProject hotBfProject, int32 hotIdx) void HandleOptions(BfProject hotBfProject, int32 hotIdx)

View file

@ -10,6 +10,13 @@ namespace IDE.Compiler
{ {
public class BfPassInstance public class BfPassInstance
{ {
public enum PassKind
{
None,
Parse,
Classify
}
[StdCall, CLink] [StdCall, CLink]
static extern void BfPassInstance_Delete(void* bfSystem); static extern void BfPassInstance_Delete(void* bfSystem);
@ -23,12 +30,12 @@ namespace IDE.Compiler
static extern int32 BfPassInstance_GetErrorCount(void* mNativeResolvePassData); static extern int32 BfPassInstance_GetErrorCount(void* mNativeResolvePassData);
[StdCall, CLink] [StdCall, CLink]
static extern char8* BfPassInstance_GetErrorData(void* mNativeResolvePassData, int32 errorIdx, out bool isWarning, static extern char8* BfPassInstance_GetErrorData(void* mNativeResolvePassData, int32 errorIdx, out int32 code, out bool isWarning,
out bool isAfter, out bool isDeferred, out bool isWhileSpecializing, out bool isAfter, out bool isDeferred, out bool isWhileSpecializing, out bool isPersistent, out char8* projectName,
out bool isPersistent, out int32 srcStart, out int32 srcEnd, out int32 moreInfoCount); out char8* fileName, out int32 srcStart, out int32 srcEnd, int32* srcLine, int32* srcColumn, out int32 moreInfoCount);
[StdCall, CLink] [StdCall, CLink]
static extern char8* BfPassInstance_Error_GetMoreInfoData(void* mNativeResolvePassData, int32 errorIdx, int32 moreInfoIdx, out char8* fileName, out int32 srcStart, out int32 srcEnd); static extern char8* BfPassInstance_Error_GetMoreInfoData(void* mNativeResolvePassData, int32 errorIdx, int32 moreInfoIdx, out char8* fileName, out int32 srcStart, out int32 srcEnd, int32* srcLine, int32* srcColumn);
[StdCall, CLink] [StdCall, CLink]
static extern bool BfPassInstance_HadSignatureChanges(void* mNativeResolvePassData); static extern bool BfPassInstance_HadSignatureChanges(void* mNativeResolvePassData);
@ -36,18 +43,22 @@ namespace IDE.Compiler
public class BfError public class BfError
{ {
public bool mIsWarning; public bool mIsWarning;
public int32 mCode;
public bool mIsAfter; public bool mIsAfter;
public bool mIsDeferred; public bool mIsDeferred;
public bool mIsWhileSpecializing; public bool mIsWhileSpecializing;
public bool mIsPersistent; public bool mIsPersistent;
public String mProject ~ delete _;
public String mError ~ delete _; public String mError ~ delete _;
public int32 mSrcStart; public int32 mSrcStart;
public int32 mSrcEnd; public int32 mSrcEnd;
public int32 mLine = -1;
public int32 mColumn = -1;
public int32 mMoreInfoCount; public int32 mMoreInfoCount;
public bool mOwnsSpan; public bool mOwnsSpan;
public IdSpan mIdSpan ~ { if (mOwnsSpan) _.Dispose(); }; public IdSpan mIdSpan ~ { if (mOwnsSpan) _.Dispose(); };
public int32 mErrorIdx = -1; public int32 mErrorIdx = -1;
public String mFileName ~ delete _; public String mFilePath ~ delete _;
public List<BfError> mMoreInfo ~ DeleteContainerAndItems!(_); public List<BfError> mMoreInfo ~ DeleteContainerAndItems!(_);
} }
@ -110,21 +121,30 @@ namespace IDE.Compiler
return BfPassInstance_GetErrorCount(mNativeBfPassInstance); return BfPassInstance_GetErrorCount(mNativeBfPassInstance);
} }
public void GetErrorData(int32 errorIdx, BfError bfError) public void GetErrorData(int32 errorIdx, BfError bfError, bool getLine = false)
{ {
Debug.Assert(bfError.mError == null); Debug.Assert(bfError.mError == null);
bfError.mErrorIdx = errorIdx; bfError.mErrorIdx = errorIdx;
bfError.mError = new String(BfPassInstance_GetErrorData(mNativeBfPassInstance, errorIdx, out bfError.mIsWarning, out bfError.mIsAfter, out bfError.mIsDeferred, char8* projectName = null;
out bfError.mIsWhileSpecializing, out bfError.mIsPersistent, out bfError.mSrcStart, out bfError.mSrcEnd, out bfError.mMoreInfoCount)); char8* fileName = null;
bfError.mError = new String(BfPassInstance_GetErrorData(mNativeBfPassInstance, errorIdx, out bfError.mCode, out bfError.mIsWarning, out bfError.mIsAfter, out bfError.mIsDeferred,
out bfError.mIsWhileSpecializing, out bfError.mIsPersistent, out projectName, out fileName, out bfError.mSrcStart, out bfError.mSrcEnd,
getLine ? &bfError.mLine : null, getLine ? &bfError.mColumn : null,
out bfError.mMoreInfoCount));
if (projectName != null)
bfError.mProject = new String(projectName);
if (fileName != null)
bfError.mFilePath = new String(fileName);
} }
public void GetMoreInfoErrorData(int32 errorIdx, int32 moreInfoIdx, BfError bfError) public void GetMoreInfoErrorData(int32 errorIdx, int32 moreInfoIdx, BfError bfError, bool getLine = false)
{ {
char8* fileName = null; char8* fileName = null;
char8* errorStr = BfPassInstance_Error_GetMoreInfoData(mNativeBfPassInstance, errorIdx, moreInfoIdx, out fileName, out bfError.mSrcStart, out bfError.mSrcEnd); char8* errorStr = BfPassInstance_Error_GetMoreInfoData(mNativeBfPassInstance, errorIdx, moreInfoIdx, out fileName, out bfError.mSrcStart, out bfError.mSrcEnd,
Debug.Assert(bfError.mFileName == null); getLine ? &bfError.mLine : null, getLine ? &bfError.mColumn : null);
Debug.Assert(bfError.mFilePath == null);
if (fileName != null) if (fileName != null)
bfError.mFileName = new String(fileName); bfError.mFilePath = new String(fileName);
if (bfError.mError == null) if (bfError.mError == null)
bfError.mError = new String(errorStr); bfError.mError = new String(errorStr);
else else

View file

@ -176,6 +176,7 @@ namespace IDE
public WatchPanel mWatchPanel; public WatchPanel mWatchPanel;
public MemoryPanel mMemoryPanel; public MemoryPanel mMemoryPanel;
public CallStackPanel mCallStackPanel; public CallStackPanel mCallStackPanel;
public ErrorsPanel mErrorsPanel;
public BreakpointPanel mBreakpointPanel; public BreakpointPanel mBreakpointPanel;
public ModulePanel mModulePanel; public ModulePanel mModulePanel;
public ThreadPanel mThreadPanel; public ThreadPanel mThreadPanel;
@ -625,6 +626,7 @@ namespace IDE
RemoveAndDelete!(mProjectPanel); RemoveAndDelete!(mProjectPanel);
RemoveAndDelete!(mClassViewPanel); RemoveAndDelete!(mClassViewPanel);
RemoveAndDelete!(mErrorsPanel);
RemoveAndDelete!(mOutputPanel); RemoveAndDelete!(mOutputPanel);
RemoveAndDelete!(mImmediatePanel); RemoveAndDelete!(mImmediatePanel);
RemoveAndDelete!(mFindResultsPanel); RemoveAndDelete!(mFindResultsPanel);
@ -4327,6 +4329,18 @@ namespace IDE
ShowPanel(mCallStackPanel, "Call Stack"); ShowPanel(mCallStackPanel, "Call Stack");
} }
[IDECommand]
public void ShowErrors()
{
ShowPanel(mErrorsPanel, "Errors");
}
[IDECommand]
public void ShowErrorNext()
{
mErrorsPanel.ShowErrorNext();
}
[IDECommand] [IDECommand]
public void ShowWatches() public void ShowWatches()
{ {
@ -4868,20 +4882,21 @@ namespace IDE
////////// //////////
subMenu = root.AddMenuItem("&View"); subMenu = root.AddMenuItem("&View");
AddMenuItem(subMenu, "Work&space Explorer", "Show Workspace Explorer"); AddMenuItem(subMenu, "A&utoComplete", "Show Autocomplete Panel");
AddMenuItem(subMenu, "C&lass View", "Show Class View"); AddMenuItem(subMenu, "&Auto Watches", "Show Auto Watches");
AddMenuItem(subMenu, "&Immediate Window", "Show Immediate"); AddMenuItem(subMenu, "&Breakpoints", "Show Breakpoints");
AddMenuItem(subMenu, "&Threads", "Show Threads");
AddMenuItem(subMenu, "&Call Stack", "Show Call Stack"); AddMenuItem(subMenu, "&Call Stack", "Show Call Stack");
AddMenuItem(subMenu, "&Watches", "Show Watches"); AddMenuItem(subMenu, "C&lass View", "Show Class View");
AddMenuItem(subMenu, "&Auto Watches", "Show Auto Watches"); AddMenuItem(subMenu, "E&rrors", "Show Errors");
AddMenuItem(subMenu, "&Breakpoints", "Show Breakpoints"); AddMenuItem(subMenu, "&Find Results", "Show Find Results");
AddMenuItem(subMenu, "&Immediate Window", "Show Immediate");
AddMenuItem(subMenu, "&Memory", "Show Memory"); AddMenuItem(subMenu, "&Memory", "Show Memory");
AddMenuItem(subMenu, "Mo&dules", "Show Modules"); AddMenuItem(subMenu, "Mo&dules", "Show Modules");
AddMenuItem(subMenu, "&Output", "Show Output"); AddMenuItem(subMenu, "&Output", "Show Output");
AddMenuItem(subMenu, "&Find Results", "Show Find Results");
AddMenuItem(subMenu, "&Profiler", "Show Profiler"); AddMenuItem(subMenu, "&Profiler", "Show Profiler");
AddMenuItem(subMenu, "A&utoComplete", "Show Autocomplete Panel"); AddMenuItem(subMenu, "&Threads", "Show Threads");
AddMenuItem(subMenu, "&Watches", "Show Watches");
AddMenuItem(subMenu, "Work&space Explorer", "Show Workspace Explorer");
subMenu.AddMenuItem(null); subMenu.AddMenuItem(null);
AddMenuItem(subMenu, "Next Document Panel", "Next Document Panel"); AddMenuItem(subMenu, "Next Document Panel", "Next Document Panel");
AddMenuItem(subMenu, "Navigate Backwards", "Navigate Backwards"); AddMenuItem(subMenu, "Navigate Backwards", "Navigate Backwards");
@ -8904,7 +8919,7 @@ namespace IDE
bool bfHadOutputChanges; bool bfHadOutputChanges;
List<String> bfFileNames = scope List<String>(); List<String> bfFileNames = scope List<String>();
bfCompiler.GetOutputFileNames(bfProject, false, out bfHadOutputChanges, bfFileNames); bfCompiler.GetOutputFileNames(bfProject, false, out bfHadOutputChanges, bfFileNames);
defer(scope) ClearAndDeleteItems(bfFileNames); defer ClearAndDeleteItems(bfFileNames);
if (bfHadOutputChanges) if (bfHadOutputChanges)
project.mNeedsTargetRebuild = true; project.mNeedsTargetRebuild = true;
} }
@ -10227,6 +10242,8 @@ namespace IDE
mCallStackPanel.mAutoDelete = false; mCallStackPanel.mAutoDelete = false;
mBreakpointPanel = new BreakpointPanel(); mBreakpointPanel = new BreakpointPanel();
mBreakpointPanel.mAutoDelete = false; mBreakpointPanel.mAutoDelete = false;
mErrorsPanel = new ErrorsPanel();
mErrorsPanel.mAutoDelete = false;
mModulePanel = new ModulePanel(); mModulePanel = new ModulePanel();
mModulePanel.mAutoDelete = false; mModulePanel.mAutoDelete = false;
mThreadPanel = new ThreadPanel(); mThreadPanel = new ThreadPanel();
@ -10857,6 +10874,9 @@ namespace IDE
didClean = true; didClean = true;
OutputLine("Cleaned Beef."); OutputLine("Cleaned Beef.");
if (mErrorsPanel != null)
mErrorsPanel.ClearParserErrors(null);
delete mBfResolveCompiler; delete mBfResolveCompiler;
delete mBfResolveSystem; delete mBfResolveSystem;
delete mBfResolveHelper; delete mBfResolveHelper;
@ -10932,6 +10952,9 @@ namespace IDE
{ {
OutputLine("Cleaned."); OutputLine("Cleaned.");
if (mErrorsPanel != null)
mErrorsPanel.ClearParserErrors(null);
let workspaceOptions = GetCurWorkspaceOptions(); let workspaceOptions = GetCurWorkspaceOptions();
delete mBfResolveHelper; delete mBfResolveHelper;
@ -11038,17 +11061,17 @@ namespace IDE
} }
} }
CurrentWorkspaceConfigChanged();
if (mBfResolveSystem != null) if (mBfResolveSystem != null)
{ {
for (var project in mWorkspace.mProjects) /*for (var project in mWorkspace.mProjects)
{ {
if (IsProjectEnabled(project)) if (IsProjectEnabled(project))
QueueProjectItems(project); QueueProjectItems(project);
} }*/
mBfResolveCompiler.QueueDeferredResolveAll(); mBfResolveCompiler.QueueDeferredResolveAll();
} }
CurrentWorkspaceConfigChanged();
} }
mBfBuildSystem.Update(); mBfBuildSystem.Update();
@ -11519,6 +11542,8 @@ namespace IDE
if ((mBuildContext == null) && (!IsCompiling)) if ((mBuildContext == null) && (!IsCompiling))
DeleteAndNullify!(mLaunchData); DeleteAndNullify!(mLaunchData);
mErrorsPanel?.CheckResolveAll();
} }
public void ShowPassOutput(BfPassInstance bfPassInstance) public void ShowPassOutput(BfPassInstance bfPassInstance)

View file

@ -72,7 +72,7 @@ namespace IDE
public String mExpectingError ~ delete _; public String mExpectingError ~ delete _;
public bool mHadExpectingError; public bool mHadExpectingError;
public int mDoneTicks; public int mDoneTicks;
public bool mAllowCompiling; public bool mIsBuildScript;
public bool mSoftFail; public bool mSoftFail;
public Verbosity mVerbosity = .Quiet; public Verbosity mVerbosity = .Quiet;
public String mProjectName ~ delete _; public String mProjectName ~ delete _;
@ -950,7 +950,7 @@ namespace IDE
if (gApp.IsCompiling) if (gApp.IsCompiling)
{ {
if (!ScriptManager.sActiveManager.mAllowCompiling) if (!ScriptManager.sActiveManager.mIsBuildScript)
return false; return false;
} }
@ -960,8 +960,16 @@ namespace IDE
if (gApp.mDebugger == null) if (gApp.mDebugger == null)
return true; return true;
if ((!gApp.AreTestsRunning()) && (!gApp.mDebugger.HasPendingDebugLoads()) && bool checkRunState = (!gApp.mDebugger.HasPendingDebugLoads()) &&
((gApp.mExecutionPaused) || (!gApp.mDebugger.mIsRunning))) ((gApp.mExecutionPaused) || (!gApp.mDebugger.mIsRunning));
if ((!ScriptManager.sActiveManager.mIsBuildScript) && (gApp.AreTestsRunning()))
checkRunState = false;
/*if (gApp.AreTestsRunning())
checkRunState = false;*/
if (checkRunState)
{ {
var runState = gApp.mDebugger.GetRunState(); var runState = gApp.mDebugger.GetRunState();
if (runState == .Terminating) if (runState == .Terminating)

View file

@ -451,12 +451,14 @@ namespace IDE
Add("Save All", "Ctrl+Shift+S"); Add("Save All", "Ctrl+Shift+S");
Add("Save File", "Ctrl+S"); Add("Save File", "Ctrl+S");
Add("Set Next Statement", "Ctrl+Shift+F10"); Add("Set Next Statement", "Ctrl+Shift+F10");
Add("Show Current", "Alt+C");
Add("Show Auto Watches", "Ctrl+Alt+A"); Add("Show Auto Watches", "Ctrl+Alt+A");
Add("Show Autocomplete Panel", "Ctrl+Alt+U"); Add("Show Autocomplete Panel", "Ctrl+Alt+U");
Add("Show Breakpoints", "Ctrl+Alt+B"); Add("Show Breakpoints", "Ctrl+Alt+B");
Add("Show Call Stack", "Ctrl+Alt+C"); Add("Show Call Stack", "Ctrl+Alt+C");
Add("Show Class View", "Ctrl+Alt+L"); Add("Show Class View", "Ctrl+Alt+L");
Add("Show Current", "Alt+C");
Add("Show Errors", "Ctrl+Alt+E");
Add("Show Error Next", "Ctrl+Shift+F12");
Add("Show File Externally", "Ctrl+Tilde"); Add("Show File Externally", "Ctrl+Tilde");
Add("Show Find Results", "Ctrl+Alt+F"); Add("Show Find Results", "Ctrl+Alt+F");
Add("Show Fixit", "Ctrl+Period"); Add("Show Fixit", "Ctrl+Period");

View file

@ -183,6 +183,9 @@ namespace IDE
cmd.Append(clientStr, 0, crPos); cmd.Append(clientStr, 0, crPos);
clientStr.Remove(0, crPos + 1); clientStr.Remove(0, crPos + 1);
if (cmd.IsWhiteSpace)
continue;
/*String outStr = scope String(); /*String outStr = scope String();
outStr.AppendF("CMD: {0}", cmd); outStr.AppendF("CMD: {0}", cmd);
QueueOutput(outStr);*/ QueueOutput(outStr);*/
@ -254,6 +257,13 @@ namespace IDE
case ":TestFinish": case ":TestFinish":
testsFinished = true; testsFinished = true;
default: default:
if ((cmdParts.Count < 5) || (cmdParts[0].StartsWith(":")))
{
QueueOutputLine("ERROR: Failed communicate with test target '{0}'", curProjectInfo.mTestExePath);
TestFailed();
return;
}
Debug.Assert(cmdParts[0][0] != ':'); Debug.Assert(cmdParts[0][0] != ':');
let attribs = cmdParts[1]; let attribs = cmdParts[1];
@ -347,11 +357,12 @@ namespace IDE
} }
else if (exitCode != 0) else if (exitCode != 0)
{ {
if (exitCode != 0) QueueOutputLine("ERROR: Test process exited with error code: {0}", exitCode);
{ TestFailed();
QueueOutputLine("ERROR: Test process exited with error code: {0}", exitCode); }
TestFailed(); else if (testInstance.mTestEntries.IsEmpty)
} {
QueueOutputLine("WARNING: No test methods defined. Consider adding a [Test] attribute to a static method in a project whose build type is set to 'Test'.");
} }
} }

View file

@ -51,7 +51,8 @@ namespace IDE.ui
public bool mNeedsResolveAll; public bool mNeedsResolveAll;
public bool mErrorsDirty; public bool mErrorsDirty;
public Monitor mMonitor = new .() ~ delete _; public Monitor mMonitor = new .() ~ delete _;
public List<BfPassInstance.BfError> mErrorList = new .() ~ DeleteContainerAndItems!(_); public Dictionary<String, List<BfPassInstance.BfError>> mParseErrors = new .() ~ delete _;
public List<BfPassInstance.BfError> mResolveErrors = new .() ~ DeleteContainerAndItems!(_);
public int mDirtyTicks; public int mDirtyTicks;
public int mErrorCount; public int mErrorCount;
@ -98,6 +99,11 @@ namespace IDE.ui
AddWidget(mDockingFrame); AddWidget(mDockingFrame);
} }
public ~this()
{
ClearParserErrors(null);
}
public override void Serialize(StructuredData data) public override void Serialize(StructuredData data)
{ {
base.Serialize(data); base.Serialize(data);
@ -122,12 +128,23 @@ namespace IDE.ui
{ {
using (mMonitor.Enter()) using (mMonitor.Enter())
{ {
mErrorCount = 0;
mWarningCount = 0;
int32 errorCount = passInstance.GetErrorCount(); int32 errorCount = passInstance.GetErrorCount();
ClearAndDeleteItems(mErrorList); if (passKind != .Parse)
mErrorList.Capacity = mErrorList.Count; {
if (!mResolveErrors.IsEmpty)
mErrorsDirty = true;
for (let error in mResolveErrors)
{
if (error.mIsWarning)
mWarningCount--;
else
mErrorCount--;
}
ClearAndDeleteItems(mResolveErrors);
mResolveErrors.Capacity = mResolveErrors.Count;
}
for (int32 errorIdx = 0; errorIdx < errorCount; errorIdx++) for (int32 errorIdx = 0; errorIdx < errorCount; errorIdx++)
{ {
@ -148,16 +165,61 @@ namespace IDE.ui
bfError.mMoreInfo.Add(moreInfo); bfError.mMoreInfo.Add(moreInfo);
} }
mErrorList.Add(bfError); if (passKind == .Parse)
} {
bool added = mParseErrors.TryAdd(bfError.mFilePath, var keyPtr, var valuePtr);
if (added)
{
*keyPtr = new .(bfError.mFilePath);
*valuePtr = new .();
}
(*valuePtr).Add(bfError);
}
else
mResolveErrors.Add(bfError);
mErrorsDirty = true; mErrorsDirty = true;
}
} }
} }
public void ClearParserErrors(StringView filePath) public void ClearParserErrors(String filePath)
{ {
using (mMonitor.Enter())
{
void DeleteErrorList(List<BfPassInstance.BfError> list)
{
for (let error in list)
{
if (error.mIsWarning)
mWarningCount--;
else
mErrorCount--;
delete error;
}
delete list;
}
if (filePath == null)
{
for (var kv in mParseErrors)
{
delete kv.key;
DeleteErrorList(kv.value);
mErrorsDirty = true;
}
mParseErrors.Clear();
}
else
{
if (mParseErrors.GetAndRemove(filePath) case .Ok((let key, let list)))
{
delete key;
DeleteErrorList(list);
mErrorsDirty = true;
}
}
}
} }
void ProcessErrors() void ProcessErrors()
@ -168,7 +230,8 @@ namespace IDE.ui
{ {
let root = mErrorLV.GetRoot(); let root = mErrorLV.GetRoot();
for (let error in mErrorList) int idx = 0;
void HandleError(BfPassInstance.BfError error)
{ {
ErrorsListViewItem item; ErrorsListViewItem item;
@ -181,7 +244,6 @@ namespace IDE.ui
item.Label = str; item.Label = str;
} }
int idx = @error.Index;
if (idx >= root.GetChildCount()) if (idx >= root.GetChildCount())
{ {
item = (.)root.CreateChildItem(); item = (.)root.CreateChildItem();
@ -225,9 +287,28 @@ namespace IDE.ui
if (changed) if (changed)
item.Focused = false; item.Focused = false;
idx++;
} }
while (root.GetChildCount() > mErrorList.Count) if (!mParseErrors.IsEmpty)
{
List<String> paths = scope .();
for (var path in mParseErrors.Keys)
paths.Add(path);
paths.Sort();
for (var path in paths)
{
for (var error in mParseErrors[path])
HandleError(error);
}
}
for (let error in mResolveErrors)
HandleError(error);
while (root.GetChildCount() > idx)
root.RemoveChildItemAt(root.GetChildCount() - 1); root.RemoveChildItemAt(root.GetChildCount() - 1);
mErrorsDirty = false; mErrorsDirty = false;
@ -277,7 +358,7 @@ namespace IDE.ui
bool foundFocused = false; bool foundFocused = false;
let root = mErrorLV.GetRoot(); let root = mErrorLV.GetRoot();
if (root.mChildItems == null) if (root.GetChildCount() == 0)
return; return;
for (let lvItem in root.mChildItems) for (let lvItem in root.mChildItems)
{ {

View file

@ -195,7 +195,7 @@ namespace IDE.ui
if (mShowingDropdown) if (mShowingDropdown)
return null; return null;
mShowingDropdown = true; mShowingDropdown = true;
defer(scope) { mShowingDropdown = false; } defer { mShowingDropdown = false; }
/*var stopWatch = scope Stopwatch(); /*var stopWatch = scope Stopwatch();
stopWatch.Start();*/ stopWatch.Start();*/

View file

@ -97,6 +97,10 @@ namespace IDE.ui
{ {
panel = gApp.mImmediatePanel; panel = gApp.mImmediatePanel;
} }
else if (type == "ErrorsPanel")
{
panel = gApp.mErrorsPanel;
}
else if (type == "FindResultsPanel") else if (type == "FindResultsPanel")
{ {
panel = gApp.mFindResultsPanel; panel = gApp.mFindResultsPanel;

View file

@ -868,7 +868,7 @@ namespace IDE.ui
String dir = scope String(fileDialog.InitialDirectory); String dir = scope String(fileDialog.InitialDirectory);
List<String> alreadyHadFileList = scope List<String>(); List<String> alreadyHadFileList = scope List<String>();
defer(scope) ClearAndDeleteItems(alreadyHadFileList); defer ClearAndDeleteItems(alreadyHadFileList);
for (String fileNameIn in fileDialog.FileNames) for (String fileNameIn in fileDialog.FileNames)
{ {

View file

@ -1653,6 +1653,9 @@ namespace IDE.ui
if (gApp.mDbgDelayedAutocomplete) if (gApp.mDbgDelayedAutocomplete)
Thread.Sleep(250); Thread.Sleep(250);
if ((resolveType == .Classify) || (resolveType == .ClassifyFullRefresh))
gApp.mErrorsPanel.SetNeedsResolveAll();
/*if (resolveType == .Autocomplete) /*if (resolveType == .Autocomplete)
{ {
Thread.Sleep(250); Thread.Sleep(250);
@ -1818,6 +1821,13 @@ namespace IDE.ui
resolvePassData.SetDocumentationRequest(resolveParams.mDocumentationName); resolvePassData.SetDocumentationRequest(resolveParams.mDocumentationName);
parser.Parse(passInstance, !mIsBeefSource); parser.Parse(passInstance, !mIsBeefSource);
parser.Reduce(passInstance); parser.Reduce(passInstance);
if ((mIsBeefSource) &&
((resolveType == .Classify) || (resolveType == .ClassifyFullRefresh)))
{
gApp.mErrorsPanel.ClearParserErrors(mFilePath);
gApp.mErrorsPanel.ProcessPassInstance(passInstance, .Parse);
}
if (isInterrupt) if (isInterrupt)
{ {
@ -2511,13 +2521,16 @@ namespace IDE.ui
if (trackedElement.mSnapToLineStart) if (trackedElement.mSnapToLineStart)
{ {
int32 lineLeft = trackedElementView.mTextPosition.mIndex; int32 lineLeft = trackedElementView.mTextPosition.mIndex;
repeat if (lineLeft < editContent.mData.mTextLength)
{ {
if (!((char8)editContent.mData.mText[lineLeft].mChar).IsWhiteSpace) repeat
startContentIdx = lineLeft; {
lineLeft--; if (!((char8)editContent.mData.mText[lineLeft].mChar).IsWhiteSpace)
} startContentIdx = lineLeft;
while ((lineLeft > 0) && (editContent.mData.mText[lineLeft].mChar != '\n')); lineLeft--;
}
while ((lineLeft > 0) && (editContent.mData.mText[lineLeft].mChar != '\n'));
}
if (startContentIdx == -1) if (startContentIdx == -1)
{ {
@ -4926,7 +4939,7 @@ namespace IDE.ui
{ {
for (var moreInfo in bestError.mMoreInfo) for (var moreInfo in bestError.mMoreInfo)
{ {
showMouseoverString.AppendF("\n@{0}\t{1}\t{2}", moreInfo.mFileName, moreInfo.mSrcStart, moreInfo.mError); showMouseoverString.AppendF("\n@{0}\t{1}\t{2}", moreInfo.mFilePath, moreInfo.mSrcStart, moreInfo.mError);
} }
} }
} }

View file

@ -365,9 +365,21 @@ namespace IDE.ui
else else
mStatusBoxUpdateCnt = -1; mStatusBoxUpdateCnt = -1;
///
{
if (gApp.mErrorsPanel.mErrorCount > 0)
{
g.Draw(DarkTheme.sDarkTheme.GetImage(.CodeError), GS!(6), 0);
}
else if (gApp.mErrorsPanel.mWarningCount > 0)
{
g.Draw(DarkTheme.sDarkTheme.GetImage(.CodeWarning), GS!(6), 0);
}
}
if (gApp.mSettings.mEnableDevMode) if (gApp.mSettings.mEnableDevMode)
{ {
g.DrawString(StackStringFormat!("FPS: {0}", gApp.mLastFPS), GS!(4), 0); g.DrawString(StackStringFormat!("FPS: {0}", gApp.mLastFPS), GS!(32), 0);
String resolveStr = scope String(); String resolveStr = scope String();
let bfResolveCompiler = gApp.mBfResolveCompiler; let bfResolveCompiler = gApp.mBfResolveCompiler;
@ -418,5 +430,16 @@ namespace IDE.ui
g.DrawString(resolveStr, GS!(100), 0); g.DrawString(resolveStr, GS!(100), 0);
} }
} }
public override void MouseDown(float x, float y, int32 btn, int32 btnCount)
{
base.MouseDown(x, y, btn, btnCount);
if (Rect(GS!(6), 0, GS!(20), mHeight).Contains(x, y))
{
gApp.mErrorsPanel.ShowErrorNext();
return;
}
}
} }
} }

View file

@ -3482,6 +3482,22 @@ void BfCompiler::ProcessAutocompleteTempType()
BF_ASSERT(mResolvePassData->mAutoComplete->mDefMethod == NULL); BF_ASSERT(mResolvePassData->mAutoComplete->mDefMethod == NULL);
if (autoComplete->mResolveType == BfResolveType_GetNavigationData) if (autoComplete->mResolveType == BfResolveType_GetNavigationData)
{ {
for (auto node : mResolvePassData->mParser->mSidechannelRootNode->mChildArr)
{
if (auto preprocNode = BfNodeDynCast<BfPreprocessorNode>(node))
{
if (preprocNode->mCommand->Equals("region"))
{
if (!autoCompleteResultString.empty())
autoCompleteResultString += "\n";
autoCompleteResultString += "#";
preprocNode->mArgument->ToString(autoCompleteResultString);
mContext->mScratchModule->UpdateSrcPos(preprocNode, (BfSrcPosFlags)(BfSrcPosFlag_NoSetDebugLoc | BfSrcPosFlag_Force));
autoCompleteResultString += StrFormat("\tregion\t%d\t%d", module->mCurFilePosition.mCurLine, module->mCurFilePosition.mCurColumn);
}
}
}
for (auto tempTypeDef : mResolvePassData->mAutoCompleteTempTypes) for (auto tempTypeDef : mResolvePassData->mAutoCompleteTempTypes)
{ {
String typeName = tempTypeDef->ToString(); String typeName = tempTypeDef->ToString();

View file

@ -195,7 +195,7 @@ void BfDefBuilder::ParseGenericParams(BfGenericParamsDeclaration* genericParamsD
{ {
if (genericParams[checkParamsIdx]->mName == name) if (genericParams[checkParamsIdx]->mName == name)
{ {
mPassInstance->Fail("Duplicate generic param name", genericParamNode); Fail("Duplicate generic param name", genericParamNode);
} }
} }
@ -256,7 +256,7 @@ void BfDefBuilder::ParseGenericParams(BfGenericParamsDeclaration* genericParamsD
{ {
if (externConstraintDefs == NULL) if (externConstraintDefs == NULL)
{ {
mPassInstance->Fail("Cannot find generic parameter in constraint", genericConstraint->mTypeRef); Fail("Cannot find generic parameter in constraint", genericConstraint->mTypeRef);
if (genericParams.IsEmpty()) if (genericParams.IsEmpty())
continue; continue;
@ -307,9 +307,9 @@ void BfDefBuilder::ParseGenericParams(BfGenericParamsDeclaration* genericParamsD
prevFlagName = "struct*"; prevFlagName = "struct*";
if (prevFlagName == name) if (prevFlagName == name)
mPassInstance->Fail(StrFormat("Cannot specify '%s' twice", prevFlagName.c_str()), constraintNode); Fail(StrFormat("Cannot specify '%s' twice", prevFlagName.c_str()), constraintNode);
else else
mPassInstance->Fail(StrFormat("Cannot specify both '%s' and '%s'", prevFlagName.c_str(), name.c_str()), constraintNode); Fail(StrFormat("Cannot specify both '%s' and '%s'", prevFlagName.c_str(), name.c_str()), constraintNode);
return; return;
} }
@ -347,7 +347,7 @@ void BfDefBuilder::ParseGenericParams(BfGenericParamsDeclaration* genericParamsD
auto constraintType = BfNodeDynCast<BfTypeReference>(constraintNode); auto constraintType = BfNodeDynCast<BfTypeReference>(constraintNode);
if (constraintType == NULL) if (constraintType == NULL)
{ {
mPassInstance->Fail("Invalid constraint", constraintNode); Fail("Invalid constraint", constraintNode);
return; return;
} }
} }
@ -360,7 +360,7 @@ void BfDefBuilder::ParseGenericParams(BfGenericParamsDeclaration* genericParamsD
} }
else else
{ {
mPassInstance->Fail("Type assignment must be the first constraint", genericConstraint->mColonToken); Fail("Type assignment must be the first constraint", genericConstraint->mColonToken);
} }
} }
@ -453,22 +453,22 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio
if (mCurTypeDef->mTypeCode == BfTypeCode_Interface) if (mCurTypeDef->mTypeCode == BfTypeCode_Interface)
{ {
if ((methodDef->mIsConcrete) && (!mCurTypeDef->mIsConcrete)) if ((methodDef->mIsConcrete) && (!mCurTypeDef->mIsConcrete))
mPassInstance->Fail("Only interfaces declared as 'concrete' can be declare methods as 'concrete'. Consider adding 'concrete' to the interface declaration.", methodDeclaration->mVirtualSpecifier); Fail("Only interfaces declared as 'concrete' can be declare methods as 'concrete'. Consider adding 'concrete' to the interface declaration.", methodDeclaration->mVirtualSpecifier);
//if (!methodDef->mIsConcrete) //if (!methodDef->mIsConcrete)
//mPassInstance->Fail(StrFormat("Interfaces methods cannot be declared as '%s'", methodDeclaration->mVirtualSpecifier->ToString().c_str()), methodDeclaration->mVirtualSpecifier); //Fail(StrFormat("Interfaces methods cannot be declared as '%s'", methodDeclaration->mVirtualSpecifier->ToString().c_str()), methodDeclaration->mVirtualSpecifier);
} }
else else
{ {
if (methodDef->mIsConcrete) if (methodDef->mIsConcrete)
mPassInstance->Fail("Only interfaces methods can be declared as 'concrete'", methodDeclaration->mVirtualSpecifier); Fail("Only interfaces methods can be declared as 'concrete'", methodDeclaration->mVirtualSpecifier);
} }
if (methodDef->mIsAbstract) if (methodDef->mIsAbstract)
{ {
if ((!mCurTypeDef->mIsAbstract) && (mCurTypeDef->mTypeCode != BfTypeCode_Interface)) if ((!mCurTypeDef->mIsAbstract) && (mCurTypeDef->mTypeCode != BfTypeCode_Interface))
mPassInstance->Fail("Method is abstract but it is contained in non-abstract class", methodDeclaration); Fail("Method is abstract but it is contained in non-abstract class", methodDeclaration);
if (methodDeclaration->mBody != NULL) if (methodDeclaration->mBody != NULL)
mPassInstance->Fail("Abstract method cannot declare a body", methodDeclaration); Fail("Abstract method cannot declare a body", methodDeclaration);
} }
} }
else else
@ -513,7 +513,7 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio
methodDef->mMethodType = BfMethodType_Operator; methodDef->mMethodType = BfMethodType_Operator;
/*if (propertyDecl->mStaticSpecifier == NULL) /*if (propertyDecl->mStaticSpecifier == NULL)
{ {
mPassInstance->Fail("Operators must be declared as static", methodDeclaration); Fail("Operators must be declared as static", methodDeclaration);
}*/ }*/
String declError; String declError;
@ -531,7 +531,7 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio
} }
if (!declError.empty()) if (!declError.empty())
{ {
mPassInstance->Fail(StrFormat("Operator must be declared %s", declError.c_str()), operatorDecl->mOperatorToken); Fail(StrFormat("Operator must be declared %s", declError.c_str()), operatorDecl->mOperatorToken);
} }
} }
else if ((mCurTypeDef->mIsDelegate) || (mCurTypeDef->mIsFunction)) else if ((mCurTypeDef->mIsDelegate) || (mCurTypeDef->mIsFunction))
@ -560,7 +560,7 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio
methodDef->mName = methodDeclaration->mNameNode->ToString(); methodDef->mName = methodDeclaration->mNameNode->ToString();
methodDef->mMethodType = BfMethodType_Mixin; methodDef->mMethodType = BfMethodType_Mixin;
/*if (!methodDef->mIsStatic) /*if (!methodDef->mIsStatic)
mPassInstance->Fail("Mixin must be declared static", methodDeclaration->mMixinSpecifier);*/ Fail("Mixin must be declared static", methodDeclaration->mMixinSpecifier);*/
} }
else else
{ {
@ -612,7 +612,7 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio
{ {
methodDef->mParams[paramIdx - 1]->mParamKind = BfParamKind_Normal; methodDef->mParams[paramIdx - 1]->mParamKind = BfParamKind_Normal;
hadParams = false; hadParams = false;
mPassInstance->Fail("Params parameter must be the last parameter", methodDef->mParams[paramIdx - 1]->mParamDeclaration); Fail("Params parameter must be the last parameter", methodDef->mParams[paramIdx - 1]->mParamDeclaration);
} }
if (paramDef->mParamDeclaration->mInitializer != NULL) if (paramDef->mParamDeclaration->mInitializer != NULL)
@ -620,7 +620,7 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio
else if (hasDefault) else if (hasDefault)
{ {
if (!didDefaultsError) if (!didDefaultsError)
mPassInstance->Fail("Optional parameters must appear after all required parameters", methodDef->mParams[paramIdx - 1]->mParamDeclaration); Fail("Optional parameters must appear after all required parameters", methodDef->mParams[paramIdx - 1]->mParamDeclaration);
didDefaultsError = true; didDefaultsError = true;
} }
} }
@ -632,6 +632,14 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio
return methodDef; return methodDef;
} }
BfError* BfDefBuilder::Fail(const StringImpl& errorStr, BfAstNode* refNode)
{
auto error = mPassInstance->Fail(errorStr, refNode);
if (error != NULL)
error->mProject = mCurSource->mProject;
return error;
}
void BfDefBuilder::Visit(BfMethodDeclaration* methodDeclaration) void BfDefBuilder::Visit(BfMethodDeclaration* methodDeclaration)
{ {
if (mCurTypeDef == NULL) if (mCurTypeDef == NULL)
@ -742,7 +750,7 @@ void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfMethodDef
{ {
if (methodDef->mParams.size() != 2) if (methodDef->mParams.size() != 2)
{ {
mPassInstance->Fail("Commutable attributes can only be applied to methods with two arguments", attributes->mAttributeTypeRef); Fail("Commutable attributes can only be applied to methods with two arguments", attributes->mAttributeTypeRef);
} }
else else
{ {
@ -790,7 +798,7 @@ void BfDefBuilder::Visit(BfPropertyDeclaration* propertyDeclaration)
if (propertyDeclaration->mConstSpecifier != NULL) if (propertyDeclaration->mConstSpecifier != NULL)
{ {
mPassInstance->Fail("Const properties are not allowed", propertyDeclaration->mConstSpecifier); Fail("Const properties are not allowed", propertyDeclaration->mConstSpecifier);
} }
HashNode(*mSignatureHashCtx, propertyDeclaration, propertyDeclaration->mDefinitionBlock); HashNode(*mSignatureHashCtx, propertyDeclaration, propertyDeclaration->mDefinitionBlock);
@ -871,7 +879,7 @@ void BfDefBuilder::Visit(BfPropertyDeclaration* propertyDeclaration)
{ {
BfProtection newProtection = GetProtection(methodDeclaration->mProtectionSpecifier); BfProtection newProtection = GetProtection(methodDeclaration->mProtectionSpecifier);
if (newProtection > methodDef->mProtection) if (newProtection > methodDef->mProtection)
mPassInstance->Fail(StrFormat("the accessibility modifier of the 'get' accessor must be more restrictive than the property or indexer '%s'", propertyDef->mName.c_str()), Fail(StrFormat("the accessibility modifier of the 'get' accessor must be more restrictive than the property or indexer '%s'", propertyDef->mName.c_str()),
methodDeclaration->mProtectionSpecifier); methodDeclaration->mProtectionSpecifier);
methodDef->mProtection = newProtection; methodDef->mProtection = newProtection;
} }
@ -997,7 +1005,7 @@ void BfDefBuilder::Visit(BfFieldDeclaration* fieldDeclaration)
// This check is a bit of a hack to determine the difference between a "MemberType mMember" and a proper case entry of "mMember(TupleType)" // This check is a bit of a hack to determine the difference between a "MemberType mMember" and a proper case entry of "mMember(TupleType)"
if (!isEnumEntryDecl) if (!isEnumEntryDecl)
{ {
mPassInstance->Fail("Non-static field declarations are not allowed in enums", fieldDeclaration); Fail("Non-static field declarations are not allowed in enums", fieldDeclaration);
} }
} }
@ -1231,7 +1239,7 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
mCurTypeDef->mName = mSystem->GetAtom(typeDeclaration->mNameNode->ToString()); mCurTypeDef->mName = mSystem->GetAtom(typeDeclaration->mNameNode->ToString());
if (mCurTypeDef->mName->mIsSystemType) if (mCurTypeDef->mName->mIsSystemType)
{ {
mPassInstance->Fail(StrFormat("Type name '%s' is reserved", typeDeclaration->mNameNode->ToString().c_str()), typeDeclaration->mNameNode); Fail(StrFormat("Type name '%s' is reserved", typeDeclaration->mNameNode->ToString().c_str()), typeDeclaration->mNameNode);
} }
} }
@ -1245,7 +1253,7 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
if ((outerTypeDef == NULL) && (typeDeclaration->mProtectionSpecifier->GetToken() != BfToken_Public)) if ((outerTypeDef == NULL) && (typeDeclaration->mProtectionSpecifier->GetToken() != BfToken_Public))
{ {
//CS1527 //CS1527
mPassInstance->Fail("Elements defined in a namespace cannot be explicitly declared as private, protected, or protected internal", typeDeclaration->mProtectionSpecifier); Fail("Elements defined in a namespace cannot be explicitly declared as private, protected, or protected internal", typeDeclaration->mProtectionSpecifier);
} }
else else
{ {
@ -1677,13 +1685,13 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
{ {
if (hasStaticCtor) if (hasStaticCtor)
{ {
mPassInstance->Fail("Only one static constructor is allowed", method->mMethodDeclaration); Fail("Only one static constructor is allowed", method->mMethodDeclaration);
method->mIsStatic = false; method->mIsStatic = false;
} }
if (method->mParams.size() != 0) if (method->mParams.size() != 0)
{ {
mPassInstance->Fail("Static constructor cannot declare parameters", method->mMethodDeclaration); Fail("Static constructor cannot declare parameters", method->mMethodDeclaration);
method->mIsStatic = false; method->mIsStatic = false;
} }
@ -1740,7 +1748,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
{ {
if (hasStaticDtor) if (hasStaticDtor)
{ {
mPassInstance->Fail("Only one static constructor is allowed", method->mMethodDeclaration); Fail("Only one static constructor is allowed", method->mMethodDeclaration);
method->mIsStatic = false; method->mIsStatic = false;
} }
@ -1750,14 +1758,14 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
{ {
if (hasDtor) if (hasDtor)
{ {
mPassInstance->Fail("Only one destructor is allowed", method->mMethodDeclaration); Fail("Only one destructor is allowed", method->mMethodDeclaration);
method->mIsStatic = false; method->mIsStatic = false;
} }
hasDtor = true; hasDtor = true;
} }
if (method->mParams.size() != 0) if (method->mParams.size() != 0)
mPassInstance->Fail("Destructors cannot declare parameters", method->GetMethodDeclaration()->mParams[0]); Fail("Destructors cannot declare parameters", method->GetMethodDeclaration()->mParams[0]);
} }
else if (method->mMethodType == BfMethodType_Normal) else if (method->mMethodType == BfMethodType_Normal)
{ {

View file

@ -41,6 +41,7 @@ public:
void ParseAttributes(BfAttributeDirective* attributes, BfMethodDef* methodDef); void ParseAttributes(BfAttributeDirective* attributes, BfMethodDef* methodDef);
void ParseAttributes(BfAttributeDirective* attributes, BfTypeDef* typeDef); void ParseAttributes(BfAttributeDirective* attributes, BfTypeDef* typeDef);
BfMethodDef* CreateMethodDef(BfMethodDeclaration* methodDecl, BfMethodDef* outerMethodDef = NULL); BfMethodDef* CreateMethodDef(BfMethodDeclaration* methodDecl, BfMethodDef* outerMethodDef = NULL);
BfError* Fail(const StringImpl& errorStr, BfAstNode* refNode);
public: public:
BfDefBuilder(BfSystem* bfSystem); BfDefBuilder(BfSystem* bfSystem);

View file

@ -2839,7 +2839,7 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI
varSkipCount--; varSkipCount--;
} }
if (varDecl->mNotCaptured) if ((varDecl != NULL) && (varDecl->mNotCaptured))
{ {
mModule->Fail("Local variable is not captured", refNode); mModule->Fail("Local variable is not captured", refNode);
} }

View file

@ -2610,6 +2610,7 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers
} }
if (bfError != NULL) if (bfError != NULL)
{ {
bfError->mProject = mProject;
bfError->mIsPersistent = isPersistent; bfError->mIsPersistent = isPersistent;
bfError->mIsWhileSpecializing = isWhileSpecializing; bfError->mIsWhileSpecializing = isWhileSpecializing;
@ -2629,7 +2630,10 @@ BfError* BfModule::FailAfter(const StringImpl& error, BfAstNode* refNode)
refNode = BfNodeToNonTemporary(refNode); refNode = BfNodeToNonTemporary(refNode);
mHadBuildError = true; mHadBuildError = true;
return mCompiler->mPassInstance->FailAfter(error, refNode); BfError* bfError = mCompiler->mPassInstance->FailAfter(error, refNode);
if (bfError != NULL)
bfError->mProject = mProject;
return bfError;
} }
BfError* BfModule::Warn(int warningNum, const StringImpl& warning, BfAstNode* refNode, bool isPersistent) BfError* BfModule::Warn(int warningNum, const StringImpl& warning, BfAstNode* refNode, bool isPersistent)
@ -2692,6 +2696,7 @@ BfError* BfModule::Warn(int warningNum, const StringImpl& warning, BfAstNode* re
BfError* bfError = mCompiler->mPassInstance->WarnAt(warningNum, warning, refNode->GetSourceData(), refNode->GetSrcStart(), refNode->GetSrcLength()); BfError* bfError = mCompiler->mPassInstance->WarnAt(warningNum, warning, refNode->GetSourceData(), refNode->GetSrcStart(), refNode->GetSrcLength());
if (bfError != NULL) if (bfError != NULL)
{ {
bfError->mProject = mProject;
AddFailType(mCurTypeInstance); AddFailType(mCurTypeInstance);
mHadBuildWarning = true; mHadBuildWarning = true;

View file

@ -197,15 +197,18 @@ BfAstNode* BfReducer::Fail(const StringImpl& errorMsg, BfAstNode* refNode)
mStmtHasError = true; mStmtHasError = true;
if (mPassInstance->HasLastFailedAt(refNode)) // No duplicate failures if (mPassInstance->HasLastFailedAt(refNode)) // No duplicate failures
return NULL; return NULL;
mPassInstance->Fail(errorMsg, refNode); auto error = mPassInstance->Fail(errorMsg, refNode);
if (error != NULL)
error->mProject = mSource->mProject;
return NULL; return NULL;
} }
BfAstNode* BfReducer::FailAfter(const StringImpl& errorMsg, BfAstNode* prevNode) BfAstNode* BfReducer::FailAfter(const StringImpl& errorMsg, BfAstNode* prevNode)
{ {
mStmtHasError = true; mStmtHasError = true;
mPassInstance->FailAfter(errorMsg, prevNode); auto error = mPassInstance->FailAfter(errorMsg, prevNode);
if (error != NULL)
error->mProject = mSource->mProject;
return NULL; return NULL;
} }
@ -4053,11 +4056,11 @@ BfAstNode* BfReducer::DoCreateStatement(BfAstNode* node, CreateStmtFlags createS
if ((unaryOperatorExpr->mOp == BfUnaryOp_Ref) || (unaryOperatorExpr->mOp == BfUnaryOp_Mut) || (unaryOperatorExpr->mOp == BfUnaryOp_Out)) if ((unaryOperatorExpr->mOp == BfUnaryOp_Ref) || (unaryOperatorExpr->mOp == BfUnaryOp_Mut) || (unaryOperatorExpr->mOp == BfUnaryOp_Out))
{ {
if (unaryOperatorExpr->mOp == BfUnaryOp_Ref) if (unaryOperatorExpr->mOp == BfUnaryOp_Ref)
mPassInstance->Fail("Cannot use 'ref' in this context", unaryOperatorExpr); Fail("Cannot use 'ref' in this context", unaryOperatorExpr);
else if (unaryOperatorExpr->mOp == BfUnaryOp_Mut) else if (unaryOperatorExpr->mOp == BfUnaryOp_Mut)
mPassInstance->Fail("Cannot use 'mut' in this context", unaryOperatorExpr); Fail("Cannot use 'mut' in this context", unaryOperatorExpr);
else else
mPassInstance->Fail("Cannot use 'out' in this context", unaryOperatorExpr); Fail("Cannot use 'out' in this context", unaryOperatorExpr);
return NULL; return NULL;
} }
} }
@ -4246,7 +4249,7 @@ BfAstNode* BfReducer::CreateStatement(BfAstNode* node, CreateStmtFlags createStm
auto nextNode = mVisitorPos.GetNext(); auto nextNode = mVisitorPos.GetNext();
if (nextNode != NULL) if (nextNode != NULL)
{ {
mPassInstance->FailAfter("Semicolon expected", expr); FailAfter("Semicolon expected", expr);
} }
return expr; return expr;
@ -4295,7 +4298,9 @@ BfAstNode* BfReducer::CreateStatement(BfAstNode* node, CreateStmtFlags createStm
if (((createStmtFlags & CreateStmtFlags_AllowUnterminatedExpression) != 0) && (origStmtNode->IsA<BfExpression>()) && (nextNode == NULL)) if (((createStmtFlags & CreateStmtFlags_AllowUnterminatedExpression) != 0) && (origStmtNode->IsA<BfExpression>()) && (nextNode == NULL))
return stmt; return stmt;
mPassInstance->FailAfterAt("Semicolon expected", node->GetSourceData(), stmt->GetSrcEnd() - 1); auto error = mPassInstance->FailAfterAt("Semicolon expected", node->GetSourceData(), stmt->GetSrcEnd() - 1);
if (error != NULL)
error->mProject = mSource->mProject;
mPrevStmtHadError = true; mPrevStmtHadError = true;
return stmt; return stmt;
} }
@ -4881,7 +4886,7 @@ BfTypeReference* BfReducer::DoCreateTypeRef(BfAstNode* firstNode, CreateTypeRefF
if ((!doAddType) && (isBoundName)) if ((!doAddType) && (isBoundName))
{ {
mPassInstance->FailAfter("Expected type", genericInstance); FailAfter("Expected type", genericInstance);
} }
if ((doAddType) && (!isUnboundName)) if ((doAddType) && (!isUnboundName))
{ {
@ -5539,7 +5544,7 @@ BfAstNode* BfReducer::ReadTypeMember(BfTokenNode* tokenNode, int depth)
innerType->mAttributes = attributes; innerType->mAttributes = attributes;
return innerType; return innerType;
} }
mPassInstance->Fail("Invalid target for attributes", memberNode); Fail("Invalid target for attributes", memberNode);
return memberNode; return memberNode;
} }
@ -8595,9 +8600,9 @@ BfTokenNode* BfReducer::ParseMethodParams(BfAstNode* node, SizedArrayImpl<BfPara
{ {
auto node = mVisitorPos.Get(errIdx); auto node = mVisitorPos.Get(errIdx);
if (auto token = BfNodeDynCast<BfTokenNode>(node)) if (auto token = BfNodeDynCast<BfTokenNode>(node))
mPassInstance->Fail("Unexpected token", node); Fail("Unexpected token", node);
else else
mPassInstance->Fail("Unexpected identifier", node); Fail("Unexpected identifier", node);
AddErrorNode(node); AddErrorNode(node);
} }

View file

@ -5568,7 +5568,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
autoComplete->CheckTypeRef(forEachStmt->mVariableTypeRef, false); autoComplete->CheckTypeRef(forEachStmt->mVariableTypeRef, false);
varType = ResolveTypeRef(forEachStmt->mVariableTypeRef, BfPopulateType_Data, BfResolveTypeRefFlag_AllowRef); varType = ResolveTypeRef(forEachStmt->mVariableTypeRef, BfPopulateType_Data, BfResolveTypeRefFlag_AllowRef);
} }
if (varType == NULL) if (varType == NULL)
varType = mContext->mBfObjectType; varType = mContext->mBfObjectType;
bool isArray = target.mType->IsArray(); bool isArray = target.mType->IsArray();
@ -5979,6 +5979,9 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
scopeData.mIsLoop = true; scopeData.mIsLoop = true;
if ((autoComplete != NULL) && (forEachStmt->mVariableTypeRef != NULL))
autoComplete->CheckVarResolution(forEachStmt->mVariableTypeRef, varType);
if (isArray || isSizedArray) if (isArray || isSizedArray)
mBfIRBuilder->CreateStore(GetConstValue(0), itr.mValue); mBfIRBuilder->CreateStore(GetConstValue(0), itr.mValue);

View file

@ -1391,17 +1391,21 @@ BfError* BfPassInstance::Fail(const StringImpl& error)
return mErrors.back(); return mErrors.back();
} }
BfError* BfPassInstance::Fail(const StringImpl& error, BfAstNode* refNode) BfError* BfPassInstance::Fail(const StringImpl& errorStr, BfAstNode* refNode)
{ {
BP_ZONE("BfPassInstance::Fail"); BP_ZONE("BfPassInstance::Fail");
BfError* error = NULL;
mFailedIdx++; mFailedIdx++;
if ((refNode == NULL) || (refNode->IsTemporary())) if ((refNode == NULL) || (refNode->IsTemporary()))
return Fail(error); error = Fail(errorStr);
else if (refNode->IsA<BfBlock>()) else if (refNode->IsA<BfBlock>())
return FailAt(error, refNode->GetSourceData(), refNode->GetSrcStart(), 1); error = FailAt(errorStr, refNode->GetSourceData(), refNode->GetSrcStart(), 1);
else else
return FailAt(error, refNode->GetSourceData(), refNode->GetSrcStart(), refNode->GetSrcLength()); error = FailAt(errorStr, refNode->GetSourceData(), refNode->GetSrcStart(), refNode->GetSrcLength());
return error;
} }
BfError* BfPassInstance::FailAfter(const StringImpl& error, BfAstNode* refNode) BfError* BfPassInstance::FailAfter(const StringImpl& error, BfAstNode* refNode)
@ -1504,7 +1508,7 @@ BfError* BfPassInstance::WarnAt(int warningNumber, const StringImpl& warning, Bf
if ((int)mErrors.size() > 1) if ((int)mErrors.size() > 1)
errorStart += StrFormat("(%d)", mErrors.size()); errorStart += StrFormat("(%d)", mErrors.size());
if (warningNumber > 0) if (warningNumber > 0)
errorStart += StrFormat(": CS%04d", warningNumber); errorStart += StrFormat(": BF%04d", warningNumber);
MessageAt(":warn", errorStart + ": " + warning, bfParser, srcIdx); MessageAt(":warn", errorStart + ": " + warning, bfParser, srcIdx);
} }
return errorVal; return errorVal;
@ -3334,7 +3338,8 @@ BF_EXPORT int BF_CALLTYPE BfPassInstance_GetErrorCount(BfPassInstance* bfPassIns
return (int)bfPassInstance->mErrors.size(); return (int)bfPassInstance->mErrors.size();
} }
BF_EXPORT const char* BF_CALLTYPE BfPassInstance_GetErrorData(BfPassInstance* bfPassInstance, int errorIdx, bool& outIsWarning, bool& outIsAfter, bool& outIsDeferred, bool& outIsWhileSpecializing, bool& outIsPersistent, int& outSrcStart, int& outSrcEnd, int& outMoreInfoCount) BF_EXPORT const char* BF_CALLTYPE BfPassInstance_GetErrorData(BfPassInstance* bfPassInstance, int errorIdx, int& outCode, bool& outIsWarning, bool& outIsAfter, bool& outIsDeferred, bool& outIsWhileSpecializing, bool& outIsPersistent,
char*& projectName, char*& fileName, int& outSrcStart, int& outSrcEnd, int* outLine, int* outColumn, int& outMoreInfoCount)
{ {
BfError* bfError = bfPassInstance->mErrors[errorIdx]; BfError* bfError = bfPassInstance->mErrors[errorIdx];
outIsWarning = bfError->mIsWarning; outIsWarning = bfError->mIsWarning;
@ -3342,13 +3347,33 @@ BF_EXPORT const char* BF_CALLTYPE BfPassInstance_GetErrorData(BfPassInstance* bf
outIsDeferred = bfError->mIsDeferred; outIsDeferred = bfError->mIsDeferred;
outIsWhileSpecializing = bfError->mIsWhileSpecializing; outIsWhileSpecializing = bfError->mIsWhileSpecializing;
outIsPersistent = bfError->mIsPersistent; outIsPersistent = bfError->mIsPersistent;
outCode = bfError->mWarningNumber;
if (bfError->mProject != NULL)
projectName = (char*)bfError->mProject->mName.c_str();
if (bfError->mSource != NULL)
{
String* srcFileName;
if (bfPassInstance->mSourceFileNameMap.TryGetValue(bfError->mSource, &srcFileName))
{
fileName = (char*)srcFileName->c_str();
}
if (outLine != NULL)
{
auto parserData = bfError->mSource->ToParserData();
if (parserData != NULL)
{
parserData->GetLineCharAtIdx(bfError->mSrcStart, *outLine, *outColumn);
}
}
}
outSrcStart = bfError->mSrcStart; outSrcStart = bfError->mSrcStart;
outSrcEnd = bfError->mSrcEnd; outSrcEnd = bfError->mSrcEnd;
outMoreInfoCount = (int)bfError->mMoreInfo.size(); outMoreInfoCount = (int)bfError->mMoreInfo.size();
return bfError->mError.c_str(); return bfError->mError.c_str();
} }
BF_EXPORT const char* BfPassInstance_Error_GetMoreInfoData(BfPassInstance* bfPassInstance, int errorIdx, int moreInfoIdx, char*& fileName, int& srcStart, int& srcEnd) BF_EXPORT const char* BfPassInstance_Error_GetMoreInfoData(BfPassInstance* bfPassInstance, int errorIdx, int moreInfoIdx, char*& fileName, int& srcStart, int& srcEnd, int* outLine, int* outColumn)
{ {
BfError* rootError = bfPassInstance->mErrors[errorIdx]; BfError* rootError = bfPassInstance->mErrors[errorIdx];
BfMoreInfo* moreInfo = rootError->mMoreInfo[moreInfoIdx]; BfMoreInfo* moreInfo = rootError->mMoreInfo[moreInfoIdx];

View file

@ -1114,17 +1114,19 @@ public:
bool mIsPersistent; bool mIsPersistent;
bool mIsWhileSpecializing; bool mIsWhileSpecializing;
bool mIgnore; bool mIgnore;
BfProject* mProject;
String mError; String mError;
int mWarningNumber; int mWarningNumber;
Array<BfMoreInfo*> mMoreInfo; Array<BfMoreInfo*> mMoreInfo;
public: public:
BfError() BfError()
{ {
mIsAfter = false; mIsAfter = false;
mIsPersistent = false; mIsPersistent = false;
mIsWhileSpecializing = false; mIsWhileSpecializing = false;
mIgnore = false; mIgnore = false;
mProject = NULL;
mWarningNumber = 0; mWarningNumber = 0;
} }