mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
More refactoring; allow ConstructorLookup to find constructors in classes.
Swift SVN r2171
This commit is contained in:
@@ -223,177 +223,6 @@ void Module::lookupValue(AccessPathTy AccessPath, Identifier Name,
|
||||
.lookupValue(AccessPath, Name, LookupKind, TU, Result);
|
||||
}
|
||||
|
||||
static void DoGlobalExtensionLookup(Type BaseType, Identifier Name,
|
||||
ArrayRef<ValueDecl*> BaseMembers,
|
||||
Module *CurModule,
|
||||
Module *BaseModule,
|
||||
SmallVectorImpl<ValueDecl*> &Result) {
|
||||
bool CurModuleHasTypeDecl = false;
|
||||
llvm::SmallPtrSet<CanType, 8> CurModuleTypes;
|
||||
|
||||
bool NameBindingLookup = CurModule->ASTStage == Module::Parsed;
|
||||
|
||||
// Find all extensions in this module.
|
||||
for (ExtensionDecl *ED : CurModule->lookupExtensions(BaseType)) {
|
||||
for (Decl *Member : ED->getMembers()) {
|
||||
if (ValueDecl *VD = dyn_cast<ValueDecl>(Member)) {
|
||||
if (VD->getName() == Name) {
|
||||
Result.push_back(VD);
|
||||
if (!NameBindingLookup)
|
||||
CurModuleTypes.insert(VD->getType()->getCanonicalType());
|
||||
CurModuleHasTypeDecl |= isa<MetaTypeType>(VD->getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (BaseModule == CurModule) {
|
||||
for (ValueDecl *VD : BaseMembers) {
|
||||
if (VD->getName() == Name) {
|
||||
Result.push_back(VD);
|
||||
if (!NameBindingLookup)
|
||||
CurModuleTypes.insert(VD->getType()->getCanonicalType());
|
||||
CurModuleHasTypeDecl |= isa<MetaTypeType>(VD->getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The builtin module has no imports.
|
||||
if (isa<BuiltinModule>(CurModule)) return;
|
||||
|
||||
// If we find a type in the current module, don't look into any
|
||||
// imported modules.
|
||||
if (CurModuleHasTypeDecl) return;
|
||||
|
||||
TranslationUnit &TU = *cast<TranslationUnit>(CurModule);
|
||||
|
||||
// Otherwise, check our imported extensions as well.
|
||||
// FIXME: Implement DAG-based shadowing rules.
|
||||
llvm::SmallPtrSet<Module *, 16> Visited;
|
||||
for (auto &ImpEntry : TU.getImportedModules()) {
|
||||
if (!Visited.insert(ImpEntry.second))
|
||||
continue;
|
||||
|
||||
for (ExtensionDecl *ED : ImpEntry.second->lookupExtensions(BaseType)) {
|
||||
for (Decl *Member : ED->getMembers()) {
|
||||
if (ValueDecl *VD = dyn_cast<ValueDecl>(Member)) {
|
||||
if (VD->getName() == Name &&
|
||||
(NameBindingLookup || isa<TypeDecl>(VD) ||
|
||||
!CurModuleTypes.count(VD->getType()->getCanonicalType()))) {
|
||||
Result.push_back(VD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (BaseModule != CurModule) {
|
||||
for (ValueDecl *VD : BaseMembers) {
|
||||
if (VD->getName() == Name &&
|
||||
(NameBindingLookup || isa<TypeDecl>(VD) ||
|
||||
!CurModuleTypes.count(VD->getType()->getCanonicalType()))) {
|
||||
Result.push_back(VD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// lookupGlobalExtensionMethods - Lookup the extensions members for the
|
||||
/// specified BaseType with the specified type, and return them in Result.
|
||||
void Module::lookupMembers(Type BaseType, Identifier Name,
|
||||
SmallVectorImpl<ValueDecl*> &Result) {
|
||||
assert(Result.empty() &&
|
||||
"This expects that the input list is empty, could be generalized");
|
||||
|
||||
TypeDecl *D;
|
||||
ArrayRef<ValueDecl*> BaseMembers;
|
||||
SmallVector<ValueDecl*, 2> BaseMembersStorage;
|
||||
if (StructType *ST = BaseType->getAs<StructType>()) {
|
||||
// FIXME: Refuse to look up "constructors" until we have real constructors.
|
||||
if (ST->getDecl()->getName() == Name)
|
||||
return;
|
||||
|
||||
D = ST->getDecl();
|
||||
for (Decl* Member : ST->getDecl()->getMembers()) {
|
||||
if (ValueDecl *VD = dyn_cast<ValueDecl>(Member))
|
||||
BaseMembersStorage.push_back(VD);
|
||||
}
|
||||
BaseMembers = BaseMembersStorage;
|
||||
} else if (ClassType *CT = BaseType->getAs<ClassType>()) {
|
||||
D = CT->getDecl();
|
||||
for (Decl* Member : CT->getDecl()->getMembers()) {
|
||||
if (ValueDecl *VD = dyn_cast<ValueDecl>(Member))
|
||||
BaseMembersStorage.push_back(VD);
|
||||
}
|
||||
BaseMembers = BaseMembersStorage;
|
||||
} else if (OneOfType *OOT = BaseType->getAs<OneOfType>()) {
|
||||
// FIXME: Refuse to look up "constructors" until we have real constructors.
|
||||
if (OOT->getDecl()->getName() == Name)
|
||||
return;
|
||||
|
||||
D = OOT->getDecl();
|
||||
for (Decl* Member : OOT->getDecl()->getMembers()) {
|
||||
if (ValueDecl *VD = dyn_cast<ValueDecl>(Member))
|
||||
BaseMembersStorage.push_back(VD);
|
||||
}
|
||||
BaseMembers = BaseMembersStorage;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
DeclContext *DC = D->getDeclContext();
|
||||
while (!DC->isModuleContext())
|
||||
DC = DC->getParent();
|
||||
|
||||
DoGlobalExtensionLookup(BaseType, Name, BaseMembers, this, cast<Module>(DC),
|
||||
Result);
|
||||
}
|
||||
|
||||
/// lookupGlobalExtensionMethods - Lookup the extensions members for the
|
||||
/// specified BaseType with the specified type, and return them in Result.
|
||||
void Module::lookupValueConstructors(Type BaseType,
|
||||
SmallVectorImpl<ValueDecl*> &Result) {
|
||||
assert(Result.empty() &&
|
||||
"This expects that the input list is empty, could be generalized");
|
||||
|
||||
TypeDecl *D;
|
||||
Identifier Constructor = Ctx.getIdentifier("constructor");
|
||||
ArrayRef<ValueDecl*> BaseMembers;
|
||||
SmallVector<ValueDecl*, 2> BaseMembersStorage;
|
||||
if (StructType *ST = BaseType->getAs<StructType>()) {
|
||||
D = ST->getDecl();
|
||||
for (Decl* Member : ST->getDecl()->getMembers()) {
|
||||
if (ValueDecl *VD = dyn_cast<ValueDecl>(Member))
|
||||
BaseMembersStorage.push_back(VD);
|
||||
}
|
||||
BaseMembers = BaseMembersStorage;
|
||||
} else if (OneOfType *OOT = BaseType->getAs<OneOfType>()) {
|
||||
D = OOT->getDecl();
|
||||
for (Decl* Member : OOT->getDecl()->getMembers()) {
|
||||
// FIXME: We shouldn't be injecting OneOfElementDecls into the results
|
||||
// like this.
|
||||
if (OneOfElementDecl *OOED = dyn_cast<OneOfElementDecl>(Member))
|
||||
Result.push_back(OOED);
|
||||
else if (ValueDecl *VD = dyn_cast<ValueDecl>(Member))
|
||||
BaseMembersStorage.push_back(VD);
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
DeclContext *DC = D->getDeclContext();
|
||||
if (!DC->isModuleContext()) {
|
||||
for (ValueDecl *VD : BaseMembers) {
|
||||
if (VD->getName() == Constructor)
|
||||
Result.push_back(VD);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
DoGlobalExtensionLookup(BaseType, Constructor, BaseMembers, this,
|
||||
cast<Module>(DC), Result);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// TranslationUnit Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
Reference in New Issue
Block a user