mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge pull request #31521 from owenv/sourcekit-find-edu-notes
[SourceKit] Discover diagnostic documentation relative to sourcekitd
This commit is contained in:
@@ -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: ]
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -36,12 +36,16 @@ 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)),
|
||||
Config(new GlobalConfig()) {
|
||||
LangSupportFactoryFn,
|
||||
bool shouldDispatchNotificationsOnMain)
|
||||
: RuntimeLibPath(RuntimeLibPath),
|
||||
DiagnosticDocumentationPath(DiagnosticDocumentationPath),
|
||||
NotificationCtr(
|
||||
new NotificationCenter(shouldDispatchNotificationsOnMain)),
|
||||
Config(new GlobalConfig()) {
|
||||
// Should be called last after everything is initialized.
|
||||
SwiftLang = LangSupportFactoryFn(*this);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
|
||||
@@ -187,24 +187,39 @@ public:
|
||||
};
|
||||
}
|
||||
|
||||
std::string sourcekitd::getRuntimeLibPath() {
|
||||
std::string MainExePath = llvm::sys::fs::getMainExecutable("sourcekit",
|
||||
reinterpret_cast<void *>(&anchorForGetMainExecutableInXPCService));
|
||||
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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -113,8 +113,10 @@ static SourceKit::Context *GlobalCtx = nullptr;
|
||||
|
||||
void sourcekitd::initialize() {
|
||||
llvm::EnablePrettyStackTrace();
|
||||
GlobalCtx = new SourceKit::Context(sourcekitd::getRuntimeLibPath(),
|
||||
SourceKit::createSwiftLangSupport);
|
||||
GlobalCtx =
|
||||
new SourceKit::Context(sourcekitd::getRuntimeLibPath(),
|
||||
sourcekitd::getDiagnosticDocumentationPath(),
|
||||
SourceKit::createSwiftLangSupport);
|
||||
GlobalCtx->getNotificationCenter()->addDocumentUpdateNotificationReceiver(
|
||||
onDocumentUpdateNotification);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>();
|
||||
|
||||
Reference in New Issue
Block a user