Skip to content

[sourcekitd] Allow mising name pieces preferred names #9014

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 25, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion test/SourceKit/NameTranslation/basic.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ func foo2 (_ a : FooClassDerived) {
// RUN: %sourcekitd-test -req=translate -objc-selector fooInstanceFunc21:withBB: -pos=15:13 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %mcp_opt %s | %FileCheck -check-prefix=CHECK8 %s
// RUN: %sourcekitd-test -req=translate -objc-name fooProperty11 -pos=16:13 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %mcp_opt %s | %FileCheck -check-prefix=CHECK9 %s
// RUN: %sourcekitd-test -req=translate -objc-selector fooInstanceFunc21:withBB:withC: -pos=15:13 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %mcp_opt %s | %FileCheck -check-prefix=CHECK-NONE %s
// RUN: %sourcekitd-test -req=translate -objc-selector fooInstanceFunc21: -pos=15:13 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %mcp_opt %s | %FileCheck -check-prefix=CHECK-NONE %s
// RUN: %sourcekitd-test -req=translate -objc-selector fooInstanceFunc21: -pos=15:13 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %mcp_opt %s | %FileCheck -check-prefix=CHECKFEWER1 %s
// RUN: %sourcekitd-test -req=translate -objc-selector fooInstanceFunc21:: -pos=15:13 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %mcp_opt %s | %FileCheck -check-prefix=CHECKMISSING1 %s
// RUN: %sourcekitd-test -req=translate -objc-selector :withBB: -pos=15:13 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %mcp_opt %s | %FileCheck -check-prefix=CHECKMISSING2 %s
// RUN: %sourcekitd-test -req=translate -objc-selector :: -pos=15:13 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %mcp_opt %s | %FileCheck -check-prefix=CHECKMISSING3 %s

// RUN: %sourcekitd-test -req=translate -objc-selector fooInstanceFunc21: -pos=17:13 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %mcp_opt %s | %FileCheck -check-prefix=CHECK10 %s
// RUN: %sourcekitd-test -req=translate -objc-selector initWithfloat2: -pos=17:13 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %mcp_opt %s | %FileCheck -check-prefix=CHECK12 %s
Expand All @@ -57,3 +60,8 @@ func foo2 (_ a : FooClassDerived) {
// CHECK12: init(float2:)
// CHECK13: init(_:)
// CHECK14: init

// CHECKFEWER1: fooInstanceFunc21(_:withB:)
// CHECKMISSING1: fooInstanceFunc21(_:withB:)
// CHECKMISSING2: fooInstanceFunc2(_:withBB:)
// CHECKMISSING3: fooInstanceFunc2(_:withB:)
7 changes: 7 additions & 0 deletions test/SourceKit/NameTranslation/swiftnames.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ class C2 {}

// REQUIRES: objc_interop
// RUN: %sourcekitd-test -req=translate -swift-name "foo(a:b:c:)" -pos=11:11 %s -- -F %S/Inputs/mock-sdk -I %t.tmp %mcp_opt %s | %FileCheck -check-prefix=CHECK1 %s
// RUN: %sourcekitd-test -req=translate -swift-name "bar(x:y:)" -pos=11:11 %s -- -F %S/Inputs/mock-sdk -I %t.tmp %mcp_opt %s | %FileCheck -check-prefix=CHECKFEWER1 %s
// RUN: %sourcekitd-test -req=translate -swift-name "bar(::)" -pos=11:11 %s -- -F %S/Inputs/mock-sdk -I %t.tmp %mcp_opt %s | %FileCheck -check-prefix=CHECKMISSING1 %s
// RUN: %sourcekitd-test -req=translate -swift-name "(x:y:z:)" -pos=11:11 %s -- -F %S/Inputs/mock-sdk -I %t.tmp %mcp_opt %s | %FileCheck -check-prefix=CHECKMISSING2 %s
// RUN: %sourcekitd-test -req=translate -swift-name "foo(a1:b1:c1:)" -pos=11:11 %s -- -F %S/Inputs/mock-sdk -I %t.tmp %mcp_opt %s | %FileCheck -check-prefix=CHECK2 %s
// RUN: %sourcekitd-test -req=translate -swift-name "foo(_:b1:c1:)" -pos=11:11 %s -- -F %S/Inputs/mock-sdk -I %t.tmp %mcp_opt %s | %FileCheck -check-prefix=CHECK3 %s
// RUN: %sourcekitd-test -req=translate -swift-name "foo1(_:_:c2:)" -pos=11:11 %s -- -F %S/Inputs/mock-sdk -I %t.tmp %mcp_opt %s | %FileCheck -check-prefix=CHECK4 %s
Expand Down Expand Up @@ -92,3 +95,7 @@ class C2 {}
// CHECK14: CustomErrorA2
// CHECK15: C2ObjC
// CHECK16: bar:other:

// CHECKFEWER1: barWithX:y:c:
// CHECKMISSING1: barWithA:b:c:
// CHECKMISSING2: fooWithX:y:z:
83 changes: 62 additions & 21 deletions tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -881,7 +881,9 @@ static bool passCursorInfoForDecl(const ValueDecl *VD,
}

static clang::DeclarationName
getClangDeclarationName(clang::ASTContext &Ctx, NameTranslatingInfo &Info) {
getClangDeclarationName(const clang::NamedDecl *ND, NameTranslatingInfo &Info) {
auto &Ctx = ND->getASTContext();
auto OrigName = ND->getDeclName();
assert(SwiftLangSupport::getNameKindForUID(Info.NameKind) == NameKind::ObjC);
if (Info.BaseName.empty() == Info.ArgNames.empty()) {
// cannot have both.
Expand All @@ -890,27 +892,61 @@ getClangDeclarationName(clang::ASTContext &Ctx, NameTranslatingInfo &Info) {
if (!Info.BaseName.empty()) {
return clang::DeclarationName(&Ctx.Idents.get(Info.BaseName));
} else {
StringRef last = Info.ArgNames.back();

switch (OrigName.getNameKind()) {
case clang::DeclarationName::ObjCZeroArgSelector:
if (last.endswith(":"))
return clang::DeclarationName();
break;
case clang::DeclarationName::ObjCOneArgSelector:
case clang::DeclarationName::ObjCMultiArgSelector:
if (!last.empty() && !last.endswith(":"))
return clang::DeclarationName();
break;
default:
return clang::DeclarationName();
}

auto OrigSel = OrigName.getObjCSelector();
unsigned NumPieces = OrigSel.isUnarySelector() ? 1 : OrigSel.getNumArgs();
if (Info.ArgNames.size() > NumPieces)
return clang::DeclarationName();

ArrayRef<StringRef> Args = llvm::makeArrayRef(Info.ArgNames);
std::vector<clang::IdentifierInfo *> Pieces;
std::transform(Args.begin(), Args.end(), std::back_inserter(Pieces),
[&](StringRef T) { return &Ctx.Idents.get(T.endswith(":") ?
T.drop_back() : T); });
return clang::DeclarationName(Ctx.Selectors.getSelector(
/*Calculate Args*/std::accumulate(Args.begin(), Args.end(), (unsigned)0,
[](unsigned I, StringRef T) { return I + (T.endswith(":") ? 1 : 0); }),
Pieces.data()));
for (unsigned i = 0; i < NumPieces; ++i) {
if (i >= Info.ArgNames.size() || Info.ArgNames[i].empty()) {
Pieces.push_back(OrigSel.getIdentifierInfoForSlot(i));
} else {
StringRef T = Args[i];
Pieces.push_back(&Ctx.Idents.get(T.endswith(":") ? T.drop_back() : T));
}
}
return clang::DeclarationName(
Ctx.Selectors.getSelector(OrigSel.getNumArgs(), Pieces.data()));
}
}

static DeclName
getSwiftDeclName(ASTContext &Ctx, NameTranslatingInfo &Info) {
static DeclName getSwiftDeclName(const ValueDecl *VD,
NameTranslatingInfo &Info) {
auto &Ctx = VD->getDeclContext()->getASTContext();
assert(SwiftLangSupport::getNameKindForUID(Info.NameKind) == NameKind::Swift);
std::vector<Identifier> Args;
std::transform(Info.ArgNames.begin(), Info.ArgNames.end(),
std::back_inserter(Args),
[&](StringRef T) { return Ctx.getIdentifier(T); });
return DeclName(Ctx, Ctx.getIdentifier(Info.BaseName),
llvm::makeArrayRef(Args));
DeclName OrigName = VD->getFullName();
Identifier BaseName = Info.BaseName.empty()
? OrigName.getBaseName()
: Ctx.getIdentifier(Info.BaseName);
auto OrigArgs = OrigName.getArgumentNames();
SmallVector<Identifier, 8> Args(OrigArgs.begin(), OrigArgs.end());
if (Info.ArgNames.size() > OrigArgs.size())
return DeclName();
for (unsigned i = 0; i < OrigArgs.size(); ++i) {
if (i < Info.ArgNames.size() && !Info.ArgNames[i].empty()) {
StringRef Arg = Info.ArgNames[i];
Args[i] = Ctx.getIdentifier(Arg == "_" ? StringRef() : Arg);
}
}
return DeclName(Ctx, BaseName, llvm::makeArrayRef(Args));
}

/// Returns true for failure to resolve.
Expand All @@ -919,9 +955,11 @@ static bool passNameInfoForDecl(const ValueDecl *VD, NameTranslatingInfo &Info,
switch (SwiftLangSupport::getNameKindForUID(Info.NameKind)) {
case NameKind::Swift: {
NameTranslatingInfo Result;
auto &Ctx = VD->getDeclContext()->getASTContext();
auto ResultPair = swift::objc_translation::getObjCNameForSwiftDecl(VD,
getSwiftDeclName(Ctx, Info));
auto DeclName = getSwiftDeclName(VD, Info);
if (!DeclName)
return true;
auto ResultPair =
swift::objc_translation::getObjCNameForSwiftDecl(VD, DeclName);
Identifier Name = ResultPair.first;
if (!Name.empty()) {
Result.NameKind = SwiftLangSupport::getUIDForNameKind(NameKind::ObjC);
Expand Down Expand Up @@ -952,8 +990,11 @@ static bool passNameInfoForDecl(const ValueDecl *VD, NameTranslatingInfo &Info,
getASTContext().getClangModuleLoader());

if (auto *Named = dyn_cast_or_null<clang::NamedDecl>(VD->getClangDecl())) {
DeclName Name = Importer->importName(Named,
getClangDeclarationName(Named->getASTContext(), Info));
auto ObjCName = getClangDeclarationName(Named, Info);
if (!ObjCName)
return true;

DeclName Name = Importer->importName(Named, ObjCName);
NameTranslatingInfo Result;
Result.NameKind = SwiftLangSupport::getUIDForNameKind(NameKind::Swift);
Result.BaseName = Name.getBaseName().str();
Expand Down
20 changes: 11 additions & 9 deletions tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ static int handleTestInvocation(ArrayRef<const char *> Args,
sourcekitd_request_dictionary_set_uid(Req, KeyRequest, RequestNameTranslation);
sourcekitd_request_dictionary_set_int64(Req, KeyOffset, ByteOffset);
StringRef BaseName;
llvm::SmallVector<StringRef, 4> ArgPices;
llvm::SmallVector<StringRef, 4> ArgPieces;
sourcekitd_uid_t ArgName;
if (!Opts.SwiftName.empty()) {
sourcekitd_request_dictionary_set_uid(Req, KeyNameKind, KindNameSwift);
Expand All @@ -609,13 +609,13 @@ static int handleTestInvocation(ArrayRef<const char *> Args,
return 1;
}
StringRef AllArgs = Text.substr(ArgStart + 1, ArgEnd - ArgStart - 1);
AllArgs.split(ArgPices, ':');
AllArgs.split(ArgPieces, ':');
if (!Args.empty()) {
if (!ArgPices.back().empty()) {
if (!ArgPieces.back().empty()) {
llvm::errs() << "Swift name is malformed.\n";
return 1;
}
ArgPices.pop_back();
ArgPieces.pop_back();
}
}
} else if (!Opts.ObjCName.empty()) {
Expand All @@ -625,11 +625,13 @@ static int handleTestInvocation(ArrayRef<const char *> Args,
} else if (!Opts.ObjCSelector.empty()) {
sourcekitd_request_dictionary_set_uid(Req, KeyNameKind, KindNameObjc);
StringRef Name(Opts.ObjCSelector);
Name.split(ArgPices, ':', -1, /*keep empty*/false);
Name.split(ArgPieces, ':');
if (ArgPieces.back().empty())
ArgPieces.pop_back();
ArgName = KeySelectorPieces;
std::transform(ArgPices.begin(), ArgPices.end(), ArgPices.begin(),
std::transform(ArgPieces.begin(), ArgPieces.end(), ArgPieces.begin(),
[Name] (StringRef T) {
if (T.data() + T.size() < Name.data() + Name.size() &&
if (!T.empty() && T.data() + T.size() < Name.data() + Name.size() &&
*(T.data() + T.size()) == ':') {
// Include the colon belonging to the piece.
return StringRef(T.data(), T.size() + 1);
Expand All @@ -644,9 +646,9 @@ static int handleTestInvocation(ArrayRef<const char *> Args,
std::string S = BaseName;
sourcekitd_request_dictionary_set_string(Req, KeyBaseName, S.c_str());
}
if (!ArgPices.empty()) {
if (!ArgPieces.empty()) {
sourcekitd_object_t Arr = sourcekitd_request_array_create(nullptr, 0);
for (StringRef A: ArgPices) {
for (StringRef A : ArgPieces) {
std::string S = A;
sourcekitd_request_array_set_string(Arr, SOURCEKITD_ARRAY_APPEND,
S.c_str());
Expand Down
5 changes: 1 addition & 4 deletions tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -818,10 +818,7 @@ handleSemanticRequest(RequestDict Req,
}
std::transform(ArgParts.begin(), ArgParts.end(),
std::back_inserter(Input.ArgNames),
[](const char *C) {
StringRef Original(C);
return Original == "_" ? StringRef() : Original;
});
[](const char *C) { return StringRef(C); });
std::transform(Selectors.begin(), Selectors.end(),
std::back_inserter(Input.ArgNames),
[](const char *C) { return StringRef(C); });
Expand Down