Merge pull request #31521 from owenv/sourcekit-find-edu-notes

[SourceKit] Discover diagnostic documentation relative to sourcekitd
This commit is contained in:
Owen Voorhees
2020-05-06 19:54:02 -05:00
committed by GitHub
13 changed files with 108 additions and 43 deletions

View File

@@ -1,8 +1,16 @@
extension (Int, Int) {}
// RUN: %sourcekitd-test -req=sema %s -- -Xfrontend -print-educational-notes -Xfrontend -diagnostic-documentation-path -Xfrontend /educational/notes/path/prefix %s | %FileCheck %s -check-prefix=DESCRIPTIVE
// RUN: %sourcekitd-test -req=sema %s -- %s | %FileCheck %s -check-prefix=NO_OVERRIDE
// NO_OVERRIDE: key.description: "non-nominal type
// NO_OVERRIDE: key.educational_note_paths: [
// NO_OVERRIDE-NEXT: share{{[/\\]+}}doc{{[/\\]+}}swift{{[/\\]+}}diagnostics{{[/\\]+}}nominal-types.md"
// NO_OVERRIDE-NEXT: ]
// RUN: %sourcekitd-test -req=sema %s -- -Xfrontend -diagnostic-documentation-path -Xfrontend /educational/notes/path/prefix %s | %FileCheck %s -check-prefix=OVERRIDE
// OVERRIDE: key.description: "non-nominal type
// OVERRIDE: key.educational_note_paths: [
// OVERRIDE-NEXT: "{{[/\\]+}}educational{{[/\\]+}}notes{{[/\\]+}}path{{[/\\]+}}prefix{{[/\\]+}}nominal-types.md"
// OVERRIDE-NEXT: ]
// DESCRIPTIVE: key.description: "non-nominal type
// DESCRIPTIVE: key.educational_note_paths: [
// DESCRIPTIVE-NEXT: "{{[/\\]+}}educational{{[/\\]+}}notes{{[/\\]+}}path{{[/\\]+}}prefix{{[/\\]+}}nominal-types.md"
// DESCRIPTIVE-NEXT: ]

View File

