Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
253 changes: 247 additions & 6 deletions src/compiler/binder.ts

Large diffs are not rendered by default.

95 changes: 9 additions & 86 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7734,7 +7734,7 @@ namespace ts {
// Grammar checking
let hasGrammarError = checkGrammarFunctionLikeDeclaration(node);
if (!hasGrammarError && node.kind === SyntaxKind.FunctionExpression) {
checkGrammarFunctionName(node.name) || checkGrammarForGenerator(node);
checkGrammarForGenerator(node);
}

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

function checkDeleteExpression(node: DeleteExpression): Type {
// Grammar checking
if (node.parserContextFlags & ParserContextFlags.StrictMode && node.expression.kind === SyntaxKind.Identifier) {
// When a delete operator occurs within strict mode code, a SyntaxError is thrown if its
// UnaryExpression is a direct reference to a variable, function argument, or function name
grammarErrorOnNode(node.expression, Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode);
}

let operandType = checkExpression(node.expression);
checkExpression(node.expression);
return booleanType;
}

Expand All @@ -7913,14 +7906,6 @@ namespace ts {
}

function checkPrefixUnaryExpression(node: PrefixUnaryExpression): Type {
// Grammar checking
// The identifier eval or arguments may not appear as the LeftHandSideExpression of an
// 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 ((node.operator === SyntaxKind.PlusPlusToken || node.operator === SyntaxKind.MinusMinusToken)) {
checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>node.operand);
}

