From 2e1738bffaa9af5feaf343830f892c84abd82ced Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 12 Jan 2018 18:24:41 -0800 Subject: [PATCH] Enable substitution for object literal shorthand property assignments in the system transform (#21106) --- src/compiler/transformers/module/system.ts | 55 +++++++++++++++++++ .../reference/systemObjectShorthandRename.js | 44 +++++++++++++++ .../systemObjectShorthandRename.symbols | 24 ++++++++ .../systemObjectShorthandRename.types | 28 ++++++++++ .../compiler/systemObjectShorthandRename.ts | 12 ++++ 5 files changed, 163 insertions(+) create mode 100644 tests/baselines/reference/systemObjectShorthandRename.js create mode 100644 tests/baselines/reference/systemObjectShorthandRename.symbols create mode 100644 tests/baselines/reference/systemObjectShorthandRename.types create mode 100644 tests/cases/compiler/systemObjectShorthandRename.ts diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index e5d638cf04d..2e6f6d84b51 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -24,6 +24,7 @@ namespace ts { context.onSubstituteNode = onSubstituteNode; context.onEmitNode = onEmitNode; context.enableSubstitution(SyntaxKind.Identifier); // Substitutes expression identifiers for imported symbols. + context.enableSubstitution(SyntaxKind.ShorthandPropertyAssignment); // Substitutes expression identifiers for imported symbols context.enableSubstitution(SyntaxKind.BinaryExpression); // Substitutes assignments to exported symbols. context.enableSubstitution(SyntaxKind.PrefixUnaryExpression); // Substitutes updates to exported symbols. context.enableSubstitution(SyntaxKind.PostfixUnaryExpression); // Substitutes updates to exported symbols. @@ -1625,10 +1626,64 @@ namespace ts { if (hint === EmitHint.Expression) { return substituteExpression(node); } + else if (hint === EmitHint.Unspecified) { + return substituteUnspecified(node); + } return node; } + /** + * Substitute the node, if necessary. + * + * @param node The node to substitute. + */ + function substituteUnspecified(node: Node) { + switch (node.kind) { + case SyntaxKind.ShorthandPropertyAssignment: + return substituteShorthandPropertyAssignment(node); + } + return node; + } + /** + * Substitution for a ShorthandPropertyAssignment whose name that may contain an imported or exported symbol. + * + * @param node The node to substitute. + */ + function substituteShorthandPropertyAssignment(node: ShorthandPropertyAssignment) { + const name = node.name; + if (!isGeneratedIdentifier(name) && !isLocalName(name)) { + const importDeclaration = resolver.getReferencedImportDeclaration(name); + if (importDeclaration) { + if (isImportClause(importDeclaration)) { + return setTextRange( + createPropertyAssignment( + getSynthesizedClone(name), + createPropertyAccess( + getGeneratedNameForNode(importDeclaration.parent), + createIdentifier("default") + ) + ), + /*location*/ node + ); + } + else if (isImportSpecifier(importDeclaration)) { + return setTextRange( + createPropertyAssignment( + getSynthesizedClone(name), + createPropertyAccess( + getGeneratedNameForNode(importDeclaration.parent.parent.parent), + getSynthesizedClone(importDeclaration.propertyName || importDeclaration.name) + ), + ), + /*location*/ node + ); + } + } + } + return node; + } + /** * Substitute the expression, if necessary. * diff --git a/tests/baselines/reference/systemObjectShorthandRename.js b/tests/baselines/reference/systemObjectShorthandRename.js new file mode 100644 index 00000000000..a7ac63968cd --- /dev/null +++ b/tests/baselines/reference/systemObjectShorthandRename.js @@ -0,0 +1,44 @@ +//// [tests/cases/compiler/systemObjectShorthandRename.ts] //// + +//// [x.ts] +export const x = 'X' +//// [index.ts] +import {x} from './x.js' + +const x2 = {x} +const a = {x2} + +const x3 = x +const b = {x3} + +//// [x.js] +System.register([], function (exports_1, context_1) { + "use strict"; + var __moduleName = context_1 && context_1.id; + var x; + return { + setters: [], + execute: function () { + exports_1("x", x = 'X'); + } + }; +}); +//// [index.js] +System.register(["./x.js"], function (exports_1, context_1) { + "use strict"; + var __moduleName = context_1 && context_1.id; + var x_js_1, x2, a, x3, b; + return { + setters: [ + function (x_js_1_1) { + x_js_1 = x_js_1_1; + } + ], + execute: function () { + x2 = { x: x_js_1.x }; + a = { x2 }; + x3 = x_js_1.x; + b = { x3 }; + } + }; +}); diff --git a/tests/baselines/reference/systemObjectShorthandRename.symbols b/tests/baselines/reference/systemObjectShorthandRename.symbols new file mode 100644 index 00000000000..3321d047ea1 --- /dev/null +++ b/tests/baselines/reference/systemObjectShorthandRename.symbols @@ -0,0 +1,24 @@ +=== tests/cases/compiler/x.ts === +export const x = 'X' +>x : Symbol(x, Decl(x.ts, 0, 12)) + +=== tests/cases/compiler/index.ts === +import {x} from './x.js' +>x : Symbol(x, Decl(index.ts, 0, 8)) + +const x2 = {x} +>x2 : Symbol(x2, Decl(index.ts, 2, 5)) +>x : Symbol(x, Decl(index.ts, 2, 12)) + +const a = {x2} +>a : Symbol(a, Decl(index.ts, 3, 5)) +>x2 : Symbol(x2, Decl(index.ts, 3, 11)) + +const x3 = x +>x3 : Symbol(x3, Decl(index.ts, 5, 5)) +>x : Symbol(x, Decl(index.ts, 0, 8)) + +const b = {x3} +>b : Symbol(b, Decl(index.ts, 6, 5)) +>x3 : Symbol(x3, Decl(index.ts, 6, 11)) + diff --git a/tests/baselines/reference/systemObjectShorthandRename.types b/tests/baselines/reference/systemObjectShorthandRename.types new file mode 100644 index 00000000000..23f3d74c951 --- /dev/null +++ b/tests/baselines/reference/systemObjectShorthandRename.types @@ -0,0 +1,28 @@ +=== tests/cases/compiler/x.ts === +export const x = 'X' +>x : "X" +>'X' : "X" + +=== tests/cases/compiler/index.ts === +import {x} from './x.js' +>x : "X" + +const x2 = {x} +>x2 : { x: string; } +>{x} : { x: string; } +>x : string + +const a = {x2} +>a : { x2: { x: string; }; } +>{x2} : { x2: { x: string; }; } +>x2 : { x: string; } + +const x3 = x +>x3 : "X" +>x : "X" + +const b = {x3} +>b : { x3: string; } +>{x3} : { x3: string; } +>x3 : string + diff --git a/tests/cases/compiler/systemObjectShorthandRename.ts b/tests/cases/compiler/systemObjectShorthandRename.ts new file mode 100644 index 00000000000..7bc6ce56649 --- /dev/null +++ b/tests/cases/compiler/systemObjectShorthandRename.ts @@ -0,0 +1,12 @@ +// @module: system +// @target: es2015 +// @filename: x.ts +export const x = 'X' +// @filename: index.ts +import {x} from './x.js' + +const x2 = {x} +const a = {x2} + +const x3 = x +const b = {x3} \ No newline at end of file