Skip to content

Commit eb8aeba

Browse files
committed
[SourceKit] Discover diagnostic documentation relative to sourcekitd
1 parent b2a742c commit eb8aeba

File tree

13 files changed

+108
-43
lines changed

13 files changed

+108
-43
lines changed

test/SourceKit/Sema/educational_note_diags.swift

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
extension (Int, Int) {}
22

3-
// 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
3+
// RUN: %sourcekitd-test -req=sema %s -- %s | %FileCheck %s -check-prefix=NO_OVERRIDE
4+
5+
// NO_OVERRIDE: key.description: "non-nominal type
6+
// NO_OVERRIDE: key.educational_note_paths: [
7+
// NO_OVERRIDE-NEXT: share{{[/\\]+}}doc{{[/\\]+}}swift{{[/\\]+}}diagnostics{{[/\\]+}}nominal-types.md"
8+
// NO_OVERRIDE-NEXT: ]
9+
10+
// RUN: %sourcekitd-test -req=sema %s -- -Xfrontend -diagnostic-documentation-path -Xfrontend /educational/notes/path/prefix %s | %FileCheck %s -check-prefix=OVERRIDE
11+
12+
// OVERRIDE: key.description: "non-nominal type
13+
// OVERRIDE: key.educational_note_paths: [
14+
// OVERRIDE-NEXT: "{{[/\\]+}}educational{{[/\\]+}}notes{{[/\\]+}}path{{[/\\]+}}prefix{{[/\\]+}}nominal-types.md"
15+
// OVERRIDE-NEXT: ]
416

5-
// DESCRIPTIVE: key.description: "non-nominal type
6-
// DESCRIPTIVE: key.educational_note_paths: [
7-
// DESCRIPTIVE-NEXT: "{{[/\\]+}}educational{{[/\\]+}}notes{{[/\\]+}}path{{[/\\]+}}prefix{{[/\\]+}}nominal-types.md"
8-
// DESCRIPTIVE-NEXT: ]

