@@ -411,6 +411,85 @@ TEST(LocateSymbol, FindOverrides) {
411
411
sym (" foo" , Code.range (" 2" ), std::nullopt)));
412
412
}
413
413
414
+ TEST (LocateSymbol, FindOverridesFromDefObjC) {
415
+ auto Code = Annotations (R"objc(
416
+ @protocol Fooey
417
+ - (void)foo;
418
+ @end
419
+ @interface Base
420
+ - (void)foo;
421
+ @end
422
+ @interface Foo : Base<Fooey>
423
+ - (void)$1[[foo]];
424
+ @end
425
+
426
+ @interface Bar : Foo
427
+ - (void)$2[[foo]];
428
+ @end
429
+ @implementation Bar
430
+ - (void)$3[[fo^o]] {}
431
+ @end
432
+ )objc" );
433
+ TestTU TU = TestTU::withCode (Code.code ());
434
+ TU.ExtraArgs .push_back (" -xobjective-c++" );
435
+ auto AST = TU.build ();
436
+ EXPECT_THAT (
437
+ locateSymbolAt (AST, Code.point (), TU.index ().get ()),
438
+ UnorderedElementsAre (sym (" foo" , Code.range (" 1" ), std::nullopt),
439
+ sym (" foo" , Code.range (" 2" ), Code.range (" 3" ))));
440
+ }
441
+
442
+ TEST (LocateSymbol, NoOverridesFromDeclObjC) {
443
+ auto Code = Annotations (R"objc(
444
+ @protocol Fooey
445
+ - (void)foo;
446
+ @end
447
+ @interface Base
448
+ - (void)foo;
449
+ @end
450
+ @interface Foo : Base<Fooey>
451
+ - (void)foo;
452
+ @end
453
+
454
+ @interface Bar : Foo
455
+ - (void)$2[[fo^o]];
456
+ @end
457
+ @implementation Bar
458
+ - (void)$3[[foo]] {}
459
+ @end
460
+ )objc" );
461
+ TestTU TU = TestTU::withCode (Code.code ());
462
+ TU.ExtraArgs .push_back (" -xobjective-c++" );
463
+ auto AST = TU.build ();
464
+ EXPECT_THAT (
465
+ locateSymbolAt (AST, Code.point (), TU.index ().get ()),
466
+ UnorderedElementsAre (sym (" foo" , Code.range (" 2" ), Code.range (" 3" ))));
467
+ }
468
+
469
+ TEST (LocateSymbol, ObjCNoOverridesOnUsage) {
470
+ auto Code = Annotations (R"objc(
471
+ @interface Foo
472
+ - (void)foo;
473
+ @end
474
+
475
+ @interface Bar : Foo
476
+ - (void)$1[[foo]];
477
+ @end
478
+ @implementation Bar
479
+ - (void)$2[[foo]] {}
480
+ @end
481
+ void doSomething(Bar *bar) {
482
+ [bar fo^o];
483
+ }
484
+ )objc" );
485
+ TestTU TU = TestTU::withCode (Code.code ());
486
+ TU.ExtraArgs .push_back (" -xobjective-c++" );
487
+ auto AST = TU.build ();
488
+ EXPECT_THAT (
489
+ locateSymbolAt (AST, Code.point (), TU.index ().get ()),
490
+ UnorderedElementsAre (sym (" foo" , Code.range (" 1" ), Code.range (" 2" ))));
491
+ }
492
+
414
493
TEST (LocateSymbol, WithIndexPreferredLocation) {
415
494
Annotations SymbolHeader (R"cpp(
416
495
class $p[[Proto]] {};
@@ -1834,6 +1913,41 @@ TEST(FindImplementations, Inheritance) {
1834
1913
}
1835
1914
}
1836
1915
1916
+ TEST (FindImplementations, InheritanceObjC) {
1917
+ llvm::StringRef Test = R"objc(
1918
+ @interface $base^Base
1919
+ - (void)fo$foo^o;
1920
+ @end
1921
+ @protocol Protocol
1922
+ - (void)$protocol^protocol;
1923
+ @end
1924
+ @interface $ChildDecl[[Child]] : Base <Protocol>
1925
+ - (void)concrete;
1926
+ - (void)$fooDecl[[foo]];
1927
+ @end
1928
+ @implementation $ChildDef[[Child]]
1929
+ - (void)concrete {}
1930
+ - (void)$fooDef[[foo]] {}
1931
+ - (void)$protocolDef[[protocol]] {}
1932
+ @end
1933
+ )objc" ;
1934
+
1935
+ Annotations Code (Test);
1936
+ auto TU = TestTU::withCode (Code.code ());
1937
+ TU.ExtraArgs .push_back (" -xobjective-c++" );
1938
+ auto AST = TU.build ();
1939
+ auto Index = TU.index ();
1940
+ EXPECT_THAT (findImplementations (AST, Code.point (" base" ), Index.get ()),
1941
+ UnorderedElementsAre (sym (" Child" , Code.range (" ChildDecl" ),
1942
+ Code.range (" ChildDef" ))));
1943
+ EXPECT_THAT (findImplementations (AST, Code.point (" foo" ), Index.get ()),
1944
+ UnorderedElementsAre (
1945
+ sym (" foo" , Code.range (" fooDecl" ), Code.range (" fooDef" ))));
1946
+ EXPECT_THAT (findImplementations (AST, Code.point (" protocol" ), Index.get ()),
1947
+ UnorderedElementsAre (sym (" protocol" , Code.range (" protocolDef" ),
1948
+ Code.range (" protocolDef" ))));
1949
+ }
1950
+
1837
1951
TEST (FindImplementations, CaptureDefinition) {
1838
1952
llvm::StringRef Test = R"cpp(
1839
1953
struct Base {
@@ -1963,6 +2077,7 @@ void checkFindRefs(llvm::StringRef Test, bool UseIndex = false) {
1963
2077
Annotations T (Test);
1964
2078
auto TU = TestTU::withCode (T.code ());
1965
2079
TU.ExtraArgs .push_back (" -std=c++20" );
2080
+ TU.ExtraArgs .push_back (" -xobjective-c++" );
1966
2081
1967
2082
auto AST = TU.build ();
1968
2083
std::vector<Matcher<ReferencesResult::Reference>> ExpectedLocations;
@@ -2260,6 +2375,25 @@ TEST(FindReferences, IncludeOverrides) {
2260
2375
checkFindRefs (Test, /* UseIndex=*/ true );
2261
2376
}
2262
2377
2378
+ TEST (FindReferences, IncludeOverridesObjC) {
2379
+ llvm::StringRef Test =
2380
+ R"objc(
2381
+ @interface Base
2382
+ - (void)$decl(Base)[[f^unc]];
2383
+ @end
2384
+ @interface Derived : Base
2385
+ - (void)$overridedecl(Derived::func)[[func]];
2386
+ @end
2387
+ @implementation Derived
2388
+ - (void)$overridedef[[func]] {}
2389
+ @end
2390
+ void test(Derived *derived, Base *base) {
2391
+ [derived func]; // No references to the overrides.
2392
+ [base $(test)[[func]]];
2393
+ })objc" ;
2394
+ checkFindRefs (Test, /* UseIndex=*/ true );
2395
+ }
2396
+
2263
2397
TEST (FindReferences, RefsToBaseMethod) {
2264
2398
llvm::StringRef Test =
2265
2399
R"cpp(
@@ -2284,6 +2418,27 @@ TEST(FindReferences, RefsToBaseMethod) {
2284
2418
checkFindRefs (Test, /* UseIndex=*/ true );
2285
2419
}
2286
2420
2421
+ TEST (FindReferences, RefsToBaseMethodObjC) {
2422
+ llvm::StringRef Test =
2423
+ R"objc(
2424
+ @interface BaseBase
2425
+ - (void)$(BaseBase)[[func]];
2426
+ @end
2427
+ @interface Base : BaseBase
2428
+ - (void)$(Base)[[func]];
2429
+ @end
2430
+ @interface Derived : Base
2431
+ - (void)$decl(Derived)[[fu^nc]];
2432
+ @end
2433
+ void test(BaseBase *bb, Base *b, Derived *d) {
2434
+ // refs to overridden methods in complete type hierarchy are reported.
2435
+ [bb $(test)[[func]]];
2436
+ [b $(test)[[func]]];
2437
+ [d $(test)[[fu^nc]]];
2438
+ })objc" ;
2439
+ checkFindRefs (Test, /* UseIndex=*/ true );
2440
+ }
2441
+
2287
2442
TEST (FindReferences, MainFileReferencesOnly) {
2288
2443
llvm::StringRef Test =
2289
2444
R"cpp(
0 commit comments