[clang-tools-extra] 4d90ff5 - [clangd] When inserting "using", add "::" in front if that's the style.
Adam Czachorowski via cfe-commits
cfe-commits at lists.llvm.org
Tue Aug 25 05:12:04 PDT 2020
Author: Adam Czachorowski
Date: 2020-08-25T14:07:49+02:00
New Revision: 4d90ff59ac453a67ac692ffdf8242e4cfbd2b34f
URL: https://github.com/llvm/llvm-project/commit/4d90ff59ac453a67ac692ffdf8242e4cfbd2b34f
DIFF: https://github.com/llvm/llvm-project/commit/4d90ff59ac453a67ac692ffdf8242e4cfbd2b34f.diff
LOG: [clangd] When inserting "using", add "::" in front if that's the style.
We guess the style based on the existing using declarations. If there
are any and they all start with ::, we add it to the newly added one
too.
Differential Revision: https://reviews.llvm.org/D86473
Added:
Modified:
clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp
clang-tools-extra/clangd/unittests/TweakTests.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp b/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp
index 9e64ceeeaead..e4900041671a 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp
@@ -86,6 +86,13 @@ class UsingFinder : public RecursiveASTVisitor<UsingFinder> {
const SourceManager &SM;
};
+bool isFullyQualified(const NestedNameSpecifier *NNS) {
+ if (!NNS)
+ return false;
+ return NNS->getKind() == NestedNameSpecifier::Global ||
+ isFullyQualified(NNS->getPrefix());
+}
+
struct InsertionPointData {
// Location to insert the "using" statement. If invalid then the statement
// should not be inserted at all (it already exists).
@@ -94,6 +101,9 @@ struct InsertionPointData {
// insertion point is anchored to, we may need one or more \n to ensure
// proper formatting.
std::string Suffix;
+ // Whether using should be fully qualified, even if what the user typed was
+ // not. This is based on our detection of the local style.
+ bool AlwaysFullyQualify = false;
};
// Finds the best place to insert the "using" statement. Returns invalid
@@ -118,7 +128,13 @@ findInsertionPoint(const Tweak::Selection &Inputs,
SM)
.TraverseAST(Inputs.AST->getASTContext());
+ bool AlwaysFullyQualify = true;
for (auto &U : Usings) {
+ // Only "upgrade" to fully qualified is all relevant using decls are fully
+ // qualified. Otherwise trust what the user typed.
+ if (!isFullyQualified(U->getQualifier()))
+ AlwaysFullyQualify = false;
+
if (SM.isBeforeInTranslationUnit(Inputs.Cursor, U->getUsingLoc()))
// "Usings" is sorted, so we're done.
break;
@@ -137,6 +153,7 @@ findInsertionPoint(const Tweak::Selection &Inputs,
if (LastUsingLoc.isValid()) {
InsertionPointData Out;
Out.Loc = LastUsingLoc;
+ Out.AlwaysFullyQualify = AlwaysFullyQualify;
return Out;
}
@@ -278,6 +295,9 @@ Expected<Tweak::Effect> AddUsing::apply(const Selection &Inputs) {
std::string UsingText;
llvm::raw_string_ostream UsingTextStream(UsingText);
UsingTextStream << "using ";
+ if (InsertionPoint->AlwaysFullyQualify &&
+ !isFullyQualified(QualifierToRemove.getNestedNameSpecifier()))
+ UsingTextStream << "::";
QualifierToRemove.getNestedNameSpecifier()->print(
UsingTextStream, Inputs.AST->getASTContext().getPrintingPolicy());
UsingTextStream << Name << ";" << InsertionPoint->Suffix;
diff --git a/clang-tools-extra/clangd/unittests/TweakTests.cpp b/clang-tools-extra/clangd/unittests/TweakTests.cpp
index b4f135b3efe2..5626b7530599 100644
--- a/clang-tools-extra/clangd/unittests/TweakTests.cpp
+++ b/clang-tools-extra/clangd/unittests/TweakTests.cpp
@@ -2723,6 +2723,63 @@ namespace foo { void fun(); }
void foo::fun() {
ff();
+})cpp"},
+ // If all other using are fully qualified, add ::
+ {R"cpp(
+#include "test.hpp"
+
+using ::one::two::cc;
+using ::one::two::ee;
+
+void fun() {
+ one::two::f^f();
+})cpp",
+ R"cpp(
+#include "test.hpp"
+
+using ::one::two::cc;
+using ::one::two::ff;using ::one::two::ee;
+
+void fun() {
+ ff();
+})cpp"},
+ // Make sure we don't add :: if it's already there
+ {R"cpp(
+#include "test.hpp"
+
+using ::one::two::cc;
+using ::one::two::ee;
+
+void fun() {
+ ::one::two::f^f();
+})cpp",
+ R"cpp(
+#include "test.hpp"
+
+using ::one::two::cc;
+using ::one::two::ff;using ::one::two::ee;
+
+void fun() {
+ ff();
+})cpp"},
+ // If even one using doesn't start with ::, do not add it
+ {R"cpp(
+#include "test.hpp"
+
+using ::one::two::cc;
+using one::two::ee;
+
+void fun() {
+ one::two::f^f();
+})cpp",
+ R"cpp(
+#include "test.hpp"
+
+using ::one::two::cc;
+using one::two::ff;using one::two::ee;
+
+void fun() {
+ ff();
})cpp"}};
llvm::StringMap<std::string> EditedFiles;
for (const auto &Case : Cases) {
More information about the cfe-commits
mailing list