From 8ee56106915afaff92151054b983dfcb2d83073d Mon Sep 17 00:00:00 2001 From: Justin Bay Date: Tue, 21 Mar 2017 20:33:40 -0400 Subject: [PATCH 1/2] expose transformers option to transpileModule --- src/services/transpile.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/services/transpile.ts b/src/services/transpile.ts index 89ddb887809..e10fcc70a64 100644 --- a/src/services/transpile.ts +++ b/src/services/transpile.ts @@ -5,6 +5,7 @@ namespace ts { reportDiagnostics?: boolean; moduleName?: string; renamedDependencies?: MapLike; + transformers?: CustomTransformers; } export interface TranspileOutput { @@ -103,7 +104,7 @@ namespace ts { addRange(/*to*/ diagnostics, /*from*/ program.getOptionsDiagnostics()); } // Emit - program.emit(); + program.emit(/*targetSourceFile*/ undefined, /*writeFile*/ undefined, /*cancellationToken*/ undefined, /*emitOnlyDtsFiles*/ undefined, transpileOptions.transformers); Debug.assert(outputText !== undefined, "Output generation failed"); From 1f815b63670eb15972528f5613d4e893fb0711a9 Mon Sep 17 00:00:00 2001 From: Justin Bay Date: Fri, 21 Apr 2017 00:27:36 -0400 Subject: [PATCH 2/2] add unit test --- src/harness/unittests/transform.ts | 104 +++++++++++------- ...transformsCorrectly.fromTranspileModule.js | 1 + 2 files changed, 66 insertions(+), 39 deletions(-) create mode 100644 tests/baselines/reference/transformApi/transformsCorrectly.fromTranspileModule.js diff --git a/src/harness/unittests/transform.ts b/src/harness/unittests/transform.ts index 7c9d60f7bc4..71f50ed94a9 100644 --- a/src/harness/unittests/transform.ts +++ b/src/harness/unittests/transform.ts @@ -3,48 +3,74 @@ namespace ts { describe("TransformAPI", () => { - function transformsCorrectly(name: string, source: string, transformers: TransformerFactory[]) { - it(name, () => { - Harness.Baseline.runBaseline(`transformApi/transformsCorrectly.${name}.js`, () => { - const transformed = transform(createSourceFile("source.ts", source, ScriptTarget.ES2015), transformers); - const printer = createPrinter({ newLine: NewLineKind.CarriageReturnLineFeed }, { - onEmitNode: transformed.emitNodeWithNotification, - substituteNode: transformed.substituteNode - }); - const result = printer.printBundle(createBundle(transformed.transformed)); - transformed.dispose(); - return result; - }); + function replaceUndefinedWithVoid0(context: ts.TransformationContext) { + const previousOnSubstituteNode = context.onSubstituteNode; + context.enableSubstitution(SyntaxKind.Identifier); + context.onSubstituteNode = (hint, node) => { + node = previousOnSubstituteNode(hint, node); + if (hint === EmitHint.Expression && node.kind === SyntaxKind.Identifier && (node).text === "undefined") { + node = createPartiallyEmittedExpression( + addSyntheticTrailingComment( + setTextRange( + createVoidZero(), + node), + SyntaxKind.MultiLineCommentTrivia, "undefined")); + } + return node; + }; + return (file: ts.SourceFile) => file; + } + + function replaceIdentifiersNamedOldNameWithNewName(context: ts.TransformationContext) { + const previousOnSubstituteNode = context.onSubstituteNode; + context.enableSubstitution(SyntaxKind.Identifier); + context.onSubstituteNode = (hint, node) => { + node = previousOnSubstituteNode(hint, node); + if (node.kind === SyntaxKind.Identifier && (node).text === "oldName") { + node = setTextRange(createIdentifier("newName"), node); + } + return node; + }; + return (file: ts.SourceFile) => file; + } + + function transformSourceFile(sourceText: string, transformers: TransformerFactory[]) { + const transformed = transform(createSourceFile("source.ts", sourceText, ScriptTarget.ES2015), transformers); + const printer = createPrinter({ newLine: NewLineKind.CarriageReturnLineFeed }, { + onEmitNode: transformed.emitNodeWithNotification, + substituteNode: transformed.substituteNode + }); + const result = printer.printBundle(createBundle(transformed.transformed)); + transformed.dispose(); + return result; + } + + function testBaseline(testName: string, test: () => string) { + it(testName, () => { + Harness.Baseline.runBaseline(`transformApi/transformsCorrectly.${testName}.js`, test); }); } - transformsCorrectly("substitution", ` - var a = undefined; - `, [ - context => { - const previousOnSubstituteNode = context.onSubstituteNode; - context.enableSubstitution(SyntaxKind.Identifier); - context.onSubstituteNode = (hint, node) => { - node = previousOnSubstituteNode(hint, node); - if (hint === EmitHint.Expression && node.kind === SyntaxKind.Identifier && (node).text === "undefined") { - node = createPartiallyEmittedExpression( - addSyntheticTrailingComment( - setTextRange( - createVoidZero(), - node), - SyntaxKind.MultiLineCommentTrivia, "undefined")); - } - return node; - }; - return file => file; - } - ]); + testBaseline("substitution", () => { + return transformSourceFile(`var a = undefined;`, [replaceUndefinedWithVoid0]); + }); - // https://github.com/Microsoft/TypeScript/issues/15192 - transformsCorrectly("types", `let a: () => void`, [ - context => file => visitNode(file, function visitor(node: Node): VisitResult { - return visitEachChild(node, visitor, context); - }) - ]); + testBaseline("types", () => { + return transformSourceFile(`let a: () => void`, [ + context => file => visitNode(file, function visitor(node: Node): VisitResult { + return visitEachChild(node, visitor, context); + }) + ]); + }); + + testBaseline("fromTranspileModule", () => { + return ts.transpileModule(`var oldName = undefined;`, { + transformers: { + before: [replaceUndefinedWithVoid0], + after: [replaceIdentifiersNamedOldNameWithNewName] + } + }).outputText; + }); }); } + diff --git a/tests/baselines/reference/transformApi/transformsCorrectly.fromTranspileModule.js b/tests/baselines/reference/transformApi/transformsCorrectly.fromTranspileModule.js new file mode 100644 index 00000000000..ddf3fd0e8d6 --- /dev/null +++ b/tests/baselines/reference/transformApi/transformsCorrectly.fromTranspileModule.js @@ -0,0 +1 @@ +var newName = void 0 /*undefined*/;