Pass DynamicLookupInfo through VisibleDeclConsumers NFC

This commit adds a new type DynamicLookupInfo that provides information
about how a dynamic member lookup found a particular Decl. This is
needed to correctly handle KeyPath dynamic member lookups, but for now
just plumb it through everywhere.
This commit is contained in:
Ben Langmuir
2019-05-01 14:28:07 -07:00
parent f5ba89d372
commit 34da079aa6
14 changed files with 318 additions and 164 deletions

View File

@@ -205,6 +205,51 @@ enum class DeclVisibilityKind {
DynamicLookup, 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<Derived, U>, 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 /// An abstract base class for a visitor that consumes declarations found within
/// a given context. /// a given context.
class VisibleDeclConsumer { class VisibleDeclConsumer {
@@ -213,7 +258,8 @@ public:
virtual ~VisibleDeclConsumer() = default; virtual ~VisibleDeclConsumer() = default;
/// This method is called by findVisibleDecls() every time it finds a decl. /// 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. /// An implementation of VisibleDeclConsumer that's built from a lambda.
@@ -223,7 +269,7 @@ class LambdaDeclConsumer : public VisibleDeclConsumer {
public: public:
LambdaDeclConsumer(Fn &&callback) : Callback(std::move(callback)) {} LambdaDeclConsumer(Fn &&callback) : Callback(std::move(callback)) {}
void foundDecl(ValueDecl *VD, DeclVisibilityKind reason) { void foundDecl(ValueDecl *VD, DeclVisibilityKind reason, DynamicLookupInfo) {
Callback(VD, reason); Callback(VD, reason);
} }
}; };
@@ -240,7 +286,8 @@ public:
explicit VectorDeclConsumer(SmallVectorImpl<ValueDecl *> &decls) explicit VectorDeclConsumer(SmallVectorImpl<ValueDecl *> &decls)
: results(decls) {} : results(decls) {}
virtual void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) override { virtual void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason,
DynamicLookupInfo) override {
results.push_back(VD); results.push_back(VD);
} }
}; };
@@ -259,7 +306,8 @@ public:
bool isTypeLookup) bool isTypeLookup)
: name(name), results(results), isTypeLookup(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, // Give clients an opportunity to filter out non-type declarations early,
// to avoid circular validation. // to avoid circular validation.
if (isTypeLookup && !isa<TypeDecl>(VD)) if (isTypeLookup && !isa<TypeDecl>(VD))
@@ -280,7 +328,8 @@ public:
VisibleDeclConsumer &consumer) VisibleDeclConsumer &consumer)
: DC(DC), ChainedConsumer(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 /// Remove any declarations in the given set that were overridden by

View File

@@ -1041,7 +1041,8 @@ ASTBuilder::findForeignTypeDecl(StringRef name,
explicit Consumer(Demangle::Node::Kind kind) : ExpectedKind(kind) {} 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 (HadError) return;
if (decl == Result) return; if (decl == Result) return;
if (!Result) { if (!Result) {

View File

@@ -278,7 +278,8 @@ private:
ConstPtrVec<ValueDecl> &classMembers; ConstPtrVec<ValueDecl> &classMembers;
Collector(ConstPtrVec<ValueDecl> &classMembers) Collector(ConstPtrVec<ValueDecl> &classMembers)
: classMembers(classMembers) {} : classMembers(classMembers) {}
void foundDecl(ValueDecl *VD, DeclVisibilityKind) override { void foundDecl(ValueDecl *VD, DeclVisibilityKind,
DynamicLookupInfo) override {
classMembers.push_back(VD); classMembers.push_back(VD);
} }
} collector{classMembers}; } collector{classMembers};

View File

@@ -298,7 +298,8 @@ void SourceLookupCache::lookupClassMembers(AccessPathTy accessPath,
for (ValueDecl *vd : member.second) { for (ValueDecl *vd : member.second) {
auto *nominal = vd->getDeclContext()->getSelfNominalTypeDecl(); auto *nominal = vd->getDeclContext()->getSelfNominalTypeDecl();
if (nominal && nominal->getName() == accessPath.front().first) if (nominal && nominal->getName() == accessPath.front().first)
consumer.foundDecl(vd, DeclVisibilityKind::DynamicLookup); consumer.foundDecl(vd, DeclVisibilityKind::DynamicLookup,
DynamicLookupInfo::AnyObject);
} }
} }
return; return;
@@ -311,7 +312,8 @@ void SourceLookupCache::lookupClassMembers(AccessPathTy accessPath,
continue; continue;
for (ValueDecl *vd : member.second) for (ValueDecl *vd : member.second)
consumer.foundDecl(vd, DeclVisibilityKind::DynamicLookup); consumer.foundDecl(vd, DeclVisibilityKind::DynamicLookup,
DynamicLookupInfo::AnyObject);
} }
} }

View File

