[clang-tools-extra] 5709842 - [clangd] Fix highlighting for implicit ObjC property refs
David Goldman via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 30 09:32:29 PDT 2021
Author: David Goldman
Date: 2021-06-30T12:31:50-04:00
New Revision: 570984204f24c326699dedcc05793b77b013f068
URL: https://github.com/llvm/llvm-project/commit/570984204f24c326699dedcc05793b77b013f068
DIFF: https://github.com/llvm/llvm-project/commit/570984204f24c326699dedcc05793b77b013f068.diff
LOG: [clangd] Fix highlighting for implicit ObjC property refs
Objective-C lets you use the `self.prop` syntax as sugar for both
`[self prop]` and `[self setProp:]`, but clangd previously did not
provide a semantic token for `prop`.
Now, we provide a semantic token, treating it like a normal property
except it's backed by a `ObjCMethodDecl` instead of a
`ObjCPropertyDecl`.
Differential Revision: https://reviews.llvm.org/D104117
Added:
Modified:
clang-tools-extra/clangd/SemanticHighlighting.cpp
clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp
index bb192596f8c52..b49eb785f2deb 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.cpp
+++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp
@@ -556,6 +556,42 @@ class CollectExtraHighlightings
return true;
}
+ // Objective-C allows you to use property syntax `self.prop` as sugar for
+ // `[self prop]` and `[self setProp:]` when there's no explicit `@property`
+ // for `prop` as well as for class properties. We treat this like a property
+ // even though semantically it's equivalent to a method expression.
+ void highlightObjCImplicitPropertyRef(const ObjCMethodDecl *OMD,
+ SourceLocation Loc) {
+ auto &Tok = H.addToken(Loc, HighlightingKind::Field)
+ .addModifier(HighlightingModifier::ClassScope);
+ if (OMD->isClassMethod())
+ Tok.addModifier(HighlightingModifier::Static);
+ if (isDefaultLibrary(OMD))
+ Tok.addModifier(HighlightingModifier::DefaultLibrary);
+ }
+
+ bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *OPRE) {
+ // We need to handle implicit properties here since they will appear to
+ // reference `ObjCMethodDecl` via an implicit `ObjCMessageExpr`, so normal
+ // highlighting will not work.
+ if (!OPRE->isImplicitProperty())
+ return true;
+ // A single property expr can reference both a getter and setter, but we can
+ // only provide a single semantic token, so prefer the getter. In most cases
+ // the end result should be the same, although it's technically possible
+ // that the user defines a setter for a system SDK.
+ if (OPRE->isMessagingGetter()) {
+ highlightObjCImplicitPropertyRef(OPRE->getImplicitPropertyGetter(),
+ OPRE->getLocation());
+ return true;
+ }
+ if (OPRE->isMessagingSetter()) {
+ highlightObjCImplicitPropertyRef(OPRE->getImplicitPropertySetter(),
+ OPRE->getLocation());
+ }
+ return true;
+ }
+
bool VisitOverloadExpr(OverloadExpr *E) {
if (!E->decls().empty())
return true; // handled by findExplicitReferences.
diff --git a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
index 02ab6bef0a817..a0212856427d6 100644
--- a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
@@ -696,11 +696,16 @@ sizeof...($TemplateParameter[[Elements]]);
int $Field_decl[[_someProperty]];
}
@property(nonatomic, assign) int $Field_decl[[someProperty]];
+ @property(readonly, class) $Class[[Foo]] *$Field_decl_readonly_static[[sharedInstance]];
@end
@implementation $Class_decl[[Foo]]
@synthesize someProperty = _someProperty;
+ - (int)$Method_decl[[otherMethod]] {
+ return 0;
+ }
- (int)$Method_decl[[doSomething]] {
- self.$Field[[someProperty]] = self.$Field[[someProperty]] + 1;
+ $Class[[Foo]].$Field_static[[sharedInstance]].$Field[[someProperty]] = 1;
+ self.$Field[[someProperty]] = self.$Field[[someProperty]] + self.$Field[[otherMethod]] + 1;
self->$Field[[_someProperty]] = $Field[[_someProperty]] + 1;
}
@end
More information about the cfe-commits
mailing list