File tree Expand file tree Collapse file tree 4 files changed +70
-0
lines changed Expand file tree Collapse file tree 4 files changed +70
-0
lines changed Original file line number Diff line number Diff line change @@ -605,6 +605,10 @@ class SelectionVisitor : public RecursiveASTVisitor<SelectionVisitor> {
605
605
bool canSafelySkipNode (const DynTypedNode &N) {
606
606
SourceRange S = N.getSourceRange ();
607
607
if (auto *TL = N.get <TypeLoc>()) {
608
+ // FIXME: TypeLoc::getBeginLoc()/getEndLoc() are pretty fragile
609
+ // heuristics. We should consider only pruning critical TypeLoc nodes, to
610
+ // be more robust.
611
+
608
612
// DeclTypeTypeLoc::getSourceRange() is incomplete, which would lead to
609
613
// failing
610
614
// to descend into the child expression.
@@ -616,6 +620,10 @@ class SelectionVisitor : public RecursiveASTVisitor<SelectionVisitor> {
616
620
// rid of this patch.
617
621
if (auto DT = TL->getAs <DecltypeTypeLoc>())
618
622
S.setEnd (DT.getUnderlyingExpr ()->getEndLoc ());
623
+ // AttributedTypeLoc may point to the attribute's range, NOT the modified
624
+ // type's range.
625
+ if (auto AT = TL->getAs <AttributedTypeLoc>())
626
+ S = AT.getModifiedLoc ().getSourceRange ();
619
627
}
620
628
if (!SelChecker.mayHit (S)) {
621
629
dlog (" {1}skip: {0}" , printNodeToString (N, PrintPolicy), indent ());
Original file line number Diff line number Diff line change @@ -831,6 +831,24 @@ TEST_F(TargetDeclTest, ObjC) {
831
831
EXPECT_DECLS (" ObjCPropertyRefExpr" ,
832
832
" @property(atomic, retain, readwrite) I *x" );
833
833
834
+ Code = R"cpp(
835
+ @interface MYObject
836
+ @end
837
+ @interface Interface
838
+ @property(retain) [[MYObject]] *x;
839
+ @end
840
+ )cpp" ;
841
+ EXPECT_DECLS (" ObjCInterfaceTypeLoc" , " @interface MYObject" );
842
+
843
+ Code = R"cpp(
844
+ @interface MYObject2
845
+ @end
846
+ @interface Interface
847
+ @property(retain, nonnull) [[MYObject2]] *x;
848
+ @end
849
+ )cpp" ;
850
+ EXPECT_DECLS (" ObjCInterfaceTypeLoc" , " @interface MYObject2" );
851
+
834
852
Code = R"cpp(
835
853
@protocol Foo
836
854
@end
Original file line number Diff line number Diff line change @@ -1991,6 +1991,34 @@ TEST(Hover, All) {
1991
1991
HI.NamespaceScope = " ObjC::" ; // FIXME: fix it
1992
1992
HI.Definition = " char data" ;
1993
1993
}},
1994
+ {
1995
+ R"cpp(
1996
+ @interface MYObject
1997
+ @end
1998
+ @interface Interface
1999
+ @property(retain) [[MYOb^ject]] *x;
2000
+ @end
2001
+ )cpp" ,
2002
+ [](HoverInfo &HI) {
2003
+ HI.Name = " MYObject" ;
2004
+ HI.Kind = index::SymbolKind::Class;
2005
+ HI.NamespaceScope = " " ;
2006
+ HI.Definition = " @interface MYObject\n @end" ;
2007
+ }},
2008
+ {
2009
+ R"cpp(
2010
+ @interface MYObject
2011
+ @end
2012
+ @interface Interface
2013
+ - (void)doWith:([[MYOb^ject]] *)object;
2014
+ @end
2015
+ )cpp" ,
2016
+ [](HoverInfo &HI) {
2017
+ HI.Name = " MYObject" ;
2018
+ HI.Kind = index::SymbolKind::Class;
2019
+ HI.NamespaceScope = " " ;
2020
+ HI.Definition = " @interface MYObject\n @end" ;
2021
+ }},
1994
2022
};
1995
2023
1996
2024
// Create a tiny index, so tests above can verify documentation is fetched.
Original file line number Diff line number Diff line change @@ -356,6 +356,22 @@ TEST(SelectionTest, CommonAncestor) {
356
356
)cpp" ,
357
357
" DeclRefExpr" },
358
358
359
+ // Objective-C nullability attributes.
360
+ {
361
+ R"cpp(
362
+ @interface I{}
363
+ @property(nullable) [[^I]] *x;
364
+ @end
365
+ )cpp" ,
366
+ " ObjCInterfaceTypeLoc" },
367
+ {
368
+ R"cpp(
369
+ @interface I{}
370
+ - (void)doSomething:(nonnull [[i^d]])argument;
371
+ @end
372
+ )cpp" ,
373
+ " TypedefTypeLoc" },
374
+
359
375
// Objective-C OpaqueValueExpr/PseudoObjectExpr has weird ASTs.
360
376
// Need to traverse the contents of the OpaqueValueExpr to the POE,
361
377
// and ensure we traverse only the syntactic form of the PseudoObjectExpr.
You can’t perform that action at this time.
0 commit comments