Skip to content

Commit 42e1a38

Browse files
committed
[SourceKit] When cursor points to an external argument name in a function-like decl, we should return the information about the function-like decl instead of being empty. rdar://32018814 (#9356)
1 parent e827d22 commit 42e1a38

File tree

5 files changed

+94
-8
lines changed

5 files changed

+94
-8
lines changed

include/swift/AST/SourceEntityWalker.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,19 @@ class SourceEntityWalker {
124124
virtual bool visitCallArgName(Identifier Name, CharSourceRange Range,
125125
ValueDecl *D);
126126

127+
/// This method is called for each external argument name in function-like
128+
/// declarations like constructor, function and subscript. The function is
129+
/// called only when a external argument label is specifically specified,
130+
/// like func foo(External Internal: Int) {}.
131+
/// If it returns false, the remaining traversal is terminated and returns
132+
/// failure.
133+
///
134+
/// \param Name the argument name.
135+
/// \param StartLoc the source loc of the argument name start.
136+
/// \param D the function-like decl.
137+
virtual bool visitDeclarationArgumentName(Identifier Name, SourceLoc StartLoc,
138+
ValueDecl *D);
139+
127140
/// This method is called when a Module is referenced in source.
128141
virtual bool visitModuleReference(ModuleEntity Mod, CharSourceRange Range);
129142

include/swift/IDE/Utils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@ class SemaLocResolver : public SourceEntityWalker {
199199
ReferenceMetaData Data) override;
200200
bool visitCallArgName(Identifier Name, CharSourceRange Range,
201201
ValueDecl *D) override;
202+
bool visitDeclarationArgumentName(Identifier Name, SourceLoc StartLoc,
203+
ValueDecl *D) override;
202204
bool visitModuleReference(ModuleEntity Mod, CharSourceRange Range) override;
203205
bool rangeContainsLoc(SourceRange Range) const {
204206
return getSourceMgr().rangeContainsTokenLoc(Range, LocToResolve);

lib/AST/SourceEntityWalker.cpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "swift/AST/Expr.h"
1919
#include "swift/AST/Module.h"
2020
#include "swift/AST/Pattern.h"
21+
#include "swift/AST/ParameterList.h"
2122
#include "swift/AST/Stmt.h"
2223
#include "swift/AST/TypeRepr.h"
2324
#include "swift/AST/Types.h"
@@ -97,7 +98,30 @@ bool SemaAnnotator::walkToDeclPre(Decl *D) {
9798
if (VD->hasName() && !VD->isImplicit())
9899
NameLen = VD->getName().getLength();
99100

100-
} else if (ExtensionDecl *ED = dyn_cast<ExtensionDecl>(D)) {
101+
auto ReportParamList = [&](ParameterList *PL) {
102+
for (auto *PD : *PL) {
103+
auto Loc = PD->getArgumentNameLoc();
104+
if (Loc.isInvalid())
105+
continue;
106+
if (!SEWalker.visitDeclarationArgumentName(PD->getArgumentName(), Loc,
107+
VD)) {
108+
Cancelled = true;
109+
return true;
110+
}
111+
}
112+
return false;
113+
};
114+
115+
if (auto AF = dyn_cast<AbstractFunctionDecl>(VD)) {
116+
for (auto *PL : AF->getParameterLists())
117+
if (ReportParamList(PL))
118+
return false;
119+
}
120+
if (auto SD = dyn_cast<SubscriptDecl>(VD)) {
121+
if (ReportParamList(SD->getIndices()))
122+
return false;
123+
}
124+
} else if (auto *ED = dyn_cast<ExtensionDecl>(D)) {
101125
SourceRange SR = ED->getExtendedTypeLoc().getSourceRange();
102126
Loc = SR.Start;
103127
if (Loc.isValid())
@@ -557,6 +581,11 @@ bool SourceEntityWalker::visitCallArgName(Identifier Name,
557581
return true;
558582
}
559583

584+
bool SourceEntityWalker::
585+
visitDeclarationArgumentName(Identifier Name, SourceLoc Start, ValueDecl *D) {
586+
return true;
587+
}
588+
560589
bool SourceEntityWalker::visitModuleReference(ModuleEntity Mod,
561590
CharSourceRange Range) {
562591
return true;

lib/IDE/SwiftSourceDocInfo.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,13 @@ bool SemaLocResolver::visitCallArgName(Identifier Name, CharSourceRange Range,
199199
return !Found;
200200
}
201201

202+
bool SemaLocResolver::
203+
visitDeclarationArgumentName(Identifier Name, SourceLoc StartLoc, ValueDecl *D) {
204+
if (isDone())
205+
return false;
206+
return !tryResolve(D, nullptr, nullptr, StartLoc, /*IsRef=*/false);
207+
}
208+
202209
bool SemaLocResolver::visitModuleReference(ModuleEntity Mod,
203210
CharSourceRange Range) {
204211
if (isDone())

test/SourceKit/CursorInfo/cursor_label.swift

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,54 @@ class C1 {
1313
let c = C1(cc: 1)
1414
c.foo(aa : 1)
1515

16+
class C2 {
17+
init(cc cc: Int) {}
18+
func foo(aa aa : Int) {}
19+
subscript(aa aa : Int, bb bb: Int)-> Int { get { return 0 } set {}}
20+
}
21+
1622
// RUN: %sourcekitd-test -req=cursor -pos=2:9 %s -- %s | %FileCheck %s -check-prefix=CHECK1
1723
// RUN: %sourcekitd-test -req=cursor -pos=3:13 %s -- %s | %FileCheck %s -check-prefix=CHECK2
1824
// RUN: %sourcekitd-test -req=cursor -pos=4:24 %s -- %s | %FileCheck %s -check-prefix=CHECK3
19-
// RUN: %sourcekitd-test -req=cursor -pos=5:15 %s -- %s | %FileCheck %s -check-prefix=CHECK-NONE
20-
// RUN: %sourcekitd-test -req=cursor -pos=6:11 %s -- %s | %FileCheck %s -check-prefix=CHECK-NONE
21-
// RUN: %sourcekitd-test -req=cursor -pos=7:16 %s -- %s | %FileCheck %s -check-prefix=CHECK-NONE
22-
// RUN: %sourcekitd-test -req=cursor -pos=8:18 %s -- %s | %FileCheck %s -check-prefix=CHECK-NONE
25+
// RUN: %sourcekitd-test -req=cursor -pos=5:15 %s -- %s | %FileCheck %s -check-prefix=CHECK-NO-PARENT-PARAM
26+
// RUN: %sourcekitd-test -req=cursor -pos=6:11 %s -- %s | %FileCheck %s -check-prefix=CHECK-NO-PARENT-PARAM
27+
// RUN: %sourcekitd-test -req=cursor -pos=7:16 %s -- %s | %FileCheck %s -check-prefix=CHECK-NO-PARENT-PARAM
28+
// RUN: %sourcekitd-test -req=cursor -pos=8:18 %s -- %s | %FileCheck %s -check-prefix=CHECK-NO-PARENT-PARAM
2329
// RUN: %sourcekitd-test -req=cursor -pos=8:28 %s -- %s | %FileCheck %s -check-prefix=CHECK4
24-
// RUN: %sourcekitd-test -req=cursor -pos=9:9 %s -- %s | %FileCheck %s -check-prefix=CHECK-NONE
25-
// RUN: %sourcekitd-test -req=cursor -pos=10:9 %s -- %s | %FileCheck %s -check-prefix=CHECK4
30+
// RUN: %sourcekitd-test -req=cursor -pos=9:9 %s -- %s | %FileCheck %s -check-prefix=CHECK-NO-PARENT-VAR
31+
// RUN: %sourcekitd-test -req=cursor -pos=10:9 %s -- %s | %FileCheck %s -check-prefix=CHECK5
2632

33+
// CHECK1: source.lang.swift.decl.var.parameter
2734
// CHECK1: PARENT OFFSET: 13
35+
36+
// CHECK2: source.lang.swift.decl.var.parameter
2837
// CHECK2: PARENT OFFSET: 37
38+
39+
// CHECK3: source.lang.swift.decl.var.parameter
2940
// CHECK3: PARENT OFFSET: 56
41+
42+
// CHECK4: source.lang.swift.decl.var.parameter
3043
// CHECK4: PARENT OFFSET: 229
31-
// CHECK-NONE-NOT: PARENT OFFSET:
44+
45+
// CHECK5: source.lang.swift.ref.var.local
46+
// CHECK5: PARENT OFFSET: 229
47+
48+
// CHECK-NO-PARENT-PARAM: source.lang.swift.decl.var.parameter
49+
// CHECK-NO-PARENT-PARAM-NOT: PARENT OFFSET:
50+
51+
// CHECK-NO-PARENT-VAR: source.lang.swift.ref.var.local
52+
// CHECK-NO-PARENT-VAR-NOT: PARENT OFFSET:
53+
54+
// RUN: %sourcekitd-test -req=cursor -pos=17:9 %s -- %s | %FileCheck %s -check-prefix=CHECK-CONSTRUCTOR
55+
// RUN: %sourcekitd-test -req=cursor -pos=18:13 %s -- %s | %FileCheck %s -check-prefix=CHECK-FUNC
56+
// RUN: %sourcekitd-test -req=cursor -pos=19:14 %s -- %s | %FileCheck %s -check-prefix=CHECK-SUBS
57+
// RUN: %sourcekitd-test -req=cursor -pos=19:27 %s -- %s | %FileCheck %s -check-prefix=CHECK-SUBS
58+
59+
// CHECK-CONSTRUCTOR: source.lang.swift.decl.function.constructor
60+
// CHECK-CONSTRUCTOR-NOT: PARENT OFFSET:
61+
62+
// CHECK-FUNC: source.lang.swift.decl.function.method.instance
63+
// CHECK-FUNC-NOT: PARENT OFFSET:
64+
65+
// CHECK-SUBS: source.lang.swift.decl.function.subscript
66+
// CHECK-SUBS-NOT: PARENT OFFSET:

0 commit comments

Comments
 (0)