Skip to content

Commit dbbe45e

Browse files
authored
Merge pull request swiftlang#30389 from benlangmuir/index-caf
[index] Add implicit callAsFunction reference to index
2 parents 05f92f1 + 3eff694 commit dbbe45e

File tree

4 files changed

+76
-0
lines changed

4 files changed

+76
-0
lines changed

include/swift/IDE/SourceEntityWalker.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,16 @@ class SourceEntityWalker {
120120
ReferenceMetaData Data,
121121
bool IsOpenBracket);
122122

123+
/// This method is called when a ValueDecl for a callAsFunction decl is
124+
/// referenced in source. If it returns false, the remaining traversal is
125+
/// terminated and returns failure.
126+
///
127+
/// \param D the referenced decl.
128+
/// \param Range the source range of the source reference.
129+
/// \param Data whether this is a read, write or read/write access, etc.
130+
virtual bool visitCallAsFunctionReference(ValueDecl *D, CharSourceRange Range,
131+
ReferenceMetaData Data);
132+
123133
/// This method is called for each keyword argument in a call expression.
124134
/// If it returns false, the remaining traversal is terminated and returns
125135
/// failure.

lib/IDE/SourceEntityWalker.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ class SemaAnnotator : public ASTWalker {
7878

7979
bool passSubscriptReference(ValueDecl *D, SourceLoc Loc,
8080
ReferenceMetaData Data, bool IsOpenBracket);
81+
bool passCallAsFunctionReference(ValueDecl *D, SourceLoc Loc,
82+
ReferenceMetaData Data);
8183

8284
bool passCallArgNames(Expr *Fn, TupleExpr *TupleE);
8385

@@ -271,6 +273,18 @@ std::pair<bool, Expr *> SemaAnnotator::walkToExprPre(Expr *E) {
271273
}
272274
}
273275

276+
if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
277+
auto *FD = dyn_cast<FuncDecl>(DRE->getDecl());
278+
// Handle implicit callAsFunction reference. An explicit reference will be
279+
// handled by the usual DeclRefExpr case below.
280+
if (DRE->isImplicit() && FD && FD->isCallAsFunctionMethod()) {
281+
ReferenceMetaData data(SemaReferenceKind::DeclMemberRef, OpAccess);
282+
if (!passCallAsFunctionReference(FD, DRE->getLoc(), data))
283+
return {false, nullptr};
284+
return {true, E};
285+
}
286+
}
287+
274288
if (!isa<InOutExpr>(E) &&
275289
!isa<LoadExpr>(E) &&
276290
!isa<OpenExistentialExpr>(E) &&
@@ -643,6 +657,17 @@ bool SemaAnnotator::passSubscriptReference(ValueDecl *D, SourceLoc Loc,
643657
return Continue;
644658
}
645659

660+
bool SemaAnnotator::passCallAsFunctionReference(ValueDecl *D, SourceLoc Loc,
661+
ReferenceMetaData Data) {
662+
CharSourceRange Range =
663+
Loc.isValid() ? CharSourceRange(Loc, 1) : CharSourceRange();
664+
665+
bool Continue = SEWalker.visitCallAsFunctionReference(D, Range, Data);
666+
if (!Continue)
667+
Cancelled = true;
668+
return Continue;
669+
}
670+
646671
bool SemaAnnotator::
647672
passReference(ValueDecl *D, Type Ty, DeclNameLoc Loc, ReferenceMetaData Data) {
648673
return passReference(D, Ty, Loc.getBaseNameLoc(), Loc.getSourceRange(), Data);
@@ -792,6 +817,12 @@ bool SourceEntityWalker::visitSubscriptReference(ValueDecl *D,
792817
: true;
793818
}
794819

820+
bool SourceEntityWalker::visitCallAsFunctionReference(ValueDecl *D,
821+
CharSourceRange Range,
822+
ReferenceMetaData Data) {
823+
return true;
824+
}
825+
795826
bool SourceEntityWalker::visitCallArgName(Identifier Name,
796827
CharSourceRange Range,
797828
ValueDecl *D) {

lib/Index/Index.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,13 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
495495
return finishSourceEntity(Info.symInfo, Info.roles);
496496
}
497497

498+
bool visitCallAsFunctionReference(ValueDecl *D, CharSourceRange Range,
499+
ReferenceMetaData Data) override {
500+
// Index implicit callAsFunction reference.
501+
return visitDeclReference(D, Range, /*CtorTyRef*/ nullptr,
502+
/*ExtTyRef*/ nullptr, Type(), Data);
503+
}
504+
498505
Decl *getParentDecl() const {
499506
if (!EntitiesStack.empty())
500507
return EntitiesStack.back().D;

test/Index/index_callasfunction.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %target-swift-ide-test -print-indexed-symbols -source-filename %s | %FileCheck %s
2+
3+
struct Adder {
4+
var base: Int
5+
func callAsFunction(_ x: Int) -> Int {
6+
// CHECK: [[@LINE-1]]:10 | instance-method/Swift | callAsFunction(_:) | [[callAsFunc1:.*]] | Def
7+
return base + x
8+
}
9+
func callAsFunction(x: Int, y: Int) -> Int {
10+
// CHECK: [[@LINE-1]]:10 | instance-method/Swift | callAsFunction(x:y:) | [[callAsFunc2:.*]] | Def
11+
return base + x + y
12+
}
13+
}
14+
15+
let add3 = Adder(base: 3)
16+
// CHECK: [[@LINE-1]]:5 | variable/Swift | add3 | [[add3:.*]] | Def
17+
let global = 1
18+
19+
add3(global)
20+
// CHECK: [[@LINE-1]]:1 | variable/Swift | add3 | [[add3]] | Ref,Read |
21+
// CHECK: [[@LINE-2]]:1 | instance-method/Swift | callAsFunction(_:) | [[callAsFunc1]] | Ref,Call,RelRec | rel: 1
22+
// CHECK: RelRec | struct/Swift | Adder |
23+
// CHECK: [[@LINE-4]]:6 | variable/Swift | global | {{.*}} | Ref,Read |
24+
25+
add3(x: 10, y: 11)
26+
// CHECK: [[@LINE-1]]:1 | variable/Swift | add3 | [[add3]] | Ref,Read |
27+
// CHECK: [[@LINE-2]]:1 | instance-method/Swift | callAsFunction(x:y:) | [[callAsFunc2]] | Ref,Call,RelRec | rel: 1
28+
// CHECK: RelRec | struct/Swift | Adder |

0 commit comments

Comments
 (0)