@@ -63,14 +63,15 @@ ValueDecl *LookupResultEntry::getBaseDecl() const {
void DebuggerClient::anchor() {} void DebuggerClient::anchor() {}
void AccessFilteringDeclConsumer::foundDecl(ValueDecl *D, void AccessFilteringDeclConsumer::foundDecl(
DeclVisibilityKind reason) { ValueDecl *D, DeclVisibilityKind reason,
DynamicLookupInfo dynamicLookupInfo) {
if (D->isInvalid()) if (D->isInvalid())
return; return;
if (!D->isAccessibleFrom(DC)) if (!D->isAccessibleFrom(DC))
return; return;
ChainedConsumer.foundDecl(D, reason); ChainedConsumer.foundDecl(D, reason, dynamicLookupInfo);
} }

View File

@@ -2225,9 +2225,10 @@ public:
assert(CMU); assert(CMU);
} }
void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) override { void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason,
DynamicLookupInfo dynamicLookupInfo) override {
if (isVisibleFromModule(ModuleFilter, VD)) if (isVisibleFromModule(ModuleFilter, VD))
NextConsumer.foundDecl(VD, Reason); NextConsumer.foundDecl(VD, Reason, dynamicLookupInfo);
} }
}; };
@@ -2242,9 +2243,10 @@ public:
assert(CMU); assert(CMU);
} }
void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) override { void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason,
DynamicLookupInfo dynamicLookupInfo) override {
if (isDeclaredInModule(ModuleFilter, VD)) if (isDeclaredInModule(ModuleFilter, VD))
NextConsumer.foundDecl(VD, Reason); NextConsumer.foundDecl(VD, Reason, dynamicLookupInfo);
} }
}; };
@@ -2307,9 +2309,10 @@ public:
topLevelModule->Name == "CoreServices"); topLevelModule->Name == "CoreServices");
} }
void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) override { void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason,
DynamicLookupInfo dynamicLookupInfo) override {
if (!shouldDiscard(VD)) if (!shouldDiscard(VD))
NextConsumer.foundDecl(VD, Reason); NextConsumer.foundDecl(VD, Reason, dynamicLookupInfo);
} }
}; };
@@ -2551,7 +2554,8 @@ public:
explicit VectorDeclPtrConsumer(SmallVectorImpl<Decl *> &Decls) explicit VectorDeclPtrConsumer(SmallVectorImpl<Decl *> &Decls)
: Results(Decls) {} : Results(Decls) {}
void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) override { void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason,
DynamicLookupInfo) override {
Results.push_back(VD); 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 // 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. // importing the member at all by checking importedName ahead of time.
if (decl->getFullName().matchesRef(name)) { 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, // Check for an alternate declaration; if its name matches,
// report it. // report it.
for (auto alternate : getAlternateDecls(decl)) { for (auto alternate : getAlternateDecls(decl)) {
if (alternate->getFullName().matchesRef(name)) { if (alternate->getFullName().matchesRef(name)) {
consumer.foundDecl(alternate, DeclVisibilityKind::DynamicLookup); consumer.foundDecl(alternate, DeclVisibilityKind::DynamicLookup,
DynamicLookupInfo::AnyObject);
} }
} }
return true; return true;

View File

@@ -437,7 +437,8 @@ void ProvidesEmitter::emitDynamicLookupMembers() const {
SmallVector<DeclBaseName, 16> names; SmallVector<DeclBaseName, 16> names;
public: public:
void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) override { void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason,
DynamicLookupInfo) override {
names.push_back(VD->getBaseName()); names.push_back(VD->getBaseName());
} }
ArrayRef<DeclBaseName> getNames() { ArrayRef<DeclBaseName> getNames() {

View File

@@ -1799,7 +1799,8 @@ public:
} }
SemanticContextKind getSemanticContext(const Decl *D, SemanticContextKind getSemanticContext(const Decl *D,
DeclVisibilityKind Reason) { DeclVisibilityKind Reason,
DynamicLookupInfo dynamicLookupInfo) {
if (ForcedSemanticContext) if (ForcedSemanticContext)
return *ForcedSemanticContext; return *ForcedSemanticContext;
@@ -1845,12 +1846,27 @@ public:
} }
case DeclVisibilityKind::DynamicLookup: case DeclVisibilityKind::DynamicLookup:
// AnyObject results can come from different modules, including the switch (dynamicLookupInfo.getKind()) {
// current module, but we always assign them the OtherModule semantic case DynamicLookupInfo::None:
// context. These declarations are uniqued by signature, so it is llvm_unreachable("invalid DynamicLookupInfo::Kind for dynamic lookup");
// totally random (determined by the hash function) which of the
// equivalent declarations (across multiple modules) we will get. case DynamicLookupInfo::AnyObject:
return SemanticContextKind::OtherModule; // 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<AnyObject, U> !?!?
assert(dynamicLookupInfo.getKeyPathDynamicMember().originalVisibility !=
DeclVisibilityKind::DynamicLookup);
return getSemanticContext(
D, dynamicLookupInfo.getKeyPathDynamicMember().originalVisibility,
{});
}
} }
llvm_unreachable("unhandled kind"); llvm_unreachable("unhandled kind");
} }
@@ -2057,7 +2073,8 @@ public:
return Type(); return Type();
} }
void addVarDeclRef(const VarDecl *VD, DeclVisibilityKind Reason) { void addVarDeclRef(const VarDecl *VD, DeclVisibilityKind Reason,
DynamicLookupInfo dynamicLookupInfo) {
if (!VD->hasName() || if (!VD->hasName() ||
!VD->isAccessibleFrom(CurrDeclContext) || !VD->isAccessibleFrom(CurrDeclContext) ||
VD->shouldHideFromEditor()) VD->shouldHideFromEditor())
@@ -2068,9 +2085,8 @@ public:
CommandWordsPairs Pairs; CommandWordsPairs Pairs;
CodeCompletionResultBuilder Builder( CodeCompletionResultBuilder Builder(
Sink, Sink, CodeCompletionResult::ResultKind::Declaration,
CodeCompletionResult::ResultKind::Declaration, getSemanticContext(VD, Reason, dynamicLookupInfo), expectedTypeContext);
getSemanticContext(VD, Reason), expectedTypeContext);
Builder.setAssociatedDecl(VD); Builder.setAssociatedDecl(VD);
addLeadingDot(Builder); addLeadingDot(Builder);
addValueBaseName(Builder, Name); addValueBaseName(Builder, Name);
@@ -2412,7 +2428,8 @@ public:
llvm_unreachable("Unhandled LookupKind in switch."); 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()) if (FD->getName().empty())
return; return;
foundFunction(FD); foundFunction(FD);
@@ -2444,7 +2461,8 @@ public:
CommandWordsPairs Pairs; CommandWordsPairs Pairs;
CodeCompletionResultBuilder Builder( CodeCompletionResultBuilder Builder(
Sink, CodeCompletionResult::ResultKind::Declaration, Sink, CodeCompletionResult::ResultKind::Declaration,
getSemanticContext(FD, Reason), expectedTypeContext); getSemanticContext(FD, Reason, dynamicLookupInfo),
expectedTypeContext);
setClangDeclKeywords(FD, Pairs, Builder); setClangDeclKeywords(FD, Pairs, Builder);
Builder.setAssociatedDecl(FD); Builder.setAssociatedDecl(FD);
addLeadingDot(Builder); addLeadingDot(Builder);
@@ -2526,6 +2544,7 @@ public:
} }
void addConstructorCall(const ConstructorDecl *CD, DeclVisibilityKind Reason, void addConstructorCall(const ConstructorDecl *CD, DeclVisibilityKind Reason,
DynamicLookupInfo dynamicLookupInfo,
Optional<Type> BaseType, Optional<Type> Result, Optional<Type> BaseType, Optional<Type> Result,
bool IsOnType = true, bool IsOnType = true,
Identifier addName = Identifier()) { Identifier addName = Identifier()) {
@@ -2553,7 +2572,8 @@ public:
CommandWordsPairs Pairs; CommandWordsPairs Pairs;
CodeCompletionResultBuilder Builder( CodeCompletionResultBuilder Builder(
Sink, CodeCompletionResult::ResultKind::Declaration, Sink, CodeCompletionResult::ResultKind::Declaration,
getSemanticContext(CD, Reason), expectedTypeContext); getSemanticContext(CD, Reason, dynamicLookupInfo),
expectedTypeContext);
setClangDeclKeywords(CD, Pairs, Builder); setClangDeclKeywords(CD, Pairs, Builder);
Builder.setAssociatedDecl(CD); Builder.setAssociatedDecl(CD);
if (needInit) { if (needInit) {
@@ -2604,7 +2624,8 @@ public:
} }
void addConstructorCallsForType(Type type, Identifier name, void addConstructorCallsForType(Type type, Identifier name,
DeclVisibilityKind Reason) { DeclVisibilityKind Reason,
DynamicLookupInfo dynamicLookupInfo) {
if (!Ctx.LangOpts.CodeCompleteInitsInPostfixExpr && !IsUnresolvedMember) if (!Ctx.LangOpts.CodeCompleteInitsInPostfixExpr && !IsUnresolvedMember)
return; return;
@@ -2620,13 +2641,15 @@ public:
cast<ConstructorDecl>(init)->getFailability() == OTK_Optional) { cast<ConstructorDecl>(init)->getFailability() == OTK_Optional) {
continue; continue;
} }
addConstructorCall(cast<ConstructorDecl>(init), Reason, type, None, addConstructorCall(cast<ConstructorDecl>(init), Reason,
dynamicLookupInfo, type, None,
/*IsOnType=*/true, name); /*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. // Don't add subscript call to unqualified completion.
if (!ExprType) if (!ExprType)
return; return;
@@ -2642,9 +2665,8 @@ public:
CommandWordsPairs Pairs; CommandWordsPairs Pairs;
CodeCompletionResultBuilder Builder( CodeCompletionResultBuilder Builder(
Sink, Sink, CodeCompletionResult::ResultKind::Declaration,
CodeCompletionResult::ResultKind::Declaration, getSemanticContext(SD, Reason, dynamicLookupInfo), expectedTypeContext);
getSemanticContext(SD, Reason), expectedTypeContext);
Builder.setAssociatedDecl(SD); Builder.setAssociatedDecl(SD);
setClangDeclKeywords(SD, Pairs, Builder); setClangDeclKeywords(SD, Pairs, Builder);
@@ -2671,15 +2693,15 @@ public:
addTypeAnnotation(Builder, resultTy); addTypeAnnotation(Builder, resultTy);
} }
void addNominalTypeRef(const NominalTypeDecl *NTD, void addNominalTypeRef(const NominalTypeDecl *NTD, DeclVisibilityKind Reason,
DeclVisibilityKind Reason) { DynamicLookupInfo dynamicLookupInfo) {
if (IsUnresolvedMember) if (IsUnresolvedMember)
return; return;
CommandWordsPairs Pairs; CommandWordsPairs Pairs;
CodeCompletionResultBuilder Builder( CodeCompletionResultBuilder Builder(
Sink, Sink, CodeCompletionResult::ResultKind::Declaration,
CodeCompletionResult::ResultKind::Declaration, getSemanticContext(NTD, Reason, dynamicLookupInfo),
getSemanticContext(NTD, Reason), expectedTypeContext); expectedTypeContext);
Builder.setAssociatedDecl(NTD); Builder.setAssociatedDecl(NTD);
setClangDeclKeywords(NTD, Pairs, Builder); setClangDeclKeywords(NTD, Pairs, Builder);
addLeadingDot(Builder); addLeadingDot(Builder);
@@ -2687,14 +2709,15 @@ public:
addTypeAnnotation(Builder, NTD->getDeclaredType()); addTypeAnnotation(Builder, NTD->getDeclaredType());
} }
void addTypeAliasRef(const TypeAliasDecl *TAD, DeclVisibilityKind Reason) { void addTypeAliasRef(const TypeAliasDecl *TAD, DeclVisibilityKind Reason,
DynamicLookupInfo dynamicLookupInfo) {
if (IsUnresolvedMember) if (IsUnresolvedMember)
return; return;
CommandWordsPairs Pairs; CommandWordsPairs Pairs;
CodeCompletionResultBuilder Builder( CodeCompletionResultBuilder Builder(
Sink, Sink, CodeCompletionResult::ResultKind::Declaration,
CodeCompletionResult::ResultKind::Declaration, getSemanticContext(TAD, Reason, dynamicLookupInfo),
getSemanticContext(TAD, Reason), expectedTypeContext); expectedTypeContext);
Builder.setAssociatedDecl(TAD); Builder.setAssociatedDecl(TAD);
setClangDeclKeywords(TAD, Pairs, Builder); setClangDeclKeywords(TAD, Pairs, Builder);
addLeadingDot(Builder); addLeadingDot(Builder);
@@ -2719,12 +2742,12 @@ public:
} }
void addGenericTypeParamRef(const GenericTypeParamDecl *GP, void addGenericTypeParamRef(const GenericTypeParamDecl *GP,
DeclVisibilityKind Reason) { DeclVisibilityKind Reason,
DynamicLookupInfo dynamicLookupInfo) {
CommandWordsPairs Pairs; CommandWordsPairs Pairs;
CodeCompletionResultBuilder Builder( CodeCompletionResultBuilder Builder(
Sink, Sink, CodeCompletionResult::ResultKind::Declaration,
CodeCompletionResult::ResultKind::Declaration, getSemanticContext(GP, Reason, dynamicLookupInfo), expectedTypeContext);
getSemanticContext(GP, Reason), expectedTypeContext);
setClangDeclKeywords(GP, Pairs, Builder); setClangDeclKeywords(GP, Pairs, Builder);
Builder.setAssociatedDecl(GP); Builder.setAssociatedDecl(GP);
addLeadingDot(Builder); addLeadingDot(Builder);
@@ -2733,12 +2756,12 @@ public:
} }
void addAssociatedTypeRef(const AssociatedTypeDecl *AT, void addAssociatedTypeRef(const AssociatedTypeDecl *AT,
DeclVisibilityKind Reason) { DeclVisibilityKind Reason,
DynamicLookupInfo dynamicLookupInfo) {
CommandWordsPairs Pairs; CommandWordsPairs Pairs;
CodeCompletionResultBuilder Builder( CodeCompletionResultBuilder Builder(
Sink, Sink, CodeCompletionResult::ResultKind::Declaration,
CodeCompletionResult::ResultKind::Declaration, getSemanticContext(AT, Reason, dynamicLookupInfo), expectedTypeContext);
getSemanticContext(AT, Reason), expectedTypeContext);
setClangDeclKeywords(AT, Pairs, Builder); setClangDeclKeywords(AT, Pairs, Builder);
Builder.setAssociatedDecl(AT); Builder.setAssociatedDecl(AT);
addLeadingDot(Builder); addLeadingDot(Builder);
@@ -2749,7 +2772,7 @@ public:
void addPrecedenceGroupRef(PrecedenceGroupDecl *PGD) { void addPrecedenceGroupRef(PrecedenceGroupDecl *PGD) {
auto semanticContext = auto semanticContext =
getSemanticContext(PGD, DeclVisibilityKind::VisibleAtTopLevel); getSemanticContext(PGD, DeclVisibilityKind::VisibleAtTopLevel, {});
CodeCompletionResultBuilder builder( CodeCompletionResultBuilder builder(
Sink, CodeCompletionResult::ResultKind::Declaration, Sink, CodeCompletionResult::ResultKind::Declaration,
semanticContext, {}); semanticContext, {});
@@ -2758,8 +2781,8 @@ public:
builder.setAssociatedDecl(PGD); builder.setAssociatedDecl(PGD);
}; };
void addEnumElementRef(const EnumElementDecl *EED, void addEnumElementRef(const EnumElementDecl *EED, DeclVisibilityKind Reason,
DeclVisibilityKind Reason, DynamicLookupInfo dynamicLookupInfo,
bool HasTypeContext) { bool HasTypeContext) {
if (!EED->hasName() || if (!EED->hasName() ||
!EED->isAccessibleFrom(CurrDeclContext) || !EED->isAccessibleFrom(CurrDeclContext) ||
@@ -2770,7 +2793,7 @@ public:
CodeCompletionResultBuilder Builder( CodeCompletionResultBuilder Builder(
Sink, CodeCompletionResult::ResultKind::Declaration, Sink, CodeCompletionResult::ResultKind::Declaration,
HasTypeContext ? SemanticContextKind::ExpressionSpecific HasTypeContext ? SemanticContextKind::ExpressionSpecific
: getSemanticContext(EED, Reason), : getSemanticContext(EED, Reason, dynamicLookupInfo),
expectedTypeContext); expectedTypeContext);
Builder.setAssociatedDecl(EED); Builder.setAssociatedDecl(EED);
setClangDeclKeywords(EED, Pairs, Builder); setClangDeclKeywords(EED, Pairs, Builder);
@@ -2846,11 +2869,13 @@ public:
/// Add the compound function name for the given function. /// Add the compound function name for the given function.
void addCompoundFunctionName(AbstractFunctionDecl *AFD, void addCompoundFunctionName(AbstractFunctionDecl *AFD,
DeclVisibilityKind Reason) { DeclVisibilityKind Reason,
DynamicLookupInfo dynamicLookupInfo) {
CommandWordsPairs Pairs; CommandWordsPairs Pairs;
CodeCompletionResultBuilder Builder( CodeCompletionResultBuilder Builder(
Sink, CodeCompletionResult::ResultKind::Declaration, Sink, CodeCompletionResult::ResultKind::Declaration,
getSemanticContext(AFD, Reason), expectedTypeContext); getSemanticContext(AFD, Reason, dynamicLookupInfo),
expectedTypeContext);
setClangDeclKeywords(AFD, Pairs, Builder); setClangDeclKeywords(AFD, Pairs, Builder);
Builder.setAssociatedDecl(AFD); Builder.setAssociatedDecl(AFD);
@@ -2879,7 +2904,8 @@ public:
} }
// Implement swift::VisibleDeclConsumer. // Implement swift::VisibleDeclConsumer.
void foundDecl(ValueDecl *D, DeclVisibilityKind Reason) override { void foundDecl(ValueDecl *D, DeclVisibilityKind Reason,
DynamicLookupInfo dynamicLookupInfo) override {
if (D->shouldHideFromEditor()) if (D->shouldHideFromEditor())
return; return;
@@ -2901,7 +2927,7 @@ public:
if (auto *CD = dyn_cast<ConstructorDecl>(D)) { if (auto *CD = dyn_cast<ConstructorDecl>(D)) {
// Do we want compound function names here? // Do we want compound function names here?
if (shouldUseFunctionReference(CD)) { if (shouldUseFunctionReference(CD)) {
addCompoundFunctionName(CD, Reason); addCompoundFunctionName(CD, Reason, dynamicLookupInfo);
return; return;
} }
@@ -2924,10 +2950,12 @@ public:
// the initializer is required, the base type's instance type is not a class, // the initializer is required, the base type's instance type is not a class,
// or this is a 'self' or 'super' reference. // or this is a 'self' or 'super' reference.
if (IsStaticMetatype || IsUnresolvedMember || Ty->is<ArchetypeType>()) if (IsStaticMetatype || IsUnresolvedMember || Ty->is<ArchetypeType>())
addConstructorCall(CD, Reason, None, Result, /*isOnType*/true); addConstructorCall(CD, Reason, dynamicLookupInfo, None, Result,
/*isOnType*/ true);
else if ((IsSelfRefExpr || IsSuperRefExpr || !Ty->is<ClassType>() || else if ((IsSelfRefExpr || IsSuperRefExpr || !Ty->is<ClassType>() ||
CD->isRequired()) && !HaveLParen) CD->isRequired()) && !HaveLParen)
addConstructorCall(CD, Reason, None, Result, /*isOnType*/false); addConstructorCall(CD, Reason, dynamicLookupInfo, None, Result,
/*isOnType*/ false);
return; return;
} }
if (!HaveLParen) { if (!HaveLParen) {
@@ -2938,7 +2966,8 @@ public:
// initializers and for 'super' in convenience initializers. // initializers and for 'super' in convenience initializers.
if ((IsSelfRefExpr && CDC->isConvenienceInit()) || if ((IsSelfRefExpr && CDC->isConvenienceInit()) ||
((IsSuperRefExpr && !CDC->isConvenienceInit()))) ((IsSuperRefExpr && !CDC->isConvenienceInit())))
addConstructorCall(CD, Reason, None, None, /*IsOnType=*/false); addConstructorCall(CD, Reason, dynamicLookupInfo, None, None,
/*IsOnType=*/false);
} }
return; return;
} }
@@ -2951,7 +2980,7 @@ public:
case LookupKind::ValueInDeclContext: case LookupKind::ValueInDeclContext:
case LookupKind::ImportFromModule: case LookupKind::ImportFromModule:
if (auto *VD = dyn_cast<VarDecl>(D)) { if (auto *VD = dyn_cast<VarDecl>(D)) {
addVarDeclRef(VD, Reason); addVarDeclRef(VD, Reason, dynamicLookupInfo);
return; return;
} }
@@ -2967,77 +2996,79 @@ public:
// Do we want compound function names here? // Do we want compound function names here?
if (shouldUseFunctionReference(FD)) { if (shouldUseFunctionReference(FD)) {
addCompoundFunctionName(FD, Reason); addCompoundFunctionName(FD, Reason, dynamicLookupInfo);
return; return;
} }
addMethodCall(FD, Reason); addMethodCall(FD, Reason, dynamicLookupInfo);
return; return;
} }
if (auto *NTD = dyn_cast<NominalTypeDecl>(D)) { if (auto *NTD = dyn_cast<NominalTypeDecl>(D)) {
addNominalTypeRef(NTD, Reason); addNominalTypeRef(NTD, Reason, dynamicLookupInfo);
addConstructorCallsForType(NTD->getDeclaredInterfaceType(), addConstructorCallsForType(NTD->getDeclaredInterfaceType(),
NTD->getName(), Reason); NTD->getName(), Reason, dynamicLookupInfo);
return; return;
} }
if (auto *TAD = dyn_cast<TypeAliasDecl>(D)) { if (auto *TAD = dyn_cast<TypeAliasDecl>(D)) {
addTypeAliasRef(TAD, Reason); addTypeAliasRef(TAD, Reason, dynamicLookupInfo);
auto type = TAD->mapTypeIntoContext(TAD->getDeclaredInterfaceType()); auto type = TAD->mapTypeIntoContext(TAD->getDeclaredInterfaceType());
if (type->mayHaveMembers()) if (type->mayHaveMembers())
addConstructorCallsForType(type, TAD->getName(), Reason); addConstructorCallsForType(type, TAD->getName(), Reason,
dynamicLookupInfo);
return; return;
} }
if (auto *GP = dyn_cast<GenericTypeParamDecl>(D)) { if (auto *GP = dyn_cast<GenericTypeParamDecl>(D)) {
addGenericTypeParamRef(GP, Reason); addGenericTypeParamRef(GP, Reason, dynamicLookupInfo);
for (auto *protocol : GP->getConformingProtocols()) for (auto *protocol : GP->getConformingProtocols())
addConstructorCallsForType(protocol->getDeclaredInterfaceType(), addConstructorCallsForType(protocol->getDeclaredInterfaceType(),
GP->getName(), Reason); GP->getName(), Reason, dynamicLookupInfo);
return; return;
} }
if (auto *AT = dyn_cast<AssociatedTypeDecl>(D)) { if (auto *AT = dyn_cast<AssociatedTypeDecl>(D)) {
addAssociatedTypeRef(AT, Reason); addAssociatedTypeRef(AT, Reason, dynamicLookupInfo);
return; return;
} }
if (auto *EED = dyn_cast<EnumElementDecl>(D)) { if (auto *EED = dyn_cast<EnumElementDecl>(D)) {
addEnumElementRef(EED, Reason, /*HasTypeContext=*/false); addEnumElementRef(EED, Reason, dynamicLookupInfo,
/*HasTypeContext=*/false);
return; return;
} }
// Swift key path allows .[0] // Swift key path allows .[0]
if (auto *SD = dyn_cast<SubscriptDecl>(D)) { if (auto *SD = dyn_cast<SubscriptDecl>(D)) {
addSubscriptCall(SD, Reason); addSubscriptCall(SD, Reason, dynamicLookupInfo);
return; return;
} }
return; return;
case LookupKind::EnumElement: case LookupKind::EnumElement:
handleEnumElement(D, Reason); handleEnumElement(D, Reason, dynamicLookupInfo);
return; return;
case LookupKind::Type: case LookupKind::Type:
case LookupKind::TypeInDeclContext: case LookupKind::TypeInDeclContext:
if (auto *NTD = dyn_cast<NominalTypeDecl>(D)) { if (auto *NTD = dyn_cast<NominalTypeDecl>(D)) {
addNominalTypeRef(NTD, Reason); addNominalTypeRef(NTD, Reason, dynamicLookupInfo);
return; return;
} }
if (auto *TAD = dyn_cast<TypeAliasDecl>(D)) { if (auto *TAD = dyn_cast<TypeAliasDecl>(D)) {
addTypeAliasRef(TAD, Reason); addTypeAliasRef(TAD, Reason, dynamicLookupInfo);
return; return;
} }
if (auto *GP = dyn_cast<GenericTypeParamDecl>(D)) { if (auto *GP = dyn_cast<GenericTypeParamDecl>(D)) {
addGenericTypeParamRef(GP, Reason); addGenericTypeParamRef(GP, Reason, dynamicLookupInfo);
return; return;
} }
if (auto *AT = dyn_cast<AssociatedTypeDecl>(D)) { if (auto *AT = dyn_cast<AssociatedTypeDecl>(D)) {
addAssociatedTypeRef(AT, Reason); addAssociatedTypeRef(AT, Reason, dynamicLookupInfo);
return; return;
} }
@@ -3045,12 +3076,14 @@ public:
} }
} }
bool handleEnumElement(ValueDecl *D, DeclVisibilityKind Reason) { bool handleEnumElement(ValueDecl *D, DeclVisibilityKind Reason,
DynamicLookupInfo dynamicLookupInfo) {
if (!D->hasInterfaceType()) if (!D->hasInterfaceType())
TypeResolver->resolveDeclSignature(D); TypeResolver->resolveDeclSignature(D);
if (auto *EED = dyn_cast<EnumElementDecl>(D)) { if (auto *EED = dyn_cast<EnumElementDecl>(D)) {
addEnumElementRef(EED, Reason, /*HasTypeContext=*/true); addEnumElementRef(EED, Reason, dynamicLookupInfo,
/*HasTypeContext=*/true);
return true; return true;
} else if (auto *ED = dyn_cast<EnumDecl>(D)) { } else if (auto *ED = dyn_cast<EnumDecl>(D)) {
llvm::DenseSet<EnumElementDecl *> Elements; llvm::DenseSet<EnumElementDecl *> Elements;
@@ -3058,7 +3091,8 @@ public:
for (auto *Ele : Elements) { for (auto *Ele : Elements) {
if (!Ele->hasInterfaceType()) if (!Ele->hasInterfaceType())
TypeResolver->resolveDeclSignature(Ele); TypeResolver->resolveDeclSignature(Ele);
addEnumElementRef(Ele, Reason, /*HasTypeContext=*/true); addEnumElementRef(Ele, Reason, dynamicLookupInfo,
/*HasTypeContext=*/true);
} }
return true; return true;
} }
@@ -3292,7 +3326,7 @@ public:
// FIXME: we should get the semantic context of the function, not the // FIXME: we should get the semantic context of the function, not the
// operator decl. // operator decl.
auto semanticContext = auto semanticContext =
getSemanticContext(op, DeclVisibilityKind::VisibleAtTopLevel); getSemanticContext(op, DeclVisibilityKind::VisibleAtTopLevel, {});
CodeCompletionResultBuilder builder( CodeCompletionResultBuilder builder(
Sink, CodeCompletionResult::ResultKind::Declaration, semanticContext, Sink, CodeCompletionResult::ResultKind::Declaration, semanticContext,
{}); {});
@@ -3341,7 +3375,7 @@ public:
// FIXME: we should get the semantic context of the function, not the // FIXME: we should get the semantic context of the function, not the
// operator decl. // operator decl.
auto semanticContext = auto semanticContext =
getSemanticContext(op, DeclVisibilityKind::VisibleAtTopLevel); getSemanticContext(op, DeclVisibilityKind::VisibleAtTopLevel, {});
CodeCompletionResultBuilder builder( CodeCompletionResultBuilder builder(
Sink, CodeCompletionResult::ResultKind::Declaration, semanticContext, Sink, CodeCompletionResult::ResultKind::Declaration, semanticContext,
{}); {});
@@ -3593,9 +3627,10 @@ public:
DeclFilter Filter; DeclFilter Filter;
FilteredDeclConsumer(swift::VisibleDeclConsumer &Consumer, FilteredDeclConsumer(swift::VisibleDeclConsumer &Consumer,
DeclFilter Filter) : Consumer(Consumer), Filter(Filter) {} 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)) if (Filter(VD, Kind))
Consumer.foundDecl(VD, Kind); Consumer.foundDecl(VD, Kind, dynamicLookupInfo);
} }
}; };
@@ -3624,7 +3659,7 @@ public:
if (!isa<ProtocolDecl>(NTD) && if (!isa<ProtocolDecl>(NTD) &&
NTD->getModuleContext() != CurrDeclContext->getParentModule()) { NTD->getModuleContext() != CurrDeclContext->getParentModule()) {
addNominalTypeRef(NT->getDecl(), 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 // type and has the same type (or if the member is a function, then the
// same result type) as the contextual type. // same result type) as the contextual type.
FilteredDeclConsumer consumer(*this, [=](ValueDecl *VD, FilteredDeclConsumer consumer(*this, [=](ValueDecl *VD,
DeclVisibilityKind reason) { DeclVisibilityKind Reason) {
if (VD->isOperator()) if (VD->isOperator())
return false; return false;
@@ -3713,11 +3749,11 @@ public:
// Only non-failable constructors are implicitly referenceable. // Only non-failable constructors are implicitly referenceable.
if (auto CD = dyn_cast<ConstructorDecl>(VD)) { if (auto CD = dyn_cast<ConstructorDecl>(VD)) {
switch (CD->getFailability()) { switch (CD->getFailability()) {
case OTK_None: case OTK_None:
case OTK_ImplicitlyUnwrappedOptional: case OTK_ImplicitlyUnwrappedOptional:
return true; return true;
case OTK_Optional: case OTK_Optional:
return false; return false;
} }
} }
@@ -3816,7 +3852,7 @@ public:
if (!TheEnumDecl) if (!TheEnumDecl)
return; return;
for (auto Element : TheEnumDecl->getAllElements()) { 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 /// Return type if the result type if \p VD should be represented as opaque
/// result type. /// result type.
TypeLoc getOpaqueResultTypeLoc(const ValueDecl *VD, DeclVisibilityKind Reason) { TypeLoc getOpaqueResultTypeLoc(const ValueDecl *VD, DeclVisibilityKind Reason,
DynamicLookupInfo dynamicLookupInfo) {
if (Reason != if (Reason !=
DeclVisibilityKind::MemberOfProtocolImplementedByCurrentNominal) DeclVisibilityKind::MemberOfProtocolImplementedByCurrentNominal)
return nullptr; return nullptr;
@@ -4100,6 +4137,7 @@ public:
} }
void addValueOverride(const ValueDecl *VD, DeclVisibilityKind Reason, void addValueOverride(const ValueDecl *VD, DeclVisibilityKind Reason,
DynamicLookupInfo dynamicLookupInfo,
CodeCompletionResultBuilder &Builder, CodeCompletionResultBuilder &Builder,
bool hasDeclIntroducer) { bool hasDeclIntroducer) {
class DeclPrinter : public StreamPrinter { class DeclPrinter : public StreamPrinter {
@@ -4131,7 +4169,8 @@ public:
unsigned NameOffset = 0; unsigned NameOffset = 0;
{ {
llvm::raw_svector_ostream OS(DeclStr); llvm::raw_svector_ostream OS(DeclStr);
DeclPrinter Printer(OS, getOpaqueResultTypeLoc(VD, Reason)); DeclPrinter Printer(
OS, getOpaqueResultTypeLoc(VD, Reason, dynamicLookupInfo));
PrintOptions Options; PrintOptions Options;
if (auto transformType = CurrDeclContext->getDeclaredTypeInContext()) if (auto transformType = CurrDeclContext->getDeclaredTypeInContext())
Options.setBaseType(transformType); Options.setBaseType(transformType);
@@ -4167,16 +4206,18 @@ public:
Builder.addTextChunk(DeclStr.str().substr(NameOffset)); Builder.addTextChunk(DeclStr.str().substr(NameOffset));
} }
void addMethodOverride(const FuncDecl *FD, DeclVisibilityKind Reason) { void addMethodOverride(const FuncDecl *FD, DeclVisibilityKind Reason,
DynamicLookupInfo dynamicLookupInfo) {
CodeCompletionResultBuilder Builder( CodeCompletionResultBuilder Builder(
Sink, CodeCompletionResult::ResultKind::Declaration, Sink, CodeCompletionResult::ResultKind::Declaration,
SemanticContextKind::Super, {}); SemanticContextKind::Super, {});
Builder.setAssociatedDecl(FD); Builder.setAssociatedDecl(FD);
addValueOverride(FD, Reason, Builder, hasFuncIntroducer); addValueOverride(FD, Reason, dynamicLookupInfo, Builder, hasFuncIntroducer);
Builder.addBraceStmtWithCursor(); 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 // Overrides cannot use 'let', but if the 'override' keyword is specified
// then the intention is clear, so provide the results anyway. The compiler // then the intention is clear, so provide the results anyway. The compiler
// can then provide an error telling you to use 'var' instead. // can then provide an error telling you to use 'var' instead.
@@ -4189,19 +4230,21 @@ public:
Sink, CodeCompletionResult::ResultKind::Declaration, Sink, CodeCompletionResult::ResultKind::Declaration,
SemanticContextKind::Super, {}); SemanticContextKind::Super, {});
Builder.setAssociatedDecl(VD); 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( CodeCompletionResultBuilder Builder(
Sink, CodeCompletionResult::ResultKind::Declaration, Sink, CodeCompletionResult::ResultKind::Declaration,
SemanticContextKind::Super, {}); SemanticContextKind::Super, {});
Builder.setAssociatedDecl(SD); Builder.setAssociatedDecl(SD);
addValueOverride(SD, Reason, Builder, false); addValueOverride(SD, Reason, dynamicLookupInfo, Builder, false);
Builder.addBraceStmtWithCursor(); Builder.addBraceStmtWithCursor();
} }
void addTypeAlias(const AssociatedTypeDecl *ATD, DeclVisibilityKind Reason) { void addTypeAlias(const AssociatedTypeDecl *ATD, DeclVisibilityKind Reason,
DynamicLookupInfo dynamicLookupInfo) {
CodeCompletionResultBuilder Builder(Sink, CodeCompletionResultBuilder Builder(Sink,
CodeCompletionResult::ResultKind::Declaration, CodeCompletionResult::ResultKind::Declaration,
SemanticContextKind::Super, {}); SemanticContextKind::Super, {});
@@ -4215,7 +4258,8 @@ public:
Builder.addSimpleNamedParameter("Type"); Builder.addSimpleNamedParameter("Type");
} }
void addConstructor(const ConstructorDecl *CD, DeclVisibilityKind Reason) { void addConstructor(const ConstructorDecl *CD, DeclVisibilityKind Reason,
DynamicLookupInfo dynamicLookupInfo) {
CodeCompletionResultBuilder Builder( CodeCompletionResultBuilder Builder(
Sink, Sink,
CodeCompletionResult::ResultKind::Declaration, CodeCompletionResult::ResultKind::Declaration,
@@ -4257,7 +4301,8 @@ public:
} }
// Implement swift::VisibleDeclConsumer. // Implement swift::VisibleDeclConsumer.
void foundDecl(ValueDecl *D, DeclVisibilityKind Reason) override { void foundDecl(ValueDecl *D, DeclVisibilityKind Reason,
DynamicLookupInfo dynamicLookupInfo) override {
if (Reason == DeclVisibilityKind::MemberOfCurrentNominal) if (Reason == DeclVisibilityKind::MemberOfCurrentNominal)
return; return;
@@ -4295,19 +4340,19 @@ public:
return; return;
if (hasFuncIntroducer || (!hasIntroducer && !hasInitializerModifier)) if (hasFuncIntroducer || (!hasIntroducer && !hasInitializerModifier))
addMethodOverride(FD, Reason); addMethodOverride(FD, Reason, dynamicLookupInfo);
return; return;
} }
if (auto *VD = dyn_cast<VarDecl>(D)) { if (auto *VD = dyn_cast<VarDecl>(D)) {
if (hasVarIntroducer || (!hasIntroducer && !hasInitializerModifier)) if (hasVarIntroducer || (!hasIntroducer && !hasInitializerModifier))
addVarOverride(VD, Reason); addVarOverride(VD, Reason, dynamicLookupInfo);
return; return;
} }
if (auto *SD = dyn_cast<SubscriptDecl>(D)) { if (auto *SD = dyn_cast<SubscriptDecl>(D)) {
if (!hasIntroducer && !hasInitializerModifier) if (!hasIntroducer && !hasInitializerModifier)
addSubscriptOverride(SD, Reason); addSubscriptOverride(SD, Reason, dynamicLookupInfo);
} }
if (auto *CD = dyn_cast<ConstructorDecl>(D)) { if (auto *CD = dyn_cast<ConstructorDecl>(D)) {
@@ -4317,7 +4362,7 @@ public:
hasStaticOrClass) hasStaticOrClass)
return; return;
if (CD->isRequired() || CD->isDesignatedInit()) if (CD->isRequired() || CD->isDesignatedInit())
addConstructor(CD, Reason); addConstructor(CD, Reason, dynamicLookupInfo);
return; return;
} }
} }
@@ -4340,7 +4385,7 @@ public:
if (Constructor->hasStubImplementation()) if (Constructor->hasStubImplementation())
continue; continue;
if (Constructor->isDesignatedInit()) if (Constructor->isDesignatedInit())
addConstructor(Constructor, DeclVisibilityKind::MemberOfSuper); addConstructor(Constructor, DeclVisibilityKind::MemberOfSuper, {});
} }
} }
@@ -4362,8 +4407,10 @@ public:
if (!Conformance->hasTypeWitness(ATD) || if (!Conformance->hasTypeWitness(ATD) ||
ATD->hasDefaultDefinitionType()) ATD->hasDefaultDefinitionType())
continue; continue;
addTypeAlias(ATD, addTypeAlias(
DeclVisibilityKind::MemberOfProtocolImplementedByCurrentNominal); ATD,
DeclVisibilityKind::MemberOfProtocolImplementedByCurrentNominal,
{});
} }
} }
} }
@@ -5423,8 +5470,8 @@ void CodeCompletionCallbacksImpl::doneParsing() {
if (auto GT = ParsedTypeLoc.getType()->getAnyGeneric()) { if (auto GT = ParsedTypeLoc.getType()->getAnyGeneric()) {
if (auto Params = GT->getGenericParams()) { if (auto Params = GT->getGenericParams()) {
for (auto GP : Params->getParams()) { for (auto GP : Params->getParams()) {
Lookup.addGenericTypeParamRef(GP, Lookup.addGenericTypeParamRef(
DeclVisibilityKind::GenericParameter); GP, DeclVisibilityKind::GenericParameter, {});
} }
} }
} }

View File

@@ -147,7 +147,8 @@ void ConformingMethodListCallbacks::getMatchingMethods(
: CurModule(DC->getParentModule()), T(T), ExpectedTypes(expectedTypes), : CurModule(DC->getParentModule()), T(T), ExpectedTypes(expectedTypes),
Result(result) {} Result(result) {}
void foundDecl(ValueDecl *VD, DeclVisibilityKind reason) { void foundDecl(ValueDecl *VD, DeclVisibilityKind reason,
DynamicLookupInfo) {
if (isMatchingMethod(VD) && !VD->shouldHideFromEditor()) if (isMatchingMethod(VD) && !VD->shouldHideFromEditor())
Result.push_back(VD); Result.push_back(VD);
} }

View File

@@ -163,7 +163,8 @@ void ContextInfoCallbacks::getImplicitMembers(
: DC(DC), TypeResolver(DC->getASTContext().getLazyResolver()), : DC(DC), TypeResolver(DC->getASTContext().getLazyResolver()),
CurModule(DC->getParentModule()), T(T), Result(Result) {} 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()) if (canBeImplictMember(VD) && !VD->shouldHideFromEditor())
Result.push_back(VD); Result.push_back(VD);
} }

View File

@@ -274,7 +274,8 @@ static void doDynamicLookup(VisibleDeclConsumer &Consumer,
: ChainedConsumer(ChainedConsumer), LS(LS), CurrDC(CurrDC), : ChainedConsumer(ChainedConsumer), LS(LS), CurrDC(CurrDC),
TypeResolver(TypeResolver) {} 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 // If the declaration has an override, name lookup will also have found
// the overridden method. Skip this declaration, because we prefer the // the overridden method. Skip this declaration, because we prefer the
// overridden method. // overridden method.
@@ -362,7 +363,8 @@ static void doDynamicLookup(VisibleDeclConsumer &Consumer,
} }
if (isDeclVisibleInLookupMode(D, LS, CurrDC, TypeResolver)) 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, LookupState LS, DeclVisibilityKind reason, LazyResolver *typeResolver,
GenericSignatureBuilder *GSB, VisitedSet &visited) { GenericSignatureBuilder *GSB, VisitedSet &visited) {
assert(hasDynamicMemberLookupAttribute(baseType)); if (!hasDynamicMemberLookupAttribute(baseType))
return;
auto &ctx = dc->getASTContext(); auto &ctx = dc->getASTContext();
// Lookup the `subscript(dynamicMember:)` methods in this type. // 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 { namespace {
struct FoundDeclTy { struct FoundDeclTy {
ValueDecl *D; ValueDecl *D;
DeclVisibilityKind Reason; DeclVisibilityKind Reason;
DynamicLookupInfo dynamicLookupInfo;
FoundDeclTy(ValueDecl *D, DeclVisibilityKind Reason) FoundDeclTy(ValueDecl *D, DeclVisibilityKind Reason,
: D(D), Reason(Reason) {} DynamicLookupInfo dynamicLookupInfo)
: D(D), Reason(Reason), dynamicLookupInfo(dynamicLookupInfo) {}
friend bool operator==(const FoundDeclTy &LHS, const FoundDeclTy &RHS) { friend bool operator==(const FoundDeclTy &LHS, const FoundDeclTy &RHS) {
// If this ever changes - e.g. to include Reason - be sure to also update // If this ever changes - e.g. to include Reason - be sure to also update
@@ -693,12 +714,13 @@ namespace llvm {
template <> struct DenseMapInfo<FoundDeclTy> { template <> struct DenseMapInfo<FoundDeclTy> {
static inline FoundDeclTy getEmptyKey() { static inline FoundDeclTy getEmptyKey() {
return FoundDeclTy{nullptr, DeclVisibilityKind::LocalVariable}; return FoundDeclTy{nullptr, DeclVisibilityKind::LocalVariable, {}};
} }
static inline FoundDeclTy getTombstoneKey() { static inline FoundDeclTy getTombstoneKey() {
return FoundDeclTy{reinterpret_cast<ValueDecl *>(0x1), return FoundDeclTy{reinterpret_cast<ValueDecl *>(0x1),
DeclVisibilityKind::LocalVariable}; DeclVisibilityKind::LocalVariable,
{}};
} }
static unsigned getHashValue(const FoundDeclTy &Val) { static unsigned getHashValue(const FoundDeclTy &Val) {
@@ -749,7 +771,8 @@ public:
assert(DC && BaseTy); assert(DC && BaseTy);
} }
void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) override { void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason,
DynamicLookupInfo dynamicLookupInfo) override {
if (!AllFoundDecls.insert(VD).second) if (!AllFoundDecls.insert(VD).second)
return; return;
@@ -758,7 +781,7 @@ public:
if (!isa<AbstractFunctionDecl>(VD) && if (!isa<AbstractFunctionDecl>(VD) &&
!isa<AbstractStorageDecl>(VD) && !isa<AbstractStorageDecl>(VD) &&
!isa<AssociatedTypeDecl>(VD)) { !isa<AssociatedTypeDecl>(VD)) {
DeclsToReport.insert(FoundDeclTy(VD, Reason)); DeclsToReport.insert(FoundDeclTy(VD, Reason, dynamicLookupInfo));
return; return;
} }
@@ -768,7 +791,7 @@ public:
if (VD->isInvalid()) { if (VD->isInvalid()) {
FoundDecls[VD->getBaseName()].insert(VD); FoundDecls[VD->getBaseName()].insert(VD);
DeclsToReport.insert(FoundDeclTy(VD, Reason)); DeclsToReport.insert(FoundDeclTy(VD, Reason, dynamicLookupInfo));
return; return;
} }
auto &PossiblyConflicting = FoundDecls[VD->getBaseName()]; auto &PossiblyConflicting = FoundDecls[VD->getBaseName()];
@@ -784,11 +807,11 @@ public:
PossiblyConflicting.insert(VD); PossiblyConflicting.insert(VD);
bool Erased = DeclsToReport.remove( bool Erased = DeclsToReport.remove(
FoundDeclTy(CurrentVD, DeclVisibilityKind::LocalVariable)); FoundDeclTy(CurrentVD, DeclVisibilityKind::LocalVariable, {}));
assert(Erased); assert(Erased);
(void)Erased; (void)Erased;
DeclsToReport.insert(FoundDeclTy(VD, Reason)); DeclsToReport.insert(FoundDeclTy(VD, Reason, dynamicLookupInfo));
return; return;
} }
CurrentVD = CurrentVD->getOverriddenDecl(); CurrentVD = CurrentVD->getOverriddenDecl();
@@ -816,7 +839,7 @@ public:
// Hack; we shouldn't be filtering at this level anyway. // Hack; we shouldn't be filtering at this level anyway.
if (!VD->hasInterfaceType()) { if (!VD->hasInterfaceType()) {
FoundDecls[VD->getBaseName()].insert(VD); FoundDecls[VD->getBaseName()].insert(VD);
DeclsToReport.insert(FoundDeclTy(VD, Reason)); DeclsToReport.insert(FoundDeclTy(VD, Reason, dynamicLookupInfo));
return; return;
} }
@@ -858,32 +881,49 @@ public:
PossiblyConflicting.insert(VD); PossiblyConflicting.insert(VD);
bool Erased = DeclsToReport.remove( bool Erased = DeclsToReport.remove(
FoundDeclTy(OtherVD, DeclVisibilityKind::LocalVariable)); FoundDeclTy(OtherVD, DeclVisibilityKind::LocalVariable, {}));
assert(Erased); assert(Erased);
(void)Erased; (void)Erased;
DeclsToReport.insert(FoundDeclTy(VD, Reason)); DeclsToReport.insert(FoundDeclTy(VD, Reason, dynamicLookupInfo));
} }
return; return;
} }
} }
PossiblyConflicting.insert(VD); 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; VisibleDeclConsumer &consumer;
llvm::DenseSet<DeclBaseName> &seen; std::function<bool(DeclBaseName)> seenBaseName;
ShadowedKeyPathMembers(VisibleDeclConsumer &consumer, llvm::DenseSet<DeclBaseName> &knownMembers) : consumer(consumer), seen(knownMembers) {}
void foundDecl(ValueDecl *VD, DeclVisibilityKind reason) override { KeyPathDynamicMemberConsumer(VisibleDeclConsumer &consumer,
std::function<bool(DeclBaseName)> 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<AbstractStorageDecl>(VD))
return;
assert(dynamicLookupInfo.getKind() !=
DynamicLookupInfo::KeyPathDynamicMember);
// Dynamic lookup members are only visible if they are not shadowed by // Dynamic lookup members are only visible if they are not shadowed by
// non-dynamic members. // non-dynamic members.
if (seen.count(VD->getBaseName()) == 0) if (isa<SubscriptDecl>(VD) || !seenBaseName(VD->getBaseName()))
consumer.foundDecl(VD, reason); consumer.foundDecl(VD, DeclVisibilityKind::DynamicLookup,
{nullptr, Type(), reason});
} }
}; };
} // end anonymous namespace } // end anonymous namespace
/// Enumerate all members in \c BaseTy (including members of extensions, /// Enumerate all members in \c BaseTy (including members of extensions,
@@ -897,23 +937,21 @@ static void lookupVisibleMemberDecls(
LookupState LS, DeclVisibilityKind Reason, LazyResolver *TypeResolver, LookupState LS, DeclVisibilityKind Reason, LazyResolver *TypeResolver,
GenericSignatureBuilder *GSB) { GenericSignatureBuilder *GSB) {
OverrideFilteringConsumer overrideConsumer(BaseTy, CurrDC, TypeResolver); OverrideFilteringConsumer overrideConsumer(BaseTy, CurrDC, TypeResolver);
KeyPathDynamicMemberConsumer dynamicConsumer(
overrideConsumer,
[&](DeclBaseName name) { return overrideConsumer.seenBaseName(name); });
VisitedSet Visited; VisitedSet Visited;
lookupVisibleMemberDeclsImpl(BaseTy, overrideConsumer, CurrDC, LS, Reason, lookupVisibleMemberDeclsImpl(BaseTy, overrideConsumer, CurrDC, LS, Reason,
TypeResolver, GSB, Visited); TypeResolver, GSB, Visited);
if (hasDynamicMemberLookupAttribute(BaseTy)) { lookupVisibleDynamicMemberLookupDecls(BaseTy, dynamicConsumer, CurrDC, LS,
llvm::DenseSet<DeclBaseName> knownMembers; Reason, TypeResolver, GSB, Visited);
for (auto &kv : overrideConsumer.FoundDecls) {
knownMembers.insert(kv.first);
}
ShadowedKeyPathMembers dynamicConsumer(overrideConsumer, knownMembers);
lookupVisibleDynamicMemberLookupDecls(BaseTy, dynamicConsumer, CurrDC, LS,
Reason, TypeResolver, GSB, Visited);
}
// Report the declarations we found to the real consumer. // Report the declarations we found to the real consumer.
for (const auto &DeclAndReason : overrideConsumer.DeclsToReport) 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, static void lookupVisibleDeclsImpl(VisibleDeclConsumer &Consumer,
@@ -1113,9 +1151,10 @@ void swift::lookupVisibleDecls(VisibleDeclConsumer &Consumer,
VisibleDeclConsumer &Consumer) VisibleDeclConsumer &Consumer)
: SM(SM), Loc(Loc), Consumer(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)) if (isUsableValue(VD, Reason))
Consumer.foundDecl(VD, Reason); Consumer.foundDecl(VD, Reason, dynamicLookupInfo);
} }
} LocalConsumer(DC->getASTContext().SourceMgr, Loc, Consumer); } LocalConsumer(DC->getASTContext().SourceMgr, Loc, Consumer);

