mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
Fixed extension initializers and dtors. [NoExtension]. Extension warning
This commit is contained in:
parent
6e71cbc765
commit
b6db69d2b0
15 changed files with 235 additions and 64 deletions
|
@ -149,6 +149,12 @@ namespace System
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[AttributeUsage(.MemberAccess)]
|
||||||
|
public struct NoExtensionAttribute : Attribute
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
[AttributeUsage(.Block)]
|
[AttributeUsage(.Block)]
|
||||||
public struct IgnoreErrorsAttribute : Attribute
|
public struct IgnoreErrorsAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
|
@ -2949,7 +2949,7 @@ public:
|
||||||
BfTokenNode* mThisToken;
|
BfTokenNode* mThisToken;
|
||||||
|
|
||||||
BfTokenNode* mInitializerColonToken;
|
BfTokenNode* mInitializerColonToken;
|
||||||
BfInvocationExpression* mInitializer;
|
BfExpression* mInitializer;
|
||||||
|
|
||||||
}; BF_AST_DECL(BfConstructorDeclaration, BfMethodDeclaration);
|
}; BF_AST_DECL(BfConstructorDeclaration, BfMethodDeclaration);
|
||||||
|
|
||||||
|
|
|
@ -395,6 +395,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
||||||
mActionTypeDef = NULL;
|
mActionTypeDef = NULL;
|
||||||
mEnumTypeDef = NULL;
|
mEnumTypeDef = NULL;
|
||||||
mFriendAttributeTypeDef = NULL;
|
mFriendAttributeTypeDef = NULL;
|
||||||
|
mNoExtensionAttributeTypeDef = NULL;
|
||||||
mCheckedAttributeTypeDef = NULL;
|
mCheckedAttributeTypeDef = NULL;
|
||||||
mUncheckedAttributeTypeDef = NULL;
|
mUncheckedAttributeTypeDef = NULL;
|
||||||
mFunctionTypeDef = NULL;
|
mFunctionTypeDef = NULL;
|
||||||
|
@ -6491,14 +6492,14 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
||||||
return typeDef;
|
return typeDef;
|
||||||
};
|
};
|
||||||
|
|
||||||
mArray1TypeDef = _GetRequiredType("System.Array1", 1);
|
mArray1TypeDef = _GetRequiredType("System.Array1", 1);
|
||||||
mArray2TypeDef = _GetRequiredType("System.Array2", 1);
|
mArray2TypeDef = _GetRequiredType("System.Array2", 1);
|
||||||
mArray3TypeDef = _GetRequiredType("System.Array3", 1);
|
mArray3TypeDef = _GetRequiredType("System.Array3", 1);
|
||||||
mArray4TypeDef = _GetRequiredType("System.Array4", 1);
|
mArray4TypeDef = _GetRequiredType("System.Array4", 1);
|
||||||
mSpanTypeDef = _GetRequiredType("System.Span", 1);
|
mSpanTypeDef = _GetRequiredType("System.Span", 1);
|
||||||
mAttributeTypeDef = _GetRequiredType("System.Attribute");
|
mAttributeTypeDef = _GetRequiredType("System.Attribute");
|
||||||
mAttributeUsageAttributeTypeDef = _GetRequiredType("System.AttributeUsageAttribute");
|
mAttributeUsageAttributeTypeDef = _GetRequiredType("System.AttributeUsageAttribute");
|
||||||
mBfObjectTypeDef = _GetRequiredType("System.Object");
|
mBfObjectTypeDef = _GetRequiredType("System.Object");
|
||||||
mClassVDataTypeDef = _GetRequiredType("System.ClassVData");
|
mClassVDataTypeDef = _GetRequiredType("System.ClassVData");
|
||||||
mCLinkAttributeTypeDef = _GetRequiredType("System.CLinkAttribute");
|
mCLinkAttributeTypeDef = _GetRequiredType("System.CLinkAttribute");
|
||||||
mImportAttributeTypeDef = _GetRequiredType("System.ImportAttribute");
|
mImportAttributeTypeDef = _GetRequiredType("System.ImportAttribute");
|
||||||
|
@ -6516,6 +6517,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
||||||
mActionTypeDef = _GetRequiredType("System.Action");
|
mActionTypeDef = _GetRequiredType("System.Action");
|
||||||
mEnumTypeDef = _GetRequiredType("System.Enum");
|
mEnumTypeDef = _GetRequiredType("System.Enum");
|
||||||
mFriendAttributeTypeDef = _GetRequiredType("System.FriendAttribute");
|
mFriendAttributeTypeDef = _GetRequiredType("System.FriendAttribute");
|
||||||
|
mNoExtensionAttributeTypeDef = _GetRequiredType("System.NoExtensionAttribute");
|
||||||
mCheckedAttributeTypeDef = _GetRequiredType("System.CheckedAttribute");
|
mCheckedAttributeTypeDef = _GetRequiredType("System.CheckedAttribute");
|
||||||
mUncheckedAttributeTypeDef = _GetRequiredType("System.UncheckedAttribute");
|
mUncheckedAttributeTypeDef = _GetRequiredType("System.UncheckedAttribute");
|
||||||
mResultTypeDef = _GetRequiredType("System.Result", 1);
|
mResultTypeDef = _GetRequiredType("System.Result", 1);
|
||||||
|
|
|
@ -394,6 +394,7 @@ public:
|
||||||
BfTypeDef* mDisableChecksAttributeTypeDef;
|
BfTypeDef* mDisableChecksAttributeTypeDef;
|
||||||
BfTypeDef* mDisableObjectAccessChecksAttributeTypeDef;
|
BfTypeDef* mDisableObjectAccessChecksAttributeTypeDef;
|
||||||
BfTypeDef* mFriendAttributeTypeDef;
|
BfTypeDef* mFriendAttributeTypeDef;
|
||||||
|
BfTypeDef* mNoExtensionAttributeTypeDef;
|
||||||
BfTypeDef* mCheckedAttributeTypeDef;
|
BfTypeDef* mCheckedAttributeTypeDef;
|
||||||
BfTypeDef* mUncheckedAttributeTypeDef;
|
BfTypeDef* mUncheckedAttributeTypeDef;
|
||||||
BfTypeDef* mStaticInitAfterAttributeTypeDef;
|
BfTypeDef* mStaticInitAfterAttributeTypeDef;
|
||||||
|
|
|
@ -2008,8 +2008,10 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
||||||
|
|
||||||
if (mCurTypeDef->mTypeCode == BfTypeCode_TypeAlias)
|
if (mCurTypeDef->mTypeCode == BfTypeCode_TypeAlias)
|
||||||
needsDefaultCtor = false;
|
needsDefaultCtor = false;
|
||||||
|
if (mCurTypeDef->mTypeCode == BfTypeCode_Extension)
|
||||||
|
needsDefaultCtor = false;
|
||||||
|
|
||||||
if ((needsDefaultCtor) && (!hasDefaultCtor))
|
if ((needsDefaultCtor) && ((!hasDefaultCtor)))
|
||||||
{
|
{
|
||||||
BfProtection prot = hasCtor ? BfProtection_Hidden : BfProtection_Public;
|
BfProtection prot = hasCtor ? BfProtection_Hidden : BfProtection_Public;
|
||||||
if (mCurTypeDef->mName == mSystem->mEmptyAtom)
|
if (mCurTypeDef->mName == mSystem->mEmptyAtom)
|
||||||
|
|
|
@ -2167,6 +2167,13 @@ bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue targe
|
||||||
// if (checkMethod->mName != mMethodName)
|
// if (checkMethod->mName != mMethodName)
|
||||||
// continue;
|
// continue;
|
||||||
|
|
||||||
|
if ((checkMethod->mDeclaringType->IsExtension()) && (mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) &&
|
||||||
|
(mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mNoExtensionAttributeTypeDef)))
|
||||||
|
{
|
||||||
|
mModule->mAttributeState->mUsed = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!isDelegate)
|
if (!isDelegate)
|
||||||
{
|
{
|
||||||
if ((!curTypeInst->IsTypeMemberIncluded(checkMethod->mDeclaringType, activeTypeDef, mModule)) ||
|
if ((!curTypeInst->IsTypeMemberIncluded(checkMethod->mDeclaringType, activeTypeDef, mModule)) ||
|
||||||
|
@ -6408,8 +6415,15 @@ BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBou
|
||||||
if (checkMethod->mIsStatic)
|
if (checkMethod->mIsStatic)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!mModule->IsInSpecializedSection())
|
if ((checkMethod->mDeclaringType->IsExtension()) && (mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) &&
|
||||||
|
(mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mNoExtensionAttributeTypeDef)))
|
||||||
{
|
{
|
||||||
|
mModule->mAttributeState->mUsed = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mModule->IsInSpecializedSection())
|
||||||
|
{
|
||||||
if ((!curTypeInst->IsTypeMemberIncluded(checkMethod->mDeclaringType, activeTypeDef, mModule)) ||
|
if ((!curTypeInst->IsTypeMemberIncluded(checkMethod->mDeclaringType, activeTypeDef, mModule)) ||
|
||||||
(!curTypeInst->IsTypeMemberAccessible(checkMethod->mDeclaringType, visibleProjectSet)))
|
(!curTypeInst->IsTypeMemberAccessible(checkMethod->mDeclaringType, visibleProjectSet)))
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -14592,14 +14592,28 @@ BfTypedValue BfModule::CallBaseCtorCalc(bool constOnly)
|
||||||
{
|
{
|
||||||
// Any errors should only be shown in the actual CTOR call
|
// Any errors should only be shown in the actual CTOR call
|
||||||
SetAndRestoreValue<bool> prevIgnoreWrites(mIgnoreErrors, true);
|
SetAndRestoreValue<bool> prevIgnoreWrites(mIgnoreErrors, true);
|
||||||
|
|
||||||
auto methodDef = mCurMethodInstance->mMethodDef;
|
auto methodDef = mCurMethodInstance->mMethodDef;
|
||||||
BF_ASSERT((methodDef->mMethodType == BfMethodType_Ctor) || (methodDef->mMethodType == BfMethodType_CtorCalcAppend));
|
BF_ASSERT((methodDef->mMethodType == BfMethodType_Ctor) || (methodDef->mMethodType == BfMethodType_CtorCalcAppend));
|
||||||
auto ctorDeclaration = (BfConstructorDeclaration*)methodDef->mMethodDeclaration;
|
auto ctorDeclaration = (BfConstructorDeclaration*)methodDef->mMethodDeclaration;
|
||||||
BfTypeInstance* targetType = NULL;
|
|
||||||
if (ctorDeclaration->mInitializer != NULL)
|
BfCustomAttributes* customAttributes = NULL;
|
||||||
|
defer(delete customAttributes);
|
||||||
|
BfInvocationExpression* ctorInvocation = NULL;
|
||||||
|
if (ctorDeclaration != NULL)
|
||||||
{
|
{
|
||||||
auto targetToken = BfNodeDynCast<BfTokenNode>(ctorDeclaration->mInitializer->mTarget);
|
ctorInvocation = BfNodeDynCast<BfInvocationExpression>(ctorDeclaration->mInitializer);
|
||||||
|
if (auto attributedExpr = BfNodeDynCast<BfAttributedExpression>(ctorDeclaration->mInitializer))
|
||||||
|
{
|
||||||
|
ctorInvocation = BfNodeDynCast<BfInvocationExpression>(attributedExpr->mExpression);
|
||||||
|
customAttributes = GetCustomAttributes(attributedExpr->mAttributes, BfAttributeTargets_MemberAccess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BfTypeInstance* targetType = NULL;
|
||||||
|
if (ctorInvocation != NULL)
|
||||||
|
{
|
||||||
|
auto targetToken = BfNodeDynCast<BfTokenNode>(ctorInvocation->mTarget);
|
||||||
targetType = (targetToken->GetToken() == BfToken_This) ? mCurTypeInstance : mCurTypeInstance->mBaseType;
|
targetType = (targetToken->GetToken() == BfToken_This) ? mCurTypeInstance : mCurTypeInstance->mBaseType;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -14614,9 +14628,9 @@ BfTypedValue BfModule::CallBaseCtorCalc(bool constOnly)
|
||||||
|
|
||||||
BfExprEvaluator exprEvaluator(this);
|
BfExprEvaluator exprEvaluator(this);
|
||||||
BfResolvedArgs argValues;
|
BfResolvedArgs argValues;
|
||||||
if ((ctorDeclaration != NULL) && (ctorDeclaration->mInitializer != NULL))
|
if ((ctorDeclaration != NULL) && (ctorInvocation != NULL))
|
||||||
{
|
{
|
||||||
argValues.Init(&ctorDeclaration->mInitializer->mArguments);
|
argValues.Init(&ctorInvocation->mArguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -14670,7 +14684,7 @@ BfTypedValue BfModule::CallBaseCtorCalc(bool constOnly)
|
||||||
{
|
{
|
||||||
// Do it again, but without mIgnoreWrites set
|
// Do it again, but without mIgnoreWrites set
|
||||||
BfResolvedArgs argValues;
|
BfResolvedArgs argValues;
|
||||||
argValues.Init(&ctorDeclaration->mInitializer->mArguments);
|
argValues.Init(&ctorInvocation->mArguments);
|
||||||
exprEvaluator.ResolveArgValues(argValues, BfResolveArgFlag_DeferParamEval);
|
exprEvaluator.ResolveArgValues(argValues, BfResolveArgFlag_DeferParamEval);
|
||||||
|
|
||||||
BfFunctionBindResult bindResult;
|
BfFunctionBindResult bindResult;
|
||||||
|
@ -15445,13 +15459,31 @@ void BfModule::EmitCtorBody(bool& skipBody)
|
||||||
auto ctorDeclaration = (BfConstructorDeclaration*)methodDef->mMethodDeclaration;
|
auto ctorDeclaration = (BfConstructorDeclaration*)methodDef->mMethodDeclaration;
|
||||||
auto typeDef = mCurTypeInstance->mTypeDef;
|
auto typeDef = mCurTypeInstance->mTypeDef;
|
||||||
|
|
||||||
|
BfCustomAttributes* customAttributes = NULL;
|
||||||
|
defer(delete customAttributes);
|
||||||
|
BfInvocationExpression* ctorInvocation = NULL;
|
||||||
|
|
||||||
|
BfAttributeState attributeState;
|
||||||
|
attributeState.mTarget = BfAttributeTargets_MemberAccess;
|
||||||
|
if (ctorDeclaration != NULL)
|
||||||
|
{
|
||||||
|
ctorInvocation = BfNodeDynCast<BfInvocationExpression>(ctorDeclaration->mInitializer);
|
||||||
|
if (auto attributedExpr = BfNodeDynCast<BfAttributedExpression>(ctorDeclaration->mInitializer))
|
||||||
|
{
|
||||||
|
ctorInvocation = BfNodeDynCast<BfInvocationExpression>(attributedExpr->mExpression);
|
||||||
|
attributeState.mCustomAttributes = GetCustomAttributes(attributedExpr->mAttributes, attributeState.mTarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetAndRestoreValue<BfAttributeState*> prevAttributeState(mAttributeState, &attributeState);
|
||||||
|
|
||||||
// Prologue
|
// Prologue
|
||||||
mBfIRBuilder->ClearDebugLocation();
|
mBfIRBuilder->ClearDebugLocation();
|
||||||
|
|
||||||
bool hadThisInitializer = false;
|
bool hadThisInitializer = false;
|
||||||
if ((ctorDeclaration != NULL) && (ctorDeclaration->mInitializer != NULL))
|
if ((ctorDeclaration != NULL) && (ctorInvocation != NULL))
|
||||||
{
|
{
|
||||||
auto targetToken = BfNodeDynCast<BfTokenNode>(ctorDeclaration->mInitializer->mTarget);
|
auto targetToken = BfNodeDynCast<BfTokenNode>(ctorInvocation->mTarget);
|
||||||
auto targetType = (targetToken->GetToken() == BfToken_This) ? mCurTypeInstance : mCurTypeInstance->mBaseType;
|
auto targetType = (targetToken->GetToken() == BfToken_This) ? mCurTypeInstance : mCurTypeInstance->mBaseType;
|
||||||
if (targetToken->GetToken() == BfToken_This)
|
if (targetToken->GetToken() == BfToken_This)
|
||||||
{
|
{
|
||||||
|
@ -15480,8 +15512,8 @@ void BfModule::EmitCtorBody(bool& skipBody)
|
||||||
}
|
}
|
||||||
|
|
||||||
BfAstNode* baseCtorNode = NULL;
|
BfAstNode* baseCtorNode = NULL;
|
||||||
if ((ctorDeclaration != NULL) && (ctorDeclaration->mInitializer != NULL) && (ctorDeclaration->mInitializer->mTarget != NULL))
|
if ((ctorDeclaration != NULL) && (ctorInvocation != NULL) && (ctorInvocation->mTarget != NULL))
|
||||||
baseCtorNode = ctorDeclaration->mInitializer->mTarget;
|
baseCtorNode = ctorInvocation->mTarget;
|
||||||
else if (methodDef->mBody != NULL)
|
else if (methodDef->mBody != NULL)
|
||||||
baseCtorNode = methodDef->mBody;
|
baseCtorNode = methodDef->mBody;
|
||||||
else if (ctorDeclaration != NULL)
|
else if (ctorDeclaration != NULL)
|
||||||
|
@ -15493,10 +15525,12 @@ void BfModule::EmitCtorBody(bool& skipBody)
|
||||||
else
|
else
|
||||||
baseCtorNode = mContext->mBfObjectType->mTypeDef->mTypeDeclaration;
|
baseCtorNode = mContext->mBfObjectType->mTypeDef->mTypeDeclaration;
|
||||||
|
|
||||||
if ((!mCurTypeInstance->IsBoxed()) && (methodDef->mMethodType == BfMethodType_Ctor))
|
bool calledCtorNoBody = false;
|
||||||
|
|
||||||
|
if ((!mCurTypeInstance->IsBoxed()) && (methodDef->mMethodType == BfMethodType_Ctor) && (!hadThisInitializer))
|
||||||
{
|
{
|
||||||
// Call the root type's default ctor (with no body) to initialize its fields and call the chained ctors
|
// Call the root type's default ctor (with no body) to initialize its fields and call the chained ctors
|
||||||
if (methodDef->mDeclaringType->mTypeCode == BfTypeCode_Extension)
|
if (mCurTypeInstance->mTypeDef->mHasCtorNoBody)
|
||||||
{
|
{
|
||||||
BfMethodDef* defaultCtor = NULL;
|
BfMethodDef* defaultCtor = NULL;
|
||||||
|
|
||||||
|
@ -15520,6 +15554,8 @@ void BfModule::EmitCtorBody(bool& skipBody)
|
||||||
SizedArray<BfIRValue, 1> irArgs;
|
SizedArray<BfIRValue, 1> irArgs;
|
||||||
exprEvaluator.PushThis(NULL, GetThis(), moduleMethodInstance.mMethodInstance, irArgs);
|
exprEvaluator.PushThis(NULL, GetThis(), moduleMethodInstance.mMethodInstance, irArgs);
|
||||||
exprEvaluator.CreateCall(moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, false, irArgs);
|
exprEvaluator.CreateCall(moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, false, irArgs);
|
||||||
|
|
||||||
|
calledCtorNoBody = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15533,7 +15569,7 @@ void BfModule::EmitCtorBody(bool& skipBody)
|
||||||
{
|
{
|
||||||
// Field initializers occur in CtorNoBody methods for extensions
|
// Field initializers occur in CtorNoBody methods for extensions
|
||||||
}
|
}
|
||||||
else if (!hadThisInitializer)
|
else if ((!hadThisInitializer) && (!calledCtorNoBody))
|
||||||
{
|
{
|
||||||
// If we had a 'this' initializer, that other ctor will have initialized our fields
|
// If we had a 'this' initializer, that other ctor will have initialized our fields
|
||||||
|
|
||||||
|
@ -15711,9 +15747,9 @@ void BfModule::EmitCtorBody(bool& skipBody)
|
||||||
if (methodDef->mBody == NULL)
|
if (methodDef->mBody == NULL)
|
||||||
SetIllegalSrcPos();
|
SetIllegalSrcPos();
|
||||||
}
|
}
|
||||||
if ((ctorDeclaration != NULL) && (ctorDeclaration->mInitializer != NULL))
|
if ((ctorDeclaration != NULL) && (ctorInvocation != NULL))
|
||||||
{
|
{
|
||||||
auto targetToken = BfNodeDynCast<BfTokenNode>(ctorDeclaration->mInitializer->mTarget);
|
auto targetToken = BfNodeDynCast<BfTokenNode>(ctorInvocation->mTarget);
|
||||||
targetType = (targetToken->GetToken() == BfToken_This) ? mCurTypeInstance : mCurTypeInstance->mBaseType;
|
targetType = (targetToken->GetToken() == BfToken_This) ? mCurTypeInstance : mCurTypeInstance->mBaseType;
|
||||||
}
|
}
|
||||||
else if ((mCurTypeInstance->mBaseType != NULL) && (!mCurTypeInstance->IsUnspecializedType()))
|
else if ((mCurTypeInstance->mBaseType != NULL) && (!mCurTypeInstance->IsUnspecializedType()))
|
||||||
|
@ -15801,9 +15837,9 @@ void BfModule::EmitCtorBody(bool& skipBody)
|
||||||
mCurMethodState->mCurAppendAlign = methodInstance->mAppendAllocAlign;
|
mCurMethodState->mCurAppendAlign = methodInstance->mAppendAllocAlign;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ctorDeclaration != NULL) && (ctorDeclaration->mInitializer != NULL) && (ctorDeclaration->mInitializer->mArguments.size() == 1) && (targetType != NULL))
|
if ((ctorDeclaration != NULL) && (ctorInvocation != NULL) && (ctorInvocation->mArguments.size() == 1) && (targetType != NULL))
|
||||||
{
|
{
|
||||||
if (auto tokenNode = BfNodeDynCast<BfUninitializedExpression>(ctorDeclaration->mInitializer->mArguments[0]))
|
if (auto tokenNode = BfNodeDynCast<BfUninitializedExpression>(ctorInvocation->mArguments[0]))
|
||||||
{
|
{
|
||||||
if (targetType == mCurTypeInstance)
|
if (targetType == mCurTypeInstance)
|
||||||
{
|
{
|
||||||
|
@ -15829,9 +15865,9 @@ void BfModule::EmitCtorBody(bool& skipBody)
|
||||||
|
|
||||||
auto autoComplete = mCompiler->GetAutoComplete();
|
auto autoComplete = mCompiler->GetAutoComplete();
|
||||||
auto wasCapturingMethodInfo = (autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo);
|
auto wasCapturingMethodInfo = (autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo);
|
||||||
if ((autoComplete != NULL) && (ctorDeclaration != NULL) && (ctorDeclaration->mInitializer != NULL))
|
if ((autoComplete != NULL) && (ctorDeclaration != NULL) && (ctorInvocation != NULL))
|
||||||
{
|
{
|
||||||
auto invocationExpr = ctorDeclaration->mInitializer;
|
auto invocationExpr = ctorInvocation;
|
||||||
autoComplete->CheckInvocation(invocationExpr, invocationExpr->mOpenParen, invocationExpr->mCloseParen, invocationExpr->mCommas);
|
autoComplete->CheckInvocation(invocationExpr, invocationExpr->mOpenParen, invocationExpr->mCloseParen, invocationExpr->mCommas);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15839,9 +15875,9 @@ void BfModule::EmitCtorBody(bool& skipBody)
|
||||||
auto target = Cast(targetRefNode, GetThis(), targetThisType);
|
auto target = Cast(targetRefNode, GetThis(), targetThisType);
|
||||||
BfExprEvaluator exprEvaluator(this);
|
BfExprEvaluator exprEvaluator(this);
|
||||||
BfResolvedArgs argValues;
|
BfResolvedArgs argValues;
|
||||||
if ((ctorDeclaration != NULL) && (ctorDeclaration->mInitializer != NULL))
|
if ((ctorDeclaration != NULL) && (ctorInvocation != NULL))
|
||||||
{
|
{
|
||||||
argValues.Init(&ctorDeclaration->mInitializer->mArguments);
|
argValues.Init(&ctorInvocation->mArguments);
|
||||||
if (gDebugStuff)
|
if (gDebugStuff)
|
||||||
{
|
{
|
||||||
OutputDebugStrF("Expr: %@ %d\n", argValues.mArguments->mVals, argValues.mArguments->mSize);
|
OutputDebugStrF("Expr: %@ %d\n", argValues.mArguments->mVals, argValues.mArguments->mSize);
|
||||||
|
@ -21367,6 +21403,8 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
||||||
Fail("Interfaces cannot contain constructors", methodDeclaration);
|
Fail("Interfaces cannot contain constructors", methodDeclaration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool foundHiddenMethod = false;
|
||||||
|
|
||||||
// Don't compare specialized generic methods against normal methods
|
// Don't compare specialized generic methods against normal methods
|
||||||
if ((((mCurMethodInstance->mIsUnspecialized) || (mCurMethodInstance->mMethodDef->mGenericParams.size() == 0))) &&
|
if ((((mCurMethodInstance->mIsUnspecialized) || (mCurMethodInstance->mMethodDef->mGenericParams.size() == 0))) &&
|
||||||
(!methodDef->mIsLocalMethod))
|
(!methodDef->mIsLocalMethod))
|
||||||
|
@ -21436,7 +21474,8 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
||||||
if (!typeInstance->IsTypeMemberAccessible(checkMethod->mDeclaringType, methodDef->mDeclaringType))
|
if (!typeInstance->IsTypeMemberAccessible(checkMethod->mDeclaringType, methodDef->mDeclaringType))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bool silentlyAllow = false;
|
bool silentlyAllow = false;
|
||||||
|
bool extensionWarn = false;
|
||||||
if (checkMethod->mDeclaringType != methodDef->mDeclaringType)
|
if (checkMethod->mDeclaringType != methodDef->mDeclaringType)
|
||||||
{
|
{
|
||||||
if (typeInstance->IsInterface())
|
if (typeInstance->IsInterface())
|
||||||
|
@ -21445,7 +21484,21 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
||||||
silentlyAllow = true;
|
silentlyAllow = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
silentlyAllow = true;
|
{
|
||||||
|
if ((methodDef->mDeclaringType->mProject != checkMethod->mDeclaringType->mProject) &&
|
||||||
|
(!checkMethod->mDeclaringType->IsExtension()))
|
||||||
|
{
|
||||||
|
foundHiddenMethod = true;
|
||||||
|
if ((methodDef->mMethodType == BfMethodType_Ctor) && (methodDef->mIsStatic))
|
||||||
|
silentlyAllow = true;
|
||||||
|
else if (methodDef->mIsNew)
|
||||||
|
silentlyAllow = true;
|
||||||
|
else
|
||||||
|
extensionWarn = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
silentlyAllow = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((checkMethod->mCommutableKind == BfCommutableKind_Reverse) || (methodDef->mCommutableKind == BfCommutableKind_Reverse))
|
if ((checkMethod->mCommutableKind == BfCommutableKind_Reverse) || (methodDef->mCommutableKind == BfCommutableKind_Reverse))
|
||||||
|
@ -21456,7 +21509,13 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
||||||
if ((!methodDef->mName.IsEmpty()) || (checkMethodInstance->mMethodDef->mIsOperator))
|
if ((!methodDef->mName.IsEmpty()) || (checkMethodInstance->mMethodDef->mIsOperator))
|
||||||
{
|
{
|
||||||
auto refNode = methodDef->GetRefNode();
|
auto refNode = methodDef->GetRefNode();
|
||||||
auto bfError = Fail("Method already declared with the same parameter types", refNode, true);
|
BfError* bfError;
|
||||||
|
if (extensionWarn)
|
||||||
|
bfError = Warn(BfWarning_CS0114_MethodHidesInherited,
|
||||||
|
StrFormat("This method hides a method in the root type definition. Use the 'new' keyword if the hiding was intentional. Note that this method is not callable from project '%s'.",
|
||||||
|
checkMethod->mDeclaringType->mProject->mName.c_str()), refNode);
|
||||||
|
else
|
||||||
|
bfError = Fail("Method already declared with the same parameter types", refNode, true);
|
||||||
if (bfError != NULL)
|
if (bfError != NULL)
|
||||||
mCompiler->mPassInstance->MoreInfo("First declaration", checkMethod->GetRefNode());
|
mCompiler->mPassInstance->MoreInfo("First declaration", checkMethod->GetRefNode());
|
||||||
}
|
}
|
||||||
|
@ -21472,8 +21531,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
||||||
(!methodDef->mIsLocalMethod) &&
|
(!methodDef->mIsLocalMethod) &&
|
||||||
(!methodInstance->mIsForeignMethodDef) && (typeInstance->mBaseType != NULL) &&
|
(!methodInstance->mIsForeignMethodDef) && (typeInstance->mBaseType != NULL) &&
|
||||||
(methodDef->mMethodType == BfMethodType_Normal) && (methodDef->mMethodDeclaration != NULL))
|
(methodDef->mMethodType == BfMethodType_Normal) && (methodDef->mMethodDeclaration != NULL))
|
||||||
{
|
{
|
||||||
bool foundHiddenMethod = false;
|
|
||||||
auto baseType = typeInstance->mBaseType;
|
auto baseType = typeInstance->mBaseType;
|
||||||
while (baseType != NULL)
|
while (baseType != NULL)
|
||||||
{
|
{
|
||||||
|
@ -21623,12 +21681,7 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo
|
||||||
|
|
||||||
if (mCurTypeInstance->IsUnspecializedTypeVariation())
|
if (mCurTypeInstance->IsUnspecializedTypeVariation())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ((mCurTypeInstance->mTypeDef->mName->ToString() == "Zornk") && (methodInstance->mMethodDef->mName == "GCMarkMembers"))
|
|
||||||
{
|
|
||||||
NOP;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto _AddVirtualDecl = [&](BfMethodInstance* declMethodInstance)
|
auto _AddVirtualDecl = [&](BfMethodInstance* declMethodInstance)
|
||||||
{
|
{
|
||||||
if (!mCompiler->mOptions.mAllowHotSwapping)
|
if (!mCompiler->mOptions.mAllowHotSwapping)
|
||||||
|
@ -21956,13 +22009,17 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo
|
||||||
{
|
{
|
||||||
methodInstance->mVirtualTableIdx = virtualMethodMatchIdx;
|
methodInstance->mVirtualTableIdx = virtualMethodMatchIdx;
|
||||||
|
|
||||||
|
bool preferRootDefinition = (methodDef->mName == BF_METHODNAME_MARKMEMBERS) || (methodDef->mMethodType == BfMethodType_Dtor);
|
||||||
|
|
||||||
|
BfMethodInstance* setMethodInstance = methodInstance;
|
||||||
|
bool doOverride = false;
|
||||||
|
|
||||||
auto& overridenRef = typeInstance->mVirtualMethodTable[virtualMethodMatchIdx].mImplementingMethod;
|
auto& overridenRef = typeInstance->mVirtualMethodTable[virtualMethodMatchIdx].mImplementingMethod;
|
||||||
if (overridenRef.mKind != BfMethodRefKind_AmbiguousRef)
|
if (overridenRef.mKind != BfMethodRefKind_AmbiguousRef)
|
||||||
{
|
{
|
||||||
methodOverriden = overridenRef;
|
methodOverriden = overridenRef;
|
||||||
|
|
||||||
BfMethodInstance* setMethodInstance = methodInstance;
|
doOverride = true;
|
||||||
bool doOverride = true;
|
|
||||||
if (methodOverriden->GetOwner() == methodInstance->GetOwner())
|
if (methodOverriden->GetOwner() == methodInstance->GetOwner())
|
||||||
{
|
{
|
||||||
bool isBetter = false;
|
bool isBetter = false;
|
||||||
|
@ -21990,7 +22047,7 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo
|
||||||
|
|
||||||
if ((isBetter) && (methodInstance->GetOwner() == methodOverriden->GetOwner()))
|
if ((isBetter) && (methodInstance->GetOwner() == methodOverriden->GetOwner()))
|
||||||
{
|
{
|
||||||
if (methodDef->mName == BF_METHODNAME_MARKMEMBERS)
|
if (preferRootDefinition)
|
||||||
{
|
{
|
||||||
// Leave the master GCMarkMember
|
// Leave the master GCMarkMember
|
||||||
isBetter = false;
|
isBetter = false;
|
||||||
|
@ -22001,14 +22058,19 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo
|
||||||
doOverride = isBetter;
|
doOverride = isBetter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if ((preferRootDefinition) && (!methodDef->mDeclaringType->IsExtension()))
|
||||||
|
{
|
||||||
|
methodOverriden = overridenRef;
|
||||||
|
doOverride = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (doOverride)
|
if (doOverride)
|
||||||
{
|
{
|
||||||
auto declMethodInstance = (BfMethodInstance*)typeInstance->mVirtualMethodTable[virtualMethodMatchIdx].mDeclaringMethod;
|
auto declMethodInstance = (BfMethodInstance*)typeInstance->mVirtualMethodTable[virtualMethodMatchIdx].mDeclaringMethod;
|
||||||
_AddVirtualDecl(declMethodInstance);
|
_AddVirtualDecl(declMethodInstance);
|
||||||
setMethodInstance->mVirtualTableIdx = virtualMethodMatchIdx;
|
setMethodInstance->mVirtualTableIdx = virtualMethodMatchIdx;
|
||||||
typeInstance->mVirtualMethodTable[virtualMethodMatchIdx].mImplementingMethod = setMethodInstance;
|
typeInstance->mVirtualMethodTable[virtualMethodMatchIdx].mImplementingMethod = setMethodInstance;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9147,8 +9147,23 @@ bool BfReducer::ParseMethod(BfMethodDeclaration* methodDeclaration, SizedArrayIm
|
||||||
MEMBER_SET(ctorDecl, mInitializerColonToken, endToken);
|
MEMBER_SET(ctorDecl, mInitializerColonToken, endToken);
|
||||||
mVisitorPos.MoveNext();
|
mVisitorPos.MoveNext();
|
||||||
|
|
||||||
|
BfAstNode* invokeAfter = ctorDecl;
|
||||||
auto nextNode = mVisitorPos.GetNext();
|
auto nextNode = mVisitorPos.GetNext();
|
||||||
endToken = ExpectTokenAfter(ctorDecl, BfToken_This, BfToken_Base);
|
|
||||||
|
BfAttributeDirective* attributeDirective = NULL;
|
||||||
|
if (auto nextToken = BfNodeDynCast<BfTokenNode>(nextNode))
|
||||||
|
{
|
||||||
|
if (nextToken->mToken == BfToken_LBracket)
|
||||||
|
{
|
||||||
|
mVisitorPos.MoveNext();
|
||||||
|
attributeDirective = CreateAttributeDirective(nextToken);
|
||||||
|
nextNode = mVisitorPos.GetNext();
|
||||||
|
if (attributeDirective != NULL)
|
||||||
|
invokeAfter = attributeDirective;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
endToken = ExpectTokenAfter(invokeAfter, BfToken_This, BfToken_Base);
|
||||||
if (endToken != NULL)
|
if (endToken != NULL)
|
||||||
{
|
{
|
||||||
auto invocationExpr = CreateInvocationExpression(endToken);
|
auto invocationExpr = CreateInvocationExpression(endToken);
|
||||||
|
@ -9162,6 +9177,18 @@ bool BfReducer::ParseMethod(BfMethodDeclaration* methodDeclaration, SizedArrayIm
|
||||||
// In process of typing - just eat identifier so we don't error out on whole method
|
// In process of typing - just eat identifier so we don't error out on whole method
|
||||||
MoveNode(identifierAfter, ctorDecl);
|
MoveNode(identifierAfter, ctorDecl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (attributeDirective != NULL)
|
||||||
|
{
|
||||||
|
BfAttributedExpression* attribExpr = mAlloc->Alloc<BfAttributedExpression>();
|
||||||
|
ReplaceNode(attributeDirective, attribExpr);
|
||||||
|
attribExpr->mAttributes = attributeDirective;
|
||||||
|
if (ctorDecl->mInitializer != NULL)
|
||||||
|
{
|
||||||
|
MEMBER_SET(attribExpr, mExpression, ctorDecl->mInitializer);
|
||||||
|
}
|
||||||
|
MEMBER_SET(ctorDecl, mInitializer, attribExpr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
endToken = NULL;
|
endToken = NULL;
|
||||||
|
|
|
@ -2640,6 +2640,7 @@ void BfSystem::InjectNewRevision(BfTypeDef* typeDef)
|
||||||
typeDef->mIsConcrete = nextTypeDef->mIsConcrete;
|
typeDef->mIsConcrete = nextTypeDef->mIsConcrete;
|
||||||
typeDef->mIsStatic = nextTypeDef->mIsStatic;
|
typeDef->mIsStatic = nextTypeDef->mIsStatic;
|
||||||
typeDef->mHasAppendCtor = nextTypeDef->mHasAppendCtor;
|
typeDef->mHasAppendCtor = nextTypeDef->mHasAppendCtor;
|
||||||
|
typeDef->mHasCtorNoBody = nextTypeDef->mHasCtorNoBody;
|
||||||
typeDef->mHasOverrideMethods = nextTypeDef->mHasOverrideMethods;
|
typeDef->mHasOverrideMethods = nextTypeDef->mHasOverrideMethods;
|
||||||
typeDef->mHasExtensionMethods = nextTypeDef->mHasExtensionMethods;
|
typeDef->mHasExtensionMethods = nextTypeDef->mHasExtensionMethods;
|
||||||
typeDef->mIsOpaque = nextTypeDef->mIsOpaque;
|
typeDef->mIsOpaque = nextTypeDef->mIsOpaque;
|
||||||
|
@ -2744,6 +2745,7 @@ void BfSystem::AddToCompositePartial(BfPassInstance* passInstance, BfTypeDef* co
|
||||||
typeDef->mIsConcrete = partialTypeDef->mIsConcrete;
|
typeDef->mIsConcrete = partialTypeDef->mIsConcrete;
|
||||||
typeDef->mIsStatic = partialTypeDef->mIsStatic;
|
typeDef->mIsStatic = partialTypeDef->mIsStatic;
|
||||||
typeDef->mHasAppendCtor = partialTypeDef->mHasAppendCtor;
|
typeDef->mHasAppendCtor = partialTypeDef->mHasAppendCtor;
|
||||||
|
typeDef->mHasCtorNoBody = partialTypeDef->mHasCtorNoBody;
|
||||||
typeDef->mHasExtensionMethods = partialTypeDef->mHasExtensionMethods;
|
typeDef->mHasExtensionMethods = partialTypeDef->mHasExtensionMethods;
|
||||||
typeDef->mHasOverrideMethods = partialTypeDef->mHasOverrideMethods;
|
typeDef->mHasOverrideMethods = partialTypeDef->mHasOverrideMethods;
|
||||||
|
|
||||||
|
@ -2780,7 +2782,7 @@ void BfSystem::AddToCompositePartial(BfPassInstance* passInstance, BfTypeDef* co
|
||||||
typeDef->mIsAbstract |= partialTypeDef->mIsAbstract;
|
typeDef->mIsAbstract |= partialTypeDef->mIsAbstract;
|
||||||
typeDef->mIsConcrete |= partialTypeDef->mIsConcrete;
|
typeDef->mIsConcrete |= partialTypeDef->mIsConcrete;
|
||||||
typeDef->mIsStatic |= partialTypeDef->mIsStatic;
|
typeDef->mIsStatic |= partialTypeDef->mIsStatic;
|
||||||
typeDef->mHasAppendCtor |= partialTypeDef->mHasAppendCtor;
|
typeDef->mHasAppendCtor |= partialTypeDef->mHasAppendCtor;
|
||||||
typeDef->mHasExtensionMethods |= partialTypeDef->mHasExtensionMethods;
|
typeDef->mHasExtensionMethods |= partialTypeDef->mHasExtensionMethods;
|
||||||
typeDef->mHasOverrideMethods |= partialTypeDef->mHasOverrideMethods;
|
typeDef->mHasOverrideMethods |= partialTypeDef->mHasOverrideMethods;
|
||||||
typeDef->mProtection = BF_MIN(typeDef->mProtection, partialTypeDef->mProtection);
|
typeDef->mProtection = BF_MIN(typeDef->mProtection, partialTypeDef->mProtection);
|
||||||
|
@ -2956,6 +2958,7 @@ void BfSystem::FinishCompositePartial(BfTypeDef* compositeTypeDef)
|
||||||
anyHasFieldInitializers = true;
|
anyHasFieldInitializers = true;
|
||||||
if (!isExtension)
|
if (!isExtension)
|
||||||
primaryHasFieldInitializers = true;
|
primaryHasFieldInitializers = true;
|
||||||
|
nextRevision->mHasCtorNoBody = true;
|
||||||
auto methodDef = BfDefBuilder::AddMethod(nextRevision, BfMethodType_CtorNoBody, BfProtection_Protected, false, "");
|
auto methodDef = BfDefBuilder::AddMethod(nextRevision, BfMethodType_CtorNoBody, BfProtection_Protected, false, "");
|
||||||
methodDef->mDeclaringType = partialTypeDef;
|
methodDef->mDeclaringType = partialTypeDef;
|
||||||
methodDef->mIsMutating = true;
|
methodDef->mIsMutating = true;
|
||||||
|
@ -2964,6 +2967,7 @@ void BfSystem::FinishCompositePartial(BfTypeDef* compositeTypeDef)
|
||||||
|
|
||||||
if ((anyHasFieldInitializers) && (!primaryHasFieldInitializers))
|
if ((anyHasFieldInitializers) && (!primaryHasFieldInitializers))
|
||||||
{
|
{
|
||||||
|
nextRevision->mHasCtorNoBody = true;
|
||||||
auto methodDef = BfDefBuilder::AddMethod(nextRevision, BfMethodType_CtorNoBody, BfProtection_Protected, false, "");
|
auto methodDef = BfDefBuilder::AddMethod(nextRevision, BfMethodType_CtorNoBody, BfProtection_Protected, false, "");
|
||||||
methodDef->mDeclaringType = primaryDef;
|
methodDef->mDeclaringType = primaryDef;
|
||||||
methodDef->mIsMutating = true;
|
methodDef->mIsMutating = true;
|
||||||
|
@ -2991,6 +2995,7 @@ void BfSystem::FinishCompositePartial(BfTypeDef* compositeTypeDef)
|
||||||
|
|
||||||
if ((allHasMethods[0][0].mDtor == 0) && (allHasMethods[1][0].mDtor > 1))
|
if ((allHasMethods[0][0].mDtor == 0) && (allHasMethods[1][0].mDtor > 1))
|
||||||
{
|
{
|
||||||
|
nextRevision->mDtorDef = NULL;
|
||||||
auto methodDef = BfDefBuilder::AddMethod(nextRevision, BfMethodType_Dtor, BfProtection_Public, false, "");
|
auto methodDef = BfDefBuilder::AddMethod(nextRevision, BfMethodType_Dtor, BfProtection_Public, false, "");
|
||||||
methodDef->mDeclaringType = primaryDef;
|
methodDef->mDeclaringType = primaryDef;
|
||||||
}
|
}
|
||||||
|
|
|
@ -919,6 +919,7 @@ public:
|
||||||
bool mIsConcrete;
|
bool mIsConcrete;
|
||||||
bool mIsStatic;
|
bool mIsStatic;
|
||||||
bool mHasAppendCtor;
|
bool mHasAppendCtor;
|
||||||
|
bool mHasCtorNoBody;
|
||||||
bool mHasExtensionMethods;
|
bool mHasExtensionMethods;
|
||||||
bool mHasOverrideMethods;
|
bool mHasOverrideMethods;
|
||||||
bool mIsOpaque;
|
bool mIsOpaque;
|
||||||
|
@ -956,6 +957,7 @@ public:
|
||||||
mIsClosure = false;
|
mIsClosure = false;
|
||||||
mIsStatic = false;
|
mIsStatic = false;
|
||||||
mHasAppendCtor = false;
|
mHasAppendCtor = false;
|
||||||
|
mHasCtorNoBody = false;
|
||||||
mHasExtensionMethods = false;
|
mHasExtensionMethods = false;
|
||||||
mHasOverrideMethods = false;
|
mHasOverrideMethods = false;
|
||||||
mIsOpaque = false;
|
mIsOpaque = false;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace LibA
|
namespace LibA
|
||||||
{
|
{
|
||||||
|
@ -90,11 +91,18 @@ namespace LibA
|
||||||
|
|
||||||
class LibClassA
|
class LibClassA
|
||||||
{
|
{
|
||||||
public int32 mA = GetVal(7, "LibA.LibClassA.mA");
|
public int32 mA = GetVal(7, 10, "LibA.LibClassA.mA");
|
||||||
|
|
||||||
|
public static int32 sMagic = 1;
|
||||||
|
|
||||||
|
public static this()
|
||||||
|
{
|
||||||
|
sMagic += 10;
|
||||||
|
}
|
||||||
|
|
||||||
public this()
|
public this()
|
||||||
{
|
{
|
||||||
PrintF("LibA.LibClassA()\n");
|
Debug.WriteLine("LibA.LibClassA()\n");
|
||||||
mA += 100;
|
mA += 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,9 +111,15 @@ class LibClassA
|
||||||
mA += a;
|
mA += a;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int32 GetVal(int32 val, String str)
|
public ~this()
|
||||||
{
|
{
|
||||||
PrintF("GetVal: %s\n", str.CStr());
|
sMagic += 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int32 GetVal(int32 val, int32 magic, String str)
|
||||||
|
{
|
||||||
|
Debug.WriteLine("GetVal: {}", str);
|
||||||
|
sMagic += magic;
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,6 +132,11 @@ class LibClassA
|
||||||
{
|
{
|
||||||
return 30;
|
return 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static LibClassA Create()
|
||||||
|
{
|
||||||
|
return new LibClassA();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LibClassB
|
class LibClassB
|
||||||
|
|
|
@ -14,15 +14,25 @@ namespace LibB
|
||||||
|
|
||||||
extension LibClassA
|
extension LibClassA
|
||||||
{
|
{
|
||||||
public int32 mB = GetVal(8, "LibB.LibClassA.mB");
|
public int32 mB = GetVal(8, 100, "LibB.LibClassA.mB");
|
||||||
|
|
||||||
public this()
|
public static this()
|
||||||
|
{
|
||||||
|
sMagic += 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ~this()
|
||||||
|
{
|
||||||
|
sMagic += 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
public new this() : [NoExtension]this()
|
||||||
{
|
{
|
||||||
PrintF("LibB.LibClassA()\n");
|
PrintF("LibB.LibClassA()\n");
|
||||||
mB += 100;
|
mB += 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
public this(int32 a)
|
public new this(int32 a)
|
||||||
{
|
{
|
||||||
PrintF("LibB.LibClassA(int32)\n");
|
PrintF("LibB.LibClassA(int32)\n");
|
||||||
mB += 1000;
|
mB += 1000;
|
||||||
|
|
|
@ -12,7 +12,17 @@ namespace LibC
|
||||||
|
|
||||||
extension LibClassA
|
extension LibClassA
|
||||||
{
|
{
|
||||||
public int32 mB = GetVal(13, "LibC.LibClassA.mB");
|
public int32 mB = GetVal(13, 1000, "LibC.LibClassA.mB");
|
||||||
|
|
||||||
|
public static this()
|
||||||
|
{
|
||||||
|
sMagic += 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ~this()
|
||||||
|
{
|
||||||
|
sMagic += 2000;
|
||||||
|
}
|
||||||
|
|
||||||
public this(int8 i8)
|
public this(int8 i8)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,15 +2,15 @@ using System;
|
||||||
|
|
||||||
extension LibClassA
|
extension LibClassA
|
||||||
{
|
{
|
||||||
public int32 mC = GetVal(9, "TestsB.LibClassA.mC");
|
public int32 mC = GetVal(9, 10000, "TestsB.LibClassA.mC");
|
||||||
|
|
||||||
public this()
|
public new this()
|
||||||
{
|
{
|
||||||
PrintF("TestB.LibClassA()\n");
|
PrintF("TestB.LibClassA()\n");
|
||||||
mB += 10000;
|
mB += 10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetVal2()
|
public new int GetVal2()
|
||||||
{
|
{
|
||||||
return 11;
|
return 11;
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,21 +227,32 @@ namespace Tests
|
||||||
[Test]
|
[Test]
|
||||||
public static void TestSharedData()
|
public static void TestSharedData()
|
||||||
{
|
{
|
||||||
|
Test.Assert(LibClassA.sMagic == 1111);
|
||||||
|
|
||||||
LibClassA ca = scope LibClassA();
|
LibClassA ca = scope LibClassA();
|
||||||
Test.Assert(ca.mA == 7);
|
Test.Assert(LibClassA.sMagic == 2221);
|
||||||
|
Test.Assert(ca.mA == 107);
|
||||||
Test.Assert(ca.LibB_GetB() == 108);
|
Test.Assert(ca.LibB_GetB() == 108);
|
||||||
Test.Assert(ca.LibC_GetB() == 13);
|
Test.Assert(ca.LibC_GetB() == 13);
|
||||||
Test.Assert(ca.GetVal2() == 9);
|
Test.Assert(ca.GetVal2() == 9);
|
||||||
|
|
||||||
ca = scope LibClassA(12345);
|
ca = scope LibClassA(12345);
|
||||||
|
Test.Assert(LibClassA.sMagic == 3331);
|
||||||
Test.Assert(ca.mA == 7);
|
Test.Assert(ca.mA == 7);
|
||||||
Test.Assert(ca.LibB_GetB() == 1008);
|
Test.Assert(ca.LibB_GetB() == 1008);
|
||||||
Test.Assert(ca.LibC_GetB() == 13);
|
Test.Assert(ca.LibC_GetB() == 13);
|
||||||
|
|
||||||
ca = scope LibClassA((int8)2);
|
ca = scope LibClassA((int8)2);
|
||||||
|
Test.Assert(LibClassA.sMagic == 4441);
|
||||||
Test.Assert(ca.mA == 7);
|
Test.Assert(ca.mA == 7);
|
||||||
Test.Assert(ca.LibB_GetB() == 8);
|
Test.Assert(ca.LibB_GetB() == 8);
|
||||||
Test.Assert(ca.LibC_GetB() == 30013);
|
Test.Assert(ca.LibC_GetB() == 30013);
|
||||||
|
|
||||||
|
ca = LibClassA.Create();
|
||||||
|
Test.Assert(LibClassA.sMagic == 5551);
|
||||||
|
Test.Assert(ca.mA == 107);
|
||||||
|
delete ca;
|
||||||
|
Test.Assert(LibClassA.sMagic == 7771);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue