diff --git a/include/swift/AST/ASTWalker.h b/include/swift/AST/ASTWalker.h index d29b3c3f60c88..af4308ecd8db4 100644 --- a/include/swift/AST/ASTWalker.h +++ b/include/swift/AST/ASTWalker.h @@ -37,6 +37,7 @@ enum class SemaReferenceKind : uint8_t { TypeRef, EnumElementRef, SubscriptRef, + DynamicMemberRef, }; struct ReferenceMetaData { diff --git a/lib/IDE/SourceEntityWalker.cpp b/lib/IDE/SourceEntityWalker.cpp index b57a33811927c..f2dc3e165a072 100644 --- a/lib/IDE/SourceEntityWalker.cpp +++ b/lib/IDE/SourceEntityWalker.cpp @@ -511,6 +511,17 @@ std::pair SemaAnnotator::walkToExprPre(Expr *E) { return doSkipChildren(); } + } else if (auto DMRE = dyn_cast(E)) { + // Visit in source order. + if (!DMRE->getBase()->walk(*this)) + return stopTraversal; + if (!passReference(DMRE->getMember().getDecl(), DMRE->getType(), + DMRE->getNameLoc(), + ReferenceMetaData(SemaReferenceKind::DynamicMemberRef, + OpAccess))) + return stopTraversal; + // We already visited the children. + return doSkipChildren(); } return { true, E }; diff --git a/test/Index/index_objc_dynamic_refs.swift b/test/Index/index_objc_dynamic_refs.swift new file mode 100644 index 0000000000000..c42805b38b5fc --- /dev/null +++ b/test/Index/index_objc_dynamic_refs.swift @@ -0,0 +1,26 @@ +// RUN: %target-swift-ide-test -print-indexed-symbols -source-filename %s | %FileCheck %s +// REQUIRES: objc_interop + +import Foundation + +@objc protocol AProtocol { + @objc optional func dynamicMethod() + // CHECK: [[@LINE-1]]:25 | instance-method/Swift | dynamicMethod() | [[DynamicMethod_USR:.*]] | Def + @objc optional var property: String { get } + // CHECK: [[@LINE-1]]:24 | instance-property/Swift | property | [[DynamicProperty_USR:.*]] | Def +} + +class AClass { + + weak var objcDelegate: AProtocol? + // CHECK: [[@LINE-1]]:14 | instance-property/Swift | objcDelegate | [[Delegate_USR:.*]] | Def + + func doSomething() { + objcDelegate?.dynamicMethod?() + // CHECK: [[@LINE-1]]:9 | instance-property/Swift | objcDelegate | [[Delegate_USR]] | Ref + // CHECK: [[@LINE-2]]:23 | instance-method/Swift | dynamicMethod() | [[DynamicMethod_USR]] | Ref + _ = objcDelegate?.property + // CHECK: [[@LINE-1]]:13 | instance-property/Swift | objcDelegate | [[Delegate_USR]] | Ref + // CHECK: [[@LINE-2]]:27 | instance-property/Swift | property | [[DynamicProperty_USR]] | Ref + } +}