From 9fe25ca0776c7b09939a8a910bf5b217272486b8 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sat, 11 Apr 2020 22:35:26 +0800 Subject: [PATCH 01/15] feat: add a codefix to fix class to className in react --- .../codefixes/fixReactClassNameAndHTMLFor.ts | 60 +++++++++++++++++++ src/services/tsconfig.json | 1 + .../codeFixReactClassNameAndHTMLFor1.ts | 15 +++++ .../codeFixReactClassNameAndHTMLFor2.ts | 15 +++++ .../codeFixReactClassNameAndHTMLFor3-1.ts | 16 +++++ .../codeFixReactClassNameAndHTMLFor3-2.ts | 17 ++++++ .../codeFixReactClassNameAndHTMLFor3-3.ts | 16 +++++ .../codeFixReactClassNameAndHTMLFor4.ts | 30 ++++++++++ 8 files changed, 170 insertions(+) create mode 100644 src/services/codefixes/fixReactClassNameAndHTMLFor.ts create mode 100644 tests/cases/fourslash/codeFixReactClassNameAndHTMLFor1.ts create mode 100644 tests/cases/fourslash/codeFixReactClassNameAndHTMLFor2.ts create mode 100644 tests/cases/fourslash/codeFixReactClassNameAndHTMLFor3-1.ts create mode 100644 tests/cases/fourslash/codeFixReactClassNameAndHTMLFor3-2.ts create mode 100644 tests/cases/fourslash/codeFixReactClassNameAndHTMLFor3-3.ts create mode 100644 tests/cases/fourslash/codeFixReactClassNameAndHTMLFor4.ts diff --git a/src/services/codefixes/fixReactClassNameAndHTMLFor.ts b/src/services/codefixes/fixReactClassNameAndHTMLFor.ts new file mode 100644 index 00000000000..aa3a92a6a1d --- /dev/null +++ b/src/services/codefixes/fixReactClassNameAndHTMLFor.ts @@ -0,0 +1,60 @@ +/* @internal */ +namespace ts.codefix { + const fixID = "fixReactClassNameAndHTMLFor"; + const errorCodes = [Diagnostics.Type_0_is_not_assignable_to_type_1.code]; + registerCodeFix({ + errorCodes, + getCodeActions: context => { + const { jsx } = context.program.getCompilerOptions(); + if (jsx !== JsxEmit.React) { + return undefined; + } + const { sourceFile, span } = context; + const node = getTokenAtPosition(sourceFile, span.start); + if (!shouldFix(node)) return undefined; + const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, node)); + return [createCodeFixAction(fixID, changes, [Diagnostics.Did_you_mean_0, getCorrectName(node)], fixID, Diagnostics.Fix_all_detected_spelling_errors)]; + }, + fixIds: [fixID], + getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => { + const node = getTokenAtPosition(context.sourceFile, diag.start); + if (!shouldFix(node)) return; + doChange(changes, context.sourceFile, node); + }), + }); + + function doChange(changeTracker: textChanges.ChangeTracker, sf: SourceFile, node: Identifier) { + changeTracker.replaceNode(sf, node, createIdentifier(getCorrectName(node))); + } + + function getCorrectName(node: Identifier) { + const text = node.text; + if (text === "class") return "className"; + if (text === "for") return "htmlFor"; + return Debug.fail(); + } + + function shouldFix(node: Node): node is Identifier { + //