Skip to content

Commit 476f92d

Browse files
committed
[Clang Importer] Only strip common prefix for swift_newtype
Rather than do whole-word common-word stripping, we only strip common prefixes. This is not as powerful as what was originally intended, but much less magical in the mapping into Swift. Test case adjusted, and common utility functions exposed.
1 parent 9c31aa4 commit 476f92d

File tree

4 files changed

+47
-22
lines changed

4 files changed

+47
-22
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2556,23 +2556,16 @@ auto ClangImporter::Implementation::importFullName(
25562556
// swift_newtype-ed declarations may have common words with the type name
25572557
// stripped.
25582558
if (auto newtypeDecl = findSwiftNewtype(D)) {
2559-
SmallString<32> newNameBuffer;
2560-
auto newtypeNameWords = camel_case::getWords(newtypeDecl->getName());
2561-
auto declNameWords = camel_case::getWords(baseName);
2562-
2563-
// Scan the decl name, and drop any words that appear in order in the type
2564-
// name
2565-
for (auto wI = declNameWords.begin(), skipWI = newtypeNameWords.begin();
2566-
wI != declNameWords.end(); ++wI) {
2567-
if (skipWI != newtypeNameWords.end() && *wI == *skipWI) {
2568-
++skipWI;
2569-
continue;
2570-
}
2571-
newNameBuffer.append(*wI);
2572-
}
2573-
2574-
if (newNameBuffer.str() != baseName) {
2575-
baseName = omitNeedlessWordsScratch.copyString(newNameBuffer);
2559+
// Skip a leading 'k' in a 'kConstant' pattern
2560+
if (baseName.size() >= 2 && baseName[0] == 'k' &&
2561+
clang::isUppercase(baseName[1]))
2562+
baseName.drop_front(1);
2563+
2564+
bool nonIdentifier = false;
2565+
auto pre =
2566+
getCommonWordPrefix(newtypeDecl->getName(), baseName, nonIdentifier);
2567+
if (pre.size()) {
2568+
baseName = baseName.drop_front(pre.size());
25762569
strippedPrefix = true;
25772570
}
25782571
}

lib/ClangImporter/ImportEnumInfo.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ void EnumInfo::classifyEnum(const clang::EnumDecl *decl,
8585
///
8686
/// This is used to derive the common prefix of enum constants so we can elide
8787
/// it from the Swift interface.
88-
static StringRef getCommonWordPrefix(StringRef a, StringRef b,
89-
bool &followedByNonIdentifier) {
88+
StringRef importer::getCommonWordPrefix(StringRef a, StringRef b,
89+
bool &followedByNonIdentifier) {
9090
auto aWords = camel_case::getWords(a), bWords = camel_case::getWords(b);
9191
auto aI = aWords.begin(), aE = aWords.end(), bI = bWords.begin(),
9292
bE = bWords.end();
@@ -124,7 +124,8 @@ static StringRef getCommonWordPrefix(StringRef a, StringRef b,
124124
/// in Cocoa and Cocoa Touch.
125125
///
126126
/// \see getCommonWordPrefix
127-
static StringRef getCommonPluralPrefix(StringRef singular, StringRef plural) {
127+
StringRef importer::getCommonPluralPrefix(StringRef singular,
128+
StringRef plural) {
128129
assert(!plural.empty());
129130

130131
if (singular.empty())

lib/ClangImporter/ImportEnumInfo.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,37 @@ class EnumInfo {
9797
void determineConstantNamePrefix(ASTContext &ctx, const clang::EnumDecl *);
9898
void classifyEnum(const clang::EnumDecl *, clang::Preprocessor &);
9999
};
100+
101+
// Utility functions of primary interest to enum constant naming
102+
103+
/// Returns the common prefix of two strings at camel-case word granularity.
104+
///
105+
/// For example, given "NSFooBar" and "NSFooBas", returns "NSFoo"
106+
/// (not "NSFooBa"). The returned StringRef is a slice of the "a" argument.
107+
///
108+
/// If either string has a non-identifier character immediately after the
109+
/// prefix, \p followedByNonIdentifier will be set to \c true. If both strings
110+
/// have identifier characters after the prefix, \p followedByNonIdentifier will
111+
/// be set to \c false. Otherwise, \p followedByNonIdentifier will not be
112+
/// changed from its initial value.
113+
///
114+
/// This is used to derive the common prefix of enum constants so we can elide
115+
/// it from the Swift interface.
116+
StringRef getCommonWordPrefix(StringRef a, StringRef b,
117+
bool &followedByNonIdentifier);
118+
119+
/// Returns the common word-prefix of two strings, allowing the second string
120+
/// to be a common English plural form of the first.
121+
///
122+
/// For example, given "NSProperty" and "NSProperties", the full "NSProperty"
123+
/// is returned. Given "NSMagicArmor" and "NSMagicArmory", only
124+
/// "NSMagic" is returned.
125+
///
126+
/// The "-s", "-es", and "-ies" patterns cover every plural NS_OPTIONS name
127+
/// in Cocoa and Cocoa Touch.
128+
///
129+
/// \see getCommonWordPrefix
130+
StringRef getCommonPluralPrefix(StringRef singular, StringRef plural);
100131
}
101132
}
102133

test/IDE/newtype.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
// PRINT-NEXT: static let one: ErrorDomain
1212
// PRINT-NEXT: static let errTwo: ErrorDomain
1313
// PRINT-NEXT: static let three: ErrorDomain
14-
// PRINT-NEXT: static let four: ErrorDomain
14+
// PRINT-NEXT: static let fourErrorDomain: ErrorDomain
1515
// PRINT-NEXT: static let stillAMember: ErrorDomain
1616
// PRINT-NEXT: }
1717
// PRINT-NEXT: struct Foo {
@@ -27,7 +27,7 @@
2727
// PRINT-NEXT: let rawValue: NSString
2828
// PRINT-NEXT: }
2929
// PRINT-NEXT: extension ClosedEnum {
30-
// PRINT-NEXT: static let firstEntry: ClosedEnum
30+
// PRINT-NEXT: static let firstClosedEntryEnum: ClosedEnum
3131
// PRINT-NEXT: static let secondEntry: ClosedEnum
3232
// PRINT-NEXT: static let thirdEntry: ClosedEnum
3333
// PRINT-NEXT: }

0 commit comments

Comments
 (0)