Skip to content

Commit a9ce2ba

Browse files
authored
Merge pull request swiftlang#28624 from CodaFi/heres-looking-up-you-kid
[NFC] Pull Semantic Member Synthesis into TypeChecker's Lookup Entrypoints
2 parents 73bb080 + 4d0dbe6 commit a9ce2ba

File tree

7 files changed

+86
-50
lines changed

7 files changed

+86
-50
lines changed

include/swift/Sema/IDETypeChecking.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ namespace swift {
3535
class Expr;
3636
class ExtensionDecl;
3737
class FunctionType;
38+
class LookupResult;
3839
class NominalTypeDecl;
3940
class PatternBindingDecl;
4041
class ProtocolDecl;
@@ -137,6 +138,9 @@ namespace swift {
137138
/// \returns true on success, false on error.
138139
bool typeCheckTopLevelCodeDecl(TopLevelCodeDecl *TLCD);
139140

141+
LookupResult
142+
lookupSemanticMember(DeclContext *DC, Type ty, DeclName name);
143+
140144
struct ExtensionInfo {
141145
// The extension with the declarations to apply.
142146
ExtensionDecl *Ext;

lib/AST/NameLookup.cpp

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1579,34 +1579,6 @@ bool DeclContext::lookupQualified(Type type,
15791579
return lookupQualified(nominalTypesToLookInto, member, options, decls);
15801580
}
15811581

1582-
static void installPropertyWrapperMembersIfNeeded(NominalTypeDecl *target,
1583-
DeclName member) {
1584-
auto &Context = target->getASTContext();
1585-
auto baseName = member.getBaseName();
1586-
if (!member.isSimpleName() || baseName.isSpecial())
1587-
return;
1588-
1589-
if ((!baseName.getIdentifier().str().startswith("$") &&
1590-
!baseName.getIdentifier().str().startswith("_")) ||
1591-
baseName.getIdentifier().str().size() <= 1) {
1592-
return;
1593-
}
1594-
1595-
// $- and _-prefixed variables can be generated by properties that have
1596-
// attached property wrappers.
1597-
auto originalPropertyName =
1598-
Context.getIdentifier(baseName.getIdentifier().str().substr(1));
1599-
for (auto member : target->lookupDirect(originalPropertyName)) {
1600-
if (auto var = dyn_cast<VarDecl>(member)) {
1601-
if (var->hasAttachedPropertyWrapper()) {
1602-
auto sourceFile = var->getDeclContext()->getParentSourceFile();
1603-
if (sourceFile && sourceFile->Kind != SourceFileKind::Interface)
1604-
(void)var->getPropertyWrapperBackingProperty();
1605-
}
1606-
}
1607-
}
1608-
}
1609-
16101582
bool DeclContext::lookupQualified(ArrayRef<NominalTypeDecl *> typeDecls,
16111583
DeclName member,
16121584
NLOptions options,
@@ -1650,7 +1622,6 @@ bool DeclContext::lookupQualified(ArrayRef<NominalTypeDecl *> typeDecls,
16501622

16511623
// Visit all of the nominal types we know about, discovering any others
16521624
// we need along the way.
1653-
auto &ctx = getASTContext();
16541625
bool wantProtocolMembers = (options & NL_ProtocolMembers);
16551626
while (!stack.empty()) {
16561627
auto current = stack.back();
@@ -1659,12 +1630,6 @@ bool DeclContext::lookupQualified(ArrayRef<NominalTypeDecl *> typeDecls,
16591630
if (tracker)
16601631
tracker->addUsedMember({current, member.getBaseName()},isLookupCascading);
16611632

1662-
// Make sure we've resolved implicit members, if we need them.
1663-
if (ctx.areSemanticQueriesEnabled()) {
1664-
current->synthesizeSemanticMembersIfNeeded(member);
1665-
installPropertyWrapperMembersIfNeeded(current, member);
1666-
}
1667-
16681633
// Look for results within the current nominal type and its extensions.
16691634
bool currentIsProtocol = isa<ProtocolDecl>(current);
16701635
auto flags = OptionSet<NominalTypeDecl::LookupDirectFlags>();

lib/IDE/CodeCompletion.cpp

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2739,22 +2739,21 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
27392739
return;
27402740

27412741
assert(CurrDeclContext);
2742-
SmallVector<ValueDecl *, 16> initializers;
2743-
if (CurrDeclContext->lookupQualified(type, DeclBaseName::createConstructor(),
2744-
NL_QualifiedDefault,
2745-
initializers)) {
2746-
for (auto *init : initializers) {
2747-
if (init->shouldHideFromEditor())
2748-
continue;
2749-
if (IsUnresolvedMember &&
2750-
cast<ConstructorDecl>(init)->isFailable() &&
2751-
!cast<ConstructorDecl>(init)->isImplicitlyUnwrappedOptional()) {
2752-
continue;
2753-
}
2754-
addConstructorCall(cast<ConstructorDecl>(init), Reason,
2755-
dynamicLookupInfo, type, None,
2756-
/*IsOnType=*/true, name);
2742+
2743+
auto results =
2744+
swift::lookupSemanticMember(const_cast<DeclContext *>(CurrDeclContext),
2745+
type, DeclBaseName::createConstructor());
2746+
for (const auto &entry : results.allResults()) {
2747+
auto *init = cast<ConstructorDecl>(entry.getValueDecl());
2748+
if (init->shouldHideFromEditor())
2749+
continue;
2750+
if (IsUnresolvedMember && init->isFailable() &&
2751+
!init->isImplicitlyUnwrappedOptional()) {
2752+
continue;
27572753
}
2754+
addConstructorCall(cast<ConstructorDecl>(init), Reason,
2755+
dynamicLookupInfo, type, None,
2756+
/*IsOnType=*/true, name);
27582757
}
27592758
}
27602759

lib/Sema/TypeCheckDeclOverride.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,12 @@ SmallVector<OverrideMatch, 2> OverrideMatcher::match(
739739
if (members.empty() || name != membersName) {
740740
membersName = name;
741741
members.clear();
742+
// FIXME: This suggests we need to use TypeChecker's high-level lookup
743+
// entrypoints. But first we need one that supports additive qualified
744+
// lookup.
745+
for (auto *ctx : superContexts) {
746+
ctx->synthesizeSemanticMembersIfNeeded(membersName);
747+
}
742748
dc->lookupQualified(superContexts, membersName,
743749
NL_QualifiedDefault, members);
744750
}

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,12 @@ static void checkInheritanceClause(
333333
}
334334
}
335335

336+
static void installCodingKeysIfNecessary(NominalTypeDecl *NTD) {
337+
auto req =
338+
ResolveImplicitMemberRequest{NTD, ImplicitMemberAction::ResolveCodingKeys};
339+
(void)evaluateOrDefault(NTD->getASTContext().evaluator, req, false);
340+
}
341+
336342
// Check for static properties that produce empty option sets
337343
// using a rawValue initializer with a value of '0'
338344
static void checkForEmptyOptionSet(const VarDecl *VD) {
@@ -1666,6 +1672,8 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
16661672

16671673
TypeChecker::addImplicitConstructors(SD);
16681674

1675+
installCodingKeysIfNecessary(SD);
1676+
16691677
for (Decl *Member : SD->getMembers())
16701678
visit(Member);
16711679

lib/Sema/TypeCheckNameLookup.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "swift/AST/NameLookup.h"
2323
#include "swift/AST/NameLookupRequests.h"
2424
#include "swift/AST/ProtocolConformance.h"
25+
#include "swift/AST/SourceFile.h"
2526
#include "swift/Basic/TopCollection.h"
2627
#include <algorithm>
2728

@@ -223,11 +224,47 @@ convertToUnqualifiedLookupOptions(NameLookupOptions options) {
223224
return newOptions;
224225
}
225226

227+
static void installPropertyWrapperMembersIfNeeded(NominalTypeDecl *target,
228+
DeclName member) {
229+
if (!target) return;
230+
231+
auto &Context = target->getASTContext();
232+
auto baseName = member.getBaseName();
233+
if (!member.isSimpleName() || baseName.isSpecial())
234+
return;
235+
236+
if ((!baseName.getIdentifier().str().startswith("$") &&
237+
!baseName.getIdentifier().str().startswith("_")) ||
238+
baseName.getIdentifier().str().size() <= 1) {
239+
return;
240+
}
241+
242+
// $- and _-prefixed variables can be generated by properties that have
243+
// attached property wrappers.
244+
auto originalPropertyName =
245+
Context.getIdentifier(baseName.getIdentifier().str().substr(1));
246+
for (auto member : target->lookupDirect(originalPropertyName)) {
247+
if (auto var = dyn_cast<VarDecl>(member)) {
248+
if (var->hasAttachedPropertyWrapper()) {
249+
auto sourceFile = var->getDeclContext()->getParentSourceFile();
250+
if (sourceFile && sourceFile->Kind != SourceFileKind::Interface)
251+
(void)var->getPropertyWrapperBackingProperty();
252+
}
253+
}
254+
}
255+
}
256+
226257
LookupResult TypeChecker::lookupUnqualified(DeclContext *dc, DeclName name,
227258
SourceLoc loc,
228259
NameLookupOptions options) {
229260
auto ulOptions = convertToUnqualifiedLookupOptions(options);
230261

262+
// Make sure we've resolved implicit members, if we need them.
263+
if (auto *current = dc->getInnermostTypeContext()) {
264+
installPropertyWrapperMembersIfNeeded(current->getSelfNominalTypeDecl(),
265+
name);
266+
}
267+
231268
auto &ctx = dc->getASTContext();
232269
auto descriptor = UnqualifiedLookupDescriptor(name, dc, loc, ulOptions);
233270
auto lookup = evaluateOrDefault(ctx.evaluator,
@@ -311,6 +348,12 @@ LookupResult TypeChecker::lookupMember(DeclContext *dc,
311348
subOptions &= ~NL_RemoveOverridden;
312349
subOptions &= ~NL_RemoveNonVisible;
313350

351+
// Make sure we've resolved implicit members, if we need them.
352+
if (auto *current = type->getAnyNominal()) {
353+
current->synthesizeSemanticMembersIfNeeded(name);
354+
installPropertyWrapperMembersIfNeeded(current, name);
355+
}
356+
314357
LookupResultBuilder builder(result, dc, options);
315358
SmallVector<ValueDecl *, 4> lookupResults;
316359
dc->lookupQualified(type, name, subOptions, lookupResults);
@@ -385,6 +428,12 @@ LookupTypeResult TypeChecker::lookupMemberType(DeclContext *dc,
385428
if (options.contains(NameLookupFlags::IgnoreAccessControl))
386429
subOptions |= NL_IgnoreAccessControl;
387430

431+
// Make sure we've resolved implicit members, if we need them.
432+
if (auto *current = type->getAnyNominal()) {
433+
current->synthesizeSemanticMembersIfNeeded(name);
434+
installPropertyWrapperMembersIfNeeded(current, name);
435+
}
436+
388437
if (!dc->lookupQualified(type, name, subOptions, decls))
389438
return result;
390439

lib/Sema/TypeChecker.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,3 +712,8 @@ TypeChecker::getDeclTypeCheckingSemantics(ValueDecl *decl) {
712712
void swift::bindExtensions(SourceFile &SF) {
713713
::bindExtensions(SF);
714714
}
715+
716+
LookupResult
717+
swift::lookupSemanticMember(DeclContext *DC, Type ty, DeclName name) {
718+
return TypeChecker::lookupMember(DC, ty, name, None);
719+
}

0 commit comments

Comments
 (0)