Include inner class members in dynamic lookup results.

Per discussion with Doug, there's no reason why this should not work:

  class Outer {
    class Inner {
      func extract() { ... }
    }
  }

  var obj : DynamicLookup = ...
  obj.extract!()

Swift SVN r7763
This commit is contained in:
Jordan Rose
2013-08-29 23:09:33 +00:00
parent 202f65bb41
commit 7f20dfd304
2 changed files with 19 additions and 6 deletions

View File

@@ -167,9 +167,18 @@ void TUModuleCache::populateMemberCache(const TranslationUnit &TU) {
void TUModuleCache::addToMemberCache(ArrayRef<Decl*> decls) { void TUModuleCache::addToMemberCache(ArrayRef<Decl*> decls) {
for (Decl *D : decls) { for (Decl *D : decls) {
auto VD = dyn_cast<ValueDecl>(D); auto VD = dyn_cast<ValueDecl>(D);
if (!VD || !VD->canBeAccessedByDynamicLookup()) if (!VD)
continue; continue;
ClassMembers[VD->getName()].push_back(VD);
if (auto NTD = dyn_cast<NominalTypeDecl>(VD)) {
assert(!VD->canBeAccessedByDynamicLookup() &&
"inner types cannot be accessed by dynamic lookup");
if (isa<ClassDecl>(NTD) || isa<ProtocolDecl>(NTD))
addToMemberCache(NTD->getMembers());
} else if (VD->canBeAccessedByDynamicLookup()) {
ClassMembers[VD->getName()].push_back(VD);
}
} }
} }

View File

@@ -588,8 +588,10 @@ void ModuleFile::lookupClassMember(Module::AccessPathTy accessPath,
if (!accessPath.empty()) { if (!accessPath.empty()) {
for (auto item : *iter) { for (auto item : *iter) {
auto vd = cast<ValueDecl>(getDecl(item.second)); auto vd = cast<ValueDecl>(getDecl(item.second));
Type ty = vd->getDeclContext()->getDeclaredTypeOfContext(); auto dc = vd->getDeclContext();
if (auto nominal = ty->getAnyNominal()) while (!dc->getParent()->isModuleContext())
dc = dc->getParent();
if (auto nominal = dc->getDeclaredTypeInContext()->getAnyNominal())
if (nominal->getName() == accessPath.front().first) if (nominal->getName() == accessPath.front().first)
results.push_back(vd); results.push_back(vd);
} }
@@ -614,8 +616,10 @@ void ModuleFile::lookupClassMembers(Module::AccessPathTy accessPath,
ClassMembersByName->data_end())) { ClassMembersByName->data_end())) {
for (auto item : list) { for (auto item : list) {
auto vd = cast<ValueDecl>(getDecl(item.second)); auto vd = cast<ValueDecl>(getDecl(item.second));
Type ty = vd->getDeclContext()->getDeclaredTypeOfContext(); auto dc = vd->getDeclContext();
if (auto nominal = ty->getAnyNominal()) while (!dc->getParent()->isModuleContext())
dc = dc->getParent();
if (auto nominal = dc->getDeclaredTypeInContext()->getAnyNominal())
if (nominal->getName() == accessPath.front().first) if (nominal->getName() == accessPath.front().first)
consumer.foundDecl(vd); consumer.foundDecl(vd);
} }