mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 16:38:05 -06:00
Merge pull request #28465 from alangpierce/enforce-const-enum-access-for-isolatedmodules
Change isolatedModules to allow const enum declaration and disallow access
This commit is contained in:
commit
eed9db5ec5
@ -23289,24 +23289,36 @@ namespace ts {
|
||||
const uninstantiatedType = checkExpressionWorker(node, checkMode, forceTuple);
|
||||
const type = instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, checkMode);
|
||||
if (isConstEnumObjectType(type)) {
|
||||
// enum object type for const enums are only permitted in:
|
||||
// - 'left' in property access
|
||||
// - 'object' in indexed access
|
||||
// - target in rhs of import statement
|
||||
const ok =
|
||||
(node.parent.kind === SyntaxKind.PropertyAccessExpression && (<PropertyAccessExpression>node.parent).expression === node) ||
|
||||
(node.parent.kind === SyntaxKind.ElementAccessExpression && (<ElementAccessExpression>node.parent).expression === node) ||
|
||||
((node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName) && isInRightSideOfImportOrExportAssignment(<Identifier>node) ||
|
||||
(node.parent.kind === SyntaxKind.TypeQuery && (<TypeQueryNode>node.parent).exprName === node));
|
||||
|
||||
if (!ok) {
|
||||
error(node, Diagnostics.const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment_or_type_query);
|
||||
}
|
||||
checkConstEnumAccess(node, type);
|
||||
}
|
||||
currentNode = saveCurrentNode;
|
||||
return type;
|
||||
}
|
||||
|
||||
function checkConstEnumAccess(node: Expression | QualifiedName, type: Type) {
|
||||
// enum object type for const enums are only permitted in:
|
||||
// - 'left' in property access
|
||||
// - 'object' in indexed access
|
||||
// - target in rhs of import statement
|
||||
const ok =
|
||||
(node.parent.kind === SyntaxKind.PropertyAccessExpression && (<PropertyAccessExpression>node.parent).expression === node) ||
|
||||
(node.parent.kind === SyntaxKind.ElementAccessExpression && (<ElementAccessExpression>node.parent).expression === node) ||
|
||||
((node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName) && isInRightSideOfImportOrExportAssignment(<Identifier>node) ||
|
||||
(node.parent.kind === SyntaxKind.TypeQuery && (<TypeQueryNode>node.parent).exprName === node));
|
||||
|
||||
if (!ok) {
|
||||
error(node, Diagnostics.const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment_or_type_query);
|
||||
}
|
||||
|
||||
if (compilerOptions.isolatedModules) {
|
||||
Debug.assert(!!(type.symbol.flags & SymbolFlags.ConstEnum));
|
||||
const constEnumDeclaration = type.symbol.valueDeclaration as EnumDeclaration;
|
||||
if (constEnumDeclaration.flags & NodeFlags.Ambient) {
|
||||
error(node, Diagnostics.Cannot_access_ambient_const_enums_when_the_isolatedModules_flag_is_provided);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkParenthesizedExpression(node: ParenthesizedExpression, checkMode?: CheckMode): Type {
|
||||
const tag = isInJSFile(node) ? getJSDocTypeTag(node) : undefined;
|
||||
if (tag) {
|
||||
@ -27484,11 +27496,6 @@ namespace ts {
|
||||
|
||||
computeEnumMemberValues(node);
|
||||
|
||||
const enumIsConst = isEnumConst(node);
|
||||
if (compilerOptions.isolatedModules && enumIsConst && node.flags & NodeFlags.Ambient) {
|
||||
error(node.name, Diagnostics.Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided);
|
||||
}
|
||||
|
||||
// Spec 2014 - Section 9.3:
|
||||
// It isn't possible for one enum declaration to continue the automatic numbering sequence of another,
|
||||
// and when an enum type has multiple declarations, only one declaration is permitted to omit a value
|
||||
@ -27499,6 +27506,7 @@ namespace ts {
|
||||
const firstDeclaration = getDeclarationOfKind(enumSymbol, node.kind);
|
||||
if (node === firstDeclaration) {
|
||||
if (enumSymbol.declarations.length > 1) {
|
||||
const enumIsConst = isEnumConst(node);
|
||||
// check that const is placed\omitted on all enum declarations
|
||||
forEach(enumSymbol.declarations, decl => {
|
||||
if (isEnumDeclaration(decl) && isEnumConst(decl) !== enumIsConst) {
|
||||
|
||||
@ -659,10 +659,6 @@
|
||||
"category": "Error",
|
||||
"code": 1208
|
||||
},
|
||||
"Ambient const enums are not allowed when the '--isolatedModules' flag is provided.": {
|
||||
"category": "Error",
|
||||
"code": 1209
|
||||
},
|
||||
"Invalid use of '{0}'. Class definitions are automatically in strict mode.": {
|
||||
"category": "Error",
|
||||
"code": 1210
|
||||
@ -2581,6 +2577,10 @@
|
||||
"category": "Error",
|
||||
"code": 2747
|
||||
},
|
||||
"Cannot access ambient const enums when the '--isolatedModules' flag is provided.": {
|
||||
"category": "Error",
|
||||
"code": 2748
|
||||
},
|
||||
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
tests/cases/compiler/file1.ts(1,20): error TS1209: Ambient const enums are not allowed when the '--isolatedModules' flag is provided.
|
||||
tests/cases/compiler/file1.ts(2,16): error TS2748: Cannot access ambient const enums when the '--isolatedModules' flag is provided.
|
||||
|
||||
|
||||
==== tests/cases/compiler/file1.ts (1 errors) ====
|
||||
declare const enum E { X = 1}
|
||||
~
|
||||
!!! error TS1209: Ambient const enums are not allowed when the '--isolatedModules' flag is provided.
|
||||
export var y;
|
||||
export var y = E.X;
|
||||
~
|
||||
!!! error TS2748: Cannot access ambient const enums when the '--isolatedModules' flag is provided.
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
//// [file1.ts]
|
||||
declare const enum E { X = 1}
|
||||
export var y;
|
||||
export var y = E.X;
|
||||
|
||||
|
||||
//// [file1.js]
|
||||
export var y;
|
||||
export var y = E.X;
|
||||
|
||||
@ -3,6 +3,9 @@ declare const enum E { X = 1}
|
||||
>E : Symbol(E, Decl(file1.ts, 0, 0))
|
||||
>X : Symbol(E.X, Decl(file1.ts, 0, 22))
|
||||
|
||||
export var y;
|
||||
export var y = E.X;
|
||||
>y : Symbol(y, Decl(file1.ts, 1, 10))
|
||||
>E.X : Symbol(E.X, Decl(file1.ts, 0, 22))
|
||||
>E : Symbol(E, Decl(file1.ts, 0, 0))
|
||||
>X : Symbol(E.X, Decl(file1.ts, 0, 22))
|
||||
|
||||
|
||||
@ -4,6 +4,9 @@ declare const enum E { X = 1}
|
||||
>X : E.X
|
||||
>1 : 1
|
||||
|
||||
export var y;
|
||||
>y : any
|
||||
export var y = E.X;
|
||||
>y : E
|
||||
>E.X : E
|
||||
>E : typeof E
|
||||
>X : E
|
||||
|
||||
|
||||
@ -4,4 +4,4 @@
|
||||
// @filename: file1.ts
|
||||
|
||||
declare const enum E { X = 1}
|
||||
export var y;
|
||||
export var y = E.X;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user