[clang-tools-extra] 39866d2 - [clangd][ObjC] Improve support for class properties
David Goldman via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 28 07:07:10 PDT 2021
Author: David Goldman
Date: 2021-04-28T10:06:27-04:00
New Revision: 39866d249a21fc3c05942a1a4fbbd88acc4660bc
URL: https://github.com/llvm/llvm-project/commit/39866d249a21fc3c05942a1a4fbbd88acc4660bc
DIFF: https://github.com/llvm/llvm-project/commit/39866d249a21fc3c05942a1a4fbbd88acc4660bc.diff
LOG: [clangd][ObjC] Improve support for class properties
Class properties are always implicit short-hands for the getter/setter
class methods.
We need to explicitly visit the interface decl `UIColor` in `UIColor.blueColor`,
otherwise we instead show the method decl even while hovering over
`UIColor` in the expression.
Differential Revision: https://reviews.llvm.org/D99975
Added:
Modified:
clang-tools-extra/clangd/FindTarget.cpp
clang-tools-extra/clangd/unittests/FindTargetTests.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp
index 6032676b0acd..d4cb2fe79111 100644
--- a/clang-tools-extra/clangd/FindTarget.cpp
+++ b/clang-tools-extra/clangd/FindTarget.cpp
@@ -306,6 +306,9 @@ struct TargetFinder {
Outer.add(OME->getMethodDecl(), Flags);
}
void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *OPRE) {
+ // FIXME: We miss visiting the class receiver if one exists, which
+ // means we skip the corresponding ObjCInterfaceDecl ref since it
+ // doesn't have a corresponding node.
if (OPRE->isExplicitProperty())
Outer.add(OPRE->getExplicitProperty(), Flags);
else {
@@ -763,6 +766,13 @@ llvm::SmallVector<ReferenceLoc> refInStmt(const Stmt *S,
}
void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *E) {
+ // There's no contained TypeLoc node for a class receiver type.
+ if (E->isClassReceiver()) {
+ Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
+ E->getReceiverLocation(),
+ /*IsDecl=*/false,
+ {E->getClassReceiver()}});
+ }
Refs.push_back(ReferenceLoc{
NestedNameSpecifierLoc(), E->getLocation(),
/*IsDecl=*/false,
diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
index 5bcbdbd2f1cd..f32081ac472c 100644
--- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -969,6 +969,33 @@ TEST_F(TargetDeclTest, ObjC) {
)cpp";
// FIXME: We currently can't disambiguate between multiple protocols.
EXPECT_DECLS("ObjCObjectTypeLoc", "@protocol Foo", "@protocol Bar");
+
+ Code = R"cpp(
+ @interface Foo
+ + (id)sharedInstance;
+ @end
+ @implementation Foo
+ + (id)sharedInstance { return 0; }
+ @end
+ void test() {
+ id value = [[Foo]].sharedInstance;
+ }
+ )cpp";
+ // FIXME: We currently can't identify the interface here.
+ EXPECT_DECLS("ObjCPropertyRefExpr", "+ (id)sharedInstance");
+
+ Code = R"cpp(
+ @interface Foo
+ + (id)sharedInstance;
+ @end
+ @implementation Foo
+ + (id)sharedInstance { return 0; }
+ @end
+ void test() {
+ id value = Foo.[[sharedInstance]];
+ }
+ )cpp";
+ EXPECT_DECLS("ObjCPropertyRefExpr", "+ (id)sharedInstance");
}
class FindExplicitReferencesTest : public ::testing::Test {
@@ -1610,6 +1637,41 @@ TEST_F(FindExplicitReferencesTest, All) {
"0: targets = {f}\n"
"1: targets = {I::x}\n"
"2: targets = {I::setY:}\n"},
+ // Objective-C: class properties
+ {
+ R"cpp(
+ @interface I {}
+ @property(class) I *x;
+ @end
+ id local;
+ void foo() {
+ $0^I.$1^x = 0;
+ $2^local = $3^I.$4^x;
+ }
+ )cpp",
+ "0: targets = {I}\n"
+ "1: targets = {I::setX:}\n"
+ "2: targets = {local}\n"
+ "3: targets = {I}\n"
+ "4: targets = {I::x}\n"},
+ // Objective-C: implicit class properties
+ {
+ R"cpp(
+ @interface I {}
+ +(I*)x;
+ +(void)setX:(I*)x;
+ @end
+ id local;
+ void foo() {
+ $0^I.$1^x = 0;
+ $2^local = $3^I.$4^x;
+ }
+ )cpp",
+ "0: targets = {I}\n"
+ "1: targets = {I::setX:}\n"
+ "2: targets = {local}\n"
+ "3: targets = {I}\n"
+ "4: targets = {I::x}\n"},
{// Objective-C: methods
R"cpp(
@interface I
More information about the cfe-commits
mailing list