From 20c88dfeb0d11b7a29987c96d8a0028a67d456fd Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Fri, 24 Jun 2022 06:45:35 -0700 Subject: [PATCH] Better enum autocomplete hygiene --- BeefLibs/corlib/src/Attribute.bf | 10 ++++++- BeefLibs/corlib/src/Enum.bf | 33 +++++++++++++------- BeefLibs/corlib/src/ValueType.bf | 1 + IDEHelper/Compiler/BfAutoComplete.cpp | 43 ++++++++++++++++++--------- IDEHelper/Compiler/BfAutoComplete.h | 2 +- IDEHelper/Compiler/BfDefBuilder.cpp | 30 +++++++++++++++++-- IDEHelper/Compiler/BfModule.cpp | 3 ++ IDEHelper/Compiler/BfSystem.cpp | 7 ++--- IDEHelper/Compiler/BfSystem.h | 17 ++++++++--- 9 files changed, 109 insertions(+), 37 deletions(-) diff --git a/BeefLibs/corlib/src/Attribute.bf b/BeefLibs/corlib/src/Attribute.bf index e0eb24ae..795eda52 100644 --- a/BeefLibs/corlib/src/Attribute.bf +++ b/BeefLibs/corlib/src/Attribute.bf @@ -425,10 +425,18 @@ namespace System } } - [AttributeUsage(.Field | .StaticField | .Method | .Property /*2*/)] + [AttributeUsage(.Field | .StaticField | .Method | .Property | .Types)] public struct NoShowAttribute : Attribute { + public this() + { + } + + public this(bool allowDirect) + { + + } } [AttributeUsage(.Parameter)] diff --git a/BeefLibs/corlib/src/Enum.bf b/BeefLibs/corlib/src/Enum.bf index 7b0ec9be..08326d01 100644 --- a/BeefLibs/corlib/src/Enum.bf +++ b/BeefLibs/corlib/src/Enum.bf @@ -5,11 +5,12 @@ namespace System { struct Enum { + [NoShow(true)] [Comptime(ConstEval=true)] - public static int GetCount() + public static int GetCount() where T : Enum { int count = 0; - for (var field in Compiler.OrigCalleeType.GetFields()) + for (var field in typeof(T).GetFields()) { if (field.IsEnumCase) count++; @@ -17,13 +18,14 @@ namespace System return count; } + [NoShow(true)] [Comptime(ConstEval=true)] - public static var GetMinValue() + public static var GetMinValue() where T : Enum { - Compiler.SetReturnType(Compiler.OrigCalleeType); + Compiler.SetReturnType(typeof(T)); int? minValue = null; - for (var field in Compiler.OrigCalleeType.GetFields()) + for (var field in typeof(T).GetFields()) { if (field.IsEnumCase) { @@ -36,13 +38,14 @@ namespace System return minValue.ValueOrDefault; } + [NoShow(true)] [Comptime(ConstEval=true)] - public static var GetMaxValue() + public static var GetMaxValue() where T : Enum { - Compiler.SetReturnType(Compiler.OrigCalleeType); + Compiler.SetReturnType(typeof(T)); int? maxValue = null; - for (var field in Compiler.OrigCalleeType.GetFields()) + for (var field in typeof(T).GetFields()) { if (field.IsEnumCase) { @@ -57,6 +60,7 @@ namespace System return maxValue.ValueOrDefault; } + [NoShow(true)] public static void EnumToString(Type type, String strBuffer, int64 iVal) { for (var field in type.GetFields()) @@ -71,6 +75,7 @@ namespace System iVal.ToString(strBuffer); } + [NoShow(true)] public static Result Parse(StringView str, bool ignoreCase = false) where T : enum { for (var (name, data) in GetEnumerator()) @@ -84,7 +89,8 @@ namespace System return .Err; } - public static bool IsDefined(T value) + [NoShow(true)] + public static bool IsDefined(T value) where T : Enum where T : enum { for (var data in GetValues()) @@ -96,24 +102,28 @@ namespace System return false; } + [NoShow(true)] public static EnumEnumerator GetEnumerator() where TEnum : enum { return .(); } + [NoShow(true)] public static EnumValuesEnumerator GetValues() where TEnum : enum { return .(); } - + + [NoShow(true)] public static EnumNamesEnumerator GetNames() where TEnum : enum { return .(); } + [NoShow(true)] private struct EnumFieldsEnumerator where TEnum : enum { @@ -179,6 +189,7 @@ namespace System } } + [NoShow(true)] public struct EnumEnumerator : EnumFieldsEnumerator, IEnumerator<(StringView name, TEnum value)> where TEnum : enum { @@ -198,6 +209,7 @@ namespace System } } + [NoShow(true)] public struct EnumValuesEnumerator : EnumFieldsEnumerator, IEnumerator where TEnum : enum { @@ -217,6 +229,7 @@ namespace System } } + [NoShow(true)] public struct EnumNamesEnumerator : EnumFieldsEnumerator, IEnumerator where TEnum : enum { diff --git a/BeefLibs/corlib/src/ValueType.bf b/BeefLibs/corlib/src/ValueType.bf index 52005fbe..86c7d0ec 100644 --- a/BeefLibs/corlib/src/ValueType.bf +++ b/BeefLibs/corlib/src/ValueType.bf @@ -2,6 +2,7 @@ namespace System { struct ValueType { + [NoShow(true)] public static extern bool Equals(T val1, T val2); } } diff --git a/IDEHelper/Compiler/BfAutoComplete.cpp b/IDEHelper/Compiler/BfAutoComplete.cpp index d9389499..e02c4947 100644 --- a/IDEHelper/Compiler/BfAutoComplete.cpp +++ b/IDEHelper/Compiler/BfAutoComplete.cpp @@ -712,13 +712,18 @@ const char* BfAutoComplete::GetTypeName(BfType* type) return "value"; } -void BfAutoComplete::AddInnerTypes(BfTypeInstance* typeInst, const StringImpl& filter, bool allowProtected, bool allowPrivate) +void BfAutoComplete::AddInnerTypes(BfTypeInstance* typeInst, const StringImpl& filter, BfTypeInstance* startType, bool allowProtected, bool allowPrivate) { if (typeInst->IsEnum()) AddEntry(AutoCompleteEntry("valuetype", "UnderlyingType"), filter); + BfShow checkShow = (typeInst == startType) ? BfShow_Hide : BfShow_HideIndirect; + for (auto innerType : typeInst->mTypeDef->mNestedTypes) { + if (innerType->mShow >= checkShow) + continue; + if (innerType->mOuterType->mTypeCode == BfTypeCode_Extension) { if (typeInst->mDefineState < BfTypeDefineState_Defined) @@ -737,7 +742,7 @@ void BfAutoComplete::AddInnerTypes(BfTypeInstance* typeInst, const StringImpl& f allowPrivate = false; if (typeInst->mBaseType != NULL) - AddInnerTypes(typeInst->mBaseType, filter, allowProtected, allowPrivate); + AddInnerTypes(typeInst->mBaseType, filter, startType, allowProtected, allowPrivate); } void BfAutoComplete::AddCurrentTypes(BfTypeInstance* typeInst, const StringImpl& filter, bool allowProtected, bool allowPrivate, bool onlyAttribute) @@ -900,7 +905,7 @@ void BfAutoComplete::AddTypeMembers(BfTypeInstance* typeInst, bool addStatic, bo auto activeTypeDef = mModule->GetActiveTypeDef(); - if ((addStatic) && (mModule->mCurMethodInstance == NULL) && (typeInst->IsEnum())) + if ((addStatic) && (mModule->mCurMethodInstance == NULL) && (typeInst->IsEnum()) && (allowImplicitThis)) { AddEntry(AutoCompleteEntry("value", "_"), filter); } @@ -909,6 +914,8 @@ void BfAutoComplete::AddTypeMembers(BfTypeInstance* typeInst, bool addStatic, bo mModule->PopulateType(typeInst, BfPopulateType_Data); + BfShow checkShow = (startType == typeInst) ? BfShow_Hide : BfShow_HideIndirect; + BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None; for (auto& fieldInst : typeInst->mFieldInstances) { @@ -916,7 +923,7 @@ void BfAutoComplete::AddTypeMembers(BfTypeInstance* typeInst, bool addStatic, bo if (fieldDef == NULL) continue; - if (fieldDef->mIsNoShow) + if (fieldDef->mShow >= checkShow) continue; if ((CHECK_STATIC(fieldDef->mIsStatic)) && @@ -934,7 +941,7 @@ void BfAutoComplete::AddTypeMembers(BfTypeInstance* typeInst, bool addStatic, bo { if (methodDef->mIsOverride) continue; - if (methodDef->mIsNoShow) + if (methodDef->mShow >= checkShow) continue; if (methodDef->mName.IsEmpty()) continue; @@ -965,7 +972,7 @@ void BfAutoComplete::AddTypeMembers(BfTypeInstance* typeInst, bool addStatic, bo for (auto propDef : typeInst->mTypeDef->mProperties) { - if (propDef->mIsNoShow) + if (propDef->mShow >= checkShow) continue; if ((!typeInst->IsTypeMemberIncluded(propDef->mDeclaringType, activeTypeDef, mModule)) || @@ -1016,13 +1023,15 @@ void BfAutoComplete::AddSelfResultTypeMembers(BfTypeInstance* typeInst, BfTypeIn mModule->PopulateType(typeInst, BfPopulateType_Data); + BfShow checkShow = allowPrivate ? BfShow_Hide : BfShow_HideIndirect; + for (auto& fieldInst : typeInst->mFieldInstances) { auto fieldDef = fieldInst.GetFieldDef(); if (fieldDef == NULL) continue; - if (fieldDef->mIsNoShow) + if (fieldDef->mShow > checkShow) continue; if ((fieldDef->mIsStatic) && (CheckProtection(fieldDef->mProtection, fieldDef->mDeclaringType, allowProtected, allowPrivate))) @@ -1042,7 +1051,7 @@ void BfAutoComplete::AddSelfResultTypeMembers(BfTypeInstance* typeInst, BfTypeIn { if (methodDef->mIsOverride) continue; - if (methodDef->mIsNoShow) + if (methodDef->mShow > checkShow) continue; if (methodDef->mName.IsEmpty()) continue; @@ -1082,7 +1091,7 @@ void BfAutoComplete::AddSelfResultTypeMembers(BfTypeInstance* typeInst, BfTypeIn for (auto propDef : typeInst->mTypeDef->mProperties) { - if (propDef->mIsNoShow) + if (propDef->mShow > checkShow) continue; if ((!typeInst->IsTypeMemberIncluded(propDef->mDeclaringType, activeTypeDef, mModule)) || @@ -1216,11 +1225,13 @@ void BfAutoComplete::AddExtensionMethods(BfTypeInstance* targetType, BfTypeInsta mModule->PopulateType(extensionContainer, BfPopulateType_Data); + BfShow checkShow = allowPrivate ? BfShow_Hide : BfShow_HideIndirect; + for (auto methodDef : extensionContainer->mTypeDef->mMethods) { if (methodDef->mMethodType != BfMethodType_Extension) continue; - if (methodDef->mIsNoShow) + if (methodDef->mShow >= checkShow) continue; if (methodDef->mName.IsEmpty()) continue; @@ -1596,7 +1607,7 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress for (auto typeInst : staticSearch->mStaticTypes) { AddTypeMembers(typeInst, true, false, filter, typeInst, true, true, false); - AddInnerTypes(typeInst, filter, false, false); + AddInnerTypes(typeInst, filter, typeInst, false, false); } } @@ -1977,7 +1988,7 @@ bool BfAutoComplete::CheckMemberReference(BfAstNode* target, BfAstNode* dotToken bool allowProtected = allowPrivate; if (isStatic) - AddInnerTypes(typeInst, filter, allowProtected, allowPrivate); + AddInnerTypes(typeInst, filter, typeInst, allowProtected, allowPrivate); if (!onlyShowTypes) { @@ -2116,11 +2127,13 @@ bool BfAutoComplete::CheckExplicitInterface(BfTypeInstance* interfaceType, BfAst auto activeTypeDef = mModule->GetActiveTypeDef(); + BfShow checkShow = BfShow_Hide; + for (auto methodDef : interfaceType->mTypeDef->mMethods) { if (methodDef->mIsOverride) continue; - if (methodDef->mIsNoShow) + if (methodDef->mShow >= checkShow) continue; if (methodDef->mName.IsEmpty()) continue; @@ -2617,12 +2630,14 @@ void BfAutoComplete::AddOverrides(const StringImpl& filter) auto activeTypeDef = mModule->GetActiveTypeDef(); + BfShow checkShow = BfShow_Hide; + BfTypeInstance* curType = mModule->mCurTypeInstance; while (curType != NULL) { for (auto methodDef : curType->mTypeDef->mMethods) { - if (methodDef->mIsNoShow) + if (methodDef->mShow >= checkShow) continue; bool allowInternalOverride = false; diff --git a/IDEHelper/Compiler/BfAutoComplete.h b/IDEHelper/Compiler/BfAutoComplete.h index bd650988..f05139a1 100644 --- a/IDEHelper/Compiler/BfAutoComplete.h +++ b/IDEHelper/Compiler/BfAutoComplete.h @@ -223,7 +223,7 @@ public: void AddField(BfTypeInstance* typeInst, BfFieldDef* fieldDef, BfFieldInstance* fieldInstance, const StringImpl& filter); void AddProp(BfTypeInstance* typeInst, BfPropertyDef* propDef, const StringImpl& filter); void AddTypeDef(BfTypeDef* typeDef, const StringImpl& filter, bool onlyAttribute = false); - void AddInnerTypes(BfTypeInstance* typeInst, const StringImpl& filter, bool allowProtected, bool allowPrivate); + void AddInnerTypes(BfTypeInstance* typeInst, const StringImpl& filter, BfTypeInstance* startType, bool allowProtected, bool allowPrivate); void AddCurrentTypes(BfTypeInstance* typeInst, const StringImpl& filter, bool allowProtected, bool allowPrivate, bool onlyAttribute); void AddTypeMembers(BfTypeInstance* typeInst, bool addStatic, bool addNonStatic, const StringImpl& filter, BfTypeInstance* startType, bool allowInterfaces, bool allowImplicitThis, bool checkOuterType); void AddSelfResultTypeMembers(BfTypeInstance* typeInst, BfTypeInstance* selfType, const StringImpl& filter, bool allowPrivate); diff --git a/IDEHelper/Compiler/BfDefBuilder.cpp b/IDEHelper/Compiler/BfDefBuilder.cpp index 03aa0cc5..c77f509e 100644 --- a/IDEHelper/Compiler/BfDefBuilder.cpp +++ b/IDEHelper/Compiler/BfDefBuilder.cpp @@ -851,7 +851,18 @@ void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfMethodDef methodDef->mHasComptime = true; } else if (typeRefName == "NoShow") - methodDef->mIsNoShow = true; + { + methodDef->mShow = BfShow_Hide; + + if (!attributes->mArguments.IsEmpty()) + { + if (auto literalExpr = BfNodeDynCast(attributes->mArguments[0])) + { + if (literalExpr->mValue.mBool) + methodDef->mShow = BfShow_HideIndirect; + } + } + } else if (typeRefName == "NoDiscard") methodDef->mIsNoDiscard = true; else if (typeRefName == "NoSplat") @@ -883,7 +894,7 @@ void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfMethodDef void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfTypeDef* typeDef) { while (attributes != NULL) - { + { if (attributes->mAttributeTypeRef != NULL) { auto typeRefName = attributes->mAttributeTypeRef->ToCleanAttributeString(); @@ -891,7 +902,20 @@ void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfTypeDef* if (typeRefName == "AlwaysInclude") typeDef->mIsAlwaysInclude = true; else if (typeRefName == "NoDiscard") - typeDef->mIsNoDiscard = true; + typeDef->mIsNoDiscard = true; + else if (typeRefName == "NoShow") + { + typeDef->mShow = BfShow_Hide; + + if (!attributes->mArguments.IsEmpty()) + { + if (auto literalExpr = BfNodeDynCast(attributes->mArguments[0])) + { + if (literalExpr->mValue.mBool) + typeDef->mShow = BfShow_HideIndirect; + } + } + } } attributes = attributes->mNextAttribute; diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index b46efa7d..ebf2dc06 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -22532,6 +22532,9 @@ void BfModule::GetMethodCustomAttributes(BfMethodInstance* methodInstance) auto propertyMethodDeclaration = methodDef->GetPropertyMethodDeclaration(); auto typeInstance = methodInstance->GetOwner(); + if (typeInstance->IsInstanceOf(mCompiler->mValueTypeTypeDef)) + return; + BfTypeState typeState(typeInstance); SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); SetAndRestoreValue prevTypeInstance(mCurTypeInstance, typeInstance); diff --git a/IDEHelper/Compiler/BfSystem.cpp b/IDEHelper/Compiler/BfSystem.cpp index 14890130..365dd36c 100644 --- a/IDEHelper/Compiler/BfSystem.cpp +++ b/IDEHelper/Compiler/BfSystem.cpp @@ -2975,7 +2975,7 @@ void BfSystem::InjectNewRevision(BfTypeDef* typeDef) BF_ASSERT(typeDef->mTypeCode == nextTypeDef->mTypeCode); typeDef->mTypeCode = nextTypeDef->mTypeCode; - + typeDef->mShow = nextTypeDef->mShow; typeDef->mIsAlwaysInclude = nextTypeDef->mIsAlwaysInclude; typeDef->mIsNoDiscard = nextTypeDef->mIsNoDiscard; typeDef->mIsPartial = nextTypeDef->mIsPartial; @@ -3080,6 +3080,7 @@ void BfSystem::AddToCompositePartial(BfPassInstance* passInstance, BfTypeDef* co typeDef->mSystem = partialTypeDef->mSystem; typeDef->mTypeCode = partialTypeDef->mTypeCode; + typeDef->mShow = partialTypeDef->mShow; typeDef->mIsFunction = partialTypeDef->mIsFunction; typeDef->mIsDelegate = partialTypeDef->mIsDelegate; typeDef->mNestDepth = partialTypeDef->mNestDepth; @@ -3500,9 +3501,7 @@ void BfSystem::CopyTypeDef(BfTypeDef* typeDef, BfTypeDef* fromTypeDef) typeDef->mProtection = fromTypeDef->mProtection; typeDef->mTypeCode = fromTypeDef->mTypeCode; - - typeDef->mTypeCode = fromTypeDef->mTypeCode; - + typeDef->mShow = fromTypeDef->mShow; typeDef->mIsAlwaysInclude = fromTypeDef->mIsAlwaysInclude; typeDef->mIsNoDiscard = fromTypeDef->mIsNoDiscard; typeDef->mIsPartial = fromTypeDef->mIsPartial; diff --git a/IDEHelper/Compiler/BfSystem.h b/IDEHelper/Compiler/BfSystem.h index 8d9465be..f3240700 100644 --- a/IDEHelper/Compiler/BfSystem.h +++ b/IDEHelper/Compiler/BfSystem.h @@ -536,6 +536,13 @@ enum BfParamKind : uint8 BfParamKind_VarArgs }; +enum BfShow : uint8 +{ + BfShow_Show, + BfShow_HideIndirect, + BfShow_Hide +}; + class BfParameterDef { public: @@ -570,7 +577,7 @@ public: BfProtection mProtection; uint8 mNamePrefixCount; // Number of @'s bool mIsStatic; - bool mIsNoShow; + BfShow mShow; bool mIsReadOnly; bool mHasMultiDefs; @@ -581,7 +588,7 @@ public: mProtection = BfProtection_Public; mNamePrefixCount = 0; mIsStatic = false; - mIsNoShow = false; + mShow = BfShow_Show; mIsReadOnly = false; mHasMultiDefs = false; } @@ -1133,7 +1140,8 @@ public: int mPartialIdx; int mNestDepth; int mDupDetectedRevision; // Error state - BfTypeCode mTypeCode; + BfTypeCode mTypeCode; + BfShow mShow; bool mIsAlwaysInclude; bool mIsNoDiscard; bool mIsPartial; @@ -1170,7 +1178,8 @@ public: mNameEx = NULL; mSystem = NULL; mProject = NULL; - mTypeCode = BfTypeCode_None; + mTypeCode = BfTypeCode_None; + mShow = BfShow_Show; mIsAlwaysInclude = false; mIsNoDiscard = false; mIsExplicitPartial = false;