From 16de3a14a4835e05f37726c8eeb83cc9ad03c8bb Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Fri, 13 Jan 2023 07:01:54 -0500 Subject: [PATCH] Property visibility fixes for default interface methods --- IDEHelper/Compiler/BfExprEvaluator.cpp | 7 ++++++- IDEHelper/Compiler/BfModule.h | 2 +- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 26 ++++++++++++++++-------- IDEHelper/Tests/LibA/src/LibA0.bf | 13 ++++++++++++ IDEHelper/Tests/src/Interfaces.bf | 8 ++++++++ 5 files changed, 45 insertions(+), 11 deletions(-) diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 16e8dfaa..95ac07ca 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -19050,7 +19050,7 @@ BfModuleMethodInstance BfExprEvaluator::GetPropertyMethodInstance(BfMethodDef* m checkType = mModule->GetWrappedStructType(checkType); if ((checkType != NULL) && (checkType->IsTypeInstance())) { - auto activeTypeDef = mModule->GetActiveTypeDef(); + auto activeTypeDef = mModule->GetActiveTypeDef(NULL, false, true); BfTypeInterfaceEntry* bestIFaceEntry = NULL; bool checkedUnderlying = false; @@ -19213,6 +19213,11 @@ BfTypedValue BfExprEvaluator::GetResult(bool clearResult, bool resolveGenericTyp } } + if (mModule->mCurMethodInstance->mIsForeignMethodDef) + { + NOP; + } + if (!handled) { SetAndRestoreValue prevFunctionBindResult(mFunctionBindResult, NULL); diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index c67f453c..46245587 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -1949,7 +1949,7 @@ public: BfType* ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTypeRef, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags); void ShowAmbiguousTypeError(BfAstNode* refNode, BfTypeDef* typeDef, BfTypeDef* otherTypeDef); void ShowGenericArgCountError(BfAstNode* typeRef, int wantedGenericParams); - BfTypeDef* GetActiveTypeDef(BfTypeInstance* typeInstanceOverride = NULL, bool useMixinDecl = false); // useMixinDecl is useful for type lookup, but we don't want the decl project to limit what methods the user can call + BfTypeDef* GetActiveTypeDef(BfTypeInstance* typeInstanceOverride = NULL, bool useMixinDecl = false, bool useForeignImpl = false); // useMixinDecl is useful for type lookup, but we don't want the decl project to limit what methods the user can call BfTypeDef* FindTypeDefRaw(const BfAtomComposite& findName, int numGenericArgs, BfTypeInstance* typeInstance, BfTypeDef* useTypeDef, BfTypeLookupError* error, BfTypeLookupResultCtx* lookupResultCtx = NULL, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0); BfTypeDef* FindTypeDef(const BfAtomComposite& findName, int numGenericArgs = 0, BfTypeInstance* typeInstanceOverride = NULL, BfTypeLookupError* error = NULL, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0); BfTypeDef* FindTypeDef(const StringImpl& typeName, int numGenericArgs = 0, BfTypeInstance* typeInstanceOverride = NULL, BfTypeLookupError* error = NULL, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0); diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 4a814ffc..e1ecf9c2 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -9921,7 +9921,7 @@ void BfModule::ShowGenericArgCountError(BfAstNode* typeRef, int wantedGenericPar Fail(StrFormat("Too few generic parameters, expected %d more", -genericArgDiffCount), lastNode); } -BfTypeDef* BfModule::GetActiveTypeDef(BfTypeInstance* typeInstanceOverride, bool useMixinDecl) +BfTypeDef* BfModule::GetActiveTypeDef(BfTypeInstance* typeInstanceOverride, bool useMixinDecl, bool useForeignImpl) { BfTypeDef* useTypeDef = NULL; BfTypeInstance* typeInstance = (typeInstanceOverride != NULL) ? typeInstanceOverride : mCurTypeInstance; @@ -9933,12 +9933,20 @@ BfTypeDef* BfModule::GetActiveTypeDef(BfTypeInstance* typeInstanceOverride, bool useTypeDef = mCurMethodState->mMixinState->mMixinMethodInstance->mMethodDef->mDeclaringType->GetDefinition(); else if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mMethodDef->mDeclaringType != NULL)) { - auto declTypeDef = mCurMethodInstance->mMethodDef->mDeclaringType; - useTypeDef = declTypeDef->GetDefinition(true); - if ((declTypeDef->IsEmitted()) && (useTypeDef->mIsCombinedPartial)) + if ((mCurMethodInstance->mIsForeignMethodDef) && (useForeignImpl)) { - // Always consider methods to belong to the primary type declaration - useTypeDef = useTypeDef->mPartials[0]; + // Use the concrete impl typeDef, not the foreign method typedecl (the interface) + } + else + { + auto declTypeDef = mCurMethodInstance->mMethodDef->mDeclaringType; + useTypeDef = declTypeDef->GetDefinition(true); + if ((declTypeDef->IsEmitted()) && (useTypeDef->mIsCombinedPartial)) + { + // Always consider methods to belong to the primary type declaration + useTypeDef = useTypeDef->mPartials[0]; + + } } } else if (mContext->mCurTypeState != NULL) @@ -14007,7 +14015,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp } } else if (toType->IsSizedArray()) - { + { auto sizedArray = (BfSizedArrayType*)toType; if (sizedArray->mElementType == GetPrimitiveType(BfTypeCode_Char8)) { @@ -14018,7 +14026,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp if (mContext->mStringObjectIdMap.TryGetValue(stringId, &entry)) { String& string = entry->mString; - + if (string.GetLength() > sizedArray->mElementCount) { if (!ignoreErrors) @@ -14981,7 +14989,7 @@ bool BfModule::TypeIsSubTypeOf(BfTypeInstance* srcType, BfTypeInstance* wantType if (checkAccessibility) { if (checkActiveTypeDef == NULL) - checkActiveTypeDef = GetActiveTypeDef(NULL, false); + checkActiveTypeDef = GetActiveTypeDef(NULL, false, true); // We need to be lenient when validating generic constraints // Otherwise "T where T : IB" declared in a lib won't be able to match a type B in a using project 'C', diff --git a/IDEHelper/Tests/LibA/src/LibA0.bf b/IDEHelper/Tests/LibA/src/LibA0.bf index fbe84f0f..1be51f59 100644 --- a/IDEHelper/Tests/LibA/src/LibA0.bf +++ b/IDEHelper/Tests/LibA/src/LibA0.bf @@ -4,6 +4,19 @@ using System.Diagnostics; namespace LibA { + public interface ITaggable + { + public String Tag + { + get; + } + + public bool MatchesTag(String tag) + { + return Tag.Equals(tag); + } + } + struct LibAStruct { int mA; diff --git a/IDEHelper/Tests/src/Interfaces.bf b/IDEHelper/Tests/src/Interfaces.bf index 41b50068..b65a770b 100644 --- a/IDEHelper/Tests/src/Interfaces.bf +++ b/IDEHelper/Tests/src/Interfaces.bf @@ -405,6 +405,14 @@ namespace Tests public static String Serialize(Self value); } + public class EngineTag : LibA.ITaggable + { + public String Tag + { + get => "ET"; + } + } + [Test] public static void TestDefaults() {