1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 03:28:20 +02:00

Handle zero-sized enums (<= 1 member)

This commit is contained in:
Brian Fiete 2024-11-08 09:16:27 -05:00
parent 7b69509b7b
commit 14a3dd8e7d
21 changed files with 461 additions and 135 deletions

View file

@ -196,7 +196,6 @@ namespace IDE.ui
{
public AutoComplete mAutoComplete;
public bool mIsInitted;
public int mIgnoreMove;
public bool mOwnsWindow;
public float mRightBoxAdjust;
public float mWantHeight;
@ -237,7 +236,7 @@ namespace IDE.ui
return;
}
if ((mIgnoreMove == 0) && (mWidgetWindow != null) && (!mWidgetWindow.mHasClosed))
if ((mAutoComplete.mIgnoreMove == 0) && (mWidgetWindow != null) && (!mWidgetWindow.mHasClosed))
mAutoComplete.Close();
}
@ -345,7 +344,6 @@ namespace IDE.ui
public override void Update()
{
base.Update();
Debug.Assert((mIgnoreMove >= 0) && (mIgnoreMove <= 4));
}
}
@ -591,15 +589,11 @@ namespace IDE.ui
int windowHeight = (int)(mWantHeight + Math.Max(0, mDocHeight - GS!(32)));
mIgnoreMove++;
if (mAutoComplete.mInvokeWidget != null)
mAutoComplete.mInvokeWidget.mIgnoreMove++;
mAutoComplete.mIgnoreMove++;
mWidgetWindow.Resize(mWidgetWindow.mNormX, mWidgetWindow.mNormY, windowWidth, windowHeight);
mScrollContent.mWidth = mWidth;
//Resize(0, 0, mWidgetWindow.mClientWidth, mWidgetWindow.mClientHeight);
mIgnoreMove--;
if (mAutoComplete.mInvokeWidget != null)
mAutoComplete.mInvokeWidget.mIgnoreMove--;
mAutoComplete.mIgnoreMove--;
ResizeContent(-1, -1, mVertScrollbar != null);
}
}
@ -653,7 +647,7 @@ namespace IDE.ui
entryWidget.mDocumentation = new:mAlloc String(documentation);
entryWidget.mIcon = icon;
entryWidget.SetMatches(matchIndices);
entryWidget.SetMatches(matchIndices ?? scope .());
UpdateEntry(entryWidget, mEntryList.Count);
mEntryList.Add(entryWidget);
@ -860,6 +854,7 @@ namespace IDE.ui
{
public String mText ~ delete _;
public String mDocumentation ~ delete _;
public int32 mArgMatchCount;
public int GetParamCount()
{
@ -941,9 +936,9 @@ namespace IDE.ui
{
if (mOwnsWindow)
{
mIgnoreMove++;
mAutoComplete.mIgnoreMove++;
mAutoComplete.UpdateWindow(ref mWidgetWindow, this, mAutoComplete.mInvokeSrcPositions[0], (int32)extWidth, (int32)extHeight);
mIgnoreMove--;
mAutoComplete.mIgnoreMove--;
}
else
{
@ -966,11 +961,15 @@ namespace IDE.ui
mSelectIdx = 0;
}
public void SelectDirection(int32 dir)
public bool SelectDirection(int32 dir)
{
int32 newSelection = mSelectIdx + dir;
if ((newSelection >= 0) && (newSelection < mEntryList.Count))
{
Select(newSelection);
return true;
}
return false;
}
public override void Update()
@ -979,36 +978,15 @@ namespace IDE.ui
}
void DrawInfo(Graphics g, out float extWidth, out float extHeight)
public void GetState(out int cursorSection)
{
var font = IDEApp.sApp.mCodeFont;
extWidth = 0;
float curX = GS!(8);
float curY = GS!(5);
if (mEntryList.Count > 1)
{
String numStr = scope String();
numStr.AppendF("{0}/{1}", mSelectIdx + 1, mEntryList.Count);
if (g != null)
{
using (g.PushColor(gApp.mSettings.mUISettings.mColors.mAutoCompleteSubText))
g.DrawString(numStr, curX, curY);
}
curX += font.GetWidth(numStr) + GS!(8);
}
cursorSection = -1;
var selectedEntry = mEntryList[mSelectIdx];
float maxWidth = mWidth;
StringView paramName = .();
List<StringView> textSections = scope List<StringView>(selectedEntry.mText.Split('\x01'));
int cursorPos = mAutoComplete.mTargetEditWidget.Content.CursorTextPos;
int cursorSection = -1;
for (int sectionIdx = 0; sectionIdx < mAutoComplete.mInvokeSrcPositions.Count - 1; sectionIdx++)
{
if (cursorPos > mAutoComplete.mInvokeSrcPositions[sectionIdx])
@ -1085,6 +1063,37 @@ namespace IDE.ui
}
}
}
}
void DrawInfo(Graphics g, out float extWidth, out float extHeight)
{
var font = IDEApp.sApp.mCodeFont;
extWidth = 0;
float curX = GS!(8);
float curY = GS!(5);
if (mEntryList.Count > 1)
{
String numStr = scope String();
numStr.AppendF("{0}/{1}", mSelectIdx + 1, mEntryList.Count);
if (g != null)
{
using (g.PushColor(gApp.mSettings.mUISettings.mColors.mAutoCompleteSubText))
g.DrawString(numStr, curX, curY);
}
curX += font.GetWidth(numStr) + GS!(8);
}
var selectedEntry = mEntryList[mSelectIdx];
float maxWidth = mWidth;
StringView paramName = .();
List<StringView> textSections = scope List<StringView>(selectedEntry.mText.Split('\x01'));
GetState(var cursorSection);
float paramX = 0;
for (int sectionIdx = 0; sectionIdx < textSections.Count; sectionIdx++)
@ -1259,6 +1268,7 @@ namespace IDE.ui
public bool mIsDocumentationPass;
public bool mIsUserRequested;
public int mIgnoreMove;
bool mClosed;
bool mPopulating;
float mWantX;
@ -1412,6 +1422,8 @@ namespace IDE.ui
public void Update()
{
Debug.Assert((mIgnoreMove >= 0) && (mIgnoreMove <= 4));
if ((mInvokeWindow != null) && (!mInvokeWidget.mIsAboveText))
{
int textIdx = mTargetEditWidget.Content.CursorTextPos;
@ -1440,18 +1452,13 @@ namespace IDE.ui
int insertLine = line;
if ((insertLine != invokeLine) && ((insertLine - invokeLine) * gApp.mCodeFont.GetHeight() < GS!(40)))
{
mInvokeWidget.mIgnoreMove++;
if (mListWindow != null)
mAutoCompleteListWidget.mIgnoreMove++;
mIgnoreMove++;
mInvokeWidget.mIsAboveText = true;
mInvokeWidget.ResizeContent(false);
UpdateWindow(ref mInvokeWindow, mInvokeWidget, mInvokeSrcPositions[0], (int32)mInvokeWidget.mWidth, (int32)mInvokeWidget.mHeight);
if (mListWindow != null)
{
UpdateWindow(ref mListWindow, mAutoCompleteListWidget, mInsertStartIdx, mListWindow.mWindowWidth, mListWindow.mWindowHeight);
mAutoCompleteListWidget.mIgnoreMove--;
}
mInvokeWidget.mIgnoreMove--;
mIgnoreMove--;
}
}
@ -1470,6 +1477,67 @@ namespace IDE.ui
Close();
}
}
/*if (mInvokeWidget != null)
{
var invokeEntry = mInvokeWidget.mEntryList[mInvokeWidget.mSelectIdx];
mInvokeWidget.GetState(var cursorSection);
if (mAutoCompleteListWidget != null)
{
}
else
{
if (cursorSection > 0)
{
int sectionStartIdx = -1;
int sectionEndIdx = -1;
int foundSectionIdx = 0;
for (var c in invokeEntry.mText.RawChars)
{
if (c == '\x01')
{
foundSectionIdx++;
if (foundSectionIdx == cursorSection)
sectionStartIdx = @c.Index;
else if (foundSectionIdx == cursorSection + 1)
sectionEndIdx = @c.Index;
}
}
if (sectionEndIdx != -1)
{
StringView argText = invokeEntry.mText.Substring(sectionStartIdx + 1, sectionEndIdx - sectionStartIdx - 1);
argText.Trim();
while (!argText.IsEmpty)
{
char8 c = argText[argText.Length - 1];
if ((c.IsLetterOrDigit) || (c == '_'))
break;
argText.RemoveFromEnd(1);
}
if (argText.StartsWith("tag "))
{
int spacePos = argText.IndexOf(' ', 4);
if (spacePos == -1)
spacePos = argText.Length;
StringView tagName = argText.Substring(4, spacePos - 4);
mInsertStartIdx = mInvokeSrcPositions[cursorSection - 1];
mInsertEndIdx = mInsertStartIdx;
mAutoCompleteListWidget = new AutoCompleteListWidget(this);
mAutoCompleteListWidget.AddEntry("value", scope $".{tagName}", DarkTheme.sDarkTheme.GetImage(.IconValue));
HandleAutoCompleteListWidget(1);
mAutoCompleteListWidget.mSelectIdx = 0;
}
}
}
}
}*/
}
public void GetFilter(String outFilter)
@ -1718,10 +1786,7 @@ namespace IDE.ui
public void SetIgnoreMove(bool ignoreMove)
{
if (mAutoCompleteListWidget != null)
mAutoCompleteListWidget.mIgnoreMove += ignoreMove ? 1 : -1;
if (mInvokeWidget != null)
mInvokeWidget.mIgnoreMove += ignoreMove ? 1 : -1;
mIgnoreMove += ignoreMove ? 1 : -1;
}
// IDEHelper/third_party/FtsFuzzyMatch.h
@ -1996,61 +2061,7 @@ namespace IDE.ui
if (mAutoCompleteListWidget != null)
{
if (mAutoCompleteListWidget.mEntryList.Count > 0)
{
mAutoCompleteListWidget.mOwnsWindow = !IsInPanel();
mAutoCompleteListWidget.mAutoFocus = IsInPanel();
int32 windowWidth = (int32)mAutoCompleteListWidget.mMaxWidth;
if (mAutoCompleteListWidget.mRightBoxAdjust != 0)
windowWidth += (int32)mAutoCompleteListWidget.mRightBoxAdjust; // - GS!(16);
//windowWidth += (int32)mAutoCompleteListWidget.mDocWidth;
windowWidth += GS!(16);
int32 contentHeight = (int32)(visibleCount * mAutoCompleteListWidget.mItemSpacing);
int32 windowHeight = contentHeight + GS!(20);
int32 maxWindowHeight = GetMaxWindowHeight();
bool wantScrollbar = false;
if (windowHeight > maxWindowHeight)
{
windowHeight = maxWindowHeight;
wantScrollbar = true;
windowWidth += GS!(12);
}
contentHeight += GS!(8);
mAutoCompleteListWidget.ResizeContent(windowWidth, contentHeight, wantScrollbar);
if ((mInsertStartIdx != -1) && (!IsInPanel()))
{
UpdateWindow(ref mListWindow, mAutoCompleteListWidget, mInsertStartIdx, windowWidth, windowHeight);
mAutoCompleteListWidget.mWantHeight = windowHeight;
}
mAutoCompleteListWidget.UpdateScrollbars();
mAutoCompleteListWidget.CenterSelection();
mAutoCompleteListWidget.UpdateWidth();
}
else
{
if ((mListWindow == null) || (mListWindow.mRootWidget != mAutoCompleteListWidget))
{
if (IsInPanel())
{
gApp.mAutoCompletePanel.Unbind(this);
if (mInvokeWidget != null)
{
if (mInvokeWidget.mParent != null)
mInvokeWidget.RemoveSelf();
delete mInvokeWidget;
mInvokeWidget = null;
}
}
delete mAutoCompleteListWidget;
}
if (mListWindow != null)
{
mListWindow.Close();
mListWindow = null;
}
mAutoCompleteListWidget = null;
}
HandleAutoCompleteListWidget(visibleCount);
}
gApp.mAutoCompletePanel.FinishBind();
SetIgnoreMove(false);
@ -2174,6 +2185,65 @@ namespace IDE.ui
//Debug.WriteLine("UpdateInfo {0} {1}", mInsertStartIdx, mInsertEndIdx);
}
public void HandleAutoCompleteListWidget(int visibleCount)
{
if (mAutoCompleteListWidget.mEntryList.Count > 0)
{
mAutoCompleteListWidget.mOwnsWindow = !IsInPanel();
mAutoCompleteListWidget.mAutoFocus = IsInPanel();
int32 windowWidth = (int32)mAutoCompleteListWidget.mMaxWidth;
if (mAutoCompleteListWidget.mRightBoxAdjust != 0)
windowWidth += (int32)mAutoCompleteListWidget.mRightBoxAdjust; // - GS!(16);
//windowWidth += (int32)mAutoCompleteListWidget.mDocWidth;
windowWidth += GS!(16);
int32 contentHeight = (int32)(visibleCount * mAutoCompleteListWidget.mItemSpacing);
int32 windowHeight = contentHeight + GS!(20);
int32 maxWindowHeight = GetMaxWindowHeight();
bool wantScrollbar = false;
if (windowHeight > maxWindowHeight)
{
windowHeight = maxWindowHeight;
wantScrollbar = true;
windowWidth += GS!(12);
}
contentHeight += GS!(8);
mAutoCompleteListWidget.ResizeContent(windowWidth, contentHeight, wantScrollbar);
if ((mInsertStartIdx != -1) && (!IsInPanel()))
{
UpdateWindow(ref mListWindow, mAutoCompleteListWidget, mInsertStartIdx, windowWidth, windowHeight);
mAutoCompleteListWidget.mWantHeight = windowHeight;
}
mAutoCompleteListWidget.UpdateScrollbars();
mAutoCompleteListWidget.CenterSelection();
mAutoCompleteListWidget.UpdateWidth();
}
else
{
if ((mListWindow == null) || (mListWindow.mRootWidget != mAutoCompleteListWidget))
{
if (IsInPanel())
{
gApp.mAutoCompletePanel.Unbind(this);
if (mInvokeWidget != null)
{
if (mInvokeWidget.mParent != null)
mInvokeWidget.RemoveSelf();
delete mInvokeWidget;
mInvokeWidget = null;
}
}
delete mAutoCompleteListWidget;
}
if (mListWindow != null)
{
mListWindow.Close();
mListWindow = null;
}
mAutoCompleteListWidget = null;
}
}
public void SetInfo(String info, bool clearList = true, int32 textOffset = 0, bool changedAfterInfo = false)
{
scope AutoBeefPerf("AutoComplete.SetInfo");
@ -2196,7 +2266,7 @@ namespace IDE.ui
{
if (mAutoCompleteListWidget != null)
{
mAutoCompleteListWidget.mIgnoreMove++;
mIgnoreMove++;
if (IsInPanel())
{
mAutoCompleteListWidget.RemoveSelf();
@ -2210,6 +2280,7 @@ namespace IDE.ui
else
delete mAutoCompleteListWidget;
mAutoCompleteListWidget = null;
mIgnoreMove--;
}
}
if (mAutoCompleteListWidget == null)
@ -2434,6 +2505,7 @@ namespace IDE.ui
var invokeEntry = new InvokeWidget.Entry();
invokeEntry.mText = new String(entryDisplay);
invokeEntry.mArgMatchCount = int32.Parse(entryInsert).GetValueOrDefault();
if (!documentation.IsEmpty)
invokeEntry.mDocumentation = new String(documentation);
mInvokeWidget.AddEntry(invokeEntry);
@ -2846,6 +2918,14 @@ namespace IDE.ui
}
}
public void GetInsertText(String outStr)
{
if (mAutoCompleteListWidget != null)
{
var entry = mAutoCompleteListWidget.mEntryList[mAutoCompleteListWidget.mSelectIdx];
outStr.Append(entry.mEntryInsert ?? entry.mEntryDisplay);
}
}
public void InsertSelection(char32 keyChar, String insertType = null, String insertStr = null)
{

View file

@ -301,6 +301,11 @@ void BfStructuralVisitor::Visit(BfTupleTypeRef* typeRef)
Visit(typeRef->ToBase());
}
void BfStructuralVisitor::Visit(BfTagTypeRef* typeRef)
{
Visit(typeRef->ToBase());
}
void BfStructuralVisitor::Visit(BfDelegateTypeRef* typeRef)
{
Visit(typeRef->ToBase());

View file

@ -389,6 +389,7 @@ class BfVarRefTypeReference;
class BfLetTypeReference;
class BfGenericInstanceTypeRef;
class BfTupleTypeRef;
class BfTagTypeRef;
class BfDelegateTypeRef;
class BfExprModTypeRef;
class BfCommentNode;
@ -561,6 +562,7 @@ public:
virtual void Visit(BfArrayTypeRef* typeRef);
virtual void Visit(BfGenericInstanceTypeRef* typeRef);
virtual void Visit(BfTupleTypeRef* typeRef);
virtual void Visit(BfTagTypeRef* typeRef);
virtual void Visit(BfDelegateTypeRef* typeRef);
virtual void Visit(BfExprModTypeRef* declTypeRef);
virtual void Visit(BfPointerTypeRef* typeRef);
@ -2667,6 +2669,15 @@ public:
}
}; BF_AST_DECL(BfTupleTypeRef, BfElementedTypeRef);
class BfTagTypeRef : public BfTypeReference
{
public:
BF_AST_TYPE(BfTagTypeRef, BfTypeReference);
BfIdentifierNode* mTagNode;
BfIdentifierNode* mNameNode;
}; BF_AST_DECL(BfTagTypeRef, BfTypeReference);
class BfDelegateTypeRef : public BfTypeReference
{
public:

View file

@ -797,12 +797,21 @@ void BfAutoComplete::AddField(BfTypeInstance* typeInst, BfFieldDef* fieldDef, Bf
{
mModule->PopulateType(typeInst);
String str;
str += mModule->TypeToString(fieldInstance->mResolvedType);
str += " ";
str += mModule->TypeToString(typeInst);
str += ".";
str += fieldDef->mName;
bool isTag = typeInst->IsEnum() && typeInst->IsOnDemand();
String str;
if (!isTag)
{
if (!fieldInstance->GetFieldDef()->IsEnumCaseEntry())
{
str += mModule->TypeToString(fieldInstance->mResolvedType);
str += " ";
}
str += mModule->TypeToString(typeInst);
str += ".";
str += fieldDef->mName;
}
if (entryAdded->mDocumentation != NULL)
{
str += "\x04";
@ -813,7 +822,9 @@ void BfAutoComplete::AddField(BfTypeInstance* typeInst, BfFieldDef* fieldDef, Bf
str += "\x05";
documentation->GetDocString(str);
}
entryAdded->mDocumentation = mAlloc.AllocString(str);
if (!str.IsEmpty())
entryAdded->mDocumentation = mAlloc.AllocString(str);
}
if ((mIsGetDefinition) && (mDefType == NULL))
@ -1270,7 +1281,11 @@ void BfAutoComplete::AddEnumTypeMembers(BfTypeInstance* typeInst, const StringIm
AutoCompleteEntry entry(hasPayload ? "payloadEnum" : "value", fieldDef->mName);
if (auto entryAdded = AddEntry(entry, filter))
{
if (CheckDocumentation(entryAdded, fieldDef->GetFieldDeclaration()->mDocumentation))
auto fieldDecl = fieldDef->GetFieldDeclaration();
if (fieldDecl == NULL)
continue;
if (CheckDocumentation(entryAdded, fieldDecl->mDocumentation))
{
}
@ -1278,8 +1293,8 @@ void BfAutoComplete::AddEnumTypeMembers(BfTypeInstance* typeInst, const StringIm
{
mDefType = typeInst->mTypeDef;
mDefField = fieldDef;
if (fieldDef->mFieldDeclaration != NULL)
SetDefinitionLocation(fieldDef->GetFieldDeclaration()->mNameNode);
if (fieldDecl != NULL)
SetDefinitionLocation(fieldDecl->mNameNode);
}
}
}

View file

@ -137,6 +137,8 @@ public:
BfTypeInstance* mTypeInstance;
BfTypeVector mGenericArguments;
BfMethodInstance* mCurMethodInstance;
bool mIsMatch;
int mArgMatchCount;
MethodMatchEntry()
{
@ -144,6 +146,8 @@ public:
mPayloadEnumField = NULL;
mTypeInstance = NULL;
mCurMethodInstance = NULL;
mIsMatch = false;
mArgMatchCount = false;
}
};

View file

@ -8608,7 +8608,9 @@ void BfCompiler::GenerateAutocompleteInfo()
}
}
autoCompleteResultString += "invoke\t" + methodText + "\n";
autoCompleteResultString += "invoke\t" + methodText;
autoCompleteResultString += StrFormat("\t%d", methodEntry.mArgMatchCount);
autoCompleteResultString += "\n";
idx++;
}

View file

@ -447,6 +447,14 @@ void BfElementVisitor::Visit(BfTupleTypeRef* typeRef)
VisitChild(typeRef->mCloseParen);
}
void BfElementVisitor::Visit(BfTagTypeRef* typeRef)
{
Visit(typeRef->ToBase());
VisitChild(typeRef->mTagNode);
VisitChild(typeRef->mNameNode);
}
void BfElementVisitor::Visit(BfExprModTypeRef* typeRef)
{
Visit(typeRef->ToBase());

View file

@ -64,6 +64,7 @@ public:
virtual void Visit(BfArrayTypeRef* typeRef);
virtual void Visit(BfGenericInstanceTypeRef* typeRef);
virtual void Visit(BfTupleTypeRef* typeRef);
virtual void Visit(BfTagTypeRef* typeRef);
virtual void Visit(BfExprModTypeRef* typeRef);
virtual void Visit(BfDelegateTypeRef* typeRef);
virtual void Visit(BfPointerTypeRef* typeRef);

View file

@ -1680,7 +1680,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
BP_ZONE("BfMethodMatcher::CheckMethod");
BackupMatchKind curMatchKind = BackupMatchKind_None;
bool hadMatch = false;
bool hadMatch = false;
// Never consider overrides - they only get found at original method declaration
// mBypassVirtual gets set when we are doing an explicit "base" call, or when we are a struct --
@ -2599,12 +2599,16 @@ NoMatch:
}
Done:
if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo) && (genericArgumentsSubstitute != NULL))
if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
{
auto methodMatchInfo = autoComplete->mMethodMatchInfo;
if (!methodMatchInfo->mInstanceList.IsEmpty())
{
methodMatchInfo->mInstanceList[methodMatchInfo->mInstanceList.size() - 1].mGenericArguments = *genericArgumentsSubstitute;
{
auto& matchInstance = methodMatchInfo->mInstanceList[methodMatchInfo->mInstanceList.size() - 1];
matchInstance.mArgMatchCount = argMatchCount;
matchInstance.mIsMatch = hadMatch;
if (genericArgumentsSubstitute != NULL)
matchInstance.mGenericArguments = *genericArgumentsSubstitute;
}
}
@ -5249,6 +5253,8 @@ BfTypedValue BfExprEvaluator::LoadField(BfAstNode* targetSrc, BfTypedValue targe
BF_ASSERT(fieldInstance->mConstIdx != -1);
auto foreignConst = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
if (resolvedFieldType->IsValuelessType())
return BfTypedValue(BfIRValue::sValueless, resolvedFieldType);
auto retVal = mModule->ConstantToCurrent(foreignConst, typeInstance->mConstHolder, resolvedFieldType);
return BfTypedValue(retVal, resolvedFieldType);
}

View file

@ -928,6 +928,10 @@ BfIRValue BfIRConstHolder::CreateConst(BfConstant* fromConst, BfIRConstHolder* f
{
return CreateConstArrayZero(fromConst->mInt32);
}
else if (fromConst->mTypeCode == BfTypeCode_None)
{
return CreateConst(fromConst->mTypeCode, 0);
}
else if ((IsInt(fromConst->mTypeCode)) || (fromConst->mTypeCode == BfTypeCode_Boolean) || (fromConst->mTypeCode == BfTypeCode_StringId))
{
return CreateConst(fromConst->mTypeCode, fromConst->mUInt64);
@ -975,7 +979,7 @@ BfIRValue BfIRConstHolder::CreateConst(BfConstant* fromConst, BfIRConstHolder* f
box->mTarget = copiedTarget.mId;
box->mToType = fromBox->mToType;
copiedConst = (BfConstant*)box;
}
}
else
{
BF_FATAL("not handled");
@ -3283,7 +3287,8 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
if (fieldInstance->mConstIdx != -1)
{
constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
staticValue = mModule->ConstantToCurrent(constant, typeInstance->mConstHolder, resolvedFieldType);
if (!resolvedFieldType->IsValuelessType())
staticValue = mModule->ConstantToCurrent(constant, typeInstance->mConstHolder, resolvedFieldType);
}
if (fieldInstance->mResolvedType->IsComposite())

View file

@ -21841,10 +21841,10 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup,
mBfIRBuilder->SaveDebugLocation();
mBfIRBuilder->ClearDebugLocation();
BfIRValue fromBool;
if (!mCurTypeInstance->IsTypedPrimitive())
if ((!mCurTypeInstance->IsTypedPrimitive()) || (mCurTypeInstance->IsValuelessType()))
{
fromBool = GetDefaultValue(methodInstance->mReturnType);
}
}
else
{
auto andResult = mBfIRBuilder->CreateAnd(mCurMethodState->mLocals[0]->mValue, mCurMethodState->mLocals[1]->mValue);
@ -21872,7 +21872,10 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup,
mBfIRBuilder->ClearDebugLocation();
BfIRValue fromBool;
mBfIRBuilder->RestoreDebugLocation();
ret = mBfIRBuilder->CreateRet(GetThis().mValue);
if (!mCurTypeInstance->IsValuelessType())
ret = mBfIRBuilder->CreateRet(GetThis().mValue);
else
mBfIRBuilder->CreateRetVoid();
//ExtendLocalLifetimes(0);
EmitLifetimeEnds(&mCurMethodState->mHeadScope);

View file

@ -3600,7 +3600,9 @@ void BfModule::DoPopulateType_FinishEnum(BfTypeInstance* typeInstance, bool unde
{
BfTypeCode typeCode;
if ((min >= -0x80) && (max <= 0x7F))
if ((min == 0) && (max == 0))
typeCode = BfTypeCode_None;
else if ((min >= -0x80) && (max <= 0x7F))
typeCode = BfTypeCode_Int8;
else if ((min >= 0) && (max <= 0xFF))
typeCode = BfTypeCode_UInt8;
@ -12232,6 +12234,19 @@ BfType* BfModule::ResolveTypeRef_Ref(BfTypeReference* typeRef, BfPopulateType po
return ResolveTypeResult(typeRef, tupleType, populateType, resolveFlags);
}
else if (auto tagTypeRef = BfNodeDynCast<BfTagTypeRef>(typeRef))
{
auto baseType = (BfTypeInstance*)ResolveTypeDef(mContext->mCompiler->mEnumTypeDef, BfPopulateType_Identity);
BfTagType* tagType = new BfTagType();
tagType->Init(baseType->mTypeDef->mProject, baseType, tagTypeRef->mNameNode->ToString());
resolvedEntry->mValue = tagType;
BF_ASSERT(BfResolvedTypeSet::Hash(tagType, &lookupCtx) == resolvedEntry->mHashCode);
populateModule->InitType(tagType, populateType);
return ResolveTypeResult(typeRef, tagType, populateType, resolveFlags);
}
else if (auto nullableTypeRef = BfNodeDynCast<BfNullableTypeRef>(typeRef))
{
BfTypeReference* elementTypeRef = nullableTypeRef->mElementType;
@ -15781,6 +15796,13 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF
str += ")";
return;
}
else if ((resolvedType->IsOnDemand()) && (resolvedType->IsEnum()))
{
auto typeInst = resolvedType->ToTypeInstance();
str += "tag ";
str += typeInst->mTypeDef->mFields[0]->mName;
return;
}
else if (resolvedType->IsDelegateFromTypeRef() || resolvedType->IsFunctionFromTypeRef())
{
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance);

View file

@ -1674,6 +1674,15 @@ void BfPrinter::Visit(BfTupleTypeRef* typeRef)
VisitChild(typeRef->mCloseParen);
}
void BfPrinter::Visit(BfTagTypeRef* typeRef)
{
Visit((BfAstNode*)typeRef);
VisitChild(typeRef->mTagNode);
ExpectSpace();
VisitChild(typeRef->mNameNode);
}
void BfPrinter::Visit(BfDelegateTypeRef* typeRef)
{
Visit((BfAstNode*)typeRef);

View file

@ -167,6 +167,7 @@ public:
virtual void Visit(BfArrayTypeRef* typeRef) override;
virtual void Visit(BfGenericInstanceTypeRef* typeRef) override;
virtual void Visit(BfTupleTypeRef * typeRef) override;
virtual void Visit(BfTagTypeRef* typeRef) override;
virtual void Visit(BfDelegateTypeRef* typeRef) override;
virtual void Visit(BfPointerTypeRef* typeRef) override;
virtual void Visit(BfNullableTypeRef* typeRef) override;

View file

@ -937,7 +937,7 @@ bool BfReducer::IsTypeReference(BfAstNode* checkNode, BfToken successToken, int
// Ignore
}
else if ((checkNode->IsA<BfIdentifierNode>()) || (checkNode->IsA<BfMemberReferenceExpression>()))
{
{
// Identifier is always allowed in tuple (parenDepth == 0), because it's potentially the field name
// (successToken == BfToken_RParen) infers we are already checking inside parentheses, such as
// when we see a potential cast expression
@ -954,8 +954,15 @@ bool BfReducer::IsTypeReference(BfAstNode* checkNode, BfToken successToken, int
hadUnexpectedIdentifier = true;
}
hadIdentifier = true;
identifierExpected = false;
// if (checkNode->Equals("tag"))
// {
// // Keep looking for tag name
// }
// else
{
hadIdentifier = true;
identifierExpected = false;
}
}
else if (checkNode->IsA<BfBlock>())
{
@ -5195,6 +5202,19 @@ BfTypeReference* BfReducer::DoCreateTypeRef(BfAstNode* firstNode, CreateTypeRefF
BfTypeReference* typeRef = BfNodeDynCast<BfTypeReference>(firstNode);
if (typeRef == NULL)
{
// if (identifierNode->Equals("tag"))
// {
// auto rightIdentifer = ExpectIdentifierAfter(identifierNode);
// if (rightIdentifer != NULL)
// {
// auto tagTypeRef = mAlloc->Alloc<BfTagTypeRef>();
// ReplaceNode(identifierNode, tagTypeRef);
// tagTypeRef->mTagNode = identifierNode;
// MEMBER_SET(tagTypeRef, mNameNode, rightIdentifer);
// return tagTypeRef;
// }
// }
typeRef = DoCreateNamedTypeRef(identifierNode);
}
@ -5250,7 +5270,7 @@ BfTypeReference* BfReducer::DoCreateTypeRef(BfAstNode* firstNode, CreateTypeRefF
{
auto rightIdentifer = ExpectIdentifierAfter(qualifiedTypeRef);
if (rightIdentifer == NULL)
return qualifiedTypeRef;
return qualifiedTypeRef;
auto namedTypeRef = mAlloc->Alloc<BfNamedTypeReference>();
namedTypeRef->mNameNode = rightIdentifer;
@ -7346,7 +7366,7 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, bool declStarted, int dept
if (openToken == NULL)
return indexerDeclaration;
MEMBER_SET(indexerDeclaration, mOpenBracket, openToken);
auto endToken = ParseMethodParams(indexerDeclaration, &params, &commas, BfToken_RBracket, true);
auto endToken = ParseMethodParams(indexerDeclaration, &params, &commas, BfToken_RBracket, false);
if (endToken == NULL)
return indexerDeclaration;
MEMBER_SET(indexerDeclaration, mCloseBracket, endToken);
@ -7780,7 +7800,7 @@ BfLambdaBindExpression* BfReducer::CreateLambdaBindExpression(BfAstNode* allocNo
if (auto tokenNode = BfNodeDynCast<BfTokenNode>(nextNode))
isRParen = tokenNode->GetToken() == BfToken_RParen;
if (!isRParen)
{
{
auto nameIdentifier = ExpectIdentifierAfter(lambdaBindExpr, "parameter name");
if (nameIdentifier == NULL)
return lambdaBindExpr;
@ -10028,7 +10048,7 @@ bool BfReducer::ParseMethod(BfMethodDeclaration* methodDeclaration, SizedArrayIm
}
}
methodDeclaration->mCloseParen = ParseMethodParams(methodDeclaration, params, commas, BfToken_RParen, true);
methodDeclaration->mCloseParen = ParseMethodParams(methodDeclaration, params, commas, BfToken_RParen, false);
// RParen
if (methodDeclaration->mCloseParen == NULL)

View file

@ -2987,6 +2987,79 @@ void BfTupleType::Finish()
//////////////////////////////////////////////////////////////////////////
BfTagType::BfTagType()
{
mCreatedTypeDef = false;
mSource = NULL;
mTypeDef = NULL;
}
BfTagType::~BfTagType()
{
mMethodInstanceGroups.Clear();
if (mCreatedTypeDef)
{
delete mTypeDef;
mTypeDef = NULL;
}
delete mSource;
}
void BfTagType::Init(BfProject* bfProject, BfTypeInstance* valueTypeInstance, const StringImpl& name)
{
auto srcTypeDef = valueTypeInstance->mTypeDef;
auto system = valueTypeInstance->mModule->mSystem;
if (mTypeDef == NULL)
mTypeDef = new BfTypeDef();
for (auto field : mTypeDef->mFields)
delete field;
mTypeDef->mFields.Clear();
mTypeDef->mSystem = system;
mTypeDef->mProject = bfProject;
mTypeDef->mTypeCode = srcTypeDef->mTypeCode;
mTypeDef->mName = system->mEmptyAtom;
mTypeDef->mSystem = system;
mTypeDef->mHash = srcTypeDef->mHash;
mTypeDef->mSignatureHash = srcTypeDef->mSignatureHash;
mTypeDef->mTypeCode = BfTypeCode_Enum;
mCreatedTypeDef = true;
auto field = BfDefBuilder::AddField(mTypeDef, NULL, name);
field->mIsStatic = true;
field->mIsConst = true;
}
void BfTagType::Dispose()
{
if (mCreatedTypeDef)
{
delete mTypeDef;
mTypeDef = NULL;
mCreatedTypeDef = false;
}
BfTypeInstance::Dispose();
}
void BfTagType::Finish()
{
BF_ASSERT(!mTypeFailed);
auto bfSystem = mTypeDef->mSystem;
mSource = new BfSource(bfSystem);
mTypeDef->mSource = mSource;
mTypeDef->mSource->mRefCount++;
BfDefBuilder bfDefBuilder(bfSystem);
bfDefBuilder.mCurTypeDef = mTypeDef;
bfDefBuilder.mCurDeclaringTypeDef = mTypeDef;
bfDefBuilder.FinishTypeDef(true);
}
//////////////////////////////////////////////////////////////////////////
BfBoxedType::~BfBoxedType()
{
//if ((mTypeDef != NULL) && (mTypeDef->mEmitParent != NULL))
@ -3132,6 +3205,7 @@ BfResolvedTypeSet::~BfResolvedTypeSet()
#define HASH_CONSTEXPR 12
#define HASH_GLOBAL 13
#define HASH_DOTDOTDOT 14
#define HASH_TAG 15
BfVariant BfResolvedTypeSet::EvaluateToVariant(LookupContext* ctx, BfExpression* expr, BfType*& outType)
{
@ -3234,6 +3308,13 @@ int BfResolvedTypeSet::DoHash(BfType* type, LookupContext* ctx, bool allowRef, i
return hashVal;
}
else if ((type->IsEnum()) && (type->IsOnDemand()))
{
BfTypeInstance* typeInstance = type->ToTypeInstance();
auto fieldName = typeInstance->mTypeDef->mFields[0]->mName;
int nameHash = (int)Hash64(fieldName.c_str(), (int)fieldName.length());
return nameHash ^ HASH_TAG;
}
else if (type->IsTypeInstance())
{
BfTypeInstance* typeInst = (BfTypeInstance*)type;
@ -4156,6 +4237,17 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa
ctx->mFailed = true;
return 0;
}
else if (auto tagTypeRef = BfNodeDynCastExact<BfTagTypeRef>(typeRef))
{
int nameHash = 0;
if (tagTypeRef->mNameNode != NULL)
{
auto fieldName = tagTypeRef->mNameNode;
const char* nameStr = fieldName->GetSourceData()->mSrc + fieldName->GetSrcStart();
nameHash = (int)Hash64(nameStr, fieldName->GetSrcLength());
}
return nameHash ^ HASH_TAG;
}
else
{
BF_FATAL("Not handled");
@ -4839,6 +4931,15 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext*
return true;
}
else if ((lhs->IsEnum()) && (lhs->IsOnDemand()))
{
BfTypeInstance* typeInstance = lhs->ToTypeInstance();
auto fieldName = typeInstance->mTypeDef->mFields[0]->mName;
auto tagTypeRef = BfNodeDynCastExact<BfTagTypeRef>(rhs);
if (tagTypeRef == NULL)
return false;
return tagTypeRef->mNameNode->Equals(fieldName);
}
else if (lhs->IsTypeInstance())
{
BfTypeInstance* lhsInst = (BfTypeInstance*) lhs;

View file

@ -2401,6 +2401,24 @@ public:
virtual int GetGenericDepth() override { return mGenericDepth; }
};
class BfTagType : public BfTypeInstance
{
public:
bool mCreatedTypeDef;
String mNameAdd;
BfSource* mSource;
public:
BfTagType();
~BfTagType();
void Init(BfProject* bfProject, BfTypeInstance* valueTypeInstance, const StringImpl& name);
virtual void Dispose() override;
void Finish();
virtual bool IsOnDemand() override { return true; }
};
class BfConcreteInterfaceType : public BfType
{
public:

View file

@ -329,6 +329,17 @@ void BfSourceClassifier::Visit(BfNamedTypeReference* typeRef)
}
}
void BfSourceClassifier::Visit(BfTagTypeRef* typeRef)
{
Visit((BfAstNode*)typeRef);
VisitChild(typeRef->mTagNode);
SetElementType(typeRef->mTagNode, BfSourceElementType_Keyword);
VisitChild(typeRef->mNameNode);
SetElementType(typeRef->mNameNode, BfSourceElementType_Type);
}
void BfSourceClassifier::Visit(BfQualifiedTypeReference* qualifiedType)
{
Visit((BfAstNode*)qualifiedType);

View file

@ -113,6 +113,7 @@ public:
virtual void Visit(BfArrayTypeRef* arrayType) override;
virtual void Visit(BfPointerTypeRef* pointerType) override;
virtual void Visit(BfNamedTypeReference* typeRef) override;
virtual void Visit(BfTagTypeRef* typeRef) override;
virtual void Visit(BfGenericInstanceTypeRef* typeRef) override;
virtual void Visit(BfLocalMethodDeclaration * methodDecl) override;
virtual void Visit(BfLiteralExpression* literalExpr) override;

View file

@ -427,6 +427,12 @@ void BfParameterDef::SetName(BfAstNode* nameNode)
//////////////////////////////////////////////////////////////////////////
bool BfFieldDef::IsEnumCaseEntry()
{
return ((mFieldDeclaration != NULL) && (BfNodeIsA<BfEnumEntryDeclaration>(mFieldDeclaration))) ||
((mFieldDeclaration == NULL) && (mIsConst) && (mDeclaringType->mTypeCode == BfTypeCode_Enum));
}
bool BfPropertyDef::IsVirtual()
{
if (((BfPropertyDeclaration*)mFieldDeclaration)->mVirtualSpecifier)

View file

@ -655,10 +655,7 @@ public:
return (mName[0] >= '0') && (mName[0] <= '9');
}
bool IsEnumCaseEntry()
{
return (mFieldDeclaration != NULL) && (BfNodeIsA<BfEnumEntryDeclaration>(mFieldDeclaration));
}
bool IsEnumCaseEntry();
bool IsNonConstStatic()
{