diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index a182b341..d9fee167 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -14952,6 +14952,8 @@ void BfModule::EmitDtorBody() { if (methodDeclaration != NULL) UpdateSrcPos(methodDeclaration); + else if ((methodDef->mDeclaringType != NULL) && (methodDef->mDeclaringType->GetRefNode() != NULL)) + UpdateSrcPos(methodDef->mDeclaringType->GetRefNode()); else if (typeDef->mTypeDeclaration != NULL) UpdateSrcPos(typeDef->mTypeDeclaration); if ((methodDeclaration != NULL) && (methodDeclaration->mFatArrowToken != NULL)) @@ -15594,6 +15596,8 @@ void BfModule::EmitCtorBody(bool& skipBody) baseCtorNode = methodDef->mBody; else if (ctorDeclaration != NULL) baseCtorNode = ctorDeclaration; + else if ((methodDef->mDeclaringType != NULL) && (methodDef->mDeclaringType->GetRefNode() != NULL)) + baseCtorNode = methodDef->mDeclaringType->GetRefNode(); else if (mCurTypeInstance->mTypeDef->mTypeDeclaration != NULL) baseCtorNode = mCurTypeInstance->mTypeDef->mTypeDeclaration->mNameNode; else if ((mCurTypeInstance->mBaseType != NULL) && (mCurTypeInstance->mBaseType->mTypeDef->mTypeDeclaration != NULL)) @@ -15604,7 +15608,7 @@ void BfModule::EmitCtorBody(bool& skipBody) 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 if (mCurTypeInstance->mTypeDef->mHasCtorNoBody) { @@ -17572,7 +17576,9 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup) if (methodDef->mBody != NULL) UpdateSrcPos(methodDef->mBody, BfSrcPosFlag_NoSetDebugLoc); 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) UpdateSrcPos(mCurTypeInstance->mTypeDef->mTypeDeclaration, BfSrcPosFlag_NoSetDebugLoc); @@ -17799,6 +17805,8 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup) UpdateSrcPos(methodDeclaration, BfSrcPosFlag_NoSetDebugLoc); else if (methodDef->mBody != NULL) 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) 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 if (methodDef->mName != "Invoke") { - UpdateSrcPos(typeDef->mTypeDeclaration); + UpdateSrcPos(methodDef->mDeclaringType->GetRefNode()); mBfIRBuilder->DbgCreateAnnotation(diFunction, "StepOver", GetConstValue32(1)); } } @@ -18133,8 +18141,10 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup) if (methodDef->mBody != NULL) UpdateSrcPos(methodDef->mBody); + else if ((methodDef->mDeclaringType != NULL) && (methodDef->mDeclaringType->GetRefNode() != NULL)) + UpdateSrcPos(methodDef->mDeclaringType->GetRefNode()); else if (mCurTypeInstance->mTypeDef->mTypeDeclaration != NULL) - UpdateSrcPos(mCurTypeInstance->mTypeDef->mTypeDeclaration); + UpdateSrcPos(mCurTypeInstance->mTypeDef->mTypeDeclaration); localIdx = 0; argIdx = 0; diff --git a/IDEHelper/Compiler/BfSystem.cpp b/IDEHelper/Compiler/BfSystem.cpp index 712682fd..77bc5af9 100644 --- a/IDEHelper/Compiler/BfSystem.cpp +++ b/IDEHelper/Compiler/BfSystem.cpp @@ -2916,15 +2916,18 @@ void BfSystem::FinishCompositePartial(BfTypeDef* compositeTypeDef) bool hasCtorNoBody = false; bool primaryHasFieldInitializers = false; - bool anyHasFieldInitializers = false; + bool anyHasInitializers = false; // For methods that require chaining, make sure the primary def has a definition for (auto partialTypeDef : nextRevision->mPartials) { bool isExtension = partialTypeDef->mTypeDeclaration != nextRevision->mTypeDeclaration; + bool hasInitializers = false; for (auto methodDef : partialTypeDef->mMethods) - { + { + if (methodDef->mMethodType == BfMethodType_Init) + hasInitializers = true; auto& hasMethods = allHasMethods[isExtension ? 1 : 0][methodDef->mIsStatic ? 1 : 0]; if (methodDef->mMethodType == BfMethodType_Ctor) { @@ -2946,16 +2949,15 @@ void BfSystem::FinishCompositePartial(BfTypeDef* compositeTypeDef) } } - bool hasFieldInitializers = false; for (auto fieldDef : partialTypeDef->mFields) { if ((!fieldDef->mIsStatic) && (fieldDef->mFieldDeclaration->mInitializer != NULL)) - hasFieldInitializers = true; + hasInitializers = true; } - if (hasFieldInitializers) + if (hasInitializers) { - anyHasFieldInitializers = true; + anyHasInitializers = true; if (!isExtension) primaryHasFieldInitializers = true; nextRevision->mHasCtorNoBody = true; @@ -2965,7 +2967,7 @@ void BfSystem::FinishCompositePartial(BfTypeDef* compositeTypeDef) } } - if ((anyHasFieldInitializers) && (!primaryHasFieldInitializers)) + if ((anyHasInitializers) && (!primaryHasFieldInitializers)) { nextRevision->mHasCtorNoBody = true; auto methodDef = BfDefBuilder::AddMethod(nextRevision, BfMethodType_CtorNoBody, BfProtection_Protected, false, ""); diff --git a/IDEHelper/Tests/LibA/src/LibA0.bf b/IDEHelper/Tests/LibA/src/LibA0.bf index af90c78b..09e6a449 100644 --- a/IDEHelper/Tests/LibA/src/LibA0.bf +++ b/IDEHelper/Tests/LibA/src/LibA0.bf @@ -87,6 +87,22 @@ namespace LibA 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 diff --git a/IDEHelper/Tests/LibB/src/LibB0.bf b/IDEHelper/Tests/LibB/src/LibB0.bf index 3542fd9b..68b39389 100644 --- a/IDEHelper/Tests/LibB/src/LibB0.bf +++ b/IDEHelper/Tests/LibB/src/LibB0.bf @@ -49,6 +49,27 @@ extension LibClassA } } +namespace LibA +{ + extension LibA3 + { + public int mB = 7; + + this + { + mA += 10; + } + } + + extension LibA4 + { + this + { + mA += 10; + } + } +} + static { public static int Overload0(int16 a) diff --git a/IDEHelper/Tests/src/Extensions.bf b/IDEHelper/Tests/src/Extensions.bf index 91874ef1..d0c5fa00 100644 --- a/IDEHelper/Tests/src/Extensions.bf +++ b/IDEHelper/Tests/src/Extensions.bf @@ -55,6 +55,17 @@ extension LibClassA } } +namespace LibA +{ + extension LibA3 + { + this + { + mA += 100; + } + } +} + namespace Tests { class Extensions @@ -267,6 +278,12 @@ namespace Tests Test.Assert(ca.mA == 107); delete ca; 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] diff --git a/IDEHelper/Tests/src/Objects.bf b/IDEHelper/Tests/src/Objects.bf index 5a586207..a2f19f50 100644 --- a/IDEHelper/Tests/src/Objects.bf +++ b/IDEHelper/Tests/src/Objects.bf @@ -1,9 +1,23 @@ +using System; + namespace Tests { class Objects { class ClassA { + public int mA = 1; + + this + { + mA *= 11; + } + + public this() + { + mA += 100; + } + public virtual void MethodA() { @@ -17,5 +31,12 @@ namespace Tests base.MethodA(); } } + + [Test] + public static void TestBasics() + { + ClassA ca = scope .(); + Test.Assert(ca.mA == 111); + } } }