Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/swift/AST/ASTWalker.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ struct ReferenceMetaData {
SemaReferenceKind Kind;
llvm::Optional<AccessKind> AccKind;
bool isImplicit = false;
bool isImplicitCtorType = false;

/// When non-none, this is a custom attribute reference.
Optional<std::pair<const CustomAttr *, Decl *>> CustomAttrRef;
Expand Down
12 changes: 12 additions & 0 deletions lib/IDE/SourceEntityWalker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,18 @@ ASTWalker::PreWalkAction SemaAnnotator::walkToTypeReprPre(TypeRepr *T) {
ReferenceMetaData(SemaReferenceKind::TypeRef, None));
return Action::StopIf(!Continue);
}
} else if (auto FT = dyn_cast<FixedTypeRepr>(T)) {
ValueDecl *VD = FT->getType()->getAnyGeneric();
if (auto DT = FT->getType()->getAs<DynamicSelfType>())
VD = DT->getSelfType()->getAnyGeneric();

if (VD) {
auto Data = ReferenceMetaData(SemaReferenceKind::TypeRef, None);
Data.isImplicitCtorType = true;
auto Continue = passReference(VD, FT->getType(), FT->getLoc(),
FT->getSourceRange(), Data);
return Action::StopIf(!Continue);
}
}

return Action::Continue();
Expand Down
7 changes: 5 additions & 2 deletions lib/IDE/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -849,8 +849,11 @@ bool swift::ide::isBeingCalled(ArrayRef<Expr *> ExprStack) {
auto *AE = dyn_cast<ApplyExpr>(E);
if (!AE || AE->isImplicit())
continue;
if (auto *CRCE = dyn_cast<ConstructorRefCallExpr>(AE)) {
if (CRCE->getBase() == Target)
if (auto *CRCE = dyn_cast<ConstructorRefCallExpr>(AE->getFn())) {
auto *Base = CRCE->getBase();
while (auto *ICE = dyn_cast<ImplicitConversionExpr>(Base))
Base = ICE->getSubExpr();
if (Base == Target)
return true;
}
if (isa<SelfApplyExpr>(AE))
Expand Down
8 changes: 6 additions & 2 deletions lib/Index/Index.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -857,9 +857,13 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
if (Data.isImplicit)
Info.roles |= (unsigned)SymbolRole::Implicit;

if (CtorTyRef)
if (!reportRef(CtorTyRef, Loc, Info, Data.AccKind))
if (CtorTyRef) {
IndexSymbol CtorInfo(Info);
if (Data.isImplicitCtorType)
CtorInfo.roles |= (unsigned)SymbolRole::Implicit;
if (!reportRef(CtorTyRef, Loc, CtorInfo, Data.AccKind))
return false;
}

if (auto *GenParam = dyn_cast<GenericTypeParamDecl>(D)) {
D = canonicalizeGenericTypeParamDeclForIndex(GenParam);
Expand Down
57 changes: 57 additions & 0 deletions test/Index/index_self.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// RUN: %target-swift-ide-test -print-indexed-symbols -source-filename %s | %FileCheck %s

struct Foo { // CHECK: [[@LINE]]:8 | struct/Swift | Foo | [[Foo_USR:.*]] | Def | rel: 0
init() {} // CHECK: [[@LINE]]:3 | constructor/Swift | init() | [[Foo_init_USR:.*]] | Def,RelChild | rel: 1

static func bar() -> Self {
.init() // CHECK: [[@LINE]]:6 | constructor/Swift | init() | [[Foo_init_USR]] | Ref,Call,RelCall,RelCont | rel: 1
}

static func baz() -> Self {
Self()
// CHECK: [[@LINE-1]]:5 | struct/Swift | Foo | [[Foo_USR]] | Ref,Impl,RelCont | rel: 1
// CHECK: [[@LINE-2]]:5 | constructor/Swift | init() | [[Foo_init_USR]] | Ref,Call,RelCall,RelCont | rel: 1
}
}

final class Final { // CHECK: [[@LINE]]:13 | class/Swift | Final | [[Final_USR:.*]] | Def | rel: 0
init() {} // CHECK: [[@LINE]]:3 | constructor/Swift | init() | [[Final_init_USR:.*]] | Def,RelChild | rel: 1

static func foo() -> Self {
.init() // CHECK: [[@LINE]]:6 | constructor/Swift | init() | [[Final_init_USR]] | Ref,Call,RelCall,RelCont | rel: 1
}

static func baz() -> Self {
Self()
// CHECK: [[@LINE-1]]:5 | class/Swift | Final | [[Final_USR]] | Ref,Impl,RelCont | rel: 1
// CHECK: [[@LINE-2]]:5 | constructor/Swift | init() | [[Final_init_USR]] | Ref,Call,RelCall,RelCont | rel: 1
}
}

class Bar { // CHECK: [[@LINE]]:7 | class/Swift | Bar | [[Bar_USR:.*]] | Def | rel: 0
required init() {} // CHECK: [[@LINE]]:12 | constructor/Swift | init() | [[Bar_init_USR:.*]] | Def,RelChild | rel: 1

static func foo() -> Self {
.init() // CHECK: [[@LINE]]:6 | constructor/Swift | init() | [[Bar_init_USR]] | Ref,Call,RelCall,RelCont | rel: 1
}

static func baz() -> Self {
Self()
// CHECK: [[@LINE-1]]:5 | class/Swift | Bar | [[Bar_USR]] | Ref,Impl,RelCont | rel: 1
// TODO: This reference should be dynamic
// CHECK: [[@LINE-3]]:5 | constructor/Swift | init() | [[Bar_init_USR]] | Ref,Call,RelCall,RelCont | rel: 1
}
}

class Baz: Bar {}

protocol Proto { // CHECK: [[@LINE]]:10 | protocol/Swift | Proto | [[Proto_USR:.*]] | Def | rel: 0
init() // CHECK: [[@LINE]]:3 | constructor/Swift | init() | [[Proto_init_USR:.*]] | Def,RelChild | rel: 1
}

extension Proto {
func foo() -> Self {
// TODO: This reference should be dynamic
Self() // CHECK: [[@LINE]]:5 | constructor/Swift | init() | [[Proto_init_USR]] | Ref,Call,RelCall,RelCont | rel: 1
}
}