1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-21 23:04:45 -05:00

fix(lsp): "Add all missing imports" uses correct specifiers (#17216)

This commit fixes "Add all missing imports" quick fix; before
it was replacing all occurrences with the same specifier. Now
every line returned from TSC is processed individually.
This commit is contained in:
Bartek Iwańczuk 2022-12-29 21:07:09 +01:00 committed by GitHub
parent 65ea554afe
commit ef5f8cd265
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 138 additions and 75 deletions

View file

@ -184,28 +184,30 @@ pub fn fix_ts_import_changes(
for change in changes {
let mut text_changes = Vec::new();
for text_change in &change.text_changes {
if let Some(captures) =
IMPORT_SPECIFIER_RE.captures(&text_change.new_text)
{
let specifier = captures
.get(1)
.ok_or_else(|| anyhow!("Missing capture."))?
.as_str();
if let Some(new_specifier) =
check_specifier(specifier, referrer, documents)
{
let new_text =
text_change.new_text.replace(specifier, &new_specifier);
text_changes.push(tsc::TextChange {
span: text_change.span.clone(),
new_text,
});
} else {
text_changes.push(text_change.clone());
}
} else {
text_changes.push(text_change.clone());
}
let lines = text_change.new_text.split('\n');
let new_lines: Vec<String> = lines
.map(|line| {
// This assumes that there's only one import per line.
if let Some(captures) = IMPORT_SPECIFIER_RE.captures(line) {
let specifier = captures.get(1).unwrap().as_str();
if let Some(new_specifier) =
check_specifier(specifier, referrer, documents)
{
line.replace(specifier, &new_specifier)
} else {
line.to_string()
}
} else {
line.to_string()
}
})
.collect();
text_changes.push(tsc::TextChange {
span: text_change.span.clone(),
new_text: new_lines.join("\n").to_string(),
});
}
r.push(tsc::FileTextChanges {
file_name: change.file_name.clone(),

View file

@ -3390,7 +3390,16 @@ mod lsp {
"uri": "file:///a/file00.ts",
"languageId": "typescript",
"version": 1,
"text": "export const abc = \"abc\";\nexport const def = \"def\";\n"
"text": r#"export interface MallardDuckConfigOptions extends DuckConfigOptions {
kind: "mallard";
}
export class MallardDuckConfig extends DuckConfig {
constructor(options: MallardDuckConfigOptions) {
super(options);
}
}
"#
}
}));
session.did_open(json!({
@ -3398,7 +3407,27 @@ mod lsp {
"uri": "file:///a/file01.ts",
"languageId": "typescript",
"version": 1,
"text": "\nconsole.log(abc);\nconsole.log(def)\n"
"text": r#"import { DuckConfigOptions } from "./file02.ts";
export class DuckConfig {
readonly kind;
constructor(options: DuckConfigOptions) {
this.kind = options.kind;
}
}
"#
}
}));
session.did_open(json!({
"textDocument": {
"uri": "file:///a/file02.ts",
"languageId": "typescript",
"version": 1,
"text": r#"export interface DuckConfigOptions {
kind: string;
quacks: boolean;
}
"#
}
}));

View file

@ -1,15 +1,15 @@
{
"textDocument": {
"uri": "file:///a/file01.ts"
"uri": "file:///a/file00.ts"
},
"range": {
"start": {
"line": 1,
"character": 12
"line": 0,
"character": 0
},
"end": {
"line": 1,
"character": 15
"line": 6,
"character": 0
}
},
"context": {
@ -17,34 +17,34 @@
{
"range": {
"start": {
"line": 1,
"character": 12
"line": 0,
"character": 50
},
"end": {
"line": 1,
"character": 15
"line": 0,
"character": 67
}
},
"severity": 1,
"code": 2304,
"source": "deno-ts",
"message": "Cannot find name 'abc'."
"message": "Cannot find name 'DuckConfigOptions'."
},
{
"range": {
"start": {
"line": 2,
"character": 12
"line": 4,
"character": 39
},
"end": {
"line": 2,
"character": 15
"line": 4,
"character": 49
}
},
"severity": 1,
"code": 2304,
"source": "deno-ts",
"message": "Cannot find name 'def'."
"message": "Cannot find name 'DuckConfig'."
}
],
"only": [

View file

@ -5,22 +5,38 @@
{
"range": {
"start": {
"line": 1,
"character": 12
"line": 0,
"character": 50
},
"end": {
"line": 1,
"character": 15
"line": 0,
"character": 67
}
},
"severity": 1,
"code": 2304,
"source": "deno-ts",
"message": "Cannot find name 'abc'."
"message": "Cannot find name 'DuckConfigOptions'."
},
{
"range": {
"start": {
"line": 4,
"character": 39
},
"end": {
"line": 4,
"character": 49
}
},
"severity": 1,
"code": 2304,
"source": "deno-ts",
"message": "Cannot find name 'DuckConfig'."
}
],
"data": {
"specifier": "file:///a/file01.ts",
"specifier": "file:///a/file00.ts",
"fixId": "fixMissingImport"
}
}

