Skip to content

Commit

Permalink
Omit needless words: distinguish class vs. instance properties for pr…
Browse files Browse the repository at this point in the history
…uning.

A class method named "bezierPath" should not prevent
"appendBezierPath" from being stripped.
  • Loading branch information
DougGregor committed Nov 17, 2015
1 parent 7b93555 commit 0f673f5
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 23 deletions.
6 changes: 4 additions & 2 deletions include/swift/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -802,11 +802,13 @@ class ASTContext {
std::unique_ptr<ArchetypeBuilder> 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;
Expand Down
38 changes: 24 additions & 14 deletions lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,12 +236,12 @@ struct ASTContext::Implementation {

/// The set of property names that show up in the defining module of a
/// class.
llvm::DenseMap<const ClassDecl *, std::unique_ptr<InheritedNameSet>>
AllProperties;
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<const clang::ObjCInterfaceDecl *,
llvm::DenseMap<std::pair<const clang::ObjCInterfaceDecl *, char>,
std::unique_ptr<InheritedNameSet>> AllPropertiesObjC;

/// \brief Structure that captures data that is segregated into different
Expand Down Expand Up @@ -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<clang::ObjCInterfaceDecl>(
classDecl->getClangDecl())) {
return getAllPropertyNames(
const_cast<clang::ObjCInterfaceDecl *>(objcClass));
const_cast<clang::ObjCInterfaceDecl *>(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.
Expand All @@ -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<InheritedNameSet>(parentSet) }).first;
{ 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());
}
Expand All @@ -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<InheritedNameSet>(parentSet) }).first;
{ 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)) {
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<clang::ObjCMethodDecl>(member)) {
if (method->getSelector().isUnarySelector() &&
!method->getReturnType()->isVoidType()) {
!method->getReturnType()->isVoidType() &&
!method->hasRelatedResultType() &&
method->isInstanceMethod() == forInstance) {
known->second->add(method->getSelector().getNameForSlot(0));
continue;
}
Expand Down
3 changes: 2 additions & 1 deletion lib/ClangImporter/ClangImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
9 changes: 6 additions & 3 deletions lib/ClangImporter/ImportType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2036,7 +2036,8 @@ DeclName ClangImporter::Implementation::omitNeedlessWordsInFunctionName(
const llvm::SmallBitVector &nonNullArgs,
const Optional<api_notes::ObjCMethodInfo> &knownMethod,
Optional<unsigned> errorParamIndex,
bool returnsSelf) {
bool returnsSelf,
bool isInstanceMethod) {
ASTContext &ctx = SwiftContext;

// Collect the argument names.
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -2303,7 +2305,8 @@ Type ClangImporter::Implementation::importMethodType(
nonNullArgs,
knownMethod,
errorInfo ? Optional<unsigned>(errorInfo->ParamIndex) : None,
clangDecl->hasRelatedResultType());
clangDecl->hasRelatedResultType(),
clangDecl->isInstanceMethod());
}

// Import the parameters.
Expand Down
3 changes: 2 additions & 1 deletion lib/ClangImporter/ImporterImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,8 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
const llvm::SmallBitVector &nonNullArgs,
const Optional<api_notes::ObjCMethodInfo> &knownMethod,
Optional<unsigned> errorParamIndex,
bool returnsSelf);
bool returnsSelf,
bool isInstanceMethod);

/// \brief Converts the given Swift identifier for Clang.
clang::DeclarationName exportName(Identifier name);
Expand Down
6 changes: 4 additions & 2 deletions lib/Sema/MiscDiagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1901,7 +1901,8 @@ static Optional<DeclName> omitNeedlessWords(AbstractFunctionDecl *afd) {
const InheritedNameSet *allPropertyNames = nullptr;
if (contextType) {
if (auto classDecl = contextType->getClassOrBoundGenericClass()) {
allPropertyNames = Context.getAllPropertyNames(classDecl);
allPropertyNames = Context.getAllPropertyNames(classDecl,
afd->isInstanceMember());
}
}

Expand Down Expand Up @@ -1967,7 +1968,8 @@ static Optional<Identifier> omitNeedlessWords(VarDecl *var) {
const InheritedNameSet *allPropertyNames = nullptr;
if (contextType) {
if (auto classDecl = contextType->getClassOrBoundGenericClass()) {
allPropertyNames = Context.getAllPropertyNames(classDecl);
allPropertyNames = Context.getAllPropertyNames(classDecl,
var->isInstanceMember());
}
}

Expand Down
2 changes: 2 additions & 0 deletions test/IDE/print_omit_needless_words.swift
Original file line number Diff line number Diff line change
Expand Up @@ -203,3 +203,5 @@
// CHECK-APPKIT: func removeGestureRecognizer(_: NSGestureRecognizer)
// CHECK-APPKIT: func favoriteViewFor(_: NSGestureRecognizer) -> NSView?
// CHECK-APPKIT: func addLayoutConstraints(_: Set<NSLayoutConstraint>)
// CHECK-APPKIT: func add(_: NSRect)
// CHECK-APPKIT: class func conjureRect(_: NSRect)
4 changes: 4 additions & 0 deletions test/Inputs/clang-importer-sdk/usr/include/AppKit.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,4 +293,8 @@ typedef NSPoint *NSPointPointer;

- (nonnull NSSet<NSLayoutConstraint *> *)layoutConstraints;
- (void)addLayoutConstraints:(nonnull NSSet<NSLayoutConstraint *> *)layoutConstraints;

+ (NSRect)rect;
- (void)addRect:(NSRect)rect;
+ (void)conjureRect:(NSRect)rect;
@end

0 comments on commit 0f673f5

Please sign in to comment.