From 0f673f5d7ac8f459a07a89a04a4621d8e0b71584 Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Mon, 16 Nov 2015 16:14:44 -0800 Subject: [PATCH] Omit needless words: distinguish class vs. instance properties for pruning. A class method named "bezierPath" should not prevent "appendBezierPath" from being stripped. --- include/swift/AST/ASTContext.h | 6 ++- lib/AST/ASTContext.cpp | 38 ++++++++++++------- lib/ClangImporter/ClangImporter.cpp | 3 +- lib/ClangImporter/ImportType.cpp | 9 +++-- lib/ClangImporter/ImporterImpl.h | 3 +- lib/Sema/MiscDiagnostics.cpp | 6 ++- test/IDE/print_omit_needless_words.swift | 2 + .../clang-importer-sdk/usr/include/AppKit.h | 4 ++ 8 files changed, 48 insertions(+), 23 deletions(-) diff --git a/include/swift/AST/ASTContext.h b/include/swift/AST/ASTContext.h index a413d8d214cf4..7349cef227efb 100644 --- a/include/swift/AST/ASTContext.h +++ b/include/swift/AST/ASTContext.h @@ -802,11 +802,13 @@ class ASTContext { std::unique_ptr builder); /// Retrieve the inherited name set for the given class. - const InheritedNameSet *getAllPropertyNames(ClassDecl *classDecl); + const InheritedNameSet *getAllPropertyNames(ClassDecl *classDecl, + bool forInstance); /// Retrieve the inherited name set for the given Objective-C class. const InheritedNameSet *getAllPropertyNames( - clang::ObjCInterfaceDecl *classDecl); + clang::ObjCInterfaceDecl *classDecl, + bool forInstance); private: friend class Decl; diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index b8872673163c7..b24d491f4fa8a 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -236,12 +236,12 @@ struct ASTContext::Implementation { /// The set of property names that show up in the defining module of a /// class. - llvm::DenseMap> - AllProperties; + llvm::DenseMap, + std::unique_ptr> AllProperties; /// The set of property names that show up in the defining module of /// an Objective-C class. - llvm::DenseMap, std::unique_ptr> AllPropertiesObjC; /// \brief Structure that captures data that is segregated into different @@ -3514,17 +3514,19 @@ void ASTContext::unregisterLazyArchetype(const ArchetypeType *archetype) { Impl.LazyArchetypes.erase(known); } -const InheritedNameSet *ASTContext::getAllPropertyNames(ClassDecl *classDecl) { +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( classDecl->getClangDecl())) { return getAllPropertyNames( - const_cast(objcClass)); + const_cast(objcClass), + forInstance); } // If we already have this information, return it. - auto known = Impl.AllProperties.find(classDecl); + auto known = Impl.AllProperties.find({classDecl, forInstance}); if (known != Impl.AllProperties.end()) return known->second.get(); // Otherwise, get information from our superclass first. @@ -3534,19 +3536,21 @@ const InheritedNameSet *ASTContext::getAllPropertyNames(ClassDecl *classDecl) { const InheritedNameSet *parentSet = nullptr; if (auto superclass = classDecl->getSuperclass()) { if (auto superclassDecl = superclass->getClassOrBoundGenericClass()) { - parentSet = getAllPropertyNames(superclassDecl); + parentSet = getAllPropertyNames(superclassDecl, forInstance); } } // Create the set of properties. known = Impl.AllProperties.insert( - {classDecl, llvm::make_unique(parentSet) }).first; + { std::pair(classDecl, forInstance), + llvm::make_unique(parentSet) }).first; // Local function to add properties from the given set. auto addProperties = [&](DeclRange members) { for (auto member : members) { auto var = dyn_cast(member); if (!var || var->getName().empty()) continue; + if (var->isInstanceMember() != forInstance) continue; known->second->add(var->getName().str()); } @@ -3566,36 +3570,42 @@ const InheritedNameSet *ASTContext::getAllPropertyNames(ClassDecl *classDecl) { } const InheritedNameSet *ASTContext::getAllPropertyNames( - clang::ObjCInterfaceDecl *classDecl) { + clang::ObjCInterfaceDecl *classDecl, + bool forInstance) { classDecl = classDecl->getCanonicalDecl(); // If we already have this information, return it. - auto known = Impl.AllPropertiesObjC.find(classDecl); + 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); + parentSet = getAllPropertyNames(superclassDecl, forInstance); } // Create the set of properties. known = Impl.AllPropertiesObjC.insert( - {classDecl, llvm::make_unique(parentSet) }).first; + { std::pair(classDecl, + forInstance), + llvm::make_unique(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(member)) { - known->second->add(property->getName()); + if (forInstance) + known->second->add(property->getName()); continue; } // Add no-parameter, non-void method names. if (auto method = dyn_cast(member)) { if (method->getSelector().isUnarySelector() && - !method->getReturnType()->isVoidType()) { + !method->getReturnType()->isVoidType() && + !method->hasRelatedResultType() && + method->isInstanceMethod() == forInstance) { known->second->add(method->getSelector().getNameForSlot(0)); continue; } diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index c339dc6e4d5e9..c8dbc0e1b6a76 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -1372,7 +1372,8 @@ ClangImporter::Implementation::importName(const clang::NamedDecl *D, if (auto objcPtrType = contextType->getAsObjCInterfacePointerType()) if (auto objcClassDecl = objcPtrType->getInterfaceDecl()) allPropertyNames = SwiftContext.getAllPropertyNames( - objcClassDecl); + objcClassDecl, + /*forInstance=*/true); } if (omitNeedlessWords(name, { }, "", propertyTypeName, contextTypeName, diff --git a/lib/ClangImporter/ImportType.cpp b/lib/ClangImporter/ImportType.cpp index ae91a27b9c9fb..1c3a8e3f527cc 100644 --- a/lib/ClangImporter/ImportType.cpp +++ b/lib/ClangImporter/ImportType.cpp @@ -2036,7 +2036,8 @@ DeclName ClangImporter::Implementation::omitNeedlessWordsInFunctionName( const llvm::SmallBitVector &nonNullArgs, const Optional &knownMethod, Optional errorParamIndex, - bool returnsSelf) { + bool returnsSelf, + bool isInstanceMethod) { ASTContext &ctx = SwiftContext; // Collect the argument names. @@ -2095,7 +2096,8 @@ DeclName ClangImporter::Implementation::omitNeedlessWordsInFunctionName( if (!contextType.isNull()) { if (auto objcPtrType = contextType->getAsObjCInterfacePointerType()) if (auto objcClassDecl = objcPtrType->getInterfaceDecl()) - allPropertyNames = SwiftContext.getAllPropertyNames(objcClassDecl); + allPropertyNames = SwiftContext.getAllPropertyNames(objcClassDecl, + isInstanceMethod); } if (!omitNeedlessWords(baseName, argNames, firstParamName, @@ -2303,7 +2305,8 @@ Type ClangImporter::Implementation::importMethodType( nonNullArgs, knownMethod, errorInfo ? Optional(errorInfo->ParamIndex) : None, - clangDecl->hasRelatedResultType()); + clangDecl->hasRelatedResultType(), + clangDecl->isInstanceMethod()); } // Import the parameters. diff --git a/lib/ClangImporter/ImporterImpl.h b/lib/ClangImporter/ImporterImpl.h index fbedeca42264c..5c6d4cee40831 100644 --- a/lib/ClangImporter/ImporterImpl.h +++ b/lib/ClangImporter/ImporterImpl.h @@ -707,7 +707,8 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation const llvm::SmallBitVector &nonNullArgs, const Optional &knownMethod, Optional errorParamIndex, - bool returnsSelf); + bool returnsSelf, + bool isInstanceMethod); /// \brief Converts the given Swift identifier for Clang. clang::DeclarationName exportName(Identifier name); diff --git a/lib/Sema/MiscDiagnostics.cpp b/lib/Sema/MiscDiagnostics.cpp index 828c6612e33f4..ea8839fd63b50 100644 --- a/lib/Sema/MiscDiagnostics.cpp +++ b/lib/Sema/MiscDiagnostics.cpp @@ -1901,7 +1901,8 @@ static Optional omitNeedlessWords(AbstractFunctionDecl *afd) { const InheritedNameSet *allPropertyNames = nullptr; if (contextType) { if (auto classDecl = contextType->getClassOrBoundGenericClass()) { - allPropertyNames = Context.getAllPropertyNames(classDecl); + allPropertyNames = Context.getAllPropertyNames(classDecl, + afd->isInstanceMember()); } } @@ -1967,7 +1968,8 @@ static Optional omitNeedlessWords(VarDecl *var) { const InheritedNameSet *allPropertyNames = nullptr; if (contextType) { if (auto classDecl = contextType->getClassOrBoundGenericClass()) { - allPropertyNames = Context.getAllPropertyNames(classDecl); + allPropertyNames = Context.getAllPropertyNames(classDecl, + var->isInstanceMember()); } } diff --git a/test/IDE/print_omit_needless_words.swift b/test/IDE/print_omit_needless_words.swift index 95596859aff7d..ddf0a5625194e 100644 --- a/test/IDE/print_omit_needless_words.swift +++ b/test/IDE/print_omit_needless_words.swift @@ -203,3 +203,5 @@ // CHECK-APPKIT: func removeGestureRecognizer(_: NSGestureRecognizer) // CHECK-APPKIT: func favoriteViewFor(_: NSGestureRecognizer) -> NSView? // CHECK-APPKIT: func addLayoutConstraints(_: Set) +// CHECK-APPKIT: func add(_: NSRect) +// CHECK-APPKIT: class func conjureRect(_: NSRect) diff --git a/test/Inputs/clang-importer-sdk/usr/include/AppKit.h b/test/Inputs/clang-importer-sdk/usr/include/AppKit.h index 6de2a18e3b686..ef44fdd85d461 100644 --- a/test/Inputs/clang-importer-sdk/usr/include/AppKit.h +++ b/test/Inputs/clang-importer-sdk/usr/include/AppKit.h @@ -293,4 +293,8 @@ typedef NSPoint *NSPointPointer; - (nonnull NSSet *)layoutConstraints; - (void)addLayoutConstraints:(nonnull NSSet *)layoutConstraints; + ++ (NSRect)rect; +- (void)addRect:(NSRect)rect; ++ (void)conjureRect:(NSRect)rect; @end