Skip to content

Commit d558e42

Browse files
External modules are always in strict mode in ES6
1 parent dcbfa69 commit d558e42

11 files changed

+70
-36
lines changed

src/compiler/binder.ts

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -618,27 +618,39 @@ namespace ts {
618618

619619
// Report error only if there are no parse errors in file
620620
if (!file.parseDiagnostics.length) {
621-
let message = getAncestor(node, SyntaxKind.ClassDeclaration) || getAncestor(node, SyntaxKind.ClassExpression) ?
622-
Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode :
623-
Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode;
624-
file.bindDiagnostics.push(createDiagnosticForNode(node, message, declarationNameToString(node)));
621+
file.bindDiagnostics.push(createDiagnosticForNode(node,
622+
getStrictModeIdentifierMessage(node), declarationNameToString(node)));
625623
}
626624
}
627625
}
628626

627+
function getStrictModeIdentifierMessage(node: Node) {
628+
// Provide specialized messages to help the user understand why we think they're in
629+
// strict mode.
630+
if (getAncestor(node, SyntaxKind.ClassDeclaration) || getAncestor(node, SyntaxKind.ClassExpression)) {
631+
return Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode;
632+
}
633+
634+
if (file.externalModuleIndicator) {
635+
return Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode;
636+
}
637+
638+
return Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode;
639+
}
640+
629641
function checkStrictModeBinaryExpression(node: BinaryExpression) {
630642
if (inStrictMode && isLeftHandSideExpression(node.left) && isAssignmentOperator(node.operatorToken.kind)) {
631643
// ECMA 262 (Annex C) The identifier eval or arguments may not appear as the LeftHandSideExpression of an
632644
// Assignment operator(11.13) or of a PostfixExpression(11.3)
633-
checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>node.left);
645+
checkStrictModeEvalOrArguments(node, <Identifier>node.left);
634646
}
635647
}
636648

637649
function checkStrictModeCatchClause(node: CatchClause) {
638650
// It is a SyntaxError if a TryStatement with a Catch occurs within strict code and the Identifier of the
639651
// Catch production is eval or arguments
640652
if (inStrictMode && node.variableDeclaration) {
641-
checkGrammarEvalOrArgumentsInStrictMode(node, node.variableDeclaration.name);
653+
checkStrictModeEvalOrArguments(node, node.variableDeclaration.name);
642654
}
643655
}
644656

@@ -657,25 +669,37 @@ namespace ts {
657669
((<Identifier>node).text === "eval" || (<Identifier>node).text === "arguments");
658670
}
659671

660-
function checkGrammarEvalOrArgumentsInStrictMode(contextNode: Node, name: Node) {
672+
function checkStrictModeEvalOrArguments(contextNode: Node, name: Node) {
661673
if (name && name.kind === SyntaxKind.Identifier) {
662674
let identifier = <Identifier>name;
663675
if (isEvalOrArgumentsIdentifier(identifier)) {
664676
// We check first if the name is inside class declaration or class expression; if so give explicit message
665677
// otherwise report generic error message.
666678
let span = getErrorSpanForNode(file, name);
667-
let message = getAncestor(identifier, SyntaxKind.ClassDeclaration) || getAncestor(identifier, SyntaxKind.ClassExpression) ?
668-
Diagnostics.Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode :
669-
Diagnostics.Invalid_use_of_0_in_strict_mode;
670-
file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, message, identifier.text));
679+
file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length,
680+
getStrictModeEvalOrArgumentsMessage(contextNode), identifier.text));
671681
}
672682
}
673683
}
674684

685+
function getStrictModeEvalOrArgumentsMessage(node: Node) {
686+
// Provide specialized messages to help the user understand why we think they're in
687+
// strict mode.
688+
if (getAncestor(node, SyntaxKind.ClassDeclaration) || getAncestor(node, SyntaxKind.ClassExpression)) {
689+
return Diagnostics.Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode;
690+
}
691+
692+
if (file.externalModuleIndicator) {
693+
return Diagnostics.Invalid_use_of_0_Modules_are_automatically_in_strict_mode;
694+
}
695+
696+
return Diagnostics.Invalid_use_of_0_in_strict_mode;
697+
}
698+
675699
function checkStrictModeFunctionName(node: FunctionLikeDeclaration) {
676700
if (inStrictMode) {
677701
// It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a strict mode FunctionDeclaration or FunctionExpression (13.1))
678-
checkGrammarEvalOrArgumentsInStrictMode(node, node.name);
702+
checkStrictModeEvalOrArguments(node, node.name);
679703
}
680704
}
681705

