Merge pull request #25822 from Kingwl/rechabilityImprove
improve enum rechability check
This commit is contained in:
commit
4975dc85b1
|
@ -2802,9 +2802,7 @@ namespace ts {
|
|||
// report error on class declarations
|
||||
node.kind === SyntaxKind.ClassDeclaration ||
|
||||
// report error on instantiated modules or const-enums only modules if preserveConstEnums is set
|
||||
(node.kind === SyntaxKind.ModuleDeclaration && shouldReportErrorOnModuleDeclaration(<ModuleDeclaration>node)) ||
|
||||
// report error on regular enums and const enums if preserveConstEnums is set
|
||||
(isEnumDeclaration(node) && (!isEnumConst(node) || options.preserveConstEnums));
|
||||
(node.kind === SyntaxKind.ModuleDeclaration && shouldReportErrorOnModuleDeclaration(<ModuleDeclaration>node));
|
||||
|
||||
if (reportError) {
|
||||
currentFlow = reportedUnreachableFlow;
|
||||
|
@ -2849,7 +2847,7 @@ namespace ts {
|
|||
// As opposed to a pure declaration like an `interface`
|
||||
function isExecutableStatement(s: Statement): boolean {
|
||||
// Don't remove statements that can validly be used before they appear.
|
||||
return !isFunctionDeclaration(s) && !isPurelyTypeDeclaration(s) &&
|
||||
return !isFunctionDeclaration(s) && !isPurelyTypeDeclaration(s) && !isEnumDeclaration(s) &&
|
||||
// `var x;` may declare a variable used above
|
||||
!(isVariableStatement(s) && !(getCombinedNodeFlags(s) & (NodeFlags.Let | NodeFlags.Const)) && s.declarationList.declarations.some(d => !d.initializer));
|
||||
}
|
||||
|
|
|
@ -1703,6 +1703,9 @@ namespace ts {
|
|||
}
|
||||
else {
|
||||
Debug.assert(!!(result.flags & SymbolFlags.ConstEnum));
|
||||
if (compilerOptions.preserveConstEnums) {
|
||||
diagnosticMessage = error(errorLocation, Diagnostics.Class_0_used_before_its_declaration, declarationName);
|
||||
}
|
||||
}
|
||||
|
||||
if (diagnosticMessage) {
|
||||
|
@ -22981,6 +22984,12 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
const enum DeclarationSpaces {
|
||||
None = 0,
|
||||
ExportValue = 1 << 0,
|
||||
ExportType = 1 << 1,
|
||||
ExportNamespace = 1 << 2,
|
||||
}
|
||||
function checkExportsOnMergedDeclarations(node: Node): void {
|
||||
if (!produceDiagnostics) {
|
||||
return;
|
||||
|
@ -23045,12 +23054,6 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
const enum DeclarationSpaces {
|
||||
None = 0,
|
||||
ExportValue = 1 << 0,
|
||||
ExportType = 1 << 1,
|
||||
ExportNamespace = 1 << 2,
|
||||
}
|
||||
function getDeclarationSpaces(decl: Declaration): DeclarationSpaces {
|
||||
let d = decl as Node;
|
||||
switch (d.kind) {
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef.ts(2,12): error TS2450: Enum 'E' used before its declaration.
|
||||
|
||||
|
||||
==== tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef.ts (1 errors) ====
|
||||
function foo1() {
|
||||
return E.A
|
||||
~
|
||||
!!! error TS2450: Enum 'E' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef.ts:3:10: 'E' is declared here.
|
||||
enum E { A }
|
||||
}
|
||||
|
||||
function foo2() {
|
||||
return E.A
|
||||
const enum E { A }
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
//// [blockScopedEnumVariablesUseBeforeDef.ts]
|
||||
function foo1() {
|
||||
return E.A
|
||||
enum E { A }
|
||||
}
|
||||
|
||||
function foo2() {
|
||||
return E.A
|
||||
const enum E { A }
|
||||
}
|
||||
|
||||
//// [blockScopedEnumVariablesUseBeforeDef.js]
|
||||
function foo1() {
|
||||
return E.A;
|
||||
var E;
|
||||
(function (E) {
|
||||
E[E["A"] = 0] = "A";
|
||||
})(E || (E = {}));
|
||||
}
|
||||
function foo2() {
|
||||
return 0 /* A */;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
=== tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef.ts ===
|
||||
function foo1() {
|
||||
>foo1 : Symbol(foo1, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 0, 0))
|
||||
|
||||
return E.A
|
||||
>E.A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 2, 12))
|
||||
>E : Symbol(E, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 1, 14))
|
||||
>A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 2, 12))
|
||||
|
||||
enum E { A }
|
||||
>E : Symbol(E, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 1, 14))
|
||||
>A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 2, 12))
|
||||
}
|
||||
|
||||
function foo2() {
|
||||
>foo2 : Symbol(foo2, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 3, 1))
|
||||
|
||||
return E.A
|
||||
>E.A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 7, 18))
|
||||
>E : Symbol(E, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 6, 14))
|
||||
>A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 7, 18))
|
||||
|
||||
const enum E { A }
|
||||
>E : Symbol(E, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 6, 14))
|
||||
>A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 7, 18))
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
=== tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef.ts ===
|
||||
function foo1() {
|
||||
>foo1 : () => E
|
||||
|
||||
return E.A
|
||||
>E.A : E
|
||||
>E : typeof E
|
||||
>A : E
|
||||
|
||||
enum E { A }
|
||||
>E : E
|
||||
>A : E
|
||||
}
|
||||
|
||||
function foo2() {
|
||||
>foo2 : () => E
|
||||
|
||||
return E.A
|
||||
>E.A : E
|
||||
>E : typeof E
|
||||
>A : E
|
||||
|
||||
const enum E { A }
|
||||
>E : E
|
||||
>A : E
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef_preserve.ts(2,12): error TS2450: Enum 'E' used before its declaration.
|
||||
tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef_preserve.ts(7,12): error TS2449: Class 'E' used before its declaration.
|
||||
|
||||
|
||||
==== tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef_preserve.ts (2 errors) ====
|
||||
function foo1() {
|
||||
return E.A
|
||||
~
|
||||
!!! error TS2450: Enum 'E' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef_preserve.ts:3:10: 'E' is declared here.
|
||||
enum E { A }
|
||||
}
|
||||
|
||||
function foo2() {
|
||||
return E.A
|
||||
~
|
||||
!!! error TS2449: Class 'E' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef_preserve.ts:8:16: 'E' is declared here.
|
||||
const enum E { A }
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
//// [blockScopedEnumVariablesUseBeforeDef_preserve.ts]
|
||||
function foo1() {
|
||||
return E.A
|
||||
enum E { A }
|
||||
}
|
||||
|
||||
function foo2() {
|
||||
return E.A
|
||||
const enum E { A }
|
||||
}
|
||||
|
||||
//// [blockScopedEnumVariablesUseBeforeDef_preserve.js]
|
||||
function foo1() {
|
||||
return E.A;
|
||||
var E;
|
||||
(function (E) {
|
||||
E[E["A"] = 0] = "A";
|
||||
})(E || (E = {}));
|
||||
}
|
||||
function foo2() {
|
||||
return 0 /* A */;
|
||||
var E;
|
||||
(function (E) {
|
||||
E[E["A"] = 0] = "A";
|
||||
})(E || (E = {}));
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
=== tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef_preserve.ts ===
|
||||
function foo1() {
|
||||
>foo1 : Symbol(foo1, Decl(blockScopedEnumVariablesUseBeforeDef_preserve.ts, 0, 0))
|
||||
|
||||
return E.A
|
||||
>E.A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef_preserve.ts, 2, 12))
|
||||
>E : Symbol(E, Decl(blockScopedEnumVariablesUseBeforeDef_preserve.ts, 1, 14))
|
||||
>A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef_preserve.ts, 2, 12))
|
||||
|
||||
enum E { A }
|
||||
>E : Symbol(E, Decl(blockScopedEnumVariablesUseBeforeDef_preserve.ts, 1, 14))
|
||||
>A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef_preserve.ts, 2, 12))
|
||||
}
|
||||
|
||||
function foo2() {
|
||||
>foo2 : Symbol(foo2, Decl(blockScopedEnumVariablesUseBeforeDef_preserve.ts, 3, 1))
|
||||
|
||||
return E.A
|
||||
>E.A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef_preserve.ts, 7, 18))
|
||||
>E : Symbol(E, Decl(blockScopedEnumVariablesUseBeforeDef_preserve.ts, 6, 14))
|
||||
>A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef_preserve.ts, 7, 18))
|
||||
|
||||
const enum E { A }
|
||||
>E : Symbol(E, Decl(blockScopedEnumVariablesUseBeforeDef_preserve.ts, 6, 14))
|
||||
>A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef_preserve.ts, 7, 18))
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
=== tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef_preserve.ts ===
|
||||
function foo1() {
|
||||
>foo1 : () => E
|
||||
|
||||
return E.A
|
||||
>E.A : E
|
||||
>E : typeof E
|
||||
>A : E
|
||||
|
||||
enum E { A }
|
||||
>E : E
|
||||
>A : E
|
||||
}
|
||||
|
||||
function foo2() {
|
||||
>foo2 : () => E
|
||||
|
||||
return E.A
|
||||
>E.A : E
|
||||
>E : typeof E
|
||||
>A : E
|
||||
|
||||
const enum E { A }
|
||||
>E : E
|
||||
>A : E
|
||||
}
|
|
@ -119,4 +119,5 @@ tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts(100,12): error TS2448:
|
|||
!!! related TS2728 tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts:102:9: 'x' is declared here.
|
||||
}
|
||||
let x
|
||||
}
|
||||
}
|
||||
|
|
@ -101,7 +101,8 @@ function foo14() {
|
|||
a: x
|
||||
}
|
||||
let x
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [blockScopedVariablesUseBeforeDef.js]
|
||||
function foo0() {
|
||||
|
|
|
@ -212,3 +212,4 @@ function foo14() {
|
|||
let x
|
||||
>x : Symbol(x, Decl(blockScopedVariablesUseBeforeDef.ts, 101, 7))
|
||||
}
|
||||
|
||||
|
|
|
@ -224,3 +224,4 @@ function foo14() {
|
|||
let x
|
||||
>x : any
|
||||
}
|
||||
|
||||
|
|
|
@ -3,11 +3,9 @@ tests/cases/compiler/reachabilityChecks1.ts(6,5): error TS7027: Unreachable code
|
|||
tests/cases/compiler/reachabilityChecks1.ts(18,5): error TS7027: Unreachable code detected.
|
||||
tests/cases/compiler/reachabilityChecks1.ts(30,5): error TS7027: Unreachable code detected.
|
||||
tests/cases/compiler/reachabilityChecks1.ts(47,5): error TS7027: Unreachable code detected.
|
||||
tests/cases/compiler/reachabilityChecks1.ts(60,5): error TS7027: Unreachable code detected.
|
||||
tests/cases/compiler/reachabilityChecks1.ts(69,5): error TS7027: Unreachable code detected.
|
||||
|
||||
|
||||
==== tests/cases/compiler/reachabilityChecks1.ts (7 errors) ====
|
||||
==== tests/cases/compiler/reachabilityChecks1.ts (5 errors) ====
|
||||
while (true);
|
||||
var x = 1;
|
||||
~~~~~~~~~~
|
||||
|
@ -83,12 +81,8 @@ tests/cases/compiler/reachabilityChecks1.ts(69,5): error TS7027: Unreachable cod
|
|||
do {
|
||||
} while (true);
|
||||
enum E {
|
||||
~~~~~~~~
|
||||
X = 1
|
||||
~~~~~~~~~~~~~
|
||||
}
|
||||
~~~~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
|
||||
function f4() {
|
||||
|
@ -96,12 +90,8 @@ tests/cases/compiler/reachabilityChecks1.ts(69,5): error TS7027: Unreachable cod
|
|||
throw new Error();
|
||||
}
|
||||
const enum E {
|
||||
~~~~~~~~~~~~~~
|
||||
X = 1
|
||||
~~~~~~~~~~~~~
|
||||
}
|
||||
~~~~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
|
||||
|
10
tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef.ts
Normal file
10
tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
// @target: ES5
|
||||
function foo1() {
|
||||
return E.A
|
||||
enum E { A }
|
||||
}
|
||||
|
||||
function foo2() {
|
||||
return E.A
|
||||
const enum E { A }
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// @target: ES5
|
||||
// @preserveConstEnums: true
|
||||
|
||||
function foo1() {
|
||||
return E.A
|
||||
enum E { A }
|
||||
}
|
||||
|
||||
function foo2() {
|
||||
return E.A
|
||||
const enum E { A }
|
||||
}
|
|
@ -101,4 +101,4 @@ function foo14() {
|
|||
a: x
|
||||
}
|
||||
let x
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
////function f() {
|
||||
//// return f();
|
||||
//// [|return 1;|]
|
||||
//// function f() {}
|
||||
//// function f(a?: EE) { return a; }
|
||||
//// [|return 2;|]
|
||||
//// type T = number;
|
||||
//// interface I {}
|
||||
//// const enum E {}
|
||||
//// [|enum E {}|]
|
||||
//// enum EE {}
|
||||
//// namespace N { export type T = number; }
|
||||
//// [|namespace N { export const x: T = 0; }|]
|
||||
//// var x: I;
|
||||
|
@ -29,11 +29,23 @@ verify.codeFixAll({
|
|||
newFileContent:
|
||||
`function f() {
|
||||
return f();
|
||||
function f() {}
|
||||
function f(a?: EE) { return a; }
|
||||
type T = number;
|
||||
interface I {}
|
||||
const enum E {}
|
||||
enum EE {}
|
||||
namespace N { export type T = number; }
|
||||
var x: I;
|
||||
}`,
|
||||
});
|
||||
|
||||
function f() {
|
||||
return f();
|
||||
function f(a?: EE) { return a; }
|
||||
type T = number;
|
||||
interface I {}
|
||||
const enum E {}
|
||||
enum EE {}
|
||||
namespace N { export type T = number; }
|
||||
var x: I;
|
||||
}
|
Loading…
Reference in a new issue