Procházet zdrojové kódy

Fixit for expanding auto constructor

Brian Fiete před 3 roky
rodič
revize
b12ceeb625

+ 5 - 0
IDE/src/ui/SourceEditWidgetContent.bf

@@ -4913,7 +4913,12 @@ namespace IDE.ui
 											var autoComplete = new AutoComplete(mEditWidget);
 											autoComplete.SetInfo(infoCopy);
 											autoComplete.mAutoCompleteListWidget.mSelectIdx = fixitIdx;
+
+											UndoBatchStart undoBatchStart = new UndoBatchStart("autocomplete");
+											mData.mUndoManager.Add(undoBatchStart);
 											autoComplete.InsertSelection(0);
+											mData.mUndoManager.Add(undoBatchStart.mBatchEnd);
+
 											autoComplete.Close();
 										}
 										~

+ 5 - 0
IDEHelper/Compiler/BfAst.cpp

@@ -596,6 +596,11 @@ void BfStructuralVisitor::Visit(BfConstructorDeclaration* ctorDeclaration)
 	Visit(ctorDeclaration->ToBase());
 }
 
+void BfStructuralVisitor::Visit(BfAutoConstructorDeclaration* ctorDeclaration)
+{
+	Visit(ctorDeclaration->ToBase());
+}
+
 void BfStructuralVisitor::Visit(BfDestructorDeclaration* dtorDeclaration)
 {
 	Visit(dtorDeclaration->ToBase());

+ 3 - 0
IDEHelper/Compiler/BfAst.h

@@ -556,6 +556,7 @@ public:
 	virtual void Visit(BfUnaryOperatorExpression* binOpExpr);
 	virtual void Visit(BfBinaryOperatorExpression* binOpExpr);
 	virtual void Visit(BfConstructorDeclaration* ctorDeclaration);
+	virtual void Visit(BfAutoConstructorDeclaration* ctorDeclaration);
 	virtual void Visit(BfDestructorDeclaration* dtorDeclaration);
 	virtual void Visit(BfMethodDeclaration* methodDeclaration);
 	virtual void Visit(BfOperatorDeclaration* operatorDeclaration);
@@ -3132,6 +3133,8 @@ class BfAutoConstructorDeclaration : public BfConstructorDeclaration
 {
 public:
 	BF_AST_TYPE(BfAutoConstructorDeclaration, BfConstructorDeclaration);
+
+	BfAstNode* mPrefix;
 };	BF_AST_DECL(BfAutoConstructorDeclaration, BfConstructorDeclaration);
 
 class BfDestructorDeclaration : public BfMethodDeclaration

+ 6 - 0
IDEHelper/Compiler/BfElementVisitor.cpp

@@ -1038,6 +1038,12 @@ void BfElementVisitor::Visit(BfConstructorDeclaration* ctorDeclaration)
 	VisitChild(ctorDeclaration->mInitializer);
 }
 
+void BfElementVisitor::Visit(BfAutoConstructorDeclaration* ctorDeclaration)
+{
+	VisitChild(ctorDeclaration->mPrefix);
+	Visit(ctorDeclaration->ToBase());
+}
+
 void BfElementVisitor::Visit(BfDestructorDeclaration* dtorDeclaration)
 {
 	Visit(dtorDeclaration->ToBase());

+ 1 - 0
IDEHelper/Compiler/BfElementVisitor.h

@@ -119,6 +119,7 @@ public:
 	virtual void Visit(BfUnaryOperatorExpression* binOpExpr);
 	virtual void Visit(BfBinaryOperatorExpression* binOpExpr);
 	virtual void Visit(BfConstructorDeclaration* ctorDeclaration);
+	virtual void Visit(BfAutoConstructorDeclaration* ctorDeclaration);
 	virtual void Visit(BfDestructorDeclaration* dtorDeclaration);
 	virtual void Visit(BfMethodDeclaration* methodDeclaration);
 	virtual void Visit(BfOperatorDeclaration* operatorDeclaration);

+ 86 - 1
IDEHelper/Compiler/BfModule.cpp

@@ -18263,6 +18263,7 @@ void BfModule::EmitCtorBody(bool& skipBody)
 		}
 	}
 
+	auto autoComplete = mCompiler->GetAutoComplete();
 	if (targetType != NULL)
 	{
 		BfAstNode* refNode = methodDeclaration;
@@ -18271,7 +18272,6 @@ void BfModule::EmitCtorBody(bool& skipBody)
 
 		BfAutoParentNodeEntry autoParentNodeEntry(this, refNode);
 
-		auto autoComplete = mCompiler->GetAutoComplete();
 		auto wasCapturingMethodInfo = (autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo);
 		if ((autoComplete != NULL) && (ctorDeclaration != NULL) && (ctorInvocation != NULL))
 		{
@@ -18317,6 +18317,91 @@ void BfModule::EmitCtorBody(bool& skipBody)
 				autoComplete->mIsCapturingMethodMatchInfo = false;
 		}
 	}
