mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-11 04:52:21 +02:00
Added 'visibleProjectSet', changed visibility rules for generics
This commit is contained in:
parent
6021518343
commit
75dd1a4213
6 changed files with 100 additions and 25 deletions
|
@ -612,11 +612,6 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
|
||||||
bool prevChainSkip = (prevMethodInstance->mChainType == BfMethodChainType_ChainMember) || (prevMethodInstance->mChainType == BfMethodChainType_ChainSkip);
|
bool prevChainSkip = (prevMethodInstance->mChainType == BfMethodChainType_ChainMember) || (prevMethodInstance->mChainType == BfMethodChainType_ChainSkip);
|
||||||
RETURN_BETTER_OR_WORSE(!chainSkip, !prevChainSkip);
|
RETURN_BETTER_OR_WORSE(!chainSkip, !prevChainSkip);
|
||||||
|
|
||||||
// If one of these methods is local to the current extension then choose that one
|
|
||||||
auto activeDef = mModule->GetActiveTypeDef();
|
|
||||||
RETURN_BETTER_OR_WORSE(newMethodDef->mDeclaringType == activeDef, prevMethodDef->mDeclaringType == activeDef);
|
|
||||||
RETURN_BETTER_OR_WORSE(newMethodDef->mDeclaringType->IsExtension(), prevMethodDef->mDeclaringType->IsExtension());
|
|
||||||
|
|
||||||
if ((!isBetter) && (!isWorse))
|
if ((!isBetter) && (!isWorse))
|
||||||
{
|
{
|
||||||
bool betterByGenericParam = false;
|
bool betterByGenericParam = false;
|
||||||
|
@ -948,6 +943,11 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
|
||||||
RETURN_BETTER_OR_WORSE(newMethodDef->mCheckedKind == mCheckedKind, prevMethodDef->mCheckedKind == mCheckedKind);
|
RETURN_BETTER_OR_WORSE(newMethodDef->mCheckedKind == mCheckedKind, prevMethodDef->mCheckedKind == mCheckedKind);
|
||||||
RETURN_BETTER_OR_WORSE(newMethodDef->mCommutableKind != BfCommutableKind_Reverse, prevMethodDef->mCommutableKind != BfCommutableKind_Reverse);
|
RETURN_BETTER_OR_WORSE(newMethodDef->mCommutableKind != BfCommutableKind_Reverse, prevMethodDef->mCommutableKind != BfCommutableKind_Reverse);
|
||||||
|
|
||||||
|
// If one of these methods is local to the current extension then choose that one
|
||||||
|
auto activeDef = mModule->GetActiveTypeDef();
|
||||||
|
RETURN_BETTER_OR_WORSE(newMethodDef->mDeclaringType == activeDef, prevMethodDef->mDeclaringType == activeDef);
|
||||||
|
RETURN_BETTER_OR_WORSE(newMethodDef->mDeclaringType->IsExtension(), prevMethodDef->mDeclaringType->IsExtension());
|
||||||
|
|
||||||
RETURN_RESULTS;
|
RETURN_RESULTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1878,6 +1878,11 @@ bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue targe
|
||||||
|
|
||||||
int checkInterfaceIdx = 0;
|
int checkInterfaceIdx = 0;
|
||||||
|
|
||||||
|
if (mMethodName == "Handle")
|
||||||
|
{
|
||||||
|
NOP;
|
||||||
|
}
|
||||||
|
|
||||||
bool targetIsBase = target.IsBase();
|
bool targetIsBase = target.IsBase();
|
||||||
bool checkExtensionBase = false;
|
bool checkExtensionBase = false;
|
||||||
if (targetIsBase)
|
if (targetIsBase)
|
||||||
|
@ -1915,6 +1920,7 @@ bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue targe
|
||||||
{
|
{
|
||||||
bool allowExplicitInterface = curTypeInst->IsInterface() && mBypassVirtual;
|
bool allowExplicitInterface = curTypeInst->IsInterface() && mBypassVirtual;
|
||||||
auto activeTypeDef = mModule->GetActiveTypeDef();
|
auto activeTypeDef = mModule->GetActiveTypeDef();
|
||||||
|
auto visibleProjectSet = mModule->GetVisibleProjectSet();
|
||||||
bool isDelegate = typeInstance->IsDelegate();
|
bool isDelegate = typeInstance->IsDelegate();
|
||||||
|
|
||||||
auto checkMethod = nextMethodDef;
|
auto checkMethod = nextMethodDef;
|
||||||
|
@ -1970,7 +1976,7 @@ bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue targe
|
||||||
if (!isDelegate)
|
if (!isDelegate)
|
||||||
{
|
{
|
||||||
if ((!curTypeInst->IsTypeMemberIncluded(checkMethod->mDeclaringType, activeTypeDef, mModule)) ||
|
if ((!curTypeInst->IsTypeMemberIncluded(checkMethod->mDeclaringType, activeTypeDef, mModule)) ||
|
||||||
(!curTypeInst->IsTypeMemberAccessible(checkMethod->mDeclaringType, activeTypeDef)))
|
(!curTypeInst->IsTypeMemberAccessible(checkMethod->mDeclaringType, visibleProjectSet)))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5353,9 +5359,11 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
||||||
if (!target)
|
if (!target)
|
||||||
{
|
{
|
||||||
FinishDeferredEvals(argValues);
|
FinishDeferredEvals(argValues);
|
||||||
mModule->Fail(StrFormat("An instance reference is required to %s the non-static method '%s'",
|
auto error = mModule->Fail(StrFormat("An instance reference is required to %s the non-static method '%s'",
|
||||||
(prevBindResult.mPrevVal != NULL) ? "bind" : "invoke",
|
(prevBindResult.mPrevVal != NULL) ? "bind" : "invoke",
|
||||||
mModule->MethodToString(methodInstance).c_str()), targetSrc);
|
mModule->MethodToString(methodInstance).c_str()), targetSrc);
|
||||||
|
if ((error != NULL) && (methodInstance->mMethodDef->GetRefNode() != NULL))
|
||||||
|
mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
|
||||||
return mModule->GetDefaultTypedValue(returnType);
|
return mModule->GetDefaultTypedValue(returnType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6023,6 +6031,7 @@ BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBou
|
||||||
BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None;
|
BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None;
|
||||||
|
|
||||||
auto activeTypeDef = mModule->GetActiveTypeDef();
|
auto activeTypeDef = mModule->GetActiveTypeDef();
|
||||||
|
auto visibleProjectSet = mModule->GetVisibleProjectSet();
|
||||||
bool isFailurePass = false;
|
bool isFailurePass = false;
|
||||||
for (int pass = 0; pass < 2; pass++)
|
for (int pass = 0; pass < 2; pass++)
|
||||||
{
|
{
|
||||||
|
@ -6047,7 +6056,7 @@ BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBou
|
||||||
if (!mModule->IsInSpecializedSection())
|
if (!mModule->IsInSpecializedSection())
|
||||||
{
|
{
|
||||||
if ((!curTypeInst->IsTypeMemberIncluded(checkMethod->mDeclaringType, activeTypeDef, mModule)) ||
|
if ((!curTypeInst->IsTypeMemberIncluded(checkMethod->mDeclaringType, activeTypeDef, mModule)) ||
|
||||||
(!curTypeInst->IsTypeMemberAccessible(checkMethod->mDeclaringType, activeTypeDef)))
|
(!curTypeInst->IsTypeMemberAccessible(checkMethod->mDeclaringType, visibleProjectSet)))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7252,9 +7261,6 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
||||||
isFailurePass = false;
|
isFailurePass = false;
|
||||||
curTypeInst = methodMatcher.mBestMethodTypeInstance;
|
curTypeInst = methodMatcher.mBestMethodTypeInstance;
|
||||||
methodDef = methodMatcher.mBestMethodDef;
|
methodDef = methodMatcher.mBestMethodDef;
|
||||||
// Extension check must check all possible extensions, no early bailout
|
|
||||||
if (!wantsExtensionCheck)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7274,9 +7280,6 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
||||||
isFailurePass = false;
|
isFailurePass = false;
|
||||||
curTypeInst = methodMatcher.mBestMethodTypeInstance;
|
curTypeInst = methodMatcher.mBestMethodTypeInstance;
|
||||||
methodDef = methodMatcher.mBestMethodDef;
|
methodDef = methodMatcher.mBestMethodDef;
|
||||||
// Extension check must check all possible extensions, no early bailout
|
|
||||||
if (!wantsExtensionCheck)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13324,16 +13327,20 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
|
||||||
|
|
||||||
if (!target)
|
if (!target)
|
||||||
{
|
{
|
||||||
mModule->Fail(StrFormat("An instance reference is required to invoke the non-static mixin '%s'",
|
BfError* error = mModule->Fail(StrFormat("An instance reference is required to invoke the non-static mixin '%s'",
|
||||||
mModule->MethodToString(methodInstance).c_str()), targetSrc);
|
mModule->MethodToString(methodInstance).c_str()), targetSrc);
|
||||||
|
if ((error != NULL) && (methodInstance->mMethodDef->GetRefNode() != NULL))
|
||||||
|
mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (target)
|
if (target)
|
||||||
{
|
{
|
||||||
mModule->Fail(StrFormat("Mixin '%s' cannot be accessed with an instance reference; qualify it with a type name instead",
|
BfError* error = mModule->Fail(StrFormat("Mixin '%s' cannot be accessed with an instance reference; qualify it with a type name instead",
|
||||||
mModule->MethodToString(methodInstance).c_str()), targetSrc);
|
mModule->MethodToString(methodInstance).c_str()), targetSrc);
|
||||||
|
if ((error != NULL) && (methodInstance->mMethodDef->GetRefNode() != NULL))
|
||||||
|
mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13354,14 +13361,14 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
|
||||||
if ((int)args.size() < explicitParamCount)
|
if ((int)args.size() < explicitParamCount)
|
||||||
{
|
{
|
||||||
BfError* error = mModule->Fail(StrFormat("Not enough arguments specified, expected %d more.", explicitParamCount - (int)arguments.size()), targetSrc);
|
BfError* error = mModule->Fail(StrFormat("Not enough arguments specified, expected %d more.", explicitParamCount - (int)arguments.size()), targetSrc);
|
||||||
if ((error != NULL) && (methodInstance->mMethodDef->mMethodDeclaration != NULL))
|
if ((error != NULL) && (methodInstance->mMethodDef->GetRefNode() != NULL))
|
||||||
mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
|
mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if ((int)args.size() > explicitParamCount)
|
else if ((int)args.size() > explicitParamCount)
|
||||||
{
|
{
|
||||||
BfError* error = mModule->Fail(StrFormat("Too many arguments specified, expected %d fewer.", (int)arguments.size() - explicitParamCount), targetSrc);
|
BfError* error = mModule->Fail(StrFormat("Too many arguments specified, expected %d fewer.", (int)arguments.size() - explicitParamCount), targetSrc);
|
||||||
if ((error != NULL) && (methodInstance->mMethodDef->mMethodDeclaration != NULL))
|
if ((error != NULL) && (methodInstance->mMethodDef->GetRefNode() != NULL))
|
||||||
mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
|
mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2204,6 +2204,62 @@ void BfModule::ValueScopeEnd(BfIRValue valueScopeStart)
|
||||||
mBfIRBuilder->CreateValueScopeHardEnd(valueScopeStart);
|
mBfIRBuilder->CreateValueScopeHardEnd(valueScopeStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BfProjectSet* BfModule::GetVisibleProjectSet()
|
||||||
|
{
|
||||||
|
if (mCurMethodState == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (mCurMethodState->mVisibleProjectSet.IsEmpty())
|
||||||
|
{
|
||||||
|
HashSet<BfType*> seenTypes;
|
||||||
|
|
||||||
|
std::function<void(BfProject* project)> _AddProject = [&](BfProject* project)
|
||||||
|
{
|
||||||
|
if (mCurMethodState->mVisibleProjectSet.Add(project))
|
||||||
|
{
|
||||||
|
for (auto dep : project->mDependencies)
|
||||||
|
_AddProject(dep);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::function<void(BfType* type)> _AddType = [&](BfType* type)
|
||||||
|
{
|
||||||
|
auto typeInstance = type->ToTypeInstance();
|
||||||
|
if (typeInstance == NULL)
|
||||||
|
return;
|
||||||
|
_AddProject(typeInstance->mTypeDef->mProject);
|
||||||
|
if (typeInstance->mGenericTypeInfo == NULL)
|
||||||
|
return;
|
||||||
|
for (auto type : typeInstance->mGenericTypeInfo->mTypeGenericArguments)
|
||||||
|
{
|
||||||
|
if (seenTypes.Add(type))
|
||||||
|
_AddType(type);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (mCurTypeInstance != NULL)
|
||||||
|
_AddType(mCurTypeInstance);
|
||||||
|
|
||||||
|
auto methodState = mCurMethodState;
|
||||||
|
while (methodState != NULL)
|
||||||
|
{
|
||||||
|
if (methodState->mMethodInstance != NULL)
|
||||||
|
{
|
||||||
|
_AddProject(methodState->mMethodInstance->mMethodDef->mDeclaringType->mProject);
|
||||||
|
if (methodState->mMethodInstance->mMethodInfoEx != NULL)
|
||||||
|
{
|
||||||
|
for (auto type : methodState->mMethodInstance->mMethodInfoEx->mMethodGenericArguments)
|
||||||
|
_AddType(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
methodState = methodState->mPrevMethodState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &mCurMethodState->mVisibleProjectSet;
|
||||||
|
}
|
||||||
|
|
||||||
BfFileInstance* BfModule::GetFileFromNode(BfAstNode* astNode)
|
BfFileInstance* BfModule::GetFileFromNode(BfAstNode* astNode)
|
||||||
{
|
{
|
||||||
auto bfParser = astNode->GetSourceData()->ToParserData();
|
auto bfParser = astNode->GetSourceData()->ToParserData();
|
||||||
|
|
|
@ -895,6 +895,7 @@ public:
|
||||||
Array<BfLambdaInstance*> mDeferredLambdaInstances;
|
Array<BfLambdaInstance*> mDeferredLambdaInstances;
|
||||||
Array<BfIRValue> mSplatDecompAddrs;
|
Array<BfIRValue> mSplatDecompAddrs;
|
||||||
BfDeferredLocalAssignData* mDeferredLocalAssignData;
|
BfDeferredLocalAssignData* mDeferredLocalAssignData;
|
||||||
|
BfProjectSet mVisibleProjectSet;
|
||||||
int mDeferredLoopListCount;
|
int mDeferredLoopListCount;
|
||||||
int mDeferredLoopListEntryCount;
|
int mDeferredLoopListEntryCount;
|
||||||
HashSet<int> mSkipObjectAccessChecks; // Indexed by BfIRValue value id
|
HashSet<int> mSkipObjectAccessChecks; // Indexed by BfIRValue value id
|
||||||
|
@ -1468,6 +1469,7 @@ public:
|
||||||
void SaveStackState(BfScopeData* scope);
|
void SaveStackState(BfScopeData* scope);
|
||||||
BfIRValue ValueScopeStart();
|
BfIRValue ValueScopeStart();
|
||||||
void ValueScopeEnd(BfIRValue valueScopeStart);
|
void ValueScopeEnd(BfIRValue valueScopeStart);
|
||||||
|
BfProjectSet* GetVisibleProjectSet();
|
||||||
|
|
||||||
void AddBasicBlock(BfIRBlock bb, bool activate = true);
|
void AddBasicBlock(BfIRBlock bb, bool activate = true);
|
||||||
void VisitEmbeddedStatement(BfAstNode* stmt, BfExprEvaluator* exprEvaluator = NULL, BfEmbeddedStatementFlags flags = BfEmbeddedStatementFlags_None);
|
void VisitEmbeddedStatement(BfAstNode* stmt, BfExprEvaluator* exprEvaluator = NULL, BfEmbeddedStatementFlags flags = BfEmbeddedStatementFlags_None);
|
||||||
|
|
|
@ -1698,6 +1698,13 @@ bool BfTypeInstance::IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfProje
|
||||||
return curProject->ContainsReference(declaringTypeDef->mProject);
|
return curProject->ContainsReference(declaringTypeDef->mProject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BfTypeInstance::IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfProjectSet* visibleProjectSet)
|
||||||
|
{
|
||||||
|
if (visibleProjectSet == NULL)
|
||||||
|
return false;
|
||||||
|
return visibleProjectSet->Contains(declaringTypeDef->mProject);
|
||||||
|
}
|
||||||
|
|
||||||
bool BfTypeInstance::WantsGCMarking()
|
bool BfTypeInstance::WantsGCMarking()
|
||||||
{
|
{
|
||||||
if (IsObjectOrInterface())
|
if (IsObjectOrInterface())
|
||||||
|
|
|
@ -553,6 +553,7 @@ public:
|
||||||
virtual bool IsTypeMemberIncluded(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef = NULL, BfModule* module = NULL) { return true; } // May be 'false' only for generic extensions with constraints
|
virtual bool IsTypeMemberIncluded(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef = NULL, BfModule* module = NULL) { return true; } // May be 'false' only for generic extensions with constraints
|
||||||
virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef) { return true; }
|
virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef) { return true; }
|
||||||
virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfProject* curProject) { return true; }
|
virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfProject* curProject) { return true; }
|
||||||
|
virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfProjectSet* visibleProjectSet) { return true; }
|
||||||
|
|
||||||
virtual void ReportMemory(MemReporter* memReporter);
|
virtual void ReportMemory(MemReporter* memReporter);
|
||||||
};
|
};
|
||||||
|
@ -1836,6 +1837,7 @@ public:
|
||||||
virtual bool HasPackingHoles() override { return mHasPackingHoles; }
|
virtual bool HasPackingHoles() override { return mHasPackingHoles; }
|
||||||
virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef) override;
|
virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef) override;
|
||||||
virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfProject* curProject) override;
|
virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfProject* curProject) override;
|
||||||
|
virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfProjectSet* visibleProjectSet) override;
|
||||||
virtual bool WantsGCMarking() override;
|
virtual bool WantsGCMarking() override;
|
||||||
virtual bool GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCode = NULL, BfTypeCode* outTypeCode2 = NULL) override;
|
virtual bool GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCode = NULL, BfTypeCode* outTypeCode2 = NULL) override;
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@ class BfProject;
|
||||||
|
|
||||||
struct BfTypeDefMapFuncs;
|
struct BfTypeDefMapFuncs;
|
||||||
typedef MultiHashSet<BfTypeDef*, BfTypeDefMapFuncs> BfTypeDefMap;
|
typedef MultiHashSet<BfTypeDef*, BfTypeDefMapFuncs> BfTypeDefMap;
|
||||||
|
typedef HashSet<BfProject*> BfProjectSet;
|
||||||
|
|
||||||
class BfAtom
|
class BfAtom
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue