From 86f290fbb9ee3ef79f5a24f681a066d138ee7d20 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 5 Nov 2014 06:21:58 -0800 Subject: [PATCH 01/33] Initial parser support for destructuring patterns --- src/compiler/binder.ts | 17 +-- src/compiler/checker.ts | 6 + .../diagnosticInformationMap.generated.ts | 2 + src/compiler/diagnosticMessages.json | 8 ++ src/compiler/parser.ts | 113 +++++++++++++++--- src/compiler/types.ts | 21 ++++ 6 files changed, 141 insertions(+), 26 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index f0b2d71ccadfc..f1d6050f8f43b 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -289,7 +289,6 @@ module ts { } declareSymbol(blockScopeContainer.locals, undefined, node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes); } - bindChildren(node, SymbolFlags.BlockScopedVariable, /*isBlockScopeContainer*/ false); } @@ -303,11 +302,17 @@ module ts { bindDeclaration(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes, /*isBlockScopeContainer*/ false); break; case SyntaxKind.VariableDeclaration: - if (node.flags & NodeFlags.BlockScoped) { - bindBlockScopedVariableDeclaration(node); + case SyntaxKind.PatternDeclaration: + if ((node).name) { + if (node.flags & NodeFlags.BlockScoped) { + bindBlockScopedVariableDeclaration(node); + } + else { + bindDeclaration(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes, /*isBlockScopeContainer*/ false); + } } else { - bindDeclaration(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes, /*isBlockScopeContainer*/ false); + bindChildren(node, 0, /*isBlockScopeContainer*/ false); } break; case SyntaxKind.Property: @@ -377,7 +382,6 @@ module ts { bindAnonymousDeclaration(node, SymbolFlags.ValueModule, '"' + removeFileExtension((node).filename) + '"', /*isBlockScopeContainer*/ true); break; } - case SyntaxKind.Block: case SyntaxKind.TryBlock: case SyntaxKind.CatchBlock: @@ -385,9 +389,8 @@ module ts { case SyntaxKind.ForStatement: case SyntaxKind.ForInStatement: case SyntaxKind.SwitchStatement: - bindChildren(node, 0 , true); + bindChildren(node, 0, /*isBlockScopeContainer*/ true); break; - default: var saveParent = parent; parent = node; diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ca4aeda4982d3..3cdc89a97524c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4255,7 +4255,10 @@ module ts { case SyntaxKind.BinaryExpression: return isAssignedInBinaryExpression(node); case SyntaxKind.VariableDeclaration: + case SyntaxKind.PatternDeclaration: return isAssignedInVariableDeclaration(node); + case SyntaxKind.ObjectBindingPattern: + case SyntaxKind.ArrayBindingPattern: case SyntaxKind.ArrayLiteral: case SyntaxKind.ObjectLiteral: case SyntaxKind.PropertyAccess: @@ -8034,6 +8037,9 @@ module ts { break; case SyntaxKind.Parameter: case SyntaxKind.Property: + case SyntaxKind.ObjectBindingPattern: + case SyntaxKind.ArrayBindingPattern: + case SyntaxKind.PatternDeclaration: case SyntaxKind.ArrayLiteral: case SyntaxKind.ObjectLiteral: case SyntaxKind.PropertyAssignment: diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index abf2f78e96660..2f00a727ba1c4 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -122,6 +122,8 @@ module ts { let_declarations_can_only_be_declared_inside_a_block: { code: 1157, category: DiagnosticCategory.Error, key: "'let' declarations can only be declared inside a block." }, Invalid_template_literal_expected: { code: 1158, category: DiagnosticCategory.Error, key: "Invalid template literal; expected '}'" }, Tagged_templates_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1159, category: DiagnosticCategory.Error, key: "Tagged templates are only available when targeting ECMAScript 6 and higher." }, + Property_destructuring_pattern_expected: { code: 1160, category: DiagnosticCategory.Error, key: "Property destructuring pattern expected." }, + Array_element_destructuring_pattern_expected: { code: 1161, category: DiagnosticCategory.Error, key: "Array element destructuring pattern expected." }, Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 6aa34240bcd3f..0269850936d6f 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -479,6 +479,14 @@ "category": "Error", "code": 1159 }, + "Property destructuring pattern expected.": { + "category": "Error", + "code": 1160 + }, + "Array element destructuring pattern expected.": { + "category": "Error", + "code": 1161 + }, "Duplicate identifier '{0}'.": { "category": "Error", diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 1980d0a4014c8..242a60f5bdec0 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -229,6 +229,14 @@ module ts { return children((node).types); case SyntaxKind.ParenType: return child((node).type); + case SyntaxKind.ObjectBindingPattern: + case SyntaxKind.ArrayBindingPattern: + return children((node).declarations); + case SyntaxKind.PatternDeclaration: + return child((node).propertyName) || + child((node).name) || + child((node).pattern) || + child((node).initializer); case SyntaxKind.ArrayLiteral: return children((node).elements); case SyntaxKind.ObjectLiteral: @@ -506,6 +514,7 @@ module ts { case SyntaxKind.Property: case SyntaxKind.EnumMember: case SyntaxKind.PropertyAssignment: + case SyntaxKind.PatternDeclaration: return (parent).initializer === node; case SyntaxKind.ExpressionStatement: case SyntaxKind.IfStatement: @@ -663,24 +672,26 @@ module ts { } enum ParsingContext { - SourceElements, // Elements in source file - ModuleElements, // Elements in module declaration - BlockStatements, // Statements in block - SwitchClauses, // Clauses in switch statement - SwitchClauseStatements, // Statements in switch clause - TypeMembers, // Members in interface or type literal - ClassMembers, // Members in class declaration - EnumMembers, // Members in enum declaration - BaseTypeReferences, // Type references in extends or implements clause - VariableDeclarations, // Variable declarations in variable statement - ArgumentExpressions, // Expressions in argument list - ObjectLiteralMembers, // Members in object literal - ArrayLiteralMembers, // Members in array literal - Parameters, // Parameters in parameter list - TypeParameters, // Type parameters in type parameter list - TypeArguments, // Type arguments in type argument list - TupleElementTypes, // Element types in tuple element type list - Count // Number of parsing contexts + SourceElements, // Elements in source file + ModuleElements, // Elements in module declaration + BlockStatements, // Statements in block + SwitchClauses, // Clauses in switch statement + SwitchClauseStatements, // Statements in switch clause + TypeMembers, // Members in interface or type literal + ClassMembers, // Members in class declaration + EnumMembers, // Members in enum declaration + BaseTypeReferences, // Type references in extends or implements clause + VariableDeclarations, // Variable declarations in variable statement + ObjectBindingDeclarations, // Binding elements in object binding list + ArrayBindingDeclarations, // Binding elements in array binding list + ArgumentExpressions, // Expressions in argument list + ObjectLiteralMembers, // Members in object literal + ArrayLiteralMembers, // Members in array literal + Parameters, // Parameters in parameter list + TypeParameters, // Type parameters in type parameter list + TypeArguments, // Type arguments in type argument list + TupleElementTypes, // Element types in tuple element type list + Count // Number of parsing contexts } enum Tristate { @@ -701,6 +712,8 @@ module ts { case ParsingContext.EnumMembers: return Diagnostics.Enum_member_expected; case ParsingContext.BaseTypeReferences: return Diagnostics.Type_reference_expected; case ParsingContext.VariableDeclarations: return Diagnostics.Variable_declaration_expected; + case ParsingContext.ObjectBindingDeclarations: return Diagnostics.Property_destructuring_pattern_expected; + case ParsingContext.ArrayBindingDeclarations: return Diagnostics.Array_element_destructuring_pattern_expected; case ParsingContext.ArgumentExpressions: return Diagnostics.Argument_expression_expected; case ParsingContext.ObjectLiteralMembers: return Diagnostics.Property_assignment_expected; case ParsingContext.ArrayLiteralMembers: return Diagnostics.Expression_or_comma_expected; @@ -1174,6 +1187,9 @@ module ts { case ParsingContext.BaseTypeReferences: return isIdentifier() && ((token !== SyntaxKind.ExtendsKeyword && token !== SyntaxKind.ImplementsKeyword) || !lookAhead(() => (nextToken(), isIdentifier()))); case ParsingContext.VariableDeclarations: + case ParsingContext.ObjectBindingDeclarations: + case ParsingContext.ArrayBindingDeclarations: + return isIdentifierOrPattern(); case ParsingContext.TypeParameters: return isIdentifier(); case ParsingContext.ArgumentExpressions: @@ -1205,6 +1221,7 @@ module ts { case ParsingContext.ClassMembers: case ParsingContext.EnumMembers: case ParsingContext.ObjectLiteralMembers: + case ParsingContext.ObjectBindingDeclarations: return token === SyntaxKind.CloseBraceToken; case ParsingContext.SwitchClauseStatements: return token === SyntaxKind.CloseBraceToken || token === SyntaxKind.CaseKeyword || token === SyntaxKind.DefaultKeyword; @@ -1220,6 +1237,7 @@ module ts { return token === SyntaxKind.CloseParenToken || token === SyntaxKind.SemicolonToken; case ParsingContext.ArrayLiteralMembers: case ParsingContext.TupleElementTypes: + case ParsingContext.ArrayBindingDeclarations: return token === SyntaxKind.CloseBracketToken; case ParsingContext.Parameters: // Tokens other than ')' and ']' (the latter for index signatures) are here for better error recovery @@ -3356,11 +3374,68 @@ module ts { // DECLARATIONS + function parseBindingDeclaration(flags: NodeFlags, context: ParsingContext): PatternDeclaration { + var node = createNode(SyntaxKind.PatternDeclaration); + node.flags = flags; + if (context === ParsingContext.ObjectBindingDeclarations) { + var id = parseIdentifier(); + if (parseOptional(SyntaxKind.ColonToken)) { + node.propertyName = id; + parseIdentifierOrPatternOfNode(node, flags); + } + else { + node.name = id; + } + } + else { + parseIdentifierOrPatternOfNode(node, flags); + } + return finishNode(node); + } + + function parseBindingList(flags: NodeFlags, context: ParsingContext): NodeArray { + return parseDelimitedList(context, () => parseBindingDeclaration(flags, context), /*allowTrailingComma*/ true); + } + + function parseObjectBindingPattern(flags: NodeFlags): BindingPattern { + var node = createNode(SyntaxKind.ObjectBindingPattern); + node.flags = flags; + parseExpected(SyntaxKind.OpenBraceToken); + node.declarations = parseBindingList(flags, ParsingContext.ObjectBindingDeclarations); + parseExpected(SyntaxKind.CloseBraceToken); + return finishNode(node); + } + + function parseArrayBindingPattern(flags: NodeFlags): BindingPattern { + var node = createNode(SyntaxKind.ArrayBindingPattern); + node.flags = flags; + parseExpected(SyntaxKind.OpenBracketToken); + node.declarations = parseBindingList(flags, ParsingContext.ArrayBindingDeclarations); + parseExpected(SyntaxKind.CloseBracketToken); + return finishNode(node); + } + + function isIdentifierOrPattern() { + return token === SyntaxKind.OpenBraceToken || token === SyntaxKind.OpenBracketToken || isIdentifier(); + } + + function parseIdentifierOrPatternOfNode(node: NameOrPatternNode, flags: NodeFlags) { + if (token === SyntaxKind.OpenBracketToken) { + node.pattern = parseArrayBindingPattern(flags); + } + else if (token === SyntaxKind.OpenBraceToken) { + node.pattern = parseObjectBindingPattern(flags); + } + else { + node.name = parseIdentifier(); + } + } + function parseVariableDeclaration(flags: NodeFlags, noIn?: boolean): VariableDeclaration { var node = createNode(SyntaxKind.VariableDeclaration); node.flags = flags; var errorCountBeforeVariableDeclaration = file.syntacticErrors.length; - node.name = parseIdentifier(); + parseIdentifierOrPatternOfNode(node, flags); node.type = parseTypeAnnotation(); // Issue any initializer-related errors on the equals token diff --git a/src/compiler/types.ts b/src/compiler/types.ts index ead8495773190..b52919edb854b 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -162,6 +162,10 @@ module ts { TupleType, UnionType, ParenType, + // Binding patterns + ObjectBindingPattern, + ArrayBindingPattern, + PatternDeclaration, // Expression ArrayLiteral, ObjectLiteral, @@ -313,10 +317,27 @@ module ts { export interface SignatureDeclaration extends Declaration, ParsedSignature { } export interface VariableDeclaration extends Declaration { + pattern?: BindingPattern; type?: TypeNode; initializer?: Expression; } + export interface BindingPattern extends Node { + declarations: PatternDeclaration[]; + } + + export interface PatternDeclaration extends Declaration { + propertyName?: Identifier; // Binding property name + name?: Identifier; // Declared variable name (pattern = undefined) + pattern?: BindingPattern; // Nested binding pattern (name = undefined) + initializer?: Expression; // Optional initializer + } + + export interface NameOrPatternNode extends Node { + name?: Identifier; + pattern?: BindingPattern; + } + export interface PropertyDeclaration extends VariableDeclaration { } export interface ParameterDeclaration extends VariableDeclaration { } From a01b44080c4c77901889e9c4ed96edd7c4462048 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 6 Nov 2014 14:15:36 -0800 Subject: [PATCH 02/33] Rework tracking and error reporting related to widening of types --- src/compiler/checker.ts | 273 +++++++++++++++++++--------------------- src/compiler/types.ts | 1 + 2 files changed, 127 insertions(+), 147 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3cdc89a97524c..ec565a94edb4a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -123,8 +123,8 @@ module ts { var numberType = createIntrinsicType(TypeFlags.Number, "number"); var booleanType = createIntrinsicType(TypeFlags.Boolean, "boolean"); var voidType = createIntrinsicType(TypeFlags.Void, "void"); - var undefinedType = createIntrinsicType(TypeFlags.Undefined, "undefined"); - var nullType = createIntrinsicType(TypeFlags.Null, "null"); + var undefinedType = createIntrinsicType(TypeFlags.Undefined | TypeFlags.Unwidened, "undefined"); + var nullType = createIntrinsicType(TypeFlags.Null | TypeFlags.Unwidened, "null"); var unknownType = createIntrinsicType(TypeFlags.Any, "unknown"); var resolvingType = createIntrinsicType(TypeFlags.Any, "__resolving__"); @@ -1643,48 +1643,19 @@ module ts { // Use the type of the initializer expression if one is present if (declaration.initializer) { var type = checkAndMarkExpression(declaration.initializer); - // Widening of property assignments is handled by checkObjectLiteral, exclude them here if (declaration.kind !== SyntaxKind.PropertyAssignment) { - var unwidenedType = type; + reportErrorsFromWidening(declaration, type); type = getWidenedType(type); - if (type !== unwidenedType) { - checkImplicitAny(type); - } } return type; } // Rest parameters default to type any[], other parameters default to type any var type = declaration.flags & NodeFlags.Rest ? createArrayType(anyType) : anyType; - checkImplicitAny(type); - return type; - - function checkImplicitAny(type: Type) { - if (!fullTypeCheck || !compilerOptions.noImplicitAny) { - return; - } - // We need to have ended up with 'any', 'any[]', 'any[][]', etc. - if (getInnermostTypeOfNestedArrayTypes(type) !== anyType) { - return; - } - // Ignore privates within ambient contexts; they exist purely for documentative purposes to avoid name clashing. - // (e.g. privates within .d.ts files do not expose type information) - if (isPrivateWithinAmbient(declaration) || (declaration.kind === SyntaxKind.Parameter && isPrivateWithinAmbient(declaration.parent))) { - return; - } - switch (declaration.kind) { - case SyntaxKind.Property: - var diagnostic = Diagnostics.Member_0_implicitly_has_an_1_type; - break; - case SyntaxKind.Parameter: - var diagnostic = declaration.flags & NodeFlags.Rest ? - Diagnostics.Rest_parameter_0_implicitly_has_an_any_type : - Diagnostics.Parameter_0_implicitly_has_an_1_type; - break; - default: - var diagnostic = Diagnostics.Variable_0_implicitly_has_an_1_type; - } - error(declaration, diagnostic, identifierToString(declaration.name), typeToString(type)); + // Report implicit any errors unless this is a private property within an ambient declaration + if (compilerOptions.noImplicitAny && !isPrivateWithinAmbient(declaration) && !(declaration.kind === SyntaxKind.Parameter && isPrivateWithinAmbient(declaration.parent))) { + reportImplicitAnyError(declaration, type); } + return type; } function getTypeOfVariableOrParameterOrProperty(symbol: Symbol): Type { @@ -2671,11 +2642,16 @@ module ts { } } + function getUnwidenedFlagOfTypes(types: Type[]): TypeFlags { + return forEach(types, t => t.flags & TypeFlags.Unwidened) || 0; + } + function createTypeReference(target: GenericType, typeArguments: Type[]): TypeReference { var id = getTypeListId(typeArguments); var type = target.instantiations[id]; if (!type) { - type = target.instantiations[id] = createObjectType(TypeFlags.Reference, target.symbol); + var flags = TypeFlags.Reference | getUnwidenedFlagOfTypes(typeArguments); + type = target.instantiations[id] = createObjectType(flags, target.symbol); type.target = target; type.typeArguments = typeArguments; } @@ -2935,7 +2911,7 @@ module ts { var id = getTypeListId(sortedTypes); var type = unionTypes[id]; if (!type) { - type = unionTypes[id] = createObjectType(TypeFlags.Union); + type = unionTypes[id] = createObjectType(TypeFlags.Union | getUnwidenedFlagOfTypes(sortedTypes)); type.types = sortedTypes; } return type; @@ -3894,76 +3870,107 @@ module ts { return type.flags & TypeFlags.Reference && (type).target === globalArrayType; } - function getInnermostTypeOfNestedArrayTypes(type: Type): Type { - while (isArrayType(type)) { - type = (type).typeArguments[0]; + function getWidenedTypeOfObjectLiteral(type: Type): Type { + var properties = getPropertiesOfObjectType(type); + var members: SymbolTable = {}; + forEach(properties, p => { + var symbol = createSymbol(p.flags | SymbolFlags.Transient, p.name); + symbol.declarations = p.declarations; + symbol.parent = p.parent; + symbol.type = getWidenedType(getTypeOfSymbol(p)); + symbol.target = p; + if (p.valueDeclaration) symbol.valueDeclaration = p.valueDeclaration; + members[symbol.name] = symbol; + }); + var stringIndexType = getIndexTypeOfType(type, IndexKind.String); + var numberIndexType = getIndexTypeOfType(type, IndexKind.Number); + if (stringIndexType) stringIndexType = getWidenedType(stringIndexType); + if (numberIndexType) numberIndexType = getWidenedType(numberIndexType); + return createAnonymousType(type.symbol, members, emptyArray, emptyArray, stringIndexType, numberIndexType); + } + + function getWidenedType(type: Type): Type { + if (type.flags & TypeFlags.Unwidened) { + if (type.flags & (TypeFlags.Undefined | TypeFlags.Null)) { + return anyType; + } + if (type.flags & TypeFlags.Union) { + return getUnionType(map((type).types, t => getWidenedType(t))); + } + if (isTypeOfObjectLiteral(type)) { + return getWidenedTypeOfObjectLiteral(type); + } + if (isArrayType(type)) { + return createArrayType(getWidenedType((type).typeArguments[0])); + } } return type; } - /* If we are widening on a literal, then we may need to the 'node' parameter for reporting purposes */ - function getWidenedType(type: Type, suppressNoImplicitAnyErrors?: boolean): Type { - if (type.flags & (TypeFlags.Undefined | TypeFlags.Null)) { - return anyType; - } + function reportWideningErrorsInType(type: Type): boolean { if (type.flags & TypeFlags.Union) { - return getWidenedTypeOfUnion(type); - } - if (isTypeOfObjectLiteral(type)) { - return getWidenedTypeOfObjectLiteral(type); + var errorReported = false; + forEach((type).types, t => { + if (reportWideningErrorsInType(t)) { + errorReported = true; + } + }); + return errorReported; } if (isArrayType(type)) { - return getWidenedTypeOfArrayLiteral(type); + return reportWideningErrorsInType((type).typeArguments[0]); } - return type; - - function getWidenedTypeOfUnion(type: Type): Type { - return getUnionType(map((type).types, t => getWidenedType(t, suppressNoImplicitAnyErrors))); - } - - function getWidenedTypeOfObjectLiteral(type: Type): Type { - var properties = getPropertiesOfObjectType(type); - if (properties.length) { - var widenedTypes: Type[] = []; - var propTypeWasWidened: boolean = false; - forEach(properties, p => { - var propType = getTypeOfSymbol(p); - var widenedType = getWidenedType(propType); - if (propType !== widenedType) { - propTypeWasWidened = true; - if (!suppressNoImplicitAnyErrors && compilerOptions.noImplicitAny && getInnermostTypeOfNestedArrayTypes(widenedType) === anyType) { - error(p.valueDeclaration, Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, p.name, typeToString(widenedType)); - } + if (isTypeOfObjectLiteral(type)) { + var errorReported = false; + forEach(getPropertiesOfObjectType(type), p => { + var t = getTypeOfSymbol(p); + if (t.flags & TypeFlags.Unwidened) { + if (!reportWideningErrorsInType(t)) { + error(p.valueDeclaration, Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, p.name, typeToString(getWidenedType(t))); } - widenedTypes.push(widenedType); - }); - if (propTypeWasWidened) { - var members: SymbolTable = {}; - var index = 0; - forEach(properties, p => { - var symbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient | p.flags, p.name); - symbol.declarations = p.declarations; - symbol.parent = p.parent; - symbol.type = widenedTypes[index++]; - symbol.target = p; - if (p.valueDeclaration) symbol.valueDeclaration = p.valueDeclaration; - members[symbol.name] = symbol; - }); - var stringIndexType = getIndexTypeOfType(type, IndexKind.String); - var numberIndexType = getIndexTypeOfType(type, IndexKind.Number); - if (stringIndexType) stringIndexType = getWidenedType(stringIndexType); - if (numberIndexType) numberIndexType = getWidenedType(numberIndexType); - type = createAnonymousType(type.symbol, members, emptyArray, emptyArray, stringIndexType, numberIndexType); + errorReported = true; } - } - return type; + }); + return errorReported; } + return false; + } - function getWidenedTypeOfArrayLiteral(type: Type): Type { - var elementType = (type).typeArguments[0]; - var widenedType = getWidenedType(elementType, suppressNoImplicitAnyErrors); - type = elementType !== widenedType ? createArrayType(widenedType) : type; - return type; + function reportImplicitAnyError(declaration: Declaration, type: Type) { + var typeAsString = typeToString(getWidenedType(type)); + switch (declaration.kind) { + case SyntaxKind.Property: + var diagnostic = Diagnostics.Member_0_implicitly_has_an_1_type; + break; + case SyntaxKind.Parameter: + var diagnostic = declaration.flags & NodeFlags.Rest ? + Diagnostics.Rest_parameter_0_implicitly_has_an_any_type : + Diagnostics.Parameter_0_implicitly_has_an_1_type; + break; + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.Method: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + case SyntaxKind.FunctionExpression: + case SyntaxKind.ArrowFunction: + if (!declaration.name) { + error(declaration, Diagnostics.Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type, typeAsString); + return; + } + var diagnostic = Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type; + break; + default: + var diagnostic = Diagnostics.Variable_0_implicitly_has_an_1_type; + } + error(declaration, diagnostic, identifierToString(declaration.name), typeAsString); + } + + function reportErrorsFromWidening(declaration: Declaration, type: Type) { + if (fullTypeCheck && compilerOptions.noImplicitAny && type.flags & TypeFlags.Unwidened) { + // Report implicit any error within type if possible, otherwise report error on declaration + if (!reportWideningErrorsInType(type)) { + reportImplicitAnyError(declaration, type); + } } } @@ -4944,11 +4951,13 @@ module ts { var members = node.symbol.members; var properties: SymbolTable = {}; var contextualType = getContextualType(node); + var typeFlags: TypeFlags; for (var id in members) { if (hasProperty(members, id)) { var member = members[id]; if (member.flags & SymbolFlags.Property) { var type = checkExpression((member.declarations[0]).initializer, contextualMapper); + typeFlags |= type.flags; var prop = createSymbol(SymbolFlags.Property | SymbolFlags.Transient | member.flags, member.name); prop.declarations = member.declarations; prop.parent = member.parent; @@ -4978,7 +4987,9 @@ module ts { } var stringIndexType = getIndexType(IndexKind.String); var numberIndexType = getIndexType(IndexKind.Number); - return createAnonymousType(node.symbol, properties, emptyArray, emptyArray, stringIndexType, numberIndexType); + var result = createAnonymousType(node.symbol, properties, emptyArray, emptyArray, stringIndexType, numberIndexType); + result.flags |= (typeFlags & TypeFlags.Unwidened); + return result; function getIndexType(kind: IndexKind) { if (contextualType && contextualTypeHasIndexSignature(contextualType, kind)) { @@ -5673,7 +5684,7 @@ module ts { var exprType = checkExpression(node.operand); var targetType = getTypeFromTypeNode(node.type); if (fullTypeCheck && targetType !== unknownType) { - var widenedType = getWidenedType(exprType, /*supressNoImplicitAnyErrors*/ true); + var widenedType = getWidenedType(exprType); if (!(isTypeAssignableTo(targetType, widenedType))) { checkTypeAssignableTo(exprType, targetType, node, Diagnostics.Neither_type_0_nor_type_1_is_assignable_to_the_other); } @@ -5704,48 +5715,26 @@ module ts { function getReturnTypeFromBody(func: FunctionDeclaration, contextualMapper?: TypeMapper): Type { var contextualSignature = getContextualSignature(func); if (func.body.kind !== SyntaxKind.FunctionBlock) { - var unwidenedType = checkAndMarkExpression(func.body, contextualMapper); - var widenedType = getWidenedType(unwidenedType); - - if (fullTypeCheck && compilerOptions.noImplicitAny && !contextualSignature && widenedType !== unwidenedType && getInnermostTypeOfNestedArrayTypes(widenedType) === anyType) { - error(func, Diagnostics.Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type, typeToString(widenedType)); - } - - return widenedType; + var type = checkAndMarkExpression(func.body, contextualMapper); } - - // Aggregate the types of expressions within all the return statements. - var types = checkAndAggregateReturnExpressionTypes(func.body, contextualMapper); - - // Try to return the best common type if we have any return expressions. - if (types.length > 0) { + else { + // Aggregate the types of expressions within all the return statements. + var types = checkAndAggregateReturnExpressionTypes(func.body, contextualMapper); + if (types.length === 0) { + return voidType; + } // When return statements are contextually typed we allow the return type to be a union type. Otherwise we require the // return expressions to have a best common supertype. - var commonType = contextualSignature ? getUnionType(types) : getCommonSupertype(types); - if (!commonType) { + var type = contextualSignature ? getUnionType(types) : getCommonSupertype(types); + if (!type) { error(func, Diagnostics.No_best_common_type_exists_among_return_expressions); - return unknownType; } - - var widenedType = getWidenedType(commonType); - - // Check and report for noImplicitAny if the best common type implicitly gets widened to an 'any'/arrays-of-'any' type. - if (fullTypeCheck && compilerOptions.noImplicitAny && !contextualSignature && widenedType !== commonType && getInnermostTypeOfNestedArrayTypes(widenedType) === anyType) { - var typeName = typeToString(widenedType); - - if (func.name) { - error(func, Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type, identifierToString(func.name), typeName); - } - else { - error(func, Diagnostics.Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type, typeName); - } - } - - return widenedType; } - - return voidType; + if (!contextualSignature) { + reportErrorsFromWidening(func, type); + } + return getWidenedType(type); } /// Returns a set of types relating to every return expression relating to a function block. @@ -6946,20 +6935,10 @@ module ts { checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, getTypeFromTypeNode(node.type)); } - // If there is no body and no explicit return type, then report an error. - if (fullTypeCheck && compilerOptions.noImplicitAny && !node.body && !node.type) { - // Ignore privates within ambient contexts; they exist purely for documentative purposes to avoid name clashing. - // (e.g. privates within .d.ts files do not expose type information) - if (!isPrivateWithinAmbient(node)) { - var typeName = typeToString(anyType); - - if (node.name) { - error(node, Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type, identifierToString(node.name), typeName); - } - else { - error(node, Diagnostics.Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type, typeName); - } - } + // Report an implicit any error if there is no body, no explicit return type, and node is not a private method + // in an ambient context + if (compilerOptions.noImplicitAny && !node.body && !node.type && !isPrivateWithinAmbient(node)) { + reportImplicitAnyError(node, anyType); } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b52919edb854b..b4ca7f810b52e 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -950,6 +950,7 @@ module ts { Union = 0x00004000, // Union Anonymous = 0x00008000, // Anonymous FromSignature = 0x00010000, // Created for signature assignment check + Unwidened = 0x00020000, // Unwidened type (is or contains Undefined or Null type) Intrinsic = Any | String | Number | Boolean | Void | Undefined | Null, StringLike = String | StringLiteral, From 3d3212b8aa7536ec59b03cb8c253cb3b0e8e0461 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 7 Nov 2014 06:50:19 -0800 Subject: [PATCH 03/33] Adding binding patterns to declaration names --- src/compiler/checker.ts | 20 ++++++++++++++++---- src/compiler/parser.ts | 23 ++++++++++------------- src/compiler/types.ts | 17 +++++------------ 3 files changed, 31 insertions(+), 29 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d70481184fc02..62d25eb227ce4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3974,7 +3974,7 @@ module ts { default: var diagnostic = Diagnostics.Variable_0_implicitly_has_an_1_type; } - error(declaration, diagnostic, identifierToString(declaration.name), typeAsString); + error(declaration, diagnostic, declarationNameToString(declaration.name), typeAsString); } function reportErrorsFromWidening(declaration: Declaration, type: Type) { @@ -6339,11 +6339,15 @@ module ts { // TODO: Check multiple declarations are identical } + // TODO(andersh): Support destructuring function checkParameter(parameterDeclaration: ParameterDeclaration) { + if (isBindingPattern(parameterDeclaration.name)) { + return; + } checkVariableDeclaration(parameterDeclaration); if (fullTypeCheck) { - checkCollisionWithIndexVariableInGeneratedCode(parameterDeclaration, parameterDeclaration.name); + checkCollisionWithIndexVariableInGeneratedCode(parameterDeclaration, parameterDeclaration.name); if (parameterDeclaration.flags & (NodeFlags.Public | NodeFlags.Private | NodeFlags.Protected) && !(parameterDeclaration.parent.kind === SyntaxKind.Constructor && (parameterDeclaration.parent).body)) { @@ -7005,7 +7009,7 @@ module ts { } forEach(node.parameters, p => { - if (p.name && p.name.text === argumentsSymbol.name) { + if (p.name && !isBindingPattern(p.name) && (p.name).text === argumentsSymbol.name) { error(p, Diagnostics.Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters); } }); @@ -7207,7 +7211,7 @@ module ts { if (node.initializer && (node.flags & NodeFlags.BlockScoped) === 0) { var symbol = getSymbolOfNode(node); if (symbol.flags & SymbolFlags.FunctionScopedVariable) { - var localDeclarationSymbol = resolveName(node, node.name.text, SymbolFlags.Variable, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined); + var localDeclarationSymbol = resolveName(node, (node.name).text, SymbolFlags.Variable, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined); if (localDeclarationSymbol && localDeclarationSymbol !== symbol && localDeclarationSymbol.flags & SymbolFlags.BlockScopedVariable) { if (getDeclarationFlagsFromSymbol(localDeclarationSymbol) & NodeFlags.Const) { error(node, Diagnostics.Cannot_redeclare_block_scoped_variable_0, symbolToString(localDeclarationSymbol)); @@ -7217,7 +7221,15 @@ module ts { } } + function isBindingPattern(name: DeclarationName) { + return name.kind === SyntaxKind.ArrayBindingPattern || name.kind === SyntaxKind.ObjectBindingPattern; + } + + // TODO(andersh): Support destructuring function checkVariableDeclaration(node: VariableDeclaration | PropertyDeclaration) { + if (isBindingPattern(node.name)) { + return; + } checkSourceElement(node.type); checkExportsOnMergedDeclarations(node); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 69c4db9f440df..1ce3b193ea47b 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -240,7 +240,6 @@ module ts { case SyntaxKind.PatternDeclaration: return child((node).propertyName) || child((node).name) || - child((node).pattern) || child((node).initializer); case SyntaxKind.ArrayLiteral: return children((node).elements); @@ -1652,7 +1651,7 @@ module ts { // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a // strict mode FunctionLikeDeclaration or FunctionExpression(13.1) if (isInStrictMode && isEvalOrArgumentsIdentifier(parameter.name)) { - reportInvalidUseInStrictMode(parameter.name); + reportInvalidUseInStrictMode(parameter.name); return; } else if (parameter.flags & NodeFlags.Rest) { @@ -3397,14 +3396,14 @@ module ts { var id = parseIdentifier(); if (parseOptional(SyntaxKind.ColonToken)) { node.propertyName = id; - parseIdentifierOrPatternOfNode(node, flags); + node.name = parseIdentifierOrPattern(flags); } else { node.name = id; } } else { - parseIdentifierOrPatternOfNode(node, flags); + node.name = parseIdentifierOrPattern(flags); } return finishNode(node); } @@ -3435,23 +3434,21 @@ module ts { return token === SyntaxKind.OpenBraceToken || token === SyntaxKind.OpenBracketToken || isIdentifier(); } - function parseIdentifierOrPatternOfNode(node: NameOrPatternNode, flags: NodeFlags) { + function parseIdentifierOrPattern(flags: NodeFlags): Identifier | BindingPattern { if (token === SyntaxKind.OpenBracketToken) { - node.pattern = parseArrayBindingPattern(flags); + return parseArrayBindingPattern(flags); } - else if (token === SyntaxKind.OpenBraceToken) { - node.pattern = parseObjectBindingPattern(flags); - } - else { - node.name = parseIdentifier(); + if (token === SyntaxKind.OpenBraceToken) { + return parseObjectBindingPattern(flags); } + return parseIdentifier(); } function parseVariableDeclaration(flags: NodeFlags, noIn?: boolean): VariableDeclaration { var node = createNode(SyntaxKind.VariableDeclaration); node.flags = flags; var errorCountBeforeVariableDeclaration = file.syntacticErrors.length; - parseIdentifierOrPatternOfNode(node, flags); + node.name = parseIdentifierOrPattern(flags); node.type = parseTypeAnnotation(); // Issue any initializer-related errors on the equals token @@ -3468,7 +3465,7 @@ module ts { 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); + reportInvalidUseInStrictMode(node.name); } return finishNode(node); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 22a0cf40502a9..79084a45583ad 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -305,7 +305,7 @@ module ts { type?: TypeNode; } - export type DeclarationName = Identifier | LiteralExpression | ComputedPropertyName; + export type DeclarationName = Identifier | LiteralExpression | ComputedPropertyName | BindingPattern; export interface Declaration extends Node { name?: DeclarationName; @@ -323,8 +323,7 @@ module ts { export interface SignatureDeclaration extends Declaration, ParsedSignature { } export interface VariableDeclaration extends Declaration { - name: Identifier; - pattern?: BindingPattern; + name: Identifier | BindingPattern; type?: TypeNode; initializer?: Expression; } @@ -334,15 +333,9 @@ module ts { } export interface PatternDeclaration extends Declaration { - propertyName?: Identifier; // Binding property name - name?: Identifier; // Declared variable name (pattern = undefined) - pattern?: BindingPattern; // Nested binding pattern (name = undefined) - initializer?: Expression; // Optional initializer - } - - export interface NameOrPatternNode extends Node { - name?: Identifier; - pattern?: BindingPattern; + propertyName?: Identifier; // Binding property name + name: Identifier | BindingPattern; // Declared variable name (pattern = undefined) + initializer?: Expression; // Optional initializer } export interface PropertyDeclaration extends Declaration { From af00c718ccc553ca059d35b05d1456589b75cb5b Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 10 Nov 2014 13:05:47 -0800 Subject: [PATCH 04/33] End-to-end support for destructuring in variable declarations --- src/compiler/binder.ts | 15 ++- src/compiler/checker.ts | 217 +++++++++++++++++++++++++++------------- src/compiler/emitter.ts | 29 +++++- src/compiler/parser.ts | 103 ++++++++++--------- src/compiler/types.ts | 18 ++-- 5 files changed, 243 insertions(+), 139 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index e06e2cf62aa74..8cdba4c905846 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -340,17 +340,14 @@ module ts { bindDeclaration(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes, /*isBlockScopeContainer*/ false); break; case SyntaxKind.VariableDeclaration: - case SyntaxKind.PatternDeclaration: - if ((node).name) { - if (node.flags & NodeFlags.BlockScoped) { - bindBlockScopedVariableDeclaration(node); - } - else { - bindDeclaration(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes, /*isBlockScopeContainer*/ false); - } + if (isBindingPattern((node).name)) { + bindChildren(node, 0, /*isBlockScopeContainer*/ false); + } + else if (node.flags & NodeFlags.BlockScoped) { + bindBlockScopedVariableDeclaration(node); } else { - bindChildren(node, 0, /*isBlockScopeContainer*/ false); + bindDeclaration(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes, /*isBlockScopeContainer*/ false); } break; case SyntaxKind.Property: diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 62d25eb227ce4..5061c2f0262da 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1628,11 +1628,48 @@ module ts { return classType.typeParameters ? createTypeReference(classType, map(classType.typeParameters, _ => anyType)) : classType; } - function getTypeOfVariableOrPropertyDeclaration(declaration: VariableDeclaration | PropertyDeclaration): Type { + function getTypeOfPropertyOfType(type: Type, name: string): Type { + var prop = getPropertyOfType(type, name); + return prop ? getTypeOfSymbol(prop) : undefined; + } + + function getTypeForBindingElement(declaration: BindingElement): Type { + var pattern = declaration.parent; + var parentType = getTypeForVariableDeclaration(pattern.parent); + if (parentType === unknownType) { + return unknownType; + } + if (!parentType || parentType === anyType) { + if (declaration.initializer) { + return checkExpressionCached(declaration.initializer); + } + return parentType; + } + if (pattern.kind === SyntaxKind.ObjectBindingPattern) { + var name = (declaration.propertyName || declaration.name).text; + var type = getTypeOfPropertyOfType(parentType, name) || + isNumericName(name) && getIndexTypeOfType(parentType, IndexKind.Number) || + getIndexTypeOfType(parentType, IndexKind.String); + } + else { + var index = indexOf(pattern.elements, declaration); + var type = getTypeOfPropertyOfType(parentType, "" + index) || getIndexTypeOfType(parentType, IndexKind.Number); + } + if (!type) { + // Error: Type {0} has no property {1} + return unknownType; + } + return type; + } + + function getTypeForVariableDeclaration(declaration: VariableDeclaration | PropertyDeclaration): Type { // A variable declared in a for..in statement is always of type any if (declaration.parent.kind === SyntaxKind.ForInStatement) { return anyType; } + if (isBindingPattern(declaration.parent)) { + return getTypeForBindingElement(declaration); + } // Use type from type annotation if one is present if (declaration.type) { return getTypeFromTypeNode(declaration.type); @@ -1654,7 +1691,26 @@ module ts { } // Use the type of the initializer expression if one is present if (declaration.initializer) { - var type = checkAndMarkExpression(declaration.initializer); + return checkExpressionCached(declaration.initializer); + } + // No type specified and nothing can be inferred + return undefined; + } + + function getWidenedTypeForVariableDeclaration(declaration: VariableDeclaration | PropertyDeclaration): Type { + var type = getTypeForVariableDeclaration(declaration); + if (type) { + return getWidenedType(type); + } + if (declaration.flags & NodeFlags.Rest) { + return createArrayType(anyType); + } + return anyType; + } + + function getTypeOfVariableOrPropertyDeclaration(declaration: VariableDeclaration | PropertyDeclaration): Type { + var type = getTypeForVariableDeclaration(declaration); + if (type) { if (declaration.kind !== SyntaxKind.PropertyAssignment) { reportErrorsFromWidening(declaration, type); type = getWidenedType(type); @@ -1670,6 +1726,48 @@ module ts { return type; } + //function getTypeOfVariableOrPropertyDeclaration(declaration: VariableDeclaration | PropertyDeclaration): Type { + // // A variable declared in a for..in statement is always of type any + // if (declaration.parent.kind === SyntaxKind.ForInStatement) { + // return anyType; + // } + // // Use type from type annotation if one is present + // if (declaration.type) { + // return getTypeFromTypeNode(declaration.type); + // } + // if (declaration.kind === SyntaxKind.Parameter) { + // var func = declaration.parent; + // // For a parameter of a set accessor, use the type of the get accessor if one is present + // if (func.kind === SyntaxKind.SetAccessor) { + // var getter = getDeclarationOfKind(declaration.parent.symbol, SyntaxKind.GetAccessor); + // if (getter) { + // return getReturnTypeOfSignature(getSignatureFromDeclaration(getter)); + // } + // } + // // Use contextual parameter type if one is available + // var type = getContextuallyTypedParameterType(declaration); + // if (type) { + // return type; + // } + // } + // // Use the type of the initializer expression if one is present + // if (declaration.initializer) { + // var type = checkAndMarkExpression(declaration.initializer); + // if (declaration.kind !== SyntaxKind.PropertyAssignment) { + // reportErrorsFromWidening(declaration, type); + // type = getWidenedType(type); + // } + // return type; + // } + // // Rest parameters default to type any[], other parameters default to type any + // var type = declaration.flags & NodeFlags.Rest ? createArrayType(anyType) : anyType; + // // Report implicit any errors unless this is a private property within an ambient declaration + // if (compilerOptions.noImplicitAny && !isPrivateWithinAmbient(declaration) && !(declaration.kind === SyntaxKind.Parameter && isPrivateWithinAmbient(declaration.parent))) { + // reportImplicitAnyError(declaration, type); + // } + // return type; + //} + function getTypeOfVariableOrParameterOrProperty(symbol: Symbol): Type { var links = getSymbolLinks(symbol); if (!links.type) { @@ -4245,6 +4343,10 @@ module ts { return type; } + function hasInitializer(node: VariableDeclaration): boolean { + return !!(node.initializer || isBindingPattern(node.parent) && hasInitializer(node.parent.parent)); + } + // Check if a given variable is assigned within a given syntax node function isVariableAssignedWithin(symbol: Symbol, node: Node): boolean { var links = getNodeLinks(node); @@ -4273,7 +4375,7 @@ module ts { } function isAssignedInVariableDeclaration(node: VariableDeclaration) { - if (getSymbolOfNode(node) === symbol && node.initializer) { + if (!isBindingPattern(node.name) && getSymbolOfNode(node) === symbol && hasInitializer(node)) { return true; } return forEachChild(node, isAssignedIn); @@ -4284,7 +4386,6 @@ module ts { case SyntaxKind.BinaryExpression: return isAssignedInBinaryExpression(node); case SyntaxKind.VariableDeclaration: - case SyntaxKind.PatternDeclaration: return isAssignedInVariableDeclaration(node); case SyntaxKind.ObjectBindingPattern: case SyntaxKind.ArrayBindingPattern: @@ -5743,7 +5844,7 @@ module ts { function getReturnTypeFromBody(func: FunctionLikeDeclaration, contextualMapper?: TypeMapper): Type { var contextualSignature = getContextualSignature(func); if (func.body.kind !== SyntaxKind.FunctionBlock) { - var type = checkAndMarkExpression(func.body, contextualMapper); + var type = checkExpressionCached(func.body, contextualMapper); } else { // Aggregate the types of expressions within all the return statements. @@ -5772,7 +5873,7 @@ module ts { forEachReturnStatement(body, returnStatement => { var expr = returnStatement.expression; if (expr) { - var type = checkAndMarkExpression(expr, contextualMapper); + var type = checkExpressionCached(expr, contextualMapper); if (!contains(aggregatedTypes, type)) { aggregatedTypes.push(type); } @@ -6225,10 +6326,12 @@ module ts { return result; } - function checkAndMarkExpression(node: Expression, contextualMapper?: TypeMapper): Type { - var result = checkExpression(node, contextualMapper); - getNodeLinks(node).flags |= NodeCheckFlags.TypeChecked; - return result; + function checkExpressionCached(node: Expression, contextualMapper?: TypeMapper): Type { + var links = getNodeLinks(node); + if (!links.resolvedType) { + links.resolvedType = checkExpression(node, contextualMapper); + } + return links.resolvedType; } // Checks an expression and returns its type. The contextualMapper parameter serves two purposes: When @@ -7221,53 +7324,40 @@ module ts { } } - function isBindingPattern(name: DeclarationName) { - return name.kind === SyntaxKind.ArrayBindingPattern || name.kind === SyntaxKind.ObjectBindingPattern; - } - - // TODO(andersh): Support destructuring function checkVariableDeclaration(node: VariableDeclaration | PropertyDeclaration) { if (isBindingPattern(node.name)) { + forEach((node.name).elements, e => { + if (e.kind === SyntaxKind.VariableDeclaration) { + checkVariableDeclaration(e); + } + }); + if (node.initializer) { + checkTypeAssignableTo(checkExpressionCached(node.initializer), getWidenedTypeForVariableDeclaration(node), node, /*headMessage*/ undefined); + } return; } checkSourceElement(node.type); - checkExportsOnMergedDeclarations(node); - - if (fullTypeCheck) { - var symbol = getSymbolOfNode(node); - - var typeOfValueDeclaration = getTypeOfVariableOrParameterOrProperty(symbol); - var type: Type; - var useTypeFromValueDeclaration = node === symbol.valueDeclaration; - if (useTypeFromValueDeclaration) { - type = typeOfValueDeclaration; + var symbol = getSymbolOfNode(node); + var type = getTypeOfVariableOrParameterOrProperty(symbol); + if (node === symbol.valueDeclaration) { + if (node.initializer) { + checkTypeAssignableTo(checkExpressionCached(node.initializer), type, node, /*headMessage*/ undefined); } - else { - type = getTypeOfVariableOrPropertyDeclaration(node); + } + else { + var declarationType = getWidenedTypeForVariableDeclaration(node); + if (type !== unknownType && declarationType !== unknownType && !isTypeIdenticalTo(type, declarationType)) { + error(node.name, Diagnostics.Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2, declarationNameToString(node.name), typeToString(type), typeToString(declarationType)); } - - if (node.initializer) { - if (!(getNodeLinks(node.initializer).flags & NodeCheckFlags.TypeChecked)) { - // Use default messages - checkTypeAssignableTo(checkAndMarkExpression(node.initializer), type, node, /*headMessage*/ undefined); - } - //TODO(jfreeman): Check that it is not a computed property - checkCollisionWithConstDeclarations(node); - } - - checkCollisionWithCapturedSuperVariable(node, node.name); - checkCollisionWithCapturedThisVariable(node, node.name); - checkCollisionWithRequireExportsInGeneratedCode(node, node.name); - if (!useTypeFromValueDeclaration) { - // TypeScript 1.0 spec (April 2014): 5.1 - // Multiple declarations for the same variable name in the same declaration space are permitted, - // provided that each declaration associates the same type with the variable. - if (typeOfValueDeclaration !== unknownType && type !== unknownType && !isTypeIdenticalTo(typeOfValueDeclaration, type)) { - error(node.name, Diagnostics.Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2, declarationNameToString(node.name), typeToString(typeOfValueDeclaration), typeToString(type)); - } + checkTypeAssignableTo(checkExpressionCached(node.initializer), declarationType, node, /*headMessage*/ undefined); } } + checkExportsOnMergedDeclarations(node); + checkCollisionWithConstDeclarations(node); + checkCollisionWithCapturedSuperVariable(node, node.name); + checkCollisionWithCapturedThisVariable(node, node.name); + checkCollisionWithRequireExportsInGeneratedCode(node, node.name); } function checkVariableStatement(node: VariableStatement) { @@ -7345,34 +7435,28 @@ module ts { // TODO: Check that target label is valid } + function isGetAccessorWithAnnotatatedSetAccessor(node: FunctionLikeDeclaration) { + return !!(node.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(getDeclarationOfKind(node.symbol, SyntaxKind.SetAccessor))); + } + function checkReturnStatement(node: ReturnStatement) { - if (node.expression && !(getNodeLinks(node.expression).flags & NodeCheckFlags.TypeChecked)) { + if (node.expression) { var func = getContainingFunction(node); if (func) { + var returnType = getReturnTypeOfSignature(getSignatureFromDeclaration(func)); + var exprType = checkExpressionCached(node.expression); if (func.kind === SyntaxKind.SetAccessor) { - if (node.expression) { - error(node.expression, Diagnostics.Setters_cannot_return_a_value); - } + error(node.expression, Diagnostics.Setters_cannot_return_a_value); } else { - var returnType = getReturnTypeOfSignature(getSignatureFromDeclaration(func)); - // do assignability check only if we short circuited in determining return type - // - function has explicit type annotation - // - function is getter with no type annotation and setter parameter type is used - // - function is a constructor (will be special cased below) - var checkAssignability = - func.type || - (func.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(getDeclarationOfKind(func.symbol, SyntaxKind.SetAccessor))); - if (checkAssignability) { - checkTypeAssignableTo(checkExpression(node.expression), returnType, node.expression, /*headMessage*/ undefined); - } - else if (func.kind == SyntaxKind.Constructor) { - // constructor doesn't have explicit return type annotation and yet its return type is known - declaring type - // handle constructors and issue specialized error message for them. - if (!isTypeAssignableTo(checkExpression(node.expression), returnType)) { + if (func.kind === SyntaxKind.Constructor) { + if (!isTypeAssignableTo(exprType, returnType)) { error(node.expression, Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class); } } + else if (func.type || isGetAccessorWithAnnotatatedSetAccessor(func)) { + checkTypeAssignableTo(exprType, returnType, node.expression, /*headMessage*/ undefined); + } } } } @@ -8201,7 +8285,6 @@ module ts { case SyntaxKind.Property: case SyntaxKind.ObjectBindingPattern: case SyntaxKind.ArrayBindingPattern: - case SyntaxKind.PatternDeclaration: case SyntaxKind.ArrayLiteral: case SyntaxKind.ObjectLiteral: case SyntaxKind.PropertyAssignment: diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index f61d4403eece6..122a5a8386e6e 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -990,6 +990,18 @@ module ts { } } + function emitObjectBindingPattern(node: BindingPattern) { + write("{ "); + emitCommaList(node.elements, /*includeTrailingComma*/ true); + write(" }"); + } + + function emitArrayBindingPattern(node: BindingPattern) { + write("["); + emitCommaList(node.elements, /*includeTrailingComma*/ true); + write("]"); + } + function emitArrayLiteral(node: ArrayLiteral) { if (node.flags & NodeFlags.MultiLine) { write("["); @@ -1437,7 +1449,16 @@ module ts { function emitVariableDeclaration(node: VariableDeclaration) { emitLeadingComments(node); - emitModuleMemberName(node); + if (node.propertyName) { + emit(node.propertyName); + write(": "); + } + if (node.name.kind === SyntaxKind.Identifier) { + emitModuleMemberName(node); + } + else { + emit(node.name); + } emitOptional(" = ", node.initializer); emitTrailingComments(node); } @@ -2207,11 +2228,9 @@ module ts { if (!node) { return; } - if (node.flags & NodeFlags.Ambient) { return emitPinnedOrTripleSlashComments(node); } - switch (node.kind) { case SyntaxKind.Identifier: return emitIdentifier(node); @@ -2244,6 +2263,10 @@ module ts { return emitTemplateSpan(node); case SyntaxKind.QualifiedName: return emitPropertyAccess(node); + case SyntaxKind.ObjectBindingPattern: + return emitObjectBindingPattern(node); + case SyntaxKind.ArrayBindingPattern: + return emitArrayBindingPattern(node); case SyntaxKind.ArrayLiteral: return emitArrayLiteral(node); case SyntaxKind.ObjectLiteral: diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 1ce3b193ea47b..69199b2b75b05 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -236,11 +236,7 @@ module ts { return child((node).type); case SyntaxKind.ObjectBindingPattern: case SyntaxKind.ArrayBindingPattern: - return children((node).declarations); - case SyntaxKind.PatternDeclaration: - return child((node).propertyName) || - child((node).name) || - child((node).initializer); + return children((node).elements); case SyntaxKind.ArrayLiteral: return children((node).elements); case SyntaxKind.ObjectLiteral: @@ -334,7 +330,8 @@ module ts { return child((node).variable) || children((node).statements); case SyntaxKind.VariableDeclaration: - return child((node).name) || + return child((node).propertyName) || + child((node).name) || child((node).type) || child((node).initializer); case SyntaxKind.ClassDeclaration: @@ -421,11 +418,11 @@ module ts { return false; } - export function getContainingFunction(node: Node): SignatureDeclaration { + export function getContainingFunction(node: Node): FunctionLikeDeclaration { while (true) { node = node.parent; if (!node || isAnyFunction(node)) { - return node; + return node; } } } @@ -518,7 +515,6 @@ module ts { case SyntaxKind.Property: case SyntaxKind.EnumMember: case SyntaxKind.PropertyAssignment: - case SyntaxKind.PatternDeclaration: return (parent).initializer === node; case SyntaxKind.ExpressionStatement: case SyntaxKind.IfStatement: @@ -565,6 +561,10 @@ module ts { return SyntaxKind.FirstTemplateToken <= kind && kind <= SyntaxKind.LastTemplateToken; } + export function isBindingPattern(node: Node) { + return node.kind === SyntaxKind.ArrayBindingPattern || node.kind === SyntaxKind.ObjectBindingPattern; + } + export function isInAmbientContext(node: Node): boolean { while (node) { if (node.flags & (NodeFlags.Ambient | NodeFlags.DeclarationFile)) return true; @@ -573,7 +573,6 @@ module ts { return false; } - export function isDeclaration(node: Node): boolean { switch (node.kind) { case SyntaxKind.TypeParameter: @@ -676,26 +675,26 @@ module ts { } enum ParsingContext { - SourceElements, // Elements in source file - ModuleElements, // Elements in module declaration - BlockStatements, // Statements in block - SwitchClauses, // Clauses in switch statement - SwitchClauseStatements, // Statements in switch clause - TypeMembers, // Members in interface or type literal - ClassMembers, // Members in class declaration - EnumMembers, // Members in enum declaration - BaseTypeReferences, // Type references in extends or implements clause - VariableDeclarations, // Variable declarations in variable statement - ObjectBindingDeclarations, // Binding elements in object binding list - ArrayBindingDeclarations, // Binding elements in array binding list - ArgumentExpressions, // Expressions in argument list - ObjectLiteralMembers, // Members in object literal - ArrayLiteralMembers, // Members in array literal - Parameters, // Parameters in parameter list - TypeParameters, // Type parameters in type parameter list - TypeArguments, // Type arguments in type argument list - TupleElementTypes, // Element types in tuple element type list - Count // Number of parsing contexts + SourceElements, // Elements in source file + ModuleElements, // Elements in module declaration + BlockStatements, // Statements in block + SwitchClauses, // Clauses in switch statement + SwitchClauseStatements, // Statements in switch clause + TypeMembers, // Members in interface or type literal + ClassMembers, // Members in class declaration + EnumMembers, // Members in enum declaration + BaseTypeReferences, // Type references in extends or implements clause + VariableDeclarations, // Variable declarations in variable statement + ObjectBindingElements, // Binding elements in object binding list + ArrayBindingElements, // Binding elements in array binding list + ArgumentExpressions, // Expressions in argument list + ObjectLiteralMembers, // Members in object literal + ArrayLiteralMembers, // Members in array literal + Parameters, // Parameters in parameter list + TypeParameters, // Type parameters in type parameter list + TypeArguments, // Type arguments in type argument list + TupleElementTypes, // Element types in tuple element type list + Count // Number of parsing contexts } const enum Tristate { @@ -716,8 +715,8 @@ module ts { case ParsingContext.EnumMembers: return Diagnostics.Enum_member_expected; case ParsingContext.BaseTypeReferences: return Diagnostics.Type_reference_expected; case ParsingContext.VariableDeclarations: return Diagnostics.Variable_declaration_expected; - case ParsingContext.ObjectBindingDeclarations: return Diagnostics.Property_destructuring_pattern_expected; - case ParsingContext.ArrayBindingDeclarations: return Diagnostics.Array_element_destructuring_pattern_expected; + case ParsingContext.ObjectBindingElements: return Diagnostics.Property_destructuring_pattern_expected; + case ParsingContext.ArrayBindingElements: return Diagnostics.Array_element_destructuring_pattern_expected; case ParsingContext.ArgumentExpressions: return Diagnostics.Argument_expression_expected; case ParsingContext.ObjectLiteralMembers: return Diagnostics.Property_assignment_expected; case ParsingContext.ArrayLiteralMembers: return Diagnostics.Expression_or_comma_expected; @@ -1191,9 +1190,10 @@ module ts { case ParsingContext.BaseTypeReferences: return isIdentifier() && ((token !== SyntaxKind.ExtendsKeyword && token !== SyntaxKind.ImplementsKeyword) || !lookAhead(() => (nextToken(), isIdentifier()))); case ParsingContext.VariableDeclarations: - case ParsingContext.ObjectBindingDeclarations: - case ParsingContext.ArrayBindingDeclarations: + case ParsingContext.ObjectBindingElements: return isIdentifierOrPattern(); + case ParsingContext.ArrayBindingElements: + return token === SyntaxKind.CommaToken || isIdentifierOrPattern(); case ParsingContext.TypeParameters: return isIdentifier(); case ParsingContext.ArgumentExpressions: @@ -1225,7 +1225,7 @@ module ts { case ParsingContext.ClassMembers: case ParsingContext.EnumMembers: case ParsingContext.ObjectLiteralMembers: - case ParsingContext.ObjectBindingDeclarations: + case ParsingContext.ObjectBindingElements: return token === SyntaxKind.CloseBraceToken; case ParsingContext.SwitchClauseStatements: return token === SyntaxKind.CloseBraceToken || token === SyntaxKind.CaseKeyword || token === SyntaxKind.DefaultKeyword; @@ -1241,7 +1241,7 @@ module ts { return token === SyntaxKind.CloseParenToken || token === SyntaxKind.SemicolonToken; case ParsingContext.ArrayLiteralMembers: case ParsingContext.TupleElementTypes: - case ParsingContext.ArrayBindingDeclarations: + case ParsingContext.ArrayBindingElements: return token === SyntaxKind.CloseBracketToken; case ParsingContext.Parameters: // Tokens other than ')' and ']' (the latter for index signatures) are here for better error recovery @@ -3389,10 +3389,13 @@ module ts { // DECLARATIONS - function parseBindingDeclaration(flags: NodeFlags, context: ParsingContext): PatternDeclaration { - var node = createNode(SyntaxKind.PatternDeclaration); + function parseBindingElement(kind: SyntaxKind, flags: NodeFlags, context: ParsingContext): BindingElement { + if (context === ParsingContext.ArrayBindingElements && token === SyntaxKind.CommaToken) { + return createNode(SyntaxKind.OmittedExpression); + } + var node = createNode(kind); node.flags = flags; - if (context === ParsingContext.ObjectBindingDeclarations) { + if (context === ParsingContext.ObjectBindingElements) { var id = parseIdentifier(); if (parseOptional(SyntaxKind.ColonToken)) { node.propertyName = id; @@ -3405,18 +3408,19 @@ module ts { else { node.name = parseIdentifierOrPattern(flags); } + node.initializer = parseInitializer(/*inParameter*/ false); return finishNode(node); } - function parseBindingList(flags: NodeFlags, context: ParsingContext): NodeArray { - return parseDelimitedList(context, () => parseBindingDeclaration(flags, context), /*allowTrailingComma*/ true); + function parseBindingList(flags: NodeFlags, context: ParsingContext): NodeArray { + return parseDelimitedList(context, () => parseBindingElement(SyntaxKind.VariableDeclaration, flags, context), /*allowTrailingComma*/ true); } function parseObjectBindingPattern(flags: NodeFlags): BindingPattern { var node = createNode(SyntaxKind.ObjectBindingPattern); node.flags = flags; parseExpected(SyntaxKind.OpenBraceToken); - node.declarations = parseBindingList(flags, ParsingContext.ObjectBindingDeclarations); + node.elements = parseBindingList(flags, ParsingContext.ObjectBindingElements); parseExpected(SyntaxKind.CloseBraceToken); return finishNode(node); } @@ -3425,7 +3429,7 @@ module ts { var node = createNode(SyntaxKind.ArrayBindingPattern); node.flags = flags; parseExpected(SyntaxKind.OpenBracketToken); - node.declarations = parseBindingList(flags, ParsingContext.ArrayBindingDeclarations); + node.elements = parseBindingList(flags, ParsingContext.ArrayBindingElements); parseExpected(SyntaxKind.CloseBracketToken); return finishNode(node); } @@ -3441,7 +3445,13 @@ module ts { if (token === SyntaxKind.OpenBraceToken) { return parseObjectBindingPattern(flags); } - return parseIdentifier(); + var id = parseIdentifier(); + if (isInStrictMode && isEvalOrArgumentsIdentifier(id)) { + // It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code + // and its Identifier is eval or arguments + reportInvalidUseInStrictMode(id); + } + return id; } function parseVariableDeclaration(flags: NodeFlags, noIn?: boolean): VariableDeclaration { @@ -3462,11 +3472,6 @@ module ts { if (!inAmbientContext && !node.initializer && flags & NodeFlags.Const) { grammarErrorOnNode(node, Diagnostics.const_declarations_must_be_initialized); } - 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); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 79084a45583ad..0f75b7f410e20 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -164,7 +164,6 @@ module ts { // Binding patterns ObjectBindingPattern, ArrayBindingPattern, - PatternDeclaration, // Expression ArrayLiteral, ObjectLiteral, @@ -323,20 +322,17 @@ module ts { export interface SignatureDeclaration extends Declaration, ParsedSignature { } export interface VariableDeclaration extends Declaration { - name: Identifier | BindingPattern; - type?: TypeNode; - initializer?: Expression; + propertyName?: Identifier; // Binding property name (in object binding pattern) + name: Identifier | BindingPattern; // Declared variable name + type?: TypeNode; // Optional type annotation + initializer?: Expression; // Optional initializer } export interface BindingPattern extends Node { - declarations: PatternDeclaration[]; + elements: NodeArray; } - export interface PatternDeclaration extends Declaration { - propertyName?: Identifier; // Binding property name - name: Identifier | BindingPattern; // Declared variable name (pattern = undefined) - initializer?: Expression; // Optional initializer - } + export interface BindingElement extends VariableDeclaration { } export interface PropertyDeclaration extends Declaration { type?: TypeNode; @@ -866,7 +862,7 @@ module ts { Prototype = 0x20000000, // Prototype property (no source representation) UnionProperty = 0x40000000, // Property in union type - Enum = RegularEnum | ConstEnum, + Enum = RegularEnum | ConstEnum, Variable = FunctionScopedVariable | BlockScopedVariable, Value = Variable | Property | EnumMember | Function | Class | Enum | ValueModule | Method | GetAccessor | SetAccessor, Type = Class | Interface | Enum | TypeLiteral | ObjectLiteral | TypeParameter | TypeAlias, From 3cda26155820ee2f41ee8d28db1893fcd0d60a00 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 10 Nov 2014 16:01:29 -0800 Subject: [PATCH 05/33] Rudimentary support in language service --- src/services/navigationBar.ts | 3 +++ src/services/services.ts | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index ca06d40fa8800..ba7cf7243e2bf 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -235,6 +235,9 @@ module ts.NavigationBar { return createItem(node, getTextOfNode((node).name), ts.ScriptElementKind.functionElement); case SyntaxKind.VariableDeclaration: + if (isBindingPattern((node).name)) { + break; + } if (node.flags & NodeFlags.Const) { return createItem(node, getTextOfNode((node).name), ts.ScriptElementKind.constantElement); } diff --git a/src/services/services.ts b/src/services/services.ts index d6465084fa49b..fb52dc768594d 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -712,6 +712,8 @@ module ts { // fall through case SyntaxKind.Constructor: case SyntaxKind.VariableStatement: + case SyntaxKind.ObjectBindingPattern: + case SyntaxKind.ArrayBindingPattern: case SyntaxKind.ModuleBlock: case SyntaxKind.FunctionBlock: forEachChild(node, visit); @@ -724,6 +726,10 @@ module ts { } // fall through case SyntaxKind.VariableDeclaration: + if (isBindingPattern((node).name)) { + forEachChild((node).name, visit); + break; + } case SyntaxKind.EnumMember: case SyntaxKind.Property: namedDeclarations.push(node); From bd65f16e06e2e8ac960b99abe3dfb6e9b7058d6d Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 11 Nov 2014 09:24:49 -0800 Subject: [PATCH 06/33] Parser errors for destructuring declarations --- .../diagnosticInformationMap.generated.ts | 2 + src/compiler/diagnosticMessages.json | 8 +++ src/compiler/parser.ts | 24 +++++++-- src/services/navigationBar.ts | 49 +++++++++++++------ 4 files changed, 63 insertions(+), 20 deletions(-) diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 8292565f000af..35d173b4fdf8d 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -124,6 +124,8 @@ module ts { Tagged_templates_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1159, category: DiagnosticCategory.Error, key: "Tagged templates are only available when targeting ECMAScript 6 and higher." }, Property_destructuring_pattern_expected: { code: 1160, category: DiagnosticCategory.Error, key: "Property destructuring pattern expected." }, Array_element_destructuring_pattern_expected: { code: 1161, category: DiagnosticCategory.Error, key: "Array element destructuring pattern expected." }, + A_destructuring_declaration_must_have_an_initializer: { code: 1162, category: DiagnosticCategory.Error, key: "A destructuring declaration must have an initializer." }, + Destructuring_declarations_are_not_allowed_in_ambient_contexts: { code: 1163, category: DiagnosticCategory.Error, key: "Destructuring declarations are not allowed in ambient contexts." }, Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 1859bc9841a8b..97bfba31d0a92 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -487,6 +487,14 @@ "category": "Error", "code": 1161 }, + "A destructuring declaration must have an initializer.": { + "category": "Error", + "code": 1162 + }, + "Destructuring declarations are not allowed in ambient contexts.": { + "category": "Error", + "code": 1163 + }, "Duplicate identifier '{0}'.": { "category": "Error", diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 69199b2b75b05..d48f6489c8e3f 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3466,11 +3466,25 @@ module ts { var initializerFirstTokenLength = scanner.getTextPos() - initializerStart; node.initializer = parseInitializer(/*inParameter*/ false, noIn); - if (inAmbientContext && node.initializer && errorCountBeforeVariableDeclaration === file.syntacticErrors.length) { - grammarErrorAtPos(initializerStart, initializerFirstTokenLength, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts); - } - if (!inAmbientContext && !node.initializer && flags & NodeFlags.Const) { - grammarErrorOnNode(node, Diagnostics.const_declarations_must_be_initialized); + if (errorCountBeforeVariableDeclaration === file.syntacticErrors.length) { + if (inAmbientContext) { + if (isBindingPattern(node.name)) { + grammarErrorOnNode(node, Diagnostics.Destructuring_declarations_are_not_allowed_in_ambient_contexts); + } + else if (node.initializer) { + grammarErrorAtPos(initializerStart, initializerFirstTokenLength, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts); + } + } + else { + if (!node.initializer) { + if (isBindingPattern(node.name)) { + grammarErrorOnNode(node, Diagnostics.A_destructuring_declaration_must_have_an_initializer); + } + else if (flags & NodeFlags.Const) { + grammarErrorOnNode(node, Diagnostics.const_declarations_must_be_initialized); + } + } + } } return finishNode(node); } diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index ba7cf7243e2bf..95d9b3462551c 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -38,26 +38,45 @@ module ts.NavigationBar { return indent; } - - function getChildNodes(nodes: Node[]): Node[] { - var childNodes: Node[] = []; - - for (var i = 0, n = nodes.length; i < n; i++) { - var node = nodes[i]; - if (node.kind === SyntaxKind.ClassDeclaration || - node.kind === SyntaxKind.EnumDeclaration || - node.kind === SyntaxKind.InterfaceDeclaration || - node.kind === SyntaxKind.ModuleDeclaration || - node.kind === SyntaxKind.FunctionDeclaration) { + function getChildNodes(nodes: Node[]): Node[] { + var childNodes: Node[] = []; - childNodes.push(node); - } - else if (node.kind === SyntaxKind.VariableStatement) { - childNodes.push.apply(childNodes, (node).declarations); + function visit(node: Node) { + switch (node.kind) { + case SyntaxKind.VariableStatement: + forEach((node).declarations, visit); + break; + case SyntaxKind.VariableDeclaration: + if (isBindingPattern(node)) { + forEach(((node).name).elements, visit); + break; + } + case SyntaxKind.ClassDeclaration: + case SyntaxKind.EnumDeclaration: + case SyntaxKind.InterfaceDeclaration: + case SyntaxKind.ModuleDeclaration: + case SyntaxKind.FunctionDeclaration: + childNodes.push(node); } } + //for (var i = 0, n = nodes.length; i < n; i++) { + // var node = nodes[i]; + + // if (node.kind === SyntaxKind.ClassDeclaration || + // node.kind === SyntaxKind.EnumDeclaration || + // node.kind === SyntaxKind.InterfaceDeclaration || + // node.kind === SyntaxKind.ModuleDeclaration || + // node.kind === SyntaxKind.FunctionDeclaration) { + + // childNodes.push(node); + // } + // else if (node.kind === SyntaxKind.VariableStatement) { + // childNodes.push.apply(childNodes, (node).declarations); + // } + //} + forEach(nodes, visit); return sortNodes(childNodes); } From a6401bb3cea713132ca45198502150aead43c536 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 12 Nov 2014 12:03:04 -0800 Subject: [PATCH 07/33] Adding destructuring variable declaration error messages --- src/compiler/checker.ts | 18 ++++++++++-------- .../diagnosticInformationMap.generated.ts | 2 ++ src/compiler/diagnosticMessages.json | 8 ++++++++ 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5061c2f0262da..f11bca7c1335e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1646,20 +1646,22 @@ module ts { return parentType; } if (pattern.kind === SyntaxKind.ObjectBindingPattern) { - var name = (declaration.propertyName || declaration.name).text; - var type = getTypeOfPropertyOfType(parentType, name) || - isNumericName(name) && getIndexTypeOfType(parentType, IndexKind.Number) || + var name = declaration.propertyName || declaration.name; + var type = getTypeOfPropertyOfType(parentType, name.text) || + isNumericName(name.text) && getIndexTypeOfType(parentType, IndexKind.Number) || getIndexTypeOfType(parentType, IndexKind.String); + if (!type) { + error(name, Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), declarationNameToString(name)); + } } else { var index = indexOf(pattern.elements, declaration); var type = getTypeOfPropertyOfType(parentType, "" + index) || getIndexTypeOfType(parentType, IndexKind.Number); + if (!type) { + error(declaration, Diagnostics.Type_0_has_no_property_1_and_no_numeric_index_signature, typeToString(parentType), "" + index); + } } - if (!type) { - // Error: Type {0} has no property {1} - return unknownType; - } - return type; + return type || unknownType; } function getTypeForVariableDeclaration(declaration: VariableDeclaration | PropertyDeclaration): Type { diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 35d173b4fdf8d..72a587977916a 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -274,6 +274,8 @@ module ts { Type_argument_candidate_1_is_not_a_valid_type_argument_because_it_is_not_a_supertype_of_candidate_0: { code: 2455, category: DiagnosticCategory.Error, key: "Type argument candidate '{1}' is not a valid type argument because it is not a supertype of candidate '{0}'." }, Type_alias_0_circularly_references_itself: { code: 2456, category: DiagnosticCategory.Error, key: "Type alias '{0}' circularly references itself." }, Type_alias_name_cannot_be_0: { code: 2457, category: DiagnosticCategory.Error, key: "Type alias name cannot be '{0}'" }, + Type_0_has_no_property_1_and_no_string_index_signature: { code: 2458, category: DiagnosticCategory.Error, key: "Type '{0}' has no property '{1}' and no string index signature." }, + Type_0_has_no_property_1_and_no_numeric_index_signature: { code: 2459, category: DiagnosticCategory.Error, key: "Type '{0}' has no property '{1}' and no numeric index signature." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: { code: 4001, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using name '{1}' from private module '{2}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 97bfba31d0a92..7a9deff62eb29 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1092,6 +1092,14 @@ "category": "Error", "code": 2457 }, + "Type '{0}' has no property '{1}' and no string index signature.": { + "category": "Error", + "code": 2458 + }, + "Type '{0}' has no property '{1}' and no numeric index signature.": { + "category": "Error", + "code": 2459 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", From 7840f0d6b87826f68e579c7950304be871f279f5 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 12 Nov 2014 12:32:14 -0800 Subject: [PATCH 08/33] Moving error reporting to getWidenedTypeForVariableDeclaration --- src/compiler/checker.ts | 69 +++++------------------------------------ 1 file changed, 7 insertions(+), 62 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f11bca7c1335e..220505e9d8969 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1699,77 +1699,22 @@ module ts { return undefined; } - function getWidenedTypeForVariableDeclaration(declaration: VariableDeclaration | PropertyDeclaration): Type { + function getWidenedTypeForVariableDeclaration(declaration: VariableDeclaration | PropertyDeclaration, reportErrors?: boolean): Type { var type = getTypeForVariableDeclaration(declaration); if (type) { - return getWidenedType(type); - } - if (declaration.flags & NodeFlags.Rest) { - return createArrayType(anyType); - } - return anyType; - } - - function getTypeOfVariableOrPropertyDeclaration(declaration: VariableDeclaration | PropertyDeclaration): Type { - var type = getTypeForVariableDeclaration(declaration); - if (type) { - if (declaration.kind !== SyntaxKind.PropertyAssignment) { + if (reportErrors) { reportErrorsFromWidening(declaration, type); - type = getWidenedType(type); } - return type; + return declaration.kind !== SyntaxKind.PropertyAssignment ? getWidenedType(type) : type; } - // Rest parameters default to type any[], other parameters default to type any - var type = declaration.flags & NodeFlags.Rest ? createArrayType(anyType) : anyType; - // Report implicit any errors unless this is a private property within an ambient declaration - if (compilerOptions.noImplicitAny && !isPrivateWithinAmbient(declaration) && !(declaration.kind === SyntaxKind.Parameter && isPrivateWithinAmbient(declaration.parent))) { + // Rest parameters default to type any[], other parameters default to type any type = declaration.flags & NodeFlags.Rest ? createArrayType(anyType) : anyType; + // Report implicit any errors unless this is a private property within an ambient declaration + if (reportErrors && compilerOptions.noImplicitAny && !isPrivateWithinAmbient(declaration) && !(declaration.kind === SyntaxKind.Parameter && isPrivateWithinAmbient(declaration.parent))) { reportImplicitAnyError(declaration, type); } return type; } - //function getTypeOfVariableOrPropertyDeclaration(declaration: VariableDeclaration | PropertyDeclaration): Type { - // // A variable declared in a for..in statement is always of type any - // if (declaration.parent.kind === SyntaxKind.ForInStatement) { - // return anyType; - // } - // // Use type from type annotation if one is present - // if (declaration.type) { - // return getTypeFromTypeNode(declaration.type); - // } - // if (declaration.kind === SyntaxKind.Parameter) { - // var func = declaration.parent; - // // For a parameter of a set accessor, use the type of the get accessor if one is present - // if (func.kind === SyntaxKind.SetAccessor) { - // var getter = getDeclarationOfKind(declaration.parent.symbol, SyntaxKind.GetAccessor); - // if (getter) { - // return getReturnTypeOfSignature(getSignatureFromDeclaration(getter)); - // } - // } - // // Use contextual parameter type if one is available - // var type = getContextuallyTypedParameterType(declaration); - // if (type) { - // return type; - // } - // } - // // Use the type of the initializer expression if one is present - // if (declaration.initializer) { - // var type = checkAndMarkExpression(declaration.initializer); - // if (declaration.kind !== SyntaxKind.PropertyAssignment) { - // reportErrorsFromWidening(declaration, type); - // type = getWidenedType(type); - // } - // return type; - // } - // // Rest parameters default to type any[], other parameters default to type any - // var type = declaration.flags & NodeFlags.Rest ? createArrayType(anyType) : anyType; - // // Report implicit any errors unless this is a private property within an ambient declaration - // if (compilerOptions.noImplicitAny && !isPrivateWithinAmbient(declaration) && !(declaration.kind === SyntaxKind.Parameter && isPrivateWithinAmbient(declaration.parent))) { - // reportImplicitAnyError(declaration, type); - // } - // return type; - //} - function getTypeOfVariableOrParameterOrProperty(symbol: Symbol): Type { var links = getSymbolLinks(symbol); if (!links.type) { @@ -1784,7 +1729,7 @@ module ts { } // Handle variable, parameter or property links.type = resolvingType; - var type = getTypeOfVariableOrPropertyDeclaration(declaration); + var type = getWidenedTypeForVariableDeclaration(declaration, /*reportErrors*/ true); if (links.type === resolvingType) { links.type = type; } From 850f3cb60962fd292f799b6d8feed33cb614c26a Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 19 Nov 2014 14:42:06 -0800 Subject: [PATCH 09/33] Destructuring parameter declarations --- src/compiler/binder.ts | 30 +++++++--- src/compiler/checker.ts | 119 ++++++++++++++++++++-------------------- src/compiler/parser.ts | 23 ++++---- src/compiler/types.ts | 28 +++++----- 4 files changed, 105 insertions(+), 95 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 8cdba4c905846..67e7dc439c944 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -330,6 +330,10 @@ module ts { bindChildren(node, SymbolFlags.BlockScopedVariable, /*isBlockScopeContainer*/ false); } + function getDestructuringParameterName(node: Declaration) { + return "__" + indexOf((node.parent).parameters, node); + } + function bind(node: Node) { node.parent = parent; switch (node.kind) { @@ -337,7 +341,17 @@ module ts { bindDeclaration(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes, /*isBlockScopeContainer*/ false); break; case SyntaxKind.Parameter: - bindDeclaration(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes, /*isBlockScopeContainer*/ false); + if (isBindingPattern((node).name)) { + if (isBindingPattern(parent)) { + bindChildren(node, 0, /*isBlockScopeContainer*/ false); + } + else { + bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, getDestructuringParameterName(node), /*isBlockScopeContainer*/ false); + } + } + else { + bindDeclaration(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes, /*isBlockScopeContainer*/ false); + } break; case SyntaxKind.VariableDeclaration: if (isBindingPattern((node).name)) { @@ -351,6 +365,8 @@ module ts { } break; case SyntaxKind.Property: + bindDeclaration(node, SymbolFlags.Property | (node.flags & NodeFlags.QuestionMark ? SymbolFlags.Optional : 0), SymbolFlags.PropertyExcludes, /*isBlockScopeContainer*/ false); + break; case SyntaxKind.PropertyAssignment: bindDeclaration(node, SymbolFlags.Property, SymbolFlags.PropertyExcludes, /*isBlockScopeContainer*/ false); break; @@ -358,16 +374,12 @@ module ts { bindDeclaration(node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes, /*isBlockScopeContainer*/ false); break; case SyntaxKind.CallSignature: - bindDeclaration(node, SymbolFlags.CallSignature, 0, /*isBlockScopeContainer*/ false); - break; - case SyntaxKind.Method: - bindDeclaration(node, SymbolFlags.Method, SymbolFlags.MethodExcludes, /*isBlockScopeContainer*/ true); - break; case SyntaxKind.ConstructSignature: - bindDeclaration(node, SymbolFlags.ConstructSignature, 0, /*isBlockScopeContainer*/ true); - break; case SyntaxKind.IndexSignature: - bindDeclaration(node, SymbolFlags.IndexSignature, 0, /*isBlockScopeContainer*/ false); + bindDeclaration(node, SymbolFlags.Signature, 0, /*isBlockScopeContainer*/ false); + break; + case SyntaxKind.Method: + bindDeclaration(node, SymbolFlags.Method | (node.flags & NodeFlags.QuestionMark ? SymbolFlags.Optional : 0), SymbolFlags.MethodExcludes, /*isBlockScopeContainer*/ true); break; case SyntaxKind.FunctionDeclaration: bindDeclaration(node, SymbolFlags.Function, SymbolFlags.FunctionExcludes, /*isBlockScopeContainer*/ true); diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 220505e9d8969..b1a0b4ebd1aa0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -741,17 +741,6 @@ module ts { members, callSignatures, constructSignatures, stringIndexType, numberIndexType); } - function isOptionalProperty(propertySymbol: Symbol): boolean { - // class C { - // constructor(public x?) { } - // } - // - // x is an optional parameter, but it is a required property. - return propertySymbol.valueDeclaration && - propertySymbol.valueDeclaration.flags & NodeFlags.QuestionMark && - propertySymbol.valueDeclaration.kind !== SyntaxKind.Parameter; - } - function forEachSymbolTableInScope(enclosingDeclaration: Node, callback: (symbolTable: SymbolTable) => T): T { var result: T; for (var location = enclosingDeclaration; location; location = location.parent) { @@ -1366,7 +1355,7 @@ module ts { var signatures = getSignaturesOfType(t, SignatureKind.Call); for (var j = 0; j < signatures.length; j++) { buildSymbolDisplay(p, writer); - if (isOptionalProperty(p)) { + if (p.flags & SymbolFlags.Optional) { writePunctuation(writer, SyntaxKind.QuestionToken); } buildSignatureDisplay(signatures[j], writer, enclosingDeclaration, globalFlagsToPass, typeStack); @@ -1376,7 +1365,7 @@ module ts { } else { buildSymbolDisplay(p, writer); - if (isOptionalProperty(p)) { + if (p.flags & SymbolFlags.Optional) { writePunctuation(writer, SyntaxKind.QuestionToken); } writePunctuation(writer, SyntaxKind.ColonToken); @@ -1699,6 +1688,31 @@ module ts { return undefined; } + function getTypeFromBindingElement(element: BindingElement): Type { + if (element.initializer) { + return getWidenedType(checkExpressionCached(element.initializer)); + } + if (isBindingPattern(element.name)) { + return getTypeFromBindingPattern(element.name); + } + return anyType; + } + + function getTypeFromBindingPattern(pattern: BindingPattern): Type { + if (pattern.kind === SyntaxKind.ArrayBindingPattern) { + return createTupleType(map(pattern.elements, getTypeFromBindingElement)); + } + var members: SymbolTable = {}; + forEach(pattern.elements, e => { + var flags = SymbolFlags.Property | SymbolFlags.Transient | (e.initializer ? SymbolFlags.Optional : 0); + var name = e.propertyName || e.name; + var symbol = createSymbol(flags, name.text); + symbol.type = getTypeFromBindingElement(e); + members[symbol.name] = symbol; + }); + return createAnonymousType(undefined, members, emptyArray, emptyArray, undefined, undefined); + } + function getWidenedTypeForVariableDeclaration(declaration: VariableDeclaration | PropertyDeclaration, reportErrors?: boolean): Type { var type = getTypeForVariableDeclaration(declaration); if (type) { @@ -1707,6 +1721,9 @@ module ts { } return declaration.kind !== SyntaxKind.PropertyAssignment ? getWidenedType(type) : type; } + if (isBindingPattern(declaration.name)) { + return getTypeFromBindingPattern(declaration.name); + } // Rest parameters default to type any[], other parameters default to type any type = declaration.flags & NodeFlags.Rest ? createArrayType(anyType) : anyType; // Report implicit any errors unless this is a private property within an ambient declaration if (reportErrors && compilerOptions.noImplicitAny && !isPrivateWithinAmbient(declaration) && !(declaration.kind === SyntaxKind.Parameter && isPrivateWithinAmbient(declaration.parent))) { @@ -3528,7 +3545,7 @@ module ts { var sourceProp = getPropertyOfType(source, targetProp.name); if (sourceProp !== targetProp) { if (!sourceProp) { - if (relation === subtypeRelation || !isOptionalProperty(targetProp)) { + if (relation === subtypeRelation || !(targetProp.flags & SymbolFlags.Optional)) { if (reportErrors) { reportError(Diagnostics.Property_0_is_missing_in_type_1, symbolToString(targetProp), typeToString(source)); } @@ -3580,7 +3597,7 @@ module ts { return Ternary.False; } result &= related; - if (isOptionalProperty(sourceProp) && !isOptionalProperty(targetProp)) { + if (sourceProp.flags & SymbolFlags.Optional && !(targetProp.flags & SymbolFlags.Optional)) { // TypeScript 1.0 spec (April 2014): 3.8.3 // S is a subtype of a type T, and T is a supertype of S if ... // S' and T are object types and, for each member M in T.. @@ -3821,7 +3838,7 @@ module ts { } } else { - if (isOptionalProperty(sourceProp) !== isOptionalProperty(targetProp)) { + if ((sourceProp.flags & SymbolFlags.Optional) !== (targetProp.flags & SymbolFlags.Optional)) { return Ternary.False; } } @@ -6389,30 +6406,27 @@ module ts { // TODO: Check multiple declarations are identical } - // TODO(andersh): Support destructuring - function checkParameter(parameterDeclaration: ParameterDeclaration) { - if (isBindingPattern(parameterDeclaration.name)) { + function checkParameter(node: ParameterDeclaration) { + checkVariableDeclaration(node); + if (isBindingPattern(node.name)) { return; } - checkVariableDeclaration(parameterDeclaration); - - if (fullTypeCheck) { - checkCollisionWithIndexVariableInGeneratedCode(parameterDeclaration, parameterDeclaration.name); - - if (parameterDeclaration.flags & (NodeFlags.Public | NodeFlags.Private | NodeFlags.Protected) && - !(parameterDeclaration.parent.kind === SyntaxKind.Constructor && (parameterDeclaration.parent).body)) { - error(parameterDeclaration, Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation); - } - if (parameterDeclaration.flags & NodeFlags.Rest) { - if (!isArrayType(getTypeOfSymbol(parameterDeclaration.symbol))) { - error(parameterDeclaration, Diagnostics.A_rest_parameter_must_be_of_an_array_type); - } + checkCollisionWithIndexVariableInGeneratedCode(node, node.name); + var func = getContainingFunction(node); + if (node.flags & (NodeFlags.Public | NodeFlags.Private | NodeFlags.Protected) && + !(func.kind === SyntaxKind.Constructor && func.body)) { + error(node, Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation); + } + if (node.flags & NodeFlags.Rest) { + if (!isArrayType(getTypeOfSymbol(node.symbol))) { + error(node, Diagnostics.A_rest_parameter_must_be_of_an_array_type); } - else { - if (parameterDeclaration.initializer && !(parameterDeclaration.parent).body) { - error(parameterDeclaration, Diagnostics.A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation); - } + } + if (node.initializer) { + if (!func.body) { + error(node, Diagnostics.A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation); } + checkReferencesInInitializer(node.initializer); } function checkReferencesInInitializer(n: Node): void { @@ -6420,33 +6434,25 @@ module ts { var referencedSymbol = getNodeLinks(n).resolvedSymbol; // check FunctionLikeDeclaration.locals (stores parameters\function local variable) // if it contains entry with a specified name and if this entry matches the resolved symbol - if (referencedSymbol && referencedSymbol !== unknownSymbol && getSymbol(parameterDeclaration.parent.locals, referencedSymbol.name, SymbolFlags.Value) === referencedSymbol) { + if (referencedSymbol && referencedSymbol !== unknownSymbol && getSymbol(func.locals, referencedSymbol.name, SymbolFlags.Value) === referencedSymbol) { if (referencedSymbol.valueDeclaration.kind === SyntaxKind.Parameter) { - if (referencedSymbol.valueDeclaration === parameterDeclaration) { - error(n, Diagnostics.Parameter_0_cannot_be_referenced_in_its_initializer, declarationNameToString(parameterDeclaration.name)); + if (referencedSymbol.valueDeclaration === node) { + error(n, Diagnostics.Parameter_0_cannot_be_referenced_in_its_initializer, declarationNameToString(node.name)); return; } - var enclosingOrReferencedParameter = - forEach((parameterDeclaration.parent).parameters, p => p === parameterDeclaration || p === referencedSymbol.valueDeclaration ? p : undefined); - - if (enclosingOrReferencedParameter === referencedSymbol.valueDeclaration) { + if (referencedSymbol.valueDeclaration.pos < node.pos) { // legal case - parameter initializer references some parameter strictly on left of current parameter declaration return; } // fall through to error reporting } - - error(n, Diagnostics.Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it, declarationNameToString(parameterDeclaration.name), declarationNameToString(n)); + error(n, Diagnostics.Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it, declarationNameToString(node.name), declarationNameToString(n)); } } else { forEachChild(n, checkReferencesInInitializer); } } - - if (parameterDeclaration.initializer) { - checkReferencesInInitializer(parameterDeclaration.initializer); - } } function checkSignatureDeclaration(node: SignatureDeclaration) { @@ -7075,7 +7081,8 @@ module ts { // - function has implementation (not a signature) // - function has rest parameters // - context is not ambient (otherwise no codegen impact) - if ((node.parent).body && hasRestParameters(node.parent) && !isInAmbientContext(node)) { + var func = getContainingFunction(node); + if (func.body && hasRestParameters(func) && !isInAmbientContext(node)) { error(node, Diagnostics.Duplicate_identifier_i_Compiler_uses_i_to_initialize_rest_parameter); } return; @@ -7122,7 +7129,7 @@ module ts { // no - go up to the next level var current = node; while (current) { - var definedOnCurrentLevel = forEach(symbol.declarations, d => d.parent === current ? d : undefined); + var definedOnCurrentLevel = forEach(symbol.declarations, d => getContainingFunction(d) === current); if (definedOnCurrentLevel) { return; } @@ -7273,11 +7280,7 @@ module ts { function checkVariableDeclaration(node: VariableDeclaration | PropertyDeclaration) { if (isBindingPattern(node.name)) { - forEach((node.name).elements, e => { - if (e.kind === SyntaxKind.VariableDeclaration) { - checkVariableDeclaration(e); - } - }); + forEach((node.name).elements, checkSourceElement); if (node.initializer) { checkTypeAssignableTo(checkExpressionCached(node.initializer), getWidenedTypeForVariableDeclaration(node), node, /*headMessage*/ undefined); } @@ -7308,7 +7311,7 @@ module ts { } function checkVariableStatement(node: VariableStatement) { - forEach(node.declarations, checkVariableDeclaration); + forEach(node.declarations, checkSourceElement); } function checkExpressionStatement(node: ExpressionStatement) { @@ -8184,7 +8187,7 @@ module ts { case SyntaxKind.TryStatement: return checkTryStatement(node); case SyntaxKind.VariableDeclaration: - return Debug.fail("Checker encountered variable declaration"); + return checkVariableDeclaration(node); case SyntaxKind.ClassDeclaration: return checkClassDeclaration(node); case SyntaxKind.InterfaceDeclaration: diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index d48f6489c8e3f..d97737b563242 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -411,6 +411,9 @@ module ts { case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: case SyntaxKind.Constructor: + case SyntaxKind.CallSignature: + case SyntaxKind.ConstructSignature: + case SyntaxKind.IndexSignature: return true; } } @@ -1245,7 +1248,7 @@ module ts { return token === SyntaxKind.CloseBracketToken; case ParsingContext.Parameters: // Tokens other than ')' and ']' (the latter for index signatures) are here for better error recovery - return token === SyntaxKind.CloseParenToken || token === SyntaxKind.CloseBracketToken || token === SyntaxKind.OpenBraceToken; + return token === SyntaxKind.CloseParenToken || token === SyntaxKind.CloseBracketToken /*|| token === SyntaxKind.OpenBraceToken*/; case ParsingContext.TypeArguments: // Tokens other than '>' are here for better error recovery return token === SyntaxKind.GreaterThanToken || token === SyntaxKind.OpenParenToken; @@ -1568,7 +1571,7 @@ module ts { } function isStartOfParameter(): boolean { - return token === SyntaxKind.DotDotDotToken || isIdentifier() || isModifier(token); + return token === SyntaxKind.DotDotDotToken || isIdentifierOrPattern() || isModifier(token); } function parseParameter(flags: NodeFlags = 0): ParameterDeclaration { @@ -1576,8 +1579,11 @@ module ts { node.flags |= parseAndCheckModifiers(ModifierContext.Parameters); if (parseOptional(SyntaxKind.DotDotDotToken)) { node.flags |= NodeFlags.Rest; + node.name = parseIdentifier(); + } + else { + node.name = parseIdentifierOrPattern(node.flags); } - node.name = parseIdentifier(); if (node.name.kind === SyntaxKind.Missing && node.flags === 0 && isModifier(token)) { // in cases like // 'use strict' @@ -1645,16 +1651,7 @@ module ts { for (var i = 0; i < parameterCount; i++) { var parameter = parameters[i]; - // 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) - if (isInStrictMode && isEvalOrArgumentsIdentifier(parameter.name)) { - reportInvalidUseInStrictMode(parameter.name); - return; - } - else if (parameter.flags & NodeFlags.Rest) { + if (parameter.flags & NodeFlags.Rest) { if (i !== (parameterCount - 1)) { grammarErrorOnNode(parameter.name, Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list); return; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 0f75b7f410e20..797c4e9bbd6f4 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -845,22 +845,21 @@ module ts { Constructor = 0x00004000, // Constructor GetAccessor = 0x00008000, // Get accessor SetAccessor = 0x00010000, // Set accessor - CallSignature = 0x00020000, // Call signature - ConstructSignature = 0x00040000, // Construct signature - IndexSignature = 0x00080000, // Index signature - TypeParameter = 0x00100000, // Type parameter - TypeAlias = 0x00200000, // Type alias + Signature = 0x00020000, // Call, construct, or index signature + TypeParameter = 0x00040000, // Type parameter + TypeAlias = 0x00080000, // Type alias // Export markers (see comment in declareModuleMember in binder) - ExportValue = 0x00400000, // Exported value marker - ExportType = 0x00800000, // Exported type marker - ExportNamespace = 0x01000000, // Exported namespace marker - Import = 0x02000000, // Import - Instantiated = 0x04000000, // Instantiated symbol - Merged = 0x08000000, // Merged symbol (created during program binding) - Transient = 0x10000000, // Transient symbol (created during type check) - Prototype = 0x20000000, // Prototype property (no source representation) - UnionProperty = 0x40000000, // Property in union type + ExportValue = 0x00100000, // Exported value marker + ExportType = 0x00200000, // Exported type marker + ExportNamespace = 0x00400000, // Exported namespace marker + Import = 0x00800000, // Import + Instantiated = 0x01000000, // Instantiated symbol + Merged = 0x02000000, // Merged symbol (created during program binding) + Transient = 0x04000000, // Transient symbol (created during type check) + Prototype = 0x08000000, // Prototype property (no source representation) + UnionProperty = 0x10000000, // Property in union type + Optional = 0x20000000, // Optional property Enum = RegularEnum | ConstEnum, Variable = FunctionScopedVariable | BlockScopedVariable, @@ -869,7 +868,6 @@ module ts { Namespace = ValueModule | NamespaceModule, Module = ValueModule | NamespaceModule, Accessor = GetAccessor | SetAccessor, - Signature = CallSignature | ConstructSignature | IndexSignature, // Variables can be redeclared, but can not redeclare a block-scoped declaration with the // same name, or any other value that is not a variable, e.g. ValueModule or Class From 2ed5f418a1715677e567940462312d0406239f63 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 20 Nov 2014 13:45:55 -0800 Subject: [PATCH 10/33] Destructuring of tuple type cannot specify extra variables --- src/compiler/checker.ts | 24 +++++++++++++++---- .../diagnosticInformationMap.generated.ts | 3 ++- src/compiler/diagnosticMessages.json | 6 ++++- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b1a0b4ebd1aa0..a188e720005a1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1644,10 +1644,18 @@ module ts { } } else { - var index = indexOf(pattern.elements, declaration); - var type = getTypeOfPropertyOfType(parentType, "" + index) || getIndexTypeOfType(parentType, IndexKind.Number); - if (!type) { - error(declaration, Diagnostics.Type_0_has_no_property_1_and_no_numeric_index_signature, typeToString(parentType), "" + index); + if (getPropertyOfType(parentType, "0")) { + var propName = "" + indexOf(pattern.elements, declaration); + var type = getTypeOfPropertyOfType(parentType, propName); + if (!type) { + error(declaration, Diagnostics.Type_0_has_no_property_1, typeToString(parentType), propName); + } + } + else { + var type = getIndexTypeOfType(parentType, IndexKind.Number); + if (!type) { + error(declaration, Diagnostics.Type_0_has_no_numeric_index_signature, typeToString(parentType)); + } } } return type || unknownType; @@ -4775,7 +4783,13 @@ module ts { return getTypeFromTypeNode(declaration.type); } if (declaration.kind === SyntaxKind.Parameter) { - return getContextuallyTypedParameterType(declaration); + var type = getContextuallyTypedParameterType(declaration); + if (type) { + return type; + } + } + if (isBindingPattern(declaration.name)) { + return getTypeFromBindingPattern(declaration.name); } } return undefined; diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 72a587977916a..ffb09786c7e2c 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -275,7 +275,8 @@ module ts { Type_alias_0_circularly_references_itself: { code: 2456, category: DiagnosticCategory.Error, key: "Type alias '{0}' circularly references itself." }, Type_alias_name_cannot_be_0: { code: 2457, category: DiagnosticCategory.Error, key: "Type alias name cannot be '{0}'" }, Type_0_has_no_property_1_and_no_string_index_signature: { code: 2458, category: DiagnosticCategory.Error, key: "Type '{0}' has no property '{1}' and no string index signature." }, - Type_0_has_no_property_1_and_no_numeric_index_signature: { code: 2459, category: DiagnosticCategory.Error, key: "Type '{0}' has no property '{1}' and no numeric index signature." }, + Type_0_has_no_property_1: { code: 2459, category: DiagnosticCategory.Error, key: "Type '{0}' has no property '{1}'." }, + Type_0_has_no_numeric_index_signature: { code: 2460, category: DiagnosticCategory.Error, key: "Type '{0}' has no numeric index signature." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: { code: 4001, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using name '{1}' from private module '{2}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 7a9deff62eb29..132117414f7c6 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1096,10 +1096,14 @@ "category": "Error", "code": 2458 }, - "Type '{0}' has no property '{1}' and no numeric index signature.": { + "Type '{0}' has no property '{1}'.": { "category": "Error", "code": 2459 }, + "Type '{0}' has no numeric index signature.": { + "category": "Error", + "code": 2460 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", From d39749ffe5afc25831fff62ba938b679634d351e Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 20 Nov 2014 15:22:28 -0800 Subject: [PATCH 11/33] Adding SyntaxKind.FunctionType/ConstructorType to isAnyFunction --- src/compiler/parser.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index cd3a5ecb05f2d..435957990aec9 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -412,16 +412,18 @@ module ts { export function isAnyFunction(node: Node): boolean { if (node) { switch (node.kind) { - case SyntaxKind.FunctionExpression: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.ArrowFunction: case SyntaxKind.Method: + case SyntaxKind.Constructor: case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: - case SyntaxKind.Constructor: case SyntaxKind.CallSignature: case SyntaxKind.ConstructSignature: case SyntaxKind.IndexSignature: + case SyntaxKind.FunctionType: + case SyntaxKind.ConstructorType: + case SyntaxKind.FunctionExpression: + case SyntaxKind.ArrowFunction: + case SyntaxKind.FunctionDeclaration: return true; } } From 607140bfa334c3da8b71708825c180eb25dda2e8 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 21 Nov 2014 15:36:39 -0800 Subject: [PATCH 12/33] Support for destructuring assignments --- src/compiler/checker.ts | 84 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7d737b9d5aa1e..4e93ea1c157e5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5063,6 +5063,20 @@ module ts { return mapper && mapper !== identityMapper; } + function isAssignmentTarget(node: Node): boolean { + var parent = node.parent; + if (parent.kind === SyntaxKind.BinaryExpression && (parent).operator === SyntaxKind.EqualsToken && (parent).left === node) { + return true; + } + if (parent.kind === SyntaxKind.PropertyAssignment) { + return isAssignmentTarget(parent.parent); + } + if (parent.kind === SyntaxKind.ArrayLiteral) { + return isAssignmentTarget(parent); + } + return false; + } + function checkArrayLiteral(node: ArrayLiteral, contextualMapper?: TypeMapper): Type { var elements = node.elements; if (!elements.length) { @@ -5070,7 +5084,7 @@ module ts { } var elementTypes = map(elements, e => checkExpression(e, contextualMapper)); var contextualType = getContextualType(node); - if (contextualType && contextualTypeIsTupleType(contextualType)) { + if ((contextualType && contextualTypeIsTupleType(contextualType)) || isAssignmentTarget(node)) { return createTupleType(elementTypes); } return createArrayType(getUnionType(elementTypes)); @@ -6340,8 +6354,76 @@ module ts { return booleanType; } + function checkObjectLiteralAssignment(node: ObjectLiteral, sourceType: Type, contextualMapper?: TypeMapper): Type { + var properties = node.properties; + for (var i = 0; i < properties.length; i++) { + var p = properties[i]; + if (p.kind === SyntaxKind.PropertyAssignment || p.kind === SyntaxKind.ShorthandPropertyAssignment) { + // TODO(andersh): Computed property support + var name = ((p).name); + var type = getTypeOfPropertyOfType(sourceType, name.text) || + isNumericName(name.text) && getIndexTypeOfType(sourceType, IndexKind.Number) || + getIndexTypeOfType(sourceType, IndexKind.String); + if (type) { + checkDestructuringAssignment((p).initializer || name, type); + } + else { + error(name, Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(sourceType), declarationNameToString(name)); + } + } + else { + error(p, Diagnostics.Property_assignment_expected); + } + } + return sourceType; + } + + function checkArrayLiteralAssignment(node: ArrayLiteral, sourceType: Type, contextualMapper?: TypeMapper): Type { + var isTupleType = getPropertyOfType(sourceType, "0"); + var elements = node.elements; + for (var i = 0; i < elements.length; i++) { + var e = elements[i]; + if (e.kind !== SyntaxKind.OmittedExpression) { + if (isTupleType) { + var propName = "" + i; + var type = getTypeOfPropertyOfType(sourceType, propName); + if (!type) { + error(e, Diagnostics.Type_0_has_no_property_1, typeToString(sourceType), propName); + } + } + else { + var type = getIndexTypeOfType(sourceType, IndexKind.Number); + if (!type) { + error(e, Diagnostics.Type_0_has_no_numeric_index_signature, typeToString(sourceType)); + } + } + } + if (type) { + checkDestructuringAssignment(e, type, contextualMapper); + } + } + return sourceType; + } + + function checkDestructuringAssignment(target: Expression, sourceType: Type, contextualMapper?: TypeMapper): Type { + if (target.kind === SyntaxKind.ObjectLiteral) { + return checkObjectLiteralAssignment(target, sourceType, contextualMapper); + } + if (target.kind === SyntaxKind.ArrayLiteral) { + return checkArrayLiteralAssignment(target, sourceType, contextualMapper); + } + var targetType = checkExpression(target, contextualMapper); + if (checkReferenceExpression(target, Diagnostics.Invalid_left_hand_side_of_assignment_expression, Diagnostics.Left_hand_side_of_assignment_expression_cannot_be_a_constant)) { + checkTypeAssignableTo(sourceType, targetType, target, /*headMessage*/ undefined); + } + return sourceType; + } + function checkBinaryExpression(node: BinaryExpression, contextualMapper?: TypeMapper) { var operator = node.operator; + if (operator === SyntaxKind.EqualsToken && (node.left.kind === SyntaxKind.ObjectLiteral || node.left.kind === SyntaxKind.ArrayLiteral)) { + return checkDestructuringAssignment(node.left, checkExpression(node.right, contextualMapper), contextualMapper); + } var leftType = checkExpression(node.left, contextualMapper); var rightType = checkExpression(node.right, contextualMapper); switch (operator) { From 38a264005322dfedc7339f7fbb11c21d7eba54b0 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 21 Nov 2014 16:50:44 -0800 Subject: [PATCH 13/33] Propagate node kind in variable/parameter destructuring declarations --- src/compiler/emitter.ts | 4 ++++ src/compiler/parser.ts | 42 ++++++++++++++++++----------------------- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 35c2b2a160e08..7b88bfde451ad 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1534,6 +1534,10 @@ module ts { function emitParameter(node: ParameterDeclaration) { emitLeadingComments(node); + if (node.propertyName) { + emit(node.propertyName); + write(": "); + } emit(node.name); emitTrailingComments(node); } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 435957990aec9..6c99d1ae61e1d 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -198,15 +198,14 @@ module ts { return child((node).name) || child((node).constraint); case SyntaxKind.Parameter: - return child((node).name) || - child((node).type) || - child((node).initializer); case SyntaxKind.Property: case SyntaxKind.PropertyAssignment: case SyntaxKind.ShorthandPropertyAssignment: - return child((node).name) || - child((node).type) || - child((node).initializer); + case SyntaxKind.VariableDeclaration: + return child((node).propertyName) || + child((node).name) || + child((node).type) || + child((node).initializer); case SyntaxKind.FunctionType: case SyntaxKind.ConstructorType: case SyntaxKind.CallSignature: @@ -337,11 +336,6 @@ module ts { case SyntaxKind.CatchBlock: return child((node).variable) || children((node).statements); - case SyntaxKind.VariableDeclaration: - return child((node).propertyName) || - child((node).name) || - child((node).type) || - child((node).initializer); case SyntaxKind.ClassDeclaration: return child((node).name) || children((node).typeParameters) || @@ -1649,7 +1643,7 @@ module ts { node.name = parseIdentifier(); } else { - node.name = parseIdentifierOrPattern(node.flags); + node.name = parseIdentifierOrPattern(SyntaxKind.Parameter, node.flags); } if (node.name.kind === SyntaxKind.Missing && node.flags === 0 && isModifier(token)) { // in cases like @@ -3486,37 +3480,37 @@ module ts { var id = parseIdentifier(); if (parseOptional(SyntaxKind.ColonToken)) { node.propertyName = id; - node.name = parseIdentifierOrPattern(flags); + node.name = parseIdentifierOrPattern(kind, flags); } else { node.name = id; } } else { - node.name = parseIdentifierOrPattern(flags); + node.name = parseIdentifierOrPattern(kind, flags); } node.initializer = parseInitializer(/*inParameter*/ false); return finishNode(node); } - function parseBindingList(flags: NodeFlags, context: ParsingContext): NodeArray { - return parseDelimitedList(context, () => parseBindingElement(SyntaxKind.VariableDeclaration, flags, context), /*allowTrailingComma*/ true); + function parseBindingList(kind: SyntaxKind, flags: NodeFlags, context: ParsingContext): NodeArray { + return parseDelimitedList(context, () => parseBindingElement(kind, flags, context), /*allowTrailingComma*/ true); } - function parseObjectBindingPattern(flags: NodeFlags): BindingPattern { + function parseObjectBindingPattern(kind: SyntaxKind, flags: NodeFlags): BindingPattern { var node = createNode(SyntaxKind.ObjectBindingPattern); node.flags = flags; parseExpected(SyntaxKind.OpenBraceToken); - node.elements = parseBindingList(flags, ParsingContext.ObjectBindingElements); + node.elements = parseBindingList(kind, flags, ParsingContext.ObjectBindingElements); parseExpected(SyntaxKind.CloseBraceToken); return finishNode(node); } - function parseArrayBindingPattern(flags: NodeFlags): BindingPattern { + function parseArrayBindingPattern(kind: SyntaxKind, flags: NodeFlags): BindingPattern { var node = createNode(SyntaxKind.ArrayBindingPattern); node.flags = flags; parseExpected(SyntaxKind.OpenBracketToken); - node.elements = parseBindingList(flags, ParsingContext.ArrayBindingElements); + node.elements = parseBindingList(kind, flags, ParsingContext.ArrayBindingElements); parseExpected(SyntaxKind.CloseBracketToken); return finishNode(node); } @@ -3525,12 +3519,12 @@ module ts { return token === SyntaxKind.OpenBraceToken || token === SyntaxKind.OpenBracketToken || isIdentifier(); } - function parseIdentifierOrPattern(flags: NodeFlags): Identifier | BindingPattern { + function parseIdentifierOrPattern(kind: SyntaxKind, flags: NodeFlags): Identifier | BindingPattern { if (token === SyntaxKind.OpenBracketToken) { - return parseArrayBindingPattern(flags); + return parseArrayBindingPattern(kind, flags); } if (token === SyntaxKind.OpenBraceToken) { - return parseObjectBindingPattern(flags); + return parseObjectBindingPattern(kind, flags); } var id = parseIdentifier(); if (isInStrictMode && isEvalOrArgumentsIdentifier(id)) { @@ -3545,7 +3539,7 @@ module ts { var node = createNode(SyntaxKind.VariableDeclaration); node.flags = flags; var errorCountBeforeVariableDeclaration = file.syntacticErrors.length; - node.name = parseIdentifierOrPattern(flags); + node.name = parseIdentifierOrPattern(SyntaxKind.VariableDeclaration, flags); node.type = parseTypeAnnotation(); // Issue any initializer-related errors on the equals token From 6b96386337972c99d4a23edfa25d9e4cb0e2439e Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 22 Nov 2014 15:38:20 -0800 Subject: [PATCH 14/33] Allow string or numeric literal as property name of object binding Require RHS of array destructuring to be an actual array type (i.e. assignable to any[]) Tighten test for tuple type (previously just required a "0" property) --- src/compiler/checker.ts | 44 +++++++++++-------- .../diagnosticInformationMap.generated.ts | 1 + src/compiler/diagnosticMessages.json | 4 ++ src/compiler/emitter.ts | 19 ++++++-- src/compiler/parser.ts | 13 +++--- 5 files changed, 52 insertions(+), 29 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4e93ea1c157e5..03df66502dd21 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -150,6 +150,8 @@ module ts { var globalRegExpType: ObjectType; var globalTemplateStringsArrayType: ObjectType; + var anyArrayType: Type; + var tupleTypes: Map = {}; var unionTypes: Map = {}; var stringLiteralTypes: Map = {}; @@ -1643,24 +1645,24 @@ module ts { getIndexTypeOfType(parentType, IndexKind.String); if (!type) { error(name, Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), declarationNameToString(name)); + return unknownType; } + return type; } - else { - if (getPropertyOfType(parentType, "0")) { - var propName = "" + indexOf(pattern.elements, declaration); - var type = getTypeOfPropertyOfType(parentType, propName); - if (!type) { - error(declaration, Diagnostics.Type_0_has_no_property_1, typeToString(parentType), propName); - } - } - else { - var type = getIndexTypeOfType(parentType, IndexKind.Number); - if (!type) { - error(declaration, Diagnostics.Type_0_has_no_numeric_index_signature, typeToString(parentType)); - } + if (!isTypeAssignableTo(parentType, anyArrayType)) { + error(pattern, Diagnostics.Type_0_is_not_an_array_type, typeToString(parentType)); + return unknownType; + } + if (isTupleType(parentType)) { + var propName = "" + indexOf(pattern.elements, declaration); + var type = getTypeOfPropertyOfType(parentType, propName); + if (!type) { + error(declaration, Diagnostics.Type_0_has_no_property_1, typeToString(parentType), propName); + return unknownType; } + return type; } - return type || unknownType; + return getIndexTypeOfType(parentType, IndexKind.Number); } function getTypeForVariableDeclaration(declaration: VariableDeclaration | PropertyDeclaration): Type { @@ -1739,7 +1741,8 @@ module ts { if (isBindingPattern(declaration.name)) { return getTypeFromBindingPattern(declaration.name); } - // Rest parameters default to type any[], other parameters default to type any type = declaration.flags & NodeFlags.Rest ? createArrayType(anyType) : anyType; + // Rest parameters default to type any[], other parameters default to type any + type = declaration.flags & NodeFlags.Rest ? anyArrayType : anyType; // Report implicit any errors unless this is a private property within an ambient declaration if (reportErrors && compilerOptions.noImplicitAny && !isPrivateWithinAmbient(declaration) && !(declaration.kind === SyntaxKind.Parameter && isPrivateWithinAmbient(declaration.parent))) { reportImplicitAnyError(declaration, type); @@ -3976,6 +3979,10 @@ module ts { return type.flags & TypeFlags.Reference && (type).target === globalArrayType; } + function isTupleType(type: Type): boolean { + return (type.flags & TypeFlags.Tuple) !== 0; + } + function getWidenedTypeOfObjectLiteral(type: Type): Type { var properties = getPropertiesOfObjectType(type); var members: SymbolTable = {}; @@ -4914,7 +4921,7 @@ module ts { // Return true if the given contextual type is a tuple-like type function contextualTypeIsTupleType(type: Type): boolean { - return !!(type.flags & TypeFlags.Union ? forEach((type).types, t => getPropertyOfObjectType(t, "0")) : getPropertyOfObjectType(type, "0")); + return !!(type.flags & TypeFlags.Union ? forEach((type).types, t => isTupleType(t)) : isTupleType(type)); } // Return true if the given contextual type provides an index signature of the given kind @@ -6379,12 +6386,11 @@ module ts { } function checkArrayLiteralAssignment(node: ArrayLiteral, sourceType: Type, contextualMapper?: TypeMapper): Type { - var isTupleType = getPropertyOfType(sourceType, "0"); var elements = node.elements; for (var i = 0; i < elements.length; i++) { var e = elements[i]; if (e.kind !== SyntaxKind.OmittedExpression) { - if (isTupleType) { + if (isTupleType(sourceType)) { var propName = "" + i; var type = getTypeOfPropertyOfType(sourceType, propName); if (!type) { @@ -9290,12 +9296,12 @@ module ts { globalNumberType = getGlobalType("Number"); globalBooleanType = getGlobalType("Boolean"); globalRegExpType = getGlobalType("RegExp"); - // If we're in ES6 mode, load the TemplateStringsArray. // Otherwise, default to 'unknown' for the purposes of type checking in LS scenarios. globalTemplateStringsArrayType = compilerOptions.target >= ScriptTarget.ES6 ? getGlobalType("TemplateStringsArray") : unknownType; + anyArrayType = createArrayType(anyType); } initializeTypeChecker(); diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 0ab30ca4dcd34..2ff4be92fd266 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -281,6 +281,7 @@ module ts { Type_0_has_no_property_1_and_no_string_index_signature: { code: 2459, category: DiagnosticCategory.Error, key: "Type '{0}' has no property '{1}' and no string index signature." }, Type_0_has_no_property_1: { code: 2460, category: DiagnosticCategory.Error, key: "Type '{0}' has no property '{1}'." }, Type_0_has_no_numeric_index_signature: { code: 2461, category: DiagnosticCategory.Error, key: "Type '{0}' has no numeric index signature." }, + Type_0_is_not_an_array_type: { code: 2462, category: DiagnosticCategory.Error, key: "Type '{0}' is not an array type." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: { code: 4001, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using name '{1}' from private module '{2}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 9a704ea948ea1..e56188eae9f37 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1120,6 +1120,10 @@ "category": "Error", "code": 2461 }, + "Type '{0}' is not an array type.": { + "category": "Error", + "code": 2462 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 7b88bfde451ad..e7df9e9136af5 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1534,11 +1534,22 @@ module ts { function emitParameter(node: ParameterDeclaration) { emitLeadingComments(node); - if (node.propertyName) { - emit(node.propertyName); - write(": "); + if (compilerOptions.target < ScriptTarget.ES6) { + if (isBindingPattern(node.name)) { + write("__" + indexOf((node.parent).parameters, node)); + } + else { + emit(node.name); + } + } + else { + if (node.propertyName) { + emit(node.propertyName); + write(": "); + } + emit(node.name); + //emitOptional(" = ", node.initializer); } - emit(node.name); emitTrailingComments(node); } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 6c99d1ae61e1d..7fd68b9ce0371 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1250,11 +1250,11 @@ module ts { return lookAhead(isClassMemberStart); case ParsingContext.EnumMembers: case ParsingContext.ObjectLiteralMembers: + case ParsingContext.ObjectBindingElements: return isPropertyName(); case ParsingContext.BaseTypeReferences: return isIdentifier() && ((token !== SyntaxKind.ExtendsKeyword && token !== SyntaxKind.ImplementsKeyword) || !lookAhead(() => (nextToken(), isIdentifier()))); case ParsingContext.VariableDeclarations: - case ParsingContext.ObjectBindingElements: return isIdentifierOrPattern(); case ParsingContext.ArrayBindingElements: return token === SyntaxKind.CommaToken || isIdentifierOrPattern(); @@ -3477,13 +3477,14 @@ module ts { var node = createNode(kind); node.flags = flags; if (context === ParsingContext.ObjectBindingElements) { - var id = parseIdentifier(); - if (parseOptional(SyntaxKind.ColonToken)) { - node.propertyName = id; - node.name = parseIdentifierOrPattern(kind, flags); + var id = parsePropertyName(); + if (id.kind === SyntaxKind.Identifier && token !== SyntaxKind.ColonToken) { + node.name = id; } else { - node.name = id; + parseExpected(SyntaxKind.ColonToken); + node.propertyName = id; + node.name = parseIdentifierOrPattern(kind, flags); } } else { From 8ed1f24e573585dc999c7465dbe29087dff0fc71 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 23 Nov 2014 08:12:30 -0800 Subject: [PATCH 15/33] Fine tuning array and tuple type checks in destructuring --- src/compiler/checker.ts | 55 +++++++++---------- .../diagnosticInformationMap.generated.ts | 3 +- src/compiler/diagnosticMessages.json | 6 +- 3 files changed, 28 insertions(+), 36 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 03df66502dd21..00968b255a21e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -242,7 +242,7 @@ module ts { } else { var message = target.flags & SymbolFlags.BlockScopedVariable || source.flags & SymbolFlags.BlockScopedVariable - ? Diagnostics.Cannot_redeclare_block_scoped_variable_0 : Diagnostics.Duplicate_identifier_0; + ? Diagnostics.Cannot_redeclare_block_scoped_variable_0 : Diagnostics.Duplicate_identifier_0; forEach(source.declarations, node => { error(node.name ? node.name : node, message, symbolToString(source)); }); @@ -1257,8 +1257,8 @@ module ts { ts.forEach(type.symbol.declarations, declaration => declaration.flags & NodeFlags.Static)); var isNonLocalFunctionSymbol = !!(type.symbol.flags & SymbolFlags.Function) && (type.symbol.parent || // is exported function symbol - ts.forEach(type.symbol.declarations, declaration => - declaration.parent.kind === SyntaxKind.SourceFile || declaration.parent.kind === SyntaxKind.ModuleBlock)); + ts.forEach(type.symbol.declarations, declaration => + declaration.parent.kind === SyntaxKind.SourceFile || declaration.parent.kind === SyntaxKind.ModuleBlock)); if (isStaticMethodSymbol || isNonLocalFunctionSymbol) { // typeof is allowed only for static/non local functions @@ -1288,7 +1288,7 @@ module ts { if (flags & TypeFormatFlags.InElementType) { writePunctuation(writer, SyntaxKind.OpenParenToken); } - buildSignatureDisplay(resolved.callSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | TypeFormatFlags.WriteArrowStyleSignature , typeStack); + buildSignatureDisplay(resolved.callSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | TypeFormatFlags.WriteArrowStyleSignature, typeStack); if (flags & TypeFormatFlags.InElementType) { writePunctuation(writer, SyntaxKind.CloseParenToken); } @@ -1467,7 +1467,7 @@ module ts { writeSpace(writer); buildTypeDisplay(getReturnTypeOfSignature(signature), writer, enclosingDeclaration, flags, typeStack); } - + function buildSignatureDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, typeStack?: Type[]) { if (signature.target && (flags & TypeFormatFlags.WriteTypeArgumentsOfSignature)) { // Instantiated signature, write type arguments instead @@ -1653,16 +1653,13 @@ module ts { error(pattern, Diagnostics.Type_0_is_not_an_array_type, typeToString(parentType)); return unknownType; } - if (isTupleType(parentType)) { - var propName = "" + indexOf(pattern.elements, declaration); - var type = getTypeOfPropertyOfType(parentType, propName); - if (!type) { - error(declaration, Diagnostics.Type_0_has_no_property_1, typeToString(parentType), propName); - return unknownType; - } - return type; + var propName = "" + indexOf(pattern.elements, declaration); + var type = isTupleType(parentType) ? getTypeOfPropertyOfType(parentType, propName) : getIndexTypeOfType(parentType, IndexKind.Number); + if (!type) { + error(declaration, Diagnostics.Type_0_has_no_property_1, typeToString(parentType), propName); + return unknownType; } - return getIndexTypeOfType(parentType, IndexKind.Number); + return type; } function getTypeForVariableDeclaration(declaration: VariableDeclaration | PropertyDeclaration): Type { @@ -3980,7 +3977,7 @@ module ts { } function isTupleType(type: Type): boolean { - return (type.flags & TypeFlags.Tuple) !== 0; + return !!getPropertyOfType(type, "0"); } function getWidenedTypeOfObjectLiteral(type: Type): Type { @@ -6368,7 +6365,8 @@ module ts { if (p.kind === SyntaxKind.PropertyAssignment || p.kind === SyntaxKind.ShorthandPropertyAssignment) { // TODO(andersh): Computed property support var name = ((p).name); - var type = getTypeOfPropertyOfType(sourceType, name.text) || + var type = sourceType.flags & TypeFlags.Any ? sourceType : + getTypeOfPropertyOfType(sourceType, name.text) || isNumericName(name.text) && getIndexTypeOfType(sourceType, IndexKind.Number) || getIndexTypeOfType(sourceType, IndexKind.String); if (type) { @@ -6386,27 +6384,26 @@ module ts { } function checkArrayLiteralAssignment(node: ArrayLiteral, sourceType: Type, contextualMapper?: TypeMapper): Type { + // TODOO(andersh): Allow iterable source type in ES6 + if (!isTypeAssignableTo(sourceType, anyArrayType)) { + error(node, Diagnostics.Type_0_is_not_an_array_type, typeToString(sourceType)); + return sourceType; + } var elements = node.elements; for (var i = 0; i < elements.length; i++) { var e = elements[i]; if (e.kind !== SyntaxKind.OmittedExpression) { - if (isTupleType(sourceType)) { - var propName = "" + i; - var type = getTypeOfPropertyOfType(sourceType, propName); - if (!type) { - error(e, Diagnostics.Type_0_has_no_property_1, typeToString(sourceType), propName); - } + var propName = "" + i; + var type = sourceType.flags & TypeFlags.Any ? sourceType : + isTupleType(sourceType) ? getTypeOfPropertyOfType(sourceType, propName) : + getIndexTypeOfType(sourceType, IndexKind.Number); + if (type) { + checkDestructuringAssignment(e, type, contextualMapper); } else { - var type = getIndexTypeOfType(sourceType, IndexKind.Number); - if (!type) { - error(e, Diagnostics.Type_0_has_no_numeric_index_signature, typeToString(sourceType)); - } + error(e, Diagnostics.Type_0_has_no_property_1, typeToString(sourceType), propName); } } - if (type) { - checkDestructuringAssignment(e, type, contextualMapper); - } } return sourceType; } diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 2ff4be92fd266..41e34605e2da5 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -280,8 +280,7 @@ module ts { An_AMD_module_cannot_have_multiple_name_assignments: { code: 2458, category: DiagnosticCategory.Error, key: "An AMD module cannot have multiple name assignments." }, Type_0_has_no_property_1_and_no_string_index_signature: { code: 2459, category: DiagnosticCategory.Error, key: "Type '{0}' has no property '{1}' and no string index signature." }, Type_0_has_no_property_1: { code: 2460, category: DiagnosticCategory.Error, key: "Type '{0}' has no property '{1}'." }, - Type_0_has_no_numeric_index_signature: { code: 2461, category: DiagnosticCategory.Error, key: "Type '{0}' has no numeric index signature." }, - Type_0_is_not_an_array_type: { code: 2462, category: DiagnosticCategory.Error, key: "Type '{0}' is not an array type." }, + Type_0_is_not_an_array_type: { code: 2461, category: DiagnosticCategory.Error, key: "Type '{0}' is not an array type." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: { code: 4001, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using name '{1}' from private module '{2}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index e56188eae9f37..c3e3f28919597 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1116,13 +1116,9 @@ "category": "Error", "code": 2460 }, - "Type '{0}' has no numeric index signature.": { - "category": "Error", - "code": 2461 - }, "Type '{0}' is not an array type.": { "category": "Error", - "code": 2462 + "code": 2461 }, "Import declaration '{0}' is using private name '{1}'.": { From d8ecd8cdc6653eae3059ebfbfbe66c7de8f5d797 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 24 Nov 2014 08:31:04 -0800 Subject: [PATCH 16/33] Fixed bug in union type identity comparison --- src/compiler/checker.ts | 61 +++++++++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 14 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 00968b255a21e..0ffb791750012 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3352,12 +3352,9 @@ module ts { // Ternary.False if they are not related. function isRelatedTo(source: Type, target: Type, reportErrors?: boolean, headMessage?: DiagnosticMessage): Ternary { var result: Ternary; - if (relation === identityRelation) { - // both types are the same - covers 'they are the same primitive type or both are Any' or the same type parameter cases - if (source === target) return Ternary.True; - } - else { - if (source === target) return Ternary.True; + // both types are the same - covers 'they are the same primitive type or both are Any' or the same type parameter cases + if (source === target) return Ternary.True; + if (relation !== identityRelation) { if (target.flags & TypeFlags.Any) return Ternary.True; if (source === undefinedType) return Ternary.True; if (source === nullType && target !== undefinedType) return Ternary.True; @@ -3368,14 +3365,37 @@ module ts { if (source === numberType && target.flags & TypeFlags.Enum) return Ternary.True; } } - if (source.flags & TypeFlags.Union) { - if (result = unionTypeRelatedToType(source, target, reportErrors)) { - return result; + if (source.flags & TypeFlags.Union || target.flags & TypeFlags.Union) { + if (relation === identityRelation) { + if (source.flags & TypeFlags.Union && target.flags & TypeFlags.Union) { + if (result = unionTypeRelatedToUnionType(source, target)) { + if (result &= unionTypeRelatedToUnionType(target, source)) { + return result; + } + } + } + else if (source.flags & TypeFlags.Union) { + if (result = unionTypeRelatedToType(source, target, reportErrors)) { + return result; + } + } + else { + if (result = unionTypeRelatedToType(target, source, reportErrors)) { + return result; + } + } } - } - else if (target.flags & TypeFlags.Union) { - if (result = typeRelatedToUnionType(source, target, reportErrors)) { - return result; + else { + if (source.flags & TypeFlags.Union) { + if (result = unionTypeRelatedToType(source, target, reportErrors)) { + return result; + } + } + else { + if (result = typeRelatedToUnionType(source, target, reportErrors)) { + return result; + } + } } } else if (source.flags & TypeFlags.TypeParameter && target.flags & TypeFlags.TypeParameter) { @@ -3409,6 +3429,19 @@ module ts { return Ternary.False; } + function unionTypeRelatedToUnionType(source: UnionType, target: UnionType): Ternary { + var result = Ternary.True; + var sourceTypes = source.types; + for (var i = 0, len = sourceTypes.length; i < len; i++) { + var related = typeRelatedToUnionType(sourceTypes[i], target, false); + if (!related) { + return Ternary.False; + } + result &= related; + } + return result; + } + function typeRelatedToUnionType(source: Type, target: UnionType, reportErrors: boolean): Ternary { var targetTypes = target.types; for (var i = 0, len = targetTypes.length; i < len; i++) { @@ -3479,7 +3512,7 @@ module ts { if (overflow) { return Ternary.False; } - var id = source.id + "," + target.id; + var id = relation !== identityRelation || source.id < target.id ? source.id + "," + target.id : target.id + "," + source.id; var related = relation[id]; if (related !== undefined) { return related ? Ternary.True : Ternary.False; From 98eaca541a25a05eb0b38adab5195b01295585dd Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 28 Nov 2014 10:06:43 -0800 Subject: [PATCH 17/33] Accepting new baselines --- .../reference/assignmentLHSIsValue.errors.txt | 9 ++++-- .../reference/classExpression.errors.txt | 6 +++- .../genericCallWithObjectTypeArgs2.types | 2 +- .../nestedClassDeclaration.errors.txt | 6 +++- ...jectTypesWithOptionalProperties.errors.txt | 4 +-- .../parserCommaInTypeMemberList2.errors.txt | 30 ++++++------------- ...serErrorRecovery_ParameterList1.errors.txt | 14 ++++++--- ...serErrorRecovery_ParameterList2.errors.txt | 14 ++++----- ...serErrorRecovery_ParameterList5.errors.txt | 4 +-- ...nfinishedTypeNameBeforeKeyword1.errors.txt | 6 +++- 10 files changed, 52 insertions(+), 43 deletions(-) diff --git a/tests/baselines/reference/assignmentLHSIsValue.errors.txt b/tests/baselines/reference/assignmentLHSIsValue.errors.txt index 2f65b36853222..41931f584eed2 100644 --- a/tests/baselines/reference/assignmentLHSIsValue.errors.txt +++ b/tests/baselines/reference/assignmentLHSIsValue.errors.txt @@ -19,7 +19,8 @@ tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(2 tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(30,1): error TS2364: Invalid left-hand side of assignment expression. tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(31,1): error TS2364: Invalid left-hand side of assignment expression. tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(32,1): error TS2364: Invalid left-hand side of assignment expression. -tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(38,1): error TS2364: Invalid left-hand side of assignment expression. +tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(38,2): error TS2364: Invalid left-hand side of assignment expression. +tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(38,6): error TS2364: Invalid left-hand side of assignment expression. tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(42,30): error TS2364: Invalid left-hand side of assignment expression. tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(44,13): error TS2364: Invalid left-hand side of assignment expression. tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(46,21): error TS2364: Invalid left-hand side of assignment expression. @@ -40,7 +41,7 @@ tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(6 tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(70,1): error TS2364: Invalid left-hand side of assignment expression. -==== tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts (40 errors) ==== +==== tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts (41 errors) ==== // expected error for all the LHS of assignments var value; @@ -111,7 +112,9 @@ tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(7 // array literals ['', ''] = value; - ~~~~~~~~ + ~~ +!!! error TS2364: Invalid left-hand side of assignment expression. + ~~ !!! error TS2364: Invalid left-hand side of assignment expression. // super diff --git a/tests/baselines/reference/classExpression.errors.txt b/tests/baselines/reference/classExpression.errors.txt index 5a2bc4fd179ae..970b09590b098 100644 --- a/tests/baselines/reference/classExpression.errors.txt +++ b/tests/baselines/reference/classExpression.errors.txt @@ -2,12 +2,13 @@ tests/cases/conformance/classes/classExpression.ts(1,9): error TS1109: Expressio tests/cases/conformance/classes/classExpression.ts(5,10): error TS1109: Expression expected. tests/cases/conformance/classes/classExpression.ts(5,16): error TS1005: ':' expected. tests/cases/conformance/classes/classExpression.ts(5,19): error TS1005: ',' expected. +tests/cases/conformance/classes/classExpression.ts(5,19): error TS1165: A destructuring declaration must have an initializer. tests/cases/conformance/classes/classExpression.ts(7,1): error TS1128: Declaration or statement expected. tests/cases/conformance/classes/classExpression.ts(10,13): error TS1109: Expression expected. tests/cases/conformance/classes/classExpression.ts(5,16): error TS2304: Cannot find name 'C2'. -==== tests/cases/conformance/classes/classExpression.ts (7 errors) ==== +==== tests/cases/conformance/classes/classExpression.ts (8 errors) ==== var x = class C { ~~~~~ !!! error TS1109: Expression expected. @@ -21,9 +22,12 @@ tests/cases/conformance/classes/classExpression.ts(5,16): error TS2304: Cannot f !!! error TS1005: ':' expected. ~ !!! error TS1005: ',' expected. + ~ ~~ !!! error TS2304: Cannot find name 'C2'. } + ~~~~~ +!!! error TS1165: A destructuring declaration must have an initializer. } ~ !!! error TS1128: Declaration or statement expected. diff --git a/tests/baselines/reference/genericCallWithObjectTypeArgs2.types b/tests/baselines/reference/genericCallWithObjectTypeArgs2.types index 3e178a7062d2b..08bce90b5de5c 100644 --- a/tests/baselines/reference/genericCallWithObjectTypeArgs2.types +++ b/tests/baselines/reference/genericCallWithObjectTypeArgs2.types @@ -56,7 +56,7 @@ var r = f({ x: new Derived(), y: new Derived2() }); // {}[] >Derived2 : typeof Derived2 var r2 = f({ x: new Base(), y: new Derived2() }); // {}[] ->r2 : Base[] +>r2 : (Base | Derived2)[] >f({ x: new Base(), y: new Derived2() }) : (Base | Derived2)[] >f : (a: { x: T; y: U; }) => (T | U)[] >{ x: new Base(), y: new Derived2() } : { x: Base; y: Derived2; } diff --git a/tests/baselines/reference/nestedClassDeclaration.errors.txt b/tests/baselines/reference/nestedClassDeclaration.errors.txt index f314546723115..ab4a2dc44171e 100644 --- a/tests/baselines/reference/nestedClassDeclaration.errors.txt +++ b/tests/baselines/reference/nestedClassDeclaration.errors.txt @@ -4,11 +4,12 @@ tests/cases/conformance/classes/nestedClassDeclaration.ts(10,5): error TS1129: S tests/cases/conformance/classes/nestedClassDeclaration.ts(12,1): error TS1128: Declaration or statement expected. tests/cases/conformance/classes/nestedClassDeclaration.ts(15,11): error TS1005: ':' expected. tests/cases/conformance/classes/nestedClassDeclaration.ts(15,14): error TS1005: ',' expected. +tests/cases/conformance/classes/nestedClassDeclaration.ts(15,14): error TS1165: A destructuring declaration must have an initializer. tests/cases/conformance/classes/nestedClassDeclaration.ts(17,1): error TS1128: Declaration or statement expected. tests/cases/conformance/classes/nestedClassDeclaration.ts(15,11): error TS2304: Cannot find name 'C4'. -==== tests/cases/conformance/classes/nestedClassDeclaration.ts (8 errors) ==== +==== tests/cases/conformance/classes/nestedClassDeclaration.ts (9 errors) ==== // nested classes are not allowed class C { @@ -36,9 +37,12 @@ tests/cases/conformance/classes/nestedClassDeclaration.ts(15,11): error TS2304: !!! error TS1005: ':' expected. ~ !!! error TS1005: ',' expected. + ~ ~~ !!! error TS2304: Cannot find name 'C4'. } + ~~~~~ +!!! error TS1165: A destructuring declaration must have an initializer. } ~ !!! error TS1128: Declaration or statement expected. diff --git a/tests/baselines/reference/objectTypesWithOptionalProperties.errors.txt b/tests/baselines/reference/objectTypesWithOptionalProperties.errors.txt index 14afcebd2136e..3f5321734d18a 100644 --- a/tests/baselines/reference/objectTypesWithOptionalProperties.errors.txt +++ b/tests/baselines/reference/objectTypesWithOptionalProperties.errors.txt @@ -1,6 +1,6 @@ tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties.ts(12,6): error TS1112: A class member cannot be declared optional. tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties.ts(20,6): error TS1112: A class member cannot be declared optional. -tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties.ts(24,6): error TS1160: An object member cannot be declared optional. +tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties.ts(24,6): error TS1162: An object member cannot be declared optional. ==== tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties.ts (3 errors) ==== @@ -33,5 +33,5 @@ tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWith var b = { x?: 1 // error -!!! error TS1160: An object member cannot be declared optional. +!!! error TS1162: An object member cannot be declared optional. } \ No newline at end of file diff --git a/tests/baselines/reference/parserCommaInTypeMemberList2.errors.txt b/tests/baselines/reference/parserCommaInTypeMemberList2.errors.txt index 025febbc9a558..8a00b9fc11542 100644 --- a/tests/baselines/reference/parserCommaInTypeMemberList2.errors.txt +++ b/tests/baselines/reference/parserCommaInTypeMemberList2.errors.txt @@ -1,29 +1,17 @@ -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserCommaInTypeMemberList2.ts(1,38): error TS1134: Variable declaration expected. -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserCommaInTypeMemberList2.ts(1,60): error TS1005: ';' expected. -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserCommaInTypeMemberList2.ts(1,70): error TS1128: Declaration or statement expected. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserCommaInTypeMemberList2.ts(1,38): error TS1165: A destructuring declaration must have an initializer. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserCommaInTypeMemberList2.ts(1,70): error TS1005: ',' expected. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserCommaInTypeMemberList2.ts(1,71): error TS1134: Variable declaration expected. tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserCommaInTypeMemberList2.ts(1,9): error TS2304: Cannot find name '$'. -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserCommaInTypeMemberList2.ts(1,31): error TS2304: Cannot find name 'any'. -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserCommaInTypeMemberList2.ts(1,50): error TS2304: Cannot find name 'any'. -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserCommaInTypeMemberList2.ts(1,55): error TS2304: Cannot find name 'width'. -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserCommaInTypeMemberList2.ts(1,62): error TS2304: Cannot find name 'string'. -==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserCommaInTypeMemberList2.ts (8 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserCommaInTypeMemberList2.ts (4 errors) ==== var s = $.extend< { workItem: any }, { workItem: any, width: string }>({ workItem: this._workItem }, {}); - ~ -!!! error TS1134: Variable declaration expected. - ~ -!!! error TS1005: ';' expected. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1165: A destructuring declaration must have an initializer. ~ -!!! error TS1128: Declaration or statement expected. +!!! error TS1005: ',' expected. + ~ +!!! error TS1134: Variable declaration expected. ~ !!! error TS2304: Cannot find name '$'. - ~~~ -!!! error TS2304: Cannot find name 'any'. - ~~~ -!!! error TS2304: Cannot find name 'any'. - ~~~~~ -!!! error TS2304: Cannot find name 'width'. - ~~~~~~ -!!! error TS2304: Cannot find name 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/parserErrorRecovery_ParameterList1.errors.txt b/tests/baselines/reference/parserErrorRecovery_ParameterList1.errors.txt index 1e8f35de06b8f..c2308f6fb115e 100644 --- a/tests/baselines/reference/parserErrorRecovery_ParameterList1.errors.txt +++ b/tests/baselines/reference/parserErrorRecovery_ParameterList1.errors.txt @@ -1,8 +1,14 @@ -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList1.ts(1,14): error TS1005: ')' expected. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList1.ts(1,14): error TS1005: ',' expected. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList1.ts(2,2): error TS1005: ')' expected. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList1.ts(1,10): error TS2391: Function implementation is missing or not immediately following the declaration. -==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList1.ts (1 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList1.ts (3 errors) ==== function f(a { ~ -!!! error TS1005: ')' expected. - } \ No newline at end of file +!!! error TS1005: ',' expected. + ~ +!!! error TS2391: Function implementation is missing or not immediately following the declaration. + } + +!!! error TS1005: ')' expected. \ No newline at end of file diff --git a/tests/baselines/reference/parserErrorRecovery_ParameterList2.errors.txt b/tests/baselines/reference/parserErrorRecovery_ParameterList2.errors.txt index fd4c286f356e2..43e3f9f028d5b 100644 --- a/tests/baselines/reference/parserErrorRecovery_ParameterList2.errors.txt +++ b/tests/baselines/reference/parserErrorRecovery_ParameterList2.errors.txt @@ -1,11 +1,11 @@ -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList2.ts(1,13): error TS1009: Trailing comma not allowed. -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList2.ts(1,15): error TS1005: ')' expected. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList2.ts(2,2): error TS1005: ')' expected. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList2.ts(1,10): error TS2391: Function implementation is missing or not immediately following the declaration. ==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList2.ts (2 errors) ==== function f(a, { - ~ -!!! error TS1009: Trailing comma not allowed. - ~ -!!! error TS1005: ')' expected. - } \ No newline at end of file + ~ +!!! error TS2391: Function implementation is missing or not immediately following the declaration. + } + +!!! error TS1005: ')' expected. \ No newline at end of file diff --git a/tests/baselines/reference/parserErrorRecovery_ParameterList5.errors.txt b/tests/baselines/reference/parserErrorRecovery_ParameterList5.errors.txt index 1d3a9d901c849..8d15f746d20f3 100644 --- a/tests/baselines/reference/parserErrorRecovery_ParameterList5.errors.txt +++ b/tests/baselines/reference/parserErrorRecovery_ParameterList5.errors.txt @@ -1,10 +1,10 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList5.ts(1,11): error TS1005: ',' expected. -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList5.ts(1,14): error TS1005: ')' expected. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList5.ts(1,17): error TS1005: ')' expected. ==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList5.ts (2 errors) ==== (a:number => { } ~~ !!! error TS1005: ',' expected. - ~ + !!! error TS1005: ')' expected. \ No newline at end of file diff --git a/tests/baselines/reference/parserUnfinishedTypeNameBeforeKeyword1.errors.txt b/tests/baselines/reference/parserUnfinishedTypeNameBeforeKeyword1.errors.txt index 1f1e1fdce00c7..bbc1f77685513 100644 --- a/tests/baselines/reference/parserUnfinishedTypeNameBeforeKeyword1.errors.txt +++ b/tests/baselines/reference/parserUnfinishedTypeNameBeforeKeyword1.errors.txt @@ -1,10 +1,11 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnfinishedTypeNameBeforeKeyword1.ts(2,8): error TS1005: '=' expected. tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnfinishedTypeNameBeforeKeyword1.ts(2,20): error TS1005: ',' expected. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnfinishedTypeNameBeforeKeyword1.ts(2,20): error TS1165: A destructuring declaration must have an initializer. tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnfinishedTypeNameBeforeKeyword1.ts(1,8): error TS2304: Cannot find name 'TypeModule1'. tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnfinishedTypeNameBeforeKeyword1.ts(2,8): error TS2304: Cannot find name 'TypeModule2'. -==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnfinishedTypeNameBeforeKeyword1.ts (4 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnfinishedTypeNameBeforeKeyword1.ts (5 errors) ==== var x: TypeModule1. ~~~~~~~~~~~~ module TypeModule2 { @@ -12,9 +13,12 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnfinishedTypeNam !!! error TS1005: '=' expected. ~ !!! error TS1005: ',' expected. + ~ ~~~~~~ !!! error TS2304: Cannot find name 'TypeModule1'. ~~~~~~~~~~~ !!! error TS2304: Cannot find name 'TypeModule2'. } + ~ +!!! error TS1165: A destructuring declaration must have an initializer. \ No newline at end of file From cf3e3ac6b80137444563ec9b78775b650f36d3f3 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 28 Nov 2014 10:13:52 -0800 Subject: [PATCH 18/33] Rewriting and emit for destructuring declarations --- src/compiler/checker.ts | 5 ++ src/compiler/emitter.ts | 168 ++++++++++++++++++++++++++++++++++------ src/compiler/parser.ts | 14 ++-- src/compiler/types.ts | 1 + 4 files changed, 155 insertions(+), 33 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0ffb791750012..bcff651c51807 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9276,6 +9276,10 @@ module ts { getSymbolDisplayBuilder().buildTypeDisplay(getReturnTypeOfSignature(signature), writer, enclosingDeclaration, flags); } + function isUnknownIdentifier(location: Node, name: string): boolean { + return !resolveName(location, name, SymbolFlags.Value, /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined); + } + function invokeEmitter(targetSourceFile?: SourceFile) { var resolver: EmitResolver = { getProgram: () => program, @@ -9295,6 +9299,7 @@ module ts { isSymbolAccessible, isImportDeclarationEntityNameReferenceDeclarationVisibile, getConstantValue, + isUnknownIdentifier, }; checkProgram(); return emitFiles(resolver, targetSourceFile); diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index e7df9e9136af5..dabd6c943e7cf 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -322,6 +322,7 @@ module ts { var decreaseIndent = writer.decreaseIndent; var extendsEmitted = false; + var tempCount = 0; /** write emitted output to disk*/ var writeEmittedFiles = writeJavaScriptFile; @@ -716,6 +717,14 @@ module ts { writeFile(jsFilePath, emitOutput, writeByteOrderMark); } + function getTempVariableName(location: Node) { + do { + var name = "_" + tempCount++; + } + while (!resolver.isUnknownIdentifier(location, name)); + return name; + } + function emitTokenText(tokenKind: SyntaxKind, startPos: number, emitFn?: () => void) { var tokenString = tokenToString(tokenKind); if (emitFn) { @@ -789,22 +798,15 @@ module ts { } function emitLiteral(node: LiteralExpression): void { - var text = getLiteralText(); - + var text = compilerOptions.target < ScriptTarget.ES6 && isTemplateLiteralKind(node.kind) ? getTemplateLiteralAsStringLiteral(node) : + node.parent ? getSourceTextOfLocalNode(node) : + node.text; if (compilerOptions.sourceMap && (node.kind === SyntaxKind.StringLiteral || isTemplateLiteralKind(node.kind))) { writer.writeLiteral(text); } else { write(text); } - - function getLiteralText() { - if (compilerOptions.target < ScriptTarget.ES6 && isTemplateLiteralKind(node.kind)) { - return getTemplateLiteralAsStringLiteral(node) - } - - return getSourceTextOfLocalNode(node); - } } function getTemplateLiteralAsStringLiteral(node: LiteralExpression): string { @@ -981,7 +983,10 @@ module ts { } function emitIdentifier(node: Identifier) { - if (!isNotExpressionIdentifier(node)) { + if (!node.parent) { + write(node.text); + } + else if (!isNotExpressionIdentifier(node)) { emitExpressionIdentifier(node); } else { @@ -1498,20 +1503,128 @@ module ts { emitEnd(node.name); } - function emitVariableDeclaration(node: VariableDeclaration) { - emitLeadingComments(node); - if (node.propertyName) { - emit(node.propertyName); - write(": "); + function rewriteDestructuringDeclaration(node: VariableDeclaration): NodeArray { + var declarations = >[]; + rewriteDeclaration(node, undefined); + return declarations; + + function addVariableDeclaration(name: Identifier, initializer: Expression) { + var node = createNode(SyntaxKind.VariableDeclaration); + node.name = name; + node.initializer = initializer; + declarations.push(node); } - if (node.name.kind === SyntaxKind.Identifier) { - emitModuleMemberName(node); + + function createTemporaryVariable(expr: Expression): Expression { + var tempName = getTempVariableName(node); + var identifier = createNode(SyntaxKind.Identifier); + identifier.text = tempName; + addVariableDeclaration(identifier, expr); + return identifier; + } + + function createVoidZero(): Expression { + var zero = createNode(SyntaxKind.NumericLiteral); + zero.text = "0"; + var result = createNode(SyntaxKind.PrefixOperator); + result.operator = SyntaxKind.VoidKeyword; + result.operand = zero; + return result; + } + + function createDefaultValueCheck(value: Expression, defaultValue: Expression): Expression { + if (value.kind !== SyntaxKind.Identifier) { + value = createTemporaryVariable(value); + } + var equals = createNode(SyntaxKind.BinaryExpression); + equals.left = value; + equals.operator = SyntaxKind.EqualsEqualsEqualsToken; + equals.right = createVoidZero(); + var cond = createNode(SyntaxKind.ConditionalExpression); + cond.condition = equals; + cond.whenTrue = defaultValue; + cond.whenFalse = value; + return cond; + } + + function createNumericLiteral(value: number) { + var node = createNode(SyntaxKind.NumericLiteral); + node.text = "" + value; + return node; + } + + function parenthesizeForAccess(expr: Expression): Expression { + if (expr.kind === SyntaxKind.Identifier || expr.kind === SyntaxKind.PropertyAccess || expr.kind === SyntaxKind.IndexedAccess) { + return expr; + } + var node = createNode(SyntaxKind.ParenExpression); + node.expression = expr; + return node; + } + + function createPropertyAccess(object: Expression, propName: Identifier): Expression { + if (propName.kind !== SyntaxKind.Identifier) { + return createIndexedAccess(object, propName); + } + var node = createNode(SyntaxKind.PropertyAccess); + node.left = parenthesizeForAccess(object); + node.right = propName; + return node; + } + + function createIndexedAccess(object: Expression, index: Expression): Expression { + var node = createNode(SyntaxKind.IndexedAccess); + node.object = parenthesizeForAccess(object); + node.index = index; + return node; + } + + function rewriteDeclaration(target: BindingElement, value: Expression) { + if (target.initializer) { + value = value ? createDefaultValueCheck(value, target.initializer) : target.initializer; + } + else if (!value) { + value = createVoidZero(); + } + if (isBindingPattern(target.name)) { + var pattern = target.name; + var elements = pattern.elements; + if (elements.length !== 1) { + value = createTemporaryVariable(value); + } + for (var i = 0; i < elements.length; i++) { + var element = elements[i]; + if (pattern.kind === SyntaxKind.ObjectBindingPattern) { + var propName = element.propertyName || element.name; + rewriteDeclaration(element, createPropertyAccess(value, propName)); + } + else { + rewriteDeclaration(element, createIndexedAccess(value, createNumericLiteral(i))); + } + } + } + else { + addVariableDeclaration(target.name, value); + } + } + } + + function emitVariableDeclaration(node: VariableDeclaration) { + if (node.parent) { + emitLeadingComments(node); + if (isBindingPattern(node.name)) { + emitCommaList(rewriteDestructuringDeclaration(node), /*includeTrailingComma*/ false); + } + else { + emitModuleMemberName(node); + emitOptional(" = ", node.initializer); + } + emitTrailingComments(node); } else { emit(node.name); + emitOptional(" = ", node.initializer); } - emitOptional(" = ", node.initializer); - emitTrailingComments(node); } function emitVariableStatement(node: VariableStatement) { @@ -1577,6 +1690,7 @@ module ts { if (hasRestParameters(node)) { var restIndex = node.parameters.length - 1; var restParam = node.parameters[restIndex]; + var tempName = "_i"; writeLine(); emitLeadingComments(restParam); emitStart(restParam); @@ -1588,22 +1702,22 @@ module ts { writeLine(); write("for ("); emitStart(restParam); - write("var _i = " + restIndex + ";"); + write("var " + tempName + " = " + restIndex + ";"); emitEnd(restParam); write(" "); emitStart(restParam); - write("_i < arguments.length;"); + write(tempName + " < arguments.length;"); emitEnd(restParam); write(" "); emitStart(restParam); - write("_i++"); + write(tempName + "++"); emitEnd(restParam); write(") {"); increaseIndent(); writeLine(); emitStart(restParam); emitNode(restParam.name); - write("[_i - " + restIndex + "] = arguments[_i];"); + write("[" + tempName + " - " + restIndex + "] = arguments[" + tempName + "];"); emitEnd(restParam); decreaseIndent(); writeLine(); @@ -1660,6 +1774,7 @@ module ts { function emitSignatureAndBody(node: FunctionLikeDeclaration) { emitSignatureParameters(node); write(" {"); + var saveTempCount = tempCount; scopeEmitStart(node); increaseIndent(); @@ -1711,6 +1826,7 @@ module ts { } } scopeEmitEnd(); + tempCount = saveTempCount; if (node.flags & NodeFlags.Export) { writeLine(); emitStart(node); @@ -1936,6 +2052,7 @@ module ts { emit(node.name); emitSignatureParameters(ctor); write(" {"); + var saveTempCount = tempCount; scopeEmitStart(node, "constructor"); increaseIndent(); if (ctor) { @@ -1975,6 +2092,7 @@ module ts { decreaseIndent(); emitToken(SyntaxKind.CloseBraceToken, ctor ? (ctor.body).statements.end : node.members.end); scopeEmitEnd(); + tempCount = saveTempCount; emitEnd(ctor || node); if (ctor) { emitTrailingComments(ctor); @@ -2082,6 +2200,7 @@ module ts { write(resolver.getLocalNameOfContainer(node)); emitEnd(node.name); write(") "); + var saveTempCount = tempCount; if (node.body.kind === SyntaxKind.ModuleBlock) { emit(node.body); } @@ -2098,6 +2217,7 @@ module ts { emitToken(SyntaxKind.CloseBraceToken, moduleBlock.statements.end); scopeEmitEnd(); } + tempCount = saveTempCount; write(")("); if (node.flags & NodeFlags.Export) { emit(node.name); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 7fd68b9ce0371..ecebcaa309b57 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -9,12 +9,8 @@ module ts { return nodeConstructors[kind] || (nodeConstructors[kind] = objectAllocator.getNodeConstructor(kind)); } - function createRootNode(kind: SyntaxKind, pos: number, end: number, flags: NodeFlags): Node { - var node = new (getNodeConstructor(kind))(); - node.pos = pos; - node.end = end; - node.flags = flags; - return node; + export function createNode(kind: SyntaxKind): Node { + return new (getNodeConstructor(kind))(); } interface ReferenceComments { @@ -4389,12 +4385,12 @@ module ts { } scanner = createScanner(languageVersion, /*skipTrivia*/ true, sourceText, scanError, onComment); - var rootNodeFlags: NodeFlags = 0; + file = createNode(SyntaxKind.SourceFile); if (fileExtensionIs(filename, ".d.ts")) { - rootNodeFlags = NodeFlags.DeclarationFile; + file.flags = NodeFlags.DeclarationFile; inAmbientContext = true; } - file = createRootNode(SyntaxKind.SourceFile, 0, sourceText.length, rootNodeFlags); + file.end = sourceText.length; file.filename = normalizePath(filename); file.text = sourceText; file.getLineAndCharacterFromPosition = getLineAndCharacterFromSourcePosition; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 706e6fe7ae2de..9807cee4649b1 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -841,6 +841,7 @@ module ts { // Returns the constant value this property access resolves to, or 'undefined' for a non-constant getConstantValue(node: PropertyAccess | IndexedAccess): number; isEmitBlocked(sourceFile?: SourceFile): boolean; + isUnknownIdentifier(location: Node, name: string): boolean; } export const enum SymbolFlags { From 28a73bc9360074616ed473ea2d054de83765ba6c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 28 Nov 2014 18:25:27 -0800 Subject: [PATCH 19/33] Emit of rest parameter for loop uses unique temporary variable name --- src/compiler/checker.ts | 83 +---------------------------------------- src/compiler/emitter.ts | 15 +++++++- 2 files changed, 14 insertions(+), 84 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bcff651c51807..c60abea743c31 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1714,7 +1714,7 @@ module ts { function getTypeFromBindingPattern(pattern: BindingPattern): Type { if (pattern.kind === SyntaxKind.ArrayBindingPattern) { - return createTupleType(map(pattern.elements, getTypeFromBindingElement)); + return createTupleType(map(pattern.elements, e => e.kind === SyntaxKind.OmittedExpression ? anyType : getTypeFromBindingElement(e))); } var members: SymbolTable = {}; forEach(pattern.elements, e => { @@ -4628,7 +4628,6 @@ module ts { checkCollisionWithCapturedSuperVariable(node, node); checkCollisionWithCapturedThisVariable(node, node); - checkCollisionWithIndexVariableInGeneratedCode(node, node); return getNarrowedTypeOfSymbol(getExportSymbolOfValueSymbolIfExported(symbol), node); } @@ -6759,7 +6758,6 @@ module ts { if (isBindingPattern(node.name)) { return; } - checkCollisionWithIndexVariableInGeneratedCode(node, node.name); var func = getContainingFunction(node); if (node.flags & (NodeFlags.Public | NodeFlags.Private | NodeFlags.Protected) && !(func.kind === SyntaxKind.Constructor && func.body)) { @@ -7418,85 +7416,6 @@ module ts { }); } - function checkCollisionWithIndexVariableInGeneratedCode(node: Node, name: Identifier) { - if (!(name && name.text === "_i")) { - return; - } - - if (node.kind === SyntaxKind.Parameter) { - // report error if parameter has name '_i' when: - // - function has implementation (not a signature) - // - function has rest parameters - // - context is not ambient (otherwise no codegen impact) - var func = getContainingFunction(node); - if (func.body && hasRestParameters(func) && !isInAmbientContext(node)) { - error(node, Diagnostics.Duplicate_identifier_i_Compiler_uses_i_to_initialize_rest_parameter); - } - return; - } - - var symbol = getNodeLinks(node).resolvedSymbol; - if (symbol === unknownSymbol) { - return; - } - - // we would like to discover cases like one below: - // - // var _i = "!"; - // function foo(...a) { - // function bar() { - // var x = { get baz() { return _i; } } - // } - // } - // - // at runtime '_i' referenced in getter will be resolved to the generated index variable '_i' used to initialize rest parameters. - // legitimate case: when '_i' is defined inside the function declaration with rest parameters. - // - // function foo(...a) { - // var _i = "!"; - // function bar() { - // var x = { get baz() { return _i; } } - // } - // } - - //// if resolved symbol for node has more than one declaration - this is definitely an error - //// (there is nothing value-like in the language that can be nested in function and consists of multiple declarations) - //if (symbol.declarations.length > 1) { - // error(node, Diagnostics.Expression_resolves_to_variable_declaration_i_that_compiler_uses_to_initialize_rest_parameter); - // return; - //} - - // short gist of the check: - // - otherwise - // - walk to the top of the tree starting from the 'node' - // - at every step check if 'current' node contains any declaration of original node - // yes - return - // no - check if current declaration is function with rest parameters - // yes - report error since '_i' from this function will shadow '_i' defined in the outer scope - // no - go up to the next level - var current = node; - while (current) { - var definedOnCurrentLevel = forEach(symbol.declarations, d => getContainingFunction(d) === current); - if (definedOnCurrentLevel) { - return; - } - switch (current.kind) { - // all kinds that might have rest parameters - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - case SyntaxKind.Method: - case SyntaxKind.ArrowFunction: - case SyntaxKind.Constructor: - if (hasRestParameters(current)) { - error(node, Diagnostics.Expression_resolves_to_variable_declaration_i_that_compiler_uses_to_initialize_rest_parameter); - return; - } - break; - } - current = current.parent; - } - } - // TODO(jfreeman): Decide what to do for computed properties function needCollisionCheckForIdentifier(node: Node, identifier: DeclarationName, name: string): boolean { if (!(identifier && (identifier).text === name)) { diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index dabd6c943e7cf..3e462729dd4c5 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1503,6 +1503,8 @@ module ts { emitEnd(node.name); } + // Rewrites a destructuring variable declaration into a sequence of regular variable declarations. + // Nodes generated by the syntactic rewrite have no parent references. function rewriteDestructuringDeclaration(node: VariableDeclaration): NodeArray { var declarations = >[]; rewriteDeclaration(node, undefined); @@ -1533,9 +1535,12 @@ module ts { } function createDefaultValueCheck(value: Expression, defaultValue: Expression): Expression { + // The value expression will be evaluated twice, so for anything but a simple identifier + // we need to generate a temporary variable if (value.kind !== SyntaxKind.Identifier) { value = createTemporaryVariable(value); } + // Return the expression 'value === void 0 ? defaultValue : value' var equals = createNode(SyntaxKind.BinaryExpression); equals.left = value; equals.operator = SyntaxKind.EqualsEqualsEqualsToken; @@ -1581,24 +1586,30 @@ module ts { function rewriteDeclaration(target: BindingElement, value: Expression) { if (target.initializer) { + // Combine value and initializer value = value ? createDefaultValueCheck(value, target.initializer) : target.initializer; } else if (!value) { + // Use 'void 0' in absence of value and initializer value = createVoidZero(); } if (isBindingPattern(target.name)) { var pattern = target.name; var elements = pattern.elements; if (elements.length !== 1) { + // For anything but a single element destructuring we need to generate a temporary + // to ensure value is evaluated exactly once. value = createTemporaryVariable(value); } for (var i = 0; i < elements.length; i++) { var element = elements[i]; if (pattern.kind === SyntaxKind.ObjectBindingPattern) { + // Rewrite element to a declaration with an initializer that fetches property var propName = element.propertyName || element.name; rewriteDeclaration(element, createPropertyAccess(value, propName)); } - else { + else if (element.kind !== SyntaxKind.OmittedExpression) { + // Rewrite element to a declaration that accesses array element at index i rewriteDeclaration(element, createIndexedAccess(value, createNumericLiteral(i))); } } @@ -1690,7 +1701,7 @@ module ts { if (hasRestParameters(node)) { var restIndex = node.parameters.length - 1; var restParam = node.parameters[restIndex]; - var tempName = "_i"; + var tempName = resolver.isUnknownIdentifier(node, "_i") ? "_i" : getTempVariableName(node); writeLine(); emitLeadingComments(restParam); emitStart(restParam); From ec7ce72c9443a328890727643b8af1083721989e Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 28 Nov 2014 18:32:51 -0800 Subject: [PATCH 20/33] Removing unused diagnostics related to '_i' variable name --- src/compiler/diagnosticInformationMap.generated.ts | 2 -- src/compiler/diagnosticMessages.json | 8 -------- 2 files changed, 10 deletions(-) diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 41e34605e2da5..5a53718d58590 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -221,8 +221,6 @@ module ts { Overload_signature_is_not_compatible_with_function_implementation: { code: 2394, category: DiagnosticCategory.Error, key: "Overload signature is not compatible with function implementation." }, Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local: { code: 2395, category: DiagnosticCategory.Error, key: "Individual declarations in merged declaration {0} must be all exported or all local." }, Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters: { code: 2396, category: DiagnosticCategory.Error, key: "Duplicate identifier 'arguments'. Compiler uses 'arguments' to initialize rest parameters." }, - Duplicate_identifier_i_Compiler_uses_i_to_initialize_rest_parameter: { code: 2397, category: DiagnosticCategory.Error, key: "Duplicate identifier '_i'. Compiler uses '_i' to initialize rest parameter." }, - Expression_resolves_to_variable_declaration_i_that_compiler_uses_to_initialize_rest_parameter: { code: 2398, category: DiagnosticCategory.Error, key: "Expression resolves to variable declaration '_i' that compiler uses to initialize rest parameter." }, Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference: { code: 2399, category: DiagnosticCategory.Error, key: "Duplicate identifier '_this'. Compiler uses variable declaration '_this' to capture 'this' reference." }, Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference: { code: 2400, category: DiagnosticCategory.Error, key: "Expression resolves to variable declaration '_this' that compiler uses to capture 'this' reference." }, Duplicate_identifier_super_Compiler_uses_super_to_capture_base_class_reference: { code: 2401, category: DiagnosticCategory.Error, key: "Duplicate identifier '_super'. Compiler uses '_super' to capture base class reference." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index c3e3f28919597..e7ac77a311aad 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -876,14 +876,6 @@ "category": "Error", "code": 2396 }, - "Duplicate identifier '_i'. Compiler uses '_i' to initialize rest parameter.": { - "category": "Error", - "code": 2397 - }, - "Expression resolves to variable declaration '_i' that compiler uses to initialize rest parameter.": { - "category": "Error", - "code": 2398 - }, "Duplicate identifier '_this'. Compiler uses variable declaration '_this' to capture 'this' reference.": { "category": "Error", "code": 2399 From 501a3704f916eb84699087ae3314108084c9de51 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 28 Nov 2014 18:33:37 -0800 Subject: [PATCH 21/33] Accepting new baselines --- ...sionRestParameterArrowFunctions.errors.txt | 19 --- .../collisionRestParameterArrowFunctions.js | 8 +- ...collisionRestParameterArrowFunctions.types | 34 +++++ ...onRestParameterClassConstructor.errors.txt | 78 ---------- .../collisionRestParameterClassConstructor.js | 16 +- ...llisionRestParameterClassConstructor.types | 137 ++++++++++++++++++ ...llisionRestParameterClassMethod.errors.txt | 47 ------ .../collisionRestParameterClassMethod.js | 12 +- .../collisionRestParameterClassMethod.types | 103 +++++++++++++ .../collisionRestParameterFunction.errors.txt | 42 ------ .../collisionRestParameterFunction.js | 12 +- .../collisionRestParameterFunction.types | 88 +++++++++++ ...estParameterFunctionExpressions.errors.txt | 33 ----- ...llisionRestParameterFunctionExpressions.js | 12 +- ...sionRestParameterFunctionExpressions.types | 62 ++++++++ ...onRestParameterUnderscoreIUsage.errors.txt | 14 -- .../collisionRestParameterUnderscoreIUsage.js | 4 +- ...llisionRestParameterUnderscoreIUsage.types | 27 ++++ 18 files changed, 483 insertions(+), 265 deletions(-) delete mode 100644 tests/baselines/reference/collisionRestParameterArrowFunctions.errors.txt create mode 100644 tests/baselines/reference/collisionRestParameterArrowFunctions.types delete mode 100644 tests/baselines/reference/collisionRestParameterClassConstructor.errors.txt create mode 100644 tests/baselines/reference/collisionRestParameterClassConstructor.types delete mode 100644 tests/baselines/reference/collisionRestParameterClassMethod.errors.txt create mode 100644 tests/baselines/reference/collisionRestParameterClassMethod.types delete mode 100644 tests/baselines/reference/collisionRestParameterFunction.errors.txt create mode 100644 tests/baselines/reference/collisionRestParameterFunction.types delete mode 100644 tests/baselines/reference/collisionRestParameterFunctionExpressions.errors.txt create mode 100644 tests/baselines/reference/collisionRestParameterFunctionExpressions.types delete mode 100644 tests/baselines/reference/collisionRestParameterUnderscoreIUsage.errors.txt create mode 100644 tests/baselines/reference/collisionRestParameterUnderscoreIUsage.types diff --git a/tests/baselines/reference/collisionRestParameterArrowFunctions.errors.txt b/tests/baselines/reference/collisionRestParameterArrowFunctions.errors.txt deleted file mode 100644 index 5c585e5a6c3a5..0000000000000 --- a/tests/baselines/reference/collisionRestParameterArrowFunctions.errors.txt +++ /dev/null @@ -1,19 +0,0 @@ -tests/cases/compiler/collisionRestParameterArrowFunctions.ts(1,11): error TS2397: Duplicate identifier '_i'. Compiler uses '_i' to initialize rest parameter. - - -==== tests/cases/compiler/collisionRestParameterArrowFunctions.ts (1 errors) ==== - var f1 = (_i: number, ...restParameters) => { //_i is error - ~~~~~~~~~~ -!!! error TS2397: Duplicate identifier '_i'. Compiler uses '_i' to initialize rest parameter. - var _i = 10; // no error - } - var f1NoError = (_i: number) => { // no error - var _i = 10; // no error - } - - var f2 = (...restParameters) => { - var _i = 10; // No Error - } - var f2NoError = () => { - var _i = 10; // no error - } \ No newline at end of file diff --git a/tests/baselines/reference/collisionRestParameterArrowFunctions.js b/tests/baselines/reference/collisionRestParameterArrowFunctions.js index cc8dc337b87fd..31f835b6a865f 100644 --- a/tests/baselines/reference/collisionRestParameterArrowFunctions.js +++ b/tests/baselines/reference/collisionRestParameterArrowFunctions.js @@ -16,8 +16,8 @@ var f2NoError = () => { //// [collisionRestParameterArrowFunctions.js] var f1 = function (_i) { var restParameters = []; - for (var _i = 1; _i < arguments.length; _i++) { - restParameters[_i - 1] = arguments[_i]; + for (var _0 = 1; _0 < arguments.length; _0++) { + restParameters[_0 - 1] = arguments[_0]; } var _i = 10; // no error }; @@ -26,8 +26,8 @@ var f1NoError = function (_i) { }; var f2 = function () { var restParameters = []; - for (var _i = 0; _i < arguments.length; _i++) { - restParameters[_i - 0] = arguments[_i]; + for (var _0 = 0; _0 < arguments.length; _0++) { + restParameters[_0 - 0] = arguments[_0]; } var _i = 10; // No Error }; diff --git a/tests/baselines/reference/collisionRestParameterArrowFunctions.types b/tests/baselines/reference/collisionRestParameterArrowFunctions.types new file mode 100644 index 0000000000000..f2316c99583a6 --- /dev/null +++ b/tests/baselines/reference/collisionRestParameterArrowFunctions.types @@ -0,0 +1,34 @@ +=== tests/cases/compiler/collisionRestParameterArrowFunctions.ts === +var f1 = (_i: number, ...restParameters) => { //_i is error +>f1 : (_i: number, ...restParameters: any[]) => void +>(_i: number, ...restParameters) => { //_i is error var _i = 10; // no error} : (_i: number, ...restParameters: any[]) => void +>_i : number +>restParameters : any[] + + var _i = 10; // no error +>_i : number +} +var f1NoError = (_i: number) => { // no error +>f1NoError : (_i: number) => void +>(_i: number) => { // no error var _i = 10; // no error} : (_i: number) => void +>_i : number + + var _i = 10; // no error +>_i : number +} + +var f2 = (...restParameters) => { +>f2 : (...restParameters: any[]) => void +>(...restParameters) => { var _i = 10; // No Error} : (...restParameters: any[]) => void +>restParameters : any[] + + var _i = 10; // No Error +>_i : number +} +var f2NoError = () => { +>f2NoError : () => void +>() => { var _i = 10; // no error} : () => void + + var _i = 10; // no error +>_i : number +} diff --git a/tests/baselines/reference/collisionRestParameterClassConstructor.errors.txt b/tests/baselines/reference/collisionRestParameterClassConstructor.errors.txt deleted file mode 100644 index a30b6d11d4b9e..0000000000000 --- a/tests/baselines/reference/collisionRestParameterClassConstructor.errors.txt +++ /dev/null @@ -1,78 +0,0 @@ -tests/cases/compiler/collisionRestParameterClassConstructor.ts(3,17): error TS2397: Duplicate identifier '_i'. Compiler uses '_i' to initialize rest parameter. -tests/cases/compiler/collisionRestParameterClassConstructor.ts(25,17): error TS2397: Duplicate identifier '_i'. Compiler uses '_i' to initialize rest parameter. -tests/cases/compiler/collisionRestParameterClassConstructor.ts(45,17): error TS2397: Duplicate identifier '_i'. Compiler uses '_i' to initialize rest parameter. - - -==== tests/cases/compiler/collisionRestParameterClassConstructor.ts (3 errors) ==== - // Constructors - class c1 { - constructor(_i: number, ...restParameters) { //_i is error - ~~~~~~~~~~ -!!! error TS2397: Duplicate identifier '_i'. Compiler uses '_i' to initialize rest parameter. - var _i = 10; // no error - } - } - class c1NoError { - constructor(_i: number) { // no error - var _i = 10; // no error - } - } - - class c2 { - constructor(...restParameters) { - var _i = 10; // no error - } - } - class c2NoError { - constructor() { - var _i = 10; // no error - } - } - - class c3 { - constructor(public _i: number, ...restParameters) { //_i is error - ~~~~~~~~~~~~~~~~~ -!!! error TS2397: Duplicate identifier '_i'. Compiler uses '_i' to initialize rest parameter. - var _i = 10; // no error - } - } - class c3NoError { - constructor(public _i: number) { // no error - var _i = 10; // no error - } - } - - declare class c4 { - constructor(_i: number, ...restParameters); // No error - no code gen - } - declare class c4NoError { - constructor(_i: number); // no error - } - - class c5 { - constructor(_i: number, ...rest); // no codegen no error - constructor(_i: string, ...rest); // no codegen no error - constructor(_i: any, ...rest) { // error - ~~~~~~~ -!!! error TS2397: Duplicate identifier '_i'. Compiler uses '_i' to initialize rest parameter. - var _i: any; // no error - } - } - - class c5NoError { - constructor(_i: number); // no error - constructor(_i: string); // no error - constructor(_i: any) { // no error - var _i: any; // no error - } - } - - declare class c6 { - constructor(_i: number, ...rest); // no codegen no error - constructor(_i: string, ...rest); // no codegen no error - } - - declare class c6NoError { - constructor(_i: number); // no error - constructor(_i: string); // no error - } \ No newline at end of file diff --git a/tests/baselines/reference/collisionRestParameterClassConstructor.js b/tests/baselines/reference/collisionRestParameterClassConstructor.js index 02c7ada9dff89..f109d6ba347fd 100644 --- a/tests/baselines/reference/collisionRestParameterClassConstructor.js +++ b/tests/baselines/reference/collisionRestParameterClassConstructor.js @@ -71,8 +71,8 @@ declare class c6NoError { var c1 = (function () { function c1(_i) { var restParameters = []; - for (var _i = 1; _i < arguments.length; _i++) { - restParameters[_i - 1] = arguments[_i]; + for (var _0 = 1; _0 < arguments.length; _0++) { + restParameters[_0 - 1] = arguments[_0]; } var _i = 10; // no error } @@ -87,8 +87,8 @@ var c1NoError = (function () { var c2 = (function () { function c2() { var restParameters = []; - for (var _i = 0; _i < arguments.length; _i++) { - restParameters[_i - 0] = arguments[_i]; + for (var _0 = 0; _0 < arguments.length; _0++) { + restParameters[_0 - 0] = arguments[_0]; } var _i = 10; // no error } @@ -103,8 +103,8 @@ var c2NoError = (function () { var c3 = (function () { function c3(_i) { var restParameters = []; - for (var _i = 1; _i < arguments.length; _i++) { - restParameters[_i - 1] = arguments[_i]; + for (var _0 = 1; _0 < arguments.length; _0++) { + restParameters[_0 - 1] = arguments[_0]; } this._i = _i; var _i = 10; // no error @@ -121,8 +121,8 @@ var c3NoError = (function () { var c5 = (function () { function c5(_i) { var rest = []; - for (var _i = 1; _i < arguments.length; _i++) { - rest[_i - 1] = arguments[_i]; + for (var _0 = 1; _0 < arguments.length; _0++) { + rest[_0 - 1] = arguments[_0]; } var _i; // no error } diff --git a/tests/baselines/reference/collisionRestParameterClassConstructor.types b/tests/baselines/reference/collisionRestParameterClassConstructor.types new file mode 100644 index 0000000000000..d0ceb9e074949 --- /dev/null +++ b/tests/baselines/reference/collisionRestParameterClassConstructor.types @@ -0,0 +1,137 @@ +=== tests/cases/compiler/collisionRestParameterClassConstructor.ts === +// Constructors +class c1 { +>c1 : c1 + + constructor(_i: number, ...restParameters) { //_i is error +>_i : number +>restParameters : any[] + + var _i = 10; // no error +>_i : number + } +} +class c1NoError { +>c1NoError : c1NoError + + constructor(_i: number) { // no error +>_i : number + + var _i = 10; // no error +>_i : number + } +} + +class c2 { +>c2 : c2 + + constructor(...restParameters) { +>restParameters : any[] + + var _i = 10; // no error +>_i : number + } +} +class c2NoError { +>c2NoError : c2NoError + + constructor() { + var _i = 10; // no error +>_i : number + } +} + +class c3 { +>c3 : c3 + + constructor(public _i: number, ...restParameters) { //_i is error +>_i : number +>restParameters : any[] + + var _i = 10; // no error +>_i : number + } +} +class c3NoError { +>c3NoError : c3NoError + + constructor(public _i: number) { // no error +>_i : number + + var _i = 10; // no error +>_i : number + } +} + +declare class c4 { +>c4 : c4 + + constructor(_i: number, ...restParameters); // No error - no code gen +>_i : number +>restParameters : any[] +} +declare class c4NoError { +>c4NoError : c4NoError + + constructor(_i: number); // no error +>_i : number +} + +class c5 { +>c5 : c5 + + constructor(_i: number, ...rest); // no codegen no error +>_i : number +>rest : any[] + + constructor(_i: string, ...rest); // no codegen no error +>_i : string +>rest : any[] + + constructor(_i: any, ...rest) { // error +>_i : any +>rest : any[] + + var _i: any; // no error +>_i : any + } +} + +class c5NoError { +>c5NoError : c5NoError + + constructor(_i: number); // no error +>_i : number + + constructor(_i: string); // no error +>_i : string + + constructor(_i: any) { // no error +>_i : any + + var _i: any; // no error +>_i : any + } +} + +declare class c6 { +>c6 : c6 + + constructor(_i: number, ...rest); // no codegen no error +>_i : number +>rest : any[] + + constructor(_i: string, ...rest); // no codegen no error +>_i : string +>rest : any[] +} + +declare class c6NoError { +>c6NoError : c6NoError + + constructor(_i: number); // no error +>_i : number + + constructor(_i: string); // no error +>_i : string +} diff --git a/tests/baselines/reference/collisionRestParameterClassMethod.errors.txt b/tests/baselines/reference/collisionRestParameterClassMethod.errors.txt deleted file mode 100644 index ac3fb1a556125..0000000000000 --- a/tests/baselines/reference/collisionRestParameterClassMethod.errors.txt +++ /dev/null @@ -1,47 +0,0 @@ -tests/cases/compiler/collisionRestParameterClassMethod.ts(2,16): error TS2397: Duplicate identifier '_i'. Compiler uses '_i' to initialize rest parameter. -tests/cases/compiler/collisionRestParameterClassMethod.ts(10,15): error TS2397: Duplicate identifier '_i'. Compiler uses '_i' to initialize rest parameter. - - -==== tests/cases/compiler/collisionRestParameterClassMethod.ts (2 errors) ==== - class c1 { - public foo(_i: number, ...restParameters) { //_i is error - ~~~~~~~~~~ -!!! error TS2397: Duplicate identifier '_i'. Compiler uses '_i' to initialize rest parameter. - var _i = 10; // no error - } - public fooNoError(_i: number) { // no error - var _i = 10; // no error - } - public f4(_i: number, ...rest); // no codegen no error - public f4(_i: string, ...rest); // no codegen no error - public f4(_i: any, ...rest) { // error - ~~~~~~~ -!!! error TS2397: Duplicate identifier '_i'. Compiler uses '_i' to initialize rest parameter. - var _i: any; // no error - } - - public f4NoError(_i: number); // no error - public f4NoError(_i: string); // no error - public f4NoError(_i: any) { // no error - var _i: any; // no error - } - } - - declare class c2 { - public foo(_i: number, ...restParameters); // No error - no code gen - public fooNoError(_i: number); // no error - - public f4(_i: number, ...rest); // no codegen no error - public f4(_i: string, ...rest); // no codegen no error - public f4NoError(_i: number); // no error - public f4NoError(_i: string); // no error - } - - class c3 { - public foo(...restParameters) { - var _i = 10; // no error - } - public fooNoError() { - var _i = 10; // no error - } - } \ No newline at end of file diff --git a/tests/baselines/reference/collisionRestParameterClassMethod.js b/tests/baselines/reference/collisionRestParameterClassMethod.js index 326ad0c424d92..592cb694cb8dc 100644 --- a/tests/baselines/reference/collisionRestParameterClassMethod.js +++ b/tests/baselines/reference/collisionRestParameterClassMethod.js @@ -44,8 +44,8 @@ var c1 = (function () { } c1.prototype.foo = function (_i) { var restParameters = []; - for (var _i = 1; _i < arguments.length; _i++) { - restParameters[_i - 1] = arguments[_i]; + for (var _0 = 1; _0 < arguments.length; _0++) { + restParameters[_0 - 1] = arguments[_0]; } var _i = 10; // no error }; @@ -54,8 +54,8 @@ var c1 = (function () { }; c1.prototype.f4 = function (_i) { var rest = []; - for (var _i = 1; _i < arguments.length; _i++) { - rest[_i - 1] = arguments[_i]; + for (var _0 = 1; _0 < arguments.length; _0++) { + rest[_0 - 1] = arguments[_0]; } var _i; // no error }; @@ -69,8 +69,8 @@ var c3 = (function () { } c3.prototype.foo = function () { var restParameters = []; - for (var _i = 0; _i < arguments.length; _i++) { - restParameters[_i - 0] = arguments[_i]; + for (var _0 = 0; _0 < arguments.length; _0++) { + restParameters[_0 - 0] = arguments[_0]; } var _i = 10; // no error }; diff --git a/tests/baselines/reference/collisionRestParameterClassMethod.types b/tests/baselines/reference/collisionRestParameterClassMethod.types new file mode 100644 index 0000000000000..2a4c23ae5a9ff --- /dev/null +++ b/tests/baselines/reference/collisionRestParameterClassMethod.types @@ -0,0 +1,103 @@ +=== tests/cases/compiler/collisionRestParameterClassMethod.ts === +class c1 { +>c1 : c1 + + public foo(_i: number, ...restParameters) { //_i is error +>foo : (_i: number, ...restParameters: any[]) => void +>_i : number +>restParameters : any[] + + var _i = 10; // no error +>_i : number + } + public fooNoError(_i: number) { // no error +>fooNoError : (_i: number) => void +>_i : number + + var _i = 10; // no error +>_i : number + } + public f4(_i: number, ...rest); // no codegen no error +>f4 : { (_i: number, ...rest: any[]): any; (_i: string, ...rest: any[]): any; } +>_i : number +>rest : any[] + + public f4(_i: string, ...rest); // no codegen no error +>f4 : { (_i: number, ...rest: any[]): any; (_i: string, ...rest: any[]): any; } +>_i : string +>rest : any[] + + public f4(_i: any, ...rest) { // error +>f4 : { (_i: number, ...rest: any[]): any; (_i: string, ...rest: any[]): any; } +>_i : any +>rest : any[] + + var _i: any; // no error +>_i : any + } + + public f4NoError(_i: number); // no error +>f4NoError : { (_i: number): any; (_i: string): any; } +>_i : number + + public f4NoError(_i: string); // no error +>f4NoError : { (_i: number): any; (_i: string): any; } +>_i : string + + public f4NoError(_i: any) { // no error +>f4NoError : { (_i: number): any; (_i: string): any; } +>_i : any + + var _i: any; // no error +>_i : any + } +} + +declare class c2 { +>c2 : c2 + + public foo(_i: number, ...restParameters); // No error - no code gen +>foo : (_i: number, ...restParameters: any[]) => any +>_i : number +>restParameters : any[] + + public fooNoError(_i: number); // no error +>fooNoError : (_i: number) => any +>_i : number + + public f4(_i: number, ...rest); // no codegen no error +>f4 : { (_i: number, ...rest: any[]): any; (_i: string, ...rest: any[]): any; } +>_i : number +>rest : any[] + + public f4(_i: string, ...rest); // no codegen no error +>f4 : { (_i: number, ...rest: any[]): any; (_i: string, ...rest: any[]): any; } +>_i : string +>rest : any[] + + public f4NoError(_i: number); // no error +>f4NoError : { (_i: number): any; (_i: string): any; } +>_i : number + + public f4NoError(_i: string); // no error +>f4NoError : { (_i: number): any; (_i: string): any; } +>_i : string +} + +class c3 { +>c3 : c3 + + public foo(...restParameters) { +>foo : (...restParameters: any[]) => void +>restParameters : any[] + + var _i = 10; // no error +>_i : number + } + public fooNoError() { +>fooNoError : () => void + + var _i = 10; // no error +>_i : number + } +} diff --git a/tests/baselines/reference/collisionRestParameterFunction.errors.txt b/tests/baselines/reference/collisionRestParameterFunction.errors.txt deleted file mode 100644 index 88a98b9c77835..0000000000000 --- a/tests/baselines/reference/collisionRestParameterFunction.errors.txt +++ /dev/null @@ -1,42 +0,0 @@ -tests/cases/compiler/collisionRestParameterFunction.ts(2,13): error TS2397: Duplicate identifier '_i'. Compiler uses '_i' to initialize rest parameter. -tests/cases/compiler/collisionRestParameterFunction.ts(21,13): error TS2397: Duplicate identifier '_i'. Compiler uses '_i' to initialize rest parameter. - - -==== tests/cases/compiler/collisionRestParameterFunction.ts (2 errors) ==== - // Functions - function f1(_i: number, ...restParameters) { //_i is error - ~~~~~~~~~~ -!!! error TS2397: Duplicate identifier '_i'. Compiler uses '_i' to initialize rest parameter. - var _i = 10; // no error - } - function f1NoError(_i: number) { // no error - var _i = 10; // no error - } - - declare function f2(_i: number, ...restParameters); // no error - no code gen - declare function f2NoError(_i: number); // no error - - function f3(...restParameters) { - var _i = 10; // no error - } - function f3NoError() { - var _i = 10; // no error - } - - function f4(_i: number, ...rest); // no codegen no error - function f4(_i: string, ...rest); // no codegen no error - function f4(_i: any, ...rest) { // error - ~~~~~~~ -!!! error TS2397: Duplicate identifier '_i'. Compiler uses '_i' to initialize rest parameter. - } - - function f4NoError(_i: number); // no error - function f4NoError(_i: string); // no error - function f4NoError(_i: any) { // no error - } - - declare function f5(_i: number, ...rest); // no codegen no error - declare function f5(_i: string, ...rest); // no codegen no error - - declare function f6(_i: number); // no codegen no error - declare function f6(_i: string); // no codegen no error \ No newline at end of file diff --git a/tests/baselines/reference/collisionRestParameterFunction.js b/tests/baselines/reference/collisionRestParameterFunction.js index c81dbb0f8d3dc..5e4bfd2e7ba89 100644 --- a/tests/baselines/reference/collisionRestParameterFunction.js +++ b/tests/baselines/reference/collisionRestParameterFunction.js @@ -37,8 +37,8 @@ declare function f6(_i: string); // no codegen no error // Functions function f1(_i) { var restParameters = []; - for (var _i = 1; _i < arguments.length; _i++) { - restParameters[_i - 1] = arguments[_i]; + for (var _0 = 1; _0 < arguments.length; _0++) { + restParameters[_0 - 1] = arguments[_0]; } var _i = 10; // no error } @@ -47,8 +47,8 @@ function f1NoError(_i) { } function f3() { var restParameters = []; - for (var _i = 0; _i < arguments.length; _i++) { - restParameters[_i - 0] = arguments[_i]; + for (var _0 = 0; _0 < arguments.length; _0++) { + restParameters[_0 - 0] = arguments[_0]; } var _i = 10; // no error } @@ -57,8 +57,8 @@ function f3NoError() { } function f4(_i) { var rest = []; - for (var _i = 1; _i < arguments.length; _i++) { - rest[_i - 1] = arguments[_i]; + for (var _0 = 1; _0 < arguments.length; _0++) { + rest[_0 - 1] = arguments[_0]; } } function f4NoError(_i) { diff --git a/tests/baselines/reference/collisionRestParameterFunction.types b/tests/baselines/reference/collisionRestParameterFunction.types new file mode 100644 index 0000000000000..f0d8abeac9d60 --- /dev/null +++ b/tests/baselines/reference/collisionRestParameterFunction.types @@ -0,0 +1,88 @@ +=== tests/cases/compiler/collisionRestParameterFunction.ts === +// Functions +function f1(_i: number, ...restParameters) { //_i is error +>f1 : (_i: number, ...restParameters: any[]) => void +>_i : number +>restParameters : any[] + + var _i = 10; // no error +>_i : number +} +function f1NoError(_i: number) { // no error +>f1NoError : (_i: number) => void +>_i : number + + var _i = 10; // no error +>_i : number +} + +declare function f2(_i: number, ...restParameters); // no error - no code gen +>f2 : (_i: number, ...restParameters: any[]) => any +>_i : number +>restParameters : any[] + +declare function f2NoError(_i: number); // no error +>f2NoError : (_i: number) => any +>_i : number + +function f3(...restParameters) { +>f3 : (...restParameters: any[]) => void +>restParameters : any[] + + var _i = 10; // no error +>_i : number +} +function f3NoError() { +>f3NoError : () => void + + var _i = 10; // no error +>_i : number +} + +function f4(_i: number, ...rest); // no codegen no error +>f4 : { (_i: number, ...rest: any[]): any; (_i: string, ...rest: any[]): any; } +>_i : number +>rest : any[] + +function f4(_i: string, ...rest); // no codegen no error +>f4 : { (_i: number, ...rest: any[]): any; (_i: string, ...rest: any[]): any; } +>_i : string +>rest : any[] + +function f4(_i: any, ...rest) { // error +>f4 : { (_i: number, ...rest: any[]): any; (_i: string, ...rest: any[]): any; } +>_i : any +>rest : any[] +} + +function f4NoError(_i: number); // no error +>f4NoError : { (_i: number): any; (_i: string): any; } +>_i : number + +function f4NoError(_i: string); // no error +>f4NoError : { (_i: number): any; (_i: string): any; } +>_i : string + +function f4NoError(_i: any) { // no error +>f4NoError : { (_i: number): any; (_i: string): any; } +>_i : any +} + +declare function f5(_i: number, ...rest); // no codegen no error +>f5 : { (_i: number, ...rest: any[]): any; (_i: string, ...rest: any[]): any; } +>_i : number +>rest : any[] + +declare function f5(_i: string, ...rest); // no codegen no error +>f5 : { (_i: number, ...rest: any[]): any; (_i: string, ...rest: any[]): any; } +>_i : string +>rest : any[] + +declare function f6(_i: number); // no codegen no error +>f6 : { (_i: number): any; (_i: string): any; } +>_i : number + +declare function f6(_i: string); // no codegen no error +>f6 : { (_i: number): any; (_i: string): any; } +>_i : string + diff --git a/tests/baselines/reference/collisionRestParameterFunctionExpressions.errors.txt b/tests/baselines/reference/collisionRestParameterFunctionExpressions.errors.txt deleted file mode 100644 index c2c237f98b3b8..0000000000000 --- a/tests/baselines/reference/collisionRestParameterFunctionExpressions.errors.txt +++ /dev/null @@ -1,33 +0,0 @@ -tests/cases/compiler/collisionRestParameterFunctionExpressions.ts(2,17): error TS2397: Duplicate identifier '_i'. Compiler uses '_i' to initialize rest parameter. -tests/cases/compiler/collisionRestParameterFunctionExpressions.ts(17,17): error TS2397: Duplicate identifier '_i'. Compiler uses '_i' to initialize rest parameter. - - -==== tests/cases/compiler/collisionRestParameterFunctionExpressions.ts (2 errors) ==== - function foo() { - function f1(_i: number, ...restParameters) { //_i is error - ~~~~~~~~~~ -!!! error TS2397: Duplicate identifier '_i'. Compiler uses '_i' to initialize rest parameter. - var _i = 10; // no error - } - function f1NoError(_i: number) { // no error - var _i = 10; // no error - } - function f3(...restParameters) { - var _i = 10; // no error - } - function f3NoError() { - var _i = 10; // no error - } - - function f4(_i: number, ...rest); // no codegen no error - function f4(_i: string, ...rest); // no codegen no error - function f4(_i: any, ...rest) { // error - ~~~~~~~ -!!! error TS2397: Duplicate identifier '_i'. Compiler uses '_i' to initialize rest parameter. - } - - function f4NoError(_i: number); // no error - function f4NoError(_i: string); // no error - function f4NoError(_i: any) { // no error - } - } \ No newline at end of file diff --git a/tests/baselines/reference/collisionRestParameterFunctionExpressions.js b/tests/baselines/reference/collisionRestParameterFunctionExpressions.js index 4f1dea2b11ea8..894854f2fb850 100644 --- a/tests/baselines/reference/collisionRestParameterFunctionExpressions.js +++ b/tests/baselines/reference/collisionRestParameterFunctionExpressions.js @@ -28,8 +28,8 @@ function foo() { function foo() { function f1(_i) { var restParameters = []; - for (var _i = 1; _i < arguments.length; _i++) { - restParameters[_i - 1] = arguments[_i]; + for (var _0 = 1; _0 < arguments.length; _0++) { + restParameters[_0 - 1] = arguments[_0]; } var _i = 10; // no error } @@ -38,8 +38,8 @@ function foo() { } function f3() { var restParameters = []; - for (var _i = 0; _i < arguments.length; _i++) { - restParameters[_i - 0] = arguments[_i]; + for (var _0 = 0; _0 < arguments.length; _0++) { + restParameters[_0 - 0] = arguments[_0]; } var _i = 10; // no error } @@ -48,8 +48,8 @@ function foo() { } function f4(_i) { var rest = []; - for (var _i = 1; _i < arguments.length; _i++) { - rest[_i - 1] = arguments[_i]; + for (var _0 = 1; _0 < arguments.length; _0++) { + rest[_0 - 1] = arguments[_0]; } } function f4NoError(_i) { diff --git a/tests/baselines/reference/collisionRestParameterFunctionExpressions.types b/tests/baselines/reference/collisionRestParameterFunctionExpressions.types new file mode 100644 index 0000000000000..c6c52390894b6 --- /dev/null +++ b/tests/baselines/reference/collisionRestParameterFunctionExpressions.types @@ -0,0 +1,62 @@ +=== tests/cases/compiler/collisionRestParameterFunctionExpressions.ts === +function foo() { +>foo : () => void + + function f1(_i: number, ...restParameters) { //_i is error +>f1 : (_i: number, ...restParameters: any[]) => void +>_i : number +>restParameters : any[] + + var _i = 10; // no error +>_i : number + } + function f1NoError(_i: number) { // no error +>f1NoError : (_i: number) => void +>_i : number + + var _i = 10; // no error +>_i : number + } + function f3(...restParameters) { +>f3 : (...restParameters: any[]) => void +>restParameters : any[] + + var _i = 10; // no error +>_i : number + } + function f3NoError() { +>f3NoError : () => void + + var _i = 10; // no error +>_i : number + } + + function f4(_i: number, ...rest); // no codegen no error +>f4 : { (_i: number, ...rest: any[]): any; (_i: string, ...rest: any[]): any; } +>_i : number +>rest : any[] + + function f4(_i: string, ...rest); // no codegen no error +>f4 : { (_i: number, ...rest: any[]): any; (_i: string, ...rest: any[]): any; } +>_i : string +>rest : any[] + + function f4(_i: any, ...rest) { // error +>f4 : { (_i: number, ...rest: any[]): any; (_i: string, ...rest: any[]): any; } +>_i : any +>rest : any[] + } + + function f4NoError(_i: number); // no error +>f4NoError : { (_i: number): any; (_i: string): any; } +>_i : number + + function f4NoError(_i: string); // no error +>f4NoError : { (_i: number): any; (_i: string): any; } +>_i : string + + function f4NoError(_i: any) { // no error +>f4NoError : { (_i: number): any; (_i: string): any; } +>_i : any + } +} diff --git a/tests/baselines/reference/collisionRestParameterUnderscoreIUsage.errors.txt b/tests/baselines/reference/collisionRestParameterUnderscoreIUsage.errors.txt deleted file mode 100644 index 08df732096b37..0000000000000 --- a/tests/baselines/reference/collisionRestParameterUnderscoreIUsage.errors.txt +++ /dev/null @@ -1,14 +0,0 @@ -tests/cases/compiler/collisionRestParameterUnderscoreIUsage.ts(5,21): error TS2398: Expression resolves to variable declaration '_i' that compiler uses to initialize rest parameter. - - -==== tests/cases/compiler/collisionRestParameterUnderscoreIUsage.ts (1 errors) ==== - declare var console: { log(msg?: string): void; }; - var _i = "This is what I'd expect to see"; - class Foo { - constructor(...args: any[]) { - console.log(_i); // This should result in error - ~~ -!!! error TS2398: Expression resolves to variable declaration '_i' that compiler uses to initialize rest parameter. - } - } - new Foo(); \ No newline at end of file diff --git a/tests/baselines/reference/collisionRestParameterUnderscoreIUsage.js b/tests/baselines/reference/collisionRestParameterUnderscoreIUsage.js index b8d3aaec91c4a..4055bcd81abaa 100644 --- a/tests/baselines/reference/collisionRestParameterUnderscoreIUsage.js +++ b/tests/baselines/reference/collisionRestParameterUnderscoreIUsage.js @@ -13,8 +13,8 @@ var _i = "This is what I'd expect to see"; var Foo = (function () { function Foo() { var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i - 0] = arguments[_i]; + for (var _0 = 0; _0 < arguments.length; _0++) { + args[_0 - 0] = arguments[_0]; } console.log(_i); // This should result in error } diff --git a/tests/baselines/reference/collisionRestParameterUnderscoreIUsage.types b/tests/baselines/reference/collisionRestParameterUnderscoreIUsage.types new file mode 100644 index 0000000000000..c700f50aca4f2 --- /dev/null +++ b/tests/baselines/reference/collisionRestParameterUnderscoreIUsage.types @@ -0,0 +1,27 @@ +=== tests/cases/compiler/collisionRestParameterUnderscoreIUsage.ts === +declare var console: { log(msg?: string): void; }; +>console : { log(msg?: string): void; } +>log : (msg?: string) => void +>msg : string + +var _i = "This is what I'd expect to see"; +>_i : string + +class Foo { +>Foo : Foo + + constructor(...args: any[]) { +>args : any[] + + console.log(_i); // This should result in error +>console.log(_i) : void +>console.log : (msg?: string) => void +>console : { log(msg?: string): void; } +>log : (msg?: string) => void +>_i : string + } +} +new Foo(); +>new Foo() : Foo +>Foo : typeof Foo + From 3ff2a628925c8324e05f2131ebe0af204b3d5766 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 30 Nov 2014 09:11:18 -0800 Subject: [PATCH 22/33] Allow assignment expressions as destructuring assignment target --- src/compiler/checker.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c60abea743c31..3d40bb6ec3ff2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6441,6 +6441,10 @@ module ts { } function checkDestructuringAssignment(target: Expression, sourceType: Type, contextualMapper?: TypeMapper): Type { + if (target.kind === SyntaxKind.BinaryExpression && (target).operator === SyntaxKind.EqualsToken) { + checkBinaryExpression(target, contextualMapper); + target = (target).left; + } if (target.kind === SyntaxKind.ObjectLiteral) { return checkObjectLiteralAssignment(target, sourceType, contextualMapper); } From 9e639113f8f74c7d8316f41948b52a55737063fd Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 2 Dec 2014 11:39:04 -0800 Subject: [PATCH 23/33] Emit for destructuring assignments --- src/compiler/emitter.ts | 257 +++++++++++++++++++++++++++++----------- 1 file changed, 187 insertions(+), 70 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 3e462729dd4c5..78ab8d6ba4796 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -323,6 +323,7 @@ module ts { var extendsEmitted = false; var tempCount = 0; + var tempNames: Identifier[]; /** write emitted output to disk*/ var writeEmittedFiles = writeJavaScriptFile; @@ -719,12 +720,35 @@ module ts { function getTempVariableName(location: Node) { do { - var name = "_" + tempCount++; + // First _a..._z, then _0, _1, ... + var name = "_" + (tempCount < 26 ? String.fromCharCode(tempCount + 0x61) : tempCount - 26); + tempCount++; } while (!resolver.isUnknownIdentifier(location, name)); return name; } + function recordTempDeclaration(name: Identifier) { + if (!tempNames) { + tempNames = []; + } + tempNames.push(name); + } + + function emitTempDeclarations(newLine: boolean) { + if (tempNames) { + if (newLine) { + writeLine(); + } + else { + write(" "); + } + write("var "); + emitCommaList(tempNames); + write(";"); + } + } + function emitTokenText(tokenKind: SyntaxKind, startPos: number, emitFn?: () => void) { var tokenString = tokenToString(tokenKind); if (emitFn) { @@ -743,16 +767,13 @@ module ts { } } - function emitTrailingCommaIfPresent(nodeList: NodeArray, isMultiline: boolean): void { + function emitTrailingCommaIfPresent(nodeList: NodeArray): void { if (nodeList.hasTrailingComma) { write(","); - if (isMultiline) { - writeLine(); - } } } - function emitCommaList(nodes: NodeArray, includeTrailingComma: boolean, count?: number) { + function emitCommaList(nodes: Node[], count?: number) { if (!(count >= 0)) { count = nodes.length; } @@ -763,14 +784,10 @@ module ts { } emit(nodes[i]); } - - if (includeTrailingComma) { - emitTrailingCommaIfPresent(nodes, /*isMultiline*/ false); - } } } - function emitMultiLineList(nodes: NodeArray, includeTrailingComma: boolean) { + function emitMultiLineList(nodes: Node[]) { if (nodes) { for (var i = 0; i < nodes.length; i++) { if (i) { @@ -779,10 +796,6 @@ module ts { writeLine(); emit(nodes[i]); } - - if (includeTrailingComma) { - emitTrailingCommaIfPresent(nodes, /*isMultiline*/ true); - } } } @@ -1018,13 +1031,15 @@ module ts { function emitObjectBindingPattern(node: BindingPattern) { write("{ "); - emitCommaList(node.elements, /*includeTrailingComma*/ true); + emitCommaList(node.elements); + emitTrailingCommaIfPresent(node.elements); write(" }"); } function emitArrayBindingPattern(node: BindingPattern) { write("["); - emitCommaList(node.elements, /*includeTrailingComma*/ true); + emitCommaList(node.elements); + emitTrailingCommaIfPresent(node.elements); write("]"); } @@ -1032,14 +1047,16 @@ module ts { if (node.flags & NodeFlags.MultiLine) { write("["); increaseIndent(); - emitMultiLineList(node.elements, /*includeTrailingComma*/ true); + emitMultiLineList(node.elements); + emitTrailingCommaIfPresent(node.elements); decreaseIndent(); writeLine(); write("]"); } else { write("["); - emitCommaList(node.elements, /*includeTrailingComma*/ true); + emitCommaList(node.elements); + emitTrailingCommaIfPresent(node.elements); write("]"); } } @@ -1051,14 +1068,20 @@ module ts { else if (node.flags & NodeFlags.MultiLine) { write("{"); increaseIndent(); - emitMultiLineList(node.properties, /*includeTrailingComma*/ compilerOptions.target >= ScriptTarget.ES5); + emitMultiLineList(node.properties); + if (compilerOptions.target >= ScriptTarget.ES5) { + emitTrailingCommaIfPresent(node.properties); + } decreaseIndent(); writeLine(); write("}"); } else { write("{ "); - emitCommaList(node.properties, /*includeTrailingComma*/ compilerOptions.target >= ScriptTarget.ES5); + emitCommaList(node.properties); + if (compilerOptions.target >= ScriptTarget.ES5) { + emitTrailingCommaIfPresent(node.properties); + } write(" }"); } } @@ -1145,13 +1168,13 @@ module ts { emitThis(node.func); if (node.arguments.length) { write(", "); - emitCommaList(node.arguments, /*includeTrailingComma*/ false); + emitCommaList(node.arguments); } write(")"); } else { write("("); - emitCommaList(node.arguments, /*includeTrailingComma*/ false); + emitCommaList(node.arguments); write(")"); } } @@ -1161,7 +1184,7 @@ module ts { emit(node.func); if (node.arguments) { write("("); - emitCommaList(node.arguments, /*includeTrailingComma*/ false); + emitCommaList(node.arguments); write(")"); } } @@ -1238,11 +1261,16 @@ module ts { } function emitBinaryExpression(node: BinaryExpression) { - emit(node.left); - if (node.operator !== SyntaxKind.CommaToken) write(" "); - write(tokenToString(node.operator)); - write(" "); - emit(node.right); + if (node.operator === SyntaxKind.EqualsToken && (node.left.kind === SyntaxKind.ObjectLiteral || node.left.kind === SyntaxKind.ArrayLiteral)) { + emitDestructuring(node); + } + else { + emit(node.left); + if (node.operator !== SyntaxKind.CommaToken) write(" "); + write(tokenToString(node.operator)); + write(" "); + emit(node.right); + } } function emitConditionalExpression(node: ConditionalExpression) { @@ -1262,6 +1290,9 @@ module ts { emitCaptureThisForNodeIfNecessary(node.parent); } emitLines(node.statements); + if (node.kind === SyntaxKind.ModuleBlock) { + emitTempDeclarations(/*newLine*/ true); + } decreaseIndent(); writeLine(); emitToken(SyntaxKind.CloseBraceToken, node.statements.end); @@ -1349,7 +1380,7 @@ module ts { emitToken(SyntaxKind.VarKeyword, endPos); } write(" "); - emitCommaList(node.declarations, /*includeTrailingComma*/ false); + emitCommaList(node.declarations); } if (node.initializer) { emit(node.initializer); @@ -1503,26 +1534,36 @@ module ts { emitEnd(node.name); } - // Rewrites a destructuring variable declaration into a sequence of regular variable declarations. - // Nodes generated by the syntactic rewrite have no parent references. - function rewriteDestructuringDeclaration(node: VariableDeclaration): NodeArray { - var declarations = >[]; - rewriteDeclaration(node, undefined); - return declarations; + function emitDestructuring(root: BinaryExpression | BindingElement) { + var emitCount = 0; + if (root.kind === SyntaxKind.BinaryExpression) { + emitAssignmentExpression(root); + } + else { + emitBindingElement(root, undefined); + } - function addVariableDeclaration(name: Identifier, initializer: Expression) { - var node = createNode(SyntaxKind.VariableDeclaration); - node.name = name; - node.initializer = initializer; - declarations.push(node); + function emitAssignment(name: Identifier, value: Expression) { + if (emitCount++) { + write(", "); + } + emit(name); + write(" = "); + emit(value); } function createTemporaryVariable(expr: Expression): Expression { - var tempName = getTempVariableName(node); - var identifier = createNode(SyntaxKind.Identifier); - identifier.text = tempName; - addVariableDeclaration(identifier, expr); - return identifier; + if (expr.kind !== SyntaxKind.Identifier) { + var tempName = getTempVariableName(root); + var identifier = createNode(SyntaxKind.Identifier); + identifier.text = tempName; + emitAssignment(identifier, expr); + if (root.kind === SyntaxKind.BinaryExpression) { + recordTempDeclaration(identifier); + } + expr = identifier; + } + return expr; } function createVoidZero(): Expression { @@ -1537,9 +1578,7 @@ module ts { function createDefaultValueCheck(value: Expression, defaultValue: Expression): Expression { // The value expression will be evaluated twice, so for anything but a simple identifier // we need to generate a temporary variable - if (value.kind !== SyntaxKind.Identifier) { - value = createTemporaryVariable(value); - } + value = createTemporaryVariable(value); // Return the expression 'value === void 0 ? defaultValue : value' var equals = createNode(SyntaxKind.BinaryExpression); equals.left = value; @@ -1584,7 +1623,75 @@ module ts { return node; } - function rewriteDeclaration(target: BindingElement, value: Expression) { + function emitObjectLiteralAssignment(target: ObjectLiteral, value: Expression) { + var properties = target.properties; + if (properties.length !== 1) { + // For anything but a single element destructuring we need to generate a temporary + // to ensure value is evaluated exactly once. + value = createTemporaryVariable(value); + } + for (var i = 0; i < properties.length; i++) { + var p = properties[i]; + if (p.kind === SyntaxKind.PropertyAssignment || p.kind === SyntaxKind.ShorthandPropertyAssignment) { + // TODO(andersh): Computed property support + var propName = ((p).name); + emitDestructuringAssignment((p).initializer || propName, createPropertyAccess(value, propName)); + } + } + } + + function emitArrayLiteralAssignment(target: ArrayLiteral, value: Expression) { + var elements = target.elements; + if (elements.length !== 1) { + // For anything but a single element destructuring we need to generate a temporary + // to ensure value is evaluated exactly once. + value = createTemporaryVariable(value); + } + for (var i = 0; i < elements.length; i++) { + var e = elements[i]; + if (e.kind !== SyntaxKind.OmittedExpression) { + emitDestructuringAssignment(e, createIndexedAccess(value, createNumericLiteral(i))); + } + } + } + + function emitDestructuringAssignment(target: Expression, value: Expression) { + if (target.kind === SyntaxKind.BinaryExpression && (target).operator === SyntaxKind.EqualsToken) { + value = createDefaultValueCheck(value, (target).right); + target = (target).left; + } + if (target.kind === SyntaxKind.ObjectLiteral) { + emitObjectLiteralAssignment(target, value); + } + else if (target.kind === SyntaxKind.ArrayLiteral) { + emitArrayLiteralAssignment(target, value); + } + else { + emitAssignment(target, value); + } + } + + function emitAssignmentExpression(root: BinaryExpression) { + var target = root.left; + var value = root.right; + if (root.parent.kind === SyntaxKind.ExpressionStatement) { + emitDestructuringAssignment(target, value); + } + else { + if (root.parent.kind !== SyntaxKind.ParenExpression) { + write("("); + } + value = createTemporaryVariable(value); + emitDestructuringAssignment(target, value); + write(", "); + emit(value); + if (root.parent.kind !== SyntaxKind.ParenExpression) { + write(")"); + } + } + } + + function emitBindingElement(target: BindingElement, value: Expression) { if (target.initializer) { // Combine value and initializer value = value ? createDefaultValueCheck(value, target.initializer) : target.initializer; @@ -1606,36 +1713,30 @@ module ts { if (pattern.kind === SyntaxKind.ObjectBindingPattern) { // Rewrite element to a declaration with an initializer that fetches property var propName = element.propertyName || element.name; - rewriteDeclaration(element, createPropertyAccess(value, propName)); + emitBindingElement(element, createPropertyAccess(value, propName)); } else if (element.kind !== SyntaxKind.OmittedExpression) { // Rewrite element to a declaration that accesses array element at index i - rewriteDeclaration(element, createIndexedAccess(value, createNumericLiteral(i))); + emitBindingElement(element, createIndexedAccess(value, createNumericLiteral(i))); } } } else { - addVariableDeclaration(target.name, value); + emitAssignment(target.name, value); } } } function emitVariableDeclaration(node: VariableDeclaration) { - if (node.parent) { - emitLeadingComments(node); - if (isBindingPattern(node.name)) { - emitCommaList(rewriteDestructuringDeclaration(node), /*includeTrailingComma*/ false); - } - else { - emitModuleMemberName(node); - emitOptional(" = ", node.initializer); - } - emitTrailingComments(node); + emitLeadingComments(node); + if (isBindingPattern(node.name)) { + emitDestructuring(node); } else { - emit(node.name); + emitModuleMemberName(node); emitOptional(" = ", node.initializer); } + emitTrailingComments(node); } function emitVariableStatement(node: VariableStatement) { @@ -1651,7 +1752,7 @@ module ts { write("var "); } } - emitCommaList(node.declarations, /*includeTrailingComma*/ false); + emitCommaList(node.declarations); write(";"); emitTrailingComments(node); } @@ -1701,7 +1802,7 @@ module ts { if (hasRestParameters(node)) { var restIndex = node.parameters.length - 1; var restParam = node.parameters[restIndex]; - var tempName = resolver.isUnknownIdentifier(node, "_i") ? "_i" : getTempVariableName(node); + var tempName = getTempVariableName(node); writeLine(); emitLeadingComments(restParam); emitStart(restParam); @@ -1776,7 +1877,7 @@ module ts { increaseIndent(); write("("); if (node) { - emitCommaList(node.parameters, /*includeTrailingComma*/ false, node.parameters.length - (hasRestParameters(node) ? 1 : 0)); + emitCommaList(node.parameters, node.parameters.length - (hasRestParameters(node) ? 1 : 0)); } write(")"); decreaseIndent(); @@ -1786,6 +1887,9 @@ module ts { emitSignatureParameters(node); write(" {"); var saveTempCount = tempCount; + var saveTempNames = tempNames; + tempCount = 0; + tempNames = undefined; scopeEmitStart(node); increaseIndent(); @@ -1806,7 +1910,9 @@ module ts { write("return "); emitNode(node.body); emitEnd(node.body); - write("; "); + write(";"); + emitTempDeclarations(/*newLine*/ false); + write(" "); emitStart(node.body); write("}"); emitEnd(node.body); @@ -1823,6 +1929,7 @@ module ts { write(";"); emitTrailingComments(node.body); } + emitTempDeclarations(/*newLine*/ true); writeLine(); if (node.body.kind === SyntaxKind.FunctionBlock) { emitLeadingCommentsOfPosition((node.body).statements.end); @@ -1838,6 +1945,7 @@ module ts { } scopeEmitEnd(); tempCount = saveTempCount; + tempNames = saveTempNames; if (node.flags & NodeFlags.Export) { writeLine(); emitStart(node); @@ -2064,6 +2172,9 @@ module ts { emitSignatureParameters(ctor); write(" {"); var saveTempCount = tempCount; + var saveTempNames = tempNames; + tempCount = 0; + tempNames = undefined; scopeEmitStart(node, "constructor"); increaseIndent(); if (ctor) { @@ -2096,6 +2207,7 @@ module ts { if (superCall) statements = statements.slice(1); emitLines(statements); } + emitTempDeclarations(/*newLine*/ true); writeLine(); if (ctor) { emitLeadingCommentsOfPosition((ctor.body).statements.end); @@ -2104,6 +2216,7 @@ module ts { emitToken(SyntaxKind.CloseBraceToken, ctor ? (ctor.body).statements.end : node.members.end); scopeEmitEnd(); tempCount = saveTempCount; + tempNames = saveTempNames; emitEnd(ctor || node); if (ctor) { emitTrailingComments(ctor); @@ -2211,9 +2324,14 @@ module ts { write(resolver.getLocalNameOfContainer(node)); emitEnd(node.name); write(") "); - var saveTempCount = tempCount; if (node.body.kind === SyntaxKind.ModuleBlock) { + var saveTempCount = tempCount; + var saveTempNames = tempNames; + tempCount = 0; + tempNames = undefined; emit(node.body); + tempCount = saveTempCount; + tempNames = saveTempNames; } else { write("{"); @@ -2228,7 +2346,6 @@ module ts { emitToken(SyntaxKind.CloseBraceToken, moduleBlock.statements.end); scopeEmitEnd(); } - tempCount = saveTempCount; write(")("); if (node.flags & NodeFlags.Export) { emit(node.name); From ab35da9b87ba8a2ebc84e3fadd8eab3849348eeb Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 2 Dec 2014 11:49:28 -0800 Subject: [PATCH 24/33] Baseline changes from updating rest parameter emit to use new temporary names --- .../arrayLiteralInNonVarArgParameter.js | 4 +-- ...patWithCallSignaturesWithRestParameters.js | 28 ++++++++-------- .../reference/baseTypeAfterDerivedType.js | 4 +-- .../collisionArgumentsArrowFunctions.js | 12 +++---- .../collisionArgumentsClassConstructor.js | 24 +++++++------- .../collisionArgumentsClassMethod.js | 20 ++++++------ .../reference/collisionArgumentsFunction.js | 20 ++++++------ .../collisionArgumentsFunctionExpressions.js | 20 ++++++------ .../collisionRestParameterArrowFunctions.js | 8 ++--- .../collisionRestParameterClassConstructor.js | 16 +++++----- .../collisionRestParameterClassMethod.js | 12 +++---- .../collisionRestParameterFunction.js | 12 +++---- ...llisionRestParameterFunctionExpressions.js | 12 +++---- .../collisionRestParameterUnderscoreIUsage.js | 4 +-- .../contextuallyTypingRestParameters.js | 4 +-- .../reference/declFileConstructors.js | 8 ++--- .../baselines/reference/declFileFunctions.js | 12 +++---- tests/baselines/reference/declFileMethods.js | 32 +++++++++---------- ...RestParametersOfFunctionAndFunctionType.js | 4 +-- ...detachedCommentAtStartOfLambdaFunction1.js | 4 +-- ...detachedCommentAtStartOfLambdaFunction2.js | 4 +-- tests/baselines/reference/funcdecl.js | 4 +-- tests/baselines/reference/functionCall10.js | 4 +-- tests/baselines/reference/functionCall13.js | 4 +-- tests/baselines/reference/functionCall14.js | 4 +-- tests/baselines/reference/functionCall15.js | 4 +-- tests/baselines/reference/functionCall16.js | 4 +-- tests/baselines/reference/functionCall17.js | 4 +-- ...tionOverloadsRecursiveGenericReturnType.js | 4 +-- tests/baselines/reference/genericRestArgs.js | 4 +-- ...icitAnyDeclareFunctionWithoutFormalType.js | 4 +-- ...eArgumentsInSignatureWithRestParameters.js | 12 +++---- .../inheritedConstructorWithRestParams.js | 4 +-- .../noImplicitAnyParametersInBareFunctions.js | 16 +++++----- .../noImplicitAnyParametersInClass.js | 32 +++++++++---------- .../noImplicitAnyParametersInModule.js | 16 +++++----- tests/baselines/reference/nonArrayRestArgs.js | 4 +-- .../overloadGenericFunctionWithRestArgs.js | 4 +-- .../overloadResolutionOverNonCTLambdas.js | 8 ++--- .../reference/restArgAssignmentCompat.js | 4 +-- .../restParameterAssignmentCompatibility.js | 4 +-- .../restParameterNoTypeAnnotation.js | 4 +-- tests/baselines/reference/restParameters.js | 16 +++++----- .../reference/restParamsWithNonRestParams.js | 12 +++---- tests/baselines/reference/sourceMapSample.js | 4 +-- .../reference/sourceMapSample.sourcemap.txt | 4 +-- .../reference/sourceMapValidationClass.js | 4 +-- .../sourceMapValidationClass.sourcemap.txt | 4 +-- .../reference/sourceMapValidationClasses.js | 4 +-- .../sourceMapValidationClasses.sourcemap.txt | 4 +-- .../reference/sourceMapValidationFunctions.js | 8 ++--- ...sourceMapValidationFunctions.sourcemap.txt | 8 ++--- tests/baselines/reference/strictMode5.js | 4 +-- .../stringLiteralTypeIsSubtypeOfString.js | 4 +-- .../reference/subtypingWithCallSignatures2.js | 8 ++--- .../reference/subtypingWithCallSignatures3.js | 8 ++--- ...plateStringsWithOverloadResolution1_ES6.js | 4 +-- ...plateStringsWithOverloadResolution2_ES6.js | 8 ++--- .../reference/undeclaredModuleError.js | 4 +-- tests/baselines/reference/underscoreTest1.js | 4 +-- .../reference/varArgParamTypeCheck.js | 4 +-- tests/baselines/reference/vararg.js | 12 +++---- 62 files changed, 270 insertions(+), 270 deletions(-) diff --git a/tests/baselines/reference/arrayLiteralInNonVarArgParameter.js b/tests/baselines/reference/arrayLiteralInNonVarArgParameter.js index 57cba07d6bf16..f44b76f24ebd9 100644 --- a/tests/baselines/reference/arrayLiteralInNonVarArgParameter.js +++ b/tests/baselines/reference/arrayLiteralInNonVarArgParameter.js @@ -7,8 +7,8 @@ panic([], 'one', 'two'); //// [arrayLiteralInNonVarArgParameter.js] function panic(val) { var opt = []; - for (var _i = 1; _i < arguments.length; _i++) { - opt[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + opt[_a - 1] = arguments[_a]; } } panic([], 'one', 'two'); diff --git a/tests/baselines/reference/assignmentCompatWithCallSignaturesWithRestParameters.js b/tests/baselines/reference/assignmentCompatWithCallSignaturesWithRestParameters.js index f4cf5cc79e29b..c541114f91c20 100644 --- a/tests/baselines/reference/assignmentCompatWithCallSignaturesWithRestParameters.js +++ b/tests/baselines/reference/assignmentCompatWithCallSignaturesWithRestParameters.js @@ -51,15 +51,15 @@ var a; // ok, same number of required params a = function () { return 1; }; // ok, same number of required params a = function () { var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + args[_a - 0] = arguments[_a]; } return 1; }; // ok, same number of required params a = function () { var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + args[_a - 0] = arguments[_a]; } return 1; }; // error, type mismatch @@ -71,8 +71,8 @@ var a2; a2 = function () { return 1; }; // ok, fewer required params a2 = function () { var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + args[_a - 0] = arguments[_a]; } return 1; }; // ok, fewer required params @@ -80,15 +80,15 @@ a2 = function (x) { return 1; }; // ok, fewer required params a2 = function (x) { return 1; }; // ok, same number of required params a2 = function (x) { var args = []; - for (var _i = 1; _i < arguments.length; _i++) { - args[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + args[_a - 1] = arguments[_a]; } return 1; }; // ok, same number of required params a2 = function (x) { var args = []; - for (var _i = 1; _i < arguments.length; _i++) { - args[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + args[_a - 1] = arguments[_a]; } return 1; }; // should be type mismatch error @@ -102,8 +102,8 @@ a3 = function (x, y) { return 1; }; // ok, all present params match a3 = function (x, y, z) { return 1; }; // error a3 = function (x) { var z = []; - for (var _i = 1; _i < arguments.length; _i++) { - z[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + z[_a - 1] = arguments[_a]; } return 1; }; // error @@ -116,8 +116,8 @@ a4 = function (x, y) { return 1; }; // error, second param has type mismatch a4 = function (x, y) { return 1; }; // ok, same number of required params with matching types a4 = function (x) { var args = []; - for (var _i = 1; _i < arguments.length; _i++) { - args[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + args[_a - 1] = arguments[_a]; } return 1; }; // error, rest params have type mismatch diff --git a/tests/baselines/reference/baseTypeAfterDerivedType.js b/tests/baselines/reference/baseTypeAfterDerivedType.js index c64239ac0c86f..893e0e737b9cd 100644 --- a/tests/baselines/reference/baseTypeAfterDerivedType.js +++ b/tests/baselines/reference/baseTypeAfterDerivedType.js @@ -22,8 +22,8 @@ var Derived2 = (function () { } Derived2.prototype.method = function () { var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + args[_a - 0] = arguments[_a]; } }; return Derived2; diff --git a/tests/baselines/reference/collisionArgumentsArrowFunctions.js b/tests/baselines/reference/collisionArgumentsArrowFunctions.js index 0aa939e1a2d7f..c2f70d0ac9c8f 100644 --- a/tests/baselines/reference/collisionArgumentsArrowFunctions.js +++ b/tests/baselines/reference/collisionArgumentsArrowFunctions.js @@ -19,15 +19,15 @@ var f2NoError = () => { //// [collisionArgumentsArrowFunctions.js] var f1 = function (i) { var arguments = []; - for (var _i = 1; _i < arguments.length; _i++) { - arguments[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + arguments[_a - 1] = arguments[_a]; } var arguments; // no error }; var f12 = function (arguments) { var rest = []; - for (var _i = 1; _i < arguments.length; _i++) { - rest[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + rest[_a - 1] = arguments[_a]; } var arguments = 10; // no error }; @@ -36,8 +36,8 @@ var f1NoError = function (arguments) { }; var f2 = function () { var restParameters = []; - for (var _i = 0; _i < arguments.length; _i++) { - restParameters[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + restParameters[_a - 0] = arguments[_a]; } var arguments = 10; // No Error }; diff --git a/tests/baselines/reference/collisionArgumentsClassConstructor.js b/tests/baselines/reference/collisionArgumentsClassConstructor.js index ca743777b39d8..0581b37a1ebc9 100644 --- a/tests/baselines/reference/collisionArgumentsClassConstructor.js +++ b/tests/baselines/reference/collisionArgumentsClassConstructor.js @@ -91,8 +91,8 @@ declare class c6NoError { var c1 = (function () { function c1(i) { var arguments = []; - for (var _i = 1; _i < arguments.length; _i++) { - arguments[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + arguments[_a - 1] = arguments[_a]; } var arguments; // no error } @@ -101,8 +101,8 @@ var c1 = (function () { var c12 = (function () { function c12(arguments) { var rest = []; - for (var _i = 1; _i < arguments.length; _i++) { - rest[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + rest[_a - 1] = arguments[_a]; } var arguments = 10; // no error } @@ -117,8 +117,8 @@ var c1NoError = (function () { var c2 = (function () { function c2() { var restParameters = []; - for (var _i = 0; _i < arguments.length; _i++) { - restParameters[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + restParameters[_a - 0] = arguments[_a]; } var arguments = 10; // no error } @@ -133,8 +133,8 @@ var c2NoError = (function () { var c3 = (function () { function c3(arguments) { var restParameters = []; - for (var _i = 1; _i < arguments.length; _i++) { - restParameters[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + restParameters[_a - 1] = arguments[_a]; } this.arguments = arguments; var arguments = 10; // no error @@ -151,8 +151,8 @@ var c3NoError = (function () { var c5 = (function () { function c5(i) { var arguments = []; - for (var _i = 1; _i < arguments.length; _i++) { - arguments[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + arguments[_a - 1] = arguments[_a]; } var arguments; // no error } @@ -161,8 +161,8 @@ var c5 = (function () { var c52 = (function () { function c52(arguments) { var rest = []; - for (var _i = 1; _i < arguments.length; _i++) { - rest[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + rest[_a - 1] = arguments[_a]; } var arguments; // no error } diff --git a/tests/baselines/reference/collisionArgumentsClassMethod.js b/tests/baselines/reference/collisionArgumentsClassMethod.js index 10c9b28854408..4ac6748a6ba65 100644 --- a/tests/baselines/reference/collisionArgumentsClassMethod.js +++ b/tests/baselines/reference/collisionArgumentsClassMethod.js @@ -54,15 +54,15 @@ var c1 = (function () { } c1.prototype.foo = function (i) { var arguments = []; - for (var _i = 1; _i < arguments.length; _i++) { - arguments[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + arguments[_a - 1] = arguments[_a]; } var arguments; // no error }; c1.prototype.foo1 = function (arguments) { var rest = []; - for (var _i = 1; _i < arguments.length; _i++) { - rest[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + rest[_a - 1] = arguments[_a]; } var arguments = 10; // no error }; @@ -71,15 +71,15 @@ var c1 = (function () { }; c1.prototype.f4 = function (i) { var arguments = []; - for (var _i = 1; _i < arguments.length; _i++) { - arguments[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + arguments[_a - 1] = arguments[_a]; } var arguments; // no error }; c1.prototype.f41 = function (arguments) { var rest = []; - for (var _i = 1; _i < arguments.length; _i++) { - rest[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + rest[_a - 1] = arguments[_a]; } var arguments; // no error }; @@ -93,8 +93,8 @@ var c3 = (function () { } c3.prototype.foo = function () { var restParameters = []; - for (var _i = 0; _i < arguments.length; _i++) { - restParameters[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + restParameters[_a - 0] = arguments[_a]; } var arguments = 10; // no error }; diff --git a/tests/baselines/reference/collisionArgumentsFunction.js b/tests/baselines/reference/collisionArgumentsFunction.js index 9ce4a5ab0e20b..505127b7c95e1 100644 --- a/tests/baselines/reference/collisionArgumentsFunction.js +++ b/tests/baselines/reference/collisionArgumentsFunction.js @@ -48,15 +48,15 @@ declare function f6(arguments: string); // no codegen no error // Functions function f1(arguments) { var restParameters = []; - for (var _i = 1; _i < arguments.length; _i++) { - restParameters[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + restParameters[_a - 1] = arguments[_a]; } var arguments = 10; // no error } function f12(i) { var arguments = []; - for (var _i = 1; _i < arguments.length; _i++) { - arguments[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + arguments[_a - 1] = arguments[_a]; } var arguments; // no error } @@ -65,8 +65,8 @@ function f1NoError(arguments) { } function f3() { var restParameters = []; - for (var _i = 0; _i < arguments.length; _i++) { - restParameters[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + restParameters[_a - 0] = arguments[_a]; } var arguments = 10; // no error } @@ -75,15 +75,15 @@ function f3NoError() { } function f4(arguments) { var rest = []; - for (var _i = 1; _i < arguments.length; _i++) { - rest[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + rest[_a - 1] = arguments[_a]; } var arguments; // No error } function f42(i) { var arguments = []; - for (var _i = 1; _i < arguments.length; _i++) { - arguments[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + arguments[_a - 1] = arguments[_a]; } var arguments; // No error } diff --git a/tests/baselines/reference/collisionArgumentsFunctionExpressions.js b/tests/baselines/reference/collisionArgumentsFunctionExpressions.js index 405ceb625c3c9..54039a4bce31f 100644 --- a/tests/baselines/reference/collisionArgumentsFunctionExpressions.js +++ b/tests/baselines/reference/collisionArgumentsFunctionExpressions.js @@ -38,15 +38,15 @@ function foo() { function foo() { function f1(arguments) { var restParameters = []; - for (var _i = 1; _i < arguments.length; _i++) { - restParameters[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + restParameters[_a - 1] = arguments[_a]; } var arguments = 10; // no error } function f12(i) { var arguments = []; - for (var _i = 1; _i < arguments.length; _i++) { - arguments[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + arguments[_a - 1] = arguments[_a]; } var arguments; // no error } @@ -55,8 +55,8 @@ function foo() { } function f3() { var restParameters = []; - for (var _i = 0; _i < arguments.length; _i++) { - restParameters[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + restParameters[_a - 0] = arguments[_a]; } var arguments = 10; // no error } @@ -65,15 +65,15 @@ function foo() { } function f4(arguments) { var rest = []; - for (var _i = 1; _i < arguments.length; _i++) { - rest[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + rest[_a - 1] = arguments[_a]; } var arguments; // No error } function f42(i) { var arguments = []; - for (var _i = 1; _i < arguments.length; _i++) { - arguments[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + arguments[_a - 1] = arguments[_a]; } var arguments; // No error } diff --git a/tests/baselines/reference/collisionRestParameterArrowFunctions.js b/tests/baselines/reference/collisionRestParameterArrowFunctions.js index 31f835b6a865f..39d449555db1d 100644 --- a/tests/baselines/reference/collisionRestParameterArrowFunctions.js +++ b/tests/baselines/reference/collisionRestParameterArrowFunctions.js @@ -16,8 +16,8 @@ var f2NoError = () => { //// [collisionRestParameterArrowFunctions.js] var f1 = function (_i) { var restParameters = []; - for (var _0 = 1; _0 < arguments.length; _0++) { - restParameters[_0 - 1] = arguments[_0]; + for (var _a = 1; _a < arguments.length; _a++) { + restParameters[_a - 1] = arguments[_a]; } var _i = 10; // no error }; @@ -26,8 +26,8 @@ var f1NoError = function (_i) { }; var f2 = function () { var restParameters = []; - for (var _0 = 0; _0 < arguments.length; _0++) { - restParameters[_0 - 0] = arguments[_0]; + for (var _a = 0; _a < arguments.length; _a++) { + restParameters[_a - 0] = arguments[_a]; } var _i = 10; // No Error }; diff --git a/tests/baselines/reference/collisionRestParameterClassConstructor.js b/tests/baselines/reference/collisionRestParameterClassConstructor.js index f109d6ba347fd..fc6e400668c06 100644 --- a/tests/baselines/reference/collisionRestParameterClassConstructor.js +++ b/tests/baselines/reference/collisionRestParameterClassConstructor.js @@ -71,8 +71,8 @@ declare class c6NoError { var c1 = (function () { function c1(_i) { var restParameters = []; - for (var _0 = 1; _0 < arguments.length; _0++) { - restParameters[_0 - 1] = arguments[_0]; + for (var _a = 1; _a < arguments.length; _a++) { + restParameters[_a - 1] = arguments[_a]; } var _i = 10; // no error } @@ -87,8 +87,8 @@ var c1NoError = (function () { var c2 = (function () { function c2() { var restParameters = []; - for (var _0 = 0; _0 < arguments.length; _0++) { - restParameters[_0 - 0] = arguments[_0]; + for (var _a = 0; _a < arguments.length; _a++) { + restParameters[_a - 0] = arguments[_a]; } var _i = 10; // no error } @@ -103,8 +103,8 @@ var c2NoError = (function () { var c3 = (function () { function c3(_i) { var restParameters = []; - for (var _0 = 1; _0 < arguments.length; _0++) { - restParameters[_0 - 1] = arguments[_0]; + for (var _a = 1; _a < arguments.length; _a++) { + restParameters[_a - 1] = arguments[_a]; } this._i = _i; var _i = 10; // no error @@ -121,8 +121,8 @@ var c3NoError = (function () { var c5 = (function () { function c5(_i) { var rest = []; - for (var _0 = 1; _0 < arguments.length; _0++) { - rest[_0 - 1] = arguments[_0]; + for (var _a = 1; _a < arguments.length; _a++) { + rest[_a - 1] = arguments[_a]; } var _i; // no error } diff --git a/tests/baselines/reference/collisionRestParameterClassMethod.js b/tests/baselines/reference/collisionRestParameterClassMethod.js index 592cb694cb8dc..e3471c85f1c9a 100644 --- a/tests/baselines/reference/collisionRestParameterClassMethod.js +++ b/tests/baselines/reference/collisionRestParameterClassMethod.js @@ -44,8 +44,8 @@ var c1 = (function () { } c1.prototype.foo = function (_i) { var restParameters = []; - for (var _0 = 1; _0 < arguments.length; _0++) { - restParameters[_0 - 1] = arguments[_0]; + for (var _a = 1; _a < arguments.length; _a++) { + restParameters[_a - 1] = arguments[_a]; } var _i = 10; // no error }; @@ -54,8 +54,8 @@ var c1 = (function () { }; c1.prototype.f4 = function (_i) { var rest = []; - for (var _0 = 1; _0 < arguments.length; _0++) { - rest[_0 - 1] = arguments[_0]; + for (var _a = 1; _a < arguments.length; _a++) { + rest[_a - 1] = arguments[_a]; } var _i; // no error }; @@ -69,8 +69,8 @@ var c3 = (function () { } c3.prototype.foo = function () { var restParameters = []; - for (var _0 = 0; _0 < arguments.length; _0++) { - restParameters[_0 - 0] = arguments[_0]; + for (var _a = 0; _a < arguments.length; _a++) { + restParameters[_a - 0] = arguments[_a]; } var _i = 10; // no error }; diff --git a/tests/baselines/reference/collisionRestParameterFunction.js b/tests/baselines/reference/collisionRestParameterFunction.js index 5e4bfd2e7ba89..8660e8f5db0ea 100644 --- a/tests/baselines/reference/collisionRestParameterFunction.js +++ b/tests/baselines/reference/collisionRestParameterFunction.js @@ -37,8 +37,8 @@ declare function f6(_i: string); // no codegen no error // Functions function f1(_i) { var restParameters = []; - for (var _0 = 1; _0 < arguments.length; _0++) { - restParameters[_0 - 1] = arguments[_0]; + for (var _a = 1; _a < arguments.length; _a++) { + restParameters[_a - 1] = arguments[_a]; } var _i = 10; // no error } @@ -47,8 +47,8 @@ function f1NoError(_i) { } function f3() { var restParameters = []; - for (var _0 = 0; _0 < arguments.length; _0++) { - restParameters[_0 - 0] = arguments[_0]; + for (var _a = 0; _a < arguments.length; _a++) { + restParameters[_a - 0] = arguments[_a]; } var _i = 10; // no error } @@ -57,8 +57,8 @@ function f3NoError() { } function f4(_i) { var rest = []; - for (var _0 = 1; _0 < arguments.length; _0++) { - rest[_0 - 1] = arguments[_0]; + for (var _a = 1; _a < arguments.length; _a++) { + rest[_a - 1] = arguments[_a]; } } function f4NoError(_i) { diff --git a/tests/baselines/reference/collisionRestParameterFunctionExpressions.js b/tests/baselines/reference/collisionRestParameterFunctionExpressions.js index 894854f2fb850..22709b087eb7b 100644 --- a/tests/baselines/reference/collisionRestParameterFunctionExpressions.js +++ b/tests/baselines/reference/collisionRestParameterFunctionExpressions.js @@ -28,8 +28,8 @@ function foo() { function foo() { function f1(_i) { var restParameters = []; - for (var _0 = 1; _0 < arguments.length; _0++) { - restParameters[_0 - 1] = arguments[_0]; + for (var _a = 1; _a < arguments.length; _a++) { + restParameters[_a - 1] = arguments[_a]; } var _i = 10; // no error } @@ -38,8 +38,8 @@ function foo() { } function f3() { var restParameters = []; - for (var _0 = 0; _0 < arguments.length; _0++) { - restParameters[_0 - 0] = arguments[_0]; + for (var _a = 0; _a < arguments.length; _a++) { + restParameters[_a - 0] = arguments[_a]; } var _i = 10; // no error } @@ -48,8 +48,8 @@ function foo() { } function f4(_i) { var rest = []; - for (var _0 = 1; _0 < arguments.length; _0++) { - rest[_0 - 1] = arguments[_0]; + for (var _a = 1; _a < arguments.length; _a++) { + rest[_a - 1] = arguments[_a]; } } function f4NoError(_i) { diff --git a/tests/baselines/reference/collisionRestParameterUnderscoreIUsage.js b/tests/baselines/reference/collisionRestParameterUnderscoreIUsage.js index 4055bcd81abaa..adc9c09de27d2 100644 --- a/tests/baselines/reference/collisionRestParameterUnderscoreIUsage.js +++ b/tests/baselines/reference/collisionRestParameterUnderscoreIUsage.js @@ -13,8 +13,8 @@ var _i = "This is what I'd expect to see"; var Foo = (function () { function Foo() { var args = []; - for (var _0 = 0; _0 < arguments.length; _0++) { - args[_0 - 0] = arguments[_0]; + for (var _a = 0; _a < arguments.length; _a++) { + args[_a - 0] = arguments[_a]; } console.log(_i); // This should result in error } diff --git a/tests/baselines/reference/contextuallyTypingRestParameters.js b/tests/baselines/reference/contextuallyTypingRestParameters.js index 17561f5d7fccb..ac48cc6db0ecc 100644 --- a/tests/baselines/reference/contextuallyTypingRestParameters.js +++ b/tests/baselines/reference/contextuallyTypingRestParameters.js @@ -10,8 +10,8 @@ var x: (...y: string[]) => void = function (.../*3*/y) { //// [contextuallyTypingRestParameters.js] var x = function () { var y = []; - for (var _i = 0; _i < arguments.length; _i++) { - y[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + y[_a - 0] = arguments[_a]; } var t = y; var x2 = t; // This should be error diff --git a/tests/baselines/reference/declFileConstructors.js b/tests/baselines/reference/declFileConstructors.js index 327221debf805..830e30e65c33e 100644 --- a/tests/baselines/reference/declFileConstructors.js +++ b/tests/baselines/reference/declFileConstructors.js @@ -118,8 +118,8 @@ exports.ConstructorWithParameters = ConstructorWithParameters; var ConstructorWithRestParamters = (function () { function ConstructorWithRestParamters(a) { var rests = []; - for (var _i = 1; _i < arguments.length; _i++) { - rests[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + rests[_a - 1] = arguments[_a]; } return a + rests.join(""); } @@ -180,8 +180,8 @@ var GlobalConstructorWithParameters = (function () { var GlobalConstructorWithRestParamters = (function () { function GlobalConstructorWithRestParamters(a) { var rests = []; - for (var _i = 1; _i < arguments.length; _i++) { - rests[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + rests[_a - 1] = arguments[_a]; } return a + rests.join(""); } diff --git a/tests/baselines/reference/declFileFunctions.js b/tests/baselines/reference/declFileFunctions.js index da1917163e186..329c61b9aba9a 100644 --- a/tests/baselines/reference/declFileFunctions.js +++ b/tests/baselines/reference/declFileFunctions.js @@ -78,8 +78,8 @@ function fooWithParameters(/** this is comment about a*/ a, exports.fooWithParameters = fooWithParameters; function fooWithRestParameters(a) { var rests = []; - for (var _i = 1; _i < arguments.length; _i++) { - rests[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + rests[_a - 1] = arguments[_a]; } return a + rests.join(""); } @@ -103,8 +103,8 @@ function nonExportedFooWithParameters(/** this is comment about a*/ a, } function nonExportedFooWithRestParameters(a) { var rests = []; - for (var _i = 1; _i < arguments.length; _i++) { - rests[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + rests[_a - 1] = arguments[_a]; } return a + rests.join(""); } @@ -123,8 +123,8 @@ function globalfooWithParameters(/** this is comment about a*/ a, } function globalfooWithRestParameters(a) { var rests = []; - for (var _i = 1; _i < arguments.length; _i++) { - rests[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + rests[_a - 1] = arguments[_a]; } return a + rests.join(""); } diff --git a/tests/baselines/reference/declFileMethods.js b/tests/baselines/reference/declFileMethods.js index 2b82a4b71b525..9b0e42414e48e 100644 --- a/tests/baselines/reference/declFileMethods.js +++ b/tests/baselines/reference/declFileMethods.js @@ -205,8 +205,8 @@ var c1 = (function () { }; c1.prototype.fooWithRestParameters = function (a) { var rests = []; - for (var _i = 1; _i < arguments.length; _i++) { - rests[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + rests[_a - 1] = arguments[_a]; } return a + rests.join(""); }; @@ -224,8 +224,8 @@ var c1 = (function () { }; c1.prototype.privateFooWithRestParameters = function (a) { var rests = []; - for (var _i = 1; _i < arguments.length; _i++) { - rests[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + rests[_a - 1] = arguments[_a]; } return a + rests.join(""); }; @@ -243,8 +243,8 @@ var c1 = (function () { }; c1.staticFooWithRestParameters = function (a) { var rests = []; - for (var _i = 1; _i < arguments.length; _i++) { - rests[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + rests[_a - 1] = arguments[_a]; } return a + rests.join(""); }; @@ -262,8 +262,8 @@ var c1 = (function () { }; c1.privateStaticFooWithRestParameters = function (a) { var rests = []; - for (var _i = 1; _i < arguments.length; _i++) { - rests[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + rests[_a - 1] = arguments[_a]; } return a + rests.join(""); }; @@ -288,8 +288,8 @@ var c2 = (function () { }; c2.prototype.fooWithRestParameters = function (a) { var rests = []; - for (var _i = 1; _i < arguments.length; _i++) { - rests[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + rests[_a - 1] = arguments[_a]; } return a + rests.join(""); }; @@ -307,8 +307,8 @@ var c2 = (function () { }; c2.prototype.privateFooWithRestParameters = function (a) { var rests = []; - for (var _i = 1; _i < arguments.length; _i++) { - rests[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + rests[_a - 1] = arguments[_a]; } return a + rests.join(""); }; @@ -326,8 +326,8 @@ var c2 = (function () { }; c2.staticFooWithRestParameters = function (a) { var rests = []; - for (var _i = 1; _i < arguments.length; _i++) { - rests[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + rests[_a - 1] = arguments[_a]; } return a + rests.join(""); }; @@ -345,8 +345,8 @@ var c2 = (function () { }; c2.privateStaticFooWithRestParameters = function (a) { var rests = []; - for (var _i = 1; _i < arguments.length; _i++) { - rests[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + rests[_a - 1] = arguments[_a]; } return a + rests.join(""); }; diff --git a/tests/baselines/reference/declFileRestParametersOfFunctionAndFunctionType.js b/tests/baselines/reference/declFileRestParametersOfFunctionAndFunctionType.js index 5ff631c6aadb7..8b784edbafb5d 100644 --- a/tests/baselines/reference/declFileRestParametersOfFunctionAndFunctionType.js +++ b/tests/baselines/reference/declFileRestParametersOfFunctionAndFunctionType.js @@ -13,8 +13,8 @@ var f6 = () => { return [10]; } //// [declFileRestParametersOfFunctionAndFunctionType.js] function f1() { var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + args[_a - 0] = arguments[_a]; } } function f2(x) { diff --git a/tests/baselines/reference/detachedCommentAtStartOfLambdaFunction1.js b/tests/baselines/reference/detachedCommentAtStartOfLambdaFunction1.js index 2505e3f60826e..72d2545e617ad 100644 --- a/tests/baselines/reference/detachedCommentAtStartOfLambdaFunction1.js +++ b/tests/baselines/reference/detachedCommentAtStartOfLambdaFunction1.js @@ -18,8 +18,8 @@ var TestFile = (function () { var _this = this; return function () { var x = []; - for (var _i = 0; _i < arguments.length; _i++) { - x[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + x[_a - 0] = arguments[_a]; } /// Test summary /// diff --git a/tests/baselines/reference/detachedCommentAtStartOfLambdaFunction2.js b/tests/baselines/reference/detachedCommentAtStartOfLambdaFunction2.js index 53f6d08eaf557..3309a395ef54a 100644 --- a/tests/baselines/reference/detachedCommentAtStartOfLambdaFunction2.js +++ b/tests/baselines/reference/detachedCommentAtStartOfLambdaFunction2.js @@ -22,8 +22,8 @@ var TestFile = (function () { /// /// var x = []; - for (var _i = 0; _i < arguments.length; _i++) { - x[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + x[_a - 0] = arguments[_a]; } return message + _this.name; }; diff --git a/tests/baselines/reference/funcdecl.js b/tests/baselines/reference/funcdecl.js index de080873b9feb..32d024f4eedc3 100644 --- a/tests/baselines/reference/funcdecl.js +++ b/tests/baselines/reference/funcdecl.js @@ -105,8 +105,8 @@ function withOptionalInitializedParams(a, c) { var withOptionalInitializedParamsVar = withOptionalInitializedParams; function withRestParams(a) { var myRestParameter = []; - for (var _i = 1; _i < arguments.length; _i++) { - myRestParameter[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + myRestParameter[_a - 1] = arguments[_a]; } return myRestParameter; } diff --git a/tests/baselines/reference/functionCall10.js b/tests/baselines/reference/functionCall10.js index 9d5cb33a56a3b..a9b5ca4788f97 100644 --- a/tests/baselines/reference/functionCall10.js +++ b/tests/baselines/reference/functionCall10.js @@ -9,8 +9,8 @@ foo(1, 'bar'); //// [functionCall10.js] function foo() { var a = []; - for (var _i = 0; _i < arguments.length; _i++) { - a[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + a[_a - 0] = arguments[_a]; } } ; diff --git a/tests/baselines/reference/functionCall13.js b/tests/baselines/reference/functionCall13.js index ce57f43215e4d..6edf95fb4bc0d 100644 --- a/tests/baselines/reference/functionCall13.js +++ b/tests/baselines/reference/functionCall13.js @@ -10,8 +10,8 @@ foo('foo', 1, 3); //// [functionCall13.js] function foo(a) { var b = []; - for (var _i = 1; _i < arguments.length; _i++) { - b[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + b[_a - 1] = arguments[_a]; } } foo('foo', 1); diff --git a/tests/baselines/reference/functionCall14.js b/tests/baselines/reference/functionCall14.js index 47447f46db5ca..343b3e58b736e 100644 --- a/tests/baselines/reference/functionCall14.js +++ b/tests/baselines/reference/functionCall14.js @@ -10,8 +10,8 @@ foo('foo', 1, 3); //// [functionCall14.js] function foo(a) { var b = []; - for (var _i = 1; _i < arguments.length; _i++) { - b[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + b[_a - 1] = arguments[_a]; } } foo('foo', 1); diff --git a/tests/baselines/reference/functionCall15.js b/tests/baselines/reference/functionCall15.js index 28fa4c917c867..07864c5f4c63b 100644 --- a/tests/baselines/reference/functionCall15.js +++ b/tests/baselines/reference/functionCall15.js @@ -4,7 +4,7 @@ function foo(a?:string, b?:number, ...b:number[]){} //// [functionCall15.js] function foo(a, b) { var b = []; - for (var _i = 2; _i < arguments.length; _i++) { - b[_i - 2] = arguments[_i]; + for (var _a = 2; _a < arguments.length; _a++) { + b[_a - 2] = arguments[_a]; } } diff --git a/tests/baselines/reference/functionCall16.js b/tests/baselines/reference/functionCall16.js index 187572a9a7e84..fdf7ed1542951 100644 --- a/tests/baselines/reference/functionCall16.js +++ b/tests/baselines/reference/functionCall16.js @@ -11,8 +11,8 @@ foo('foo', 'bar', 3); //// [functionCall16.js] function foo(a, b) { var c = []; - for (var _i = 2; _i < arguments.length; _i++) { - c[_i - 2] = arguments[_i]; + for (var _a = 2; _a < arguments.length; _a++) { + c[_a - 2] = arguments[_a]; } } foo('foo', 1); diff --git a/tests/baselines/reference/functionCall17.js b/tests/baselines/reference/functionCall17.js index 73f7fd6070b22..a6794012d68c7 100644 --- a/tests/baselines/reference/functionCall17.js +++ b/tests/baselines/reference/functionCall17.js @@ -11,8 +11,8 @@ foo('foo', 'bar', 3, 4); //// [functionCall17.js] function foo(a, b, c) { var d = []; - for (var _i = 3; _i < arguments.length; _i++) { - d[_i - 3] = arguments[_i]; + for (var _a = 3; _a < arguments.length; _a++) { + d[_a - 3] = arguments[_a]; } } foo('foo', 1); diff --git a/tests/baselines/reference/functionOverloadsRecursiveGenericReturnType.js b/tests/baselines/reference/functionOverloadsRecursiveGenericReturnType.js index ab0baf2059296..73bb56b3f7e82 100644 --- a/tests/baselines/reference/functionOverloadsRecursiveGenericReturnType.js +++ b/tests/baselines/reference/functionOverloadsRecursiveGenericReturnType.js @@ -27,8 +27,8 @@ var A = (function () { })(); function Choice() { var v_args = []; - for (var _i = 0; _i < arguments.length; _i++) { - v_args[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + v_args[_a - 0] = arguments[_a]; } return new A(); } diff --git a/tests/baselines/reference/genericRestArgs.js b/tests/baselines/reference/genericRestArgs.js index 75c88d7cbf2cc..1896e886c9732 100644 --- a/tests/baselines/reference/genericRestArgs.js +++ b/tests/baselines/reference/genericRestArgs.js @@ -15,8 +15,8 @@ var a2Gc = makeArrayG(1, ""); // error //// [genericRestArgs.js] function makeArrayG() { var items = []; - for (var _i = 0; _i < arguments.length; _i++) { - items[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + items[_a - 0] = arguments[_a]; } return items; } diff --git a/tests/baselines/reference/implicitAnyDeclareFunctionWithoutFormalType.js b/tests/baselines/reference/implicitAnyDeclareFunctionWithoutFormalType.js index 72d68da22872b..2d452a9f5339c 100644 --- a/tests/baselines/reference/implicitAnyDeclareFunctionWithoutFormalType.js +++ b/tests/baselines/reference/implicitAnyDeclareFunctionWithoutFormalType.js @@ -24,8 +24,8 @@ function func2(a, b, c) { ; function func3() { var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + args[_a - 0] = arguments[_a]; } } ; diff --git a/tests/baselines/reference/inferTypeArgumentsInSignatureWithRestParameters.js b/tests/baselines/reference/inferTypeArgumentsInSignatureWithRestParameters.js index 1cc86829a6b0b..198bd3dcfa787 100644 --- a/tests/baselines/reference/inferTypeArgumentsInSignatureWithRestParameters.js +++ b/tests/baselines/reference/inferTypeArgumentsInSignatureWithRestParameters.js @@ -14,20 +14,20 @@ i(a); // OK //// [inferTypeArgumentsInSignatureWithRestParameters.js] function f(array) { var args = []; - for (var _i = 1; _i < arguments.length; _i++) { - args[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + args[_a - 1] = arguments[_a]; } } function g(array) { var args = []; - for (var _i = 1; _i < arguments.length; _i++) { - args[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + args[_a - 1] = arguments[_a]; } } function h(nonarray) { var args = []; - for (var _i = 1; _i < arguments.length; _i++) { - args[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + args[_a - 1] = arguments[_a]; } } function i(array, opt) { diff --git a/tests/baselines/reference/inheritedConstructorWithRestParams.js b/tests/baselines/reference/inheritedConstructorWithRestParams.js index b924fe25db9c8..67b9cc0832288 100644 --- a/tests/baselines/reference/inheritedConstructorWithRestParams.js +++ b/tests/baselines/reference/inheritedConstructorWithRestParams.js @@ -24,8 +24,8 @@ var __extends = this.__extends || function (d, b) { var Base = (function () { function Base() { var a = []; - for (var _i = 0; _i < arguments.length; _i++) { - a[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + a[_a - 0] = arguments[_a]; } } return Base; diff --git a/tests/baselines/reference/noImplicitAnyParametersInBareFunctions.js b/tests/baselines/reference/noImplicitAnyParametersInBareFunctions.js index 06848d7e89af4..f23819244c366 100644 --- a/tests/baselines/reference/noImplicitAnyParametersInBareFunctions.js +++ b/tests/baselines/reference/noImplicitAnyParametersInBareFunctions.js @@ -63,15 +63,15 @@ function f5(x, y, z) { // Implicit-'any[]' error for r. function f6() { var r = []; - for (var _i = 0; _i < arguments.length; _i++) { - r[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + r[_a - 0] = arguments[_a]; } } // Implicit-'any'/'any[]' errors for x, r. function f7(x) { var r = []; - for (var _i = 1; _i < arguments.length; _i++) { - r[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + r[_a - 1] = arguments[_a]; } } function f8(x3, y3) { @@ -87,16 +87,16 @@ var f12 = function (x, y, z) { return ""; }; // Implicit-'any[]' error for r. var f13 = function () { var r = []; - for (var _i = 0; _i < arguments.length; _i++) { - r[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + r[_a - 0] = arguments[_a]; } return ""; }; // Implicit-'any'/'any[]' errors for x, r. var f14 = function (x) { var r = []; - for (var _i = 1; _i < arguments.length; _i++) { - r[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + r[_a - 1] = arguments[_a]; } return ""; }; diff --git a/tests/baselines/reference/noImplicitAnyParametersInClass.js b/tests/baselines/reference/noImplicitAnyParametersInClass.js index 82164884b801c..3a2ee3e38bd86 100644 --- a/tests/baselines/reference/noImplicitAnyParametersInClass.js +++ b/tests/baselines/reference/noImplicitAnyParametersInClass.js @@ -106,16 +106,16 @@ var C = (function () { // Implicit-'any[]' error for r. this.pub_f13 = function () { var r = []; - for (var _i = 0; _i < arguments.length; _i++) { - r[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + r[_a - 0] = arguments[_a]; } return ""; }; // Implicit-'any'/'any[]' errors for x, r. this.pub_f14 = function (x) { var r = []; - for (var _i = 1; _i < arguments.length; _i++) { - r[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + r[_a - 1] = arguments[_a]; } return ""; }; @@ -130,16 +130,16 @@ var C = (function () { // Implicit-'any[]' error for r. this.priv_f13 = function () { var r = []; - for (var _i = 0; _i < arguments.length; _i++) { - r[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + r[_a - 0] = arguments[_a]; } return ""; }; // Implicit-'any'/'any[]' errors for x, r. this.priv_f14 = function (x) { var r = []; - for (var _i = 1; _i < arguments.length; _i++) { - r[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + r[_a - 1] = arguments[_a]; } return ""; }; @@ -162,15 +162,15 @@ var C = (function () { // Implicit-'any[]' errors for r. C.prototype.pub_f6 = function () { var r = []; - for (var _i = 0; _i < arguments.length; _i++) { - r[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + r[_a - 0] = arguments[_a]; } }; // Implicit-'any'/'any[]' errors for x, r. C.prototype.pub_f7 = function (x) { var r = []; - for (var _i = 1; _i < arguments.length; _i++) { - r[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + r[_a - 1] = arguments[_a]; } }; C.prototype.pub_f8 = function (x3, y3) { @@ -194,15 +194,15 @@ var C = (function () { // Implicit-'any[]' errors for r. C.prototype.priv_f6 = function () { var r = []; - for (var _i = 0; _i < arguments.length; _i++) { - r[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + r[_a - 0] = arguments[_a]; } }; // Implicit-'any'/'any[]' errors for x, r. C.prototype.priv_f7 = function (x) { var r = []; - for (var _i = 1; _i < arguments.length; _i++) { - r[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + r[_a - 1] = arguments[_a]; } }; C.prototype.priv_f8 = function (x3, y3) { diff --git a/tests/baselines/reference/noImplicitAnyParametersInModule.js b/tests/baselines/reference/noImplicitAnyParametersInModule.js index fccb16cefa79a..b9af2af132efe 100644 --- a/tests/baselines/reference/noImplicitAnyParametersInModule.js +++ b/tests/baselines/reference/noImplicitAnyParametersInModule.js @@ -67,15 +67,15 @@ var M; // Implicit-'any[]' error for r. function m_f6() { var r = []; - for (var _i = 0; _i < arguments.length; _i++) { - r[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + r[_a - 0] = arguments[_a]; } } // Implicit-'any'/'any[]' errors for x and r. function m_f7(x) { var r = []; - for (var _i = 1; _i < arguments.length; _i++) { - r[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + r[_a - 1] = arguments[_a]; } } function m_f8(x3, y3) { @@ -91,16 +91,16 @@ var M; // Implicit-'any[]' errors for r. var m_f13 = function () { var r = []; - for (var _i = 0; _i < arguments.length; _i++) { - r[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + r[_a - 0] = arguments[_a]; } return ""; }; // Implicit-'any'/'any[]' errors for x and r. var m_f14 = function (x) { var r = []; - for (var _i = 1; _i < arguments.length; _i++) { - r[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + r[_a - 1] = arguments[_a]; } return ""; }; diff --git a/tests/baselines/reference/nonArrayRestArgs.js b/tests/baselines/reference/nonArrayRestArgs.js index d16b7dea3466e..27e05034a1a4d 100644 --- a/tests/baselines/reference/nonArrayRestArgs.js +++ b/tests/baselines/reference/nonArrayRestArgs.js @@ -7,8 +7,8 @@ function foo(...rest: number) { // error //// [nonArrayRestArgs.js] function foo() { var rest = []; - for (var _i = 0; _i < arguments.length; _i++) { - rest[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + rest[_a - 0] = arguments[_a]; } var x = rest[0]; return x; diff --git a/tests/baselines/reference/overloadGenericFunctionWithRestArgs.js b/tests/baselines/reference/overloadGenericFunctionWithRestArgs.js index c4b133ea44c48..62676c0d03c9c 100644 --- a/tests/baselines/reference/overloadGenericFunctionWithRestArgs.js +++ b/tests/baselines/reference/overloadGenericFunctionWithRestArgs.js @@ -23,8 +23,8 @@ var A = (function () { })(); function Choice() { var v_args = []; - for (var _i = 0; _i < arguments.length; _i++) { - v_args[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + v_args[_a - 0] = arguments[_a]; } return new A(); } diff --git a/tests/baselines/reference/overloadResolutionOverNonCTLambdas.js b/tests/baselines/reference/overloadResolutionOverNonCTLambdas.js index 86e84ced58f0f..52a2c92f10f08 100644 --- a/tests/baselines/reference/overloadResolutionOverNonCTLambdas.js +++ b/tests/baselines/reference/overloadResolutionOverNonCTLambdas.js @@ -34,13 +34,13 @@ var Bugs; // replace(searchValue: RegExp, replaceValue: (substring: string, ...args: any[]) => string): string; function bug2(message) { var args = []; - for (var _i = 1; _i < arguments.length; _i++) { - args[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + args[_a - 1] = arguments[_a]; } var result = message.replace(/\{(\d+)\}/g, function (match) { var rest = []; - for (var _i = 1; _i < arguments.length; _i++) { - rest[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + rest[_a - 1] = arguments[_a]; } var index = rest[0]; return typeof args[index] !== 'undefined' ? args[index] : match; diff --git a/tests/baselines/reference/restArgAssignmentCompat.js b/tests/baselines/reference/restArgAssignmentCompat.js index a52cff7ec5c1d..5fb98a0125d76 100644 --- a/tests/baselines/reference/restArgAssignmentCompat.js +++ b/tests/baselines/reference/restArgAssignmentCompat.js @@ -12,8 +12,8 @@ n([4], 'foo'); //// [restArgAssignmentCompat.js] function f() { var x = []; - for (var _i = 0; _i < arguments.length; _i++) { - x[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + x[_a - 0] = arguments[_a]; } x.forEach(function (n, i) { return void ('item ' + i + ' = ' + n); }); } diff --git a/tests/baselines/reference/restParameterAssignmentCompatibility.js b/tests/baselines/reference/restParameterAssignmentCompatibility.js index 62c0204c74991..ca81a284eddba 100644 --- a/tests/baselines/reference/restParameterAssignmentCompatibility.js +++ b/tests/baselines/reference/restParameterAssignmentCompatibility.js @@ -32,8 +32,8 @@ var T = (function () { } T.prototype.m = function () { var p3 = []; - for (var _i = 0; _i < arguments.length; _i++) { - p3[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + p3[_a - 0] = arguments[_a]; } }; return T; diff --git a/tests/baselines/reference/restParameterNoTypeAnnotation.js b/tests/baselines/reference/restParameterNoTypeAnnotation.js index 95e092fdd4373..195b6e28a08fd 100644 --- a/tests/baselines/reference/restParameterNoTypeAnnotation.js +++ b/tests/baselines/reference/restParameterNoTypeAnnotation.js @@ -8,8 +8,8 @@ function foo(...rest) { //// [restParameterNoTypeAnnotation.js] function foo() { var rest = []; - for (var _i = 0; _i < arguments.length; _i++) { - rest[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + rest[_a - 0] = arguments[_a]; } var x = rest[0]; return x; diff --git a/tests/baselines/reference/restParameters.js b/tests/baselines/reference/restParameters.js index 2e5b7bb4c928a..5b5717b34fd33 100644 --- a/tests/baselines/reference/restParameters.js +++ b/tests/baselines/reference/restParameters.js @@ -10,25 +10,25 @@ function f21(a:string, b?:string, c?:number, ...d:number[]){} //// [restParameters.js] function f18(a) { var b = []; - for (var _i = 1; _i < arguments.length; _i++) { - b[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + b[_a - 1] = arguments[_a]; } } function f19(a, b) { var c = []; - for (var _i = 2; _i < arguments.length; _i++) { - c[_i - 2] = arguments[_i]; + for (var _a = 2; _a < arguments.length; _a++) { + c[_a - 2] = arguments[_a]; } } function f20(a, b) { var c = []; - for (var _i = 2; _i < arguments.length; _i++) { - c[_i - 2] = arguments[_i]; + for (var _a = 2; _a < arguments.length; _a++) { + c[_a - 2] = arguments[_a]; } } function f21(a, b, c) { var d = []; - for (var _i = 3; _i < arguments.length; _i++) { - d[_i - 3] = arguments[_i]; + for (var _a = 3; _a < arguments.length; _a++) { + d[_a - 3] = arguments[_a]; } } diff --git a/tests/baselines/reference/restParamsWithNonRestParams.js b/tests/baselines/reference/restParamsWithNonRestParams.js index 6b0caa723940a..745c91d4a0cb7 100644 --- a/tests/baselines/reference/restParamsWithNonRestParams.js +++ b/tests/baselines/reference/restParamsWithNonRestParams.js @@ -9,22 +9,22 @@ foo3(); // error but shouldn't be //// [restParamsWithNonRestParams.js] function foo() { var b = []; - for (var _i = 0; _i < arguments.length; _i++) { - b[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + b[_a - 0] = arguments[_a]; } } foo(); // ok function foo2(a) { var b = []; - for (var _i = 1; _i < arguments.length; _i++) { - b[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + b[_a - 1] = arguments[_a]; } } foo2(); // should be an error function foo3(a) { var b = []; - for (var _i = 1; _i < arguments.length; _i++) { - b[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + b[_a - 1] = arguments[_a]; } } foo3(); // error but shouldn't be diff --git a/tests/baselines/reference/sourceMapSample.js b/tests/baselines/reference/sourceMapSample.js index 96c78c94c0cd2..62ad950935114 100644 --- a/tests/baselines/reference/sourceMapSample.js +++ b/tests/baselines/reference/sourceMapSample.js @@ -57,8 +57,8 @@ var Foo; var str = greeter.greet(); function foo2(greeting) { var restGreetings = []; - for (var _i = 1; _i < arguments.length; _i++) { - restGreetings[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + restGreetings[_a - 1] = arguments[_a]; } var greeters = []; greeters[0] = new Greeter(greeting); diff --git a/tests/baselines/reference/sourceMapSample.sourcemap.txt b/tests/baselines/reference/sourceMapSample.sourcemap.txt index 218dfb1c15228..7608a68193606 100644 --- a/tests/baselines/reference/sourceMapSample.sourcemap.txt +++ b/tests/baselines/reference/sourceMapSample.sourcemap.txt @@ -454,7 +454,7 @@ sourceFile:sourceMapSample.ts 1->Emitted(21, 13) Source(21, 37) + SourceIndex(0) name (Foo.Bar.foo2) 2 >Emitted(21, 36) Source(21, 63) + SourceIndex(0) name (Foo.Bar.foo2) --- ->>> for (var _i = 1; _i < arguments.length; _i++) { +>>> for (var _a = 1; _a < arguments.length; _a++) { 1->^^^^^^^^^^^^^^^^^ 2 > ^^^^^^^^^^^ 3 > ^ @@ -474,7 +474,7 @@ sourceFile:sourceMapSample.ts 5 >Emitted(22, 53) Source(21, 37) + SourceIndex(0) name (Foo.Bar.foo2) 6 >Emitted(22, 57) Source(21, 63) + SourceIndex(0) name (Foo.Bar.foo2) --- ->>> restGreetings[_i - 1] = arguments[_i]; +>>> restGreetings[_a - 1] = arguments[_a]; 1 >^^^^^^^^^^^^^^^^ 2 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1 > diff --git a/tests/baselines/reference/sourceMapValidationClass.js b/tests/baselines/reference/sourceMapValidationClass.js index eef5a723ebf3e..bc526bc674cdc 100644 --- a/tests/baselines/reference/sourceMapValidationClass.js +++ b/tests/baselines/reference/sourceMapValidationClass.js @@ -22,8 +22,8 @@ class Greeter { var Greeter = (function () { function Greeter(greeting) { var b = []; - for (var _i = 1; _i < arguments.length; _i++) { - b[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + b[_a - 1] = arguments[_a]; } this.greeting = greeting; this.x1 = 10; diff --git a/tests/baselines/reference/sourceMapValidationClass.sourcemap.txt b/tests/baselines/reference/sourceMapValidationClass.sourcemap.txt index 1c80abde32e90..8909f29310004 100644 --- a/tests/baselines/reference/sourceMapValidationClass.sourcemap.txt +++ b/tests/baselines/reference/sourceMapValidationClass.sourcemap.txt @@ -48,7 +48,7 @@ sourceFile:sourceMapValidationClass.ts 1 >Emitted(3, 9) Source(2, 42) + SourceIndex(0) name (Greeter.constructor) 2 >Emitted(3, 20) Source(2, 56) + SourceIndex(0) name (Greeter.constructor) --- ->>> for (var _i = 1; _i < arguments.length; _i++) { +>>> for (var _a = 1; _a < arguments.length; _a++) { 1->^^^^^^^^^^^^^ 2 > ^^^^^^^^^^^ 3 > ^ @@ -68,7 +68,7 @@ sourceFile:sourceMapValidationClass.ts 5 >Emitted(4, 49) Source(2, 42) + SourceIndex(0) name (Greeter.constructor) 6 >Emitted(4, 53) Source(2, 56) + SourceIndex(0) name (Greeter.constructor) --- ->>> b[_i - 1] = arguments[_i]; +>>> b[_a - 1] = arguments[_a]; 1 >^^^^^^^^^^^^ 2 > ^^^^^^^^^^^^^^^^^^^^^^^^^^ 1 > diff --git a/tests/baselines/reference/sourceMapValidationClasses.js b/tests/baselines/reference/sourceMapValidationClasses.js index 96724f7c3c770..0ab0d1e10aa2c 100644 --- a/tests/baselines/reference/sourceMapValidationClasses.js +++ b/tests/baselines/reference/sourceMapValidationClasses.js @@ -58,8 +58,8 @@ var Foo; var str = greeter.greet(); function foo2(greeting) { var restGreetings = []; - for (var _i = 1; _i < arguments.length; _i++) { - restGreetings[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + restGreetings[_a - 1] = arguments[_a]; } var greeters = []; /* inline block comment */ greeters[0] = new Greeter(greeting); diff --git a/tests/baselines/reference/sourceMapValidationClasses.sourcemap.txt b/tests/baselines/reference/sourceMapValidationClasses.sourcemap.txt index d82ac6c3e0516..31d276c68a110 100644 --- a/tests/baselines/reference/sourceMapValidationClasses.sourcemap.txt +++ b/tests/baselines/reference/sourceMapValidationClasses.sourcemap.txt @@ -456,7 +456,7 @@ sourceFile:sourceMapValidationClasses.ts 1->Emitted(21, 13) Source(21, 37) + SourceIndex(0) name (Foo.Bar.foo2) 2 >Emitted(21, 36) Source(21, 83) + SourceIndex(0) name (Foo.Bar.foo2) --- ->>> for (var _i = 1; _i < arguments.length; _i++) { +>>> for (var _a = 1; _a < arguments.length; _a++) { 1->^^^^^^^^^^^^^^^^^ 2 > ^^^^^^^^^^^ 3 > ^ @@ -476,7 +476,7 @@ sourceFile:sourceMapValidationClasses.ts 5 >Emitted(22, 53) Source(21, 37) + SourceIndex(0) name (Foo.Bar.foo2) 6 >Emitted(22, 57) Source(21, 83) + SourceIndex(0) name (Foo.Bar.foo2) --- ->>> restGreetings[_i - 1] = arguments[_i]; +>>> restGreetings[_a - 1] = arguments[_a]; 1 >^^^^^^^^^^^^^^^^ 2 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1 > diff --git a/tests/baselines/reference/sourceMapValidationFunctions.js b/tests/baselines/reference/sourceMapValidationFunctions.js index 58222aa48c782..11b3fe40a6b6b 100644 --- a/tests/baselines/reference/sourceMapValidationFunctions.js +++ b/tests/baselines/reference/sourceMapValidationFunctions.js @@ -22,8 +22,8 @@ function greet(greeting) { function greet2(greeting, n, x) { if (n === void 0) { n = 10; } var restParams = []; - for (var _i = 3; _i < arguments.length; _i++) { - restParams[_i - 3] = arguments[_i]; + for (var _a = 3; _a < arguments.length; _a++) { + restParams[_a - 3] = arguments[_a]; } greetings++; return greetings; @@ -31,8 +31,8 @@ function greet2(greeting, n, x) { function foo(greeting, n, x) { if (n === void 0) { n = 10; } var restParams = []; - for (var _i = 3; _i < arguments.length; _i++) { - restParams[_i - 3] = arguments[_i]; + for (var _a = 3; _a < arguments.length; _a++) { + restParams[_a - 3] = arguments[_a]; } return; } diff --git a/tests/baselines/reference/sourceMapValidationFunctions.sourcemap.txt b/tests/baselines/reference/sourceMapValidationFunctions.sourcemap.txt index a9e43e404a747..a1dff1a3b9ac5 100644 --- a/tests/baselines/reference/sourceMapValidationFunctions.sourcemap.txt +++ b/tests/baselines/reference/sourceMapValidationFunctions.sourcemap.txt @@ -145,7 +145,7 @@ sourceFile:sourceMapValidationFunctions.ts 1 >Emitted(8, 5) Source(6, 55) + SourceIndex(0) name (greet2) 2 >Emitted(8, 25) Source(6, 78) + SourceIndex(0) name (greet2) --- ->>> for (var _i = 3; _i < arguments.length; _i++) { +>>> for (var _a = 3; _a < arguments.length; _a++) { 1->^^^^^^^^^ 2 > ^^^^^^^^^^^ 3 > ^ @@ -165,7 +165,7 @@ sourceFile:sourceMapValidationFunctions.ts 5 >Emitted(9, 45) Source(6, 55) + SourceIndex(0) name (greet2) 6 >Emitted(9, 49) Source(6, 78) + SourceIndex(0) name (greet2) --- ->>> restParams[_i - 3] = arguments[_i]; +>>> restParams[_a - 3] = arguments[_a]; 1 >^^^^^^^^ 2 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1 > @@ -272,7 +272,7 @@ sourceFile:sourceMapValidationFunctions.ts 1 >Emitted(17, 5) Source(10, 52) + SourceIndex(0) name (foo) 2 >Emitted(17, 25) Source(10, 75) + SourceIndex(0) name (foo) --- ->>> for (var _i = 3; _i < arguments.length; _i++) { +>>> for (var _a = 3; _a < arguments.length; _a++) { 1->^^^^^^^^^ 2 > ^^^^^^^^^^^ 3 > ^ @@ -292,7 +292,7 @@ sourceFile:sourceMapValidationFunctions.ts 5 >Emitted(18, 45) Source(10, 52) + SourceIndex(0) name (foo) 6 >Emitted(18, 49) Source(10, 75) + SourceIndex(0) name (foo) --- ->>> restParams[_i - 3] = arguments[_i]; +>>> restParams[_a - 3] = arguments[_a]; 1 >^^^^^^^^ 2 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1 > diff --git a/tests/baselines/reference/strictMode5.js b/tests/baselines/reference/strictMode5.js index c46de926dbb55..747c84f5540e4 100644 --- a/tests/baselines/reference/strictMode5.js +++ b/tests/baselines/reference/strictMode5.js @@ -22,8 +22,8 @@ function bar(x: number = 10) { function foo() { "use strict"; var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + args[_a - 0] = arguments[_a]; } } var A = (function () { diff --git a/tests/baselines/reference/stringLiteralTypeIsSubtypeOfString.js b/tests/baselines/reference/stringLiteralTypeIsSubtypeOfString.js index 37aa59bef433f..9ba7e17b2e3a9 100644 --- a/tests/baselines/reference/stringLiteralTypeIsSubtypeOfString.js +++ b/tests/baselines/reference/stringLiteralTypeIsSubtypeOfString.js @@ -133,8 +133,8 @@ var C = (function () { }; C.prototype.concat = function () { var strings = []; - for (var _i = 0; _i < arguments.length; _i++) { - strings[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + strings[_a - 0] = arguments[_a]; } return null; }; diff --git a/tests/baselines/reference/subtypingWithCallSignatures2.js b/tests/baselines/reference/subtypingWithCallSignatures2.js index a887c52d2a159..f863756e60312 100644 --- a/tests/baselines/reference/subtypingWithCallSignatures2.js +++ b/tests/baselines/reference/subtypingWithCallSignatures2.js @@ -254,15 +254,15 @@ var r9a = [r9arg1, r9arg2]; var r9b = [r9arg2, r9arg1]; var r10arg1 = function () { var x = []; - for (var _i = 0; _i < arguments.length; _i++) { - x[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + x[_a - 0] = arguments[_a]; } return x[0]; }; var r10arg2 = function () { var x = []; - for (var _i = 0; _i < arguments.length; _i++) { - x[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + x[_a - 0] = arguments[_a]; } return null; }; diff --git a/tests/baselines/reference/subtypingWithCallSignatures3.js b/tests/baselines/reference/subtypingWithCallSignatures3.js index fb7b0fef5510f..936c6550bca63 100644 --- a/tests/baselines/reference/subtypingWithCallSignatures3.js +++ b/tests/baselines/reference/subtypingWithCallSignatures3.js @@ -170,15 +170,15 @@ var Errors; var r3b = [r3arg, r3arg2]; var r4arg = function () { var x = []; - for (var _i = 0; _i < arguments.length; _i++) { - x[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + x[_a - 0] = arguments[_a]; } return null; }; var r4arg2 = function () { var x = []; - for (var _i = 0; _i < arguments.length; _i++) { - x[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + x[_a - 0] = arguments[_a]; } return null; }; diff --git a/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution1_ES6.js b/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution1_ES6.js index a2a96168fd8c8..2c53b71301467 100644 --- a/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution1_ES6.js +++ b/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution1_ES6.js @@ -25,8 +25,8 @@ var z = foo `${1}${2}${3}`; // any (with error) //// [taggedTemplateStringsWithOverloadResolution1_ES6.js] function foo() { var stuff = []; - for (var _i = 0; _i < arguments.length; _i++) { - stuff[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + stuff[_a - 0] = arguments[_a]; } return undefined; } diff --git a/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution2_ES6.js b/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution2_ES6.js index 44da93f8041b5..1f3762e5331f2 100644 --- a/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution2_ES6.js +++ b/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution2_ES6.js @@ -20,8 +20,8 @@ var d = foo2([], 1); // number //// [taggedTemplateStringsWithOverloadResolution2_ES6.js] function foo1() { var stuff = []; - for (var _i = 0; _i < arguments.length; _i++) { - stuff[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + stuff[_a - 0] = arguments[_a]; } return undefined; } @@ -29,8 +29,8 @@ var a = foo1 `${1}`; // string var b = foo1([], 1); // number function foo2() { var stuff = []; - for (var _i = 0; _i < arguments.length; _i++) { - stuff[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + stuff[_a - 0] = arguments[_a]; } return undefined; } diff --git a/tests/baselines/reference/undeclaredModuleError.js b/tests/baselines/reference/undeclaredModuleError.js index e7e9b70ee7b75..681417085188b 100644 --- a/tests/baselines/reference/undeclaredModuleError.js +++ b/tests/baselines/reference/undeclaredModuleError.js @@ -21,8 +21,8 @@ define(["require", "exports", 'fs'], function (require, exports, fs) { } function join() { var paths = []; - for (var _i = 0; _i < arguments.length; _i++) { - paths[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + paths[_a - 0] = arguments[_a]; } } function instrumentFile(covFileDir, covFileName, originalFilePath) { diff --git a/tests/baselines/reference/underscoreTest1.js b/tests/baselines/reference/underscoreTest1.js index 290e7aa6c888b..0c792f981ae16 100644 --- a/tests/baselines/reference/underscoreTest1.js +++ b/tests/baselines/reference/underscoreTest1.js @@ -985,8 +985,8 @@ var fibonacci = _.memoize(function (n) { }); var log = _.bind(function (message) { var rest = []; - for (var _i = 1; _i < arguments.length; _i++) { - rest[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + rest[_a - 1] = arguments[_a]; } }, Date); _.delay(log, 1000, 'logged later'); diff --git a/tests/baselines/reference/varArgParamTypeCheck.js b/tests/baselines/reference/varArgParamTypeCheck.js index c2a33416436a0..761e0d5ee5190 100644 --- a/tests/baselines/reference/varArgParamTypeCheck.js +++ b/tests/baselines/reference/varArgParamTypeCheck.js @@ -24,8 +24,8 @@ sequence( //// [varArgParamTypeCheck.js] function sequence() { var sequences = []; - for (var _i = 0; _i < arguments.length; _i++) { - sequences[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + sequences[_a - 0] = arguments[_a]; } } function callback(clb) { diff --git a/tests/baselines/reference/vararg.js b/tests/baselines/reference/vararg.js index 038afb90cbc50..0a5e23e2fab45 100644 --- a/tests/baselines/reference/vararg.js +++ b/tests/baselines/reference/vararg.js @@ -46,8 +46,8 @@ var M; } C.prototype.f = function (x) { var rest = []; - for (var _i = 1; _i < arguments.length; _i++) { - rest[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + rest[_a - 1] = arguments[_a]; } var sum = 0; for (var i = 0; i < rest.length; i++) { @@ -58,14 +58,14 @@ var M; }; C.prototype.fnope = function (x) { var rest = []; - for (var _i = 1; _i < arguments.length; _i++) { - rest[_i - 1] = arguments[_i]; + for (var _a = 1; _a < arguments.length; _a++) { + rest[_a - 1] = arguments[_a]; } }; C.prototype.fonly = function () { var rest = []; - for (var _i = 0; _i < arguments.length; _i++) { - rest[_i - 0] = arguments[_i]; + for (var _a = 0; _a < arguments.length; _a++) { + rest[_a - 0] = arguments[_a]; } builder = ""; for (var i = 0; i < rest.length; i++) { From 7994e9013c7478a7902b21e3224e26aad999b84b Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 2 Dec 2014 12:51:44 -0800 Subject: [PATCH 25/33] Emit for destructuring parameter declarations --- src/compiler/emitter.ts | 129 +++++++++++++++++++++++----------------- 1 file changed, 73 insertions(+), 56 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 78ab8d6ba4796..978924a949c9c 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -323,7 +323,8 @@ module ts { var extendsEmitted = false; var tempCount = 0; - var tempNames: Identifier[]; + var tempVariables: Identifier[]; + var tempParameters: Identifier[]; /** write emitted output to disk*/ var writeEmittedFiles = writeJavaScriptFile; @@ -718,25 +719,27 @@ module ts { writeFile(jsFilePath, emitOutput, writeByteOrderMark); } - function getTempVariableName(location: Node) { + function createTempVariable(location: Node): Identifier { do { // First _a..._z, then _0, _1, ... var name = "_" + (tempCount < 26 ? String.fromCharCode(tempCount + 0x61) : tempCount - 26); tempCount++; } while (!resolver.isUnknownIdentifier(location, name)); - return name; + var result = createNode(SyntaxKind.Identifier); + result.text = name; + return result; } function recordTempDeclaration(name: Identifier) { - if (!tempNames) { - tempNames = []; + if (!tempVariables) { + tempVariables = []; } - tempNames.push(name); + tempVariables.push(name); } function emitTempDeclarations(newLine: boolean) { - if (tempNames) { + if (tempVariables) { if (newLine) { writeLine(); } @@ -744,7 +747,7 @@ module ts { write(" "); } write("var "); - emitCommaList(tempNames); + emitCommaList(tempVariables); write(";"); } } @@ -1534,13 +1537,13 @@ module ts { emitEnd(node.name); } - function emitDestructuring(root: BinaryExpression | BindingElement) { + function emitDestructuring(root: BinaryExpression | BindingElement, value?: Expression) { var emitCount = 0; if (root.kind === SyntaxKind.BinaryExpression) { emitAssignmentExpression(root); } else { - emitBindingElement(root, undefined); + emitBindingElement(root, value); } function emitAssignment(name: Identifier, value: Expression) { @@ -1552,15 +1555,13 @@ module ts { emit(value); } - function createTemporaryVariable(expr: Expression): Expression { + function ensureIdentifier(expr: Expression): Expression { if (expr.kind !== SyntaxKind.Identifier) { - var tempName = getTempVariableName(root); - var identifier = createNode(SyntaxKind.Identifier); - identifier.text = tempName; - emitAssignment(identifier, expr); + var identifier = createTempVariable(root); if (root.kind === SyntaxKind.BinaryExpression) { recordTempDeclaration(identifier); } + emitAssignment(identifier, expr); expr = identifier; } return expr; @@ -1578,7 +1579,7 @@ module ts { function createDefaultValueCheck(value: Expression, defaultValue: Expression): Expression { // The value expression will be evaluated twice, so for anything but a simple identifier // we need to generate a temporary variable - value = createTemporaryVariable(value); + value = ensureIdentifier(value); // Return the expression 'value === void 0 ? defaultValue : value' var equals = createNode(SyntaxKind.BinaryExpression); equals.left = value; @@ -1628,7 +1629,7 @@ module ts { if (properties.length !== 1) { // For anything but a single element destructuring we need to generate a temporary // to ensure value is evaluated exactly once. - value = createTemporaryVariable(value); + value = ensureIdentifier(value); } for (var i = 0; i < properties.length; i++) { var p = properties[i]; @@ -1645,7 +1646,7 @@ module ts { if (elements.length !== 1) { // For anything but a single element destructuring we need to generate a temporary // to ensure value is evaluated exactly once. - value = createTemporaryVariable(value); + value = ensureIdentifier(value); } for (var i = 0; i < elements.length; i++) { var e = elements[i]; @@ -1681,7 +1682,7 @@ module ts { if (root.parent.kind !== SyntaxKind.ParenExpression) { write("("); } - value = createTemporaryVariable(value); + value = ensureIdentifier(value); emitDestructuringAssignment(target, value); write(", "); emit(value); @@ -1706,7 +1707,7 @@ module ts { if (elements.length !== 1) { // For anything but a single element destructuring we need to generate a temporary // to ensure value is evaluated exactly once. - value = createTemporaryVariable(value); + value = ensureIdentifier(value); } for (var i = 0; i < elements.length; i++) { var element = elements[i]; @@ -1759,40 +1760,50 @@ module ts { function emitParameter(node: ParameterDeclaration) { emitLeadingComments(node); - if (compilerOptions.target < ScriptTarget.ES6) { - if (isBindingPattern(node.name)) { - write("__" + indexOf((node.parent).parameters, node)); - } - else { - emit(node.name); + if (isBindingPattern(node.name)) { + var name = createTempVariable(node); + if (!tempParameters) { + tempParameters = []; } + tempParameters.push(name); + emit(name); } else { - if (node.propertyName) { - emit(node.propertyName); - write(": "); - } emit(node.name); - //emitOptional(" = ", node.initializer); } + // TODO(andersh): Enable ES6 code generation below + //if (node.propertyName) { + // emit(node.propertyName); + // write(": "); + //} + //emit(node.name); + //emitOptional(" = ", node.initializer); emitTrailingComments(node); } function emitDefaultValueAssignments(node: FunctionLikeDeclaration) { - forEach(node.parameters, param => { - if (param.initializer) { + var tempIndex = 0; + forEach(node.parameters, p => { + if (isBindingPattern(p.name)) { writeLine(); - emitStart(param); + write("var "); + emitDestructuring(p, tempParameters[tempIndex]); + write(";"); + tempIndex++; + } + else if (p.initializer) { + writeLine(); + emitStart(p); write("if ("); - emitNode(param.name); + emitNode(p.name); write(" === void 0)"); - emitEnd(param); + emitEnd(p); write(" { "); - emitStart(param); - emitNode(param.name); + emitStart(p); + emitNode(p.name); write(" = "); - emitNode(param.initializer); - emitEnd(param); + emitNode(p.initializer); + emitEnd(p); write("; }"); } }); @@ -1802,7 +1813,7 @@ module ts { if (hasRestParameters(node)) { var restIndex = node.parameters.length - 1; var restParam = node.parameters[restIndex]; - var tempName = getTempVariableName(node); + var tempName = createTempVariable(node).text; writeLine(); emitLeadingComments(restParam); emitStart(restParam); @@ -1884,12 +1895,14 @@ module ts { } function emitSignatureAndBody(node: FunctionLikeDeclaration) { - emitSignatureParameters(node); - write(" {"); var saveTempCount = tempCount; - var saveTempNames = tempNames; + var saveTempVariables = tempVariables; + var saveTempParameters = tempParameters; tempCount = 0; - tempNames = undefined; + tempVariables = undefined; + tempParameters = undefined; + emitSignatureParameters(node); + write(" {"); scopeEmitStart(node); increaseIndent(); @@ -1944,8 +1957,6 @@ module ts { } } scopeEmitEnd(); - tempCount = saveTempCount; - tempNames = saveTempNames; if (node.flags & NodeFlags.Export) { writeLine(); emitStart(node); @@ -1955,6 +1966,9 @@ module ts { emitEnd(node); write(";"); } + tempCount = saveTempCount; + tempVariables = saveTempVariables; + tempParameters = saveTempParameters; } function findInitialSuperCall(ctor: ConstructorDeclaration): ExpressionStatement { @@ -2155,6 +2169,12 @@ module ts { emitTrailingComments(node); function emitConstructorOfClass() { + var saveTempCount = tempCount; + var saveTempVariables = tempVariables; + var saveTempParameters = tempParameters; + tempCount = 0; + tempVariables = undefined; + tempParameters = undefined; // Emit the constructor overload pinned comments forEach(node.members, member => { if (member.kind === SyntaxKind.Constructor && !(member).body) { @@ -2171,10 +2191,6 @@ module ts { emit(node.name); emitSignatureParameters(ctor); write(" {"); - var saveTempCount = tempCount; - var saveTempNames = tempNames; - tempCount = 0; - tempNames = undefined; scopeEmitStart(node, "constructor"); increaseIndent(); if (ctor) { @@ -2215,12 +2231,13 @@ module ts { decreaseIndent(); emitToken(SyntaxKind.CloseBraceToken, ctor ? (ctor.body).statements.end : node.members.end); scopeEmitEnd(); - tempCount = saveTempCount; - tempNames = saveTempNames; emitEnd(ctor || node); if (ctor) { emitTrailingComments(ctor); } + tempCount = saveTempCount; + tempVariables = saveTempVariables; + tempParameters = saveTempParameters; } } @@ -2326,12 +2343,12 @@ module ts { write(") "); if (node.body.kind === SyntaxKind.ModuleBlock) { var saveTempCount = tempCount; - var saveTempNames = tempNames; + var saveTempVariables = tempVariables; tempCount = 0; - tempNames = undefined; + tempVariables = undefined; emit(node.body); tempCount = saveTempCount; - tempNames = saveTempNames; + tempVariables = saveTempVariables; } else { write("{"); From 0731a289781ad2cff1e7995b8b7856a926d34918 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 2 Dec 2014 15:52:29 -0800 Subject: [PATCH 26/33] Support exported destructuring variable declarations Support .d.ts generation for functions with destructuring parameters --- src/compiler/emitter.ts | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 978924a949c9c..f3b54ca242330 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1539,6 +1539,7 @@ module ts { function emitDestructuring(root: BinaryExpression | BindingElement, value?: Expression) { var emitCount = 0; + var isDeclaration = (root.kind === SyntaxKind.VariableDeclaration && !(root.flags & NodeFlags.Export)) || root.kind === SyntaxKind.Parameter; if (root.kind === SyntaxKind.BinaryExpression) { emitAssignmentExpression(root); } @@ -1550,7 +1551,12 @@ module ts { if (emitCount++) { write(", "); } - emit(name); + if (name.parent && name.parent.kind === SyntaxKind.VariableDeclaration) { + emitModuleMemberName(name.parent); + } + else { + emit(name); + } write(" = "); emit(value); } @@ -1558,7 +1564,7 @@ module ts { function ensureIdentifier(expr: Expression): Expression { if (expr.kind !== SyntaxKind.Identifier) { var identifier = createTempVariable(root); - if (root.kind === SyntaxKind.BinaryExpression) { + if (!isDeclaration) { recordTempDeclaration(identifier); } emitAssignment(identifier, expr); @@ -3611,7 +3617,12 @@ module ts { if (node.flags & NodeFlags.Rest) { write("..."); } - emitSourceTextOfNode(node.name); + if (isBindingPattern(node.name)) { + write("_" + indexOf((node.parent).parameters, node)); + } + else { + emitSourceTextOfNode(node.name); + } if (node.initializer || (node.flags & NodeFlags.QuestionMark)) { write("?"); } From dc39de19e8d89d3292689dd62ef4d645c3095eed Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 2 Dec 2014 15:53:13 -0800 Subject: [PATCH 27/33] Removing fourslash test that no longer applies --- tests/cases/fourslash/unclosedFunctionErrorRecovery2.ts | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 tests/cases/fourslash/unclosedFunctionErrorRecovery2.ts diff --git a/tests/cases/fourslash/unclosedFunctionErrorRecovery2.ts b/tests/cases/fourslash/unclosedFunctionErrorRecovery2.ts deleted file mode 100644 index 8af1be00cc45f..0000000000000 --- a/tests/cases/fourslash/unclosedFunctionErrorRecovery2.ts +++ /dev/null @@ -1,8 +0,0 @@ -/// - -////function alpha( {} -/////**/ -////function beta() { alpha(); } -//// - -verify.not.errorExistsAfterMarker(); \ No newline at end of file From ecfcb9dded83f078d1482060a39bfd7b7da4a3ca Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 2 Dec 2014 16:01:32 -0800 Subject: [PATCH 28/33] Fixing fourslash test --- tests/cases/fourslash/goToDefinitionUnionTypeProperty2.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/cases/fourslash/goToDefinitionUnionTypeProperty2.ts b/tests/cases/fourslash/goToDefinitionUnionTypeProperty2.ts index 6536bb76e7dda..960a6b7a86e34 100644 --- a/tests/cases/fourslash/goToDefinitionUnionTypeProperty2.ts +++ b/tests/cases/fourslash/goToDefinitionUnionTypeProperty2.ts @@ -18,8 +18,8 @@ goTo.marker("propertyReference"); goTo.definition(0); -verify.caretAtMarker("propertyDefinition1"); +verify.caretAtMarker("propertyDefinition2"); goTo.marker("propertyReference"); goTo.definition(1); -verify.caretAtMarker("propertyDefinition2"); +verify.caretAtMarker("propertyDefinition1"); From 65d151076945fff60e4b2aff80f04401ab3ca891 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 2 Dec 2014 16:23:37 -0800 Subject: [PATCH 29/33] Adding rudimentary tests --- .../declarationInAmbientContext.errors.txt | 12 + .../declarationWithNoInitializer.errors.txt | 12 + .../declarationsAndAssignments.errors.txt | 202 ++++++++++++ .../reference/declarationsAndAssignments.js | 288 ++++++++++++++++++ .../declarationInAmbientContext.ts | 2 + .../declarationWithNoInitializer.ts | 2 + .../declarationsAndAssignments.ts | 149 +++++++++ 7 files changed, 667 insertions(+) create mode 100644 tests/baselines/reference/declarationInAmbientContext.errors.txt create mode 100644 tests/baselines/reference/declarationWithNoInitializer.errors.txt create mode 100644 tests/baselines/reference/declarationsAndAssignments.errors.txt create mode 100644 tests/baselines/reference/declarationsAndAssignments.js create mode 100644 tests/cases/conformance/es6/destructuring/declarationInAmbientContext.ts create mode 100644 tests/cases/conformance/es6/destructuring/declarationWithNoInitializer.ts create mode 100644 tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts diff --git a/tests/baselines/reference/declarationInAmbientContext.errors.txt b/tests/baselines/reference/declarationInAmbientContext.errors.txt new file mode 100644 index 0000000000000..85e8808a278b6 --- /dev/null +++ b/tests/baselines/reference/declarationInAmbientContext.errors.txt @@ -0,0 +1,12 @@ +tests/cases/conformance/es6/destructuring/declarationInAmbientContext.ts(1,13): error TS1166: Destructuring declarations are not allowed in ambient contexts. +tests/cases/conformance/es6/destructuring/declarationInAmbientContext.ts(2,13): error TS1166: Destructuring declarations are not allowed in ambient contexts. + + +==== tests/cases/conformance/es6/destructuring/declarationInAmbientContext.ts (2 errors) ==== + declare var [a, b]; // Error, destructuring declaration not allowed in ambient context + ~~~~~~ +!!! error TS1166: Destructuring declarations are not allowed in ambient contexts. + declare var {c, d}; // Error, destructuring declaration not allowed in ambient context + ~~~~~~ +!!! error TS1166: Destructuring declarations are not allowed in ambient contexts. + \ No newline at end of file diff --git a/tests/baselines/reference/declarationWithNoInitializer.errors.txt b/tests/baselines/reference/declarationWithNoInitializer.errors.txt new file mode 100644 index 0000000000000..6d5c2022a9582 --- /dev/null +++ b/tests/baselines/reference/declarationWithNoInitializer.errors.txt @@ -0,0 +1,12 @@ +tests/cases/conformance/es6/destructuring/declarationWithNoInitializer.ts(1,5): error TS1165: A destructuring declaration must have an initializer. +tests/cases/conformance/es6/destructuring/declarationWithNoInitializer.ts(2,5): error TS1165: A destructuring declaration must have an initializer. + + +==== tests/cases/conformance/es6/destructuring/declarationWithNoInitializer.ts (2 errors) ==== + var [a, b]; // Error, no initializer + ~~~~~~ +!!! error TS1165: A destructuring declaration must have an initializer. + var {c, d}; // Error, no initializer + ~~~~~~ +!!! error TS1165: A destructuring declaration must have an initializer. + \ No newline at end of file diff --git a/tests/baselines/reference/declarationsAndAssignments.errors.txt b/tests/baselines/reference/declarationsAndAssignments.errors.txt new file mode 100644 index 0000000000000..2c9a54c869c1f --- /dev/null +++ b/tests/baselines/reference/declarationsAndAssignments.errors.txt @@ -0,0 +1,202 @@ +tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(5,16): error TS2460: Type '[number, string]' has no property '2'. +tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(56,17): error TS2322: Type 'number' is not assignable to type 'string'. +tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(63,13): error TS2460: Type '[number]' has no property '1'. +tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(63,16): error TS2460: Type '[number]' has no property '2'. +tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(67,9): error TS2461: Type '{ [x: number]: undefined; }' is not an array type. +tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(68,9): error TS2461: Type '{ [x: number]: number; 0: number; 1: number; }' is not an array type. +tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(73,11): error TS2459: Type '{}' has no property 'a' and no string index signature. +tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(73,14): error TS2459: Type '{}' has no property 'b' and no string index signature. +tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(74,11): error TS2459: Type 'undefined[]' has no property 'a' and no string index signature. +tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(74,14): error TS2459: Type 'undefined[]' has no property 'b' and no string index signature. +tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(106,5): error TS2345: Argument of type '[number, [string, { y: boolean; }]]' is not assignable to parameter of type '[number, [string, { x: any; y?: boolean; }]]'. + Types of property '1' are incompatible. + Type '[string, { y: boolean; }]' is not assignable to type '[string, { x: any; y?: boolean; }]'. + Types of property '1' are incompatible. + Type '{ y: boolean; }' is not assignable to type '{ x: any; y?: boolean; }'. + Property 'x' is missing in type '{ y: boolean; }'. +tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(138,6): error TS2322: Type 'string' is not assignable to type 'number'. +tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(138,9): error TS2322: Type 'number' is not assignable to type 'string'. + + +==== tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts (13 errors) ==== + function f0() { + var [] = [1, "hello"]; + var [x] = [1, "hello"]; + var [x, y] = [1, "hello"]; + var [x, y, z] = [1, "hello"]; // Error + ~ +!!! error TS2460: Type '[number, string]' has no property '2'. + var [,, z] = [0, 1, 2]; + var x: number; + var y: string; + } + + function f1() { + var a = [1, "hello"]; + var [x] = a; + var [x, y] = a; + var [x, y, z] = a; + var x: number | string; + var y: number | string; + var z: number | string; + } + + function f2() { + var { } = { x: 5, y: "hello" }; + var { x } = { x: 5, y: "hello" }; + var { y } = { x: 5, y: "hello" }; + var { x, y } = { x: 5, y: "hello" }; + var x: number; + var y: string; + var { x: a } = { x: 5, y: "hello" }; + var { y: b } = { x: 5, y: "hello" }; + var { x: a, y: b } = { x: 5, y: "hello" }; + var a: number; + var b: string; + } + + function f3() { + var [x, [y, [z]]] = [1, ["hello", [true]]]; + var x: number; + var y: string; + var z: boolean; + } + + function f4() { + var { a: x, b: { a: y, b: { a: z }}} = { a: 1, b: { a: "hello", b: { a: true } } }; + var x: number; + var y: string; + var z: boolean; + } + + function f6() { + var [x = 0, y = ""] = [1, "hello"]; + var x: number; + var y: string; + } + + function f7() { + var [x = 0, y = 1] = [1, "hello"]; // Error, initializer for y must be string + ~ +!!! error TS2322: Type 'number' is not assignable to type 'string'. + var x: number; + var y: string; + } + + function f8() { + var [a, b, c] = []; // Ok, [] is an array + var [d, e, f] = [1]; // Error, [1] is a tuple + ~ +!!! error TS2460: Type '[number]' has no property '1'. + ~ +!!! error TS2460: Type '[number]' has no property '2'. + } + + function f9() { + var [a, b] = {}; // Error, not array type + ~~~~~~ +!!! error TS2461: Type '{ [x: number]: undefined; }' is not an array type. + var [c, d] = { 0: 10, 1: 20 }; // Error, not array type + ~~~~~~ +!!! error TS2461: Type '{ [x: number]: number; 0: number; 1: number; }' is not an array type. + var [e, f] = [10, 20]; + } + + function f10() { + var { a, b } = {}; // Error + ~ +!!! error TS2459: Type '{}' has no property 'a' and no string index signature. + ~ +!!! error TS2459: Type '{}' has no property 'b' and no string index signature. + var { a, b } = []; // Error + ~ +!!! error TS2459: Type 'undefined[]' has no property 'a' and no string index signature. + ~ +!!! error TS2459: Type 'undefined[]' has no property 'b' and no string index signature. + } + + function f11() { + var { x: a, y: b } = { x: 10, y: "hello" }; + var { 0: a, 1: b } = { 0: 10, 1: "hello" }; + var { "<": a, ">": b } = { "<": 10, ">": "hello" }; + var { 0: a, 1: b } = [10, "hello"]; + var a: number; + var b: string; + } + + function f12() { + var [a, [b, { x, y: c }] = ["abc", { x: 10, y: false }]] = [1, ["hello", { x: 5, y: true }]]; + var a: number; + var b: string; + var x: number; + var c: boolean; + } + + function f13() { + var [x, y] = [1, "hello"]; + var [a, b] = [[x, y], { x: x, y: y }]; + } + + function f14([a = 1, [b = "hello", { x, y: c = false }]]) { + var a: number; + var b: string; + var c: boolean; + } + f14([2, ["abc", { x: 0, y: true }]]); + f14([2, ["abc", { x: 0 }]]); + f14([2, ["abc", { y: false }]]); // Error, no x + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '[number, [string, { y: boolean; }]]' is not assignable to parameter of type '[number, [string, { x: any; y?: boolean; }]]'. +!!! error TS2345: Types of property '1' are incompatible. +!!! error TS2345: Type '[string, { y: boolean; }]' is not assignable to type '[string, { x: any; y?: boolean; }]'. +!!! error TS2345: Types of property '1' are incompatible. +!!! error TS2345: Type '{ y: boolean; }' is not assignable to type '{ x: any; y?: boolean; }'. +!!! error TS2345: Property 'x' is missing in type '{ y: boolean; }'. + + module M { + export var [a, b] = [1, 2]; + } + + function f15() { + var a = "hello"; + var b = 1; + var c = true; + return { a, b, c }; + } + + function f16() { + var { a, b, c } = f15(); + } + + function f17({ a = "", b = 0, c = false }) { + } + + f17({}); + f17({ a: "hello" }); + f17({ c: true }); + f17(f15()); + + function g4() { + var a: number; + var b: string; + var aa: number[]; + ({ a, b } = { a, b }); + ({ a, b } = { b, a }); + [aa[0], b] = [a, b]; + [a, b] = [b, a]; // Error + ~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. + ~ +!!! error TS2322: Type 'number' is not assignable to type 'string'. + [a = 1, b = "abc"] = [2, "def"]; + } + + function g5() { + var a, b; + [a, b] = [1, 2]; + [a, b] = [b, a]; + ({ a, b } = { b, a }); + [[a, b] = [1, 2]] = [[2, 3]]; + var x = ([a, b] = [1, 2]); + } + \ No newline at end of file diff --git a/tests/baselines/reference/declarationsAndAssignments.js b/tests/baselines/reference/declarationsAndAssignments.js new file mode 100644 index 0000000000000..ba2e74dc420a3 --- /dev/null +++ b/tests/baselines/reference/declarationsAndAssignments.js @@ -0,0 +1,288 @@ +//// [declarationsAndAssignments.ts] +function f0() { + var [] = [1, "hello"]; + var [x] = [1, "hello"]; + var [x, y] = [1, "hello"]; + var [x, y, z] = [1, "hello"]; // Error + var [,, z] = [0, 1, 2]; + var x: number; + var y: string; +} + +function f1() { + var a = [1, "hello"]; + var [x] = a; + var [x, y] = a; + var [x, y, z] = a; + var x: number | string; + var y: number | string; + var z: number | string; +} + +function f2() { + var { } = { x: 5, y: "hello" }; + var { x } = { x: 5, y: "hello" }; + var { y } = { x: 5, y: "hello" }; + var { x, y } = { x: 5, y: "hello" }; + var x: number; + var y: string; + var { x: a } = { x: 5, y: "hello" }; + var { y: b } = { x: 5, y: "hello" }; + var { x: a, y: b } = { x: 5, y: "hello" }; + var a: number; + var b: string; +} + +function f3() { + var [x, [y, [z]]] = [1, ["hello", [true]]]; + var x: number; + var y: string; + var z: boolean; +} + +function f4() { + var { a: x, b: { a: y, b: { a: z }}} = { a: 1, b: { a: "hello", b: { a: true } } }; + var x: number; + var y: string; + var z: boolean; +} + +function f6() { + var [x = 0, y = ""] = [1, "hello"]; + var x: number; + var y: string; +} + +function f7() { + var [x = 0, y = 1] = [1, "hello"]; // Error, initializer for y must be string + var x: number; + var y: string; +} + +function f8() { + var [a, b, c] = []; // Ok, [] is an array + var [d, e, f] = [1]; // Error, [1] is a tuple +} + +function f9() { + var [a, b] = {}; // Error, not array type + var [c, d] = { 0: 10, 1: 20 }; // Error, not array type + var [e, f] = [10, 20]; +} + +function f10() { + var { a, b } = {}; // Error + var { a, b } = []; // Error +} + +function f11() { + var { x: a, y: b } = { x: 10, y: "hello" }; + var { 0: a, 1: b } = { 0: 10, 1: "hello" }; + var { "<": a, ">": b } = { "<": 10, ">": "hello" }; + var { 0: a, 1: b } = [10, "hello"]; + var a: number; + var b: string; +} + +function f12() { + var [a, [b, { x, y: c }] = ["abc", { x: 10, y: false }]] = [1, ["hello", { x: 5, y: true }]]; + var a: number; + var b: string; + var x: number; + var c: boolean; +} + +function f13() { + var [x, y] = [1, "hello"]; + var [a, b] = [[x, y], { x: x, y: y }]; +} + +function f14([a = 1, [b = "hello", { x, y: c = false }]]) { + var a: number; + var b: string; + var c: boolean; +} +f14([2, ["abc", { x: 0, y: true }]]); +f14([2, ["abc", { x: 0 }]]); +f14([2, ["abc", { y: false }]]); // Error, no x + +module M { + export var [a, b] = [1, 2]; +} + +function f15() { + var a = "hello"; + var b = 1; + var c = true; + return { a, b, c }; +} + +function f16() { + var { a, b, c } = f15(); +} + +function f17({ a = "", b = 0, c = false }) { +} + +f17({}); +f17({ a: "hello" }); +f17({ c: true }); +f17(f15()); + +function g4() { + var a: number; + var b: string; + var aa: number[]; + ({ a, b } = { a, b }); + ({ a, b } = { b, a }); + [aa[0], b] = [a, b]; + [a, b] = [b, a]; // Error + [a = 1, b = "abc"] = [2, "def"]; +} + +function g5() { + var a, b; + [a, b] = [1, 2]; + [a, b] = [b, a]; + ({ a, b } = { b, a }); + [[a, b] = [1, 2]] = [[2, 3]]; + var x = ([a, b] = [1, 2]); +} + + +//// [declarationsAndAssignments.js] +function f0() { + var _a = [1, "hello"]; + var x = ([1, "hello"])[0]; + var _b = [1, "hello"], x = _b[0], y = _b[1]; + var _c = [1, "hello"], x = _c[0], y = _c[1], z = _c[2]; // Error + var _d = [0, 1, 2], z = _d[2]; + var x; + var y; +} +function f1() { + var a = [1, "hello"]; + var x = a[0]; + var x = a[0], y = a[1]; + var x = a[0], y = a[1], z = a[2]; + var x; + var y; + var z; +} +function f2() { + var _a = { x: 5, y: "hello" }; + var x = ({ x: 5, y: "hello" }).x; + var y = ({ x: 5, y: "hello" }).y; + var _b = { x: 5, y: "hello" }, x = _b.x, y = _b.y; + var x; + var y; + var a = ({ x: 5, y: "hello" }).x; + var b = ({ x: 5, y: "hello" }).y; + var _c = { x: 5, y: "hello" }, a = _c.x, b = _c.y; + var a; + var b; +} +function f3() { + var _a = [1, ["hello", [true]]], x = _a[0], _b = _a[1], y = _b[0], z = _b[1][0]; + var x; + var y; + var z; +} +function f4() { + var _a = { a: 1, b: { a: "hello", b: { a: true } } }, x = _a.a, _b = _a.b, y = _b.a, z = _b.b.a; + var x; + var y; + var z; +} +function f6() { + var _a = [1, "hello"], _b = _a[0], x = _b === void 0 ? 0 : _b, _c = _a[1], y = _c === void 0 ? "" : _c; + var x; + var y; +} +function f7() { + var _a = [1, "hello"], _b = _a[0], x = _b === void 0 ? 0 : _b, _c = _a[1], y = _c === void 0 ? 1 : _c; // Error, initializer for y must be string + var x; + var y; +} +function f8() { + var _a = [], a = _a[0], b = _a[1], c = _a[2]; // Ok, [] is an array + var _b = [1], d = _b[0], e = _b[1], f = _b[2]; // Error, [1] is a tuple +} +function f9() { + var _a = {}, a = _a[0], b = _a[1]; // Error, not array type + var _b = { 0: 10, 1: 20 }, c = _b[0], d = _b[1]; // Error, not array type + var _c = [10, 20], e = _c[0], f = _c[1]; +} +function f10() { + var _a = {}, a = _a.a, b = _a.b; // Error + var _b = [], a = _b.a, b = _b.b; // Error +} +function f11() { + var _a = { x: 10, y: "hello" }, a = _a.x, b = _a.y; + var _b = { 0: 10, 1: "hello" }, a = _b[0], b = _b[1]; + var _c = { "<": 10, ">": "hello" }, a = _c["<"], b = _c[">"]; + var _d = [10, "hello"], a = _d[0], b = _d[1]; + var a; + var b; +} +function f12() { + var _a = [1, ["hello", { x: 5, y: true }]], a = _a[0], _b = _a[1], _c = _b === void 0 ? ["abc", { x: 10, y: false }] : _b, b = _c[0], _d = _c[1], x = _d.x, c = _d.y; + var a; + var b; + var x; + var c; +} +function f13() { + var _a = [1, "hello"], x = _a[0], y = _a[1]; + var _b = [[x, y], { x: x, y: y }], a = _b[0], b = _b[1]; +} +function f14(_a) { + var _b = _a[0], a = _b === void 0 ? 1 : _b, _c = _a[1], _d = _c[0], b = _d === void 0 ? "hello" : _d, _e = _c[1], x = _e.x, _f = _e.y, c = _f === void 0 ? false : _f; + var a; + var b; + var c; +} +f14([2, ["abc", { x: 0, y: true }]]); +f14([2, ["abc", { x: 0 }]]); +f14([2, ["abc", { y: false }]]); // Error, no x +var M; +(function (M) { + _a = [1, 2], M.a = _a[0], M.b = _a[1]; + var _a; +})(M || (M = {})); +function f15() { + var a = "hello"; + var b = 1; + var c = true; + return { a: a, b: b, c: c }; +} +function f16() { + var _a = f15(), a = _a.a, b = _a.b, c = _a.c; +} +function f17(_a) { + var _b = _a.a, a = _b === void 0 ? "" : _b, _c = _a.b, b = _c === void 0 ? 0 : _c, _d = _a.c, c = _d === void 0 ? false : _d; +} +f17({}); +f17({ a: "hello" }); +f17({ c: true }); +f17(f15()); +function g4() { + var a; + var b; + var aa; + (_a = { a: a, b: b }, a = _a.a, b = _a.b, _a); + (_b = { b: b, a: a }, a = _b.a, b = _b.b, _b); + _c = [a, b], aa[0] = _c[0], b = _c[1]; + _d = [b, a], a = _d[0], b = _d[1]; // Error + _e = [2, "def"], _f = _e[0], a = _f === void 0 ? 1 : _f, _g = _e[1], b = _g === void 0 ? "abc" : _g; + var _a, _b, _c, _d, _e, _f, _g; +} +function g5() { + var a, b; + _a = [1, 2], a = _a[0], b = _a[1]; + _b = [b, a], a = _b[0], b = _b[1]; + (_c = { b: b, a: a }, a = _c.a, b = _c.b, _c); + _d = ([[2, 3]])[0], _e = _d === void 0 ? [1, 2] : _d, a = _e[0], b = _e[1]; + var x = (_f = [1, 2], a = _f[0], b = _f[1], _f); + var _a, _b, _c, _d, _e, _f; +} diff --git a/tests/cases/conformance/es6/destructuring/declarationInAmbientContext.ts b/tests/cases/conformance/es6/destructuring/declarationInAmbientContext.ts new file mode 100644 index 0000000000000..a3db3753de489 --- /dev/null +++ b/tests/cases/conformance/es6/destructuring/declarationInAmbientContext.ts @@ -0,0 +1,2 @@ +declare var [a, b]; // Error, destructuring declaration not allowed in ambient context +declare var {c, d}; // Error, destructuring declaration not allowed in ambient context diff --git a/tests/cases/conformance/es6/destructuring/declarationWithNoInitializer.ts b/tests/cases/conformance/es6/destructuring/declarationWithNoInitializer.ts new file mode 100644 index 0000000000000..1fb8b07e585eb --- /dev/null +++ b/tests/cases/conformance/es6/destructuring/declarationWithNoInitializer.ts @@ -0,0 +1,2 @@ +var [a, b]; // Error, no initializer +var {c, d}; // Error, no initializer diff --git a/tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts b/tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts new file mode 100644 index 0000000000000..04cdd153a5763 --- /dev/null +++ b/tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts @@ -0,0 +1,149 @@ +function f0() { + var [] = [1, "hello"]; + var [x] = [1, "hello"]; + var [x, y] = [1, "hello"]; + var [x, y, z] = [1, "hello"]; // Error + var [,, z] = [0, 1, 2]; + var x: number; + var y: string; +} + +function f1() { + var a = [1, "hello"]; + var [x] = a; + var [x, y] = a; + var [x, y, z] = a; + var x: number | string; + var y: number | string; + var z: number | string; +} + +function f2() { + var { } = { x: 5, y: "hello" }; + var { x } = { x: 5, y: "hello" }; + var { y } = { x: 5, y: "hello" }; + var { x, y } = { x: 5, y: "hello" }; + var x: number; + var y: string; + var { x: a } = { x: 5, y: "hello" }; + var { y: b } = { x: 5, y: "hello" }; + var { x: a, y: b } = { x: 5, y: "hello" }; + var a: number; + var b: string; +} + +function f3() { + var [x, [y, [z]]] = [1, ["hello", [true]]]; + var x: number; + var y: string; + var z: boolean; +} + +function f4() { + var { a: x, b: { a: y, b: { a: z }}} = { a: 1, b: { a: "hello", b: { a: true } } }; + var x: number; + var y: string; + var z: boolean; +} + +function f6() { + var [x = 0, y = ""] = [1, "hello"]; + var x: number; + var y: string; +} + +function f7() { + var [x = 0, y = 1] = [1, "hello"]; // Error, initializer for y must be string + var x: number; + var y: string; +} + +function f8() { + var [a, b, c] = []; // Ok, [] is an array + var [d, e, f] = [1]; // Error, [1] is a tuple +} + +function f9() { + var [a, b] = {}; // Error, not array type + var [c, d] = { 0: 10, 1: 20 }; // Error, not array type + var [e, f] = [10, 20]; +} + +function f10() { + var { a, b } = {}; // Error + var { a, b } = []; // Error +} + +function f11() { + var { x: a, y: b } = { x: 10, y: "hello" }; + var { 0: a, 1: b } = { 0: 10, 1: "hello" }; + var { "<": a, ">": b } = { "<": 10, ">": "hello" }; + var { 0: a, 1: b } = [10, "hello"]; + var a: number; + var b: string; +} + +function f12() { + var [a, [b, { x, y: c }] = ["abc", { x: 10, y: false }]] = [1, ["hello", { x: 5, y: true }]]; + var a: number; + var b: string; + var x: number; + var c: boolean; +} + +function f13() { + var [x, y] = [1, "hello"]; + var [a, b] = [[x, y], { x: x, y: y }]; +} + +function f14([a = 1, [b = "hello", { x, y: c = false }]]) { + var a: number; + var b: string; + var c: boolean; +} +f14([2, ["abc", { x: 0, y: true }]]); +f14([2, ["abc", { x: 0 }]]); +f14([2, ["abc", { y: false }]]); // Error, no x + +module M { + export var [a, b] = [1, 2]; +} + +function f15() { + var a = "hello"; + var b = 1; + var c = true; + return { a, b, c }; +} + +function f16() { + var { a, b, c } = f15(); +} + +function f17({ a = "", b = 0, c = false }) { +} + +f17({}); +f17({ a: "hello" }); +f17({ c: true }); +f17(f15()); + +function g4() { + var a: number; + var b: string; + var aa: number[]; + ({ a, b } = { a, b }); + ({ a, b } = { b, a }); + [aa[0], b] = [a, b]; + [a, b] = [b, a]; // Error + [a = 1, b = "abc"] = [2, "def"]; +} + +function g5() { + var a, b; + [a, b] = [1, 2]; + [a, b] = [b, a]; + ({ a, b } = { b, a }); + [[a, b] = [1, 2]] = [[2, 3]]; + var x = ([a, b] = [1, 2]); +} From b49e2772ea1e6cb09382ecbfc5dd81e89f470683 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 4 Dec 2014 17:43:15 -0800 Subject: [PATCH 30/33] Addressing CR feedback --- src/compiler/checker.ts | 65 ++++++++++++++++++++++++++++------- src/compiler/emitter.ts | 19 ++++++---- src/compiler/parser.ts | 2 +- src/services/navigationBar.ts | 7 +++- 4 files changed, 72 insertions(+), 21 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e65567cf8a518..43340d39e8692 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1660,17 +1660,23 @@ module ts { return classType.typeParameters ? createTypeReference(classType, map(classType.typeParameters, _ => anyType)) : classType; } + // Return the type of the given property in the given type, or undefined if no such property exists function getTypeOfPropertyOfType(type: Type, name: string): Type { var prop = getPropertyOfType(type, name); return prop ? getTypeOfSymbol(prop) : undefined; } + // Return the inferred type for a binding element function getTypeForBindingElement(declaration: BindingElement): Type { var pattern = declaration.parent; var parentType = getTypeForVariableDeclaration(pattern.parent); + // If parent has the unknown (error) type, then so does this binding element if (parentType === unknownType) { return unknownType; } + // If no type was specified or inferred for parent, or if the specified or inferred type is any, + // infer from the initializer of the binding element if one is present. Otherwise, go with the + // undefined or any type of the parent. if (!parentType || parentType === anyType) { if (declaration.initializer) { return checkExpressionCached(declaration.initializer); @@ -1678,7 +1684,10 @@ module ts { return parentType; } if (pattern.kind === SyntaxKind.ObjectBindingPattern) { + // Use explicitly specified property name ({ p: xxx } form), or otherwise the implied name ({ p } form) var name = declaration.propertyName || declaration.name; + // Use type of the specified property, or otherwise, for a numeric name, the type of the numeric index signature, + // or otherwise the type of the string index signature. var type = getTypeOfPropertyOfType(parentType, name.text) || isNumericName(name.text) && getIndexTypeOfType(parentType, IndexKind.Number) || getIndexTypeOfType(parentType, IndexKind.String); @@ -1688,12 +1697,14 @@ module ts { } return type; } + // For an array binding element the specified or inferred type of the parent must be assignable to any[] if (!isTypeAssignableTo(parentType, anyArrayType)) { error(pattern, Diagnostics.Type_0_is_not_an_array_type, typeToString(parentType)); return unknownType; } + // Use specific property type when parent is a tuple or numeric index type when parent is an array var propName = "" + indexOf(pattern.elements, declaration); - var type = isTupleType(parentType) ? getTypeOfPropertyOfType(parentType, propName) : getIndexTypeOfType(parentType, IndexKind.Number); + var type = isTupleLikeType(parentType) ? getTypeOfPropertyOfType(parentType, propName) : getIndexTypeOfType(parentType, IndexKind.Number); if (!type) { error(declaration, Diagnostics.Type_0_has_no_property_1, typeToString(parentType), propName); return unknownType; @@ -1701,6 +1712,7 @@ module ts { return type; } + // Return the inferred type for a variable, parameter, or property declaration function getTypeForVariableDeclaration(declaration: VariableDeclaration): Type { // A variable declared in a for..in statement is always of type any if (declaration.parent.kind === SyntaxKind.ForInStatement) { @@ -1732,15 +1744,17 @@ module ts { if (declaration.initializer) { return checkExpressionCached(declaration.initializer); } - // If it is a short-hand property assignment; Use the type of the identifier + // If it is a short-hand property assignment, use the type of the identifier if (declaration.kind === SyntaxKind.ShorthandPropertyAssignment) { - var type = checkIdentifier(declaration.name); - return type + return checkIdentifier(declaration.name); } // No type specified and nothing can be inferred return undefined; } + // Return the type implied by a binding pattern element. This is the type of the initializer of the element if + // one is present. Otherwise, if the element is itself a binding pattern, it is the type implied by the binding + // pattern. Otherwise, it is the type any. function getTypeFromBindingElement(element: BindingElement): Type { if (element.initializer) { return getWidenedType(checkExpressionCached(element.initializer)); @@ -1751,6 +1765,13 @@ module ts { return anyType; } + // Return the type implied by a binding pattern. This is the type implied purely by the binding pattern itself + // and without regard to its context (i.e. without regard any type annotation or initializer associated with the + // declaration in which the binding pattern is contained). For example, the implied type of [x, y] is [any, any] + // and the implied type of { x, y: z = 1 } is { x: any; y: number; }. The type implied by a binding pattern is + // used as the contextual type of an initializer associated with the binding pattern. Also, for a destructuring + // parameter with no type annotation or initializer, the type implied by the binding pattern becomes the type of + // the parameter. function getTypeFromBindingPattern(pattern: BindingPattern): Type { if (pattern.kind === SyntaxKind.ArrayBindingPattern) { return createTupleType(map(pattern.elements, e => e.kind === SyntaxKind.OmittedExpression ? anyType : getTypeFromBindingElement(e))); @@ -1766,14 +1787,28 @@ module ts { return createAnonymousType(undefined, members, emptyArray, emptyArray, undefined, undefined); } + // Return the type associated with a variable, parameter, or property declaration. In the simple case this is the type + // specified in a type annotation or inferred from an initializer. However, in the case of a destructuring declaration it + // is a bit more involved. For example: + // + // var [x, s = ""] = [1, "one"]; + // + // Here, the array literal [1, "one"] is contextually typed by the type [any, string], which is the implied type of the + // binding pattern [x, s = ""]. Because the contextual type is a tuple type, the resulting type of [1, "one"] is the + // tuple type [number, string]. Thus, the type inferred for 'x' is number and the type inferred for 's' is string. function getWidenedTypeForVariableDeclaration(declaration: VariableDeclaration, reportErrors?: boolean): Type { var type = getTypeForVariableDeclaration(declaration); if (type) { if (reportErrors) { reportErrorsFromWidening(declaration, type); } + // During a normal type check we'll never get to here with a property assignment (the check of the containing + // object literal uses a different path). We exclude widening only so that language services and type verification + // tools see the actual type. return declaration.kind !== SyntaxKind.PropertyAssignment ? getWidenedType(type) : type; } + // If no type was specified and nothing could be inferred, and if the declaration specifies a binding pattern, use + // the type implied by the binding pattern if (isBindingPattern(declaration.name)) { return getTypeFromBindingPattern(declaration.name); } @@ -4052,7 +4087,7 @@ module ts { return type.flags & TypeFlags.Reference && (type).target === globalArrayType; } - function isTupleType(type: Type): boolean { + function isTupleLikeType(type: Type): boolean { return !!getPropertyOfType(type, "0"); } @@ -4890,9 +4925,10 @@ module ts { } // In a variable, parameter or property declaration with a type annotation, the contextual type of an initializer - // expression is the type of the variable, parameter or property. In a parameter declaration of a contextually - // typed function expression, the contextual type of an initializer expression is the contextual type of the - // parameter. + // expression is the type of the variable, parameter or property. Otherwise, in a parameter declaration of a + // contextually typed function expression, the contextual type of an initializer expression is the contextual type + // of the parameter. Otherwise, in a variable or parameter declaration with a binding pattern name, the contextual + // type of an initializer expression is the type implied by the binding pattern. function getContextualTypeForInitializerExpression(node: Expression): Type { var declaration = node.parent; if (node === declaration.initializer) { @@ -5001,8 +5037,8 @@ module ts { } // Return true if the given contextual type is a tuple-like type - function contextualTypeIsTupleType(type: Type): boolean { - return !!(type.flags & TypeFlags.Union ? forEach((type).types, t => isTupleType(t)) : isTupleType(type)); + function contextualTypeIsTupleLikeType(type: Type): boolean { + return !!(type.flags & TypeFlags.Union ? forEach((type).types, t => isTupleLikeType(t)) : isTupleLikeType(type)); } // Return true if the given contextual type provides an index signature of the given kind @@ -5160,6 +5196,9 @@ module ts { return mapper && mapper !== identityMapper; } + // A node is an assignment target if it is on the left hand side of an '=' token, if it is parented by a property + // assignment in an object literal that is an assignment target, or if it is parented by an array literal that is + // an assignment target. Examples include 'a = xxx', '{ p: a } = xxx', '[{ p: a}] = xxx'. function isAssignmentTarget(node: Node): boolean { var parent = node.parent; if (parent.kind === SyntaxKind.BinaryExpression && (parent).operator === SyntaxKind.EqualsToken && (parent).left === node) { @@ -5181,7 +5220,7 @@ module ts { } var elementTypes = map(elements, e => checkExpression(e, contextualMapper)); var contextualType = getContextualType(node); - if ((contextualType && contextualTypeIsTupleType(contextualType)) || isAssignmentTarget(node)) { + if ((contextualType && contextualTypeIsTupleLikeType(contextualType)) || isAssignmentTarget(node)) { return createTupleType(elementTypes); } return createArrayType(getUnionType(elementTypes)); @@ -6492,7 +6531,7 @@ module ts { var p = properties[i]; if (p.kind === SyntaxKind.PropertyAssignment || p.kind === SyntaxKind.ShorthandPropertyAssignment) { // TODO(andersh): Computed property support - var name = ((p).name); + var name = (p).name; var type = sourceType.flags & TypeFlags.Any ? sourceType : getTypeOfPropertyOfType(sourceType, name.text) || isNumericName(name.text) && getIndexTypeOfType(sourceType, IndexKind.Number) || @@ -6523,7 +6562,7 @@ module ts { if (e.kind !== SyntaxKind.OmittedExpression) { var propName = "" + i; var type = sourceType.flags & TypeFlags.Any ? sourceType : - isTupleType(sourceType) ? getTypeOfPropertyOfType(sourceType, propName) : + isTupleLikeType(sourceType) ? getTypeOfPropertyOfType(sourceType, propName) : getIndexTypeOfType(sourceType, IndexKind.Number); if (type) { checkDestructuringAssignment(e, type, contextualMapper); diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index f58e3c3a050cf..2856e806de178 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1881,13 +1881,18 @@ module ts { writeFile(compilerHost, diagnostics, jsFilePath, emitOutput, writeByteOrderMark); } - function createTempVariable(location: Node): Identifier { - do { - // First _a..._z, then _0, _1, ... - var name = "_" + (tempCount < 26 ? String.fromCharCode(tempCount + 0x61) : tempCount - 26); + // Create a temporary variable with a unique unused name. The forLoopVariable parameter signals that the + // name should be one that is appropriate for a for loop variable. + function createTempVariable(location: Node, forLoopVariable?: boolean): Identifier { + var name = forLoopVariable ? "_i" : undefined; + while (true) { + if (name && resolver.isUnknownIdentifier(location, name)) { + break; + } + // _a .. _h, _j ... _z, _0, _1, ... + name = "_" + (tempCount < 25 ? String.fromCharCode(tempCount + (tempCount < 8 ? 0: 1) + CharacterCodes.a) : tempCount - 25); tempCount++; } - while (!resolver.isUnknownIdentifier(location, name)); var result = createNode(SyntaxKind.Identifier); result.text = name; return result; @@ -2758,6 +2763,8 @@ module ts { function emitDestructuring(root: BinaryExpression | BindingElement, value?: Expression) { var emitCount = 0; + // An exported declaration is actually emitted as an assignment (to a property on the module object), so + // temporary variables in an exported declaration need to have real declarations elsewhere. var isDeclaration = (root.kind === SyntaxKind.VariableDeclaration && !(root.flags & NodeFlags.Export)) || root.kind === SyntaxKind.Parameter; if (root.kind === SyntaxKind.BinaryExpression) { emitAssignmentExpression(root); @@ -3038,7 +3045,7 @@ module ts { if (hasRestParameters(node)) { var restIndex = node.parameters.length - 1; var restParam = node.parameters[restIndex]; - var tempName = createTempVariable(node).text; + var tempName = createTempVariable(node, /*forLoopVariable*/ true).text; writeLine(); emitLeadingComments(restParam); emitStart(restParam); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 94772b8b5dc42..bfb9636f1c8ab 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -812,7 +812,7 @@ module ts { return undefined; } - enum ParsingContext { + const enum ParsingContext { SourceElements, // Elements in source file ModuleElements, // Elements in module declaration BlockStatements, // Statements in block diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 40cd8980608dc..6a4d7cc3eaa24 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -46,11 +46,16 @@ module ts.NavigationBar { case SyntaxKind.VariableStatement: forEach((node).declarations, visit); break; + case SyntaxKind.ObjectBindingPattern: + case SyntaxKind.ArrayBindingPattern: + forEach((node).elements, visit); + break; case SyntaxKind.VariableDeclaration: if (isBindingPattern(node)) { - forEach(((node).name).elements, visit); + visit((node).name); break; } + // Fall through case SyntaxKind.ClassDeclaration: case SyntaxKind.EnumDeclaration: case SyntaxKind.InterfaceDeclaration: From 4118ffc7032a2245e56ba2d6800d2801b1cc3212 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 4 Dec 2014 17:43:51 -0800 Subject: [PATCH 31/33] Accepting new baselines --- .../arrayLiteralInNonVarArgParameter.js | 4 +-- ...patWithCallSignaturesWithRestParameters.js | 28 ++++++++-------- .../reference/baseTypeAfterDerivedType.js | 4 +-- .../collisionArgumentsArrowFunctions.js | 12 +++---- .../collisionArgumentsClassConstructor.js | 24 +++++++------- .../collisionArgumentsClassMethod.js | 20 ++++++------ .../reference/collisionArgumentsFunction.js | 20 ++++++------ .../collisionArgumentsFunctionExpressions.js | 20 ++++++------ .../contextuallyTypingRestParameters.js | 4 +-- .../reference/declFileConstructors.js | 8 ++--- .../baselines/reference/declFileFunctions.js | 12 +++---- tests/baselines/reference/declFileMethods.js | 32 +++++++++---------- ...RestParametersOfFunctionAndFunctionType.js | 4 +-- ...detachedCommentAtStartOfLambdaFunction1.js | 4 +-- ...detachedCommentAtStartOfLambdaFunction2.js | 4 +-- tests/baselines/reference/funcdecl.js | 4 +-- tests/baselines/reference/functionCall10.js | 4 +-- tests/baselines/reference/functionCall13.js | 4 +-- tests/baselines/reference/functionCall14.js | 4 +-- tests/baselines/reference/functionCall15.js | 4 +-- tests/baselines/reference/functionCall16.js | 4 +-- tests/baselines/reference/functionCall17.js | 4 +-- ...tionOverloadsRecursiveGenericReturnType.js | 4 +-- tests/baselines/reference/genericRestArgs.js | 4 +-- ...icitAnyDeclareFunctionWithoutFormalType.js | 4 +-- ...eArgumentsInSignatureWithRestParameters.js | 12 +++---- .../inheritedConstructorWithRestParams.js | 4 +-- .../noImplicitAnyParametersInBareFunctions.js | 16 +++++----- .../noImplicitAnyParametersInClass.js | 32 +++++++++---------- .../noImplicitAnyParametersInModule.js | 16 +++++----- tests/baselines/reference/nonArrayRestArgs.js | 4 +-- .../overloadGenericFunctionWithRestArgs.js | 4 +-- .../overloadResolutionOverNonCTLambdas.js | 8 ++--- .../reference/restArgAssignmentCompat.js | 4 +-- .../restParameterAssignmentCompatibility.js | 4 +-- .../restParameterNoTypeAnnotation.js | 4 +-- tests/baselines/reference/restParameters.js | 16 +++++----- .../reference/restParamsWithNonRestParams.js | 12 +++---- tests/baselines/reference/sourceMapSample.js | 4 +-- .../reference/sourceMapSample.sourcemap.txt | 4 +-- .../reference/sourceMapValidationClass.js | 4 +-- .../sourceMapValidationClass.sourcemap.txt | 4 +-- .../reference/sourceMapValidationClasses.js | 4 +-- .../sourceMapValidationClasses.sourcemap.txt | 4 +-- .../reference/sourceMapValidationFunctions.js | 8 ++--- ...sourceMapValidationFunctions.sourcemap.txt | 8 ++--- tests/baselines/reference/strictMode5.js | 4 +-- .../stringLiteralTypeIsSubtypeOfString.js | 4 +-- .../reference/subtypingWithCallSignatures2.js | 8 ++--- .../reference/subtypingWithCallSignatures3.js | 8 ++--- ...plateStringsWithOverloadResolution1_ES6.js | 4 +-- ...plateStringsWithOverloadResolution2_ES6.js | 8 ++--- .../reference/undeclaredModuleError.js | 4 +-- tests/baselines/reference/underscoreTest1.js | 4 +-- .../reference/varArgParamTypeCheck.js | 4 +-- tests/baselines/reference/vararg.js | 12 +++---- 56 files changed, 238 insertions(+), 238 deletions(-) diff --git a/tests/baselines/reference/arrayLiteralInNonVarArgParameter.js b/tests/baselines/reference/arrayLiteralInNonVarArgParameter.js index f44b76f24ebd9..57cba07d6bf16 100644 --- a/tests/baselines/reference/arrayLiteralInNonVarArgParameter.js +++ b/tests/baselines/reference/arrayLiteralInNonVarArgParameter.js @@ -7,8 +7,8 @@ panic([], 'one', 'two'); //// [arrayLiteralInNonVarArgParameter.js] function panic(val) { var opt = []; - for (var _a = 1; _a < arguments.length; _a++) { - opt[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + opt[_i - 1] = arguments[_i]; } } panic([], 'one', 'two'); diff --git a/tests/baselines/reference/assignmentCompatWithCallSignaturesWithRestParameters.js b/tests/baselines/reference/assignmentCompatWithCallSignaturesWithRestParameters.js index c541114f91c20..f4cf5cc79e29b 100644 --- a/tests/baselines/reference/assignmentCompatWithCallSignaturesWithRestParameters.js +++ b/tests/baselines/reference/assignmentCompatWithCallSignaturesWithRestParameters.js @@ -51,15 +51,15 @@ var a; // ok, same number of required params a = function () { return 1; }; // ok, same number of required params a = function () { var args = []; - for (var _a = 0; _a < arguments.length; _a++) { - args[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i - 0] = arguments[_i]; } return 1; }; // ok, same number of required params a = function () { var args = []; - for (var _a = 0; _a < arguments.length; _a++) { - args[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i - 0] = arguments[_i]; } return 1; }; // error, type mismatch @@ -71,8 +71,8 @@ var a2; a2 = function () { return 1; }; // ok, fewer required params a2 = function () { var args = []; - for (var _a = 0; _a < arguments.length; _a++) { - args[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i - 0] = arguments[_i]; } return 1; }; // ok, fewer required params @@ -80,15 +80,15 @@ a2 = function (x) { return 1; }; // ok, fewer required params a2 = function (x) { return 1; }; // ok, same number of required params a2 = function (x) { var args = []; - for (var _a = 1; _a < arguments.length; _a++) { - args[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; } return 1; }; // ok, same number of required params a2 = function (x) { var args = []; - for (var _a = 1; _a < arguments.length; _a++) { - args[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; } return 1; }; // should be type mismatch error @@ -102,8 +102,8 @@ a3 = function (x, y) { return 1; }; // ok, all present params match a3 = function (x, y, z) { return 1; }; // error a3 = function (x) { var z = []; - for (var _a = 1; _a < arguments.length; _a++) { - z[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + z[_i - 1] = arguments[_i]; } return 1; }; // error @@ -116,8 +116,8 @@ a4 = function (x, y) { return 1; }; // error, second param has type mismatch a4 = function (x, y) { return 1; }; // ok, same number of required params with matching types a4 = function (x) { var args = []; - for (var _a = 1; _a < arguments.length; _a++) { - args[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; } return 1; }; // error, rest params have type mismatch diff --git a/tests/baselines/reference/baseTypeAfterDerivedType.js b/tests/baselines/reference/baseTypeAfterDerivedType.js index 893e0e737b9cd..c64239ac0c86f 100644 --- a/tests/baselines/reference/baseTypeAfterDerivedType.js +++ b/tests/baselines/reference/baseTypeAfterDerivedType.js @@ -22,8 +22,8 @@ var Derived2 = (function () { } Derived2.prototype.method = function () { var args = []; - for (var _a = 0; _a < arguments.length; _a++) { - args[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i - 0] = arguments[_i]; } }; return Derived2; diff --git a/tests/baselines/reference/collisionArgumentsArrowFunctions.js b/tests/baselines/reference/collisionArgumentsArrowFunctions.js index c2f70d0ac9c8f..0aa939e1a2d7f 100644 --- a/tests/baselines/reference/collisionArgumentsArrowFunctions.js +++ b/tests/baselines/reference/collisionArgumentsArrowFunctions.js @@ -19,15 +19,15 @@ var f2NoError = () => { //// [collisionArgumentsArrowFunctions.js] var f1 = function (i) { var arguments = []; - for (var _a = 1; _a < arguments.length; _a++) { - arguments[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + arguments[_i - 1] = arguments[_i]; } var arguments; // no error }; var f12 = function (arguments) { var rest = []; - for (var _a = 1; _a < arguments.length; _a++) { - rest[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + rest[_i - 1] = arguments[_i]; } var arguments = 10; // no error }; @@ -36,8 +36,8 @@ var f1NoError = function (arguments) { }; var f2 = function () { var restParameters = []; - for (var _a = 0; _a < arguments.length; _a++) { - restParameters[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + restParameters[_i - 0] = arguments[_i]; } var arguments = 10; // No Error }; diff --git a/tests/baselines/reference/collisionArgumentsClassConstructor.js b/tests/baselines/reference/collisionArgumentsClassConstructor.js index 0581b37a1ebc9..ca743777b39d8 100644 --- a/tests/baselines/reference/collisionArgumentsClassConstructor.js +++ b/tests/baselines/reference/collisionArgumentsClassConstructor.js @@ -91,8 +91,8 @@ declare class c6NoError { var c1 = (function () { function c1(i) { var arguments = []; - for (var _a = 1; _a < arguments.length; _a++) { - arguments[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + arguments[_i - 1] = arguments[_i]; } var arguments; // no error } @@ -101,8 +101,8 @@ var c1 = (function () { var c12 = (function () { function c12(arguments) { var rest = []; - for (var _a = 1; _a < arguments.length; _a++) { - rest[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + rest[_i - 1] = arguments[_i]; } var arguments = 10; // no error } @@ -117,8 +117,8 @@ var c1NoError = (function () { var c2 = (function () { function c2() { var restParameters = []; - for (var _a = 0; _a < arguments.length; _a++) { - restParameters[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + restParameters[_i - 0] = arguments[_i]; } var arguments = 10; // no error } @@ -133,8 +133,8 @@ var c2NoError = (function () { var c3 = (function () { function c3(arguments) { var restParameters = []; - for (var _a = 1; _a < arguments.length; _a++) { - restParameters[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + restParameters[_i - 1] = arguments[_i]; } this.arguments = arguments; var arguments = 10; // no error @@ -151,8 +151,8 @@ var c3NoError = (function () { var c5 = (function () { function c5(i) { var arguments = []; - for (var _a = 1; _a < arguments.length; _a++) { - arguments[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + arguments[_i - 1] = arguments[_i]; } var arguments; // no error } @@ -161,8 +161,8 @@ var c5 = (function () { var c52 = (function () { function c52(arguments) { var rest = []; - for (var _a = 1; _a < arguments.length; _a++) { - rest[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + rest[_i - 1] = arguments[_i]; } var arguments; // no error } diff --git a/tests/baselines/reference/collisionArgumentsClassMethod.js b/tests/baselines/reference/collisionArgumentsClassMethod.js index 4ac6748a6ba65..10c9b28854408 100644 --- a/tests/baselines/reference/collisionArgumentsClassMethod.js +++ b/tests/baselines/reference/collisionArgumentsClassMethod.js @@ -54,15 +54,15 @@ var c1 = (function () { } c1.prototype.foo = function (i) { var arguments = []; - for (var _a = 1; _a < arguments.length; _a++) { - arguments[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + arguments[_i - 1] = arguments[_i]; } var arguments; // no error }; c1.prototype.foo1 = function (arguments) { var rest = []; - for (var _a = 1; _a < arguments.length; _a++) { - rest[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + rest[_i - 1] = arguments[_i]; } var arguments = 10; // no error }; @@ -71,15 +71,15 @@ var c1 = (function () { }; c1.prototype.f4 = function (i) { var arguments = []; - for (var _a = 1; _a < arguments.length; _a++) { - arguments[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + arguments[_i - 1] = arguments[_i]; } var arguments; // no error }; c1.prototype.f41 = function (arguments) { var rest = []; - for (var _a = 1; _a < arguments.length; _a++) { - rest[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + rest[_i - 1] = arguments[_i]; } var arguments; // no error }; @@ -93,8 +93,8 @@ var c3 = (function () { } c3.prototype.foo = function () { var restParameters = []; - for (var _a = 0; _a < arguments.length; _a++) { - restParameters[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + restParameters[_i - 0] = arguments[_i]; } var arguments = 10; // no error }; diff --git a/tests/baselines/reference/collisionArgumentsFunction.js b/tests/baselines/reference/collisionArgumentsFunction.js index 505127b7c95e1..9ce4a5ab0e20b 100644 --- a/tests/baselines/reference/collisionArgumentsFunction.js +++ b/tests/baselines/reference/collisionArgumentsFunction.js @@ -48,15 +48,15 @@ declare function f6(arguments: string); // no codegen no error // Functions function f1(arguments) { var restParameters = []; - for (var _a = 1; _a < arguments.length; _a++) { - restParameters[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + restParameters[_i - 1] = arguments[_i]; } var arguments = 10; // no error } function f12(i) { var arguments = []; - for (var _a = 1; _a < arguments.length; _a++) { - arguments[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + arguments[_i - 1] = arguments[_i]; } var arguments; // no error } @@ -65,8 +65,8 @@ function f1NoError(arguments) { } function f3() { var restParameters = []; - for (var _a = 0; _a < arguments.length; _a++) { - restParameters[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + restParameters[_i - 0] = arguments[_i]; } var arguments = 10; // no error } @@ -75,15 +75,15 @@ function f3NoError() { } function f4(arguments) { var rest = []; - for (var _a = 1; _a < arguments.length; _a++) { - rest[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + rest[_i - 1] = arguments[_i]; } var arguments; // No error } function f42(i) { var arguments = []; - for (var _a = 1; _a < arguments.length; _a++) { - arguments[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + arguments[_i - 1] = arguments[_i]; } var arguments; // No error } diff --git a/tests/baselines/reference/collisionArgumentsFunctionExpressions.js b/tests/baselines/reference/collisionArgumentsFunctionExpressions.js index 54039a4bce31f..405ceb625c3c9 100644 --- a/tests/baselines/reference/collisionArgumentsFunctionExpressions.js +++ b/tests/baselines/reference/collisionArgumentsFunctionExpressions.js @@ -38,15 +38,15 @@ function foo() { function foo() { function f1(arguments) { var restParameters = []; - for (var _a = 1; _a < arguments.length; _a++) { - restParameters[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + restParameters[_i - 1] = arguments[_i]; } var arguments = 10; // no error } function f12(i) { var arguments = []; - for (var _a = 1; _a < arguments.length; _a++) { - arguments[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + arguments[_i - 1] = arguments[_i]; } var arguments; // no error } @@ -55,8 +55,8 @@ function foo() { } function f3() { var restParameters = []; - for (var _a = 0; _a < arguments.length; _a++) { - restParameters[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + restParameters[_i - 0] = arguments[_i]; } var arguments = 10; // no error } @@ -65,15 +65,15 @@ function foo() { } function f4(arguments) { var rest = []; - for (var _a = 1; _a < arguments.length; _a++) { - rest[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + rest[_i - 1] = arguments[_i]; } var arguments; // No error } function f42(i) { var arguments = []; - for (var _a = 1; _a < arguments.length; _a++) { - arguments[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + arguments[_i - 1] = arguments[_i]; } var arguments; // No error } diff --git a/tests/baselines/reference/contextuallyTypingRestParameters.js b/tests/baselines/reference/contextuallyTypingRestParameters.js index ac48cc6db0ecc..17561f5d7fccb 100644 --- a/tests/baselines/reference/contextuallyTypingRestParameters.js +++ b/tests/baselines/reference/contextuallyTypingRestParameters.js @@ -10,8 +10,8 @@ var x: (...y: string[]) => void = function (.../*3*/y) { //// [contextuallyTypingRestParameters.js] var x = function () { var y = []; - for (var _a = 0; _a < arguments.length; _a++) { - y[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + y[_i - 0] = arguments[_i]; } var t = y; var x2 = t; // This should be error diff --git a/tests/baselines/reference/declFileConstructors.js b/tests/baselines/reference/declFileConstructors.js index 830e30e65c33e..327221debf805 100644 --- a/tests/baselines/reference/declFileConstructors.js +++ b/tests/baselines/reference/declFileConstructors.js @@ -118,8 +118,8 @@ exports.ConstructorWithParameters = ConstructorWithParameters; var ConstructorWithRestParamters = (function () { function ConstructorWithRestParamters(a) { var rests = []; - for (var _a = 1; _a < arguments.length; _a++) { - rests[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + rests[_i - 1] = arguments[_i]; } return a + rests.join(""); } @@ -180,8 +180,8 @@ var GlobalConstructorWithParameters = (function () { var GlobalConstructorWithRestParamters = (function () { function GlobalConstructorWithRestParamters(a) { var rests = []; - for (var _a = 1; _a < arguments.length; _a++) { - rests[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + rests[_i - 1] = arguments[_i]; } return a + rests.join(""); } diff --git a/tests/baselines/reference/declFileFunctions.js b/tests/baselines/reference/declFileFunctions.js index 329c61b9aba9a..da1917163e186 100644 --- a/tests/baselines/reference/declFileFunctions.js +++ b/tests/baselines/reference/declFileFunctions.js @@ -78,8 +78,8 @@ function fooWithParameters(/** this is comment about a*/ a, exports.fooWithParameters = fooWithParameters; function fooWithRestParameters(a) { var rests = []; - for (var _a = 1; _a < arguments.length; _a++) { - rests[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + rests[_i - 1] = arguments[_i]; } return a + rests.join(""); } @@ -103,8 +103,8 @@ function nonExportedFooWithParameters(/** this is comment about a*/ a, } function nonExportedFooWithRestParameters(a) { var rests = []; - for (var _a = 1; _a < arguments.length; _a++) { - rests[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + rests[_i - 1] = arguments[_i]; } return a + rests.join(""); } @@ -123,8 +123,8 @@ function globalfooWithParameters(/** this is comment about a*/ a, } function globalfooWithRestParameters(a) { var rests = []; - for (var _a = 1; _a < arguments.length; _a++) { - rests[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + rests[_i - 1] = arguments[_i]; } return a + rests.join(""); } diff --git a/tests/baselines/reference/declFileMethods.js b/tests/baselines/reference/declFileMethods.js index 9b0e42414e48e..2b82a4b71b525 100644 --- a/tests/baselines/reference/declFileMethods.js +++ b/tests/baselines/reference/declFileMethods.js @@ -205,8 +205,8 @@ var c1 = (function () { }; c1.prototype.fooWithRestParameters = function (a) { var rests = []; - for (var _a = 1; _a < arguments.length; _a++) { - rests[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + rests[_i - 1] = arguments[_i]; } return a + rests.join(""); }; @@ -224,8 +224,8 @@ var c1 = (function () { }; c1.prototype.privateFooWithRestParameters = function (a) { var rests = []; - for (var _a = 1; _a < arguments.length; _a++) { - rests[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + rests[_i - 1] = arguments[_i]; } return a + rests.join(""); }; @@ -243,8 +243,8 @@ var c1 = (function () { }; c1.staticFooWithRestParameters = function (a) { var rests = []; - for (var _a = 1; _a < arguments.length; _a++) { - rests[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + rests[_i - 1] = arguments[_i]; } return a + rests.join(""); }; @@ -262,8 +262,8 @@ var c1 = (function () { }; c1.privateStaticFooWithRestParameters = function (a) { var rests = []; - for (var _a = 1; _a < arguments.length; _a++) { - rests[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + rests[_i - 1] = arguments[_i]; } return a + rests.join(""); }; @@ -288,8 +288,8 @@ var c2 = (function () { }; c2.prototype.fooWithRestParameters = function (a) { var rests = []; - for (var _a = 1; _a < arguments.length; _a++) { - rests[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + rests[_i - 1] = arguments[_i]; } return a + rests.join(""); }; @@ -307,8 +307,8 @@ var c2 = (function () { }; c2.prototype.privateFooWithRestParameters = function (a) { var rests = []; - for (var _a = 1; _a < arguments.length; _a++) { - rests[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + rests[_i - 1] = arguments[_i]; } return a + rests.join(""); }; @@ -326,8 +326,8 @@ var c2 = (function () { }; c2.staticFooWithRestParameters = function (a) { var rests = []; - for (var _a = 1; _a < arguments.length; _a++) { - rests[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + rests[_i - 1] = arguments[_i]; } return a + rests.join(""); }; @@ -345,8 +345,8 @@ var c2 = (function () { }; c2.privateStaticFooWithRestParameters = function (a) { var rests = []; - for (var _a = 1; _a < arguments.length; _a++) { - rests[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + rests[_i - 1] = arguments[_i]; } return a + rests.join(""); }; diff --git a/tests/baselines/reference/declFileRestParametersOfFunctionAndFunctionType.js b/tests/baselines/reference/declFileRestParametersOfFunctionAndFunctionType.js index c6d26308abfb8..2d071c80de99f 100644 --- a/tests/baselines/reference/declFileRestParametersOfFunctionAndFunctionType.js +++ b/tests/baselines/reference/declFileRestParametersOfFunctionAndFunctionType.js @@ -13,8 +13,8 @@ var f6 = () => { return [10]; } //// [declFileRestParametersOfFunctionAndFunctionType.js] function f1() { var args = []; - for (var _a = 0; _a < arguments.length; _a++) { - args[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i - 0] = arguments[_i]; } } function f2(x) { diff --git a/tests/baselines/reference/detachedCommentAtStartOfLambdaFunction1.js b/tests/baselines/reference/detachedCommentAtStartOfLambdaFunction1.js index 72d2545e617ad..2505e3f60826e 100644 --- a/tests/baselines/reference/detachedCommentAtStartOfLambdaFunction1.js +++ b/tests/baselines/reference/detachedCommentAtStartOfLambdaFunction1.js @@ -18,8 +18,8 @@ var TestFile = (function () { var _this = this; return function () { var x = []; - for (var _a = 0; _a < arguments.length; _a++) { - x[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + x[_i - 0] = arguments[_i]; } /// Test summary /// diff --git a/tests/baselines/reference/detachedCommentAtStartOfLambdaFunction2.js b/tests/baselines/reference/detachedCommentAtStartOfLambdaFunction2.js index 3309a395ef54a..53f6d08eaf557 100644 --- a/tests/baselines/reference/detachedCommentAtStartOfLambdaFunction2.js +++ b/tests/baselines/reference/detachedCommentAtStartOfLambdaFunction2.js @@ -22,8 +22,8 @@ var TestFile = (function () { /// /// var x = []; - for (var _a = 0; _a < arguments.length; _a++) { - x[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + x[_i - 0] = arguments[_i]; } return message + _this.name; }; diff --git a/tests/baselines/reference/funcdecl.js b/tests/baselines/reference/funcdecl.js index 32d024f4eedc3..de080873b9feb 100644 --- a/tests/baselines/reference/funcdecl.js +++ b/tests/baselines/reference/funcdecl.js @@ -105,8 +105,8 @@ function withOptionalInitializedParams(a, c) { var withOptionalInitializedParamsVar = withOptionalInitializedParams; function withRestParams(a) { var myRestParameter = []; - for (var _a = 1; _a < arguments.length; _a++) { - myRestParameter[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + myRestParameter[_i - 1] = arguments[_i]; } return myRestParameter; } diff --git a/tests/baselines/reference/functionCall10.js b/tests/baselines/reference/functionCall10.js index a9b5ca4788f97..9d5cb33a56a3b 100644 --- a/tests/baselines/reference/functionCall10.js +++ b/tests/baselines/reference/functionCall10.js @@ -9,8 +9,8 @@ foo(1, 'bar'); //// [functionCall10.js] function foo() { var a = []; - for (var _a = 0; _a < arguments.length; _a++) { - a[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + a[_i - 0] = arguments[_i]; } } ; diff --git a/tests/baselines/reference/functionCall13.js b/tests/baselines/reference/functionCall13.js index 6edf95fb4bc0d..ce57f43215e4d 100644 --- a/tests/baselines/reference/functionCall13.js +++ b/tests/baselines/reference/functionCall13.js @@ -10,8 +10,8 @@ foo('foo', 1, 3); //// [functionCall13.js] function foo(a) { var b = []; - for (var _a = 1; _a < arguments.length; _a++) { - b[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + b[_i - 1] = arguments[_i]; } } foo('foo', 1); diff --git a/tests/baselines/reference/functionCall14.js b/tests/baselines/reference/functionCall14.js index 343b3e58b736e..47447f46db5ca 100644 --- a/tests/baselines/reference/functionCall14.js +++ b/tests/baselines/reference/functionCall14.js @@ -10,8 +10,8 @@ foo('foo', 1, 3); //// [functionCall14.js] function foo(a) { var b = []; - for (var _a = 1; _a < arguments.length; _a++) { - b[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + b[_i - 1] = arguments[_i]; } } foo('foo', 1); diff --git a/tests/baselines/reference/functionCall15.js b/tests/baselines/reference/functionCall15.js index 07864c5f4c63b..28fa4c917c867 100644 --- a/tests/baselines/reference/functionCall15.js +++ b/tests/baselines/reference/functionCall15.js @@ -4,7 +4,7 @@ function foo(a?:string, b?:number, ...b:number[]){} //// [functionCall15.js] function foo(a, b) { var b = []; - for (var _a = 2; _a < arguments.length; _a++) { - b[_a - 2] = arguments[_a]; + for (var _i = 2; _i < arguments.length; _i++) { + b[_i - 2] = arguments[_i]; } } diff --git a/tests/baselines/reference/functionCall16.js b/tests/baselines/reference/functionCall16.js index fdf7ed1542951..187572a9a7e84 100644 --- a/tests/baselines/reference/functionCall16.js +++ b/tests/baselines/reference/functionCall16.js @@ -11,8 +11,8 @@ foo('foo', 'bar', 3); //// [functionCall16.js] function foo(a, b) { var c = []; - for (var _a = 2; _a < arguments.length; _a++) { - c[_a - 2] = arguments[_a]; + for (var _i = 2; _i < arguments.length; _i++) { + c[_i - 2] = arguments[_i]; } } foo('foo', 1); diff --git a/tests/baselines/reference/functionCall17.js b/tests/baselines/reference/functionCall17.js index a6794012d68c7..73f7fd6070b22 100644 --- a/tests/baselines/reference/functionCall17.js +++ b/tests/baselines/reference/functionCall17.js @@ -11,8 +11,8 @@ foo('foo', 'bar', 3, 4); //// [functionCall17.js] function foo(a, b, c) { var d = []; - for (var _a = 3; _a < arguments.length; _a++) { - d[_a - 3] = arguments[_a]; + for (var _i = 3; _i < arguments.length; _i++) { + d[_i - 3] = arguments[_i]; } } foo('foo', 1); diff --git a/tests/baselines/reference/functionOverloadsRecursiveGenericReturnType.js b/tests/baselines/reference/functionOverloadsRecursiveGenericReturnType.js index 73bb56b3f7e82..ab0baf2059296 100644 --- a/tests/baselines/reference/functionOverloadsRecursiveGenericReturnType.js +++ b/tests/baselines/reference/functionOverloadsRecursiveGenericReturnType.js @@ -27,8 +27,8 @@ var A = (function () { })(); function Choice() { var v_args = []; - for (var _a = 0; _a < arguments.length; _a++) { - v_args[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + v_args[_i - 0] = arguments[_i]; } return new A(); } diff --git a/tests/baselines/reference/genericRestArgs.js b/tests/baselines/reference/genericRestArgs.js index 1896e886c9732..75c88d7cbf2cc 100644 --- a/tests/baselines/reference/genericRestArgs.js +++ b/tests/baselines/reference/genericRestArgs.js @@ -15,8 +15,8 @@ var a2Gc = makeArrayG(1, ""); // error //// [genericRestArgs.js] function makeArrayG() { var items = []; - for (var _a = 0; _a < arguments.length; _a++) { - items[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + items[_i - 0] = arguments[_i]; } return items; } diff --git a/tests/baselines/reference/implicitAnyDeclareFunctionWithoutFormalType.js b/tests/baselines/reference/implicitAnyDeclareFunctionWithoutFormalType.js index 2d452a9f5339c..72d68da22872b 100644 --- a/tests/baselines/reference/implicitAnyDeclareFunctionWithoutFormalType.js +++ b/tests/baselines/reference/implicitAnyDeclareFunctionWithoutFormalType.js @@ -24,8 +24,8 @@ function func2(a, b, c) { ; function func3() { var args = []; - for (var _a = 0; _a < arguments.length; _a++) { - args[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i - 0] = arguments[_i]; } } ; diff --git a/tests/baselines/reference/inferTypeArgumentsInSignatureWithRestParameters.js b/tests/baselines/reference/inferTypeArgumentsInSignatureWithRestParameters.js index 198bd3dcfa787..1cc86829a6b0b 100644 --- a/tests/baselines/reference/inferTypeArgumentsInSignatureWithRestParameters.js +++ b/tests/baselines/reference/inferTypeArgumentsInSignatureWithRestParameters.js @@ -14,20 +14,20 @@ i(a); // OK //// [inferTypeArgumentsInSignatureWithRestParameters.js] function f(array) { var args = []; - for (var _a = 1; _a < arguments.length; _a++) { - args[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; } } function g(array) { var args = []; - for (var _a = 1; _a < arguments.length; _a++) { - args[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; } } function h(nonarray) { var args = []; - for (var _a = 1; _a < arguments.length; _a++) { - args[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; } } function i(array, opt) { diff --git a/tests/baselines/reference/inheritedConstructorWithRestParams.js b/tests/baselines/reference/inheritedConstructorWithRestParams.js index 67b9cc0832288..b924fe25db9c8 100644 --- a/tests/baselines/reference/inheritedConstructorWithRestParams.js +++ b/tests/baselines/reference/inheritedConstructorWithRestParams.js @@ -24,8 +24,8 @@ var __extends = this.__extends || function (d, b) { var Base = (function () { function Base() { var a = []; - for (var _a = 0; _a < arguments.length; _a++) { - a[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + a[_i - 0] = arguments[_i]; } } return Base; diff --git a/tests/baselines/reference/noImplicitAnyParametersInBareFunctions.js b/tests/baselines/reference/noImplicitAnyParametersInBareFunctions.js index f23819244c366..06848d7e89af4 100644 --- a/tests/baselines/reference/noImplicitAnyParametersInBareFunctions.js +++ b/tests/baselines/reference/noImplicitAnyParametersInBareFunctions.js @@ -63,15 +63,15 @@ function f5(x, y, z) { // Implicit-'any[]' error for r. function f6() { var r = []; - for (var _a = 0; _a < arguments.length; _a++) { - r[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + r[_i - 0] = arguments[_i]; } } // Implicit-'any'/'any[]' errors for x, r. function f7(x) { var r = []; - for (var _a = 1; _a < arguments.length; _a++) { - r[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + r[_i - 1] = arguments[_i]; } } function f8(x3, y3) { @@ -87,16 +87,16 @@ var f12 = function (x, y, z) { return ""; }; // Implicit-'any[]' error for r. var f13 = function () { var r = []; - for (var _a = 0; _a < arguments.length; _a++) { - r[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + r[_i - 0] = arguments[_i]; } return ""; }; // Implicit-'any'/'any[]' errors for x, r. var f14 = function (x) { var r = []; - for (var _a = 1; _a < arguments.length; _a++) { - r[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + r[_i - 1] = arguments[_i]; } return ""; }; diff --git a/tests/baselines/reference/noImplicitAnyParametersInClass.js b/tests/baselines/reference/noImplicitAnyParametersInClass.js index 3a2ee3e38bd86..82164884b801c 100644 --- a/tests/baselines/reference/noImplicitAnyParametersInClass.js +++ b/tests/baselines/reference/noImplicitAnyParametersInClass.js @@ -106,16 +106,16 @@ var C = (function () { // Implicit-'any[]' error for r. this.pub_f13 = function () { var r = []; - for (var _a = 0; _a < arguments.length; _a++) { - r[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + r[_i - 0] = arguments[_i]; } return ""; }; // Implicit-'any'/'any[]' errors for x, r. this.pub_f14 = function (x) { var r = []; - for (var _a = 1; _a < arguments.length; _a++) { - r[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + r[_i - 1] = arguments[_i]; } return ""; }; @@ -130,16 +130,16 @@ var C = (function () { // Implicit-'any[]' error for r. this.priv_f13 = function () { var r = []; - for (var _a = 0; _a < arguments.length; _a++) { - r[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + r[_i - 0] = arguments[_i]; } return ""; }; // Implicit-'any'/'any[]' errors for x, r. this.priv_f14 = function (x) { var r = []; - for (var _a = 1; _a < arguments.length; _a++) { - r[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + r[_i - 1] = arguments[_i]; } return ""; }; @@ -162,15 +162,15 @@ var C = (function () { // Implicit-'any[]' errors for r. C.prototype.pub_f6 = function () { var r = []; - for (var _a = 0; _a < arguments.length; _a++) { - r[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + r[_i - 0] = arguments[_i]; } }; // Implicit-'any'/'any[]' errors for x, r. C.prototype.pub_f7 = function (x) { var r = []; - for (var _a = 1; _a < arguments.length; _a++) { - r[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + r[_i - 1] = arguments[_i]; } }; C.prototype.pub_f8 = function (x3, y3) { @@ -194,15 +194,15 @@ var C = (function () { // Implicit-'any[]' errors for r. C.prototype.priv_f6 = function () { var r = []; - for (var _a = 0; _a < arguments.length; _a++) { - r[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + r[_i - 0] = arguments[_i]; } }; // Implicit-'any'/'any[]' errors for x, r. C.prototype.priv_f7 = function (x) { var r = []; - for (var _a = 1; _a < arguments.length; _a++) { - r[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + r[_i - 1] = arguments[_i]; } }; C.prototype.priv_f8 = function (x3, y3) { diff --git a/tests/baselines/reference/noImplicitAnyParametersInModule.js b/tests/baselines/reference/noImplicitAnyParametersInModule.js index b9af2af132efe..fccb16cefa79a 100644 --- a/tests/baselines/reference/noImplicitAnyParametersInModule.js +++ b/tests/baselines/reference/noImplicitAnyParametersInModule.js @@ -67,15 +67,15 @@ var M; // Implicit-'any[]' error for r. function m_f6() { var r = []; - for (var _a = 0; _a < arguments.length; _a++) { - r[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + r[_i - 0] = arguments[_i]; } } // Implicit-'any'/'any[]' errors for x and r. function m_f7(x) { var r = []; - for (var _a = 1; _a < arguments.length; _a++) { - r[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + r[_i - 1] = arguments[_i]; } } function m_f8(x3, y3) { @@ -91,16 +91,16 @@ var M; // Implicit-'any[]' errors for r. var m_f13 = function () { var r = []; - for (var _a = 0; _a < arguments.length; _a++) { - r[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + r[_i - 0] = arguments[_i]; } return ""; }; // Implicit-'any'/'any[]' errors for x and r. var m_f14 = function (x) { var r = []; - for (var _a = 1; _a < arguments.length; _a++) { - r[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + r[_i - 1] = arguments[_i]; } return ""; }; diff --git a/tests/baselines/reference/nonArrayRestArgs.js b/tests/baselines/reference/nonArrayRestArgs.js index 27e05034a1a4d..d16b7dea3466e 100644 --- a/tests/baselines/reference/nonArrayRestArgs.js +++ b/tests/baselines/reference/nonArrayRestArgs.js @@ -7,8 +7,8 @@ function foo(...rest: number) { // error //// [nonArrayRestArgs.js] function foo() { var rest = []; - for (var _a = 0; _a < arguments.length; _a++) { - rest[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + rest[_i - 0] = arguments[_i]; } var x = rest[0]; return x; diff --git a/tests/baselines/reference/overloadGenericFunctionWithRestArgs.js b/tests/baselines/reference/overloadGenericFunctionWithRestArgs.js index 62676c0d03c9c..c4b133ea44c48 100644 --- a/tests/baselines/reference/overloadGenericFunctionWithRestArgs.js +++ b/tests/baselines/reference/overloadGenericFunctionWithRestArgs.js @@ -23,8 +23,8 @@ var A = (function () { })(); function Choice() { var v_args = []; - for (var _a = 0; _a < arguments.length; _a++) { - v_args[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + v_args[_i - 0] = arguments[_i]; } return new A(); } diff --git a/tests/baselines/reference/overloadResolutionOverNonCTLambdas.js b/tests/baselines/reference/overloadResolutionOverNonCTLambdas.js index 52a2c92f10f08..86e84ced58f0f 100644 --- a/tests/baselines/reference/overloadResolutionOverNonCTLambdas.js +++ b/tests/baselines/reference/overloadResolutionOverNonCTLambdas.js @@ -34,13 +34,13 @@ var Bugs; // replace(searchValue: RegExp, replaceValue: (substring: string, ...args: any[]) => string): string; function bug2(message) { var args = []; - for (var _a = 1; _a < arguments.length; _a++) { - args[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; } var result = message.replace(/\{(\d+)\}/g, function (match) { var rest = []; - for (var _a = 1; _a < arguments.length; _a++) { - rest[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + rest[_i - 1] = arguments[_i]; } var index = rest[0]; return typeof args[index] !== 'undefined' ? args[index] : match; diff --git a/tests/baselines/reference/restArgAssignmentCompat.js b/tests/baselines/reference/restArgAssignmentCompat.js index 5fb98a0125d76..a52cff7ec5c1d 100644 --- a/tests/baselines/reference/restArgAssignmentCompat.js +++ b/tests/baselines/reference/restArgAssignmentCompat.js @@ -12,8 +12,8 @@ n([4], 'foo'); //// [restArgAssignmentCompat.js] function f() { var x = []; - for (var _a = 0; _a < arguments.length; _a++) { - x[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + x[_i - 0] = arguments[_i]; } x.forEach(function (n, i) { return void ('item ' + i + ' = ' + n); }); } diff --git a/tests/baselines/reference/restParameterAssignmentCompatibility.js b/tests/baselines/reference/restParameterAssignmentCompatibility.js index ca81a284eddba..62c0204c74991 100644 --- a/tests/baselines/reference/restParameterAssignmentCompatibility.js +++ b/tests/baselines/reference/restParameterAssignmentCompatibility.js @@ -32,8 +32,8 @@ var T = (function () { } T.prototype.m = function () { var p3 = []; - for (var _a = 0; _a < arguments.length; _a++) { - p3[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + p3[_i - 0] = arguments[_i]; } }; return T; diff --git a/tests/baselines/reference/restParameterNoTypeAnnotation.js b/tests/baselines/reference/restParameterNoTypeAnnotation.js index 195b6e28a08fd..95e092fdd4373 100644 --- a/tests/baselines/reference/restParameterNoTypeAnnotation.js +++ b/tests/baselines/reference/restParameterNoTypeAnnotation.js @@ -8,8 +8,8 @@ function foo(...rest) { //// [restParameterNoTypeAnnotation.js] function foo() { var rest = []; - for (var _a = 0; _a < arguments.length; _a++) { - rest[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + rest[_i - 0] = arguments[_i]; } var x = rest[0]; return x; diff --git a/tests/baselines/reference/restParameters.js b/tests/baselines/reference/restParameters.js index 5b5717b34fd33..2e5b7bb4c928a 100644 --- a/tests/baselines/reference/restParameters.js +++ b/tests/baselines/reference/restParameters.js @@ -10,25 +10,25 @@ function f21(a:string, b?:string, c?:number, ...d:number[]){} //// [restParameters.js] function f18(a) { var b = []; - for (var _a = 1; _a < arguments.length; _a++) { - b[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + b[_i - 1] = arguments[_i]; } } function f19(a, b) { var c = []; - for (var _a = 2; _a < arguments.length; _a++) { - c[_a - 2] = arguments[_a]; + for (var _i = 2; _i < arguments.length; _i++) { + c[_i - 2] = arguments[_i]; } } function f20(a, b) { var c = []; - for (var _a = 2; _a < arguments.length; _a++) { - c[_a - 2] = arguments[_a]; + for (var _i = 2; _i < arguments.length; _i++) { + c[_i - 2] = arguments[_i]; } } function f21(a, b, c) { var d = []; - for (var _a = 3; _a < arguments.length; _a++) { - d[_a - 3] = arguments[_a]; + for (var _i = 3; _i < arguments.length; _i++) { + d[_i - 3] = arguments[_i]; } } diff --git a/tests/baselines/reference/restParamsWithNonRestParams.js b/tests/baselines/reference/restParamsWithNonRestParams.js index 745c91d4a0cb7..6b0caa723940a 100644 --- a/tests/baselines/reference/restParamsWithNonRestParams.js +++ b/tests/baselines/reference/restParamsWithNonRestParams.js @@ -9,22 +9,22 @@ foo3(); // error but shouldn't be //// [restParamsWithNonRestParams.js] function foo() { var b = []; - for (var _a = 0; _a < arguments.length; _a++) { - b[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + b[_i - 0] = arguments[_i]; } } foo(); // ok function foo2(a) { var b = []; - for (var _a = 1; _a < arguments.length; _a++) { - b[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + b[_i - 1] = arguments[_i]; } } foo2(); // should be an error function foo3(a) { var b = []; - for (var _a = 1; _a < arguments.length; _a++) { - b[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + b[_i - 1] = arguments[_i]; } } foo3(); // error but shouldn't be diff --git a/tests/baselines/reference/sourceMapSample.js b/tests/baselines/reference/sourceMapSample.js index 62ad950935114..96c78c94c0cd2 100644 --- a/tests/baselines/reference/sourceMapSample.js +++ b/tests/baselines/reference/sourceMapSample.js @@ -57,8 +57,8 @@ var Foo; var str = greeter.greet(); function foo2(greeting) { var restGreetings = []; - for (var _a = 1; _a < arguments.length; _a++) { - restGreetings[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + restGreetings[_i - 1] = arguments[_i]; } var greeters = []; greeters[0] = new Greeter(greeting); diff --git a/tests/baselines/reference/sourceMapSample.sourcemap.txt b/tests/baselines/reference/sourceMapSample.sourcemap.txt index 7608a68193606..218dfb1c15228 100644 --- a/tests/baselines/reference/sourceMapSample.sourcemap.txt +++ b/tests/baselines/reference/sourceMapSample.sourcemap.txt @@ -454,7 +454,7 @@ sourceFile:sourceMapSample.ts 1->Emitted(21, 13) Source(21, 37) + SourceIndex(0) name (Foo.Bar.foo2) 2 >Emitted(21, 36) Source(21, 63) + SourceIndex(0) name (Foo.Bar.foo2) --- ->>> for (var _a = 1; _a < arguments.length; _a++) { +>>> for (var _i = 1; _i < arguments.length; _i++) { 1->^^^^^^^^^^^^^^^^^ 2 > ^^^^^^^^^^^ 3 > ^ @@ -474,7 +474,7 @@ sourceFile:sourceMapSample.ts 5 >Emitted(22, 53) Source(21, 37) + SourceIndex(0) name (Foo.Bar.foo2) 6 >Emitted(22, 57) Source(21, 63) + SourceIndex(0) name (Foo.Bar.foo2) --- ->>> restGreetings[_a - 1] = arguments[_a]; +>>> restGreetings[_i - 1] = arguments[_i]; 1 >^^^^^^^^^^^^^^^^ 2 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1 > diff --git a/tests/baselines/reference/sourceMapValidationClass.js b/tests/baselines/reference/sourceMapValidationClass.js index bc526bc674cdc..eef5a723ebf3e 100644 --- a/tests/baselines/reference/sourceMapValidationClass.js +++ b/tests/baselines/reference/sourceMapValidationClass.js @@ -22,8 +22,8 @@ class Greeter { var Greeter = (function () { function Greeter(greeting) { var b = []; - for (var _a = 1; _a < arguments.length; _a++) { - b[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + b[_i - 1] = arguments[_i]; } this.greeting = greeting; this.x1 = 10; diff --git a/tests/baselines/reference/sourceMapValidationClass.sourcemap.txt b/tests/baselines/reference/sourceMapValidationClass.sourcemap.txt index 8909f29310004..1c80abde32e90 100644 --- a/tests/baselines/reference/sourceMapValidationClass.sourcemap.txt +++ b/tests/baselines/reference/sourceMapValidationClass.sourcemap.txt @@ -48,7 +48,7 @@ sourceFile:sourceMapValidationClass.ts 1 >Emitted(3, 9) Source(2, 42) + SourceIndex(0) name (Greeter.constructor) 2 >Emitted(3, 20) Source(2, 56) + SourceIndex(0) name (Greeter.constructor) --- ->>> for (var _a = 1; _a < arguments.length; _a++) { +>>> for (var _i = 1; _i < arguments.length; _i++) { 1->^^^^^^^^^^^^^ 2 > ^^^^^^^^^^^ 3 > ^ @@ -68,7 +68,7 @@ sourceFile:sourceMapValidationClass.ts 5 >Emitted(4, 49) Source(2, 42) + SourceIndex(0) name (Greeter.constructor) 6 >Emitted(4, 53) Source(2, 56) + SourceIndex(0) name (Greeter.constructor) --- ->>> b[_a - 1] = arguments[_a]; +>>> b[_i - 1] = arguments[_i]; 1 >^^^^^^^^^^^^ 2 > ^^^^^^^^^^^^^^^^^^^^^^^^^^ 1 > diff --git a/tests/baselines/reference/sourceMapValidationClasses.js b/tests/baselines/reference/sourceMapValidationClasses.js index 0ab0d1e10aa2c..96724f7c3c770 100644 --- a/tests/baselines/reference/sourceMapValidationClasses.js +++ b/tests/baselines/reference/sourceMapValidationClasses.js @@ -58,8 +58,8 @@ var Foo; var str = greeter.greet(); function foo2(greeting) { var restGreetings = []; - for (var _a = 1; _a < arguments.length; _a++) { - restGreetings[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + restGreetings[_i - 1] = arguments[_i]; } var greeters = []; /* inline block comment */ greeters[0] = new Greeter(greeting); diff --git a/tests/baselines/reference/sourceMapValidationClasses.sourcemap.txt b/tests/baselines/reference/sourceMapValidationClasses.sourcemap.txt index 31d276c68a110..d82ac6c3e0516 100644 --- a/tests/baselines/reference/sourceMapValidationClasses.sourcemap.txt +++ b/tests/baselines/reference/sourceMapValidationClasses.sourcemap.txt @@ -456,7 +456,7 @@ sourceFile:sourceMapValidationClasses.ts 1->Emitted(21, 13) Source(21, 37) + SourceIndex(0) name (Foo.Bar.foo2) 2 >Emitted(21, 36) Source(21, 83) + SourceIndex(0) name (Foo.Bar.foo2) --- ->>> for (var _a = 1; _a < arguments.length; _a++) { +>>> for (var _i = 1; _i < arguments.length; _i++) { 1->^^^^^^^^^^^^^^^^^ 2 > ^^^^^^^^^^^ 3 > ^ @@ -476,7 +476,7 @@ sourceFile:sourceMapValidationClasses.ts 5 >Emitted(22, 53) Source(21, 37) + SourceIndex(0) name (Foo.Bar.foo2) 6 >Emitted(22, 57) Source(21, 83) + SourceIndex(0) name (Foo.Bar.foo2) --- ->>> restGreetings[_a - 1] = arguments[_a]; +>>> restGreetings[_i - 1] = arguments[_i]; 1 >^^^^^^^^^^^^^^^^ 2 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1 > diff --git a/tests/baselines/reference/sourceMapValidationFunctions.js b/tests/baselines/reference/sourceMapValidationFunctions.js index 11b3fe40a6b6b..58222aa48c782 100644 --- a/tests/baselines/reference/sourceMapValidationFunctions.js +++ b/tests/baselines/reference/sourceMapValidationFunctions.js @@ -22,8 +22,8 @@ function greet(greeting) { function greet2(greeting, n, x) { if (n === void 0) { n = 10; } var restParams = []; - for (var _a = 3; _a < arguments.length; _a++) { - restParams[_a - 3] = arguments[_a]; + for (var _i = 3; _i < arguments.length; _i++) { + restParams[_i - 3] = arguments[_i]; } greetings++; return greetings; @@ -31,8 +31,8 @@ function greet2(greeting, n, x) { function foo(greeting, n, x) { if (n === void 0) { n = 10; } var restParams = []; - for (var _a = 3; _a < arguments.length; _a++) { - restParams[_a - 3] = arguments[_a]; + for (var _i = 3; _i < arguments.length; _i++) { + restParams[_i - 3] = arguments[_i]; } return; } diff --git a/tests/baselines/reference/sourceMapValidationFunctions.sourcemap.txt b/tests/baselines/reference/sourceMapValidationFunctions.sourcemap.txt index a1dff1a3b9ac5..a9e43e404a747 100644 --- a/tests/baselines/reference/sourceMapValidationFunctions.sourcemap.txt +++ b/tests/baselines/reference/sourceMapValidationFunctions.sourcemap.txt @@ -145,7 +145,7 @@ sourceFile:sourceMapValidationFunctions.ts 1 >Emitted(8, 5) Source(6, 55) + SourceIndex(0) name (greet2) 2 >Emitted(8, 25) Source(6, 78) + SourceIndex(0) name (greet2) --- ->>> for (var _a = 3; _a < arguments.length; _a++) { +>>> for (var _i = 3; _i < arguments.length; _i++) { 1->^^^^^^^^^ 2 > ^^^^^^^^^^^ 3 > ^ @@ -165,7 +165,7 @@ sourceFile:sourceMapValidationFunctions.ts 5 >Emitted(9, 45) Source(6, 55) + SourceIndex(0) name (greet2) 6 >Emitted(9, 49) Source(6, 78) + SourceIndex(0) name (greet2) --- ->>> restParams[_a - 3] = arguments[_a]; +>>> restParams[_i - 3] = arguments[_i]; 1 >^^^^^^^^ 2 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1 > @@ -272,7 +272,7 @@ sourceFile:sourceMapValidationFunctions.ts 1 >Emitted(17, 5) Source(10, 52) + SourceIndex(0) name (foo) 2 >Emitted(17, 25) Source(10, 75) + SourceIndex(0) name (foo) --- ->>> for (var _a = 3; _a < arguments.length; _a++) { +>>> for (var _i = 3; _i < arguments.length; _i++) { 1->^^^^^^^^^ 2 > ^^^^^^^^^^^ 3 > ^ @@ -292,7 +292,7 @@ sourceFile:sourceMapValidationFunctions.ts 5 >Emitted(18, 45) Source(10, 52) + SourceIndex(0) name (foo) 6 >Emitted(18, 49) Source(10, 75) + SourceIndex(0) name (foo) --- ->>> restParams[_a - 3] = arguments[_a]; +>>> restParams[_i - 3] = arguments[_i]; 1 >^^^^^^^^ 2 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1 > diff --git a/tests/baselines/reference/strictMode5.js b/tests/baselines/reference/strictMode5.js index 747c84f5540e4..c46de926dbb55 100644 --- a/tests/baselines/reference/strictMode5.js +++ b/tests/baselines/reference/strictMode5.js @@ -22,8 +22,8 @@ function bar(x: number = 10) { function foo() { "use strict"; var args = []; - for (var _a = 0; _a < arguments.length; _a++) { - args[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i - 0] = arguments[_i]; } } var A = (function () { diff --git a/tests/baselines/reference/stringLiteralTypeIsSubtypeOfString.js b/tests/baselines/reference/stringLiteralTypeIsSubtypeOfString.js index 9ba7e17b2e3a9..37aa59bef433f 100644 --- a/tests/baselines/reference/stringLiteralTypeIsSubtypeOfString.js +++ b/tests/baselines/reference/stringLiteralTypeIsSubtypeOfString.js @@ -133,8 +133,8 @@ var C = (function () { }; C.prototype.concat = function () { var strings = []; - for (var _a = 0; _a < arguments.length; _a++) { - strings[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + strings[_i - 0] = arguments[_i]; } return null; }; diff --git a/tests/baselines/reference/subtypingWithCallSignatures2.js b/tests/baselines/reference/subtypingWithCallSignatures2.js index f863756e60312..a887c52d2a159 100644 --- a/tests/baselines/reference/subtypingWithCallSignatures2.js +++ b/tests/baselines/reference/subtypingWithCallSignatures2.js @@ -254,15 +254,15 @@ var r9a = [r9arg1, r9arg2]; var r9b = [r9arg2, r9arg1]; var r10arg1 = function () { var x = []; - for (var _a = 0; _a < arguments.length; _a++) { - x[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + x[_i - 0] = arguments[_i]; } return x[0]; }; var r10arg2 = function () { var x = []; - for (var _a = 0; _a < arguments.length; _a++) { - x[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + x[_i - 0] = arguments[_i]; } return null; }; diff --git a/tests/baselines/reference/subtypingWithCallSignatures3.js b/tests/baselines/reference/subtypingWithCallSignatures3.js index 936c6550bca63..fb7b0fef5510f 100644 --- a/tests/baselines/reference/subtypingWithCallSignatures3.js +++ b/tests/baselines/reference/subtypingWithCallSignatures3.js @@ -170,15 +170,15 @@ var Errors; var r3b = [r3arg, r3arg2]; var r4arg = function () { var x = []; - for (var _a = 0; _a < arguments.length; _a++) { - x[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + x[_i - 0] = arguments[_i]; } return null; }; var r4arg2 = function () { var x = []; - for (var _a = 0; _a < arguments.length; _a++) { - x[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + x[_i - 0] = arguments[_i]; } return null; }; diff --git a/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution1_ES6.js b/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution1_ES6.js index 2c53b71301467..a2a96168fd8c8 100644 --- a/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution1_ES6.js +++ b/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution1_ES6.js @@ -25,8 +25,8 @@ var z = foo `${1}${2}${3}`; // any (with error) //// [taggedTemplateStringsWithOverloadResolution1_ES6.js] function foo() { var stuff = []; - for (var _a = 0; _a < arguments.length; _a++) { - stuff[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + stuff[_i - 0] = arguments[_i]; } return undefined; } diff --git a/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution2_ES6.js b/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution2_ES6.js index 1f3762e5331f2..44da93f8041b5 100644 --- a/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution2_ES6.js +++ b/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution2_ES6.js @@ -20,8 +20,8 @@ var d = foo2([], 1); // number //// [taggedTemplateStringsWithOverloadResolution2_ES6.js] function foo1() { var stuff = []; - for (var _a = 0; _a < arguments.length; _a++) { - stuff[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + stuff[_i - 0] = arguments[_i]; } return undefined; } @@ -29,8 +29,8 @@ var a = foo1 `${1}`; // string var b = foo1([], 1); // number function foo2() { var stuff = []; - for (var _a = 0; _a < arguments.length; _a++) { - stuff[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + stuff[_i - 0] = arguments[_i]; } return undefined; } diff --git a/tests/baselines/reference/undeclaredModuleError.js b/tests/baselines/reference/undeclaredModuleError.js index 681417085188b..e7e9b70ee7b75 100644 --- a/tests/baselines/reference/undeclaredModuleError.js +++ b/tests/baselines/reference/undeclaredModuleError.js @@ -21,8 +21,8 @@ define(["require", "exports", 'fs'], function (require, exports, fs) { } function join() { var paths = []; - for (var _a = 0; _a < arguments.length; _a++) { - paths[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + paths[_i - 0] = arguments[_i]; } } function instrumentFile(covFileDir, covFileName, originalFilePath) { diff --git a/tests/baselines/reference/underscoreTest1.js b/tests/baselines/reference/underscoreTest1.js index 0c792f981ae16..290e7aa6c888b 100644 --- a/tests/baselines/reference/underscoreTest1.js +++ b/tests/baselines/reference/underscoreTest1.js @@ -985,8 +985,8 @@ var fibonacci = _.memoize(function (n) { }); var log = _.bind(function (message) { var rest = []; - for (var _a = 1; _a < arguments.length; _a++) { - rest[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + rest[_i - 1] = arguments[_i]; } }, Date); _.delay(log, 1000, 'logged later'); diff --git a/tests/baselines/reference/varArgParamTypeCheck.js b/tests/baselines/reference/varArgParamTypeCheck.js index 761e0d5ee5190..c2a33416436a0 100644 --- a/tests/baselines/reference/varArgParamTypeCheck.js +++ b/tests/baselines/reference/varArgParamTypeCheck.js @@ -24,8 +24,8 @@ sequence( //// [varArgParamTypeCheck.js] function sequence() { var sequences = []; - for (var _a = 0; _a < arguments.length; _a++) { - sequences[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + sequences[_i - 0] = arguments[_i]; } } function callback(clb) { diff --git a/tests/baselines/reference/vararg.js b/tests/baselines/reference/vararg.js index 0a5e23e2fab45..038afb90cbc50 100644 --- a/tests/baselines/reference/vararg.js +++ b/tests/baselines/reference/vararg.js @@ -46,8 +46,8 @@ var M; } C.prototype.f = function (x) { var rest = []; - for (var _a = 1; _a < arguments.length; _a++) { - rest[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + rest[_i - 1] = arguments[_i]; } var sum = 0; for (var i = 0; i < rest.length; i++) { @@ -58,14 +58,14 @@ var M; }; C.prototype.fnope = function (x) { var rest = []; - for (var _a = 1; _a < arguments.length; _a++) { - rest[_a - 1] = arguments[_a]; + for (var _i = 1; _i < arguments.length; _i++) { + rest[_i - 1] = arguments[_i]; } }; C.prototype.fonly = function () { var rest = []; - for (var _a = 0; _a < arguments.length; _a++) { - rest[_a - 0] = arguments[_a]; + for (var _i = 0; _i < arguments.length; _i++) { + rest[_i - 0] = arguments[_i]; } builder = ""; for (var i = 0; i < rest.length; i++) { From 05c9966180a14bbcdb7d4f665e4a252db08d3651 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 6 Dec 2014 13:53:06 -0800 Subject: [PATCH 32/33] Addressing CR feedback: New SyntaxKind.BindingElement Introduced new VariableLikeDeclaration and BindingElement types Cleaned up VariableDeclaration, ParameterDeclaration, PropertyDeclaration types Node kind of binding element is always SyntaxKind.BindingElement Changed CheckVariableDeclaration to CheckVariableLikeDeclaration Reorganized CheckVariableLikeDeclaration --- src/compiler/binder.ts | 8 +- src/compiler/checker.ts | 228 ++++++++++++++++++++-------------- src/compiler/emitter.ts | 13 +- src/compiler/parser.ts | 70 ++++++----- src/compiler/types.ts | 63 +++++++--- src/services/navigationBar.ts | 3 + src/services/services.ts | 2 + 7 files changed, 231 insertions(+), 156 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 2a58fd9f9e1bd..575b20d3d838b 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -389,18 +389,14 @@ module ts { break; case SyntaxKind.Parameter: if (isBindingPattern((node).name)) { - if (isBindingPattern(parent)) { - bindChildren(node, 0, /*isBlockScopeContainer*/ false); - } - else { - bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, getDestructuringParameterName(node), /*isBlockScopeContainer*/ false); - } + bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, getDestructuringParameterName(node), /*isBlockScopeContainer*/ false); } else { bindDeclaration(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes, /*isBlockScopeContainer*/ false); } break; case SyntaxKind.VariableDeclaration: + case SyntaxKind.BindingElement: if (isBindingPattern((node).name)) { bindChildren(node, 0, /*isBlockScopeContainer*/ false); } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 43340d39e8692..34694f4b5bd99 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1435,7 +1435,7 @@ module ts { writePunctuation(writer, SyntaxKind.DotDotDotToken); } appendSymbolNameOnly(p, writer); - if (hasQuestionToken(p.valueDeclaration) || (p.valueDeclaration).initializer) { + if (hasQuestionToken(p.valueDeclaration) || (p.valueDeclaration).initializer) { writePunctuation(writer, SyntaxKind.QuestionToken); } writePunctuation(writer, SyntaxKind.ColonToken); @@ -1589,6 +1589,7 @@ module ts { function determineIfDeclarationIsVisible() { switch (node.kind) { case SyntaxKind.VariableDeclaration: + case SyntaxKind.BindingElement: case SyntaxKind.ModuleDeclaration: case SyntaxKind.ClassDeclaration: case SyntaxKind.InterfaceDeclaration: @@ -1596,8 +1597,7 @@ module ts { case SyntaxKind.FunctionDeclaration: case SyntaxKind.EnumDeclaration: case SyntaxKind.ImportDeclaration: - // In case of variable declaration, node.parent is variable statement so look at the variable statement's parent - var parent = node.kind === SyntaxKind.VariableDeclaration ? node.parent.parent : node.parent; + var parent = getDeclarationContainer(node); // If the node is not exported or it is not ambient module element (except import declaration) if (!(node.flags & NodeFlags.Export) && !(node.kind !== SyntaxKind.ImportDeclaration && parent.kind !== SyntaxKind.SourceFile && isInAmbientContext(parent))) { @@ -1651,6 +1651,18 @@ module ts { } } + function getRootDeclaration(node: Node): Node { + while (node.kind === SyntaxKind.BindingElement) { + node = node.parent.parent; + } + return node; + } + + function getDeclarationContainer(node: Node): Node { + node = getRootDeclaration(node); + return node.kind === SyntaxKind.VariableDeclaration ? node.parent.parent : node.parent; + } + function getTypeOfPrototypeProperty(prototype: Symbol): Type { // TypeScript 1.0 spec (April 2014): 8.4 // Every class automatically contains a static property member named 'prototype', @@ -1669,7 +1681,7 @@ module ts { // Return the inferred type for a binding element function getTypeForBindingElement(declaration: BindingElement): Type { var pattern = declaration.parent; - var parentType = getTypeForVariableDeclaration(pattern.parent); + var parentType = getTypeForVariableDeclaration(pattern.parent); // If parent has the unknown (error) type, then so does this binding element if (parentType === unknownType) { return unknownType; @@ -1713,7 +1725,7 @@ module ts { } // Return the inferred type for a variable, parameter, or property declaration - function getTypeForVariableDeclaration(declaration: VariableDeclaration): Type { + function getTypeForVariableDeclaration(declaration: VariableLikeDeclaration): Type { // A variable declared in a for..in statement is always of type any if (declaration.parent.kind === SyntaxKind.ForInStatement) { return anyType; @@ -1796,7 +1808,7 @@ module ts { // Here, the array literal [1, "one"] is contextually typed by the type [any, string], which is the implied type of the // binding pattern [x, s = ""]. Because the contextual type is a tuple type, the resulting type of [1, "one"] is the // tuple type [number, string]. Thus, the type inferred for 'x' is number and the type inferred for 's' is string. - function getWidenedTypeForVariableDeclaration(declaration: VariableDeclaration, reportErrors?: boolean): Type { + function getWidenedTypeForVariableDeclaration(declaration: VariableLikeDeclaration, reportErrors?: boolean): Type { var type = getTypeForVariableDeclaration(declaration); if (type) { if (reportErrors) { @@ -1814,9 +1826,12 @@ module ts { } // Rest parameters default to type any[], other parameters default to type any type = declaration.dotDotDotToken ? anyArrayType : anyType; - // Report implicit any errors unless this is a private property within an ambient declaration - if (reportErrors && compilerOptions.noImplicitAny && !isPrivateWithinAmbient(declaration) && !(declaration.kind === SyntaxKind.Parameter && isPrivateWithinAmbient(declaration.parent))) { - reportImplicitAnyError(declaration, type); + // Report implicit any errors unless this is a private property within an ambient declaration + if (reportErrors && compilerOptions.noImplicitAny) { + var root = getRootDeclaration(declaration); + if (!isPrivateWithinAmbient(root) && !(root.kind === SyntaxKind.Parameter && isPrivateWithinAmbient(root.parent))) { + reportImplicitAnyError(declaration, type); + } } return type; } @@ -1835,7 +1850,7 @@ module ts { } // Handle variable, parameter or property links.type = resolvingType; - var type = getWidenedTypeForVariableDeclaration(declaration, /*reportErrors*/ true); + var type = getWidenedTypeForVariableDeclaration(declaration, /*reportErrors*/ true); if (links.type === resolvingType) { links.type = type; } @@ -1843,7 +1858,7 @@ module ts { else if (links.type === resolvingType) { links.type = anyType; if (compilerOptions.noImplicitAny) { - var diagnostic = (symbol.valueDeclaration).type ? + var diagnostic = (symbol.valueDeclaration).type ? Diagnostics._0_implicitly_has_type_any_because_it_is_referenced_directly_or_indirectly_in_its_own_type_annotation : Diagnostics._0_implicitly_has_type_any_because_it_is_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer; error(symbol.valueDeclaration, diagnostic, symbolToString(symbol)); @@ -3090,7 +3105,7 @@ module ts { } return links.resolvedType; } - + function getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node: Node): Type { var links = getNodeLinks(node); if (!links.resolvedType) { @@ -3912,7 +3927,7 @@ module ts { return related; } return Ternary.True; - } + } function numberIndexTypesRelatedTo(source: ObjectType, target: ObjectType, reportErrors: boolean): Ternary { if (relation === identityRelation) { @@ -4375,7 +4390,7 @@ module ts { } } - function getInferenceCandidates(context: InferenceContext, index: number): Type[]{ + function getInferenceCandidates(context: InferenceContext, index: number): Type[] { var inferences = context.inferences[index]; return inferences.primary || inferences.secondary || emptyArray; } @@ -4454,8 +4469,8 @@ module ts { return type; } - function hasInitializer(node: VariableDeclaration): boolean { - return !!(node.initializer || isBindingPattern(node.parent) && hasInitializer(node.parent.parent)); + function hasInitializer(node: VariableLikeDeclaration): boolean { + return !!(node.initializer || isBindingPattern(node.parent) && hasInitializer(node.parent.parent)); } // Check if a given variable is assigned within a given syntax node @@ -4485,7 +4500,7 @@ module ts { return forEachChild(node, isAssignedIn); } - function isAssignedInVariableDeclaration(node: VariableDeclaration) { + function isAssignedInVariableDeclaration(node: VariableLikeDeclaration) { if (!isBindingPattern(node.name) && getSymbolOfNode(node) === symbol && hasInitializer(node)) { return true; } @@ -4497,7 +4512,8 @@ module ts { case SyntaxKind.BinaryExpression: return isAssignedInBinaryExpression(node); case SyntaxKind.VariableDeclaration: - return isAssignedInVariableDeclaration(node); + case SyntaxKind.BindingElement: + return isAssignedInVariableDeclaration(node); case SyntaxKind.ObjectBindingPattern: case SyntaxKind.ArrayBindingPattern: case SyntaxKind.ArrayLiteralExpression: @@ -4856,7 +4872,7 @@ module ts { container.kind === SyntaxKind.Property || container.kind === SyntaxKind.Constructor; } - } + } } if (canUseSuperExpression) { @@ -4914,7 +4930,7 @@ module ts { } // If last parameter is contextually rest parameter get its type - if (indexOfParameter === (func.parameters.length - 1) && + if (indexOfParameter === (func.parameters.length - 1) && funcHasRestParameters && contextualSignature.hasRestParameter && func.parameters.length >= contextualSignature.parameters.length) { return getTypeOfSymbol(contextualSignature.parameters[contextualSignature.parameters.length - 1]); } @@ -4930,13 +4946,13 @@ module ts { // of the parameter. Otherwise, in a variable or parameter declaration with a binding pattern name, the contextual // type of an initializer expression is the type implied by the binding pattern. function getContextualTypeForInitializerExpression(node: Expression): Type { - var declaration = node.parent; + var declaration = node.parent; if (node === declaration.initializer) { if (declaration.type) { return getTypeFromTypeNode(declaration.type); } if (declaration.kind === SyntaxKind.Parameter) { - var type = getContextuallyTypedParameterType(declaration); + var type = getContextuallyTypedParameterType(declaration); if (type) { return type; } @@ -5079,7 +5095,7 @@ module ts { // In a contextually typed conditional expression, the true/false expressions are contextually typed by the same type. function getContextualTypeForConditionalOperand(node: Expression): Type { var conditional = node.parent; - return node === conditional.whenTrue || node === conditional.whenFalse ? getContextualType(conditional) : undefined; + return node === conditional.whenTrue || node === conditional.whenFalse ? getContextualType(conditional) : undefined; } // Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily @@ -5097,6 +5113,7 @@ module ts { case SyntaxKind.VariableDeclaration: case SyntaxKind.Parameter: case SyntaxKind.Property: + case SyntaxKind.BindingElement: return getContextualTypeForInitializerExpression(node); case SyntaxKind.ArrowFunction: case SyntaxKind.ReturnStatement: @@ -5225,7 +5242,7 @@ module ts { } return createArrayType(getUnionType(elementTypes)); } - + function isNumericName(name: string) { // The intent of numeric names is that // - they are names with text in a numeric form, and that @@ -5250,7 +5267,7 @@ module ts { // with the strings '"Infinity"', '"-Infinity"', and '"NaN"' respectively. return (+name).toString() === name; } - + function checkObjectLiteral(node: ObjectLiteralExpression, contextualMapper?: TypeMapper): Type { var members = node.symbol.members; var properties: SymbolTable = {}; @@ -5581,10 +5598,7 @@ module ts { * @param callIsIncomplete Whether or not a call is unfinished, and we should be "lenient" when we have too few arguments. * @param signature The signature whose arity we are comparing. */ - function checkArity(adjustedArgCount: number, - typeArguments: NodeArray, - callIsIncomplete: boolean, - signature: Signature): boolean { + function checkArity(adjustedArgCount: number, typeArguments: NodeArray, callIsIncomplete: boolean, signature: Signature): boolean { // Too many arguments implies incorrect arity. if (!signature.hasRestParameter && adjustedArgCount > signature.parameters.length) { return false; @@ -5686,7 +5700,7 @@ module ts { var constraint = getConstraintOfTypeParameter(typeParameters[i]); if (constraint) { typeArgumentsAreAssignable = checkTypeAssignableTo(typeArgument, constraint, reportErrors ? typeArgNode : undefined, - Diagnostics.Type_0_does_not_satisfy_the_constraint_1); + Diagnostics.Type_0_does_not_satisfy_the_constraint_1); } } } @@ -6487,7 +6501,7 @@ module ts { return (type.flags & TypeFlags.Structured) !== 0; } - function isConstEnumObjectType(type: Type) : boolean { + function isConstEnumObjectType(type: Type): boolean { return type.flags & (TypeFlags.ObjectType | TypeFlags.Anonymous) && type.symbol && isConstEnumSymbol(type.symbol); } @@ -6634,8 +6648,8 @@ module ts { // if a user tries to apply a bitwise operator to 2 boolean operands // try and return them a helpful suggestion if ((leftType.flags & TypeFlags.Boolean) && - (rightType.flags & TypeFlags.Boolean) && - (suggestedOperator = getSuggestedBooleanOperator(node.operator)) !== undefined) { + (rightType.flags & TypeFlags.Boolean) && + (suggestedOperator = getSuggestedBooleanOperator(node.operator)) !== undefined) { error(node, Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, tokenToString(node.operator), tokenToString(suggestedOperator)); } else { @@ -6644,7 +6658,7 @@ module ts { var rightOk = checkArithmeticOperandType(node.right, rightType, Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type); if (leftOk && rightOk) { checkAssignmentOperator(numberType); - } + } } return numberType; @@ -6709,8 +6723,8 @@ module ts { case SyntaxKind.CommaToken: return rightType; } - - function getSuggestedBooleanOperator(operator: SyntaxKind): SyntaxKind { + + function getSuggestedBooleanOperator(operator: SyntaxKind): SyntaxKind { switch (operator) { case SyntaxKind.BarToken: case SyntaxKind.BarEqualsToken: @@ -6899,51 +6913,19 @@ module ts { } function checkParameter(node: ParameterDeclaration) { - checkVariableDeclaration(node); - if (isBindingPattern(node.name)) { - return; - } + checkVariableLikeDeclaration(node); var func = getContainingFunction(node); - if (node.flags & (NodeFlags.Public | NodeFlags.Private | NodeFlags.Protected) && - !(func.kind === SyntaxKind.Constructor && func.body)) { - error(node, Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation); + if (node.flags & (NodeFlags.Public | NodeFlags.Private | NodeFlags.Protected)) { + func = getContainingFunction(node); + if (!(func.kind === SyntaxKind.Constructor && func.body)) { + error(node, Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation); + } } if (node.dotDotDotToken) { if (!isArrayType(getTypeOfSymbol(node.symbol))) { error(node, Diagnostics.A_rest_parameter_must_be_of_an_array_type); } } - if (node.initializer) { - if (!func.body) { - error(node, Diagnostics.A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation); - } - checkReferencesInInitializer(node.initializer); - } - - function checkReferencesInInitializer(n: Node): void { - if (n.kind === SyntaxKind.Identifier) { - var referencedSymbol = getNodeLinks(n).resolvedSymbol; - // check FunctionLikeDeclaration.locals (stores parameters\function local variable) - // if it contains entry with a specified name and if this entry matches the resolved symbol - if (referencedSymbol && referencedSymbol !== unknownSymbol && getSymbol(func.locals, referencedSymbol.name, SymbolFlags.Value) === referencedSymbol) { - if (referencedSymbol.valueDeclaration.kind === SyntaxKind.Parameter) { - if (referencedSymbol.valueDeclaration === node) { - error(n, Diagnostics.Parameter_0_cannot_be_referenced_in_its_initializer, declarationNameToString(node.name)); - return; - } - if (referencedSymbol.valueDeclaration.pos < node.pos) { - // legal case - parameter initializer references some parameter strictly on left of current parameter declaration - return; - } - // fall through to error reporting - } - error(n, Diagnostics.Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it, declarationNameToString(node.name), declarationNameToString(n)); - } - } - else { - forEachChild(n, checkReferencesInInitializer); - } - } } function checkSignatureDeclaration(node: SignatureDeclaration) { @@ -6988,7 +6970,7 @@ module ts { var seenStringIndexer = false; for (var i = 0, len = indexSymbol.declarations.length; i < len; ++i) { var declaration = indexSymbol.declarations[i]; - if (declaration.parameters.length == 1 && declaration.parameters[0].type) { + if (declaration.parameters.length == 1 && declaration.parameters[0].type) { switch (declaration.parameters[0].type.kind) { case SyntaxKind.StringKeyword: if (!seenStringIndexer) { @@ -7013,8 +6995,7 @@ module ts { } function checkPropertyDeclaration(node: PropertyDeclaration) { - // TODO(andesh): Reconcile declaration types - checkVariableDeclaration(node); + checkVariableLikeDeclaration(node); } function checkMethodDeclaration(node: MethodDeclaration) { @@ -7077,7 +7058,7 @@ module ts { // Constructors of classes with no extends clause may not contain super calls, whereas // constructors of derived classes must contain at least one super call somewhere in their function body. if (getClassBaseTypeNode(node.parent)) { - + if (containsSuperCall(node.body)) { // The first statement in the body of a constructor must be a super call if both of the following are true: // - The containing class is a derived class. @@ -7517,7 +7498,7 @@ module ts { case SyntaxKind.ImportDeclaration: var result: SymbolFlags = 0; var target = resolveImport(getSymbolOfNode(d)); - forEach(target.declarations, d => { result |= getDeclarationSpaces(d); } ); + forEach(target.declarations, d => { result |= getDeclarationSpaces(d); }); return result; default: return SymbolFlags.ExportValue; @@ -7606,7 +7587,8 @@ module ts { return false; } - if (node.kind === SyntaxKind.Parameter && !(node.parent).body) { + var root = getRootDeclaration(node); + if (root.kind === SyntaxKind.Parameter && !(root.parent).body) { // just an overload - no codegen impact return false; } @@ -7672,7 +7654,7 @@ module ts { } // In case of variable declaration, node.parent is variable statement so look at the variable statement's parent - var parent = node.kind === SyntaxKind.VariableDeclaration ? node.parent.parent : node.parent; + var parent = getDeclarationContainer(node); if (parent.kind === SyntaxKind.SourceFile && isExternalModule(parent)) { // If the declaration happens to be in external module, report error that require and exports are reserved keywords error(name, Diagnostics.Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_an_external_module, @@ -7680,7 +7662,7 @@ module ts { } } - function checkCollisionWithConstDeclarations(node: VariableOrParameterDeclaration) { + function checkCollisionWithConstDeclarations(node: VariableLikeDeclaration) { // Variable declarations are hoisted to the top of their function scope. They can shadow // block scoped declarations, which bind tighter. this will not be flagged as duplicate definition // by the binder as the declaration scope is different. @@ -7712,30 +7694,84 @@ module ts { } } - function checkVariableDeclaration(node: VariableDeclaration) { + function isParameterDeclaration(node: VariableLikeDeclaration) { + while (node.kind === SyntaxKind.BindingElement) { + node = node.parent.parent; + } + return node.kind === SyntaxKind.Parameter; + } + + // Check that a parameter initializer contains no references to parameters declared to the right of itself + function checkParameterInitializer(node: VariableLikeDeclaration): void { + if (getRootDeclaration(node).kind === SyntaxKind.Parameter) { + var func = getContainingFunction(node); + visit(node.initializer); + } + function visit(n: Node) { + if (n.kind === SyntaxKind.Identifier) { + var referencedSymbol = getNodeLinks(n).resolvedSymbol; + // check FunctionLikeDeclaration.locals (stores parameters\function local variable) + // if it contains entry with a specified name and if this entry matches the resolved symbol + if (referencedSymbol && referencedSymbol !== unknownSymbol && getSymbol(func.locals, referencedSymbol.name, SymbolFlags.Value) === referencedSymbol) { + if (referencedSymbol.valueDeclaration.kind === SyntaxKind.Parameter) { + if (referencedSymbol.valueDeclaration === node) { + error(n, Diagnostics.Parameter_0_cannot_be_referenced_in_its_initializer, declarationNameToString(node.name)); + return; + } + if (referencedSymbol.valueDeclaration.pos < node.pos) { + // legal case - parameter initializer references some parameter strictly on left of current parameter declaration + return; + } + // fall through to error reporting + } + error(n, Diagnostics.Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it, declarationNameToString(node.name), declarationNameToString(n)); + } + } + else { + forEachChild(n, visit); + } + } + } + + // Check variable, parameter, or property declaration + function checkVariableLikeDeclaration(node: VariableLikeDeclaration) { checkSourceElement(node.type); - if (isBindingPattern(node.name)) { - forEach((node.name).elements, checkSourceElement); + // For a computed property, just check the initializer and exit + if (hasComputedNameButNotSymbol(node)) { if (node.initializer) { - checkTypeAssignableTo(checkExpressionCached(node.initializer), getWidenedTypeForVariableDeclaration(node), node, /*headMessage*/ undefined); + checkExpressionCached(node.initializer); } return; } - if (hasComputedNameButNotSymbol(node)) { - // Just check the initializer, since this property won't contribute to the enclosing type + // For a binding pattern, check contained binding elements + if (isBindingPattern(node.name)) { + forEach((node.name).elements, checkSourceElement); + } + // For a parameter declaration with an initializer, error and exit if the containing function doesn't have a body + if (node.initializer && getRootDeclaration(node).kind === SyntaxKind.Parameter && !getContainingFunction(node).body) { + error(node, Diagnostics.A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation); + return; + } + // For a binding pattern, validate the initializer and exit + if (isBindingPattern(node.name)) { if (node.initializer) { - checkExpressionCached(node.initializer); + checkTypeAssignableTo(checkExpressionCached(node.initializer), getWidenedTypeForVariableDeclaration(node), node, /*headMessage*/ undefined); + checkParameterInitializer(node); } return; } var symbol = getSymbolOfNode(node); var type = getTypeOfVariableOrParameterOrProperty(symbol); if (node === symbol.valueDeclaration) { + // Node is the primary declaration of the symbol, just validate the initializer if (node.initializer) { checkTypeAssignableTo(checkExpressionCached(node.initializer), type, node, /*headMessage*/ undefined); + checkParameterInitializer(node); } } else { + // Node is a secondary declaration, check that type is identical to primary declaration and check that + // initializer is consistent with type associated with the node var declarationType = getWidenedTypeForVariableDeclaration(node); if (type !== unknownType && declarationType !== unknownType && !isTypeIdenticalTo(type, declarationType)) { error(node.name, Diagnostics.Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2, declarationNameToString(node.name), typeToString(type), typeToString(declarationType)); @@ -7747,7 +7783,7 @@ module ts { if (node.kind !== SyntaxKind.Property) { // We know we don't have a binding pattern or computed name here checkExportsOnMergedDeclarations(node); - checkCollisionWithConstDeclarations(node); + checkCollisionWithConstDeclarations(node); checkCollisionWithCapturedSuperVariable(node, node.name); checkCollisionWithCapturedThisVariable(node, node.name); checkCollisionWithRequireExportsInGeneratedCode(node, node.name); @@ -7779,7 +7815,7 @@ module ts { } function checkForStatement(node: ForStatement) { - if (node.declarations) forEach(node.declarations, checkVariableDeclaration); + if (node.declarations) forEach(node.declarations, checkVariableLikeDeclaration); if (node.initializer) checkExpression(node.initializer); if (node.condition) checkExpression(node.condition); if (node.iterator) checkExpression(node.iterator); @@ -7796,7 +7832,7 @@ module ts { if (node.declarations) { if (node.declarations.length >= 1) { var decl = node.declarations[0]; - checkVariableDeclaration(decl); + checkVariableLikeDeclaration(decl); if (decl.type) { error(decl, Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation); } @@ -8646,7 +8682,8 @@ module ts { case SyntaxKind.TryStatement: return checkTryStatement(node); case SyntaxKind.VariableDeclaration: - return checkVariableDeclaration(node); + case SyntaxKind.BindingElement: + return checkVariableLikeDeclaration(node); case SyntaxKind.ClassDeclaration: return checkClassDeclaration(node); case SyntaxKind.InterfaceDeclaration: @@ -8694,6 +8731,7 @@ module ts { case SyntaxKind.Property: case SyntaxKind.ObjectBindingPattern: case SyntaxKind.ArrayBindingPattern: + case SyntaxKind.BindingElement: case SyntaxKind.ArrayLiteralExpression: case SyntaxKind.ObjectLiteralExpression: case SyntaxKind.PropertyAssignment: @@ -8973,7 +9011,7 @@ module ts { case SyntaxKind.Property: case SyntaxKind.Parameter: case SyntaxKind.VariableDeclaration: - return node === (parent).type; + return node === (parent).type; case SyntaxKind.FunctionDeclaration: case SyntaxKind.FunctionExpression: case SyntaxKind.ArrowFunction: @@ -9394,7 +9432,7 @@ module ts { return undefined; } - function writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableOrParameterDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter) { + function writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter) { // Get type of the symbol if this is the valid symbol otherwise get type at location var symbol = getSymbolOfNode(declaration); var type = symbol && !(symbol.flags & (SymbolFlags.TypeLiteral | SymbolFlags.Signature)) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 2856e806de178..18db6c6d7f6f7 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -440,7 +440,7 @@ module ts { handleSymbolAccessibilityError(resolver.isSymbolAccessible(symbol, enclosingDeclaration, meaning)); } - function writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableOrParameterDeclaration, type: TypeNode | StringLiteralExpression, getSymbolAccessibilityDiagnostic: GetSymbolAccessibilityDiagnostic) { + function writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, type: TypeNode | StringLiteralExpression, getSymbolAccessibilityDiagnostic: GetSymbolAccessibilityDiagnostic) { writer.getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic; write(": "); if (type) { @@ -996,7 +996,7 @@ module ts { } } - function emitTypeOfVariableDeclarationFromTypeLiteral(node: VariableOrParameterDeclaration) { + function emitTypeOfVariableDeclarationFromTypeLiteral(node: VariableLikeDeclaration) { // if this is property of type literal, // or is parameter of method/call/construct/index signature of type literal // emit only if type is specified @@ -2149,6 +2149,7 @@ module ts { switch (parent.kind) { case SyntaxKind.Parameter: case SyntaxKind.VariableDeclaration: + case SyntaxKind.BindingElement: case SyntaxKind.Property: case SyntaxKind.PropertyAssignment: case SyntaxKind.ShorthandPropertyAssignment: @@ -2761,10 +2762,10 @@ module ts { emitEnd(node.name); } - function emitDestructuring(root: BinaryExpression | BindingElement, value?: Expression) { + function emitDestructuring(root: BinaryExpression | VariableDeclaration | ParameterDeclaration, value?: Expression) { var emitCount = 0; // An exported declaration is actually emitted as an assignment (to a property on the module object), so - // temporary variables in an exported declaration need to have real declarations elsewhere. + // temporary variables in an exported declaration need to have real declarations elsewhere var isDeclaration = (root.kind === SyntaxKind.VariableDeclaration && !(root.flags & NodeFlags.Export)) || root.kind === SyntaxKind.Parameter; if (root.kind === SyntaxKind.BinaryExpression) { emitAssignmentExpression(root); @@ -2777,8 +2778,8 @@ module ts { if (emitCount++) { write(", "); } - if (name.parent && name.parent.kind === SyntaxKind.VariableDeclaration) { - emitModuleMemberName(name.parent); + if (name.parent && (name.parent.kind === SyntaxKind.VariableDeclaration || name.parent.kind === SyntaxKind.BindingElement)) { + emitModuleMemberName(name.parent); } else { emit(name); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index bfb9636f1c8ab..f803a1efa823f 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -102,6 +102,7 @@ module ts { // This list is a work in progress. Add missing node kinds to improve their error // spans. case SyntaxKind.VariableDeclaration: + case SyntaxKind.BindingElement: case SyntaxKind.ClassDeclaration: case SyntaxKind.InterfaceDeclaration: case SyntaxKind.ModuleDeclaration: @@ -216,13 +217,14 @@ module ts { case SyntaxKind.PropertyAssignment: case SyntaxKind.ShorthandPropertyAssignment: case SyntaxKind.VariableDeclaration: + case SyntaxKind.BindingElement: return children(node.modifiers) || - child((node).propertyName) || - child((node).dotDotDotToken) || - child((node).name) || - child((node).questionToken) || - child((node).type) || - child((node).initializer); + child((node).propertyName) || + child((node).dotDotDotToken) || + child((node).name) || + child((node).questionToken) || + child((node).type) || + child((node).initializer); case SyntaxKind.FunctionType: case SyntaxKind.ConstructorType: case SyntaxKind.CallSignature: @@ -580,7 +582,8 @@ module ts { case SyntaxKind.Property: case SyntaxKind.EnumMember: case SyntaxKind.PropertyAssignment: - return (parent).initializer === node; + case SyntaxKind.BindingElement: + return (parent).initializer === node; case SyntaxKind.ExpressionStatement: case SyntaxKind.IfStatement: case SyntaxKind.DoStatement: @@ -679,6 +682,7 @@ module ts { case SyntaxKind.TypeParameter: case SyntaxKind.Parameter: case SyntaxKind.VariableDeclaration: + case SyntaxKind.BindingElement: case SyntaxKind.Property: case SyntaxKind.PropertyAssignment: case SyntaxKind.ShorthandPropertyAssignment: @@ -1892,12 +1896,7 @@ module ts { // [+GeneratorParameter]BindingIdentifier[Yield]Initializer[In]opt // [~GeneratorParameter]BindingIdentifier[?Yield]Initializer[In, ?Yield]opt - var savedYieldContext = inYieldContext(); - if (inGeneratorParameterContext()) { - setYieldContext(true); - } - node.name = parseIdentifierOrPattern(SyntaxKind.Parameter); - setYieldContext(savedYieldContext); + node.name = inGeneratorParameterContext() ? doInYieldContext(parseIdentifierOrPattern) : parseIdentifierOrPattern(); if (getFullWidth(node.name) === 0 && node.flags === 0 && isModifier(token)) { // in cases like @@ -1913,9 +1912,7 @@ module ts { node.questionToken = parseOptionalToken(SyntaxKind.QuestionToken); node.type = parseParameterType(); - node.initializer = inGeneratorParameterContext() - ? doOutsideOfYieldContext(parseParameterInitializer) - : parseParameterInitializer(); + node.initializer = inGeneratorParameterContext() ? doOutsideOfYieldContext(parseParameterInitializer) : parseParameterInitializer(); // Do not check for initializers in an ambient context for parameters. This is not // a grammar error because the grammar allows arbitrary call signatures in @@ -3691,11 +3688,11 @@ module ts { // DECLARATIONS - function parseBindingElement(kind: SyntaxKind, context: ParsingContext): BindingElement { + function parseBindingElement(context: ParsingContext): BindingElement { if (context === ParsingContext.ArrayBindingElements && token === SyntaxKind.CommaToken) { return createNode(SyntaxKind.OmittedExpression); } - var node = createNode(kind); + var node = createNode(SyntaxKind.BindingElement); if (context === ParsingContext.ObjectBindingElements) { // TODO(andersh): Handle computed properties var id = parsePropertyName(); @@ -3705,32 +3702,32 @@ module ts { else { parseExpected(SyntaxKind.ColonToken); node.propertyName = id; - node.name = parseIdentifierOrPattern(kind); + node.name = parseIdentifierOrPattern(); } } else { - node.name = parseIdentifierOrPattern(kind); + node.name = parseIdentifierOrPattern(); } node.initializer = parseInitializer(/*inParameter*/ false); return finishNode(node); } - function parseBindingList(kind: SyntaxKind, context: ParsingContext): NodeArray { - return parseDelimitedList(context, () => parseBindingElement(kind, context)); + function parseBindingList(context: ParsingContext): NodeArray { + return parseDelimitedList(context, () => parseBindingElement(context)); } - function parseObjectBindingPattern(kind: SyntaxKind): BindingPattern { + function parseObjectBindingPattern(): BindingPattern { var node = createNode(SyntaxKind.ObjectBindingPattern); parseExpected(SyntaxKind.OpenBraceToken); - node.elements = parseBindingList(kind, ParsingContext.ObjectBindingElements); + node.elements = parseBindingList(ParsingContext.ObjectBindingElements); parseExpected(SyntaxKind.CloseBraceToken); return finishNode(node); } - function parseArrayBindingPattern(kind: SyntaxKind): BindingPattern { + function parseArrayBindingPattern(): BindingPattern { var node = createNode(SyntaxKind.ArrayBindingPattern); parseExpected(SyntaxKind.OpenBracketToken); - node.elements = parseBindingList(kind, ParsingContext.ArrayBindingElements); + node.elements = parseBindingList(ParsingContext.ArrayBindingElements); parseExpected(SyntaxKind.CloseBracketToken); return finishNode(node); } @@ -3739,19 +3736,19 @@ module ts { return token === SyntaxKind.OpenBraceToken || token === SyntaxKind.OpenBracketToken || isIdentifier(); } - function parseIdentifierOrPattern(kind: SyntaxKind): Identifier | BindingPattern { + function parseIdentifierOrPattern(): Identifier | BindingPattern { if (token === SyntaxKind.OpenBracketToken) { - return parseArrayBindingPattern(kind); + return parseArrayBindingPattern(); } if (token === SyntaxKind.OpenBraceToken) { - return parseObjectBindingPattern(kind); + return parseObjectBindingPattern(); } return parseIdentifier(); } function parseVariableDeclaration(): VariableDeclaration { var node = createNode(SyntaxKind.VariableDeclaration); - node.name = parseIdentifierOrPattern(SyntaxKind.VariableDeclaration); + node.name = parseIdentifierOrPattern(); node.type = parseTypeAnnotation(); node.initializer = parseInitializer(/*inParameter*/ false); return finishNode(node); @@ -4492,6 +4489,7 @@ module ts { case SyntaxKind.EnumDeclaration: return checkEnumDeclaration(node); case SyntaxKind.BinaryExpression: return checkBinaryExpression(node); + case SyntaxKind.BindingElement: return checkBindingElement(node); case SyntaxKind.CatchClause: return checkCatchClause(node); case SyntaxKind.ClassDeclaration: return checkClassDeclaration(node); case SyntaxKind.ComputedPropertyName: return checkComputedPropertyName(node); @@ -5594,14 +5592,22 @@ module ts { return checkTypeArguments(node.typeArguments); } + function checkBindingElement(node: BindingElement) { + if (node.parserContextFlags & ParserContextFlags.StrictMode && isEvalOrArgumentsIdentifier(node.name)) { + // It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code + // and its Identifier is eval or arguments + return reportInvalidUseInStrictMode(node.name); + } + } + function checkVariableDeclaration(node: VariableDeclaration) { if (inAmbientContext) { if (isBindingPattern(node.name)) { return grammarErrorOnNode(node, Diagnostics.Destructuring_declarations_are_not_allowed_in_ambient_contexts); } if (node.initializer) { - var equalsPos = node.type ? skipTrivia(sourceText, node.type.end) : skipTrivia(sourceText, node.name.end); - return grammarErrorAtPos(equalsPos, "=".length, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts); + // Error on equals token which immediate precedes the initializer + return grammarErrorAtPos(node.initializer.pos - 1, 1, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts); } } else { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 4627d9cf07f3a..b2bd418926db6 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -168,6 +168,7 @@ module ts { // Binding patterns ObjectBindingPattern, ArrayBindingPattern, + BindingElement, // Expression ArrayLiteralExpression, ObjectLiteralExpression, @@ -366,37 +367,65 @@ module ts { export interface SignatureDeclaration extends Declaration, ParsedSignature { } + // SyntaxKind.VariableDeclaration export interface VariableDeclaration extends Declaration { - propertyName?: Identifier; // Binding property name (in object binding pattern) - dotDotDotToken?: Node; // Present on rest parameter or rest element in binding pattern name: Identifier | BindingPattern; // Declared variable name - questionToken?: Node; // Present on optional parameter or property type?: TypeNode; // Optional type annotation initializer?: Expression; // Optional initializer } - export interface BindingPattern extends Node { - elements: NodeArray; + // SyntaxKind.Parameter + export interface ParameterDeclaration extends Declaration { + dotDotDotToken?: Node; // Present on rest parameter + name: Identifier | BindingPattern; // Declared parameter name + questionToken?: Node; // Present on optional parameter + type?: TypeNode; // Optional type annotation + initializer?: Expression; // Optional initializer } - export interface BindingElement extends VariableDeclaration { } - - export interface ParameterDeclaration extends VariableDeclaration { } + // SyntaxKind.BindingElement + export interface BindingElement extends Declaration { + propertyName?: Identifier; // Binding property name (in object binding pattern) + dotDotDotToken?: Node; // Present on rest binding element + name: Identifier | BindingPattern; // Declared binding element name + initializer?: Expression; // Optional initializer + } + // SyntaxKind.Property + // SyntaxKind.PropertyAssignment export interface PropertyDeclaration extends Declaration, ClassElement { - questionToken?: Node; - type?: TypeNode; - initializer?: Expression; + name: DeclarationName; // Declared property name + questionToken?: Node; // Present on optional property + type?: TypeNode; // Optional type annotation + initializer?: Expression; // Optional initializer } - export type VariableOrParameterDeclaration = VariableDeclaration | ParameterDeclaration; - export type VariableOrParameterOrPropertyDeclaration = VariableOrParameterDeclaration | PropertyDeclaration; - + // SyntaxKind.ShorthandPropertyAssignment export interface ShorthandPropertyDeclaration extends Declaration { name: Identifier; questionToken?: Node; } + // SyntaxKind.VariableDeclaration + // SyntaxKind.Parameter + // SyntaxKind.BindingElement + // SyntaxKind.Property + // SyntaxKind.PropertyAssignment + // SyntaxKind.ShorthandPropertyAssignment + // SyntaxKind.EnumMember + export interface VariableLikeDeclaration extends Declaration { + propertyName?: Identifier; + dotDotDotToken?: Node; + name: DeclarationName; + questionToken?: Node; + type?: TypeNode; + initializer?: Expression; + } + + export interface BindingPattern extends Node { + elements: NodeArray; + } + /** * Several node kinds share function-like features such as a signature, * a name, and a body. These nodes should extend FunctionLikeDeclaration. @@ -1004,7 +1033,7 @@ module ts { hasSemanticErrors(sourceFile?: SourceFile): boolean; isDeclarationVisible(node: Declaration): boolean; isImplementationOfOverload(node: FunctionLikeDeclaration): boolean; - writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableOrParameterDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; + writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; writeReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags): SymbolAccessiblityResult; isEntityNameVisible(entityName: EntityName, enclosingDeclaration: Node): SymbolVisibilityResult; @@ -1056,9 +1085,9 @@ module ts { Module = ValueModule | NamespaceModule, Accessor = GetAccessor | SetAccessor, - // Variables can be redeclared, but can not redeclare a block-scoped declaration with the + // Variables can be redeclared, but can not redeclare a block-scoped declaration with the // same name, or any other value that is not a variable, e.g. ValueModule or Class - FunctionScopedVariableExcludes = Value & ~FunctionScopedVariable, + FunctionScopedVariableExcludes = Value & ~FunctionScopedVariable, // Block-scoped declarations are not allowed to be re-declared // they can not merge with anything in the value space diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 6a4d7cc3eaa24..b69c7bbbd7006 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -224,6 +224,9 @@ module ts.NavigationBar { function createChildItem(node: Node): ts.NavigationBarItem { switch (node.kind) { case SyntaxKind.Parameter: + if (isBindingPattern((node).name)) { + break; + } if ((node.flags & NodeFlags.Modifier) === 0) { return undefined; } diff --git a/src/services/services.ts b/src/services/services.ts index 1fb408c5db8a6..4d3490f5f18ca 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -819,6 +819,7 @@ module ts { } // fall through case SyntaxKind.VariableDeclaration: + case SyntaxKind.BindingElement: if (isBindingPattern((node).name)) { forEachChild((node).name, visit); break; @@ -4712,6 +4713,7 @@ module ts { switch (node.kind) { case SyntaxKind.Parameter: case SyntaxKind.VariableDeclaration: + case SyntaxKind.BindingElement: case SyntaxKind.Property: case SyntaxKind.PropertyAssignment: case SyntaxKind.ShorthandPropertyAssignment: From b3dffffeb7b662901282118ba9b2c6b3343ca683 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 6 Dec 2014 14:56:34 -0800 Subject: [PATCH 33/33] Addressing a bit more CR feedback --- src/compiler/checker.ts | 16 ++++++++-------- src/services/navigationBar.ts | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 34694f4b5bd99..413737d9b3fe5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1681,7 +1681,7 @@ module ts { // Return the inferred type for a binding element function getTypeForBindingElement(declaration: BindingElement): Type { var pattern = declaration.parent; - var parentType = getTypeForVariableDeclaration(pattern.parent); + var parentType = getTypeForVariableLikeDeclaration(pattern.parent); // If parent has the unknown (error) type, then so does this binding element if (parentType === unknownType) { return unknownType; @@ -1725,7 +1725,7 @@ module ts { } // Return the inferred type for a variable, parameter, or property declaration - function getTypeForVariableDeclaration(declaration: VariableLikeDeclaration): Type { + function getTypeForVariableLikeDeclaration(declaration: VariableLikeDeclaration): Type { // A variable declared in a for..in statement is always of type any if (declaration.parent.kind === SyntaxKind.ForInStatement) { return anyType; @@ -1808,8 +1808,8 @@ module ts { // Here, the array literal [1, "one"] is contextually typed by the type [any, string], which is the implied type of the // binding pattern [x, s = ""]. Because the contextual type is a tuple type, the resulting type of [1, "one"] is the // tuple type [number, string]. Thus, the type inferred for 'x' is number and the type inferred for 's' is string. - function getWidenedTypeForVariableDeclaration(declaration: VariableLikeDeclaration, reportErrors?: boolean): Type { - var type = getTypeForVariableDeclaration(declaration); + function getWidenedTypeForVariableLikeDeclaration(declaration: VariableLikeDeclaration, reportErrors?: boolean): Type { + var type = getTypeForVariableLikeDeclaration(declaration); if (type) { if (reportErrors) { reportErrorsFromWidening(declaration, type); @@ -1850,7 +1850,7 @@ module ts { } // Handle variable, parameter or property links.type = resolvingType; - var type = getWidenedTypeForVariableDeclaration(declaration, /*reportErrors*/ true); + var type = getWidenedTypeForVariableLikeDeclaration(declaration, /*reportErrors*/ true); if (links.type === resolvingType) { links.type = type; } @@ -6970,7 +6970,7 @@ module ts { var seenStringIndexer = false; for (var i = 0, len = indexSymbol.declarations.length; i < len; ++i) { var declaration = indexSymbol.declarations[i]; - if (declaration.parameters.length == 1 && declaration.parameters[0].type) { + if (declaration.parameters.length === 1 && declaration.parameters[0].type) { switch (declaration.parameters[0].type.kind) { case SyntaxKind.StringKeyword: if (!seenStringIndexer) { @@ -7755,7 +7755,7 @@ module ts { // For a binding pattern, validate the initializer and exit if (isBindingPattern(node.name)) { if (node.initializer) { - checkTypeAssignableTo(checkExpressionCached(node.initializer), getWidenedTypeForVariableDeclaration(node), node, /*headMessage*/ undefined); + checkTypeAssignableTo(checkExpressionCached(node.initializer), getWidenedTypeForVariableLikeDeclaration(node), node, /*headMessage*/ undefined); checkParameterInitializer(node); } return; @@ -7772,7 +7772,7 @@ module ts { else { // Node is a secondary declaration, check that type is identical to primary declaration and check that // initializer is consistent with type associated with the node - var declarationType = getWidenedTypeForVariableDeclaration(node); + var declarationType = getWidenedTypeForVariableLikeDeclaration(node); if (type !== unknownType && declarationType !== unknownType && !isTypeIdenticalTo(type, declarationType)) { error(node.name, Diagnostics.Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2, declarationNameToString(node.name), typeToString(type), typeToString(declarationType)); } diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index b69c7bbbd7006..219b5866ce5d1 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -224,7 +224,7 @@ module ts.NavigationBar { function createChildItem(node: Node): ts.NavigationBarItem { switch (node.kind) { case SyntaxKind.Parameter: - if (isBindingPattern((node).name)) { + if (isBindingPattern((node).name)) { break; } if ((node.flags & NodeFlags.Modifier) === 0) {