1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-09 03:52:19 +02:00

Show comptime emits as embedded sourceviews

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

View file

@ -59,7 +59,7 @@ namespace Beefy.theme.dark
public uint32 mBkgColor; public uint32 mBkgColor;
public DarkEditWidget mEditWidget; public DarkEditWidget mEditWidget;
bool mAllowReverseDropdown; // Allow popdown to "popup" if there isn't enough space bool mAllowReverseDropdown; // Allow popdown to "popup" if there isn't enough space
public Widget mPrevFocusWidget; public SafeWidgetRef mPrevFocusWidget ~ delete _;
public bool mFocusDropdown = true; public bool mFocusDropdown = true;
virtual public StringView Label virtual public StringView Label
@ -170,12 +170,16 @@ namespace Beefy.theme.dark
public virtual void MenuClosed() public virtual void MenuClosed()
{ {
if (mPrevFocusWidget != null) mPrevFocusWidget?.Value?.SetFocus();
{
mPrevFocusWidget.SetFocus();
}
} }
protected override void RemovedFromWindow()
{
base.RemovedFromWindow();
mCurMenuWidget?.mMenu.mOnMenuClosed.Dispose();
}
void HandleClose(Menu menu, Menu selectedItem) void HandleClose(Menu menu, Menu selectedItem)
{ {
mCurMenuWidget = null; mCurMenuWidget = null;
@ -186,7 +190,8 @@ namespace Beefy.theme.dark
public virtual MenuWidget ShowDropdown() public virtual MenuWidget ShowDropdown()
{ {
mPrevFocusWidget = mWidgetWindow.mFocusWidget; if ((mPrevFocusWidget == null) && (mWidgetWindow.mFocusWidget != null))
mPrevFocusWidget = new .(mWidgetWindow.mFocusWidget);
float popupXOfs = GS!(5); float popupXOfs = GS!(5);
float popupYOfs = GS!(-2); float popupYOfs = GS!(-2);
@ -302,6 +307,16 @@ namespace Beefy.theme.dark
return true; return true;
} }
public void SelectFromLabel()
{
var label = Label;
for (let itemWidget in mCurMenuWidget.mItemWidgets)
{
if (itemWidget.mMenuItem.mLabel == label)
mCurMenuWidget.SetSelection(@itemWidget.Index);
}
}
void EditKeyDownHandler(KeyDownEvent evt) void EditKeyDownHandler(KeyDownEvent evt)
{ {
if (!WantsKeyHandling()) if (!WantsKeyHandling())
@ -318,13 +333,7 @@ namespace Beefy.theme.dark
if ((evt.mKeyCode == .Down) && (mCurMenuWidget == null)) if ((evt.mKeyCode == .Down) && (mCurMenuWidget == null))
{ {
ShowDropdown(); ShowDropdown();
SelectFromLabel();
var label = Label;
for (let itemWidget in mCurMenuWidget.mItemWidgets)
{
if (itemWidget.mMenuItem.mLabel == label)
mCurMenuWidget.SetSelection(@itemWidget.Index);
}
} }
if ((evt.mKeyCode == .Escape) && (mCurMenuWidget != null) && (mEditWidget != null)) if ((evt.mKeyCode == .Escape) && (mCurMenuWidget != null) && (mEditWidget != null))

View file

@ -21,6 +21,7 @@ namespace Beefy.theme.dark
} }
public Kind mKind; public Kind mKind;
public int32 mLine = -1;
public ~this() public ~this()
{ {
@ -61,7 +62,8 @@ namespace Beefy.theme.dark
public uint32 mViewWhiteSpaceColor; public uint32 mViewWhiteSpaceColor;
public bool mScrollToStartOnLostFocus; public bool mScrollToStartOnLostFocus;
public bool mHiliteCurrentLine; public bool mHiliteCurrentLine;
public Dictionary<int, Embed> mEmbeds = new .() ~ DeleteDictionaryAndValues!(_); public Dictionary<int32, Embed> mEmbeds = new .() ~ DeleteDictionaryAndValues!(_);
public Range? mLineRange;
protected static uint32[] sDefaultColors = new uint32[] ( Color.White ) ~ delete _; protected static uint32[] sDefaultColors = new uint32[] ( Color.White ) ~ delete _;
@ -498,7 +500,7 @@ namespace Beefy.theme.dark
((embed.mKind == .HideLine) && (!hideLine))) ((embed.mKind == .HideLine) && (!hideLine)))
selStartX += GS!(4); selStartX += GS!(4);
Rect rect = .(selStartX, mLineCoords[lineIdx] - GS!(2), embed.GetWidth(hideLine), mFont.GetLineSpacing() + GS!(4)); Rect rect = .(selStartX, mLineCoords[lineIdx] - GS!(1), embed.GetWidth(hideLine), mFont.GetLineSpacing() + GS!(3));
if (rect.mY < 0) if (rect.mY < 0)
rect.mY = 0; rect.mY = 0;
return rect; return rect;
@ -508,7 +510,6 @@ namespace Beefy.theme.dark
{ {
base.Draw(g); base.Draw(g);
#unwarn #unwarn
int lineCount = GetLineCount(); int lineCount = GetLineCount();
float lineSpacing = mFont.GetLineSpacing(); float lineSpacing = mFont.GetLineSpacing();
@ -588,6 +589,12 @@ namespace Beefy.theme.dark
drewCursor = true; drewCursor = true;
} }
if (mLineRange != null)
{
firstLine = Math.Max(firstLine, mLineRange.Value.Start);
lastLine = Math.Min(lastLine, mLineRange.Value.End - 1);
}
String sectionText = scope String(256); String sectionText = scope String(256);
for (int lineIdx = firstLine; lineIdx <= lastLine; lineIdx++) for (int lineIdx = firstLine; lineIdx <= lastLine; lineIdx++)
{ {
@ -604,7 +611,7 @@ namespace Beefy.theme.dark
continue; continue;
DarkEditWidgetContent.Embed embed = null; DarkEditWidgetContent.Embed embed = null;
if (mEmbeds.GetValue(lineIdx) case .Ok(out embed)) if (mEmbeds.GetValue((.)lineIdx) case .Ok(out embed))
{ {
if ((embed.mKind == .HideLine) && if ((embed.mKind == .HideLine) &&
((!IsInCollapseGroup(lineIdx, CursorLine)) || (!mEditWidget.mHasFocus))) ((!IsInCollapseGroup(lineIdx, CursorLine)) || (!mEditWidget.mHasFocus)))
@ -813,6 +820,20 @@ namespace Beefy.theme.dark
return line; return line;
} }
public override void PhysCursorMoved(CursorMoveKind moveKind)
{
base.PhysCursorMoved(moveKind);
if (mLineRange != null)
{
var lineAndColumn = CursorLineAndColumn;
if (lineAndColumn.mLine < mLineRange.Value.Start)
CursorLineAndColumn = .(mLineRange.Value.Start, lineAndColumn.mColumn);
else if (lineAndColumn.mLine >= mLineRange.Value.End)
CursorLineAndColumn = .(mLineRange.Value.End - 1, lineAndColumn.mColumn);
}
}
public override bool GetLineCharAtCoord(float x, float y, out int line, out int lineChar, out float overflowX) public override bool GetLineCharAtCoord(float x, float y, out int line, out int lineChar, out float overflowX)
{ {
line = GetLineAt(y); line = GetLineAt(y);
@ -1145,7 +1166,7 @@ namespace Beefy.theme.dark
bool isOverEmbed = false; bool isOverEmbed = false;
if (mEmbeds.GetValue(line) case .Ok(let embed)) if (mEmbeds.GetValue((.)line) case .Ok(let embed))
{ {
Rect embedRect = GetEmbedRect(line, embed); Rect embedRect = GetEmbedRect(line, embed);
if (embedRect.Contains(x, y)) if (embedRect.Contains(x, y))
@ -1223,6 +1244,21 @@ namespace Beefy.theme.dark
mVertScrollbar.mScrollIncrement = scrollIncrement; mVertScrollbar.mScrollIncrement = scrollIncrement;
} }
public override void UpdateScrollbarData()
{
base.UpdateScrollbarData();
var ewc = mEditWidgetContent as DarkEditWidgetContent;
if (ewc.mLineRange != null)
{
ewc.GetTextData();
mVertScrollbar.mContentStart = ewc.mLineCoords[Math.Min(ewc.mLineRange.Value.Start, ewc.mLineCoords.Count - 1)];
mVertScrollbar.mContentSize = ewc.mLineCoords[Math.Min(ewc.mLineRange.Value.End, ewc.mLineCoords.Count - 1)] - mVertScrollbar.mContentStart;
ScrollPositionChanged();
mVertScrollbar.UpdateData();
}
}
public override void Draw(Graphics g) public override void Draw(Graphics g)
{ {
base.Draw(g); base.Draw(g);

View file

@ -125,14 +125,14 @@ namespace Beefy.theme.dark
float trackSize = sizeLeft - mThumb.mWidth; float trackSize = sizeLeft - mThumb.mWidth;
float trackPct = (x - btnMargin) / trackSize; float trackPct = (x - btnMargin) / trackSize;
double contentPos = (mContentSize - mPageSize) * trackPct; double contentPos = (mContentSize - mPageSize) * trackPct;
return contentPos; return contentPos + mContentStart;
} }
else else
{ {
float trackSize = sizeLeft - mThumb.mHeight; float trackSize = sizeLeft - mThumb.mHeight;
float trackPct = (y - btnMargin) / trackSize; float trackPct = (y - btnMargin) / trackSize;
double contentPos = (mContentSize - mPageSize) * trackPct; double contentPos = (mContentSize - mPageSize) * trackPct;
return contentPos; return contentPos + mContentStart;
} }
} }

View file

@ -2868,11 +2868,11 @@ namespace Beefy.widgets
ExtractString(lineStart, lineEnd - lineStart, outStr); // Full line ExtractString(lineStart, lineEnd - lineStart, outStr); // Full line
} }
public int GetTextIdx(int line, int charIdx) public int GetTextIdx(int line, int lineChar)
{ {
GetTextData(); GetTextData();
int useLine = Math.Min(line, mData.mLineStarts.Count - 1); int useLine = Math.Min(line, mData.mLineStarts.Count - 1);
return mData.mLineStarts[useLine] + charIdx; return mData.mLineStarts[useLine] + lineChar;
} }
public int GetCharIdIdx(int32 findCharId) public int GetCharIdIdx(int32 findCharId)
@ -3139,13 +3139,15 @@ namespace Beefy.widgets
float lineHeight = GetLineHeight(line); float lineHeight = GetLineHeight(line);
double yOfs = (mEditWidget.mVertScrollbar?.mContentStart).GetValueOrDefault();
if (mIsMultiline) if (mIsMultiline)
{ {
if (aY < mEditWidget.mVertPos.mDest + mTextInsets.mTop) if (aY < mEditWidget.mVertPos.mDest + mTextInsets.mTop + yOfs)
{ {
if (scrollView) if (scrollView)
{ {
float scrollPos = aY - mTextInsets.mTop; double scrollPos = aY - mTextInsets.mTop - yOfs;
if (centerView) if (centerView)
{ {
scrollPos -= mEditWidget.mScrollContentContainer.mHeight * 0.50f; scrollPos -= mEditWidget.mScrollContentContainer.mHeight * 0.50f;
@ -3158,7 +3160,7 @@ namespace Beefy.widgets
int aLine; int aLine;
int aCharIdx; int aCharIdx;
float overflowX; float overflowX;
GetLineCharAtCoord(aX, (float)mEditWidget.mVertPos.mDest + mTextInsets.mTop, out aLine, out aCharIdx, out overflowX); GetLineCharAtCoord(aX, (float)(mEditWidget.mVertPos.mDest + mTextInsets.mTop + yOfs), out aLine, out aCharIdx, out overflowX);
float newX; float newX;
float newY; float newY;
@ -3169,11 +3171,11 @@ namespace Beefy.widgets
MoveCursorTo(aLine, aCharIdx); MoveCursorTo(aLine, aCharIdx);
} }
} }
else if (aY + lineHeight + mShowLineBottomPadding > mEditWidget.mVertPos.mDest + mEditWidget.mScrollContentContainer.mHeight) else if (aY + lineHeight + mShowLineBottomPadding > mEditWidget.mVertPos.mDest + mEditWidget.mScrollContentContainer.mHeight + yOfs)
{ {
if (scrollView) if (scrollView)
{ {
float scrollPos = aY + lineHeight + mShowLineBottomPadding - mEditWidget.mScrollContentContainer.mHeight; double scrollPos = aY + lineHeight + mShowLineBottomPadding - mEditWidget.mScrollContentContainer.mHeight - yOfs;
if (centerView) if (centerView)
{ {
// Show slightly more content on bottom // Show slightly more content on bottom
@ -3183,7 +3185,7 @@ namespace Beefy.widgets
mEditWidget.VertScrollTo(scrollPos); mEditWidget.VertScrollTo(scrollPos);
} }
else else
MoveCursorToCoord(aX, (float)mEditWidget.mVertPos.mDest + mEditWidget.mScrollContentContainer.mHeight - lineHeight); MoveCursorToCoord(aX, (float)(mEditWidget.mVertPos.mDest + mEditWidget.mScrollContentContainer.mHeight - lineHeight + yOfs));
} }
} }

View file

@ -121,7 +121,11 @@ namespace Beefy.widgets
public bool VertScrollTo(double vertPos, bool immediate = false) public bool VertScrollTo(double vertPos, bool immediate = false)
{ {
double aVertPos = Math.Max(0, Math.Min(vertPos, mScrollContent.mHeight - mScrollContentContainer.mHeight)); float contentHeight = mScrollContent.mHeight;
if (mVertScrollbar != null)
contentHeight = (float)mVertScrollbar.mContentSize;
double aVertPos = Math.Max(0, Math.Min(vertPos, contentHeight - mScrollContentContainer.mHeight));
if (aVertPos == mVertPos.mDest) if (aVertPos == mVertPos.mDest)
return false; return false;
@ -200,6 +204,7 @@ namespace Beefy.widgets
mHorzScrollbar.UpdateData(); mHorzScrollbar.UpdateData();
MarkDirty(); MarkDirty();
} }
if ((mVertScrollbar != null) && (mVertScrollbar.mContentPos != mVertPos.v)) if ((mVertScrollbar != null) && (mVertScrollbar.mContentPos != mVertPos.v))
{ {
mVertScrollbar.mContentPos = mVertPos.v; mVertScrollbar.mContentPos = mVertPos.v;
@ -208,7 +213,9 @@ namespace Beefy.widgets
} }
if (mScrollContent != null) if (mScrollContent != null)
{ {
mScrollContent.Resize((int32)(-mHorzPos.v), (int32)(-mVertPos.v), mScrollContent.Resize(
(int32)(-mHorzPos.v - (mHorzScrollbar?.mContentStart).GetValueOrDefault()),
(int32)(-mVertPos.v - (mVertScrollbar?.mContentStart).GetValueOrDefault()),
mScrollContent.mWidth, mScrollContent.mHeight); mScrollContent.mWidth, mScrollContent.mHeight);
} }
@ -253,6 +260,7 @@ namespace Beefy.widgets
public override void MouseWheel(float x, float y, float deltaX, float deltaY) public override void MouseWheel(float x, float y, float deltaX, float deltaY)
{ {
base.MouseWheel(x, y, deltaX, deltaY); base.MouseWheel(x, y, deltaX, deltaY);
if (deltaY != 0) if (deltaY != 0)
{ {
if (mVertScrollbar != null) if (mVertScrollbar != null)

View file

@ -100,6 +100,7 @@ namespace Beefy.widgets
Vert Vert
} }
public double mContentStart;
public double mContentSize; public double mContentSize;
public double mPageSize; public double mPageSize;
public double mContentPos; public double mContentPos;
@ -120,6 +121,7 @@ namespace Beefy.widgets
public float mScrollIncrement; public float mScrollIncrement;
public bool mAlignItems; public bool mAlignItems;
public bool mDoAutoClamp = true; public bool mDoAutoClamp = true;
public bool mAllowMouseWheel = true;
public Event<ScrollEventHandler> mOnScrollEvent ~ _.Dispose(); public Event<ScrollEventHandler> mOnScrollEvent ~ _.Dispose();
@ -147,6 +149,9 @@ namespace Beefy.widgets
public virtual void ScrollTo(double pos) public virtual void ScrollTo(double pos)
{ {
var pos;
pos -= mContentStart;
MarkDirty(); MarkDirty();
double oldPos = mContentPos; double oldPos = mContentPos;
@ -161,8 +166,8 @@ namespace Beefy.widgets
if ((mOnScrollEvent.HasListeners) && (oldPos != mContentPos)) if ((mOnScrollEvent.HasListeners) && (oldPos != mContentPos))
{ {
ScrollEvent scrollEvent = scope ScrollEvent(); ScrollEvent scrollEvent = scope ScrollEvent();
scrollEvent.mOldPos = oldPos; scrollEvent.mOldPos = oldPos + mContentStart;
scrollEvent.mNewPos = mContentPos; scrollEvent.mNewPos = mContentPos + mContentStart;
mOnScrollEvent(scrollEvent); mOnScrollEvent(scrollEvent);
} }
} }
@ -176,7 +181,7 @@ namespace Beefy.widgets
public virtual void Scroll(double amt) public virtual void Scroll(double amt)
{ {
ScrollTo(mContentPos + amt); ScrollTo(mContentPos + amt + mContentStart);
} }
public virtual double GetContentPosAt(float x, float y) public virtual double GetContentPosAt(float x, float y)
@ -226,6 +231,12 @@ namespace Beefy.widgets
public override void MouseWheel(float x, float y, float deltaX, float deltaY) public override void MouseWheel(float x, float y, float deltaX, float deltaY)
{ {
if (!mAllowMouseWheel)
{
base.MouseWheel(x, y, deltaX, deltaY);
return;
}
float delta = (mOrientation == .Horz) ? deltaX : deltaY; float delta = (mOrientation == .Horz) ? deltaX : deltaY;
Scroll(GetScrollIncrement() * -delta); Scroll(GetScrollIncrement() * -delta);
} }

View file

@ -834,4 +834,27 @@ namespace Beefy.widgets
return true; return true;
} }
} }
class SafeWidgetRef
{
Widget mWidget;
public this(Widget widget)
{
mWidget = widget;
mWidget.mOnDeleted.Add(new => OnDelete);
}
public ~this()
{
mWidget?.mOnDeleted.Remove(scope => OnDelete, true);
}
public Widget Value => mWidget;
void OnDelete(Widget widget)
{
mWidget = null;
}
}
} }

View file

@ -1624,6 +1624,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"</Co
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release Static|x64'">TurnOffAllWarnings</WarningLevel> <WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release Static|x64'">TurnOffAllWarnings</WarningLevel>
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">TurnOffAllWarnings</WarningLevel> <WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">TurnOffAllWarnings</WarningLevel>
</ClCompile> </ClCompile>
<ClCompile Include="third_party\miniz\miniz.c" />
<ClCompile Include="third_party\png\png.c"> <ClCompile Include="third_party\png\png.c">
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level1</WarningLevel> <WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level1</WarningLevel>
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug Static|Win32'">Level1</WarningLevel> <WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug Static|Win32'">Level1</WarningLevel>
@ -1950,6 +1951,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"</Co
<ClCompile Include="util\UTF8.cpp" /> <ClCompile Include="util\UTF8.cpp" />
<ClCompile Include="util\Vector.cpp" /> <ClCompile Include="util\Vector.cpp" />
<ClCompile Include="util\WorkThread.cpp" /> <ClCompile Include="util\WorkThread.cpp" />
<ClCompile Include="util\ZipFile.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="BFApp.h" /> <ClInclude Include="BFApp.h" />
@ -2133,6 +2135,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"</Co
<ClInclude Include="third_party\jpeg\transupp.h" /> <ClInclude Include="third_party\jpeg\transupp.h" />
<ClInclude Include="third_party\libffi\i686-pc-cygwin\include\ffi.h" /> <ClInclude Include="third_party\libffi\i686-pc-cygwin\include\ffi.h" />
<ClInclude Include="third_party\libffi\i686-pc-cygwin\include\ffitarget.h" /> <ClInclude Include="third_party\libffi\i686-pc-cygwin\include\ffitarget.h" />
<ClInclude Include="third_party\miniz\miniz.h" />
<ClInclude Include="third_party\png\png.h" /> <ClInclude Include="third_party\png\png.h" />
<ClInclude Include="third_party\png\pngasmrd.h" /> <ClInclude Include="third_party\png\pngasmrd.h" />
<ClInclude Include="third_party\png\pngconf.h" /> <ClInclude Include="third_party\png\pngconf.h" />
@ -2190,6 +2193,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"</Co
<ClInclude Include="util\UTF8.h" /> <ClInclude Include="util\UTF8.h" />
<ClInclude Include="util\Vector.h" /> <ClInclude Include="util\Vector.h" />
<ClInclude Include="util\WorkThread.h" /> <ClInclude Include="util\WorkThread.h" />
<ClInclude Include="util\ZipFile.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<CustomBuild Include="third_party\libffi\i686-pc-cygwin\src\x86\win64.asm"> <CustomBuild Include="third_party\libffi\i686-pc-cygwin\src\x86\win64.asm">

View file

@ -75,6 +75,9 @@
<Filter Include="src\third_party\stb"> <Filter Include="src\third_party\stb">
<UniqueIdentifier>{b85b0989-3047-46e9-93d7-5bc352fb0df7}</UniqueIdentifier> <UniqueIdentifier>{b85b0989-3047-46e9-93d7-5bc352fb0df7}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="src\third_party\miniz">
<UniqueIdentifier>{a159b9ee-1a71-44f5-a412-1e01e20b70c7}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="platform\win\DXRenderDevice.cpp"> <ClCompile Include="platform\win\DXRenderDevice.cpp">
@ -722,6 +725,12 @@
<ClCompile Include="util\Compress.cpp"> <ClCompile Include="util\Compress.cpp">
<Filter>src\util</Filter> <Filter>src\util</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="third_party\miniz\miniz.c">
<Filter>src\third_party\miniz</Filter>
</ClCompile>
<ClCompile Include="util\ZipFile.cpp">
<Filter>src\util</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Common.h"> <ClInclude Include="Common.h">
@ -1108,6 +1117,12 @@
<ClInclude Include="util\BitSet.h"> <ClInclude Include="util\BitSet.h">
<Filter>src\util</Filter> <Filter>src\util</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="third_party\miniz\miniz.h">
<Filter>src\third_party\miniz</Filter>
</ClInclude>
<ClInclude Include="util\ZipFile.h">
<Filter>src\util</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<CustomBuild Include="third_party\libffi\i686-pc-cygwin\src\x86\win32.asm"> <CustomBuild Include="third_party\libffi\i686-pc-cygwin\src\x86\win32.asm">

View file

@ -677,6 +677,7 @@
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level1</WarningLevel> <WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level1</WarningLevel>
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level1</WarningLevel> <WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level1</WarningLevel>
</ClCompile> </ClCompile>
<ClCompile Include="third_party\miniz\miniz.c" />
<ClCompile Include="third_party\png\png.c"> <ClCompile Include="third_party\png\png.c">
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level1</WarningLevel> <WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level1</WarningLevel>
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level1</WarningLevel> <WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level1</WarningLevel>
@ -883,6 +884,7 @@
<ClCompile Include="util\UTF8.cpp" /> <ClCompile Include="util\UTF8.cpp" />
<ClCompile Include="util\Vector.cpp" /> <ClCompile Include="util\Vector.cpp" />
<ClCompile Include="util\WorkThread.cpp" /> <ClCompile Include="util\WorkThread.cpp" />
<ClCompile Include="util\ZipFile.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="BFApp.h" /> <ClInclude Include="BFApp.h" />
@ -1007,6 +1009,7 @@
<ClInclude Include="third_party\jpeg\transupp.h" /> <ClInclude Include="third_party\jpeg\transupp.h" />
<ClInclude Include="third_party\libffi\i686-pc-cygwin\include\ffi.h" /> <ClInclude Include="third_party\libffi\i686-pc-cygwin\include\ffi.h" />
<ClInclude Include="third_party\libffi\i686-pc-cygwin\include\ffitarget.h" /> <ClInclude Include="third_party\libffi\i686-pc-cygwin\include\ffitarget.h" />
<ClInclude Include="third_party\miniz\miniz.h" />
<ClInclude Include="third_party\png\png.h" /> <ClInclude Include="third_party\png\png.h" />
<ClInclude Include="third_party\png\pngasmrd.h" /> <ClInclude Include="third_party\png\pngasmrd.h" />
<ClInclude Include="third_party\png\pngconf.h" /> <ClInclude Include="third_party\png\pngconf.h" />
@ -1049,6 +1052,7 @@
<ClInclude Include="util\UTF8.h" /> <ClInclude Include="util\UTF8.h" />
<ClInclude Include="util\Vector.h" /> <ClInclude Include="util\Vector.h" />
<ClInclude Include="util\WorkThread.h" /> <ClInclude Include="util\WorkThread.h" />
<ClInclude Include="util\ZipFile.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<CustomBuild Include="third_party\libffi\i686-pc-cygwin\src\x86\win64.asm"> <CustomBuild Include="third_party\libffi\i686-pc-cygwin\src\x86\win64.asm">

View file

@ -66,6 +66,9 @@
<Filter Include="src\third_party\utf8proc"> <Filter Include="src\third_party\utf8proc">
<UniqueIdentifier>{1309f90f-4745-4623-ab21-5d7b1450103c}</UniqueIdentifier> <UniqueIdentifier>{1309f90f-4745-4623-ab21-5d7b1450103c}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="src\third_party\miniz">
<UniqueIdentifier>{d32cb9b0-e79b-49fe-82e2-33302be0baf6}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="platform\win\DXRenderDevice.cpp"> <ClCompile Include="platform\win\DXRenderDevice.cpp">
@ -575,6 +578,12 @@
<ClCompile Include="util\Compress.cpp"> <ClCompile Include="util\Compress.cpp">
<Filter>src\util</Filter> <Filter>src\util</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="util\ZipFile.cpp">
<Filter>src\util</Filter>
</ClCompile>
<ClCompile Include="third_party\miniz\miniz.c">
<Filter>src\third_party\miniz</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Common.h"> <ClInclude Include="Common.h">
@ -883,6 +892,12 @@
<ClInclude Include="util\Compress.h"> <ClInclude Include="util\Compress.h">
<Filter>src\util</Filter> <Filter>src\util</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="util\ZipFile.h">
<Filter>src\util</Filter>
</ClInclude>
<ClInclude Include="third_party\miniz\miniz.h">
<Filter>src\third_party\miniz</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<CustomBuild Include="third_party\libffi\i686-pc-cygwin\src\x86\win32.asm"> <CustomBuild Include="third_party\libffi\i686-pc-cygwin\src\x86\win32.asm">

View file

@ -1152,6 +1152,9 @@ String Beefy::FixPath(const StringImpl& pathIn)
String Beefy::FixPathAndCase(const StringImpl& pathIn) String Beefy::FixPathAndCase(const StringImpl& pathIn)
{ {
if ((!pathIn.IsEmpty()) && (pathIn[0] == '$'))
return pathIn;
String path = FixPath(pathIn); String path = FixPath(pathIn);
#ifdef _WIN32 #ifdef _WIN32
for (int i = 0; i < (int)path.length(); ++i) for (int i = 0; i < (int)path.length(); ++i)
@ -1180,8 +1183,7 @@ String Beefy::RemoveTrailingSlash(const StringImpl& str)
bool Beefy::FileNameEquals(const StringImpl& filePathA, const StringImpl& filePathB) bool Beefy::FileNameEquals(const StringImpl& filePathA, const StringImpl& filePathB)
{ {
#ifdef _WIN32 #ifdef _WIN32
//return _stricmp(filePathA.c_str(), filePathB.c_str()) == 0;
if (filePathA.length() != filePathB.length()) if (filePathA.length() != filePathB.length())
return false; return false;

View file

@ -0,0 +1,110 @@
#include "ZipFile.h"
extern "C"
{
#include "miniz/miniz.h"
}
USING_NS_BF;
class ZipFile::Data
{
public:
bool mIsWriter;
mz_zip_archive mZip;
};
ZipFile::ZipFile()
{
mData = NULL;
}
ZipFile::~ZipFile()
{
if (mData != NULL)
Close();
}
bool ZipFile::Open(const StringImpl& filePath)
{
if (mData != NULL)
Close();
mData = new ZipFile::Data();
memset(mData, 0, sizeof(ZipFile::Data));
if (!mz_zip_reader_init_file(&mData->mZip, filePath.c_str(), 0))
return false;
return true;
}
bool ZipFile::Create(const StringImpl& filePath)
{
if (mData != NULL)
Close();
mData = new ZipFile::Data();
memset(mData, 0, sizeof(ZipFile::Data));
if (!mz_zip_writer_init_file(&mData->mZip, filePath.c_str(), 0))
{
delete mData;
mData = NULL;
return false;
}
mData->mIsWriter = true;
return true;
}
bool ZipFile::Close()
{
if (mData == NULL)
return false;
if (mData->mIsWriter)
{
if (!mz_zip_writer_finalize_archive(&mData->mZip))
return false;
if (!mz_zip_writer_end(&mData->mZip))
return false;
}
else
{
if (!mz_zip_reader_end(&mData->mZip))
return false;
}
return true;
}
bool ZipFile::IsOpen()
{
return mData != NULL;
}
bool ZipFile::Add(const StringImpl& fileName, Span<uint8> data)
{
if (mData == NULL)
return false;
if (!mz_zip_writer_add_mem(&mData->mZip, fileName.c_str(), data.mVals, data.mSize, MZ_NO_COMPRESSION))
return false;
return true;
}
bool ZipFile::Get(const StringImpl& fileName, Array<uint8>& data)
{
if (mData == NULL)
return false;
int idx = mz_zip_reader_locate_file(&mData->mZip, fileName.c_str(), NULL, 0);
if (idx < 0)
return false;
size_t size = 0;
void* ptr = mz_zip_reader_extract_to_heap(&mData->mZip, idx, &size, 0);
data.Insert(data.mSize, (uint8*)ptr, (intptr)size);
return true;
}

View file

@ -0,0 +1,30 @@
#pragma once
#include "../Common.h"
#include "../Span.h"
NS_BF_BEGIN
class ZipFile
{
public:
class Data;
public:
Data* mData;
public:
ZipFile();
~ZipFile();
bool Open(const StringImpl& filePath);
bool Create(const StringImpl& filePath);
bool Close();
bool IsOpen();
bool Add(const StringImpl& fileName, Span<uint8> data);
bool Get(const StringImpl& fileName, Array<uint8>& data);
};
NS_BF_END

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

File diff suppressed because it is too large Load diff

View file

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

View file

@ -5,14 +5,18 @@
#include "DebugTarget.h" #include "DebugTarget.h"
#include "DebugManager.h" #include "DebugManager.h"
#include "DWARFInfo.h" #include "DWARFInfo.h"
#include "BeefySysLib/Util/PerfTimer.h" #include "BeefySysLib/util/PerfTimer.h"
#include "BeefySysLib/Util/Dictionary.h" #include "BeefySysLib/util/Dictionary.h"
#include "BeefySysLib/Util/BeefPerf.h" #include "BeefySysLib/util/BeefPerf.h"
#include "BeefySysLib/util/BeefPerf.h"
#include "BeefySysLib/util/ZipFile.h"
#include "BeefySysLib/util/Hash.h"
#include "BeefySysLib/platform/PlatformHelper.h" #include "BeefySysLib/platform/PlatformHelper.h"
#include "WinDebugger.h" #include "WinDebugger.h"
#include "MiniDumpDebugger.h" #include "MiniDumpDebugger.h"
#include "Linker/BlHash.h" #include "Linker/BlHash.h"
#include "Backend/BeLibManger.h" #include "Backend/BeLibManger.h"
#include "Compiler/BfUtil.h"
#include <shlobj.h> #include <shlobj.h>
#include "BeefySysLib/util/AllocDebug.h" #include "BeefySysLib/util/AllocDebug.h"
@ -262,6 +266,7 @@ COFF::COFF(DebugTarget* debugTarget) : DbgModule(debugTarget)
mPrevScanName = NULL; mPrevScanName = NULL;
mProcSymCount = 0; mProcSymCount = 0;
mCvSrcSrvStream = -1; mCvSrcSrvStream = -1;
mCvEmitStream = -1;
mIsFastLink = false; mIsFastLink = false;
mHotThunkCurAddr = 0; mHotThunkCurAddr = 0;
mHotThunkDataLeft = 0; mHotThunkDataLeft = 0;
@ -270,6 +275,7 @@ COFF::COFF(DebugTarget* debugTarget) : DbgModule(debugTarget)
mDbgSymRequest = NULL; mDbgSymRequest = NULL;
mWantsAutoLoadDebugInfo = false; mWantsAutoLoadDebugInfo = false;
mPDBLoaded = false; mPDBLoaded = false;
mEmitSourceFile = NULL;
} }
COFF::~COFF() COFF::~COFF()
@ -3605,8 +3611,17 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c
GET_INTO(uint, fileTableOfs); GET_INTO(uint, fileTableOfs);
const char* fileName = mStringTable.mStrTable + fileTableOfs; const char* fileName = mStringTable.mStrTable + fileTableOfs;
if ((fileName[0] == '\\') && (fileName[1] == '$'))
fileName++;
DbgSrcFile* srcFile = NULL; DbgSrcFile* srcFile = NULL;
if ((fileName[0] == '/') || (fileName[0] == '\\') ||
if (fileName[0] == '$')
{
srcFile = AddSrcFile(compileUnit, fileName);
}
else if ((fileName[0] == '/') || (fileName[0] == '\\') ||
((fileName[0] != 0) && (fileName[1] == ':'))) ((fileName[0] != 0) && (fileName[1] == ':')))
{ {
srcFile = AddSrcFile(compileUnit, fileName); srcFile = AddSrcFile(compileUnit, fileName);
@ -4642,6 +4657,8 @@ void COFF::ScanCompileUnit(int compileUnitId)
else else
{ {
const char* fileName = mStringTable.mStrTable + fileTableOfs; const char* fileName = mStringTable.mStrTable + fileTableOfs;
if ((fileName[0] == '\\') && (fileName[1] == '$'))
fileName++;
srcFile = AddSrcFile(NULL, fileName); srcFile = AddSrcFile(NULL, fileName);
mSrcFileDeferredRefs.Add(srcFile); mSrcFileDeferredRefs.Add(srcFile);
*srcFilePtr = srcFile; *srcFilePtr = srcFile;
@ -4967,6 +4984,8 @@ bool COFF::CvParseHeader(uint8 wantGuid[16], int32 wantAge)
mStringTable.mStream = streamNum; mStringTable.mStream = streamNum;
if (strcmp(tableName, "srcsrv") == 0) if (strcmp(tableName, "srcsrv") == 0)
mCvSrcSrvStream = streamNum; mCvSrcSrvStream = streamNum;
if (strcmp(tableName, "emit") == 0)
mCvEmitStream = streamNum;
/*if (tableIdx == nameTableIdx) /*if (tableIdx == nameTableIdx)
{ {
@ -6095,6 +6114,9 @@ void COFF::ClosePDB()
delete kv.mValue; delete kv.mValue;
mHotLibMap.Clear(); mHotLibMap.Clear();
mHotLibSymMap.Clear(); mHotLibSymMap.Clear();
delete mEmitSourceFile;
mEmitSourceFile = NULL;
} }
bool COFF::LoadPDB(const String& pdbPath, uint8 wantGuid[16], int32 wantAge) bool COFF::LoadPDB(const String& pdbPath, uint8 wantGuid[16], int32 wantAge)
@ -6669,6 +6691,60 @@ String COFF::GetOldSourceCommand(const StringImpl& path)
return ""; return "";
} }
bool COFF::GetEmitSource(const StringImpl& filePath, String& outText)
{
if (!filePath.StartsWith("$Emit"))
return false;
if (mEmitSourceFile == NULL)
{
mEmitSourceFile = new ZipFile();
String zipPath = mPDBPath;
int dotPos = zipPath.LastIndexOf('.');
zipPath.RemoveToEnd(dotPos);
zipPath.Append("__emit.zip");
if (!mEmitSourceFile->Open(zipPath))
{
if (mCvEmitStream == -1)
return "";
int outSize;
uint8* data = CvReadStream(mCvEmitStream, &outSize);
FileStream fileStream;
fileStream.Open(zipPath, "wb");
fileStream.Write(data, outSize);
fileStream.Close();
delete data;
mEmitSourceFile->Open(zipPath);
}
}
if (mEmitSourceFile->IsOpen())
{
String usePath = filePath;
if (usePath.StartsWith("$Emit"))
{
int dollarPos = usePath.IndexOf('$', 1);
usePath.Remove(0, dollarPos + 1);
}
usePath = EncodeFileName(usePath);
usePath.Append(".bf");
Array<uint8> data;
if (mEmitSourceFile->Get(usePath, data))
{
outText.Insert(outText.mLength, (char*)data.mVals, data.mSize);
return true;
}
}
return false;
}
bool COFF::HasPendingDebugInfo() bool COFF::HasPendingDebugInfo()
{ {
if (mDbgSymRequest == NULL) if (mDbgSymRequest == NULL)
@ -7016,7 +7092,7 @@ addr_target COFF::LocateSymbol(const StringImpl& name)
delete dbgModule; delete dbgModule;
return 0; return 0;
} }
mDebugger->mDebugTarget->mDbgModules.push_back(dbgModule); mDebugger->mDebugTarget->AddDbgModule(dbgModule);
auto symbolEntry = mSymbolNameMap.Find(name.c_str()); auto symbolEntry = mSymbolNameMap.Find(name.c_str());
if (symbolEntry != NULL) if (symbolEntry != NULL)

View file

@ -13,6 +13,7 @@ namespace Beefy
class DataStream; class DataStream;
class MemStream; class MemStream;
class SafeMemStream; class SafeMemStream;
class ZipFile;
} }
struct CV_LVAR_ADDR_RANGE; struct CV_LVAR_ADDR_RANGE;
@ -214,6 +215,7 @@ public:
}; };
public: public:
ZipFile* mEmitSourceFile;
uint8 mWantPDBGuid[16]; uint8 mWantPDBGuid[16];
int mWantAge; int mWantAge;
@ -262,6 +264,7 @@ public:
int mCvPublicSymbolInfoStream; int mCvPublicSymbolInfoStream;
int mCvSymbolRecordStream; int mCvSymbolRecordStream;
int mCvSrcSrvStream; int mCvSrcSrvStream;
int mCvEmitStream;
int mCvNewFPOStream; int mCvNewFPOStream;
Array<CvModuleInfo*> mCvModuleInfo; Array<CvModuleInfo*> mCvModuleInfo;
Dictionary<int, DbgSrcFile*> mCVSrcFileRefCache; Dictionary<int, DbgSrcFile*> mCVSrcFileRefCache;
@ -320,6 +323,7 @@ public:
virtual intptr EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, DbgAddrType* outAddrType, DbgEvalLocFlags flags = DbgEvalLocFlag_None) override; virtual intptr EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, DbgAddrType* outAddrType, DbgEvalLocFlags flags = DbgEvalLocFlag_None) override;
virtual bool CanGetOldSource() override; virtual bool CanGetOldSource() override;
virtual String GetOldSourceCommand(const StringImpl& path) override; virtual String GetOldSourceCommand(const StringImpl& path) override;
virtual bool GetEmitSource(const StringImpl& filePath, String& outText) override;
virtual bool HasPendingDebugInfo() override; virtual bool HasPendingDebugInfo() override;
virtual void PreCacheImage() override; virtual void PreCacheImage() override;
virtual void PreCacheDebugInfo() override; virtual void PreCacheDebugInfo() override;

View file

@ -276,10 +276,15 @@ int BfAutoComplete::GetCursorIdx(BfAstNode* node)
if (node == NULL) if (node == NULL)
return -1; return -1;
if (!node->IsFromParser(mCompiler->mResolvePassData->mParser)) // if (!node->IsFromParser(mCompiler->mResolvePassData->mParser))
// return -1;
if (node->IsTemporary())
return false;
auto bfParser = node->GetSourceData()->ToParser();
if (bfParser == NULL)
return -1; return -1;
auto bfParser = node->GetSourceData()->ToParser();
if ((bfParser->mParserFlags & ParserFlag_Autocomplete) == 0) if ((bfParser->mParserFlags & ParserFlag_Autocomplete) == 0)
return -1; return -1;
@ -291,10 +296,14 @@ bool BfAutoComplete::IsAutocompleteNode(BfAstNode* node, int lengthAdd, int star
if (node == NULL) if (node == NULL)
return false; return false;
if (!node->IsFromParser(mCompiler->mResolvePassData->mParser)) // if (!node->IsFromParser(mCompiler->mResolvePassData->mParser))
return false; // return false;
if (node->IsTemporary())
return false;
auto bfParser = node->GetSourceData()->ToParser(); auto bfParser = node->GetSourceData()->ToParser();
if (bfParser == NULL)
return false;
if ((bfParser->mParserFlags & ParserFlag_Autocomplete) == 0) if ((bfParser->mParserFlags & ParserFlag_Autocomplete) == 0)
return false; return false;
@ -313,10 +322,14 @@ bool BfAutoComplete::IsAutocompleteNode(BfAstNode* startNode, BfAstNode* endNode
if ((startNode == NULL) || (endNode == NULL)) if ((startNode == NULL) || (endNode == NULL))
return false; return false;
if (!startNode->IsFromParser(mCompiler->mResolvePassData->mParser)) // if (!startNode->IsFromParser(mCompiler->mResolvePassData->mParser))
return false; // return false;
if (startNode->IsTemporary())
return false;
auto bfParser = startNode->GetSourceData()->ToParser(); auto bfParser = startNode->GetSourceData()->ToParser();
if (bfParser == NULL)
return false;
if ((bfParser->mParserFlags & ParserFlag_Autocomplete) == 0) if ((bfParser->mParserFlags & ParserFlag_Autocomplete) == 0)
return false; return false;
@ -335,10 +348,14 @@ bool BfAutoComplete::IsAutocompleteLineNode(BfAstNode* node)
if (node == NULL) if (node == NULL)
return false; return false;
if (!node->IsFromParser(mCompiler->mResolvePassData->mParser)) // if (!node->IsFromParser(mCompiler->mResolvePassData->mParser))
return false; // return false;
if (node->IsTemporary())
return false;
auto bfParser = node->GetSourceData()->ToParser(); auto bfParser = node->GetSourceData()->ToParser();
if (bfParser == NULL)
return false;
if ((bfParser->mParserFlags & ParserFlag_Autocomplete) == 0) if ((bfParser->mParserFlags & ParserFlag_Autocomplete) == 0)
return false; return false;
@ -414,7 +431,7 @@ BfTypedValue BfAutoComplete::LookupTypeRefOrIdentifier(BfAstNode* node, bool* is
{ {
// This keeps the classifier from colorizing properties - this causes 'flashing' when we go back over this with a resolve pass // This keeps the classifier from colorizing properties - this causes 'flashing' when we go back over this with a resolve pass
// that wouldn't catch this // that wouldn't catch this
SetAndRestoreValue<BfSourceClassifier*> prevClassifier(mModule->mCompiler->mResolvePassData->mSourceClassifier, NULL); SetAndRestoreValue<bool> prevClassifier(mModule->mCompiler->mResolvePassData->mIsClassifying, false);
BfExprEvaluator exprEvaluator(mModule); BfExprEvaluator exprEvaluator(mModule);
auto fieldResult = exprEvaluator.LookupField(qualifiedTypeRef->mRight, leftValue, rightNamedTypeRef->mNameNode->ToString()); auto fieldResult = exprEvaluator.LookupField(qualifiedTypeRef->mRight, leftValue, rightNamedTypeRef->mNameNode->ToString());
@ -1271,11 +1288,17 @@ BfProject* BfAutoComplete::GetActiveProject()
auto activeTypeDef = mModule->GetActiveTypeDef(); auto activeTypeDef = mModule->GetActiveTypeDef();
if (activeTypeDef != NULL) if (activeTypeDef != NULL)
bfProject = activeTypeDef->mProject; bfProject = activeTypeDef->mProject;
else else if (!mCompiler->mResolvePassData->mParsers.IsEmpty())
bfProject = mCompiler->mResolvePassData->mParser->mProject; bfProject = mCompiler->mResolvePassData->mParsers[0]->mProject;
return bfProject; return bfProject;
} }
bool BfAutoComplete::WantsEntries()
{
return (mResolveType == BfResolveType_Autocomplete) ||
(mResolveType == BfResolveType_Autocomplete_HighPri);
}
void BfAutoComplete::AddTopLevelNamespaces(BfAstNode* identifierNode) void BfAutoComplete::AddTopLevelNamespaces(BfAstNode* identifierNode)
{ {
String filter; String filter;
@ -1419,8 +1442,8 @@ void BfAutoComplete::AddTopLevelTypes(BfAstNode* identifierNode, bool onlyAttrib
else else
{ {
BfProject* curProject = NULL; BfProject* curProject = NULL;
if (mModule->mCompiler->mResolvePassData->mParser != NULL) if (!mModule->mCompiler->mResolvePassData->mParsers.IsEmpty())
curProject = mModule->mCompiler->mResolvePassData->mParser->mProject; curProject = mModule->mCompiler->mResolvePassData->mParsers[0]->mProject;
String prevName; String prevName;
for (auto typeDef : mModule->mSystem->mTypeDefs) for (auto typeDef : mModule->mSystem->mTypeDefs)
@ -1468,14 +1491,6 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress
} }
} }
} }
//bool isUsingDirective = false;
//bool isUsingDirective = (identifierNode != NULL) && (identifierNode->mParent != NULL) && (identifierNode->mParent->IsA<BfUsingDirective>());
if (mCompiler->mResolvePassData->mSourceClassifier != NULL)
{
//TODO: Color around dots
//mCompiler->mResolvePassData->mSourceClassifier->SetElementType(identifierNode, BfSourceElementType_Namespace);
}
if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(identifierNode)) if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(identifierNode))
{ {
@ -1483,10 +1498,6 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress
return; return;
} }
//bool isInExpression = true;
// if (identifierNode != NULL)
// isInExpression = IsInExpression(identifierNode);
AddTopLevelNamespaces(identifierNode); AddTopLevelNamespaces(identifierNode);
if (isUsingDirective) if (isUsingDirective)
return; // Only do namespaces return; // Only do namespaces
@ -1759,6 +1770,9 @@ String BfAutoComplete::GetFilter(BfAstNode* node)
bool BfAutoComplete::CheckMemberReference(BfAstNode* target, BfAstNode* dotToken, BfAstNode* memberName, bool onlyShowTypes, BfType* expectingType, bool isUsingDirective, bool onlyAttribute) bool BfAutoComplete::CheckMemberReference(BfAstNode* target, BfAstNode* dotToken, BfAstNode* memberName, bool onlyShowTypes, BfType* expectingType, bool isUsingDirective, bool onlyAttribute)
{ {
if (!WantsEntries())
return false;
BfAttributedIdentifierNode* attrIdentifier = NULL; BfAttributedIdentifierNode* attrIdentifier = NULL;
bool isAutocompletingName = false; bool isAutocompletingName = false;
if ((attrIdentifier = BfNodeDynCast<BfAttributedIdentifierNode>(memberName))) if ((attrIdentifier = BfNodeDynCast<BfAttributedIdentifierNode>(memberName)))

View file

@ -208,6 +208,7 @@ public:
public: public:
BfProject* GetActiveProject(); BfProject* GetActiveProject();
bool WantsEntries();
bool CheckProtection(BfProtection protection, BfTypeDef* typeDef, bool allowProtected, bool allowPrivate); bool CheckProtection(BfProtection protection, BfTypeDef* typeDef, bool allowProtected, bool allowPrivate);
String GetFilter(BfAstNode* node); String GetFilter(BfAstNode* node);
const char* GetTypeName(BfType* type); const char* GetTypeName(BfType* type);

View file

@ -27,6 +27,7 @@
#include "BfAutoComplete.h" #include "BfAutoComplete.h"
#include "BfResolvePass.h" #include "BfResolvePass.h"
#include "BeefySysLib/util/BeefPerf.h" #include "BeefySysLib/util/BeefPerf.h"
#include "BeefySysLib/util/ZipFile.h"
#include "../LLVMUtils.h" #include "../LLVMUtils.h"
#include "BfNamespaceVisitor.h" #include "BfNamespaceVisitor.h"
#include "CeMachine.h" #include "CeMachine.h"
@ -2276,7 +2277,7 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork)
bool madeFullPass = true; bool madeFullPass = true;
if (mCanceling) if (mCanceling)
madeFullPass = false; madeFullPass = false;
if ((mResolvePassData != NULL) && (mResolvePassData->mParser != NULL)) if ((mResolvePassData != NULL) && (!mResolvePassData->mParsers.IsEmpty()))
madeFullPass = false; madeFullPass = false;
SetAndRestoreValue<bool> prevAssertOnPopulateType(mContext->mAssertOnPopulateType, deleteUnusued && madeFullPass); SetAndRestoreValue<bool> prevAssertOnPopulateType(mContext->mAssertOnPopulateType, deleteUnusued && madeFullPass);
@ -3736,19 +3737,19 @@ void BfCompiler::VisitAutocompleteExteriorIdentifiers()
if (mResolvePassData->mAutoComplete != NULL) if (mResolvePassData->mAutoComplete != NULL)
mResolvePassData->mAutoComplete->CheckIdentifier(checkIdentifier, false, isUsingDirective); mResolvePassData->mAutoComplete->CheckIdentifier(checkIdentifier, false, isUsingDirective);
if ((checkIdentifier->IsFromParser(mResolvePassData->mParser)) && (mResolvePassData->mSourceClassifier != NULL)) if (auto sourceClassifier = mResolvePassData->GetSourceClassifier(checkIdentifier))
{ {
if (isUsingDirective) if (isUsingDirective)
{ {
while (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(checkIdentifier)) while (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(checkIdentifier))
{ {
mResolvePassData->mSourceClassifier->SetElementType(qualifiedNameNode->mRight, BfSourceElementType_Namespace); sourceClassifier->SetElementType(qualifiedNameNode->mRight, BfSourceElementType_Namespace);
checkIdentifier = qualifiedNameNode->mLeft; checkIdentifier = qualifiedNameNode->mLeft;
} }
if (checkIdentifier != NULL) if (checkIdentifier != NULL)
mResolvePassData->mSourceClassifier->SetElementType(checkIdentifier, BfSourceElementType_Namespace); sourceClassifier->SetElementType(checkIdentifier, BfSourceElementType_Namespace);
} }
} }
} }
@ -3903,9 +3904,10 @@ void BfCompiler::VisitSourceExteriorNodes()
parser->mParserData->mExteriorNodesCheckIdx = mSystem->mTypeMapVersion; parser->mParserData->mExteriorNodesCheckIdx = mSystem->mTypeMapVersion;
}; };
if ((mResolvePassData != NULL) && (mResolvePassData->mParser != NULL)) if (mResolvePassData != NULL)
{ {
_CheckParser(mResolvePassData->mParser); for (auto parser : mResolvePassData->mParsers)
_CheckParser(parser);
} }
else else
{ {
@ -3936,18 +3938,21 @@ void BfCompiler::ProcessAutocompleteTempType()
if (autoComplete->mResolveType == BfResolveType_GetNavigationData) if (autoComplete->mResolveType == BfResolveType_GetNavigationData)
{ {
for (auto node : mResolvePassData->mParser->mSidechannelRootNode->mChildArr) for (auto parser : mResolvePassData->mParsers)
{ {
if (auto preprocNode = BfNodeDynCast<BfPreprocessorNode>(node)) for (auto node : parser->mSidechannelRootNode->mChildArr)
{ {
if (preprocNode->mCommand->Equals("region")) if (auto preprocNode = BfNodeDynCast<BfPreprocessorNode>(node))
{ {
if (!autoCompleteResultString.empty()) if (preprocNode->mCommand->Equals("region"))
autoCompleteResultString += "\n"; {
autoCompleteResultString += "#"; if (!autoCompleteResultString.empty())
preprocNode->mArgument->ToString(autoCompleteResultString); autoCompleteResultString += "\n";
mContext->mScratchModule->UpdateSrcPos(preprocNode, (BfSrcPosFlags)(BfSrcPosFlag_NoSetDebugLoc | BfSrcPosFlag_Force)); autoCompleteResultString += "#";
autoCompleteResultString += StrFormat("\tregion\t%d\t%d", module->mCurFilePosition.mCurLine, module->mCurFilePosition.mCurColumn); preprocNode->mArgument->ToString(autoCompleteResultString);
mContext->mScratchModule->UpdateSrcPos(preprocNode, (BfSrcPosFlags)(BfSrcPosFlag_NoSetDebugLoc | BfSrcPosFlag_Force));
autoCompleteResultString += StrFormat("\tregion\t%d\t%d", module->mCurFilePosition.mCurLine, module->mCurFilePosition.mCurColumn);
}
} }
} }
} }
@ -4041,7 +4046,7 @@ void BfCompiler::ProcessAutocompleteTempType()
if (autoComplete->mResolveType == BfResolveType_GetCurrentLocation) if (autoComplete->mResolveType == BfResolveType_GetCurrentLocation)
{ {
for (auto tempTypeDef : mResolvePassData->mAutoCompleteTempTypes) for (auto tempTypeDef : mResolvePassData->mAutoCompleteTempTypes)
{ {
String typeName = tempTypeDef->mNamespace.ToString(); String typeName = tempTypeDef->mNamespace.ToString();
if (!typeName.empty()) if (!typeName.empty())
typeName += "."; typeName += ".";
@ -4049,16 +4054,21 @@ void BfCompiler::ProcessAutocompleteTempType()
autoCompleteResultString = typeName; autoCompleteResultString = typeName;
int cursorPos = mResolvePassData->mParser->mCursorIdx;
for (auto methodDef : tempTypeDef->mMethods) for (auto methodDef : tempTypeDef->mMethods)
{ {
BfAstNode* defNode = methodDef->mMethodDeclaration; BfAstNode* defNode = methodDef->mMethodDeclaration;
if (auto propertyDeclaration = methodDef->GetPropertyDeclaration()) if (auto propertyDeclaration = methodDef->GetPropertyDeclaration())
defNode = propertyDeclaration; defNode = propertyDeclaration;
if (defNode == NULL)
continue;
auto parser = defNode->GetParser();
if ((parser == NULL) || (parser->mCursorIdx == -1))
continue;
if ((defNode != NULL) && if ((defNode != NULL) &&
(defNode->Contains(cursorPos))) (defNode->Contains(parser->mCursorIdx)))
{ {
String methodText = methodDef->ToString(); String methodText = methodDef->ToString();
if (typeName != "@") if (typeName != "@")
@ -4070,6 +4080,53 @@ void BfCompiler::ProcessAutocompleteTempType()
} }
} }
if (mResolvePassData->mAutoCompleteTempTypes.IsEmpty())
{
for (auto& kv : mResolvePassData->mEmitEmbedEntries)
{
if (kv.mValue.mCursorIdx < 0)
continue;
String typeName = kv.mKey;
auto type = GetType(typeName);
if (type == NULL)
continue;
auto typeInst = type->ToTypeInstance();
if (typeInst == NULL)
continue;
if (mResolvePassData->mParsers.IsEmpty())
break;
autoCompleteResultString = mContext->mScratchModule->TypeToString(typeInst);
for (auto methodDef : typeInst->mTypeDef->mMethods)
{
BfAstNode* defNode = methodDef->mMethodDeclaration;
if (auto propertyDeclaration = methodDef->GetPropertyDeclaration())
defNode = propertyDeclaration;
if (defNode == NULL)
continue;
if ((defNode != NULL) &&
(defNode->Contains(kv.mValue.mCursorIdx)))
{
auto defParser = defNode->GetParser();
if (defParser == NULL)
continue;
if (!defParser->mIsEmitted)
continue;
autoCompleteResultString += ".";
autoCompleteResultString += methodDef->ToString();
break;
}
}
}
}
module->CleanupFileInstances(); module->CleanupFileInstances();
return; return;
} }
@ -4094,59 +4151,58 @@ void BfCompiler::ProcessAutocompleteTempType()
BfAstNode* conflictStart = NULL; BfAstNode* conflictStart = NULL;
BfAstNode* conflictSplit = NULL; BfAstNode* conflictSplit = NULL;
auto src = mResolvePassData->mParser->mSrc; for (auto parser : mResolvePassData->mParsers)
for (int checkIdx = 0; checkIdx < (int)mResolvePassData->mParser->mSidechannelRootNode->mChildArr.mSize; checkIdx++)
{ {
auto sideNode = mResolvePassData->mParser->mSidechannelRootNode->mChildArr.mVals[checkIdx]; auto src = parser->mSrc;
if (autoComplete->CheckFixit(sideNode))
for (int checkIdx = 0; checkIdx < (int)parser->mSidechannelRootNode->mChildArr.mSize; checkIdx++)
{ {
if (src[sideNode->mSrcStart] == '<') auto sideNode = parser->mSidechannelRootNode->mChildArr.mVals[checkIdx];
if (autoComplete->CheckFixit(sideNode))
{ {
conflictStart = sideNode; if (src[sideNode->mSrcStart] == '<')
conflictSplit = NULL; {
} conflictStart = sideNode;
} conflictSplit = NULL;
else }
{ }
if (src[sideNode->mSrcStart] == '<') else
{ {
conflictStart = NULL; if (src[sideNode->mSrcStart] == '<')
conflictSplit = NULL;
}
else if (src[sideNode->mSrcStart] == '=')
{
if (conflictStart != NULL)
conflictSplit = sideNode;
}
else if (src[sideNode->mSrcStart] == '>')
{
if (conflictSplit != NULL)
{ {
autoComplete->AddEntry(AutoCompleteEntry("fixit", StrFormat("Accept First\tdelete|%s-%d|\x01""delete|%s-%d|",
autoComplete->FixitGetLocation(mResolvePassData->mParser->mParserData, conflictSplit->mSrcStart).c_str(), sideNode->mSrcEnd - conflictSplit->mSrcStart + 1,
autoComplete->FixitGetLocation(mResolvePassData->mParser->mParserData, conflictStart->mSrcStart).c_str(), conflictStart->mSrcEnd - conflictStart->mSrcStart + 1).c_str()));
autoComplete->AddEntry(AutoCompleteEntry("fixit", StrFormat("Accept Second\tdelete|%s-%d|\x01""delete|%s-%d|",
autoComplete->FixitGetLocation(mResolvePassData->mParser->mParserData, sideNode->mSrcStart).c_str(), sideNode->mSrcEnd - sideNode->mSrcStart + 1,
autoComplete->FixitGetLocation(mResolvePassData->mParser->mParserData, conflictStart->mSrcStart).c_str(), conflictSplit->mSrcEnd - conflictStart->mSrcStart + 1).c_str()));
autoComplete->AddEntry(AutoCompleteEntry("fixit", StrFormat("Accept Both\tdelete|%s-%d|\x01""delete|%s-%d|\x01""delete|%s-%d|",
autoComplete->FixitGetLocation(mResolvePassData->mParser->mParserData, sideNode->mSrcStart).c_str(), sideNode->mSrcEnd - sideNode->mSrcStart + 1,
autoComplete->FixitGetLocation(mResolvePassData->mParser->mParserData, conflictSplit->mSrcStart).c_str(), conflictSplit->mSrcEnd - conflictSplit->mSrcStart + 1,
autoComplete->FixitGetLocation(mResolvePassData->mParser->mParserData, conflictStart->mSrcStart).c_str(), conflictStart->mSrcEnd - conflictStart->mSrcStart + 1).c_str()));
conflictStart = NULL; conflictStart = NULL;
conflictSplit = NULL; conflictSplit = NULL;
} }
else if (src[sideNode->mSrcStart] == '=')
{
if (conflictStart != NULL)
conflictSplit = sideNode;
}
else if (src[sideNode->mSrcStart] == '>')
{
if (conflictSplit != NULL)
{
autoComplete->AddEntry(AutoCompleteEntry("fixit", StrFormat("Accept First\tdelete|%s-%d|\x01""delete|%s-%d|",
autoComplete->FixitGetLocation(parser->mParserData, conflictSplit->mSrcStart).c_str(), sideNode->mSrcEnd - conflictSplit->mSrcStart + 1,
autoComplete->FixitGetLocation(parser->mParserData, conflictStart->mSrcStart).c_str(), conflictStart->mSrcEnd - conflictStart->mSrcStart + 1).c_str()));
autoComplete->AddEntry(AutoCompleteEntry("fixit", StrFormat("Accept Second\tdelete|%s-%d|\x01""delete|%s-%d|",
autoComplete->FixitGetLocation(parser->mParserData, sideNode->mSrcStart).c_str(), sideNode->mSrcEnd - sideNode->mSrcStart + 1,
autoComplete->FixitGetLocation(parser->mParserData, conflictStart->mSrcStart).c_str(), conflictSplit->mSrcEnd - conflictStart->mSrcStart + 1).c_str()));
autoComplete->AddEntry(AutoCompleteEntry("fixit", StrFormat("Accept Both\tdelete|%s-%d|\x01""delete|%s-%d|\x01""delete|%s-%d|",
autoComplete->FixitGetLocation(parser->mParserData, sideNode->mSrcStart).c_str(), sideNode->mSrcEnd - sideNode->mSrcStart + 1,
autoComplete->FixitGetLocation(parser->mParserData, conflictSplit->mSrcStart).c_str(), conflictSplit->mSrcEnd - conflictSplit->mSrcStart + 1,
autoComplete->FixitGetLocation(parser->mParserData, conflictStart->mSrcStart).c_str(), conflictStart->mSrcEnd - conflictStart->mSrcStart + 1).c_str()));
conflictStart = NULL;
conflictSplit = NULL;
}
}
} }
} }
} }
for (auto sideNode : mResolvePassData->mParser->mSidechannelRootNode->mChildArr)
{
}
} }
if (autoComplete->mResolveType == BfResolveType_GetSymbolInfo) if (autoComplete->mResolveType == BfResolveType_GetSymbolInfo)
@ -4154,7 +4210,8 @@ void BfCompiler::ProcessAutocompleteTempType()
BfNamespaceVisitor namespaceVisitor; BfNamespaceVisitor namespaceVisitor;
namespaceVisitor.mResolvePassData = mResolvePassData; namespaceVisitor.mResolvePassData = mResolvePassData;
namespaceVisitor.mSystem = mSystem; namespaceVisitor.mSystem = mSystem;
namespaceVisitor.Visit(mResolvePassData->mParser->mRootNode); for (auto parser : mResolvePassData->mParsers)
namespaceVisitor.Visit(parser->mRootNode);
} }
auto _FindAcutalTypeDef = [&](BfTypeDef* tempTypeDef) auto _FindAcutalTypeDef = [&](BfTypeDef* tempTypeDef)
@ -4204,6 +4261,9 @@ void BfCompiler::ProcessAutocompleteTempType()
mContext->HandleChangedTypeDef(checkTempType, true); mContext->HandleChangedTypeDef(checkTempType, true);
} }
auto sourceClassifier = mResolvePassData->GetSourceClassifier(checkTempType->mTypeDeclaration->mNameNode);
if (sourceClassifier == NULL)
continue;
BfSourceElementType elemType = BfSourceElementType_Type; BfSourceElementType elemType = BfSourceElementType_Type;
if (checkTempType->mTypeCode == BfTypeCode_Interface) if (checkTempType->mTypeCode == BfTypeCode_Interface)
elemType = BfSourceElementType_Interface; elemType = BfSourceElementType_Interface;
@ -4211,11 +4271,32 @@ void BfCompiler::ProcessAutocompleteTempType()
elemType = BfSourceElementType_RefType; elemType = BfSourceElementType_RefType;
else if (checkTempType->mTypeCode == BfTypeCode_Struct) else if (checkTempType->mTypeCode == BfTypeCode_Struct)
elemType = BfSourceElementType_Struct; elemType = BfSourceElementType_Struct;
mResolvePassData->mSourceClassifier->SetElementType(checkTempType->mTypeDeclaration->mNameNode, elemType); sourceClassifier->SetElementType(checkTempType->mTypeDeclaration->mNameNode, elemType);
} }
if (tempTypeDef == NULL) if (tempTypeDef == NULL)
{ {
if ((autoComplete != NULL) && (autoComplete->mResolveType == BfResolveType_GoToDefinition))
{
for (auto& kv : mResolvePassData->mEmitEmbedEntries)
{
String typeName = kv.mKey;
auto type = GetType(typeName);
if (type == NULL)
continue;
auto typeInst = type->ToTypeInstance();
if (typeInst == NULL)
continue;
mContext->RebuildType(typeInst);
if (!typeInst->mModule->mIsModuleMutable)
typeInst->mModule->StartNewRevision(BfModule::RebuildKind_All, true);
mContext->mScratchModule->PopulateType(typeInst, Beefy::BfPopulateType_Full_Force);
}
DoWorkLoop();
}
GenerateAutocompleteInfo(); GenerateAutocompleteInfo();
BfLogSysM("ProcessAutocompleteTempType - no tempTypeDef\n"); BfLogSysM("ProcessAutocompleteTempType - no tempTypeDef\n");
return; return;
@ -4319,10 +4400,11 @@ void BfCompiler::ProcessAutocompleteTempType()
return; return;
} }
auto sourceClassifier = mResolvePassData->GetSourceClassifier(tempTypeDef->mTypeDeclaration);
if (tempTypeDef->mTypeCode == BfTypeCode_Extension) if (tempTypeDef->mTypeCode == BfTypeCode_Extension)
mResolvePassData->mSourceClassifier->SetElementType(tempTypeDef->mTypeDeclaration->mNameNode, actualTypeDef->mTypeCode); sourceClassifier->SetElementType(tempTypeDef->mTypeDeclaration->mNameNode, actualTypeDef->mTypeCode);
if (tempTypeDef->mTypeDeclaration->mAttributes != NULL) if (tempTypeDef->mTypeDeclaration->mAttributes != NULL)
mResolvePassData->mSourceClassifier->VisitChild(tempTypeDef->mTypeDeclaration->mAttributes); sourceClassifier->VisitChild(tempTypeDef->mTypeDeclaration->mAttributes);
BfTypeInstance* typeInst; BfTypeInstance* typeInst;
{ {
@ -4750,10 +4832,16 @@ BfType* BfCompiler::CheckSymbolReferenceTypeRef(BfModule* module, BfTypeReferenc
void BfCompiler::AddToRebuildTypeList(BfTypeInstance* typeInst, HashSet<BfTypeInstance*>& rebuildTypeInstList) void BfCompiler::AddToRebuildTypeList(BfTypeInstance* typeInst, HashSet<BfTypeInstance*>& rebuildTypeInstList)
{ {
if (mResolvePassData->mParser != NULL) if (!mResolvePassData->mParsers.IsEmpty())
{ {
// Only find references within the current file bool found = false;
if (!typeInst->mTypeDef->GetDefinition()->HasSource(mResolvePassData->mParser)) for (auto parser : mResolvePassData->mParsers)
{
// Only find references within the current file
if (typeInst->mTypeDef->GetDefinition()->HasSource(parser))
found = true;
}
if (!found)
return; return;
} }
@ -4922,7 +5010,17 @@ void BfCompiler::GetSymbolReferences()
for (auto checkTypeDef : typeDef->mPartials) for (auto checkTypeDef : typeDef->mPartials)
{ {
auto nameNode = checkTypeDef->mTypeDeclaration->mNameNode; auto nameNode = checkTypeDef->mTypeDeclaration->mNameNode;
if ((mResolvePassData->mParser == NULL) || (nameNode->IsFromParser(mResolvePassData->mParser)))
for (auto parser : mResolvePassData->mParsers)
{
if (nameNode->IsFromParser(parser))
{
mResolvePassData->HandleTypeReference(nameNode, typeDef);
break;
}
}
if (mResolvePassData->mParsers.IsEmpty())
mResolvePassData->HandleTypeReference(nameNode, typeDef); mResolvePassData->HandleTypeReference(nameNode, typeDef);
if (checkTypeDef->IsExtension()) if (checkTypeDef->IsExtension())
@ -5365,9 +5463,7 @@ bool BfCompiler::IsDataResolvePass()
bool BfCompiler::WantsClassifyNode(BfAstNode* node) bool BfCompiler::WantsClassifyNode(BfAstNode* node)
{ {
return ((mResolvePassData != NULL) && return (mResolvePassData != NULL) && (mResolvePassData->GetSourceClassifier(node) != NULL);
(node->IsFromParser(mResolvePassData->mParser)) &&
(mResolvePassData->mSourceClassifier != NULL));
} }
BfAutoComplete* BfCompiler::GetAutoComplete() BfAutoComplete* BfCompiler::GetAutoComplete()
@ -6673,7 +6769,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
mHasComptimeRebuilds = false; mHasComptimeRebuilds = false;
int revision = mRevision; int revision = mRevision;
BfLogSysM("Compile Start. Revision: %d. HasParser:%d AutoComplete:%d\n", revision, BfLogSysM("Compile Start. Revision: %d. HasParser:%d AutoComplete:%d\n", revision,
(mResolvePassData != NULL) && (mResolvePassData->mParser != NULL), (mResolvePassData != NULL) && (!mResolvePassData->mParsers.IsEmpty()),
(mResolvePassData != NULL) && (mResolvePassData->mAutoComplete != NULL)); (mResolvePassData != NULL) && (mResolvePassData->mAutoComplete != NULL));
if (mOptions.mCompileOnDemandKind == BfCompileOnDemandKind_AlwaysInclude) if (mOptions.mCompileOnDemandKind == BfCompileOnDemandKind_AlwaysInclude)
@ -6785,7 +6881,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
BfTypeDef* typeDef; BfTypeDef* typeDef;
BfLogSysM("UpdateRevisedTypes Revision %d. ResolvePass:%d CursorIdx:%d\n", mRevision, mIsResolveOnly, BfLogSysM("UpdateRevisedTypes Revision %d. ResolvePass:%d CursorIdx:%d\n", mRevision, mIsResolveOnly,
((mResolvePassData == NULL) || (mResolvePassData->mParser == NULL)) ? - 1 : mResolvePassData->mParser->mCursorIdx); ((mResolvePassData == NULL) || (mResolvePassData->mParsers.IsEmpty())) ? - 1 : mResolvePassData->mParsers[0]->mCursorIdx);
mCompileState = CompileState_Normal; mCompileState = CompileState_Normal;
UpdateRevisedTypes(); UpdateRevisedTypes();
@ -7455,7 +7551,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
} }
else else
{ {
bool isTargeted = (mResolvePassData != NULL) && (mResolvePassData->mParser != NULL); bool isTargeted = (mResolvePassData != NULL) && (!mResolvePassData->mParsers.IsEmpty());
if (!isTargeted) if (!isTargeted)
{ {
for (auto bfModule : mContext->mModules) for (auto bfModule : mContext->mModules)
@ -7477,7 +7573,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
//CompileLog("%d object files written: %s\n", numModulesWritten, moduleListStr.c_str()); //CompileLog("%d object files written: %s\n", numModulesWritten, moduleListStr.c_str());
//printf("Compile done, waiting for finish\n"); //printf("Compile done, waiting for finish\n");
while (true) while (true)
{ {
if (mCanceling) if (mCanceling)
@ -7543,7 +7639,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
libManager->mErrors.Clear(); libManager->mErrors.Clear();
} }
#endif #endif
int numObjFilesWritten = 0; int numObjFilesWritten = 0;
for (auto& fileEntry : mCodeGen.mCodeGenFiles) for (auto& fileEntry : mCodeGen.mCodeGenFiles)
{ {
@ -7588,7 +7684,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
String compileInfo; String compileInfo;
if (mIsResolveOnly) if (mIsResolveOnly)
compileInfo += StrFormat("ResolveOnly ResolveType:%d Parser:%d\n", mResolvePassData->mResolveType, mResolvePassData->mParser != NULL); compileInfo += StrFormat("ResolveOnly ResolveType:%d Parser:%d\n", mResolvePassData->mResolveType, !mResolvePassData->mParsers.IsEmpty());
compileInfo += StrFormat("TotalTypes:%d\nTypesPopulated:%d\nMethodsDeclared:%d\nMethodsProcessed:%d\nCanceled? %d\n", mStats.mTotalTypes, mStats.mTypesPopulated, mStats.mMethodDeclarations, mStats.mMethodsProcessed, mCanceling); compileInfo += StrFormat("TotalTypes:%d\nTypesPopulated:%d\nMethodsDeclared:%d\nMethodsProcessed:%d\nCanceled? %d\n", mStats.mTotalTypes, mStats.mTypesPopulated, mStats.mMethodDeclarations, mStats.mMethodsProcessed, mCanceling);
compileInfo += StrFormat("TypesPopulated:%d\n", mStats.mTypesPopulated); compileInfo += StrFormat("TypesPopulated:%d\n", mStats.mTypesPopulated);
compileInfo += StrFormat("MethodDecls:%d\nMethodsProcessed:%d\nModulesStarted:%d\nModulesFinished:%d\n", mStats.mMethodDeclarations, mStats.mMethodsProcessed, mStats.mModulesFinished); compileInfo += StrFormat("MethodDecls:%d\nMethodsProcessed:%d\nModulesStarted:%d\nModulesFinished:%d\n", mStats.mMethodDeclarations, mStats.mMethodsProcessed, mStats.mModulesFinished);
@ -7854,8 +7950,11 @@ void BfCompiler::GenerateAutocompleteInfo()
if (autoComplete->mInsertEndIdx > 0) if (autoComplete->mInsertEndIdx > 0)
{ {
if (mResolvePassData->mParser->mSrc[autoComplete->mInsertEndIdx - 1] == '!') if (!mResolvePassData->mParsers.IsEmpty())
autoComplete->mInsertEndIdx--; {
if (mResolvePassData->mParsers[0]->mSrc[autoComplete->mInsertEndIdx - 1] == '!')
autoComplete->mInsertEndIdx--;
}
} }
} }
@ -9065,17 +9164,75 @@ String BfCompiler::GetTypeDefInfo(const StringImpl& inTypeName)
return result; return result;
} }
int BfCompiler::GetTypeId(const StringImpl& typeName)
{
auto type = GetType(typeName);
if (type != NULL)
return type->mTypeId;
return -1;
}
BfType* BfCompiler::GetType(const StringImpl& fullTypeName)
{
AutoCrit autoCrit(mSystem->mSystemLock);
BfPassInstance passInstance(mSystem);
BfProject* activeProject = NULL;
String typeName = fullTypeName;
int colonPos = (int)typeName.IndexOf(':');
if (colonPos != -1)
{
activeProject = mSystem->GetProject(typeName.Substring(0, colonPos));
typeName.Remove(0, colonPos + 1);
}
BfTypeState typeState;
typeState.mPrevState = mContext->mCurTypeState;
typeState.mActiveProject = activeProject;
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
BfParser parser(mSystem);
parser.SetSource(typeName.c_str(), (int)typeName.length());
parser.Parse(&passInstance);
BfReducer reducer;
reducer.mAlloc = parser.mAlloc;
reducer.mPassInstance = &passInstance;
if (parser.mRootNode->mChildArr.mSize == 0)
return NULL;
auto firstNode = parser.mRootNode->mChildArr[0];
auto endIdx = parser.mRootNode->mSrcEnd;
reducer.mVisitorPos = BfReducer::BfVisitorPos(parser.mRootNode);
reducer.mVisitorPos.MoveNext();
auto typeRef = reducer.CreateTypeRef(firstNode);
if (typeRef == NULL)
return NULL;
BfResolvePassData resolvePass;
SetAndRestoreValue<bool> prevIgnoreError(mContext->mScratchModule->mIgnoreErrors, true);
SetAndRestoreValue<bool> prevIgnoreWarnings(mContext->mScratchModule->mIgnoreWarnings, true);
SetAndRestoreValue<BfResolvePassData*> prevResolvePass(mResolvePassData, &resolvePass);
auto type = mContext->mScratchModule->ResolveTypeRef(typeRef, BfPopulateType_Identity, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoCreate | BfResolveTypeRefFlag_AllowUnboundGeneric));
if (type != NULL)
return type;
return NULL;
}
int BfCompiler::GetEmitSource(const StringImpl& fileName, StringImpl* outBuffer) int BfCompiler::GetEmitSource(const StringImpl& fileName, StringImpl* outBuffer)
{ {
int lastDollarPos = (int)fileName.LastIndexOf('$'); int lastDollarPos = (int)fileName.LastIndexOf('$');
if (lastDollarPos == -1) if (lastDollarPos == -1)
return -1; return -1;
int dotPos = (int)fileName.LastIndexOf('.');
if (dotPos == -1)
return -1;
String typeIdStr = fileName.Substring(lastDollarPos + 1, dotPos - lastDollarPos - 1); String typeName = fileName.Substring(lastDollarPos + 1);
int typeId = (int)atoi(typeIdStr.c_str()); int typeId = GetTypeId(typeName);
if ((typeId <= 0) || (typeId >= mContext->mTypes.mSize)) if ((typeId <= 0) || (typeId >= mContext->mTypes.mSize))
return -1; return -1;
@ -9097,6 +9254,96 @@ int BfCompiler::GetEmitSource(const StringImpl& fileName, StringImpl* outBuffer)
return typeInst->mRevision; return typeInst->mRevision;
} }
String BfCompiler::GetEmitLocation(const StringImpl& typeName, int emitLine, int& outEmbedLine, int& outEmbedLineChar)
{
outEmbedLine = 0;
int typeId = GetTypeId(typeName);
if (typeId <= 0)
return "";
auto bfType = mContext->FindTypeById(typeId);
if (bfType == NULL)
return "";
auto typeInst = bfType->ToTypeInstance();
if (typeInst == NULL)
return "";
if (typeInst->mCeTypeInfo == NULL)
return "";
for (auto& kv : typeInst->mCeTypeInfo->mEmitSourceMap)
{
int partialIdx = (int)(kv.mKey >> 32);
int charIdx = (int)(kv.mKey & 0xFFFFFFFF);
auto typeDef = typeInst->mTypeDef;
if (partialIdx > 0)
typeDef = typeDef->mPartials[partialIdx];
auto origParser = typeDef->GetDefinition()->GetLastSource()->ToParser();
if (origParser == NULL)
continue;
auto emitParser = typeInst->mTypeDef->GetLastSource()->ToParser();
if (emitParser == NULL)
continue;
int startLine = 0;
int startLineChar = 0;
emitParser->GetLineCharAtIdx(kv.mValue.mSrcStart, startLine, startLineChar);
int endLine = 0;
int endLineChar = 0;
emitParser->GetLineCharAtIdx(kv.mValue.mSrcEnd - 1, endLine, endLineChar);
if ((emitLine >= startLine) && (emitLine <= endLine))
{
origParser->GetLineCharAtIdx(charIdx, outEmbedLine, outEmbedLineChar);
return origParser->mFileName;
}
}
return "";
}
bool BfCompiler::WriteEmitData(const StringImpl& filePath, BfProject* project)
{
ZipFile zipFile;
for (auto type : mContext->mResolvedTypes)
{
auto typeInst = type->ToTypeInstance();
if (typeInst == NULL)
continue;
if (typeInst->mTypeDef->mEmitParent == NULL)
continue;
if (!project->ContainsReference(typeInst->mTypeDef->mProject))
continue;
auto bfParser = typeInst->mTypeDef->GetLastSource()->ToParser();
String name = bfParser->mFileName;
if (name.StartsWith("$Emit$"))
name.Remove(0, 6);
String path = EncodeFileName(name);
path.Append(".bf");
if (!zipFile.IsOpen())
{
if (!zipFile.Create(filePath))
return false;
}
zipFile.Add(path, Span<uint8>((uint8*)bfParser->mSrc, bfParser->mSrcLength));
}
if (zipFile.IsOpen())
return zipFile.Close();
return true;
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
PerfManager* BfGetPerfManager(BfParser* bfParser); PerfManager* BfGetPerfManager(BfParser* bfParser);
@ -9122,57 +9369,33 @@ BF_EXPORT void BF_CALLTYPE BfCompiler_ClearResults(BfCompiler* bfCompiler)
bfCompiler->ClearResults(); bfCompiler->ClearResults();
} }
BF_EXPORT bool BF_CALLTYPE BfCompiler_ClassifySource(BfCompiler* bfCompiler, BfPassInstance* bfPassInstance, BfParser* bfParser, BfResolvePassData* resolvePassData, BfSourceClassifier::CharData* charData) BF_EXPORT bool BF_CALLTYPE BfCompiler_ClassifySource(BfCompiler* bfCompiler, BfPassInstance* bfPassInstance, BfResolvePassData* resolvePassData)
{ {
BP_ZONE("BfCompiler_ClassifySource"); BP_ZONE("BfCompiler_ClassifySource");
BfSourceClassifier bfSourceClassifier(bfParser, charData);
bfSourceClassifier.mClassifierPassId = bfPassInstance->mClassifierPassId;
String& autoCompleteResultString = *gTLStrReturn.Get(); String& autoCompleteResultString = *gTLStrReturn.Get();
autoCompleteResultString.clear(); autoCompleteResultString.clear();
bool doClassifyPass = (charData != NULL) && (resolvePassData->mResolveType <= BfResolveType_Autocomplete_HighPri);
bfSourceClassifier.mEnabled = doClassifyPass;
// Full classifier pass?
bfSourceClassifier.mSkipMethodInternals = true; bfPassInstance->mCompiler = bfCompiler;
bfSourceClassifier.mSkipTypeDeclarations = true; for (auto parser : resolvePassData->mParsers)
if (charData != NULL) bfPassInstance->mFilterErrorsTo.Add(parser->mSourceData);
{
resolvePassData->mSourceClassifier = &bfSourceClassifier;
if (doClassifyPass)
bfSourceClassifier.Visit(bfParser->mRootNode);
}
bfSourceClassifier.mSkipTypeDeclarations = false;
bfSourceClassifier.mSkipMethodInternals = false;
bfPassInstance->mFilterErrorsTo = bfParser;
bfPassInstance->mTrimMessagesToCursor = true; bfPassInstance->mTrimMessagesToCursor = true;
SetAndRestoreValue<BfResolvePassData*> prevCompilerResolvePassData(bfCompiler->mResolvePassData, resolvePassData); SetAndRestoreValue<BfResolvePassData*> prevCompilerResolvePassData(bfCompiler->mResolvePassData, resolvePassData);
SetAndRestoreValue<BfPassInstance*> prevPassInstance(bfCompiler->mPassInstance, bfPassInstance); SetAndRestoreValue<BfPassInstance*> prevPassInstance(bfCompiler->mPassInstance, bfPassInstance);
bool canceled = false; bool canceled = false;
if (resolvePassData->mAutoComplete != NULL)
{ if ((resolvePassData->mAutoComplete != NULL) && (!resolvePassData->mParsers.IsEmpty()))
{
bfCompiler->ProcessAutocompleteTempType(); bfCompiler->ProcessAutocompleteTempType();
} }
else else
canceled = !bfCompiler->Compile(""); canceled = !bfCompiler->Compile("");
resolvePassData->mSourceClassifier = NULL;
if ((charData != NULL) && (doClassifyPass))
{
bfSourceClassifier.mIsSideChannel = false;
bfSourceClassifier.Visit(bfParser->mErrorRootNode);
bfSourceClassifier.mIsSideChannel = true;
bfSourceClassifier.Visit(bfParser->mSidechannelRootNode);
}
return !canceled; return !canceled;
} }
BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCompiler, BfParser* bfParser) BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCompiler, BfParser* bfParser, BfResolvePassData* resolvePassData, char* explicitEmitTypeNames)
{ {
String& outString = *gTLStrReturn.Get(); String& outString = *gTLStrReturn.Get();
outString.Clear(); outString.Clear();
@ -9515,6 +9738,112 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo
collapseVisitor.FlushSeries(); collapseVisitor.FlushSeries();
Array<BfTypeInstance*> explicitEmitTypes;
String checkStr = explicitEmitTypeNames;
for (auto& typeName : checkStr.Split('\n'))
{
if (typeName.IsEmpty())
continue;
auto bfType = bfCompiler->GetType(typeName);
if ((bfType != NULL) && (bfType->IsTypeInstance()))
explicitEmitTypes.Add(bfType->ToTypeInstance());
}
// Embed emit info
BfPassInstance bfPassInstance(bfCompiler->mSystem);
SetAndRestoreValue<BfResolvePassData*> prevCompilerResolvePassData(bfCompiler->mResolvePassData, resolvePassData);
SetAndRestoreValue<BfPassInstance*> prevPassInstance(bfCompiler->mPassInstance, &bfPassInstance);
Dictionary<int, int> foundTypeIds;
for (auto typeDef : bfParser->mTypeDefs)
{
auto useTypeDef = typeDef;
if (useTypeDef->mIsPartial)
{
useTypeDef = bfCompiler->mSystem->GetCombinedPartial(useTypeDef);
if (useTypeDef == NULL)
continue;
}
auto type = bfCompiler->mContext->mScratchModule->ResolveTypeDef(useTypeDef);
if (type == NULL)
continue;
if (auto typeInst = type->ToTypeInstance())
{
auto origTypeInst = typeInst;
if (typeInst->mCeTypeInfo == NULL)
continue;
for (auto checkIdx = explicitEmitTypes.mSize - 1; checkIdx >= 0; checkIdx--)
{
auto checkType = explicitEmitTypes[checkIdx];
if (checkType->mTypeDef->GetDefinition()->GetLatest() == typeInst->mTypeDef->GetDefinition()->GetLatest())
{
typeInst = checkType;
bfCompiler->mContext->mScratchModule->PopulateType(typeInst);
break;
}
}
for (auto& kv : typeInst->mCeTypeInfo->mEmitSourceMap)
{
int partialIdx = (int)(kv.mKey >> 32);
int charIdx = (int)(kv.mKey & 0xFFFFFFFF);
auto typeDef = typeInst->mTypeDef;
if (partialIdx > 0)
typeDef = typeDef->mPartials[partialIdx];
auto parser = typeDef->GetDefinition()->GetLastSource()->ToParser();
if (parser == NULL)
continue;
if (!FileNameEquals(parser->mFileName, bfParser->mFileName))
continue;
auto emitParser = typeInst->mTypeDef->GetLastSource()->ToParser();
if (emitParser == NULL)
continue;
int startLine = 0;
int startLineChar = 0;
emitParser->GetLineCharAtIdx(kv.mValue.mSrcStart, startLine, startLineChar);
int srcEnd = kv.mValue.mSrcEnd - 1;
while (srcEnd >= kv.mValue.mSrcStart)
{
char c = emitParser->mSrc[srcEnd];
if (!::isspace((uint8)c))
break;
srcEnd--;
}
int endLine = 0;
int endLineChar = 0;
emitParser->GetLineCharAtIdx(srcEnd, endLine, endLineChar);
int dollarPos = (int)emitParser->mFileName.LastIndexOf('$');
if (dollarPos == -1)
continue;
int* keyPtr = NULL;
int* valuePtr = NULL;
if (foundTypeIds.TryAdd(typeInst->mTypeId, &keyPtr, &valuePtr))
{
*valuePtr = foundTypeIds.mCount - 1;
outString += "+";
outString += emitParser->mFileName.Substring(dollarPos + 1);
outString += "\n";
}
outString += (kv.mValue.mKind == BfCeTypeEmitSourceKind_Method) ? 'm' : 't';
outString += StrFormat("%d,%d,%d,%d,%d,%d\n", *valuePtr, typeInst->mRevision, partialIdx, charIdx, startLine, endLine + 1);
}
}
}
return outString.c_str(); return outString.c_str();
} }
@ -9587,7 +9916,7 @@ BF_EXPORT bool BF_CALLTYPE BfCompiler_VerifyTypeName(BfCompiler* bfCompiler, cha
resolvePassData.mAutoComplete->mCompiler = bfCompiler; resolvePassData.mAutoComplete->mCompiler = bfCompiler;
resolvePassData.mAutoComplete->mModule = bfCompiler->mContext->mScratchModule; resolvePassData.mAutoComplete->mModule = bfCompiler->mContext->mScratchModule;
} }
resolvePassData.mParser = &parser; resolvePassData.mParsers.Add(&parser);
SetAndRestoreValue<BfResolvePassData*> prevCompilerResolvePassData(bfCompiler->mResolvePassData, &resolvePassData); SetAndRestoreValue<BfResolvePassData*> prevCompilerResolvePassData(bfCompiler->mResolvePassData, &resolvePassData);
SetAndRestoreValue<BfPassInstance*> prevPassInstance(bfCompiler->mPassInstance, &passInstance); SetAndRestoreValue<BfPassInstance*> prevPassInstance(bfCompiler->mPassInstance, &passInstance);
@ -9733,6 +10062,11 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetTypeDefInfo(BfCompiler* bfCompil
return outString.c_str(); return outString.c_str();
} }
BF_EXPORT int BF_CALLTYPE BfCompiler_GetTypeId(BfCompiler* bfCompiler, const char* name)
{
return bfCompiler->GetTypeId(name);
}
BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetTypeInfo(BfCompiler* bfCompiler, const char* name) BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetTypeInfo(BfCompiler* bfCompiler, const char* name)
{ {
String& outString = *gTLStrReturn.Get(); String& outString = *gTLStrReturn.Get();
@ -9820,6 +10154,40 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetTypeInfo(BfCompiler* bfCompiler,
return outString.c_str(); return outString.c_str();
} }
BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetGenericTypeInstances(BfCompiler* bfCompiler, const char* typeName)
{
String& outString = *gTLStrReturn.Get();
outString = "";
auto lookupType = bfCompiler->GetType(typeName);
if (lookupType == NULL)
return "";
auto lookupTypeInst = lookupType->ToTypeInstance();
if (lookupTypeInst == NULL)
return "";
for (auto type : bfCompiler->mContext->mResolvedTypes)
{
auto typeInst = type->ToTypeInstance();
if (typeInst == NULL)
continue;
if (typeInst->IsUnspecializedTypeVariation())
continue;
if (typeInst->mTypeDef->GetDefinition()->GetLatest() == lookupTypeInst->mTypeDef->GetDefinition()->GetLatest())
{
outString += typeInst->mTypeDef->mProject->mName;
outString += ":";
outString += bfCompiler->mContext->mScratchModule->TypeToString(typeInst, BfTypeNameFlags_None);
outString += "\n";
}
}
return outString.c_str();
}
enum BfUsedOutputFlags enum BfUsedOutputFlags
{ {
BfUsedOutputFlags_None = 0, BfUsedOutputFlags_None = 0,
@ -10236,3 +10604,16 @@ BF_EXPORT int32 BF_CALLTYPE BfCompiler_GetEmitSourceVersion(BfCompiler* bfCompil
{ {
return bfCompiler->GetEmitSource(fileName, NULL); return bfCompiler->GetEmitSource(fileName, NULL);
} }
BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetEmitLocation(BfCompiler* bfCompiler, char* typeName, int line, int& outEmbedLine, int& outEmbedLineChar)
{
String& outString = *gTLStrReturn.Get();
outString.clear();
outString = bfCompiler->GetEmitLocation(typeName, line, outEmbedLine, outEmbedLineChar);
return outString.c_str();
}
BF_EXPORT bool BF_CALLTYPE BfCompiler_WriteEmitData(BfCompiler* bfCompiler, char* filePath, BfProject* project)
{
return bfCompiler->WriteEmitData(filePath, project);
}

View file

@ -543,7 +543,11 @@ public:
String GetTypeDefMatches(const StringImpl& searchSrc); String GetTypeDefMatches(const StringImpl& searchSrc);
void GetTypeDefs(const StringImpl& typeName, Array<BfTypeDef*>& typeDefs); void GetTypeDefs(const StringImpl& typeName, Array<BfTypeDef*>& typeDefs);
String GetTypeDefInfo(const StringImpl& typeName); String GetTypeDefInfo(const StringImpl& typeName);
int GetTypeId(const StringImpl& typeName);
BfType* GetType(const StringImpl& typeName);
int GetEmitSource(const StringImpl& fileName, StringImpl* outBuffer); int GetEmitSource(const StringImpl& fileName, StringImpl* outBuffer);
String GetEmitLocation(const StringImpl& typeName, int line, int& outEmbedLine, int& outEmbedLineChar);
bool WriteEmitData(const StringImpl& filePath, BfProject* project);
void CompileLog(const char* fmt ...); void CompileLog(const char* fmt ...);
void ReportMemory(MemReporter* memReporter); void ReportMemory(MemReporter* memReporter);

View file

@ -355,8 +355,8 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods)
while (!mCompiler->mCanceling) while (!mCompiler->mCanceling)
{ {
BfParser* resolveParser = NULL; BfParser* resolveParser = NULL;
if (mCompiler->mResolvePassData != NULL) if ((mCompiler->mResolvePassData != NULL) && (!mCompiler->mResolvePassData->mParsers.IsEmpty()))
resolveParser = mCompiler->mResolvePassData->mParser; resolveParser = mCompiler->mResolvePassData->mParsers[0];
bool didWork = false; bool didWork = false;
@ -549,8 +549,16 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods)
BF_ASSERT(!module->mAwaitingFinish); BF_ASSERT(!module->mAwaitingFinish);
if ((resolveParser != NULL) && (methodInstance->mMethodDef->mDeclaringType != NULL) && (methodInstance->mMethodDef->mDeclaringType->GetDefinition()->mSource != resolveParser)) if ((resolveParser != NULL) && (methodInstance->mMethodDef->mDeclaringType != NULL) && (methodInstance->mMethodDef->mDeclaringType->GetDefinition()->mSource != resolveParser))
{ {
continue; bool allow = false;
if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mHasCursorIdx))
{
auto parser = methodInstance->mMethodDef->mDeclaringType->GetLastSource()->ToParser();
if ((parser != NULL) && (parser->mCursorIdx >= 0))
allow = true;
}
if (!allow)
continue;
} }
hasBeenProcessed = methodInstance->mHasBeenProcessed; hasBeenProcessed = methodInstance->mHasBeenProcessed;
@ -722,7 +730,7 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods)
BP_ZONE("PWL_CheckIncompleteGenerics"); BP_ZONE("PWL_CheckIncompleteGenerics");
for (auto type : mResolvedTypes) for (auto type : mResolvedTypes)
{ {
if ((type->IsIncomplete()) && (type->HasBeenReferenced())) if ((type->IsIncomplete()) && (type->HasBeenReferenced()))
{ {
// The only reason a type instance wouldn't have already been in the work list is // The only reason a type instance wouldn't have already been in the work list is
@ -759,12 +767,13 @@ void BfContext::HandleChangedTypeDef(BfTypeDef* typeDef, bool isAutoCompleteTemp
{ {
BF_ASSERT(typeDef->mEmitParent == NULL); BF_ASSERT(typeDef->mEmitParent == NULL);
if ((mCompiler->mResolvePassData == NULL) || (!typeDef->HasSource(mCompiler->mResolvePassData->mParser))) if ((mCompiler->mResolvePassData == NULL) || (mCompiler->mResolvePassData->mParsers.IsEmpty()) ||
(!typeDef->HasSource(mCompiler->mResolvePassData->mParsers[0])))
return; return;
if (typeDef->mDefState != BfTypeDef::DefState_Defined) if (typeDef->mDefState != BfTypeDef::DefState_Defined)
{ {
if (mCompiler->mResolvePassData->mSourceClassifier != NULL) if (mCompiler->mResolvePassData->mIsClassifying)
{ {
auto _CheckSource = [&](BfTypeDef* checkTypeDef) auto _CheckSource = [&](BfTypeDef* checkTypeDef)
{ {
@ -774,12 +783,11 @@ void BfContext::HandleChangedTypeDef(BfTypeDef* typeDef, bool isAutoCompleteTemp
if (typeDecl == NULL) if (typeDecl == NULL)
return; return;
if (typeDecl->GetSourceData() == mCompiler->mResolvePassData->mParser->mSourceData) if (auto sourceClassifier = mCompiler->mResolvePassData->GetSourceClassifier(typeDecl))
{ {
SetAndRestoreValue<bool> prevSkipTypeDeclaration(mCompiler->mResolvePassData->mSourceClassifier->mSkipTypeDeclarations, true); SetAndRestoreValue<bool> prevSkipTypeDeclaration(sourceClassifier->mSkipTypeDeclarations, true);
auto classifier = mCompiler->mResolvePassData->mSourceClassifier; sourceClassifier->mSkipMethodInternals = isAutoCompleteTempType;
classifier->mSkipMethodInternals = isAutoCompleteTempType; sourceClassifier->Handle(typeDecl);
classifier->Handle(typeDecl);
} }
}; };

View file

@ -156,6 +156,7 @@ public:
BfFieldDef* mCurFieldDef; BfFieldDef* mCurFieldDef;
BfTypeDef* mCurTypeDef; BfTypeDef* mCurTypeDef;
BfTypeDef* mForceActiveTypeDef; BfTypeDef* mForceActiveTypeDef;
BfProject* mActiveProject;
ResolveKind mResolveKind; ResolveKind mResolveKind;
BfAstNode* mCurVarInitializer; BfAstNode* mCurVarInitializer;
int mArrayInitializerSize; int mArrayInitializerSize;
@ -174,6 +175,7 @@ public:
mCurAttributeTypeRef = NULL; mCurAttributeTypeRef = NULL;
mCurTypeDef = NULL; mCurTypeDef = NULL;
mForceActiveTypeDef = NULL; mForceActiveTypeDef = NULL;
mActiveProject = NULL;
mCurVarInitializer = NULL; mCurVarInitializer = NULL;
mArrayInitializerSize = -1; mArrayInitializerSize = -1;
mResolveKind = ResolveKind_None; mResolveKind = ResolveKind_None;

View file

@ -153,8 +153,12 @@ void BfDefBuilder::Visit(BfIdentifierNode* identifier)
// already been handled, so we need to ignore that space while determining if we're "inside" this method or not during // already been handled, so we need to ignore that space while determining if we're "inside" this method or not during
// autocompletion // autocompletion
bool BfDefBuilder::WantsNode(BfAstNode* wholeNode, BfAstNode* startNode, int addLen) bool BfDefBuilder::WantsNode(BfAstNode* wholeNode, BfAstNode* startNode, int addLen)
{ {
if ((mResolvePassData == NULL) || (mResolvePassData->mParser->mCursorIdx == -1)) if ((mResolvePassData == NULL) || (!mResolvePassData->mHasCursorIdx))
return true;
auto parser = wholeNode->GetParser();
if (parser->mCursorIdx == -1)
return true; return true;
// We need to get all nodes when we get fixits because the cursor could be either before or after fields with // We need to get all nodes when we get fixits because the cursor could be either before or after fields with
@ -163,9 +167,9 @@ bool BfDefBuilder::WantsNode(BfAstNode* wholeNode, BfAstNode* startNode, int add
//return true; //return true;
addLen++; addLen++;
if ((mResolvePassData->mParser->mCursorIdx >= wholeNode->GetSrcStart()) && (mResolvePassData->mParser->mCursorIdx < wholeNode->GetSrcEnd() + addLen)) if ((parser->mCursorIdx >= wholeNode->GetSrcStart()) && (parser->mCursorIdx < wholeNode->GetSrcEnd() + addLen))
{ {
if ((startNode == NULL) || (mResolvePassData->mParser->mCursorIdx >= startNode->GetSrcStart())) if ((startNode == NULL) || (parser->mCursorIdx >= startNode->GetSrcStart()))
return true; return true;
} }
return false; return false;
@ -1417,13 +1421,20 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
{ {
isAutoCompleteTempType = (mResolvePassData->mAutoComplete != NULL); isAutoCompleteTempType = (mResolvePassData->mAutoComplete != NULL);
int cursorIdx = mResolvePassData->mParser->mCursorIdx; if (mResolvePassData->mHasCursorIdx)
if (typeDeclaration->Contains(cursorIdx, 1, 0))
{ {
// Within bounds auto parser = typeDeclaration->GetParser();
if (parser != NULL)
{
int cursorIdx = parser->mCursorIdx;
if (typeDeclaration->Contains(cursorIdx, 1, 0))
{
// Within bounds
}
else if (cursorIdx != -1)
return;
}
} }
else if (cursorIdx != -1)
return;
} }
int curLine = 0; int curLine = 0;

View file

@ -4260,7 +4260,8 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI
if ((resolvingFieldDef != NULL) && if ((resolvingFieldDef != NULL) &&
(mModule->mCompiler->mResolvePassData != NULL) && (mModule->mCompiler->mResolvePassData != NULL) &&
(mModule->mCompiler->mResolvePassData->mParser == resolvingFieldDef->mFieldDeclaration->GetParser()) && (!mModule->mCompiler->mResolvePassData->mParsers.IsEmpty()) &&
(mModule->mCompiler->mResolvePassData->mParsers[0] == resolvingFieldDef->mFieldDeclaration->GetParser()) &&
(GetAutoComplete() != NULL)) (GetAutoComplete() != NULL))
{ {
return mModule->GetDefaultTypedValue(mModule->mCurTypeInstance); return mModule->GetDefaultTypedValue(mModule->mCurTypeInstance);
@ -8805,7 +8806,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
auto autoComplete = GetAutoComplete(); auto autoComplete = GetAutoComplete();
if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo)) if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
{ {
if ((!targetSrc->IsFromParser(mModule->mCompiler->mResolvePassData->mParser)) || if ((!targetSrc->IsFromParser(mModule->mCompiler->mResolvePassData->mParsers[0])) ||
((autoComplete->mMethodMatchInfo->mInvocationSrcIdx != -1) && (autoComplete->mMethodMatchInfo->mInvocationSrcIdx != targetSrc->GetSrcStart()))) ((autoComplete->mMethodMatchInfo->mInvocationSrcIdx != -1) && (autoComplete->mMethodMatchInfo->mInvocationSrcIdx != targetSrc->GetSrcStart())))
{ {
autoComplete->mIsCapturingMethodMatchInfo = false; autoComplete->mIsCapturingMethodMatchInfo = false;
@ -9247,10 +9248,13 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
} }
if (enumResult) if (enumResult)
{ {
if (mModule->mCompiler->WantsClassifyNode(targetSrc)) if (mModule->mCompiler->mResolvePassData != NULL)
{ {
mModule->mCompiler->mResolvePassData->mSourceClassifier->SetElementType(targetSrc, BfSourceElementType_Normal); if (auto sourceClassifier = mModule->mCompiler->mResolvePassData->GetSourceClassifier(targetSrc))
{
sourceClassifier->SetElementType(targetSrc, BfSourceElementType_Normal);
}
} }
return enumResult; return enumResult;
} }
@ -14444,7 +14448,7 @@ void BfExprEvaluator::CheckObjectCreateTypeRef(BfType* expectingType, BfAstNode*
{ {
auto autoComplete = GetAutoComplete(); auto autoComplete = GetAutoComplete();
if ((autoComplete != NULL) && (afterNode != NULL) && (autoComplete->mIsAutoComplete) && if ((autoComplete != NULL) && (afterNode != NULL) && (autoComplete->mIsAutoComplete) &&
(afterNode->IsFromParser(mModule->mCompiler->mResolvePassData->mParser)) && (afterNode->IsFromParser(mModule->mCompiler->mResolvePassData->mParsers[0])) &&
(afterNode->GetParser()->mCursorIdx == afterNode->GetSrcEnd() + 1)) (afterNode->GetParser()->mCursorIdx == afterNode->GetSrcEnd() + 1))
{ {
BfType* expectingType = mExpectingType; BfType* expectingType = mExpectingType;

View file

@ -2874,11 +2874,10 @@ bool BfModule::CheckProtection(BfProtectionCheckFlags& flags, BfTypeInstance* me
void BfModule::SetElementType(BfAstNode* astNode, BfSourceElementType elementType) void BfModule::SetElementType(BfAstNode* astNode, BfSourceElementType elementType)
{ {
if ((mCompiler->mResolvePassData != NULL) && if (mCompiler->mResolvePassData != NULL)
(mCompiler->mResolvePassData->mSourceClassifier != NULL) &&
(astNode->IsFromParser(mCompiler->mResolvePassData->mParser)))
{ {
mCompiler->mResolvePassData->mSourceClassifier->SetElementType(astNode, elementType); if (auto sourceClassifier = mCompiler->mResolvePassData->GetSourceClassifier(astNode))
sourceClassifier->SetElementType(astNode, elementType);
} }
} }
@ -4441,10 +4440,13 @@ BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance,
} }
else else
{ {
if ((mCompiler->mIsResolveOnly) && (mCompiler->mResolvePassData->mSourceClassifier != NULL) && (initializer->IsFromParser(mCompiler->mResolvePassData->mParser))) if (mCompiler->mIsResolveOnly)
{ {
mCompiler->mResolvePassData->mSourceClassifier->SetElementType(initializer, BfSourceElementType_Normal); if (auto sourceClassifier = mCompiler->mResolvePassData->GetSourceClassifier(initializer))
mCompiler->mResolvePassData->mSourceClassifier->VisitChildNoRef(initializer); {
sourceClassifier->SetElementType(initializer, BfSourceElementType_Normal);
sourceClassifier->VisitChildNoRef(initializer);
}
} }
if ((mCurTypeInstance->IsPayloadEnum()) && (fieldDef->IsEnumCaseEntry())) if ((mCurTypeInstance->IsPayloadEnum()) && (fieldDef->IsEnumCaseEntry()))
@ -11631,10 +11633,10 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
if (!mCompiler->mHasRequiredTypes) if (!mCompiler->mHasRequiredTypes)
return; return;
if ((attributesDirective != NULL) && (mCompiler->mResolvePassData != NULL) && if ((attributesDirective != NULL) && (mCompiler->mResolvePassData != NULL))
(attributesDirective->IsFromParser(mCompiler->mResolvePassData->mParser)) && (mCompiler->mResolvePassData->mSourceClassifier != NULL))
{ {
mCompiler->mResolvePassData->mSourceClassifier->VisitChild(attributesDirective); if (auto sourceClassifier = mCompiler->mResolvePassData->GetSourceClassifier(attributesDirective))
sourceClassifier->VisitChild(attributesDirective);
} }
SetAndRestoreValue<bool> prevIsCapturingMethodMatchInfo; SetAndRestoreValue<bool> prevIsCapturingMethodMatchInfo;
@ -11644,6 +11646,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
BfTypeInstance* baseAttrTypeInst = mContext->mUnreifiedModule->ResolveTypeDef(mCompiler->mAttributeTypeDef)->ToTypeInstance(); BfTypeInstance* baseAttrTypeInst = mContext->mUnreifiedModule->ResolveTypeDef(mCompiler->mAttributeTypeDef)->ToTypeInstance();
BfAttributeTargets targetOverride = (BfAttributeTargets)0; BfAttributeTargets targetOverride = (BfAttributeTargets)0;
BfTypeDef* activeTypeDef = GetActiveTypeDef();
BfAutoComplete* autoComplete = NULL; BfAutoComplete* autoComplete = NULL;
if (mCompiler->mResolvePassData != NULL) if (mCompiler->mResolvePassData != NULL)
autoComplete = mCompiler->mResolvePassData->mAutoComplete; autoComplete = mCompiler->mResolvePassData->mAutoComplete;
@ -11674,6 +11677,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
BfCustomAttribute customAttribute; BfCustomAttribute customAttribute;
customAttribute.mAwaitingValidation = true; customAttribute.mAwaitingValidation = true;
customAttribute.mDeclaringType = activeTypeDef;
customAttribute.mRef = attributesDirective; customAttribute.mRef = attributesDirective;
if (attributesDirective->mAttrOpenToken != NULL) if (attributesDirective->mAttrOpenToken != NULL)
@ -12109,7 +12113,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
} }
if (success) if (success)
{ {
customAttributes->mAttributes.push_back(customAttribute); customAttributes->mAttributes.push_back(customAttribute);
} }
} }
@ -13446,10 +13450,10 @@ BfModule* BfModule::GetOrCreateMethodModule(BfMethodInstance* methodInstance)
if (methodDecl != NULL) if (methodDecl != NULL)
{ {
auto attributesDirective = methodDecl->mAttributes; auto attributesDirective = methodDecl->mAttributes;
if ((attributesDirective != NULL) && (mCompiler->mResolvePassData != NULL) && if ((attributesDirective != NULL) && (mCompiler->mResolvePassData != NULL))
(attributesDirective->IsFromParser(mCompiler->mResolvePassData->mParser)) && (mCompiler->mResolvePassData->mSourceClassifier != NULL))
{ {
mCompiler->mResolvePassData->mSourceClassifier->VisitChild(attributesDirective); if (auto sourceClassifier = mCompiler->mResolvePassData->GetSourceClassifier(attributesDirective))
sourceClassifier->VisitChild(attributesDirective);
} }
} }
} }
@ -16239,7 +16243,7 @@ bool BfModule::IsInterestedInMethod(BfTypeInstance* typeInstance, BfMethodDef* m
if (methodDeclaration == NULL) if (methodDeclaration == NULL)
checkNode = methodDef->mBody; checkNode = methodDef->mBody;
if ((mCompiler->mResolvePassData->mParser != NULL) && (typeDef->mTypeDeclaration->IsFromParser(mCompiler->mResolvePassData->mParser))) if ((!mCompiler->mResolvePassData->mParsers.IsEmpty()) && (typeDef->mTypeDeclaration->IsFromParser(mCompiler->mResolvePassData->mParsers[0])))
{ {
if (mCompiler->mResolvePassData->mAutoComplete == NULL) if (mCompiler->mResolvePassData->mAutoComplete == NULL)
return true; return true;
@ -16650,10 +16654,10 @@ void BfModule::CreateStaticCtor()
{ {
if (fieldDef->mInitializer != NULL) if (fieldDef->mInitializer != NULL)
{ {
if (mCompiler->mResolvePassData->mSourceClassifier != NULL) if (auto sourceClassifier = mCompiler->mResolvePassData->GetSourceClassifier(fieldDef->mInitializer))
{ {
mCompiler->mResolvePassData->mSourceClassifier->SetElementType(fieldDef->mInitializer, BfSourceElementType_Normal); sourceClassifier->SetElementType(fieldDef->mInitializer, BfSourceElementType_Normal);
mCompiler->mResolvePassData->mSourceClassifier->VisitChild(fieldDef->mInitializer); sourceClassifier->VisitChild(fieldDef->mInitializer);
} }
BfType* wantType = NULL; BfType* wantType = NULL;
if ((!BfNodeIsA<BfVarTypeReference>(fieldDef->mTypeRef)) && (!BfNodeIsA<BfLetTypeReference>(fieldDef->mTypeRef))) if ((!BfNodeIsA<BfVarTypeReference>(fieldDef->mTypeRef)) && (!BfNodeIsA<BfLetTypeReference>(fieldDef->mTypeRef)))
@ -16835,10 +16839,13 @@ void BfModule::EmitDtorBody()
while (fieldDtor != NULL) while (fieldDtor != NULL)
{ {
if (mCompiler->WantsClassifyNode(fieldDtor)) if (mCompiler->mResolvePassData != NULL)
{ {
mCompiler->mResolvePassData->mSourceClassifier->SetElementType(fieldDtor, BfSourceElementType_Normal); if (auto sourceClassifier = mCompiler->mResolvePassData->GetSourceClassifier(fieldDtor))
mCompiler->mResolvePassData->mSourceClassifier->VisitChild(fieldDtor); {
sourceClassifier->SetElementType(fieldDtor, BfSourceElementType_Normal);
sourceClassifier->VisitChild(fieldDtor);
}
} }
UpdateSrcPos(fieldDtor); UpdateSrcPos(fieldDtor);
@ -16910,7 +16917,7 @@ void BfModule::EmitDtorBody()
for (auto fieldDef : tempTypeDef->mFields) for (auto fieldDef : tempTypeDef->mFields)
{ {
if ((fieldDef->mIsStatic == methodDef->mIsStatic) && (fieldDef->mFieldDeclaration != NULL) && if ((fieldDef->mIsStatic == methodDef->mIsStatic) && (fieldDef->mFieldDeclaration != NULL) &&
(fieldDef->mFieldDeclaration->mFieldDtor != NULL) && (mCompiler->mResolvePassData->mSourceClassifier != NULL)) (fieldDef->mFieldDeclaration->mFieldDtor != NULL) && (mCompiler->mResolvePassData->mIsClassifying))
{ {
BfType* fieldType = NULL; BfType* fieldType = NULL;
@ -16943,8 +16950,11 @@ void BfModule::EmitDtorBody()
while (fieldDtor != NULL) while (fieldDtor != NULL)
{ {
mCompiler->mResolvePassData->mSourceClassifier->SetElementType(fieldDtor, BfSourceElementType_Normal); if (auto sourceClassifier = mCompiler->mResolvePassData->GetSourceClassifier(fieldDtor))
mCompiler->mResolvePassData->mSourceClassifier->VisitChild(fieldDtor); {
sourceClassifier->SetElementType(fieldDtor, BfSourceElementType_Normal);
sourceClassifier->VisitChild(fieldDtor);
}
UpdateSrcPos(fieldDtor); UpdateSrcPos(fieldDtor);
VisitEmbeddedStatement(fieldDtor->mBody); VisitEmbeddedStatement(fieldDtor->mBody);
@ -17659,10 +17669,13 @@ void BfModule::EmitCtorBody(bool& skipBody)
{ {
for (auto fieldDef : tempTypeDef->mFields) for (auto fieldDef : tempTypeDef->mFields)
{ {
if ((!fieldDef->mIsStatic) && (fieldDef->mInitializer != NULL) && (mCompiler->mResolvePassData->mSourceClassifier != NULL)) if ((!fieldDef->mIsStatic) && (fieldDef->mInitializer != NULL) && (mCompiler->mResolvePassData->mIsClassifying))
{ {
mCompiler->mResolvePassData->mSourceClassifier->SetElementType(fieldDef->mInitializer, BfSourceElementType_Normal); if (auto sourceClassifier = mCompiler->mResolvePassData->GetSourceClassifier(fieldDef->mInitializer))
mCompiler->mResolvePassData->mSourceClassifier->VisitChild(fieldDef->mInitializer); {
sourceClassifier->SetElementType(fieldDef->mInitializer, BfSourceElementType_Normal);
sourceClassifier->VisitChild(fieldDef->mInitializer);
}
BfType* wantType = NULL; BfType* wantType = NULL;
if ((!BfNodeIsA<BfVarTypeReference>(fieldDef->mTypeRef)) && if ((!BfNodeIsA<BfVarTypeReference>(fieldDef->mTypeRef)) &&
@ -19300,12 +19313,12 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup,
BF_ASSERT(!methodInstance->mIRFunction.IsFake() || (methodInstance->GetImportCallKind() != BfImportCallKind_None)); BF_ASSERT(!methodInstance->mIRFunction.IsFake() || (methodInstance->GetImportCallKind() != BfImportCallKind_None));
} }
SetAndRestoreValue<BfSourceClassifier*> prevSourceClassifier; SetAndRestoreValue<bool> prevIsClassifying;
if (((methodInstance->mMethodDef->mMethodType == BfMethodType_CtorCalcAppend) || (methodInstance->mIsForeignMethodDef) || (methodInstance->IsSpecializedGenericMethod())) && if (((methodInstance->mMethodDef->mMethodType == BfMethodType_CtorCalcAppend) || (methodInstance->mIsForeignMethodDef) || (methodInstance->IsSpecializedGenericMethod())) &&
(mCompiler->mResolvePassData != NULL)) (mCompiler->mResolvePassData != NULL))
{ {
// Don't classify on the CtorCalcAppend, just on the actual Ctor // Don't classify on the CtorCalcAppend, just on the actual Ctor
prevSourceClassifier.Init(mCompiler->mResolvePassData->mSourceClassifier, NULL); prevIsClassifying.Init(mCompiler->mResolvePassData->mIsClassifying, false);
} }
if (methodInstance->mHasBeenProcessed) if (methodInstance->mHasBeenProcessed)
@ -19573,10 +19586,10 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup,
if ((mCurMethodState == NULL) && (!IsInSpecializedSection())) // Only do initial classify for the 'outer' method state, not any local methods or lambdas if ((mCurMethodState == NULL) && (!IsInSpecializedSection())) // Only do initial classify for the 'outer' method state, not any local methods or lambdas
{ {
if ((mCompiler->mIsResolveOnly) && (!mIsComptimeModule) && (methodDef->mBody != NULL) && (!mCurTypeInstance->IsBoxed()) && if ((mCompiler->mIsResolveOnly) && (!mIsComptimeModule) && (methodDef->mBody != NULL) && (!mCurTypeInstance->IsBoxed()))
(methodDef->mBody->IsFromParser(mCompiler->mResolvePassData->mParser)) && (mCompiler->mResolvePassData->mSourceClassifier != NULL))
{ {
mCompiler->mResolvePassData->mSourceClassifier->VisitChildNoRef(methodDef->mBody); if (auto sourceClassifier = mCompiler->mResolvePassData->GetSourceClassifier(methodDef->mBody))
sourceClassifier->VisitChildNoRef(methodDef->mBody);
} }
} }

View file

@ -34,6 +34,7 @@ class BfResolvedType;
class BfExprEvaluator; class BfExprEvaluator;
class CeEmitContext; class CeEmitContext;
class CeDbgState; class CeDbgState;
enum BfCeTypeEmitSourceKind;
enum BfPopulateType enum BfPopulateType
{ {
@ -1780,8 +1781,8 @@ public:
BfModuleOptions GetModuleOptions(); BfModuleOptions GetModuleOptions();
BfCheckedKind GetDefaultCheckedKind(); BfCheckedKind GetDefaultCheckedKind();
void FinishCEParseContext(BfAstNode* refNode, BfTypeInstance* typeInstance, BfCEParseContext* ceParseContext); void FinishCEParseContext(BfAstNode* refNode, BfTypeInstance* typeInstance, BfCEParseContext* ceParseContext);
BfCEParseContext CEEmitParse(BfTypeInstance* typeInstance, const StringImpl& src); BfCEParseContext CEEmitParse(BfTypeInstance* typeInstance, BfTypeDef* declaringType, const StringImpl& src, BfAstNode* refNode, BfCeTypeEmitSourceKind emitSourceKind);
void UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, const StringImpl& ctxString, BfAstNode* refNode); void UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, BfTypeDef* declaringType, const StringImpl& ctxString, BfAstNode* refNode, BfCeTypeEmitSourceKind emitSourceKind);
void HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance* typeInst, BfFieldInstance* fieldInstance, BfCustomAttributes* customAttributes, Dictionary<BfTypeInstance*, BfIRValue>& foundAttributes, bool underlyingTypeDeferred); void HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance* typeInst, BfFieldInstance* fieldInstance, BfCustomAttributes* customAttributes, Dictionary<BfTypeInstance*, BfIRValue>& foundAttributes, bool underlyingTypeDeferred);
void CEMixin(BfAstNode* refNode, const StringImpl& src); void CEMixin(BfAstNode* refNode, const StringImpl& src);
void ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance* typeInst, BfCEOnCompileKind onCompileKind, bool underlyingTypeDeferred); void ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance* typeInst, BfCEOnCompileKind onCompileKind, bool underlyingTypeDeferred);

View file

@ -2023,7 +2023,7 @@ void BfModule::SetTypeOptions(BfTypeInstance* typeInstance)
typeInstance->mTypeOptionsIdx = GenerateTypeOptions(typeInstance->mCustomAttributes, typeInstance, true); typeInstance->mTypeOptionsIdx = GenerateTypeOptions(typeInstance->mCustomAttributes, typeInstance, true);
} }
BfCEParseContext BfModule::CEEmitParse(BfTypeInstance* typeInstance, const StringImpl& src) BfCEParseContext BfModule::CEEmitParse(BfTypeInstance* typeInstance, BfTypeDef* declaringType, const StringImpl& src, BfAstNode* refNode, BfCeTypeEmitSourceKind emitSourceKind)
{ {
BfCEParseContext ceParseContext; BfCEParseContext ceParseContext;
ceParseContext.mFailIdx = mCompiler->mPassInstance->mFailedIdx; ceParseContext.mFailIdx = mCompiler->mPassInstance->mFailedIdx;
@ -2034,6 +2034,21 @@ BfCEParseContext BfModule::CEEmitParse(BfTypeInstance* typeInstance, const Strin
BfParser* emitParser = NULL; BfParser* emitParser = NULL;
int64 emitSourceMapKey = ((int64)declaringType->mPartialIdx << 32) | refNode->mSrcStart;
if (typeInstance->mCeTypeInfo == NULL)
typeInstance->mCeTypeInfo = new BfCeTypeInfo();
auto ceTypeInfo = typeInstance->mCeTypeInfo;
if (ceTypeInfo->mNext != NULL)
ceTypeInfo = ceTypeInfo->mNext;
BfCeTypeEmitSource* ceEmitSource = NULL;
ceTypeInfo->mEmitSourceMap.TryAdd(emitSourceMapKey, NULL, &ceEmitSource);
ceEmitSource->mKind = emitSourceKind;
int emitSrcStart = 0;
BfEmitEmbedEntry* emitEmbedEntry = NULL;
if (typeInstance->mTypeDef->mEmitParent == NULL) if (typeInstance->mTypeDef->mEmitParent == NULL)
{ {
BF_ASSERT(typeInstance->mTypeDef->mNextRevision == NULL); BF_ASSERT(typeInstance->mTypeDef->mNextRevision == NULL);
@ -2048,21 +2063,38 @@ BfCEParseContext BfModule::CEEmitParse(BfTypeInstance* typeInstance, const Strin
createdParser = true; createdParser = true;
emitParser = new BfParser(mSystem, typeInstance->mTypeDef->mProject); emitParser = new BfParser(mSystem, typeInstance->mTypeDef->mProject);
emitParser->mIsEmitted = true; emitParser->mIsEmitted = true;
emitParser->mFileName = typeInstance->mTypeDef->mName->ToString();
BfLogSys(mSystem, "Emit typeDef for type %p created %p parser %p typeDecl %p\n", typeInstance, emitTypeDef, emitParser, emitTypeDef->mTypeDeclaration); BfLogSys(mSystem, "Emit typeDef for type %p created %p parser %p typeDecl %p\n", typeInstance, emitTypeDef, emitParser, emitTypeDef->mTypeDeclaration);
if (mCompiler->mIsResolveOnly) String typeName;
emitParser->mFileName += "$EmitR$"; typeName += typeInstance->mTypeDef->mProject->mName;
else typeName += ":";
emitParser->mFileName += "$Emit$";
typeName += TypeToString(typeInstance, BfTypeNameFlags_None);
if ((mCompiler->mResolvePassData != NULL) && (!mCompiler->mResolvePassData->mEmitEmbedEntries.IsEmpty()))
mCompiler->mResolvePassData->mEmitEmbedEntries.TryGetValue(typeName, &emitEmbedEntry);
emitParser->mFileName = "$Emit$";
emitParser->mFileName += typeName;
emitParser->mFileName += StrFormat("%d", typeInstance->mTypeId);
emitParser->mFileName += StrFormat(".bf|%d", typeInstance->mRevision);
emitTypeDef->mSource = emitParser; emitTypeDef->mSource = emitParser;
emitParser->mRefCount++; emitParser->mRefCount++;
emitParser->SetSource(src.c_str(), src.mLength); emitParser->SetSource(src.c_str(), src.mLength);
if (emitEmbedEntry != NULL)
{
emitEmbedEntry->mRevision = typeInstance->mRevision;
emitEmbedEntry->mParser = emitParser;
emitEmbedEntry->mParser->mSourceClassifier = new BfSourceClassifier(emitEmbedEntry->mParser, NULL);
mCompiler->mPassInstance->mFilterErrorsTo.Add(emitEmbedEntry->mParser->mParserData);
if (emitEmbedEntry->mCursorIdx != -1)
{
emitParser->SetCursorIdx(emitEmbedEntry->mCursorIdx);
emitParser->mParserFlags = (BfParserFlag)(emitParser->mParserFlags | ParserFlag_Autocomplete | ParserFlag_Classifying);
}
}
// If we emit only from method attributes then we will already have method instances created // If we emit only from method attributes then we will already have method instances created
auto _FixMethod = [&](BfMethodInstance* methodInstance) auto _FixMethod = [&](BfMethodInstance* methodInstance)
{ {
@ -2082,19 +2114,57 @@ BfCEParseContext BfModule::CEEmitParse(BfTypeInstance* typeInstance, const Strin
}; };
} }
else else
{ {
emitParser = typeInstance->mTypeDef->mSource->ToParser(); emitParser = typeInstance->mTypeDef->mSource->ToParser();
int idx = emitParser->AllocChars(src.mLength + 1); if ((mCompiler->mResolvePassData != NULL) && (!mCompiler->mResolvePassData->mEmitEmbedEntries.IsEmpty()))
memcpy((uint8*)emitParser->mSrc + idx, src.c_str(), src.mLength + 1); {
int dollarPos = (int)emitParser->mFileName.LastIndexOf('$');
if (dollarPos != -1)
mCompiler->mResolvePassData->mEmitEmbedEntries.TryGetValue(emitParser->mFileName.Substring(dollarPos + 1), &emitEmbedEntry);
}
int idx = emitParser->AllocChars(2 + src.mLength + 1);
emitSrcStart = idx + 2;
memcpy((uint8*)emitParser->mSrc + idx, "\n\n", 2);
memcpy((uint8*)emitParser->mSrc + idx + 2, src.c_str(), src.mLength + 1);
emitParser->mSrcIdx = idx; emitParser->mSrcIdx = idx;
emitParser->mSrcLength = idx + src.mLength; emitParser->mSrcLength = idx + src.mLength + 2;
emitParser->mParserData->mSrcLength = emitParser->mSrcLength; emitParser->mParserData->mSrcLength = emitParser->mSrcLength;
emitParser->mOrigSrcLength = emitParser->mSrcLength;
}
if (ceEmitSource->mSrcStart == -1)
{
ceEmitSource->mSrcStart = emitSrcStart;
ceEmitSource->mSrcEnd = emitParser->mSrcLength;
}
else
{
ceEmitSource->mSrcStart = BF_MIN(ceEmitSource->mSrcStart, emitSrcStart);
ceEmitSource->mSrcEnd = BF_MAX(ceEmitSource->mSrcEnd, emitParser->mSrcLength);
} }
emitParser->Parse(mCompiler->mPassInstance); emitParser->Parse(mCompiler->mPassInstance);
emitParser->FinishSideNodes(); emitParser->FinishSideNodes();
if (emitEmbedEntry != NULL)
{
int prevStart = emitEmbedEntry->mCharData.mSize;
emitEmbedEntry->mCharData.GrowUninitialized(emitParser->mSrcLength - emitEmbedEntry->mCharData.mSize);
auto charDataPtr = emitEmbedEntry->mCharData.mVals;
for (int i = prevStart; i < emitParser->mSrcLength; i++)
{
charDataPtr[i].mChar = emitParser->mSrc[i];
charDataPtr[i].mDisplayPassId = 0;
charDataPtr[i].mDisplayTypeId = 0;
charDataPtr[i].mDisplayFlags = 0;
}
emitEmbedEntry->mParser->mSourceClassifier->mCharData = emitEmbedEntry->mCharData.mVals;
}
if (createdParser) if (createdParser)
{ {
AutoCrit crit(mSystem->mDataLock); AutoCrit crit(mSystem->mDataLock);
@ -2117,7 +2187,7 @@ void BfModule::FinishCEParseContext(BfAstNode* refNode, BfTypeInstance* typeInst
} }
} }
void BfModule::UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, const StringImpl& ctxString, BfAstNode* refNode) void BfModule::UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, BfTypeDef* declaringType, const StringImpl& ctxString, BfAstNode* refNode, BfCeTypeEmitSourceKind emitSourceKind)
{ {
for (int ifaceTypeId : ceEmitContext->mInterfaces) for (int ifaceTypeId : ceEmitContext->mInterfaces)
typeInstance->mCeTypeInfo->mPendingInterfaces.Add(ifaceTypeId); typeInstance->mCeTypeInfo->mPendingInterfaces.Add(ifaceTypeId);
@ -2127,16 +2197,16 @@ void BfModule::UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeIn
String src; String src;
if (typeInstance->mTypeDef->mEmitParent != NULL) // if (typeInstance->mTypeDef->mEmitParent != NULL)
src += "\n\n"; // src += "\n\n";
src += "// Code emission in "; // src += "// Code emission in ";
src += ctxString; // src += ctxString;
src += "\n\n"; // src += "\n\n";
src += ceEmitContext->mEmitData; src += ceEmitContext->mEmitData;
ceEmitContext->mEmitData.Clear(); ceEmitContext->mEmitData.Clear();
BfCEParseContext ceParseContext = CEEmitParse(typeInstance, src); BfCEParseContext ceParseContext = CEEmitParse(typeInstance, declaringType, src, refNode, emitSourceKind);
auto emitParser = typeInstance->mTypeDef->mSource->ToParser(); auto emitParser = typeInstance->mTypeDef->mSource->ToParser();
auto typeDeclaration = emitParser->mAlloc->Alloc<BfTypeDeclaration>(); auto typeDeclaration = emitParser->mAlloc->Alloc<BfTypeDeclaration>();
@ -2167,6 +2237,13 @@ void BfModule::UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeIn
FinishCEParseContext(refNode, typeInstance, &ceParseContext); FinishCEParseContext(refNode, typeInstance, &ceParseContext);
if (emitParser->mSourceClassifier != NULL)
{
emitParser->mSourceClassifier->VisitChild(emitParser->mRootNode);
emitParser->mSourceClassifier->VisitChild(emitParser->mSidechannelRootNode);
emitParser->mSourceClassifier->VisitChild(emitParser->mErrorRootNode);
}
if (typeInstance->mTypeDef->mEmitParent != NULL) if (typeInstance->mTypeDef->mEmitParent != NULL)
{ {
// Remove generated fields like the 'underlying type' enum field // Remove generated fields like the 'underlying type' enum field
@ -2347,7 +2424,8 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance*
ctxStr += TypeToString(typeInstance); ctxStr += TypeToString(typeInstance);
ctxStr += " "; ctxStr += " ";
ctxStr += customAttribute.mRef->LocationToString(); ctxStr += customAttribute.mRef->LocationToString();
UpdateCEEmit(ceEmitContext, typeInstance, ctxStr, customAttribute.mRef);
UpdateCEEmit(ceEmitContext, typeInstance, customAttribute.mDeclaringType, ctxStr, customAttribute.mRef, BfCeTypeEmitSourceKind_Type);
} }
} }
@ -2361,11 +2439,11 @@ void BfModule::CEMixin(BfAstNode* refNode, const StringImpl& code)
//auto emitParser = activeTypeDef->mEmitParser; //auto emitParser = activeTypeDef->mEmitParser;
String src; String src;
if (mCurTypeInstance->mTypeDef->mEmitParent != NULL) // if (mCurTypeInstance->mTypeDef->mEmitParent != NULL)
src += "\n\n"; // src += "\n\n";
src += "// Code emission in "; // src += "// Code emission in ";
src += MethodToString(mCurMethodInstance); // src += MethodToString(mCurMethodInstance);
src += "\n"; // src += "\n";
src += code; src += code;
BfReducer bfReducer; BfReducer bfReducer;
@ -2380,7 +2458,7 @@ void BfModule::CEMixin(BfAstNode* refNode, const StringImpl& code)
bool wantsDIData = (mBfIRBuilder->DbgHasInfo()) && (mHasFullDebugInfo); bool wantsDIData = (mBfIRBuilder->DbgHasInfo()) && (mHasFullDebugInfo);
mBfIRBuilder->SaveDebugLocation(); mBfIRBuilder->SaveDebugLocation();
BfCEParseContext ceParseContext = CEEmitParse(mCurTypeInstance, src); BfCEParseContext ceParseContext = CEEmitParse(mCurTypeInstance, activeTypeDef, src, refNode, BfCeTypeEmitSourceKind_Method);
auto emitParser = mCurTypeInstance->mTypeDef->mSource->ToParser(); auto emitParser = mCurTypeInstance->mTypeDef->mSource->ToParser();
bfReducer.mSource = emitParser; bfReducer.mSource = emitParser;
bfReducer.mAlloc = emitParser->mAlloc; bfReducer.mAlloc = emitParser->mAlloc;
@ -2503,6 +2581,11 @@ void BfModule::ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance*
if (methodDeclaration->mAttributes == NULL) if (methodDeclaration->mAttributes == NULL)
continue; continue;
BfTypeState typeState;
typeState.mPrevState = mContext->mCurTypeState;
typeState.mForceActiveTypeDef = methodDef->mDeclaringType;
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
bool wantsAttributes = false; bool wantsAttributes = false;
BfAttributeDirective* checkAttributes = methodDeclaration->mAttributes; BfAttributeDirective* checkAttributes = methodDeclaration->mAttributes;
while (checkAttributes != NULL) while (checkAttributes != NULL)
@ -2607,7 +2690,7 @@ void BfModule::ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance*
ctxStr += MethodToString(methodInstance); ctxStr += MethodToString(methodInstance);
ctxStr += " "; ctxStr += " ";
ctxStr += methodInstance->mMethodDef->GetRefNode()->LocationToString(); ctxStr += methodInstance->mMethodDef->GetRefNode()->LocationToString();
UpdateCEEmit(ceEmitContext, typeInstance, ctxStr, methodInstance->mMethodDef->GetRefNode()); UpdateCEEmit(ceEmitContext, typeInstance, methodDef->mDeclaringType, ctxStr, methodInstance->mMethodDef->GetRefNode(), BfCeTypeEmitSourceKind_Type);
} }
} }
@ -2751,13 +2834,13 @@ void BfModule::DoCEEmit(BfMethodInstance* methodInstance)
if ((!ceEmitContext.mEmitData.IsEmpty()) || (!ceEmitContext.mExitEmitData.IsEmpty())) if ((!ceEmitContext.mEmitData.IsEmpty()) || (!ceEmitContext.mExitEmitData.IsEmpty()))
{ {
String src; String src;
src += "// Code emission in comptime ApplyToMethod of "; // src += "// Code emission in comptime ApplyToMethod of ";
src += TypeToString(attrType); // src += TypeToString(attrType);
src += " to "; // src += " to ";
src += MethodToString(methodInstance); // src += MethodToString(methodInstance);
src += " "; // src += " ";
src += customAttribute.mRef->LocationToString(); // src += customAttribute.mRef->LocationToString();
src += "\n"; // src += "\n";
//auto emitTypeDef = typeInstance->mCeTypeInfo->mNext->mTypeDef; //auto emitTypeDef = typeInstance->mCeTypeInfo->mNext->mTypeDef;
//auto emitParser = emitTypeDef->mSource->ToParser(); //auto emitParser = emitTypeDef->mSource->ToParser();
@ -2771,16 +2854,29 @@ void BfModule::DoCEEmit(BfMethodInstance* methodInstance)
bfReducer.mCurTypeDecl = activeTypeDef->mTypeDeclaration; bfReducer.mCurTypeDecl = activeTypeDef->mTypeDeclaration;
bfReducer.mCurMethodDecl = BfNodeDynCast<BfMethodDeclaration>(methodInstance->mMethodDef->mMethodDeclaration); bfReducer.mCurMethodDecl = BfNodeDynCast<BfMethodDeclaration>(methodInstance->mMethodDef->mMethodDeclaration);
BfAstNode* bodyNode = NULL;
if (auto methodDecl = BfNodeDynCast<BfMethodDeclaration>(methodInstance->mMethodDef->mMethodDeclaration))
bodyNode = methodDecl->mBody;
if (!ceEmitContext.mEmitData.IsEmpty()) if (!ceEmitContext.mEmitData.IsEmpty())
{ {
SetAndRestoreValue<BfAstNode*> prevCustomAttribute(mCurMethodState->mEmitRefNode, customAttribute.mRef); SetAndRestoreValue<BfAstNode*> prevCustomAttribute(mCurMethodState->mEmitRefNode, customAttribute.mRef);
String entrySrc = src; String entrySrc = src;
if (mCurTypeInstance->mTypeDef->mEmitParent != NULL) // if (mCurTypeInstance->mTypeDef->mEmitParent != NULL)
entrySrc += "\n\n"; // entrySrc += "\n\n";
entrySrc += src; entrySrc += src;
entrySrc += ceEmitContext.mEmitData; entrySrc += ceEmitContext.mEmitData;
BfCEParseContext ceParseContext = CEEmitParse(typeInstance, entrySrc);
BfAstNode* refNode = customAttribute.mRef;
if (bodyNode != NULL)
{
refNode = bodyNode;
if (auto blockNode = BfNodeDynCast<BfBlock>(bodyNode))
if (blockNode->mOpenBrace != NULL)
refNode = blockNode->mOpenBrace;
}
BfCEParseContext ceParseContext = CEEmitParse(typeInstance, methodInstance->mMethodDef->mDeclaringType, entrySrc, refNode, BfCeTypeEmitSourceKind_Type);
auto emitParser = mCurTypeInstance->mTypeDef->mSource->ToParser(); auto emitParser = mCurTypeInstance->mTypeDef->mSource->ToParser();
bfReducer.mSource = emitParser; bfReducer.mSource = emitParser;
bfReducer.mAlloc = emitParser->mAlloc; bfReducer.mAlloc = emitParser->mAlloc;
@ -2796,7 +2892,18 @@ void BfModule::DoCEEmit(BfMethodInstance* methodInstance)
exitSrc += "\n\n"; exitSrc += "\n\n";
exitSrc += src; exitSrc += src;
exitSrc += ceEmitContext.mExitEmitData; exitSrc += ceEmitContext.mExitEmitData;
BfCEParseContext ceParseContext = CEEmitParse(typeInstance, exitSrc);
BfAstNode* refNode = customAttribute.mRef;
if (bodyNode != NULL)
{
refNode = bodyNode;
if (auto blockNode = BfNodeDynCast<BfBlock>(bodyNode))
if (blockNode->mCloseBrace != NULL)
refNode = blockNode->mCloseBrace;
}
BfCEParseContext ceParseContext = CEEmitParse(typeInstance, methodInstance->mMethodDef->mDeclaringType, exitSrc, refNode, BfCeTypeEmitSourceKind_Type);
auto emitParser = mCurTypeInstance->mTypeDef->mSource->ToParser(); auto emitParser = mCurTypeInstance->mTypeDef->mSource->ToParser();
bfReducer.mSource = emitParser; bfReducer.mSource = emitParser;
bfReducer.mAlloc = emitParser->mAlloc; bfReducer.mAlloc = emitParser->mAlloc;
@ -4540,7 +4647,14 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
if (typeInstance->mCeTypeInfo->mNext != NULL) if (typeInstance->mCeTypeInfo->mNext != NULL)
{ {
auto ceInfo = typeInstance->mCeTypeInfo->mNext; auto ceInfo = typeInstance->mCeTypeInfo->mNext;
HashContext hashCtx; HashContext hashCtx;
hashCtx.Mixin(ceInfo->mEmitSourceMap.mCount);
for (auto& kv : ceInfo->mEmitSourceMap)
{
hashCtx.Mixin(kv.mKey);
hashCtx.Mixin(kv.mValue);
}
hashCtx.Mixin(ceInfo->mOnCompileMap.mCount); hashCtx.Mixin(ceInfo->mOnCompileMap.mCount);
for (auto& kv : ceInfo->mOnCompileMap) for (auto& kv : ceInfo->mOnCompileMap)
{ {
@ -4559,15 +4673,26 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
if (!typeInstance->mCeTypeInfo->mNext->mFailed) if (!typeInstance->mCeTypeInfo->mNext->mFailed)
{ {
if ((typeInstance->mCeTypeInfo->mHash != typeInstance->mCeTypeInfo->mNext->mHash) && (!typeInstance->mCeTypeInfo->mHash.IsZero())) if ((typeInstance->mCeTypeInfo->mHash != typeInstance->mCeTypeInfo->mNext->mHash) && (!typeInstance->mCeTypeInfo->mHash.IsZero()))
mContext->RebuildDependentTypes_MidCompile(typeInstance, "comptime hash changed"); mContext->RebuildDependentTypes_MidCompile(typeInstance, "comptime hash changed");
typeInstance->mCeTypeInfo->mEmitSourceMap = typeInstance->mCeTypeInfo->mNext->mEmitSourceMap;
typeInstance->mCeTypeInfo->mOnCompileMap = typeInstance->mCeTypeInfo->mNext->mOnCompileMap; typeInstance->mCeTypeInfo->mOnCompileMap = typeInstance->mCeTypeInfo->mNext->mOnCompileMap;
typeInstance->mCeTypeInfo->mTypeIFaceMap = typeInstance->mCeTypeInfo->mNext->mTypeIFaceMap; typeInstance->mCeTypeInfo->mTypeIFaceMap = typeInstance->mCeTypeInfo->mNext->mTypeIFaceMap;
typeInstance->mCeTypeInfo->mHash = typeInstance->mCeTypeInfo->mNext->mHash; typeInstance->mCeTypeInfo->mHash = typeInstance->mCeTypeInfo->mNext->mHash;
} }
delete typeInstance->mCeTypeInfo->mNext; delete typeInstance->mCeTypeInfo->mNext;
typeInstance->mCeTypeInfo->mNext = NULL; typeInstance->mCeTypeInfo->mNext = NULL;
} }
else
{
// Removed emissions
if (!typeInstance->mCeTypeInfo->mHash.IsZero())
mContext->RebuildDependentTypes_MidCompile(typeInstance, "comptime hash changed");
typeInstance->mCeTypeInfo->mEmitSourceMap.Clear();
typeInstance->mCeTypeInfo->mOnCompileMap.Clear();
typeInstance->mCeTypeInfo->mTypeIFaceMap.Clear();
typeInstance->mCeTypeInfo->mHash = Val128();
}
} }
if ((typeInstance->mCeTypeInfo != NULL) && (!typeInstance->mCeTypeInfo->mPendingInterfaces.IsEmpty())) if ((typeInstance->mCeTypeInfo != NULL) && (!typeInstance->mCeTypeInfo->mPendingInterfaces.IsEmpty()))
@ -5312,16 +5437,19 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
if ((typeDeclaration != NULL) && (typeDeclaration->mNameNode != NULL)) if ((typeDeclaration != NULL) && (typeDeclaration->mNameNode != NULL))
{ {
auto typeRefSource = typeDeclaration->mNameNode->GetParserData(); auto typeRefSource = typeDeclaration->mNameNode->GetParserData();
if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mSourceClassifier != NULL) && (typeRefSource != NULL) && (typeRefSource == mCompiler->mResolvePassData->mParser->mSourceData)) if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mIsClassifying) && (typeRefSource != NULL))
{ {
BfSourceElementType elemType = BfSourceElementType_Type; if (auto sourceClassifier = mCompiler->mResolvePassData->GetSourceClassifier(typeDeclaration->mNameNode))
if (typeInstance->IsInterface()) {
elemType = BfSourceElementType_Interface; BfSourceElementType elemType = BfSourceElementType_Type;
else if (typeInstance->IsObject()) if (typeInstance->IsInterface())
elemType = BfSourceElementType_RefType; elemType = BfSourceElementType_Interface;
else if (typeInstance->IsStruct() || (typeInstance->IsTypedPrimitive() && !typeInstance->IsEnum())) else if (typeInstance->IsObject())
elemType = BfSourceElementType_Struct; elemType = BfSourceElementType_RefType;
mCompiler->mResolvePassData->mSourceClassifier->SetElementType(typeDeclaration->mNameNode, elemType); else if (typeInstance->IsStruct() || (typeInstance->IsTypedPrimitive() && !typeInstance->IsEnum()))
elemType = BfSourceElementType_Struct;
sourceClassifier->SetElementType(typeDeclaration->mNameNode, elemType);
}
} }
} }
}; };
@ -8775,11 +8903,17 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
else else
typeRefSource = typeRef->GetSourceData(); typeRefSource = typeRef->GetSourceData();
bool wantsFileNamespaceInfo = (((mCompiler->mResolvePassData->mSourceClassifier != NULL) || (isGetDefinition) || (mCompiler->mResolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Namespace)) && BfSourceClassifier* sourceClassifier = NULL;
(typeRefSource != NULL) && (mCompiler->mResolvePassData->mParser != NULL) && if ((mCompiler->mResolvePassData->mIsClassifying) && (typeRefSource != NULL))
(typeRefSource == mCompiler->mResolvePassData->mParser->mSourceData)); {
auto parser = typeRefSource->ToParser();
if (parser != NULL)
sourceClassifier = mCompiler->mResolvePassData->GetSourceClassifier(parser);
}
bool wantsAllNamespaceInfo = (mCompiler->mResolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Namespace) && (mCompiler->mResolvePassData->mParser == NULL); bool wantsFileNamespaceInfo = ((sourceClassifier != NULL) || (isGetDefinition) || (mCompiler->mResolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Namespace));
bool wantsAllNamespaceInfo = (mCompiler->mResolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Namespace) && (mCompiler->mResolvePassData->mParsers.IsEmpty());
if (wantsFileNamespaceInfo || wantsAllNamespaceInfo) if (wantsFileNamespaceInfo || wantsAllNamespaceInfo)
{ {
@ -8841,14 +8975,14 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
while (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(checkTypeRef)) while (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(checkTypeRef))
{ {
if ((mCompiler->mResolvePassData->mSourceClassifier != NULL) && (checkTypeRef == headTypeRef) && (elemType != BfSourceElementType_Type)) if ((sourceClassifier != NULL) && (checkTypeRef == headTypeRef) && (elemType != BfSourceElementType_Type))
mCompiler->mResolvePassData->mSourceClassifier->SetElementType(qualifiedTypeRef->mRight, elemType); sourceClassifier->SetElementType(qualifiedTypeRef->mRight, elemType);
StringView leftString = qualifiedTypeRef->mLeft->ToStringView(); StringView leftString = qualifiedTypeRef->mLeft->ToStringView();
BfSizedAtomComposite leftComposite; BfSizedAtomComposite leftComposite;
bool isValid = mSystem->ParseAtomComposite(leftString, leftComposite); bool isValid = mSystem->ParseAtomComposite(leftString, leftComposite);
if (mCompiler->mResolvePassData->mSourceClassifier != NULL) if (sourceClassifier != NULL)
mCompiler->mResolvePassData->mSourceClassifier->SetHighestElementType(qualifiedTypeRef->mRight, isNamespace ? BfSourceElementType_Namespace : BfSourceElementType_Type); sourceClassifier->SetHighestElementType(qualifiedTypeRef->mRight, isNamespace ? BfSourceElementType_Namespace : BfSourceElementType_Type);
if (resolvedTypeInstance == NULL) if (resolvedTypeInstance == NULL)
{ {
if ((isValid) && (mCompiler->mSystem->ContainsNamespace(leftComposite, mCurTypeInstance->mTypeDef->mProject))) if ((isValid) && (mCompiler->mSystem->ContainsNamespace(leftComposite, mCurTypeInstance->mTypeDef->mProject)))
@ -8874,16 +9008,16 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
auto checkNameNode = namedTypeRef->mNameNode; auto checkNameNode = namedTypeRef->mNameNode;
bool setType = false; bool setType = false;
if ((mCompiler->mResolvePassData->mSourceClassifier != NULL) && (checkTypeRef == headTypeRef) && (elemType != BfSourceElementType_Type)) if ((sourceClassifier != NULL) && (checkTypeRef == headTypeRef) && (elemType != BfSourceElementType_Type))
{ {
if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(checkNameNode)) if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(checkNameNode))
{ {
mCompiler->mResolvePassData->mSourceClassifier->SetElementType(qualifiedNameNode->mRight, elemType); sourceClassifier->SetElementType(qualifiedNameNode->mRight, elemType);
} }
else else
{ {
setType = true; setType = true;
mCompiler->mResolvePassData->mSourceClassifier->SetElementType(checkNameNode, elemType); sourceClassifier->SetElementType(checkNameNode, elemType);
} }
} }
@ -8892,8 +9026,8 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
StringView leftString = qualifiedNameNode->mLeft->ToStringView(); StringView leftString = qualifiedNameNode->mLeft->ToStringView();
BfSizedAtomComposite leftComposite; BfSizedAtomComposite leftComposite;
bool isValid = mSystem->ParseAtomComposite(leftString, leftComposite); bool isValid = mSystem->ParseAtomComposite(leftString, leftComposite);
if (mCompiler->mResolvePassData->mSourceClassifier != NULL) if (sourceClassifier != NULL)
mCompiler->mResolvePassData->mSourceClassifier->SetHighestElementType(qualifiedNameNode->mRight, isNamespace ? BfSourceElementType_Namespace : BfSourceElementType_Type); sourceClassifier->SetHighestElementType(qualifiedNameNode->mRight, isNamespace ? BfSourceElementType_Namespace : BfSourceElementType_Type);
if (resolvedTypeInstance == NULL) if (resolvedTypeInstance == NULL)
{ {
if ((isValid) && (mCompiler->mSystem->ContainsNamespace(leftComposite, mCurTypeInstance->mTypeDef->mProject))) if ((isValid) && (mCompiler->mSystem->ContainsNamespace(leftComposite, mCurTypeInstance->mTypeDef->mProject)))
@ -8913,9 +9047,9 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
} }
checkNameNode = qualifiedNameNode->mLeft; checkNameNode = qualifiedNameNode->mLeft;
} }
if ((mCompiler->mResolvePassData->mSourceClassifier != NULL) && if ((sourceClassifier != NULL) &&
((!setType) || (checkNameNode != namedTypeRef->mNameNode))) ((!setType) || (checkNameNode != namedTypeRef->mNameNode)))
mCompiler->mResolvePassData->mSourceClassifier->SetHighestElementType(checkNameNode, isNamespace ? BfSourceElementType_Namespace : BfSourceElementType_Type); sourceClassifier->SetHighestElementType(checkNameNode, isNamespace ? BfSourceElementType_Namespace : BfSourceElementType_Type);
} }
} }
@ -8964,6 +9098,7 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
else else
break; break;
} }
if ((baseNode != NULL) && (autoComplete->IsAutocompleteNode(baseNode))) if ((baseNode != NULL) && (autoComplete->IsAutocompleteNode(baseNode)))
{ {
// We didn't have this mDefType check before - why? We always want to catch the FIRST definition, // We didn't have this mDefType check before - why? We always want to catch the FIRST definition,
@ -9348,8 +9483,10 @@ BfTypeDef* BfModule::FindTypeDef(const BfAtomComposite& findName, int numGeneric
if ((typeInstance == NULL) && (useTypeDef == NULL)) if ((typeInstance == NULL) && (useTypeDef == NULL))
{ {
BfProject* project = NULL; BfProject* project = NULL;
if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mParser != NULL)) if ((mContext->mCurTypeState != NULL) && (mContext->mCurTypeState->mActiveProject != NULL))
project = mCompiler->mResolvePassData->mParser->mProject; project = mContext->mCurTypeState->mActiveProject;
else if ((mCompiler->mResolvePassData != NULL) && (!mCompiler->mResolvePassData->mParsers.IsEmpty()))
project = mCompiler->mResolvePassData->mParsers[0]->mProject;
BP_ZONE("System.FindTypeDef_2"); BP_ZONE("System.FindTypeDef_2");
Array<BfAtomComposite> namespaceSearch; Array<BfAtomComposite> namespaceSearch;
@ -9535,7 +9672,7 @@ void BfModule::CheckTypeRefFixit(BfAstNode* typeRef, const char* appendName)
std::set<String> fixitNamespaces; std::set<String> fixitNamespaces;
//TODO: Do proper value for numGenericArgs //TODO: Do proper value for numGenericArgs
mSystem->FindFixitNamespaces(typeName, -1, mCompiler->mResolvePassData->mParser->mProject, fixitNamespaces); mSystem->FindFixitNamespaces(typeName, -1, mCompiler->mResolvePassData->mParsers[0]->mProject, fixitNamespaces);
int insertLoc = 0; int insertLoc = 0;
@ -9810,8 +9947,11 @@ BfTypedValue BfModule::TryLookupGenericConstVaue(BfIdentifierNode* identifierNod
if (genericParamResult != NULL) if (genericParamResult != NULL)
{ {
auto typeRefSource = identifierNode->GetSourceData(); auto typeRefSource = identifierNode->GetSourceData();
if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mSourceClassifier != NULL) && (typeRefSource != NULL) && (typeRefSource == mCompiler->mResolvePassData->mParser->mSourceData)) if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mIsClassifying) && (typeRefSource != NULL))
mCompiler->mResolvePassData->mSourceClassifier->SetElementType(identifierNode, BfSourceElementType_GenericParam); {
if (auto sourceClassifier = mCompiler->mResolvePassData->GetSourceClassifier(identifierNode))
sourceClassifier->SetElementType(identifierNode, BfSourceElementType_GenericParam);
}
if (genericParamResult->IsConstExprValue()) if (genericParamResult->IsConstExprValue())
{ {

View file

@ -345,6 +345,7 @@ BfParser::BfParser(BfSystem* bfSystem, BfProject* bfProject) : BfSource(bfSystem
gParserCount++; gParserCount++;
mEmbedKind = BfSourceEmbedKind_None;
mUsingCache = false; mUsingCache = false;
mParserData = NULL; mParserData = NULL;
mAwaitingDelete = false; mAwaitingDelete = false;
@ -354,7 +355,7 @@ BfParser::BfParser(BfSystem* bfSystem, BfProject* bfProject) : BfSource(bfSystem
mJumpTable = NULL; mJumpTable = NULL;
mProject = bfProject; mProject = bfProject;
mPassInstance = NULL; mPassInstance = NULL;
mPassInstance = NULL; mSourceClassifier = NULL;
mPrevRevision = NULL; mPrevRevision = NULL;
mNextRevision = NULL; mNextRevision = NULL;
mOrigSrcLength = 0; mOrigSrcLength = 0;
@ -375,7 +376,7 @@ BfParser::BfParser(BfSystem* bfSystem, BfProject* bfProject) : BfSource(bfSystem
mCompatMode = false; mCompatMode = false;
mQuickCompatMode = false; mQuickCompatMode = false;
mLiteral.mWarnType = 0; mLiteral.mWarnType = 0;
mDataId = -1; mDataId = -1;
mTriviaStart = 0; mTriviaStart = 0;
mParsingFailed = false; mParsingFailed = false;
@ -3820,6 +3821,11 @@ BF_EXPORT void BF_CALLTYPE BfParser_SetIsClassifying(BfParser* bfParser)
bfParser->mParserFlags = (BfParserFlag)(bfParser->mParserFlags | ParserFlag_Classifying); bfParser->mParserFlags = (BfParserFlag)(bfParser->mParserFlags | ParserFlag_Classifying);
} }
BF_EXPORT void BF_CALLTYPE BfParser_SetEmbedKind(BfParser* bfParser, BfSourceEmbedKind embedKind)
{
bfParser->mEmbedKind = embedKind;
}
BF_EXPORT void BF_CALLTYPE BfParser_SetAutocomplete(BfParser* bfParser, int cursorIdx) BF_EXPORT void BF_CALLTYPE BfParser_SetAutocomplete(BfParser* bfParser, int cursorIdx)
{ {
BF_ASSERT(bfParser->mParserData->mRefCount == -1); BF_ASSERT(bfParser->mParserData->mRefCount == -1);
@ -3972,7 +3978,8 @@ BF_EXPORT BfResolvePassData* BF_CALLTYPE BfParser_CreateResolvePassData(BfParser
{ {
auto bfResolvePassData = new BfResolvePassData(); auto bfResolvePassData = new BfResolvePassData();
bfResolvePassData->mResolveType = resolveType; bfResolvePassData->mResolveType = resolveType;
bfResolvePassData->mParser = bfParser; if (bfParser != NULL)
bfResolvePassData->mParsers.Add(bfParser);
if ((bfParser != NULL) && ((bfParser->mParserFlags & ParserFlag_Autocomplete) != 0)) if ((bfParser != NULL) && ((bfParser->mParserFlags & ParserFlag_Autocomplete) != 0))
bfResolvePassData->mAutoComplete = new BfAutoComplete(resolveType, doFuzzyAutoComplete); bfResolvePassData->mAutoComplete = new BfAutoComplete(resolveType, doFuzzyAutoComplete);
return bfResolvePassData; return bfResolvePassData;
@ -3980,6 +3987,9 @@ BF_EXPORT BfResolvePassData* BF_CALLTYPE BfParser_CreateResolvePassData(BfParser
BF_EXPORT bool BF_CALLTYPE BfParser_BuildDefs(BfParser* bfParser, BfPassInstance* bfPassInstance, BfResolvePassData* resolvePassData, bool fullRefresh) BF_EXPORT bool BF_CALLTYPE BfParser_BuildDefs(BfParser* bfParser, BfPassInstance* bfPassInstance, BfResolvePassData* resolvePassData, bool fullRefresh)
{ {
if (bfParser->mCursorIdx != -1)
resolvePassData->mHasCursorIdx = true;
BP_ZONE("BfParser_BuildDefs"); BP_ZONE("BfParser_BuildDefs");
int startFailIdx = bfPassInstance->mFailedIdx; int startFailIdx = bfPassInstance->mFailedIdx;
BfDefBuilder defBuilder(bfParser->mSystem); BfDefBuilder defBuilder(bfParser->mSystem);
@ -4007,6 +4017,51 @@ BF_EXPORT void BF_CALLTYPE BfParser_ClassifySource(BfParser* bfParser, BfSourceC
bfSourceClassifier.Visit(bfParser->mSidechannelRootNode); bfSourceClassifier.Visit(bfParser->mSidechannelRootNode);
} }
BF_EXPORT void BF_CALLTYPE BfParser_CreateClassifier(BfParser* bfParser, BfPassInstance* bfPassInstance, BfResolvePassData* resolvePassData, BfSourceClassifier::CharData* charData)
{
resolvePassData->mIsClassifying = true;
bfParser->mSourceClassifier = new BfSourceClassifier(bfParser, charData);
bfParser->mSourceClassifier->mClassifierPassId = bfPassInstance->mClassifierPassId;
if ((resolvePassData->mParsers.IsEmpty()) || (bfParser != resolvePassData->mParsers[0]))
resolvePassData->mParsers.Add(bfParser);
bool doClassifyPass = (charData != NULL) && (resolvePassData->mResolveType <= BfResolveType_Autocomplete_HighPri);
bfParser->mSourceClassifier->mEnabled = doClassifyPass;
bfParser->mSourceClassifier->mSkipMethodInternals = true;
bfParser->mSourceClassifier->mSkipTypeDeclarations = true;
if (charData != NULL)
{
if ((doClassifyPass) && (bfParser->mRootNode != NULL))
bfParser->mSourceClassifier->Visit(bfParser->mRootNode);
}
bfParser->mSourceClassifier->mSkipTypeDeclarations = false;
bfParser->mSourceClassifier->mSkipMethodInternals = false;
}
BF_EXPORT void BF_CALLTYPE BfParser_FinishClassifier(BfParser* bfParser, BfResolvePassData* resolvePassData)
{
if (bfParser->mSourceClassifier == NULL)
return;
bool doClassifyPass = (bfParser->mSourceClassifier->mCharData != NULL) && (resolvePassData->mResolveType <= BfResolveType_Autocomplete_HighPri);
if (doClassifyPass)
{
bfParser->mSourceClassifier->mIsSideChannel = false;
if (bfParser->mErrorRootNode != NULL)
bfParser->mSourceClassifier->Visit(bfParser->mErrorRootNode);
bfParser->mSourceClassifier->mIsSideChannel = true;
if (bfParser->mSidechannelRootNode != NULL)
bfParser->mSourceClassifier->Visit(bfParser->mSidechannelRootNode);
}
delete bfParser->mSourceClassifier;
bfParser->mSourceClassifier = NULL;
}
BF_EXPORT void BF_CALLTYPE BfParser_GenerateAutoCompletionFrom(BfParser* bfParser, int srcPosition) BF_EXPORT void BF_CALLTYPE BfParser_GenerateAutoCompletionFrom(BfParser* bfParser, int srcPosition)
{ {
BP_ZONE("BfParser_GenerateAutoCompletionFrom"); BP_ZONE("BfParser_GenerateAutoCompletionFrom");

View file

@ -14,6 +14,7 @@ NS_BF_BEGIN
class BfPassInstance; class BfPassInstance;
class BfProject; class BfProject;
class BfSourceClassifier;
enum BfSyntaxToken enum BfSyntaxToken
{ {
@ -136,13 +137,20 @@ public:
void ReportMemory(MemReporter* memReporter); void ReportMemory(MemReporter* memReporter);
}; };
enum BfDefineState enum BfDefineState : int8
{ {
BfDefineState_FromProject, BfDefineState_FromProject,
BfDefineState_ManualSet, BfDefineState_ManualSet,
BfDefineState_ManualUnset BfDefineState_ManualUnset
}; };
enum BfSourceEmbedKind : int8
{
BfSourceEmbedKind_None,
BfSourceEmbedKind_Type,
BfSourceEmbedKind_Method
};
class BfParser : public BfSource class BfParser : public BfSource
{ {
public: public:
@ -150,7 +158,9 @@ public:
bool mUsingCache; bool mUsingCache;
BfPassInstance* mPassInstance; BfPassInstance* mPassInstance;
BfSourceClassifier* mSourceClassifier;
String mFileName; String mFileName;
BfSourceEmbedKind mEmbedKind;
bool mAwaitingDelete; bool mAwaitingDelete;
bool mCompatMode; // Does C++ compatible parsing bool mCompatMode; // Does C++ compatible parsing

View file

@ -6781,7 +6781,8 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, bool declStarted, int dept
// if (depth == 0) // if (depth == 0)
// prevTypeMemberNodeStart.Set(); // prevTypeMemberNodeStart.Set();
AssertCurrentNode(node); if (mCurTypeDecl != NULL)
AssertCurrentNode(node);
BfTokenNode* refToken = NULL; BfTokenNode* refToken = NULL;
@ -8239,6 +8240,58 @@ BfAstNode* BfReducer::HandleTopLevel(BfBlock* node)
bool hadPrevFail = false; bool hadPrevFail = false;
bool isDone = !mVisitorPos.MoveNext(); bool isDone = !mVisitorPos.MoveNext();
auto parser = mSource->ToParser();
if ((parser != NULL) && (parser->mEmbedKind == BfSourceEmbedKind_Type))
{
while (!isDone)
{
auto node = mVisitorPos.GetCurrent();
if (node == prevNode)
{
// If we're stuck on an error and can't process any more nodes
break;
}
prevNode = node;
BfAstNode* typeMember = BfNodeDynCast<BfMemberDeclaration>(node);
if (typeMember == NULL)
{
SetAndRestoreValue<BfAstNode*> prevTypeMemberNodeStart(mTypeMemberNodeStart, node);
typeMember = ReadTypeMember(node);
}
//methodDeclaration->mDocumentation = FindDocumentation(methodDeclaration);
isDone = !mVisitorPos.MoveNext();
if (typeMember != NULL)
{
mVisitorPos.Write(typeMember);
}
}
}
if ((parser != NULL) && (parser->mEmbedKind == BfSourceEmbedKind_Method))
{
bool allowEndingExpression = false;
BfAstNode* nextNode = NULL;
while (!isDone)
{
BfAstNode* node = mVisitorPos.GetCurrent();
CreateStmtFlags flags = (CreateStmtFlags)(CreateStmtFlags_FindTrailingSemicolon | CreateStmtFlags_AllowLocalFunction);
if (allowEndingExpression)
flags = (CreateStmtFlags)(flags | CreateStmtFlags_AllowUnterminatedExpression);
auto statement = CreateStatement(node, flags);
if ((statement == NULL) && (mSource != NULL))
statement = mSource->CreateErrorNode(node);
isDone = !mVisitorPos.MoveNext();
if (statement != NULL)
mVisitorPos.Write(statement);
}
}
while (!isDone) while (!isDone)
{ {
@ -10246,7 +10299,7 @@ void BfReducer::HandleTypeDeclaration(BfTypeDeclaration* typeDecl, BfAttributeDi
MEMBER_SET(typeDecl, mAttributes, attributes); MEMBER_SET(typeDecl, mAttributes, attributes);
} }
if (!IsNodeRelevant(deferredHeadNode, typeDecl)) if ((!IsNodeRelevant(deferredHeadNode, typeDecl)) && (!typeDecl->IsTemporary()))
{ {
typeDecl->mIgnoreDeclaration = true; typeDecl->mIgnoreDeclaration = true;
return; return;

View file

@ -18,9 +18,24 @@ BfResolvePassData::BfResolvePassData()
mSymbolTypeGenericParamIdx = -1; mSymbolTypeGenericParamIdx = -1;
mAutoComplete = NULL; mAutoComplete = NULL;
mSourceClassifier = NULL;
mResolveType = BfResolveType_None; mResolveType = BfResolveType_None;
mParser = NULL; mIsClassifying = false;
mHasCursorIdx = false;
}
BfResolvePassData::~BfResolvePassData()
{
for (auto& emitEntryKV : mEmitEmbedEntries)
{
auto parser = emitEntryKV.mValue.mParser;
if (parser != NULL)
{
delete parser->mSourceClassifier;
parser->mSourceClassifier = NULL;
parser->mParserFlags = ParserFlag_None;
parser->mCursorCheckIdx = -1;
}
}
} }
void BfResolvePassData::RecordReplaceNode(BfParserData* parser, int srcStart, int srcLen) void BfResolvePassData::RecordReplaceNode(BfParserData* parser, int srcStart, int srcLen)
@ -179,3 +194,20 @@ void BfResolvePassData::HandleNamespaceReference(BfAstNode* node, const BfAtomCo
RecordReplaceNode(baseNode); RecordReplaceNode(baseNode);
} }
} }
BfSourceClassifier* BfResolvePassData::GetSourceClassifier(BfAstNode* astNode)
{
if (!mIsClassifying)
return NULL;
auto parser = astNode->GetParser();
if (parser == NULL)
return NULL;
return parser->mSourceClassifier;
}
BfSourceClassifier* BfResolvePassData::GetSourceClassifier(BfParser* parser)
{
if (!mIsClassifying)
return NULL;
return parser->mSourceClassifier;
}

View file

@ -2,6 +2,7 @@
#include "BfSystem.h" #include "BfSystem.h"
#include "BfResolvedTypeUtils.h" #include "BfResolvedTypeUtils.h"
#include "BfSourceClassifier.h"
NS_BF_BEGIN NS_BF_BEGIN
@ -40,17 +41,33 @@ enum BfGetSymbolReferenceKind
BfGetSymbolReferenceKind_Namespace BfGetSymbolReferenceKind_Namespace
}; };
class BfEmitEmbedEntry
{
public:
int mCursorIdx;
int mRevision;
BfParser* mParser;
Array<BfSourceClassifier::CharData> mCharData;
public:
BfEmitEmbedEntry()
{
mCursorIdx = -1;
mRevision = -1;
mParser = NULL;
}
};
class BfResolvePassData class BfResolvePassData
{ {
public: public:
BfResolveType mResolveType; BfResolveType mResolveType;
BfParser* mParser; Array<BfParser*> mParsers;
BfAutoComplete* mAutoComplete; BfAutoComplete* mAutoComplete;
Array<BfTypeDef*> mAutoCompleteTempTypes; // Contains multiple values when we have nested types Array<BfTypeDef*> mAutoCompleteTempTypes; // Contains multiple values when we have nested types
Dictionary<BfTypeDef*, BfStaticSearch> mStaticSearchMap; Dictionary<BfTypeDef*, BfStaticSearch> mStaticSearchMap;
Dictionary<BfTypeDef*, BfInternalAccessSet> mInternalAccessMap; Dictionary<BfTypeDef*, BfInternalAccessSet> mInternalAccessMap;
BfSourceClassifier* mSourceClassifier;
Array<BfAstNode*> mExteriorAutocompleteCheckNodes; Array<BfAstNode*> mExteriorAutocompleteCheckNodes;
BfGetSymbolReferenceKind mGetSymbolReferenceKind; BfGetSymbolReferenceKind mGetSymbolReferenceKind;
@ -64,11 +81,15 @@ public:
int mSymbolReferencePropertyIdx; int mSymbolReferencePropertyIdx;
int mSymbolMethodGenericParamIdx; int mSymbolMethodGenericParamIdx;
int mSymbolTypeGenericParamIdx; int mSymbolTypeGenericParamIdx;
bool mIsClassifying;
bool mHasCursorIdx;
typedef Dictionary<BfParserData*, String> FoundSymbolReferencesParserDataMap; typedef Dictionary<BfParserData*, String> FoundSymbolReferencesParserDataMap;
FoundSymbolReferencesParserDataMap mFoundSymbolReferencesParserData; FoundSymbolReferencesParserDataMap mFoundSymbolReferencesParserData;
//std::vector<BfIdentifierNode*> mSymbolReferenceIdentifiers; //std::vector<BfIdentifierNode*> mSymbolReferenceIdentifiers;
Dictionary<String, BfEmitEmbedEntry> mEmitEmbedEntries;
public: public:
void RecordReplaceNode(BfParserData* parser, int srcStart, int srcLen); void RecordReplaceNode(BfParserData* parser, int srcStart, int srcLen);
void RecordReplaceNode(BfAstNode* node); void RecordReplaceNode(BfAstNode* node);
@ -76,6 +97,7 @@ public:
public: public:
BfResolvePassData(); BfResolvePassData();
~BfResolvePassData();
void HandleLocalReference(BfIdentifierNode* identifier, BfTypeDef* typeDef, BfMethodDef* methodDef, int localVarIdx); void HandleLocalReference(BfIdentifierNode* identifier, BfTypeDef* typeDef, BfMethodDef* methodDef, int localVarIdx);
void HandleLocalReference(BfIdentifierNode* identifier, BfIdentifierNode* origNameNode, BfTypeDef* typeDef, BfMethodDef* methodDef, int localVarIdx); void HandleLocalReference(BfIdentifierNode* identifier, BfIdentifierNode* origNameNode, BfTypeDef* typeDef, BfMethodDef* methodDef, int localVarIdx);
@ -87,6 +109,8 @@ public:
void HandleTypeReference(BfAstNode* node, BfTypeDef* typeDef); void HandleTypeReference(BfAstNode* node, BfTypeDef* typeDef);
void HandleNamespaceReference(BfAstNode* node, const BfAtomComposite& namespaceName); void HandleNamespaceReference(BfAstNode* node, const BfAtomComposite& namespaceName);
BfSourceClassifier* GetSourceClassifier(BfAstNode* astNode);
BfSourceClassifier* GetSourceClassifier(BfParser* parser);
//void ReplaceIdentifiers(); //void ReplaceIdentifiers();
}; };

View file

@ -57,7 +57,7 @@ enum BfTypeNameFlags : uint16
BfTypeNameFlag_InternalName = 0x100, // Use special delimiters to remove ambiguities (ie: '+' for inner types) BfTypeNameFlag_InternalName = 0x100, // Use special delimiters to remove ambiguities (ie: '+' for inner types)
BfTypeNameFlag_HideGlobalName = 0x200, BfTypeNameFlag_HideGlobalName = 0x200,
BfTypeNameFlag_ExtendedInfo = 0x400, BfTypeNameFlag_ExtendedInfo = 0x400,
BfTypeNameFlag_ShortConst = 0x800 BfTypeNameFlag_ShortConst = 0x800
}; };
enum BfMethodNameFlags : uint8 enum BfMethodNameFlags : uint8
@ -1886,12 +1886,6 @@ public:
void ReportMemory(MemReporter* memReporter); void ReportMemory(MemReporter* memReporter);
}; };
class BfCeTypeEmitEntry
{
public:
String mEmitData;
};
class BfCeTypeInfo; class BfCeTypeInfo;
// Instance of struct or class // Instance of struct or class
@ -2543,6 +2537,7 @@ class BfCustomAttribute
{ {
public: public:
BfAttributeDirective* mRef; BfAttributeDirective* mRef;
BfTypeDef* mDeclaringType;
BfTypeInstance* mType; BfTypeInstance* mType;
BfMethodDef* mCtor; BfMethodDef* mCtor;
Array<BfIRValue> mCtorArgs; Array<BfIRValue> mCtorArgs;

View file

@ -30,9 +30,19 @@ void Beefy::DoBfLog(int fileIdx, const char* fmt ...)
static BfpFile* fp[10] = { NULL }; static BfpFile* fp[10] = { NULL };
static bool openedLog[10] = { false }; static bool openedLog[10] = { false };
static int64 logSize[10] = { 0 };
static int logCount[10] = { 0 };
if (logSize[fileIdx] >= 1 * 1024 * 1024 * 1024)
{
BfpFile_Release(fp[fileIdx]);
openedLog[fileIdx] = false;
}
if (!openedLog[fileIdx]) if (!openedLog[fileIdx])
{ {
openedLog[fileIdx] = true; openedLog[fileIdx] = true;
logSize[fileIdx] = 0;
char exeName[512]; char exeName[512];
int len = 512; int len = 512;
@ -42,10 +52,16 @@ void Beefy::DoBfLog(int fileIdx, const char* fmt ...)
int dotPos = (int)dbgName.IndexOf('.'); int dotPos = (int)dbgName.IndexOf('.');
if (dotPos != -1) if (dotPos != -1)
dbgName.RemoveToEnd(dotPos); dbgName.RemoveToEnd(dotPos);
dbgName += StrFormat("_%d.txt", fileIdx); dbgName += StrFormat("_%d", fileIdx);
if (logCount[fileIdx] > 0)
dbgName += 'B';
dbgName += ".txt";
fp[fileIdx] = BfpFile_Create(dbgName.c_str(), BfpFileCreateKind_CreateAlways, (BfpFileCreateFlags)(BfpFileCreateFlag_Write | BfpFileCreateFlag_NoBuffering | BfpFileCreateFlag_ShareRead), BfpFileAttribute_Normal, NULL); fp[fileIdx] = BfpFile_Create(dbgName.c_str(), BfpFileCreateKind_CreateAlways, (BfpFileCreateFlags)(BfpFileCreateFlag_Write | BfpFileCreateFlag_NoBuffering | BfpFileCreateFlag_ShareRead), BfpFileAttribute_Normal, NULL);
onNewLine[fileIdx] = true; onNewLine[fileIdx] = true;
logCount[fileIdx]++;
} }
if (fp[fileIdx] == NULL) if (fp[fileIdx] == NULL)
return; return;
@ -74,6 +90,8 @@ void Beefy::DoBfLog(int fileIdx, const char* fmt ...)
{ {
if (strOfs + numChars > 0) if (strOfs + numChars > 0)
{ {
logSize[fileIdx] += strOfs + numChars;
BfpFile_Write(fp[fileIdx], lineStr, strOfs + numChars, -1, NULL); BfpFile_Write(fp[fileIdx], lineStr, strOfs + numChars, -1, NULL);
if (lineStr[strOfs + numChars - 1] == '\n') if (lineStr[strOfs + numChars - 1] == '\n')
onNewLine[fileIdx] = true; onNewLine[fileIdx] = true;
@ -98,6 +116,7 @@ void Beefy::DoBfLog(int fileIdx, const char* fmt ...)
else else
onNewLine[fileIdx] = false; onNewLine[fileIdx] = false;
logSize[fileIdx] += aResult.length();
BfpFile_Write(fp[fileIdx], aResult.c_str(), aResult.length(), -1, NULL); BfpFile_Write(fp[fileIdx], aResult.c_str(), aResult.length(), -1, NULL);
} }
@ -1137,8 +1156,9 @@ bool BfPassInstance::PopOutString(String* outString)
bool BfPassInstance::WantsRangeRecorded(BfSourceData* bfSource, int srcIdx, int srcLen, bool isWarning, bool isDeferred) bool BfPassInstance::WantsRangeRecorded(BfSourceData* bfSource, int srcIdx, int srcLen, bool isWarning, bool isDeferred)
{ {
if ((mFilterErrorsTo != NULL) && (bfSource != mFilterErrorsTo->mSourceData)) if ((!mFilterErrorsTo.IsEmpty()) && (!mFilterErrorsTo.Contains(bfSource)))
return false; return false;
if (bfSource == NULL) if (bfSource == NULL)
return true; return true;
@ -3964,6 +3984,28 @@ BF_EXPORT void BfResolvePassData_SetDocumentationRequest(BfResolvePassData* reso
resolvePassData->mAutoComplete->mDocumentationEntryName = entryName; resolvePassData->mAutoComplete->mDocumentationEntryName = entryName;
} }
BF_EXPORT void BfResolvePassData_AddEmitEmbed(BfResolvePassData* resolvePassData, char* typeName, int32 cursorIdx)
{
BfEmitEmbedEntry emitEmbedEntry;
emitEmbedEntry.mCursorIdx = cursorIdx;
resolvePassData->mEmitEmbedEntries[typeName] = emitEmbedEntry;
}
BF_EXPORT void* BfResolvePassData_GetEmitEmbedData(BfResolvePassData* resolvePassData, char* typeName, int* charCount, int* revision)
{
*charCount = -1;
*revision = 0;
BfEmitEmbedEntry* emitEmbedEntry = NULL;
if (!resolvePassData->mEmitEmbedEntries.TryGetValue(typeName, &emitEmbedEntry))
return NULL;
if (emitEmbedEntry->mParser == NULL)
return NULL;
*revision = emitEmbedEntry->mRevision;
*charCount = emitEmbedEntry->mParser->mSrcLength;
return emitEmbedEntry->mParser->mSourceClassifier->mCharData;
}
BF_EXPORT BfParser* BF_CALLTYPE BfSystem_CreateParser(BfSystem* bfSystem, BfProject* bfProject) BF_EXPORT BfParser* BF_CALLTYPE BfSystem_CreateParser(BfSystem* bfSystem, BfProject* bfProject)
{ {
return bfSystem->CreateParser(bfProject); return bfSystem->CreateParser(bfProject);

View file

@ -38,8 +38,8 @@ namespace llvm
NS_BF_BEGIN NS_BF_BEGIN
class BfSystem; class BfSystem;
class BfTypeReference;
class BfCompiler; class BfCompiler;
class BfTypeReference;
class BfProject; class BfProject;
class BfTypeDef; class BfTypeDef;
@ -157,7 +157,7 @@ enum BfCompilerOptionFlags
BfCompilerOptionFlag_EnableSideStack = 0x1000, BfCompilerOptionFlag_EnableSideStack = 0x1000,
BfCompilerOptionFlag_EnableHotSwapping = 0x2000, BfCompilerOptionFlag_EnableHotSwapping = 0x2000,
BfCompilerOptionFlag_IncrementalBuild = 0x4000, BfCompilerOptionFlag_IncrementalBuild = 0x4000,
BfCompilerOptionFlag_DebugAlloc = 0x8000, BfCompilerOptionFlag_DebugAlloc = 0x8000,
BfCompilerOptionFlag_OmitDebugHelpers = 0x10000, BfCompilerOptionFlag_OmitDebugHelpers = 0x10000,
BfCompilerOptionFlag_NoFramePointerElim = 0x20000, BfCompilerOptionFlag_NoFramePointerElim = 0x20000,
BfCompilerOptionFlag_ArithmeticChecks = 0x40000, BfCompilerOptionFlag_ArithmeticChecks = 0x40000,
@ -1412,6 +1412,7 @@ public:
const int sMaxErrors = 1000; const int sMaxErrors = 1000;
BfSystem* mSystem; BfSystem* mSystem;
BfCompiler* mCompiler;
bool mTrimMessagesToCursor; bool mTrimMessagesToCursor;
int mFailedIdx; int mFailedIdx;
int mWarnIdx; int mWarnIdx;
@ -1426,7 +1427,7 @@ public:
bool mLastWasDisplayed; bool mLastWasDisplayed;
bool mLastWasAdded; bool mLastWasAdded;
uint8 mClassifierPassId; uint8 mClassifierPassId;
BfParser* mFilterErrorsTo; HashSet<BfSourceData*> mFilterErrorsTo;
bool mHadSignatureChanges; bool mHadSignatureChanges;
public: public:
@ -1436,13 +1437,13 @@ public:
mFailedIdx = 0; mFailedIdx = 0;
mWarnIdx = 0; mWarnIdx = 0;
mSystem = bfSystem; mSystem = bfSystem;
mCompiler = NULL;
mLastWasDisplayed = false; mLastWasDisplayed = false;
mLastWasAdded = false; mLastWasAdded = false;
mClassifierPassId = 0; mClassifierPassId = 0;
mWarningCount = 0; mWarningCount = 0;
mDeferredErrorCount = 0; mDeferredErrorCount = 0;
mIgnoreCount = 0; mIgnoreCount = 0;
mFilterErrorsTo = NULL;
mHadSignatureChanges = false; mHadSignatureChanges = false;
} }

View file

@ -1,4 +1,5 @@
#include "BfUtil.h" #include "BfUtil.h"
#include "BeefySysLib/util/Hash.h"
USING_NS_BF; USING_NS_BF;
@ -52,6 +53,26 @@ void* Beefy::ZeroedAlloc(int size)
return data; return data;
} }
String Beefy::EncodeFileName(const StringImpl& fromStr)
{
String path;
if (fromStr.mLength > 80)
path.Insert(0, fromStr.mPtr, 80);
else
path += fromStr;
path.Replace("$", "\\");
for (auto& c : path)
{
if ((!::isalnum((uint8)c)) && (c != '_'))
c = '-';
}
path += "_";
path += HashEncode128(Hash128(fromStr.c_str(), (int)fromStr.length()));
return path;
}
uint64 stouln(const char* str, int len) uint64 stouln(const char* str, int len)
{ {
uint64 val = 0; uint64 val = 0;

View file

@ -283,6 +283,8 @@ String EncodeDataPtr(uint32 addr, bool doPrefix);
String EncodeDataPtr(uint64 addr, bool doPrefix); String EncodeDataPtr(uint64 addr, bool doPrefix);
String EncodeDataPtr(int addr, bool doPrefix); String EncodeDataPtr(int addr, bool doPrefix);
void* ZeroedAlloc(int size); void* ZeroedAlloc(int size);
String EncodeFileName(const StringImpl& fromStr); // Make short, only legal chars, with a hash at end
/*template <typename T> /*template <typename T>
T* ZeroedAlloc() T* ZeroedAlloc()
{ {

View file

@ -938,7 +938,7 @@ String CeDebugger::DoEvaluate(CePendingExpr* pendingExpr, bool inCompilerThread)
autoComplete.mSystem = module->mSystem; autoComplete.mSystem = module->mSystem;
BfResolvePassData resolvePass; BfResolvePassData resolvePass;
resolvePass.mParser = pendingExpr->mParser; resolvePass.mParsers.Add(pendingExpr->mParser);
resolvePass.mAutoComplete = &autoComplete; resolvePass.mAutoComplete = &autoComplete;
SetAndRestoreValue<BfResolvePassData*> prevResolvePass; SetAndRestoreValue<BfResolvePassData*> prevResolvePass;
@ -4925,3 +4925,8 @@ bool CeDebugger::IsOnDemandDebugger()
{ {
return true; return true;
} }
bool CeDebugger::GetEmitSource(const StringImpl& filePath, String& outText)
{
return false;
}

View file

@ -402,6 +402,7 @@ public:
virtual Profiler* PopProfiler() override; // Profiler requested by target program virtual Profiler* PopProfiler() override; // Profiler requested by target program
virtual void ReportMemory(MemReporter* memReporter) override; virtual void ReportMemory(MemReporter* memReporter) override;
virtual bool IsOnDemandDebugger() override; virtual bool IsOnDemandDebugger() override;
virtual bool GetEmitSource(const StringImpl& filePath, String& outText) override;
}; };
NS_BF_END NS_BF_END

View file

@ -972,11 +972,42 @@ public:
} }
}; };
enum BfCeTypeEmitSourceKind
{
BfCeTypeEmitSourceKind_Unknown,
BfCeTypeEmitSourceKind_Type,
BfCeTypeEmitSourceKind_Method
};
class BfCeTypeEmitSource
{
public:
BfCeTypeEmitSourceKind mKind;
int mSrcStart;
int mSrcEnd;
public:
BfCeTypeEmitSource()
{
mKind = BfCeTypeEmitSourceKind_Unknown;
mSrcStart = -1;
mSrcEnd = -1;
}
};
class BfCeTypeEmitEntry
{
public:
String mEmitData;
};
class BfCeTypeInfo class BfCeTypeInfo
{ {
public: public:
Dictionary<int, BfCeTypeEmitEntry> mOnCompileMap; Dictionary<int, BfCeTypeEmitEntry> mOnCompileMap;
Dictionary<int, BfCeTypeEmitEntry> mTypeIFaceMap; Dictionary<int, BfCeTypeEmitEntry> mTypeIFaceMap;
Dictionary<int64, BfCeTypeEmitSource> mEmitSourceMap; // key is (extension<<32)|charId
Array<int> mPendingInterfaces; Array<int> mPendingInterfaces;
Dictionary<CeRebuildKey, CeRebuildValue> mRebuildMap; Dictionary<CeRebuildKey, CeRebuildValue> mRebuildMap;
Val128 mHash; Val128 mHash;

View file

@ -2190,6 +2190,7 @@ DbgModule::DbgModule(DebugTarget* debugTarget) : mDefaultCompileUnit(this)
mStartTypeIdx = 0; mStartTypeIdx = 0;
mEndTypeIdx = 0; mEndTypeIdx = 0;
mHotIdx = 0; mHotIdx = 0;
mId = 0;
mStartSubprogramIdx = 0; mStartSubprogramIdx = 0;
mEndSubprogramIdx = 0; mEndSubprogramIdx = 0;
mCodeAddress = NULL; mCodeAddress = NULL;
@ -7139,6 +7140,9 @@ DbgFileExistKind DbgModule::CheckSourceFileExist(const StringImpl& path)
{ {
DbgFileExistKind existsKind = DbgFileExistKind_NotFound; DbgFileExistKind existsKind = DbgFileExistKind_NotFound;
if (path.StartsWith("$Emit"))
return DbgFileExistKind_Found;
if (FileExists(path)) if (FileExists(path))
existsKind = DbgFileExistKind_Found; existsKind = DbgFileExistKind_Found;

View file

@ -1146,6 +1146,7 @@ public:
bool mMayBeOld; // If we had to load debug info from the SymCache or a SymServer then it may be old bool mMayBeOld; // If we had to load debug info from the SymCache or a SymServer then it may be old
bool mDeleting; bool mDeleting;
bool mFailed; bool mFailed;
int mId;
int mHotIdx; int mHotIdx;
String mFilePath; String mFilePath;
String mDisplayName; String mDisplayName;
@ -1226,6 +1227,7 @@ public:
virtual void ProcessDebugInfo(); virtual void ProcessDebugInfo();
virtual bool CanGetOldSource() { return false; } virtual bool CanGetOldSource() { return false; }
virtual String GetOldSourceCommand(const StringImpl& path) { return ""; } virtual String GetOldSourceCommand(const StringImpl& path) { return ""; }
virtual bool GetEmitSource(const StringImpl& filePath, String& outText) { return false; }
virtual bool DbgIsStrMutable(const char* str) { return true; } // Always assume its a copy virtual bool DbgIsStrMutable(const char* str) { return true; } // Always assume its a copy
virtual addr_target LocateSymbol(const StringImpl& name) { return 0; } virtual addr_target LocateSymbol(const StringImpl& name) { return 0; }
virtual DbgSubprogram* FindSubprogram(DbgType* dbgType, const char* methodName); virtual DbgSubprogram* FindSubprogram(DbgType* dbgType, const char* methodName);

View file

@ -1609,6 +1609,19 @@ BF_EXPORT const char* BF_CALLTYPE Debugger_GetHotResolveData(uint8* outTypeData,
return outString.c_str(); return outString.c_str();
} }
BF_EXPORT const char* BF_CALLTYPE Debugger_GetEmitSource(char* inFilePath)
{
AutoCrit autoCrit(gDebugManager->mCritSect);
String& outString = *gTLStrReturn.Get();
outString.Clear();
if (!gDebugger->GetEmitSource(inFilePath, outString))
return NULL;
return outString.c_str();
}
BF_EXPORT NetResult* HTTP_GetFile(char* url, char* destPath) BF_EXPORT NetResult* HTTP_GetFile(char* url, char* destPath)
{ {
AutoCrit autoCrit(gDebugManager->mNetManager->mThreadPool.mCritSect); AutoCrit autoCrit(gDebugManager->mNetManager->mThreadPool.mCritSect);

View file

@ -162,14 +162,14 @@ DbgModule* DebugTarget::Init(const StringImpl& launchPath, const StringImpl& tar
} }
CheckTargetBinary(dwarf); CheckTargetBinary(dwarf);
mDbgModules.push_back(dwarf); AddDbgModule(dwarf);
return dwarf; return dwarf;
} }
void DebugTarget::CreateEmptyTarget() void DebugTarget::CreateEmptyTarget()
{ {
auto emptyTarget = new DbgModule(this); auto emptyTarget = new DbgModule(this);
mDbgModules.push_back(emptyTarget); AddDbgModule(emptyTarget);
mTargetBinary = emptyTarget; mTargetBinary = emptyTarget;
mLaunchBinary = emptyTarget; mLaunchBinary = emptyTarget;
} }
@ -198,7 +198,7 @@ DbgModule* DebugTarget::HotLoad(const StringImpl& fileName, int hotIdx)
delete dwarf; delete dwarf;
return NULL; return NULL;
} }
mDbgModules.push_back(dwarf); AddDbgModule(dwarf);
return dwarf; return dwarf;
} }
@ -217,7 +217,7 @@ DbgModule* DebugTarget::SetupDyn(const StringImpl& filePath, DataStream* stream,
delete dwarf; delete dwarf;
return NULL; return NULL;
} }
mDbgModules.push_back(dwarf); AddDbgModule(dwarf);
dwarf->mDisplayName = GetFileName(filePath); dwarf->mDisplayName = GetFileName(filePath);
dwarf->mOrigImageData = new DbgModuleMemoryCache(dwarf->mImageBase, dwarf->mImageSize); dwarf->mOrigImageData = new DbgModuleMemoryCache(dwarf->mImageBase, dwarf->mImageSize);
@ -905,6 +905,12 @@ void DebugTarget::GetCompilerSettings()
} }
} }
void DebugTarget::AddDbgModule(DbgModule* dbgModule)
{
static int id = 0;
dbgModule->mId = ++id;
mDbgModules.Add(dbgModule);
}
#if 1 #if 1
bool DebugTarget::RollBackStackFrame_ExceptionDirectory(addr_target findPC, CPURegisters* registers, addr_target* outReturnAddressLoc, bool& alreadyRolledBackPC) bool DebugTarget::RollBackStackFrame_ExceptionDirectory(addr_target findPC, CPURegisters* registers, addr_target* outReturnAddressLoc, bool& alreadyRolledBackPC)

View file

@ -37,10 +37,8 @@ public:
int mLastHotHeapCleanIdx; int mLastHotHeapCleanIdx;
String mTargetPath; String mTargetPath;
DbgModule* mLaunchBinary; DbgModule* mLaunchBinary;
DbgModule* mTargetBinary; DbgModule* mTargetBinary;
//DbgModule* m Array<DbgModule*> mDbgModules;
Array<DbgModule*> mDbgModules;
//DbgModule* mLastDWARF;
HashSet<DbgSrcFile*> mPendingSrcFileRehup; // Waiting to remove old/invalid line info HashSet<DbgSrcFile*> mPendingSrcFileRehup; // Waiting to remove old/invalid line info
BumpAllocator mAlloc; BumpAllocator mAlloc;
@ -57,12 +55,11 @@ public:
Array<DwCommonFrameDescriptor*> mCommonFrameDescriptors; Array<DwCommonFrameDescriptor*> mCommonFrameDescriptors;
std::map<addr_target, DwFrameDescriptor> mDwFrameDescriptorMap; std::map<addr_target, DwFrameDescriptor> mDwFrameDescriptorMap;
std::map<addr_target, COFFFrameDescriptorEntry> mCOFFFrameDescriptorMap; std::map<addr_target, COFFFrameDescriptorEntry> mCOFFFrameDescriptorMap;
//Array<DbgSrcFile*> mSrcFiles;
Dictionary<String, DbgSrcFile*> mSrcFiles; Dictionary<String, DbgSrcFile*> mSrcFiles;
Dictionary<String, String> mLocalToOrigSrcMap; Dictionary<String, String> mLocalToOrigSrcMap;
protected: protected:
bool RollBackStackFrame_ExceptionDirectory(addr_target findPC, CPURegisters* registers, addr_target* outReturnAddressLoc, bool& alreadyRolledBackPC); bool RollBackStackFrame_ExceptionDirectory(addr_target findPC, CPURegisters* registers, addr_target* outReturnAddressLoc, bool& alreadyRolledBackPC);
bool RollBackStackFrame_ExceptionDirectory(CPURegisters* registers, addr_target* outReturnAddressLoc, bool& alreadyRolledBackPC); bool RollBackStackFrame_ExceptionDirectory(CPURegisters* registers, addr_target* outReturnAddressLoc, bool& alreadyRolledBackPC);
bool RollBackStackFrame_DwFrameDescriptor(CPURegisters* registers, addr_target* outReturnAddressLoc); bool RollBackStackFrame_DwFrameDescriptor(CPURegisters* registers, addr_target* outReturnAddressLoc);
@ -76,6 +73,7 @@ public:
DebugTarget(WinDebugger* debugger); DebugTarget(WinDebugger* debugger);
~DebugTarget(); ~DebugTarget();
void AddDbgModule(DbgModule* dbgModule);
DbgModule* Init(const StringImpl& launchPath, const StringImpl& targetPath, intptr imageBase = 0); DbgModule* Init(const StringImpl& launchPath, const StringImpl& targetPath, intptr imageBase = 0);
void SetupTargetBinary(); void SetupTargetBinary();
void CheckTargetBinary(DbgModule* module); void CheckTargetBinary(DbgModule* module);

View file

@ -351,7 +351,8 @@ public:
virtual Profiler* StartProfiling() = 0; virtual Profiler* StartProfiling() = 0;
virtual Profiler* PopProfiler() = 0; // Profiler requested by target program virtual Profiler* PopProfiler() = 0; // Profiler requested by target program
virtual void ReportMemory(MemReporter* memReporter) = 0; virtual void ReportMemory(MemReporter* memReporter) = 0;
virtual bool IsOnDemandDebugger() = 0; virtual bool IsOnDemandDebugger() = 0;
virtual bool GetEmitSource(const StringImpl& filePath, String& outText) = 0;
}; };
class Profiler class Profiler

View file

@ -76,7 +76,7 @@ MiniDumpDebugger::MiniDumpDebugger(DebugManager* debugManager, DbgMiniDump* mini
auto miscEntry = &mMiniDump->GetData<char>(module.MiscRecord.Rva); auto miscEntry = &mMiniDump->GetData<char>(module.MiscRecord.Rva);
mDebugTarget->mDbgModules.Add(dbgModule); mDebugTarget->AddDbgModule(dbgModule);
//TESTING //TESTING
/*{ /*{

View file

@ -1531,6 +1531,24 @@ void WinDebugger::ReportMemory(MemReporter* memReporter)
mDebugTarget->ReportMemory(memReporter); mDebugTarget->ReportMemory(memReporter);
} }
bool WinDebugger::GetEmitSource(const StringImpl& filePath, String& outText)
{
if (!filePath.StartsWith("$Emit"))
return false;
int dollarPos = filePath.IndexOf('$', 1);
String numStr = filePath.Substring(5, dollarPos - 5);
int id = atoi(numStr.c_str());
for (auto dbgModule : mDebugTarget->mDbgModules)
{
if (dbgModule->mId == id)
return dbgModule->GetEmitSource(filePath, outText);
}
return false;
}
void WinDebugger::ModuleChanged(DbgModule* dbgModule) void WinDebugger::ModuleChanged(DbgModule* dbgModule)
{ {
mDebugManager->mOutMessages.push_back(String("dbgInfoLoaded ") + dbgModule->mFilePath); mDebugManager->mOutMessages.push_back(String("dbgInfoLoaded ") + dbgModule->mFilePath);
@ -11092,6 +11110,21 @@ String WinDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* o
*outFlags |= FrameFlags_WasHotReplaced; *outFlags |= FrameFlags_WasHotReplaced;
}; };
auto _FixFilePath = [&](DbgModule* dbgModule)
{
if (outFile == NULL)
return;
if (outFile->StartsWith("$Emit"))
{
int dollarPos = outFile->IndexOf('$', 1);
if (dollarPos == -1)
return;
outFile->Insert(dollarPos, StrFormat("%d", dbgModule->mId));
}
};
if (wdStackFrame->mInInlineMethod) if (wdStackFrame->mInInlineMethod)
{ {
WdStackFrame* nextStackFrame = mCallStack[actualStackFrameIdx - 1]; WdStackFrame* nextStackFrame = mCallStack[actualStackFrameIdx - 1];
@ -11122,6 +11155,7 @@ String WinDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* o
*outLanguage = callingSubProgram->mCompileUnit->mLanguage; *outLanguage = callingSubProgram->mCompileUnit->mLanguage;
auto srcFile = callingSrcFile; auto srcFile = callingSrcFile;
*outFile = srcFile->GetLocalPath(); *outFile = srcFile->GetLocalPath();
_CheckHashSrcFile(*outFile, subProgram->mCompileUnit->mDbgModule, srcFile); _CheckHashSrcFile(*outFile, subProgram->mCompileUnit->mDbgModule, srcFile);
if (*outLine == callingLineData->mLine) if (*outLine == callingLineData->mLine)
*outColumn = callingLineData->mColumn; *outColumn = callingLineData->mColumn;
@ -11131,7 +11165,8 @@ String WinDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* o
DbgModule* dbgModule = wdStackFrame->mSubProgram->mCompileUnit->mDbgModule; DbgModule* dbgModule = wdStackFrame->mSubProgram->mCompileUnit->mDbgModule;
DbgModule* linkedModule = dbgModule->GetLinkedModule(); DbgModule* linkedModule = dbgModule->GetLinkedModule();
if (!linkedModule->mDisplayName.empty()) if (!linkedModule->mDisplayName.empty())
name = linkedModule->mDisplayName + "!" + name; name = linkedModule->mDisplayName + "!" + name;
_FixFilePath(dbgModule);
return name; return name;
} }
@ -11211,10 +11246,12 @@ String WinDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* o
*outDefLineEnd = dwEndLineData->mLine; *outDefLineEnd = dwEndLineData->mLine;
} }
_FixFilePath(dbgModule);
return demangledName; return demangledName;
} }
else else
{ {
_FixFilePath(dbgModule);
return demangledName + StrFormat("+0x%X", pcAddress - dwSubprogram->mBlock.mLowPC); return demangledName + StrFormat("+0x%X", pcAddress - dwSubprogram->mBlock.mLowPC);
} }
} }
@ -11222,7 +11259,7 @@ String WinDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* o
{ {
String symbolName; String symbolName;
addr_target offset; addr_target offset;
DbgModule* dbgModule; DbgModule* dbgModule = NULL;
if (mDebugTarget->FindSymbolAt(pcAddress, &symbolName, &offset, &dbgModule)) if (mDebugTarget->FindSymbolAt(pcAddress, &symbolName, &offset, &dbgModule))
{ {
if (dbgModule->HasPendingDebugInfo()) if (dbgModule->HasPendingDebugInfo())
@ -11242,6 +11279,7 @@ String WinDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* o
String demangledName = BfDemangler::Demangle(symbolName, DbgLanguage_Unknown); String demangledName = BfDemangler::Demangle(symbolName, DbgLanguage_Unknown);
if (!linkedModule->mDisplayName.empty()) if (!linkedModule->mDisplayName.empty())
demangledName = linkedModule->mDisplayName + "!" + demangledName; demangledName = linkedModule->mDisplayName + "!" + demangledName;
_FixFilePath(dbgModule);
return demangledName + StrFormat("+0x%X", offset); return demangledName + StrFormat("+0x%X", offset);
} }
} }
@ -11257,6 +11295,7 @@ String WinDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* o
String outName = EncodeDataPtr(pcAddress, true); String outName = EncodeDataPtr(pcAddress, true);
if ((linkedModule != NULL) && (!linkedModule->mDisplayName.empty())) if ((linkedModule != NULL) && (!linkedModule->mDisplayName.empty()))
outName = linkedModule->mDisplayName + "!" + outName; outName = linkedModule->mDisplayName + "!" + outName;
_FixFilePath(dbgModule);
return outName; return outName;
} }

View file

@ -657,10 +657,11 @@ public:
void AddProfiler(DbgProfiler* profiler); void AddProfiler(DbgProfiler* profiler);
void RemoveProfiler(DbgProfiler* profiler); void RemoveProfiler(DbgProfiler* profiler);
virtual void ReportMemory(MemReporter* memReporter) override; virtual void ReportMemory(MemReporter* memReporter) override;
virtual bool IsOnDemandDebugger() override { return false; } virtual bool IsOnDemandDebugger() override { return false; }
virtual bool IsMiniDumpDebugger() { return false; } virtual bool IsMiniDumpDebugger() { return false; }
virtual bool GetEmitSource(const StringImpl& filePath, String& outText);
}; };
template<typename T> bool WinDebugger::WriteMemory(intptr addr, T val) template<typename T> bool WinDebugger::WriteMemory(intptr addr, T val)