Skip to content

Commit 718dc5b

Browse files
Merge pull request #3517 from Microsoft/strictMode
Remove 'strict mode' from parsing and checking, and make it purely something purely checked at bind time.
2 parents 2a1b898 + 300089c commit 718dc5b

30 files changed

+411
-332
lines changed

src/compiler/binder.ts

Lines changed: 247 additions & 6 deletions
Large diffs are not rendered by default.

src/compiler/checker.ts

Lines changed: 9 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -7734,7 +7734,7 @@ namespace ts {
77347734
// Grammar checking
77357735
let hasGrammarError = checkGrammarFunctionLikeDeclaration(node);
77367736
if (!hasGrammarError && node.kind === SyntaxKind.FunctionExpression) {
7737-
checkGrammarFunctionName(node.name) || checkGrammarForGenerator(node);
7737+
checkGrammarForGenerator(node);
77387738
}
77397739

77407740
// The identityMapper object is used to indicate that function expressions are wildcards
@@ -7891,14 +7891,7 @@ namespace ts {
78917891
}
78927892

78937893
function checkDeleteExpression(node: DeleteExpression): Type {
7894-
// Grammar checking
7895-
if (node.parserContextFlags & ParserContextFlags.StrictMode && node.expression.kind === SyntaxKind.Identifier) {
7896-
// When a delete operator occurs within strict mode code, a SyntaxError is thrown if its
7897-
// UnaryExpression is a direct reference to a variable, function argument, or function name
7898-
grammarErrorOnNode(node.expression, Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode);
7899-
}
7900-
7901-
let operandType = checkExpression(node.expression);
7894+
checkExpression(node.expression);
79027895
return booleanType;
79037896
}
79047897

@@ -7913,14 +7906,6 @@ namespace ts {
79137906
}
79147907

79157908
function checkPrefixUnaryExpression(node: PrefixUnaryExpression): Type {
7916-
// Grammar checking
7917-
// The identifier eval or arguments may not appear as the LeftHandSideExpression of an
7918-
// Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression
7919-
// operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator
7920-
if ((node.operator === SyntaxKind.PlusPlusToken || node.operator === SyntaxKind.MinusMinusToken)) {
7921-
checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>node.operand);
7922-
}
7923-
79247909
let operandType = checkExpression(node.operand);
79257910
switch (node.operator) {
79267911
case SyntaxKind.PlusToken:
@@ -7947,12 +7932,6 @@ namespace ts {
79477932
}
79487933

79497934
function checkPostfixUnaryExpression(node: PostfixUnaryExpression): Type {
7950-
// Grammar checking
7951-
// The identifier eval or arguments may not appear as the LeftHandSideExpression of an
7952-
// Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression
7953-
// operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator.
7954-
checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>node.operand);
7955-
79567935
let operandType = checkExpression(node.operand);
79577936
let ok = checkArithmeticOperandType(node.operand, operandType, Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type);
79587937
if (ok) {
@@ -8132,13 +8111,6 @@ namespace ts {
81328111
}
81338112

81348113
function checkBinaryExpression(node: BinaryExpression, contextualMapper?: TypeMapper) {
8135-
// Grammar checking
8136-
if (isLeftHandSideExpression(node.left) && isAssignmentOperator(node.operatorToken.kind)) {
8137-
// ECMA 262 (Annex C) The identifier eval or arguments may not appear as the LeftHandSideExpression of an
8138-
// Assignment operator(11.13) or of a PostfixExpression(11.3)
8139-
checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>node.left);
8140-
}
8141-
81428114
let operator = node.operatorToken.kind;
81438115
if (operator === SyntaxKind.EqualsToken && (node.left.kind === SyntaxKind.ObjectLiteralExpression || node.left.kind === SyntaxKind.ArrayLiteralExpression)) {
81448116
return checkDestructuringAssignment(node.left, checkExpression(node.right, contextualMapper), contextualMapper);
@@ -8580,11 +8552,9 @@ namespace ts {
85808552
// It is a SyntaxError if the Identifier "eval" or the Identifier "arguments" occurs as the
85818553
// Identifier in a PropertySetParameterList of a PropertyAssignment that is contained in strict code
85828554
// or if its FunctionBody is strict code(11.1.5).
8583-
// It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a
8584-
// strict mode FunctionLikeDeclaration or FunctionExpression(13.1)
85858555

85868556
// Grammar checking
8587-
checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>node.name);
8557+
checkGrammarDecorators(node) || checkGrammarModifiers(node);
85888558

85898559
checkVariableLikeDeclaration(node);
85908560
let func = getContainingFunction(node);
@@ -9476,9 +9446,7 @@ namespace ts {
94769446

94779447
function checkFunctionDeclaration(node: FunctionDeclaration): void {
94789448
if (produceDiagnostics) {
9479-
checkFunctionLikeDeclaration(node) ||
9480-
checkGrammarFunctionName(node.name) ||
9481-
checkGrammarForGenerator(node);
9449+
checkFunctionLikeDeclaration(node) || checkGrammarForGenerator(node);
94829450

94839451
checkCollisionWithCapturedSuperVariable(node, node.name);
94849452
checkCollisionWithCapturedThisVariable(node, node.name);
@@ -10305,12 +10273,7 @@ namespace ts {
1030510273
}
1030610274

1030710275
function checkWithStatement(node: WithStatement) {
10308-
// Grammar checking for withStatement
10309-
if (!checkGrammarStatementInAmbientContext(node)) {
10310-
if (node.parserContextFlags & ParserContextFlags.StrictMode) {
10311-
grammarErrorOnFirstToken(node, Diagnostics.with_statements_are_not_allowed_in_strict_mode);
10312-
}
10313-
}
10276+
checkGrammarStatementInAmbientContext(node);
1031410277

1031510278
checkExpression(node.expression);
1031610279
error(node.expression, Diagnostics.All_symbols_within_a_with_block_will_be_resolved_to_any);
@@ -10414,10 +10377,6 @@ namespace ts {
1041410377
grammarErrorOnNode(localSymbol.valueDeclaration, Diagnostics.Cannot_redeclare_identifier_0_in_catch_clause, identifierName);
1041510378
}
1041610379
}
10417-
10418-
// It is a SyntaxError if a TryStatement with a Catch occurs within strict code and the Identifier of the
10419-
// Catch production is eval or arguments
10420-
checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>catchClause.variableDeclaration.name);
1042110380
}
1042210381
}
1042310382

@@ -13022,11 +12981,6 @@ namespace ts {
1302212981
}
1302312982
}
1302412983

13025-
function checkGrammarFunctionName(name: Node) {
13026-
// It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a strict mode FunctionDeclaration or FunctionExpression (13.1))
13027-
return checkGrammarEvalOrArgumentsInStrictMode(name, <Identifier>name);
13028-
}
13029-
1303012984
function checkGrammarForInvalidQuestionMark(node: Declaration, questionToken: Node, message: DiagnosticMessage): boolean {
1303112985
if (questionToken) {
1303212986
return grammarErrorOnNode(questionToken, message);
@@ -13039,7 +12993,6 @@ namespace ts {
1303912993
let GetAccessor = 2;
1304012994
let SetAccesor = 4;
1304112995
let GetOrSetAccessor = GetAccessor | SetAccesor;
13042-
let inStrictMode = (node.parserContextFlags & ParserContextFlags.StrictMode) !== 0;
1304312996

1304412997
for (let prop of node.properties) {
1304512998
let name = prop.name;
@@ -13086,9 +13039,7 @@ namespace ts {
1308613039
else {
1308713040
let existingKind = seen[(<Identifier>name).text];
1308813041
if (currentKind === Property && existingKind === Property) {
13089-
if (inStrictMode) {
13090-
grammarErrorOnNode(name, Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode);
13091-
}
13042+
continue;
1309213043
}
1309313044
else if ((currentKind & GetOrSetAccessor) && (existingKind & GetOrSetAccessor)) {
1309413045
if (existingKind !== GetOrSetAccessor && currentKind !== existingKind) {
@@ -13311,9 +13262,6 @@ namespace ts {
1331113262
return grammarErrorAtPos(getSourceFileOfNode(node), node.initializer.pos - 1, 1, Diagnostics.A_rest_element_cannot_have_an_initializer);
1331213263
}
1331313264
}
13314-
// It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code
13315-
// and its Identifier is eval or arguments
13316-
return checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>node.name);
1331713265
}
1331813266

1331913267
function checkGrammarVariableDeclaration(node: VariableDeclaration) {
@@ -13345,8 +13293,7 @@ namespace ts {
1334513293

1334613294
// It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code
1334713295
// and its Identifier is eval or arguments
13348-
return (checkLetConstNames && checkGrammarNameInLetOrConstDeclarations(node.name)) ||
13349-
checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>node.name);
13296+
return checkLetConstNames && checkGrammarNameInLetOrConstDeclarations(node.name);
1335013297
}
1335113298

1335213299
function checkGrammarNameInLetOrConstDeclarations(name: Identifier | BindingPattern): boolean {
@@ -13485,25 +13432,6 @@ namespace ts {
1348513432
}
1348613433
}
1348713434

13488-
function checkGrammarEvalOrArgumentsInStrictMode(contextNode: Node, name: Node): boolean {
13489-
if (name && name.kind === SyntaxKind.Identifier) {
13490-
let identifier = <Identifier>name;
13491-
if (contextNode && (contextNode.parserContextFlags & ParserContextFlags.StrictMode) && isEvalOrArgumentsIdentifier(identifier)) {
13492-
// We check first if the name is inside class declaration or class expression; if so give explicit message
13493-
// otherwise report generic error message.
13494-
let message = getAncestor(identifier, SyntaxKind.ClassDeclaration) || getAncestor(identifier, SyntaxKind.ClassExpression) ?
13495-
Diagnostics.Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode :
13496-
Diagnostics.Invalid_use_of_0_in_strict_mode;
13497-
return grammarErrorOnNode(identifier, message, declarationNameToString(identifier));
13498-
}
13499-
}
13500-
}
13501-
13502-
function isEvalOrArgumentsIdentifier(node: Node): boolean {
13503-
return node.kind === SyntaxKind.Identifier &&
13504-
((<Identifier>node).text === "eval" || (<Identifier>node).text === "arguments");
13505-
}
13506-
1350713435
function checkGrammarConstructorTypeParameters(node: ConstructorDeclaration) {
1350813436
if (node.typeParameters) {
1350913437
return grammarErrorAtPos(getSourceFileOfNode(node), node.typeParameters.pos, node.typeParameters.end - node.typeParameters.pos, Diagnostics.Type_parameters_cannot_appear_on_a_constructor_declaration);
@@ -13613,13 +13541,8 @@ namespace ts {
1361313541

1361413542
function checkGrammarNumericLiteral(node: Identifier): boolean {
1361513543
// Grammar checking
13616-
if (node.flags & NodeFlags.OctalLiteral) {
13617-
if (node.parserContextFlags & ParserContextFlags.StrictMode) {
13618-
return grammarErrorOnNode(node, Diagnostics.Octal_literals_are_not_allowed_in_strict_mode);
13619-
}
13620-
else if (languageVersion >= ScriptTarget.ES5) {
13621-
return grammarErrorOnNode(node, Diagnostics.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher);
13622-
}
13544+
if (node.flags & NodeFlags.OctalLiteral && languageVersion >= ScriptTarget.ES5) {
13545+
return grammarErrorOnNode(node, Diagnostics.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher);
1362313546
}
1362413547
}
1362513548

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

0 commit comments

Comments
 (0)