+
+	auto autoCtorDecl = BfNodeDynCast<BfAutoConstructorDeclaration>(methodDeclaration);
+	if ((autoComplete != NULL) && (autoComplete->CheckFixit(methodDeclaration)) && (methodDeclaration != NULL) && (autoCtorDecl != NULL))
+	{
+		auto typeDecl = methodDef->mDeclaringType->mTypeDeclaration;
+		BfParserData* parser = typeDecl->GetSourceData()->ToParserData();
+		if (parser != NULL)
+		{
+			String fixitStr = "Expand auto constructor\t";
+			int insertPos = typeDecl->mSrcStart;
+
+			bool needsBlock = false;
+
+			if (auto defBlock = BfNodeDynCast<BfBlock>(typeDecl->mDefineNode))
+			{
+				insertPos = defBlock->mOpenBrace->mSrcStart + 1;
+			}
+			else if (auto tokenNode = BfNodeDynCast<BfTokenNode>(typeDecl->mDefineNode))
+			{
+				insertPos = tokenNode->mSrcStart;
+				fixitStr += StrFormat("delete|%s-%d|\x01",
+					autoComplete->FixitGetLocation(parser, tokenNode->mSrcStart).c_str(), tokenNode->mSrcEnd - tokenNode->mSrcStart);
+				needsBlock = true;
+			}
+
+			int srcStart = methodDeclaration->mSrcStart;
+			if ((autoCtorDecl->mPrefix == NULL) && (typeDecl->mColonToken != NULL))
+				srcStart = typeDecl->mColonToken->mSrcStart;
+
+			while ((srcStart > 0) && (::isspace((uint8)parser->mSrc[srcStart - 1])))
+				srcStart--;
+
+			fixitStr += StrFormat("expand|%s|%d|",
+				parser->mFileName.c_str(), insertPos);
+
+			if (needsBlock)
+				fixitStr += "\t";
+			else
+				fixitStr += "\f";
+
+			for (int paramIdx = 0; paramIdx < autoCtorDecl->mParams.mSize; paramIdx++)
+			{
+				String paramStr = autoCtorDecl->mParams[paramIdx]->ToString();
+				paramStr.Replace('\n', '\r');
+
+				fixitStr += "public ";
+				fixitStr += paramStr;
+				fixitStr += ";\r";
+			}
+
+			fixitStr += "\rpublic this(";
+			for (int paramIdx = 0; paramIdx < autoCtorDecl->mParams.mSize; paramIdx++)
+			{
+				if (paramIdx > 0)
+					fixitStr += ", ";
+				String paramStr = autoCtorDecl->mParams[paramIdx]->ToString();
+				paramStr.Replace('\n', '\r');
+				fixitStr += paramStr;
+			}
+			fixitStr += ")\t";
+			for (int paramIdx = 0; paramIdx < autoCtorDecl->mParams.mSize; paramIdx++)
+			{
+				if (paramIdx > 0)
+					fixitStr += "\r";
+				auto nameNode = autoCtorDecl->mParams[paramIdx]->mNameNode;
+				if (nameNode == NULL)
+					continue;
+				String nameStr = nameNode->ToString();
+				fixitStr += "this.";
+				fixitStr += nameStr;
+				fixitStr += " = ";
+				fixitStr += nameStr;
+				fixitStr += ";";
+			}
+			fixitStr += "\b";
+
+			if (needsBlock)
+				fixitStr += "\b";
+
+			fixitStr += StrFormat("\x01""delete|%s-%d|",
+				autoComplete->FixitGetLocation(parser, srcStart).c_str(), autoCtorDecl->mSrcEnd - srcStart);
+
+			mCompiler->mResolvePassData->mAutoComplete->AddEntry(AutoCompleteEntry("fixit", fixitStr.c_str()));
+		}
+	}
 }
 
 void BfModule::EmitEnumToStringBody()

+ 10 - 0
IDEHelper/Compiler/BfPrinter.cpp

@@ -2493,6 +2493,16 @@ void BfPrinter::Visit(BfConstructorDeclaration* ctorDeclaration)
 	FlushVisitChild();
 }
 
+void BfPrinter::Visit(BfAutoConstructorDeclaration* ctorDeclaration)
+{
+	if (ctorDeclaration->mPrefix != NULL)
+	{
+		VisitChild(ctorDeclaration->mPrefix);
+		ExpectSpace();
+	}
+	Visit(ctorDeclaration->ToBase());
+}
+
 void BfPrinter::Visit(BfDestructorDeclaration* dtorDeclaration)
 {
 	//Visit((BfAstNode*)dtorDeclaration);

+ 1 - 0
IDEHelper/Compiler/BfPrinter.h

@@ -218,6 +218,7 @@ public:
 	virtual void Visit(BfUnaryOperatorExpression* binOpExpr) override;
 	virtual void Visit(BfBinaryOperatorExpression* binOpExpr) override;
 	virtual void Visit(BfConstructorDeclaration* ctorDeclaration) override;
+	virtual void Visit(BfAutoConstructorDeclaration* ctorDeclaration) override;
 	virtual void Visit(BfDestructorDeclaration* dtorDeclaration) override;
 	virtual void Visit(BfMethodDeclaration* methodDeclaration) override;
 	virtual void Visit(BfOperatorDeclaration* opreratorDeclaration) override;

+ 7 - 0
IDEHelper/Compiler/BfReducer.cpp

@@ -8960,6 +8960,13 @@ BfAstNode* BfReducer::CreateTopLevelObject(BfTokenNode* tokenNode, BfAttributeDi
 						MEMBER_SET(ctorDecl, mThisToken, tokenNode);
 						ParseMethod(ctorDecl, &params, &commas);
 
+						if (!baseClassCommas.IsEmpty())
+						{
+							ctorDecl->mPrefix = baseClassCommas.back();
+							baseClassCommas.pop_back();
+							ctorDecl->mSrcStart = ctorDecl->mPrefix->mSrcStart;
+						}
+
 						if (typeDeclaration->mAutoCtor == NULL)
 						{
 							MEMBER_SET(typeDeclaration, mAutoCtor, ctorDecl);