diff --git a/include/swift/AST/NameLookup.h b/include/swift/AST/NameLookup.h index 18851ddca22..2fa19acfaba 100644 --- a/include/swift/AST/NameLookup.h +++ b/include/swift/AST/NameLookup.h @@ -205,6 +205,51 @@ enum class DeclVisibilityKind { DynamicLookup, }; +/// For Decls found with DeclVisibilityKind::DynamicLookup, contains details of +/// how they were looked up. For example, the SubscriptDecl used to find a +/// KeyPath dynamic member. +class DynamicLookupInfo { +public: + enum Kind { + None, + AnyObject, + KeyPathDynamicMember, + }; + + struct KeyPathDynamicMemberInfo { + /// The subscript(dynamicMember:) by which we found the declaration. + SubscriptDecl *subscript = nullptr; + + /// The type context of `subscript`, which may be different than the + /// original base type of the lookup if this declaration was found by nested + /// dynamic lookups. + Type baseType = Type(); + + /// Visibility of the declaration itself without dynamic lookup. + /// + /// For example, dynamic lookup for KeyPath, might find + /// Base::foo with originalVisibility == MemberOfSuper. + DeclVisibilityKind originalVisibility = DeclVisibilityKind::DynamicLookup; + }; + + Kind getKind() const { return kind; } + + const KeyPathDynamicMemberInfo &getKeyPathDynamicMember() const; + + DynamicLookupInfo() : kind(None) {} + DynamicLookupInfo(Kind kind) : kind(kind) { + assert(kind != KeyPathDynamicMember && "use KeyPathDynamicMemberInfo ctor"); + } + + /// Construct for a KeyPath dynamic member lookup. + DynamicLookupInfo(SubscriptDecl *subscript, Type baseType, + DeclVisibilityKind originalVisibility); + +private: + Kind kind; + KeyPathDynamicMemberInfo keypath = {}; +}; + /// An abstract base class for a visitor that consumes declarations found within /// a given context. class VisibleDeclConsumer { @@ -213,7 +258,8 @@ public: virtual ~VisibleDeclConsumer() = default; /// This method is called by findVisibleDecls() every time it finds a decl. - virtual void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) = 0; + virtual void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo = {}) = 0; }; /// An implementation of VisibleDeclConsumer that's built from a lambda. @@ -223,7 +269,7 @@ class LambdaDeclConsumer : public VisibleDeclConsumer { public: LambdaDeclConsumer(Fn &&callback) : Callback(std::move(callback)) {} - void foundDecl(ValueDecl *VD, DeclVisibilityKind reason) { + void foundDecl(ValueDecl *VD, DeclVisibilityKind reason, DynamicLookupInfo) { Callback(VD, reason); } }; @@ -240,7 +286,8 @@ public: explicit VectorDeclConsumer(SmallVectorImpl &decls) : results(decls) {} - virtual void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) override { + virtual void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason, + DynamicLookupInfo) override { results.push_back(VD); } }; @@ -259,7 +306,8 @@ public: bool isTypeLookup) : name(name), results(results), isTypeLookup(isTypeLookup) {} - virtual void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) override { + virtual void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo = {}) override { // Give clients an opportunity to filter out non-type declarations early, // to avoid circular validation. if (isTypeLookup && !isa(VD)) @@ -280,7 +328,8 @@ public: VisibleDeclConsumer &consumer) : DC(DC), ChainedConsumer(consumer) {} - void foundDecl(ValueDecl *D, DeclVisibilityKind reason) override; + void foundDecl(ValueDecl *D, DeclVisibilityKind reason, + DynamicLookupInfo dynamicLookupInfo = {}) override; }; /// Remove any declarations in the given set that were overridden by diff --git a/lib/AST/ASTDemangler.cpp b/lib/AST/ASTDemangler.cpp index 2b90f599074..b18766dbb38 100644 --- a/lib/AST/ASTDemangler.cpp +++ b/lib/AST/ASTDemangler.cpp @@ -1041,7 +1041,8 @@ ASTBuilder::findForeignTypeDecl(StringRef name, explicit Consumer(Demangle::Node::Kind kind) : ExpectedKind(kind) {} - void foundDecl(ValueDecl *decl, DeclVisibilityKind reason) override { + void foundDecl(ValueDecl *decl, DeclVisibilityKind reason, + DynamicLookupInfo dynamicLookupInfo = {}) override { if (HadError) return; if (decl == Result) return; if (!Result) { diff --git a/lib/AST/ExperimentalDependenciesSourceFileDepGraphConstructor.cpp b/lib/AST/ExperimentalDependenciesSourceFileDepGraphConstructor.cpp index a0052f43a24..3987a603312 100644 --- a/lib/AST/ExperimentalDependenciesSourceFileDepGraphConstructor.cpp +++ b/lib/AST/ExperimentalDependenciesSourceFileDepGraphConstructor.cpp @@ -278,7 +278,8 @@ private: ConstPtrVec &classMembers; Collector(ConstPtrVec &classMembers) : classMembers(classMembers) {} - void foundDecl(ValueDecl *VD, DeclVisibilityKind) override { + void foundDecl(ValueDecl *VD, DeclVisibilityKind, + DynamicLookupInfo) override { classMembers.push_back(VD); } } collector{classMembers}; diff --git a/lib/AST/Module.cpp b/lib/AST/Module.cpp index 92f209c63fb..f37498a7482 100644 --- a/lib/AST/Module.cpp +++ b/lib/AST/Module.cpp @@ -298,7 +298,8 @@ void SourceLookupCache::lookupClassMembers(AccessPathTy accessPath, for (ValueDecl *vd : member.second) { auto *nominal = vd->getDeclContext()->getSelfNominalTypeDecl(); if (nominal && nominal->getName() == accessPath.front().first) - consumer.foundDecl(vd, DeclVisibilityKind::DynamicLookup); + consumer.foundDecl(vd, DeclVisibilityKind::DynamicLookup, + DynamicLookupInfo::AnyObject); } } return; @@ -311,7 +312,8 @@ void SourceLookupCache::lookupClassMembers(AccessPathTy accessPath, continue; for (ValueDecl *vd : member.second) - consumer.foundDecl(vd, DeclVisibilityKind::DynamicLookup); + consumer.foundDecl(vd, DeclVisibilityKind::DynamicLookup, + DynamicLookupInfo::AnyObject); } } diff --git a/lib/AST/NameLookup.cpp b/lib/AST/NameLookup.cpp index dde4faa2b1a..126b1d2c3f7 100644 --- a/lib/AST/NameLookup.cpp +++ b/lib/AST/NameLookup.cpp @@ -63,14 +63,15 @@ ValueDecl *LookupResultEntry::getBaseDecl() const { void DebuggerClient::anchor() {} -void AccessFilteringDeclConsumer::foundDecl(ValueDecl *D, - DeclVisibilityKind reason) { +void AccessFilteringDeclConsumer::foundDecl( + ValueDecl *D, DeclVisibilityKind reason, + DynamicLookupInfo dynamicLookupInfo) { if (D->isInvalid()) return; if (!D->isAccessibleFrom(DC)) return; - ChainedConsumer.foundDecl(D, reason); + ChainedConsumer.foundDecl(D, reason, dynamicLookupInfo); } diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index 0d1ebee7a5a..4ee8b14639d 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -2225,9 +2225,10 @@ public: assert(CMU); } - void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) override { + void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo) override { if (isVisibleFromModule(ModuleFilter, VD)) - NextConsumer.foundDecl(VD, Reason); + NextConsumer.foundDecl(VD, Reason, dynamicLookupInfo); } }; @@ -2242,9 +2243,10 @@ public: assert(CMU); } - void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) override { + void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo) override { if (isDeclaredInModule(ModuleFilter, VD)) - NextConsumer.foundDecl(VD, Reason); + NextConsumer.foundDecl(VD, Reason, dynamicLookupInfo); } }; @@ -2307,9 +2309,10 @@ public: topLevelModule->Name == "CoreServices"); } - void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) override { + void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo) override { if (!shouldDiscard(VD)) - NextConsumer.foundDecl(VD, Reason); + NextConsumer.foundDecl(VD, Reason, dynamicLookupInfo); } }; @@ -2551,7 +2554,8 @@ public: explicit VectorDeclPtrConsumer(SmallVectorImpl &Decls) : Results(Decls) {} - void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) override { + void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason, + DynamicLookupInfo) override { Results.push_back(VD); } }; @@ -3526,14 +3530,16 @@ void ClangImporter::Implementation::lookupObjCMembers( // FIXME: If we didn't need to check alternate decls here, we could avoid // importing the member at all by checking importedName ahead of time. if (decl->getFullName().matchesRef(name)) { - consumer.foundDecl(decl, DeclVisibilityKind::DynamicLookup); + consumer.foundDecl(decl, DeclVisibilityKind::DynamicLookup, + DynamicLookupInfo::AnyObject); } // Check for an alternate declaration; if its name matches, // report it. for (auto alternate : getAlternateDecls(decl)) { if (alternate->getFullName().matchesRef(name)) { - consumer.foundDecl(alternate, DeclVisibilityKind::DynamicLookup); + consumer.foundDecl(alternate, DeclVisibilityKind::DynamicLookup, + DynamicLookupInfo::AnyObject); } } return true; diff --git a/lib/FrontendTool/ReferenceDependencies.cpp b/lib/FrontendTool/ReferenceDependencies.cpp index 15e4c86f314..6c73f563b64 100644 --- a/lib/FrontendTool/ReferenceDependencies.cpp +++ b/lib/FrontendTool/ReferenceDependencies.cpp @@ -437,7 +437,8 @@ void ProvidesEmitter::emitDynamicLookupMembers() const { SmallVector names; public: - void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) override { + void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason, + DynamicLookupInfo) override { names.push_back(VD->getBaseName()); } ArrayRef getNames() { diff --git a/lib/IDE/CodeCompletion.cpp b/lib/IDE/CodeCompletion.cpp index 73deb7fffb8..23578931323 100644 --- a/lib/IDE/CodeCompletion.cpp +++ b/lib/IDE/CodeCompletion.cpp @@ -1799,7 +1799,8 @@ public: } SemanticContextKind getSemanticContext(const Decl *D, - DeclVisibilityKind Reason) { + DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo) { if (ForcedSemanticContext) return *ForcedSemanticContext; @@ -1845,12 +1846,27 @@ public: } case DeclVisibilityKind::DynamicLookup: - // AnyObject results can come from different modules, including the - // current module, but we always assign them the OtherModule semantic - // context. These declarations are uniqued by signature, so it is - // totally random (determined by the hash function) which of the - // equivalent declarations (across multiple modules) we will get. - return SemanticContextKind::OtherModule; + switch (dynamicLookupInfo.getKind()) { + case DynamicLookupInfo::None: + llvm_unreachable("invalid DynamicLookupInfo::Kind for dynamic lookup"); + + case DynamicLookupInfo::AnyObject: + // AnyObject results can come from different modules, including the + // current module, but we always assign them the OtherModule semantic + // context. These declarations are uniqued by signature, so it is + // totally random (determined by the hash function) which of the + // equivalent declarations (across multiple modules) we will get. + return SemanticContextKind::OtherModule; + + case DynamicLookupInfo::KeyPathDynamicMember: + // Use the visibility of the underlying declaration. + // FIXME: KeyPath !?!? + assert(dynamicLookupInfo.getKeyPathDynamicMember().originalVisibility != + DeclVisibilityKind::DynamicLookup); + return getSemanticContext( + D, dynamicLookupInfo.getKeyPathDynamicMember().originalVisibility, + {}); + } } llvm_unreachable("unhandled kind"); } @@ -2057,7 +2073,8 @@ public: return Type(); } - void addVarDeclRef(const VarDecl *VD, DeclVisibilityKind Reason) { + void addVarDeclRef(const VarDecl *VD, DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo) { if (!VD->hasName() || !VD->isAccessibleFrom(CurrDeclContext) || VD->shouldHideFromEditor()) @@ -2068,9 +2085,8 @@ public: CommandWordsPairs Pairs; CodeCompletionResultBuilder Builder( - Sink, - CodeCompletionResult::ResultKind::Declaration, - getSemanticContext(VD, Reason), expectedTypeContext); + Sink, CodeCompletionResult::ResultKind::Declaration, + getSemanticContext(VD, Reason, dynamicLookupInfo), expectedTypeContext); Builder.setAssociatedDecl(VD); addLeadingDot(Builder); addValueBaseName(Builder, Name); @@ -2412,7 +2428,8 @@ public: llvm_unreachable("Unhandled LookupKind in switch."); } - void addMethodCall(const FuncDecl *FD, DeclVisibilityKind Reason) { + void addMethodCall(const FuncDecl *FD, DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo) { if (FD->getName().empty()) return; foundFunction(FD); @@ -2444,7 +2461,8 @@ public: CommandWordsPairs Pairs; CodeCompletionResultBuilder Builder( Sink, CodeCompletionResult::ResultKind::Declaration, - getSemanticContext(FD, Reason), expectedTypeContext); + getSemanticContext(FD, Reason, dynamicLookupInfo), + expectedTypeContext); setClangDeclKeywords(FD, Pairs, Builder); Builder.setAssociatedDecl(FD); addLeadingDot(Builder); @@ -2526,6 +2544,7 @@ public: } void addConstructorCall(const ConstructorDecl *CD, DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo, Optional BaseType, Optional Result, bool IsOnType = true, Identifier addName = Identifier()) { @@ -2553,7 +2572,8 @@ public: CommandWordsPairs Pairs; CodeCompletionResultBuilder Builder( Sink, CodeCompletionResult::ResultKind::Declaration, - getSemanticContext(CD, Reason), expectedTypeContext); + getSemanticContext(CD, Reason, dynamicLookupInfo), + expectedTypeContext); setClangDeclKeywords(CD, Pairs, Builder); Builder.setAssociatedDecl(CD); if (needInit) { @@ -2604,7 +2624,8 @@ public: } void addConstructorCallsForType(Type type, Identifier name, - DeclVisibilityKind Reason) { + DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo) { if (!Ctx.LangOpts.CodeCompleteInitsInPostfixExpr && !IsUnresolvedMember) return; @@ -2620,13 +2641,15 @@ public: cast(init)->getFailability() == OTK_Optional) { continue; } - addConstructorCall(cast(init), Reason, type, None, + addConstructorCall(cast(init), Reason, + dynamicLookupInfo, type, None, /*IsOnType=*/true, name); } } } - void addSubscriptCall(const SubscriptDecl *SD, DeclVisibilityKind Reason) { + void addSubscriptCall(const SubscriptDecl *SD, DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo) { // Don't add subscript call to unqualified completion. if (!ExprType) return; @@ -2642,9 +2665,8 @@ public: CommandWordsPairs Pairs; CodeCompletionResultBuilder Builder( - Sink, - CodeCompletionResult::ResultKind::Declaration, - getSemanticContext(SD, Reason), expectedTypeContext); + Sink, CodeCompletionResult::ResultKind::Declaration, + getSemanticContext(SD, Reason, dynamicLookupInfo), expectedTypeContext); Builder.setAssociatedDecl(SD); setClangDeclKeywords(SD, Pairs, Builder); @@ -2671,15 +2693,15 @@ public: addTypeAnnotation(Builder, resultTy); } - void addNominalTypeRef(const NominalTypeDecl *NTD, - DeclVisibilityKind Reason) { + void addNominalTypeRef(const NominalTypeDecl *NTD, DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo) { if (IsUnresolvedMember) return; CommandWordsPairs Pairs; CodeCompletionResultBuilder Builder( - Sink, - CodeCompletionResult::ResultKind::Declaration, - getSemanticContext(NTD, Reason), expectedTypeContext); + Sink, CodeCompletionResult::ResultKind::Declaration, + getSemanticContext(NTD, Reason, dynamicLookupInfo), + expectedTypeContext); Builder.setAssociatedDecl(NTD); setClangDeclKeywords(NTD, Pairs, Builder); addLeadingDot(Builder); @@ -2687,14 +2709,15 @@ public: addTypeAnnotation(Builder, NTD->getDeclaredType()); } - void addTypeAliasRef(const TypeAliasDecl *TAD, DeclVisibilityKind Reason) { + void addTypeAliasRef(const TypeAliasDecl *TAD, DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo) { if (IsUnresolvedMember) return; CommandWordsPairs Pairs; CodeCompletionResultBuilder Builder( - Sink, - CodeCompletionResult::ResultKind::Declaration, - getSemanticContext(TAD, Reason), expectedTypeContext); + Sink, CodeCompletionResult::ResultKind::Declaration, + getSemanticContext(TAD, Reason, dynamicLookupInfo), + expectedTypeContext); Builder.setAssociatedDecl(TAD); setClangDeclKeywords(TAD, Pairs, Builder); addLeadingDot(Builder); @@ -2719,12 +2742,12 @@ public: } void addGenericTypeParamRef(const GenericTypeParamDecl *GP, - DeclVisibilityKind Reason) { + DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo) { CommandWordsPairs Pairs; CodeCompletionResultBuilder Builder( - Sink, - CodeCompletionResult::ResultKind::Declaration, - getSemanticContext(GP, Reason), expectedTypeContext); + Sink, CodeCompletionResult::ResultKind::Declaration, + getSemanticContext(GP, Reason, dynamicLookupInfo), expectedTypeContext); setClangDeclKeywords(GP, Pairs, Builder); Builder.setAssociatedDecl(GP); addLeadingDot(Builder); @@ -2733,12 +2756,12 @@ public: } void addAssociatedTypeRef(const AssociatedTypeDecl *AT, - DeclVisibilityKind Reason) { + DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo) { CommandWordsPairs Pairs; CodeCompletionResultBuilder Builder( - Sink, - CodeCompletionResult::ResultKind::Declaration, - getSemanticContext(AT, Reason), expectedTypeContext); + Sink, CodeCompletionResult::ResultKind::Declaration, + getSemanticContext(AT, Reason, dynamicLookupInfo), expectedTypeContext); setClangDeclKeywords(AT, Pairs, Builder); Builder.setAssociatedDecl(AT); addLeadingDot(Builder); @@ -2749,7 +2772,7 @@ public: void addPrecedenceGroupRef(PrecedenceGroupDecl *PGD) { auto semanticContext = - getSemanticContext(PGD, DeclVisibilityKind::VisibleAtTopLevel); + getSemanticContext(PGD, DeclVisibilityKind::VisibleAtTopLevel, {}); CodeCompletionResultBuilder builder( Sink, CodeCompletionResult::ResultKind::Declaration, semanticContext, {}); @@ -2758,8 +2781,8 @@ public: builder.setAssociatedDecl(PGD); }; - void addEnumElementRef(const EnumElementDecl *EED, - DeclVisibilityKind Reason, + void addEnumElementRef(const EnumElementDecl *EED, DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo, bool HasTypeContext) { if (!EED->hasName() || !EED->isAccessibleFrom(CurrDeclContext) || @@ -2770,7 +2793,7 @@ public: CodeCompletionResultBuilder Builder( Sink, CodeCompletionResult::ResultKind::Declaration, HasTypeContext ? SemanticContextKind::ExpressionSpecific - : getSemanticContext(EED, Reason), + : getSemanticContext(EED, Reason, dynamicLookupInfo), expectedTypeContext); Builder.setAssociatedDecl(EED); setClangDeclKeywords(EED, Pairs, Builder); @@ -2846,11 +2869,13 @@ public: /// Add the compound function name for the given function. void addCompoundFunctionName(AbstractFunctionDecl *AFD, - DeclVisibilityKind Reason) { + DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo) { CommandWordsPairs Pairs; CodeCompletionResultBuilder Builder( Sink, CodeCompletionResult::ResultKind::Declaration, - getSemanticContext(AFD, Reason), expectedTypeContext); + getSemanticContext(AFD, Reason, dynamicLookupInfo), + expectedTypeContext); setClangDeclKeywords(AFD, Pairs, Builder); Builder.setAssociatedDecl(AFD); @@ -2879,7 +2904,8 @@ public: } // Implement swift::VisibleDeclConsumer. - void foundDecl(ValueDecl *D, DeclVisibilityKind Reason) override { + void foundDecl(ValueDecl *D, DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo) override { if (D->shouldHideFromEditor()) return; @@ -2901,7 +2927,7 @@ public: if (auto *CD = dyn_cast(D)) { // Do we want compound function names here? if (shouldUseFunctionReference(CD)) { - addCompoundFunctionName(CD, Reason); + addCompoundFunctionName(CD, Reason, dynamicLookupInfo); return; } @@ -2924,10 +2950,12 @@ public: // the initializer is required, the base type's instance type is not a class, // or this is a 'self' or 'super' reference. if (IsStaticMetatype || IsUnresolvedMember || Ty->is()) - addConstructorCall(CD, Reason, None, Result, /*isOnType*/true); + addConstructorCall(CD, Reason, dynamicLookupInfo, None, Result, + /*isOnType*/ true); else if ((IsSelfRefExpr || IsSuperRefExpr || !Ty->is() || CD->isRequired()) && !HaveLParen) - addConstructorCall(CD, Reason, None, Result, /*isOnType*/false); + addConstructorCall(CD, Reason, dynamicLookupInfo, None, Result, + /*isOnType*/ false); return; } if (!HaveLParen) { @@ -2938,7 +2966,8 @@ public: // initializers and for 'super' in convenience initializers. if ((IsSelfRefExpr && CDC->isConvenienceInit()) || ((IsSuperRefExpr && !CDC->isConvenienceInit()))) - addConstructorCall(CD, Reason, None, None, /*IsOnType=*/false); + addConstructorCall(CD, Reason, dynamicLookupInfo, None, None, + /*IsOnType=*/false); } return; } @@ -2951,7 +2980,7 @@ public: case LookupKind::ValueInDeclContext: case LookupKind::ImportFromModule: if (auto *VD = dyn_cast(D)) { - addVarDeclRef(VD, Reason); + addVarDeclRef(VD, Reason, dynamicLookupInfo); return; } @@ -2967,77 +2996,79 @@ public: // Do we want compound function names here? if (shouldUseFunctionReference(FD)) { - addCompoundFunctionName(FD, Reason); + addCompoundFunctionName(FD, Reason, dynamicLookupInfo); return; } - addMethodCall(FD, Reason); + addMethodCall(FD, Reason, dynamicLookupInfo); return; } if (auto *NTD = dyn_cast(D)) { - addNominalTypeRef(NTD, Reason); + addNominalTypeRef(NTD, Reason, dynamicLookupInfo); addConstructorCallsForType(NTD->getDeclaredInterfaceType(), - NTD->getName(), Reason); + NTD->getName(), Reason, dynamicLookupInfo); return; } if (auto *TAD = dyn_cast(D)) { - addTypeAliasRef(TAD, Reason); + addTypeAliasRef(TAD, Reason, dynamicLookupInfo); auto type = TAD->mapTypeIntoContext(TAD->getDeclaredInterfaceType()); if (type->mayHaveMembers()) - addConstructorCallsForType(type, TAD->getName(), Reason); + addConstructorCallsForType(type, TAD->getName(), Reason, + dynamicLookupInfo); return; } if (auto *GP = dyn_cast(D)) { - addGenericTypeParamRef(GP, Reason); + addGenericTypeParamRef(GP, Reason, dynamicLookupInfo); for (auto *protocol : GP->getConformingProtocols()) addConstructorCallsForType(protocol->getDeclaredInterfaceType(), - GP->getName(), Reason); + GP->getName(), Reason, dynamicLookupInfo); return; } if (auto *AT = dyn_cast(D)) { - addAssociatedTypeRef(AT, Reason); + addAssociatedTypeRef(AT, Reason, dynamicLookupInfo); return; } if (auto *EED = dyn_cast(D)) { - addEnumElementRef(EED, Reason, /*HasTypeContext=*/false); + addEnumElementRef(EED, Reason, dynamicLookupInfo, + /*HasTypeContext=*/false); return; } // Swift key path allows .[0] if (auto *SD = dyn_cast(D)) { - addSubscriptCall(SD, Reason); + addSubscriptCall(SD, Reason, dynamicLookupInfo); return; } return; case LookupKind::EnumElement: - handleEnumElement(D, Reason); + handleEnumElement(D, Reason, dynamicLookupInfo); return; case LookupKind::Type: case LookupKind::TypeInDeclContext: if (auto *NTD = dyn_cast(D)) { - addNominalTypeRef(NTD, Reason); + addNominalTypeRef(NTD, Reason, dynamicLookupInfo); return; } if (auto *TAD = dyn_cast(D)) { - addTypeAliasRef(TAD, Reason); + addTypeAliasRef(TAD, Reason, dynamicLookupInfo); return; } if (auto *GP = dyn_cast(D)) { - addGenericTypeParamRef(GP, Reason); + addGenericTypeParamRef(GP, Reason, dynamicLookupInfo); return; } if (auto *AT = dyn_cast(D)) { - addAssociatedTypeRef(AT, Reason); + addAssociatedTypeRef(AT, Reason, dynamicLookupInfo); return; } @@ -3045,12 +3076,14 @@ public: } } - bool handleEnumElement(ValueDecl *D, DeclVisibilityKind Reason) { + bool handleEnumElement(ValueDecl *D, DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo) { if (!D->hasInterfaceType()) TypeResolver->resolveDeclSignature(D); if (auto *EED = dyn_cast(D)) { - addEnumElementRef(EED, Reason, /*HasTypeContext=*/true); + addEnumElementRef(EED, Reason, dynamicLookupInfo, + /*HasTypeContext=*/true); return true; } else if (auto *ED = dyn_cast(D)) { llvm::DenseSet Elements; @@ -3058,7 +3091,8 @@ public: for (auto *Ele : Elements) { if (!Ele->hasInterfaceType()) TypeResolver->resolveDeclSignature(Ele); - addEnumElementRef(Ele, Reason, /*HasTypeContext=*/true); + addEnumElementRef(Ele, Reason, dynamicLookupInfo, + /*HasTypeContext=*/true); } return true; } @@ -3292,7 +3326,7 @@ public: // FIXME: we should get the semantic context of the function, not the // operator decl. auto semanticContext = - getSemanticContext(op, DeclVisibilityKind::VisibleAtTopLevel); + getSemanticContext(op, DeclVisibilityKind::VisibleAtTopLevel, {}); CodeCompletionResultBuilder builder( Sink, CodeCompletionResult::ResultKind::Declaration, semanticContext, {}); @@ -3341,7 +3375,7 @@ public: // FIXME: we should get the semantic context of the function, not the // operator decl. auto semanticContext = - getSemanticContext(op, DeclVisibilityKind::VisibleAtTopLevel); + getSemanticContext(op, DeclVisibilityKind::VisibleAtTopLevel, {}); CodeCompletionResultBuilder builder( Sink, CodeCompletionResult::ResultKind::Declaration, semanticContext, {}); @@ -3593,9 +3627,10 @@ public: DeclFilter Filter; FilteredDeclConsumer(swift::VisibleDeclConsumer &Consumer, DeclFilter Filter) : Consumer(Consumer), Filter(Filter) {} - void foundDecl(ValueDecl *VD, DeclVisibilityKind Kind) override { + void foundDecl(ValueDecl *VD, DeclVisibilityKind Kind, + DynamicLookupInfo dynamicLookupInfo) override { if (Filter(VD, Kind)) - Consumer.foundDecl(VD, Kind); + Consumer.foundDecl(VD, Kind, dynamicLookupInfo); } }; @@ -3624,7 +3659,7 @@ public: if (!isa(NTD) && NTD->getModuleContext() != CurrDeclContext->getParentModule()) { addNominalTypeRef(NT->getDecl(), - DeclVisibilityKind::VisibleAtTopLevel); + DeclVisibilityKind::VisibleAtTopLevel, {}); } } } @@ -3686,7 +3721,8 @@ public: // type and has the same type (or if the member is a function, then the // same result type) as the contextual type. FilteredDeclConsumer consumer(*this, [=](ValueDecl *VD, - DeclVisibilityKind reason) { + DeclVisibilityKind Reason) { + if (VD->isOperator()) return false; @@ -3713,11 +3749,11 @@ public: // Only non-failable constructors are implicitly referenceable. if (auto CD = dyn_cast(VD)) { switch (CD->getFailability()) { - case OTK_None: - case OTK_ImplicitlyUnwrappedOptional: - return true; - case OTK_Optional: - return false; + case OTK_None: + case OTK_ImplicitlyUnwrappedOptional: + return true; + case OTK_Optional: + return false; } } @@ -3816,7 +3852,7 @@ public: if (!TheEnumDecl) return; for (auto Element : TheEnumDecl->getAllElements()) { - foundDecl(Element, DeclVisibilityKind::MemberOfCurrentNominal); + foundDecl(Element, DeclVisibilityKind::MemberOfCurrentNominal, {}); } } @@ -4058,7 +4094,8 @@ public: /// Return type if the result type if \p VD should be represented as opaque /// result type. - TypeLoc getOpaqueResultTypeLoc(const ValueDecl *VD, DeclVisibilityKind Reason) { + TypeLoc getOpaqueResultTypeLoc(const ValueDecl *VD, DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo) { if (Reason != DeclVisibilityKind::MemberOfProtocolImplementedByCurrentNominal) return nullptr; @@ -4100,6 +4137,7 @@ public: } void addValueOverride(const ValueDecl *VD, DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo, CodeCompletionResultBuilder &Builder, bool hasDeclIntroducer) { class DeclPrinter : public StreamPrinter { @@ -4131,7 +4169,8 @@ public: unsigned NameOffset = 0; { llvm::raw_svector_ostream OS(DeclStr); - DeclPrinter Printer(OS, getOpaqueResultTypeLoc(VD, Reason)); + DeclPrinter Printer( + OS, getOpaqueResultTypeLoc(VD, Reason, dynamicLookupInfo)); PrintOptions Options; if (auto transformType = CurrDeclContext->getDeclaredTypeInContext()) Options.setBaseType(transformType); @@ -4167,16 +4206,18 @@ public: Builder.addTextChunk(DeclStr.str().substr(NameOffset)); } - void addMethodOverride(const FuncDecl *FD, DeclVisibilityKind Reason) { + void addMethodOverride(const FuncDecl *FD, DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo) { CodeCompletionResultBuilder Builder( Sink, CodeCompletionResult::ResultKind::Declaration, SemanticContextKind::Super, {}); Builder.setAssociatedDecl(FD); - addValueOverride(FD, Reason, Builder, hasFuncIntroducer); + addValueOverride(FD, Reason, dynamicLookupInfo, Builder, hasFuncIntroducer); Builder.addBraceStmtWithCursor(); } - void addVarOverride(const VarDecl *VD, DeclVisibilityKind Reason) { + void addVarOverride(const VarDecl *VD, DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo) { // Overrides cannot use 'let', but if the 'override' keyword is specified // then the intention is clear, so provide the results anyway. The compiler // can then provide an error telling you to use 'var' instead. @@ -4189,19 +4230,21 @@ public: Sink, CodeCompletionResult::ResultKind::Declaration, SemanticContextKind::Super, {}); Builder.setAssociatedDecl(VD); - addValueOverride(VD, Reason, Builder, hasVarIntroducer); + addValueOverride(VD, Reason, dynamicLookupInfo, Builder, hasVarIntroducer); } - void addSubscriptOverride(const SubscriptDecl *SD, DeclVisibilityKind Reason) { + void addSubscriptOverride(const SubscriptDecl *SD, DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo) { CodeCompletionResultBuilder Builder( Sink, CodeCompletionResult::ResultKind::Declaration, SemanticContextKind::Super, {}); Builder.setAssociatedDecl(SD); - addValueOverride(SD, Reason, Builder, false); + addValueOverride(SD, Reason, dynamicLookupInfo, Builder, false); Builder.addBraceStmtWithCursor(); } - void addTypeAlias(const AssociatedTypeDecl *ATD, DeclVisibilityKind Reason) { + void addTypeAlias(const AssociatedTypeDecl *ATD, DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo) { CodeCompletionResultBuilder Builder(Sink, CodeCompletionResult::ResultKind::Declaration, SemanticContextKind::Super, {}); @@ -4215,7 +4258,8 @@ public: Builder.addSimpleNamedParameter("Type"); } - void addConstructor(const ConstructorDecl *CD, DeclVisibilityKind Reason) { + void addConstructor(const ConstructorDecl *CD, DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo) { CodeCompletionResultBuilder Builder( Sink, CodeCompletionResult::ResultKind::Declaration, @@ -4257,7 +4301,8 @@ public: } // Implement swift::VisibleDeclConsumer. - void foundDecl(ValueDecl *D, DeclVisibilityKind Reason) override { + void foundDecl(ValueDecl *D, DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo) override { if (Reason == DeclVisibilityKind::MemberOfCurrentNominal) return; @@ -4295,19 +4340,19 @@ public: return; if (hasFuncIntroducer || (!hasIntroducer && !hasInitializerModifier)) - addMethodOverride(FD, Reason); + addMethodOverride(FD, Reason, dynamicLookupInfo); return; } if (auto *VD = dyn_cast(D)) { if (hasVarIntroducer || (!hasIntroducer && !hasInitializerModifier)) - addVarOverride(VD, Reason); + addVarOverride(VD, Reason, dynamicLookupInfo); return; } if (auto *SD = dyn_cast(D)) { if (!hasIntroducer && !hasInitializerModifier) - addSubscriptOverride(SD, Reason); + addSubscriptOverride(SD, Reason, dynamicLookupInfo); } if (auto *CD = dyn_cast(D)) { @@ -4317,7 +4362,7 @@ public: hasStaticOrClass) return; if (CD->isRequired() || CD->isDesignatedInit()) - addConstructor(CD, Reason); + addConstructor(CD, Reason, dynamicLookupInfo); return; } } @@ -4340,7 +4385,7 @@ public: if (Constructor->hasStubImplementation()) continue; if (Constructor->isDesignatedInit()) - addConstructor(Constructor, DeclVisibilityKind::MemberOfSuper); + addConstructor(Constructor, DeclVisibilityKind::MemberOfSuper, {}); } } @@ -4362,8 +4407,10 @@ public: if (!Conformance->hasTypeWitness(ATD) || ATD->hasDefaultDefinitionType()) continue; - addTypeAlias(ATD, - DeclVisibilityKind::MemberOfProtocolImplementedByCurrentNominal); + addTypeAlias( + ATD, + DeclVisibilityKind::MemberOfProtocolImplementedByCurrentNominal, + {}); } } } @@ -5423,8 +5470,8 @@ void CodeCompletionCallbacksImpl::doneParsing() { if (auto GT = ParsedTypeLoc.getType()->getAnyGeneric()) { if (auto Params = GT->getGenericParams()) { for (auto GP : Params->getParams()) { - Lookup.addGenericTypeParamRef(GP, - DeclVisibilityKind::GenericParameter); + Lookup.addGenericTypeParamRef( + GP, DeclVisibilityKind::GenericParameter, {}); } } } diff --git a/lib/IDE/ConformingMethodList.cpp b/lib/IDE/ConformingMethodList.cpp index 2209e2a2ea1..ee68ecbee65 100644 --- a/lib/IDE/ConformingMethodList.cpp +++ b/lib/IDE/ConformingMethodList.cpp @@ -147,7 +147,8 @@ void ConformingMethodListCallbacks::getMatchingMethods( : CurModule(DC->getParentModule()), T(T), ExpectedTypes(expectedTypes), Result(result) {} - void foundDecl(ValueDecl *VD, DeclVisibilityKind reason) { + void foundDecl(ValueDecl *VD, DeclVisibilityKind reason, + DynamicLookupInfo) { if (isMatchingMethod(VD) && !VD->shouldHideFromEditor()) Result.push_back(VD); } diff --git a/lib/IDE/TypeContextInfo.cpp b/lib/IDE/TypeContextInfo.cpp index 20a31146e37..e24ec8a2ac7 100644 --- a/lib/IDE/TypeContextInfo.cpp +++ b/lib/IDE/TypeContextInfo.cpp @@ -163,7 +163,8 @@ void ContextInfoCallbacks::getImplicitMembers( : DC(DC), TypeResolver(DC->getASTContext().getLazyResolver()), CurModule(DC->getParentModule()), T(T), Result(Result) {} - void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) { + void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason, + DynamicLookupInfo) { if (canBeImplictMember(VD) && !VD->shouldHideFromEditor()) Result.push_back(VD); } diff --git a/lib/Sema/LookupVisibleDecls.cpp b/lib/Sema/LookupVisibleDecls.cpp index 047260d5b97..468f9323469 100644 --- a/lib/Sema/LookupVisibleDecls.cpp +++ b/lib/Sema/LookupVisibleDecls.cpp @@ -274,7 +274,8 @@ static void doDynamicLookup(VisibleDeclConsumer &Consumer, : ChainedConsumer(ChainedConsumer), LS(LS), CurrDC(CurrDC), TypeResolver(TypeResolver) {} - void foundDecl(ValueDecl *D, DeclVisibilityKind Reason) override { + void foundDecl(ValueDecl *D, DeclVisibilityKind Reason, + DynamicLookupInfo) override { // If the declaration has an override, name lookup will also have found // the overridden method. Skip this declaration, because we prefer the // overridden method. @@ -362,7 +363,8 @@ static void doDynamicLookup(VisibleDeclConsumer &Consumer, } if (isDeclVisibleInLookupMode(D, LS, CurrDC, TypeResolver)) - ChainedConsumer.foundDecl(D, DeclVisibilityKind::DynamicLookup); + ChainedConsumer.foundDecl(D, DeclVisibilityKind::DynamicLookup, + DynamicLookupInfo::AnyObject); } }; @@ -640,7 +642,9 @@ static void lookupVisibleDynamicMemberLookupDecls( LookupState LS, DeclVisibilityKind reason, LazyResolver *typeResolver, GenericSignatureBuilder *GSB, VisitedSet &visited) { - assert(hasDynamicMemberLookupAttribute(baseType)); + if (!hasDynamicMemberLookupAttribute(baseType)) + return; + auto &ctx = dc->getASTContext(); // Lookup the `subscript(dynamicMember:)` methods in this type. @@ -671,14 +675,31 @@ static void lookupVisibleDynamicMemberLookupDecls( } } +swift::DynamicLookupInfo::DynamicLookupInfo( + SubscriptDecl *subscript, Type baseType, + DeclVisibilityKind originalVisibility) + : kind(KeyPathDynamicMember) { + keypath.subscript = subscript; + keypath.baseType = baseType; + keypath.originalVisibility = originalVisibility; +} + +const DynamicLookupInfo::KeyPathDynamicMemberInfo & +swift::DynamicLookupInfo::getKeyPathDynamicMember() const { + assert(kind == KeyPathDynamicMember); + return keypath; +} + namespace { struct FoundDeclTy { ValueDecl *D; DeclVisibilityKind Reason; + DynamicLookupInfo dynamicLookupInfo; - FoundDeclTy(ValueDecl *D, DeclVisibilityKind Reason) - : D(D), Reason(Reason) {} + FoundDeclTy(ValueDecl *D, DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo) + : D(D), Reason(Reason), dynamicLookupInfo(dynamicLookupInfo) {} friend bool operator==(const FoundDeclTy &LHS, const FoundDeclTy &RHS) { // If this ever changes - e.g. to include Reason - be sure to also update @@ -693,12 +714,13 @@ namespace llvm { template <> struct DenseMapInfo { static inline FoundDeclTy getEmptyKey() { - return FoundDeclTy{nullptr, DeclVisibilityKind::LocalVariable}; + return FoundDeclTy{nullptr, DeclVisibilityKind::LocalVariable, {}}; } static inline FoundDeclTy getTombstoneKey() { return FoundDeclTy{reinterpret_cast(0x1), - DeclVisibilityKind::LocalVariable}; + DeclVisibilityKind::LocalVariable, + {}}; } static unsigned getHashValue(const FoundDeclTy &Val) { @@ -749,7 +771,8 @@ public: assert(DC && BaseTy); } - void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) override { + void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo) override { if (!AllFoundDecls.insert(VD).second) return; @@ -758,7 +781,7 @@ public: if (!isa(VD) && !isa(VD) && !isa(VD)) { - DeclsToReport.insert(FoundDeclTy(VD, Reason)); + DeclsToReport.insert(FoundDeclTy(VD, Reason, dynamicLookupInfo)); return; } @@ -768,7 +791,7 @@ public: if (VD->isInvalid()) { FoundDecls[VD->getBaseName()].insert(VD); - DeclsToReport.insert(FoundDeclTy(VD, Reason)); + DeclsToReport.insert(FoundDeclTy(VD, Reason, dynamicLookupInfo)); return; } auto &PossiblyConflicting = FoundDecls[VD->getBaseName()]; @@ -784,11 +807,11 @@ public: PossiblyConflicting.insert(VD); bool Erased = DeclsToReport.remove( - FoundDeclTy(CurrentVD, DeclVisibilityKind::LocalVariable)); + FoundDeclTy(CurrentVD, DeclVisibilityKind::LocalVariable, {})); assert(Erased); (void)Erased; - DeclsToReport.insert(FoundDeclTy(VD, Reason)); + DeclsToReport.insert(FoundDeclTy(VD, Reason, dynamicLookupInfo)); return; } CurrentVD = CurrentVD->getOverriddenDecl(); @@ -816,7 +839,7 @@ public: // Hack; we shouldn't be filtering at this level anyway. if (!VD->hasInterfaceType()) { FoundDecls[VD->getBaseName()].insert(VD); - DeclsToReport.insert(FoundDeclTy(VD, Reason)); + DeclsToReport.insert(FoundDeclTy(VD, Reason, dynamicLookupInfo)); return; } @@ -858,32 +881,49 @@ public: PossiblyConflicting.insert(VD); bool Erased = DeclsToReport.remove( - FoundDeclTy(OtherVD, DeclVisibilityKind::LocalVariable)); + FoundDeclTy(OtherVD, DeclVisibilityKind::LocalVariable, {})); assert(Erased); (void)Erased; - DeclsToReport.insert(FoundDeclTy(VD, Reason)); + DeclsToReport.insert(FoundDeclTy(VD, Reason, dynamicLookupInfo)); } return; } } PossiblyConflicting.insert(VD); - DeclsToReport.insert(FoundDeclTy(VD, Reason)); + DeclsToReport.insert(FoundDeclTy(VD, Reason, dynamicLookupInfo)); + } + + bool seenBaseName(DeclBaseName name) { + return FoundDecls.find(name) != FoundDecls.end(); } }; -struct ShadowedKeyPathMembers : public VisibleDeclConsumer { +struct KeyPathDynamicMemberConsumer : public VisibleDeclConsumer { VisibleDeclConsumer &consumer; - llvm::DenseSet &seen; - ShadowedKeyPathMembers(VisibleDeclConsumer &consumer, llvm::DenseSet &knownMembers) : consumer(consumer), seen(knownMembers) {} - void foundDecl(ValueDecl *VD, DeclVisibilityKind reason) override { + std::function seenBaseName; + + KeyPathDynamicMemberConsumer(VisibleDeclConsumer &consumer, + std::function seenBaseName) + : consumer(consumer), seenBaseName(std::move(seenBaseName)) {} + + void foundDecl(ValueDecl *VD, DeclVisibilityKind reason, + DynamicLookupInfo dynamicLookupInfo) override { + // Only variables and subscripts are allowed in a keypath. + if (!isa(VD)) + return; + + assert(dynamicLookupInfo.getKind() != + DynamicLookupInfo::KeyPathDynamicMember); + // Dynamic lookup members are only visible if they are not shadowed by // non-dynamic members. - if (seen.count(VD->getBaseName()) == 0) - consumer.foundDecl(VD, reason); + if (isa(VD) || !seenBaseName(VD->getBaseName())) + consumer.foundDecl(VD, DeclVisibilityKind::DynamicLookup, + {nullptr, Type(), reason}); } -}; +}; } // end anonymous namespace /// Enumerate all members in \c BaseTy (including members of extensions, @@ -897,23 +937,21 @@ static void lookupVisibleMemberDecls( LookupState LS, DeclVisibilityKind Reason, LazyResolver *TypeResolver, GenericSignatureBuilder *GSB) { OverrideFilteringConsumer overrideConsumer(BaseTy, CurrDC, TypeResolver); + KeyPathDynamicMemberConsumer dynamicConsumer( + overrideConsumer, + [&](DeclBaseName name) { return overrideConsumer.seenBaseName(name); }); + VisitedSet Visited; lookupVisibleMemberDeclsImpl(BaseTy, overrideConsumer, CurrDC, LS, Reason, TypeResolver, GSB, Visited); - if (hasDynamicMemberLookupAttribute(BaseTy)) { - llvm::DenseSet knownMembers; - for (auto &kv : overrideConsumer.FoundDecls) { - knownMembers.insert(kv.first); - } - ShadowedKeyPathMembers dynamicConsumer(overrideConsumer, knownMembers); - lookupVisibleDynamicMemberLookupDecls(BaseTy, dynamicConsumer, CurrDC, LS, - Reason, TypeResolver, GSB, Visited); - } + lookupVisibleDynamicMemberLookupDecls(BaseTy, dynamicConsumer, CurrDC, LS, + Reason, TypeResolver, GSB, Visited); // Report the declarations we found to the real consumer. for (const auto &DeclAndReason : overrideConsumer.DeclsToReport) - Consumer.foundDecl(DeclAndReason.D, DeclAndReason.Reason); + Consumer.foundDecl(DeclAndReason.D, DeclAndReason.Reason, + DeclAndReason.dynamicLookupInfo); } static void lookupVisibleDeclsImpl(VisibleDeclConsumer &Consumer, @@ -1113,9 +1151,10 @@ void swift::lookupVisibleDecls(VisibleDeclConsumer &Consumer, VisibleDeclConsumer &Consumer) : SM(SM), Loc(Loc), Consumer(Consumer) {} - void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) { + void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo) override { if (isUsableValue(VD, Reason)) - Consumer.foundDecl(VD, Reason); + Consumer.foundDecl(VD, Reason, dynamicLookupInfo); } } LocalConsumer(DC->getASTContext().SourceMgr, Loc, Consumer); diff --git a/lib/Serialization/ModuleFile.cpp b/lib/Serialization/ModuleFile.cpp index 8e6eed81e03..58cd3fda5c5 100644 --- a/lib/Serialization/ModuleFile.cpp +++ b/lib/Serialization/ModuleFile.cpp @@ -2086,7 +2086,8 @@ void ModuleFile::lookupClassMembers(ModuleDecl::AccessPathTy accessPath, dc = dc->getParent(); if (auto nominal = dc->getSelfNominalTypeDecl()) if (nominal->getName() == accessPath.front().first) - consumer.foundDecl(vd, DeclVisibilityKind::DynamicLookup); + consumer.foundDecl(vd, DeclVisibilityKind::DynamicLookup, + DynamicLookupInfo::AnyObject); } } return; @@ -2095,7 +2096,8 @@ void ModuleFile::lookupClassMembers(ModuleDecl::AccessPathTy accessPath, for (const auto &list : ClassMembersForDynamicLookup->data()) { for (auto item : list) consumer.foundDecl(cast(getDecl(item.second)), - DeclVisibilityKind::DynamicLookup); + DeclVisibilityKind::DynamicLookup, + DynamicLookupInfo::AnyObject); } } diff --git a/tools/swift-api-digester/ModuleAnalyzerNodes.cpp b/tools/swift-api-digester/ModuleAnalyzerNodes.cpp index de3615333d8..6b14e06b0ac 100644 --- a/tools/swift-api-digester/ModuleAnalyzerNodes.cpp +++ b/tools/swift-api-digester/ModuleAnalyzerNodes.cpp @@ -1613,7 +1613,8 @@ void SwiftDeclCollector::lookupVisibleDecls(ArrayRef Modules) { continue; KnownDecls.insert(D); if (auto VD = dyn_cast(D)) - foundDecl(VD, DeclVisibilityKind::DynamicLookup); + foundDecl(VD, DeclVisibilityKind::DynamicLookup, + DynamicLookupInfo::AnyObject); else processDecl(D); } @@ -1676,7 +1677,8 @@ void SwiftDeclCollector::processValueDecl(ValueDecl *VD) { } } -void SwiftDeclCollector::foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) { +void SwiftDeclCollector::foundDecl(ValueDecl *VD, DeclVisibilityKind Reason, + DynamicLookupInfo) { if (VD->getClangMacro()) { // Collect macros, we will sort them afterwards. ClangMacros.push_back(VD); diff --git a/tools/swift-api-digester/ModuleAnalyzerNodes.h b/tools/swift-api-digester/ModuleAnalyzerNodes.h index d1c3120ffe4..20bc4e443bb 100644 --- a/tools/swift-api-digester/ModuleAnalyzerNodes.h +++ b/tools/swift-api-digester/ModuleAnalyzerNodes.h @@ -690,7 +690,8 @@ public: std::vector createParameterNodes(ParameterList *PL); SDKNode *constructTypeNode(Type T, TypeInitInfo Info = TypeInitInfo()); void processValueDecl(ValueDecl *VD); - void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) override; + void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason, + DynamicLookupInfo dynamicLookupInfo = {}) override; void processDecl(Decl *D); public: void lookupVisibleDecls(ArrayRef Modules);