From c97e5017bfcdab79b96aafa247c1c0b4fa6d31e2 Mon Sep 17 00:00:00 2001 From: Mohsen Azimi Date: Sat, 19 May 2018 13:44:40 -0700 Subject: [PATCH 1/5] wip --- .gitignore | 2 +- .vscode/launch.json | 30 ++++----- README.md | 1 + src/index.ts | 3 + ...lt-export-variable-assignment-transform.ts | 67 +++++++++++++++++++ .../input.tsx | 7 ++ .../output.tsx | 8 +++ .../basic/input.tsx | 1 + .../basic/output.tsx | 2 + test/transformers.test.ts | 2 + 10 files changed, 104 insertions(+), 19 deletions(-) create mode 100644 src/transforms/remove-default-export-variable-assignment-transform.ts create mode 100644 test/end-to-end/stateless-function-exported-default/input.tsx create mode 100644 test/end-to-end/stateless-function-exported-default/output.tsx create mode 100644 test/remove-default-export-variable-assignment-transform/basic/input.tsx create mode 100644 test/remove-default-export-variable-assignment-transform/basic/output.tsx diff --git a/.gitignore b/.gitignore index b899a48..6897440 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,4 @@ node_modules dist .DS_Store coverage/ -.log +*.log diff --git a/.vscode/launch.json b/.vscode/launch.json index fff8a01..cb6f1f9 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -2,28 +2,22 @@ "version": "0.2.0", "configurations": [ { - "args": [], - "cwd": "${workspaceRoot}", - "env": { - "NODE_ENV": "test" - }, - "console": "internalConsole", - "name": "Run Tests", - "outFiles": ["${workspaceRoot}/dist"], - "preLaunchTask": "tsc", - "program": "${workspaceRoot}/node_modules/.bin/jest", + "type": "node", "request": "launch", - "runtimeArgs": [], - "runtimeExecutable": null, - "sourceMaps": true, - "stopOnEntry": false, - "type": "node" + "name": "Jest All", + "program": "${workspaceFolder}/node_modules/jest/bin/jest", + "args": ["--runInBand"], + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen" }, { - "name": "Attach", "type": "node", - "request": "attach", - "port": 5858 + "request": "launch", + "name": "Jest A single case (edit config)", + "program": "${workspaceFolder}/node_modules/jest/bin/jest", + "args": ["-t", "remove-default-export-variable-assignment-transform basic"], + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen" } ] } diff --git a/README.md b/README.md index 3fe6824..271fbc4 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ Transforms React code written in JavaScript to TypeScript. [**🖥 Download the VSCode Extension**](https://marketplace.visualstudio.com/items?itemName=mohsen1.react-javascript-to-typescript-transform-vscode) + ## Features: * Proxies `PropTypes` to `React.Component` generic type and removes PropTypes diff --git a/src/index.ts b/src/index.ts index 831dbd9..c7fff84 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,6 +9,7 @@ import { collapseIntersectionInterfacesTransformFactoryFactory } from './transfo import { reactRemoveStaticPropTypesMemberTransformFactoryFactory } from './transforms/react-remove-static-prop-types-member-transform'; import { reactStatelessFunctionMakePropsTransformFactoryFactory } from './transforms/react-stateless-function-make-props-transform'; import { reactRemovePropTypesImportTransformFactoryFactory } from './transforms/react-remove-prop-types-import'; +import { removeDefaultExportVariableAssignmentTransformFactoryFactory } from './transforms/remove-default-export-variable-assignment-transform'; export { reactMovePropTypesToClassTransformFactoryFactory, @@ -18,6 +19,7 @@ export { reactRemovePropTypesAssignmentTransformFactoryFactory, reactRemoveStaticPropTypesMemberTransformFactoryFactory, reactRemovePropTypesImportTransformFactoryFactory, + removeDefaultExportVariableAssignmentTransformFactoryFactory, compile, }; @@ -29,6 +31,7 @@ export const allTransforms = [ reactRemovePropTypesAssignmentTransformFactoryFactory, reactRemoveStaticPropTypesMemberTransformFactoryFactory, reactRemovePropTypesImportTransformFactoryFactory, + removeDefaultExportVariableAssignmentTransformFactoryFactory, ]; export type TransformFactoryFactory = (typeChecker: ts.TypeChecker) => ts.TransformerFactory; diff --git a/src/transforms/remove-default-export-variable-assignment-transform.ts b/src/transforms/remove-default-export-variable-assignment-transform.ts new file mode 100644 index 0000000..342050c --- /dev/null +++ b/src/transforms/remove-default-export-variable-assignment-transform.ts @@ -0,0 +1,67 @@ +import * as ts from 'typescript'; +import * as _ from 'lodash'; + +import * as helpers from '../helpers'; + +/** + * Remove default export variable assignment + * + * @example + * Before: + * export default const foo: string = 'str'; + * + * After + * const foo: string = 'str'; + * export default foo; + */ +export function removeDefaultExportVariableAssignmentTransformFactoryFactory( + typeChecker: ts.TypeChecker, +): ts.TransformerFactory { + return function removeDefaultExportVariableAssignmentTransformFactory(context: ts.TransformationContext) { + return function removeDefaultExportVariableAssignmentTransform(sourceFile: ts.SourceFile) { + const visited = visitSourceFile(sourceFile, typeChecker); + ts.addEmitHelpers(visited, context.readEmitHelpers()); + return visited; + }; + }; +} + +function visitSourceFile(sourceFile: ts.SourceFile, typeChecker: ts.TypeChecker) { + let statements = _.toArray(sourceFile.statements); + const newStatements = []; + + let index = 0; + while (index < statements.length) { + const statement = statements[index]; + const nextStatement = statements[index + 1]; + let statementText; + try { + statementText = statement.getText(); + } catch {} + + if ( + nextStatement && + ts.isExportAssignment(statement) && + statementText === 'export default' && + ts.isVariableStatement(nextStatement) + ) { + // push variable declaration + newStatements.push(nextStatement); + + // push export default for variable declaration + const identifer = ts.createIdentifier( + nextStatement.declarationList.declarations[0] && + nextStatement.declarationList.declarations[0].name.getText(), + ); + const defaultExport = ts.createExportDefault(identifer); + newStatements.push(defaultExport); + + // skip next statement because we pushed nextStatement already + index++; + } else { + newStatements.push(statement); + } + index++; + } + return ts.updateSourceFileNode(sourceFile, newStatements); +} diff --git a/test/end-to-end/stateless-function-exported-default/input.tsx b/test/end-to-end/stateless-function-exported-default/input.tsx new file mode 100644 index 0000000..e8b57d1 --- /dev/null +++ b/test/end-to-end/stateless-function-exported-default/input.tsx @@ -0,0 +1,7 @@ +export default function Hello({ message }) { + return
hello {message}
+} + +Hello.propTypes = { + message: React.PropTypes.string, +} diff --git a/test/end-to-end/stateless-function-exported-default/output.tsx b/test/end-to-end/stateless-function-exported-default/output.tsx new file mode 100644 index 0000000..5af2f25 --- /dev/null +++ b/test/end-to-end/stateless-function-exported-default/output.tsx @@ -0,0 +1,8 @@ +type HelloProps = { + message?: string, +}; +const Hello: React.SFC = ({ message }) => { + return
hello {message}
; +}; + +export default Hello; diff --git a/test/remove-default-export-variable-assignment-transform/basic/input.tsx b/test/remove-default-export-variable-assignment-transform/basic/input.tsx new file mode 100644 index 0000000..c89e79d --- /dev/null +++ b/test/remove-default-export-variable-assignment-transform/basic/input.tsx @@ -0,0 +1 @@ +export default const foo: string = 'str'; diff --git a/test/remove-default-export-variable-assignment-transform/basic/output.tsx b/test/remove-default-export-variable-assignment-transform/basic/output.tsx new file mode 100644 index 0000000..ba7e18e --- /dev/null +++ b/test/remove-default-export-variable-assignment-transform/basic/output.tsx @@ -0,0 +1,2 @@ +const foo: string = 'str'; +export default foo; diff --git a/test/transformers.test.ts b/test/transformers.test.ts index 8b845d4..44cf002 100644 --- a/test/transformers.test.ts +++ b/test/transformers.test.ts @@ -17,6 +17,7 @@ import { reactRemoveStaticPropTypesMemberTransformFactoryFactory, collapseIntersectionInterfacesTransformFactoryFactory, reactRemovePropTypesImportTransformFactoryFactory, + removeDefaultExportVariableAssignmentTransformFactoryFactory, allTransforms, compile, TransformFactoryFactory @@ -32,6 +33,7 @@ const transformToFolderMap: [string, TransformFactoryFactory[]][] = [ ['collapse-intersection-interfaces-transform', [collapseIntersectionInterfacesTransformFactoryFactory]], ['react-move-prop-types-to-class-transform', [reactMovePropTypesToClassTransformFactoryFactory]], ['react-remove-prop-types-import', [reactRemovePropTypesImportTransformFactoryFactory]], + ['remove-default-export-variable-assignment-transform', [removeDefaultExportVariableAssignmentTransformFactoryFactory]], ['end-to-end', allTransforms], ]; From 188db755cb85b57209cf489404b966cf1007b143 Mon Sep 17 00:00:00 2001 From: Mohsen Azimi Date: Sat, 19 May 2018 13:56:17 -0700 Subject: [PATCH 2/5] Add more test cases --- .vscode/launch.json | 6 +++--- .../repeated/output.tsx | 2 -- .../with-other-exports/input.tsx | 4 ++++ .../with-other-exports/output.tsx | 5 +++++ .../with-var-statement-after/input.tsx | 2 ++ .../with-var-statement-after/output.tsx | 3 +++ .../with-var-statement-before/input.tsx | 2 ++ .../with-var-statement-before/output.tsx | 3 +++ 8 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 test/remove-default-export-variable-assignment-transform/with-other-exports/input.tsx create mode 100644 test/remove-default-export-variable-assignment-transform/with-other-exports/output.tsx create mode 100644 test/remove-default-export-variable-assignment-transform/with-var-statement-after/input.tsx create mode 100644 test/remove-default-export-variable-assignment-transform/with-var-statement-after/output.tsx create mode 100644 test/remove-default-export-variable-assignment-transform/with-var-statement-before/input.tsx create mode 100644 test/remove-default-export-variable-assignment-transform/with-var-statement-before/output.tsx diff --git a/.vscode/launch.json b/.vscode/launch.json index cb6f1f9..33051d6 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,7 +4,7 @@ { "type": "node", "request": "launch", - "name": "Jest All", + "name": "Test All", "program": "${workspaceFolder}/node_modules/jest/bin/jest", "args": ["--runInBand"], "console": "integratedTerminal", @@ -13,9 +13,9 @@ { "type": "node", "request": "launch", - "name": "Jest A single case (edit config)", + "name": "Test A single case (edit 'args' config first)", "program": "${workspaceFolder}/node_modules/jest/bin/jest", - "args": ["-t", "remove-default-export-variable-assignment-transform basic"], + "args": ["-t", "end-to-end initial-state-and-proprypes-and-set-state"], "console": "integratedTerminal", "internalConsoleOptions": "neverOpen" } diff --git a/test/collapse-intersection-interfaces-transform/repeated/output.tsx b/test/collapse-intersection-interfaces-transform/repeated/output.tsx index 5dc0eec..cc2144f 100644 --- a/test/collapse-intersection-interfaces-transform/repeated/output.tsx +++ b/test/collapse-intersection-interfaces-transform/repeated/output.tsx @@ -1,12 +1,10 @@ type A = { foo: string, }; - type B = { foo: string | number, bar: number, }; - type C = { foo: string | number, bar: number, diff --git a/test/remove-default-export-variable-assignment-transform/with-other-exports/input.tsx b/test/remove-default-export-variable-assignment-transform/with-other-exports/input.tsx new file mode 100644 index 0000000..df97315 --- /dev/null +++ b/test/remove-default-export-variable-assignment-transform/with-other-exports/input.tsx @@ -0,0 +1,4 @@ +export const bar = 1; +export default const foo: string = 'str'; +let baz = 1; +export {baz}; diff --git a/test/remove-default-export-variable-assignment-transform/with-other-exports/output.tsx b/test/remove-default-export-variable-assignment-transform/with-other-exports/output.tsx new file mode 100644 index 0000000..c7e9135 --- /dev/null +++ b/test/remove-default-export-variable-assignment-transform/with-other-exports/output.tsx @@ -0,0 +1,5 @@ +export const bar = 1; +const foo: string = 'str'; +export default foo; +let baz = 1; +export { baz }; diff --git a/test/remove-default-export-variable-assignment-transform/with-var-statement-after/input.tsx b/test/remove-default-export-variable-assignment-transform/with-var-statement-after/input.tsx new file mode 100644 index 0000000..34cc185 --- /dev/null +++ b/test/remove-default-export-variable-assignment-transform/with-var-statement-after/input.tsx @@ -0,0 +1,2 @@ +export default const foo: string = 'str'; +var baz = 42; diff --git a/test/remove-default-export-variable-assignment-transform/with-var-statement-after/output.tsx b/test/remove-default-export-variable-assignment-transform/with-var-statement-after/output.tsx new file mode 100644 index 0000000..1fb164b --- /dev/null +++ b/test/remove-default-export-variable-assignment-transform/with-var-statement-after/output.tsx @@ -0,0 +1,3 @@ +const foo: string = 'str'; +export default foo; +var baz = 42; diff --git a/test/remove-default-export-variable-assignment-transform/with-var-statement-before/input.tsx b/test/remove-default-export-variable-assignment-transform/with-var-statement-before/input.tsx new file mode 100644 index 0000000..e10835b --- /dev/null +++ b/test/remove-default-export-variable-assignment-transform/with-var-statement-before/input.tsx @@ -0,0 +1,2 @@ +const bar = 1; +export default const foo: string = 'str'; diff --git a/test/remove-default-export-variable-assignment-transform/with-var-statement-before/output.tsx b/test/remove-default-export-variable-assignment-transform/with-var-statement-before/output.tsx new file mode 100644 index 0000000..b1bdd30 --- /dev/null +++ b/test/remove-default-export-variable-assignment-transform/with-var-statement-before/output.tsx @@ -0,0 +1,3 @@ +const bar = 1; +const foo: string = 'str'; +export default foo; From 88bfa743def7d949870c57254b909bfeaece2ffd Mon Sep 17 00:00:00 2001 From: Mohsen Azimi Date: Sat, 19 May 2018 14:02:40 -0700 Subject: [PATCH 3/5] push Remove default imports higher in transformers list --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index c7fff84..d505d44 100644 --- a/src/index.ts +++ b/src/index.ts @@ -27,11 +27,11 @@ export const allTransforms = [ reactMovePropTypesToClassTransformFactoryFactory, reactJSMakePropsAndStateInterfaceTransformFactoryFactory, reactStatelessFunctionMakePropsTransformFactoryFactory, + removeDefaultExportVariableAssignmentTransformFactoryFactory, collapseIntersectionInterfacesTransformFactoryFactory, reactRemovePropTypesAssignmentTransformFactoryFactory, reactRemoveStaticPropTypesMemberTransformFactoryFactory, reactRemovePropTypesImportTransformFactoryFactory, - removeDefaultExportVariableAssignmentTransformFactoryFactory, ]; export type TransformFactoryFactory = (typeChecker: ts.TypeChecker) => ts.TransformerFactory; From 28c17afdfda8acad8e718916aa21c3fe006ace7b Mon Sep 17 00:00:00 2001 From: Mohsen Azimi Date: Sat, 19 May 2018 14:50:06 -0700 Subject: [PATCH 4/5] add more test --- .../with-import/input.tsx | 3 +++ .../with-import/output.tsx | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 test/remove-default-export-variable-assignment-transform/with-import/input.tsx create mode 100644 test/remove-default-export-variable-assignment-transform/with-import/output.tsx diff --git a/test/remove-default-export-variable-assignment-transform/with-import/input.tsx b/test/remove-default-export-variable-assignment-transform/with-import/input.tsx new file mode 100644 index 0000000..a18d410 --- /dev/null +++ b/test/remove-default-export-variable-assignment-transform/with-import/input.tsx @@ -0,0 +1,3 @@ +import bar from 'bar'; +export default const foo: string = 'str'; + diff --git a/test/remove-default-export-variable-assignment-transform/with-import/output.tsx b/test/remove-default-export-variable-assignment-transform/with-import/output.tsx new file mode 100644 index 0000000..1305625 --- /dev/null +++ b/test/remove-default-export-variable-assignment-transform/with-import/output.tsx @@ -0,0 +1,3 @@ +import bar from 'bar'; +const foo: string = 'str'; +export default foo; From 21e0c56dff928421bbea4867e9ef4ff1b7a4fcae Mon Sep 17 00:00:00 2001 From: Mohsen Azimi Date: Sat, 19 May 2018 14:50:18 -0700 Subject: [PATCH 5/5] jest vscode --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 535d695..090a7dc 100644 --- a/README.md +++ b/README.md @@ -114,3 +114,15 @@ Pass `-t` with transform name and case name space separated to `npm test` ``` npm test -- -t "react-js-make-props-and-state-transform propless-stateless" ``` + +#### Using Visual Studio Code to debug tests + +To run all test run "Test All" from debug panel. + +##### Run a single test + +Edit `.vscode/launch.json` to add the same argument you pass to jest for your specific test. + +##### Breakpoints work with test 🎉 + +Throw a breakpoint anywhere in code to stop the test there and inspect issue.