mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
Fixes for type initializer blocks
This commit is contained in:
parent
9cd47a784b
commit
34dcd47dd5
6 changed files with 98 additions and 11 deletions
|
@ -14952,6 +14952,8 @@ void BfModule::EmitDtorBody()
|
||||||
{
|
{
|
||||||
if (methodDeclaration != NULL)
|
if (methodDeclaration != NULL)
|
||||||
UpdateSrcPos(methodDeclaration);
|
UpdateSrcPos(methodDeclaration);
|
||||||
|
else if ((methodDef->mDeclaringType != NULL) && (methodDef->mDeclaringType->GetRefNode() != NULL))
|
||||||
|
UpdateSrcPos(methodDef->mDeclaringType->GetRefNode());
|
||||||
else if (typeDef->mTypeDeclaration != NULL)
|
else if (typeDef->mTypeDeclaration != NULL)
|
||||||
UpdateSrcPos(typeDef->mTypeDeclaration);
|
UpdateSrcPos(typeDef->mTypeDeclaration);
|
||||||
if ((methodDeclaration != NULL) && (methodDeclaration->mFatArrowToken != NULL))
|
if ((methodDeclaration != NULL) && (methodDeclaration->mFatArrowToken != NULL))
|
||||||
|
@ -15594,6 +15596,8 @@ void BfModule::EmitCtorBody(bool& skipBody)
|
||||||
baseCtorNode = methodDef->mBody;
|
baseCtorNode = methodDef->mBody;
|
||||||
else if (ctorDeclaration != NULL)
|
else if (ctorDeclaration != NULL)
|
||||||
baseCtorNode = ctorDeclaration;
|
baseCtorNode = ctorDeclaration;
|
||||||
|
else if ((methodDef->mDeclaringType != NULL) && (methodDef->mDeclaringType->GetRefNode() != NULL))
|
||||||
|
baseCtorNode = methodDef->mDeclaringType->GetRefNode();
|
||||||
else if (mCurTypeInstance->mTypeDef->mTypeDeclaration != NULL)
|
else if (mCurTypeInstance->mTypeDef->mTypeDeclaration != NULL)
|
||||||
baseCtorNode = mCurTypeInstance->mTypeDef->mTypeDeclaration->mNameNode;
|
baseCtorNode = mCurTypeInstance->mTypeDef->mTypeDeclaration->mNameNode;
|
||||||
else if ((mCurTypeInstance->mBaseType != NULL) && (mCurTypeInstance->mBaseType->mTypeDef->mTypeDeclaration != NULL))
|
else if ((mCurTypeInstance->mBaseType != NULL) && (mCurTypeInstance->mBaseType->mTypeDef->mTypeDeclaration != NULL))
|
||||||
|
@ -15604,7 +15608,7 @@ void BfModule::EmitCtorBody(bool& skipBody)
|
||||||
bool calledCtorNoBody = false;
|
bool calledCtorNoBody = false;
|
||||||
|
|
||||||
if ((!mCurTypeInstance->IsBoxed()) && (methodDef->mMethodType == BfMethodType_Ctor) && (!hadThisInitializer))
|
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 (mCurTypeInstance->mTypeDef->mHasCtorNoBody)
|
if (mCurTypeInstance->mTypeDef->mHasCtorNoBody)
|
||||||
{
|
{
|
||||||
|
@ -17572,7 +17576,9 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
||||||
if (methodDef->mBody != NULL)
|
if (methodDef->mBody != NULL)
|
||||||
UpdateSrcPos(methodDef->mBody, BfSrcPosFlag_NoSetDebugLoc);
|
UpdateSrcPos(methodDef->mBody, BfSrcPosFlag_NoSetDebugLoc);
|
||||||
else if (methodDeclaration != NULL)
|
else if (methodDeclaration != NULL)
|
||||||
UpdateSrcPos(methodDeclaration, BfSrcPosFlag_NoSetDebugLoc);
|
UpdateSrcPos(methodDeclaration, BfSrcPosFlag_NoSetDebugLoc);
|
||||||
|
else if ((methodDef->mDeclaringType != NULL) && (methodDef->mDeclaringType->GetRefNode() != NULL))
|
||||||
|
UpdateSrcPos(methodDef->mDeclaringType->GetRefNode(), BfSrcPosFlag_NoSetDebugLoc);
|
||||||
else if (mCurTypeInstance->mTypeDef->mTypeDeclaration != NULL)
|
else if (mCurTypeInstance->mTypeDef->mTypeDeclaration != NULL)
|
||||||
UpdateSrcPos(mCurTypeInstance->mTypeDef->mTypeDeclaration, BfSrcPosFlag_NoSetDebugLoc);
|
UpdateSrcPos(mCurTypeInstance->mTypeDef->mTypeDeclaration, BfSrcPosFlag_NoSetDebugLoc);
|
||||||
|
|
||||||
|
@ -17799,6 +17805,8 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
||||||
UpdateSrcPos(methodDeclaration, BfSrcPosFlag_NoSetDebugLoc);
|
UpdateSrcPos(methodDeclaration, BfSrcPosFlag_NoSetDebugLoc);
|
||||||
else if (methodDef->mBody != NULL)
|
else if (methodDef->mBody != NULL)
|
||||||
UpdateSrcPos(methodDef->mBody, BfSrcPosFlag_NoSetDebugLoc);
|
UpdateSrcPos(methodDef->mBody, BfSrcPosFlag_NoSetDebugLoc);
|
||||||
|
else if ((methodDef->mDeclaringType != NULL) && (methodDef->mDeclaringType->GetRefNode() != NULL))
|
||||||
|
UpdateSrcPos(methodDef->mDeclaringType->GetRefNode(), BfSrcPosFlag_NoSetDebugLoc);
|
||||||
else if (mCurTypeInstance->mTypeDef->mTypeDeclaration != NULL)
|
else if (mCurTypeInstance->mTypeDef->mTypeDeclaration != NULL)
|
||||||
UpdateSrcPos(mCurTypeInstance->mTypeDef->mTypeDeclaration, BfSrcPosFlag_NoSetDebugLoc);
|
UpdateSrcPos(mCurTypeInstance->mTypeDef->mTypeDeclaration, BfSrcPosFlag_NoSetDebugLoc);
|
||||||
}
|
}
|
||||||
|
@ -17956,7 +17964,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
||||||
// We want to be able to step into delegate invokes -- we actually step over them
|
// We want to be able to step into delegate invokes -- we actually step over them
|
||||||
if (methodDef->mName != "Invoke")
|
if (methodDef->mName != "Invoke")
|
||||||
{
|
{
|
||||||
UpdateSrcPos(typeDef->mTypeDeclaration);
|
UpdateSrcPos(methodDef->mDeclaringType->GetRefNode());
|
||||||
mBfIRBuilder->DbgCreateAnnotation(diFunction, "StepOver", GetConstValue32(1));
|
mBfIRBuilder->DbgCreateAnnotation(diFunction, "StepOver", GetConstValue32(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18133,8 +18141,10 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
||||||
|
|
||||||
if (methodDef->mBody != NULL)
|
if (methodDef->mBody != NULL)
|
||||||
UpdateSrcPos(methodDef->mBody);
|
UpdateSrcPos(methodDef->mBody);
|
||||||
|
else if ((methodDef->mDeclaringType != NULL) && (methodDef->mDeclaringType->GetRefNode() != NULL))
|
||||||
|
UpdateSrcPos(methodDef->mDeclaringType->GetRefNode());
|
||||||
else if (mCurTypeInstance->mTypeDef->mTypeDeclaration != NULL)
|
else if (mCurTypeInstance->mTypeDef->mTypeDeclaration != NULL)
|
||||||
UpdateSrcPos(mCurTypeInstance->mTypeDef->mTypeDeclaration);
|
UpdateSrcPos(mCurTypeInstance->mTypeDef->mTypeDeclaration);
|
||||||
|
|
||||||
localIdx = 0;
|
localIdx = 0;
|
||||||
argIdx = 0;
|
argIdx = 0;
|
||||||
|
|
|
@ -2916,15 +2916,18 @@ void BfSystem::FinishCompositePartial(BfTypeDef* compositeTypeDef)
|
||||||
bool hasCtorNoBody = false;
|
bool hasCtorNoBody = false;
|
||||||
|
|
||||||
bool primaryHasFieldInitializers = false;
|
bool primaryHasFieldInitializers = false;
|
||||||
bool anyHasFieldInitializers = false;
|
bool anyHasInitializers = false;
|
||||||
|
|
||||||
// For methods that require chaining, make sure the primary def has a definition
|
// For methods that require chaining, make sure the primary def has a definition
|
||||||
for (auto partialTypeDef : nextRevision->mPartials)
|
for (auto partialTypeDef : nextRevision->mPartials)
|
||||||
{
|
{
|
||||||
bool isExtension = partialTypeDef->mTypeDeclaration != nextRevision->mTypeDeclaration;
|
bool isExtension = partialTypeDef->mTypeDeclaration != nextRevision->mTypeDeclaration;
|
||||||
|
|
||||||
|
bool hasInitializers = false;
|
||||||
for (auto methodDef : partialTypeDef->mMethods)
|
for (auto methodDef : partialTypeDef->mMethods)
|
||||||
{
|
{
|
||||||
|
if (methodDef->mMethodType == BfMethodType_Init)
|
||||||
|
hasInitializers = true;
|
||||||
auto& hasMethods = allHasMethods[isExtension ? 1 : 0][methodDef->mIsStatic ? 1 : 0];
|
auto& hasMethods = allHasMethods[isExtension ? 1 : 0][methodDef->mIsStatic ? 1 : 0];
|
||||||
if (methodDef->mMethodType == BfMethodType_Ctor)
|
if (methodDef->mMethodType == BfMethodType_Ctor)
|
||||||
{
|
{
|
||||||
|
@ -2946,16 +2949,15 @@ void BfSystem::FinishCompositePartial(BfTypeDef* compositeTypeDef)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasFieldInitializers = false;
|
|
||||||
for (auto fieldDef : partialTypeDef->mFields)
|
for (auto fieldDef : partialTypeDef->mFields)
|
||||||
{
|
{
|
||||||
if ((!fieldDef->mIsStatic) && (fieldDef->mFieldDeclaration->mInitializer != NULL))
|
if ((!fieldDef->mIsStatic) && (fieldDef->mFieldDeclaration->mInitializer != NULL))
|
||||||
hasFieldInitializers = true;
|
hasInitializers = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasFieldInitializers)
|
if (hasInitializers)
|
||||||
{
|
{
|
||||||
anyHasFieldInitializers = true;
|
anyHasInitializers = true;
|
||||||
if (!isExtension)
|
if (!isExtension)
|
||||||
primaryHasFieldInitializers = true;
|
primaryHasFieldInitializers = true;
|
||||||
nextRevision->mHasCtorNoBody = true;
|
nextRevision->mHasCtorNoBody = true;
|
||||||
|
@ -2965,7 +2967,7 @@ void BfSystem::FinishCompositePartial(BfTypeDef* compositeTypeDef)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((anyHasFieldInitializers) && (!primaryHasFieldInitializers))
|
if ((anyHasInitializers) && (!primaryHasFieldInitializers))
|
||||||
{
|
{
|
||||||
nextRevision->mHasCtorNoBody = true;
|
nextRevision->mHasCtorNoBody = true;
|
||||||
auto methodDef = BfDefBuilder::AddMethod(nextRevision, BfMethodType_CtorNoBody, BfProtection_Protected, false, "");
|
auto methodDef = BfDefBuilder::AddMethod(nextRevision, BfMethodType_CtorNoBody, BfProtection_Protected, false, "");
|
||||||
|
|
|
@ -87,6 +87,22 @@ namespace LibA
|
||||||
return lhs == rhs;
|
return lhs == rhs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class LibA3
|
||||||
|
{
|
||||||
|
public int mA = 3;
|
||||||
|
public static LibA3 sLibA3 = new LibA3() ~ delete _;
|
||||||
|
|
||||||
|
public this()
|
||||||
|
{
|
||||||
|
mA++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LibA4
|
||||||
|
{
|
||||||
|
public int mA;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LibClassA
|
class LibClassA
|
||||||
|
|
|
@ -49,6 +49,27 @@ extension LibClassA
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace LibA
|
||||||
|
{
|
||||||
|
extension LibA3
|
||||||
|
{
|
||||||
|
public int mB = 7;
|
||||||
|
|
||||||
|
this
|
||||||
|
{
|
||||||
|
mA += 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension LibA4
|
||||||
|
{
|
||||||
|
this
|
||||||
|
{
|
||||||
|
mA += 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
public static int Overload0(int16 a)
|
public static int Overload0(int16 a)
|
||||||
|
|
|
@ -55,6 +55,17 @@ extension LibClassA
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace LibA
|
||||||
|
{
|
||||||
|
extension LibA3
|
||||||
|
{
|
||||||
|
this
|
||||||
|
{
|
||||||
|
mA += 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace Tests
|
namespace Tests
|
||||||
{
|
{
|
||||||
class Extensions
|
class Extensions
|
||||||
|
@ -267,6 +278,12 @@ namespace Tests
|
||||||
Test.Assert(ca.mA == 107);
|
Test.Assert(ca.mA == 107);
|
||||||
delete ca;
|
delete ca;
|
||||||
Test.Assert(LibClassA.sMagic == 7771);
|
Test.Assert(LibClassA.sMagic == 7771);
|
||||||
|
|
||||||
|
LibA.LibA3 la3 = scope .();
|
||||||
|
Test.Assert(la3.mA == 114);
|
||||||
|
Test.Assert(la3.mB == 7);
|
||||||
|
LibA.LibA4 la4 = scope .();
|
||||||
|
Test.Assert(la4.mA == 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|
|
@ -1,9 +1,23 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace Tests
|
namespace Tests
|
||||||
{
|
{
|
||||||
class Objects
|
class Objects
|
||||||
{
|
{
|
||||||
class ClassA
|
class ClassA
|
||||||
{
|
{
|
||||||
|
public int mA = 1;
|
||||||
|
|
||||||
|
this
|
||||||
|
{
|
||||||
|
mA *= 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
public this()
|
||||||
|
{
|
||||||
|
mA += 100;
|
||||||
|
}
|
||||||
|
|
||||||
public virtual void MethodA()
|
public virtual void MethodA()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -17,5 +31,12 @@ namespace Tests
|
||||||
base.MethodA();
|
base.MethodA();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public static void TestBasics()
|
||||||
|
{
|
||||||
|
ClassA ca = scope .();
|
||||||
|
Test.Assert(ca.mA == 111);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue