Skip to content

Commit 50113b7

Browse files
author
Nathan Hawes
committed
[indexer] Fix all function references being reported with the call role regardless of them actually being called or not
1 parent 202ee90 commit 50113b7

File tree

2 files changed

+49
-18
lines changed

2 files changed

+49
-18
lines changed

lib/Index/Index.cpp

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,6 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
210210
return false;
211211
}
212212

213-
214-
215213
public:
216214
IndexSwiftASTWalker(IndexDataConsumer &IdxConsumer, ASTContext &Ctx,
217215
unsigned BufferID)
@@ -327,14 +325,18 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
327325

328326
}
329327

328+
Expr *getContainingExpr(size_t index) {
329+
if (ExprStack.size() > index)
330+
return ExprStack.end()[-(index + 1)];
331+
return nullptr;
332+
}
333+
330334
Expr *getCurrentExpr() {
331335
return ExprStack.empty() ? nullptr : ExprStack.back();
332336
}
333337

334338
Expr *getParentExpr() {
335-
if (ExprStack.size() >= 2)
336-
return ExprStack.end()[-2];
337-
return nullptr;
339+
return getContainingExpr(1);
338340
}
339341

340342

@@ -376,8 +378,7 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
376378
bool initIndexSymbol(ExtensionDecl *D, ValueDecl *ExtendedD, SourceLoc Loc,
377379
IndexSymbol &Info);
378380
bool initFuncDeclIndexSymbol(FuncDecl *D, IndexSymbol &Info);
379-
bool initFuncRefIndexSymbol(Expr *CurrentE, Expr *ParentE, ValueDecl *D,
380-
SourceLoc Loc, IndexSymbol &Info);
381+
bool initFuncRefIndexSymbol(ValueDecl *D, SourceLoc Loc, IndexSymbol &Info);
381382
bool initVarRefIndexSymbols(Expr *CurrentE, ValueDecl *D, SourceLoc Loc,
382383
IndexSymbol &Info);
383384

@@ -685,7 +686,7 @@ bool IndexSwiftASTWalker::reportPseudoAccessor(AbstractStorageDecl *D,
685686
// AbstractStorageDecl.
686687
assert(getParentDecl() == D);
687688
auto PreviousTop = EntitiesStack.pop_back_val();
688-
bool initFailed = initFuncRefIndexSymbol(getCurrentExpr(), getParentExpr(), D, Loc, Info);
689+
bool initFailed = initFuncRefIndexSymbol(D, Loc, Info);
689690
EntitiesStack.push_back(PreviousTop);
690691

691692
if (initFailed)
@@ -821,7 +822,7 @@ bool IndexSwiftASTWalker::reportRef(ValueDecl *D, SourceLoc Loc,
821822
return true; // keep walking
822823

823824
if (isa<AbstractFunctionDecl>(D)) {
824-
if (initFuncRefIndexSymbol(getCurrentExpr(), getParentExpr(), D, Loc, Info))
825+
if (initFuncRefIndexSymbol(D, Loc, Info))
825826
return true;
826827
} else if (isa<AbstractStorageDecl>(D)) {
827828
if (initVarRefIndexSymbols(getCurrentExpr(), D, Loc, Info))
@@ -1021,33 +1022,49 @@ static bool isDynamicCall(Expr *BaseE, ValueDecl *D) {
10211022
return true;
10221023
}
10231024

1024-
bool IndexSwiftASTWalker::initFuncRefIndexSymbol(Expr *CurrentE, Expr *ParentE,
1025-
ValueDecl *D, SourceLoc Loc,
1025+
static bool isBeingCalled(Expr *Target, Expr *Parent, Expr *GrandParent) {
1026+
if (!Target || !Parent || !isa<ApplyExpr>(Parent))
1027+
return false;
1028+
1029+
if (!isa<SelfApplyExpr>(Parent))
1030+
return cast<ApplyExpr>(Parent)->getFn() == Target;
1031+
1032+
return GrandParent && isa<CallExpr>(GrandParent) &&
1033+
cast<CallExpr>(GrandParent)->getFn() == Parent;
1034+
}
1035+
1036+
bool IndexSwiftASTWalker::initFuncRefIndexSymbol(ValueDecl *D, SourceLoc Loc,
10261037
IndexSymbol &Info) {
10271038

10281039
if (initIndexSymbol(D, Loc, /*IsRef=*/true, Info))
10291040
return true;
10301041

1042+
Expr *CurrentE = getCurrentExpr();
10311043
if (!CurrentE)
10321044
return false;
10331045

1046+
Expr *ParentE = getParentExpr();
1047+
10341048
// FIXME: the below check maintains existing indexing behavior with
10351049
// pseudo/accessor output but seems incorrect. E.g otherGlobal in:
10361050
// let global = otherGlobal
10371051
// will not have a parent expression so no accessor call is reported
1038-
if (!ParentE)
1052+
if (isa<AbstractStorageDecl>(D) && !ParentE)
10391053
return true;
10401054

1041-
Info.roles |= (unsigned)SymbolRole::Call;
1055+
if (!isa<AbstractStorageDecl>(D) &&
1056+
!isBeingCalled(CurrentE, ParentE, getContainingExpr(2)))
1057+
return false;
10421058

1043-
Decl *ParentD = getParentDecl();
1044-
if (ParentD && isa<ValueDecl>(ParentD)) {
1045-
if (addRelation(Info, (SymbolRoleSet) SymbolRole::RelationCalledBy, cast<ValueDecl>(ParentD)))
1046-
return true;
1059+
1060+
Info.roles |= (unsigned)SymbolRole::Call;
1061+
if (auto *Caller = dyn_cast_or_null<AbstractFunctionDecl>(getParentDecl())) {
1062+
if (addRelation(Info, (SymbolRoleSet) SymbolRole::RelationCalledBy, Caller))
1063+
return true;
10471064
}
10481065

10491066
Expr *BaseE = nullptr;
1050-
if (auto DotE = dyn_cast<DotSyntaxCallExpr>(ParentE))
1067+
if (auto DotE = dyn_cast_or_null<DotSyntaxCallExpr>(ParentE))
10511068
BaseE = DotE->getBase();
10521069
else if (auto MembE = dyn_cast<MemberRefExpr>(CurrentE))
10531070
BaseE = MembE->getBase();

test/Index/roles.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ func aCaller() {
6868
// CHECK-NEXT: RelCall | aCaller() | s:F14swift_ide_test7aCallerFT_T_
6969
}
7070

71+
let _ = aCalledFunction
72+
// CHECK: [[@LINE-1]]:9 | function/Swift | aCalledFunction() | s:F14swift_ide_test15aCalledFunctionFT_T_ | Ref | rel: 0
73+
7174
// RelationChildOf, Implicit
7275
struct AStruct {
7376
var x: Int
@@ -133,6 +136,17 @@ class AClass {
133136
}
134137
}
135138

139+
let _ = AClass.foo
140+
// CHECK: [[@LINE-1]]:16 | instance-method/Swift | foo() | s:FC14swift_ide_test6AClass3fooFT_Si | Ref | rel: 0
141+
let _ = AClass(x: 1).foo
142+
// CHECK: [[@LINE-1]]:22 | instance-method/Swift | foo() | s:FC14swift_ide_test6AClass3fooFT_Si | Ref | rel: 0
143+
let _ = AClass(x: 1)[1]
144+
// CHECK: [[@LINE-1]]:21 | instance-property/subscript/Swift | subscript(_:) | s:iC14swift_ide_test6AClass9subscriptFSiSi | Ref,Read | rel: 0
145+
// CHECK: [[@LINE-2]]:21 | function/acc-get/Swift | getter:subscript(_:) | s:FC14swift_ide_test6AClassg9subscriptFSiSi | Ref,Call,Dyn,Impl,RelRec | rel: 1
146+
let _ = AClass(x: 1)[1] = 2
147+
// CHECK: [[@LINE-1]]:21 | instance-property/subscript/Swift | subscript(_:) | s:iC14swift_ide_test6AClass9subscriptFSiSi | Ref,Writ | rel: 0
148+
// CHECK: [[@LINE-2]]:21 | function/acc-set/Swift | setter:subscript(_:) | s:FC14swift_ide_test6AClasss9subscriptFSiSi | Ref,Call,Dyn,Impl,RelRec | rel: 1
149+
136150
protocol AProtocol {
137151
// CHECK: [[@LINE-1]]:10 | protocol/Swift | AProtocol | [[AProtocol_USR:.*]] | Def | rel: 0
138152
func foo() -> Int

0 commit comments

Comments
 (0)