[Selector splitting] Drop non-directional prepositions from the beginning of imported argument names.

Swift SVN r15865
This commit is contained in:
Doug Gregor
2014-04-03 14:22:20 +00:00
parent 6f232af3bb
commit 08e7797f86
2 changed files with 37 additions and 18 deletions

View File

@@ -583,13 +583,28 @@ splitFirstSelectorPiece(StringRef selector, SmallVectorImpl<char> &scratch) {
return { selector, "" }; return { selector, "" };
} }
/// Import the given string directly as an identifier, where the empty /// Import an argument name.
/// string maps to a null identifier. static Identifier importArgName(ASTContext &ctx, StringRef name) {
static Identifier importNameOrNull(ASTContext &ctx, StringRef name) { // Simple case: empty name.
if (name.empty()) if (name.empty())
return Identifier(); return Identifier();
return ctx.getIdentifier(name); // If the first word isn't a non-directional preposition, lowercase
// it to form the argument name.
llvm::SmallString<16> scratch;
auto firstWord = camel_case::getFirstWord(name);
if (!ctx.LangOpts.SplitPrepositions ||
getPrepositionKind(firstWord) != PK_Nondirectional)
return ctx.getIdentifier(camel_case::toLowercaseWord(name, scratch));
// The first word is a non-directional preposition.
// If there's only one word, we're left with no argument name.
if (firstWord.size() == name.size())
return Identifier();
return ctx.getIdentifier(
camel_case::toLowercaseWord(name.substr(firstWord.size()), scratch));
} }
DeclName DeclName
@@ -603,17 +618,14 @@ ClangImporter::Implementation::importName(clang::Selector selector,
// Simple case. // Simple case.
if (!isInitializer || name.size() == 4) if (!isInitializer || name.size() == 4)
return importNameOrNull(SwiftContext, name); return SwiftContext.getIdentifier(name);
// This is an initializer with no parameters but a name that // This is an initializer with no parameters but a name that
// contains more than 'init', so synthesize an argument to capture // contains more than 'init', so synthesize an argument to capture
// what follows 'init'. // what follows 'init'.
assert(camel_case::getFirstWord(name).equals("init")); assert(camel_case::getFirstWord(name).equals("init"));
llvm::SmallString<16> scratch;
auto baseName = SwiftContext.Id_init; auto baseName = SwiftContext.Id_init;
auto argName auto argName = importArgName(SwiftContext, name.substr(4));
= importNameOrNull(SwiftContext,
camel_case::toLowercaseWord(name.substr(4), scratch));
return DeclName(SwiftContext, baseName, argName); return DeclName(SwiftContext, baseName, argName);
} }
@@ -622,19 +634,16 @@ ClangImporter::Implementation::importName(clang::Selector selector,
SmallVector<Identifier, 2> argumentNames; SmallVector<Identifier, 2> argumentNames;
StringRef firstPiece = selector.getNameForSlot(0); StringRef firstPiece = selector.getNameForSlot(0);
if (isInitializer) { if (isInitializer) {
llvm::SmallString<16> scratch;
assert(camel_case::getFirstWord(firstPiece).equals("init")); assert(camel_case::getFirstWord(firstPiece).equals("init"));
baseName = SwiftContext.Id_init; baseName = SwiftContext.Id_init;
auto firstArgName = camel_case::toLowercaseWord(firstPiece.substr(4), argumentNames.push_back(importArgName(SwiftContext, firstPiece.substr(4)));
scratch);
argumentNames.push_back(importNameOrNull(SwiftContext, firstArgName));
} else if (SplitPrepositions) { } else if (SplitPrepositions) {
llvm::SmallString<16> scratch; llvm::SmallString<16> scratch;
StringRef funcName, firstArgName; StringRef funcName, firstArgName;
std::tie(funcName, firstArgName) = splitFirstSelectorPiece(firstPiece, std::tie(funcName, firstArgName) = splitFirstSelectorPiece(firstPiece,
scratch); scratch);
baseName = importNameOrNull(SwiftContext, funcName); baseName = SwiftContext.getIdentifier(funcName);
argumentNames.push_back(importNameOrNull(SwiftContext, firstArgName)); argumentNames.push_back(importArgName(SwiftContext, firstArgName));
} else { } else {
baseName = SwiftContext.getIdentifier(firstPiece); baseName = SwiftContext.getIdentifier(firstPiece);
argumentNames.push_back(Identifier()); argumentNames.push_back(Identifier());
@@ -642,8 +651,8 @@ ClangImporter::Implementation::importName(clang::Selector selector,
// Determine the remaining argument names. // Determine the remaining argument names.
for (unsigned i = 1, e = selector.getNumArgs(); i < e; ++i) { for (unsigned i = 1, e = selector.getNumArgs(); i < e; ++i) {
argumentNames.push_back(importNameOrNull(SwiftContext, argumentNames.push_back(importArgName(SwiftContext,
selector.getNameForSlot(i))); selector.getNameForSlot(i)));
} }
return DeclName(SwiftContext, baseName, argumentNames); return DeclName(SwiftContext, baseName, argumentNames);

View File

@@ -4155,9 +4155,19 @@ createSubobjectInitOverride(TypeChecker &tc,
// Set the type of the initializer. // Set the type of the initializer.
configureConstructorType(ctor, outerGenericParams, selfType, configureConstructorType(ctor, outerGenericParams, selfType,
argParamPatterns->getType()); argParamPatterns->getType());
if (superclassCtor->isObjC()) if (superclassCtor->isObjC()) {
ctor->setIsObjC(true); ctor->setIsObjC(true);
// Inherit the @objc name from the superclass initializer, if it
// has one.
// FIXME: Generalize inheritance of attributes here?
if (auto objcAttr = superclassCtor->getAttrs().getAttribute<ObjCAttr>()) {
if (objcAttr->hasName())
ctor->getMutableAttrs().add(objcAttr->clone(ctx));
}
}
// Wire up the overides. // Wire up the overides.
DeclChecker(tc, false, false).checkOverrides(ctor); DeclChecker(tc, false, false).checkOverrides(ctor);