|
15 | 15 | //
|
16 | 16 | //===----------------------------------------------------------------------===//
|
17 | 17 |
|
| 18 | +#include "TypeChecker.h" |
18 | 19 | #include "swift/AST/ASTContext.h"
|
19 | 20 | #include "swift/AST/GenericSignature.h"
|
20 | 21 | #include "swift/AST/GenericSignatureBuilder.h"
|
|
24 | 25 | #include "swift/AST/ModuleNameLookup.h"
|
25 | 26 | #include "swift/AST/NameLookup.h"
|
26 | 27 | #include "swift/AST/ProtocolConformance.h"
|
| 28 | +#include "swift/AST/PropertyWrappers.h" |
27 | 29 | #include "swift/AST/SourceFile.h"
|
28 | 30 | #include "swift/Basic/SourceManager.h"
|
29 | 31 | #include "swift/Basic/STLExtras.h"
|
@@ -474,6 +476,53 @@ static void
|
474 | 476 | lookupTypeMembers(BaseTy, PT, Consumer, CurrDC, LS, Reason);
|
475 | 477 | }
|
476 | 478 |
|
| 479 | +/// Trigger synthesizing implicit member declarations to make them "visible". |
| 480 | +static void synthesizeMemberDeclsForLookup(NominalTypeDecl *NTD, |
| 481 | + const DeclContext *DC) { |
| 482 | + // Synthesize the memberwise initializer for structs or default initializer |
| 483 | + // for classes. |
| 484 | + if (!NTD->hasInterfaceType()) |
| 485 | + TypeChecker::addImplicitConstructors(NTD); |
| 486 | + |
| 487 | + // Check all conformances to trigger the synthesized decl generation. |
| 488 | + // e.g. init(rawValue:) for RawRepresentable. |
| 489 | + for (auto Conformance : NTD->getAllConformances()) { |
| 490 | + auto Proto = Conformance->getProtocol(); |
| 491 | + if (!Proto->isAccessibleFrom(DC)) |
| 492 | + continue; |
| 493 | + auto NormalConformance = dyn_cast<NormalProtocolConformance>( |
| 494 | + Conformance->getRootConformance()); |
| 495 | + if (!NormalConformance) |
| 496 | + continue; |
| 497 | + for (auto Member : Proto->getMembers()) { |
| 498 | + auto *VD = dyn_cast<ValueDecl>(Member); |
| 499 | + if (!VD || !VD->isProtocolRequirement()) |
| 500 | + continue; |
| 501 | + if (auto *ATD = dyn_cast<AssociatedTypeDecl>(Member)) |
| 502 | + (void)NormalConformance->getTypeWitnessAndDecl(ATD); |
| 503 | + else |
| 504 | + (void)NormalConformance->getWitness(VD); |
| 505 | + } |
| 506 | + } |
| 507 | + |
| 508 | + // Generate '$' and '_' prefixed variables that have attached property |
| 509 | + // wrappers. |
| 510 | + auto synthesizePropertyWrappers = [](IterableDeclContext *IDC) { |
| 511 | + for (auto Member : IDC->getMembers()) { |
| 512 | + if (auto var = dyn_cast<VarDecl>(Member)) { |
| 513 | + if (var->hasAttachedPropertyWrapper()) { |
| 514 | + auto sourceFile = var->getDeclContext()->getParentSourceFile(); |
| 515 | + if (sourceFile && sourceFile->Kind != SourceFileKind::Interface) |
| 516 | + (void)var->getPropertyWrapperBackingPropertyInfo(); |
| 517 | + } |
| 518 | + } |
| 519 | + } |
| 520 | + }; |
| 521 | + synthesizePropertyWrappers(NTD); |
| 522 | + for (auto ED : NTD->getExtensions()) |
| 523 | + synthesizePropertyWrappers(ED); |
| 524 | +} |
| 525 | + |
477 | 526 | static void lookupVisibleMemberDeclsImpl(
|
478 | 527 | Type BaseTy, VisibleDeclConsumer &Consumer, const DeclContext *CurrDC,
|
479 | 528 | LookupState LS, DeclVisibilityKind Reason, GenericSignatureBuilder *GSB,
|
@@ -583,6 +632,8 @@ static void lookupVisibleMemberDeclsImpl(
|
583 | 632 | if (!CurNominal)
|
584 | 633 | break;
|
585 | 634 |
|
| 635 | + synthesizeMemberDeclsForLookup(CurNominal, CurrDC); |
| 636 | + |
586 | 637 | // Look in for members of a nominal type.
|
587 | 638 | lookupTypeMembers(BaseTy, BaseTy, Consumer, CurrDC, LS, Reason);
|
588 | 639 | lookupDeclsFromProtocolsBeingConformedTo(BaseTy, Consumer, LS, CurrDC,
|
|
0 commit comments