emit unqualified enum members as qualified
This commit is contained in:
parent
1317d23a8a
commit
0e0182c1ea
4 changed files with 85 additions and 27 deletions
|
@ -13,6 +13,8 @@ namespace ts {
|
||||||
NamespaceExports = 1 << 1,
|
NamespaceExports = 1 << 1,
|
||||||
/** Enables substitutions for async methods with `super` calls. */
|
/** Enables substitutions for async methods with `super` calls. */
|
||||||
AsyncMethodsWithSuper = 1 << 2,
|
AsyncMethodsWithSuper = 1 << 2,
|
||||||
|
/* Enables substitutions for unqualified enum members */
|
||||||
|
NonQualifiedEnumMembers = 1 << 3
|
||||||
}
|
}
|
||||||
|
|
||||||
export function transformTypeScript(context: TransformationContext) {
|
export function transformTypeScript(context: TransformationContext) {
|
||||||
|
@ -65,7 +67,7 @@ namespace ts {
|
||||||
* Keeps track of whether we are within any containing namespaces when performing
|
* Keeps track of whether we are within any containing namespaces when performing
|
||||||
* just-in-time substitution while printing an expression identifier.
|
* just-in-time substitution while printing an expression identifier.
|
||||||
*/
|
*/
|
||||||
let isEnclosedInNamespace: boolean;
|
let applicableSubstitutions: TypeScriptSubstitutionFlags;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This keeps track of containers where `super` is valid, for use with
|
* This keeps track of containers where `super` is valid, for use with
|
||||||
|
@ -2234,26 +2236,29 @@ namespace ts {
|
||||||
// ...
|
// ...
|
||||||
// })(x || (x = {}));
|
// })(x || (x = {}));
|
||||||
statements.push(
|
statements.push(
|
||||||
setOriginalNode(
|
setNodeEmitFlags(
|
||||||
createStatement(
|
setOriginalNode(
|
||||||
createCall(
|
createStatement(
|
||||||
createFunctionExpression(
|
createCall(
|
||||||
|
createFunctionExpression(
|
||||||
/*asteriskToken*/ undefined,
|
/*asteriskToken*/ undefined,
|
||||||
/*name*/ undefined,
|
/*name*/ undefined,
|
||||||
[createParameter(localName)],
|
[createParameter(localName)],
|
||||||
transformEnumBody(node, localName)
|
transformEnumBody(node, localName)
|
||||||
),
|
),
|
||||||
[createLogicalOr(
|
[createLogicalOr(
|
||||||
name,
|
|
||||||
createAssignment(
|
|
||||||
name,
|
name,
|
||||||
createObjectLiteral()
|
createAssignment(
|
||||||
)
|
name,
|
||||||
)]
|
createObjectLiteral()
|
||||||
),
|
)
|
||||||
|
)]
|
||||||
|
),
|
||||||
/*location*/ node
|
/*location*/ node
|
||||||
),
|
),
|
||||||
/*original*/ node
|
/*original*/ node
|
||||||
|
),
|
||||||
|
NodeEmitFlags.AdviseOnEmitNode
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2317,11 +2322,14 @@ namespace ts {
|
||||||
if (value !== undefined) {
|
if (value !== undefined) {
|
||||||
return createLiteral(value);
|
return createLiteral(value);
|
||||||
}
|
}
|
||||||
else if (member.initializer) {
|
|
||||||
return visitNode(member.initializer, visitor, isExpression);
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
return createVoidZero();
|
enableSubstitutionForNonQualifiedEnumMembers();
|
||||||
|
if (member.initializer) {
|
||||||
|
return visitNode(member.initializer, visitor, isExpression);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return createVoidZero();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2634,8 +2642,12 @@ namespace ts {
|
||||||
return getOriginalNode(node).kind === SyntaxKind.ModuleDeclaration;
|
return getOriginalNode(node).kind === SyntaxKind.ModuleDeclaration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isTransformedEnumDeclaration(node: Node): boolean {
|
||||||
|
return getOriginalNode(node).kind === SyntaxKind.EnumDeclaration;
|
||||||
|
}
|
||||||
|
|
||||||
function onEmitNode(node: Node, emit: (node: Node) => void): void {
|
function onEmitNode(node: Node, emit: (node: Node) => void): void {
|
||||||
const savedIsEnclosedInNamespace = isEnclosedInNamespace;
|
const savedApplicableSubstitutions = applicableSubstitutions;
|
||||||
const savedCurrentSuperContainer = currentSuperContainer;
|
const savedCurrentSuperContainer = currentSuperContainer;
|
||||||
|
|
||||||
// If we need support substitutions for aliases for decorated classes,
|
// If we need support substitutions for aliases for decorated classes,
|
||||||
|
@ -2651,7 +2663,10 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enabledSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports && isTransformedModuleDeclaration(node)) {
|
if (enabledSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports && isTransformedModuleDeclaration(node)) {
|
||||||
isEnclosedInNamespace = true;
|
applicableSubstitutions |= TypeScriptSubstitutionFlags.NamespaceExports;
|
||||||
|
}
|
||||||
|
if (enabledSubstitutions & TypeScriptSubstitutionFlags.NonQualifiedEnumMembers && isTransformedEnumDeclaration(node)) {
|
||||||
|
applicableSubstitutions |= TypeScriptSubstitutionFlags.NonQualifiedEnumMembers;
|
||||||
}
|
}
|
||||||
|
|
||||||
previousOnEmitNode(node, emit);
|
previousOnEmitNode(node, emit);
|
||||||
|
@ -2660,7 +2675,7 @@ namespace ts {
|
||||||
currentDecoratedClassAliases[getOriginalNodeId(node)] = undefined;
|
currentDecoratedClassAliases[getOriginalNodeId(node)] = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
isEnclosedInNamespace = savedIsEnclosedInNamespace;
|
applicableSubstitutions = savedApplicableSubstitutions;
|
||||||
currentSuperContainer = savedCurrentSuperContainer;
|
currentSuperContainer = savedCurrentSuperContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2705,18 +2720,22 @@ namespace ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enabledSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports && isEnclosedInNamespace) {
|
if (enabledSubstitutions & applicableSubstitutions) {
|
||||||
// If we are nested within a namespace declaration, we may need to qualifiy
|
// If we are nested within a namespace declaration, we may need to qualifiy
|
||||||
// an identifier that is exported from a merged namespace.
|
// an identifier that is exported from a merged namespace.
|
||||||
const original = getOriginalNode(node);
|
const original = getOriginalNode(node);
|
||||||
if (isIdentifier(original) && original.parent) {
|
if (isIdentifier(original) && original.parent) {
|
||||||
const container = resolver.getReferencedExportContainer(original);
|
const container = resolver.getReferencedExportContainer(original);
|
||||||
if (container && container.kind === SyntaxKind.ModuleDeclaration) {
|
if (container) {
|
||||||
return createPropertyAccess(getGeneratedNameForNode(container), node, /*location*/ node);
|
const substitute =
|
||||||
|
(applicableSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports && container.kind === SyntaxKind.ModuleDeclaration) ||
|
||||||
|
(applicableSubstitutions & TypeScriptSubstitutionFlags.NonQualifiedEnumMembers && container.kind === SyntaxKind.EnumDeclaration);
|
||||||
|
if (substitute) {
|
||||||
|
return createPropertyAccess(getGeneratedNameForNode(container), node, /*location*/ node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2770,6 +2789,13 @@ namespace ts {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function enableSubstitutionForNonQualifiedEnumMembers() {
|
||||||
|
if ((enabledSubstitutions & TypeScriptSubstitutionFlags.NonQualifiedEnumMembers) === 0) {
|
||||||
|
enabledSubstitutions |= TypeScriptSubstitutionFlags.NonQualifiedEnumMembers;
|
||||||
|
context.enableExpressionSubstitution(SyntaxKind.Identifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function enableExpressionSubstitutionForAsyncMethodsWithSuper() {
|
function enableExpressionSubstitutionForAsyncMethodsWithSuper() {
|
||||||
if ((enabledSubstitutions & TypeScriptSubstitutionFlags.AsyncMethodsWithSuper) === 0) {
|
if ((enabledSubstitutions & TypeScriptSubstitutionFlags.AsyncMethodsWithSuper) === 0) {
|
||||||
enabledSubstitutions |= TypeScriptSubstitutionFlags.AsyncMethodsWithSuper;
|
enabledSubstitutions |= TypeScriptSubstitutionFlags.AsyncMethodsWithSuper;
|
||||||
|
|
12
tests/baselines/reference/enumWithComputedMember.errors.txt
Normal file
12
tests/baselines/reference/enumWithComputedMember.errors.txt
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
tests/cases/compiler/enumWithComputedMember.ts(4,5): error TS1061: Enum member must have initializer.
|
||||||
|
|
||||||
|
|
||||||
|
==== tests/cases/compiler/enumWithComputedMember.ts (1 errors) ====
|
||||||
|
enum A {
|
||||||
|
X = "".length,
|
||||||
|
Y = X,
|
||||||
|
Z
|
||||||
|
~
|
||||||
|
!!! error TS1061: Enum member must have initializer.
|
||||||
|
}
|
||||||
|
|
15
tests/baselines/reference/enumWithComputedMember.js
Normal file
15
tests/baselines/reference/enumWithComputedMember.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
//// [enumWithComputedMember.ts]
|
||||||
|
enum A {
|
||||||
|
X = "".length,
|
||||||
|
Y = X,
|
||||||
|
Z
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//// [enumWithComputedMember.js]
|
||||||
|
var A;
|
||||||
|
(function (A) {
|
||||||
|
A[A["X"] = "".length] = "X";
|
||||||
|
A[A["Y"] = A.X] = "Y";
|
||||||
|
A[A["Z"] = void 0] = "Z";
|
||||||
|
})(A || (A = {}));
|
5
tests/cases/compiler/enumWithComputedMember.ts
Normal file
5
tests/cases/compiler/enumWithComputedMember.ts
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
enum A {
|
||||||
|
X = "".length,
|
||||||
|
Y = X,
|
||||||
|
Z
|
||||||
|
}
|
Loading…
Reference in a new issue