[PATCH] D104117: [clangd] Fix highlighting for implicit ObjC property refs

David Goldman via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 11 07:21:08 PDT 2021


dgoldman created this revision.
dgoldman added reviewers: sammccall, kadircet.
Herald added subscribers: usaxena95, arphaman.
dgoldman requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.
Herald added a project: clang-tools-extra.

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`.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D104117

Files:
  clang-tools-extra/clangd/SemanticHighlighting.cpp
  clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp


Index: clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
+++ clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
@@ -696,11 +696,16 @@
           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
Index: clang-tools-extra/clangd/SemanticHighlighting.cpp
===================================================================
--- clang-tools-extra/clangd/SemanticHighlighting.cpp
+++ clang-tools-extra/clangd/SemanticHighlighting.cpp
@@ -556,6 +556,40 @@
     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`. 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.
+    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.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D104117.351441.patch
Type: text/x-patch
Size: 3120 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210611/0d01757c/attachment.bin>


More information about the cfe-commits mailing list