tools/SourceKit/include/SourceKit/Core/Context.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,22 @@ class GlobalConfig {
4949

5050
class Context {
5151
std::string RuntimeLibPath;
52+
std::string DiagnosticDocumentationPath;
5253
std::unique_ptr<LangSupport> SwiftLang;
5354
std::shared_ptr<NotificationCenter> NotificationCtr;
5455
std::shared_ptr<GlobalConfig> Config;
5556

5657
public:
57-
Context(StringRef RuntimeLibPath,
58-
llvm::function_ref<
59-
std::unique_ptr<LangSupport>(Context &)> LangSupportFactoryFn,
58+
Context(StringRef RuntimeLibPath, StringRef DiagnosticDocumentationPath,
59+
llvm::function_ref<std::unique_ptr<LangSupport>(Context &)>
60+
LangSupportFactoryFn,
6061
bool shouldDispatchNotificationsOnMain = true);
6162
~Context();
6263

6364
StringRef getRuntimeLibPath() const { return RuntimeLibPath; }
65+
StringRef getDiagnosticDocumentationPath() const {
66+
return DiagnosticDocumentationPath;
67+
}
6468

6569
LangSupport &getSwiftLangSupport() { return *SwiftLang; }
6670

tools/SourceKit/lib/Core/Context.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,16 @@ bool GlobalConfig::shouldOptimizeForIDE() const {
2929
return State.OptimizeForIDE;
3030
}
3131

32-
SourceKit::Context::Context(StringRef RuntimeLibPath,
32+
SourceKit::Context::Context(
33+
StringRef RuntimeLibPath, StringRef DiagnosticDocumentationPath,
3334
llvm::function_ref<std::unique_ptr<LangSupport>(Context &)>
34-
LangSupportFactoryFn,
35-
bool shouldDispatchNotificationsOnMain) : RuntimeLibPath(RuntimeLibPath),
36-
NotificationCtr(new NotificationCenter(shouldDispatchNotificationsOnMain)),
37-
Config(new GlobalConfig()) {
35+
LangSupportFactoryFn,
36+
bool shouldDispatchNotificationsOnMain)
37+
: RuntimeLibPath(RuntimeLibPath),
38+
DiagnosticDocumentationPath(DiagnosticDocumentationPath),
39+
NotificationCtr(
40+
new NotificationCenter(shouldDispatchNotificationsOnMain)),
41+
Config(new GlobalConfig()) {
3842
// Should be called last after everything is initialized.
3943
SwiftLang = LangSupportFactoryFn(*this);
4044
}

tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -373,16 +373,19 @@ struct SwiftASTManager::Implementation {
373373
explicit Implementation(
374374
std::shared_ptr<SwiftEditorDocumentFileMap> EditorDocs,
375375
std::shared_ptr<GlobalConfig> Config,
376-
std::shared_ptr<SwiftStatistics> Stats, StringRef RuntimeResourcePath)
376+
std::shared_ptr<SwiftStatistics> Stats, StringRef RuntimeResourcePath,
377+
StringRef DiagnosticDocumentationPath)
377378
: EditorDocs(EditorDocs), Config(Config), Stats(Stats),
378379
RuntimeResourcePath(RuntimeResourcePath),
380+
DiagnosticDocumentationPath(DiagnosticDocumentationPath),
379381
SessionTimestamp(llvm::sys::toTimeT(std::chrono::system_clock::now())) {
380382
}
381383

382384
std::shared_ptr<SwiftEditorDocumentFileMap> EditorDocs;
383385
std::shared_ptr<GlobalConfig> Config;
384386
std::shared_ptr<SwiftStatistics> Stats;
385387
std::string RuntimeResourcePath;
388+
std::string DiagnosticDocumentationPath;
386389
SourceManager SourceMgr;
387390
Cache<ASTKey, ASTProducerRef> ASTCache{ "sourcekit.swift.ASTCache" };
388391
llvm::sys::Mutex CacheMtx;
@@ -408,9 +411,10 @@ struct SwiftASTManager::Implementation {
408411
SwiftASTManager::SwiftASTManager(
409412
std::shared_ptr<SwiftEditorDocumentFileMap> EditorDocs,
410413
std::shared_ptr<GlobalConfig> Config,
411-
std::shared_ptr<SwiftStatistics> Stats, StringRef RuntimeResourcePath)
412-
: Impl(*new Implementation(EditorDocs, Config, Stats,
413-
RuntimeResourcePath)) {}
414+
std::shared_ptr<SwiftStatistics> Stats, StringRef RuntimeResourcePath,
415+
StringRef DiagnosticDocumentationPath)
416+
: Impl(*new Implementation(EditorDocs, Config, Stats, RuntimeResourcePath,
417+
DiagnosticDocumentationPath)) {}
414418

415419
SwiftASTManager::~SwiftASTManager() {
416420
delete &Impl;
@@ -485,10 +489,14 @@ bool SwiftASTManager::initCompilerInvocation(
485489
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem,
486490
std::string &Error) {
487491
SmallVector<const char *, 16> Args;
488-
// Make sure to put '-resource-dir' at the top to allow overriding it by
489-
// the passed in arguments.
492+
// Make sure to put '-resource-dir' and '-diagnostic-documentation-path' at
493+
// the top to allow overriding them with the passed in arguments.
490494
Args.push_back("-resource-dir");
491495
Args.push_back(Impl.RuntimeResourcePath.c_str());
496+
Args.push_back("-Xfrontend");
497+
Args.push_back("-diagnostic-documentation-path");
498+
Args.push_back("-Xfrontend");
499+
Args.push_back(Impl.DiagnosticDocumentationPath.c_str());
492500
Args.append(OrigArgs.begin(), OrigArgs.end());
493501

494502
SmallString<32> ErrStr;

tools/SourceKit/lib/SwiftLang/SwiftASTManager.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ class SwiftASTManager : public std::enable_shared_from_this<SwiftASTManager> {
9292
explicit SwiftASTManager(std::shared_ptr<SwiftEditorDocumentFileMap>,
9393
std::shared_ptr<GlobalConfig> Config,
9494
std::shared_ptr<SwiftStatistics> Stats,
95-
StringRef RuntimeResourcePath);
95+
StringRef RuntimeResourcePath,
96+
StringRef DiagnosticDocumentationPath);
9697
~SwiftASTManager();
9798

9899
SwiftInvocationRef getInvocation(

tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,12 +263,13 @@ SwiftLangSupport::SwiftLangSupport(SourceKit::Context &SKCtx)
263263
llvm::SmallString<128> LibPath(SKCtx.getRuntimeLibPath());
264264
llvm::sys::path::append(LibPath, "swift");
265265
RuntimeResourcePath = std::string(LibPath.str());
266+
DiagnosticDocumentationPath = SKCtx.getDiagnosticDocumentationPath();
266267

267268
Stats = std::make_shared<SwiftStatistics>();
268269
EditorDocuments = std::make_shared<SwiftEditorDocumentFileMap>();
269-
ASTMgr = std::make_shared<SwiftASTManager>(EditorDocuments,
270-
SKCtx.getGlobalConfiguration(),
271-
Stats, RuntimeResourcePath);
270+
ASTMgr = std::make_shared<SwiftASTManager>(
271+
EditorDocuments, SKCtx.getGlobalConfiguration(), Stats,
272+
RuntimeResourcePath, DiagnosticDocumentationPath);
272273

273274
CompletionInst = std::make_unique<CompletionInstance>();
274275

tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ struct SwiftStatistics {
286286
class SwiftLangSupport : public LangSupport {
287287
std::shared_ptr<NotificationCenter> NotificationCtr;
288288
std::string RuntimeResourcePath;
289+
std::string DiagnosticDocumentationPath;
289290
std::shared_ptr<SwiftASTManager> ASTMgr;
290291
std::shared_ptr<SwiftEditorDocumentFileMap> EditorDocuments;
291292
SwiftInterfaceGenMap IFaceGenContexts;
@@ -306,6 +307,9 @@ class SwiftLangSupport : public LangSupport {
306307
}
307308

308309
StringRef getRuntimeResourcePath() const { return RuntimeResourcePath; }
310+
StringRef getDiagnosticDocumentationPath() const {
311+
return DiagnosticDocumentationPath;
312+
}
309313

310314
std::shared_ptr<SwiftASTManager> getASTManager() { return ASTMgr; }
311315

tools/SourceKit/tools/sourcekitd/bin/InProc/sourcekitdInProc.cpp

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,31 +80,46 @@ UIdent sourcekitd::UIdentFromSKDUID(sourcekitd_uid_t uid) {
8080
return UIdent::getFromOpaqueValue(uid);
8181
}
8282

83-
std::string sourcekitd::getRuntimeLibPath() {
83+
static void getToolchainPrefixPath(llvm::SmallVectorImpl<char> &Path) {
8484
#if defined(_WIN32)
8585
MEMORY_BASIC_INFORMATION mbi;
86-
llvm::SmallString<128> libPath;
8786
char path[MAX_PATH + 1];
8887
if (!VirtualQuery(static_cast<void *>(sourcekitd_initialize), &mbi,
8988
sizeof(mbi)))
9089
llvm_unreachable("call to VirtualQuery failed");
9190
if (!GetModuleFileNameA(static_cast<HINSTANCE>(mbi.AllocationBase), path,
9291
MAX_PATH))
9392
llvm_unreachable("call to GetModuleFileNameA failed");
94-
libPath = llvm::sys::path::parent_path(llvm::sys::path::parent_path(path));
95-
llvm::sys::path::append(libPath, "lib");
96-
return libPath.str().str();
93+
auto parent =
94+
llvm::sys::path::parent_path(llvm::sys::path::parent_path(path));
95+
Path.append(parent.begin(), parent.end());
9796
#else
9897
// This silly cast below avoids a C++ warning.
9998
Dl_info info;
10099
if (dladdr((void *)(uintptr_t)sourcekitd_initialize, &info) == 0)
101100
llvm_unreachable("Call to dladdr() failed");
102101

103-
// We now have the path to the shared lib, move to the parent 'lib' path.
104-
return llvm::sys::path::parent_path(info.dli_fname).str();
102+
// We now have the path to the shared lib, move to the parent prefix path.
103+
auto parent = llvm::sys::path::parent_path(
104+
llvm::sys::path::parent_path(info.dli_fname));
105+
Path.append(parent.begin(), parent.end());
105106
#endif
106107
}
107108

109+
std::string sourcekitd::getRuntimeLibPath() {
110+
llvm::SmallString<128> libPath;
111+
getToolchainPrefixPath(libPath);
112+
llvm::sys::path::append(libPath, "lib");
113+
return libPath.str().str();
114+
}
115+
116+
std::string sourcekitd::getDiagnosticDocumentationPath() {
117+
llvm::SmallString<128> docPath;
118+
getToolchainPrefixPath(docPath);
119+
llvm::sys::path::append(docPath, "share", "doc", "swift", "diagnostics");
120+
return docPath.str().str();
121+
}
122+
108123
void sourcekitd::set_interrupted_connection_handler(
109124
llvm::function_ref<void()> handler) {
110125
}

tools/SourceKit/tools/sourcekitd/bin/XPC/Service/XPCService.cpp

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -187,24 +187,39 @@ class XPCResponder {
187187
};
188188
}
189189

190-
std::string sourcekitd::getRuntimeLibPath() {
191-
std::string MainExePath = llvm::sys::fs::getMainExecutable("sourcekit",
192-
reinterpret_cast<void *>(&anchorForGetMainExecutableInXPCService));
190+
static void getToolchainPrefixPath(llvm::SmallVectorImpl<char> &Path) {
191+
std::string executablePath = llvm::sys::fs::getMainExecutable(
192+
"sourcekit",
193+
reinterpret_cast<void *>(&anchorForGetMainExecutableInXPCService));
194+
Path.append(executablePath.begin(), executablePath.end());
193195
#ifdef SOURCEKIT_UNVERSIONED_FRAMEWORK_BUNDLE
194-
// MainExePath points to "lib/sourcekitd.framework/XPCServices/
196+
// Path points to e.g. "usr/lib/sourcekitd.framework/XPCServices/
195197
// SourceKitService.xpc/SourceKitService"
196-
const unsigned MainExeLibNestingLevel = 4;
198+
const unsigned MainExeLibNestingLevel = 5;
197199
#else
198-
// MainExePath points to "lib/sourcekitd.framework/Versions/Current/XPCServices/
200+
// Path points to e.g.
201+
// "usr/lib/sourcekitd.framework/Versions/Current/XPCServices/
199202
// SourceKitService.xpc/Contents/MacOS/SourceKitService"
200-
const unsigned MainExeLibNestingLevel = 8;
203+
const unsigned MainExeLibNestingLevel = 9;
201204
#endif
202205

203-
// Get it to lib.
204-
StringRef Path = MainExePath;
206+
// Get it to usr.
205207
for (unsigned i = 0; i < MainExeLibNestingLevel; ++i)
206-
Path = llvm::sys::path::parent_path(Path);
207-
return Path.str();
208+
llvm::sys::path::remove_filename(Path);
209+
}
210+
211+
std::string sourcekitd::getRuntimeLibPath() {
212+
llvm::SmallString<128> path;
213+
getToolchainPrefixPath(path);
214+
llvm::sys::path::append(path, "lib");
215+
return path.str().str();
216+
}
217+
218+
std::string sourcekitd::getDiagnosticDocumentationPath() {
219+
llvm::SmallString<128> path;
220+
getToolchainPrefixPath(path);
221+
llvm::sys::path::append(path, "share", "doc", "swift", "diagnostics");
222+
return path.str().str();
208223
}
209224

210225
static void sourcekitdServer_peer_event_handler(xpc_connection_t peer,

tools/SourceKit/tools/sourcekitd/include/sourcekitd/Internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ sourcekitd_uid_t SKDUIDFromUIdent(SourceKit::UIdent UID);
174174
SourceKit::UIdent UIdentFromSKDUID(sourcekitd_uid_t uid);
175175

176176
std::string getRuntimeLibPath();
177+
std::string getDiagnosticDocumentationPath();
177178

178179
void writeEscaped(llvm::StringRef Str, llvm::raw_ostream &OS);
179180

0 commit comments

Comments
 (0)