Skip to content
This repository was archived by the owner on Sep 4, 2020. It is now read-only.

Commit d35a58c

Browse files
authored
improve auto imports (#40)
* custom `getCodeFixesAtPosition` * fix auto import
1 parent b28ead1 commit d35a58c

File tree

4 files changed

+115
-0
lines changed

4 files changed

+115
-0
lines changed

src/code_fixes/import_fixes.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { CodeFixAction } from "typescript/lib/tsserverlibrary";
2+
3+
import { registerCodeFix } from "../codefix_provider";
4+
import { HashMeta } from "../module_resolver/hash_meta";
5+
6+
export const importFixName = "import";
7+
// const importFixId = "fixMissingImport";
8+
9+
const errorCodes: readonly number[] = [
10+
2304, // Diagnostics.Cannot_find_name_0.code,
11+
2552, // Diagnostics.Cannot_find_name_0_Did_you_mean_1.code,
12+
2663, // Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0.code,
13+
2662, // Diagnostics.Cannot_find_name_0_Did_you_mean_the_static_member_1_0.code,
14+
2503, // Diagnostics.Cannot_find_namespace_0.code,
15+
2686, // Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code,
16+
2693, // Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here.code,
17+
];
18+
19+
function replaceCodeActions(codeFixActions: readonly CodeFixAction[]): void {
20+
for (const codeAction of codeFixActions) {
21+
if (codeAction.fixName !== importFixName) {
22+
continue;
23+
}
24+
25+
const matchs = codeAction.description.match(
26+
/\.\..+deno\/deps\/https?\/.+\/\w{64}/,
27+
);
28+
if (matchs == null || matchs.length === 0) {
29+
continue;
30+
}
31+
32+
const originImport = matchs[0];
33+
const meta = HashMeta.create(`${originImport}.metadata.json`);
34+
if (meta == null) {
35+
continue;
36+
}
37+
38+
const newImport = meta.url.href;
39+
codeAction.description = codeAction.description.replace(
40+
originImport,
41+
newImport,
42+
);
43+
44+
for (const change of codeAction.changes) {
45+
for (const textChange of change.textChanges) {
46+
textChange.newText = textChange.newText.replace(
47+
originImport,
48+
newImport,
49+
);
50+
}
51+
}
52+
}
53+
}
54+
55+
registerCodeFix({
56+
errorCodes,
57+
replaceCodeActions,
58+
});

src/code_fixes/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import "./import_fixes"

src/codefix_provider.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { CodeFixAction } from "typescript/lib/tsserverlibrary";
2+
3+
export interface CodeFixRegistration {
4+
errorCodes: readonly number[];
5+
// fixIds: readonly string[],
6+
replaceCodeActions: (codeFixActions: readonly CodeFixAction[]) => void;
7+
}
8+
9+
export const errorCodeToFixes: Map<
10+
number,
11+
Pick<CodeFixRegistration, "replaceCodeActions">[]
12+
> = new Map();
13+
14+
export function registerCodeFix(reg: CodeFixRegistration) {
15+
for (const error of reg.errorCodes) {
16+
if (errorCodeToFixes.has(error)) {
17+
errorCodeToFixes.get(error)!.push(reg);
18+
} else {
19+
errorCodeToFixes.set(error, [reg]);
20+
}
21+
}
22+
}

src/index.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import merge from "merge-deep";
77
import ts_module, {
88
ResolvedModuleFull,
99
CompilerOptions,
10+
UserPreferences,
11+
FormatCodeSettings,
12+
CodeFixAction,
1013
} from "typescript/lib/tsserverlibrary";
1114
import { parseFromString, resolve, ImportMaps } from "import-maps";
1215

@@ -21,6 +24,8 @@ import {
2124

2225
import { universalModuleResolver } from "./module_resolver/universal_module_resolver";
2326
import { HashMeta } from "./module_resolver/hash_meta";
27+
import { errorCodeToFixes } from "./codefix_provider";
28+
import './code_fixes'
2429

2530
let logger: Logger;
2631
let pluginInfo: ts_module.server.PluginCreateInfo;
@@ -404,12 +409,41 @@ module.exports = function init(
404409
});
405410
}
406411

412+
// TODO(justjavac): maybe also `getCombinedCodeFix`
413+
function getCodeFixesAtPosition(
414+
fileName: string,
415+
start: number,
416+
end: number,
417+
errorCodes: readonly number[],
418+
formatOptions: FormatCodeSettings,
419+
preferences: UserPreferences,
420+
): readonly CodeFixAction[] {
421+
const codeFixActions = tsLs.getCodeFixesAtPosition(
422+
fileName,
423+
start,
424+
end,
425+
errorCodes,
426+
formatOptions,
427+
preferences,
428+
);
429+
430+
for (const errorCode of errorCodes) {
431+
const fixes = errorCodeToFixes.get(errorCode)!
432+
for (const fix of fixes) {
433+
fix.replaceCodeActions(codeFixActions);
434+
}
435+
}
436+
437+
return codeFixActions;
438+
}
439+
407440
const proxy: ts_module.LanguageService = Object.assign(
408441
Object.create(null),
409442
tsLs,
410443
{
411444
getCompletionEntryDetails,
412445
getSemanticDiagnostics,
446+
getCodeFixesAtPosition,
413447
},
414448
);
415449

0 commit comments

Comments
 (0)