From a02de171efa64b76239307d057ff7182158d961a Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Tue, 7 Jul 2020 10:46:53 -0700 Subject: [PATCH] Added ability to lookup types with 'using static' --- IDEHelper/Compiler/BfModule.h | 4 +- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 110 +++++++++++++++------ IDEHelper/Compiler/BfResolvedTypeUtils.cpp | 88 ++++++++++++++--- IDEHelper/Compiler/BfResolvedTypeUtils.h | 5 +- IDEHelper/Tests/src/UsingStatic.bf | 45 +++++++++ 5 files changed, 204 insertions(+), 48 deletions(-) create mode 100644 IDEHelper/Tests/src/UsingStatic.bf diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 46053130..39d85abf 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -1694,13 +1694,13 @@ public: void CheckIdentifierFixit(BfAstNode* node); void TypeRefNotFound(BfTypeReference* typeRef, const char* appendName = NULL); bool ValidateTypeWildcard(BfTypeReference* typeRef, bool isAttributeRef); - BfType* ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0); + BfType* ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0, int numGenericArgs = 0); BfType* ResolveTypeRefAllowUnboundGenerics(BfTypeReference* typeRef, BfPopulateType populateType = BfPopulateType_Data, bool resolveGenericParam = true); BfType* ResolveTypeRef(BfAstNode* astNode, const BfSizedArray* genericArgs, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0); //BfType* ResolveTypeRef(BfIdentifierNode* identifier, const BfSizedArray& genericArgs, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0); BfType* ResolveTypeDef(BfTypeDef* typeDef, BfPopulateType populateType = BfPopulateType_Data); BfType* ResolveTypeDef(BfTypeDef* typeDef, const BfTypeVector& genericArgs, BfPopulateType populateType = BfPopulateType_Data); - BfType* ResolveInnerType(BfType* outerType, BfTypeReference* typeRef, BfPopulateType populateType = BfPopulateType_Data, bool ignoreErrors = false); + BfType* ResolveInnerType(BfType* outerType, BfTypeReference* typeRef, BfPopulateType populateType = BfPopulateType_Data, bool ignoreErrors = false, int numGenericArgs = 0); BfType* ResolveInnerType(BfType* outerType, BfIdentifierNode* identifier, BfPopulateType populateType = BfPopulateType_Data, bool ignoreErrors = false); BfTypeDef* GetCombinedPartialTypeDef(BfTypeDef* type); BfTypeInstance* GetOuterType(BfType* type); diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 390dc4ab..5ab10c86 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -5257,7 +5257,7 @@ void BfModule::HandleMethodGenericParamRef(BfAstNode* refNode, BfTypeDef* typeDe mCompiler->mResolvePassData->HandleMethodGenericParam(refNode, typeDef, methodDef, methodGenericParamIdx); } -BfType* BfModule::ResolveInnerType(BfType* outerType, BfTypeReference* typeRef, BfPopulateType populateType, bool ignoreErrors) +BfType* BfModule::ResolveInnerType(BfType* outerType, BfTypeReference* typeRef, BfPopulateType populateType, bool ignoreErrors, int numGenericArgs) { BfTypeDef* nestedTypeDef = NULL; @@ -5315,7 +5315,14 @@ BfType* BfModule::ResolveInnerType(BfType* outerType, BfTypeReference* typeRef, if ((!isFailurePass) && (!CheckProtection(latestCheckType->mProtection, allowProtected, allowPrivate))) continue; - if (checkType->mName->mString == findName) + if (checkType->mProject != checkOuterType->mTypeDef->mProject) + { + auto visibleProjectSet = GetVisibleProjectSet(); + if ((visibleProjectSet == NULL) || (!visibleProjectSet->Contains(checkType->mProject))) + continue; + } + + if ((checkType->mName->mString == findName) && (checkType->GetSelfGenericParamCount() == numGenericArgs)) { if (isFailurePass) { @@ -5696,7 +5703,7 @@ BfTypeDef* BfModule::ResolveGenericInstanceDef(BfGenericInstanceTypeRef* generic if (auto qualifiedTypeRef = BfNodeDynCast(typeRef)) { BfAutoParentNodeEntry autoParentNodeEntry(this, genericTypeRef); - auto type = ResolveTypeRef(qualifiedTypeRef, BfPopulateType_TypeDef); + auto type = ResolveTypeRef(qualifiedTypeRef, BfPopulateType_TypeDef, BfResolveTypeRefFlag_None, numGenericParams); if (type == NULL) return NULL; if (outType != NULL) @@ -6676,6 +6683,28 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, checkNamespace, allowPrivate, &lookupCtx); } } + + if (!lookupCtx.HasValidMatch()) + { + auto staticSearch = GetStaticSearch(); + if (staticSearch != NULL) + { + for (auto staticTypeInstance : staticSearch->mStaticTypes) + { + if (mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, staticTypeInstance->mTypeDef->mFullNameEx, false, &lookupCtx)) + { + if (lookupCtx.HasValidMatch()) + break; + + if (lookupCtx.mBestTypeDef->mProtection < BfProtection_Public) + { + protErrorTypeDef = lookupCtx.mBestTypeDef; + protErrorOuterType = staticTypeInstance; + } + } + } + } + } if ((error != NULL) && (lookupCtx.mAmbiguousTypeDef != NULL)) { @@ -7110,7 +7139,7 @@ BfTypedValue BfModule::TryLookupGenericConstVaue(BfIdentifierNode* identifierNod return BfTypedValue(); } -BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags) +BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags, int numGenericArgs) { BP_ZONE("BfModule::ResolveTypeRef"); @@ -7183,7 +7212,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula auto namedTypeRef = BfNodeDynCastExact(typeRef); auto directStrTypeRef = BfNodeDynCastExact(typeRef); if (((namedTypeRef != NULL) && (namedTypeRef->mNameNode != NULL)) || (directStrTypeRef != NULL)) - { + { StringT<128> findName; if (namedTypeRef != NULL) namedTypeRef->mNameNode->ToString(findName); @@ -7392,10 +7421,10 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } } } - + if ((typeDef == NULL) && (mCurTypeInstance != NULL)) { - // Try searching within inner type + // Try searching within inner type auto checkOuterType = mCurTypeInstance; while (checkOuterType != NULL) { @@ -7414,7 +7443,25 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula checkOuterType = GetOuterType(checkOuterType); } } - + + if (typeDef == NULL) + { + auto staticSearch = GetStaticSearch(); + if (staticSearch != NULL) + { + for (auto staticTypeInst : staticSearch->mStaticTypes) + { + auto resolvedType = ResolveInnerType(staticTypeInst, typeRef, populateType, true); + if (resolvedType != NULL) + { + if (mCurTypeInstance != NULL) + AddDependency(staticTypeInst, mCurTypeInstance, BfDependencyMap::DependencyFlag_NameReference); + return ResolveTypeResult(typeRef, resolvedType, populateType, resolveFlags); + } + } + } + } + if (typeDef == NULL) { #ifdef BF_AST_HAS_PARENT_MEMBER @@ -7596,7 +7643,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags); } - auto resolvedType = ResolveInnerType(leftType, qualifiedTypeRef->mRight, populateType); + auto resolvedType = ResolveInnerType(leftType, qualifiedTypeRef->mRight, populateType, false, numGenericArgs); if ((resolvedType != NULL) && (mCurTypeInstance != NULL)) AddDependency(leftType, mCurTypeInstance, BfDependencyMap::DependencyFlag_NameReference); return ResolveTypeResult(typeRef, resolvedType, populateType, resolveFlags); @@ -7787,15 +7834,18 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula return ResolveTypeResult(typeRef, primType, populateType, resolveFlags); } - if ((mCurTypeInstance != NULL) && (typeDef->mGenericParamDefs.size() != 0)) + BfTypeInstance* outerTypeInstance = lookupCtx.mRootOuterTypeInstance; + if (outerTypeInstance == NULL) + outerTypeInstance = mCurTypeInstance; + if ((outerTypeInstance != NULL) && (typeDef->mGenericParamDefs.size() != 0)) { // Try to inherit generic params from current parent BfTypeDef* outerType = mSystem->GetCombinedPartial(typeDef->mOuterType); BF_ASSERT(!outerType->mIsPartial); - if (TypeHasParentOrEquals(mCurTypeInstance->mTypeDef, outerType)) + if (TypeHasParentOrEquals(outerTypeInstance->mTypeDef, outerType)) { - BfType* checkCurType = mCurTypeInstance; + BfType* checkCurType = outerTypeInstance; if (checkCurType->IsBoxed()) checkCurType = checkCurType->GetUnderlyingType(); if (checkCurType->IsTypeAlias()) @@ -8012,24 +8062,23 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula mContext->mResolvedTypes.RemoveEntry(resolvedEntry); return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags); } - + + BfTypeInstance* outerTypeInstance = mCurTypeInstance; + auto outerType = typeDef->mOuterType; BfTypeDef* commonOuterType = NULL; - if (mCurTypeInstance != NULL) + + int startDefGenericParamIdx = 0; + commonOuterType = BfResolvedTypeSet::FindRootCommonOuterType(outerType, &lookupCtx, outerTypeInstance); + if ((commonOuterType) && (outerTypeInstance->IsGenericTypeInstance())) { - // Copy generic params for our parent type if the current type instance shares that parent type - auto outerType = typeDef->mOuterType; - commonOuterType = FindCommonOuterType(mCurTypeInstance->mTypeDef, outerType); - if ((commonOuterType) && (mCurTypeInstance->IsGenericTypeInstance())) - { - int startDefGenericParamIdx = (int)commonOuterType->mGenericParamDefs.size(); - auto parentTypeInstance = (BfTypeInstance*)mCurTypeInstance; - if (parentTypeInstance->IsTypeAlias()) - parentTypeInstance = (BfTypeInstance*)GetOuterType(parentTypeInstance)->ToTypeInstance(); - for (int i = 0; i < startDefGenericParamIdx; i++) - genericArgs.push_back(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i]); - } - } + startDefGenericParamIdx = (int)commonOuterType->mGenericParamDefs.size(); + auto parentTypeInstance = outerTypeInstance; + if (parentTypeInstance->IsTypeAlias()) + parentTypeInstance = (BfTypeInstance*)GetOuterType(parentTypeInstance)->ToTypeInstance(); + for (int i = 0; i < startDefGenericParamIdx; i++) + genericArgs.push_back(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i]); + } for (auto genericArgRef : genericArguments) { @@ -8080,13 +8129,12 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula mContext->mResolvedTypes.RemoveEntry(resolvedEntry); return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags); } - - int startDefGenericParamIdx = 0; + genericTypeInst->mTypeDef = typeDef; - if ((commonOuterType != NULL) && (mCurTypeInstance->IsGenericTypeInstance())) + if ((commonOuterType != NULL) && (outerTypeInstance->IsGenericTypeInstance())) { - auto parentTypeInstance = (BfTypeInstance*)mCurTypeInstance; + auto parentTypeInstance = outerTypeInstance; if (parentTypeInstance->IsTypeAlias()) parentTypeInstance = (BfTypeInstance*)GetOuterType(parentTypeInstance)->ToTypeInstance(); for (int i = 0; i < startDefGenericParamIdx; i++) diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index 4a8821f6..ca7be36e 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -2590,6 +2590,31 @@ int BfResolvedTypeSet::DirectHash(BfTypeReference* typeRef, LookupContext* ctx, return Hash(resolvedType, ctx); } +BfTypeDef* BfResolvedTypeSet::FindRootCommonOuterType(BfTypeDef* outerType, LookupContext* ctx, BfTypeInstance*& outOuterTypeInstance) +{ + BfTypeDef* commonOuterType = ctx->mModule->FindCommonOuterType(ctx->mModule->mCurTypeInstance->mTypeDef, outerType); + if ((commonOuterType == NULL) && (outerType != NULL)) + { + auto staticSearch = ctx->mModule->GetStaticSearch(); + if (staticSearch != NULL) + { + for (auto staticTypeInst : staticSearch->mStaticTypes) + { + auto foundOuterType = ctx->mModule->FindCommonOuterType(staticTypeInst->mTypeDef, outerType); + if ((foundOuterType != NULL) && + ((commonOuterType == NULL) || (foundOuterType->mNestDepth > commonOuterType->mNestDepth))) + { + commonOuterType = foundOuterType; + outOuterTypeInstance = staticTypeInst; + } + } + } + } + if (outOuterTypeInstance != NULL) + ctx->mRootOuterTypeInstance = outOuterTypeInstance; + return commonOuterType; +} + int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags) { if ((typeRef == ctx->mRootTypeRef) && (ctx->mRootTypeDef != NULL) && @@ -2598,7 +2623,7 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash BfTypeDef* typeDef = ctx->mRootTypeDef; int hashVal = typeDef->mHash; - + if (typeDef->mGenericParamDefs.size() != 0) { auto checkTypeInstance = ctx->mModule->mCurTypeInstance; @@ -2606,14 +2631,38 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash checkTypeInstance = checkTypeInstance->GetUnderlyingType()->ToTypeInstance(); auto outerType = ctx->mModule->mSystem->GetOuterTypeNonPartial(typeDef); - BfTypeDef* commonOuterType = ctx->mModule->FindCommonOuterType(ctx->mModule->mCurTypeInstance->mTypeDef, outerType); + + BfTypeDef* commonOuterType; + if (typeRef == ctx->mRootTypeRef) + commonOuterType = FindRootCommonOuterType(outerType, ctx, checkTypeInstance); + else + commonOuterType = ctx->mModule->FindCommonOuterType(ctx->mModule->mCurTypeInstance->mTypeDef, outerType); + + if ((commonOuterType == NULL) && (outerType != NULL)) + { + auto staticSearch = ctx->mModule->GetStaticSearch(); + if (staticSearch != NULL) + { + for (auto staticTypeInst : staticSearch->mStaticTypes) + { + auto foundOuterType = ctx->mModule->FindCommonOuterType(staticTypeInst->mTypeDef, outerType); + if ((foundOuterType != NULL) && + ((commonOuterType == NULL) || (foundOuterType->mNestDepth > commonOuterType->mNestDepth))) + { + commonOuterType = foundOuterType; + checkTypeInstance = staticTypeInst; + } + } + } + } + if ((commonOuterType == NULL) || (commonOuterType->mGenericParamDefs.size() == 0)) { ctx->mModule->Fail("Generic arguments expected", typeRef); ctx->mFailed = true; return 0; } - + BF_ASSERT(checkTypeInstance->IsGenericTypeInstance()); auto curGenericTypeInst = (BfTypeInstance*)checkTypeInstance; int numParentGenericParams = (int)commonOuterType->mGenericParamDefs.size(); @@ -2688,12 +2737,18 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash } // Do we need to add generic arguments from an in-context outer class? - if ((elementTypeDef->mOuterType != NULL) && (ctx->mModule->mCurTypeInstance != NULL) && (ctx->mModule->mCurTypeInstance->IsGenericTypeInstance())) + if ((elementTypeDef->mOuterType != NULL) && (ctx->mModule->mCurTypeInstance != NULL)) { - BfTypeDef* commonOuterType = ctx->mModule->FindCommonOuterType(ctx->mModule->mCurTypeInstance->mTypeDef, elementTypeDef->mOuterType); - if (commonOuterType != NULL) + BfTypeInstance* checkTypeInstance = ctx->mModule->mCurTypeInstance; + BfTypeDef* commonOuterType; + if (typeRef == ctx->mRootTypeRef) + commonOuterType = FindRootCommonOuterType(elementTypeDef->mOuterType, ctx, checkTypeInstance); + else + commonOuterType = ctx->mModule->FindCommonOuterType(ctx->mModule->mCurTypeInstance->mTypeDef, elementTypeDef->mOuterType); + + if ((commonOuterType != NULL) && (checkTypeInstance->IsGenericTypeInstance())) { - auto parentTypeInstance = (BfTypeInstance*)ctx->mModule->mCurTypeInstance; + auto parentTypeInstance = checkTypeInstance; int numParentGenericParams = (int)commonOuterType->mGenericParamDefs.size(); for (int i = 0; i < numParentGenericParams; i++) hashVal = ((hashVal ^ (Hash(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i], ctx))) << 5) - hashVal; @@ -3252,7 +3307,11 @@ bool BfResolvedTypeSet::GenericTypeEquals(BfTypeInstance* lhsGenericType, BfType } bool BfResolvedTypeSet::GenericTypeEquals(BfTypeInstance* lhsGenericType, BfTypeVector* lhsTypeGenericArguments, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx) -{ +{ + BfTypeInstance* rootOuterTypeInstance = ctx->mModule->mCurTypeInstance; + if ((rhsTypeDef == ctx->mRootTypeDef) && (ctx->mRootOuterTypeInstance != NULL)) + rootOuterTypeInstance = ctx->mRootOuterTypeInstance; + auto rhsGenericTypeInstRef = BfNodeDynCastExact(rhs); if (rhsGenericTypeInstRef == NULL) { @@ -3268,15 +3327,16 @@ bool BfResolvedTypeSet::GenericTypeEquals(BfTypeInstance* lhsGenericType, BfType } } - if ((rhsTypeDef != NULL) && (ctx->mModule->mCurTypeInstance != NULL)) + if ((rhsTypeDef != NULL) && (rootOuterTypeInstance != NULL)) { // See if we're referring to an non-generic inner type where the outer type is generic if (lhsGenericType->mTypeDef != rhsTypeDef) return false; - BfTypeDef* commonOuterType = ctx->mModule->FindCommonOuterType(ctx->mModule->mCurTypeInstance->mTypeDef, rhsTypeDef->mOuterType); + + BfTypeDef* commonOuterType = ctx->mModule->FindCommonOuterType(rootOuterTypeInstance->mTypeDef, rhsTypeDef->mOuterType); if (commonOuterType != NULL) { - BfTypeInstance* checkTypeInstance = ctx->mModule->mCurTypeInstance; + BfTypeInstance* checkTypeInstance = rootOuterTypeInstance; if (checkTypeInstance->IsBoxed()) checkTypeInstance = checkTypeInstance->GetUnderlyingType()->ToTypeInstance(); BF_ASSERT(checkTypeInstance->IsGenericTypeInstance()); @@ -3307,12 +3367,12 @@ bool BfResolvedTypeSet::GenericTypeEquals(BfTypeInstance* lhsGenericType, BfType int genericParamOffset = 0; // Do we need to add generic arguments from an in-context outer class? - if ((elementTypeDef->mOuterType != NULL) && (ctx->mModule->mCurTypeInstance != NULL) && (ctx->mModule->mCurTypeInstance->IsGenericTypeInstance())) + if ((elementTypeDef->mOuterType != NULL) && (rootOuterTypeInstance != NULL) && (rootOuterTypeInstance->IsGenericTypeInstance())) { - BfTypeDef* commonOuterType = ctx->mModule->FindCommonOuterType(ctx->mModule->mCurTypeInstance->mTypeDef, elementTypeDef->mOuterType); + BfTypeDef* commonOuterType = ctx->mModule->FindCommonOuterType(rootOuterTypeInstance->mTypeDef, elementTypeDef->mOuterType); if (commonOuterType != NULL) { - auto parentTypeInstance = (BfTypeInstance*)ctx->mModule->mCurTypeInstance; + auto parentTypeInstance = rootOuterTypeInstance; genericParamOffset = (int) commonOuterType->mGenericParamDefs.size(); for (int i = 0; i < genericParamOffset; i++) for (auto genericArg : parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments) diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.h b/IDEHelper/Compiler/BfResolvedTypeUtils.h index f1138200..852a0c55 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.h +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.h @@ -2328,6 +2328,7 @@ public: BfModule* mModule; BfTypeReference* mRootTypeRef; BfTypeDef* mRootTypeDef; + BfTypeInstance* mRootOuterTypeInstance; BfType* mResolvedType; BfResolveTypeRefFlags mResolveFlags; bool mFailed; @@ -2336,7 +2337,8 @@ public: LookupContext() { mRootTypeRef = NULL; - mRootTypeDef = NULL; + mRootTypeDef = NULL; + mRootOuterTypeInstance = NULL; mModule = NULL; mResolvedType = NULL; mFailed = false; @@ -2348,6 +2350,7 @@ public: }; public: + static BfTypeDef* FindRootCommonOuterType(BfTypeDef* outerType, LookupContext* ctx, BfTypeInstance*& outCheckTypeInstance); static BfVariant EvaluateToVariant(LookupContext* ctx, BfExpression* expr, BfType*& constGenericParam); static bool GenericTypeEquals(BfTypeInstance* lhsGenericType, BfTypeVector* lhsTypeGenericArguments, BfTypeReference* rhs, LookupContext* ctx, int& genericParamOffset); static bool GenericTypeEquals(BfTypeInstance* lhsGenericType, BfTypeVector* typeGenericArguments, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx); diff --git a/IDEHelper/Tests/src/UsingStatic.bf b/IDEHelper/Tests/src/UsingStatic.bf new file mode 100644 index 00000000..16f8d595 --- /dev/null +++ b/IDEHelper/Tests/src/UsingStatic.bf @@ -0,0 +1,45 @@ +#pragma warning disable 168 + +using static Tests.USOuter; +using static Tests.USOuter.USInnerC; + +namespace Tests +{ + class USOuter + { + public static int sVal0 = 123; + + public class USInnerA + { + public class USInnerB + { + + } + } + + public class USInnerC + { + public class USInnerD + { + + } + + public class USInnerE + { + + } + } + } + + class UsingStatic + { + public static void TestBasics() + { + USInnerA innerA; + USInnerA.USInnerB innerB; + int val = sVal0; + USInnerD id; + USInnerE ie; + } + } +}