Skip to content

Commit 96995e7

Browse files
committed
Merge pull request #2684 from Microsoft/migrateStrictModeCheck
Migrate strict mode check
2 parents 1c7d8a2 + 63a2359 commit 96995e7

File tree

88 files changed

+1420
-665
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+1420
-665
lines changed

src/compiler/checker.ts

+169-14
Large diffs are not rendered by default.

src/compiler/diagnosticInformationMap.generated.ts

+6
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,12 @@ module ts {
169169
Ambient_const_enums_are_not_allowed_when_the_separateCompilation_flag_is_provided: { code: 1209, category: DiagnosticCategory.Error, key: "Ambient const enums are not allowed when the '--separateCompilation' flag is provided." },
170170
Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode: { code: 1210, category: DiagnosticCategory.Error, key: "Invalid use of '{0}'. Class definitions are automatically in strict mode." },
171171
A_class_declaration_without_the_default_modifier_must_have_a_name: { code: 1211, category: DiagnosticCategory.Error, key: "A class declaration without the 'default' modifier must have a name" },
172+
Identifier_expected_0_is_a_reserved_word_in_strict_mode: { code: 1212, category: DiagnosticCategory.Error, key: "Identifier expected. '{0}' is a reserved word in strict mode" },
173+
Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode: { code: 1213, category: DiagnosticCategory.Error, key: "Identifier expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode." },
174+
Identifier_expected_0_is_a_reserved_word_in_strict_mode_External_Module_is_automatically_in_strict_mode: { code: 1214, category: DiagnosticCategory.Error, key: "Identifier expected. '{0}' is a reserved word in strict mode. External Module is automatically in strict mode." },
175+
Type_expected_0_is_a_reserved_word_in_strict_mode: { code: 1215, category: DiagnosticCategory.Error, key: "Type expected. '{0}' is a reserved word in strict mode" },
176+
Type_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode: { code: 1216, category: DiagnosticCategory.Error, key: "Type expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode." },
177+
Type_expected_0_is_a_reserved_word_in_strict_mode_Module_is_automatically_in_strict_mode: { code: 1217, category: DiagnosticCategory.Error, key: "Type expected. '{0}' is a reserved word in strict mode. Module is automatically in strict mode." },
172178
Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." },
173179
Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." },
174180
Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." },

src/compiler/diagnosticMessages.json

+25-1
Original file line numberDiff line numberDiff line change
@@ -657,12 +657,36 @@
657657
},
658658
"Invalid use of '{0}'. Class definitions are automatically in strict mode.": {
659659
"category": "Error",
660-
"code": 1210
660+
"code": 1210
661661
},
662662
"A class declaration without the 'default' modifier must have a name": {
663663
"category": "Error",
664664
"code": 1211
665665
},
666+
"Identifier expected. '{0}' is a reserved word in strict mode": {
667+
"category": "Error",
668+
"code": 1212
669+
},
670+
"Identifier expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode.": {
671+
"category": "Error",
672+
"code": 1213
673+
},
674+
"Identifier expected. '{0}' is a reserved word in strict mode. External Module is automatically in strict mode.": {
675+
"category": "Error",
676+
"code": 1214
677+
},
678+
"Type expected. '{0}' is a reserved word in strict mode": {
679+
"category": "Error",
680+
"code": 1215
681+
},
682+
"Type expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode.": {
683+
"category": "Error",
684+
"code": 1216
685+
},
686+
"Type expected. '{0}' is a reserved word in strict mode. Module is automatically in strict mode.": {
687+
"category": "Error",
688+
"code": 1217
689+
},
666690
"Duplicate identifier '{0}'.": {
667691
"category": "Error",
668692
"code": 2300

src/compiler/parser.ts

+29-1
Original file line numberDiff line numberDiff line change
@@ -1349,6 +1349,7 @@ module ts {
13491349
return speculationHelper(callback, /*isLookAhead:*/ false);
13501350
}
13511351

1352+
// Ignore strict mode flag because we will report an error in type checker instead.
13521353
function isIdentifier(): boolean {
13531354
if (token === SyntaxKind.Identifier) {
13541355
return true;
@@ -1360,7 +1361,7 @@ module ts {
13601361
return false;
13611362
}
13621363

1363-
return inStrictModeContext() ? token > SyntaxKind.LastFutureReservedWord : token > SyntaxKind.LastReservedWord;
1364+
return token > SyntaxKind.LastReservedWord;
13641365
}
13651366

13661367
function parseExpected(kind: SyntaxKind, diagnosticMessage?: DiagnosticMessage): boolean {
@@ -1484,6 +1485,11 @@ module ts {
14841485
identifierCount++;
14851486
if (isIdentifier) {
14861487
let node = <Identifier>createNode(SyntaxKind.Identifier);
1488+
1489+
// Store original token kind if it is not just an Identifier so we can report appropriate error later in type checker
1490+
if (token !== SyntaxKind.Identifier) {
1491+
node.originalKeywordKind = token;
1492+
}
14871493
node.text = internIdentifier(scanner.getTokenValue());
14881494
nextToken();
14891495
return finishNode(node);
@@ -4599,6 +4605,18 @@ module ts {
45994605
return finishNode(node);
46004606
}
46014607

4608+
function isClassMemberModifier(idToken: SyntaxKind) {
4609+
switch (idToken) {
4610+
case SyntaxKind.PublicKeyword:
4611+
case SyntaxKind.PrivateKeyword:
4612+
case SyntaxKind.ProtectedKeyword:
4613+
case SyntaxKind.StaticKeyword:
4614+
return true;
4615+
default:
4616+
return false;
4617+
}
4618+
}
4619+
46024620
function isClassMemberStart(): boolean {
46034621
let idToken: SyntaxKind;
46044622

@@ -4609,6 +4627,16 @@ module ts {
46094627
// Eat up all modifiers, but hold on to the last one in case it is actually an identifier.
46104628
while (isModifier(token)) {
46114629
idToken = token;
4630+
// If the idToken is a class modifier (protected, private, public, and static), it is
4631+
// certain that we are starting to parse class member. This allows better error recovery
4632+
// Example:
4633+
// public foo() ... // true
4634+
// public @dec blah ... // true; we will then report an error later
4635+
// export public ... // true; we will then report an error later
4636+
if (isClassMemberModifier(idToken)) {
4637+
return true;
4638+
}
4639+
46124640
nextToken();
46134641
}
46144642

src/compiler/types.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,8 @@ module ts {
388388
}
389389

390390
export interface Identifier extends PrimaryExpression {
391-
text: string; // Text of identifier (with escapes converted to characters)
391+
text: string; // Text of identifier (with escapes converted to characters)
392+
originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later
392393
}
393394

394395
export interface QualifiedName extends Node {

tests/baselines/reference/classUpdateTests.errors.txt

+14-8
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@ tests/cases/compiler/classUpdateTests.ts(95,1): error TS1128: Declaration or sta
1313
tests/cases/compiler/classUpdateTests.ts(99,3): error TS1129: Statement expected.
1414
tests/cases/compiler/classUpdateTests.ts(101,1): error TS1128: Declaration or statement expected.
1515
tests/cases/compiler/classUpdateTests.ts(105,3): error TS1129: Statement expected.
16-
tests/cases/compiler/classUpdateTests.ts(105,15): error TS2339: Property 'p1' does not exist on type 'Q'.
16+
tests/cases/compiler/classUpdateTests.ts(105,14): error TS1005: ';' expected.
17+
tests/cases/compiler/classUpdateTests.ts(107,1): error TS1128: Declaration or statement expected.
1718
tests/cases/compiler/classUpdateTests.ts(111,3): error TS1129: Statement expected.
18-
tests/cases/compiler/classUpdateTests.ts(111,16): error TS2339: Property 'p1' does not exist on type 'R'.
19+
tests/cases/compiler/classUpdateTests.ts(111,15): error TS1005: ';' expected.
20+
tests/cases/compiler/classUpdateTests.ts(113,1): error TS1128: Declaration or statement expected.
1921

2022

21-
==== tests/cases/compiler/classUpdateTests.ts (16 errors) ====
23+
==== tests/cases/compiler/classUpdateTests.ts (18 errors) ====
2224
//
2325
// test codegen for instance properties
2426
//
@@ -158,17 +160,21 @@ tests/cases/compiler/classUpdateTests.ts(111,16): error TS2339: Property 'p1' do
158160
public this.p1 = 0; // ERROR
159161
~~~~~~
160162
!!! error TS1129: Statement expected.
161-
~~
162-
!!! error TS2339: Property 'p1' does not exist on type 'Q'.
163+
~
164+
!!! error TS1005: ';' expected.
163165
}
164166
}
167+
~
168+
!!! error TS1128: Declaration or statement expected.
165169

166170
class R {
167171
constructor() {
168172
private this.p1 = 0; // ERROR
169173
~~~~~~~
170174
!!! error TS1129: Statement expected.
171-
~~
172-
!!! error TS2339: Property 'p1' does not exist on type 'R'.
175+
~
176+
!!! error TS1005: ';' expected.
173177
}
174-
}
178+
}
179+
~
180+
!!! error TS1128: Declaration or statement expected.
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
tests/cases/compiler/constructorStaticParamName.ts(4,18): error TS1003: Identifier expected.
1+
tests/cases/compiler/constructorStaticParamName.ts(4,18): error TS1213: Identifier expected. 'static' is a reserved word in strict mode. Class definitions are automatically in strict mode.
22

33

44
==== tests/cases/compiler/constructorStaticParamName.ts (1 errors) ====
@@ -7,6 +7,6 @@ tests/cases/compiler/constructorStaticParamName.ts(4,18): error TS1003: Identifi
77
class test {
88
constructor (static) { }
99
~~~~~~
10-
!!! error TS1003: Identifier expected.
10+
!!! error TS1213: Identifier expected. 'static' is a reserved word in strict mode. Class definitions are automatically in strict mode.
1111
}
1212

tests/baselines/reference/constructorStaticParamName.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class test {
99
//// [constructorStaticParamName.js]
1010
// static as constructor parameter name should only give error if 'use strict'
1111
var test = (function () {
12-
function test() {
12+
function test(static) {
1313
}
1414
return test;
1515
})();
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
tests/cases/compiler/constructorStaticParamNameErrors.ts(4,18): error TS1003: Identifier expected.
1+
tests/cases/compiler/constructorStaticParamNameErrors.ts(4,18): error TS1213: Identifier expected. 'static' is a reserved word in strict mode. Class definitions are automatically in strict mode.
22

33

44
==== tests/cases/compiler/constructorStaticParamNameErrors.ts (1 errors) ====
@@ -7,5 +7,5 @@ tests/cases/compiler/constructorStaticParamNameErrors.ts(4,18): error TS1003: Id
77
class test {
88
constructor (static) { }
99
~~~~~~
10-
!!! error TS1003: Identifier expected.
10+
!!! error TS1213: Identifier expected. 'static' is a reserved word in strict mode. Class definitions are automatically in strict mode.
1111
}

tests/baselines/reference/constructorStaticParamNameErrors.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class test {
99
'use strict';
1010
// static as constructor parameter name should give error if 'use strict'
1111
var test = (function () {
12-
function test() {
12+
function test(static) {
1313
}
1414
return test;
1515
})();

0 commit comments

Comments
 (0)