Skip to content

Commit 2e1738b

Browse files
authored
Enable substitution for object literal shorthand property assignments in the system transform (#21106)
1 parent 64305ed commit 2e1738b

File tree

5 files changed

+163
-0
lines changed

5 files changed

+163
-0
lines changed

src/compiler/transformers/module/system.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ namespace ts {
2424
context.onSubstituteNode = onSubstituteNode;
2525
context.onEmitNode = onEmitNode;
2626
context.enableSubstitution(SyntaxKind.Identifier); // Substitutes expression identifiers for imported symbols.
27+
context.enableSubstitution(SyntaxKind.ShorthandPropertyAssignment); // Substitutes expression identifiers for imported symbols
2728
context.enableSubstitution(SyntaxKind.BinaryExpression); // Substitutes assignments to exported symbols.
2829
context.enableSubstitution(SyntaxKind.PrefixUnaryExpression); // Substitutes updates to exported symbols.
2930
context.enableSubstitution(SyntaxKind.PostfixUnaryExpression); // Substitutes updates to exported symbols.
@@ -1625,10 +1626,64 @@ namespace ts {
16251626
if (hint === EmitHint.Expression) {
16261627
return substituteExpression(<Expression>node);
16271628
}
1629+
else if (hint === EmitHint.Unspecified) {
1630+
return substituteUnspecified(node);
1631+
}
16281632

16291633
return node;
16301634
}
16311635

1636+
/**
1637+
* Substitute the node, if necessary.
1638+
*
1639+
* @param node The node to substitute.
1640+
*/
1641+
function substituteUnspecified(node: Node) {
1642+
switch (node.kind) {
1643+
case SyntaxKind.ShorthandPropertyAssignment:
1644+
return substituteShorthandPropertyAssignment(<ShorthandPropertyAssignment>node);
1645+
}
1646+
return node;
1647+
}
1648+
/**
1649+
* Substitution for a ShorthandPropertyAssignment whose name that may contain an imported or exported symbol.
1650+
*
1651+
* @param node The node to substitute.
1652+
*/
1653+
function substituteShorthandPropertyAssignment(node: ShorthandPropertyAssignment) {
1654+
const name = node.name;
1655+
if (!isGeneratedIdentifier(name) && !isLocalName(name)) {
1656+
const importDeclaration = resolver.getReferencedImportDeclaration(name);
1657+
if (importDeclaration) {
1658+
if (isImportClause(importDeclaration)) {
1659+
return setTextRange(
1660+
createPropertyAssignment(
1661+
getSynthesizedClone(name),
1662+
createPropertyAccess(
1663+
getGeneratedNameForNode(importDeclaration.parent),
1664+
createIdentifier("default")
1665+
)
1666+
),
1667+
/*location*/ node
1668+
);
1669+
}
1670+
else if (isImportSpecifier(importDeclaration)) {
1671+
return setTextRange(
1672+
createPropertyAssignment(
1673+
getSynthesizedClone(name),
1674+
createPropertyAccess(
1675+
getGeneratedNameForNode(importDeclaration.parent.parent.parent),
1676+
getSynthesizedClone(importDeclaration.propertyName || importDeclaration.name)
1677+
),
1678+
),
1679+
/*location*/ node
1680+
);
1681+
}
1682+
}
1683+
}
1684+
return node;
1685+
}
1686+
16321687
/**
16331688
* Substitute the expression, if necessary.
16341689
*
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//// [tests/cases/compiler/systemObjectShorthandRename.ts] ////
2+
3+
//// [x.ts]
4+
export const x = 'X'
5+
//// [index.ts]
6+
import {x} from './x.js'
7+
8+
const x2 = {x}
9+
const a = {x2}
10+
11+
const x3 = x
12+
const b = {x3}
13+
14+
//// [x.js]
15+
System.register([], function (exports_1, context_1) {
16+
"use strict";
17+
var __moduleName = context_1 && context_1.id;
18+
var x;
19+
return {
20+
setters: [],
21+
execute: function () {
22+
exports_1("x", x = 'X');
23+
}
24+
};
25+
});
26+
//// [index.js]
27+
System.register(["./x.js"], function (exports_1, context_1) {
28+
"use strict";
29+
var __moduleName = context_1 && context_1.id;
30+
var x_js_1, x2, a, x3, b;
31+
return {
32+
setters: [
33+
function (x_js_1_1) {
34+
x_js_1 = x_js_1_1;
35+
}
36+
],
37+
execute: function () {
38+
x2 = { x: x_js_1.x };
39+
a = { x2 };
40+
x3 = x_js_1.x;
41+
b = { x3 };
42+
}
43+
};
44+
});
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
=== tests/cases/compiler/x.ts ===
2+
export const x = 'X'
3+
>x : Symbol(x, Decl(x.ts, 0, 12))
4+
5+
=== tests/cases/compiler/index.ts ===
6+
import {x} from './x.js'
7+
>x : Symbol(x, Decl(index.ts, 0, 8))
8+
9+
const x2 = {x}
10+
>x2 : Symbol(x2, Decl(index.ts, 2, 5))
11+
>x : Symbol(x, Decl(index.ts, 2, 12))
12+
13+
const a = {x2}
14+
>a : Symbol(a, Decl(index.ts, 3, 5))
15+
>x2 : Symbol(x2, Decl(index.ts, 3, 11))
16+
17+
const x3 = x
18+
>x3 : Symbol(x3, Decl(index.ts, 5, 5))
19+
>x : Symbol(x, Decl(index.ts, 0, 8))
20+
21+
const b = {x3}
22+
>b : Symbol(b, Decl(index.ts, 6, 5))
23+
>x3 : Symbol(x3, Decl(index.ts, 6, 11))
24+
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
=== tests/cases/compiler/x.ts ===
2+
export const x = 'X'
3+
>x : "X"
4+
>'X' : "X"
5+
6+
=== tests/cases/compiler/index.ts ===
7+
import {x} from './x.js'
8+
>x : "X"
9+
10+
const x2 = {x}
11+
>x2 : { x: string; }
12+
>{x} : { x: string; }
13+
>x : string
14+
15+
const a = {x2}
16+
>a : { x2: { x: string; }; }
17+
>{x2} : { x2: { x: string; }; }
18+
>x2 : { x: string; }
19+
20+
const x3 = x
21+
>x3 : "X"
22+
>x : "X"
23+
24+
const b = {x3}
25+
>b : { x3: string; }
26+
>{x3} : { x3: string; }
27+
>x3 : string
28+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// @module: system
2+
// @target: es2015
3+
// @filename: x.ts
4+
export const x = 'X'
5+
// @filename: index.ts
6+
import {x} from './x.js'
7+
8+
const x2 = {x}
9+
const a = {x2}
10+
11+
const x3 = x
12+
const b = {x3}

0 commit comments

Comments
 (0)