External modules are always in strict mode in ES6

This commit is contained in:
Cyrus Najmabadi
2015-06-15 18:20:44 -07:00
parent dcbfa6988a
commit d558e42d94
11 changed files with 70 additions and 36 deletions

View File

@@ -618,19 +618,31 @@ namespace ts {
// Report error only if there are no parse errors in file
if (!file.parseDiagnostics.length) {
let message = getAncestor(node, SyntaxKind.ClassDeclaration) || getAncestor(node, SyntaxKind.ClassExpression) ?
Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode :
Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode;
file.bindDiagnostics.push(createDiagnosticForNode(node, message, declarationNameToString(node)));
file.bindDiagnostics.push(createDiagnosticForNode(node,
getStrictModeIdentifierMessage(node), declarationNameToString(node)));
}
}
}
function getStrictModeIdentifierMessage(node: Node) {
// Provide specialized messages to help the user understand why we think they're in
// strict mode.
if (getAncestor(node, SyntaxKind.ClassDeclaration) || getAncestor(node, SyntaxKind.ClassExpression)) {
return Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode;
}
if (file.externalModuleIndicator) {
return Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode;
}
return Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode;
}
function checkStrictModeBinaryExpression(node: BinaryExpression) {
if (inStrictMode && isLeftHandSideExpression(node.left) && isAssignmentOperator(node.operatorToken.kind)) {
// ECMA 262 (Annex C) The identifier eval or arguments may not appear as the LeftHandSideExpression of an
// Assignment operator(11.13) or of a PostfixExpression(11.3)
checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>node.left);
checkStrictModeEvalOrArguments(node, <Identifier>node.left);
}
}
@@ -638,7 +650,7 @@ namespace ts {
// It is a SyntaxError if a TryStatement with a Catch occurs within strict code and the Identifier of the
// Catch production is eval or arguments
if (inStrictMode && node.variableDeclaration) {
checkGrammarEvalOrArgumentsInStrictMode(node, node.variableDeclaration.name);
checkStrictModeEvalOrArguments(node, node.variableDeclaration.name);
}
}
@@ -657,25 +669,37 @@ namespace ts {
((<Identifier>node).text === "eval" || (<Identifier>node).text === "arguments");
}
function checkGrammarEvalOrArgumentsInStrictMode(contextNode: Node, name: Node) {
function checkStrictModeEvalOrArguments(contextNode: Node, name: Node) {
if (name && name.kind === SyntaxKind.Identifier) {
let identifier = <Identifier>name;
if (isEvalOrArgumentsIdentifier(identifier)) {
// We check first if the name is inside class declaration or class expression; if so give explicit message
// otherwise report generic error message.
let span = getErrorSpanForNode(file, name);
let message = getAncestor(identifier, SyntaxKind.ClassDeclaration) || getAncestor(identifier, SyntaxKind.ClassExpression) ?
Diagnostics.Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode :
Diagnostics.Invalid_use_of_0_in_strict_mode;
file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, message, identifier.text));
file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length,
getStrictModeEvalOrArgumentsMessage(contextNode), identifier.text));
}
}
}
function getStrictModeEvalOrArgumentsMessage(node: Node) {
// Provide specialized messages to help the user understand why we think they're in
// strict mode.
if (getAncestor(node, SyntaxKind.ClassDeclaration) || getAncestor(node, SyntaxKind.ClassExpression)) {
return Diagnostics.Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode;
}
if (file.externalModuleIndicator) {
return Diagnostics.Invalid_use_of_0_Modules_are_automatically_in_strict_mode;
}
return Diagnostics.Invalid_use_of_0_in_strict_mode;
}
function checkStrictModeFunctionName(node: FunctionLikeDeclaration) {
if (inStrictMode) {
// It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a strict mode FunctionDeclaration or FunctionExpression (13.1))
checkGrammarEvalOrArgumentsInStrictMode(node, node.name);
checkStrictModeEvalOrArguments(node, node.name);
}
}
@@ -691,7 +715,7 @@ namespace ts {
// Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression
// operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator.
if (inStrictMode) {
checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>node.operand);
checkStrictModeEvalOrArguments(node, <Identifier>node.operand);
}
}
@@ -699,7 +723,7 @@ namespace ts {
// Grammar checking
if (inStrictMode) {
if (node.operator === SyntaxKind.PlusPlusToken || node.operator === SyntaxKind.MinusMinusToken) {
checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>node.operand);
checkStrictModeEvalOrArguments(node, <Identifier>node.operand);
}
}
}
@@ -962,7 +986,7 @@ namespace ts {
function bindVariableDeclarationOrBindingElement(node: VariableDeclaration | BindingElement) {
if (inStrictMode) {
checkGrammarEvalOrArgumentsInStrictMode(node, node.name)
checkStrictModeEvalOrArguments(node, node.name)
}
if (!isBindingPattern(node.name)) {
@@ -991,7 +1015,7 @@ namespace ts {
if (inStrictMode) {
// It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a
// strict mode FunctionLikeDeclaration or FunctionExpression(13.1)
checkGrammarEvalOrArgumentsInStrictMode(node, node.name);
checkStrictModeEvalOrArguments(node, node.name);
}
if (isBindingPattern(node.name)) {

View File

@@ -171,6 +171,8 @@ namespace ts {
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" },
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" },
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." },
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." },
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." },
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'." },
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." },
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." },

View File

@@ -671,6 +671,14 @@
"category": "Error",
"code": 1213
},
"Identifier expected. '{0}' is a reserved word in strict mode. Modules are automatically in strict mode.": {
"category": "Error",
"code": 1214
},
"Invalid use of '{0}'. Modules are automatically in strict mode.": {
"category": "Error",
"code": 1215
},
"Export assignment is not supported when '--module' flag is 'system'.": {
"category": "Error",
"code": 1218