View File

@@ -2086,7 +2086,8 @@ void ModuleFile::lookupClassMembers(ModuleDecl::AccessPathTy accessPath,
dc = dc->getParent(); dc = dc->getParent();
if (auto nominal = dc->getSelfNominalTypeDecl()) if (auto nominal = dc->getSelfNominalTypeDecl())
if (nominal->getName() == accessPath.front().first) if (nominal->getName() == accessPath.front().first)
consumer.foundDecl(vd, DeclVisibilityKind::DynamicLookup); consumer.foundDecl(vd, DeclVisibilityKind::DynamicLookup,
DynamicLookupInfo::AnyObject);
} }
} }
return; return;
@@ -2095,7 +2096,8 @@ void ModuleFile::lookupClassMembers(ModuleDecl::AccessPathTy accessPath,
for (const auto &list : ClassMembersForDynamicLookup->data()) { for (const auto &list : ClassMembersForDynamicLookup->data()) {
for (auto item : list) for (auto item : list)
consumer.foundDecl(cast<ValueDecl>(getDecl(item.second)), consumer.foundDecl(cast<ValueDecl>(getDecl(item.second)),
DeclVisibilityKind::DynamicLookup); DeclVisibilityKind::DynamicLookup,
DynamicLookupInfo::AnyObject);
} }
} }

