Skip to content

Commit 0227997

Browse files
author
Andy
authored
Use import().T for import completions/fixes of pure types in JS files (microsoft#25852)
* Use `import().T` for import completions/fixes of pure types in JS files * Don't call tryUseExistingNamespaceImport if position undefined
1 parent d590d5b commit 0227997

File tree

7 files changed

+183
-43
lines changed

7 files changed

+183
-43
lines changed

src/services/codefixes/importFixes.ts

Lines changed: 69 additions & 37 deletions
Large diffs are not rendered by default.

src/services/completions.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ namespace ts.Completions {
592592
}
593593
case "symbol": {
594594
const { symbol, location, symbolToOriginInfoMap, previousToken } = symbolCompletion;
595-
const { codeActions, sourceDisplay } = getCompletionEntryCodeActionsAndSourceDisplay(symbolToOriginInfoMap, symbol, program, typeChecker, host, compilerOptions, sourceFile, previousToken, formatContext, program.getSourceFiles(), preferences);
595+
const { codeActions, sourceDisplay } = getCompletionEntryCodeActionsAndSourceDisplay(symbolToOriginInfoMap, symbol, program, typeChecker, host, compilerOptions, sourceFile, position, previousToken, formatContext, preferences);
596596
return createCompletionDetailsForSymbol(symbol, typeChecker, sourceFile, location!, cancellationToken, codeActions, sourceDisplay); // TODO: GH#18217
597597
}
598598
case "literal": {
@@ -652,9 +652,9 @@ namespace ts.Completions {
652652
host: LanguageServiceHost,
653653
compilerOptions: CompilerOptions,
654654
sourceFile: SourceFile,
655+
position: number,
655656
previousToken: Node | undefined,
656657
formatContext: formatting.FormatContext,
657-
allSourceFiles: ReadonlyArray<SourceFile>,
658658
preferences: UserPreferences,
659659
): CodeActionsAndSourceDisplay {
660660
const symbolOriginInfo = symbolToOriginInfoMap[getSymbolId(symbol)];
@@ -671,10 +671,8 @@ namespace ts.Completions {
671671
getSymbolName(symbol, symbolOriginInfo, compilerOptions.target!),
672672
host,
673673
program,
674-
checker,
675-
allSourceFiles,
676674
formatContext,
677-
previousToken,
675+
previousToken && isIdentifier(previousToken) ? previousToken.getStart(sourceFile) : position,
678676
preferences);
679677
return { sourceDisplay: [textPart(moduleSpecifier)], codeActions: [codeAction] };
680678
}

src/services/textChanges.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ namespace ts.textChanges {
333333
this.changes.push({ kind: ChangeKind.Text, sourceFile, range, text });
334334
}
335335

336-
private insertText(sourceFile: SourceFile, pos: number, text: string): void {
336+
public insertText(sourceFile: SourceFile, pos: number, text: string): void {
337337
this.replaceRangeWithText(sourceFile, createTextRange(pos), text);
338338
}
339339

src/services/utilities.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,6 +1291,14 @@ namespace ts {
12911291
}
12921292
}
12931293

1294+
export function getQuoteFromPreference(qp: QuotePreference): string {
1295+
switch (qp) {
1296+
case QuotePreference.Single: return "'";
1297+
case QuotePreference.Double: return '"';
1298+
default: return Debug.assertNever(qp);
1299+
}
1300+
}
1301+
12941302
export function symbolNameNoDefault(symbol: Symbol): string | undefined {
12951303
const escaped = symbolEscapedNameNoDefault(symbol);
12961304
return escaped === undefined ? undefined : unescapeLeadingUnderscores(escaped);
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
// @allowJs: true
4+
5+
// @Filename: /a.js
6+
////export const x = 0;
7+
////export class C {}
8+
/////** @typedef {number} T */
9+
10+
// @Filename: /b.js
11+
/////** @type {/*0*/} */
12+
/////** @type {/*1*/} */
13+
14+
verify.completions({
15+
marker: ["0", "1"],
16+
includes: [
17+
{
18+
name: "C",
19+
source: "/a",
20+
sourceDisplay: "./a",
21+
text: "class C",
22+
hasAction: true,
23+
},
24+
{
25+
name: "T",
26+
source: "/a",
27+
sourceDisplay: "./a",
28+
text: "type T = number",
29+
hasAction: true,
30+
},
31+
],
32+
excludes: "x",
33+
preferences: {
34+
includeCompletionsForModuleExports: true,
35+
},
36+
});
37+
38+
// Something with a value-side will get a normal import.
39+
verify.applyCodeActionFromCompletion("0", {
40+
name: "C",
41+
source: "/a",
42+
description: `Import 'C' from module "./a"`,
43+
newFileContent:
44+
`import { C } from "./a";
45+
46+
/** @type {} */
47+
/** @type {} */`,
48+
});
49+
50+
// A pure type will get `import().T`
51+
verify.applyCodeActionFromCompletion("1", {
52+
name: "T",
53+
source: "/a",
54+
description: `Change 'T' to 'import("./a").T'`,
55+
newFileContent:
56+
`import { C } from "./a";
57+
58+
/** @type {} */
59+
/** @type {import("./a").} */`,
60+
});
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
// @allowJs: true
4+
// @checkJs: true
5+
6+
// @Filename: /a.js
7+
////export class C {}
8+
/////** @typedef {number} T */
9+
10+
// @Filename: /b.js
11+
////C;
12+
/////** @type {T} */
13+
////const x = 0;
14+
15+
goTo.file("/b.js");
16+
verify.codeFixAll({
17+
fixId: "fixMissingImport",
18+
fixAllDescription: "Add all missing imports",
19+
newFileContent:
20+
`import { C } from "./a";
21+
22+
C;
23+
/** @type {import("./a").T} */
24+
const x = 0;`,
25+
});
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
// @allowJs: true
4+
// @checkJs: true
5+
6+
// @Filename: /a.js
7+
////export {};
8+
/////** @typedef {number} T */
9+
10+
// @Filename: /b.js
11+
/////** @type {T} */
12+
////const x = 0;
13+
14+
goTo.file("/b.js");
15+
verify.importFixAtPosition([
16+
`/** @type {import("./a").T} */
17+
const x = 0;`]);

0 commit comments

Comments
 (0)