Merge pull request #217 from Microsoft/strict_mode

Strict mode support
This commit is contained in:
Vladimir Matveev 2014-07-24 13:15:49 -07:00
Родитель 64ab02ec43 4c70d738dd
Коммит a490eb29f3
42 изменённых файлов: 344 добавлений и 352 удалений

Просмотреть файл

@ -99,6 +99,9 @@ module ts {
A_constructor_implementation_cannot_be_declared_in_an_ambient_context: { code: 1111, category: DiagnosticCategory.Error, key: "A constructor implementation cannot be declared in an ambient context." },
A_class_member_cannot_be_declared_optional: { code: 1112, category: DiagnosticCategory.Error, key: "A class member cannot be declared optional." },
A_default_clause_cannot_appear_more_than_once_in_a_switch_statement: { code: 1113, category: DiagnosticCategory.Error, key: "A 'default' clause cannot appear more than once in a 'switch' statement." },
An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode: { code: 1114, category: DiagnosticCategory.Error, key: "An object literal cannot have multiple properties with the same name in strict mode." },
An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name: { code: 1115, category: DiagnosticCategory.Error, key: "An object literal cannot have multiple get/set accessors with the same name." },
An_object_literal_cannot_have_property_and_accessor_with_the_same_name: { code: 1116, category: DiagnosticCategory.Error, key: "An object literal cannot have property and accessor with the same name." },
Duplicate_identifier_0: { code: 2000, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." },
new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead: { code: 2068, category: DiagnosticCategory.Error, key: "'new T[]' cannot be used to create an array. Use 'new Array<T>()' instead." },
Multiple_constructor_implementations_are_not_allowed: { code: 2070, category: DiagnosticCategory.Error, key: "Multiple constructor implementations are not allowed." },

Просмотреть файл

@ -388,7 +388,18 @@
"category": "Error",
"code": 1113
},
"An object literal cannot have multiple properties with the same name in strict mode.": {
"category": "Error",
"code": 1114
},
"An object literal cannot have multiple get/set accessors with the same name.": {
"category": "Error",
"code": 1115
},
"An object literal cannot have property and accessor with the same name.": {
"category": "Error",
"code": 1116
},
"Duplicate identifier '{0}'.": {
"category": "Error",
"code": 2000

Просмотреть файл

@ -1669,8 +1669,7 @@ module ts {
function emitDirectivePrologues(statements: Statement[], startWithNewLine: boolean): number {
for (var i = 0; i < statements.length; ++i) {
if (statements[i].kind === SyntaxKind.ExpressionStatement &&
(<ExpressionStatement>statements[i]).expression.kind === SyntaxKind.StringLiteral) {
if (isPrologueDirective(statements[i])) {
if (startWithNewLine || i > 0) {
writeLine();
}

Просмотреть файл

@ -119,6 +119,22 @@ module ts {
return file.externalModuleIndicator !== undefined;
}
export function isPrologueDirective(node: Node): boolean {
return node.kind === SyntaxKind.ExpressionStatement && (<ExpressionStatement>node).expression.kind === SyntaxKind.StringLiteral;
}
function isEvalOrArgumentsIdentifier(node: Node): boolean {
return node.kind === SyntaxKind.Identifier &&
(<Identifier>node).text &&
((<Identifier>node).text === "eval" || (<Identifier>node).text === "arguments")
}
/// Should be called only on prologue directives (isPrologueDirective(node) should be true)
function isUseStrictPrologueDirective(node: Node): boolean {
Debug.assert(isPrologueDirective(node));
return (<Identifier>(<ExpressionStatement>node).expression).text === "use strict";
}
// Invokes a callback for each child of the given node. The 'cbNode' callback is invoked for all child nodes
// stored in properties. If a 'cbNodes' callback is specified, it is invoked for embedded arrays; otherwise,
// embedded arrays are flattened and the 'cbNode' callback is invoked for each element. If a callback returns
@ -383,6 +399,7 @@ module ts {
var identifierCount = 0;
var nodeCount = 0;
var lineStarts: number[];
var isInStrictMode = false;
var lookAheadMode = LookAheadMode.NotLookingAhead;
var inAmbientContext = false;
@ -418,6 +435,13 @@ module ts {
file.syntacticErrors.push(createFileDiagnostic(file, start, length, message, arg0, arg1, arg2));
}
function reportInvalidUseInStrictMode(node: Identifier): void {
// identifierToString cannot be used here since it uses backreference to 'parent' that is not yet set
var name = sourceText.substring(skipTrivia(sourceText, node.pos), node.end);
grammarErrorOnNode(node, Diagnostics.Invalid_use_of_0_in_strict_mode, name);
}
function grammarErrorAtPos(start: number, length: number, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): void {
file.syntacticErrors.push(createFileDiagnostic(file, start, length, message, arg0, arg1, arg2));
}
@ -522,7 +546,7 @@ module ts {
}
function isIdentifier(): boolean {
return token === SyntaxKind.Identifier || token > SyntaxKind.LastReservedWord;
return token === SyntaxKind.Identifier || (isInStrictMode ? token > SyntaxKind.LastFutureReservedWord : token > SyntaxKind.LastReservedWord);
}
function isSemicolon(): boolean {
@ -767,14 +791,28 @@ module ts {
}
// Parses a list of elements
function parseList<T extends Node>(kind: ParsingContext, parseElement: () => T): NodeArray<T> {
function parseList<T extends Node>(kind: ParsingContext, checkForStrictMode: boolean, parseElement: () => T): NodeArray<T> {
var saveParsingContext = parsingContext;
parsingContext |= 1 << kind;
var result = <NodeArray<T>>[];
result.pos = getNodePos();
var saveIsInStrictMode = isInStrictMode;
while (!isListTerminator(kind)) {
if (isListElement(kind, /* inErrorRecovery */ false)) {
result.push(parseElement());
var element = parseElement();
result.push(element);
// test elements only if we are not already in strict mode
if (!isInStrictMode && checkForStrictMode) {
if (isPrologueDirective(element)) {
if (isUseStrictPrologueDirective(element)) {
isInStrictMode = true;
checkForStrictMode = false;
}
}
else {
checkForStrictMode = false;
}
}
}
else {
error(parsingContextErrors(kind));
@ -784,6 +822,7 @@ module ts {
nextToken();
}
}
isInStrictMode = saveIsInStrictMode;
result.end = getNodeEnd();
parsingContext = saveParsingContext;
return result;
@ -969,6 +1008,18 @@ module ts {
node.flags |= NodeFlags.Rest;
}
node.name = parseIdentifier();
if (node.name.kind === SyntaxKind.Missing && node.flags === 0 && isModifier(token)) {
// in cases like
// 'use strict'
// function foo(static)
// isParameter('static') === true, because of isModifier('static')
// however 'static' is not a legal identifier in a strict mode.
// so result of this function will be ParameterDeclaration (flags = 0, name = missing, type = undefined, initializer = undefined)
// and current token will not change => parsing of the enclosing parameter list will last till the end of time (or OOM)
// to avoid this we'll advance cursor to the next token.
nextToken();
}
if (parseOptional(SyntaxKind.QuestionToken)) {
node.flags |= NodeFlags.QuestionMark;
}
@ -1013,8 +1064,16 @@ module ts {
for (var i = 0; i < parameterCount; i++) {
var parameter = parameters[i];
if (parameter.flags & NodeFlags.Rest) {
// 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 FunctionDeclaration or FunctionExpression(13.1)
if (isInStrictMode && isEvalOrArgumentsIdentifier(parameter.name)) {
reportInvalidUseInStrictMode(parameter.name);
return;
}
else if (parameter.flags & NodeFlags.Rest) {
if (i !== (parameterCount - 1)) {
grammarErrorOnNode(parameter.name, Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list);
return;
@ -1171,7 +1230,7 @@ module ts {
function parseTypeLiteral(): TypeLiteralNode {
var node = <TypeLiteralNode>createNode(SyntaxKind.TypeLiteral);
if (parseExpected(SyntaxKind.OpenBraceToken)) {
node.members = parseList(ParsingContext.TypeMembers, parseTypeMember);
node.members = parseList(ParsingContext.TypeMembers, /*checkForStrictMode*/ false, parseTypeMember);
parseExpected(SyntaxKind.CloseBraceToken);
}
else {
@ -1359,8 +1418,13 @@ module ts {
// Now see if we might be in cases '2' or '3'.
// If the expression was a LHS expression, and we have an assignment operator, then
// we're in '2' or '3'. Consume the assignement and return.
// we're in '2' or '3'. Consume the assignment and return.
if (isLeftHandSideExpression(expr) && isAssignmentOperator()) {
if (isInStrictMode && isEvalOrArgumentsIdentifier(expr)) {
// 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)
reportInvalidUseInStrictMode(<Identifier>expr);
}
var operator = token;
nextToken();
return makeBinaryExpression(expr, operator, parseAssignmentExpression(noIn));
@ -1660,6 +1724,19 @@ module ts {
var operator = token;
nextToken();
var operand = parseUnaryExpression();
if (isInStrictMode) {
// 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 ((token === SyntaxKind.PlusPlusToken || token === SyntaxKind.MinusMinusToken) && isEvalOrArgumentsIdentifier(operand)) {
reportInvalidUseInStrictMode(<Identifier>operand);
}
else if (token === SyntaxKind.DeleteKeyword && operand.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(operand, Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode);
}
}
return makeUnaryExpression(SyntaxKind.PrefixOperator, pos, operator, operand);
case SyntaxKind.LessThanToken:
return parseTypeAssertion();
@ -1681,6 +1758,12 @@ module ts {
Debug.assert(isLeftHandSideExpression(expr));
if ((token === SyntaxKind.PlusPlusToken || token === SyntaxKind.MinusMinusToken) && !scanner.hasPrecedingLineBreak()) {
// 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 (isInStrictMode && isEvalOrArgumentsIdentifier(expr)) {
reportInvalidUseInStrictMode(<Identifier>expr);
}
var operator = token;
nextToken();
expr = makeUnaryExpression(SyntaxKind.PostfixOperator, expr.pos, operator, expr);
@ -1867,6 +1950,61 @@ module ts {
if (scanner.hasPrecedingLineBreak()) node.flags |= NodeFlags.MultiLine;
node.properties = parseDelimitedList(ParsingContext.ObjectLiteralMembers, parseObjectLiteralMember, TrailingCommaBehavior.Preserve);
parseExpected(SyntaxKind.CloseBraceToken);
var seen: Map<SymbolFlags> = {};
var Property = 1;
var GetAccessor = 2;
var SetAccesor = 4;
var GetOrSetAccessor = GetAccessor | SetAccesor;
forEach(node.properties, (p: Declaration) => {
if (p.kind === SyntaxKind.OmittedExpression) {
return;
}
// ECMA-262 11.1.5 Object Initialiser
// If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true
// a.This production is contained in strict code and IsDataDescriptor(previous) is true and
// IsDataDescriptor(propId.descriptor) is true.
// b.IsDataDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true.
// c.IsAccessorDescriptor(previous) is true and IsDataDescriptor(propId.descriptor) is true.
// d.IsAccessorDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true
// and either both previous and propId.descriptor have[[Get]] fields or both previous and propId.descriptor have[[Set]] fields
var currentKind: number;
if (p.kind === SyntaxKind.PropertyAssignment) {
currentKind = Property;
}
else if (p.kind === SyntaxKind.GetAccessor) {
currentKind = GetAccessor;
}
else if (p.kind === SyntaxKind.SetAccessor) {
currentKind = SetAccesor;
}
else {
Debug.fail("Unexpected syntax kind:" + SyntaxKind[p.kind]);
}
if (!hasProperty(seen, p.name.text)) {
seen[p.name.text] = currentKind;
}
else {
var existingKind = seen[p.name.text];
if (currentKind === Property && existingKind === Property) {
if (isInStrictMode) {
grammarErrorOnNode(p.name, Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode);
}
}
else if ((currentKind & GetOrSetAccessor) && (existingKind & GetOrSetAccessor)) {
if (existingKind !== GetOrSetAccessor && currentKind !== existingKind) {
seen[p.name.text] = currentKind | existingKind;
}
else {
grammarErrorOnNode(p.name, Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name);
}
}
else {
grammarErrorOnNode(p.name, Diagnostics.An_object_literal_cannot_have_property_and_accessor_with_the_same_name);
}
}
});
return finishNode(node);
}
@ -1876,6 +2014,11 @@ module ts {
var name = isIdentifier() ? parseIdentifier() : undefined;
var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken);
var body = parseBody(/* ignoreMissingOpenBrace */ false);
if (name && isInStrictMode && isEvalOrArgumentsIdentifier(name)) {
// It is a SyntaxError to use within strict mode code the identifiers eval or arguments as the
// Identifier of a FunctionDeclaration or FunctionExpression or as a formal parameter name(13.1)
reportInvalidUseInStrictMode(name);
}
return makeFunctionExpression(SyntaxKind.FunctionExpression, pos, name, sig, body);
}
@ -1902,10 +2045,10 @@ module ts {
// STATEMENTS
function parseBlock(ignoreMissingOpenBrace: boolean): Block {
function parseBlock(ignoreMissingOpenBrace: boolean, checkForStrictMode: boolean): Block {
var node = <Block>createNode(SyntaxKind.Block);
if (parseExpected(SyntaxKind.OpenBraceToken) || ignoreMissingOpenBrace) {
node.statements = parseList(ParsingContext.BlockStatements, parseStatement);
node.statements = parseList(ParsingContext.BlockStatements,checkForStrictMode, parseStatement);
parseExpected(SyntaxKind.CloseBraceToken);
}
else {
@ -1915,7 +2058,7 @@ module ts {
}
function parseBody(ignoreMissingOpenBrace: boolean): Block {
var block = parseBlock(ignoreMissingOpenBrace);
var block = parseBlock(ignoreMissingOpenBrace, /*checkForStrictMode*/ true);
block.kind = SyntaxKind.FunctionBlock;
return block;
}
@ -2031,12 +2174,20 @@ module ts {
function parseWithStatement(): WithStatement {
var node = <WithStatement>createNode(SyntaxKind.WithStatement);
var startPos = scanner.getTokenPos();
parseExpected(SyntaxKind.WithKeyword);
var endPos = scanner.getStartPos();
parseExpected(SyntaxKind.OpenParenToken);
node.expression = parseExpression();
parseExpected(SyntaxKind.CloseParenToken);
node.statement = parseStatement();
return finishNode(node);
node = finishNode(node);
if (isInStrictMode) {
// Strict mode code may not include a WithStatement. The occurrence of a WithStatement in such
// a context is an
grammarErrorAtPos(startPos, endPos - startPos, Diagnostics.with_statements_are_not_allowed_in_strict_mode)
}
return node;
}
function parseCaseClause(): CaseOrDefaultClause {
@ -2044,7 +2195,7 @@ module ts {
parseExpected(SyntaxKind.CaseKeyword);
node.expression = parseExpression();
parseExpected(SyntaxKind.ColonToken);
node.statements = parseList(ParsingContext.SwitchClauseStatements, parseStatement);
node.statements = parseList(ParsingContext.SwitchClauseStatements, /*checkForStrictMode*/ false, parseStatement);
return finishNode(node);
}
@ -2052,7 +2203,7 @@ module ts {
var node = <CaseOrDefaultClause>createNode(SyntaxKind.DefaultClause);
parseExpected(SyntaxKind.DefaultKeyword);
parseExpected(SyntaxKind.ColonToken);
node.statements = parseList(ParsingContext.SwitchClauseStatements, parseStatement);
node.statements = parseList(ParsingContext.SwitchClauseStatements, /*checkForStrictMode*/ false, parseStatement);
return finishNode(node);
}
@ -2067,7 +2218,7 @@ module ts {
node.expression = parseExpression();
parseExpected(SyntaxKind.CloseParenToken);
parseExpected(SyntaxKind.OpenBraceToken);
node.clauses = parseList(ParsingContext.SwitchClauses, parseCaseOrDefaultClause);
node.clauses = parseList(ParsingContext.SwitchClauses, /*checkForStrictMode*/ false, parseCaseOrDefaultClause);
parseExpected(SyntaxKind.CloseBraceToken);
// Error on duplicate 'default' clauses.
@ -2112,7 +2263,7 @@ module ts {
function parseTokenAndBlock(token: SyntaxKind, kind: SyntaxKind): Block {
var pos = getNodePos();
parseExpected(token);
var result = parseBlock(/* ignoreMissingOpenBrace */ false);
var result = parseBlock(/* ignoreMissingOpenBrace */ false, /*checkForStrictMode*/ false);
result.kind = kind;
result.pos = pos;
return result;
@ -2127,7 +2278,7 @@ module ts {
var typeAnnotationColonLength = scanner.getTextPos() - typeAnnotationColonStart;
var typeAnnotation = parseTypeAnnotation();
parseExpected(SyntaxKind.CloseParenToken);
var result = <CatchBlock>parseBlock(/* ignoreMissingOpenBrace */ false);
var result = <CatchBlock>parseBlock(/* ignoreMissingOpenBrace */ false, /*checkForStrictMode*/ false);
result.kind = SyntaxKind.CatchBlock;
result.pos = pos;
result.variable = variable;
@ -2135,6 +2286,11 @@ module ts {
if (typeAnnotation) {
errorAtPos(typeAnnotationColonStart, typeAnnotationColonLength, Diagnostics.Catch_clause_parameter_cannot_have_a_type_annotation);
}
if (isInStrictMode && isEvalOrArgumentsIdentifier(variable)) {
// 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
reportInvalidUseInStrictMode(variable);
}
return result;
}
@ -2207,7 +2363,7 @@ module ts {
function parseStatement(): Statement {
switch (token) {
case SyntaxKind.OpenBraceToken:
return parseBlock(/* ignoreMissingOpenBrace */ false);
return parseBlock(/* ignoreMissingOpenBrace */ false, /*checkForStrictMode*/ false);
case SyntaxKind.VarKeyword:
return parseVariableStatement();
case SyntaxKind.FunctionKeyword:
@ -2285,6 +2441,11 @@ module ts {
if (inAmbientContext && node.initializer && errorCountBeforeVariableDeclaration === file.syntacticErrors.length) {
grammarErrorAtPos(initializerStart, initializerFirstTokenLength, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
}
if (isInStrictMode && isEvalOrArgumentsIdentifier(node.name)) {
// It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code
// and its Identifier is eval or arguments
reportInvalidUseInStrictMode(node.name);
}
return finishNode(node);
}
@ -2315,6 +2476,11 @@ module ts {
node.parameters = sig.parameters;
node.type = sig.type;
node.body = parseAndCheckFunctionBody(/*isConstructor*/ false);
if (isInStrictMode && isEvalOrArgumentsIdentifier(node.name)) {
// It is a SyntaxError to use within strict mode code the identifiers eval or arguments as the
// Identifier of a FunctionDeclaration or FunctionExpression or as a formal parameter name(13.1)
reportInvalidUseInStrictMode(node.name);
}
return finishNode(node);
}
@ -2657,7 +2823,7 @@ module ts {
}
var errorCountBeforeClassBody = file.syntacticErrors.length;
if (parseExpected(SyntaxKind.OpenBraceToken)) {
node.members = parseList(ParsingContext.ClassMembers, parseClassMemberDeclaration);
node.members = parseList(ParsingContext.ClassMembers, /*checkForStrictMode*/ false, parseClassMemberDeclaration);
parseExpected(SyntaxKind.CloseBraceToken);
}
else {
@ -2757,7 +2923,7 @@ module ts {
function parseModuleBody(): Block {
var node = <Block>createNode(SyntaxKind.ModuleBlock);
if (parseExpected(SyntaxKind.OpenBraceToken)) {
node.statements = parseList(ParsingContext.ModuleElements, parseModuleElement);
node.statements = parseList(ParsingContext.ModuleElements, /*checkForStrictMode*/ false, parseModuleElement);
parseExpected(SyntaxKind.CloseBraceToken);
}
else {
@ -3014,7 +3180,7 @@ module ts {
var referenceComments = processReferenceComments();
file.referencedFiles = referenceComments.referencedFiles;
file.amdDependencies = referenceComments.amdDependencies;
file.statements = parseList(ParsingContext.SourceElements, parseSourceElement);
file.statements = parseList(ParsingContext.SourceElements, /*checkForStrictMode*/ true, parseSourceElement);
file.externalModuleIndicator = getExternalModuleIndicator();
file.nodeCount = nodeCount;
file.identifierCount = identifierCount;

Просмотреть файл

@ -215,7 +215,9 @@ module ts {
FirstReservedWord = BreakKeyword,
LastReservedWord = WithKeyword,
FirstKeyword = BreakKeyword,
LastKeyword = StringKeyword
LastKeyword = StringKeyword,
FirstFutureReservedWord = ImplementsKeyword,
LastFutureReservedWord = YieldKeyword
}
export enum NodeFlags {

Просмотреть файл

@ -0,0 +1,8 @@
==== tests/cases/compiler/constructorStaticParamNameErrors.ts (1 errors) ====
'use strict'
// static as constructor parameter name should give error if 'use strict'
class test {
constructor (static) { }
~~~~~~
!!! Identifier expected.
}

Просмотреть файл

@ -1,14 +0,0 @@
//// [constructorStaticParamNameErrors.ts]
'use strict'
// static as constructor parameter name should give error if 'use strict'
class test {
constructor (static) { }
}
//// [constructorStaticParamNameErrors.js]
'use strict';
var test = (function () {
function test(static) {
}
return test;
})();

Просмотреть файл

@ -1,4 +1,4 @@
==== tests/cases/compiler/duplicateObjectLiteralProperty.ts (8 errors) ====
==== tests/cases/compiler/duplicateObjectLiteralProperty.ts (9 errors) ====
var x = {
a: 1,
b: true, // OK
@ -30,6 +30,8 @@
~
!!! Accessors are only available when targeting ECMAScript 5 and higher.
~
!!! An object literal cannot have multiple get/set accessors with the same name.
~
!!! Duplicate identifier 'a'.
};

Просмотреть файл

@ -0,0 +1,10 @@
==== tests/cases/compiler/duplicatePropertiesInStrictMode.ts (2 errors) ====
"use strict";
var x = {
x: 1,
x: 2
~
!!! An object literal cannot have multiple properties with the same name in strict mode.
~
!!! Duplicate identifier 'x'.
}

Просмотреть файл

@ -1,4 +1,4 @@
==== tests/cases/conformance/expressions/objectLiterals/objectLiteralErrors.ts (41 errors) ====
==== tests/cases/conformance/expressions/objectLiterals/objectLiteralErrors.ts (59 errors) ====
// Multiple properties with the same name
var e1 = { a: 0, a: 0 };
@ -59,57 +59,93 @@
// Accessor and property with the same name
var f1 = { a: 0, get a() { return 0; } };
~
!!! An object literal cannot have property and accessor with the same name.
~
!!! Duplicate identifier 'a'.
var f2 = { a: '', get a() { return ''; } };
~
!!! An object literal cannot have property and accessor with the same name.
~
!!! Duplicate identifier 'a'.
var f3 = { a: 0, get a() { return ''; } };
~
!!! An object literal cannot have property and accessor with the same name.
~
!!! Duplicate identifier 'a'.
var f4 = { a: true, get a() { return false; } };
~
!!! An object literal cannot have property and accessor with the same name.
~
!!! Duplicate identifier 'a'.
var f5 = { a: {}, get a() { return {}; } };
~
!!! An object literal cannot have property and accessor with the same name.
~
!!! Duplicate identifier 'a'.
var f6 = { a: 0, get 'a'() { return 0; } };
~~~
!!! An object literal cannot have property and accessor with the same name.
~~~
!!! Duplicate identifier ''a''.
var f7 = { 'a': 0, get a() { return 0; } };
~
!!! An object literal cannot have property and accessor with the same name.
~
!!! Duplicate identifier 'a'.
var f8 = { 'a': 0, get "a"() { return 0; } };
~~~
!!! An object literal cannot have property and accessor with the same name.
~~~
!!! Duplicate identifier '"a"'.
var f9 = { 'a': 0, get 'a'() { return 0; } };
~~~
!!! An object literal cannot have property and accessor with the same name.
~~~
!!! Duplicate identifier ''a''.
var f10 = { "a": 0, get 'a'() { return 0; } };
~~~
!!! An object literal cannot have property and accessor with the same name.
~~~
!!! Duplicate identifier ''a''.
var f11 = { 1.0: 0, get '1'() { return 0; } };
~~~
!!! An object literal cannot have property and accessor with the same name.
~~~
!!! Duplicate identifier ''1''.
var f12 = { 0: 0, get 0() { return 0; } };
~
!!! An object literal cannot have property and accessor with the same name.
~
!!! Duplicate identifier '0'.
var f13 = { 0: 0, get 0() { return 0; } };
~
!!! An object literal cannot have property and accessor with the same name.
~
!!! Duplicate identifier '0'.
var f14 = { 0: 0, get 0x0() { return 0; } };
~~~
!!! An object literal cannot have property and accessor with the same name.
~~~
!!! Duplicate identifier '0x0'.
var f14 = { 0: 0, get 000() { return 0; } };
~~~
!!! An object literal cannot have property and accessor with the same name.
~~~
!!! Duplicate identifier '000'.
var f15 = { "100": 0, get 1e2() { return 0; } };
~~~
!!! An object literal cannot have property and accessor with the same name.
~~~
!!! Duplicate identifier '1e2'.
var f16 = { 0x20: 0, get 3.2e1() { return 0; } };
~~~~~
!!! An object literal cannot have property and accessor with the same name.
~~~~~
!!! Duplicate identifier '3.2e1'.
var f17 = { a: 0, get b() { return 1; }, get a() { return 0; } };
~
!!! An object literal cannot have property and accessor with the same name.
~
!!! Duplicate identifier 'a'.
// Get and set accessor with mismatched type annotations

Просмотреть файл

@ -1,135 +0,0 @@
//// [objectLiteralErrors.ts]
// Multiple properties with the same name
var e1 = { a: 0, a: 0 };
var e2 = { a: '', a: '' };
var e3 = { a: 0, a: '' };
var e4 = { a: true, a: false };
var e5 = { a: {}, a: {} };
var e6 = { a: 0, 'a': 0 };
var e7 = { 'a': 0, a: 0 };
var e8 = { 'a': 0, "a": 0 };
var e9 = { 'a': 0, 'a': 0 };
var e10 = { "a": 0, 'a': 0 };
var e11 = { 1.0: 0, '1': 0 };
var e12 = { 0: 0, 0: 0 };
var e13 = { 0: 0, 0: 0 };
var e14 = { 0: 0, 0x0: 0 };
var e14 = { 0: 0, 000: 0 };
var e15 = { "100": 0, 1e2: 0 };
var e16 = { 0x20: 0, 3.2e1: 0 };
var e17 = { a: 0, b: 1, a: 0 };
// Accessor and property with the same name
var f1 = { a: 0, get a() { return 0; } };
var f2 = { a: '', get a() { return ''; } };
var f3 = { a: 0, get a() { return ''; } };
var f4 = { a: true, get a() { return false; } };
var f5 = { a: {}, get a() { return {}; } };
var f6 = { a: 0, get 'a'() { return 0; } };
var f7 = { 'a': 0, get a() { return 0; } };
var f8 = { 'a': 0, get "a"() { return 0; } };
var f9 = { 'a': 0, get 'a'() { return 0; } };
var f10 = { "a": 0, get 'a'() { return 0; } };
var f11 = { 1.0: 0, get '1'() { return 0; } };
var f12 = { 0: 0, get 0() { return 0; } };
var f13 = { 0: 0, get 0() { return 0; } };
var f14 = { 0: 0, get 0x0() { return 0; } };
var f14 = { 0: 0, get 000() { return 0; } };
var f15 = { "100": 0, get 1e2() { return 0; } };
var f16 = { 0x20: 0, get 3.2e1() { return 0; } };
var f17 = { a: 0, get b() { return 1; }, get a() { return 0; } };
// Get and set accessor with mismatched type annotations
var g1 = { get a(): number { return 4; }, set a(n: string) { } };
var g2 = { get a() { return 4; }, set a(n: string) { } };
var g3 = { get a(): number { return undefined; }, set a(n: string) { } };
//// [objectLiteralErrors.js]
var e1 = { a: 0, a: 0 };
var e2 = { a: '', a: '' };
var e3 = { a: 0, a: '' };
var e4 = { a: true, a: false };
var e5 = { a: {}, a: {} };
var e6 = { a: 0, 'a': 0 };
var e7 = { 'a': 0, a: 0 };
var e8 = { 'a': 0, "a": 0 };
var e9 = { 'a': 0, 'a': 0 };
var e10 = { "a": 0, 'a': 0 };
var e11 = { 1.0: 0, '1': 0 };
var e12 = { 0: 0, 0: 0 };
var e13 = { 0: 0, 0: 0 };
var e14 = { 0: 0, 0x0: 0 };
var e14 = { 0: 0, 000: 0 };
var e15 = { "100": 0, 1e2: 0 };
var e16 = { 0x20: 0, 3.2e1: 0 };
var e17 = { a: 0, b: 1, a: 0 };
var f1 = { a: 0, get a() {
return 0;
} };
var f2 = { a: '', get a() {
return '';
} };
var f3 = { a: 0, get a() {
return '';
} };
var f4 = { a: true, get a() {
return false;
} };
var f5 = { a: {}, get a() {
return {};
} };
var f6 = { a: 0, get 'a'() {
return 0;
} };
var f7 = { 'a': 0, get a() {
return 0;
} };
var f8 = { 'a': 0, get "a"() {
return 0;
} };
var f9 = { 'a': 0, get 'a'() {
return 0;
} };
var f10 = { "a": 0, get 'a'() {
return 0;
} };
var f11 = { 1.0: 0, get '1'() {
return 0;
} };
var f12 = { 0: 0, get 0() {
return 0;
} };
var f13 = { 0: 0, get 0() {
return 0;
} };
var f14 = { 0: 0, get 0x0() {
return 0;
} };
var f14 = { 0: 0, get 000() {
return 0;
} };
var f15 = { "100": 0, get 1e2() {
return 0;
} };
var f16 = { 0x20: 0, get 3.2e1() {
return 0;
} };
var f17 = { a: 0, get b() {
return 1;
}, get a() {
return 0;
} };
var g1 = { get a() {
return 4;
}, set a(n) {
} };
var g2 = { get a() {
return 4;
}, set a(n) {
} };
var g3 = { get a() {
return undefined;
}, set a(n) {
} };

Просмотреть файл

@ -1,4 +1,4 @@
==== tests/cases/conformance/parser/ecmascript5/parser10.1.1-8gs.ts (1 errors) ====
==== tests/cases/conformance/parser/ecmascript5/parser10.1.1-8gs.ts (4 errors) ====
/// Copyright (c) 2012 Ecma International. All rights reserved.
/// Ecma International makes this code available under the terms and conditions set
/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
@ -18,4 +18,10 @@
~~~~~~~~~~~~~
!!! Cannot find name 'NotEarlyError'.
var public = 1;
~~~~~~
!!! Variable declaration expected.
~
!!! Variable declaration expected.
~
!!! Variable declaration expected.

Просмотреть файл

@ -1,25 +0,0 @@
//// [parser10.1.1-8gs.ts]
/// Copyright (c) 2012 Ecma International. All rights reserved.
/// Ecma International makes this code available under the terms and conditions set
/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
/// "Use Terms"). Any redistribution of this code must retain the above
/// copyright and this notice and otherwise comply with the Use Terms.
/**
* @path ch10/10.1/10.1.1/10.1.1-8gs.js
* @description Strict Mode - Use Strict Directive Prologue is ''use strict';' which appears twice in the code
* @noStrict
* @negative ^((?!NotEarlyError).)*$
*/
"use strict";
"use strict";
throw NotEarlyError;
var public = 1;
//// [parser10.1.1-8gs.js]
"use strict";
"use strict";
throw NotEarlyError;
var public = 1;

Просмотреть файл

@ -0,0 +1,9 @@
==== tests/cases/conformance/parser/ecmascript5/RegressionTests/parser642331_1.ts (1 errors) ====
"use strict";
class test {
constructor (static) { }
~~~~~~
!!! Identifier expected.
}

Просмотреть файл

@ -1,15 +0,0 @@
//// [parser642331_1.ts]
"use strict";
class test {
constructor (static) { }
}
//// [parser642331_1.js]
"use strict";
var test = (function () {
function test(static) {
}
return test;
})();

Просмотреть файл

@ -0,0 +1,6 @@
==== tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode10.ts (1 errors) ====
"use strict";
function f(eval) {
~~~~
!!! Invalid use of 'eval' in strict mode.
}

Просмотреть файл

@ -1,9 +0,0 @@
//// [parserStrictMode10.ts]
"use strict";
function f(eval) {
}
//// [parserStrictMode10.js]
"use strict";
function f(eval) {
}

Просмотреть файл

@ -0,0 +1,6 @@
==== tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode11.ts (1 errors) ====
"use strict";
var v = function f(eval) {
~~~~
!!! Invalid use of 'eval' in strict mode.
};

Просмотреть файл

@ -1,9 +0,0 @@
//// [parserStrictMode11.ts]
"use strict";
var v = function f(eval) {
};
//// [parserStrictMode11.js]
"use strict";
var v = function f(eval) {
};

Просмотреть файл

@ -1,5 +1,5 @@
==== tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode12.ts (1 errors) ====
"use strict";
var v = { set foo(eval) { } }
~~~
!!! Accessors are only available when targeting ECMAScript 5 and higher.
~~~~
!!! Invalid use of 'eval' in strict mode.

Просмотреть файл

@ -0,0 +1,8 @@
==== tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode13.ts (1 errors) ====
"use strict";
try {
}
catch(eval) {
~~~~
!!! Invalid use of 'eval' in strict mode.
}

Просмотреть файл

@ -1,13 +0,0 @@
//// [parserStrictMode13.ts]
"use strict";
try {
}
catch(eval) {
}
//// [parserStrictMode13.js]
"use strict";
try {
}
catch (eval) {
}

Просмотреть файл

@ -1,6 +1,8 @@
==== tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode14.ts (2 errors) ====
==== tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode14.ts (3 errors) ====
"use strict";
with (a) {
~~~~
!!! 'with' statements are not allowed in strict mode.
~
!!! All symbols within a 'with' block will be resolved to 'any'.
~

Просмотреть файл

@ -1,9 +0,0 @@
//// [parserStrictMode14.ts]
"use strict";
with (a) {
}
//// [parserStrictMode14.js]
"use strict";
with (a) {
}

Просмотреть файл

@ -1,4 +1,4 @@
==== tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode2.ts (4 errors) ====
==== tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode2.ts (5 errors) ====
"use strict";
foo1();
~~~~
@ -11,4 +11,6 @@
!!! Cannot find name 'foo1'.
static();
~~~~~~
!!! Cannot find name 'static'.
!!! Declaration or statement expected.
~
!!! '=>' expected.

Просмотреть файл

@ -1,13 +0,0 @@
//// [parserStrictMode2.ts]
"use strict";
foo1();
foo1();
foo1();
static();
//// [parserStrictMode2.js]
"use strict";
foo1();
foo1();
foo1();
static();

Просмотреть файл

@ -1,5 +1,7 @@
==== tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode3.ts (1 errors) ====
==== tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode3.ts (2 errors) ====
"use strict";
eval = 1;
~~~~
!!! Invalid use of 'eval' in strict mode.
~~~~
!!! Invalid left-hand side of assignment expression.

Просмотреть файл

@ -1,7 +0,0 @@
//// [parserStrictMode3.ts]
"use strict";
eval = 1;
//// [parserStrictMode3.js]
"use strict";
eval = 1;

Просмотреть файл

@ -1,5 +1,7 @@
==== tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode4.ts (1 errors) ====
==== tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode4.ts (2 errors) ====
"use strict";
arguments = 1;
~~~~~~~~~
!!! Invalid use of 'arguments' in strict mode.
~~~~~~~~~
!!! Cannot find name 'arguments'.

Просмотреть файл

@ -1,7 +0,0 @@
//// [parserStrictMode4.ts]
"use strict";
arguments = 1;
//// [parserStrictMode4.js]
"use strict";
arguments = 1;

Просмотреть файл

@ -1,5 +1,7 @@
==== tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode5.ts (1 errors) ====
==== tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode5.ts (2 errors) ====
"use strict";
eval += 1;
~~~~
!!! Invalid use of 'eval' in strict mode.
~~~~~~~~~
!!! Operator '+=' cannot be applied to types '(x: string) => any' and 'number'.

Просмотреть файл

@ -1,7 +0,0 @@
//// [parserStrictMode5.ts]
"use strict";
eval += 1;
//// [parserStrictMode5.js]
"use strict";
eval += 1;

Просмотреть файл

@ -1,5 +1,7 @@
==== tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode6.ts (1 errors) ====
==== tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode6.ts (2 errors) ====
"use strict";
eval++;
~~~~
!!! Invalid use of 'eval' in strict mode.
~~~~
!!! An arithmetic operand must be of type 'any', 'number' or an enum type.

Просмотреть файл

@ -1,7 +0,0 @@
//// [parserStrictMode6.ts]
"use strict";
eval++;
//// [parserStrictMode6.js]
"use strict";
eval++;

Просмотреть файл

@ -1,6 +1,8 @@
==== tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode8.ts (1 errors) ====
==== tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode8.ts (2 errors) ====
"use strict";
function eval() {
~~~~
!!! Invalid use of 'eval' in strict mode.
~~~~
!!! Overload signatures must all be ambient or non-ambient.
}

Просмотреть файл

@ -1,9 +0,0 @@
//// [parserStrictMode8.ts]
"use strict";
function eval() {
}
//// [parserStrictMode8.js]
"use strict";
function eval() {
}

Просмотреть файл

@ -0,0 +1,6 @@
==== tests/cases/conformance/parser/ecmascript5/StrictMode/parserStrictMode9.ts (1 errors) ====
"use strict";
var v = function eval() {
~~~~
!!! Invalid use of 'eval' in strict mode.
};

Просмотреть файл

@ -1,9 +0,0 @@
//// [parserStrictMode9.ts]
"use strict";
var v = function eval() {
};
//// [parserStrictMode9.js]
"use strict";
var v = function eval() {
};

Просмотреть файл

@ -1,4 +1,4 @@
==== tests/cases/conformance/scanner/ecmascript5/scanner10.1.1-8gs.ts (1 errors) ====
==== tests/cases/conformance/scanner/ecmascript5/scanner10.1.1-8gs.ts (4 errors) ====
/// Copyright (c) 2012 Ecma International. All rights reserved.
/// Ecma International makes this code available under the terms and conditions set
/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
@ -18,4 +18,10 @@
~~~~~~~~~~~~~
!!! Cannot find name 'NotEarlyError'.
var public = 1;
~~~~~~
!!! Variable declaration expected.
~
!!! Variable declaration expected.
~
!!! Variable declaration expected.

Просмотреть файл

@ -1,25 +0,0 @@
//// [scanner10.1.1-8gs.ts]
/// Copyright (c) 2012 Ecma International. All rights reserved.
/// Ecma International makes this code available under the terms and conditions set
/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
/// "Use Terms"). Any redistribution of this code must retain the above
/// copyright and this notice and otherwise comply with the Use Terms.
/**
* @path ch10/10.1/10.1.1/10.1.1-8gs.js
* @description Strict Mode - Use Strict Directive Prologue is ''use strict';' which appears twice in the code
* @noStrict
* @negative ^((?!NotEarlyError).)*$
*/
"use strict";
"use strict";
throw NotEarlyError;
var public = 1;
//// [scanner10.1.1-8gs.js]
"use strict";
"use strict";
throw NotEarlyError;
var public = 1;

Просмотреть файл

@ -1,4 +1,4 @@
==== tests/cases/conformance/classes/propertyMemberDeclarations/twoAccessorsWithSameName.ts (13 errors) ====
==== tests/cases/conformance/classes/propertyMemberDeclarations/twoAccessorsWithSameName.ts (14 errors) ====
class C {
get x() { return 1; }
~
@ -44,6 +44,8 @@
~
!!! Accessors are only available when targeting ECMAScript 5 and higher.
~
!!! An object literal cannot have multiple get/set accessors with the same name.
~
!!! Duplicate identifier 'x'.
return 1;
}

Просмотреть файл

@ -0,0 +1,5 @@
"use strict";
var x = {
x: 1,
x: 2
}