[SourceKit] Check if the realpath of a module is inside the SDK to decide 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
This commit is contained in:
Alex Hoppen
2024-10-18 22:37:58 -07:00
parent b7f551ffb5
commit a287e2ae8e
2 changed files with 31 additions and 2 deletions

View File

@@ -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 {