diff --git a/clang-tools-extra/clangd/refactor/tweaks/ExtractVariable.cpp b/clang-tools-extra/clangd/refactor/tweaks/ExtractVariable.cpp --- a/clang-tools-extra/clangd/refactor/tweaks/ExtractVariable.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/ExtractVariable.cpp @@ -77,16 +77,22 @@ return Visitor.ReferencedDecls; } -// An expr is not extractable if it's null or an expression of type void -// FIXME: Ignore assignment (a = 1) Expr since it is extracted as dummy = a = +// An expr is not extractable if it's null, an expression of type void, an +// assignment expression, MemberExpr or a DeclRefExpr static bool isExtractableExpr(const clang::Expr *Expr) { - if (Expr) { - const Type *ExprType = Expr->getType().getTypePtrOrNull(); - // FIXME: check if we need to cover any other types - if (ExprType) - return !ExprType->isVoidType(); - } - return false; + if (!Expr) + return false; + // FIXME: check if we need to cover any other types + if (const Type *ExprType = Expr->getType().getTypePtrOrNull()) + if (ExprType->isVoidType()) + return false; + if (const BinaryOperator *BinOpExpr = + llvm::dyn_cast_or_null(Expr)) + if (BinOpExpr->getOpcode() == BinaryOperatorKind::BO_Assign) + return false; + if (llvm::isa(Expr) || llvm::isa(Expr)) + return false; + return true; } ExtractionContext::ExtractionContext(const SelectionTree::Node *Node, diff --git a/clang-tools-extra/clangd/unittests/TweakTests.cpp b/clang-tools-extra/clangd/unittests/TweakTests.cpp --- a/clang-tools-extra/clangd/unittests/TweakTests.cpp +++ b/clang-tools-extra/clangd/unittests/TweakTests.cpp @@ -299,10 +299,10 @@ return ^1; } void f() { - int a = 5 + [[4 ^* ^xyz^()]]; + int a = 5 + [[4 ^* xyz^()]]; // multivariable initialization if(1) - int x = ^1, y = ^a + 1, a = ^1, z = a + 1; + int x = ^1, y = [[a + 1]], a = ^1, z = a + 1; // if without else if(^1) {} // if with else @@ -320,7 +320,7 @@ a = ^2; // while while(a < ^1) - ^a++; + [[a++]]; // do while do a = ^1; @@ -340,8 +340,10 @@ return 1; class T { T(int a = ^1) {}; + T f() { return T(); } int xyz = ^1; }; + [[T.[[^t]]]](); } // function default argument void f(int b = ^1) { @@ -359,6 +361,10 @@ a = ^a ^+ 1; // lambda auto lamb = [&^a, &^b](int r = ^1) {return 1;} + // assigment + [[a ^= 5]]; + // DeclRefExpr + a = [[b]], b = [[xyz]](); } )cpp"); // vector of pairs of input and output strings