@@ -54,18 +54,22 @@ public:
class Context {
std::string RuntimeLibPath;
std::string DiagnosticDocumentationPath;
std::unique_ptr<LangSupport> SwiftLang;
std::shared_ptr<NotificationCenter> NotificationCtr;
std::shared_ptr<GlobalConfig> Config;
public:
Context(StringRef RuntimeLibPath,
llvm::function_ref<
std::unique_ptr<LangSupport>(Context &)> LangSupportFactoryFn,
Context(StringRef RuntimeLibPath, StringRef DiagnosticDocumentationPath,
llvm::function_ref<std::unique_ptr<LangSupport>(Context &)>
LangSupportFactoryFn,
bool shouldDispatchNotificationsOnMain = true);
~Context();
StringRef getRuntimeLibPath() const { return RuntimeLibPath; }
StringRef getDiagnosticDocumentationPath() const {
return DiagnosticDocumentationPath;
}
LangSupport &getSwiftLangSupport() { return *SwiftLang; }

View File

@@ -36,11 +36,15 @@ unsigned GlobalConfig::getCompletionCheckDependencyInterval() const {
return State.CompletionCheckDependencyInterval;
}
SourceKit::Context::Context(StringRef RuntimeLibPath,
SourceKit::Context::Context(
StringRef RuntimeLibPath, StringRef DiagnosticDocumentationPath,
llvm::function_ref<std::unique_ptr<LangSupport>(Context &)>
LangSupportFactoryFn,
bool shouldDispatchNotificationsOnMain) : RuntimeLibPath(RuntimeLibPath),
NotificationCtr(new NotificationCenter(shouldDispatchNotificationsOnMain)),
bool shouldDispatchNotificationsOnMain)
: RuntimeLibPath(RuntimeLibPath),
DiagnosticDocumentationPath(DiagnosticDocumentationPath),
NotificationCtr(
new NotificationCenter(shouldDispatchNotificationsOnMain)),
Config(new GlobalConfig()) {
// Should be called last after everything is initialized.
SwiftLang = LangSupportFactoryFn(*this);

View File

@@ -373,9 +373,11 @@ struct SwiftASTManager::Implementation {
explicit Implementation(
std::shared_ptr<SwiftEditorDocumentFileMap> EditorDocs,
std::shared_ptr<GlobalConfig> Config,
std::shared_ptr<SwiftStatistics> Stats, StringRef RuntimeResourcePath)
std::shared_ptr<SwiftStatistics> Stats, StringRef RuntimeResourcePath,
StringRef DiagnosticDocumentationPath)
: EditorDocs(EditorDocs), Config(Config), Stats(Stats),
RuntimeResourcePath(RuntimeResourcePath),
DiagnosticDocumentationPath(DiagnosticDocumentationPath),
SessionTimestamp(llvm::sys::toTimeT(std::chrono::system_clock::now())) {
}
@@ -383,6 +385,7 @@ struct SwiftASTManager::Implementation {
std::shared_ptr<GlobalConfig> Config;
std::shared_ptr<SwiftStatistics> Stats;
std::string RuntimeResourcePath;
std::string DiagnosticDocumentationPath;
SourceManager SourceMgr;
Cache<ASTKey, ASTProducerRef> ASTCache{ "sourcekit.swift.ASTCache" };
llvm::sys::Mutex CacheMtx;
@@ -408,9 +411,10 @@ struct SwiftASTManager::Implementation {
SwiftASTManager::SwiftASTManager(
std::shared_ptr<SwiftEditorDocumentFileMap> EditorDocs,
std::shared_ptr<GlobalConfig> Config,
std::shared_ptr<SwiftStatistics> Stats, StringRef RuntimeResourcePath)
: Impl(*new Implementation(EditorDocs, Config, Stats,
RuntimeResourcePath)) {}
std::shared_ptr<SwiftStatistics> Stats, StringRef RuntimeResourcePath,
StringRef DiagnosticDocumentationPath)
: Impl(*new Implementation(EditorDocs, Config, Stats, RuntimeResourcePath,
DiagnosticDocumentationPath)) {}
SwiftASTManager::~SwiftASTManager() {
delete &Impl;
@@ -485,10 +489,14 @@ bool SwiftASTManager::initCompilerInvocation(
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem,
std::string &Error) {
SmallVector<const char *, 16> Args;
// Make sure to put '-resource-dir' at the top to allow overriding it by
// the passed in arguments.
// Make sure to put '-resource-dir' and '-diagnostic-documentation-path' at
// the top to allow overriding them with the passed in arguments.
Args.push_back("-resource-dir");
Args.push_back(Impl.RuntimeResourcePath.c_str());
Args.push_back("-Xfrontend");
Args.push_back("-diagnostic-documentation-path");
Args.push_back("-Xfrontend");
Args.push_back(Impl.DiagnosticDocumentationPath.c_str());
Args.append(OrigArgs.begin(), OrigArgs.end());
SmallString<32> ErrStr;

View File

@@ -92,7 +92,8 @@ public:
explicit SwiftASTManager(std::shared_ptr<SwiftEditorDocumentFileMap>,
std::shared_ptr<GlobalConfig> Config,
std::shared_ptr<SwiftStatistics> Stats,
StringRef RuntimeResourcePath);
StringRef RuntimeResourcePath,
StringRef DiagnosticDocumentationPath);
~SwiftASTManager();
SwiftInvocationRef getInvocation(

View File

@@ -270,12 +270,13 @@ SwiftLangSupport::SwiftLangSupport(SourceKit::Context &SKCtx)
llvm::SmallString<128> LibPath(SKCtx.getRuntimeLibPath());
llvm::sys::path::append(LibPath, "swift");
RuntimeResourcePath = std::string(LibPath.str());
DiagnosticDocumentationPath = SKCtx.getDiagnosticDocumentationPath();
Stats = std::make_shared<SwiftStatistics>();
EditorDocuments = std::make_shared<SwiftEditorDocumentFileMap>();
ASTMgr = std::make_shared<SwiftASTManager>(EditorDocuments,
SKCtx.getGlobalConfiguration(),
Stats, RuntimeResourcePath);
ASTMgr = std::make_shared<SwiftASTManager>(
EditorDocuments, SKCtx.getGlobalConfiguration(), Stats,
RuntimeResourcePath, DiagnosticDocumentationPath);
CompletionInst = std::make_shared<CompletionInstance>();
configureCompletionInstance(CompletionInst, SKCtx.getGlobalConfiguration());

View File

@@ -286,6 +286,7 @@ struct SwiftStatistics {
class SwiftLangSupport : public LangSupport {
std::shared_ptr<NotificationCenter> NotificationCtr;
std::string RuntimeResourcePath;
std::string DiagnosticDocumentationPath;
std::shared_ptr<SwiftASTManager> ASTMgr;
std::shared_ptr<SwiftEditorDocumentFileMap> EditorDocuments;
SwiftInterfaceGenMap IFaceGenContexts;
@@ -306,6 +307,9 @@ public:
}
StringRef getRuntimeResourcePath() const { return RuntimeResourcePath; }
StringRef getDiagnosticDocumentationPath() const {
return DiagnosticDocumentationPath;
}
std::shared_ptr<SwiftASTManager> getASTManager() { return ASTMgr; }

View File

@@ -80,10 +80,9 @@ UIdent sourcekitd::UIdentFromSKDUID(sourcekitd_uid_t uid) {
return UIdent::getFromOpaqueValue(uid);
}
std::string sourcekitd::getRuntimeLibPath() {
static void getToolchainPrefixPath(llvm::SmallVectorImpl<char> &Path) {
#if defined(_WIN32)
MEMORY_BASIC_INFORMATION mbi;
llvm::SmallString<128> libPath;
char path[MAX_PATH + 1];
if (!VirtualQuery(static_cast<void *>(sourcekitd_initialize), &mbi,
sizeof(mbi)))
@@ -91,20 +90,36 @@ std::string sourcekitd::getRuntimeLibPath() {
if (!GetModuleFileNameA(static_cast<HINSTANCE>(mbi.AllocationBase), path,
MAX_PATH))
llvm_unreachable("call to GetModuleFileNameA failed");
libPath = llvm::sys::path::parent_path(llvm::sys::path::parent_path(path));
llvm::sys::path::append(libPath, "lib");
return libPath.str().str();
auto parent =
llvm::sys::path::parent_path(llvm::sys::path::parent_path(path));
Path.append(parent.begin(), parent.end());
#else
// This silly cast below avoids a C++ warning.
Dl_info info;
if (dladdr((void *)(uintptr_t)sourcekitd_initialize, &info) == 0)
llvm_unreachable("Call to dladdr() failed");
// We now have the path to the shared lib, move to the parent 'lib' path.
return llvm::sys::path::parent_path(info.dli_fname).str();
// We now have the path to the shared lib, move to the parent prefix path.
auto parent = llvm::sys::path::parent_path(
llvm::sys::path::parent_path(info.dli_fname));
Path.append(parent.begin(), parent.end());
#endif
}
std::string sourcekitd::getRuntimeLibPath() {
llvm::SmallString<128> libPath;
getToolchainPrefixPath(libPath);
llvm::sys::path::append(libPath, "lib");
return libPath.str().str();
}
std::string sourcekitd::getDiagnosticDocumentationPath() {
llvm::SmallString<128> docPath;
getToolchainPrefixPath(docPath);
llvm::sys::path::append(docPath, "share", "doc", "swift", "diagnostics");
return docPath.str().str();
}
void sourcekitd::set_interrupted_connection_handler(
llvm::function_ref<void()> handler) {
}

View File

@@ -187,24 +187,39 @@ public:
};
}
std::string sourcekitd::getRuntimeLibPath() {
std::string MainExePath = llvm::sys::fs::getMainExecutable("sourcekit",
static void getToolchainPrefixPath(llvm::SmallVectorImpl<char> &Path) {
std::string executablePath = llvm::sys::fs::getMainExecutable(
"sourcekit",
reinterpret_cast<void *>(&anchorForGetMainExecutableInXPCService));
Path.append(executablePath.begin(), executablePath.end());
#ifdef SOURCEKIT_UNVERSIONED_FRAMEWORK_BUNDLE
// MainExePath points to "lib/sourcekitd.framework/XPCServices/
// Path points to e.g. "usr/lib/sourcekitd.framework/XPCServices/
// SourceKitService.xpc/SourceKitService"
const unsigned MainExeLibNestingLevel = 4;
const unsigned MainExeLibNestingLevel = 5;
#else
// MainExePath points to "lib/sourcekitd.framework/Versions/Current/XPCServices/
// Path points to e.g.
// "usr/lib/sourcekitd.framework/Versions/Current/XPCServices/
// SourceKitService.xpc/Contents/MacOS/SourceKitService"
const unsigned MainExeLibNestingLevel = 8;
const unsigned MainExeLibNestingLevel = 9;
#endif
// Get it to lib.
StringRef Path = MainExePath;
// Get it to usr.
for (unsigned i = 0; i < MainExeLibNestingLevel; ++i)
Path = llvm::sys::path::parent_path(Path);
return Path.str();
llvm::sys::path::remove_filename(Path);
}
std::string sourcekitd::getRuntimeLibPath() {
llvm::SmallString<128> path;
getToolchainPrefixPath(path);
llvm::sys::path::append(path, "lib");
return path.str().str();
}
std::string sourcekitd::getDiagnosticDocumentationPath() {
llvm::SmallString<128> path;
getToolchainPrefixPath(path);
llvm::sys::path::append(path, "share", "doc", "swift", "diagnostics");
return path.str().str();
}
static void sourcekitdServer_peer_event_handler(xpc_connection_t peer,

View File

@@ -174,6 +174,7 @@ sourcekitd_uid_t SKDUIDFromUIdent(SourceKit::UIdent UID);
SourceKit::UIdent UIdentFromSKDUID(sourcekitd_uid_t uid);
std::string getRuntimeLibPath();
std::string getDiagnosticDocumentationPath();
void writeEscaped(llvm::StringRef Str, llvm::raw_ostream &OS);

View File

@@ -113,7 +113,9 @@ static SourceKit::Context *GlobalCtx = nullptr;
void sourcekitd::initialize() {
llvm::EnablePrettyStackTrace();
GlobalCtx = new SourceKit::Context(sourcekitd::getRuntimeLibPath(),
GlobalCtx =
new SourceKit::Context(sourcekitd::getRuntimeLibPath(),
sourcekitd::getDiagnosticDocumentationPath(),
SourceKit::createSwiftLangSupport);
GlobalCtx->getNotificationCenter()->addDocumentUpdateNotificationReceiver(
onDocumentUpdateNotification);

View File

@@ -116,6 +116,7 @@ public:
CursorInfoTest()
: Ctx(*new SourceKit::Context(getRuntimeLibPath(),
/*diagnosticDocumentationPath*/ "",
SourceKit::createSwiftLangSupport,
/*dispatchOnMain=*/false)) {
// This is avoiding destroying \p SourceKit::Context because another

View File

@@ -114,6 +114,7 @@ public:
// thread may be active trying to use it to post notifications.
// FIXME: Use shared_ptr ownership to avoid such issues.
Ctx = new SourceKit::Context(getRuntimeLibPath(),
/*diagnosticDocumentationPath*/ "",
SourceKit::createSwiftLangSupport,
/*dispatchOnMain=*/false);
auto localDocUpdState = std::make_shared<DocUpdateMutexState>();