Skip to content

[SourceKit] Move demangle/mangle logic to SwfitLangSupport #63111

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
Jan 20, 2023
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: 10 additions & 0 deletions tools/SourceKit/include/SourceKit/Core/LangSupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,16 @@ class LangSupport {

virtual void dependencyUpdated() {}

virtual void demangleNames(
ArrayRef<const char *> MangledNames, bool Simplified,
std::function<void(const RequestResult<ArrayRef<std::string>> &)>
Receiver) = 0;

virtual void mangleSimpleClassNames(
ArrayRef<std::pair<StringRef, StringRef>> ModuleClassPairs,
std::function<void(const RequestResult<ArrayRef<std::string>> &)>
Receiver) = 0;

virtual void indexSource(StringRef Filename,
IndexingConsumer &Consumer,
ArrayRef<const char *> Args) = 0;
Expand Down
1 change: 1 addition & 0 deletions tools/SourceKit/lib/SwiftLang/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ add_sourcekit_library(SourceKitSwiftLang
SwiftEditorInterfaceGen.cpp
SwiftIndexing.cpp
SwiftLangSupport.cpp
SwiftMangling.cpp
SwiftSourceDocInfo.cpp
SwiftTypeContextInfo.cpp
LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD}
Expand Down
10 changes: 10 additions & 0 deletions tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,16 @@ class SwiftLangSupport : public LangSupport {

void dependencyUpdated() override;

void demangleNames(
ArrayRef<const char *> MangledNames, bool Simplified,
std::function<void(const RequestResult<ArrayRef<std::string>> &)>
Receiver) override;

void mangleSimpleClassNames(
ArrayRef<std::pair<StringRef, StringRef>> ModuleClassPairs,
std::function<void(const RequestResult<ArrayRef<std::string>> &)>
Receiver) override;

void indexSource(StringRef Filename, IndexingConsumer &Consumer,
ArrayRef<const char *> Args) override;

Expand Down
92 changes: 92 additions & 0 deletions tools/SourceKit/lib/SwiftLang/SwiftMangling.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
//===--- SwiftMangling.cpp ------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "SwiftLangSupport.h"

#include "swift/Demangling/Demangle.h"
#include "swift/Demangling/Demangler.h"

using namespace SourceKit;
using namespace swift;
using namespace ide;

void SwiftLangSupport::demangleNames(
ArrayRef<const char *> MangledNames, bool Simplified,
std::function<void(const RequestResult<ArrayRef<std::string>> &)>
Receiver) {

swift::Demangle::DemangleOptions DemangleOptions;
if (Simplified) {
DemangleOptions =
swift::Demangle::DemangleOptions::SimplifiedUIDemangleOptions();
}

auto getDemangledName = [&](StringRef MangledName) -> std::string {
if (!swift::Demangle::isSwiftSymbol(MangledName))
return std::string(); // Not a mangled name

std::string Result =
swift::Demangle::demangleSymbolAsString(MangledName, DemangleOptions);

if (Result == MangledName)
return std::string(); // Not a mangled name

return Result;
};

SmallVector<std::string, 4> results;
for (auto &MangledName : MangledNames) {
results.push_back(getDemangledName(MangledName));
}

Receiver(RequestResult<ArrayRef<std::string>>::fromResult(results));
}

static ManglingErrorOr<std::string> mangleSimpleClass(StringRef moduleName,
StringRef className) {
using namespace swift::Demangle;
Demangler Dem;
auto moduleNode = Dem.createNode(Node::Kind::Module, moduleName);
auto IdNode = Dem.createNode(Node::Kind::Identifier, className);
auto classNode = Dem.createNode(Node::Kind::Class);
auto typeNode = Dem.createNode(Node::Kind::Type);
auto typeManglingNode = Dem.createNode(Node::Kind::TypeMangling);
auto globalNode = Dem.createNode(Node::Kind::Global);

classNode->addChild(moduleNode, Dem);
classNode->addChild(IdNode, Dem);
typeNode->addChild(classNode, Dem);
typeManglingNode->addChild(typeNode, Dem);
globalNode->addChild(typeManglingNode, Dem);
return mangleNode(globalNode);
}

void SwiftLangSupport::mangleSimpleClassNames(
ArrayRef<std::pair<StringRef, StringRef>> ModuleClassPairs,
std::function<void(const RequestResult<ArrayRef<std::string>> &)>
Receiver) {

SmallVector<std::string, 4> results;
for (auto &pair : ModuleClassPairs) {
auto mangling = mangleSimpleClass(pair.first, pair.second);
if (!mangling.isSuccess()) {
std::string message = "name mangling failed for ";
message += pair.first;
message += ".";
message += pair.second;
Receiver(RequestResult<ArrayRef<std::string>>::fromError(message));
return;
}
results.push_back(mangling.result());
}
Receiver(RequestResult<ArrayRef<std::string>>::fromResult(results));
}
119 changes: 31 additions & 88 deletions tools/SourceKit/tools/sourcekitd/lib/Service/Requests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,17 @@
#include "SourceKit/Support/UIdent.h"
#include "SourceKit/SwiftLang/Factory.h"

#include "swift/Basic/ExponentialGrowthAppendingBinaryByteStream.h"
#include "swift/Basic/LLVMInitialize.h"
#include "swift/Basic/InitializeSwiftModules.h"
#include "swift/Basic/Mangler.h"
#include "swift/Basic/LLVMInitialize.h"
#include "swift/Basic/Statistic.h"
#include "swift/Basic/Version.h"
#include "swift/Demangling/Demangler.h"
#include "swift/Demangling/ManglingMacros.h"

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/BinaryByteStream.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/NativeFormatting.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/VirtualFileSystem.h"
Expand Down Expand Up @@ -187,12 +181,6 @@ static SourceKit::Context &getGlobalContext() {
return *GlobalCtx;
}

static sourcekitd_response_t demangleNames(ArrayRef<const char *> MangledNames,
bool Simplified);

static sourcekitd_response_t
mangleSimpleClassNames(ArrayRef<std::pair<StringRef, StringRef>> ModuleClassPairs);

static sourcekitd_response_t indexSource(StringRef Filename,
ArrayRef<const char *> Args);

Expand Down Expand Up @@ -620,7 +608,21 @@ static void handleRequestDemangle(const RequestDict &Req,
}
int64_t Simplified = false;
Req.getInt64(KeySimplified, Simplified, /*isOptional=*/true);
return Rec(demangleNames(MangledNames, Simplified));

LangSupport &Lang = getGlobalContext().getSwiftLangSupport();
Lang.demangleNames(MangledNames, Simplified, [Rec](auto result) {
if (result.isError())
return Rec(createErrorRequestFailed(result.getError()));
if (result.isCancelled())
return Rec(createErrorRequestFailed(result.getError()));
ResponseBuilder RespBuilder;
auto Arr = RespBuilder.getDictionary().setArray(KeyResults);
for (auto demangldedName : result.value()) {
auto Entry = Arr.appendDictionary();
Entry.set(KeyName, demangldedName.c_str());
}
Rec(RespBuilder.createResponse());
});
}
}

