r335983 - [clang-format/ObjC] Fix NS_SWIFT_NAME(foo(bar:baz:)) after ObjC method decl

Ben Hamilton via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 29 08:26:37 PDT 2018


Author: benhamilton
Date: Fri Jun 29 08:26:37 2018
New Revision: 335983

URL: http://llvm.org/viewvc/llvm-project?rev=335983&view=rev
Log:
[clang-format/ObjC] Fix NS_SWIFT_NAME(foo(bar:baz:)) after ObjC method decl

Summary:
In D44638, I partially fixed `NS_SWIFT_NAME(foo(bar:baz:))`-style
annotations on C functions, but didn't add a test for Objective-C
method declarations.

For ObjC method declarations which are annotated with `NS_SWIFT_NAME(...)`,
we currently fail to annotate the final component of the selector
name as `TT_SelectorName`.

Because the token type is left unknown, clang-format will happily
cause a compilation error when it changes the following:

```
@interface Foo
- (void)doStuffWithFoo:(id)name
                   bar:(id)bar
                   baz:(id)baz
    NS_SWIFT_NAME(doStuff(withFoo:bar:baz:));
@end
```

to:

```
@interface Foo
- (void)doStuffWithFoo:(id)name
                   bar:(id)bar
                   baz:(id)baz
    NS_SWIFT_NAME(doStuff(withFoo:bar:baz
:));
@end
```

(note the linebreak before the final `:`).

The logic which decides whether or not to annotate the token before a
`:` with `TT_SelectorName` is pretty fragile, and has to handle some
pretty odd cases like pair-parameters:

```
[I drawRectOn:surface ofSize:aa:bbb atOrigin:cc:dd];
```

So, to minimize the effect of this change, I decided to only annotate
unknown identifiers before a `:` as `TT_SelectorName` for Objective-C
declaration lines.

Test Plan: New tests included. Confirmed tests failed before change and
  passed after change. Ran tests with:
  % make -j16 FormatTests && ./tools/clang/unittests/Format/FormatTests

Reviewers: djasper, krasimir, jolesiak

Reviewed By: krasimir

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D48679

Modified:
    cfe/trunk/lib/Format/TokenAnnotator.cpp
    cfe/trunk/unittests/Format/FormatTestObjC.cpp

Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=335983&r1=335982&r2=335983&view=diff
==============================================================================
--- cfe/trunk/lib/Format/TokenAnnotator.cpp (original)
+++ cfe/trunk/lib/Format/TokenAnnotator.cpp Fri Jun 29 08:26:37 2018
@@ -698,13 +698,19 @@ private:
                  Line.startsWith(TT_ObjCMethodSpecifier)) {
         Tok->Type = TT_ObjCMethodExpr;
         const FormatToken *BeforePrevious = Tok->Previous->Previous;
+        // Ensure we tag all identifiers in method declarations as
+        // TT_SelectorName.
+        bool UnknownIdentifierInMethodDeclaration =
+            Line.startsWith(TT_ObjCMethodSpecifier) &&
+            Tok->Previous->is(tok::identifier) && Tok->Previous->is(TT_Unknown);
         if (!BeforePrevious ||
             // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen.
             !(BeforePrevious->is(TT_CastRParen) ||
               (BeforePrevious->is(TT_ObjCMethodExpr) &&
                BeforePrevious->is(tok::colon))) ||
             BeforePrevious->is(tok::r_square) ||
-            Contexts.back().LongestObjCSelectorName == 0) {
+            Contexts.back().LongestObjCSelectorName == 0 ||
+            UnknownIdentifierInMethodDeclaration) {
           Tok->Previous->Type = TT_SelectorName;
           if (!Contexts.back().FirstObjCSelectorName)
             Contexts.back().FirstObjCSelectorName = Tok->Previous;

Modified: cfe/trunk/unittests/Format/FormatTestObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestObjC.cpp?rev=335983&r1=335982&r2=335983&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTestObjC.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTestObjC.cpp Fri Jun 29 08:26:37 2018
@@ -923,6 +923,14 @@ TEST_F(FormatTestObjC, ObjCSnippets) {
   verifyFormat("@property(assign, nonatomic) CGFloat hoverAlpha;");
   verifyFormat("@property(assign, getter=isEditable) BOOL editable;");
 
+  Style.ColumnLimit = 50;
+  verifyFormat("@interface Foo\n"
+               "- (void)doStuffWithFoo:(id)name\n"
+               "                   bar:(id)bar\n"
+               "                   baz:(id)baz\n"
+               "    NS_SWIFT_NAME(doStuff(withFoo:bar:baz:));\n"
+               "@end");
+
   Style = getMozillaStyle();
   verifyFormat("@property (assign, getter=isEditable) BOOL editable;");
   verifyFormat("@property BOOL editable;");




More information about the cfe-commits mailing list