1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-28 16:20:57 -05:00

fix(lsp): scope attribution for asset documents (#24663)

This commit is contained in:
Nayeem Rahman 2024-07-22 15:06:08 +01:00 committed by GitHub
parent 95847f4e94
commit 5a696551b7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 19 additions and 3 deletions

View file

@ -153,7 +153,7 @@ impl AssetOrDocument {
pub fn scope(&self) -> Option<&ModuleSpecifier> { pub fn scope(&self) -> Option<&ModuleSpecifier> {
match self { match self {
AssetOrDocument::Asset(_) => None, AssetOrDocument::Asset(asset_doc) => Some(asset_doc.specifier()),
AssetOrDocument::Document(doc) => doc.scope(), AssetOrDocument::Document(doc) => doc.scope(),
} }
} }

View file

@ -169,6 +169,10 @@ delete Object.prototype.__proto__;
const isCjsCache = new SpecifierIsCjsCache(); const isCjsCache = new SpecifierIsCjsCache();
// Maps asset specifiers to the first scope that the asset was loaded into.
/** @type {Map<string, string | null>} */
const assetScopes = new Map();
/** @type {number | null} */ /** @type {number | null} */
let projectVersionCache = null; let projectVersionCache = null;
@ -837,6 +841,9 @@ delete Object.prototype.__proto__;
} }
const sourceFile = sourceFileCache.get(specifier); const sourceFile = sourceFileCache.get(specifier);
if (sourceFile) { if (sourceFile) {
if (!assetScopes.has(specifier)) {
assetScopes.set(specifier, lastRequestScope);
}
// This case only occurs for assets. // This case only occurs for assets.
return ts.ScriptSnapshot.fromString(sourceFile.text); return ts.ScriptSnapshot.fromString(sourceFile.text);
} }
@ -1210,6 +1217,7 @@ delete Object.prototype.__proto__;
const newConfigsByScope = maybeChange[2]; const newConfigsByScope = maybeChange[2];
if (newConfigsByScope) { if (newConfigsByScope) {
isNodeSourceFileCache.clear(); isNodeSourceFileCache.clear();
assetScopes.clear();
/** @type { typeof languageServiceEntries.byScope } */ /** @type { typeof languageServiceEntries.byScope } */
const newByScope = new Map(); const newByScope = new Map();
for (const [scope, config] of newConfigsByScope) { for (const [scope, config] of newConfigsByScope) {
@ -1247,6 +1255,12 @@ delete Object.prototype.__proto__;
} }
} }
// For requests pertaining to an asset document, we make it so that the
// passed scope is just its own specifier. We map it to an actual scope here
// based on the first scope that the asset was loaded into.
if (scope?.startsWith(ASSETS_URL_PREFIX)) {
scope = assetScopes.get(scope) ?? null;
}
lastRequestMethod = method; lastRequestMethod = method;
lastRequestScope = scope; lastRequestScope = scope;
const ls = (scope ? languageServiceEntries.byScope.get(scope)?.ls : null) ?? const ls = (scope ? languageServiceEntries.byScope.get(scope)?.ls : null) ??

View file

@ -1409,11 +1409,13 @@ fn lsp_hover() {
#[test] #[test]
fn lsp_hover_asset() { fn lsp_hover_asset() {
let context = TestContextBuilder::new().use_temp_cwd().build(); let context = TestContextBuilder::new().use_temp_cwd().build();
let temp_dir = context.temp_dir();
temp_dir.write("deno.json", json!({}).to_string());
let mut client = context.new_lsp_command().build(); let mut client = context.new_lsp_command().build();
client.initialize_default(); client.initialize_default();
client.did_open(json!({ client.did_open(json!({
"textDocument": { "textDocument": {
"uri": "file:///a/file.ts", "uri": temp_dir.uri().join("file.ts").unwrap(),
"languageId": "typescript", "languageId": "typescript",
"version": 1, "version": 1,
"text": "console.log(Date.now());\n" "text": "console.log(Date.now());\n"
@ -1423,7 +1425,7 @@ fn lsp_hover_asset() {
"textDocument/definition", "textDocument/definition",
json!({ json!({
"textDocument": { "textDocument": {
"uri": "file:///a/file.ts" "uri": temp_dir.uri().join("file.ts").unwrap()
}, },
"position": { "line": 0, "character": 14 } "position": { "line": 0, "character": 14 }
}), }),