View file

@ -5,25 +5,41 @@
{
"range": {
"start": {
"line": 1,
"character": 12
"line": 0,
"character": 50
},
"end": {
"line": 1,
"character": 15
"line": 0,
"character": 67
}
},
"severity": 1,
"code": 2304,
"source": "deno-ts",
"message": "Cannot find name 'abc'."
"message": "Cannot find name 'DuckConfigOptions'."
},
{
"range": {
"start": {
"line": 4,
"character": 39
},
"end": {
"line": 4,
"character": 49
}
},
"severity": 1,
"code": 2304,
"source": "deno-ts",
"message": "Cannot find name 'DuckConfig'."
}
],
"edit": {
"documentChanges": [
{
"textDocument": {
"uri": "file:///a/file01.ts",
"uri": "file:///a/file00.ts",
"version": 1
},
"edits": [
@ -38,14 +54,14 @@
"character": 0
}
},
"newText": "import { abc,def } from \"./file00.ts\";\n"
"newText": "import { DuckConfig } from \"./file01.ts\";\nimport { DuckConfigOptions } from \"./file02.ts\";\n\n"
}
]
}
]
},
"data": {
"specifier": "file:///a/file01.ts",
"specifier": "file:///a/file00.ts",
"fixId": "fixMissingImport"
}
}

View file

@ -1,30 +1,30 @@
[
{
"title": "Add import from \"./file00.ts\"",
"title": "Add import from \"./file02.ts\"",
"kind": "quickfix",
"diagnostics": [
{
"range": {
"start": {
"line": 1,
"character": 12
"line": 0,
"character": 50
},
"end": {
"line": 1,
"character": 15
"line": 0,
"character": 67
}
},
"severity": 1,
"code": 2304,
"source": "deno-ts",
"message": "Cannot find name 'abc'."
"message": "Cannot find name 'DuckConfigOptions'."
}
],
"edit": {
"documentChanges": [
{
"textDocument": {
"uri": "file:///a/file01.ts",
"uri": "file:///a/file00.ts",
"version": 1
},
"edits": [
@ -39,7 +39,7 @@
"character": 0
}
},
"newText": "import { abc } from \"./file00.ts\";\n"
"newText": "import { DuckConfigOptions } from \"./file02.ts\";\n\n"
}
]
}
@ -53,51 +53,51 @@
{
"range": {
"start": {
"line": 1,
"character": 12
"line": 0,
"character": 50
},
"end": {
"line": 1,
"character": 15
"line": 0,
"character": 67
}
},
"severity": 1,
"code": 2304,
"source": "deno-ts",
"message": "Cannot find name 'abc'."
"message": "Cannot find name 'DuckConfigOptions'."
}
],
"data": {
"specifier": "file:///a/file01.ts",
"specifier": "file:///a/file00.ts",
"fixId": "fixMissingImport"
}
},
{
"title": "Add import from \"./file00.ts\"",
"title": "Add import from \"./file01.ts\"",
"kind": "quickfix",
"diagnostics": [
{
"range": {
"start": {
"line": 2,
"character": 12
"line": 4,
"character": 39
},
"end": {
"line": 2,
"character": 15
"line": 4,
"character": 49
}
},
"severity": 1,
"code": 2304,
"source": "deno-ts",
"message": "Cannot find name 'def'."
"message": "Cannot find name 'DuckConfig'."
}
],
"edit": {
"documentChanges": [
{
"textDocument": {
"uri": "file:///a/file01.ts",
"uri": "file:///a/file00.ts",
"version": 1
},
"edits": [
@ -112,7 +112,7 @@
"character": 0
}
},
"newText": "import { def } from \"./file00.ts\";\n"
"newText": "import { DuckConfig } from \"./file01.ts\";\n\n"
}
]
}