Merge pull request #12837 from DougGregor/clang-name-importer-all-properties-4.0
[4.0] [Clang importer] Move the "all properties" lists into the name importer.
diff --git a/include/swift/AST/ASTContext.h b/include/swift/AST/ASTContext.h
index 1937e57..7cec457 100644
--- a/include/swift/AST/ASTContext.h
+++ b/include/swift/AST/ASTContext.h
@@ -850,15 +850,6 @@
GenericSignature *sig,
ModuleDecl &module);
- /// Retrieve the inherited name set for the given class.
- const InheritedNameSet *getAllPropertyNames(ClassDecl *classDecl,
- bool forInstance);
-
- /// Retrieve the inherited name set for the given Objective-C class.
- const InheritedNameSet *getAllPropertyNames(
- clang::ObjCInterfaceDecl *classDecl,
- bool forInstance);
-
/// Retrieve a generic signature with a single unconstrained type parameter,
/// like `<T>`.
CanGenericSignature getSingleGenericParameterSignature() const;
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 2bb7bb5..292f4d7 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -247,16 +247,6 @@
/// The keys are the generic signature builders in \c GenericSignatureBuilders.
llvm::DenseMap<GenericSignatureBuilder *, GenericEnvironment *>
CanonicalGenericEnvironments;
-
- /// The set of property names that show up in the defining module of a
- /// class.
- llvm::DenseMap<std::pair<const ClassDecl *, char>,
- std::unique_ptr<InheritedNameSet>> AllProperties;
-
- /// The set of property names that show up in the defining module of
- /// an Objective-C class.
- llvm::DenseMap<std::pair<const clang::ObjCInterfaceDecl *, char>,
- std::unique_ptr<InheritedNameSet>> AllPropertiesObjC;
/// The single-parameter generic signature with no constraints, <T>.
CanGenericSignature SingleGenericParameterSignature;
@@ -4154,129 +4144,6 @@
return Type();
}
-const InheritedNameSet *ASTContext::getAllPropertyNames(ClassDecl *classDecl,
- bool forInstance) {
- // If this class was defined in Objective-C, perform the lookup based on
- // the Objective-C class.
- if (auto objcClass = dyn_cast_or_null<clang::ObjCInterfaceDecl>(
- classDecl->getClangDecl())) {
- return getAllPropertyNames(
- const_cast<clang::ObjCInterfaceDecl *>(objcClass),
- forInstance);
- }
-
- // If we already have this information, return it.
- auto known = Impl.AllProperties.find({classDecl, forInstance});
- if (known != Impl.AllProperties.end()) return known->second.get();
-
- // Otherwise, get information from our superclass first.
- if (auto resolver = getLazyResolver())
- resolver->resolveSuperclass(classDecl);
-
- const InheritedNameSet *parentSet = nullptr;
- if (auto superclass = classDecl->getSuperclass()) {
- if (auto superclassDecl = superclass->getClassOrBoundGenericClass()) {
- parentSet = getAllPropertyNames(superclassDecl, forInstance);
- }
- }
-
- // Create the set of properties.
- known = Impl.AllProperties.insert(
- { std::pair<const ClassDecl *, char>(classDecl, forInstance),
- llvm::make_unique<InheritedNameSet>(parentSet) }).first;
-
- // Local function to add properties from the given set.
- auto addProperties = [&](DeclRange members) {
- for (auto member : members) {
- auto var = dyn_cast<VarDecl>(member);
- if (!var || var->getName().empty()) continue;
- if (var->isInstanceMember() != forInstance) continue;
-
- known->second->add(var->getName().str());
- }
- };
-
- // Collect property names from the class.
- addProperties(classDecl->getMembers());
-
- // Collect property names from all extensions in the same module as the class.
- auto module = classDecl->getParentModule();
- for (auto ext : classDecl->getExtensions()) {
- if (ext->getParentModule() != module) continue;
- addProperties(ext->getMembers());
- }
-
- return known->second.get();
-}
-
-const InheritedNameSet *ASTContext::getAllPropertyNames(
- clang::ObjCInterfaceDecl *classDecl,
- bool forInstance) {
- classDecl = classDecl->getCanonicalDecl();
-
- // If we already have this information, return it.
- auto known = Impl.AllPropertiesObjC.find({classDecl, forInstance});
- if (known != Impl.AllPropertiesObjC.end()) return known->second.get();
-
- // Otherwise, get information from our superclass first.
- const InheritedNameSet *parentSet = nullptr;
- if (auto superclassDecl = classDecl->getSuperClass()) {
- parentSet = getAllPropertyNames(superclassDecl, forInstance);
- }
-
- // Create the set of properties.
- known = Impl.AllPropertiesObjC.insert(
- { std::pair<const clang::ObjCInterfaceDecl *, char>(classDecl,
- forInstance),
- llvm::make_unique<InheritedNameSet>(parentSet) }).first;
-
- // Local function to add properties from the given set.
- auto addProperties = [&](clang::DeclContext::decl_range members) {
- for (auto member : members) {
- // Add Objective-C property names.
- if (auto property = dyn_cast<clang::ObjCPropertyDecl>(member)) {
- if (forInstance)
- known->second->add(property->getName());
- continue;
- }
-
- // Add no-parameter, non-void method names.
- if (auto method = dyn_cast<clang::ObjCMethodDecl>(member)) {
- if (method->getSelector().isUnarySelector() &&
- !method->getReturnType()->isVoidType() &&
- !method->hasRelatedResultType() &&
- method->isInstanceMethod() == forInstance) {
- known->second->add(method->getSelector().getNameForSlot(0));
- continue;
- }
- }
- }
- };
-
- // Dig out the class definition.
- auto classDef = classDecl->getDefinition();
- if (!classDef) return known->second.get();
-
- // Collect property names from the class definition.
- addProperties(classDef->decls());
-
- // Dig out the module that owns the class definition.
- auto module = classDef->getImportedOwningModule();
- if (module) module = module->getTopLevelModule();
-
- // Collect property names from all categories and extensions in the same
- // module as the class.
- for (auto category : classDef->known_categories()) {
- auto categoryModule = category->getImportedOwningModule();
- if (categoryModule) categoryModule = categoryModule->getTopLevelModule();
- if (module != categoryModule) continue;
-
- addProperties(category->decls());
- }
-
- return known->second.get();
-}
-
CanGenericSignature ASTContext::getSingleGenericParameterSignature() const {
if (auto theSig = Impl.SingleGenericParameterSignature)
return theSig;
diff --git a/lib/ClangImporter/ImportName.cpp b/lib/ClangImporter/ImportName.cpp
index 4506c95..eb00e0b 100644
--- a/lib/ClangImporter/ImportName.cpp
+++ b/lib/ClangImporter/ImportName.cpp
@@ -783,7 +783,7 @@
if (!contextType.isNull()) {
if (auto objcPtrType = contextType->getAsObjCInterfacePointerType())
if (auto objcClassDecl = objcPtrType->getInterfaceDecl())
- allPropertyNames = nameImporter.getContext().getAllPropertyNames(
+ allPropertyNames = nameImporter.getAllPropertyNames(
objcClassDecl, isInstanceMethod);
}
@@ -1596,8 +1596,7 @@
if (auto objcPtrType = contextType->getAsObjCInterfacePointerType())
if (auto objcClassDecl = objcPtrType->getInterfaceDecl())
allPropertyNames =
- swiftCtx.getAllPropertyNames(objcClassDecl,
- /*forInstance=*/true);
+ getAllPropertyNames(objcClassDecl, /*forInstance=*/true);
}
(void)omitNeedlessWords(baseName, {}, "", propertyTypeName,
@@ -1716,3 +1715,72 @@
importNameCache[key] = res;
return res;
}
+
+const InheritedNameSet *NameImporter::getAllPropertyNames(
+ clang::ObjCInterfaceDecl *classDecl,
+ bool forInstance) {
+ classDecl = classDecl->getCanonicalDecl();
+
+ // If we already have this information, return it.
+ auto known = allProperties.find({classDecl, forInstance});
+ if (known != allProperties.end()) return known->second.get();
+
+ // Otherwise, get information from our superclass first.
+ const InheritedNameSet *parentSet = nullptr;
+ if (auto superclassDecl = classDecl->getSuperClass()) {
+ parentSet = getAllPropertyNames(superclassDecl, forInstance);
+ }
+
+ // Create the set of properties.
+ known = allProperties.insert(
+ { std::pair<const clang::ObjCInterfaceDecl *, char>(classDecl,
+ forInstance),
+ llvm::make_unique<InheritedNameSet>(parentSet) }).first;
+
+ // Local function to add properties from the given set.
+ auto addProperties = [&](clang::DeclContext::decl_range members) {
+ for (auto member : members) {
+ // Add Objective-C property names.
+ if (auto property = dyn_cast<clang::ObjCPropertyDecl>(member)) {
+ if (forInstance)
+ known->second->add(property->getName());
+ continue;
+ }
+
+ // Add no-parameter, non-void method names.
+ if (auto method = dyn_cast<clang::ObjCMethodDecl>(member)) {
+ if (method->getSelector().isUnarySelector() &&
+ !method->getReturnType()->isVoidType() &&
+ !method->hasRelatedResultType() &&
+ method->isInstanceMethod() == forInstance) {
+ known->second->add(method->getSelector().getNameForSlot(0));
+ continue;
+ }
+ }
+ }
+ };
+
+ // Dig out the class definition.
+ auto classDef = classDecl->getDefinition();
+ if (!classDef) return known->second.get();
+
+ // Collect property names from the class definition.
+ addProperties(classDef->decls());
+
+ // Dig out the module that owns the class definition.
+ auto module = classDef->getImportedOwningModule();
+ if (module) module = module->getTopLevelModule();
+
+ // Collect property names from all categories and extensions in the same
+ // module as the class.
+ for (auto category : classDef->known_categories()) {
+ auto categoryModule = category->getImportedOwningModule();
+ if (categoryModule) categoryModule = categoryModule->getTopLevelModule();
+ if (module != categoryModule) continue;
+
+ addProperties(category->decls());
+ }
+
+ return known->second.get();
+}
+
diff --git a/lib/ClangImporter/ImportName.h b/lib/ClangImporter/ImportName.h
index b8f33cc..2c37f5d 100644
--- a/lib/ClangImporter/ImportName.h
+++ b/lib/ClangImporter/ImportName.h
@@ -297,6 +297,11 @@
/// Cache for repeated calls
llvm::DenseMap<CacheKeyType, ImportedName> importNameCache;
+ /// The set of property names that show up in the defining module of
+ /// an Objective-C class.
+ llvm::DenseMap<std::pair<const clang::ObjCInterfaceDecl *, char>,
+ std::unique_ptr<InheritedNameSet>> allProperties;
+
public:
NameImporter(ASTContext &ctx, const PlatformAvailability &avail,
clang::Sema &cSema, bool inferIAM)
@@ -340,6 +345,11 @@
return getClangSema().getPreprocessor();
}
+ /// Retrieve the inherited name set for the given Objective-C class.
+ const InheritedNameSet *getAllPropertyNames(
+ clang::ObjCInterfaceDecl *classDecl,
+ bool forInstance);
+
private:
bool enableObjCInterop() const { return swiftCtx.LangOpts.EnableObjCInterop; }
diff --git a/lib/Sema/MiscDiagnostics.cpp b/lib/Sema/MiscDiagnostics.cpp
index 2c59d60..4c48d38 100644
--- a/lib/Sema/MiscDiagnostics.cpp
+++ b/lib/Sema/MiscDiagnostics.cpp
@@ -3861,21 +3861,12 @@
if (params->size() != 0 && !params->get(0)->getName().empty())
firstParamName = params->get(0)->getName().str();
- // Find the set of property names.
- const InheritedNameSet *allPropertyNames = nullptr;
- if (contextType) {
- if (auto classDecl = contextType->getClassOrBoundGenericClass()) {
- allPropertyNames = Context.getAllPropertyNames(classDecl,
- afd->isInstanceMember());
- }
- }
-
StringScratchSpace scratch;
if (!swift::omitNeedlessWords(baseNameStr, argNameStrs, firstParamName,
getTypeNameForOmission(resultType),
getTypeNameForOmission(contextType),
paramTypes, returnsSelf, false,
- allPropertyNames, scratch))
+ /*allPropertyNames=*/nullptr, scratch))
return None;
/// Retrieve a replacement identifier.
@@ -3927,23 +3918,13 @@
while (auto optObjectTy = type->getAnyOptionalObjectType())
type = optObjectTy;
- // Find the set of property names.
- const InheritedNameSet *allPropertyNames = nullptr;
- if (contextType) {
- if (auto classDecl = contextType->getClassOrBoundGenericClass()) {
- allPropertyNames = Context.getAllPropertyNames(classDecl,
- var->isInstanceMember());
- }
- }
-
-
// Omit needless words.
StringScratchSpace scratch;
OmissionTypeName typeName = getTypeNameForOmission(var->getInterfaceType());
OmissionTypeName contextTypeName = getTypeNameForOmission(contextType);
if (::omitNeedlessWords(name, { }, "", typeName, contextTypeName, { },
- /*returnsSelf=*/false, true, allPropertyNames,
- scratch)) {
+ /*returnsSelf=*/false, true,
+ /*allPropertyNames=*/nullptr, scratch)) {
return Context.getIdentifier(name);
}