adamcz created this revision.
Herald added subscribers: cfe-commits, usaxena95, kadircet, arphaman.
Herald added a project: clang.
adamcz requested review of this revision.
Herald added subscribers: MaskRay, ilya-biryukov.
This improves the behavior related to type aliases, as well as cases of
typo correction.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D91966
Files:
clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp
clang-tools-extra/clangd/unittests/TweakTests.cpp
Index: clang-tools-extra/clangd/unittests/TweakTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/TweakTests.cpp
+++ clang-tools-extra/clangd/unittests/TweakTests.cpp
@@ -2520,6 +2520,9 @@
EXPECT_UNAVAILABLE(Header + "void fun() { ::ban::fo^o(); }");
EXPECT_AVAILABLE(Header + "void fun() { banana::fo^o(); }");
+ // Do not offer code action on typo-corrections.
+ EXPECT_UNAVAILABLE(Header + "/*error-ok*/c^c C;");
+
// Check that we do not trigger in header files.
FileName = "test.h";
ExtraArgs.push_back("-xc++-header"); // .h file is treated a C by default.
@@ -2793,6 +2796,21 @@
void fun() {
ff();
+})cpp"},
+ // using alias; insert using for the spelled name.
+ {R"cpp(
+#include "test.hpp"
+
+void fun() {
+ one::u^u u;
+})cpp",
+ R"cpp(
+#include "test.hpp"
+
+using one::uu;
+
+void fun() {
+ uu u;
})cpp"}};
llvm::StringMap<std::string> EditedFiles;
for (const auto &Case : Cases) {
@@ -2809,6 +2827,7 @@
static void mm() {}
};
}
+using uu = two::cc;
})cpp";
EXPECT_EQ(apply(SubCase, &EditedFiles), Case.ExpectedSource);
}
Index: clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp
===================================================================
--- clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp
+++ clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp
@@ -43,10 +43,11 @@
}
private:
- // The qualifier to remove. Set by prepare().
+ // All of the following are set by prepare().
+ // The qualifier to remove.
NestedNameSpecifierLoc QualifierToRemove;
- // The name following QualifierToRemove. Set by prepare().
- llvm::StringRef Name;
+ // The name following QualifierToRemove.
+ std::string Name;
};
REGISTER_TWEAK(AddUsing)
@@ -206,8 +207,17 @@
return false;
}
+std::string GetNNSLAsString(NestedNameSpecifierLoc &NNSL,
+ const PrintingPolicy &Policy) {
+ std::string Out;
+ llvm::raw_string_ostream OutStream(Out);
+ NNSL.getNestedNameSpecifier()->print(OutStream, Policy);
+ return OutStream.str();
+}
+
bool AddUsing::prepare(const Selection &Inputs) {
auto &SM = Inputs.AST->getSourceManager();
+ auto &TB = Inputs.AST->getTokens();
// Do not suggest "using" in header files. That way madness lies.
if (isHeaderFile(SM.getFileEntryForID(SM.getMainFileID())->getName(),
@@ -243,15 +253,25 @@
if (auto *D = Node->ASTNode.get<DeclRefExpr>()) {
if (auto *II = D->getDecl()->getIdentifier()) {
QualifierToRemove = D->getQualifierLoc();
- Name = II->getName();
+ Name = II->getName().str();
}
} else if (auto *T = Node->ASTNode.get<TypeLoc>()) {
if (auto E = T->getAs<ElaboratedTypeLoc>()) {
- if (auto *BaseTypeIdentifier =
- E.getType().getUnqualifiedType().getBaseTypeIdentifier()) {
- Name = BaseTypeIdentifier->getName();
- QualifierToRemove = E.getQualifierLoc();
- }
+ QualifierToRemove = E.getQualifierLoc();
+
+ auto SpelledTokens =
+ TB.spelledForExpanded(TB.expandedTokens(E.getSourceRange()));
+ if (!SpelledTokens)
+ return false;
+ auto SpelledRange = syntax::Token::range(SM, SpelledTokens->front(),
+ SpelledTokens->back());
+ llvm::StringRef NameRef = SpelledRange.text(SM);
+
+ std::string QualifierToRemoveStr = GetNNSLAsString(
+ QualifierToRemove, Inputs.AST->getASTContext().getPrintingPolicy());
+ if (!NameRef.consume_front(QualifierToRemoveStr))
+ return false; // What's spelled doesn't match the qualifier.
+ Name = NameRef.str();
}
}
@@ -283,20 +303,13 @@
Expected<Tweak::Effect> AddUsing::apply(const Selection &Inputs) {
auto &SM = Inputs.AST->getSourceManager();
- auto &TB = Inputs.AST->getTokens();
- // Determine the length of the qualifier under the cursor, then remove it.
- auto SpelledTokens = TB.spelledForExpanded(
- TB.expandedTokens(QualifierToRemove.getSourceRange()));
- if (!SpelledTokens) {
- return error("Could not determine length of the qualifier");
- }
- unsigned Length =
- syntax::Token::range(SM, SpelledTokens->front(), SpelledTokens->back())
- .length();
+ std::string QualifierToRemoveStr = GetNNSLAsString(
+ QualifierToRemove, Inputs.AST->getASTContext().getPrintingPolicy());
tooling::Replacements R;
if (auto Err = R.add(tooling::Replacement(
- SM, SpelledTokens->front().location(), Length, ""))) {
+ SM, SM.getSpellingLoc(QualifierToRemove.getBeginLoc()),
+ QualifierToRemoveStr.length(), ""))) {
return std::move(Err);
}
@@ -313,9 +326,8 @@
if (InsertionPoint->AlwaysFullyQualify &&
!isFullyQualified(QualifierToRemove.getNestedNameSpecifier()))
UsingTextStream << "::";
- QualifierToRemove.getNestedNameSpecifier()->print(
- UsingTextStream, Inputs.AST->getASTContext().getPrintingPolicy());
- UsingTextStream << Name << ";" << InsertionPoint->Suffix;
+ UsingTextStream << QualifierToRemoveStr << Name << ";"
+ << InsertionPoint->Suffix;
assert(SM.getFileID(InsertionPoint->Loc) == SM.getMainFileID());
if (auto Err = R.add(tooling::Replacement(SM, InsertionPoint->Loc, 0,
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits