From 815af77641b0b9a956f8cbefa078b68c72e0092d Mon Sep 17 00:00:00 2001 From: Joseph Battelle Date: Wed, 3 Feb 2021 00:37:54 -0800 Subject: [PATCH 01/71] Allow secondary windows to be maximized Prior to this change, secondary windows could be minimized by right-clicking on the title bar, but not maximized. Maximizing is very useful for multi-monitor setups. The popup menu includes restore as well. To enable these actions directly from the titlebar without navigating a popup, the 'ToolWindow' style would have to be removed because it inhibits the standard system buttons. --- BeefLibs/Beefy2D/src/widgets/TabbedView.bf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BeefLibs/Beefy2D/src/widgets/TabbedView.bf b/BeefLibs/Beefy2D/src/widgets/TabbedView.bf index 84904080..823aa76f 100644 --- a/BeefLibs/Beefy2D/src/widgets/TabbedView.bf +++ b/BeefLibs/Beefy2D/src/widgets/TabbedView.bf @@ -237,7 +237,7 @@ namespace Beefy.widgets 300, 500, BFWindowBase.Flags.Border | BFWindowBase.Flags.ThickFrame | BFWindowBase.Flags.Resizable | BFWindowBase.Flags.SysMenu | BFWindowBase.Flags.Caption | BFWindowBase.Flags.Minimize | BFWindowBase.Flags.ToolWindow | BFWindowBase.Flags.TopMost | - BFWindowBase.Flags.UseParentMenu, + BFWindowBase.Flags.UseParentMenu | BFWindowBase.Flags.Maximize, subFrame); Dock(subFrame, null, DockingFrame.WidgetAlign.Top); //subFrame.AddDockedWidget(fourthTabbedView, null, DockingFrame.WidgetAlign.Left, false); From 83d3ae658deb1cb98ebf40d3bb16b32d89257ae1 Mon Sep 17 00:00:00 2001 From: Joseph Battelle Date: Wed, 3 Feb 2021 17:09:24 -0800 Subject: [PATCH 02/71] Fix for Workspace Explorer panel with no workspace Don't give focus to a non-existent child. Previously any hide/show of the Workspace Explorer without a workspace loaded would crash. --- IDE/src/ui/ProjectPanel.bf | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/IDE/src/ui/ProjectPanel.bf b/IDE/src/ui/ProjectPanel.bf index ef594582..1a963d03 100644 --- a/IDE/src/ui/ProjectPanel.bf +++ b/IDE/src/ui/ProjectPanel.bf @@ -181,9 +181,10 @@ namespace IDE.ui { base.FocusForKeyboard(); SetFocus(); - if (mListView.GetRoot().FindFocusedItem() == null) + let root = mListView.GetRoot(); + if (root.IsOpen && root.FindFocusedItem() == null) { - mListView.GetRoot().GetChildAtIndex(0).Focused = true; + root.GetChildAtIndex(0).Focused = true; } } From d63d65bd7168d2144eb45897635933c7e18a0c19 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Thu, 4 Feb 2021 16:05:03 -0800 Subject: [PATCH 03/71] Null check fix --- IDEHelper/Compiler/BfReducer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/IDEHelper/Compiler/BfReducer.cpp b/IDEHelper/Compiler/BfReducer.cpp index b00c8d54..afc95e51 100644 --- a/IDEHelper/Compiler/BfReducer.cpp +++ b/IDEHelper/Compiler/BfReducer.cpp @@ -9264,9 +9264,9 @@ bool BfReducer::ParseMethod(BfMethodDeclaration* methodDeclaration, SizedArrayIm bool isFunction = false; bool isDelegate = false; - if ((mCurTypeDecl->mTypeNode != NULL) && (mCurTypeDecl->mTypeNode->GetToken() == BfToken_Function)) + if ((mCurTypeDecl != NULL) && (mCurTypeDecl->mTypeNode != NULL) && (mCurTypeDecl->mTypeNode->GetToken() == BfToken_Function)) isFunction = true; - else if ((mCurTypeDecl->mTypeNode != NULL) && (mCurTypeDecl->mTypeNode->GetToken() == BfToken_Delegate)) + else if ((mCurTypeDecl != NULL) && (mCurTypeDecl->mTypeNode != NULL) && (mCurTypeDecl->mTypeNode->GetToken() == BfToken_Delegate)) isDelegate = true; if ((!isFunction) && (!isDelegate)) From d4d6ba60fbd4d4b0309779b980d0c27658e41565 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Fri, 5 Feb 2021 09:39:58 -0800 Subject: [PATCH 04/71] Fixed ReplaceWithNewVReg from mov arg0 vregload --- IDEHelper/Backend/BeMCContext.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/IDEHelper/Backend/BeMCContext.cpp b/IDEHelper/Backend/BeMCContext.cpp index c8d3471e..c7bdf13e 100644 --- a/IDEHelper/Backend/BeMCContext.cpp +++ b/IDEHelper/Backend/BeMCContext.cpp @@ -3787,7 +3787,7 @@ BeMCOperand BeMCContext::AllocVirtualReg(BeType* type, int refCount, bool mustBe if (mDebugging) { - if (mcOperand.mVRegIdx == 6) + if (mcOperand.mVRegIdx == 227) { NOP; } @@ -10361,7 +10361,7 @@ bool BeMCContext::DoLegalization() inst->mArg0.mKind = BeMCOperandKind_SymbolAddr; } - ReplaceWithNewVReg(inst->mArg0, movInstIdx, true, false); + ReplaceWithNewVReg(inst->mArg0, movInstIdx, true, false, true); auto vregInfo = GetVRegInfo(inst->mArg0); vregInfo->mDisableR11 = true; instIdx += 2; @@ -15839,7 +15839,7 @@ void BeMCContext::Generate(BeFunction* function) mDbgPreferredRegs[32] = X64Reg_R8;*/ //mDbgPreferredRegs[8] = X64Reg_RAX; - //mDebugging = (function->mName == "?Zoips@TestProgram@BeefTest@bf@@SAXXZ"); + //mDebugging = (function->mName == "?Init@TimeZoneInfo@System@bf@@AEAA?AU?$Result@X@23@UStringView@23@VTimeSpan@23@000PEAV?$Array1@PEAVAdjustmentRule@TimeZoneInfo@System@bf@@@23@_N@Z"); // || (function->mName == "?MethodA@TestProgram@BeefTest@bf@@CAXXZ"); // || (function->mName == "?Hey@Blurg@bf@@SAXXZ") // ; From 59f0ff880628b7f826d5b0e81e9a3d95227f4e68 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Fri, 5 Feb 2021 12:00:25 -0800 Subject: [PATCH 05/71] Enable multiprocessor compilation on VS projects --- BeefRT/BeefRT.vcxproj | 12 ++++++++++++ BeefySysLib/BeefySysLib.vcxproj | 8 ++++++++ Debugger32/Debugger32.vcxproj | 4 ++++ Debugger64/Debugger64.vcxproj | 4 ++++ IDEHelper/IDEHelper.vcxproj | 6 ++++++ 5 files changed, 34 insertions(+) diff --git a/BeefRT/BeefRT.vcxproj b/BeefRT/BeefRT.vcxproj index f4e02f8c..7becbac9 100644 --- a/BeefRT/BeefRT.vcxproj +++ b/BeefRT/BeefRT.vcxproj @@ -479,6 +479,7 @@ false false ProgramDatabase + true Windows @@ -499,6 +500,7 @@ false false ProgramDatabase + true Windows @@ -519,6 +521,7 @@ false false ProgramDatabase + true Windows @@ -541,6 +544,7 @@ stdcpp17 false ProgramDatabase + true Windows @@ -566,6 +570,7 @@ stdcpp17 false ProgramDatabase + true Windows @@ -590,6 +595,7 @@ stdcpp17 false ProgramDatabase + true Windows @@ -612,6 +618,7 @@ stdcpp17 MultiThreaded false + true Windows @@ -634,6 +641,7 @@ .;..;../BeefySysLib/third_party;../BeefySysLib;../BeefySysLib/platform/win;gperftools/src;gperftools/src/windows;../BeefySysLib/third_party/libffi/i686-pc-cygwin;../BeefySysLib/third_party/libffi/i686-pc-cygwin/include;../BeefySysLib/third_party/libffi/include stdcpp17 false + true Windows @@ -656,6 +664,7 @@ stdcpp17 MultiThreaded false + true Windows @@ -681,6 +690,7 @@ false false stdcpp17 + true Windows @@ -707,6 +717,7 @@ false stdcpp17 ProgramDatabase + true Windows @@ -733,6 +744,7 @@ false stdcpp17 ProgramDatabase + true Windows diff --git a/BeefySysLib/BeefySysLib.vcxproj b/BeefySysLib/BeefySysLib.vcxproj index 46f8d0c6..8b60f95d 100644 --- a/BeefySysLib/BeefySysLib.vcxproj +++ b/BeefySysLib/BeefySysLib.vcxproj @@ -188,6 +188,7 @@ ./;./platform/win/;./platform/sdl/;third_party/agg-2.4/include;third_party/agg-2.4/include/platform/win32;third_party/;third_party/libffi/i686-pc-cygwin;third_party/libffi/i686-pc-cygwin/include;third_party/libffi/include;third_party/SDL2-2.0.1/include;../extern/fbxsdk/include;third_party/freetype/include MultiThreadedDebugDLL false + true Windows @@ -224,6 +225,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"MultiThreadedDebug false false + true Windows @@ -254,6 +256,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"WIN32;_DEBUG;_WINDOWS;BFSYSLIB_STATIC;%(PreprocessorDefinitions) ./;./platform/win/;./platform/sdl/;third_party/agg-2.4/include;third_party/agg-2.4/include/platform/win32;third_party/;third_party/libffi/i686-pc-cygwin;third_party/libffi/i686-pc-cygwin/include;third_party/libffi/include;third_party/SDL2-2.0.1/include;../extern/fbxsdk/include MultiThreadedDebug + true Windows @@ -282,6 +285,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"./; ./platform/win/; third_party/agg-2.4/include; third_party/agg-2.4/include/platform/win32; third_party/; third_party/libffi/i686-pc-cygwin; third_party/libffi/i686-pc-cygwin/include; third_party/libffi/include MultiThreadedDebug false + true Windows @@ -311,6 +315,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"BFP_NOEXPORT;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;_USRDLL;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions) MultiThreadedDLL ./; ./platform/win/; ./platform/sdl/; third_party/agg-2.4/include; third_party/agg-2.4/include/platform/win32; third_party/; third_party/libffi/i686-pc-cygwin; third_party/libffi/i686-pc-cygwin/include; third_party/libffi/include; third_party/SDL2-2.0.1/include;;../extern/fbxsdk/include + true Windows @@ -348,6 +353,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"MultiThreaded ./;./platform/win/;./platform/sdl/;third_party/agg-2.4/include;third_party/agg-2.4/include/platform/win32;third_party/;third_party/libffi/i686-pc-cygwin;third_party/libffi/i686-pc-cygwin/include;third_party/libffi/include;third_party/SDL2-2.0.1/include;../extern/fbxsdk/include;third_party/freetype/include false + true Windows @@ -382,6 +388,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"WIN32;NDEBUG;_WINDOWS;_USRDLL;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions) MultiThreaded ./; ./platform/win/; ./platform/sdl/; third_party/agg-2.4/include; third_party/agg-2.4/include/platform/win32; third_party/; third_party/libffi/i686-pc-cygwin; third_party/libffi/i686-pc-cygwin/include; third_party/libffi/include; third_party/SDL2-2.0.1/include + true Windows @@ -413,6 +420,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"WIN32;NDEBUG;_WINDOWS;_USRDLL;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions) MultiThreaded ./; ./platform/win/; third_party/agg-2.4/include; third_party/agg-2.4/include/platform/win32; third_party/; third_party/libffi/i686-pc-cygwin; third_party/libffi/i686-pc-cygwin/include; third_party/libffi/include + true Windows diff --git a/Debugger32/Debugger32.vcxproj b/Debugger32/Debugger32.vcxproj index c4bd07ae..7fee08a3 100644 --- a/Debugger32/Debugger32.vcxproj +++ b/Debugger32/Debugger32.vcxproj @@ -132,6 +132,7 @@ BF_DBG_32;WIN32;_DEBUG;_WINDOWS;_USRDLL;IDEHELPER_EXPORTS;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions) ../;../IDEHelper;../BeefySysLib/platform/win;../BeefySysLib/third_party;C:\llvm-3.8\llvm\include;C:\llvm-3.8\bin64\include;C:\llvm-3.8\llvm\lib\Target;C:\llvm-3.8\bin64\lib\Target\X86;C:\llvm-3.8\llvm\tools\clang\include false + true Windows @@ -150,6 +151,7 @@ -D_SCL_SECURE_NO_WARNINGS %(AdditionalOptions) false MultiThreadedDebug + true Windows @@ -166,6 +168,7 @@ true BF_DBG_32;WIN32;NDEBUG;_WINDOWS;_USRDLL;IDEHELPER_EXPORTS;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions) ../;../IDEHelper;../BeefySysLib/platform/win;../BeefySysLib/third_party;C:\llvm-3.8\llvm\include;C:\llvm-3.8\bin64\include;C:\llvm-3.8\llvm\lib\Target;C:\llvm-3.8\bin64\lib\Target\X86;C:\llvm-3.8\llvm\tools\clang\include + true Windows @@ -186,6 +189,7 @@ ../;../IDEHelper;../BeefySysLib/platform/win;../BeefySysLib/third_party;..\extern\llvm-project_11_0_0\llvm\include;..\extern\llvm_win64_11_0_0\include;..\extern\llvm-project_11_0_0\llvm\lib\Target;..\extern\llvm_win64_11_0_0\lib\Target\X86;..\extern\llvm-project_11_0_0\llvm\tools\clang\include MultiThreaded false + true Windows diff --git a/Debugger64/Debugger64.vcxproj b/Debugger64/Debugger64.vcxproj index 2c281774..7b3fe4b2 100644 --- a/Debugger64/Debugger64.vcxproj +++ b/Debugger64/Debugger64.vcxproj @@ -132,6 +132,7 @@ BF_DBG_64;WIN32;_DEBUG;_WINDOWS;_USRDLL;IDEHELPER_EXPORTS;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions) ../;../IDEHelper;../BeefySysLib/platform/win;../BeefySysLib/third_party;C:\llvm-3.8\llvm\include;C:\llvm-3.8\bin64\include;C:\llvm-3.8\llvm\lib\Target;C:\llvm-3.8\bin64\lib\Target\X86;C:\llvm-3.8\llvm\tools\clang\include false + true Windows @@ -150,6 +151,7 @@ -D_SCL_SECURE_NO_WARNINGS %(AdditionalOptions) false MultiThreadedDebug + true Windows @@ -166,6 +168,7 @@ true BF_DBG_64;WIN32;NDEBUG;_WINDOWS;_USRDLL;IDEHELPER_EXPORTS;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions) ../;../IDEHelper;../BeefySysLib/platform/win;../BeefySysLib/third_party;C:\llvm-3.8\llvm\include;C:\llvm-3.8\bin64\include;C:\llvm-3.8\llvm\lib\Target;C:\llvm-3.8\bin64\lib\Target\X86;C:\llvm-3.8\llvm\tools\clang\include + true Windows @@ -186,6 +189,7 @@ ../;../IDEHelper;../BeefySysLib/platform/win;../BeefySysLib/third_party;..\extern\llvm-project_11_0_0\llvm\include;..\extern\llvm_win64_11_0_0\include;..\extern\llvm-project_11_0_0\llvm\lib\Target;..\extern\llvm_win64_11_0_0\lib\Target\X86;..\extern\llvm-project_11_0_0\llvm\tools\clang\include MultiThreaded false + true Windows diff --git a/IDEHelper/IDEHelper.vcxproj b/IDEHelper/IDEHelper.vcxproj index 10e6e389..7e8c6f2e 100644 --- a/IDEHelper/IDEHelper.vcxproj +++ b/IDEHelper/IDEHelper.vcxproj @@ -139,6 +139,7 @@ MultiThreadedDebugDLL ProgramDatabase false + true Windows @@ -166,6 +167,7 @@ MultiThreadedDebug ProgramDatabase false + true Windows @@ -197,6 +199,7 @@ WIN32;NDEBUG;_WINDOWS;_USRDLL;IDEHELPER_EXPORTS;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions) ../;../BeefySysLib/platform/win;../BeefySysLib/third_party;C:\llvm-3.8\llvm\include;C:\llvm-3.8\bin\include;C:\llvm-3.8\llvm\lib\Target;C:\llvm-3.8\bin\lib\Target\X86;C:\llvm-3.8\llvm\tools\clang\include MultiThreadedDLL + true Windows @@ -222,6 +225,7 @@ ../;../BeefySysLib/platform/win;../BeefySysLib/third_party;..\extern\llvm-project_11_0_0\llvm\include;..\extern\llvm_win64_11_0_0\include;..\extern\llvm-project_11_0_0\llvm\lib\Target;..\extern\llvm_win64_11_0_0\lib\Target\X86;..\extern\llvm-project_11_0_0\llvm\tools\clang\include;..\extern\curl\builds\libcurl-vc15-x64-release-static-zlib-static-ipv6-sspi-winssl\include MultiThreaded false + true Windows @@ -251,6 +255,7 @@ WIN32;NDEBUG;_WINDOWS;_USRDLL;IDEHELPER_EXPORTS;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions) ../;../BeefySysLib/platform/win;../BeefySysLib/third_party;C:\llvm\llvm\include;C:\llvm\src\include;C:\llvm\llvm\lib\Target;C:\llvm\src\lib\Target\X86;C:\llvm\llvm\tools\clang\include MultiThreadedDLL + true Windows @@ -275,6 +280,7 @@ WIN32;NDEBUG;_WINDOWS;_USRDLL;IDEHELPER_EXPORTS;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions) ../;../BeefySysLib/platform/win;../BeefySysLib/third_party;C:\llvm\llvm\include;C:\llvm\src\include;C:\llvm\llvm\lib\Target;C:\llvm\src\lib\Target\X86;C:\llvm\llvm\tools\clang\include MultiThreadedDLL + true Windows From 5d5186f8127af4c670f76d7af7df735d3544a16d Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Fri, 5 Feb 2021 12:35:25 -0800 Subject: [PATCH 06/71] Missed lib --- IDE/dist/lib/gen/src/Program.bf | 2 +- IDE/dist/lib/x64/shell32.lib | Bin 0 -> 116740 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 IDE/dist/lib/x64/shell32.lib diff --git a/IDE/dist/lib/gen/src/Program.bf b/IDE/dist/lib/gen/src/Program.bf index f174bd0b..30a53782 100644 --- a/IDE/dist/lib/gen/src/Program.bf +++ b/IDE/dist/lib/gen/src/Program.bf @@ -12,7 +12,7 @@ namespace gen { class Program { - static String[] sNames = new .[]("comdlg32", "gdi32", "kernel32", "ole32", "netapi32", "ntdll", "rpcrt4", "user32", "version", "winmm") ~ delete _; + static String[] sNames = new .[]("comdlg32", "gdi32", "kernel32", "ole32", "netapi32", "ntdll", "rpcrt4", "shell32", "user32", "version", "winmm") ~ delete _; public static int Main(String[] args) { diff --git a/IDE/dist/lib/x64/shell32.lib b/IDE/dist/lib/x64/shell32.lib new file mode 100644 index 0000000000000000000000000000000000000000..c9fbebedb32c389297507ba40b73dda7bfbdf242 GIT binary patch literal 116740 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 Date: Fri, 5 Feb 2021 13:23:16 -0800 Subject: [PATCH 07/71] Fix for FOLDERID_ linkage for msvcrt builds --- BeefySysLib/platform/win/Platform.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/BeefySysLib/platform/win/Platform.cpp b/BeefySysLib/platform/win/Platform.cpp index 18d1ae94..0d82acc0 100644 --- a/BeefySysLib/platform/win/Platform.cpp +++ b/BeefySysLib/platform/win/Platform.cpp @@ -1,3 +1,8 @@ +#define INITKNOWNFOLDERS +#include +#include +#undef INITKNOWNFOLDERS + #pragma warning(disable:4065) #pragma warning(disable:4996) From 2e4792d51ea14f09456424f71587f5755a05ac68 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Sat, 6 Feb 2021 06:55:32 -0800 Subject: [PATCH 08/71] Fix to disable VS check when VS is not required --- BeefLibs/Beefy2D/src/widgets/KeyCode.bf | 18 +++++++++++++ IDE/src/BuildContext.bf | 24 +++++++++-------- IDE/src/IDEApp.bf | 34 +++++++++++++++++++++++-- 3 files changed, 63 insertions(+), 13 deletions(-) diff --git a/BeefLibs/Beefy2D/src/widgets/KeyCode.bf b/BeefLibs/Beefy2D/src/widgets/KeyCode.bf index 400b1c03..4369d2a3 100644 --- a/BeefLibs/Beefy2D/src/widgets/KeyCode.bf +++ b/BeefLibs/Beefy2D/src/widgets/KeyCode.bf @@ -106,6 +106,24 @@ namespace Beefy.widgets extension KeyCode { + public bool IsModifier + { + get + { + switch (this) + { + case .LWin, + .RWin, + .Alt, + .Control, + .Command: + return true; + default: + return false; + } + } + } + public static Result Parse(StringView str) { if (str.Length == 1) diff --git a/IDE/src/BuildContext.bf b/IDE/src/BuildContext.bf index ffbbfa23..571ccaeb 100644 --- a/IDE/src/BuildContext.bf +++ b/IDE/src/BuildContext.bf @@ -874,9 +874,9 @@ namespace IDE minRTModName.Insert(0, "_"); if (!is64Bit) - linkLine.Append("-libpath:\"", gApp.mInstallDir, "lib\\x86\" ", gApp.mInstallDir, "lib\\x86\\msvcrt.lib Beef", IDEApp.sRTVersionStr,"MinRT32", minRTModName, ".lib "); + linkLine.Append("-libpath:\"", gApp.mInstallDir, "lib\\x86\" \"", gApp.mInstallDir, "lib\\x86\\msvcrt.lib\" Beef", IDEApp.sRTVersionStr,"MinRT32", minRTModName, ".lib "); else - linkLine.Append("-libpath:\"", gApp.mInstallDir, "lib\\x64\" ", gApp.mInstallDir, "lib\\x64\\msvcrt.lib Beef", IDEApp.sRTVersionStr,"MinRT64", minRTModName, ".lib "); + linkLine.Append("-libpath:\"", gApp.mInstallDir, "lib\\x64\" \"", gApp.mInstallDir, "lib\\x64\\msvcrt.lib\" Beef", IDEApp.sRTVersionStr,"MinRT64", minRTModName, ".lib "); linkLine.Append("ntdll.lib user32.lib kernel32.lib gdi32.lib winmm.lib shell32.lib ole32.lib rpcrt4.lib version.lib comdlg32.lib -ignore:4049 -ignore:4217 "); } @@ -1062,17 +1062,8 @@ namespace IDE IDEUtils.AppendWithOptionalQuotes(linkLine, resOutPath); } - - let binPath = (!is64Bit) ? gApp.mSettings.mVSSettings.mBin32Path : gApp.mSettings.mVSSettings.mBin64Path; - if (binPath.IsWhiteSpace) - { - gApp.OutputErrorLine("Visual Studio tool path not configured. Check Visual Studio configuration in File\\Preferences\\Settings."); - return false; - } String linkerPath = scope String(); - linkerPath.Append(binPath); - linkerPath.Append("/link.exe"); if (workspaceOptions.mToolsetType == .LLVM) { linkerPath.Clear(); @@ -1097,6 +1088,17 @@ namespace IDE if ((mPlatformType == .Windows) && (!is64Bit)) linkLine.Append(" /safeseh:no"); } + else + { + let binPath = (!is64Bit) ? gApp.mSettings.mVSSettings.mBin32Path : gApp.mSettings.mVSSettings.mBin64Path; + if (binPath.IsWhiteSpace) + { + gApp.OutputErrorLine("Visual Studio tool path not configured. Check Visual Studio configuration in File\\Preferences\\Settings."); + return false; + } + linkerPath.Append(binPath); + linkerPath.Append("/link.exe"); + } if (options.mBuildOptions.mBeefLibType != .DynamicDebug) { diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf index 9b9855c8..fadb8c6a 100644 --- a/IDE/src/IDEApp.bf +++ b/IDE/src/IDEApp.bf @@ -7497,7 +7497,7 @@ namespace IDE } } } - else + else if (!evt.mKeyCode.IsModifier) { // Not found if (hadChordState) @@ -10411,6 +10411,36 @@ namespace IDE #endif } + public bool IsVisualStudioRequired + { + get + { + if (Workspace.PlatformType.GetFromName(mPlatformName) != .Windows) + return false; + var workspaceOptions = GetCurWorkspaceOptions(); + if (workspaceOptions.mToolsetType != .LLVM) + return true; + + for (var project in mWorkspace.mProjects) + { + if ((project.mGeneralOptions.mTargetType != .BeefConsoleApplication) && + (project.mGeneralOptions.mTargetType != .BeefGUIApplication) && + (project.mGeneralOptions.mTargetType != .BeefApplication_DynamicLib) && + (project.mGeneralOptions.mTargetType != .BeefApplication_StaticLib)) + { + continue; + } + + var options = GetCurProjectOptions(project); + if (options == null) + continue; + if (options.mBuildOptions.mCLibType != .SystemMSVCRT) + return true; + } + return false; + } + } + protected bool Compile(CompileKind compileKind = .Normal, Project hotProject = null) { Debug.Assert(mBuildContext == null); @@ -10585,7 +10615,7 @@ namespace IDE } } - if (Workspace.PlatformType.GetFromName(mPlatformName) == .Windows) + if ((Workspace.PlatformType.GetFromName(mPlatformName) == .Windows) && (IsVisualStudioRequired)) { if (!mSettings.mVSSettings.IsConfigured()) mSettings.mVSSettings.SetDefaults(); From 5f5c752f5da348db854b1672709ef0e8723c7be3 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Sat, 6 Feb 2021 07:10:30 -0800 Subject: [PATCH 09/71] Better key chord matching --- IDE/src/IDEApp.bf | 154 ++++++++++++++++++++++++++-------------------- 1 file changed, 87 insertions(+), 67 deletions(-) diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf index fadb8c6a..0cdaae19 100644 --- a/IDE/src/IDEApp.bf +++ b/IDE/src/IDEApp.bf @@ -7428,83 +7428,103 @@ namespace IDE return; } } - - var keyState = scope KeyState(); - keyState.mKeyCode = evt.mKeyCode; - keyState.mKeyFlags = evt.mKeyFlags; - - var curKeyMap = mCommands.mKeyMap; - bool hadChordState = mKeyChordState != null; - if (mKeyChordState != null) - curKeyMap = mKeyChordState.mCommandMap; - DeleteAndNullify!(mKeyChordState); - - KeyState matchedKey; - IDECommandBase commandBase; - if (curKeyMap.mMap.TryGet(keyState, out matchedKey, out commandBase)) + + if ((mKeyChordState != null) && (evt.mKeyCode.IsModifier)) { - if (var commandMap = commandBase as CommandMap) + // Ignore + } + else + { + var keyState = scope KeyState(); + keyState.mKeyCode = evt.mKeyCode; + keyState.mKeyFlags = evt.mKeyFlags; + + var curKeyMap = mCommands.mKeyMap; + + bool hadChordState = mKeyChordState != null; + if (mKeyChordState != null) + curKeyMap = mKeyChordState.mCommandMap; + var prevKeyChordState = mKeyChordState; + defer delete prevKeyChordState; + mKeyChordState = null; + + KeyState matchedKey; + IDECommandBase commandBase; + + bool hadMatch = curKeyMap.mMap.TryGet(keyState, out matchedKey, out commandBase); + if ((!hadMatch) && (prevKeyChordState != null)) { - mKeyChordState = new .(); - mKeyChordState.mCommandMap = commandMap; - mKeyChordState.mKeyState = matchedKey; - evt.mHandled = true; - return; + // If we have a "Ctrl+A, Ctrl+B" style sequence then also try to match that against "Ctrl+A, B" + KeyState rawKeyState = keyState; + rawKeyState.mKeyFlags &= ~prevKeyChordState.mKeyState.mKeyFlags; + hadMatch = curKeyMap.mMap.TryGet(rawKeyState, out matchedKey, out commandBase); } - else if (var command = commandBase as IDECommand) + + if (hadMatch) { - bool foundMatch = false; - if (useFlags != .None) - { - var checkCommand = command; - while (checkCommand != null) - { - bool matches = checkCommand.mContextFlags == .None; - if (checkCommand.mContextFlags.HasFlag(.Editor)) - matches |= useFlags.HasFlag(.Editor); - if (checkCommand.mContextFlags.HasFlag(.MainWindow)) - matches |= useFlags.HasFlag(.MainWindow); - if (checkCommand.mContextFlags.HasFlag(.WorkWindow)) - matches |= useFlags.HasFlag(.WorkWindow); - - if (matches) - { - checkCommand.mAction(); - foundMatch = true; - } - checkCommand = checkCommand.mNext; - } - } - - if (!foundMatch) - { - var checkCommand = command; - while (checkCommand != null) - { - if (checkCommand.mContextFlags == .None) - { - checkCommand.mAction(); - foundMatch = true; - } - checkCommand = checkCommand.mNext; - } - } - - if (foundMatch) + if (var commandMap = commandBase as CommandMap) { + mKeyChordState = new .(); + mKeyChordState.mCommandMap = commandMap; + mKeyChordState.mKeyState = matchedKey; evt.mHandled = true; return; } + else if (var command = commandBase as IDECommand) + { + bool foundMatch = false; + if (useFlags != .None) + { + var checkCommand = command; + while (checkCommand != null) + { + bool matches = checkCommand.mContextFlags == .None; + if (checkCommand.mContextFlags.HasFlag(.Editor)) + matches |= useFlags.HasFlag(.Editor); + if (checkCommand.mContextFlags.HasFlag(.MainWindow)) + matches |= useFlags.HasFlag(.MainWindow); + if (checkCommand.mContextFlags.HasFlag(.WorkWindow)) + matches |= useFlags.HasFlag(.WorkWindow); + + if (matches) + { + checkCommand.mAction(); + foundMatch = true; + } + checkCommand = checkCommand.mNext; + } + } + + if (!foundMatch) + { + var checkCommand = command; + while (checkCommand != null) + { + if (checkCommand.mContextFlags == .None) + { + checkCommand.mAction(); + foundMatch = true; + } + checkCommand = checkCommand.mNext; + } + } + + if (foundMatch) + { + evt.mHandled = true; + return; + } + } } - } - else if (!evt.mKeyCode.IsModifier) - { - // Not found - if (hadChordState) + else { - Beep(.Error); - evt.mHandled = true; - return; + // Not found + if (hadChordState) + { + Beep(.Error); + evt.mHandled = true; + return; + } } } From eddbf7a98466ddc9468229aec180dd88c246fc7d Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Sun, 7 Feb 2021 06:00:34 -0800 Subject: [PATCH 10/71] Reworked !hasRequiredTypes state --- IDEHelper/Compiler/BfCompiler.cpp | 64 +++++++++--------------- IDEHelper/Compiler/BfCompiler.h | 1 + IDEHelper/Compiler/BfConstResolver.cpp | 21 +++++--- IDEHelper/Compiler/BfConstResolver.h | 2 +- IDEHelper/Compiler/BfContext.cpp | 17 +++++-- IDEHelper/Compiler/BfDefBuilder.cpp | 27 +++++----- IDEHelper/Compiler/BfModule.cpp | 15 ++++-- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 12 +++-- IDEHelper/Compiler/BfSystem.cpp | 10 +++- IDEHelper/Compiler/BfSystem.h | 4 +- IDEHelper/Compiler/CeMachine.cpp | 8 +-- 11 files changed, 104 insertions(+), 77 deletions(-) diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index 6c25707a..e13faae1 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -341,11 +341,10 @@ BfCompiler::HotResolveData::~HotResolveData() BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly) { - //llvm::DebugFlag = true; - memset(&mStats, 0, sizeof(mStats)); mCompletionPct = 0; mCanceling = false; + mHasRequiredTypes = false; mNeedsFullRefresh = false; mFastFinish = false; mHasQueuedTypeRebuilds = false; @@ -2146,7 +2145,7 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork) madeFullPass = false; if ((mResolvePassData != NULL) && (mResolvePassData->mParser != NULL)) madeFullPass = false; - + SetAndRestoreValue prevAssertOnPopulateType(mContext->mAssertOnPopulateType, deleteUnusued && madeFullPass); if ((deleteUnusued) && (madeFullPass)) @@ -5220,7 +5219,7 @@ int BfCompiler::GetVTableMethodOffset() bool BfCompiler::DoWorkLoop(bool onlyReifiedTypes, bool onlyReifiedMethods) { bool hadAnyWork = false; - + while (true) { bool didWork = false; @@ -6596,7 +6595,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) BpEnter("Compile_Start"); - bool hasRequiredTypes = true; + mHasRequiredTypes = true; //HashSet internalTypeDefs; @@ -6606,7 +6605,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) if (typeDef == NULL) { mPassInstance->Fail(StrFormat("Unable to find system type: %s", typeName.c_str())); - hasRequiredTypes = false; + mHasRequiredTypes = false; } return typeDef; }; @@ -6722,21 +6721,17 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) mContext->mBfTypeType = NULL; mContext->mBfClassVDataPtrType = NULL; - if (!hasRequiredTypes) - { - // Force rebuilding - BfLogSysM("Compile missing required types\n"); - mInInvalidState = true; - mOptions.mForceRebuildIdx++; - return true; - } + if (!mHasRequiredTypes) + { + // Force rebuilding + BfLogSysM("Compile missing required types\n"); + mOptions.mForceRebuildIdx++; + } mSystem->CheckLockYield(); mContext->mScratchModule->ResolveTypeDef(mBfObjectTypeDef); - VisitSourceExteriorNodes(); - - //BF_ASSERT(hasRequiredTypes); + VisitSourceExteriorNodes(); if (!mIsResolveOnly) { @@ -6811,19 +6806,14 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) if (mIsResolveOnly) VisitAutocompleteExteriorIdentifiers(); - - if (!hasRequiredTypes) - { - BfLogSysM("Missing required types\n"); - } - + mStats.mTypesQueued = 0; mStats.mMethodsQueued = 0; mStats.mTypesQueued += (int)mContext->mPopulateTypeWorkList.size(); mStats.mMethodsQueued += (int)mContext->mMethodWorkList.size(); - if (hasRequiredTypes) + // { mContext->mScratchModule->ResolveTypeDef(mBfObjectTypeDef, BfPopulateType_Full); @@ -6864,9 +6854,8 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) } } } - - if (hasRequiredTypes) - ProcessPurgatory(true); + + ProcessPurgatory(true); // Mark used modules if ((mOptions.mCompileOnDemandKind != BfCompileOnDemandKind_AlwaysInclude) && (!mCanceling)) @@ -6967,7 +6956,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) } // Generate slot nums - if ((!mIsResolveOnly) && (hasRequiredTypes) && (!mCanceling)) + if ((!mIsResolveOnly) && (!mCanceling)) { if ((!IsHotCompile()) || (mHotState->mHasNewInterfaceTypes)) { @@ -6996,7 +6985,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) } } } - + DoWorkLoop(); BfLogSysM("Compile QueueUnused\n"); @@ -7098,13 +7087,12 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) { DoWorkLoop(); } - - if (hasRequiredTypes) - ProcessPurgatory(false); + + ProcessPurgatory(false); // Old Mark used modules - if ((!mIsResolveOnly) && (hasRequiredTypes)) + if (!mIsResolveOnly) { // if ((!mPassInstance->HasFailed()) && (!mCanceling)) // { @@ -7161,7 +7149,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) String moduleListStr; int numModulesWritten = 0; - if ((hasRequiredTypes) && (!mCanceling)) + if (!mCanceling) { if (!mIsResolveOnly) { @@ -7250,9 +7238,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) //printf("Compile done, waiting for finish\n"); while (true) - { - if (!hasRequiredTypes) - break; + { if (mCanceling) mCodeGen.Cancel(); bool isDone = mCodeGen.Finish(); @@ -7391,8 +7377,8 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) // gBEMemReporter.Report(); // int memReporterSize = gBEMemReporterSize; - mLastRevisionAborted = mCanceling || !hasRequiredTypes; - bool didCancel = mCanceling && hasRequiredTypes; + mLastRevisionAborted = mCanceling; + bool didCancel = mCanceling; mCanceling = false; mContext->ValidateDependencies(); diff --git a/IDEHelper/Compiler/BfCompiler.h b/IDEHelper/Compiler/BfCompiler.h index 24aba505..65c8eb83 100644 --- a/IDEHelper/Compiler/BfCompiler.h +++ b/IDEHelper/Compiler/BfCompiler.h @@ -323,6 +323,7 @@ public: BfCodeGen mCodeGen; String mOutputDirectory; bool mCanceling; + bool mHasRequiredTypes; bool mNeedsFullRefresh; bool mFastFinish; bool mHasQueuedTypeRebuilds; // Infers we had a fast finish that requires a type rebuild diff --git a/IDEHelper/Compiler/BfConstResolver.cpp b/IDEHelper/Compiler/BfConstResolver.cpp index 0c76c570..727bbdda 100644 --- a/IDEHelper/Compiler/BfConstResolver.cpp +++ b/IDEHelper/Compiler/BfConstResolver.cpp @@ -416,15 +416,22 @@ bool BfConstResolver::PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatch } else { - if ((argValue.mValue.IsFake()) && (!argValue.mType->IsValuelessType())) - { - if ((mModule->mCurMethodInstance == NULL) || (mModule->mCurMethodInstance->mMethodDef->mMethodType != BfMethodType_Mixin)) - { - mModule->Fail("Expression does not evaluate to a constant value", argExpr); - } + bool requiresConst = false; + if ((mModule->mCurMethodInstance == NULL) || (mModule->mCurMethodInstance->mMethodDef->mMethodType != BfMethodType_Mixin)) + requiresConst = true; + + if ((requiresConst) && (argValue.mValue.IsFake()) && (!argValue.mType->IsValuelessType())) + { + mModule->Fail("Expression does not evaluate to a constant value", argExpr); } - llvmArgs.push_back(argValue.mValue); + if (!argValue.mType->IsVar()) + { + if ((!requiresConst) || (argValue.mValue.IsConst()) || (argValue.mType->IsValuelessType())) + llvmArgs.push_back(argValue.mValue); + else + llvmArgs.push_back(mModule->GetDefaultValue(argValue.mType)); + } paramIdx++; } argIdx++; diff --git a/IDEHelper/Compiler/BfConstResolver.h b/IDEHelper/Compiler/BfConstResolver.h index 19a6b0bf..53f0dafd 100644 --- a/IDEHelper/Compiler/BfConstResolver.h +++ b/IDEHelper/Compiler/BfConstResolver.h @@ -33,7 +33,7 @@ public: BfConstResolver(BfModule* bfModule); BfTypedValue Resolve(BfExpression* expr, BfType* wantType = NULL, BfConstResolveFlags flags = BfConstResolveFlag_None); - bool PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatcher* methodMatcher, Array& llvmArgs); + bool PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatcher* methodMatcher, Array& llvmArgs); }; NS_BF_END \ No newline at end of file diff --git a/IDEHelper/Compiler/BfContext.cpp b/IDEHelper/Compiler/BfContext.cpp index d4b81a39..b5b32149 100644 --- a/IDEHelper/Compiler/BfContext.cpp +++ b/IDEHelper/Compiler/BfContext.cpp @@ -2917,10 +2917,21 @@ void BfContext::Cleanup() // Clean up deleted BfTypes // These need to get deleted before the modules because we access mModule in the MethodInstance dtors - for (auto type : mTypeGraveyard) + for (int pass = 0; pass < 2; pass++) { - BF_ASSERT(type->mRebuildFlags & BfTypeRebuildFlag_Deleted); - delete type; + for (int i = 0; i < (int)mTypeGraveyard.size(); i++) + { + auto type = mTypeGraveyard[i]; + if (type == NULL) + continue; + bool deleteNow = (type->IsBoxed() == (pass == 0)); + if (!deleteNow) + continue; + + BF_ASSERT(type->mRebuildFlags & BfTypeRebuildFlag_Deleted); + delete type; + mTypeGraveyard[i] = NULL; + } } mTypeGraveyard.Clear(); diff --git a/IDEHelper/Compiler/BfDefBuilder.cpp b/IDEHelper/Compiler/BfDefBuilder.cpp index 828f271a..efa70672 100644 --- a/IDEHelper/Compiler/BfDefBuilder.cpp +++ b/IDEHelper/Compiler/BfDefBuilder.cpp @@ -1775,24 +1775,21 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration) bool doInsertNew = true; if (prevRevisionTypeDef != NULL) { - mCurTypeDef->mIsNextRevision = true; + mCurTypeDef->mIsNextRevision = true; bfParser->mTypeDefs.Add(prevRevisionTypeDef); if (prevRevisionTypeDef->mDefState == BfTypeDef::DefState_AwaitingNewVersion) { - delete prevRevisionTypeDef->mNextRevision; + if (prevRevisionTypeDef->mNextRevision != NULL) + { + BfLogSysM("Deleting unused nextRevision %p from prevRevision %p\n", prevRevisionTypeDef->mNextRevision, prevRevisionTypeDef); + delete prevRevisionTypeDef->mNextRevision; + } prevRevisionTypeDef->mNextRevision = mCurTypeDef; BF_ASSERT(mCurTypeDef->mSystem != NULL); mCurActualTypeDef = prevRevisionTypeDef; doInsertNew = false; - } - else - { - if (prevRevisionTypeDef->mNextRevision != NULL) - prevRevisionTypeDef = prevRevisionTypeDef->mNextRevision; - - prevRevisionTypeDef = NULL; - } + } } else { @@ -1820,8 +1817,8 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration) outerTypeDef->mNestedTypes.push_back(mCurActualTypeDef); } - BfLogSysM("Creating TypeDef %p Hash:%d from TypeDecl: %p Source: %p ResolvePass: %d AutoComplete:%d\n", mCurTypeDef, mSystem->mTypeDefs.GetHash(mCurTypeDef), typeDeclaration, - typeDeclaration->GetSourceData(), mResolvePassData != NULL, isAutoCompleteTempType); + BfLogSysM("Creating TypeDef %p Hash:%d from TypeDecl: %p Source: %p ResolvePass: %d AutoComplete:%d PrevRevision:%d\n", mCurTypeDef, mSystem->mTypeDefs.GetHash(mCurTypeDef), typeDeclaration, + typeDeclaration->GetSourceData(), mResolvePassData != NULL, isAutoCompleteTempType, prevRevisionTypeDef); BF_ASSERT(mCurTypeDef->mNameEx == NULL); @@ -1875,9 +1872,9 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration) if (mCurTypeDef->mFullHash == prevRevisionTypeDef->mFullHash) { - if (!mFullRefresh) + if ((!mFullRefresh) && (!prevRevisionTypeDef->mForceUseNextRevision)) { - BfLogSys(bfParser->mSystem, "DefBuilder deleting typeDef with no changes %p\n", prevRevisionTypeDef); + BfLogSys(bfParser->mSystem, "DefBuilder deleting typeDef with no changes %p prevRevision: %p\n", mCurTypeDef, prevRevisionTypeDef); prevRevisionTypeDef->mDefState = BfTypeDef::DefState_Defined; BF_ASSERT(prevRevisionTypeDef->mNextRevision == mCurTypeDef); prevRevisionTypeDef->mNextRevision = NULL; @@ -1962,7 +1959,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString) auto ctorDeclaration = (BfConstructorDeclaration*)method->mMethodDeclaration; if (method->mHasAppend) - { + { mCurTypeDef->mHasAppendCtor = true; auto methodDef = new BfMethodDef(); diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 9fdf6c83..091e3a7c 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -10786,6 +10786,9 @@ void BfModule::ValidateCustomAttributes(BfCustomAttributes* customAttributes, Bf void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeDirective* attributesDirective, BfAttributeTargets attrTarget, bool allowNonConstArgs, BfCaptureInfo* captureInfo) { + if (!mCompiler->mHasRequiredTypes) + return; + if ((attributesDirective != NULL) && (mCompiler->mResolvePassData != NULL) && (attributesDirective->IsFromParser(mCompiler->mResolvePassData->mParser)) && (mCompiler->mResolvePassData->mSourceClassifier != NULL)) { @@ -11076,8 +11079,10 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri if (assignExpr->mRight != NULL) { BfTypedValue result = constResolver.Resolve(assignExpr->mRight, propType); - if (result) + if ((result) && (!result.mType->IsVar())) { + if (!result.mValue.IsConst()) + result = GetDefaultTypedValue(result.mType); BF_ASSERT(result.mType == propType); CurrentAddToConstHolder(result.mValue); setProperty.mParam = result; @@ -19437,7 +19442,11 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup) } auto bodyBlock = BfNodeDynCast(methodDef->mBody); - if (methodDef->mBody == NULL) + if (!mCompiler->mHasRequiredTypes) + { + // Skip processing to avoid errors + } + else if (methodDef->mBody == NULL) { if (methodDeclaration != NULL) { @@ -22037,7 +22046,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool resolvedParamType = CreateArrayType(mContext->mBfObjectType, 1); } - if (addParams) + if ((addParams) && (resolvedParamType != NULL)) { BfMethodParam methodParam; methodParam.mResolvedType = resolvedParamType; diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index fba3451e..7499da7d 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -5979,11 +5979,14 @@ BfArrayType* BfModule::CreateArrayType(BfType* resolvedType, int dimensions) BF_ASSERT(!resolvedType->IsVar()); BF_ASSERT(!resolvedType->IsIntUnknown()); + auto arrayTypeDef = mCompiler->GetArrayTypeDef(dimensions); + if (arrayTypeDef == NULL) + return NULL; auto arrayType = mContext->mArrayTypePool.Get(); delete arrayType->mGenericTypeInfo; arrayType->mGenericTypeInfo = new BfGenericTypeInfo(); arrayType->mContext = mContext; - arrayType->mTypeDef = mCompiler->GetArrayTypeDef(dimensions); + arrayType->mTypeDef = arrayTypeDef; arrayType->mDimensions = dimensions; arrayType->mGenericTypeInfo->mTypeGenericArguments.clear(); arrayType->mGenericTypeInfo->mTypeGenericArguments.push_back(resolvedType); @@ -9745,12 +9748,13 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } auto elementType = ResolveTypeRef(arrayTypeRef->mElementType, BfPopulateType_Declaration, BfResolveTypeRefFlag_AllowGenericParamConstValue); - if (elementType == NULL) + auto arrayTypeDef = mCompiler->GetArrayTypeDef(arrayTypeRef->mDimensions); + if ((elementType == NULL) || (arrayTypeDef == NULL)) { mContext->mResolvedTypes.RemoveEntry(resolvedEntry); return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags); } - + if ((arrayTypeRef->mDimensions == 1) && (arrayTypeRef->mParams.size() == 1)) { intptr elementCount = -1; @@ -9818,7 +9822,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula arrayType->mGenericTypeInfo = new BfGenericTypeInfo(); arrayType->mContext = mContext; arrayType->mDimensions = arrayTypeRef->mDimensions; - arrayType->mTypeDef = mCompiler->GetArrayTypeDef(arrayType->mDimensions); + arrayType->mTypeDef = arrayTypeDef; arrayType->mGenericTypeInfo->mTypeGenericArguments.push_back(elementType); resolvedEntry->mValue = arrayType; diff --git a/IDEHelper/Compiler/BfSystem.cpp b/IDEHelper/Compiler/BfSystem.cpp index 098a58be..247cfb4a 100644 --- a/IDEHelper/Compiler/BfSystem.cpp +++ b/IDEHelper/Compiler/BfSystem.cpp @@ -1810,7 +1810,7 @@ BfSystem::BfSystem() if (gPerfManager == NULL) gPerfManager = new PerfManager(); //gPerfManager->StartRecording(); - + mAtomUpdateIdx = 0; mAtomCreateIdx = 0; mTypeMapVersion = 1; @@ -2586,6 +2586,13 @@ void BfSystem::RemoveTypeDef(BfTypeDef* typeDef) mTypeDefs.Remove(typeDef); AutoCrit autoCrit(mDataLock); + if (typeDef->mOuterType != NULL) + { + // We are in the outer type's mNestedTypes list + BfLogSys(this, "Setting mForceUseNextRevision on outer type %p from %p\n", typeDef->mOuterType, typeDef); + typeDef->mOuterType->mForceUseNextRevision = true; + } + // This will get properly handled in UntrackName when we process the mTypeDefDeleteQueue, but this // mAtomUpdateIdx increment will trigger lookup changes in BfContext::VerifyTypeLookups if (typeDef->mName != mEmptyAtom) @@ -2797,6 +2804,7 @@ void BfSystem::InjectNewRevision(BfTypeDef* typeDef) typeDef->mNextRevision = NULL; typeDef->mDefState = BfTypeDef::DefState_Defined; + typeDef->mForceUseNextRevision = false; VerifyTypeDef(typeDef); } diff --git a/IDEHelper/Compiler/BfSystem.h b/IDEHelper/Compiler/BfSystem.h index dc7876c4..cec7a07d 100644 --- a/IDEHelper/Compiler/BfSystem.h +++ b/IDEHelper/Compiler/BfSystem.h @@ -1006,6 +1006,7 @@ public: bool mIsNextRevision; bool mInDeleteQueue; bool mHasEmitMembers; + bool mForceUseNextRevision; public: BfTypeDef() @@ -1048,6 +1049,7 @@ public: mIsNextRevision = false; mInDeleteQueue = false; mHasEmitMembers = false; + mForceUseNextRevision = false; mDupDetectedRevision = -1; mNestDepth = 0; mOuterType = NULL; @@ -1500,7 +1502,7 @@ public: Array mMergedTypeOptions; int mUpdateCnt; bool mWorkspaceConfigChanged; - Val128 mWorkspaceConfigHash; + Val128 mWorkspaceConfigHash; Array mCompilers; diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index e39ece14..efaaad68 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -6255,6 +6255,9 @@ CeMachine::~CeMachine() auto _RemoveFunctionInfo = [&](CeFunctionInfo* functionInfo) { + if (functionInfo->mMethodInstance != NULL) + functionInfo->mMethodInstance->mInCEMachine = false; + if (functionInfo->mCeFunction != NULL) { // We don't need to actually unmap it at this point @@ -6932,10 +6935,9 @@ CeFunction* CeMachine::GetFunction(BfMethodInstance* methodInstance, BfIRValue f ceFunction->mCeMachine = this; ceFunction->mIsVarReturn = methodInstance->mReturnType->IsVar(); ceFunction->mCeFunctionInfo = ceFunctionInfo; - ceFunction->mMethodInstance = methodInstance; - + ceFunction->mMethodInstance = methodInstance; ceFunctionInfo->mMethodInstance = methodInstance; - ceFunctionInfo->mCeFunction = ceFunction; + ceFunctionInfo->mCeFunction = ceFunction; MapFunctionId(ceFunction); } From 9268e3b25df1ff09d82766c7da5b17be1eb3f70c Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Sun, 7 Feb 2021 16:17:24 -0800 Subject: [PATCH 11/71] Fixed dtor lookup --- IDEHelper/Compiler/BfContext.cpp | 8 +---- IDEHelper/Compiler/BfModule.cpp | 16 ++------- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 6 ++-- IDEHelper/Compiler/BfStmtEvaluator.cpp | 10 +----- IDEHelper/Compiler/BfSystem.cpp | 24 ++++++++++--- IDEHelper/Tests/src/Extensions.bf | 46 ++++++++++++++++++++++++ 6 files changed, 73 insertions(+), 37 deletions(-) diff --git a/IDEHelper/Compiler/BfContext.cpp b/IDEHelper/Compiler/BfContext.cpp index b5b32149..84a13720 100644 --- a/IDEHelper/Compiler/BfContext.cpp +++ b/IDEHelper/Compiler/BfContext.cpp @@ -829,8 +829,7 @@ void BfContext::ValidateDependencies() void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuildModule, bool placeSpecializiedInPurgatory) { BfTypeInstance* typeInst = type->ToTypeInstance(); - - + if (type->IsDeleting()) { return; @@ -2517,11 +2516,6 @@ void BfContext::QueueMethodSpecializations(BfTypeInstance* typeInst, bool checkS BP_ZONE("BfContext::QueueMethodSpecializations"); - if (typeInst->mTypeId == 578) - { - NOP; - } - auto module = typeInst->mModule; if (module == NULL) return; diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 091e3a7c..770a8908 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -1916,13 +1916,7 @@ void BfModule::AddStackAlloc(BfTypedValue val, BfIRValue arraySize, BfAstNode* r bool hadDtorCall = false; while (checkBaseType != NULL) { - checkBaseType->mTypeDef->PopulateMemberSets(); - BfMemberSetEntry* entry = NULL; - BfMethodDef* dtorMethodDef = NULL; - checkBaseType->mTypeDef->mMethodSet.TryGetWith(String("~this"), &entry); - if (entry != NULL) - dtorMethodDef = (BfMethodDef*)entry->mMemberDef; - + BfMethodDef* dtorMethodDef = checkBaseType->mTypeDef->GetMethodByName("~this"); if (dtorMethodDef != NULL) { auto dtorMethodInstance = GetMethodInstance(checkBaseType, dtorMethodDef, BfTypeVector()); @@ -15740,13 +15734,7 @@ void BfModule::EmitDtorBody() UpdateSrcPos(typeDef->mTypeDeclaration->mNameNode); } - checkBaseType->mTypeDef->PopulateMemberSets(); - BfMemberSetEntry* entry = NULL; - BfMethodDef* dtorMethodDef = NULL; - checkBaseType->mTypeDef->mMethodSet.TryGetWith(String("~this"), &entry); - if (entry != NULL) - dtorMethodDef = (BfMethodDef*)entry->mMemberDef; - + BfMethodDef* dtorMethodDef = checkBaseType->mTypeDef->GetMethodByName("~this"); if (dtorMethodDef != NULL) { auto dtorMethodInstance = GetMethodInstance(checkBaseType, dtorMethodDef, BfTypeVector()); diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 7499da7d..c4b1a44e 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -2599,8 +2599,10 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy SetAndRestoreValue prevTypeInstance(mCurTypeInstance, typeInstance); SetAndRestoreValue prevMethodInstance(mCurMethodInstance, NULL); SetAndRestoreValue prevMethodState(mCurMethodState, NULL); - SetAndRestoreValue prevHadError(mHadBuildError, false); - SetAndRestoreValue prevHadWarning(mHadBuildWarning, false); + + // WHY were we clearing these values? + //SetAndRestoreValue prevHadError(mHadBuildError, false); + //SetAndRestoreValue prevHadWarning(mHadBuildWarning, false); BfTypeState typeState(mCurTypeInstance, mContext->mCurTypeState); typeState.mPopulateType = populateType; diff --git a/IDEHelper/Compiler/BfStmtEvaluator.cpp b/IDEHelper/Compiler/BfStmtEvaluator.cpp index 46e94efd..556d9105 100644 --- a/IDEHelper/Compiler/BfStmtEvaluator.cpp +++ b/IDEHelper/Compiler/BfStmtEvaluator.cpp @@ -3934,15 +3934,7 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt) bool allowProtected = allowPrivate || TypeIsSubTypeOf(mCurTypeInstance, checkTypeInst); while (checkTypeInst != NULL) { - auto checkTypeDef = checkTypeInst->mTypeDef; - - checkTypeDef->PopulateMemberSets(); - BfMemberSetEntry* entry = NULL; - BfMethodDef* dtorMethodDef = NULL; - checkTypeDef->mMethodSet.TryGetWith(String("~this"), &entry); - if (entry != NULL) - dtorMethodDef = (BfMethodDef*)entry->mMemberDef; - + auto dtorMethodDef = checkTypeInst->mTypeDef->GetMethodByName("~this"); if (dtorMethodDef) { if (!CheckProtection(dtorMethodDef->mProtection, checkTypeInst->mTypeDef, allowProtected, allowPrivate)) diff --git a/IDEHelper/Compiler/BfSystem.cpp b/IDEHelper/Compiler/BfSystem.cpp index 247cfb4a..9dfdcc7f 100644 --- a/IDEHelper/Compiler/BfSystem.cpp +++ b/IDEHelper/Compiler/BfSystem.cpp @@ -833,12 +833,26 @@ int BfTypeDef::GetSelfGenericParamCount() BfMethodDef* BfTypeDef::GetMethodByName(const StringImpl& name, int paramCount) { - for (auto method : mMethods) - { - if ((name == method->mName) && ((paramCount == -1) || (paramCount == (int)method->mParams.size()))) - return method; + PopulateMemberSets(); + BfMemberSetEntry* entry = NULL; + if (!mMethodSet.TryGetWith(name, &entry)) + return NULL; + + BfMethodDef* bestMethodDef = NULL; + auto methodDef = (BfMethodDef*)entry->mMemberDef; + while (methodDef != NULL) + { + if ((name == methodDef->mName) && ((paramCount == -1) || (paramCount == (int)methodDef->mParams.size()))) + { + if ((bestMethodDef == NULL) || + ((bestMethodDef->mDeclaringType->IsExtension()) && (!methodDef->mDeclaringType->IsExtension()))) + bestMethodDef = methodDef; + } + + methodDef = methodDef->mNextWithSameName; } - return NULL; + + return bestMethodDef; } BfFieldDef* BfTypeDef::GetFieldByName(const StringImpl& name) diff --git a/IDEHelper/Tests/src/Extensions.bf b/IDEHelper/Tests/src/Extensions.bf index f4e343db..63e5a5d0 100644 --- a/IDEHelper/Tests/src/Extensions.bf +++ b/IDEHelper/Tests/src/Extensions.bf @@ -160,6 +160,32 @@ namespace Tests return 1; } } + + class ClassF + { + public static int sVal = 3; + + public int mF0 = 1 ~ + { + sVal += 40; + }; + } + + extension ClassF + { + public int mF1 = 2 ~ + { + sVal += 500; + }; + } + + class ClassG : ClassF + { + public int mG0 = 3 ~ + { + sVal += 6000; + }; + } extension TClassA where T : IGetExVal { @@ -226,6 +252,26 @@ namespace Tests ClassE ce = scope .(); Test.Assert(ce.mD == 1); Test.Assert(ce.mE == 1); + + /// + { + ClassF cf = scope .(); + } + Test.Assert(ClassF.sVal == 543); + /// + { + ClassF.sVal = 3; + ClassG cg = scope .(); + } + Test.Assert(ClassF.sVal == 6543); + ClassF.sVal = 3; + Object obj = new ClassF(); + delete obj; + Test.Assert(ClassF.sVal == 543); + ClassF.sVal = 3; + obj = new ClassG(); + delete obj; + Test.Assert(ClassF.sVal == 6543); } [Test] From 5077876ef7ce03fc01f2556d3eba7894d4706022 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Sun, 7 Feb 2021 16:17:47 -0800 Subject: [PATCH 12/71] Better failure for invalid method instance --- IDEHelper/Compiler/CeMachine.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index efaaad68..5ee68f7b 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -4335,7 +4335,7 @@ static void CeSetAddrVal(void* ptr, addr_ce val, int32 ptrSize) } bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr, BfType*& returnType) -{ +{ auto ceModule = mCeMachine->mCeModule; CeFunction* ceFunction = startFunction; returnType = startFunction->mMethodInstance->mReturnType; @@ -5408,6 +5408,15 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* mCeMachine->PrepareFunction(callEntry.mFunction, NULL); } + if (callEntry.mFunction->mMethodInstance != NULL) + { + if (callEntry.mFunction->mMethodInstance->GetOwner()->IsDeleting()) + { + _Fail("Calling method on deleted type"); + return false; + } + } + callEntry.mBindRevision = mCeMachine->mMethodBindRevision; } From 3da1881c9ba5efb28da339a7c47f06106a292b00 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Sun, 7 Feb 2021 16:18:19 -0800 Subject: [PATCH 13/71] Preserve equal-hash order during rehash --- BeefySysLib/util/MultiHashSet.h | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/BeefySysLib/util/MultiHashSet.h b/BeefySysLib/util/MultiHashSet.h index 6e9548a9..5ff9efc7 100644 --- a/BeefySysLib/util/MultiHashSet.h +++ b/BeefySysLib/util/MultiHashSet.h @@ -164,17 +164,30 @@ public: { auto newHashHeads = (Entry**)TFuncs::AllocateZero(sizeof(Entry*) * newHashSize, alignof(Entry*)); + SizedArray entryList; + for (int hashIdx = 0; hashIdx < mHashSize; hashIdx++) { Entry* checkEntry = mHashHeads[hashIdx]; - while (checkEntry != NULL) + if (checkEntry != NULL) { - auto nextEntry = checkEntry->mNext; - int newHashIdx = (checkEntry->mHash & 0x7FFFFFFF) % newHashSize; - checkEntry->mNext = newHashHeads[newHashIdx]; - newHashHeads[newHashIdx] = checkEntry; - - checkEntry = nextEntry; + // We want to keep elements with equal hashes in their insert order so we need to + // iterate through the linked list in reverse + entryList.Clear(); + + while (checkEntry != NULL) + { + entryList.Add(checkEntry); + checkEntry = checkEntry->mNext; + } + + for (int i = (int)entryList.mSize - 1; i >= 0; i--) + { + auto checkEntry = entryList[i]; + int newHashIdx = (checkEntry->mHash & 0x7FFFFFFF) % newHashSize; + checkEntry->mNext = newHashHeads[newHashIdx]; + newHashHeads[newHashIdx] = checkEntry; + } } } From 0d57e54033cfdd28bf81deca85248cdd2f803576 Mon Sep 17 00:00:00 2001 From: Joseph Battelle Date: Sun, 7 Feb 2021 21:33:53 -0800 Subject: [PATCH 14/71] Respect 'Permanent' on TabbedViews when dragging tabs out TabbedViews now remain open when a single remaining tab is dragged out of the view when the DockedWidget has 'mAutoClose = false'. This also applies to views of secondary windows which now remain open and empty when permanent. In this case, the full window visual no longer participates in the drag when a single tab is dragged out. --- BeefLibs/Beefy2D/src/widgets/TabbedView.bf | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/BeefLibs/Beefy2D/src/widgets/TabbedView.bf b/BeefLibs/Beefy2D/src/widgets/TabbedView.bf index 823aa76f..59e00f54 100644 --- a/BeefLibs/Beefy2D/src/widgets/TabbedView.bf +++ b/BeefLibs/Beefy2D/src/widgets/TabbedView.bf @@ -200,7 +200,8 @@ namespace Beefy.widgets { return (mTabbedView.mParentDockingFrame.mParentDockingFrame == null) && (mTabbedView.mParentDockingFrame.GetDockedWindowCount() == 1) && - (mTabbedView.GetTabCount() == 1); + (mTabbedView.GetTabCount() == 1) && + mTabbedView.mAutoClose; } void WindowDragLostFocusHandler(BFWindow window, BFWindow newFocus) @@ -288,7 +289,7 @@ namespace Beefy.widgets if ((refWidget != null) && (refWidget.mWidgetWindow != mWidgetWindow) && (mWidgetWindow != null)) mWidgetWindow.SetForeground(); - if (mTabbedView.GetTabCount() == 1) + if ((mTabbedView.GetTabCount() == 1) && mTabbedView.mAutoClose) { mTabbedView.Dock(frame, refWidget, align); return; @@ -327,7 +328,7 @@ namespace Beefy.widgets tabbedView.Dock(frame, refWidget, align); } - if (prevTabbedView.GetTabCount() == 0) + if ((prevTabbedView.GetTabCount() == 0) && prevTabbedView.mAutoClose) { prevTabbedView.mParentDockingFrame.RemoveDockedWidget(prevTabbedView); } From 4592044436b29b1722011d0082d4229745267bb1 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Mon, 8 Feb 2021 05:04:14 -0800 Subject: [PATCH 15/71] Name comparison fix --- IDEHelper/Compiler/BfSystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IDEHelper/Compiler/BfSystem.cpp b/IDEHelper/Compiler/BfSystem.cpp index 9dfdcc7f..1c5fa766 100644 --- a/IDEHelper/Compiler/BfSystem.cpp +++ b/IDEHelper/Compiler/BfSystem.cpp @@ -842,7 +842,7 @@ BfMethodDef* BfTypeDef::GetMethodByName(const StringImpl& name, int paramCount) auto methodDef = (BfMethodDef*)entry->mMemberDef; while (methodDef != NULL) { - if ((name == methodDef->mName) && ((paramCount == -1) || (paramCount == (int)methodDef->mParams.size()))) + if (((paramCount == -1) || (paramCount == (int)methodDef->mParams.size()))) { if ((bestMethodDef == NULL) || ((bestMethodDef->mDeclaringType->IsExtension()) && (!methodDef->mDeclaringType->IsExtension()))) From 90fa8941a6d5c9e5f8c7732ed182e6e30d59ce4b Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Mon, 8 Feb 2021 05:16:44 -0800 Subject: [PATCH 16/71] More libs generated --- IDE/dist/lib/gen/src/Program.bf | 3 ++- IDE/dist/lib/x64/WS2_32.lib | Bin 0 -> 42432 bytes IDE/dist/lib/x64/advapi32.lib | Bin 0 -> 196168 bytes IDE/dist/lib/x64/crypt32.lib | Bin 0 -> 73474 bytes IDE/dist/lib/x64/d3d11.lib | Bin 0 -> 13870 bytes IDE/dist/lib/x64/dinput8.lib | Bin 0 -> 2792 bytes IDE/dist/lib/x64/shlwapi.lib | Bin 0 -> 77242 bytes IDE/dist/lib/x64/winhttp.lib | Bin 0 -> 17904 bytes IDE/dist/lib/x64/wininet.lib | Bin 0 -> 70750 bytes IDE/dist/lib/x64/wsock32.lib | Bin 0 -> 15472 bytes 10 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 IDE/dist/lib/x64/WS2_32.lib create mode 100644 IDE/dist/lib/x64/advapi32.lib create mode 100644 IDE/dist/lib/x64/crypt32.lib create mode 100644 IDE/dist/lib/x64/d3d11.lib create mode 100644 IDE/dist/lib/x64/dinput8.lib create mode 100644 IDE/dist/lib/x64/shlwapi.lib create mode 100644 IDE/dist/lib/x64/winhttp.lib create mode 100644 IDE/dist/lib/x64/wininet.lib create mode 100644 IDE/dist/lib/x64/wsock32.lib diff --git a/IDE/dist/lib/gen/src/Program.bf b/IDE/dist/lib/gen/src/Program.bf index 30a53782..9e94988f 100644 --- a/IDE/dist/lib/gen/src/Program.bf +++ b/IDE/dist/lib/gen/src/Program.bf @@ -12,7 +12,8 @@ namespace gen { class Program { - static String[] sNames = new .[]("comdlg32", "gdi32", "kernel32", "ole32", "netapi32", "ntdll", "rpcrt4", "shell32", "user32", "version", "winmm") ~ delete _; + static String[] sNames = new .[]("advapi32", "comdlg32", "crypt32", "d3d11", "dinput8", "gdi32", "kernel32", "ole32", "netapi32", + "ntdll", "rpcrt4", "shell32", "shlwapi", "user32", "version", "winmm", "winhttp", "wininet", "WS2_32", "wsock32") ~ delete _; public static int Main(String[] args) { diff --git a/IDE/dist/lib/x64/WS2_32.lib b/IDE/dist/lib/x64/WS2_32.lib new file mode 100644 index 0000000000000000000000000000000000000000..af86d862190e0b2c2817576b5ac7be66e17dbd07 GIT binary patch literal 42432 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 literal 0 HcmV?d00001 diff --git a/IDE/dist/lib/x64/advapi32.lib b/IDE/dist/lib/x64/advapi32.lib new file mode 100644 index 0000000000000000000000000000000000000000..058ed1c5ed144a7f0d74192819ca6cda52229631 GIT binary patch literal 196168 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 literal 0 HcmV?d00001 diff --git a/IDE/dist/lib/x64/crypt32.lib b/IDE/dist/lib/x64/crypt32.lib new file mode 100644 index 0000000000000000000000000000000000000000..ee8c57ad89229570c84b314b9c547497746b1ccb GIT binary patch literal 73474 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 Wx6gKrM3QHgeM7C*d5z|X1NXm@`3fHZ literal 0 HcmV?d00001 diff --git a/IDE/dist/lib/x64/d3d11.lib b/IDE/dist/lib/x64/d3d11.lib new file mode 100644 index 0000000000000000000000000000000000000000..d82b5da8bcd06fea888ceff970413fad4d132295 GIT binary patch literal 13870 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 WoRCnH?_;_`^WA)&)zI8d(*FPnS;z$d literal 0 HcmV?d00001 diff --git a/IDE/dist/lib/x64/wininet.lib b/IDE/dist/lib/x64/wininet.lib new file mode 100644 index 0000000000000000000000000000000000000000..28d2f015ce75fbd12e8f90efa6771bf93b6bf59e GIT binary patch literal 70750 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 literal 0 HcmV?d00001 From f999ada369a16aa18bc9f97bf1475568bfccf77d Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Mon, 8 Feb 2021 06:32:47 -0800 Subject: [PATCH 17/71] Fixed ResolveGenericType case from unspecialized type variation --- IDEHelper/Compiler/BfExprEvaluator.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index cae21833..12b44f05 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -14785,7 +14785,15 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc, if (unspecializedMethod == NULL) unspecializedMethod = mModule->GetRawMethodInstance(curTypeInst, methodDef); - BfType* specializedReturnType = mModule->ResolveGenericType(unspecializedMethod->mReturnType, NULL, &methodMatcher.mBestMethodGenericArguments); + BfTypeVector* typeGenericArgs = NULL; + auto typeUnspecMethodInstance = unspecializedMethod; + if (curTypeInst->IsUnspecializedTypeVariation()) + { + typeUnspecMethodInstance = mModule->GetUnspecializedMethodInstance(typeUnspecMethodInstance, true); + typeGenericArgs = &curTypeInst->mGenericTypeInfo->mTypeGenericArguments; + } + + BfType* specializedReturnType = mModule->ResolveGenericType(typeUnspecMethodInstance->mReturnType, typeGenericArgs, &methodMatcher.mBestMethodGenericArguments); if (specializedReturnType != NULL) *overrideReturnType = specializedReturnType; } From cf878097fe293c4801603982d2318a413d320f56 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Mon, 8 Feb 2021 07:01:44 -0800 Subject: [PATCH 18/71] Fixed tuple expression for tuples with valueless field --- IDEHelper/Compiler/BfExprEvaluator.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 12b44f05..614046f5 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -18713,10 +18713,10 @@ void BfExprEvaluator::Visit(BfTupleExpression* tupleExpr) int valueIdx = -1; for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++) { - BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx]; + BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx]; + ++valueIdx; if (fieldInstance->mResolvedType->IsValuelessType()) continue; - ++valueIdx; auto typedVal = typedValues[valueIdx]; if (!typedVal) { From fd001a2f69e5ed363c42fa8c0e637ca4b2c429c8 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Mon, 8 Feb 2021 07:56:23 -0800 Subject: [PATCH 19/71] Fixed erroneous data cycle detection in unions --- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 11 ++++++++--- IDEHelper/Compiler/BfResolvedTypeUtils.cpp | 4 ++-- IDEHelper/Compiler/BfResolvedTypeUtils.h | 2 ++ 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index c4b1a44e..129a15b4 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -2642,8 +2642,8 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy if (typeInstance->mIsFinishingType) { - // This type already failed - return; + if (typeInstance->mTypeFailed) + return; } if (!typeInstance->mTypeFailed) @@ -3736,7 +3736,12 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy if (populateChildType) { - BF_ASSERT(!resolvedFieldType->IsDataIncomplete()); + if (resolvedFieldType->IsFinishingType()) + { + AssertErrorState(); + } + else + BF_ASSERT(!resolvedFieldType->IsDataIncomplete()); } else { diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index 26044546..a3335f72 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -1686,7 +1686,7 @@ BfType* BfTypeInstance::GetUnionInnerType(bool* wantSplat) { SetAndRestoreValue prevTypeRef(mContext->mCurTypeState->mCurFieldDef, fieldDef); - mModule->PopulateType(checkInnerType); + mModule->PopulateType(checkInnerType, checkInnerType->IsValueType() ? BfPopulateType_Data : BfPopulateType_Declaration); if (checkInnerType->mSize > unionSize) unionSize = checkInnerType->mSize; @@ -2196,7 +2196,7 @@ bool BfTypeInstance::WantsGCMarking() return true; if ((IsEnum()) && (!IsPayloadEnum())) return false; - BF_ASSERT(mDefineState >= BfTypeDefineState_Defined); + BF_ASSERT((mDefineState >= BfTypeDefineState_Defined) || (mTypeFailed)); return mWantsGCMarking; } diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.h b/IDEHelper/Compiler/BfResolvedTypeUtils.h index 4e8172bc..097a3ea6 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.h +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.h @@ -501,6 +501,7 @@ public: virtual bool HasBeenReferenced() { return mDefineState != BfTypeDefineState_Undefined; } virtual bool HasTypeFailed() { return false; } virtual bool IsDataIncomplete() { return mDefineState == BfTypeDefineState_Undefined; } + virtual bool IsFinishingType() { return false; } virtual bool IsIncomplete() { return mDefineState < BfTypeDefineState_Defined; } virtual bool IsDeleting() { return ((mRebuildFlags & (BfTypeRebuildFlag_Deleted | BfTypeRebuildFlag_DeleteQueued)) != 0); } virtual bool IsDeclared() { return mDefineState >= BfTypeDefineState_Declared; } @@ -1954,6 +1955,7 @@ public: virtual bool IsReified() override { return mIsReified; } virtual bool NeedsExplicitAlignment() override { return !IsSizeAligned() || mIsPacked; } virtual bool IsDataIncomplete() override { return ((mTypeIncomplete) || (mBaseTypeMayBeIncomplete)) && (!mNeedsMethodProcessing); } + virtual bool IsFinishingType() override { return mIsFinishingType; } virtual bool IsIncomplete() override { return (mTypeIncomplete) || (mBaseTypeMayBeIncomplete); } virtual bool IsSplattable() override { BF_ASSERT((mInstSize >= 0) || (!IsComposite())); return mIsSplattable; } virtual int GetSplatCount() override; From 66adc12f7318eb56e1f9f09b44da54a8db5915ff Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Mon, 8 Feb 2021 08:51:02 -0800 Subject: [PATCH 20/71] Improved dragging list view items --- BeefLibs/Beefy2D/src/theme/dark/DarkListView.bf | 7 +++++++ IDE/src/ui/WatchPanel.bf | 1 + 2 files changed, 8 insertions(+) diff --git a/BeefLibs/Beefy2D/src/theme/dark/DarkListView.bf b/BeefLibs/Beefy2D/src/theme/dark/DarkListView.bf index 7cfd7388..f433f187 100644 --- a/BeefLibs/Beefy2D/src/theme/dark/DarkListView.bf +++ b/BeefLibs/Beefy2D/src/theme/dark/DarkListView.bf @@ -796,6 +796,13 @@ namespace Beefy.theme.dark mDragKind = .None; } + if (Math.Abs(dY) < mSelfHeight * 0.21f) + { + mDragKind = .None; + mDragTarget = null; + return; + } + delete mCurDragEvent; mCurDragEvent = new DragEvent(); mCurDragEvent.mX = x; diff --git a/IDE/src/ui/WatchPanel.bf b/IDE/src/ui/WatchPanel.bf index 60cc666a..4ca1eab3 100644 --- a/IDE/src/ui/WatchPanel.bf +++ b/IDE/src/ui/WatchPanel.bf @@ -1740,6 +1740,7 @@ namespace IDE.ui evt.mDragKind = .After; dragTarget = (WatchListViewItem)dragTarget.mParentItem; evt.mDragTarget = dragTarget; + return; } if ((dragTarget.mLabel == "") && (dragKind == .After)) dragKind = .Before; From 0f014cbec854cda3074de1f012ad95b20090586b Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Mon, 8 Feb 2021 09:56:24 -0800 Subject: [PATCH 21/71] Added !raw immediate window command for string dumps --- IDE/src/Debugger/DebugManager.bf | 3 ++- IDE/src/ui/HoverWatch.bf | 19 ++++++++++++++++- IDE/src/ui/ImmediateWidget.bf | 36 +++++++++++++++++++++++++++++--- IDE/src/ui/WatchPanel.bf | 3 ++- IDEHelper/Debugger.h | 1 + IDEHelper/WinDebugger.cpp | 5 +++++ 6 files changed, 61 insertions(+), 6 deletions(-) diff --git a/IDE/src/Debugger/DebugManager.bf b/IDE/src/Debugger/DebugManager.bf index a3b8a63e..046b01c8 100644 --- a/IDE/src/Debugger/DebugManager.bf +++ b/IDE/src/Debugger/DebugManager.bf @@ -96,7 +96,8 @@ namespace IDE.Debugger MemoryAddress = 0x40, MemoryWatch = 0x80, Symbol = 0x100, - StepIntoCall = 0x200 + StepIntoCall = 0x200, + RawStr = 0x400, } [Reflect] diff --git a/IDE/src/ui/HoverWatch.bf b/IDE/src/ui/HoverWatch.bf index dae9c039..5fae8f47 100644 --- a/IDE/src/ui/HoverWatch.bf +++ b/IDE/src/ui/HoverWatch.bf @@ -718,6 +718,14 @@ namespace IDE.ui var watch = useListViewItem.mWatchEntry; String.NewOrSet!(watch.mName, displayString); String.NewOrSet!(watch.mEvalStr, evalString); + + if (watch.mEvalStr.StartsWith("!raw")) + { + for (int i < 4) + watch.mEvalStr[i] = ' '; + watch.mResultType = .RawText; + } + useListViewItem.mWatchEntry = watch; if (!isLiteral) useListViewItem.Label = displayString; @@ -759,11 +767,13 @@ namespace IDE.ui flags |= .AllowSideEffects | .AllowCalls; if (gApp.mSettings.mDebuggerSettings.mAutoEvaluateProperties) flags |= .AllowProperties; + if (watch.mResultType == .RawText) + flags |= .RawStr; DebugManager.Language language = mLanguage; if (parentWatchEntry != null) language = parentWatchEntry.mLanguage; - gApp.DebugEvaluate(null, evalString, val, -1, language, flags); + gApp.DebugEvaluate(null, watch.mEvalStr, val, -1, language, flags); } if (val == "!pending") { @@ -773,6 +783,13 @@ namespace IDE.ui } watch.mIsPending = false; } + + if (watch.mResultType == .RawText) + { + String.NewOrSet!(valueSubItem.mLabel, val); + return useListViewItem; + } + var vals = scope List(val.Split('\n')); //if (!vals[0].IsEmpty) diff --git a/IDE/src/ui/ImmediateWidget.bf b/IDE/src/ui/ImmediateWidget.bf index 1151fe1f..0c31f89b 100644 --- a/IDE/src/ui/ImmediateWidget.bf +++ b/IDE/src/ui/ImmediateWidget.bf @@ -7,6 +7,7 @@ using Beefy.theme.dark; using Beefy.gfx; using System.Diagnostics; using System.IO; +using IDE.Debugger; namespace IDE.ui { @@ -379,7 +380,11 @@ namespace IDE.ui var subItemLabel = result.GetSubItem(1).mLabel; if (subItemLabel == null) subItemLabel = ""; - mEditWidgetContent.AppendText(scope String(" ", subItemLabel, "\n")); + + if (result.mWatchEntry.mResultType == .RawText) + mEditWidgetContent.AppendText(scope String(subItemLabel, "\n")); + else + mEditWidgetContent.AppendText(scope String(" ", subItemLabel, "\n")); if (result.mWatchEntry.mWarnings != null) { @@ -415,7 +420,11 @@ namespace IDE.ui for (int32 i = startPos; i < mEditWidgetContent.mData.mTextLength; i++) mEditWidgetContent.mData.mText[i].mDisplayTypeId = (uint8)SourceElementType.Error; } - else + else if (result.mWatchEntry.mResultType == .RawText) + { + // No info button + } + else { mInfoButton.Resize(resultX - GS!(3), resultY - GS!(2), GS!(20), GS!(20)); mEditWidgetContent.AddWidget(mInfoButton); @@ -547,7 +556,16 @@ namespace IDE.ui } else { - gApp.DebugEvaluate(null, cmdText, val, mEditWidgetContent.CursorTextPos - mEntryStartPos.mIndex - 2); + DebugManager.EvalExpressionFlags flags = .None; + + if (cmdText.StartsWith("!raw")) + { + for (int i < 4) + cmdText[i] = ' '; + flags |= .RawStr; + } + + gApp.DebugEvaluate(null, cmdText, val, mEditWidgetContent.CursorTextPos - mEntryStartPos.mIndex - 2, .NotSet, flags); gApp.mIsImmediateDebugExprEval = true; } } @@ -570,7 +588,19 @@ namespace IDE.ui } var info = scope String()..Append(val, idx + ":autocomplete\n".Length); if (!editWidgetContent.mAutoComplete.mIsDocumentationPass) + { + if ((cmdText.StartsWith("!")) && (!cmdText.Contains(' '))) + { + if ("!raw".Contains(cmdText)) + info.Append("cmd\traw\n"); + if ("!info".Contains(cmdText)) + info.Append("cmd\tinfo\n"); + if ("!step".Contains(cmdText)) + info.Append("cmd\tstep\n"); + } + editWidgetContent.mAutoComplete.SetInfo(info, true, mEntryStartPos.mIndex + 1); + } } else if (editWidgetContent.mAutoComplete != null) editWidgetContent.mAutoComplete.Close(); diff --git a/IDE/src/ui/WatchPanel.bf b/IDE/src/ui/WatchPanel.bf index 4ca1eab3..497beab4 100644 --- a/IDE/src/ui/WatchPanel.bf +++ b/IDE/src/ui/WatchPanel.bf @@ -27,7 +27,8 @@ namespace IDE.ui TypeClass = 0x80, TypeValueType = 0x100, Namespace = 0x200, - Text = 0x400 + Text = 0x400, + RawText = 0x800 } public class WatchEntry diff --git a/IDEHelper/Debugger.h b/IDEHelper/Debugger.h index 1b0a740e..a9416539 100644 --- a/IDEHelper/Debugger.h +++ b/IDEHelper/Debugger.h @@ -120,6 +120,7 @@ enum DwEvalExpressionFlags : int16 DwEvalExpressionFlag_MemoryWatch = 0x80, DwEvalExpressionFlag_Symbol = 0x100, DwEvalExpressionFlag_StepIntoCalls = 0x200, + DwEvalExpressionFlag_RawStr = 0x400 }; struct DwDisplayInfo diff --git a/IDEHelper/WinDebugger.cpp b/IDEHelper/WinDebugger.cpp index e685cd74..b443c538 100644 --- a/IDEHelper/WinDebugger.cpp +++ b/IDEHelper/WinDebugger.cpp @@ -9504,6 +9504,11 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in expressionFlags = (DwEvalExpressionFlags)(expressionFlags & ~DwEvalExpressionFlag_AllowCalls); } + if ((expressionFlags & DwEvalExpressionFlag_RawStr) != 0) + { + formatInfo.mRawString = true; + } + auto dbgModule = GetCallStackDbgModule(callStackIdx); auto dbgSubprogram = GetCallStackSubprogram(callStackIdx); DbgCompileUnit* dbgCompileUnit = NULL; From aed9fb5d36e1f3d8fb1bd077bd9610612a3859c0 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Mon, 8 Feb 2021 11:48:52 -0800 Subject: [PATCH 22/71] Fixed hex ToString --- IDE/src/ui/MemoryPanel.bf | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/IDE/src/ui/MemoryPanel.bf b/IDE/src/ui/MemoryPanel.bf index 853152cb..a8d36ee7 100644 --- a/IDE/src/ui/MemoryPanel.bf +++ b/IDE/src/ui/MemoryPanel.bf @@ -284,26 +284,20 @@ namespace IDE.ui s.AppendF("0x{:A}", (uint64)lockRange.mBaseOffset); case RepType.Int8: hasAltS = true; - (*(int8*)lockRange.mData.CArray()).ToString(s, (altIntBase == 10) ? "" : "X2", null); - if (altIntBase == 10) - ((UInt64)*(uint8*)lockRange.mData.CArray()).ToString(altS, "", null); + (*(int8*)lockRange.mData.CArray()).ToString(s, (intBase == 10) ? "" : "X2", null); + ((UInt64)*(uint8*)lockRange.mData.CArray()).ToString(altS, (altIntBase == 10) ? "" : "X2", null); case RepType.Int16: hasAltS = true; - (*(int16*)lockRange.mData.CArray()).ToString(s, (altIntBase == 10) ? "" : "X4", null); - if (altIntBase == 10) - ((UInt64)*(uint16*)lockRange.mData.CArray()).ToString(altS, "", null); + (*(int16*)lockRange.mData.CArray()).ToString(s, (intBase == 10) ? "" : "X4", null); + ((UInt64)*(uint16*)lockRange.mData.CArray()).ToString(altS, (altIntBase == 10) ? "" : "X4", null); case RepType.Int32: hasAltS = true; - (*(int32*)lockRange.mData.CArray()).ToString(s, (altIntBase == 10) ? "" : "X8", null); - if (altIntBase == 10) - ((UInt64)*(uint32*)lockRange.mData.CArray()).ToString(altS, "", null); + (*(int32*)lockRange.mData.CArray()).ToString(s, (intBase == 10) ? "" : "X8", null); + ((UInt64)*(uint32*)lockRange.mData.CArray()).ToString(altS, (altIntBase == 10) ? "" : "X8", null); case RepType.Int64: hasAltS = true; - (*(int64*)lockRange.mData.CArray()).ToString(s, (altIntBase == 10) ? "" : "X16", null); - if (altIntBase == 0x10) - s.Insert(8, '\''); - if (altIntBase == 10) - ((UInt64)*(uint64*)lockRange.mData.CArray()).ToString(altS, "", null); + (*(int64*)lockRange.mData.CArray()).ToString(s, (intBase == 10) ? "" : "X16", null); + ((UInt64)*(uint64*)lockRange.mData.CArray()).ToString(altS, (altIntBase == 10) ? "" : "X16", null); case RepType.Float: (*(float*)lockRange.mData.CArray()).ToString(s); case RepType.Double: From b0f69ae37d4b89600c780e0d0b75c867b4ecebf2 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Mon, 8 Feb 2021 12:12:49 -0800 Subject: [PATCH 23/71] Made comment wrapping smarter --- IDEHelper/Compiler/BfPrinter.cpp | 44 ++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/IDEHelper/Compiler/BfPrinter.cpp b/IDEHelper/Compiler/BfPrinter.cpp index 8faa4a8c..c567db5b 100644 --- a/IDEHelper/Compiler/BfPrinter.cpp +++ b/IDEHelper/Compiler/BfPrinter.cpp @@ -374,6 +374,50 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node) { Visit((BfAstNode*)node); startIdx = node->mSrcStart; + + if (doWrap) + { + bool wantWrap = false; + + int spacedWordCount = 0; + bool inQuotes = false; + auto src = astNodeSrc->mSrc; + bool isDefinitelyCode = false; + bool hadNonSlash = false; + + for (int i = node->mSrcStart + 1; i < node->mSrcEnd - 1; i++) + { + char c = src[i]; + if (c != '/') + hadNonSlash = true; + if (inQuotes) + { + if (c == '\\') + { + i++; + } + else if (c == '\"') + { + inQuotes = false; + } + } + else if (c == '"') + { + inQuotes = true; + } + else if (c == ' ') + { + if ((isalpha(src[i - 1])) && (isalpha(src[i + 1]))) + spacedWordCount++; + } + else if ((c == '/') && (src[i - 1] == '/') && (hadNonSlash)) + isDefinitelyCode = true; + } + + // If this doesn't look like a sentence then don't try to word wrap + if ((isDefinitelyCode) || (spacedWordCount < 4)) + doWrap = false; + } } int lineEmittedChars = 0; From bb2fe56dc9c079888cfebc9e5346c7774e51819b Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Mon, 8 Feb 2021 17:46:22 -0800 Subject: [PATCH 24/71] Reordered postbuild commands to occur after all linking --- IDE/src/BuildContext.bf | 49 ++++++++++++++++++++++++----------------- IDE/src/IDEApp.bf | 6 +++++ 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/IDE/src/BuildContext.bf b/IDE/src/BuildContext.bf index 571ccaeb..15c4fe20 100644 --- a/IDE/src/BuildContext.bf +++ b/IDE/src/BuildContext.bf @@ -29,12 +29,8 @@ namespace IDE public int32 mUpdateCnt; public Project mHotProject; public Workspace.Options mWorkspaceOptions; - public Dictionary mImpLibMap = new .() ~ - { - for (let val in _.Values) - delete val; - delete _; - }; + public Dictionary mImpLibMap = new .() ~ DeleteDictionaryAndValues!(_); + public Dictionary mTargetPathMap = new .() ~ DeleteDictionaryAndValues!(_); public ScriptManager.Context mScriptContext = new .() ~ _.ReleaseLastRef(); public ScriptManager mScriptManager ~ delete _; @@ -1218,6 +1214,8 @@ namespace IDE } } + mTargetPathMap[project] = new String(targetPath); + if (hotProject == null) { switch (QueueProjectCustomBuildCommands(project, targetPath, compileKind.WantsRunAfter ? options.mBuildOptions.mBuildCommandsOnRun : options.mBuildOptions.mBuildCommandsOnCompile, options.mBuildOptions.mPreBuildCmds)) @@ -1228,22 +1226,9 @@ namespace IDE completedCompileCmd.mFailed = true; } } - - void DoPostBuild() - { - switch (QueueProjectCustomBuildCommands(project, targetPath, compileKind.WantsRunAfter ? options.mBuildOptions.mBuildCommandsOnRun : options.mBuildOptions.mBuildCommandsOnCompile, options.mBuildOptions.mPostBuildCmds)) - { - case .NoCommands: - case .HadCommands: - case .Failed: - completedCompileCmd.mFailed = true; - } - } if (project.mGeneralOptions.mTargetType == .CustomBuild) { - if (hotProject == null) - DoPostBuild(); return true; } @@ -1404,8 +1389,32 @@ namespace IDE return false; } - DoPostBuild(); return true; } + + public bool QueueProjectPostBuild(Project project, Project hotProject, IDEApp.BuildCompletedCmd completedCompileCmd, List hotFileNames, CompileKind compileKind) + { + if (hotProject != null) + return true; + + Project.Options options = gApp.GetCurProjectOptions(project); + if (options == null) + return true; + + String targetPath = null; + mTargetPathMap.TryGetValue(project, out targetPath); + if (targetPath == null) + return false; + + switch (QueueProjectCustomBuildCommands(project, targetPath, compileKind.WantsRunAfter ? options.mBuildOptions.mBuildCommandsOnRun : options.mBuildOptions.mBuildCommandsOnCompile, options.mBuildOptions.mPostBuildCmds)) + { + case .NoCommands: + case .HadCommands: + case .Failed: + completedCompileCmd.mFailed = true; + } + + return true; + } } } diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf index 0cdaae19..f31ad44c 100644 --- a/IDE/src/IDEApp.bf +++ b/IDE/src/IDEApp.bf @@ -10252,6 +10252,12 @@ namespace IDE success = false; } + for (var project in orderedProjectList) + { + if (!mBuildContext.QueueProjectPostBuild(project, hotProject, completedCompileCmd, hotFileNames, compileKind)) + success = false; + } + if (hotFileNames.Count > 0) { // Why were we rehupping BEFORE hotLoad? From 9d79db063b6b4efa54eebcaac69f21ab3b796b22 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Tue, 9 Feb 2021 10:40:37 -0800 Subject: [PATCH 25/71] Improved string table usage tracking --- IDEHelper/Compiler/BfConstResolver.cpp | 10 ++- IDEHelper/Compiler/BfConstResolver.h | 7 +- IDEHelper/Compiler/BfModule.cpp | 96 +++++++++++++++++------- IDEHelper/Compiler/BfModule.h | 21 +++--- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 13 ++-- IDEHelper/Compiler/BfStmtEvaluator.cpp | 2 +- 6 files changed, 94 insertions(+), 55 deletions(-) diff --git a/IDEHelper/Compiler/BfConstResolver.cpp b/IDEHelper/Compiler/BfConstResolver.cpp index 727bbdda..64e24e7d 100644 --- a/IDEHelper/Compiler/BfConstResolver.cpp +++ b/IDEHelper/Compiler/BfConstResolver.cpp @@ -35,7 +35,7 @@ BfConstResolver::BfConstResolver(BfModule* bfModule) : BfExprEvaluator(bfModule) } BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfConstResolveFlags flags) -{ +{ mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime); // Handle the 'int[?] val = .(1, 2, 3)' case @@ -137,11 +137,11 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo int stringId = mModule->GetStringPoolIdx(mResult.mValue); if (stringId != -1) { - if ((flags & BfConstResolveFlag_RemapFromStringId) != 0) + if ((flags & BfConstResolveFlag_ActualizeValues) != 0) { prevIgnoreWrites.Restore(); mModule->mBfIRBuilder->PopulateType(mResult.mType); - return BfTypedValue(mModule->GetStringObjectValue(stringId), mResult.mType); + return BfTypedValue(mModule->GetStringObjectValue(stringId, false, true), mResult.mType); } return BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_StringId, stringId), toType); @@ -232,7 +232,9 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo }*/ mModule->FixIntUnknown(mResult); - mModule->FixValueActualization(mResult); + + if ((flags & BfConstResolveFlag_NoActualizeValues) == 0) + mModule->FixValueActualization(mResult, !prevIgnoreWrites.mPrevVal || ((flags & BfConstResolveFlag_ActualizeValues) != 0)); return mResult; } diff --git a/IDEHelper/Compiler/BfConstResolver.h b/IDEHelper/Compiler/BfConstResolver.h index 53f0dafd..6d1d02ff 100644 --- a/IDEHelper/Compiler/BfConstResolver.h +++ b/IDEHelper/Compiler/BfConstResolver.h @@ -15,9 +15,10 @@ enum BfConstResolveFlags BfConstResolveFlag_ExplicitCast = 1, BfConstResolveFlag_NoCast = 2, BfConstResolveFlag_AllowSoftFail = 4, - BfConstResolveFlag_RemapFromStringId = 8, - BfConstResolveFlag_ArrayInitSize = 0x10, - BfConstResolveFlag_AllowGlobalVariable = 0x20, + BfConstResolveFlag_ActualizeValues = 8, + BfConstResolveFlag_NoActualizeValues = 0x10, + BfConstResolveFlag_ArrayInitSize = 0x20, + BfConstResolveFlag_AllowGlobalVariable = 0x40, }; class BfConstResolver : public BfExprEvaluator diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 770a8908..bc57a481 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -1654,8 +1654,11 @@ String* BfModule::GetStringPoolString(BfIRValue constantStr, BfIRConstHolder * c return NULL; } -BfIRValue BfModule::GetStringCharPtr(int stringId) +BfIRValue BfModule::GetStringCharPtr(int stringId, bool force) { + if ((mBfIRBuilder->mIgnoreWrites) && (!force)) + return mBfIRBuilder->CreateConst(BfTypeCode_StringId, stringId); + BfIRValue* irValue = NULL; if (!mStringCharPtrPool.TryAdd(stringId, NULL, &irValue)) return *irValue; @@ -1670,13 +1673,13 @@ BfIRValue BfModule::GetStringCharPtr(int stringId) return strCharPtrConst; } -BfIRValue BfModule::GetStringCharPtr(BfIRValue strValue) +BfIRValue BfModule::GetStringCharPtr(BfIRValue strValue, bool force) { if (strValue.IsConst()) { int stringId = GetStringPoolIdx(strValue); BF_ASSERT(stringId != -1); - return GetStringCharPtr(stringId); + return GetStringCharPtr(stringId, force); } BfIRValue charPtrPtr = mBfIRBuilder->CreateInBoundsGEP(strValue, 0, 1); @@ -1684,27 +1687,32 @@ BfIRValue BfModule::GetStringCharPtr(BfIRValue strValue) return charPtr; } -BfIRValue BfModule::GetStringCharPtr(const StringImpl& str) +BfIRValue BfModule::GetStringCharPtr(const StringImpl& str, bool force) { - return GetStringCharPtr(GetStringObjectValue(str)); + return GetStringCharPtr(GetStringObjectValue(str, force), force); } -BfIRValue BfModule::GetStringObjectValue(int strId) +BfIRValue BfModule::GetStringObjectValue(int strId, bool define, bool force) { BfIRValue* objValue; if (mStringObjectPool.TryGetValue(strId, &objValue)) return *objValue; auto stringPoolEntry = mContext->mStringObjectIdMap[strId]; - return GetStringObjectValue(stringPoolEntry.mString, true); + return GetStringObjectValue(stringPoolEntry.mString, define, force); } -BfIRValue BfModule::GetStringObjectValue(const StringImpl& str, bool define) +BfIRValue BfModule::GetStringObjectValue(const StringImpl& str, bool define, bool force) { auto stringType = ResolveTypeDef(mCompiler->mStringTypeDef, define ? BfPopulateType_Data : BfPopulateType_Declaration); mBfIRBuilder->PopulateType(stringType); - int strId = mContext->GetStringLiteralId(str); + int strId = mContext->GetStringLiteralId(str); + + if ((mBfIRBuilder->mIgnoreWrites) && (!force)) + { + return mBfIRBuilder->CreateConst(BfTypeCode_StringId, strId); + } BfIRValue* irValuePtr = NULL; if (!mStringObjectPool.TryAdd(strId, NULL, &irValuePtr)) @@ -5900,8 +5908,8 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin if (needsTypeNames) { - typeNameConst = GetStringObjectValue(typeDef->mName->mString, true); - namespaceConst = GetStringObjectValue(typeDef->mNamespace.ToString(), true); + typeNameConst = GetStringObjectValue(typeDef->mName->mString, !mIsComptimeModule); + namespaceConst = GetStringObjectValue(typeDef->mNamespace.ToString(), !mIsComptimeModule); } else { @@ -6041,7 +6049,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin *orderedIdPtr = (int)usedStringIdMap.size() - 1; } - GetStringObjectValue(stringId); + GetStringObjectValue(stringId, true, true); PUSH_INT8(0xFF); // String PUSH_INT32(*orderedIdPtr); argIdx++; @@ -6061,7 +6069,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin *orderedIdPtr = (int)usedStringIdMap.size() - 1; } - GetStringObjectValue(stringId); + GetStringObjectValue(stringId, true, true); PUSH_INT8(0xFF); // String PUSH_INT32(*orderedIdPtr); argIdx++; @@ -6225,7 +6233,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin BfType* payloadType = typeInstance->GetUnionInnerType(); if (!payloadType->IsValuelessType()) { - BfIRValue payloadNameConst = GetStringObjectValue("$payload", true); + BfIRValue payloadNameConst = GetStringObjectValue("$payload", !mIsComptimeModule); SizedArray payloadFieldVals = { emptyValueType, @@ -6240,7 +6248,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin } BfType* dscrType = typeInstance->GetDiscriminatorType(); - BfIRValue dscrNameConst = GetStringObjectValue("$discriminator", true); + BfIRValue dscrNameConst = GetStringObjectValue("$discriminator", !mIsComptimeModule); SizedArray dscrFieldVals = { emptyValueType, @@ -6262,7 +6270,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin BfFieldInstance* fieldInstance = &typeInstance->mFieldInstances[fieldIdx]; BfFieldDef* fieldDef = fieldInstance->GetFieldDef(); - BfIRValue fieldNameConst = GetStringObjectValue(fieldDef->mName, true); + BfIRValue fieldNameConst = GetStringObjectValue(fieldDef->mName, !mIsComptimeModule); int typeId = 0; auto fieldType = fieldInstance->GetResolvedType(); @@ -6538,7 +6546,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin funcVal = mBfIRBuilder->CreateBitCast(moduleMethodInstance.mFunc, voidPtrIRType); } - BfIRValue methodNameConst = GetStringObjectValue(methodDef->mName, true); + BfIRValue methodNameConst = GetStringObjectValue(methodDef->mName, !mIsComptimeModule); BfMethodFlags methodFlags = defaultMethod->GetMethodFlags(); @@ -6561,7 +6569,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin if (defaultMethod->GetParamIsSplat(paramIdx)) paramFlags = (ParamFlags)(paramFlags | ParamFlag_Splat); - BfIRValue paramNameConst = GetStringObjectValue(paramName, true); + BfIRValue paramNameConst = GetStringObjectValue(paramName, !mIsComptimeModule); SizedArray paramDataVals = { @@ -10621,17 +10629,18 @@ BfTypedValue BfModule::GetTypedValueFromConstant(BfConstant* constant, BfIRConst auto constVal = mBfIRBuilder->CreateConst(constant, constHolder); BfTypedValue typedValue; + bool allowUnactualized = mBfIRBuilder->mIgnoreWrites; if (constant->mTypeCode == BfTypeCode_StringId) { if ((wantType->IsInstanceOf(mCompiler->mStringTypeDef)) || ((wantType->IsPointer()) && (wantType->GetUnderlyingType() == GetPrimitiveType(BfTypeCode_Char8)))) { - typedValue = BfTypedValue(ConstantToCurrent(constant, constHolder, wantType), wantType); + typedValue = BfTypedValue(ConstantToCurrent(constant, constHolder, wantType, allowUnactualized), wantType); return typedValue; } auto stringType = ResolveTypeDef(mCompiler->mStringTypeDef); - typedValue = BfTypedValue(ConstantToCurrent(constant, constHolder, stringType), stringType); + typedValue = BfTypedValue(ConstantToCurrent(constant, constHolder, stringType, allowUnactualized), stringType); } if (!typedValue) @@ -10675,7 +10684,27 @@ BfTypedValue BfModule::GetTypedValueFromConstant(BfConstant* constant, BfIRConst return BfTypedValue(irValue, wantType, false); } -BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType, bool allowStringId) +bool BfModule::HasUnactializedConstant(BfConstant* constant, BfIRConstHolder* constHolder) +{ + if ((constant->mConstType == BfConstType_TypeOf) || (constant->mConstType == BfConstType_TypeOf_WithData)) + return true; + if (constant->mTypeCode == BfTypeCode_StringId) + return true; + + if (constant->mConstType == BfConstType_Agg) + { + auto constArray = (BfConstantAgg*)constant; + for (auto val : constArray->mValues) + { + if (HasUnactializedConstant(constHolder->GetConstant(val), constHolder)) + return true; + } + } + + return false; +} + +BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType, bool allowUnactualized) { if (constant->mTypeCode == BfTypeCode_NullPtr) { @@ -10690,20 +10719,27 @@ BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* con if (constant->mTypeCode == BfTypeCode_StringId) { - if (!allowStringId) + if (!allowUnactualized) { if ((wantType->IsInstanceOf(mCompiler->mStringTypeDef)) || ((wantType->IsPointer()) && (wantType->GetUnderlyingType() == GetPrimitiveType(BfTypeCode_Char8)))) { const StringImpl& str = mContext->mStringObjectIdMap[constant->mInt32].mString; - BfIRValue stringObjConst = GetStringObjectValue(str); + BfIRValue stringObjConst = GetStringObjectValue(str, false, true); if (wantType->IsPointer()) - return GetStringCharPtr(stringObjConst); + return GetStringCharPtr(stringObjConst, true); return stringObjConst; } } } + if (constant->mConstType == Beefy::BfConstType_TypeOf) + { + auto constTypeOf = (BfTypeOf_Const*)constant; + AddDependency(constTypeOf->mType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference); + return CreateTypeDataRef(constTypeOf->mType); + } + if (constant->mConstType == BfConstType_Agg) { auto constArray = (BfConstantAgg*)constant; @@ -11012,8 +11048,8 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri auto& fieldTypeInst = checkTypeInst->mFieldInstances[bestField->mIdx]; if (assignExpr->mRight != NULL) - { - BfTypedValue result = constResolver.Resolve(assignExpr->mRight, fieldTypeInst.mResolvedType); + { + BfTypedValue result = constResolver.Resolve(assignExpr->mRight, fieldTypeInst.mResolvedType, BfConstResolveFlag_NoActualizeValues); if (result) { CurrentAddToConstHolder(result.mValue); @@ -14049,8 +14085,10 @@ void BfModule::DoLocalVariableDebugInfo(BfLocalVariable* localVarDef, bool doAli if (mBfIRBuilder->HasDebugLocation()) { if ((isConstant) && (!didConstToMem)) - { - localVarDef->mDbgDeclareInst = mBfIRBuilder->DbgInsertValueIntrinsic(localVarDef->mConstValue, diVariable); + { + BfTypedValue result(localVarDef->mConstValue, localVarDef->mResolvedType); + FixValueActualization(result); + localVarDef->mDbgDeclareInst = mBfIRBuilder->DbgInsertValueIntrinsic(result.mValue, diVariable); } else { @@ -18139,7 +18177,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup) auto methodDeclaration = methodDef->GetMethodDeclaration(); if ((methodDef->mHasComptime) && (!mIsComptimeModule)) - mBfIRBuilder->mIgnoreWrites = true; + mBfIRBuilder->mIgnoreWrites = true; if ((methodInstance->mIsReified) && (methodInstance->mVirtualTableIdx != -1)) { diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index fedc977d..881944c0 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -1538,12 +1538,12 @@ public: BfIRValue CreateStringCharPtr(const StringImpl& str, int stringId, bool define); int GetStringPoolIdx(BfIRValue constantStr, BfIRConstHolder* constHolder = NULL); String* GetStringPoolString(BfIRValue constantStr, BfIRConstHolder* constHolder = NULL); - BfIRValue GetStringCharPtr(int stringId); - BfIRValue GetStringCharPtr(BfIRValue strValue); - BfIRValue GetStringCharPtr(const StringImpl& str); - BfIRValue GetStringObjectValue(int idx); - BfIRValue GetStringObjectValue(const StringImpl& str, bool define = false); - BfIRValue CreateGlobalConstValue(const StringImpl& name, BfIRValue constant, BfIRType type, bool external); + BfIRValue GetStringCharPtr(int stringId, bool force = false); + BfIRValue GetStringCharPtr(BfIRValue strValue, bool force = false); + BfIRValue GetStringCharPtr(const StringImpl& str, bool force = false); + BfIRValue GetStringObjectValue(int idx, bool define, bool force); + BfIRValue GetStringObjectValue(const StringImpl& str, bool define = false, bool force = false); + BfIRValue CreateGlobalConstValue(const StringImpl& name, BfIRValue constant, BfIRType type, bool external); void VariantToString(StringImpl& str, const BfVariant& variant); StringT<128> TypeToString(BfType* resolvedType, Array* genericMethodParamNameOverrides = NULL); StringT<128> TypeToString(BfType* resolvedType, BfTypeNameFlags typeNameFlags, Array* genericMethodParamNameOverrides = NULL); @@ -1553,8 +1553,9 @@ public: void pm(BfMethodInstance* type); void CurrentAddToConstHolder(BfIRValue& irVal); void ClearConstData(); - BfTypedValue GetTypedValueFromConstant(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType); - BfIRValue ConstantToCurrent(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType, bool allowStringId = false); + bool HasUnactializedConstant(BfConstant* constant, BfIRConstHolder* constHolder); + BfTypedValue GetTypedValueFromConstant(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType); + BfIRValue ConstantToCurrent(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType, bool allowUnactualized = false); void ValidateCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeTargets attrTarget); void GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, bool allowNonConstArgs = false, BfCaptureInfo* captureInfo = NULL); BfCustomAttributes* GetCustomAttributes(BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, bool allowNonConstArgs = false, BfCaptureInfo* captureInfo = NULL); @@ -1771,8 +1772,8 @@ public: BfMethodRefType* CreateMethodRefType(BfMethodInstance* methodInstance, bool mustAlreadyExist = false); BfType* FixIntUnknown(BfType* type); void FixIntUnknown(BfTypedValue& typedVal, BfType* matchType = NULL); - void FixIntUnknown(BfTypedValue& lhs, BfTypedValue& rhs); - void FixValueActualization(BfTypedValue& typedVal); + void FixIntUnknown(BfTypedValue& lhs, BfTypedValue& rhs); + void FixValueActualization(BfTypedValue& typedVal, bool force = false); bool TypeEquals(BfTypedValue& val, BfType* type); BfTypeDef* ResolveGenericInstanceDef(BfGenericInstanceTypeRef* genericTypeRef, BfType** outType = NULL, BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None); BfType* ResolveType(BfType* lookupType, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None); diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 129a15b4..7f3de22b 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -6439,19 +6439,16 @@ void BfModule::FixIntUnknown(BfTypedValue& lhs, BfTypedValue& rhs) FixIntUnknown(rhs); } -void BfModule::FixValueActualization(BfTypedValue& typedVal) +void BfModule::FixValueActualization(BfTypedValue& typedVal, bool force) { if (!typedVal.mValue.IsConst()) return; - if (mBfIRBuilder->mIgnoreWrites) + if ((mBfIRBuilder->mIgnoreWrites) && (!force)) return; auto constant = mBfIRBuilder->GetConstant(typedVal.mValue); - if (constant->mConstType == BfConstType_TypeOf) - { - auto constTypeOf = (BfTypeOf_Const*)constant; - AddDependency(constTypeOf->mType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference); - typedVal.mValue = CreateTypeDataRef(constTypeOf->mType); - } + if (!HasUnactializedConstant(constant, mBfIRBuilder)) + return; + typedVal.mValue = ConstantToCurrent(constant, mBfIRBuilder, typedVal.mType, false); } BfTypeInstance* BfModule::GetPrimitiveStructType(BfTypeCode typeCode) diff --git a/IDEHelper/Compiler/BfStmtEvaluator.cpp b/IDEHelper/Compiler/BfStmtEvaluator.cpp index 556d9105..e04eaeeb 100644 --- a/IDEHelper/Compiler/BfStmtEvaluator.cpp +++ b/IDEHelper/Compiler/BfStmtEvaluator.cpp @@ -1654,7 +1654,7 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD if (isConst) { BfConstResolver constResolver(this); - initValue = constResolver.Resolve(varDecl->mInitializer, resolvedType, BfConstResolveFlag_RemapFromStringId); + initValue = constResolver.Resolve(varDecl->mInitializer, resolvedType, BfConstResolveFlag_ActualizeValues); if (!initValue) initValue = GetDefaultTypedValue(resolvedType); } From 7ff8a25307510c9fabbb662a820fdde63892b4d1 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Tue, 9 Feb 2021 11:37:45 -0800 Subject: [PATCH 26/71] Fixed attribute ctor idx. Order reflected methods by name --- IDEHelper/Compiler/BfModule.cpp | 78 ++++++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 10 deletions(-) diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index bc57a481..fac79d2b 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -6025,7 +6025,28 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin PUSH_INT16(0); // mSize PUSH_INT32(attr->mType->mTypeId); // mType - PUSH_INT16(attr->mCtor->mIdx); + + int ctorIdx = -1; + int ctorCount = 0; + + attr->mType->mTypeDef->PopulateMemberSets(); + BfMemberSetEntry* entry; + if (attr->mType->mTypeDef->mMethodSet.TryGetWith(String("__BfCtor"), &entry)) + { + BfMethodDef* nextMethodDef = (BfMethodDef*)entry->mMemberDef; + while (nextMethodDef != NULL) + { + if (nextMethodDef == attr->mCtor) + ctorIdx = ctorCount; + nextMethodDef = nextMethodDef->mNextWithSameName; + ctorCount++; + } + } + + BF_ASSERT(ctorIdx != -1); + if (ctorIdx != -1) + ctorIdx = (ctorCount - 1) - ctorIdx; + PUSH_INT16(ctorIdx); auto ctorMethodInstance = GetRawMethodInstanceAtIdx(attr->mType, attr->mCtor->mIdx); int argIdx = 0; @@ -6450,6 +6471,14 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin BfType* reflectParamDataType = ResolveTypeDef(mCompiler->mReflectParamDataDef); BfType* reflectParamDataPtrType = CreatePointerType(reflectParamDataType); + struct _SortedMethodInfo + { + BfMethodDef* mMethodDef; + BfCustomAttributes* mMethodCustomAttributes; + }; + + Array<_SortedMethodInfo> sortedMethodList; + SizedArray methodTypes; for (int methodIdx = 0; methodIdx < (int)typeDef->mMethods.size(); methodIdx++) { @@ -6462,7 +6491,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin auto methodInstanceGroup = &typeInstance->mMethodInstanceGroups[methodIdx]; if (!methodInstanceGroup->IsImplemented()) - continue; + continue; auto methodDef = typeDef->mMethods[methodIdx]; if (methodDef->mIsNoReflect) continue; @@ -6476,12 +6505,12 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin continue; if (!defaultMethod->mIsReified) continue; - + if ((defaultMethod->mChainType == BfMethodChainType_ChainMember) || (defaultMethod->mChainType == BfMethodChainType_ChainSkip)) continue; if (defaultMethod->mMethodDef->mMethodType == BfMethodType_CtorNoBody) - continue; - + continue; + auto methodReflectKind = (BfReflectKind)(reflectKind & ~BfReflectKind_User); bool includeMethod = reflectIncludeAllMethods; @@ -6503,10 +6532,10 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin } } } - + if ((!mIsComptimeModule) && (!typeInstance->IsTypeMemberAccessible(methodDef->mDeclaringType, mProject))) continue; - + // { SetAndRestoreValue prevTypeInstance(mCurTypeInstance, typeInstance); @@ -6524,13 +6553,42 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin includeMethod = true; if ((methodDef->mIsStatic) && ((methodReflectKind & BfReflectKind_StaticMethods) != 0)) includeMethod = true; - + if ((!includeMethod) && (typeOptions != NULL)) includeMethod = ApplyTypeOptionMethodFilters(includeMethod, methodDef, typeOptions); - + if (!includeMethod) continue; + sortedMethodList.Add({ methodDef, methodCustomAttributes }); + } + + auto _GetMethodKind = [](BfMethodDef* methodDef) + { + if (methodDef->mMethodType == BfMethodType_Ctor) + return 0; + return 1; + }; + + std::sort(sortedMethodList.begin(), sortedMethodList.end(), [_GetMethodKind](const _SortedMethodInfo& lhs, const _SortedMethodInfo& rhs) + { + int lhsKind = _GetMethodKind(lhs.mMethodDef); + int rhsKind = _GetMethodKind(rhs.mMethodDef); + + if (lhsKind != rhsKind) + return lhsKind < rhsKind; + if (lhs.mMethodDef->mName != rhs.mMethodDef->mName) + return lhs.mMethodDef->mName < rhs.mMethodDef->mName; + return lhs.mMethodDef->mIdx < rhs.mMethodDef->mIdx; + }); + + for (auto& methodInfo : sortedMethodList) + { + auto methodDef = methodInfo.mMethodDef; + int methodIdx = methodDef->mIdx; + auto methodInstanceGroup = &typeInstance->mMethodInstanceGroups[methodIdx]; + auto defaultMethod = methodInstanceGroup->mDefault; + BfModuleMethodInstance moduleMethodInstance; BfIRValue funcVal = voidPtrNull; @@ -6550,7 +6608,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin BfMethodFlags methodFlags = defaultMethod->GetMethodFlags(); - int customAttrIdx = _HandleCustomAttrs(methodCustomAttributes); + int customAttrIdx = _HandleCustomAttrs(methodInfo.mMethodCustomAttributes); enum ParamFlags { From e3803ed00766453dfaca7253e69a67e435a496fe Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Tue, 9 Feb 2021 14:07:11 -0800 Subject: [PATCH 27/71] Fixed some attribute reification issues --- IDEHelper/Compiler/BfCompiler.cpp | 6 ++++++ IDEHelper/Compiler/BfModule.cpp | 26 +++++++++++++++++++----- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 25 ++++++++++++++++++++--- IDEHelper/Compiler/CeMachine.cpp | 2 +- 4 files changed, 50 insertions(+), 9 deletions(-) diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index e13faae1..e913964c 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -5106,6 +5106,12 @@ void BfCompiler::MarkStringPool(BfModule* module) stringPoolEntry.mLastUsedRevision = mRevision; } + for (int stringId : module->mImportFileNames) + { + BfStringPoolEntry& stringPoolEntry = module->mContext->mStringObjectIdMap[stringId]; + stringPoolEntry.mLastUsedRevision = mRevision; + } + /*if (module->mOptModule != NULL) MarkStringPool(module->mOptModule);*/ auto altModule = module->mNextAltModule; diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index fac79d2b..fd7dd99e 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -1543,7 +1543,7 @@ BfIRValue BfModule::CreateStringCharPtr(const StringImpl& str, int stringId, boo } BfIRValue BfModule::CreateStringObjectValue(const StringImpl& str, int stringId, bool define) -{ +{ auto stringTypeInst = ResolveTypeDef(mCompiler->mStringTypeDef, define ? BfPopulateType_Data : BfPopulateType_Declaration)->ToTypeInstance(); mBfIRBuilder->PopulateType(stringTypeInst); @@ -5970,6 +5970,11 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin BfType* reflectFieldDataType = ResolveTypeDef(mCompiler->mReflectFieldDataDef); BfIRValue emptyValueType = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectFieldDataType->ToTypeInstance()->mBaseType), SizedArray()); + if (typeInstance->mTypeDef->mName->ToString() == "TestProgram") + { + NOP; + } + auto _HandleCustomAttrs = [&](BfCustomAttributes* customAttributes) { if (customAttributes == NULL) @@ -10996,6 +11001,17 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri continue; } + if (mModuleName == "BeefTest_TestProgram") + { + NOP; + } + + if ((mIsReified) && (attrTypeInst->mAttributeData != NULL) && ((attrTypeInst->mAttributeData->mFlags & BfAttributeFlag_ReflectAttribute) != 0)) + { + // Reify attribute + PopulateType(attrTypeInst); + } + if (mCurTypeInstance != NULL) AddDependency(attrTypeInst, mCurTypeInstance, BfDependencyMap::DependencyFlag_CustomAttribute); @@ -11166,7 +11182,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri auto propType = methodInstance.mMethodInstance->GetParamType(0); if (assignExpr->mRight != NULL) { - BfTypedValue result = constResolver.Resolve(assignExpr->mRight, propType); + BfTypedValue result = constResolver.Resolve(assignExpr->mRight, propType, BfConstResolveFlag_NoActualizeValues); if ((result) && (!result.mType->IsVar())) { if (!result.mValue.IsConst()) @@ -11182,7 +11198,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri } if ((!handledExpr) && (assignExpr->mRight != NULL)) - constResolver.Resolve(assignExpr->mRight); + constResolver.Resolve(assignExpr->mRight, NULL, BfConstResolveFlag_NoActualizeValues); } else { @@ -11202,7 +11218,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri resolvedArg.mArgFlags = BfArgFlag_DeferredEval; } else - resolvedArg.mTypedValue = constResolver.Resolve(arg); + resolvedArg.mTypedValue = constResolver.Resolve(arg, NULL, BfConstResolveFlag_NoActualizeValues); if (!inPropSet) { @@ -11283,7 +11299,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri if ((arg.mArgFlags & BfArgFlag_DeferredEval) != 0) { if (auto expr = BfNodeDynCast(arg.mExpression)) - constResolver.Resolve(expr); + constResolver.Resolve(expr, NULL, BfConstResolveFlag_NoActualizeValues); } } diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 7f3de22b..76103f25 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -1029,7 +1029,21 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType typeModule->mIsReified = true; typeModule->mWantsIRIgnoreWrites = false; for (auto ownedTypes : typeModule->mOwnedTypeInstances) + { ownedTypes->mIsReified = true; + + if (ownedTypes->mCustomAttributes != NULL) + { + for (auto& attr : ownedTypes->mCustomAttributes->mAttributes) + { + if ((attr.mType->mAttributeData != NULL) && ((attr.mType->mAttributeData->mFlags & BfCustomAttributeFlags_ReflectAttribute) != 0)) + { + // Reify this attribute + typeModule->PopulateType(attr.mType); + } + } + } + } mCompiler->mStats.mReifiedModuleCount++; if (typeModule->mBfIRBuilder != NULL) { @@ -1038,7 +1052,7 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType typeModule->SetupIRBuilder(false); } else - typeModule->PrepareForIRWriting(resolvedTypeRef->ToTypeInstance()); + typeModule->PrepareForIRWriting(resolvedTypeRef->ToTypeInstance()); } else { @@ -2002,7 +2016,7 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance* for (auto& customAttribute : customAttributes->mAttributes) { auto attrType = customAttribute.mType; - PopulateType(attrType, BfPopulateType_DataAndMethods); + mContext->mUnreifiedModule->PopulateType(attrType, BfPopulateType_DataAndMethods); if (attrType->mDefineState < BfTypeDefineState_DefinedAndMethodsSlotted) continue; @@ -2331,7 +2345,7 @@ void BfModule::DoCEEmit(BfMethodInstance* methodInstance) for (auto& customAttribute : customAttributes->mAttributes) { auto attrType = customAttribute.mType; - PopulateType(attrType, BfPopulateType_DataAndMethods); + mContext->mUnreifiedModule->PopulateType(attrType, BfPopulateType_DataAndMethods); if (attrType->mDefineState < BfTypeDefineState_DefinedAndMethodsSlotted) continue; @@ -9716,6 +9730,11 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } typeInst->mTypeDef = typeDef; + if (((resolveFlags & BfResolveTypeRefFlag_NoReify) != 0) && (mCompiler->mOptions.mCompileOnDemandKind != BfCompileOnDemandKind_AlwaysInclude)) + { + typeInst->mIsReified = false; + } + if (typeInst->mTypeDef->mGenericParamDefs.size() != 0) { Fail("Generic type arguments expected", typeRef); diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index 5ee68f7b..2f302190 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -3809,7 +3809,7 @@ BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType BfIRValue CeContext::CreateAttribute(BfAstNode* targetSrc, BfModule* module, BfIRConstHolder* constHolder, BfCustomAttribute* customAttribute) { - module->PopulateType(customAttribute->mType); + module->mContext->mUnreifiedModule->PopulateType(customAttribute->mType); auto ceAttrAddr = CeMalloc(customAttribute->mType->mSize) - mMemory.mVals; BfIRValue ceAttrVal = module->mBfIRBuilder->CreateConstAggCE(module->mBfIRBuilder->MapType(customAttribute->mType, BfIRPopulateType_Identity), ceAttrAddr); BfTypedValue ceAttrTypedValue(ceAttrVal, customAttribute->mType); From e6a918600bb9671cb6ad6de29f294fac3b29713f Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Tue, 9 Feb 2021 16:24:02 -0800 Subject: [PATCH 28/71] Fixed string literal issues with import --- IDEHelper/Compiler/BfModule.cpp | 70 ++++++++++++++++--------------- IDEHelper/Tests/src/Reflection.bf | 66 ++++++++++++++--------------- 2 files changed, 70 insertions(+), 66 deletions(-) diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index fd7dd99e..0f294eb0 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -5969,11 +5969,6 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin // Fields BfType* reflectFieldDataType = ResolveTypeDef(mCompiler->mReflectFieldDataDef); BfIRValue emptyValueType = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectFieldDataType->ToTypeInstance()->mBaseType), SizedArray()); - - if (typeInstance->mTypeDef->mName->ToString() == "TestProgram") - { - NOP; - } auto _HandleCustomAttrs = [&](BfCustomAttributes* customAttributes) { @@ -11001,11 +10996,6 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri continue; } - if (mModuleName == "BeefTest_TestProgram") - { - NOP; - } - if ((mIsReified) && (attrTypeInst->mAttributeData != NULL) && ((attrTypeInst->mAttributeData->mFlags & BfAttributeFlag_ReflectAttribute) != 0)) { // Reify attribute @@ -18376,7 +18366,36 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup) } BfLogSysM("ProcessMethod %p Unspecialized: %d Module: %p IRFunction: %d Reified: %d Incomplete:%d\n", methodInstance, mCurTypeInstance->IsUnspecializedType(), this, methodInstance->mIRFunction.mId, methodInstance->mIsReified, mIncompleteMethodCount); - + + int importStrNum = -1; + auto importKind = methodInstance->GetImportKind(); + if ((!mCompiler->mIsResolveOnly) && + ((importKind == BfImportKind_Import_Static) || (importKind == BfImportKind_Import_Dynamic))) + { + if (auto customAttr = methodInstance->GetCustomAttributes()->Get(mCompiler->mImportAttributeTypeDef)) + { + if (customAttr->mCtorArgs.size() == 1) + { + auto fileNameArg = customAttr->mCtorArgs[0]; + auto constant = mCurTypeInstance->mConstHolder->GetConstant(fileNameArg); + if (constant != NULL) + { + if (!constant->IsNull()) + importStrNum = constant->mInt32; + } + else + { + importStrNum = GetStringPoolIdx(fileNameArg, mCurTypeInstance->mConstHolder); + } + if (importStrNum != -1) + { + if (!mStringPoolRefs.Contains(importStrNum)) + mStringPoolRefs.Add(importStrNum); + } + } + } + } + if (methodInstance->GetImportCallKind() != BfImportCallKind_None) { if (mBfIRBuilder->mIgnoreWrites) @@ -19558,34 +19577,19 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup) } bool isDllImport = false; - if (methodInstance->GetImportKind() == BfImportKind_Import_Static) + if ((importKind == BfImportKind_Import_Static) || (importKind == BfImportKind_Import_Dynamic)) { - for (auto customAttr : methodInstance->GetCustomAttributes()->mAttributes) - { - if (customAttr.mType->mTypeDef->mFullName.ToString() == "System.ImportAttribute") + if (importStrNum != -1) + { + if (importKind == BfImportKind_Import_Static) { - if (customAttr.mCtorArgs.size() == 1) + if (!mImportFileNames.Contains(importStrNum)) { - auto fileNameArg = customAttr.mCtorArgs[0]; - int strNum = 0; - auto constant = mCurTypeInstance->mConstHolder->GetConstant(fileNameArg); - if (constant != NULL) - { - if (constant->IsNull()) - continue; // Invalid - strNum = constant->mInt32; - } - else - { - strNum = GetStringPoolIdx(fileNameArg, mCurTypeInstance->mConstHolder); - } - if (!mImportFileNames.Contains(strNum)) - mImportFileNames.Add(strNum); + mImportFileNames.Add(importStrNum); } } + } - - //mImportFileNames } else if (methodInstance->GetImportKind() == BfImportKind_Import_Dynamic) { diff --git a/IDEHelper/Tests/src/Reflection.bf b/IDEHelper/Tests/src/Reflection.bf index 85ccaa1a..89dcc0f1 100644 --- a/IDEHelper/Tests/src/Reflection.bf +++ b/IDEHelper/Tests/src/Reflection.bf @@ -239,6 +239,32 @@ namespace Tests switch (methodIdx) { case 0: + Test.Assert(methodInfo.Name == "__BfCtor"); + Test.Assert(methodInfo.IsConstructor); + case 1: + Test.Assert(methodInfo.Name == "__BfStaticCtor"); + Test.Assert(methodInfo.IsConstructor); + case 2: + Test.Assert(methodInfo.Name == "GetA"); + var result = methodInfo.Invoke(ca, 123).Get(); + Test.Assert(result.Get() == 1123); + result.Dispose(); + result = methodInfo.Invoke(ca2, 123).Get(); + Test.Assert(result.Get() == 2123); + result.Dispose(); + result = methodInfo.Invoke(.Create(ca2), .Create(123)).Get(); + Test.Assert(result.Get() == 2123); + result.Dispose(); + case 3: + Test.Assert(methodInfo.Name == "MemberMethodA"); + var result = methodInfo.Invoke(ca, 100, (int32)20, 3.0f).Get(); + Test.Assert(result.Get() == 123); + result.Dispose(); + + result = methodInfo.Invoke(.Create(ca), .Create(100), .Create((int32)20), .Create(3.0f)).Get(); + Test.Assert(result.Get() == 123); + result.Dispose(); + case 4: StructA sa = .() { mA = 1, mB = 2 }; Test.Assert(methodInfo.Name == "StaticMethodA"); @@ -291,7 +317,7 @@ namespace Tests let attrC = methodInfo.GetCustomAttribute().Get(); Test.Assert(attrC.mA == 71); Test.Assert(attrC.mB == 72); - case 1: + case 5: Test.Assert(methodInfo.Name == "StaticMethodB"); var fieldA = typeInfo.GetField("mA").Value; @@ -337,33 +363,6 @@ namespace Tests res.Dispose(); fieldSAV.Dispose(); fieldSStrV.Dispose(); - - case 2: - Test.Assert(methodInfo.Name == "MemberMethodA"); - var result = methodInfo.Invoke(ca, 100, (int32)20, 3.0f).Get(); - Test.Assert(result.Get() == 123); - result.Dispose(); - - result = methodInfo.Invoke(.Create(ca), .Create(100), .Create((int32)20), .Create(3.0f)).Get(); - Test.Assert(result.Get() == 123); - result.Dispose(); - case 3: - Test.Assert(methodInfo.Name == "GetA"); - var result = methodInfo.Invoke(ca, 123).Get(); - Test.Assert(result.Get() == 1123); - result.Dispose(); - result = methodInfo.Invoke(ca2, 123).Get(); - Test.Assert(result.Get() == 2123); - result.Dispose(); - result = methodInfo.Invoke(.Create(ca2), .Create(123)).Get(); - Test.Assert(result.Get() == 2123); - result.Dispose(); - case 4: - Test.Assert(methodInfo.Name == "__BfStaticCtor"); - Test.Assert(methodInfo.IsConstructor); - case 5: - Test.Assert(methodInfo.Name == "__BfCtor"); - Test.Assert(methodInfo.IsConstructor); case 6: Test.FatalError(); // Shouldn't have any more } @@ -445,6 +444,8 @@ namespace Tests switch (methodIdx) { case 0: + Test.Assert(methodInfo.Name == "__BfCtor"); + case 1: Test.Assert(methodInfo.Name == "GetA"); var result = methodInfo.Invoke(sa, 34).Get(); @@ -464,7 +465,7 @@ namespace Tests result = methodInfo.Invoke(.Create(&sa), .Create(34)); Test.Assert(result.Get() == 1234); result.Dispose(); - case 1: + case 2: Test.Assert(methodInfo.Name == "GetB"); var result = methodInfo.Invoke(sa, 34).Get(); @@ -489,16 +490,15 @@ namespace Tests Test.Assert(sa.mB == 91); result.Dispose(); - case 2: - Test.Assert(methodInfo.Name == "MethodA0"); case 3: - Test.Assert(methodInfo.Name == "MethodA1"); + Test.Assert(methodInfo.Name == "MethodA0"); case 4: - Test.Assert(methodInfo.Name == "__BfCtor"); + Test.Assert(methodInfo.Name == "MethodA1"); case 5: Test.Assert(methodInfo.Name == "__Equals"); case 6: Test.Assert(methodInfo.Name == "__StrictEquals"); + default: Test.FatalError(); // Shouldn't have any more } From a31770ca98a1475e9ffdb3230e44c76b5d1eb019 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Tue, 9 Feb 2021 17:02:00 -0800 Subject: [PATCH 29/71] Unreified string table reference fix --- IDEHelper/Compiler/BfCompiler.cpp | 6 ++++++ IDEHelper/Compiler/BfModule.cpp | 10 +++++++++- IDEHelper/Compiler/BfModule.h | 1 + 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index e913964c..0b7fcaf4 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -5106,6 +5106,12 @@ void BfCompiler::MarkStringPool(BfModule* module) stringPoolEntry.mLastUsedRevision = mRevision; } + for (int stringId : module->mUnreifiedStringPoolRefs) + { + BfStringPoolEntry& stringPoolEntry = module->mContext->mStringObjectIdMap[stringId]; + stringPoolEntry.mLastUsedRevision = mRevision; + } + for (int stringId : module->mImportFileNames) { BfStringPoolEntry& stringPoolEntry = module->mContext->mStringObjectIdMap[stringId]; diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 0f294eb0..7d1c7329 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -1222,7 +1222,10 @@ void BfModule::StartNewRevision(RebuildKind rebuildKind, bool force) // Clear this here, not in ClearModuleData, so we preserve those references even after writing out module if (rebuildKind != BfModule::RebuildKind_None) // Leave string pool refs for when we need to use things like [LinkName("")] methods bofore re-reification - mStringPoolRefs.Clear(); + { + mStringPoolRefs.Clear(); + mUnreifiedStringPoolRefs.Clear(); + } mDllImportEntries.Clear(); mImportFileNames.Clear(); for (auto& pairVal : mDeferredMethodCallData) @@ -1657,7 +1660,10 @@ String* BfModule::GetStringPoolString(BfIRValue constantStr, BfIRConstHolder * c BfIRValue BfModule::GetStringCharPtr(int stringId, bool force) { if ((mBfIRBuilder->mIgnoreWrites) && (!force)) + { + mUnreifiedStringPoolRefs.Add(stringId); return mBfIRBuilder->CreateConst(BfTypeCode_StringId, stringId); + } BfIRValue* irValue = NULL; if (!mStringCharPtrPool.TryAdd(stringId, NULL, &irValue)) @@ -1711,6 +1717,7 @@ BfIRValue BfModule::GetStringObjectValue(const StringImpl& str, bool define, boo if ((mBfIRBuilder->mIgnoreWrites) && (!force)) { + mUnreifiedStringPoolRefs.Add(strId); return mBfIRBuilder->CreateConst(BfTypeCode_StringId, strId); } @@ -10658,6 +10665,7 @@ void BfModule::ClearConstData() mStringObjectPool.Clear(); mStringCharPtrPool.Clear(); mStringPoolRefs.Clear(); + mUnreifiedStringPoolRefs.Clear(); } BfTypedValue BfModule::GetTypedValueFromConstant(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType) diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 881944c0..5ae6babe 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -1435,6 +1435,7 @@ public: Dictionary mStringObjectPool; Dictionary mStringCharPtrPool; Array mStringPoolRefs; + HashSet mUnreifiedStringPoolRefs; Array mPrevIRBuilders; // Before extensions BfIRBuilder* mBfIRBuilder; From e209f7ac66d7a7e4a616efb520faab38a93218f3 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Tue, 9 Feb 2021 17:10:24 -0800 Subject: [PATCH 30/71] Made debug command path relative to the working directory --- IDE/src/IDEApp.bf | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf index f31ad44c..beb2ab53 100644 --- a/IDE/src/IDEApp.bf +++ b/IDE/src/IDEApp.bf @@ -10825,8 +10825,8 @@ namespace IDE //options.mDebugOptions.mCommand - String launchPath = scope String(); - ResolveConfigString(mPlatformName, workspaceOptions, project, options, options.mDebugOptions.mCommand, "debug command", launchPath); + String launchPathRel = scope String(); + ResolveConfigString(mPlatformName, workspaceOptions, project, options, options.mDebugOptions.mCommand, "debug command", launchPathRel); String arguments = scope String(); ResolveConfigString(mPlatformName, workspaceOptions, project, options, "$(Arguments)", "debug command arguments", arguments); String workingDirRel = scope String(); @@ -10834,6 +10834,9 @@ namespace IDE var workingDir = scope String(); Path.GetAbsolutePath(workingDirRel, project.mProjectDir, workingDir); + String launchPath = scope String(); + Path.GetAbsolutePath(launchPathRel, workingDir, launchPath); + String targetPath = scope .(); ResolveConfigString(mPlatformName, workspaceOptions, project, options, "$(TargetPath)", "Target path", targetPath); From fd5756a93b79b36b323b761a7e3e6344c2ce5b77 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Wed, 10 Feb 2021 07:13:41 -0800 Subject: [PATCH 31/71] Fixed invalid stream write after a FileStream open error --- IDEHelper/Compiler/BfCodeGen.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/IDEHelper/Compiler/BfCodeGen.cpp b/IDEHelper/Compiler/BfCodeGen.cpp index 9b374f23..cd767442 100644 --- a/IDEHelper/Compiler/BfCodeGen.cpp +++ b/IDEHelper/Compiler/BfCodeGen.cpp @@ -439,7 +439,8 @@ void BfCodeGenThread::RunLoop() errorMsg += "\n"; errorMsg += "Failed writing IR '" + fileName + "': " + ec.message(); } - fs.WriteSNZ(str); + else + fs.WriteSNZ(str); } if (!hasCacheMatch) From f9ea536d4ac5533b09a756665a52ca3a1cf219c7 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Wed, 10 Feb 2021 07:15:18 -0800 Subject: [PATCH 32/71] Can set project macro project name like $(BuildDir ProjName) --- IDE/src/IDEApp.bf | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf index beb2ab53..18f1b346 100644 --- a/IDE/src/IDEApp.bf +++ b/IDE/src/IDEApp.bf @@ -9164,7 +9164,8 @@ namespace IDE public bool DoResolveConfigString(String platformName, Workspace.Options workspaceOptions, Project project, Project.Options options, StringView configString, String error, String result) { - int i = result.Length; + int startIdx = result.Length; + int i = startIdx; result.Append(configString); bool hadError = false; @@ -9259,6 +9260,26 @@ namespace IDE cmdErr = "Invalid number of arguments"; case "Var": break ReplaceBlock; + case "TargetDir", + "TargetPath", + "ProjectDir", + "BuildDir", + "LinkFlags": + var selProject = mWorkspace.FindProject(args[0]); + if (selProject != null) + { + Workspace.Options selWorkspaceOptions = gApp.GetCurWorkspaceOptions(); + Project.Options selOptions = gApp.GetCurProjectOptions(selProject); + String selConfigString = scope String()..Append(configString); + selConfigString.Remove(i - startIdx + 2 + cmd.Length, parenPos - i - 2 - cmd.Length); + + result.RemoveToEnd(startIdx); + return DoResolveConfigString(platformName, selWorkspaceOptions, selProject, selOptions, selConfigString, error, result); + } + else + cmdErr = "Unable to find project"; + default: + cmdErr = "Invalid command"; } if (newString == null) From fa9b0d2297f6949a976ef189f4f6a278d373f48e Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Wed, 10 Feb 2021 07:37:31 -0800 Subject: [PATCH 33/71] Improved project name override for macros --- IDE/src/IDEApp.bf | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf index 18f1b346..6fa3a871 100644 --- a/IDE/src/IDEApp.bf +++ b/IDE/src/IDEApp.bf @@ -9260,21 +9260,23 @@ namespace IDE cmdErr = "Invalid number of arguments"; case "Var": break ReplaceBlock; - case "TargetDir", - "TargetPath", - "ProjectDir", + case "Arguments", "BuildDir", - "LinkFlags": + "LinkFlags", + "ProjectDir", + "ProjectName", + "TargetDir", + "TargetPath", + "WorkingDir": var selProject = mWorkspace.FindProject(args[0]); if (selProject != null) { Workspace.Options selWorkspaceOptions = gApp.GetCurWorkspaceOptions(); Project.Options selOptions = gApp.GetCurProjectOptions(selProject); - String selConfigString = scope String()..Append(configString); - selConfigString.Remove(i - startIdx + 2 + cmd.Length, parenPos - i - 2 - cmd.Length); - - result.RemoveToEnd(startIdx); - return DoResolveConfigString(platformName, selWorkspaceOptions, selProject, selOptions, selConfigString, error, result); + String selConfigString = scope $"$({cmd})"; + replaceStr.Clear(); + newString = scope:ReplaceBlock .(); + DoResolveConfigString(platformName, selWorkspaceOptions, selProject, selOptions, selConfigString, error, newString); } else cmdErr = "Unable to find project"; From 503590cea5e918f1119a7954650081de3c6ca5c5 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Wed, 10 Feb 2021 09:03:17 -0800 Subject: [PATCH 34/71] Fixed unreachable code warning with lambda dtor --- IDEHelper/Compiler/BfExprEvaluator.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 614046f5..80d787ea 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -11918,17 +11918,18 @@ void BfExprEvaluator::VisitLambdaBodies(BfAstNode* body, BfFieldDtorDeclaration* if (auto blockBody = BfNodeDynCast(body)) mModule->VisitChild(blockBody); else if (auto bodyExpr = BfNodeDynCast(body)) - { + { auto result = mModule->CreateValueFromExpression(bodyExpr); if ((result) && (mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mReturnTypeInferState == BfReturnTypeInferState_Inferring)) - mModule->mCurMethodState->mClosureState->mReturnType = result.mType; + mModule->mCurMethodState->mClosureState->mReturnType = result.mType; } while (fieldDtor != NULL) { + mModule->mCurMethodState->mLeftBlockUncond = false; mModule->VisitChild(fieldDtor->mBody); - fieldDtor = fieldDtor->mNextFieldDtor; + fieldDtor = fieldDtor->mNextFieldDtor; } } From fb0bace727199795b937f4d8d250fdfbc78fca6f Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Thu, 11 Feb 2021 06:48:51 -0800 Subject: [PATCH 35/71] Fixed duplicate global variables when used as default args --- IDEHelper/Compiler/BfIRBuilder.cpp | 77 ++++++++++++++++-------------- IDEHelper/Compiler/BfIRBuilder.h | 5 +- IDEHelper/Compiler/BfIRCodeGen.cpp | 36 ++++++++------ IDEHelper/Compiler/BfModule.cpp | 15 +++--- 4 files changed, 73 insertions(+), 60 deletions(-) diff --git a/IDEHelper/Compiler/BfIRBuilder.cpp b/IDEHelper/Compiler/BfIRBuilder.cpp index 9469c721..09d6927c 100644 --- a/IDEHelper/Compiler/BfIRBuilder.cpp +++ b/IDEHelper/Compiler/BfIRBuilder.cpp @@ -615,17 +615,7 @@ BfIRValue BfIRConstHolder::CreateConst(BfConstant* fromConst, BfIRConstHolder* f else if (fromConst->mConstType == BfConstType_GlobalVar) { auto fromGlobalVar = (BfGlobalVar*)fromConst; - auto constGV = mTempAlloc.Alloc(); - chunkId = mTempAlloc.GetChunkedId(constGV); - constGV->mStreamId = -1; - constGV->mConstType = BfConstType_GlobalVar; - constGV->mType = fromGlobalVar->mType; - constGV->mIsConst = fromGlobalVar->mIsConst; - constGV->mLinkageType = fromGlobalVar->mLinkageType; - constGV->mInitializer = fromGlobalVar->mInitializer; - constGV->mName = AllocStr(fromGlobalVar->mName); - constGV->mIsTLS = fromGlobalVar->mIsTLS; - copiedConst = (BfConstant*)constGV; + return CreateGlobalVariableConstant(fromGlobalVar->mType, fromGlobalVar->mIsConst, fromGlobalVar->mLinkageType, fromGlobalVar->mInitializer, fromGlobalVar->mName, fromGlobalVar->mIsTLS); } else if (fromConst->mConstType == BfConstType_GEP32_2) { @@ -1875,6 +1865,7 @@ void BfIRBuilder::ClearConstData() mTempAlloc.Clear(); mConstMemMap.Clear(); mFunctionMap.Clear(); + mGlobalVarMap.Clear(); BF_ASSERT(mMethodTypeMap.GetCount() == 0); BF_ASSERT(mTypeMap.GetCount() == 0); BF_ASSERT(mDITemporaryTypes.size() == 0); @@ -1889,6 +1880,7 @@ void BfIRBuilder::ClearNonConstData() { mMethodTypeMap.Clear(); mFunctionMap.Clear(); + mGlobalVarMap.Clear(); mTypeMap.Clear(); mConstMemMap.Clear(); mDITemporaryTypes.Clear(); @@ -2996,11 +2988,6 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) if (fieldInstance->mConstIdx != -1) { - if (fieldInstance->GetFieldDef()->mName == "mMembers") - { - NOP; - } - constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx); staticValue = mModule->ConstantToCurrent(constant, typeInstance->mConstHolder, resolvedFieldType); } @@ -4743,39 +4730,55 @@ BfIRValue BfIRBuilder::CreateStackRestore(BfIRValue stackVal) return retVal; } -BfIRValue BfIRBuilder::CreateGlobalVariable(BfIRType varType, bool isConstant, BfIRLinkageType linkageType, BfIRValue initializer, const StringImpl& name, bool isTLS) +void BfIRBuilder::CreateGlobalVariable(BfIRValue irValue) { + auto globalVar = (BfGlobalVar*)GetConstant(irValue); + + if (!mIgnoreWrites) + { + BF_ASSERT(globalVar->mStreamId == -1); + + if (globalVar->mInitializer) + mHasGlobalDefs = true; + + BfIRValue retVal = WriteCmd(BfIRCmd_GlobalVariable, globalVar->mType, globalVar->mIsConst, (uint8)globalVar->mLinkageType, String(globalVar->mName), globalVar->mIsTLS, globalVar->mInitializer); + globalVar->mStreamId = retVal.mId; + + NEW_CMD_INSERTED_IRVALUE; + } +} + +BfIRValue BfIRConstHolder::CreateGlobalVariableConstant(BfIRType varType, bool isConstant, BfIRLinkageType linkageType, BfIRValue initializer, const StringImpl& name, bool isTLS) +{ + BfIRValue* valuePtr = NULL; + if ((!mGlobalVarMap.TryAdd(name, NULL, &valuePtr)) && (!initializer)) + { + return *valuePtr; + } + BF_ASSERT(varType); auto constGV = mTempAlloc.Alloc(); int chunkId = mTempAlloc.GetChunkedId(constGV); constGV->mStreamId = -1; - constGV->mConstType = BfConstType_GlobalVar; - constGV->mType = varType; + constGV->mConstType = BfConstType_GlobalVar; + constGV->mType = varType; constGV->mIsConst = isConstant; constGV->mLinkageType = linkageType; constGV->mInitializer = initializer; constGV->mName = AllocStr(name); - constGV->mIsTLS = isTLS; + constGV->mIsTLS = isTLS; - if (!mIgnoreWrites) - { - if (initializer) - mHasGlobalDefs = true; + auto irValue = BfIRValue(BfIRValueFlags_Const, chunkId);; + *valuePtr = irValue; + return irValue; +} - BfIRValue retVal = WriteCmd(BfIRCmd_GlobalVariable, varType, isConstant, (uint8)linkageType, name, isTLS, initializer); - constGV->mStreamId = retVal.mId; - retVal.mFlags = BfIRValueFlags_Const; -#ifdef CHECK_CONSTHOLDER - retVal.mHolder = this; -#endif - retVal.mId = chunkId; - NEW_CMD_INSERTED_IRVALUE; - return retVal; - } - - auto irValue = BfIRValue(BfIRValueFlags_Const, chunkId); - return irValue; +BfIRValue BfIRBuilder::CreateGlobalVariable(BfIRType varType, bool isConstant, BfIRLinkageType linkageType, BfIRValue initializer, const StringImpl& name, bool isTLS) +{ + auto irValue = CreateGlobalVariableConstant(varType, isConstant, linkageType, initializer, name); + CreateGlobalVariable(irValue); + return irValue; } void BfIRBuilder::GlobalVar_SetUnnamedAddr(BfIRValue val, bool unnamedAddr) diff --git a/IDEHelper/Compiler/BfIRBuilder.h b/IDEHelper/Compiler/BfIRBuilder.h index ff098a6c..3d045deb 100644 --- a/IDEHelper/Compiler/BfIRBuilder.h +++ b/IDEHelper/Compiler/BfIRBuilder.h @@ -901,6 +901,7 @@ class BfIRConstHolder public: BumpAllocatorT<256> mTempAlloc; BfModule* mModule; + Dictionary mGlobalVarMap; public: void FixTypeCode(BfTypeCode& typeCode); @@ -936,6 +937,7 @@ public: BfIRValue CreateTypeOf(BfType* type); BfIRValue CreateTypeOf(BfType* type, BfIRValue typeData); BfIRValue GetUndefConstValue(BfIRType type); + BfIRValue CreateGlobalVariableConstant(BfIRType varType, bool isConstant, BfIRLinkageType linkageType, BfIRValue initializer, const StringImpl& name, bool isTLS = false); bool WriteConstant(BfIRValue val, void* ptr, BfType* type); BfIRValue ReadConstant(void* ptr, BfType* type); @@ -979,7 +981,7 @@ public: bool mHasDebugInfo; bool mHasDebugLineInfo; Dictionary mMethodTypeMap; - Dictionary mFunctionMap; + Dictionary mFunctionMap; Dictionary mTypeMap; Dictionary mConstMemMap; Array mDITemporaryTypes; @@ -1227,6 +1229,7 @@ public: BfIRValue CreateStackRestore(BfIRValue stackVal); BfIRValue CreateGlobalVariable(BfIRType varType, bool isConstant, BfIRLinkageType linkageType, BfIRValue initializer, const StringImpl& name, bool isTLS = false); + void CreateGlobalVariable(BfIRValue irValue); void GlobalVar_SetUnnamedAddr(BfIRValue val, bool unnamedAddr); void GlobalVar_SetInitializer(BfIRValue globalVar, BfIRValue initVal); void GlobalVar_SetAlignment(BfIRValue globalVar, int alignment); diff --git a/IDEHelper/Compiler/BfIRCodeGen.cpp b/IDEHelper/Compiler/BfIRCodeGen.cpp index 79ea9430..25dcc194 100644 --- a/IDEHelper/Compiler/BfIRCodeGen.cpp +++ b/IDEHelper/Compiler/BfIRCodeGen.cpp @@ -810,13 +810,17 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry, llvm::GlobalVariable* globalVariable = mLLVMModule->getGlobalVariable(name.c_str(), true); if (globalVariable == NULL) { - globalVariable = new llvm::GlobalVariable( - *mLLVMModule, - varType, - isConstant, - LLVMMapLinkageType(linkageType), - initializer, - name.c_str(), NULL, isTLS ? llvm::GlobalValue::GeneralDynamicTLSModel : llvm::GlobalValue::NotThreadLocal); + globalVariable = mLLVMModule->getGlobalVariable(name.c_str()); + if (globalVariable == NULL) + { + globalVariable = new llvm::GlobalVariable( + *mLLVMModule, + varType, + isConstant, + LLVMMapLinkageType(linkageType), + initializer, + name.c_str(), NULL, isTLS ? llvm::GlobalValue::GeneralDynamicTLSModel : llvm::GlobalValue::NotThreadLocal); + } } llvmValue = globalVariable; @@ -2390,13 +2394,17 @@ void BfIRCodeGen::HandleNextCmd() CMD_PARAM(bool, isTLS); CMD_PARAM(llvm::Constant*, initializer); - auto globalVariable = new llvm::GlobalVariable( - *mLLVMModule, - varType, - isConstant, - LLVMMapLinkageType(linkageType), - initializer, - name.c_str(), NULL, isTLS ? llvm::GlobalValue::GeneralDynamicTLSModel : llvm::GlobalValue::NotThreadLocal); + auto globalVariable = mLLVMModule->getGlobalVariable(name.c_str()); + if (globalVariable == NULL) + { + globalVariable = new llvm::GlobalVariable( + *mLLVMModule, + varType, + isConstant, + LLVMMapLinkageType(linkageType), + initializer, + name.c_str(), NULL, isTLS ? llvm::GlobalValue::GeneralDynamicTLSModel : llvm::GlobalValue::NotThreadLocal); + } SetResult(curId, globalVariable); } break; diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 7d1c7329..7b6c32ab 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -13722,6 +13722,10 @@ BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance) { globalValue = *globalValuePtr; BF_ASSERT(globalValue); + + auto globalVar = (BfGlobalVar*)mBfIRBuilder->GetConstant(globalValue); + if ((globalVar->mStreamId == -1) && (!mBfIRBuilder->mIgnoreWrites)) + mBfIRBuilder->CreateGlobalVariable(globalValue); } else { @@ -13753,16 +13757,11 @@ BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance) BfIRValue(), staticVarName, IsThreadLocal(fieldInstance)); - - if (!mBfIRBuilder->mIgnoreWrites) - { - // Only store this if we actually did the creation - BF_ASSERT(globalValue); - mStaticFieldRefs[fieldInstance] = globalValue; - } + + BF_ASSERT(globalValue); + mStaticFieldRefs[fieldInstance] = globalValue; BfLogSysM("Mod:%p Type:%p ReferenceStaticField %p -> %p\n", this, fieldInstance->mOwner, fieldInstance, globalValue); - } } From cffd849045bebcb044ec4193cec2eb0da9e92445 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Thu, 11 Feb 2021 07:46:05 -0800 Subject: [PATCH 36/71] Fixed lookup infinite field loop during custom attribute population --- IDEHelper/Compiler/BfExprEvaluator.cpp | 8 +++++++ IDEHelper/Compiler/BfModule.cpp | 29 +------------------------- 2 files changed, 9 insertions(+), 28 deletions(-) diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 80d787ea..08d580f4 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -4248,6 +4248,14 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar mModule->PopulateType(startCheckType, BfPopulateType_BaseType); } + if ((startCheckType != NULL) && (mModule->mContext->mCurTypeState != NULL)) + { + // Don't allow lookups yet + if ((mModule->mContext->mCurTypeState->mResolveKind == BfTypeState::ResolveKind_Attributes) && + (startCheckType == mModule->mContext->mCurTypeState->mTypeInstance)) + return BfTypedValue(); + } + String findName; int varSkipCount = 0; if (fieldName.StartsWith('@')) diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 7b6c32ab..eb6a4b11 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -13773,7 +13773,7 @@ BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance) } BfTypedValue BfModule::GetThis() -{ +{ auto useMethodState = mCurMethodState; while ((useMethodState != NULL) && (useMethodState->mClosureState != NULL) && (useMethodState->mClosureState->mCapturing)) { @@ -13802,33 +13802,6 @@ BfTypedValue BfModule::GetThis() return BfTypedValue(); } -// if (useMethodState->HasNonStaticMixin()) -// { -// auto checkMethodState = useMethodState; -// while (checkMethodState != NULL) -// { -// for (int localIdx = (int)checkMethodState->mLocals.size() - 1; localIdx >= 0; localIdx--) -// { -// auto varDecl = checkMethodState->mLocals[localIdx]; -// if (varDecl->mName == "this") -// { -// varDecl->mReadFromId = useMethodState->GetRootMethodState()->mCurAccessId++; -// if (varDecl->mIsSplat) -// { -// return BfTypedValue(varDecl->mValue, varDecl->mResolvedType, BfTypedValueKind_ThisSplatHead); -// } -// else if ((varDecl->mResolvedType->IsValueType()) && (varDecl->mAddr)) -// { -// return BfTypedValue(varDecl->mAddr, varDecl->mResolvedType, BfTypedValueKind_ThisAddr); -// } -// return BfTypedValue(varDecl->mValue, varDecl->mResolvedType, varDecl->mResolvedType->IsValueType() ? BfTypedValueKind_ThisAddr : BfTypedValueKind_ThisValue); -// } -// } -// -// checkMethodState = checkMethodState->mPrevMethodState; -// } -// } - // Check mixin state for 'this' { auto checkMethodState = mCurMethodState; From 1c1417763851344e87fc6848ed67747dc3e46db3 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Thu, 11 Feb 2021 08:20:57 -0800 Subject: [PATCH 37/71] Fixed MapType issue with global var --- IDEHelper/Backend/BeIRCodeGen.cpp | 6 +++++- IDEHelper/Compiler/BfModule.cpp | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/IDEHelper/Backend/BeIRCodeGen.cpp b/IDEHelper/Backend/BeIRCodeGen.cpp index 884244e5..e6b14d68 100644 --- a/IDEHelper/Backend/BeIRCodeGen.cpp +++ b/IDEHelper/Backend/BeIRCodeGen.cpp @@ -690,6 +690,8 @@ void BeIRCodeGen::Read(BeValue*& beValue) CMD_PARAM(BeConstant*, initializer); CMD_PARAM(String, name); CMD_PARAM(bool, isTLS); + + BF_ASSERT(varType != NULL); auto globalVariable = mBeModule->mGlobalVariables.Alloc(); globalVariable->mModule = mBeModule; @@ -1907,7 +1909,9 @@ void BeIRCodeGen::HandleNextCmd() CMD_PARAM(StringT<256>, name); CMD_PARAM(bool, isTLS); CMD_PARAM(BeConstant*, initializer); - + + BF_ASSERT(varType != NULL); + auto globalVariable = mBeModule->mGlobalVariables.Alloc(); globalVariable->mModule = mBeModule; globalVariable->mType = varType; diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index eb6a4b11..9a7bc70a 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -13725,7 +13725,10 @@ BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance) auto globalVar = (BfGlobalVar*)mBfIRBuilder->GetConstant(globalValue); if ((globalVar->mStreamId == -1) && (!mBfIRBuilder->mIgnoreWrites)) + { + mBfIRBuilder->MapType(fieldInstance->mResolvedType); mBfIRBuilder->CreateGlobalVariable(globalValue); + } } else { From 85c9a6ebc85768adbdab0cf0211b702952505ff0 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Thu, 11 Feb 2021 09:19:34 -0800 Subject: [PATCH 38/71] Fixed global var TLS issue --- IDEHelper/Compiler/BfIRBuilder.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/IDEHelper/Compiler/BfIRBuilder.cpp b/IDEHelper/Compiler/BfIRBuilder.cpp index 09d6927c..427f6c9d 100644 --- a/IDEHelper/Compiler/BfIRBuilder.cpp +++ b/IDEHelper/Compiler/BfIRBuilder.cpp @@ -4734,10 +4734,8 @@ void BfIRBuilder::CreateGlobalVariable(BfIRValue irValue) { auto globalVar = (BfGlobalVar*)GetConstant(irValue); - if (!mIgnoreWrites) + if ((!mIgnoreWrites) && (globalVar->mStreamId == -1)) { - BF_ASSERT(globalVar->mStreamId == -1); - if (globalVar->mInitializer) mHasGlobalDefs = true; @@ -4776,7 +4774,7 @@ BfIRValue BfIRConstHolder::CreateGlobalVariableConstant(BfIRType varType, bool i BfIRValue BfIRBuilder::CreateGlobalVariable(BfIRType varType, bool isConstant, BfIRLinkageType linkageType, BfIRValue initializer, const StringImpl& name, bool isTLS) { - auto irValue = CreateGlobalVariableConstant(varType, isConstant, linkageType, initializer, name); + auto irValue = CreateGlobalVariableConstant(varType, isConstant, linkageType, initializer, name, isTLS); CreateGlobalVariable(irValue); return irValue; } From b356e4735cc4289d9bb5063dab495e40e906cd31 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Fri, 12 Feb 2021 05:50:10 -0800 Subject: [PATCH 39/71] Refactored prebuild/postbuild command handling --- IDE/src/BuildContext.bf | 16 +++++----------- IDE/src/IDEApp.bf | 26 ++++++++++++++++++++++++++ IDE/src/ScriptManager.bf | 2 +- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/IDE/src/BuildContext.bf b/IDE/src/BuildContext.bf index 15c4fe20..211d5f3e 100644 --- a/IDE/src/BuildContext.bf +++ b/IDE/src/BuildContext.bf @@ -118,7 +118,7 @@ namespace IDE bool didCommands = false; - let targetName = scope String("Project ", project.mProjectName); + //let targetName = scope String("Project ", project.mProjectName); //Console.WriteLine("Executing custom command {0} {1} {2}", highestDateTime, targetDateTime, forceRebuild); for (let origCustomCmd in cmdList) @@ -159,19 +159,13 @@ namespace IDE didCommands = true; } - mScriptManager.QueueCommands(customCmd, scope String()..AppendF("project {}", project.mProjectName), .NoLines); + let scriptCmd = new IDEApp.ScriptCmd(); + scriptCmd.mCmd = new String(customCmd); + scriptCmd.mPath = new $"project {project.mProjectName}"; + gApp.mExecutionQueue.Add(scriptCmd); continue; } - let targetCompleteCmd = new IDEApp.TargetCompletedCmd(project); - if (didCommands) - { - mScriptManager.QueueCommands(scope String()..AppendF("%targetComplete {}", project.mProjectName), targetName, .NoLines); - targetCompleteCmd.mIsReady = false; - project.mNeedsTargetRebuild = true; - } - gApp.mExecutionQueue.Add(targetCompleteCmd); - return didCommands ? .HadCommands : .NoCommands; } diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf index 6fa3a871..3ea4ef87 100644 --- a/IDE/src/IDEApp.bf +++ b/IDE/src/IDEApp.bf @@ -435,6 +435,12 @@ namespace IDE } } + public class ScriptCmd : ExecutionCmd + { + public String mCmd ~ delete _; + public String mPath ~ delete _; + } + public enum ArgsFileKind { None, @@ -8257,6 +8263,21 @@ namespace IDE } } + if (let scriptCmd = next as ScriptCmd) + { + if (mBuildContext?.mScriptManager != null) + { + if (scriptCmd.mCmd != null) + { + mBuildContext.mScriptManager.QueueCommands(scriptCmd.mCmd, scriptCmd.mPath, .NoLines); + DeleteAndNullify!(scriptCmd.mCmd); + } + + if (mBuildContext.mScriptManager.HasQueuedCommands) + return; + } + } + defer delete next; mExecutionQueue.RemoveAt(0); @@ -8412,6 +8433,11 @@ namespace IDE if (gApp.mDebugger.mIsRunning) mProfilePanel.StartProfiling(profileCmd.mThreadId, profileCmd.mDesc, profileCmd.mSampleRate); } + else if (var scriptCmd = next as ScriptCmd) + { + // Already handled + (void)scriptCmd; + } else { Runtime.FatalError("Unknown command"); diff --git a/IDE/src/ScriptManager.bf b/IDE/src/ScriptManager.bf index 0e1973f8..4c0bafe9 100644 --- a/IDE/src/ScriptManager.bf +++ b/IDE/src/ScriptManager.bf @@ -1007,7 +1007,7 @@ namespace IDE if (!gApp.[Friend]mExecutionQueue.IsEmpty) { var nextCmd = gApp.mExecutionQueue[0]; - if (!(nextCmd is IDEApp.TargetCompletedCmd)) + if (!(nextCmd is IDEApp.ScriptCmd)) return false; } From 3cdc70c1be319bd3860e24493d335e91a41ae0a6 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Fri, 12 Feb 2021 07:44:43 -0800 Subject: [PATCH 40/71] Fixed defer statement warning in emitted code --- IDEHelper/Compiler/BfStmtEvaluator.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/IDEHelper/Compiler/BfStmtEvaluator.cpp b/IDEHelper/Compiler/BfStmtEvaluator.cpp index e04eaeeb..091b96e6 100644 --- a/IDEHelper/Compiler/BfStmtEvaluator.cpp +++ b/IDEHelper/Compiler/BfStmtEvaluator.cpp @@ -6726,7 +6726,13 @@ void BfModule::Visit(BfDeferStatement* deferStmt) if ((scope == mCurMethodState->mCurScope) && (scope->mCloseNode == NULL)) { - Warn(0, "This defer will immediately execute. Consider specifying a wider scope target such as 'defer::'", deferStmt->mDeferToken); + auto parser = deferStmt->GetParser(); + if ((parser != NULL) && (parser->mFileName.Contains('|'))) + { + // Is emitted + } + else + Warn(0, "This defer will immediately execute. Consider specifying a wider scope target such as 'defer::'", deferStmt->mDeferToken); } if (auto block = BfNodeDynCast(deferStmt->mTargetNode)) From fda6c326c090062d925e37f2ce159f40459de501 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Fri, 12 Feb 2021 08:04:08 -0800 Subject: [PATCH 41/71] Fixed crash with illegal recursive generic definitions --- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 50 ++++++++++++++---------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 76103f25..44a593d5 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -3403,6 +3403,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy for (auto& validateEntry : deferredTypeValidateList) { + SetAndRestoreValue prevAttributeTypeRef(typeState.mCurAttributeTypeRef, validateEntry.mTypeRef); SetAndRestoreValue ignoreErrors(mIgnoreErrors, mIgnoreErrors | validateEntry.mIgnoreErrors); ValidateGenericConstraints(validateEntry.mTypeRef, validateEntry.mGenericType, false); } @@ -4332,34 +4333,41 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy if ((mCompiler->mOptions.mAllowHotSwapping) && (typeInstance->mDefineState < BfTypeDefineState_Defined)) { - auto hotTypeVersion = typeInstance->mHotTypeData->mTypeVersions.back(); - - if ((typeInstance->mBaseType != NULL) && (typeInstance->mBaseType->mHotTypeData != NULL)) + if (typeInstance->mHotTypeData == NULL) { - hotTypeVersion->mMembers.Add(typeInstance->mBaseType->mHotTypeData->GetLatestVersion()); + BF_ASSERT(typeInstance->mTypeFailed); } - - for (auto& fieldInst : typeInstance->mFieldInstances) + else { - auto fieldDef = fieldInst.GetFieldDef(); - if ((fieldDef == NULL) || (fieldDef->mIsStatic)) - continue; - auto depType = fieldInst.mResolvedType; + auto hotTypeVersion = typeInstance->mHotTypeData->mTypeVersions.back(); - while (depType->IsSizedArray()) - depType = ((BfSizedArrayType*)depType)->mElementType; - if (depType->IsStruct()) + if ((typeInstance->mBaseType != NULL) && (typeInstance->mBaseType->mHotTypeData != NULL)) { - PopulateType(depType); - auto depTypeInst = depType->ToTypeInstance(); - BF_ASSERT(depTypeInst->mHotTypeData != NULL); - if (depTypeInst->mHotTypeData != NULL) - hotTypeVersion->mMembers.Add(depTypeInst->mHotTypeData->GetLatestVersion()); + hotTypeVersion->mMembers.Add(typeInstance->mBaseType->mHotTypeData->GetLatestVersion()); } - } - for (auto member : hotTypeVersion->mMembers) - member->mRefCount++; + for (auto& fieldInst : typeInstance->mFieldInstances) + { + auto fieldDef = fieldInst.GetFieldDef(); + if ((fieldDef == NULL) || (fieldDef->mIsStatic)) + continue; + auto depType = fieldInst.mResolvedType; + + while (depType->IsSizedArray()) + depType = ((BfSizedArrayType*)depType)->mElementType; + if (depType->IsStruct()) + { + PopulateType(depType); + auto depTypeInst = depType->ToTypeInstance(); + BF_ASSERT(depTypeInst->mHotTypeData != NULL); + if (depTypeInst->mHotTypeData != NULL) + hotTypeVersion->mMembers.Add(depTypeInst->mHotTypeData->GetLatestVersion()); + } + } + + for (auto member : hotTypeVersion->mMembers) + member->mRefCount++; + } } if (typeInstance->mDefineState < BfTypeDefineState_Defined) From a6e8436b2f61f7dadf1f66b0a24460a5cafc9393 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Fri, 12 Feb 2021 09:31:09 -0800 Subject: [PATCH 42/71] Derived CRTP fixes --- IDEHelper/Compiler/BfContext.h | 4 +++- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 16 +++++++++++++++ IDEHelper/Tests/src/Classes.bf | 26 ++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 IDEHelper/Tests/src/Classes.bf diff --git a/IDEHelper/Compiler/BfContext.h b/IDEHelper/Compiler/BfContext.h index 6efd1fdd..c9ab4227 100644 --- a/IDEHelper/Compiler/BfContext.h +++ b/IDEHelper/Compiler/BfContext.h @@ -143,10 +143,11 @@ public: BfPopulateType mPopulateType; BfTypeReference* mCurBaseTypeRef; + BfTypeInstance* mCurBaseType; BfTypeReference* mCurAttributeTypeRef; BfFieldDef* mCurFieldDef; BfTypeDef* mCurTypeDef; - BfTypeDef* mForceActiveTypeDef; + BfTypeDef* mForceActiveTypeDef; ResolveKind mResolveKind; BfAstNode* mCurVarInitializer; int mArrayInitializerSize; @@ -160,6 +161,7 @@ public: mPopulateType = BfPopulateType_Identity; mCurBaseTypeRef = NULL; + mCurBaseType = NULL; mCurFieldDef = NULL; mCurAttributeTypeRef = NULL; mCurTypeDef = NULL; diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 44a593d5..9f2df9a8 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -3022,7 +3022,10 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy bool populateBase = !typeInstance->mTypeFailed; auto checkType = ResolveTypeRef(checkTypeRef, BfPopulateType_Declaration); if ((checkType != NULL) && (!checkType->IsInterface()) && (populateBase)) + { + SetAndRestoreValue prevBaseType(mContext->mCurTypeState->mCurBaseType, checkType->ToTypeInstance()); PopulateType(checkType, BfPopulateType_Data); + } if (typeInstance->mDefineState >= BfTypeDefineState_Defined) { @@ -12793,6 +12796,19 @@ bool BfModule::TypeIsSubTypeOf(BfTypeInstance* srcType, BfTypeInstance* wantType if (srcType->mDefineState < BfTypeDefineState_HasInterfaces) { + if (srcType->mDefineState == BfTypeDefineState_ResolvingBaseType) + { + auto typeState = mContext->mCurTypeState; + while (typeState != NULL) + { + if ((typeState->mTypeInstance == srcType) && (typeState->mCurBaseType != NULL)) + { + return TypeIsSubTypeOf(typeState->mCurBaseType, wantType, checkAccessibility); + } + typeState = typeState->mPrevState; + } + } + // Type is incomplete. We don't do the IsIncomplete check here because of re-entry // While handling 'var' resolution, we don't want to force a PopulateType reentry // but we do have enough information for TypeIsSubTypeOf diff --git a/IDEHelper/Tests/src/Classes.bf b/IDEHelper/Tests/src/Classes.bf new file mode 100644 index 00000000..b4d4c0f0 --- /dev/null +++ b/IDEHelper/Tests/src/Classes.bf @@ -0,0 +1,26 @@ +namespace Tests +{ + class Classes + { + public abstract class Plugin where T : Plugin, new, class + { + public abstract void OnLoad(); + public abstract void OnUnload(); + } + + public abstract class ProgramPlugin : Plugin where T : ProgramPlugin + { + } + + public class ExamplePlugin : ProgramPlugin + { + public override void OnLoad() + { + } + + public override void OnUnload() + { + } + } + } +} From 1d5bb1fade76cea0fe0091676c6ca3340274a5d7 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Sat, 13 Feb 2021 06:02:50 -0800 Subject: [PATCH 43/71] SDL_GetDisplayUsableBounds linkname fix --- BeefLibs/SDL2/src/SDL2.bf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BeefLibs/SDL2/src/SDL2.bf b/BeefLibs/SDL2/src/SDL2.bf index 5eb54f5b..dda59478 100644 --- a/BeefLibs/SDL2/src/SDL2.bf +++ b/BeefLibs/SDL2/src/SDL2.bf @@ -717,7 +717,7 @@ namespace SDL2 public static extern int32 GetDisplayMode(int32 displayIndex, int32 modeIndex, out SDL_DisplayMode mode); /* Available in 2.0.5 or higher */ - [LinkName("SDL_GetDisplayMode")] + [LinkName("SDL_GetDisplayUsableBounds")] public static extern int SDL_GetDisplayUsableBounds(int displayIndex, out Rect rect); [LinkName("SDL_GetNumDisplayModes")] From 6e5845482509dde3d566514ae9f9e2edc3129c23 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Sat, 13 Feb 2021 07:24:26 -0800 Subject: [PATCH 44/71] Fixed global lookup in default param values --- IDEHelper/Compiler/BfModule.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 9a7bc70a..eb6652d5 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -22002,6 +22002,12 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool } else { + BfTypeState typeState; + typeState.mTypeInstance = mCurTypeInstance; + typeState.mCurTypeDef = methodDef->mDeclaringType; + //typeState.mCurMethodDef = methodDef; + SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); + BfConstResolver constResolver(this); defaultValue = constResolver.Resolve(paramDef->mParamDeclaration->mInitializer, resolvedParamType, (BfConstResolveFlags)(BfConstResolveFlag_NoCast | BfConstResolveFlag_AllowGlobalVariable)); if ((defaultValue) && (defaultValue.mType != resolvedParamType)) From ed679f6f105c1a3da2d131c4438d77a16bafa84a Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Sun, 14 Feb 2021 06:40:02 -0800 Subject: [PATCH 45/71] Fixed null coalescing for function pointers --- IDEHelper/Compiler/BfExprEvaluator.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 08d580f4..b819317f 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -20615,14 +20615,19 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod return; } - if ((binaryOp == BfBinaryOp_NullCoalesce) && ((leftValue.mType->IsPointer()) || (leftValue.mType->IsObject()))) + if ((binaryOp == BfBinaryOp_NullCoalesce) && ((leftValue.mType->IsPointer()) || (leftValue.mType->IsFunction()) || (leftValue.mType->IsObject()))) { auto prevBB = mModule->mBfIRBuilder->GetInsertBlock(); auto rhsBB = mModule->mBfIRBuilder->CreateBlock("nullc.rhs"); auto endBB = mModule->mBfIRBuilder->CreateBlock("nullc.end"); - auto isNull = mModule->mBfIRBuilder->CreateIsNull(leftValue.mValue); + BfIRValue isNull; + if (leftValue.mType->IsFunction()) + isNull = mModule->mBfIRBuilder->CreateIsNull( + mModule->mBfIRBuilder->CreateIntToPtr(leftValue.mValue, mModule->mBfIRBuilder->MapType(mModule->GetPrimitiveType(BfTypeCode_NullPtr)))); + else + isNull = mModule->mBfIRBuilder->CreateIsNull(leftValue.mValue); mModule->mBfIRBuilder->CreateCondBr(isNull, rhsBB, endBB); mModule->AddBasicBlock(rhsBB); From 10f175b0c5dfc2e45e164d47b18a36afacd23fca Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Sun, 14 Feb 2021 07:36:26 -0800 Subject: [PATCH 46/71] Fix for deleting mFileNames values in Reset --- BeefLibs/corlib/src/IO/OpenFileDialog.bf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/BeefLibs/corlib/src/IO/OpenFileDialog.bf b/BeefLibs/corlib/src/IO/OpenFileDialog.bf index 8c32cbc3..bb8cb5f2 100644 --- a/BeefLibs/corlib/src/IO/OpenFileDialog.bf +++ b/BeefLibs/corlib/src/IO/OpenFileDialog.bf @@ -119,7 +119,8 @@ namespace System.IO DeleteAndNullify!(mTitle); DeleteAndNullify!(mInitialDir); DeleteAndNullify!(mDefaultExt); - DeleteAndNullify!(mFileNames); + DeleteContainerAndItems!(mFileNames); + mFileNames = null; DeleteAndNullify!(mFilter); mFilterIndex = 1; mSupportMultiDottedExtensions = false; From ce967720549003905bd1e47c0e885175404a524b Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Mon, 15 Feb 2021 07:03:48 -0800 Subject: [PATCH 47/71] Fixed concrete return in interface extension --- IDEHelper/Compiler/BfDefBuilder.cpp | 12 +----------- IDEHelper/Compiler/BfModule.cpp | 5 +++++ IDEHelper/Compiler/BfModuleTypeUtils.cpp | 2 +- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/IDEHelper/Compiler/BfDefBuilder.cpp b/IDEHelper/Compiler/BfDefBuilder.cpp index efa70672..aa19e6e3 100644 --- a/IDEHelper/Compiler/BfDefBuilder.cpp +++ b/IDEHelper/Compiler/BfDefBuilder.cpp @@ -443,17 +443,7 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio { methodDef->mIsConcrete = true; methodDef->mIsVirtual = false; - } - - if (mCurTypeDef->mTypeCode == BfTypeCode_Interface) - { - // - } - else - { - if (methodDef->mIsConcrete) - Fail("Only interfaces methods can be declared as 'concrete'", methodDeclaration->mVirtualSpecifier); - } + } if (methodDef->mIsAbstract) { diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index eb6652d5..3d0ef3df 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -22780,6 +22780,11 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool } } + if ((methodDef->mIsConcrete) && (!methodInstance->mIsForeignMethodDef) && (!mCurTypeInstance->IsInterface())) + { + Fail("Only interfaces methods can be declared as 'concrete'", methodDeclaration->mVirtualSpecifier); + } + if ((methodDef->mIsVirtual) && (methodDef->mIsStatic) && (!methodInstance->mIsInnerOverride)) { if ((virtualToken != NULL) && (virtualToken->mToken == BfToken_Override) && (methodDef->mDeclaringType->mTypeCode == BfTypeCode_Extension)) diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 9f2df9a8..641054e3 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -8336,7 +8336,7 @@ BfTypeDef* BfModule::GetActiveTypeDef(BfTypeInstance* typeInstanceOverride, bool useTypeDef = typeInstance->mTypeDef; if ((mCurMethodState != NULL) && (mCurMethodState->mMixinState != NULL) && (useMixinDecl)) useTypeDef = mCurMethodState->mMixinState->mMixinMethodInstance->mMethodDef->mDeclaringType; - else if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mMethodDef->mDeclaringType != NULL)) + else if ((mCurMethodInstance != NULL) && (!mCurMethodInstance->mIsForeignMethodDef) && (mCurMethodInstance->mMethodDef->mDeclaringType != NULL)) useTypeDef = mCurMethodInstance->mMethodDef->mDeclaringType; else if (mContext->mCurTypeState != NULL) { From 0bbb8398d213ceba5a0f617f50793601c3dacd08 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Mon, 15 Feb 2021 07:18:58 -0800 Subject: [PATCH 48/71] Fixed field dtors with valueless fields --- IDEHelper/Compiler/BfModule.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 3d0ef3df..37d9eec9 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -15743,7 +15743,11 @@ void BfModule::EmitDtorBody() } else { - if (!mCurTypeInstance->IsValueType()) + if (fieldInst->mResolvedType->IsValuelessType()) + { + value = mBfIRBuilder->GetFakeVal(); + } + else if (!mCurTypeInstance->IsValueType()) { auto thisValue = GetThis(); value = mBfIRBuilder->CreateInBoundsGEP(thisValue.mValue, 0, fieldInst->mDataIdx); From a9001b73b644f8a2e527e3b3382ad3aeb0c1adc3 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Mon, 15 Feb 2021 07:26:37 -0800 Subject: [PATCH 49/71] Fixed active typedef issue --- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 641054e3..9f2df9a8 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -8336,7 +8336,7 @@ BfTypeDef* BfModule::GetActiveTypeDef(BfTypeInstance* typeInstanceOverride, bool useTypeDef = typeInstance->mTypeDef; if ((mCurMethodState != NULL) && (mCurMethodState->mMixinState != NULL) && (useMixinDecl)) useTypeDef = mCurMethodState->mMixinState->mMixinMethodInstance->mMethodDef->mDeclaringType; - else if ((mCurMethodInstance != NULL) && (!mCurMethodInstance->mIsForeignMethodDef) && (mCurMethodInstance->mMethodDef->mDeclaringType != NULL)) + else if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mMethodDef->mDeclaringType != NULL)) useTypeDef = mCurMethodInstance->mMethodDef->mDeclaringType; else if (mContext->mCurTypeState != NULL) { From bb848624d1376e2df7391e2499afc7676fa4cd20 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Mon, 15 Feb 2021 07:28:59 -0800 Subject: [PATCH 50/71] Version bump (0.43.0) --- BeefBuild/BeefProj.toml | 2 +- IDE/BeefProj.toml | 2 +- IDE/src/IDEApp.bf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/BeefBuild/BeefProj.toml b/BeefBuild/BeefProj.toml index 20e063e6..6eba383c 100644 --- a/BeefBuild/BeefProj.toml +++ b/BeefBuild/BeefProj.toml @@ -7,7 +7,7 @@ StartupObject = "BeefBuild.Program" [Platform.Windows] Description = "BeefBuild" -FileVersion = "0.42.9" +FileVersion = "0.43.0" [Configs.Debug.Win32] TargetName = "" diff --git a/IDE/BeefProj.toml b/IDE/BeefProj.toml index 789bf02c..21b0b853 100644 --- a/IDE/BeefProj.toml +++ b/IDE/BeefProj.toml @@ -13,7 +13,7 @@ Description = "Beef IDE" Company = "BeefyTech LLC" Product = "Beef IDE" Copyright = "Copyright 2019 BeefyTech" -FileVersion = "0.42.9" +FileVersion = "0.43.0" ProductVersion = "0000000000000000" [Configs.Debug.Win32] diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf index 3ea4ef87..e40fac3f 100644 --- a/IDE/src/IDEApp.bf +++ b/IDE/src/IDEApp.bf @@ -119,7 +119,7 @@ namespace IDE public class IDEApp : BFApp { public static String sRTVersionStr = "042"; - public const String cVersion = "0.42.9"; + public const String cVersion = "0.43.0"; #if BF_PLATFORM_WINDOWS public static readonly String sPlatform64Name = "Win64"; From f2516b7ab8193eca2de354f9b1d05ed00c5726f8 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Mon, 15 Feb 2021 09:56:51 -0800 Subject: [PATCH 51/71] Retry on unexpected http failures --- IDEHelper/NetManager.cpp | 127 +++++++++++++++++++++------------------ 1 file changed, 67 insertions(+), 60 deletions(-) diff --git a/IDEHelper/NetManager.cpp b/IDEHelper/NetManager.cpp index 7bc4edd3..c198ea6d 100644 --- a/IDEHelper/NetManager.cpp +++ b/IDEHelper/NetManager.cpp @@ -82,17 +82,14 @@ static size_t WriteMemoryCallback(void* contents, size_t size, size_t nmemb, voi void NetRequest::Cleanup() { if (mCURLMulti != NULL) - { - curl_multi_remove_handle(mCURLMulti, mCURL); - } + curl_multi_remove_handle(mCURLMulti, mCURL); + if (mCURL != NULL) + curl_easy_cleanup(mCURL); + if (mCURLMulti != NULL) + curl_multi_cleanup(mCURLMulti); - if (mCURL != NULL) - curl_easy_cleanup(mCURL); - - if (mCURLMulti != NULL) - { - curl_multi_cleanup(mCURLMulti); - } + mCURL = NULL; + mCURLMulti = NULL; } void NetRequest::DoTransfer() @@ -105,65 +102,75 @@ void NetRequest::DoTransfer() // return; // } - BfLogDbg("NetManager starting get on %s\n", mURL.c_str()); - mNetManager->mDebugManager->OutputRawMessage(StrFormat("msgLo Getting '%s'\n", mURL.c_str())); - - mOutTempPath = mOutPath + "__partial"; - - mCURLMulti = curl_multi_init(); - - mCURL = curl_easy_init(); - - if (mShowTracking) - { - mNetManager->mDebugManager->OutputRawMessage(StrFormat("symsrv Getting '%s'", mURL.c_str())); - } - - //OutputDebugStrF("Getting '%s'\n", mURL.c_str()); - - curl_easy_setopt(mCURL, CURLOPT_URL, mURL.c_str()); - curl_easy_setopt(mCURL, CURLOPT_WRITEDATA, (void*)this); - curl_easy_setopt(mCURL, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); - curl_easy_setopt(mCURL, CURLOPT_XFERINFODATA, (void*)this); - curl_easy_setopt(mCURL, CURLOPT_XFERINFOFUNCTION, TransferInfoCallback); - curl_easy_setopt(mCURL, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt(mCURL, CURLOPT_NOPROGRESS, 0L); - curl_easy_setopt(mCURL, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); // Connects go slow without this - //auto result = curl_easy_perform(mCURL); - - CURLMcode mcode = curl_multi_add_handle(mCURLMulti, mCURL); - if (mcode != CURLM_OK) + long response_code = 0; + for (int pass = 0; pass < 3; pass++) { - mFailed = true; - return; - } - - while (true) - { - int activeCount = 0; - curl_multi_perform(mCURLMulti, &activeCount); - if (activeCount == 0) - break; + BfLogDbg("NetManager starting get on %s Pass:%d\n", mURL.c_str(), pass); + mNetManager->mDebugManager->OutputRawMessage(StrFormat("msgLo Getting '%s'\n", mURL.c_str())); - int waitRet = 0; - curl_multi_wait(mCURLMulti, NULL, 0, 20, &waitRet); + mOutTempPath = mOutPath + "__partial"; - if (mCancelling) + mCURLMulti = curl_multi_init(); + + mCURL = curl_easy_init(); + + if (mShowTracking) + { + mNetManager->mDebugManager->OutputRawMessage(StrFormat("symsrv Getting '%s'", mURL.c_str())); + } + + //OutputDebugStrF("Getting '%s'\n", mURL.c_str()); + + curl_easy_setopt(mCURL, CURLOPT_URL, mURL.c_str()); + curl_easy_setopt(mCURL, CURLOPT_WRITEDATA, (void*)this); + curl_easy_setopt(mCURL, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); + curl_easy_setopt(mCURL, CURLOPT_XFERINFODATA, (void*)this); + curl_easy_setopt(mCURL, CURLOPT_XFERINFOFUNCTION, TransferInfoCallback); + curl_easy_setopt(mCURL, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(mCURL, CURLOPT_NOPROGRESS, 0L); + curl_easy_setopt(mCURL, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); // Connects go slow without this + //auto result = curl_easy_perform(mCURL); + + CURLMcode mcode = curl_multi_add_handle(mCURLMulti, mCURL); + if (mcode != CURLM_OK) { mFailed = true; return; } - } -// if (result != CURLE_OK) -// { -// mFailed = true; -// return; -// } + while (true) + { + int activeCount = 0; + curl_multi_perform(mCURLMulti, &activeCount); + if (activeCount == 0) + break; + + int waitRet = 0; + curl_multi_wait(mCURLMulti, NULL, 0, 20, &waitRet); + + if (mCancelling) + { + mFailed = true; + return; + } + } + + // if (result != CURLE_OK) + // { + // mFailed = true; + // return; + // } - long response_code = 0; - curl_easy_getinfo(mCURL, CURLINFO_RESPONSE_CODE, &response_code); - mNetManager->mDebugManager->OutputRawMessage(StrFormat("msgLo Result for '%s': %d\n", mURL.c_str(), response_code)); + response_code = 0; + curl_easy_getinfo(mCURL, CURLINFO_RESPONSE_CODE, &response_code); + mNetManager->mDebugManager->OutputRawMessage(StrFormat("msgLo Result for '%s': %d\n", mURL.c_str(), response_code)); + + if ((response_code == 0) || (response_code == 200) || (response_code == 404)) + break; + + Cleanup(); + // Try again! + } if (response_code == 200) { From 8d0f70588fb6e88da20f9c8f1befde1db5cea52b Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Mon, 15 Feb 2021 10:21:00 -0800 Subject: [PATCH 52/71] Fixed isalpha signed issue --- IDEHelper/Compiler/BfPrinter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IDEHelper/Compiler/BfPrinter.cpp b/IDEHelper/Compiler/BfPrinter.cpp index c567db5b..54a5c8c4 100644 --- a/IDEHelper/Compiler/BfPrinter.cpp +++ b/IDEHelper/Compiler/BfPrinter.cpp @@ -407,7 +407,7 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node) } else if (c == ' ') { - if ((isalpha(src[i - 1])) && (isalpha(src[i + 1]))) + if ((isalpha((uint8)src[i - 1])) && (isalpha((uint8)src[i + 1]))) spacedWordCount++; } else if ((c == '/') && (src[i - 1] == '/') && (hadNonSlash)) From 3681b521b529d3843d5e719bb1428eefea3fff86 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Tue, 16 Feb 2021 14:51:31 -0800 Subject: [PATCH 53/71] Fixes for safe mode --- IDE/src/ui/ClassViewPanel.bf | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/IDE/src/ui/ClassViewPanel.bf b/IDE/src/ui/ClassViewPanel.bf index 39e7a378..8211dfe6 100644 --- a/IDE/src/ui/ClassViewPanel.bf +++ b/IDE/src/ui/ClassViewPanel.bf @@ -876,16 +876,22 @@ namespace IDE.ui { base.Update(); + if (gApp.mBfResolveCompiler == null) + return; + var focusedItem = (ClassViewListViewItem)mTypeLV.GetRoot().FindFocusedItem(); var focusedStr = scope String(); if (focusedItem != null) GetName(focusedItem, focusedStr); - int32 compileRevision = gApp.mBfResolveCompiler.GetCompileRevision(); - if (mLastCompileRevision != compileRevision) + if (gApp.mBfResolveCompiler != null) { - mCompileRevisionDirtyDelay = 30; - mLastCompileRevision = compileRevision; + int32 compileRevision = gApp.mBfResolveCompiler.GetCompileRevision(); + if (mLastCompileRevision != compileRevision) + { + mCompileRevisionDirtyDelay = 30; + mLastCompileRevision = compileRevision; + } } if ((mCompileRevisionDirtyDelay > 0) && (--mCompileRevisionDirtyDelay == 0)) From eb86c717f038c90318b3e85eb5376fca06d87763 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Tue, 16 Feb 2021 14:53:48 -0800 Subject: [PATCH 54/71] Partial recursive generic fixes, deferred constraint type validation --- IDEHelper/Compiler/BfCompiler.cpp | 8 +-- IDEHelper/Compiler/BfCompiler.h | 4 +- IDEHelper/Compiler/BfModule.cpp | 39 +++++++++----- IDEHelper/Compiler/BfModule.h | 2 +- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 62 ++++++++++++++++++---- IDEHelper/Compiler/BfResolvedTypeUtils.cpp | 60 ++++++++++++++------- IDEHelper/Compiler/BfResolvedTypeUtils.h | 12 +++-- IDEHelper/Tests/src/Classes.bf | 18 +++++++ IDEHelper/Tests/src/Generics2.bf | 10 ++++ 9 files changed, 162 insertions(+), 53 deletions(-) diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index 0b7fcaf4..fe46736d 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -398,6 +398,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly) mDbgRawAllocDataTypeDef = NULL; mDeferredCallTypeDef = NULL; mDelegateTypeDef = NULL; + mFunctionTypeDef = NULL; mActionTypeDef = NULL; mEnumTypeDef = NULL; mFriendAttributeTypeDef = NULL; @@ -405,8 +406,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly) mConstEvalAttributeTypeDef = NULL; mNoExtensionAttributeTypeDef = NULL; mCheckedAttributeTypeDef = NULL; - mUncheckedAttributeTypeDef = NULL; - mFunctionTypeDef = NULL; + mUncheckedAttributeTypeDef = NULL; mGCTypeDef = NULL; mGenericIEnumerableTypeDef = NULL; mGenericIEnumeratorTypeDef = NULL; @@ -6665,6 +6665,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) mDbgRawAllocDataTypeDef = _GetRequiredType("System.DbgRawAllocData"); mDeferredCallTypeDef = _GetRequiredType("System.DeferredCall"); mDelegateTypeDef = _GetRequiredType("System.Delegate"); + mFunctionTypeDef = _GetRequiredType("System.Function"); mActionTypeDef = _GetRequiredType("System.Action"); mEnumTypeDef = _GetRequiredType("System.Enum"); mFriendAttributeTypeDef = _GetRequiredType("System.FriendAttribute"); @@ -6673,8 +6674,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) mNoExtensionAttributeTypeDef = _GetRequiredType("System.NoExtensionAttribute"); mCheckedAttributeTypeDef = _GetRequiredType("System.CheckedAttribute"); mUncheckedAttributeTypeDef = _GetRequiredType("System.UncheckedAttribute"); - mResultTypeDef = _GetRequiredType("System.Result", 1); - mFunctionTypeDef = _GetRequiredType("System.Function"); + mResultTypeDef = _GetRequiredType("System.Result", 1); mGCTypeDef = _GetRequiredType("System.GC"); mGenericIEnumerableTypeDef = _GetRequiredType("System.Collections.IEnumerable", 1); mGenericIEnumeratorTypeDef = _GetRequiredType("System.Collections.IEnumerator", 1); diff --git a/IDEHelper/Compiler/BfCompiler.h b/IDEHelper/Compiler/BfCompiler.h index 65c8eb83..03bcaec0 100644 --- a/IDEHelper/Compiler/BfCompiler.h +++ b/IDEHelper/Compiler/BfCompiler.h @@ -353,14 +353,14 @@ public: BfTypeDef* mDbgRawAllocDataTypeDef; BfTypeDef* mDeferredCallTypeDef; BfTypeDef* mDelegateTypeDef; + BfTypeDef* mFunctionTypeDef; BfTypeDef* mActionTypeDef; BfTypeDef* mEnumTypeDef; BfTypeDef* mStringTypeDef; BfTypeDef* mStringViewTypeDef; BfTypeDef* mTypeTypeDef; BfTypeDef* mValueTypeTypeDef; - BfTypeDef* mResultTypeDef; - BfTypeDef* mFunctionTypeDef; + BfTypeDef* mResultTypeDef; BfTypeDef* mGCTypeDef; BfTypeDef* mGenericIEnumerableTypeDef; BfTypeDef* mGenericIEnumeratorTypeDef; diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 37d9eec9..351dbdd4 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -3425,10 +3425,11 @@ void BfModule::AddDependency(BfType* usedType, BfType* userType, BfDependencyMap BfModule* usedModule; if (usedType->IsFunction()) { - auto typeInst = usedType->ToTypeInstance(); - if (typeInst->mBaseType == NULL) - PopulateType(typeInst); - usedModule = typeInst->mBaseType->GetModule(); + if (mCompiler->mFunctionTypeDef != NULL) + { + auto functionType = ResolveTypeDef(mCompiler->mFunctionTypeDef)->ToTypeInstance(); + usedModule = functionType->GetModule(); + } } else usedModule = usedType->GetModule(); @@ -7217,7 +7218,7 @@ BfIRFunction BfModule::GetBuiltInFunc(BfBuiltInFuncType funcTypeId) return mBuiltInFuncs[(int)funcTypeId]; } -void BfModule::ResolveGenericParamConstraints(BfGenericParamInstance* genericParamInstance, bool isUnspecialized) +void BfModule::ResolveGenericParamConstraints(BfGenericParamInstance* genericParamInstance, bool isUnspecialized, Array* deferredResolveTypes) { BfGenericParamDef* genericParamDef = genericParamInstance->GetGenericParamDef(); BfExternalConstraintDef* externConstraintDef = genericParamInstance->GetExternConstraintDef(); @@ -7323,14 +7324,23 @@ void BfModule::ResolveGenericParamConstraints(BfGenericParamInstance* genericPar if (bfAutocomplete != NULL) bfAutocomplete->CheckTypeRef(constraintTypeRef, true); //TODO: Constraints may refer to other generic params (of either type or method) - // TO allow resolution, perhaps move this generic param initalization into GetMethodInstance (passing a genericPass bool) + // TO allow resolution, perhaps move this generic param initialization into GetMethodInstance (passing a genericPass bool) BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_AllowGenericMethodParamConstValue; if (isUnspecialized) resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_DisallowComptime); - auto constraintType = ResolveTypeRef(constraintTypeRef, BfPopulateType_Declaration, resolveFlags); + // We we have a deferredResolveTypes then we defer the generic validation, because we may have a case like + // `where T : Dictionay and TElem : IHashable` and we don't want to throw the error on `T` before we build `TElem` + auto constraintType = ResolveTypeRef(constraintTypeRef, (deferredResolveTypes != NULL) ? BfPopulateType_Identity : BfPopulateType_Declaration, resolveFlags); if (constraintType != NULL) - { + { + if (deferredResolveTypes != NULL) + { + PopulateType(constraintType, BfPopulateType_Declaration); + if (constraintType->IsUnspecializedTypeVariation()) + deferredResolveTypes->Add(constraintTypeRef); + } + if ((constraintDef->mGenericParamFlags & BfGenericParamFlag_Const) != 0) { bool isValidTypeCode = false; @@ -7511,11 +7521,11 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS origCheckArgType = origCheckArgType->GetUnderlyingType(); bool argMayBeReferenceType = false; - + int checkGenericParamFlags = 0; if (checkArgType->IsGenericParam()) { - auto checkGenericParamInst = GetGenericParamInstance((BfGenericParamType*)checkArgType); + BfGenericParamInstance* checkGenericParamInst = GetGenericParamInstance((BfGenericParamType*)checkArgType); checkGenericParamFlags = checkGenericParamInst->mGenericParamFlags; if (checkGenericParamInst->mTypeConstraint != NULL) checkArgType = checkGenericParamInst->mTypeConstraint; @@ -7849,7 +7859,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS if (TypeIsSubTypeOf(wrappedStructType, typeConstraintInst)) implementsInterface = true; } - + if (!implementsInterface) { if ((!ignoreErrors) && (PreFail())) @@ -21616,6 +21626,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool { BfTypeInstance* unspecializedTypeInstance = NULL; + Array deferredResolveTypes; for (int genericParamIdx = 0; genericParamIdx < (int)methodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++) { auto genericParam = methodInstance->mMethodInfoEx->mGenericParams[genericParamIdx]; @@ -21639,8 +21650,8 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool else genericParam->mExternType = GetPrimitiveType(BfTypeCode_Var); } - - ResolveGenericParamConstraints(genericParam, methodInstance->mIsUnspecialized); + + ResolveGenericParamConstraints(genericParam, methodInstance->mIsUnspecialized, &deferredResolveTypes); if (genericParamIdx < (int)methodDef->mGenericParams.size()) { @@ -21654,6 +21665,8 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool } } } + for (auto typeRef : deferredResolveTypes) + auto constraintType = ResolveTypeRef(typeRef, BfPopulateType_Declaration, BfResolveTypeRefFlag_None); for (auto genericParam : methodInstance->mMethodInfoEx->mGenericParams) { diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 5ae6babe..ed3dcf89 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -1778,7 +1778,7 @@ public: bool TypeEquals(BfTypedValue& val, BfType* type); BfTypeDef* ResolveGenericInstanceDef(BfGenericInstanceTypeRef* genericTypeRef, BfType** outType = NULL, BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None); BfType* ResolveType(BfType* lookupType, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None); - void ResolveGenericParamConstraints(BfGenericParamInstance* genericParamInstance, bool isUnspecialized); + void ResolveGenericParamConstraints(BfGenericParamInstance* genericParamInstance, bool isUnspecialized, Array* deferredResolveTypes = NULL); String GenericParamSourceToString(const BfGenericParamSource& genericParamSource); bool CheckGenericConstraints(const BfGenericParamSource& genericParamSource, BfType* checkArgType, BfAstNode* checkArgTypeRef, BfGenericParamInstance* genericParamInst, BfTypeVector* methodGenericArgs = NULL, BfError** errorOut = NULL); BfIRValue AllocLocalVariable(BfType* type, const StringImpl& name, bool doLifetimeEnd = true); diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 9f2df9a8..300df1aa 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -164,7 +164,8 @@ bool BfModule::FinishGenericParams(BfType* resolvedTypeRef) typeState.mResolveKind = BfTypeState::ResolveKind_BuildingGenericParams; typeState.mTypeInstance = resolvedTypeRef->ToTypeInstance(); SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); - + Array deferredResolveTypes; + BF_ASSERT(mCurMethodInstance == NULL); auto genericTypeInst = resolvedTypeRef->ToGenericTypeInstance(); @@ -210,7 +211,7 @@ bool BfModule::FinishGenericParams(BfType* resolvedTypeRef) genericParamInstance->mExternType = GetPrimitiveType(BfTypeCode_Var); } - ResolveGenericParamConstraints(genericParamInstance, genericTypeInst->IsUnspecializedType()); + ResolveGenericParamConstraints(genericParamInstance, genericTypeInst->IsUnspecializedType(), &deferredResolveTypes); if (genericParamDef != NULL) { @@ -283,7 +284,7 @@ bool BfModule::FinishGenericParams(BfType* resolvedTypeRef) genericParamInstance->mExternType = GetPrimitiveType(BfTypeCode_Var); } - ResolveGenericParamConstraints(genericParamInstance, genericTypeInst->IsUnspecializedType()); + ResolveGenericParamConstraints(genericParamInstance, genericTypeInst->IsUnspecializedType(), &deferredResolveTypes); auto genericParamDef = genericParamInstance->GetGenericParamDef(); if (genericParamDef != NULL) { @@ -295,6 +296,9 @@ bool BfModule::FinishGenericParams(BfType* resolvedTypeRef) } } + for (auto typeRef : deferredResolveTypes) + auto constraintType = ResolveTypeRef(typeRef, BfPopulateType_Declaration, BfResolveTypeRefFlag_None); + for (auto genericParam : genericTypeInst->mGenericTypeInfo->mGenericParams) { for (auto constraintTypeInst : genericParam->mInterfaceConstraints) @@ -339,6 +343,13 @@ bool BfModule::ValidateGenericConstraints(BfTypeReference* typeRef, BfTypeInstan return true; } + for (auto typeArg : genericTypeInst->mGenericTypeInfo->mTypeGenericArguments) + { + auto genericArg = typeArg->ToGenericTypeInstance(); + if (genericArg != NULL) + genericTypeInst->mGenericTypeInfo->mMaxGenericDepth = BF_MAX(genericTypeInst->mGenericTypeInfo->mMaxGenericDepth, genericArg->mGenericTypeInfo->mMaxGenericDepth + 1); + } + auto typeDef = genericTypeInst->mTypeDef; for (int paramIdx = 0; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mGenericParams.size(); paramIdx++) { @@ -4973,7 +4984,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) // { - if (typeInstance->IsSpecializedType()) + if ((typeInstance->IsSpecializedType()) || (typeInstance->IsUnspecializedTypeVariation())) wantsOnDemandMethods = true; else if ((mCompiler->mOptions.mCompileOnDemandKind != BfCompileOnDemandKind_AlwaysInclude) && (!typeInstance->IsUnspecializedTypeVariation())) @@ -7939,7 +7950,7 @@ bool BfModule::ResolveTypeResult_Validate(BfTypeReference* typeRef, BfType* reso if ((curGenericTypeInstance->mDependencyMap.mMinDependDepth > 32) && (genericTypeInstance->mDependencyMap.mMinDependDepth > 32)) { - Fail(StrFormat("Generic type dependency depth exceeded for type '{}'", TypeToString(genericTypeInstance).c_str()), typeRef); + Fail(StrFormat("Generic type dependency depth exceeded for type '%s'", TypeToString(genericTypeInstance).c_str()), typeRef); return false; } @@ -9724,7 +9735,14 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula CheckUnspecializedGenericType(genericTypeInst, populateType); resolvedEntry->mValue = genericTypeInst; populateModule->InitType(genericTypeInst, populateType); - BF_ASSERT(BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) == resolvedEntry->mHash); +#ifdef _DEBUG + if (BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) != resolvedEntry->mHash) + { + int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx); + int typeHash = BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx); + BF_ASSERT(refHash == typeHash); + } +#endif return ResolveTypeResult(typeRef, genericTypeInst, populateType, resolveFlags); } } @@ -9978,15 +9996,16 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula auto parentTypeInstance = outerTypeInstance; if (parentTypeInstance->IsTypeAlias()) parentTypeInstance = (BfTypeInstance*)GetOuterType(parentTypeInstance)->ToTypeInstance(); + genericTypeInst->mGenericTypeInfo->mMaxGenericDepth = BF_MAX(genericTypeInst->mGenericTypeInfo->mMaxGenericDepth, parentTypeInstance->mGenericTypeInfo->mMaxGenericDepth); for (int i = 0; i < startDefGenericParamIdx; i++) { genericTypeInst->mGenericTypeInfo->mGenericParams.push_back(parentTypeInstance->mGenericTypeInfo->mGenericParams[i]->AddRef()); genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.push_back(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i]); auto typeGenericArg = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[i]; genericTypeInst->mGenericTypeInfo->mIsUnspecialized |= typeGenericArg->IsGenericParam() || typeGenericArg->IsUnspecializedType(); + } - } - + } int wantedGenericParams = genericParamCount - startDefGenericParamIdx; int genericArgDiffCount = (int)genericArguments.size() - wantedGenericParams; @@ -10005,14 +10024,28 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula for (auto genericArgRef : genericArguments) { auto genericArg = genericArgs[genericParamIdx + startDefGenericParamIdx]; + + if (auto genericGenericArg = genericArg->ToGenericTypeInstance()) + { + genericTypeInst->mGenericTypeInfo->mMaxGenericDepth = BF_MAX(genericTypeInst->mGenericTypeInfo->mMaxGenericDepth, genericGenericArg->mGenericTypeInfo->mMaxGenericDepth + 1); + } + genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.push_back(genericArg); genericTypeInst->mGenericTypeInfo->mTypeGenericArgumentRefs.push_back(genericArgRef); genericParamIdx++; } - resolvedEntry->mValue = genericTypeInst; + if (genericTypeInst->mGenericTypeInfo->mMaxGenericDepth > 64) + { + Fail("Maximum generic depth exceeded", typeRef); + delete genericTypeInst; + mContext->mResolvedTypes.RemoveEntry(resolvedEntry); + return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags); + } + resolvedEntry->mValue = genericTypeInst; + CheckUnspecializedGenericType(genericTypeInst, populateType); populateModule->InitType(genericTypeInst, populateType); @@ -10027,6 +10060,8 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula { BF_ASSERT(BfResolvedTypeSet::Equals(genericTypeInst, typeRef, &lookupCtx)); } + + BfLogSysM("Generic type %p typeHash: %8X\n", genericTypeInst, resolvedEntry->mHash); #endif BF_ASSERT(BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) == resolvedEntry->mHash); @@ -10161,7 +10196,14 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula CheckUnspecializedGenericType(genericTypeInst, populateType); resolvedEntry->mValue = genericTypeInst; - BF_ASSERT(BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) == resolvedEntry->mHash); +#ifdef _DEBUG + if (BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) != resolvedEntry->mHash) + { + int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx); + int typeHash = BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx); + BF_ASSERT(refHash == typeHash); + } +#endif populateModule->InitType(genericTypeInst, populateType); return ResolveTypeResult(typeRef, genericTypeInst, populateType, resolveFlags); } diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index a3335f72..2d71d37a 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -2723,6 +2723,8 @@ BfResolvedTypeSet::~BfResolvedTypeSet() } +#define HASH_MIX(origHashVal, newHashVal) ((((origHashVal) << 5) - (origHashVal)) ^ (newHashVal)) + #define HASH_VAL_PTR 1 #define HASH_VAL_BOXED 2 #define HASH_VAL_REF 3 @@ -2769,7 +2771,7 @@ BfVariant BfResolvedTypeSet::EvaluateToVariant(LookupContext* ctx, BfExpression* return variant; } -int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef) +int BfResolvedTypeSet::DoHash(BfType* type, LookupContext* ctx, bool allowRef, int hashSeed) { //BP_ZONE("BfResolvedTypeSet::Hash"); @@ -2875,8 +2877,8 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef) else if (type->IsGenericTypeInstance()) { BfTypeInstance* genericType = (BfTypeInstance*)type; - for (auto genericArg : genericType->mGenericTypeInfo->mTypeGenericArguments) - hashVal = ((hashVal ^ (Hash(genericArg, ctx))) << 5) - hashVal; + for (auto genericArg : genericType->mGenericTypeInfo->mTypeGenericArguments) + hashVal = HASH_MIX(hashVal, Hash(genericArg, ctx, BfHashFlag_None, hashSeed + 1)); } return hashVal; } @@ -2952,21 +2954,29 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef) return 0; } -void BfResolvedTypeSet::HashGenericArguments(BfTypeReference* typeRef, LookupContext* ctx, int& hashVal) +int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef, int hashSeed) +{ + int hashVal = DoHash(type, ctx, allowRef, hashSeed); + if (hashSeed == 0) + return hashVal; + return HASH_MIX(hashVal, hashSeed); +} + +void BfResolvedTypeSet::HashGenericArguments(BfTypeReference* typeRef, LookupContext* ctx, int& hashVal, int hashSeed) { if (auto elementedTypeRef = BfNodeDynCast(typeRef)) { - HashGenericArguments(elementedTypeRef->mElementType, ctx, hashVal); + HashGenericArguments(elementedTypeRef->mElementType, ctx, hashVal, hashSeed); } else if (auto qualifiedTypeRef = BfNodeDynCast(typeRef)) { - HashGenericArguments(qualifiedTypeRef->mLeft, ctx, hashVal); + HashGenericArguments(qualifiedTypeRef->mLeft, ctx, hashVal, hashSeed); } if (auto genericTypeRef = BfNodeDynCast(typeRef)) { for (auto genericArg : genericTypeRef->mGenericArguments) - hashVal = ((hashVal ^ (Hash(genericArg, ctx, BfHashFlag_AllowGenericParamConstValue))) << 5) - hashVal; + hashVal = HASH_MIX(hashVal, Hash(genericArg, ctx, BfHashFlag_AllowGenericParamConstValue, hashSeed + 1)); } } @@ -2978,7 +2988,7 @@ static int HashNode(BfAstNode* node) return (int)Hash64(nameStr, node->GetSrcLength()); } -int BfResolvedTypeSet::DirectHash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags) +int BfResolvedTypeSet::DirectHash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags, int hashSeed) { bool isHeadType = typeRef == ctx->mRootTypeRef; @@ -2992,7 +3002,7 @@ int BfResolvedTypeSet::DirectHash(BfTypeReference* typeRef, LookupContext* ctx, ctx->mFailed = true; return 0; } - return Hash(resolvedType, ctx); + return Hash(resolvedType, ctx, BfHashFlag_None, hashSeed); } BfTypeDef* BfResolvedTypeSet::FindRootCommonOuterType(BfTypeDef* outerType, LookupContext* ctx, BfTypeInstance*& outOuterTypeInstance) @@ -3022,7 +3032,7 @@ BfTypeDef* BfResolvedTypeSet::FindRootCommonOuterType(BfTypeDef* outerType, Look return commonOuterType; } -int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags) +int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags, int& hashSeed) { if ((typeRef == ctx->mRootTypeRef) && (ctx->mRootTypeDef != NULL) && ((typeRef->IsNamedTypeReference()) || (BfNodeIsA(typeRef)))) @@ -3074,8 +3084,8 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash auto curGenericTypeInst = (BfTypeInstance*)checkTypeInstance; int numParentGenericParams = (int)commonOuterType->mGenericParamDefs.size(); for (int i = 0; i < numParentGenericParams; i++) - { - hashVal = ((hashVal ^ (Hash(curGenericTypeInst->mGenericTypeInfo->mTypeGenericArguments[i], ctx))) << 5) - hashVal; + { + hashVal = HASH_MIX(hashVal, Hash(curGenericTypeInst->mGenericTypeInfo->mTypeGenericArguments[i], ctx, BfHashFlag_None, hashSeed + 1)); } } @@ -3084,7 +3094,9 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash if (typeRef->IsNamedTypeReference()) { - return DirectHash(typeRef, ctx, flags); + int hashVal = DirectHash(typeRef, ctx, flags, hashSeed); + hashSeed = 0; + return hashVal; } if (auto genericInstTypeRef = BfNodeDynCastExact(typeRef)) { @@ -3157,12 +3169,12 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash { auto parentTypeInstance = checkTypeInstance; int numParentGenericParams = (int)commonOuterType->mGenericParamDefs.size(); - for (int i = 0; i < numParentGenericParams; i++) - hashVal = ((hashVal ^ (Hash(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i], ctx))) << 5) - hashVal; + for (int i = 0; i < numParentGenericParams; i++) + hashVal = HASH_MIX(hashVal, Hash(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i], ctx, Beefy::BfResolvedTypeSet::BfHashFlag_None, hashSeed + 1)); } } - HashGenericArguments(genericInstTypeRef, ctx, hashVal); + HashGenericArguments(genericInstTypeRef, ctx, hashVal, hashSeed); return hashVal; } @@ -3296,8 +3308,8 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash if (ctx->mRootTypeRef == typeRef) ctx->mRootTypeDef = ctx->mModule->mCompiler->mNullableTypeDef; - int hashVal = ctx->mModule->mCompiler->mNullableTypeDef->mHash; - hashVal = ((hashVal ^ (Hash(nullableType->mElementType, ctx))) << 5) - hashVal; + int hashVal = ctx->mModule->mCompiler->mNullableTypeDef->mHash; + hashVal = HASH_MIX(hashVal, Hash(nullableType->mElementType, ctx, BfHashFlag_None, hashSeed + 1)); return hashVal; } else if (auto refType = BfNodeDynCastExact(typeRef)) @@ -3510,7 +3522,9 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash return 0; } - return Hash(cachedResolvedType, ctx, flags); + int hashVal = Hash(cachedResolvedType, ctx, flags, hashSeed); + hashSeed = 0; + return hashVal; } else if (auto constExprTypeRef = BfNodeDynCastExact(typeRef)) { @@ -3546,6 +3560,14 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash return 0; } +int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags, int hashSeed) +{ + int hashVal = DoHash(typeRef, ctx, flags, hashSeed); + if (hashSeed == 0) + return hashVal; + return HASH_MIX(hashVal, hashSeed); +} + // These types can be from different contexts ("foreign" types) so we can't just compare ptrs bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx) { diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.h b/IDEHelper/Compiler/BfResolvedTypeUtils.h index 097a3ea6..bfea6ed0 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.h +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.h @@ -1774,6 +1774,7 @@ public: bool mInitializedGenericParams; bool mFinishedGenericParams; Array mProjectsReferenced; // Generic methods that only refer to these projects don't need a specialized extension + int32 mMaxGenericDepth; public: BfGenericTypeInfo() @@ -1785,6 +1786,7 @@ public: mValidatedGenericConstraints = false; mInitializedGenericParams = false; mFinishedGenericParams = false; + mMaxGenericDepth = -1; } ~BfGenericTypeInfo(); @@ -2525,10 +2527,12 @@ public: static BfVariant EvaluateToVariant(LookupContext* ctx, BfExpression* expr, BfType*& outType); static bool GenericTypeEquals(BfTypeInstance* lhsGenericType, BfTypeVector* lhsTypeGenericArguments, BfTypeReference* rhs, LookupContext* ctx, int& genericParamOffset); static bool GenericTypeEquals(BfTypeInstance* lhsGenericType, BfTypeVector* typeGenericArguments, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx); - static void HashGenericArguments(BfTypeReference* typeRef, LookupContext* ctx, int& hash); - static int Hash(BfType* type, LookupContext* ctx, bool allowRef = false); - static int DirectHash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags = BfHashFlag_None); - static int Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags = BfHashFlag_None); + static void HashGenericArguments(BfTypeReference* typeRef, LookupContext* ctx, int& hash, int hashSeed); + static int DoHash(BfType* type, LookupContext* ctx, bool allowRef, int hashSeed); + static int Hash(BfType* type, LookupContext* ctx, bool allowRef = false, int hashSeed = 0); + static int DirectHash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags = BfHashFlag_None, int hashSeed = 0); + static int DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags, int& hashSeed); + static int Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags = BfHashFlag_None, int hashSeed = 0); static bool Equals(BfType* lhs, BfType* rhs, LookupContext* ctx); static bool Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* ctx); static bool Equals(BfType* lhs, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx); diff --git a/IDEHelper/Tests/src/Classes.bf b/IDEHelper/Tests/src/Classes.bf index b4d4c0f0..03e1fdee 100644 --- a/IDEHelper/Tests/src/Classes.bf +++ b/IDEHelper/Tests/src/Classes.bf @@ -1,3 +1,4 @@ +using System; namespace Tests { class Classes @@ -22,5 +23,22 @@ namespace Tests { } } + + class ClassA + { + //public ClassA> mVal; + + public ClassA> GetRecursive() + { + return null; + } + } + + [Test] + static void TestBasics() + { + ClassA ca = scope .(); + Test.Assert(typeof(decltype(ca.GetRecursive())) == typeof(ClassA>)); + } } } diff --git a/IDEHelper/Tests/src/Generics2.bf b/IDEHelper/Tests/src/Generics2.bf index 390b6892..98ef35d3 100644 --- a/IDEHelper/Tests/src/Generics2.bf +++ b/IDEHelper/Tests/src/Generics2.bf @@ -95,6 +95,16 @@ namespace Tests } } + class IFaceA where T0 : Dictionary where T1 : IHashable + { + Dictionary mDict; + } + + public static void MethodA() where T0 : Dictionary where T1 : IHashable + { + + } + [Test] public static void TestBasics() { From a9c82d41250cd901a98da2abdc989726c831e9db Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Tue, 16 Feb 2021 15:03:53 -0800 Subject: [PATCH 55/71] Added Beef.Linq to CI tests --- IDEHelper/Tests/Beef.Linq/BeefSpace.toml | 2 + IDEHelper/Tests/Beef.Linq/src/BeefProj.toml | 7 + .../Tests/Beef.Linq/src/src/Enumerable.bf | 2868 +++++++++++++++++ .../Tests/Beef.Linq/src/test/BeefProj.toml | 8 + .../Beef.Linq/src/test/src/EnumerableTests.bf | 777 +++++ bin/test_build.bat | 4 + 6 files changed, 3666 insertions(+) create mode 100644 IDEHelper/Tests/Beef.Linq/BeefSpace.toml create mode 100644 IDEHelper/Tests/Beef.Linq/src/BeefProj.toml create mode 100644 IDEHelper/Tests/Beef.Linq/src/src/Enumerable.bf create mode 100644 IDEHelper/Tests/Beef.Linq/src/test/BeefProj.toml create mode 100644 IDEHelper/Tests/Beef.Linq/src/test/src/EnumerableTests.bf diff --git a/IDEHelper/Tests/Beef.Linq/BeefSpace.toml b/IDEHelper/Tests/Beef.Linq/BeefSpace.toml new file mode 100644 index 00000000..c8a1ef89 --- /dev/null +++ b/IDEHelper/Tests/Beef.Linq/BeefSpace.toml @@ -0,0 +1,2 @@ +FileVersion = 1 +Projects = {"Beef.Linq" = {Path = "src"}, "Beef.Linq.Tests" = {Path = "src/test"}} diff --git a/IDEHelper/Tests/Beef.Linq/src/BeefProj.toml b/IDEHelper/Tests/Beef.Linq/src/BeefProj.toml new file mode 100644 index 00000000..858ac746 --- /dev/null +++ b/IDEHelper/Tests/Beef.Linq/src/BeefProj.toml @@ -0,0 +1,7 @@ +FileVersion = 1 + +[Project] +Name = "Beef.Linq" +TargetType = "BeefLib" +StartupObject = "Beef.Linq.Program" +DefaultNamespace = "System.Linq" diff --git a/IDEHelper/Tests/Beef.Linq/src/src/Enumerable.bf b/IDEHelper/Tests/Beef.Linq/src/src/Enumerable.bf new file mode 100644 index 00000000..f855bcc7 --- /dev/null +++ b/IDEHelper/Tests/Beef.Linq/src/src/Enumerable.bf @@ -0,0 +1,2868 @@ +using System.Collections; +using System; +using internal System.Linq; + +namespace System.Linq +{ + public static + { + public static class Enumerable + { + public struct EmptyEnumerable : IEnumerable + { + public Enumerator GetEnumerator() => .(); + + public struct Enumerator : IEnumerator + { + public Result GetNext() + { + return .Err; + } + } + } + + public static EmptyEnumerable Empty() => .(); + + public struct RangeEnumerable : IEnumerable where TSource : operator TSource + int + { + TSource mStart; + TSource mEnd; + + public this(TSource start, TSource end) + { + mStart = start; + mEnd = end; + } + + public Enumerator GetEnumerator() => .(mStart, mEnd); + + public struct Enumerator : IEnumerator + { + TSource mCurrent; + TSource mEnd; + + public this(TSource start, TSource end) + { + mCurrent = start; + mEnd = end; + } + + public Result GetNext() mut + { + if (mCurrent == mEnd) + return .Err; + + let next = mCurrent; + mCurrent = mCurrent + 1; + return .Ok(next); + } + } + } + + public static RangeEnumerable + Range(TSource count) + where TSource : operator TSource + int + { + return .(default, count); + } + + public static RangeEnumerable + Range(TSource start, TSource end) + where TSource : operator TSource + int + where TSource : operator TSource + TSource + { + return .(start, end); + } + + public struct RepeatEnumerable : IEnumerable + { + TSource mValue; + int mCount; + + public this(TSource value, int count) + { + mValue = value; + mCount = count; + } + + public Enumerator GetEnumerator() => .(mValue, mCount); + + public struct Enumerator : IEnumerator + { + TSource mValue; + int mCount; + + public this(TSource value, int count) + { + mValue = value; + mCount = count; + } + + public Result GetNext() mut + { + if (--mCount >= 0) + return .Ok(mValue); + + return .Err; + } + } + } + + public static RepeatEnumerable + Repeat(TSource value, int count) + { + return .(value, count); + } + } + + + #region Matching + public static bool All(this TEnum items, TPredicate predicate) + where TEnum : concrete, IEnumerator + where TPredicate : delegate bool(TSource) + { + return InternalAll(items, predicate); + } + + public static bool All(this TCollection items, TPredicate predicate) + where TCollection : concrete, IEnumerable + where TPredicate : delegate bool(TSource) + { + return InternalAll(items.GetEnumerator(), predicate); + } + + static bool InternalAll(TEnum items, TPredicate predicate) + where TEnum : concrete, IEnumerator + where TPredicate : delegate bool(TSource) + { + using (var iterator = Iterator.Wrap(items)) + { + var enumerator = iterator.mEnum; + switch (enumerator.GetNext()) + { + case .Ok(let val): if (!predicate(val)) return false; + case .Err: return false; + } + + while (enumerator.GetNext() case .Ok(let val)) + if (!predicate(val)) + return false; + + return true; + } + } + + public static bool Any(this TCollection items) + where TCollection : concrete, IEnumerable + { + for (var it in items) + return true; + + return false; + } + + public static bool Any(this TCollection items, TPredicate predicate) + where TCollection : concrete, IEnumerable + where TPredicate : delegate bool(TSource) + { + for (var it in items) + if (predicate(it)) + return true; + + return false; + } + + public static bool Any(this TEnum items) + where TEnum : concrete, IEnumerator + { + for (var it in items) + return true; + + return false; + } + + public static bool Any(this TEnum items, TPredicate predicate) + where TEnum : concrete, IEnumerator + where TPredicate : delegate bool(TSource) + { + for (var it in items) + if (predicate(it)) + return true; + + return false; + } + + public static bool Contains(this TCollection items, TSource source) + where TCollection : concrete, IEnumerable + where bool : operator TSource == TSource + { + for (var it in items) + if (it == source) + return true; + + return false; + } + + public static bool Contains(this TEnum items, TSource source) + where TEnum : concrete, IEnumerator + where bool : operator TSource == TSource + { + for (var it in items) + if (it == source) + return true; + + return false; + } + + + public static bool SequenceEquals(this TLeft left, TRight right) + where TLeft : concrete, IEnumerable + where TRight : concrete, IEnumerable + where bool : operator TSource == TSource + { + return InternalSequenceEquals< + decltype(default(TLeft).GetEnumerator()), + decltype(default(TRight).GetEnumerator()), + TSource>(left.GetEnumerator(), right.GetEnumerator()); + } + + public static bool SequenceEquals(this TLeft left, TRight right) + where TLeft : concrete, IEnumerable + where TRight : concrete, IEnumerator + where bool : operator TSource == TSource + { + return InternalSequenceEquals< + decltype(default(TLeft).GetEnumerator()), + TRight, + TSource>(left.GetEnumerator(), right); + } + + public static bool SequenceEquals(this TLeft left, TRight right) + where TLeft : concrete, IEnumerator + where TRight : concrete, IEnumerable + where bool : operator TSource == TSource + { + return InternalSequenceEquals< + TLeft, + decltype(default(TRight).GetEnumerator()), + TSource>(left, right.GetEnumerator()); + } + + public static bool SequenceEquals(this TLeft left, TRight right) + where TLeft : concrete, IEnumerator + where TRight : concrete, IEnumerator + where bool : operator TSource == TSource + { + return InternalSequenceEquals(left, right); + } + + static bool InternalSequenceEquals(TLeft left, TRight right) + where TLeft : concrete, IEnumerator + where TRight : concrete, IEnumerator + where bool : operator TSource == TSource + { + using (var iterator0 = Iterator.Wrap(left)) + { + var e0 = iterator0.mEnum; + using (var iterator1 = Iterator.Wrap(right)) + { + var e1 = iterator1.mEnum; + while (true) + { + switch (e0.GetNext()) + { + case .Ok(let i0): + switch (e1.GetNext()) + { + case .Ok(let i1): + if (i0 != i1) + return false; + case .Err: + return false; + } + case .Err: + return e1.GetNext() case .Err; + } + } + } + } + } + + #endregion + + #region Aggregates + + public static TSource Average(this TCollection items) + where TCollection : concrete, IEnumerable + where TSource : operator TSource / int + where TSource : operator TSource + TSource + { + return InternalAverage(items.GetEnumerator()); + } + + public static TSource Average(this TEnum items) + where TEnum : concrete, IEnumerator + where TSource : operator TSource / int + where TSource : operator TSource + TSource + { + return InternalAverage(items); + } + + static TSource InternalAverage(TEnum items) + where TEnum : concrete, IEnumerator + where TSource : operator TSource / int + where TSource : operator TSource + TSource + { + var count = 0; + TSource sum = ?; + using (var iterator = Iterator.Wrap(items)) + { + var enumerator = iterator.mEnum; + + switch (enumerator.GetNext()) + { + case .Ok(let val): + sum = val; + count++; + case .Err: return default; + } + + while (enumerator.GetNext() case .Ok(let val)) + { + sum += val; + count++; + } + + return sum / count; + } + } + + public static TSource Max(this TCollection items) + where TCollection : concrete, IEnumerable + where bool : operator TSource < TSource + { + return InternalMax(items.GetEnumerator()); + } + + public static TSource Max(this TEnum items) + where TEnum : concrete, IEnumerator + where bool : operator TSource < TSource + { + return InternalMax(items); + } + + static TSource InternalMax(TEnum items) + where TEnum : concrete, IEnumerator + where bool : operator TSource < TSource + { + TSource max = ?; + using (var iterator = Iterator.Wrap(items)) + { + var enumerator = iterator.mEnum; + switch (enumerator.GetNext()) + { + case .Ok(let val): max = val; + case .Err: return default; + } + + while (enumerator.GetNext() case .Ok(let val)) + { + let next = val; + if (max < next) + max = next; + } + } + return max; + } + + public static TSource Min(this TCollection items) + where TCollection : concrete, IEnumerable + where bool : operator TSource < TSource + { + return InternalMin(items.GetEnumerator()); + } + + public static TSource Min(this TEnum items) + where TEnum : concrete, IEnumerator + where bool : operator TSource < TSource + { + return InternalMin(items); + } + + static TSource InternalMin(TEnum items) + where TEnum : concrete, IEnumerator + where bool : operator TSource < TSource + { + TSource min = ?; + using (var iterator = Iterator.Wrap(items)) + { + var enumerator = iterator.mEnum; + switch (enumerator.GetNext()) + { + case .Ok(let val): min = val; + case .Err: return default; + } + + while (enumerator.GetNext() case .Ok(let val)) + { + let next = val; + if (next < min) + min = next; + } + } + return min; + } + + public static TSource Sum(this TCollection items) + where TCollection : concrete, IEnumerable + where TPredicate : delegate bool(TSource) + where TSource : operator TSource + TSource + { + return InternalSum(items.GetEnumerator()); + } + + public static TSource Sum(this TEnum items) + where TEnum : concrete, IEnumerator + where TPredicate : delegate bool(TSource) + where TSource : operator TSource + TSource + { + return InternalSum(items); + } + + static TSource InternalSum(TEnum items) + where TEnum : concrete, IEnumerator + where TPredicate : delegate bool(TSource) + where TSource : operator TSource + TSource + { + TSource sum = ?; + using (var iterator = Iterator.Wrap(items)) + { + var enumerator = iterator.mEnum; + switch (enumerator.GetNext()) + { + case .Ok(let val): sum = val; + case .Err: return default; + } + + while (enumerator.GetNext() case .Ok(let val)) + sum += val; + } + return sum; + } + + public static int Count(this TCollection items) + where TCollection : concrete, IEnumerable + { + if (typeof(TCollection) == typeof(List)) + return (items as List).Count; + if (typeof(TCollection) == typeof(TSource[])) + return (items as TSource[]).Count; + + return InternalCount(items.GetEnumerator()); + } + + + public static int Count(this TEnum items) + where TEnum : concrete, IEnumerator + { + return InternalCount(items); + } + + public static int InternalCount(TEnum items) + where TEnum : concrete, IEnumerator + { + var count = 0; + using (var iterator = Iterator.Wrap(items)) + { + var enumerator = iterator.mEnum; + while (enumerator.GetNext() case .Ok) + count++; + } + return count; + } + + #endregion + + #region Find in enumerable + + internal static bool InternalElementAt(TEnum items, int index, out TSource val) + where TEnum : concrete, IEnumerator + { + var index; + using (var iterator = Iterator.Wrap(items)) + { + var enumerator = iterator.mEnum; + while (--index > 0) + { + if (enumerator.GetNext() case .Err) + break; + } + + if (index == 0 && enumerator.GetNext() case .Ok(out val)) + return true; + } + val = default; + return false; + } + + public static TSource ElementAt(this TCollection items, int index) + where TCollection : concrete, IEnumerable + { + if (InternalElementAt(items.GetEnumerator(), index, let val)) + return val; + + Runtime.FatalError("Not enough elements in the sequence."); + } + + public static TSource ElementAt(this TEnum items, int index) + where TEnum : concrete, IEnumerator + { + if (InternalElementAt(items, index, let val)) + return val; + + Runtime.FatalError("Not enough elements in the sequence."); + } + + public static TSource ElementAtOrDefault(this TCollection items, int index) + where TCollection : concrete, IEnumerable + { + if (InternalElementAt(items.GetEnumerator(), index, let val)) + return val; + + return default; + } + + public static TSource ElementAtOrDefault(this TEnum items, int index) + where TEnum : concrete, IEnumerator + { + if (InternalElementAt(items, index, let val)) + return val; + + return default; + } + + public static bool InternalFirst(TEnum items, out TSource val) + where TEnum : concrete, IEnumerator + { + using (var iterator = Iterator.Wrap(items)) + { + var enumerator = iterator.mEnum; + if (enumerator.GetNext() case .Ok(out val)) + return true; + } + + return false; + } + + public static TSource First(this TCollection items) + where TCollection : concrete, IEnumerable + { + if (InternalFirst(items.GetEnumerator(), let val)) + return val; + Runtime.FatalError("Sequence contained no elements."); + } + + public static TSource First(this TEnum items) + where TEnum : concrete, IEnumerator + { + if (InternalFirst(items, let val)) + return val; + Runtime.FatalError("Sequence contained no elements."); + } + + public static TSource FirstOrDefault(this TCollection items) + where TCollection : concrete, IEnumerable + { + if (InternalFirst(items.GetEnumerator(), let val)) + return val; + + return default; + } + + public static TSource FirstOrDefault(this TEnum items) + where TEnum : concrete, IEnumerator + { + if (InternalFirst(items, let val)) + return val; + + return default; + } + + internal static bool InternalLast(TEnum items, out TSource val) + where TEnum : concrete, IEnumerator + { + var found = false; + using (var iterator = Iterator.Wrap(items)) + { + var enumerator = iterator.mEnum; + if (enumerator.GetNext() case .Ok(out val)) + found = true; + + while (enumerator.GetNext() case .Ok(let temp)) + val = temp; + } + + return found; + } + + public static TSource Last(this TCollection items) + where TCollection : concrete, IEnumerable + { + if (InternalLast(items.GetEnumerator(), let val)) + return val; + + Runtime.FatalError("Sequence contained no elements."); + } + + public static TSource Last(this TEnum items) + where TEnum : concrete, IEnumerator + { + if (InternalLast(items, let val)) + return val; + + Runtime.FatalError("Sequence contained no elements."); + } + + public static TSource LastOrDefault(this TCollection items) + where TCollection : concrete, IEnumerable + { + if (InternalLast(items.GetEnumerator(), let val)) + return val; + + return default; + } + + public static TSource LastOrDefault(this TEnum items) + where TEnum : concrete, IEnumerator + { + if (InternalLast(items, let val)) + return val; + + return default; + } + + internal static bool InternalSingle(TEnum items, out TSource val) + where TEnum : concrete, IEnumerator + { + using (var iterator = Iterator.Wrap(items)) + { + var enumerator = iterator.mEnum; + + if (enumerator.GetNext() case .Ok(out val)) + { + if (enumerator.GetNext() case .Err) + return true; + + Runtime.FatalError("Sequence matched more than one element."); + } + } + + return false; + } + + public static TSource Single(this TCollection items) + where TCollection : concrete, IEnumerable + { + if (InternalSingle(items.GetEnumerator(), let val)) + return val; + + Runtime.FatalError("Sequence contained no elements."); + } + + public static TSource Single(this TEnum items) + where TEnum : concrete, IEnumerator + { + if (InternalSingle(items, let val)) + return val; + + Runtime.FatalError("Sequence contained no elements."); + } + + public static TSource SingleOrDefault(this TCollection items) + where TCollection : concrete, IEnumerable + { + if (InternalSingle(items.GetEnumerator(), let val)) + return val; + + return default; + } + + public static TSource SingleOrDefault(this TEnum items) + where TEnum : concrete, IEnumerator + { + if (InternalSingle(items, let val)) + return val; + + return default; + } + + #endregion + +#region Enumerable Chains + struct Iterator + { + public static Iterator Wrap(TEnum items) + where TEnum : concrete, IEnumerator + { + return .(items); + } + + public static Iterator Wrap(TCollection items) + where TCollection : concrete, IEnumerable + { + return .(items.GetEnumerator()); + } + } + + struct Iterator : IDisposable + where TEnum : concrete, IEnumerator + { + internal TEnum mEnum; + + public this(TEnum items) + { + mEnum = items; + } + + [SkipCall] + public void Dispose() mut { } + + public static implicit operator Iterator(TEnum enumerator) => .(enumerator); + } + + extension Iterator : IDisposable where TEnum : IDisposable + { + public void Dispose() mut => mEnum.Dispose(); + } + + struct SelectEnumerable : Iterator, IEnumerable + where TSelect : delegate TResult(TSource) + where TEnum : concrete, IEnumerator + { + TSelect mDlg; + + public this(TEnum e, TSelect dlg) : base(e) + { + mDlg = dlg; + } + + Result GetNext() mut + { + if (mEnum.GetNext() case .Ok(let val)) + return mDlg(val); + + return .Err; + } + + public Enumerator GetEnumerator() => .(this); + + public struct Enumerator : IEnumerator + { + SelfOuter mEnum; + public this(SelfOuter enumerator) + { + mEnum = enumerator; + } + public Result GetNext() mut => mEnum.GetNext(); + } + } + + public static SelectEnumerable + Select(this TCollection items, TSelect select) + where TCollection : concrete, IEnumerable + where TSelect : delegate TResult(TSource) + { + return .(items.GetEnumerator(), select); + } + + public static SelectEnumerable + Select(this TEnum items, TSelect select) + where TEnum : concrete, IEnumerator + where TSelect : delegate TResult(TSource) + { + return .(items, select); + } + + struct WhereEnumerable : IEnumerable, IDisposable + where TPredicate : delegate bool(TSource) + where TEnum : concrete, IEnumerator + { + TPredicate mPredicate; + Iterator mIterator; + + public this(TEnum enumerator, TPredicate predicate) + { + mIterator = enumerator; + mPredicate = predicate; + } + + Result GetNext() mut + { + while (mIterator.mEnum.GetNext() case .Ok(let val)) + if (mPredicate(val)) + return .Ok(val); + + return .Err; + } + + public Enumerator GetEnumerator() => .(this); + + public struct Enumerator : IEnumerator, IDisposable + { + SelfOuter mSelf; + public this(SelfOuter self) + { + mSelf = self; + } + public Result GetNext() mut => mSelf.GetNext(); + + public void Dispose() mut + { + mSelf.Dispose(); + } + } + + public void Dispose() mut + { + mIterator.Dispose(); + } + } + + public static WhereEnumerable + Where(this TCollection items, TPredicate predicate) + where TCollection : concrete, IEnumerable + where TPredicate : delegate bool(TSource) + { + return .(items.GetEnumerator(), predicate); + } + + public static WhereEnumerable + Where(this TEnum items, TPredicate predicate) + where TEnum : concrete, IEnumerator + where TPredicate : delegate bool(TSource) + { + return .(items, predicate); + } + + struct TakeEnumerable : Iterator, IEnumerable + where TEnum : concrete, IEnumerator + { + int mCount; + + public this(TEnum enumerator, int count) : base(enumerator) + { + mCount = count; + } + + public Result GetNext() mut + { + while (mCount-- > 0 && mEnum.GetNext() case .Ok(let val)) + return val; + + return .Err; + } + + public Enumerator GetEnumerator() => .(this); + + public struct Enumerator : IEnumerator + { + SelfOuter mEnum; + public this(SelfOuter enumerator) + { + mEnum = enumerator; + } + public Result GetNext() mut => mEnum.GetNext(); + } + } + + public static TakeEnumerable + Take(this TCollection items, int count) + where TCollection : concrete, IEnumerable + { + return .(items.GetEnumerator(), count); + } + + public static TakeEnumerable + Take(this TEnum items, int count) + where TEnum : concrete, IEnumerator + { + return .(items, count); + } + + struct TakeWhileEnumerable : Iterator, IEnumerable + where TEnum : concrete, IEnumerator + where TPredicate : delegate bool(TSource) + { + TPredicate mPredicate; + + public this(TEnum enumerator, TPredicate predicate) : base(enumerator) + { + mPredicate = predicate; + } + + Result GetNext() mut + { + if (mEnum.GetNext() case .Ok(let val)) + if (mPredicate(val)) + return .Ok(val); + + return .Err; + } + + public Enumerator GetEnumerator() => .(this); + + public struct Enumerator : IEnumerator + { + SelfOuter mEnum; + public this(SelfOuter enumerator) + { + mEnum = enumerator; + } + public Result GetNext() mut => mEnum.GetNext(); + } + } + + public static TakeWhileEnumerable + TakeWhile(this TCollection items, TPredicate predicate) + where TCollection : concrete, IEnumerable + where TPredicate : delegate bool(TSource) + { + return .(items.GetEnumerator(), predicate); + } + + public static TakeWhileEnumerable + TakeWhile(this TEnum items, TPredicate predicate) + where TEnum : concrete, IEnumerator + where TPredicate : delegate bool(TSource) + { + return .(items, predicate); + } + + struct SkipEnumerable : Iterator, IEnumerable + where TEnum : concrete, IEnumerator + { + int mCount; + + public this(TEnum enumerator, int count) : base(enumerator) + { + mCount = count; + } + + public Result GetNext() mut + { + while (mCount-- > 0 && mEnum.GetNext() case .Ok(?)) { } + + while (mEnum.GetNext() case .Ok(let val)) + return val; + + return .Err; + } + + public Enumerator GetEnumerator() => .(this); + + public struct Enumerator : IEnumerator + { + SelfOuter mEnum; + public this(SelfOuter enumerator) + { + mEnum = enumerator; + } + public Result GetNext() mut => mEnum.GetNext(); + } + } + + public static SkipEnumerable + Skip(this TCollection items, int count) + where TCollection : concrete, IEnumerable + { + return .(items.GetEnumerator(), count); + } + + public static SkipEnumerable + Skip(this TEnum items, int count) + where TEnum : concrete, IEnumerator + { + return .(items, count); + } + + struct SkipWhileEnumerable : Iterator, IEnumerable + where TEnum : concrete, IEnumerator + where TPredicate : delegate bool(TSource) + { + TPredicate mPredicate; + int mState = 0; + + public this(TEnum enumerator, TPredicate predicate) : base(enumerator) + { + mPredicate = predicate; + } + + public Result GetNext() mut + { + switch (mState) { + case 0: + while (mEnum.GetNext() case .Ok(let val)) + { + if (!mPredicate(val)) + { + mState = 1; + return .Ok(val); + } + } + case 1: + return mEnum.GetNext(); + } + + return .Err; + } + + public Enumerator GetEnumerator() => .(this); + + public struct Enumerator : IEnumerator + { + SelfOuter mEnum; + public this(SelfOuter enumerator) + { + mEnum = enumerator; + } + public Result GetNext() mut => mEnum.GetNext(); + } + } + + public static SkipWhileEnumerable + SkipWhile(this TCollection items, TPredicate predicate) + where TCollection : concrete, IEnumerable + where TPredicate : delegate bool(TSource) + { + return .(items.GetEnumerator(), predicate); + } + + public static SkipWhileEnumerable + SkipWhile(this TEnum items, TPredicate predicate) + where TEnum : concrete, IEnumerator + where TPredicate : delegate bool(TSource) + { + return .(items, predicate); + } + + struct DefaultIfEmptyEnumerable : Iterator, IEnumerable + where TEnum : concrete, IEnumerator + { + TSource mDefaultValue; + int mState = 0; + + public this(TEnum enumerator, TSource defaultValue) : base(enumerator) + { + mDefaultValue = defaultValue; + } + + public Result GetNext() mut + { + switch (mState) { + case 0: + if (mEnum.GetNext() case .Ok(let val)) + { + mState = 1; + return .Ok(val); + } + + mState = 2; + return .Ok(mDefaultValue); + case 1: + return mEnum.GetNext(); + } + + return .Err; + } + + public Enumerator GetEnumerator() => .(this); + + public struct Enumerator : IEnumerator + { + SelfOuter mEnum; + public this(SelfOuter enumerator) + { + mEnum = enumerator; + } + public Result GetNext() mut => mEnum.GetNext(); + } + } + + public static DefaultIfEmptyEnumerable + DefaultIfEmpty(this TCollection items) + where TCollection : concrete, IEnumerable + { + return .(items.GetEnumerator(), default); + } + + public static DefaultIfEmptyEnumerable + DefaultIfEmpty(this TEnum items) + where TEnum : concrete, IEnumerator + { + return .(items, default); + } + + public static DefaultIfEmptyEnumerable + DefaultIfEmpty(this TCollection items, TSource defaultValue = default) + where TCollection : concrete, IEnumerable + { + return .(items.GetEnumerator(), defaultValue); + } + + public static DefaultIfEmptyEnumerable + DefaultIfEmpty(this TEnum items, TSource defaultValue = default) + where TEnum : concrete, IEnumerator + { + return .(items, defaultValue); + } + + struct DistinctEnumerable : IEnumerable, IDisposable + where TEnum : concrete, IEnumerator + where TSource : IHashable + { + HashSet mDistinctValues; + HashSet.Enumerator mEnum; + Iterator mIterator; + int mState = 0; + + public this(TEnum enumerator) + { + mIterator = .(enumerator); + mDistinctValues = new .(); + mEnum = default; + } + + public Result GetNext() mut + { + switch (mState) { + case 0: + var enumerator = mIterator.mEnum; + while (enumerator.GetNext() case .Ok(let val)) + mDistinctValues.Add(val); + + mIterator.Dispose(); + mIterator = default; + mEnum = mDistinctValues.GetEnumerator(); + mState = 1; + fallthrough; + case 1: + return mEnum.GetNext(); + } + + return .Err; + } + + public void Dispose() mut + { + mEnum.Dispose(); + DeleteAndNullify!(mDistinctValues); + } + + public Enumerator GetEnumerator() => .(this); + + public struct Enumerator : IEnumerator, IDisposable + { + SelfOuter mEnum; + public this(SelfOuter enumerator) + { + mEnum = enumerator; + } + public Result GetNext() mut => mEnum.GetNext(); + + public void Dispose() mut => mEnum.Dispose(); + } + } + + public static DistinctEnumerable + Distinct(this TCollection items) + where TCollection : concrete, IEnumerable + where TSource : IHashable + { + return .(items.GetEnumerator()); + } + + public static DistinctEnumerable + Distinct(this TEnum items) + where TEnum : concrete, IEnumerator + where TSource : IHashable + { + return .(items); + } + + struct ReverseEnumerable : IEnumerable, IDisposable + where TEnum : concrete, IEnumerator + { + List mCopyValues; + List.Enumerator mEnum; + Iterator mIterator; + int mIndex = -1; + + public this(TEnum enumerator) + { + mIterator = .(enumerator); + mCopyValues = new .(); + mEnum = default; + } + + public Result GetNext() mut + { + switch (mIndex) { + case -1: + var enumerator = mIterator.mEnum; + while (enumerator.GetNext() case .Ok(let val)) + mCopyValues.Add(val); + + mIterator.Dispose(); + mIterator = default; + mEnum = mCopyValues.GetEnumerator(); + mIndex = mCopyValues.Count; + fallthrough; + default: + if (--mIndex >= 0) + return .Ok(mCopyValues[mIndex]); + + return .Err; + } + } + + public void Dispose() mut + { + mEnum.Dispose(); + DeleteAndNullify!(mCopyValues); + } + + public Enumerator GetEnumerator() => .(this); + + public struct Enumerator : IEnumerator, IDisposable + { + SelfOuter mSelf; + public this(SelfOuter self) + { + mSelf = self; + } + public Result GetNext() mut => mSelf.GetNext(); + + public void Dispose() mut + { + mSelf.Dispose(); + } + } + } + + public static ReverseEnumerable + Reverse(this TCollection items) + where TCollection : concrete, IEnumerable + { + return .(items.GetEnumerator()); + } + + struct MapEnumerable : Iterator, IEnumerator, IEnumerable + where bool : operator TSource < TSource + where TSource : operator TSource - TSource + where TResult : operator TResult + TResult + where TResult : operator TResult - TResult + where float : operator float / TSource + where float : operator TSource * float + where float : operator float / TResult + where TResult : operator explicit float + where TEnum : concrete, IEnumerator + { + int mState = 0; + float mScale = 0f, mMapScale; + TSource mMin = default; + TResult mMapMin; + + public this(TEnum enumerator, TResult mapMin, TResult mapMax) : base(enumerator) + { + mMapMin = mapMin; + mMapScale = 1f / (mapMax - mapMin); + } + + public Result GetNext() mut + { + switch (mState) { + case 0: + var copyEnum = mEnum; + switch (copyEnum.GetNext()) { + case .Ok(let first): + var min = first; + var max = first; + + while (copyEnum.GetNext() case .Ok(let next)) + { + if (next < min) min = next; + if (max < next) max = next; + } + + mMin = min; + mScale = 1f / (max - min); + if (mScale == default) + { + mState = 2; + return .Ok(default); + } + + mState = 1; + case .Err: return .Err; + } + fallthrough; + case 1: + if (mEnum.GetNext() case .Ok(let val)) + return (TResult)(((val - mMin) * mScale) / mMapScale) + mMapMin; + case 2: + if (mEnum.GetNext() case .Ok(let val)) + return .Ok(default); + } + + return .Err; + } + + /*typealias SelfOuter = MapEnumerable; + public Enumerator GetEnumerator() => .(this); + + public struct Enumerator: IEnumerator + { + SelfOuter mEnum; + public this(SelfOuter enumerator) + { + mEnum = enumerator; + } + public Result GetNext() mut => mEnum.GetNext(); + }*/ + + public Self GetEnumerator() => this; + } + + public static MapEnumerable + Map(this TCollection items, TResult min, TResult max) + where TCollection : concrete, IEnumerable + where bool : operator TSource < TSource + where TSource : operator TSource - TSource + where TResult : operator TResult + TResult + where TResult : operator TResult - TResult + where float : operator float / TSource + where float : operator TSource * float + where float : operator float / TResult + where TResult : operator explicit float + { + return .(items.GetEnumerator(), min, max); + } + + public static MapEnumerable + Map(this TEnum items, TResult min, TResult max) + where TEnum : concrete, IEnumerator + where bool : operator TSource < TSource + where TSource : operator TSource - TSource + where TResult : operator TResult + TResult + where TResult : operator TResult - TResult + where float : operator float / TSource + where float : operator TSource * float + where float : operator float / TResult + where TResult : operator explicit float + { + return .(items, min, max); + } +#endregion + +#region ToXYZ methods + public static void ToDictionary(this TCollection items, TKeyDlg keyDlg, TValueDlg valueDlg, Dictionary output) + where TCollection : concrete, IEnumerable + where TKey : IHashable + where TKeyDlg : delegate TKey(TSource) + where TValueDlg : delegate TValue(TSource) + { + for (var it in items) + output.Add(keyDlg(it), valueDlg(it)); + } + + public static void ToDictionary(this TEnum items, TKeyDlg keyDlg, TValueDlg valueDlg, Dictionary output) + where TEnum : concrete, IEnumerator + where TKey : IHashable + where TKeyDlg : delegate TKey(TSource) + where TValueDlg : delegate TValue(TSource) + { + for (var it in items) + output.Add(keyDlg(it), valueDlg(it)); + } + + public static void ToDictionary(this TCollection items, TKeyDlg keyDlg, Dictionary output) + where TCollection : concrete, IEnumerable + where TKey : IHashable + where TKeyDlg : delegate TKey(TSource) + { + for (var it in items) + output.Add(keyDlg(it), it); + } + + public static void ToDictionary(this TEnum items, TKeyDlg keyDlg, Dictionary output) + where TEnum : concrete, IEnumerator + where TKey : IHashable + where TKeyDlg : delegate TKey(TSource) + { + for (var it in items) + output.Add(keyDlg(it), it); + } + + public static void ToHashSet(this TCollection items, HashSet output) + where TCollection : concrete, IEnumerable + where TSource : IHashable + { + for (var it in items) + output.Add(it); + } + + public static void ToHashSet(this TEnum items, HashSet output) + where TEnum : concrete, IEnumerator + where TSource : IHashable + { + for (var it in items) + output.Add(it); + } + + public static void ToList(this TCollection items, List output) + where TCollection : concrete, IEnumerable + { + for (var it in items) + output.Add(it); + } + + public static void ToList(this TEnum items, List output) + where TEnum : concrete, IEnumerator + { + for (var it in items) + output.Add(it); + } +#endregion + +#region Aggregates + public static TSource + Aggregate(this TCollection items, TAccumulate accumulate) + where TCollection : concrete, IEnumerable + where TAccumulate : delegate TSource(TSource, TSource) + { + if (InternalAggregate(items.GetEnumerator(), accumulate, let result)) + return result; + + Runtime.FatalError("No elements in the sequence."); + } + + public static TSource + Aggregate(this TEnum items, TAccumulate accumulate) + where TEnum : concrete, IEnumerator + where TAccumulate : delegate TSource(TSource, TSource) + { + if (InternalAggregate(items, accumulate, let result)) + return result; + + Runtime.FatalError("No elements in the sequence."); + } + + public static TAccumulate + Aggregate(this TCollection items, TAccumulate seed, TAccDlg accumulate) + where TCollection : concrete, IEnumerable + where TAccDlg : delegate TAccumulate(TAccumulate, TSource) + { + if (InternalAggregate(items.GetEnumerator(), seed, accumulate, let result)) + return result; + + return seed; + } + + public static TAccumulate + Aggregate(this TEnum items, TAccumulate seed, TAccDlg accumulate) + where TEnum : concrete, IEnumerator + where TAccDlg : delegate TAccumulate(TAccumulate, TSource) + { + if (InternalAggregate(items, seed, accumulate, let result)) + return result; + + return seed; + } + + public static TResult + Aggregate(this TCollection items, TAccDlg accumulate, TResDlg resultSelector) + where TCollection : concrete, IEnumerable + where TAccDlg : delegate TSource(TSource, TSource) + where TResDlg : delegate TResult(TSource) + { + if (InternalAggregate(items.GetEnumerator(), accumulate, let result)) + return resultSelector(result); + + return resultSelector(default); + } + + public static TResult + Aggregate(this TEnum items, TAccDlg accumulate, TResDlg resultSelector) + where TEnum : concrete, IEnumerator + where TAccDlg : delegate TSource(TSource, TSource) + where TResDlg : delegate TResult(TSource) + { + if (InternalAggregate(items, accumulate, let result)) + return resultSelector(result); + + return resultSelector(default); + } + + public static TResult + Aggregate(this TCollection items, TAccumulate seed, TAccDlg accumulate, TResDlg resultSelector) + where TCollection : concrete, IEnumerable + where TAccDlg : delegate TAccumulate(TAccumulate, TSource) + where TResDlg : delegate TResult(TAccumulate) + { + if (InternalAggregate(items.GetEnumerator(), seed, accumulate, let result)) + return resultSelector(result); + + return resultSelector(seed); + } + + public static TResult + Aggregate(this TEnum items, TAccumulate seed, TAccDlg accumulate, TResDlg resultSelector) + where TEnum : concrete, IEnumerator + where TAccDlg : delegate TAccumulate(TAccumulate, TSource) + where TResDlg : delegate TResult(TAccumulate) + { + if (InternalAggregate(items, seed, accumulate, let result)) + return resultSelector(result); + + return resultSelector(seed); + } + + static bool InternalAggregate(TEnum items, TAccDlg accumulate, out TSource aggregate) + where TEnum : concrete, IEnumerator + where TAccDlg : delegate TSource(TSource, TSource) + { + aggregate = default; + using (var iterator = Iterator.Wrap(items)) + { + var enumerator = iterator.mEnum; + + //I guess we need at least 2 elements to do an accumulation without a seed? + if (!(enumerator.GetNext() case .Ok(out aggregate))) + return false; + + while (enumerator.GetNext() case .Ok(let val)) + aggregate = accumulate(aggregate, val); + } + return true; + } + + + static bool InternalAggregate(TEnum items, TAccumulate seed, TAccDlg func, out TAccumulate result) + where TEnum : concrete, IEnumerator + where TAccDlg : delegate TAccumulate(TAccumulate, TSource) + { + TAccumulate sum = seed; + var accumulated = false; + using (var iterator = Iterator.Wrap(items)) + { + var enumerator = iterator.mEnum; + + if (enumerator.GetNext() case .Ok(let val)) + { + sum = func(sum, val); + accumulated = true; + } + + if (accumulated) + while (enumerator.GetNext() case .Ok(let val)) + sum = func(sum, val); + } + + result = sum; + return accumulated; + } + #endregion + +#region GroupBy + + struct DynamicArray : IDisposable + { + TValue[] mPtr = default; + Span mSpan = default; + int mLength = 0; + int mSize = 4; + int mIndex = 0; + + public int Length => mLength; + + public this() + { + this.mPtr = new TValue[mSize]; + this.mLength = 0; + } + + public ref TValue this[int index] => ref mPtr[index]; + + public void Dispose() mut + { + DeleteAndNullify!(mPtr); + mPtr = null; + } + public void Add(TValue value) mut + { + if (mLength + 1 > mSize) + { + var newSize = mSize * 3 / 2; + var dst = new TValue[newSize]; + Array.Copy(mPtr, dst, mLength); + Swap!(mPtr, dst); + delete dst; + mSize = newSize; + } + mPtr[mLength++] = value; + } + + public Span.Enumerator GetEnumerator() mut + { + mSpan = .(mPtr, 0, mLength); + return mSpan.GetEnumerator(); + } + + public static implicit operator Span(Self it) => .(it.mPtr, 0, it.mLength); + } + + public extension DynamicArray : IDisposable + where TValue : IDisposable + { + public void Dispose() mut + { + for (var it in mPtr) + it.Dispose(); + + base.Dispose(); + } + } + + public struct Grouping : IEnumerable, IDisposable, IResettable + { + List mValues; + int mIndex = 0; + public readonly TKey Key; + + public this(TKey key) + { + Key = key; + mValues = new .(); + } + + public void Reset() mut + { + mIndex = 0; + } + + public List.Enumerator GetEnumerator() + { + return mValues.GetEnumerator(); + } + + public void Add(TValue value) mut + { + mValues.Add(value); + } + + public void Dispose() mut + { + DeleteAndNullify!(mValues); + } + } + + public class GroupByResult : IEnumerable> + where bool : operator TKey == TKey//where TKey : IHashable + { + DynamicArray> mResults = .() ~ mResults.Dispose(); + + public int Count => mResults.Length; + + public void Add(Grouping group) + { + mResults.Add(group); + } + + public ref Grouping this[int index] => ref mResults[index]; + + public Enumerator GetEnumerator() => .(this); + + public struct Enumerator : IRefEnumerator*>, IEnumerator>, IResettable + { + SelfOuter mSelf; + Span> mSpan; + int mIndex = 0; + + public this(SelfOuter self) + { + mSelf = self; + mSpan = self.mResults; + } + + public Result> GetNext() mut + { + if (mIndex < mSpan.Length) + return .Ok(mSpan[mIndex++]); + + return .Err; + } + + public Result*> GetNextRef() mut + { + if (mIndex < mSpan.Length) + return .Ok(&mSpan[mIndex++]); + + return .Err; + } + + public void Reset() mut + { + mIndex = 0; + } + } + } + + public struct GroupByEnumerable : IEnumerable>, IDisposable + where TEnum : concrete, IEnumerator + where bool : operator TKey == TKey//where TKey : IHashable + where TKeyDlg : delegate TKey(TSource) + where TValueDlg : delegate TValue(TSource) + { + GroupByResult mResults; + TKeyDlg mKeyDlg; + TValueDlg mValueDlg; + Iterator mIterator; + int mIndex = -1; + bool mDeleteResult; + + public this(GroupByResult results, TEnum enumerator, TKeyDlg keyDlg, TValueDlg valueDlg, bool deleteResult) + { + mResults = results; + mIterator = .(enumerator); + mKeyDlg = keyDlg; + mValueDlg = valueDlg; + mDeleteResult = deleteResult; + } + + Result> GetNext() mut + { + if (mIndex == -1) + { + while (mIterator.mEnum.GetNext() case .Ok(let val)) + { + let k = mKeyDlg(val); + let v = mValueDlg(val); + var added = false; + for (var it in ref mResults) + { + if (it.Key == k) + { + it.Add(v); + added = true; + } + } + + if (!added) + { + var group = mResults.Add(.. .(k)); + group.Add(v); + } + } + mIndex = 0; + } + + if (mIndex < mResults.Count) + return mResults[mIndex++]; + + return .Err; + } + + public void Dispose() mut + { + mIterator.Dispose(); + if (mDeleteResult) + DeleteAndNullify!(mResults); + } + + public Enumerator GetEnumerator() => .(this); + + public struct Enumerator : IEnumerator>, IDisposable + { + SelfOuter mSelf; + + public this(SelfOuter self) + { + mSelf = self; + } + + public Result> GetNext() mut => mSelf.GetNext(); + + public void Dispose() mut => mSelf.Dispose(); + } + } + + extension GroupByEnumerable + where TValueDlg : Object + { + public void Dispose() mut + { + base.Dispose(); + DeleteAndNullify!(mValueDlg); + } + } + + public static GroupByEnumerable + GroupBy(this TCollection items, TKeyDlg key) + where TCollection : concrete, IEnumerable + where TKeyDlg : delegate TKey(TSource) + where TKey : IHashable + { + //guess we could optimize out this scope with some code duplication + return .(new .(), items.GetEnumerator(), key, new (val) => val, true); + } + + public static GroupByEnumerable + GroupBy(this TEnum items, TKeyDlg key) + where TEnum : concrete, IEnumerator + where TKeyDlg : delegate TKey(TSource) + where TKey : IHashable + { + //guess we could optimize out this scope with some code duplication + return .(new .(), items, key, new (val) => val, true); + } + + public static GroupByEnumerable + GroupBy(this TCollection items, TKeyDlg key, GroupByResult results) + where TCollection : concrete, IEnumerable + where TKeyDlg : delegate TKey(TSource) + where TKey : IHashable + { + //guess we could optimize out this scope with some code duplication + return .(results, items.GetEnumerator(), key, new (val) => val, false); + } + + public static GroupByEnumerable + GroupBy(this TEnum items, TKeyDlg key, GroupByResult results) + where TEnum : concrete, IEnumerator + where TKeyDlg : delegate TKey(TSource) + where TKey : IHashable + { + //guess we could optimize out this scope with some code duplication + return .(results, items, key, new (val) => val, false); + } + + /*public static GroupByEnumerable GroupBy(this TCollection items, TKeyDlg + key, GroupByResult results) where TCollection : concrete, IEnumerable where TKeyDlg : + delegate TKey(TSource) where TKey : IHashable + { + //guess we could optimize out this scope with some code duplication + return .(results, items.GetEnumerator(), key, scope (val) => val); + }*/ +#endregion + struct UnionEnumerable : IEnumerable, IDisposable + where TEnum : concrete, IEnumerator + where TEnum2 : concrete, IEnumerator + where TSource : IHashable + { + HashSet mDistinctValues; + Iterator mSource; + Iterator mOther; + int mState = 0; + + public this(TEnum sourceEnumerator, TEnum2 otherEnumerator) + { + mSource = sourceEnumerator; + mOther = otherEnumerator; + + mDistinctValues = new .(); + } + + Result GetNext() mut + { + switch (mState) { + case 0: + var e = mSource.mEnum; + while (e.GetNext() case .Ok(let val)) + if (mDistinctValues.Add(val)) + return .Ok(val); + + mState++; + fallthrough; + case 1: + var e = mOther.mEnum; + while (e.GetNext() case .Ok(let val)) + if (mDistinctValues.Add(val)) + return .Ok(val); + + mState++; + } + + return .Err; + } + + public Enumerator GetEnumerator() => .(this); + + public struct Enumerator : IEnumerator, IDisposable + { + SelfOuter mSelf; + + public this(SelfOuter self) + { + mSelf = self; + } + + public Result GetNext() mut => mSelf.GetNext(); + + public void Dispose() mut => mSelf.Dispose(); + } + + public void Dispose() mut + { + mSource.Dispose(); + mOther.Dispose(); + DeleteAndNullify!(mDistinctValues); + } + } + + public static UnionEnumerable + Union(this TCollection items, TCollection2 other) + where TCollection : concrete, IEnumerable + where TCollection2 : concrete, IEnumerable + where TSource : IHashable + { + return .(items.GetEnumerator(), other.GetEnumerator()); + } + + public static UnionEnumerable + Union(this TEnum items, TCollection2 other) + where TEnum : concrete, IEnumerator + where TCollection2 : concrete, IEnumerable + where TSource : IHashable + { + return .(items, other.GetEnumerator()); + } + + public static UnionEnumerable + Union(this TCollection items, TEnum other) + where TCollection : concrete, IEnumerable + where TEnum : concrete, IEnumerator + where TSource : IHashable + { + return .(items.GetEnumerator(), other); + } + + public static UnionEnumerable + Union(this TEnum items, TEnum2 other) + where TEnum : concrete, IEnumerator + where TEnum2 : concrete, IEnumerator + where TSource : IHashable + { + return .(items, other); + } + + struct ExceptEnumerable : IEnumerable, IDisposable + where TEnum : concrete, IEnumerator + where TEnum2 : concrete, IEnumerator + where TSource : IHashable + { + HashSet mDistinctValues; + Iterator mSource; + Iterator mOther; + int mState = 0; + + public this(TEnum sourceEnumerator, TEnum2 otherEnumerator) + { + mSource = sourceEnumerator; + mOther = otherEnumerator; + + mDistinctValues = new .(); + } + + Result GetNext() mut + { + switch (mState) { + case 0: + var e = mOther.mEnum; + while (e.GetNext() case .Ok(let val)) + mDistinctValues.Add(val); + + mState++; + fallthrough; + case 1: + var e = mSource.mEnum; + while (e.GetNext() case .Ok(let val)) + if (mDistinctValues.Add(val)) + return .Ok(val); + + mState++; + } + + return .Err; + } + + public Enumerator GetEnumerator() => .(this); + + public struct Enumerator : IEnumerator, IDisposable + { + SelfOuter mSelf; + + public this(SelfOuter self) + { + mSelf = self; + } + + public Result GetNext() mut => mSelf.GetNext(); + + public void Dispose() mut => mSelf.Dispose(); + } + + public void Dispose() mut + { + mSource.Dispose(); + mOther.Dispose(); + DeleteAndNullify!(mDistinctValues); + } + } + + public static ExceptEnumerable + Except(this TCollection items, TCollection2 other) + where TCollection : concrete, IEnumerable + where TCollection2 : concrete, IEnumerable + where TSource : IHashable + { + return .(items.GetEnumerator(), other.GetEnumerator()); + } + + public static ExceptEnumerable + Except(this TEnum items, TCollection2 other) + where TEnum : concrete, IEnumerator + where TCollection2 : concrete, IEnumerable + where TSource : IHashable + { + return .(items, other.GetEnumerator()); + } + + public static ExceptEnumerable + Except(this TCollection items, TEnum other) + where TCollection : concrete, IEnumerable + where TEnum : concrete, IEnumerator + where TSource : IHashable + { + return .(items.GetEnumerator(), other); + } + + public static ExceptEnumerable + Except(this TEnum items, TEnum2 other) + where TEnum : concrete, IEnumerator + where TEnum2 : concrete, IEnumerator + where TSource : IHashable + { + return .(items, other); + } + + struct IntersectEnumerable : IEnumerable, IDisposable + where TEnum : concrete, IEnumerator + where TEnum2 : concrete, IEnumerator + where TSource : IHashable + { + HashSet mDistinctValues; + Iterator mSource; + Iterator mIntersect; + int mState = 0; + + public this(TEnum sourceEnumerator, TEnum2 intersectEnumerator) + { + mSource = .(sourceEnumerator); + mIntersect = .(intersectEnumerator); + mDistinctValues = new .(); + } + + Result GetNext() mut + { + switch (mState) + { + case 0: + var e = mSource.mEnum; + while (e.GetNext() case .Ok(let val)) + mDistinctValues.Add(val); + + mState++; + fallthrough; + case 1: + var e = mIntersect.mEnum; + while (e.GetNext() case .Ok(let val)) + if (mDistinctValues.Remove(val)) + return .Ok(val); + + mState++; + } + + return .Err; + } + + public Enumerator GetEnumerator() => .(this); + + public struct Enumerator : IEnumerator, IDisposable + { + SelfOuter mSelf; + + public this(SelfOuter self) + { + mSelf = self; + } + + public Result GetNext() mut => mSelf.GetNext(); + + public void Dispose() mut => mSelf.Dispose(); + } + + public void Dispose() mut + { + mSource.Dispose(); + mIntersect.Dispose(); + DeleteAndNullify!(mDistinctValues); + } + } + + public static IntersectEnumerable + Intersect(this TCollection items, TCollection2 other) + where TCollection : concrete, IEnumerable + where TCollection2 : concrete, IEnumerable + where TSource : IHashable + { + return .(items.GetEnumerator(), other.GetEnumerator()); + } + + public static IntersectEnumerable + Intersect(this TEnum items, TCollection2 other) + where TEnum : concrete, IEnumerator + where TCollection2 : concrete, IEnumerable + where TSource : IHashable + { + return .(items, other.GetEnumerator()); + } + + public static IntersectEnumerable + Intersect(this TCollection items, TEnum other) + where TCollection : concrete, IEnumerable + where TEnum : concrete, IEnumerator + where TSource : IHashable + { + return .(items.GetEnumerator(), other); + } + + public static IntersectEnumerable + Intersect(this TEnum items, TEnum2 other) + where TEnum : concrete, IEnumerator + where TEnum2 : concrete, IEnumerator + where TSource : IHashable + { + return .(items, other); + } + + struct ZipEnumerable : IEnumerable, IDisposable + where TEnum : concrete, IEnumerator + where TEnum2 : concrete, IEnumerator + where TSelect : delegate TResult(TSource first, TSource second) + { + Iterator mSource; + Iterator mOther; + TSelect mSelect; + + public this(TEnum sourceEnumerator, TEnum2 otherEnumerator, TSelect select) + { + mSource = sourceEnumerator; + mOther = otherEnumerator; + mSelect = select; + } + + Result GetNext() mut + { + if (mSource.mEnum.GetNext() case .Ok(let first)) + if (mOther.mEnum.GetNext() case .Ok(let second)) + return mSelect(first, second); + + return .Err; + } + + public Enumerator GetEnumerator() => .(this); + + public struct Enumerator : IEnumerator, IDisposable + { + SelfOuter mSelf; + + public this(SelfOuter self) + { + mSelf = self; + } + + public Result GetNext() mut => mSelf.GetNext(); + + public void Dispose() mut => mSelf.Dispose(); + } + + + public void Dispose() mut + { + mSource.Dispose(); + mOther.Dispose(); + } + } + + public static ZipEnumerable + Zip(this TCollection items, TCollection2 other, TSelect select) + where TCollection : concrete, IEnumerable + where TCollection2 : concrete, IEnumerable + where TSelect : delegate TResult(TSource first, TSource second) + { + return .(items.GetEnumerator(), other.GetEnumerator(), select); + } + + public static ZipEnumerable + Zip(this TEnum items, TCollection2 other, TSelect select) + where TEnum : concrete, IEnumerator + where TCollection2 : concrete, IEnumerable + where TSelect : delegate TResult(TSource first, TSource second) + { + return .(items, other.GetEnumerator(), select); + } + + public static ZipEnumerable + Zip(this TCollection items, TEnum other, TSelect select) + where TCollection : concrete, IEnumerable + where TEnum : concrete, IEnumerator + where TSelect : delegate TResult(TSource first, TSource second) + { + return .(items.GetEnumerator(), other, select); + } + + public static ZipEnumerable + Zip(this TEnum items, TEnum2 other, TSelect select) + where TEnum : concrete, IEnumerator + where TEnum2 : concrete, IEnumerator + where TSelect : delegate TResult(TSource first, TSource second) + { + return .(items, other, select); + } + + struct ConcatEnumerable : IEnumerable, IDisposable + where TEnum : concrete, IEnumerator + where TEnum2 : concrete, IEnumerator + { + Iterator mFirst; + Iterator mSecond; + int mState = 0; + + public this(TEnum firstEnumerator, TEnum2 secondEnumerator) + { + mFirst = firstEnumerator; + mSecond = secondEnumerator; + } + + Result GetNext() mut + { + switch (mState) { + case 0: + if (mFirst.mEnum.GetNext() case .Ok(let val)) + return .Ok(val); + + mState++; + fallthrough; + case 1: + if (mSecond.mEnum.GetNext() case .Ok(let val)) + return .Ok(val); + + mState++; + } + + return .Err; + } + + public Enumerator GetEnumerator() => .(this); + + public struct Enumerator : IEnumerator, IDisposable + { + SelfOuter mSelf; + + public this(SelfOuter self) + { + mSelf = self; + } + + public Result GetNext() mut => mSelf.GetNext(); + + public void Dispose() mut => mSelf.Dispose(); + } + + public void Dispose() mut + { + mFirst.Dispose(); + mSecond.Dispose(); + } + } + + + + public static ConcatEnumerable + Concat(this TCollection items, TCollection2 other) + where TCollection : concrete, IEnumerable + where TCollection2 : concrete, IEnumerable + { + return .(items.GetEnumerator(), other.GetEnumerator()); + } + + public static ConcatEnumerable + Concat(this TEnum items, TCollection2 other) + where TEnum : concrete, IEnumerator + where TCollection2 : concrete, IEnumerable + { + return .(items, other.GetEnumerator()); + } + + public static ConcatEnumerable + Concat(this TCollection items, TEnum other) + where TCollection : concrete, IEnumerable + where TEnum : concrete, IEnumerator + { + return .(items.GetEnumerator(), other); + } + + public static ConcatEnumerable + Concat(this TEnum items, TEnum2 other) + where TEnum : concrete, IEnumerator + where TEnum2 : concrete, IEnumerator + { + return .(items, other); + } + + public static ConcatEnumerable + Append(this TCollection items, TCollection2 other) + where TCollection : concrete, IEnumerable + where TCollection2 : concrete, IEnumerable + { + return .(items.GetEnumerator(), other.GetEnumerator()); + } + + public static ConcatEnumerable + Append(this TEnum items, TCollection2 other) + where TEnum : concrete, IEnumerator + where TCollection2 : concrete, IEnumerable + { + return .(items, other.GetEnumerator()); + } + + public static ConcatEnumerable + Append(this TCollection items, TEnum other) + where TCollection : concrete, IEnumerable + where TEnum : concrete, IEnumerator + { + return .(items.GetEnumerator(), other); + } + + public static ConcatEnumerable + Append(this TEnum items, TEnum2 other) + where TEnum : concrete, IEnumerator + where TEnum2 : concrete, IEnumerator + { + return .(items, other); + } + + public static ConcatEnumerable + Prepend(this TCollection items, TCollection2 other) + where TCollection : concrete, IEnumerable + where TCollection2 : concrete, IEnumerable + { + return .(other.GetEnumerator(), items.GetEnumerator()); + } + + public static ConcatEnumerable + Prepend(this TEnum items, TCollection2 other) + where TEnum : concrete, IEnumerator + where TCollection2 : concrete, IEnumerable + { + return .(other.GetEnumerator(), items); + } + + public static ConcatEnumerable + Prepend(this TCollection items, TEnum other) + where TCollection : concrete, IEnumerable + where TEnum : concrete, IEnumerator + { + return .(other, items.GetEnumerator()); + } + + public static ConcatEnumerable + Prepend(this TEnum items, TEnum2 other) + where TEnum : concrete, IEnumerator + where TEnum2 : concrete, IEnumerator + { + return .(other, items); + } + + + + static class OrderByComparison + where int : operator T <=> T + { + typealias TCompare = delegate int(T lhs, T rhs); + public readonly static TCompare Comparison = (new (lhs, rhs) => lhs <=> rhs) ~ delete _; + } + + struct SortedEnumerable : IEnumerator<(TKey key, TSource value)>, IDisposable + where TEnum : concrete, IEnumerator + where TKeyDlg : delegate TKey(TSource) + where TCompare : delegate int(TKey lhs, TKey rhs) + { + List<(TKey key, TSource value)> mOrderedList; + Iterator mIterator; + TKeyDlg mKey; + TCompare mCompare; + int mIndex; + int mCount = 0; + bool mDescending; + + public this(TEnum firstEnumerator, TKeyDlg key, TCompare compare, bool descending) + { + mOrderedList = new .(); + mKey = key; + mIterator = firstEnumerator; + mCompare = compare; + mIndex = -1; + mDescending = descending; + } + + public Result<(TKey key, TSource value)> GetNext() mut + { + if (mIndex == -1) + { + while (mIterator.mEnum.GetNext() case .Ok(let val)) + mOrderedList.Add((mKey(val), val)); + + mOrderedList.Sort(scope (l, r) => mCompare(l.key, r.key)); + mCount = mOrderedList.Count;//keeping vars local + mIndex = mDescending ? mCount : 0; + } + + if (mDescending) + { + if (mIndex > 0) + return .Ok(mOrderedList[--mIndex]); + } + else if (mIndex < mCount) + return .Ok(mOrderedList[mIndex++]); + + return .Err; + } + + + public Enumerator GetEnumerator() => .(this); + public struct Enumerator : IEnumerator<(TKey key, TSource value)>, IDisposable + { + SelfOuter mSelf; + + public this(SelfOuter self) + { + mSelf = self; + } + + public Result<(TKey key, TSource value)> GetNext() mut => mSelf.GetNext(); + + public void Dispose() mut => mSelf.Dispose(); + } + + + public void Dispose() mut + { + mIterator.Dispose(); + DeleteAndNullify!(mOrderedList); + } + } + + //if the data is a large struct, this could get pretty slow with all the copies + //we may need to investigate the ability to use ptrs instead if the type is a struct? + struct OrderByEnumerable : IEnumerable, IDisposable + where TEnum : concrete, IEnumerator + { + typealias TCompare = delegate int(TSource lhs, TSource rhs); + + struct Comparer + { + public TCompare comparer; + public bool descending; + } + + DynamicArray mValues; + int[] mMap; + //List mOrderedList; + List mCompares = default; + Iterator mIterator; + int mIndex; + + public this(TEnum enumerator, TCompare compare, bool descending) + { + mCompares = new .(); + var add = mCompares.GrowUnitialized(1); + add.comparer = compare; + add.descending = descending; + + mValues = ?; + mMap = null; + mIterator = enumerator; + mIndex = -1; + } + + void QuickSort(int left, int right) { + var left; + var right; +#unwarn + repeat { + int i = left; + int j = right; + int x = mMap[i + ((j - i) >> 1)]; + repeat { + while (i < mMap.Count && CompareKeys(x, mMap[i]) > 0) i++; + while (j >= 0 && CompareKeys(x, mMap[j]) < 0) j--; + if (i > j) break; + if (i < j) { + int temp = mMap[i]; + mMap[i] = mMap[j]; + mMap[j] = temp; + } + i++; + j--; + } while (i <= j); + if (j - left <= right - i) { + if (left < j) QuickSort(left, j); + left = i; + } + else { + if (i < right) QuickSort(i, right); + right = j; + } + } while (left < right); + } + + [Inline] + int CompareKeys(int index1, int index2) + { + for(var cmp in ref mCompares) + { + int c = cmp.comparer(mValues[index1], mValues[index2]); + if (c != 0) + return cmp.descending ? -c : c; + } + + return index1 - index2; + } + + Result GetNext() mut + { + if (mIndex == -1) + { + mIndex = 0; + mValues = .(); + while (mIterator.mEnum.GetNext() case .Ok(let val)) + mValues.Add(val); + + let count = mValues.Length; + mMap = new int[count]; + for (int i = 0; i < count; i++) mMap[i] = i; + QuickSort( 0, count - 1); + } + + if (mIndex < mValues.Length) + return .Ok(mValues[mMap[mIndex++]]); + + return .Err; + } + + public Enumerator GetEnumerator() => .(this); + + public struct Enumerator : IEnumerator, IDisposable + { + SelfOuter mSelf; + + public this(SelfOuter self) + { + mSelf = self; + } + + public Result GetNext() mut => mSelf.GetNext(); + + public void Dispose() mut => mSelf.Dispose(); + } + + public void Dispose() mut + { + mIterator.Dispose(); + + for(var it in mCompares) + delete it.comparer; + DeleteAndNullify!(mCompares); + DeleteAndNullify!(mMap); + mValues.Dispose(); + } + + public Self ThenBy(TKeyDlg2 keySelect, TCompare2 comparison) mut + where TKeyDlg2 : delegate TKey2(TSource) + where TCompare2 : delegate int(TKey2 lhs, TKey2 rhs) + { + var add = mCompares.GrowUnitialized(1); + add.comparer = new (l, r) => comparison(keySelect(l), keySelect(r)); + add.descending = false; + return this; + } + + public Self ThenBy(TKeyDlg2 keySelect) + where TKeyDlg2 : delegate TKey2(TSource) + where int : operator TKey2 <=> TKey2 + { + let comparison = OrderByComparison.Comparison; + var add = mCompares.GrowUnitialized(1); + add.comparer = new (l, r) => comparison(keySelect(l), keySelect(r)); + add.descending = false; + return this; + } + + + public Self ThenByDescending(TKeyDlg2 keySelect, TCompare2 comparison) mut + where TKeyDlg2 : delegate TKey2(TSource) + where TCompare2 : delegate int(TKey2 lhs, TKey2 rhs) + { + var add = mCompares.GrowUnitialized(1); + add.comparer = new (l, r) => comparison(keySelect(l), keySelect(r)); + add.descending = true; + return this; + } + + public Self ThenByDescending(TKeyDlg2 keySelect) + where TKeyDlg2 : delegate TKey2(TSource) + where int : operator TKey2 <=> TKey2 + { + let comparison = OrderByComparison.Comparison; + var add = mCompares.GrowUnitialized(1); + add.comparer = new (l, r) => comparison(keySelect(l), keySelect(r)); + add.descending = true; + return this; + } + } + + public static OrderByEnumerable + OrderBy(this TCollection items, TKeyDlg keySelect) + where TCollection : concrete, IEnumerable + where TKeyDlg : delegate TKey(TSource) + where int : operator TKey <=> TKey + { + let comparison = OrderByComparison.Comparison; + return .(items.GetEnumerator(), new (l, r) => comparison(keySelect(l), keySelect(r)), false); + } + + public static OrderByEnumerable + OrderBy(this TEnum items, TKeyDlg keySelect) + where TEnum : concrete, IEnumerator + where TKeyDlg : delegate TKey(TSource) + where int : operator TKey <=> TKey + { + let comparison = OrderByComparison.Comparison; + return .(items, new (l, r) => comparison(keySelect(l), keySelect(r)), false); + } + + public static OrderByEnumerable + OrderBy(this TCollection items, TKeyDlg keySelect, TCompare comparison) + where TCollection : concrete, IEnumerable + where TKeyDlg : delegate TKey(TSource) + where TCompare : delegate int(TKey lhs, TKey rhs) + { + return .(items.GetEnumerator(), new (l, r) => comparison(keySelect(l), keySelect(r)), false); + } + + public static OrderByEnumerable + OrderBy(this TEnum items, TKeyDlg keySelect, TCompare comparison) + where TEnum : concrete, IEnumerator + where TKeyDlg : delegate TKey(TSource) + where TCompare : delegate int(TKey lhs, TKey rhs) + { + return .(items, new (l, r) => comparison(keySelect(l), keySelect(r)), false); + } + + public static OrderByEnumerable + OrderByDescending(this TCollection items, TKeyDlg keySelect) + where TCollection : concrete, IEnumerable + where TKeyDlg : delegate TKey(TSource) + where int : operator TKey <=> TKey + { + let comparison = OrderByComparison.Comparison; + return .(items.GetEnumerator(), new (l, r) => comparison(keySelect(l), keySelect(r)), true); + } + + public static OrderByEnumerable + OrderByDescending(this TEnum items, TKeyDlg keySelect) + where TEnum : concrete, IEnumerator + where TKeyDlg : delegate TKey(TSource) + where int : operator TKey <=> TKey + { + let comparison = OrderByComparison.Comparison; + return .(items, new (l, r) => comparison(keySelect(l), keySelect(r)), true); + } + + public static OrderByEnumerable + OrderByDescending(this TCollection items, TKeyDlg keySelect, TCompare comparison) + where TCollection : concrete, IEnumerable + where TKeyDlg : delegate TKey(TSource) + where TCompare : delegate int(TKey lhs, TKey rhs) + { + return .(items.GetEnumerator(),new (l, r) => comparison(keySelect(l), keySelect(r)), true); + } + + public static OrderByEnumerable + OrderByDescending(this TEnum items, TKeyDlg keySelect, TCompare comparison) + where TEnum : concrete, IEnumerator + where TKeyDlg : delegate TKey(TSource) + where TCompare : delegate int(TKey lhs, TKey rhs) + { + return .(items, new (l, r) => comparison(keySelect(l), keySelect(r)), true); + } + + struct SelectManyEnumerable : IEnumerable, IDisposable + where TEnum : concrete, IEnumerator + where TEnum2 : concrete, IEnumerator + where TSelect : delegate TEnum2(TSource) + { + public readonly static String SelectManyEnum = new String() ~ delete _; + + Iterator mItems; + Iterator mCurrent = default; + TSelect mSelect; + int mState = -1; + + public this(TEnum firstEnumerator, TSelect select) + { + mItems = firstEnumerator; + mSelect = select; + } + + Result GetNext(out bool moveNext) mut + { + if (mState < 1) + { + if (mState == 0) + mCurrent.Dispose(); + + if (mItems.mEnum.GetNext() case .Ok(var val)) + { + mCurrent = mSelect(val); + mState = 1; + } + else + { + //no more elements + moveNext = false; + return .Err; + } + } + + if (mCurrent.mEnum.GetNext() case .Ok(let val)) + { + moveNext = false; + return .Ok(val); + } + + //done with current enumerator + mState = 0; + moveNext = true; + return .Err; + } + + Result GetNext() mut + { + var moveNext = true; + while (moveNext) + { + let result = GetNext(out moveNext); + if (!moveNext) + return result; + } + + return .Err; + } + + public Enumerator GetEnumerator() => .(this); + + public struct Enumerator : IEnumerator, IDisposable + { + SelfOuter mSelf; + + public this(SelfOuter self) + { + mSelf = self; + } + + public Result GetNext() mut => mSelf.GetNext(); + + public void Dispose() mut => mSelf.Dispose(); + } + + public void Dispose() mut + { + mItems.Dispose(); + } + } + extension SelectManyEnumerable + where TSelect : Object + { + public void Dispose() mut + { + base.Dispose(); + DeleteAndNullify!(mSelect); + } + } + + public static SelectManyEnumerable + SelectMany(this TCollection items, TSelect select) + where TCollection : concrete, IEnumerable + where TCollection2 : concrete, IEnumerable + where TSelect : delegate TCollection2(TSource) + { + return .(items.GetEnumerator(), new (x) => select(x).GetEnumerator()); + } + + public static SelectManyEnumerable + SelectMany(this TCollection items, TSelect select) + where TCollection : concrete, IEnumerable + where TEnum2 : concrete, IEnumerator + where TSelect : delegate TEnum2(TSource) + { + return .(items.GetEnumerator(), select); + } + + /*struct OfTypeEnumerable : Iterator, IEnumerator, IEnumerable + where TEnum : concrete, IEnumerator + where TSource : class + { + public this(TEnum enumerator) : base(enumerator) + { + } + + public Result GetNext() mut + { + while (mEnum.GetNext() case .Ok(let val)) + { + if (val is TOf) + return .Ok(*(TOf*)Internal.UnsafeCastToPtr(val)); + } + return .Err; + } + + public Self GetEnumerator() + { + return this; + } + } + + public static OfTypeEnumerable + OfType(this TCollection items) + where TCollection : concrete, IEnumerable + where TSource : class + { + return .(items.GetEnumerator()); + }*/ + + + } +} diff --git a/IDEHelper/Tests/Beef.Linq/src/test/BeefProj.toml b/IDEHelper/Tests/Beef.Linq/src/test/BeefProj.toml new file mode 100644 index 00000000..70d49547 --- /dev/null +++ b/IDEHelper/Tests/Beef.Linq/src/test/BeefProj.toml @@ -0,0 +1,8 @@ +FileVersion = 1 +Dependencies = {corlib = "*", "Beef.Linq" = "*"} + +[Project] +Name = "Beef.Linq.Tests" +TargetType = "BeefTest" +StartupObject = "Befe.Linq.Tests.Program" +DefaultNamespace = "System.Linq" diff --git a/IDEHelper/Tests/Beef.Linq/src/test/src/EnumerableTests.bf b/IDEHelper/Tests/Beef.Linq/src/test/src/EnumerableTests.bf new file mode 100644 index 00000000..1407b52d --- /dev/null +++ b/IDEHelper/Tests/Beef.Linq/src/test/src/EnumerableTests.bf @@ -0,0 +1,777 @@ +//#define INCLUDE_FAILURES + +using System.Collections; +using System; +namespace System.Linq +{ + public class EnumerableTests + { + [Test] + public static void Any() + { + let data = scope List(); + + var actual = data.Any(); + Test.Assert(!actual); + + actual = data.Any((it) => it == 2); + Test.Assert(!actual); + + data.Add(1); + data.Add(2); + data.Add(3); + data.Add(4); + + actual = data.Any((it) => it == 2); + Test.Assert(actual); + + actual = data.Any(); + Test.Assert(actual); + + data.RemoveAt(1); + actual = data.Any((it) => it == 2); + Test.Assert(!actual); + } + + [Test] + public static void All() + { + let data = scope List(); + + var actual = data.All((it) => it == 2); + Test.Assert(!actual); + + data.Add(2); + data.Add(2); + data.Add(2); + data.Add(2); + + actual = data.All((it) => it == 2); + Test.Assert(actual); + + data.Add(3); + actual = data.All((it) => it == 2); + Test.Assert(!actual); + } + + + struct ContainsTest : IEnumerable, IEnumerator + { + int mState = 0; + public Self GetEnumerator() + { + return this; + } + + public Result GetNext() mut + { + if (mState > 3) + return .Err; + + return .Ok(mState++); + } + } + + [Test] + public static void Contains() + { + let data = ContainsTest(); + + var actual = data.Contains(2); + Test.Assert(actual); + + actual = data.Contains(4); + Test.Assert(!actual); + } + + + [Test] + public static void Average() + { + let data = scope List() { 1, 1, 2, 2, 4 }; + { + let actual = data.Average(); + Test.Assert(actual == 2); + } + { + let actual = data.GetEnumerator().Average(); + Test.Assert(actual == 2); + } + } + + + [Test] + public static void Max() + { + { + let data = scope List(); + + var actual = data.Max(); + Test.Assert(actual == default); + + data.Add(3); + actual = data.Max(); + Test.Assert(actual == 3); + + data.Add(1); + actual = data.Max(); + Test.Assert(actual == 3); + } + { + let data = scope List(); + + var actual = data.GetEnumerator().Max(); + Test.Assert(actual == default); + + data.Add(3); + actual = data.GetEnumerator().Max(); + Test.Assert(actual == 3); + + data.Add(1); + actual = data.GetEnumerator().Max(); + Test.Assert(actual == 3); + } + } + + [Test] + public static void Min() + { + let data = scope List(); + + var actual = data.Min(); + Test.Assert(actual == default); + + data.Add(3); + actual = data.Min(); + Test.Assert(actual == 3); + + data.Add(1); + actual = data.Min(); + Test.Assert(actual == 1); + } + + [Test] + public static void Sum() + { + { + let data = scope List() { 1, 2, 3, 4 }; + let actual = data.Sum(); + Test.Assert(actual == 10); + } + { + let data = scope List() { 1, 2, 3, 4 }; + let actual = data.Sum(); + Test.Assert(actual == 10); + } + { + let data = scope List() { 1, null, 3, 4 }; + let actual = data.Sum(); + Test.Assert(actual == null); + } + { + let data = scope List(); + let actual = data.Sum(); + Test.Assert(actual == null); + } + } + + [Test] + public static void ElementAt() + { + let data = scope List() { 1, 2, 3 }; + let actual = data.ElementAt(1); + Test.Assert(actual == 1); + } + + [Test] + public static void First() + { + let data = scope List() { 1, 2, 3 }; + let actual = data.First(); + Test.Assert(actual == 1); + } + + [Test] + public static void FirstOrDefault() + { + let data = scope List(); + let actual = data.FirstOrDefault(); + Test.Assert(actual == default); + } + + [Test] + public static void Last() + { + let data = scope List() { 1, 2, 3 }; + let actual = data.Last(); + Test.Assert(actual == 3); + } + + [Test] + public static void LastOrDefault() + { + let data = scope List(); + let actual = data.LastOrDefault(); + Test.Assert(actual == default); + } + + [Test] + public static void Take() + { + let data = scope List(); + for (var i < 20) data.Add(i); + + let actual = data.Take(10).ToList(.. scope .()); + + let expected = scope List(); + for (var i < 10) expected.Add(i); + + Test.Assert(actual.Count == 10); + Test.Assert(actual.SequenceEquals(expected) == true); + } + + [Test] + public static void Skip() + { + let data = scope List(); + for (var i < 20) data.Add(i); + + let actual = data.Skip(10).ToList(.. scope .()); + + let expected = scope List(); + for (var i < 10) expected.Add(i + 10); + + Test.Assert(actual.Count == 10); + Test.Assert(actual.SequenceEquals(expected) == true); + } + + [Test] + public static void Empty() + { + let actual = Enumerable.Empty().ToList(.. scope .()); + Test.Assert(actual.Count == 0); + } + + [Test] + public static void Range() + { + { + let actual = Enumerable.Range(10).ToList(.. scope .()); + let expected = scope List(); + for (var i < 10) expected.Add(i); + Test.Assert(actual.SequenceEquals(expected) == true); + } + { + let actual = Enumerable.Range(10, 20).ToList(.. scope .()); + let expected = scope List(); + for (var i < 10) expected.Add(i + 10); + Test.Assert(actual.SequenceEquals(expected) == true); + } + } + + [Test] + public static void Map() + { + { + let data = scope List() { 0, 5, 10 }; + let actual = data.Map(0f, 1f).ToList(.. scope .()); + let expected = scope List() { 0f, 0.5f, 1f }; + + Test.Assert(actual.SequenceEquals(expected)); + } + { + let data = scope List() { 0, 5, 10 }; + let actual = data.Map(0, 100).ToList(.. scope .()); + let expected = scope List(); + expected.Add(0); + expected.Add(50); + expected.Add(100); + + Test.Assert(actual.SequenceEquals(expected)); + } + } + + + [Test] + public static void Select() + { + let data = scope List<(int x, int y, float z, float w)>() { (1, 2, 3, 4), (4, 3, 2, 1) }; + let actual = data.Select((it) => (x: it.x, y: it.y)).ToList(.. scope .()); + let expected = scope List<(int x, int y)>(); + expected.Add((1, 2)); + expected.Add((4, 3)); + + Test.Assert(actual.Count == 2); + Test.Assert(actual.SequenceEquals(expected)); + } + + [Test] + public static void Where() + { + let data = scope List<(int x, int y, float z, float w)>() { (1, 2, 3, 4), (4, 3, 2, 1) }; + let actual = data.Where((it) => it.x == 1).ToList(.. scope .()); + Test.Assert(actual.Count == 1); + Test.Assert(actual[0] == (1, 2, 3, 4)); + } + + [Test] + public static void TakeWhile() + { + let data = scope List() { 1, 1, 2, 4 }; + let actual = data.TakeWhile((it) => it == 1).ToList(.. scope .()); + let expected = scope List(); + expected.Add(1); + expected.Add(1); + Test.Assert(actual.Count == 2); + } + + + [Test] + public static void SkipWhile() + { + let data = scope List() { 1, 1, 2, 3 }; + let actual = data.SkipWhile((it) => it == 1).ToList(.. scope .()); + let expected = scope List(); + expected.Add(2); + expected.Add(3); + Test.Assert(actual.Count == expected.Count); + } + + [Test] + public static void Repeat() + { + let actual = Enumerable.Repeat(10, 10).ToList(.. scope .()); + let expected = scope List(); + for (var i < 10) + expected.Add(10); + + Test.Assert(actual.SequenceEquals(expected)); + } + + [Test] + public static void Distinct() + { + let data = scope List() { 1, 1, 2, 3 }; + let actual = data.Distinct().ToList(.. scope .()); + let expected = scope List(); + expected.Add(1); + expected.Add(2); + expected.Add(3); + + Test.Assert(actual.Count == expected.Count); + Test.Assert(actual.SequenceEquals(expected)); + } + + [Test] + public static void Reverse() + { + let data = scope List() { 1, 1, 2, 3 }; + let actual = data.Reverse().ToList(.. scope .()); + let expected = scope List(); + expected.Add(3); + expected.Add(2); + expected.Add(1); + expected.Add(1); + + Test.Assert(actual.Count == expected.Count); + Test.Assert(actual.SequenceEquals(expected)); + } + + [Test] + public static void DefaultIfEmpty() + { + { + let data = scope List(); + let actual = data.DefaultIfEmpty().ToList(.. scope .()); + let expected = scope List(); + expected.Add(null); + Test.Assert(actual.Count == 1); + Test.Assert(actual[0] == null); + } + { + let data = scope List(); + let actual = data.DefaultIfEmpty().ToList(.. scope .()); + let expected = scope List(); + expected.Add(10); + Test.Assert(actual.Count == 1); + Test.Assert(actual[0] == 0); + } + { + let data = scope List(); + let actual = data.DefaultIfEmpty(10).ToList(.. scope .()); + let expected = scope List(); + expected.Add(10); + Test.Assert(actual.Count == 1); + Test.Assert(actual[0] == 10); + } + } + + + [Test] + public static void Aggregate() + { + { + let data = scope List() { 1, 2, 3, 4, 5 }; + let actual = data.Aggregate((sum, next) => sum + next); + Test.Assert(actual == 15); + } + { + let data = scope List() { 1, 2, 3, 4, 5 }; + let actual = data.Aggregate(5, (sum, next) => sum + next); + Test.Assert(actual == 20); + } + + /*{ + let data = scope List() { 1, 2, 3, 4, 5 }; + let actual = data.Aggregate( (sum, next) => sum + next, (result) => result * 1000f); + Test.Assert(actual == 15000f); + }*/ + { + let data = scope List() { 1, 2, 3, 4, 5 }; + let actual = data.Aggregate(5, (sum, next) => sum + next, (result) => result * 1000f); + Test.Assert(actual == 20000f); + } + } + +#region ToXYZ methods + [Test] + public static void ToDictionary() + { + { + let data = scope List<(int x, float y)>() { (1, 2f), (4, 3f) }; + let actual = data.ToDictionary((it) => it.x, .. scope .()); + + Test.Assert(actual.Count == 2); + Test.Assert(actual.Contains((1, (1, 2f)))); + Test.Assert(actual.Contains((4, (4, 3f)))); + } + { + let data = scope List<(int x, float y)>() { (1, 2f), (4, 3f) }; + let actual = data.ToDictionary((it) => it.x, (it) => it.y, .. scope .()); + + Test.Assert(actual.Count == 2); + Test.Assert(actual.Contains((1, 2f))); + Test.Assert(actual.Contains((4, 3f))); + } + } + + [Test] + public static void ToHashSet() + { + let data = scope List() { 1, 2, 2 }; + let actual = data.ToHashSet(.. scope .()); + + Test.Assert(actual.Count == 2); + Test.Assert(actual.Contains(1)); + Test.Assert(actual.Contains(2)); + } +#endregion + +#region GroupBy + + /*public static mixin GroupBy(this TCollection items, TKey key) + where TCollection : concrete, IEnumerable + where TKeyDlg : delegate TKey(TSource) + { + let groupByMemory = scope:mixin GroupByMemory(); + return InternalGroupBy(groupByMemory, items, key); + }*/ + + [Test] + public static void GroupBy() + { + { + let data = scope List<(int x, int y, int z)>() { (0, 1, 9), (0, 2, 8), (2, 4, 5), (1, 1, 1), (2, 2, 2) }; + let actual = data.GroupBy((key) => key.x, scope .()).ToList(.. scope .()); + + Test.Assert(actual.Count == 3); + + var i = 0; + for (var it in actual) + { + switch (it.Key) + { + case 0: Test.Assert(it.SequenceEquals(scope List<(int x, int y, int z)>() { (0, 1, 9), (0, 2, 8) })); i |= 1; + case 1: Test.Assert(it.SequenceEquals(scope List<(int x, int y, int z)>() { (1, 1, 1) })); i |= 2; + case 2: Test.Assert(it.SequenceEquals(scope List<(int x, int y, int z)>() { (2, 4, 5), (2, 2, 2) })); i |= 4; + } + } + + Test.Assert(i == 7); + } + + { + let data = scope List<(int x, int y, int z)>() { (0, 1, 9), (0, 2, 8), (2, 4, 5), (1, 1, 1), (2, 2, 2) }; + + var i = 0; + for (var it in data.GroupBy((key) => key.x)) + { + switch (it.Key) + { + case 0: Test.Assert(it.SequenceEquals(scope List<(int x, int y, int z)>() { (0, 1, 9), (0, 2, 8) })); i |= 1; + case 1: Test.Assert(it.SequenceEquals(scope List<(int x, int y, int z)>() { (1, 1, 1) })); i |= 2; + case 2: Test.Assert(it.SequenceEquals(scope List<(int x, int y, int z)>() { (2, 4, 5), (2, 2, 2) })); i |= 4; + } + } + + Test.Assert(i == 7); + } + } + +#endregion + + [Test] + public static void Union() + { + let data = scope List() { 0, 1, 2 }; + let other = scope List() { 3, 4, 5 }; + let actual = data.Union(other).ToList(.. scope .()); + + Test.Assert(actual.SequenceEquals(int[6](0, 1, 2, 3, 4, 5))); + } + + [Test] + public static void Intersect() + { + let data = scope List() { 0, 1, 2 }; + let other = scope List() { 1, 5, 2 }; + let actual = data.Intersect(other).ToList(.. scope .()); + + Test.Assert(actual.SequenceEquals(int[2](1, 2))); + } + + [Test] + public static void Except() + { + let data = scope List() { 0, 1, 2 }; + let other = scope List() { 0, 5, 2 }; + let actual = data.Except(other).ToList(.. scope .()); + + Test.Assert(actual.SequenceEquals(int[1](1))); + } + + [Test] + public static void Zip() + { + let data = scope List() { 0, 1, 2, 3 }; + let other = scope List() { 1, 2, 3 }; + let actual = data.Zip(other, (first, second) => first + second).ToList(.. scope .()); + + Test.Assert(actual.SequenceEquals(int[3](1, 3, 5))); + } + + [Test] + public static void Concat() + { + let data = scope List() { 0, 1, 2, 3 }; + let other = scope List() { 1, 2, 3 }; + let actual = data.Concat(other).ToList(.. scope .()); + + Test.Assert(actual.SequenceEquals(int[?](0, 1, 2, 3, 1, 2, 3))); + } + + [Test] + public static void Append() + { + let data = scope List() { 0, 1, 2 }; + let other = scope List() { 1, 2, 3, 3 }; + let actual = data.Append(other).ToList(.. scope .()); + + Test.Assert(actual.SequenceEquals(int[?](0, 1, 2, 1, 2, 3, 3))); + } + + [Test] + public static void Prepend() + { + let data = scope List() { 0, 1, 2 }; + let other = scope List() { 1, 2, 3, 3 }; + let actual = data.Prepend(other).ToList(.. scope .()); + + Test.Assert(actual.SequenceEquals(int[?](1, 2, 3, 3, 0, 1, 2))); + } + + [Test] + public static void OrderBy() + { + { + let data = scope List<(int x, int y)>() { (1, 2), (1, 3), (3, 2), (0, 4), (2, 0) }; + let actual = data.OrderBy((it) => it.x).ToList(.. scope .()); + + let expected = scope List<(int x, int y)>() { (0, 4), (1, 2), (1, 3), (2, 0), (3, 2) }; + Test.Assert(actual.SequenceEquals(expected)); + } + { + let data = scope List<(int x, int y)>() { (1, 2), (1, 3), (3, 2), (0, 4), (2, 0) }; + let actual = data.OrderBy((it) => it.x, (l, r) => l - r).ToList(.. scope .()); + + let expected = scope List<(int x, int y)>() { (0, 4), (1, 2), (1, 3), (2, 0), (3, 2) }; + Test.Assert(actual.SequenceEquals(expected)); + } + { + //orderby has some temp allocations, this test is just to make sure those temp allocations don't fail + let data = scope List<(int x, int y)>() { (1, 2), (1, 3), (3, 2), (0, 4), (2, 0) }; + let actual = data.OrderBy((it) => it.x, (l, r) => l - r).OrderBy((it) => it.x, (l, r) => r - l).ToList(.. scope .()); + + let expected = scope List<(int x, int y)>() { (3, 2), (2, 0), (1, 2), (1, 3), (0, 4) }; + Test.Assert(actual.SequenceEquals(expected)); + } + } + + [Test] + public static void OrderByDescending() + { + //this method shouldn't be using reverse, but I'm being lazy + { + let data = scope List<(int x, int y)>() { (1, 2), (1, 3), (3, 2), (0, 4), (2, 0) }; + let actual = data.OrderByDescending((it) => it.x).ToList(.. scope .()); + + let expected = scope List<(int x, int y)>() { (0, 4), (1, 3), (1, 2), (2, 0), (3, 2) }; + Test.Assert(actual.SequenceEquals(expected.Reverse())); + } + { + let data = scope List<(int x, int y)>() { (1, 2), (1, 3), (3, 2), (0, 4), (2, 0) }; + let actual = data.OrderByDescending((it) => it.x, (l, r) => l - r).ToList(.. scope .()); + + let expected = scope List<(int x, int y)>() { (0, 4), (1, 3), (1, 2), (2, 0), (3, 2) }; + Test.Assert(actual.SequenceEquals(expected.Reverse())); + } + { + //orderby has some temp allocations, this test is just to make sure those temp allocations don't fail + let data = scope List<(int x, int y)>() { (1, 2), (1, 3), (3, 2), (0, 4), (2, 0) }; + let actual = data.OrderByDescending((it) => it.x, (l, r) => l - r).OrderBy((it) => it.x, (l, r) => r - l).ToList(.. scope .()); + + let expected = scope List<(int x, int y)>() { (3, 2), (2, 0), (1, 2), (1, 3), (0, 4) }; + Test.Assert(actual.SequenceEquals(expected)); + } + } + + [Test] + public static void ThenBy() + { + { + let data = scope List<(int x, int y)>() { (1, 2), (1, 3), (3, 2), (0, 4), (2, 0) }; + let actual = data.OrderBy((it) => it.x).ThenBy((it) => it.y).ToList(.. scope .()); + + let expected = scope List<(int x, int y)>() { (0, 4), (1, 2), (1, 3), (2, 0), (3, 2) }; + Test.Assert(actual.SequenceEquals(expected)); + } + { + let data = scope List<(int x, int y)>() { (1, 2), (1, 3), (3, 2), (0, 4), (2, 0) }; + let actual = data.OrderBy((it) => it.x, (l, r) => l - r).ThenBy((it) => it.y).ToList(.. scope .()); + + let expected = scope List<(int x, int y)>() { (0, 4), (1, 2), (1, 3), (2, 0), (3, 2) }; + Test.Assert(actual.SequenceEquals(expected)); + } + { + //orderby has some temp allocations, this test is just to make sure those temp allocations don't fail + let data = scope List<(int x, int y)>() { (1, 2), (1, 3), (3, 2), (0, 4), (2, 0) }; + let actual = data.OrderBy((it) => it.x, (l, r) => l - r).OrderBy((it) => it.x, (l, r) => r - l).ToList(.. scope .()); + + let expected = scope List<(int x, int y)>() { (3, 2), (2, 0), (1, 2), (1, 3), (0, 4) }; + Test.Assert(actual.SequenceEquals(expected)); + } + } + + + [Test] + public static void ThenByDescending() + { + { + let data = scope List<(int x, int y)>() { (1, 2), (1, 3), (3, 2), (0, 4), (2, 0) }; + let actual = data.OrderBy((it) => it.x).ThenByDescending((it) => it.y).ToList(.. scope .()); + + let expected = scope List<(int x, int y)>() { (0, 4), (1, 3), (1, 2), (2, 0), (3, 2) }; + Test.Assert(actual.SequenceEquals(expected)); + } + { + let data = scope List<(int x, int y)>() { (1, 2), (1, 3), (3, 2), (0, 4), (2, 0) }; + let actual = data.OrderBy((it) => it.x, (l, r) => l - r).ThenByDescending((it) => it.y).ToList(.. scope .()); + + let expected = scope List<(int x, int y)>() { (0, 4), (1, 3), (1, 2), (2, 0), (3, 2) }; + Test.Assert(actual.SequenceEquals(expected)); + } + } + + [Test] + public static void SelectMany() + { + { + let data = scope List>() + { + scope List(), + scope List(), + scope List(), + scope List(), + scope List() + }; + + for (var i < 5) + for (var k < 2) + data[i].Add(i * 2 + k); + + let actual = data.SelectMany((x) => x).ToList(.. scope .()); + let actual2 = data.SelectMany((x) => x.GetEnumerator()).ToList(.. scope .()); + + Test.Assert(actual.SequenceEquals(scope int[](0, 1, 2, 3, 4, 5, 6, 7, 8, 9))); + Test.Assert(actual2.SequenceEquals(scope int[](0, 1, 2, 3, 4, 5, 6, 7, 8, 9))); + } + } + +#region Failures +#if INCLUDE_FAILURES + [Test(ShouldFail = true)] + public static void ElementAtSequenceError() + { + let data = scope List(){ 1, 2, 3}; + data.ElementAt(4); + } + + [Test(ShouldFail = true)] + public static void FirstFatalOnEmpty() + { + let data = scope List(); + data.First(); + } + + [Test(ShouldFail = true)] + public static void LastFatalOnEmpty() + { + let data = scope List(); + + data.Last(); + } +#endif +#endregion + + [AttributeUsage(.Method)] + public struct MyTestAttribute : Attribute + { + } + + [Reflect(.Methods), AlwaysInclude(IncludeAllMethods = true)] + public struct ReflectionTest + { + [MyTest, AlwaysInclude, Reflect] + public int HelloWorld() { return 1; } + } + +#region Reported bugs + + /*[Test] + public static void HitGetMethodsReflectionIssue() + { + let actual = typeof(ReflectionTest).GetMethods().Where((m) => m.GetCustomAttribute() case .Ok).ToList(.. scope .()); + Test.Assert(actual.Count == 1); + }*/ + + [Test] + public static void HigCallingMutatingIssue() + { + int[] test1 = scope .(10, 11, 10, 12, 13, 14, -1); + let actual = test1.Reverse().Where((x) => x > 0 && x % 2 == 0).Sum(); + + Test.Assert(actual == 46); + } +#endregion + } +} diff --git a/bin/test_build.bat b/bin/test_build.bat index 921387e8..c59718a2 100644 --- a/bin/test_build.bat +++ b/bin/test_build.bat @@ -15,11 +15,15 @@ CALL bin/msbuild.bat IDEHelper\Tests\CLib\CLib.vcxproj /p:Configuration=Debug /p @IF %ERRORLEVEL% NEQ 0 GOTO HADERROR IDE\dist\BeefBuild_d -proddir=IDEHelper\Tests -test @IF %ERRORLEVEL% NEQ 0 GOTO HADERROR +IDE\dist\BeefBuild_d -proddir=IDEHelper\Tests\Beef.Linq -test +@IF %ERRORLEVEL% NEQ 0 GOTO HADERROR @ECHO Testing IDEHelper\Tests (Win32) CALL bin/msbuild.bat IDEHelper\Tests\CLib\CLib.vcxproj /p:Configuration=Debug /p:Platform=x86 IDE\dist\BeefBuild_d -proddir=IDEHelper\Tests -test -platform=Win32 @IF %ERRORLEVEL% NEQ 0 GOTO HADERROR +IDE\dist\BeefBuild_d -proddir=IDEHelper\Tests\Beef.Linq -test -platform=Win32 +@IF %ERRORLEVEL% NEQ 0 GOTO HADERROR @ECHO Testing SysMSVCRT del IDE\Tests\SysMSVCRT\build\Debug_Win64\SysMSVCRT\SysMSVCRT.exe From 9163312712c479c0c202de6341c8c5ccb14b14bb Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Tue, 16 Feb 2021 15:16:32 -0800 Subject: [PATCH 56/71] Handled some missing system types better --- IDEHelper/Compiler/BfExprEvaluator.cpp | 3 +++ IDEHelper/Compiler/BfModuleTypeUtils.cpp | 14 +++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index b819317f..4451676b 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -13833,6 +13833,9 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs mModule->Fail("Too many array dimensions, consider using a jagged array.", objCreateExpr); } + if (arrayType == NULL) + return; + if (isAppendAlloc) arrayValue = BfTypedValue(mModule->AppendAllocFromType(resultType, BfIRValue(), 0, arraySize, (int)dimLengthVals.size(), isRawArrayAlloc, zeroMemory), arrayType); else diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 300df1aa..3b6a7b4e 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -10339,7 +10339,11 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula if ((mCurTypeInstance == NULL) || (!mCurTypeInstance->IsGenericTypeInstance())) wantGeneric = false; - auto baseDelegateType = ResolveTypeDef(mCompiler->mDelegateTypeDef)->ToTypeInstance(); + BfTypeInstance* baseDelegateType = NULL; + if (mCompiler->mDelegateTypeDef != NULL) + baseDelegateType = ResolveTypeDef(mCompiler->mDelegateTypeDef)->ToTypeInstance(); + else + failed = true; BfDelegateInfo* delegateInfo = NULL; BfTypeInstance* delegateType = NULL; @@ -10386,7 +10390,8 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula Val128 hashContext; BfTypeDef* typeDef = new BfTypeDef(); - typeDef->mProject = baseDelegateType->mTypeDef->mProject; + if (baseDelegateType != NULL) + typeDef->mProject = baseDelegateType->mTypeDef->mProject; typeDef->mSystem = mCompiler->mSystem; typeDef->mName = mSystem->mEmptyAtom; if (delegateTypeRef->mTypeToken->GetToken() == BfToken_Delegate) @@ -10418,9 +10423,12 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula delegateInfo->mDirectAllocNodes.push_back(directTypeRef); if (typeDef->mIsDelegate) directTypeRef->Init(delegateType); + else if (mCompiler->mFunctionTypeDef == NULL) + failed = true; else directTypeRef->Init(ResolveTypeDef(mCompiler->mFunctionTypeDef)); - typeDef->mBaseTypes.push_back(directTypeRef); + if (!failed) + typeDef->mBaseTypes.push_back(directTypeRef); directTypeRef = BfAstNode::ZeroedAlloc(); delegateInfo->mDirectAllocNodes.push_back(directTypeRef); From fe317aba34a7d8f431f9a93c56499e748567dc56 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Wed, 17 Feb 2021 06:51:12 -0800 Subject: [PATCH 57/71] Temporarily remove Win32 Linq test --- bin/test_build.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/test_build.bat b/bin/test_build.bat index c59718a2..0473c7e5 100644 --- a/bin/test_build.bat +++ b/bin/test_build.bat @@ -22,7 +22,7 @@ IDE\dist\BeefBuild_d -proddir=IDEHelper\Tests\Beef.Linq -test CALL bin/msbuild.bat IDEHelper\Tests\CLib\CLib.vcxproj /p:Configuration=Debug /p:Platform=x86 IDE\dist\BeefBuild_d -proddir=IDEHelper\Tests -test -platform=Win32 @IF %ERRORLEVEL% NEQ 0 GOTO HADERROR -IDE\dist\BeefBuild_d -proddir=IDEHelper\Tests\Beef.Linq -test -platform=Win32 +@REM IDE\dist\BeefBuild_d -proddir=IDEHelper\Tests\Beef.Linq -test -platform=Win32 @IF %ERRORLEVEL% NEQ 0 GOTO HADERROR @ECHO Testing SysMSVCRT From e626620e48cef23a26dc48d80bd0e3a7dcd78901 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Wed, 17 Feb 2021 07:08:09 -0800 Subject: [PATCH 58/71] Fix typeof(T).MinValue/MaxValue with generic params --- IDEHelper/Compiler/BfExprEvaluator.cpp | 62 +++++++++++++++++++------- 1 file changed, 47 insertions(+), 15 deletions(-) diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 4451676b..3d1dfd8c 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -10107,19 +10107,22 @@ void BfExprEvaluator::Visit(BfTypeOfExpression* typeOfExpr) bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifierNode* propName) { - // We ignore errors because we go through the normal Visit(BfTypeOfExpression) if this fails, which will throw the error again - SetAndRestoreValue prevIgnoreErrors(mModule->mIgnoreErrors, true); - auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef); BfType* type; - if (auto genericTypeRef = BfNodeDynCast(typeOfExpr->mTypeRef)) + // { - type = mModule->ResolveTypeRefAllowUnboundGenerics(typeOfExpr->mTypeRef, BfPopulateType_Identity); - } - else - { - type = ResolveTypeRef(typeOfExpr->mTypeRef, BfPopulateType_Identity); + // We ignore errors because we go through the normal Visit(BfTypeOfExpression) if this fails, which will throw the error again + SetAndRestoreValue prevIgnoreErrors(mModule->mIgnoreErrors, true); + if (auto genericTypeRef = BfNodeDynCast(typeOfExpr->mTypeRef)) + { + SetAndRestoreValue prevIgnoreErrors(mModule->mIgnoreErrors, true); + type = mModule->ResolveTypeRefAllowUnboundGenerics(typeOfExpr->mTypeRef, BfPopulateType_Identity); + } + else + { + type = ResolveTypeRef(typeOfExpr->mTypeRef, BfPopulateType_Identity, BfResolveTypeRefFlag_IgnoreLookupError); + } } if (type == NULL) @@ -10209,11 +10212,40 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie else if ((memberName == "MinValue") || (memberName == "MaxValue")) { bool isMin = memberName == "MinValue"; - - BfType* checkType = typeInstance; + + BfType* checkType = type; if (checkType->IsTypedPrimitive()) checkType = checkType->GetUnderlyingType(); + if (checkType->IsGenericParam()) + { + bool foundMatch = false; + + auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)checkType); + if ((genericParamInstance->mTypeConstraint != NULL) && (genericParamInstance->mTypeConstraint->IsInstanceOf(mModule->mCompiler->mEnumTypeDef))) + foundMatch = true; + + if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized) && (mModule->mCurMethodInstance->mMethodInfoEx != NULL)) + { + for (int genericParamIdx = (int)mModule->mCurMethodInstance->mMethodInfoEx->mMethodGenericArguments.size(); + genericParamIdx < mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++) + { + genericParamInstance = mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx]; + if (genericParamInstance->mExternType == type) + { + if ((genericParamInstance->mTypeConstraint != NULL) && (genericParamInstance->mTypeConstraint->IsInstanceOf(mModule->mCompiler->mEnumTypeDef))) + foundMatch = true; + } + } + } + + if (foundMatch) + { + mResult = mModule->GetDefaultTypedValue(type, false, Beefy::BfDefaultValueKind_Undef); + return true; + } + } + if (checkType->IsPrimitiveType()) { auto primType = (BfPrimitiveType*)checkType; @@ -10260,15 +10292,15 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie default: break; } } - } + } - if (typeInstance->IsEnum()) + if (type->IsEnum()) { - mModule->Fail("'MinValue' cannot be used on enums with payloads", propName); + mModule->Fail(StrFormat("'MinValue' cannot be used on enum with payload '%s'", mModule->TypeToString(type).c_str()), propName); } else { - mModule->Fail(StrFormat("'%s' cannot be used on type '%s'", memberName.c_str(), mModule->TypeToString(typeInstance).c_str()), propName); + mModule->Fail(StrFormat("'%s' cannot be used on type '%s'", memberName.c_str(), mModule->TypeToString(type).c_str()), propName); } } else From a3ed5b77691d34b0754b14bf264c9d844400f81f Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Wed, 17 Feb 2021 07:10:15 -0800 Subject: [PATCH 59/71] Also made work for `where T : enum` --- IDEHelper/Compiler/BfExprEvaluator.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 3d1dfd8c..f7e82b18 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -10222,7 +10222,8 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie bool foundMatch = false; auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)checkType); - if ((genericParamInstance->mTypeConstraint != NULL) && (genericParamInstance->mTypeConstraint->IsInstanceOf(mModule->mCompiler->mEnumTypeDef))) + if (((genericParamInstance->mGenericParamFlags & BfGenericParamFlag_Enum) != 0) || + ((genericParamInstance->mTypeConstraint != NULL) && (genericParamInstance->mTypeConstraint->IsInstanceOf(mModule->mCompiler->mEnumTypeDef)))) foundMatch = true; if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized) && (mModule->mCurMethodInstance->mMethodInfoEx != NULL)) @@ -10233,7 +10234,8 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie genericParamInstance = mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx]; if (genericParamInstance->mExternType == type) { - if ((genericParamInstance->mTypeConstraint != NULL) && (genericParamInstance->mTypeConstraint->IsInstanceOf(mModule->mCompiler->mEnumTypeDef))) + if (((genericParamInstance->mGenericParamFlags & BfGenericParamFlag_Enum) != 0) || + ((genericParamInstance->mTypeConstraint != NULL) && (genericParamInstance->mTypeConstraint->IsInstanceOf(mModule->mCompiler->mEnumTypeDef)))) foundMatch = true; } } From d460c1fb2f1f688b85607b54acd39a45df085056 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Wed, 17 Feb 2021 07:15:51 -0800 Subject: [PATCH 60/71] Fixed defer target printing --- IDEHelper/Compiler/BfPrinter.cpp | 2 +- IDEHelper/Compiler/BfReducer.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/IDEHelper/Compiler/BfPrinter.cpp b/IDEHelper/Compiler/BfPrinter.cpp index 54a5c8c4..6e424020 100644 --- a/IDEHelper/Compiler/BfPrinter.cpp +++ b/IDEHelper/Compiler/BfPrinter.cpp @@ -1847,7 +1847,7 @@ void BfPrinter::Visit(BfDeferStatement* deferStmt) VisitChild(deferStmt->mDeferToken); VisitChild(deferStmt->mColonToken); - VisitChild(deferStmt->mScopeToken); + VisitChild(deferStmt->mScopeName); if (deferStmt->mBind != NULL) { diff --git a/IDEHelper/Compiler/BfReducer.cpp b/IDEHelper/Compiler/BfReducer.cpp index afc95e51..64b05b01 100644 --- a/IDEHelper/Compiler/BfReducer.cpp +++ b/IDEHelper/Compiler/BfReducer.cpp @@ -3797,6 +3797,8 @@ BfAstNode* BfReducer::DoCreateStatement(BfAstNode* node, CreateStmtFlags createS } else if (nextTokenNode->GetToken() == BfToken_LParen) { + mPassInstance->Warn(0, "Syntax deprecated", nextTokenNode); + MEMBER_SET(deferStmt, mOpenParen, nextTokenNode); mVisitorPos.MoveNext(); From 2d76efdaaaaf4776ccd1bdd4d68d435bd193a80a Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Wed, 17 Feb 2021 07:37:37 -0800 Subject: [PATCH 61/71] Require explicit cast for enum-constrained generic-to-int conversion --- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 3b6a7b4e..cb4e4863 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -11079,7 +11079,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp { SetAndRestoreValue prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true); auto constraintTypeInst = genericParamInst->mTypeConstraint->ToTypeInstance(); - if ((constraintTypeInst != NULL) && (constraintTypeInst->mTypeDef == mCompiler->mEnumTypeDef)) + if ((constraintTypeInst != NULL) && (constraintTypeInst->mTypeDef == mCompiler->mEnumTypeDef) && (explicitCast)) { // Enum->int if ((explicitCast) && (toType->IsInteger())) @@ -11118,7 +11118,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp } } - if (toType->IsInteger()) + if ((toType->IsInteger()) && (explicitCast)) { if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Enum) != 0) { From 483f579e656f4d4acf4da01d940de0d4cf8b2604 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Wed, 17 Feb 2021 11:00:02 -0800 Subject: [PATCH 62/71] Defer syntax fixes --- IDE/src/ui/DisassemblyPanel.bf | 2 +- IDE/src/ui/SourceEditWidgetContent.bf | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/IDE/src/ui/DisassemblyPanel.bf b/IDE/src/ui/DisassemblyPanel.bf index cd9c039c..0273b030 100644 --- a/IDE/src/ui/DisassemblyPanel.bf +++ b/IDE/src/ui/DisassemblyPanel.bf @@ -266,7 +266,7 @@ namespace IDE.ui IdSpan liveCharIdData; String liveText = scope:: String(); app.FindProjectSourceContent(projectSource, out liveCharIdData, true, liveText, null); - defer(stack) liveCharIdData.Dispose(); + defer:: liveCharIdData.Dispose(); var compileInstance = IDEApp.sApp.mWorkspace.GetProjectSourceCompileInstance(projectSource, mHotIdx); if (compileInstance == null) diff --git a/IDE/src/ui/SourceEditWidgetContent.bf b/IDE/src/ui/SourceEditWidgetContent.bf index 540c766f..af07c861 100644 --- a/IDE/src/ui/SourceEditWidgetContent.bf +++ b/IDE/src/ui/SourceEditWidgetContent.bf @@ -1244,7 +1244,7 @@ namespace IDE.ui { var undoBatchStart = new UndoBatchStart("pasteText"); mData.mUndoManager.Add(undoBatchStart); - defer(stack) mData.mUndoManager.Add(undoBatchStart.mBatchEnd); + defer:: mData.mUndoManager.Add(undoBatchStart.mBatchEnd); } if (HasSelection()) @@ -3644,7 +3644,7 @@ namespace IDE.ui bool hadSuggestion = false; List suggestions = scope List(); - defer (scope) ClearAndDeleteItems(suggestions); + defer ClearAndDeleteItems(suggestions); spellChecker.GetSuggestions(word, suggestions); for (var suggestion in suggestions) { @@ -3789,7 +3789,7 @@ namespace IDE.ui else if (bfSystem != null) { parser = bfSystem.CreateEmptyParser(null); - defer(stack) delete parser; + defer:: delete parser; var text = scope String(); mEditWidget.GetText(text); parser.SetSource(text, mSourceViewPanel.mFilePath); From a70b99368615a14e4e89ba9b4eaca5c72cb632e1 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Wed, 17 Feb 2021 11:00:20 -0800 Subject: [PATCH 63/71] Type map hash fixes --- IDEHelper/Compiler/BfCompiler.cpp | 3 +- IDEHelper/Compiler/BfResolvedTypeUtils.cpp | 66 ++++++++++++---------- 2 files changed, 38 insertions(+), 31 deletions(-) diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index fe46736d..1bd87e39 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -8959,9 +8959,10 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetTypeInfo(BfCompiler* bfCompiler, SetAndRestoreValue prevIgnoreWarnings(bfCompiler->mContext->mScratchModule->mIgnoreWarnings, true); SetAndRestoreValue prevResolvePass(bfCompiler->mResolvePassData, &resolvePass); - auto type = bfCompiler->mContext->mScratchModule->ResolveTypeRef(typeRef, BfPopulateType_Data, BfResolveTypeRefFlag_NoCreate); + auto type = bfCompiler->mContext->mScratchModule->ResolveTypeRef(typeRef, BfPopulateType_Identity, BfResolveTypeRefFlag_NoCreate); if (type != NULL) { + bfCompiler->mContext->mScratchModule->PopulateType(type); outString += "Found"; if (auto typeInst = type->ToTypeInstance()) { diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index 2d71d37a..5be39d7a 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -2676,7 +2676,7 @@ size_t BfTypeVectorHash::operator()(const BfTypeVector& typeVec) const size_t hash = typeVec.size(); BfResolvedTypeSet::LookupContext ctx; for (auto type : typeVec) - hash = ((hash ^ BfResolvedTypeSet::Hash(type, &ctx)) << 5) - hash; + hash = ((hash ^ BfResolvedTypeSet::Hash(type, &ctx, Beefy::BfResolvedTypeSet::BfHashFlag_None, 0)) << 5) - hash; return hash; } @@ -2791,13 +2791,13 @@ int BfResolvedTypeSet::DoHash(BfType* type, LookupContext* ctx, bool allowRef, i if (type->IsBoxed()) { BfBoxedType* boxedType = (BfBoxedType*)type; - int elemHash = Hash(boxedType->mElementType, ctx) ^ HASH_VAL_BOXED; + int elemHash = Hash(boxedType->mElementType, ctx, BfHashFlag_None, hashSeed) ^ HASH_VAL_BOXED; return (elemHash << 5) - elemHash; } else if (type->IsArray()) { BfArrayType* arrayType = (BfArrayType*)type; - int elemHash = Hash(arrayType->mGenericTypeInfo->mTypeGenericArguments[0], ctx) ^ (arrayType->mDimensions << 8); + int elemHash = Hash(arrayType->mGenericTypeInfo->mTypeGenericArguments[0], ctx, BfHashFlag_None, hashSeed) ^ (arrayType->mDimensions << 8); return (elemHash << 5) - elemHash; } else if (type->IsDelegateFromTypeRef() || type->IsFunctionFromTypeRef()) @@ -2807,7 +2807,7 @@ int BfResolvedTypeSet::DoHash(BfType* type, LookupContext* ctx, bool allowRef, i auto delegateInfo = type->GetDelegateInfo(); - hashVal = ((hashVal ^ (Hash(delegateInfo->mReturnType, ctx))) << 5) - hashVal; + hashVal = ((hashVal ^ (Hash(delegateInfo->mReturnType, ctx, BfHashFlag_None, hashSeed))) << 5) - hashVal; auto methodDef = typeInst->mTypeDef->mMethods[0]; BF_ASSERT(methodDef->mName == "Invoke"); @@ -2821,7 +2821,7 @@ int BfResolvedTypeSet::DoHash(BfType* type, LookupContext* ctx, bool allowRef, i for (int paramIdx = 0; paramIdx < delegateInfo->mParams.size(); paramIdx++) { // Parse attributes? - hashVal = ((hashVal ^ (Hash(delegateInfo->mParams[paramIdx], ctx))) << 5) - hashVal; + hashVal = ((hashVal ^ (Hash(delegateInfo->mParams[paramIdx], ctx, BfHashFlag_None, hashSeed))) << 5) - hashVal; String paramName = methodDef->mParams[paramIdx]->mName; int nameHash = (int)Hash64(paramName.c_str(), (int)paramName.length()); hashVal = ((hashVal ^ (nameHash)) << 5) - hashVal; @@ -2856,7 +2856,7 @@ int BfResolvedTypeSet::DoHash(BfType* type, LookupContext* ctx, bool allowRef, i BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx]; auto fieldType = fieldInstance->mResolvedType; - hashVal = ((hashVal ^ (Hash(fieldType, ctx))) << 5) - hashVal; + hashVal = ((hashVal ^ (Hash(fieldType, ctx, BfHashFlag_None, hashSeed))) << 5) - hashVal; BfFieldDef* fieldDef = NULL; if (tupleType->mTypeDef != NULL) fieldDef = fieldInstance->GetFieldDef(); @@ -2890,7 +2890,7 @@ int BfResolvedTypeSet::DoHash(BfType* type, LookupContext* ctx, bool allowRef, i else if (type->IsPointer()) { BfPointerType* pointerType = (BfPointerType*) type; - int elemHash = Hash(pointerType->mElementType, ctx) ^ HASH_VAL_PTR; + int elemHash = Hash(pointerType->mElementType, ctx, BfHashFlag_None, hashSeed) ^ HASH_VAL_PTR; return (elemHash << 5) - elemHash; } else if (type->IsGenericParam()) @@ -2901,30 +2901,30 @@ int BfResolvedTypeSet::DoHash(BfType* type, LookupContext* ctx, bool allowRef, i else if (type->IsRef()) { auto refType = (BfRefType*)type; - int elemHash = Hash(refType->mElementType, ctx) ^ (HASH_VAL_REF + (int)refType->mRefKind); + int elemHash = Hash(refType->mElementType, ctx, BfHashFlag_None, hashSeed) ^ (HASH_VAL_REF + (int)refType->mRefKind); return (elemHash << 5) - elemHash; } else if (type->IsModifiedTypeType()) { auto modifiedTypeType = (BfModifiedTypeType*)type; - int elemHash = Hash(modifiedTypeType->mElementType, ctx) ^ HASH_MODTYPE + (int)modifiedTypeType->mModifiedKind; + int elemHash = Hash(modifiedTypeType->mElementType, ctx, BfHashFlag_None, hashSeed) ^ HASH_MODTYPE + (int)modifiedTypeType->mModifiedKind; return (elemHash << 5) - elemHash; } else if (type->IsConcreteInterfaceType()) { auto concreteInterfaceType = (BfConcreteInterfaceType*)type; - int elemHash = Hash(concreteInterfaceType->mInterface, ctx) ^ HASH_CONCRETE_INTERFACE; + int elemHash = Hash(concreteInterfaceType->mInterface, ctx, BfHashFlag_None, hashSeed) ^ HASH_CONCRETE_INTERFACE; return (elemHash << 5) - elemHash; } else if (type->IsSizedArray()) { auto sizedArray = (BfSizedArrayType*)type; - int elemHash = Hash(sizedArray->mElementType, ctx) ^ HASH_SIZED_ARRAY; + int elemHash = Hash(sizedArray->mElementType, ctx, BfHashFlag_None, hashSeed) ^ HASH_SIZED_ARRAY; int hashVal = (elemHash << 5) - elemHash; if (type->IsUnknownSizedArrayType()) { auto unknownSizedArray = (BfUnknownSizedArrayType*)type; - int elemHash = Hash(unknownSizedArray->mElementCountSource, ctx); + int elemHash = Hash(unknownSizedArray->mElementCountSource, ctx, BfHashFlag_None, hashSeed); hashVal = ((hashVal ^ elemHash) << 5) - hashVal; } else @@ -2944,7 +2944,7 @@ int BfResolvedTypeSet::DoHash(BfType* type, LookupContext* ctx, bool allowRef, i { BfConstExprValueType* constExprValueType = (BfConstExprValueType*)type; int hashVal = ((int)constExprValueType->mValue.mTypeCode << 17) ^ (constExprValueType->mValue.mInt32 << 3) ^ HASH_CONSTTYPE; - hashVal = ((hashVal ^ (Hash(constExprValueType->mType, ctx, BfHashFlag_AllowRef))) << 5) - hashVal; + hashVal = ((hashVal ^ (Hash(constExprValueType->mType, ctx, BfHashFlag_AllowRef, hashSeed))) << 5) - hashVal; return hashVal; } else @@ -3138,7 +3138,7 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa ctx->mFailed = true; return 0; } - return Hash(underlyingType, ctx, flags); + return Hash(underlyingType, ctx, flags, hashSeed); } } } @@ -3179,13 +3179,13 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa return hashVal; } else if (auto tupleTypeRef = BfNodeDynCastExact(typeRef)) - { + { int hashVal = HASH_VAL_TUPLE; for (int fieldIdx = 0; fieldIdx < (int)tupleTypeRef->mFieldTypes.size(); fieldIdx++) { BfTypeReference* fieldType = tupleTypeRef->mFieldTypes[fieldIdx]; - hashVal = ((hashVal ^ (Hash(fieldType, ctx))) << 5) - hashVal; + hashVal = ((hashVal ^ (Hash(fieldType, ctx, BfHashFlag_None, hashSeed))) << 5) - hashVal; int nameHash = 0; BfIdentifierNode* fieldName = NULL; @@ -3211,7 +3211,7 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa { if ((arrayType->mDimensions == 1) && (arrayType->mParams.size() != 0)) { - int rawElemHash = Hash(arrayType->mElementType, ctx); + int rawElemHash = Hash(arrayType->mElementType, ctx, BfHashFlag_None, hashSeed); int elemHash = rawElemHash ^ HASH_SIZED_ARRAY; int hashVal = (elemHash << 5) - elemHash; @@ -3235,7 +3235,7 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa BfTypedValue typedVal = constResolver.Resolve(sizeExpr, NULL, BfConstResolveFlag_ArrayInitSize); if (typedVal.mKind == BfTypedValueKind_GenericConstValue) { - int elemHash = Hash(typedVal.mType, ctx); + int elemHash = Hash(typedVal.mType, ctx, BfHashFlag_None, hashSeed); hashVal = ((hashVal ^ elemHash) << 5) - hashVal; return hashVal; } @@ -3294,13 +3294,13 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa } } - int elemHash = Hash(arrayType->mElementType, ctx) ^ (arrayType->mDimensions << 8); + int elemHash = Hash(arrayType->mElementType, ctx, BfHashFlag_None, hashSeed) ^ (arrayType->mDimensions << 8); return (elemHash << 5) - elemHash; } } else if (auto pointerType = BfNodeDynCastExact(typeRef)) { - int elemHash = Hash(pointerType->mElementType, ctx) ^ HASH_VAL_PTR; + int elemHash = Hash(pointerType->mElementType, ctx, BfHashFlag_None, hashSeed) ^ HASH_VAL_PTR; return (elemHash << 5) - elemHash; } else if (auto nullableType = BfNodeDynCastExact(typeRef)) @@ -3326,7 +3326,7 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa else if (refType->mRefToken->GetToken() == BfToken_Mut) refKind = BfRefType::RefKind_Mut; - int elemHash = Hash(refType->mElementType, ctx) ^ (HASH_VAL_REF + (int)refKind); + int elemHash = Hash(refType->mElementType, ctx, BfHashFlag_None, hashSeed) ^ (HASH_VAL_REF + (int)refKind); return (elemHash << 5) - elemHash; } else @@ -3370,7 +3370,9 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa ctx->mFailed = true; return 0; } - return Hash(resolvedType, ctx); + int hashVal = Hash(resolvedType, ctx, BfHashFlag_None, hashSeed); + hashSeed = 0; + return hashVal; } else if (auto varType = BfNodeDynCastExact(typeRef)) { @@ -3393,26 +3395,26 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa if (ctx->mRootTypeRef != retTypeTypeRef) { auto type = ctx->mModule->ResolveTypeRef(retTypeTypeRef, BfPopulateType_Identity, ctx->mResolveFlags); - return Hash(type, ctx, flags); + return Hash(type, ctx, flags, hashSeed); } - int elemHash = Hash(retTypeTypeRef->mElementType, ctx) ^ HASH_MODTYPE + retTypeTypeRef->mRetTypeToken->mToken; + int elemHash = Hash(retTypeTypeRef->mElementType, ctx, BfHashFlag_None, hashSeed) ^ HASH_MODTYPE + retTypeTypeRef->mRetTypeToken->mToken; return (elemHash << 5) - elemHash; } else if (auto resolvedTypeRef = BfNodeDynCastExact(typeRef)) { - return Hash(resolvedTypeRef->mType, ctx); + return Hash(resolvedTypeRef->mType, ctx, BfHashFlag_None, hashSeed); } else if (auto constTypeRef = BfNodeDynCastExact(typeRef)) { // We purposely don't mix in a HASH_CONSTTYPE because there's no such thing as a const type in Beef, so we just strip it - return Hash(constTypeRef->mElementType, ctx, flags); + return Hash(constTypeRef->mElementType, ctx, flags, hashSeed); } else if (auto delegateTypeRef = BfNodeDynCastExact(typeRef)) { int hashVal = HASH_DELEGATE; if (delegateTypeRef->mReturnType != NULL) - hashVal = ((hashVal ^ (Hash(delegateTypeRef->mReturnType, ctx, BfHashFlag_AllowRef))) << 5) - hashVal; + hashVal = ((hashVal ^ (Hash(delegateTypeRef->mReturnType, ctx, BfHashFlag_AllowRef, hashSeed))) << 5) - hashVal; else ctx->mFailed = true; @@ -3445,7 +3447,7 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa } } - hashVal = ((hashVal ^ (Hash(fieldType, ctx, (BfHashFlags)(BfHashFlag_AllowRef)))) << 5) - hashVal; + hashVal = ((hashVal ^ (Hash(fieldType, ctx, (BfHashFlags)(BfHashFlag_AllowRef), hashSeed))) << 5) - hashVal; hashVal = ((hashVal ^ (HashNode(param->mNameNode))) << 5) - hashVal; isFirstParam = true; } @@ -3534,7 +3536,11 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa { result = EvaluateToVariant(ctx, constExprTypeRef->mConstExpr, resultType); if ((resultType != NULL) && (resultType->IsGenericParam())) - return Hash(resultType, ctx); + { + int hashVal = Hash(resultType, ctx, BfHashFlag_None, hashSeed); + hashSeed = 0; + return hashVal; + } } if (resultType == NULL) @@ -3544,7 +3550,7 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa } auto hashVal = ((int)result.mTypeCode << 17) ^ (result.mInt32 << 3) ^ HASH_CONSTTYPE; - hashVal = ((hashVal ^ (Hash(resultType, ctx, BfHashFlag_AllowRef))) << 5) - hashVal; + hashVal = ((hashVal ^ (Hash(resultType, ctx, BfHashFlag_AllowRef, hashSeed))) << 5) - hashVal; return hashVal; } else if (auto dotTypeRef = BfNodeDynCastExact(typeRef)) From aa89d7d4969fc12fa9691ce23f135f8f1504e07a Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Thu, 18 Feb 2021 06:13:56 -0800 Subject: [PATCH 64/71] Fixed issues with very long errors --- IDE/src/ui/ErrorsPanel.bf | 10 +++++++++- IDE/src/ui/HoverWatch.bf | 2 +- IDE/src/ui/SourceViewPanel.bf | 9 +++++++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/IDE/src/ui/ErrorsPanel.bf b/IDE/src/ui/ErrorsPanel.bf index 0d13162c..f64e2724 100644 --- a/IDE/src/ui/ErrorsPanel.bf +++ b/IDE/src/ui/ErrorsPanel.bf @@ -276,7 +276,15 @@ namespace IDE.ui SetLabel(item, codeStr); let descItem = item.GetSubItem(1); - String errStr = scope String(32)..Append(error.mError); + String errStr = scope String(32); + int maxLen = 4*1024; + if (error.mError.Length > maxLen) + { + errStr.Append(error.mError.Substring(0, maxLen)); + errStr.Append("..."); + } + else + errStr.Append(error.mError); errStr.Replace('\n', ' '); SetLabel(descItem, errStr); diff --git a/IDE/src/ui/HoverWatch.bf b/IDE/src/ui/HoverWatch.bf index 5fae8f47..77468a09 100644 --- a/IDE/src/ui/HoverWatch.bf +++ b/IDE/src/ui/HoverWatch.bf @@ -738,7 +738,7 @@ namespace IDE.ui String val = scope String(); if (evalString.StartsWith(":", StringComparison.Ordinal)) { - var showString = scope String(evalString, 1); + var showString = scope String(4096)..Append(evalString, 1); bool isShowingDoc = showString.Contains('\x01'); if (!isShowingDoc) { diff --git a/IDE/src/ui/SourceViewPanel.bf b/IDE/src/ui/SourceViewPanel.bf index d25fed70..98a4cf3c 100644 --- a/IDE/src/ui/SourceViewPanel.bf +++ b/IDE/src/ui/SourceViewPanel.bf @@ -5073,7 +5073,11 @@ namespace IDE.ui String showMouseoverString = null; if (bestError.mError != null) { - showMouseoverString = scope:: String(":", bestError.mError); + int maxLen = 16*1024; + if (bestError.mError.Length > maxLen) + showMouseoverString = scope:: String()..Concat(":", StringView(bestError.mError, 0, maxLen), "..."); + else + showMouseoverString = scope:: String()..Concat(":", bestError.mError); if (bestError.mMoreInfo != null) { @@ -5676,7 +5680,8 @@ namespace IDE.ui } } - UpdateMouseover(); + if (gApp.mIsUpdateBatchStart) + UpdateMouseover(); var compiler = ResolveCompiler; var bfSystem = BfResolveSystem; From 02f17a889a639e076b1aad11c69a1c9dcdcc8714 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Thu, 18 Feb 2021 06:43:53 -0800 Subject: [PATCH 65/71] Fixed alias type hashing issue --- IDEHelper/Compiler/BfResolvedTypeUtils.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index 5be39d7a..0b6e6c1f 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -3138,7 +3138,9 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa ctx->mFailed = true; return 0; } - return Hash(underlyingType, ctx, flags, hashSeed); + int hashVal = Hash(underlyingType, ctx, flags, hashSeed); + hashSeed = 0; + return hashVal; } } } From 18f9fb881fdb4e886ecb67965e7591e4faa9d2ca Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Thu, 18 Feb 2021 07:52:44 -0800 Subject: [PATCH 66/71] Fixed duplicate Equals methods with code generation on structs --- IDEHelper/Compiler/BfDefBuilder.cpp | 15 ++++++++++----- IDEHelper/Compiler/BfModule.cpp | 2 +- IDEHelper/Tests/src/Comptime.bf | 22 ++++++++++++++++++++++ 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/IDEHelper/Compiler/BfDefBuilder.cpp b/IDEHelper/Compiler/BfDefBuilder.cpp index aa19e6e3..3e34d58d 100644 --- a/IDEHelper/Compiler/BfDefBuilder.cpp +++ b/IDEHelper/Compiler/BfDefBuilder.cpp @@ -1905,9 +1905,10 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString) BfMethodDef* dynamicCastMethod = NULL; BfMethodDef* toStringMethod = NULL; bool needsEqualsMethod = ((mCurTypeDef->mTypeCode == BfTypeCode_Struct) || (mCurTypeDef->mTypeCode == BfTypeCode_Enum)) && (!mCurTypeDef->mIsStatic); + BfMethodDef* equalsOpMethod = NULL; BfMethodDef* equalsMethod = NULL; - BfMethodDef* strictEqualsMethod = NULL; - + BfMethodDef* strictEqualsMethod = NULL; + bool needsStaticInit = false; for (int methodIdx = 0; methodIdx < (int)mCurTypeDef->mMethods.size(); methodIdx++) { @@ -2025,6 +2026,10 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString) { if (method->mName == BF_METHODNAME_MARKMEMBERS_STATIC) _SetMethod(staticMarkMethod, method); + if (method->mName == BF_METHODNAME_DEFAULT_EQUALS) + _SetMethod(equalsMethod, method); + if (method->mName == BF_METHODNAME_DEFAULT_STRICT_EQUALS) + _SetMethod(strictEqualsMethod, method); } else { @@ -2048,7 +2053,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString) if ((method->mParams[0]->mTypeRef->ToString() == mCurTypeDef->mName->ToString()) && (method->mParams[1]->mTypeRef->ToString() == mCurTypeDef->mName->ToString())) { - _SetMethod(equalsMethod, method); + _SetMethod(equalsOpMethod, method); } } } @@ -2287,7 +2292,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString) methodDef->mAddedAfterEmit = mIsComptime; } - if ((needsEqualsMethod) && (equalsMethod == NULL)) + if ((needsEqualsMethod) && (equalsMethod == NULL) && (equalsOpMethod == NULL)) { auto methodDef = new BfMethodDef(); mCurTypeDef->mMethods.push_back(methodDef); @@ -2301,7 +2306,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString) methodDef->mAddedAfterEmit = mIsComptime; } - if (needsEqualsMethod) + if ((needsEqualsMethod) && (strictEqualsMethod == NULL)) { auto methodDef = new BfMethodDef(); mCurTypeDef->mMethods.push_back(methodDef); diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 351dbdd4..51f5194a 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -5245,7 +5245,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin typeFlags |= BfTypeFlags_Delegate; if (type->IsFunction()) typeFlags |= BfTypeFlags_Function; - if (type->WantsGCMarking()) + if ((type->mDefineState != BfTypeDefineState_CETypeInit) && (type->WantsGCMarking())) typeFlags |= BfTypeFlags_WantsMarking; int virtSlotIdx = -1; diff --git a/IDEHelper/Tests/src/Comptime.bf b/IDEHelper/Tests/src/Comptime.bf index 1d264f89..2fe333cd 100644 --- a/IDEHelper/Tests/src/Comptime.bf +++ b/IDEHelper/Tests/src/Comptime.bf @@ -80,6 +80,21 @@ namespace Tests } } + [IFaceA("C", InitVal=345)] + struct StructA + { + public int mA = 123; + + [OnCompile(.TypeInit), Comptime] + public static void Generate() + { + Compiler.EmitTypeBody(typeof(Self), """ + public int32 mB = 234; + public int32 GetValB() => mB; + """); + } + } + enum MethodAErr { ErrorA, @@ -168,6 +183,13 @@ namespace Tests Test.Assert(ca.mC == 345); Test.Assert(ca.GetValC() == 345); + StructA sa = .(); + Test.Assert(sa.mA == 123); + Test.Assert(sa.mB == 234); + Test.Assert(sa.GetValB() == 234); + Test.Assert(sa.mC == 345); + Test.Assert(sa.GetValC() == 345); + Compiler.Mixin("int val = 99;"); Test.Assert(val == 99); From 4c40028b33c5944c19851e3ca9c3e7010cafcf69 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Fri, 19 Feb 2021 06:05:00 -0800 Subject: [PATCH 67/71] Fixed O^2 issue relative to method chain length --- IDEHelper/Compiler/BfSourceClassifier.cpp | 44 +++++++++++++++++------ 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/IDEHelper/Compiler/BfSourceClassifier.cpp b/IDEHelper/Compiler/BfSourceClassifier.cpp index 387671ca..fc073b17 100644 --- a/IDEHelper/Compiler/BfSourceClassifier.cpp +++ b/IDEHelper/Compiler/BfSourceClassifier.cpp @@ -1,5 +1,6 @@ #include "BfSourceClassifier.h" #include "BfParser.h" +#include "BeefySysLib/util/BeefPerf.h" USING_NS_BF; @@ -421,14 +422,22 @@ void BfSourceClassifier::Visit(BfTokenNode* tokenNode) void BfSourceClassifier::Visit(BfInvocationExpression* invocationExpr) { - BfElementVisitor::Visit(invocationExpr); + //BfElementVisitor::Visit(invocationExpr); + Visit(invocationExpr->ToBase()); + + //BP_ZONE("BfSourceClassifier BfInvocationExpression"); BfAstNode* target = invocationExpr->mTarget; if (target == NULL) return; - + + VisitChild(invocationExpr->mOpenParen); + VisitChild(invocationExpr->mCloseParen); + VisitChild(invocationExpr->mGenericArgs); + if (auto scopedTarget = BfNodeDynCast(target)) { + VisitChild(target); target = scopedTarget->mTarget; VisitChild(scopedTarget->mScopeName); } @@ -438,25 +447,33 @@ void BfSourceClassifier::Visit(BfInvocationExpression* invocationExpr) { VisitChild(qualifiedName->mLeft); VisitChild(qualifiedName->mDot); + VisitChild(qualifiedName->mRight); identifier = qualifiedName->mRight; } else if ((identifier = BfNodeDynCast(target))) { + VisitChild(target); // Leave as BfAttributedIdentifierNode if that's the case - identifier = target; + identifier = target; } else if (auto qualifiedName = BfNodeDynCast(target)) { VisitChild(qualifiedName->mLeft); VisitChild(qualifiedName->mDot); + VisitChild(qualifiedName->mRight); identifier = qualifiedName->mRight; } else if (auto memberRefExpr = BfNodeDynCast(target)) { VisitChild(memberRefExpr->mTarget); VisitChild(memberRefExpr->mDotToken); + VisitChild(memberRefExpr->mMemberName); identifier = memberRefExpr->mMemberName; } + else + { + VisitChild(target); + } if (identifier != NULL) { @@ -469,20 +486,25 @@ void BfSourceClassifier::Visit(BfInvocationExpression* invocationExpr) if (identifier != NULL) SetElementType(identifier, BfSourceElementType_Method); } + + for (auto& val : invocationExpr->mArguments) + VisitChild(val); + for (auto& val : invocationExpr->mCommas) + VisitChild(val); } void BfSourceClassifier::Visit(BfIndexerExpression* indexerExpr) { - BfElementVisitor::Visit(indexerExpr); + //BfElementVisitor::Visit(indexerExpr); + Visit(indexerExpr->ToBase()); VisitChild(indexerExpr->mTarget); VisitChild(indexerExpr->mOpenBracket); - for (int i = 0; i < (int) indexerExpr->mArguments.size(); i++) - { - if (i > 0) - VisitChild(indexerExpr->mCommas[i - 1]); - VisitChild(indexerExpr->mArguments[i]); - } + + for (auto& val : indexerExpr->mArguments) + VisitChild(val); + for (auto& val : indexerExpr->mCommas) + VisitChild(val); VisitChild(indexerExpr->mCloseBracket); } @@ -523,6 +545,8 @@ void BfSourceClassifier::Visit(BfMethodDeclaration* methodDeclaration) if (!IsInterestedInMember(methodDeclaration)) return; + //BP_ZONE("BfSourceClassifier BfMethodDeclaration"); + SetAndRestoreValue prevMember(mCurMember, methodDeclaration); BfElementVisitor::Visit(methodDeclaration); From 9a854a0237e726b7240bab5a13b04a3ee93565ab Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Fri, 19 Feb 2021 11:24:14 -0800 Subject: [PATCH 68/71] Made null coalescing short-circuit --- IDEHelper/Compiler/BfExprEvaluator.cpp | 118 +++++++++++++------------ 1 file changed, 60 insertions(+), 58 deletions(-) diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index f7e82b18..4a782da5 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -20440,11 +20440,70 @@ void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExp } return; } - + BfType* wantType = leftValue.mType; if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift)) wantType = NULL; // Don't presume wantType = mModule->FixIntUnknown(wantType); + + if ((binaryOp == BfBinaryOp_NullCoalesce) && (leftValue) && ((leftValue.mType->IsPointer()) || (leftValue.mType->IsFunction()) || (leftValue.mType->IsObject()))) + { + auto prevBB = mModule->mBfIRBuilder->GetInsertBlock(); + + auto rhsBB = mModule->mBfIRBuilder->CreateBlock("nullc.rhs"); + auto endBB = mModule->mBfIRBuilder->CreateBlock("nullc.end"); + + BfIRValue isNull; + if (leftValue.mType->IsFunction()) + isNull = mModule->mBfIRBuilder->CreateIsNull( + mModule->mBfIRBuilder->CreateIntToPtr(leftValue.mValue, mModule->mBfIRBuilder->MapType(mModule->GetPrimitiveType(BfTypeCode_NullPtr)))); + else + isNull = mModule->mBfIRBuilder->CreateIsNull(leftValue.mValue); + mModule->mBfIRBuilder->CreateCondBr(isNull, rhsBB, endBB); + + mModule->AddBasicBlock(rhsBB); + rightValue = mModule->CreateValueFromExpression(rightExpression, wantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast)); + if (!rightValue) + { + mModule->AssertErrorState(); + return; + } + else + { + auto rightToLeftValue = mModule->CastToValue(rightExpression, rightValue, leftValue.mType, BfCastFlags_SilentFail); + if (rightToLeftValue) + { + rightValue = BfTypedValue(rightToLeftValue, leftValue.mType); + } + else + { + auto leftToRightValue = mModule->CastToValue(leftExpression, leftValue, rightValue.mType, BfCastFlags_SilentFail); + if (leftToRightValue) + { + leftValue = BfTypedValue(leftToRightValue, rightValue.mType); + } + else + { + // Note: Annoying trigraph split for '??' + mModule->Fail(StrFormat("Operator '?" "?' cannot be applied to operands of type '%s' and '%s'", + mModule->TypeToString(leftValue.mType).c_str(), mModule->TypeToString(rightValue.mType).c_str()), opToken); + leftValue = mModule->GetDefaultTypedValue(rightValue.mType); + } + } + } + + mModule->mBfIRBuilder->CreateBr(endBB); + + auto endRhsBB = mModule->mBfIRBuilder->GetInsertBlock(); + mModule->AddBasicBlock(endBB); + auto phi = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(leftValue.mType), 2); + mModule->mBfIRBuilder->AddPhiIncoming(phi, leftValue.mValue, prevBB); + mModule->mBfIRBuilder->AddPhiIncoming(phi, rightValue.mValue, endRhsBB); + mResult = BfTypedValue(phi, leftValue.mType); + + return; + } + rightValue = mModule->CreateValueFromExpression(rightExpression, wantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast)); if ((!leftValue) || (!rightValue)) return; @@ -20652,63 +20711,6 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod return; } - if ((binaryOp == BfBinaryOp_NullCoalesce) && ((leftValue.mType->IsPointer()) || (leftValue.mType->IsFunction()) || (leftValue.mType->IsObject()))) - { - auto prevBB = mModule->mBfIRBuilder->GetInsertBlock(); - - auto rhsBB = mModule->mBfIRBuilder->CreateBlock("nullc.rhs"); - auto endBB = mModule->mBfIRBuilder->CreateBlock("nullc.end"); - - BfIRValue isNull; - if (leftValue.mType->IsFunction()) - isNull = mModule->mBfIRBuilder->CreateIsNull( - mModule->mBfIRBuilder->CreateIntToPtr(leftValue.mValue, mModule->mBfIRBuilder->MapType(mModule->GetPrimitiveType(BfTypeCode_NullPtr)))); - else - isNull = mModule->mBfIRBuilder->CreateIsNull(leftValue.mValue); - mModule->mBfIRBuilder->CreateCondBr(isNull, rhsBB, endBB); - - mModule->AddBasicBlock(rhsBB); - if (!rightValue) - { - mModule->AssertErrorState(); - return; - } - else - { - auto rightToLeftValue = mModule->CastToValue(rightExpression, rightValue, leftValue.mType, BfCastFlags_SilentFail); - if (rightToLeftValue) - { - rightValue = BfTypedValue(rightToLeftValue, leftValue.mType); - } - else - { - auto leftToRightValue = mModule->CastToValue(leftExpression, leftValue, rightValue.mType, BfCastFlags_SilentFail); - if (leftToRightValue) - { - leftValue = BfTypedValue(leftToRightValue, rightValue.mType); - } - else - { - // Note: Annoying trigraph split for '??' - mModule->Fail(StrFormat("Operator '?" "?' cannot be applied to operands of type '%s' and '%s'", - mModule->TypeToString(leftValue.mType).c_str(), mModule->TypeToString(rightValue.mType).c_str()), opToken); - leftValue = mModule->GetDefaultTypedValue(rightValue.mType); - } - } - } - - mModule->mBfIRBuilder->CreateBr(endBB); - - auto endRhsBB = mModule->mBfIRBuilder->GetInsertBlock(); - mModule->AddBasicBlock(endBB); - auto phi = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(leftValue.mType), 2); - mModule->mBfIRBuilder->AddPhiIncoming(phi, leftValue.mValue, prevBB); - mModule->mBfIRBuilder->AddPhiIncoming(phi, rightValue.mValue, endRhsBB); - mResult = BfTypedValue(phi, leftValue.mType); - - return; - } - if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift)) { forceLeftType = true; From 8047bebfcacde76aaa911c8e50e316dc5e536df5 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Fri, 19 Feb 2021 16:14:35 -0800 Subject: [PATCH 69/71] Fixed const float generic arg --- IDEHelper/Compiler/BfModule.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 51f5194a..3ce64219 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -11626,14 +11626,17 @@ BfVariant BfModule::TypedValueToVariant(BfAstNode* refNode, const BfTypedValue& case BfTypeCode_UIntPtr: case BfTypeCode_IntUnknown: case BfTypeCode_UIntUnknown: - case BfTypeCode_Float: case BfTypeCode_Double: case BfTypeCode_Char8: case BfTypeCode_Char16: case BfTypeCode_Char32: variant.mTypeCode = constant->mTypeCode; variant.mInt64 = constant->mInt64; - break; + break; + case BfTypeCode_Float: + variant.mTypeCode = constant->mTypeCode; + variant.mSingle = (float)constant->mDouble; + break; default: if (refNode != NULL) Fail("Invalid const expression type", refNode); From a5e0a5688b6e142ae7d50084a56d7d9d13be7ff9 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Sat, 20 Feb 2021 05:45:52 -0800 Subject: [PATCH 70/71] Added string literal to fixup queue --- IDEHelper/Compiler/CeMachine.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index 2f302190..1945bee8 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -6423,8 +6423,21 @@ CeErrorKind CeMachine::WriteConstant(CeConstStructData& data, BeConstant* constV if (globalVar->mName.StartsWith("__bfStrObj")) { int stringId = atoi(globalVar->mName.c_str() + 10); - addr_ce stringAddr = ceContext->GetString(stringId); + addr_ce stringAddr; + if (data.mQueueFixups) + { + stringAddr = 0; + CeConstStructFixup fixup; + fixup.mKind = CeConstStructFixup::Kind_StringPtr; + fixup.mValue = stringId; + fixup.mOffset = (int)data.mData.mSize; + data.mFixups.Add(fixup); + } + else + { + stringAddr = ceContext->GetString(stringId); + } auto ptr = data.mData.GrowUninitialized(ceModule->mSystem->mPtrSize); int64 addr64 = stringAddr; memcpy(ptr, &addr64, ceModule->mSystem->mPtrSize); From 59d4e258d5dd71a0cbcfd43cc223ef75fdb71f02 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Sun, 21 Feb 2021 06:25:27 -0800 Subject: [PATCH 71/71] Fixed prop binding issue with direct-autoprop optimization interference --- IDEHelper/Compiler/BfExprEvaluator.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 4a782da5..4f00c9d4 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -4635,6 +4635,8 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar bool doAccessCheck = true; + if ((flags & BfLookupFieldFlag_BindOnly) != 0) + doAccessCheck = false; if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mDisableObjectAccessChecksAttributeTypeDef))) doAccessCheck = false; @@ -4861,7 +4863,7 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar } // Check for direct auto-property access - if (startCheckType == mModule->mCurTypeInstance) + if ((startCheckType == mModule->mCurTypeInstance) && ((flags & BfLookupFieldFlag_BindOnly) == 0)) { if (auto propertyDeclaration = BfNodeDynCast(mPropDef->mFieldDeclaration)) {