omtcyfz updated this revision to Diff 154379.
omtcyfz added a comment.
Add const qualifier to UsingShadowDecl in unit tests.
https://reviews.llvm.org/D49012
Files:
clang-tools-extra/clangd/Quality.cpp
clang-tools-extra/unittests/clangd/QualityTests.cpp
clang/include/clang/Sema/CodeCompleteConsumer.h
clang/lib/Sema/SemaCodeComplete.cpp
Index: clang/lib/Sema/SemaCodeComplete.cpp
===================================================================
--- clang/lib/Sema/SemaCodeComplete.cpp
+++ clang/lib/Sema/SemaCodeComplete.cpp
@@ -859,12 +859,12 @@
}
// Look through using declarations.
- if (const UsingShadowDecl *Using =
- dyn_cast<UsingShadowDecl>(R.Declaration)) {
- MaybeAddResult(Result(Using->getTargetDecl(),
- getBasePriority(Using->getTargetDecl()),
- R.Qualifier),
- CurContext);
+ if (const UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
+ CodeCompletionResult Result(Using->getTargetDecl(),
+ getBasePriority(Using->getTargetDecl()),
+ R.Qualifier);
+ Result.setShadowDecl(Using);
+ MaybeAddResult(Result, CurContext);
return;
}
@@ -977,10 +977,11 @@
// Look through using declarations.
if (const UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
- AddResult(Result(Using->getTargetDecl(),
- getBasePriority(Using->getTargetDecl()),
- R.Qualifier),
- CurContext, Hiding);
+ CodeCompletionResult Result(Using->getTargetDecl(),
+ getBasePriority(Using->getTargetDecl()),
+ R.Qualifier);
+ Result.setShadowDecl(Using);
+ AddResult(Result, CurContext, Hiding);
return;
}
@@ -1004,10 +1005,10 @@
if (AsNestedNameSpecifier) {
R.StartsNestedNameSpecifier = true;
R.Priority = CCP_NestedNameSpecifier;
- }
- else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
- isa<CXXRecordDecl>(R.Declaration->getDeclContext()
- ->getRedeclContext()))
+ } else if (Filter == &ResultBuilder::IsMember && !R.Qualifier &&
+ InBaseClass &&
+ isa<CXXRecordDecl>(
+ R.Declaration->getDeclContext()->getRedeclContext()))
R.QualifierIsInformative = true;
// If this result is supposed to have an informative qualifier, add one.
Index: clang/include/clang/Sema/CodeCompleteConsumer.h
===================================================================
--- clang/include/clang/Sema/CodeCompleteConsumer.h
+++ clang/include/clang/Sema/CodeCompleteConsumer.h
@@ -45,8 +45,9 @@
class NamedDecl;
class NestedNameSpecifier;
class Preprocessor;
-class Sema;
class RawComment;
+class Sema;
+class UsingShadowDecl;
/// Default priority values for code-completion results based
/// on their kind.
@@ -836,18 +837,25 @@
/// informative rather than required.
NestedNameSpecifier *Qualifier = nullptr;
+ /// If this Decl was unshadowed by using declaration, this would would store
+ /// a pointer to the UsingShadowDecl which was used in the unshadowing
+ /// process. This information can be used to uprank CodeCompletionResults
+ /// which have corresponding `using decl::qualified::name;` nearby.
+ const UsingShadowDecl *ShadowDecl = nullptr;
+
/// Build a result that refers to a declaration.
CodeCompletionResult(const NamedDecl *Declaration, unsigned Priority,
NestedNameSpecifier *Qualifier = nullptr,
bool QualifierIsInformative = false,
bool Accessible = true,
- std::vector<FixItHint> FixIts = std::vector<FixItHint>())
+ std::vector<FixItHint> FixIts = std::vector<FixItHint>(),
+ const UsingShadowDecl *ShadowDecl = nullptr)
: Declaration(Declaration), Priority(Priority), Kind(RK_Declaration),
FixIts(std::move(FixIts)), Hidden(false),
QualifierIsInformative(QualifierIsInformative),
StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
- DeclaringEntity(false), Qualifier(Qualifier) {
- //FIXME: Add assert to check FixIts range requirements.
+ DeclaringEntity(false), Qualifier(Qualifier), ShadowDecl(ShadowDecl) {
+ // FIXME: Add assert to check FixIts range requirements.
computeCursorKindAndAvailability(Accessible);
}
@@ -900,6 +908,10 @@
return Keyword;
}
+ void setShadowDecl(const UsingShadowDecl *Shadow) {
+ this->ShadowDecl = Shadow;
+ }
+
/// Create a new code-completion string that describes how to insert
/// this result into a program.
///
Index: clang-tools-extra/unittests/clangd/QualityTests.cpp
===================================================================
--- clang-tools-extra/unittests/clangd/QualityTests.cpp
+++ clang-tools-extra/unittests/clangd/QualityTests.cpp
@@ -79,8 +79,18 @@
Test.HeaderCode = R"cpp(
int header();
int header_main();
+
+ namespace foo {
+ class Bar {};
+ } // namespace foo
+
+ namespace bar {
+ class Foo {};
+ } // namespace bar
)cpp";
Test.Code = R"cpp(
+ using foo::Bar;
+
int ::header_main() {}
int main();
@@ -109,7 +119,36 @@
Relevance = {};
Relevance.merge(CodeCompletionResult(&findDecl(AST, "header_main"), 42));
EXPECT_FLOAT_EQ(Relevance.SemaProximityScore, 1.0f)
- << "Current file and header";
+ << "Current file and definition in header";
+
+ Relevance = {};
+ const auto SymbolName = "Bar";
+ const NamedDecl *FoundDecl;
+ const UsingShadowDecl *Shadow;
+ auto findUsingDecl = [&SymbolName, &Shadow,
+ &FoundDecl](const NamedDecl &ND) -> bool {
+ if (const UsingDecl *Using = dyn_cast<UsingDecl>(&ND)) {
+ if (UsingShadowDecl *ShadowDecl = *Using->shadow_begin()) {
+ if (ShadowDecl->getTargetDecl()->getName() == SymbolName) {
+ Shadow = ShadowDecl;
+ FoundDecl = Shadow->getTargetDecl();
+ return true;
+ }
+ }
+ }
+ return false;
+ };
+ findAnyDecl(AST, findUsingDecl);
+ CodeCompletionResult Result(FoundDecl, 42);
+ Result.setShadowDecl(Shadow);
+ Relevance.merge(Result);
+ EXPECT_FLOAT_EQ(Relevance.SemaProximityScore, 1.0f)
+ << "Uprank declaration which has using directive in current directory";
+
+ Relevance = {};
+ Relevance.merge(CodeCompletionResult(&findDecl(AST, "bar::Foo"), 42));
+ EXPECT_FLOAT_EQ(Relevance.SemaProximityScore, 0.6f)
+ << "Only definition in header";
Relevance = {};
Relevance.merge(CodeCompletionResult(&findAnyDecl(AST, "X"), 42));
Index: clang-tools-extra/clangd/Quality.cpp
===================================================================
--- clang-tools-extra/clangd/Quality.cpp
+++ clang-tools-extra/clangd/Quality.cpp
@@ -41,6 +41,17 @@
return false;
}
+static bool hasUsingDeclInMainFile(const CodeCompletionResult &R) {
+ const auto &Context = R.Declaration->getASTContext();
+ const auto &SourceMgr = Context.getSourceManager();
+ if (R.ShadowDecl) {
+ const auto Loc = SourceMgr.getSpellingLoc(R.ShadowDecl->getLocation());
+ if (SourceMgr.isWrittenInMainFile(Loc))
+ return true;
+ }
+ return false;
+}
+
static SymbolQualitySignals::SymbolCategory categorize(const NamedDecl &ND) {
class Switch
: public ConstDeclVisitor<Switch, SymbolQualitySignals::SymbolCategory> {
@@ -231,8 +242,10 @@
// We boost things that have decls in the main file. We give a fixed score
// for all other declarations in sema as they are already included in the
// translation unit.
- float DeclProximity =
- hasDeclInMainFile(*SemaCCResult.Declaration) ? 1.0 : 0.6;
+ float DeclProximity = (hasDeclInMainFile(*SemaCCResult.Declaration) ||
+ hasUsingDeclInMainFile(SemaCCResult))
+ ? 1.0
+ : 0.6;
SemaProximityScore = std::max(DeclProximity, SemaProximityScore);
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits