Skip to content

Commit 5d46d43

Browse files
author
Kanchalai Tanglertsampan
committed
Error when used enum before declaration
1 parent f7df4e0 commit 5d46d43

File tree

5 files changed

+51
-6
lines changed

5 files changed

+51
-6
lines changed

src/compiler/checker.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,9 +1056,10 @@ namespace ts {
10561056
// block-scoped variable and namespace module. However, only when we
10571057
// try to resolve name in /*1*/ which is used in variable position,
10581058
// we want to check for block-scoped
1059-
if (meaning & SymbolFlags.BlockScopedVariable || (meaning & SymbolFlags.Class && (meaning & SymbolFlags.Value) === SymbolFlags.Value)) {
1059+
if (meaning & SymbolFlags.BlockScopedVariable ||
1060+
((meaning & SymbolFlags.Class || meaning & SymbolFlags.Enum) && (meaning & SymbolFlags.Value) === SymbolFlags.Value)) {
10601061
const exportOrLocalSymbol = getExportSymbolOfValueSymbolIfExported(result);
1061-
if (exportOrLocalSymbol.flags & SymbolFlags.BlockScopedVariable || exportOrLocalSymbol.flags & SymbolFlags.Class) {
1062+
if (exportOrLocalSymbol.flags & SymbolFlags.BlockScopedVariable || exportOrLocalSymbol.flags & SymbolFlags.Class || exportOrLocalSymbol.flags & SymbolFlags.Enum) {
10621063
checkResolvedBlockScopedVariable(exportOrLocalSymbol, errorLocation);
10631064
}
10641065
}
@@ -1171,19 +1172,22 @@ namespace ts {
11711172
}
11721173

11731174
function checkResolvedBlockScopedVariable(result: Symbol, errorLocation: Node): void {
1174-
Debug.assert(!!(result.flags & SymbolFlags.BlockScopedVariable || result.flags & SymbolFlags.Class));
1175+
Debug.assert(!!(result.flags & SymbolFlags.BlockScopedVariable || result.flags & SymbolFlags.Class || result.flags & SymbolFlags.Enum));
11751176
// Block-scoped variables cannot be used before their definition
1176-
const declaration = forEach(result.declarations, d => isBlockOrCatchScoped(d) || isClassLike(d) ? d : undefined);
1177+
const declaration = forEach(result.declarations, d => isBlockOrCatchScoped(d) || isClassLike(d) || (d.kind === SyntaxKind.EnumDeclaration) ? d : undefined);
11771178

1178-
Debug.assert(declaration !== undefined, "Block-scoped variable declaration is undefined");
1179+
Debug.assert(declaration !== undefined, "Declaration to checkResolvedBlockScopedVariable is undefined");
11791180

11801181
if (!isInAmbientContext(declaration) && !isBlockScopedNameDeclaredBeforeUse(declaration, errorLocation)) {
11811182
if (result.flags & SymbolFlags.BlockScopedVariable) {
11821183
error(errorLocation, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, declarationNameToString(declaration.name));
11831184
}
1184-
else {
1185+
else if (result.flags & SymbolFlags.Class) {
11851186
error(errorLocation, Diagnostics.Class_0_used_before_its_declaration, declarationNameToString(declaration.name));
11861187
}
1188+
else if (result.flags & SymbolFlags.Enum) {
1189+
error(errorLocation, Diagnostics.Enum_0_used_before_its_declaration, declarationNameToString(declaration.name));
1190+
}
11871191
}
11881192
}
11891193

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1439,6 +1439,10 @@
14391439
"category": "Error",
14401440
"code": 2449
14411441
},
1442+
"Enum '{0}' used before its declaration.": {
1443+
"category": "Error",
1444+
"code": 2450
1445+
},
14421446
"Cannot redeclare block-scoped variable '{0}'.": {
14431447
"category": "Error",
14441448
"code": 2451
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
tests/cases/compiler/enumUsedBeforeDeclaration.ts(1,18): error TS2450: Enum 'Color' used before its declaration.
2+
tests/cases/compiler/enumUsedBeforeDeclaration.ts(2,24): error TS2450: Enum 'ConstColor' used before its declaration.
3+
4+
5+
==== tests/cases/compiler/enumUsedBeforeDeclaration.ts (2 errors) ====
6+
const v: Color = Color.Green;
7+
~~~~~
8+
!!! error TS2450: Enum 'Color' used before its declaration.
9+
const v2: ConstColor = ConstColor.Green;
10+
~~~~~~~~~~
11+
!!! error TS2450: Enum 'ConstColor' used before its declaration.
12+
enum Color { Red, Green, Blue }
13+
const enum ConstColor { Red, Green, Blue }
14+
15+
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//// [enumUsedBeforeDeclaration.ts]
2+
const v: Color = Color.Green;
3+
const v2: ConstColor = ConstColor.Green;
4+
enum Color { Red, Green, Blue }
5+
const enum ConstColor { Red, Green, Blue }
6+
7+
8+
9+
//// [enumUsedBeforeDeclaration.js]
10+
var v = Color.Green;
11+
var v2 = 1 /* Green */;
12+
var Color;
13+
(function (Color) {
14+
Color[Color["Red"] = 0] = "Red";
15+
Color[Color["Green"] = 1] = "Green";
16+
Color[Color["Blue"] = 2] = "Blue";
17+
})(Color || (Color = {}));
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const v: Color = Color.Green;
2+
const v2: ConstColor = ConstColor.Green;
3+
enum Color { Red, Green, Blue }
4+
const enum ConstColor { Red, Green, Blue }
5+

0 commit comments

Comments
 (0)