@@ -691,15 +715,15 @@ namespace ts {
691715
// Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression
692716
// operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator.
693717
if (inStrictMode) {
694-
checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>node.operand);
718+
checkStrictModeEvalOrArguments(node, <Identifier>node.operand);
695719
}
696720
}
697721

698722
function checkStrictModePrefixUnaryExpression(node: PrefixUnaryExpression) {
699723
// Grammar checking
700724
if (inStrictMode) {
701725
if (node.operator === SyntaxKind.PlusPlusToken || node.operator === SyntaxKind.MinusMinusToken) {
702-
checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>node.operand);
726+
checkStrictModeEvalOrArguments(node, <Identifier>node.operand);
703727
}
704728
}
705729
}
@@ -962,7 +986,7 @@ namespace ts {
962986

963987
function bindVariableDeclarationOrBindingElement(node: VariableDeclaration | BindingElement) {
964988
if (inStrictMode) {
965-
checkGrammarEvalOrArgumentsInStrictMode(node, node.name)
989+
checkStrictModeEvalOrArguments(node, node.name)
966990
}
967991

968992
if (!isBindingPattern(node.name)) {
@@ -991,7 +1015,7 @@ namespace ts {
9911015
if (inStrictMode) {
9921016
// It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a
9931017
// strict mode FunctionLikeDeclaration or FunctionExpression(13.1)
994-
checkGrammarEvalOrArgumentsInStrictMode(node, node.name);
1018+
checkStrictModeEvalOrArguments(node, node.name);
9951019
}
9961020

9971021
if (isBindingPattern(node.name)) {

src/compiler/diagnosticInformationMap.generated.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ namespace ts {
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" },
172172
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" },
173173
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_Modules_are_automatically_in_strict_mode: { code: 1214, category: DiagnosticCategory.Error, key: "Identifier expected. '{0}' is a reserved word in strict mode. Modules are automatically in strict mode." },
175+
Invalid_use_of_0_Modules_are_automatically_in_strict_mode: { code: 1215, category: DiagnosticCategory.Error, key: "Invalid use of '{0}'. Modules are automatically in strict mode." },
174176
Export_assignment_is_not_supported_when_module_flag_is_system: { code: 1218, category: DiagnosticCategory.Error, key: "Export assignment is not supported when '--module' flag is 'system'." },
175177
Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Specify_experimentalDecorators_to_remove_this_warning: { code: 1219, category: DiagnosticCategory.Error, key: "Experimental support for decorators is a feature that is subject to change in a future release. Specify '--experimentalDecorators' to remove this warning." },
176178
Generators_are_only_available_when_targeting_ECMAScript_6_or_higher: { code: 1220, category: DiagnosticCategory.Error, key: "Generators are only available when targeting ECMAScript 6 or higher." },

src/compiler/diagnosticMessages.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,14 @@
671671
"category": "Error",
672672
"code": 1213
673673
},
674+
"Identifier expected. '{0}' is a reserved word in strict mode. Modules are automatically in strict mode.": {
675+
"category": "Error",
676+
"code": 1214
677+
},
678+
"Invalid use of '{0}'. Modules are automatically in strict mode.": {
679+
"category": "Error",
680+
"code": 1215
681+
},
674682
"Export assignment is not supported when '--module' flag is 'system'.": {
675683
"category": "Error",
676684
"code": 1218

tests/baselines/reference/exportNonInitializedVariablesAMD.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
tests/cases/conformance/externalModules/exportNonInitializedVariablesAMD.ts(2,4): error TS1123: Variable declaration list cannot be empty.
2-
tests/cases/conformance/externalModules/exportNonInitializedVariablesAMD.ts(3,1): error TS1212: Identifier expected. 'let' is a reserved word in strict mode
2+
tests/cases/conformance/externalModules/exportNonInitializedVariablesAMD.ts(3,1): error TS1214: Identifier expected. 'let' is a reserved word in strict mode. Modules are automatically in strict mode.
33
tests/cases/conformance/externalModules/exportNonInitializedVariablesAMD.ts(3,1): error TS2304: Cannot find name 'let'.
44
tests/cases/conformance/externalModules/exportNonInitializedVariablesAMD.ts(4,6): error TS1123: Variable declaration list cannot be empty.
55

@@ -11,7 +11,7 @@ tests/cases/conformance/externalModules/exportNonInitializedVariablesAMD.ts(4,6)
1111
!!! error TS1123: Variable declaration list cannot be empty.
1212
let;
1313
~~~
14-
!!! error TS1212: Identifier expected. 'let' is a reserved word in strict mode
14+
!!! error TS1214: Identifier expected. 'let' is a reserved word in strict mode. Modules are automatically in strict mode.
1515
~~~
1616
!!! error TS2304: Cannot find name 'let'.
1717
const;

tests/baselines/reference/exportNonInitializedVariablesCommonJS.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
tests/cases/conformance/externalModules/exportNonInitializedVariablesCommonJS.ts(2,4): error TS1123: Variable declaration list cannot be empty.
2-
tests/cases/conformance/externalModules/exportNonInitializedVariablesCommonJS.ts(3,1): error TS1212: Identifier expected. 'let' is a reserved word in strict mode
2+
tests/cases/conformance/externalModules/exportNonInitializedVariablesCommonJS.ts(3,1): error TS1214: Identifier expected. 'let' is a reserved word in strict mode. Modules are automatically in strict mode.
33
tests/cases/conformance/externalModules/exportNonInitializedVariablesCommonJS.ts(3,1): error TS2304: Cannot find name 'let'.
44
tests/cases/conformance/externalModules/exportNonInitializedVariablesCommonJS.ts(4,6): error TS1123: Variable declaration list cannot be empty.
55

@@ -11,7 +11,7 @@ tests/cases/conformance/externalModules/exportNonInitializedVariablesCommonJS.ts
1111
!!! error TS1123: Variable declaration list cannot be empty.
1212
let;
1313
~~~
14-
!!! error TS1212: Identifier expected. 'let' is a reserved word in strict mode
14+
!!! error TS1214: Identifier expected. 'let' is a reserved word in strict mode. Modules are automatically in strict mode.
1515
~~~
1616
!!! error TS2304: Cannot find name 'let'.
1717
const;

tests/baselines/reference/exportNonInitializedVariablesES6.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
tests/cases/conformance/externalModules/exportNonInitializedVariablesES6.ts(2,4): error TS1123: Variable declaration list cannot be empty.
2-
tests/cases/conformance/externalModules/exportNonInitializedVariablesES6.ts(3,1): error TS1212: Identifier expected. 'let' is a reserved word in strict mode
2+
tests/cases/conformance/externalModules/exportNonInitializedVariablesES6.ts(3,1): error TS1214: Identifier expected. 'let' is a reserved word in strict mode. Modules are automatically in strict mode.
33
tests/cases/conformance/externalModules/exportNonInitializedVariablesES6.ts(3,1): error TS2304: Cannot find name 'let'.
44
tests/cases/conformance/externalModules/exportNonInitializedVariablesES6.ts(4,6): error TS1123: Variable declaration list cannot be empty.
55

@@ -11,7 +11,7 @@ tests/cases/conformance/externalModules/exportNonInitializedVariablesES6.ts(4,6)
1111
!!! error TS1123: Variable declaration list cannot be empty.
1212
let;
1313
~~~
14-
!!! error TS1212: Identifier expected. 'let' is a reserved word in strict mode
14+
!!! error TS1214: Identifier expected. 'let' is a reserved word in strict mode. Modules are automatically in strict mode.
1515
~~~
1616
!!! error TS2304: Cannot find name 'let'.
1717
const;

tests/baselines/reference/exportNonInitializedVariablesSystem.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
tests/cases/conformance/externalModules/exportNonInitializedVariablesSystem.ts(2,4): error TS1123: Variable declaration list cannot be empty.
2-
tests/cases/conformance/externalModules/exportNonInitializedVariablesSystem.ts(3,1): error TS1212: Identifier expected. 'let' is a reserved word in strict mode
2+
tests/cases/conformance/externalModules/exportNonInitializedVariablesSystem.ts(3,1): error TS1214: Identifier expected. 'let' is a reserved word in strict mode. Modules are automatically in strict mode.
33
tests/cases/conformance/externalModules/exportNonInitializedVariablesSystem.ts(3,1): error TS2304: Cannot find name 'let'.
44
tests/cases/conformance/externalModules/exportNonInitializedVariablesSystem.ts(4,6): error TS1123: Variable declaration list cannot be empty.
55

@@ -11,7 +11,7 @@ tests/cases/conformance/externalModules/exportNonInitializedVariablesSystem.ts(4
1111
!!! error TS1123: Variable declaration list cannot be empty.
1212
let;
1313
~~~
14-
!!! error TS1212: Identifier expected. 'let' is a reserved word in strict mode
14+
!!! error TS1214: Identifier expected. 'let' is a reserved word in strict mode. Modules are automatically in strict mode.
1515
~~~
1616
!!! error TS2304: Cannot find name 'let'.
1717
const;

tests/baselines/reference/exportNonInitializedVariablesUMD.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
tests/cases/conformance/externalModules/exportNonInitializedVariablesUMD.ts(2,4): error TS1123: Variable declaration list cannot be empty.
2-
tests/cases/conformance/externalModules/exportNonInitializedVariablesUMD.ts(3,1): error TS1212: Identifier expected. 'let' is a reserved word in strict mode
2+
tests/cases/conformance/externalModules/exportNonInitializedVariablesUMD.ts(3,1): error TS1214: Identifier expected. 'let' is a reserved word in strict mode. Modules are automatically in strict mode.
33
tests/cases/conformance/externalModules/exportNonInitializedVariablesUMD.ts(3,1): error TS2304: Cannot find name 'let'.
44
tests/cases/conformance/externalModules/exportNonInitializedVariablesUMD.ts(4,6): error TS1123: Variable declaration list cannot be empty.
55

@@ -11,7 +11,7 @@ tests/cases/conformance/externalModules/exportNonInitializedVariablesUMD.ts(4,6)
1111
!!! error TS1123: Variable declaration list cannot be empty.
1212
let;
1313
~~~
14-
!!! error TS1212: Identifier expected. 'let' is a reserved word in strict mode
14+
!!! error TS1214: Identifier expected. 'let' is a reserved word in strict mode. Modules are automatically in strict mode.
1515
~~~
1616
!!! error TS2304: Cannot find name 'let'.
1717
const;

tests/baselines/reference/exportsAndImportsWithContextualKeywordNames01.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
tests/cases/conformance/es6/modules/t3.ts(1,17): error TS1212: Identifier expected. 'yield' is a reserved word in strict mode
1+
tests/cases/conformance/es6/modules/t3.ts(1,17): error TS1214: Identifier expected. 'yield' is a reserved word in strict mode. Modules are automatically in strict mode.
22

33

44
==== tests/cases/conformance/es6/modules/t1.ts (0 errors) ====
@@ -17,7 +17,7 @@ tests/cases/conformance/es6/modules/t3.ts(1,17): error TS1212: Identifier expect
1717
==== tests/cases/conformance/es6/modules/t3.ts (1 errors) ====
1818
import { set as yield } from "./t1";
1919
~~~~~
20-
!!! error TS1212: Identifier expected. 'yield' is a reserved word in strict mode
20+
!!! error TS1214: Identifier expected. 'yield' is a reserved word in strict mode. Modules are automatically in strict mode.
2121

2222
==== tests/cases/conformance/es6/modules/t4.ts (0 errors) ====
2323
import { get } from "./t1";
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
tests/cases/compiler/strictModeReservedWordInImportEqualDeclaration.ts(3,8): error TS1212: Identifier expected. 'public' is a reserved word in strict mode
1+
tests/cases/compiler/strictModeReservedWordInImportEqualDeclaration.ts(3,8): error TS1214: Identifier expected. 'public' is a reserved word in strict mode. Modules are automatically in strict mode.
22
tests/cases/compiler/strictModeReservedWordInImportEqualDeclaration.ts(3,25): error TS2307: Cannot find module '1'.
33

44

@@ -7,6 +7,6 @@ tests/cases/compiler/strictModeReservedWordInImportEqualDeclaration.ts(3,25): er
77
"use strict"
88
import public = require("1");
99
~~~~~~
10-
!!! error TS1212: Identifier expected. 'public' is a reserved word in strict mode
10+
!!! error TS1214: Identifier expected. 'public' is a reserved word in strict mode. Modules are automatically in strict mode.
1111
~~~
1212
!!! error TS2307: Cannot find module '1'.

0 commit comments

Comments
 (0)