Expand Down Expand Up @@ -652,7 +654,20 @@ handleRequestMangleSimpleClass(const RequestDict &Req,
return Rec(err);
}

return Rec(mangleSimpleClassNames(ModuleClassPairs));
LangSupport &Lang = getGlobalContext().getSwiftLangSupport();
Lang.mangleSimpleClassNames(ModuleClassPairs, [Rec](auto result) {
if (result.isError())
return Rec(createErrorRequestFailed(result.getError()));
if (result.isCancelled())
return Rec(createErrorRequestFailed(result.getError()));
ResponseBuilder RespBuilder;
auto Arr = RespBuilder.getDictionary().setArray(KeyResults);
for (auto &mangledName : result.value()) {
auto Entry = Arr.appendDictionary();
Entry.set(KeyName, mangledName.c_str());
}
Rec(RespBuilder.createResponse());
});
}
}

Expand Down Expand Up @@ -2054,78 +2069,6 @@ class SKDocConsumer : public DocInfoConsumer {
};
} // end anonymous namespace

static sourcekitd_response_t demangleNames(ArrayRef<const char *> MangledNames,
bool Simplified) {
swift::Demangle::DemangleOptions DemangleOptions;
if (Simplified) {
DemangleOptions =
swift::Demangle::DemangleOptions::SimplifiedUIDemangleOptions();
}

auto getDemangledName = [&](StringRef MangledName) -> std::string {
if (!swift::Demangle::isSwiftSymbol(MangledName))
return std::string(); // Not a mangled name

std::string Result = swift::Demangle::demangleSymbolAsString(
MangledName, DemangleOptions);

if (Result == MangledName)
return std::string(); // Not a mangled name

return Result;
};

ResponseBuilder RespBuilder;
auto Arr = RespBuilder.getDictionary().setArray(KeyResults);
for (auto MangledName : MangledNames) {
std::string Result = getDemangledName(MangledName);
auto Entry = Arr.appendDictionary();
Entry.set(KeyName, Result.c_str());
}

return RespBuilder.createResponse();
}

static ManglingErrorOr<std::string> mangleSimpleClass(StringRef moduleName,
StringRef className) {
using namespace swift::Demangle;
Demangler Dem;
auto moduleNode = Dem.createNode(Node::Kind::Module, moduleName);
auto IdNode = Dem.createNode(Node::Kind::Identifier, className);
auto classNode = Dem.createNode(Node::Kind::Class);
auto typeNode = Dem.createNode(Node::Kind::Type);
auto typeManglingNode = Dem.createNode(Node::Kind::TypeMangling);
auto globalNode = Dem.createNode(Node::Kind::Global);

classNode->addChild(moduleNode, Dem);
classNode->addChild(IdNode, Dem);
typeNode->addChild(classNode, Dem);
typeManglingNode->addChild(typeNode, Dem);
globalNode->addChild(typeManglingNode, Dem);
return mangleNode(globalNode);
}

static sourcekitd_response_t
mangleSimpleClassNames(ArrayRef<std::pair<StringRef, StringRef>> ModuleClassPairs) {
ResponseBuilder RespBuilder;
auto Arr = RespBuilder.getDictionary().setArray(KeyResults);
for (auto &pair : ModuleClassPairs) {
auto Mangling = mangleSimpleClass(pair.first, pair.second);
if (!Mangling.isSuccess()) {
std::string message = "name mangling failed for ";
message += pair.first.str();
message += ".";
message += pair.second.str();
return createErrorRequestFailed(message);
}
std::string Result = Mangling.result();
auto Entry = Arr.appendDictionary();
Entry.set(KeyName, Result.c_str());
}

return RespBuilder.createResponse();
}

static sourcekitd_response_t reportDocInfo(llvm::MemoryBuffer *InputBuf,
StringRef ModuleName,
ArrayRef<const char *> Args) {
Expand Down