diff --git a/lib/IDE/IDERequests.cpp b/lib/IDE/IDERequests.cpp index 45c6986de3d80..d936e262a242f 100644 --- a/lib/IDE/IDERequests.cpp +++ b/lib/IDE/IDERequests.cpp @@ -158,6 +158,13 @@ bool CursorInfoResolver::tryResolve(ValueDecl *D, TypeDecl *CtorTyRef, IsDynamic = true; ide::getReceiverType(BaseE, ReceiverTypes); } + } else if (ExprStack.empty() && isDeclOverridable(D)) { + // We aren't in a call (otherwise we would have an expression stack wouldn't + // be empty), so we're at the declaration of an overridable declaration. + // Mark the declaration as dynamic so that jump-to-definition can offer to + // jump to any declaration that overrides this declaration. + IsDynamic = true; + ReceiverTypes.push_back(D->getDeclContext()->getSelfNominalTypeDecl()); } if (Data) diff --git a/test/SourceKit/CursorInfo/cursor_of_protocol_requirement_is_dynamic.swift b/test/SourceKit/CursorInfo/cursor_of_protocol_requirement_is_dynamic.swift new file mode 100644 index 0000000000000..ed88b63834c99 --- /dev/null +++ b/test/SourceKit/CursorInfo/cursor_of_protocol_requirement_is_dynamic.swift @@ -0,0 +1,17 @@ +protocol MyProto { + // RUN: %sourcekitd-test -req=cursor -pos=%(line + 1):9 %s -- %s | %FileCheck %s + func foo() +} + +// CHECK: DYNAMIC +// CHECK: RECEIVERS BEGIN +// CHECK: s:41cursor_of_protocol_requirement_is_dynamic7MyProtoP +// CHECK: RECEIVERS END + +class ClassA: MyProto { + func foo() {} +} + +class ClassB: MyProto { + func foo() {} +}