mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-16 05:58:32 -06:00
Merge pull request #7921 from Microsoft/unqualifiedEnumMembers
emit unqualified enum members as qualified
This commit is contained in:
commit
5c6009ceae
@ -18,6 +18,8 @@ namespace ts {
|
||||
NamespaceExports = 1 << 1,
|
||||
/** Enables substitutions for async methods with `super` calls. */
|
||||
AsyncMethodsWithSuper = 1 << 2,
|
||||
/* Enables substitutions for unqualified enum members */
|
||||
NonQualifiedEnumMembers = 1 << 3
|
||||
}
|
||||
|
||||
export function transformTypeScript(context: TransformationContext) {
|
||||
@ -70,7 +72,7 @@ namespace ts {
|
||||
* Keeps track of whether we are within any containing namespaces when performing
|
||||
* 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
|
||||
@ -2263,26 +2265,29 @@ namespace ts {
|
||||
// ...
|
||||
// })(x || (x = {}));
|
||||
statements.push(
|
||||
setOriginalNode(
|
||||
createStatement(
|
||||
createCall(
|
||||
createFunctionExpression(
|
||||
setNodeEmitFlags(
|
||||
setOriginalNode(
|
||||
createStatement(
|
||||
createCall(
|
||||
createFunctionExpression(
|
||||
/*asteriskToken*/ undefined,
|
||||
/*name*/ undefined,
|
||||
[createParameter(localName)],
|
||||
transformEnumBody(node, localName)
|
||||
),
|
||||
[createLogicalOr(
|
||||
name,
|
||||
createAssignment(
|
||||
[createParameter(localName)],
|
||||
transformEnumBody(node, localName)
|
||||
),
|
||||
[createLogicalOr(
|
||||
name,
|
||||
createObjectLiteral()
|
||||
)
|
||||
)]
|
||||
),
|
||||
createAssignment(
|
||||
name,
|
||||
createObjectLiteral()
|
||||
)
|
||||
)]
|
||||
),
|
||||
/*location*/ node
|
||||
),
|
||||
),
|
||||
/*original*/ node
|
||||
),
|
||||
NodeEmitFlags.AdviseOnEmitNode
|
||||
)
|
||||
);
|
||||
|
||||
@ -2346,11 +2351,14 @@ namespace ts {
|
||||
if (value !== undefined) {
|
||||
return createLiteral(value);
|
||||
}
|
||||
else if (member.initializer) {
|
||||
return visitNode(member.initializer, visitor, isExpression);
|
||||
}
|
||||
else {
|
||||
return createVoidZero();
|
||||
enableSubstitutionForNonQualifiedEnumMembers();
|
||||
if (member.initializer) {
|
||||
return visitNode(member.initializer, visitor, isExpression);
|
||||
}
|
||||
else {
|
||||
return createVoidZero();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2663,8 +2671,12 @@ namespace ts {
|
||||
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 {
|
||||
const savedIsEnclosedInNamespace = isEnclosedInNamespace;
|
||||
const savedApplicableSubstitutions = applicableSubstitutions;
|
||||
const savedCurrentSuperContainer = currentSuperContainer;
|
||||
|
||||
// If we need support substitutions for aliases for decorated classes,
|
||||
@ -2680,7 +2692,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (enabledSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports && isTransformedModuleDeclaration(node)) {
|
||||
isEnclosedInNamespace = true;
|
||||
applicableSubstitutions |= TypeScriptSubstitutionFlags.NamespaceExports;
|
||||
}
|
||||
if (enabledSubstitutions & TypeScriptSubstitutionFlags.NonQualifiedEnumMembers && isTransformedEnumDeclaration(node)) {
|
||||
applicableSubstitutions |= TypeScriptSubstitutionFlags.NonQualifiedEnumMembers;
|
||||
}
|
||||
|
||||
previousOnEmitNode(node, emit);
|
||||
@ -2689,7 +2704,7 @@ namespace ts {
|
||||
currentDecoratedClassAliases[getOriginalNodeId(node)] = undefined;
|
||||
}
|
||||
|
||||
isEnclosedInNamespace = savedIsEnclosedInNamespace;
|
||||
applicableSubstitutions = savedApplicableSubstitutions;
|
||||
currentSuperContainer = savedCurrentSuperContainer;
|
||||
}
|
||||
|
||||
@ -2734,18 +2749,22 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
if (enabledSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports && isEnclosedInNamespace) {
|
||||
if (enabledSubstitutions & applicableSubstitutions) {
|
||||
// If we are nested within a namespace declaration, we may need to qualifiy
|
||||
// an identifier that is exported from a merged namespace.
|
||||
const original = getOriginalNode(node);
|
||||
if (isIdentifier(original) && original.parent) {
|
||||
const container = resolver.getReferencedExportContainer(original);
|
||||
if (container && container.kind === SyntaxKind.ModuleDeclaration) {
|
||||
return createPropertyAccess(getGeneratedNameForNode(container), node, /*location*/ node);
|
||||
if (container) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -2799,6 +2818,13 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
function enableSubstitutionForNonQualifiedEnumMembers() {
|
||||
if ((enabledSubstitutions & TypeScriptSubstitutionFlags.NonQualifiedEnumMembers) === 0) {
|
||||
enabledSubstitutions |= TypeScriptSubstitutionFlags.NonQualifiedEnumMembers;
|
||||
context.enableExpressionSubstitution(SyntaxKind.Identifier);
|
||||
}
|
||||
}
|
||||
|
||||
function enableExpressionSubstitutionForAsyncMethodsWithSuper() {
|
||||
if ((enabledSubstitutions & TypeScriptSubstitutionFlags.AsyncMethodsWithSuper) === 0) {
|
||||
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…
x
Reference in New Issue
Block a user