Skip to content

Commit

Permalink
[SourceKit] Check if the realpath of a module is inside the SDK to de…
Browse files Browse the repository at this point in the history
…cide if it's system

On Windows, we run into the following situation when running SourceKit-LSP tests:
- The SDK is located at `S:\Program Files\Swift\Platforms\Windows.platform\Developer\SDKs\Windows.sdk` with `S:` being a substitution drive
- We find `Swift.swiftmodule` at `S:\Program Files\Swift\Platforms\Windows.platform\Developer\SDKs\Windows.sdk\usr\lib\swift\windows\Swift.swiftmodule`
- Now, to check if `Swift.swiftmodule` is a system module, we take the realpath of the SDK, which resolves the substitution drive an results in something like `C:\Users\alex\src\Program Files\Swift\Platforms\Windows.platform\Developer\SDKs\Windows.sdk`
- Since we don’t take the realpath of `Swift.swiftmodule`, we will assume that it’s not in the SDK, because the SDK’s path is on `C:` while `Swift.swiftmodule` lives on `S:`

To fix this, we also need to check if a module’s real path is inside the SDK.

Fixes swiftlang/sourcekit-lsp#1770
rdar://138210224
  • Loading branch information
ahoppen committed Oct 19, 2024
1 parent b7f551f commit 50ae6c6
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 2 deletions.
23 changes: 21 additions & 2 deletions lib/AST/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4004,8 +4004,27 @@ bool IsNonUserModuleRequest::evaluate(Evaluator &evaluator, ModuleDecl *mod) con
auto sdkOrPlatform = searchPathOpts.getSDKPlatformPath(FS).value_or(sdkPath);

StringRef runtimePath = searchPathOpts.RuntimeResourcePath;
return (!runtimePath.empty() && pathStartsWith(runtimePath, modulePath)) ||
(!sdkOrPlatform.empty() && pathStartsWith(sdkOrPlatform, modulePath));
if (!runtimePath.empty() && pathStartsWith(runtimePath, modulePath)) {
return true;
}
if (!sdkOrPlatform.empty() && pathStartsWith(sdkOrPlatform, modulePath)) {
return true;
}

// `getSDKPlatformPath` returns a real path but the module might have path
// inside a symlink pointing to that real path. To catch this case, also check
// whether the module's real path is inside the SDK's real path.
llvm::SmallString<128> moduleRealPath;
if (FS->getRealPath(modulePath, moduleRealPath)) {
modulePath = moduleRealPath;
}
if (!runtimePath.empty() && pathStartsWith(runtimePath, moduleRealPath)) {
return true;
}
if (!sdkOrPlatform.empty() && pathStartsWith(sdkOrPlatform, moduleRealPath)) {
return true;
}
return false;
}

version::Version ModuleDecl::getLanguageVersionBuiltWith() const {
Expand Down
10 changes: 10 additions & 0 deletions validation-test/IDE/complete_sdk_is_symlink.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// UNSUPPORTED: OS=windows-msvc

// RUN: %empty-directory(%t)
// RUN: ln -s %sdk %t/sdk
// RUN: ln -s %test_resource_dir %t/test_resource_dir

// RUN: %batch-code-completion -sdk %t/sdk -resource-dir %t/test_resource_dir

#^COMPLETE^#
// COMPLETE: Decl[FreeFunction]/OtherModule[Swift]/IsSystem: print

0 comments on commit 50ae6c6

Please sign in to comment.