View File

@@ -1613,7 +1613,8 @@ void SwiftDeclCollector::lookupVisibleDecls(ArrayRef<ModuleDecl *> Modules) {
continue; continue;
KnownDecls.insert(D); KnownDecls.insert(D);
if (auto VD = dyn_cast<ValueDecl>(D)) if (auto VD = dyn_cast<ValueDecl>(D))
foundDecl(VD, DeclVisibilityKind::DynamicLookup); foundDecl(VD, DeclVisibilityKind::DynamicLookup,
DynamicLookupInfo::AnyObject);
else else
processDecl(D); 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()) { if (VD->getClangMacro()) {
// Collect macros, we will sort them afterwards. // Collect macros, we will sort them afterwards.
ClangMacros.push_back(VD); ClangMacros.push_back(VD);

View File

@@ -690,7 +690,8 @@ public:
std::vector<SDKNode*> createParameterNodes(ParameterList *PL); std::vector<SDKNode*> createParameterNodes(ParameterList *PL);
SDKNode *constructTypeNode(Type T, TypeInitInfo Info = TypeInitInfo()); SDKNode *constructTypeNode(Type T, TypeInitInfo Info = TypeInitInfo());
void processValueDecl(ValueDecl *VD); void processValueDecl(ValueDecl *VD);
void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) override; void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason,
DynamicLookupInfo dynamicLookupInfo = {}) override;
void processDecl(Decl *D); void processDecl(Decl *D);
public: public:
void lookupVisibleDecls(ArrayRef<ModuleDecl *> Modules); void lookupVisibleDecls(ArrayRef<ModuleDecl *> Modules);