Skip to content

Commit ecf6df6

Browse files
committed
[Omit needless words] More broadly recognize collection types
1 parent c011d5f commit ecf6df6

File tree

4 files changed

+50
-6
lines changed

4 files changed

+50
-6
lines changed

lib/ClangImporter/ImportType.cpp

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1496,9 +1496,9 @@ static bool isObjCMethodResultAudited(const clang::Decl *decl) {
14961496
decl->hasAttr<clang::ObjCReturnsInnerPointerAttr>());
14971497
}
14981498

1499-
/// Determine whether this is the name of an Objective-C collection
1500-
/// with a single element type.
1501-
static bool isObjCCollectionName(StringRef typeName) {
1499+
/// Determine whether this is the name of a collection with a single
1500+
/// element type.
1501+
static bool isCollectionName(StringRef typeName) {
15021502
auto lastWord = camel_case::getLastWord(typeName);
15031503
return lastWord == "Array" || lastWord == "Set";
15041504
}
@@ -1555,12 +1555,31 @@ OmissionTypeName ClangImporter::Implementation::getClangTypeNameForOmission(
15551555
if (name == "NSInteger" || name == "NSUInteger" || name == "CGFloat")
15561556
return name;
15571557

1558+
// If it's a collection name and of pointer type, call it an
1559+
// array of the pointee type.
1560+
if (isCollectionName(name)) {
1561+
if (auto ptrType = type->getAs<clang::PointerType>()) {
1562+
return OmissionTypeName(
1563+
name, None,
1564+
getClangTypeNameForOmission(ctx, ptrType->getPointeeType())
1565+
.Name);
1566+
}
1567+
}
1568+
15581569
// Otherwise, desugar one level...
15591570
lastTypedefName = name;
15601571
type = typedefType->getDecl()->getUnderlyingType();
15611572
continue;
15621573
}
15631574

1575+
// For array types, convert the element type and treat this an as array.
1576+
if (auto arrayType = dyn_cast<clang::ArrayType>(typePtr)) {
1577+
return OmissionTypeName(
1578+
"Array", None,
1579+
getClangTypeNameForOmission(ctx, arrayType->getElementType())
1580+
.Name);
1581+
}
1582+
15641583
// Look through reference types.
15651584
if (auto refType = dyn_cast<clang::ReferenceType>(typePtr)) {
15661585
type = refType->getPointeeTypeAsWritten();
@@ -1594,9 +1613,18 @@ OmissionTypeName ClangImporter::Implementation::getClangTypeNameForOmission(
15941613
if (objcClass) {
15951614
// If this isn't the name of an Objective-C collection, we're done.
15961615
auto className = objcClass->getName();
1597-
if (!isObjCCollectionName(className))
1616+
if (!isCollectionName(className))
15981617
return className;
15991618

1619+
// If we don't have type parameters, use the prefix of the type
1620+
// name as the collection element type.
1621+
if (objcClass && !objcClass->getTypeParamList()) {
1622+
unsigned lastWordSize = camel_case::getLastWord(className).size();
1623+
StringRef elementName =
1624+
className.substr(0, className.size() - lastWordSize);
1625+
return OmissionTypeName(className, None, elementName);
1626+
}
1627+
16001628
// If we don't have type arguments, the collection element type
16011629
// is "Object".
16021630
auto typeArgs = objcObjectPtr->getTypeArgs();
@@ -1803,7 +1831,8 @@ bool ClangImporter::Implementation::omitNeedlessWordsInFunctionName(
18031831
SwiftContext.getIdentifier(baseName), numParams,
18041832
argumentName, isLastParameter) != DefaultArgumentKind::None;
18051833

1806-
paramTypes.push_back(getClangTypeNameForOmission(clangCtx, param->getType())
1834+
paramTypes.push_back(getClangTypeNameForOmission(clangCtx,
1835+
param->getOriginalType())
18071836
.withDefaultArgument(hasDefaultArg));
18081837
}
18091838

test/IDE/Inputs/custom-modules/OmitNeedlessWords.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
@import Foundation;
22

3+
@interface SEGreebieArray : NSObject
4+
@end
5+
36
@interface OmitNeedlessWords : NSObject
47
-(void)jumpToUrl:(nonnull NSURL *)url;
58
-(BOOL)objectIsCompatibleWithObject:(nonnull id)other;
@@ -20,4 +23,7 @@
2023
-(void)isCompatibleWithString:(nonnull NSString *)string;
2124
-(void)addObjectValue:(nonnull id)object;
2225
-(nonnull OmitNeedlessWords *)wordsBySlobbering:(nonnull NSString *)string;
26+
-(void)drawPolygonWithPoints:(const NSPoint[])points count:(NSInteger)count;
27+
-(void)drawFilledPolygonWithPoints:(NSPointArray)points count:(NSInteger)count;
28+
-(void)drawGreebies:(nonnull SEGreebieArray*)greebies;
2329
@end

test/IDE/print_omit_needless_words.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,5 +298,14 @@
298298

299299
// CHECK-OMIT-NEEDLESS-WORDS: func slobbering(_: String) -> OmitNeedlessWords
300300

301+
// Elements of C array types
302+
// CHECK-OMIT-NEEDLESS-WORDS: func drawPolygon(_: UnsafePointer<Point>, count: Int)
303+
304+
// Typedef ending in "Array".
305+
// CHECK-OMIT-NEEDLESS-WORDS: func drawFilledPolygon(_: PointArray, count: Int)
306+
307+
// Non-parameterized Objective-C class ending in "Array".
308+
// CHECK-OMIT-NEEDLESS-WORDS: func draw(_: SEGreebieArray)
309+
301310
// Don't drop the 'error'.
302311
// CHECK-ERRORS: func tryAndReturnError(_: ()) throws

test/Inputs/clang-importer-sdk/usr/include/Foundation.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ BOOL BOOLtoBOOL(BOOL b);
264264
typedef CGPoint NSPoint;
265265
typedef CGSize NSSize;
266266
typedef CGRect NSRect;
267-
267+
typedef NSPoint *NSPointArray;
268268

269269
@interface BadCollection
270270
- (id)objectForKeyedSubscript:(id)key;

0 commit comments

Comments
 (0)