let operandType = checkExpression(node.operand);
switch (node.operator) {
case SyntaxKind.PlusToken:
Expand All @@ -7947,12 +7932,6 @@ namespace ts {
}

function checkPostfixUnaryExpression(node: PostfixUnaryExpression): Type {
// Grammar checking
// The identifier eval or arguments may not appear as the LeftHandSideExpression of an
// 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.
checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>node.operand);

let operandType = checkExpression(node.operand);
let ok = checkArithmeticOperandType(node.operand, operandType, Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type);
if (ok) {
Expand Down Expand Up @@ -8132,13 +8111,6 @@ namespace ts {
}

function checkBinaryExpression(node: BinaryExpression, contextualMapper?: TypeMapper) {
// Grammar checking
if (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);
}

let operator = node.operatorToken.kind;
if (operator === SyntaxKind.EqualsToken && (node.left.kind === SyntaxKind.ObjectLiteralExpression || node.left.kind === SyntaxKind.ArrayLiteralExpression)) {
return checkDestructuringAssignment(node.left, checkExpression(node.right, contextualMapper), contextualMapper);
Expand Down Expand Up @@ -8580,11 +8552,9 @@ namespace ts {
// It is a SyntaxError if the Identifier "eval" or the Identifier "arguments" occurs as the
// Identifier in a PropertySetParameterList of a PropertyAssignment that is contained in strict code
// or if its FunctionBody is strict code(11.1.5).
// It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a
// strict mode FunctionLikeDeclaration or FunctionExpression(13.1)

// Grammar checking
checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>node.name);
checkGrammarDecorators(node) || checkGrammarModifiers(node);

checkVariableLikeDeclaration(node);
let func = getContainingFunction(node);
Expand Down Expand Up @@ -9476,9 +9446,7 @@ namespace ts {

function checkFunctionDeclaration(node: FunctionDeclaration): void {
if (produceDiagnostics) {
checkFunctionLikeDeclaration(node) ||
checkGrammarFunctionName(node.name) ||
checkGrammarForGenerator(node);
checkFunctionLikeDeclaration(node) || checkGrammarForGenerator(node);

checkCollisionWithCapturedSuperVariable(node, node.name);
checkCollisionWithCapturedThisVariable(node, node.name);
Expand Down Expand Up @@ -10305,12 +10273,7 @@ namespace ts {
}

function checkWithStatement(node: WithStatement) {
// Grammar checking for withStatement
if (!checkGrammarStatementInAmbientContext(node)) {
if (node.parserContextFlags & ParserContextFlags.StrictMode) {
grammarErrorOnFirstToken(node, Diagnostics.with_statements_are_not_allowed_in_strict_mode);
}
}
checkGrammarStatementInAmbientContext(node);

checkExpression(node.expression);
error(node.expression, Diagnostics.All_symbols_within_a_with_block_will_be_resolved_to_any);
Expand Down Expand Up @@ -10414,10 +10377,6 @@ namespace ts {
grammarErrorOnNode(localSymbol.valueDeclaration, Diagnostics.Cannot_redeclare_identifier_0_in_catch_clause, identifierName);
}
}

// 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
checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>catchClause.variableDeclaration.name);
}
}

Expand Down Expand Up @@ -13022,11 +12981,6 @@ namespace ts {
}
}

function checkGrammarFunctionName(name: Node) {
// It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a strict mode FunctionDeclaration or FunctionExpression (13.1))
return checkGrammarEvalOrArgumentsInStrictMode(name, <Identifier>name);
}

function checkGrammarForInvalidQuestionMark(node: Declaration, questionToken: Node, message: DiagnosticMessage): boolean {
if (questionToken) {
return grammarErrorOnNode(questionToken, message);
Expand All @@ -13039,7 +12993,6 @@ namespace ts {
let GetAccessor = 2;
let SetAccesor = 4;
let GetOrSetAccessor = GetAccessor | SetAccesor;
let inStrictMode = (node.parserContextFlags & ParserContextFlags.StrictMode) !== 0;

for (let prop of node.properties) {
let name = prop.name;
Expand Down Expand Up @@ -13086,9 +13039,7 @@ namespace ts {
else {
let existingKind = seen[(<Identifier>name).text];
if (currentKind === Property && existingKind === Property) {
if (inStrictMode) {
grammarErrorOnNode(name, Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode);
}
continue;
}
else if ((currentKind & GetOrSetAccessor) && (existingKind & GetOrSetAccessor)) {
if (existingKind !== GetOrSetAccessor && currentKind !== existingKind) {
Expand Down Expand Up @@ -13311,9 +13262,6 @@ namespace ts {
return grammarErrorAtPos(getSourceFileOfNode(node), node.initializer.pos - 1, 1, Diagnostics.A_rest_element_cannot_have_an_initializer);
}
}
// It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code
// and its Identifier is eval or arguments
return checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>node.name);
}

function checkGrammarVariableDeclaration(node: VariableDeclaration) {
Expand Down Expand Up @@ -13345,8 +13293,7 @@ namespace ts {

// It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code
// and its Identifier is eval or arguments
return (checkLetConstNames && checkGrammarNameInLetOrConstDeclarations(node.name)) ||
checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>node.name);
return checkLetConstNames && checkGrammarNameInLetOrConstDeclarations(node.name);
}

function checkGrammarNameInLetOrConstDeclarations(name: Identifier | BindingPattern): boolean {
Expand Down Expand Up @@ -13485,25 +13432,6 @@ namespace ts {
}
}

function checkGrammarEvalOrArgumentsInStrictMode(contextNode: Node, name: Node): boolean {
if (name && name.kind === SyntaxKind.Identifier) {
let identifier = <Identifier>name;
if (contextNode && (contextNode.parserContextFlags & ParserContextFlags.StrictMode) && 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 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;
return grammarErrorOnNode(identifier, message, declarationNameToString(identifier));
}
}
}

function isEvalOrArgumentsIdentifier(node: Node): boolean {
return node.kind === SyntaxKind.Identifier &&
((<Identifier>node).text === "eval" || (<Identifier>node).text === "arguments");
}

function checkGrammarConstructorTypeParameters(node: ConstructorDeclaration) {
if (node.typeParameters) {
return grammarErrorAtPos(getSourceFileOfNode(node), node.typeParameters.pos, node.typeParameters.end - node.typeParameters.pos, Diagnostics.Type_parameters_cannot_appear_on_a_constructor_declaration);
Expand Down Expand Up @@ -13613,13 +13541,8 @@ namespace ts {

function checkGrammarNumericLiteral(node: Identifier): boolean {
// Grammar checking
if (node.flags & NodeFlags.OctalLiteral) {
if (node.parserContextFlags & ParserContextFlags.StrictMode) {
return grammarErrorOnNode(node, Diagnostics.Octal_literals_are_not_allowed_in_strict_mode);
}
else if (languageVersion >= ScriptTarget.ES5) {
return grammarErrorOnNode(node, Diagnostics.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher);
}
if (node.flags & NodeFlags.OctalLiteral && languageVersion >= ScriptTarget.ES5) {
return grammarErrorOnNode(node, Diagnostics.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher);
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/compiler/diagnosticInformationMap.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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." },
Expand Down
8 changes: 8 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading