Merge pull request #1346 from Microsoft/destructuring

Destructuring
This commit is contained in:
Anders Hejlsberg 2014-12-09 11:39:23 -08:00
commit bb70e9eb12
45 changed files with 2586 additions and 1080 deletions

View file

@ -332,10 +332,9 @@ module ts {
// symbol as its sole member. To the rest of the system, this symbol will be indistinguishable
// from an actual type literal symbol you would have gotten had you used the long form.
var symbolKind = node.kind === SyntaxKind.FunctionType ? SymbolFlags.CallSignature : SymbolFlags.ConstructSignature;
var symbol = createSymbol(symbolKind, getDeclarationName(node));
addDeclarationToSymbol(symbol, node, symbolKind);
bindChildren(node, symbolKind, /*isBlockScopeContainer:*/ false);
var symbol = createSymbol(SymbolFlags.Signature, getDeclarationName(node));
addDeclarationToSymbol(symbol, node, SymbolFlags.Signature);
bindChildren(node, SymbolFlags.Signature, /*isBlockScopeContainer:*/ false);
var typeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, "__type");
addDeclarationToSymbol(typeLiteralSymbol, node, SymbolFlags.TypeLiteral);
@ -376,10 +375,13 @@ module ts {
}
declareSymbol(blockScopeContainer.locals, undefined, node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes);
}
bindChildren(node, SymbolFlags.BlockScopedVariable, /*isBlockScopeContainer*/ false);
}
function getDestructuringParameterName(node: Declaration) {
return "__" + indexOf((<SignatureDeclaration>node.parent).parameters, node);
}
function bind(node: Node) {
node.parent = parent;
switch (node.kind) {
@ -387,10 +389,19 @@ module ts {
bindDeclaration(<Declaration>node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes, /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.Parameter:
bindDeclaration(<Declaration>node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes, /*isBlockScopeContainer*/ false);
if (isBindingPattern((<Declaration>node).name)) {
bindAnonymousDeclaration(<Declaration>node, SymbolFlags.FunctionScopedVariable, getDestructuringParameterName(<Declaration>node), /*isBlockScopeContainer*/ false);
}
else {
bindDeclaration(<Declaration>node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes, /*isBlockScopeContainer*/ false);
}
break;
case SyntaxKind.VariableDeclaration:
if (node.flags & NodeFlags.BlockScoped) {
case SyntaxKind.BindingElement:
if (isBindingPattern((<Declaration>node).name)) {
bindChildren(node, 0, /*isBlockScopeContainer*/ false);
}
else if (node.flags & NodeFlags.BlockScoped) {
bindBlockScopedVariableDeclaration(<Declaration>node);
}
else {
@ -399,6 +410,8 @@ module ts {
break;
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.PropertySignature:
bindDeclaration(<Declaration>node, SymbolFlags.Property | ((<PropertyDeclaration>node).questionToken ? SymbolFlags.Optional : 0), SymbolFlags.PropertyExcludes, /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.PropertyAssignment:
case SyntaxKind.ShorthandPropertyAssignment:
bindDeclaration(<Declaration>node, SymbolFlags.Property, SymbolFlags.PropertyExcludes, /*isBlockScopeContainer*/ false);
@ -407,10 +420,9 @@ module ts {
bindDeclaration(<Declaration>node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes, /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.CallSignature:
bindDeclaration(<Declaration>node, SymbolFlags.CallSignature, 0, /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.ConstructSignature:
bindDeclaration(<Declaration>node, SymbolFlags.ConstructSignature, 0, /*isBlockScopeContainer*/ true);
case SyntaxKind.IndexSignature:
bindDeclaration(<Declaration>node, SymbolFlags.Signature, 0, /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
@ -418,12 +430,9 @@ module ts {
// as other properties in the object literal. So we use SymbolFlags.PropertyExcludes
// so that it will conflict with any other object literal members with the same
// name.
bindDeclaration(<Declaration>node, SymbolFlags.Method,
bindDeclaration(<Declaration>node, SymbolFlags.Method | ((<MethodDeclaration>node).questionToken ? SymbolFlags.Optional : 0),
isObjectLiteralMethod(node) ? SymbolFlags.PropertyExcludes : SymbolFlags.MethodExcludes, /*isBlockScopeContainer*/ true);
break;
case SyntaxKind.IndexSignature:
bindDeclaration(<Declaration>node, SymbolFlags.IndexSignature, 0, /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.FunctionDeclaration:
bindDeclaration(<Declaration>node, SymbolFlags.Function, SymbolFlags.FunctionExcludes, /*isBlockScopeContainer*/ true);
break;
@ -483,7 +492,6 @@ module ts {
bindAnonymousDeclaration(<SourceFile>node, SymbolFlags.ValueModule, '"' + removeFileExtension((<SourceFile>node).filename) + '"', /*isBlockScopeContainer*/ true);
break;
}
case SyntaxKind.Block:
case SyntaxKind.TryBlock:
case SyntaxKind.CatchClause:
@ -491,9 +499,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;

File diff suppressed because it is too large Load diff

View file

@ -140,6 +140,10 @@ module ts {
Binary_digit_expected: { code: 1177, category: DiagnosticCategory.Error, key: "Binary digit expected." },
Octal_digit_expected: { code: 1178, category: DiagnosticCategory.Error, key: "Octal digit expected." },
Unexpected_token_expected: { code: 1179, category: DiagnosticCategory.Error, key: "Unexpected token. '{' expected." },
Property_destructuring_pattern_expected: { code: 1180, category: DiagnosticCategory.Error, key: "Property destructuring pattern expected." },
Array_element_destructuring_pattern_expected: { code: 1181, category: DiagnosticCategory.Error, key: "Array element destructuring pattern expected." },
A_destructuring_declaration_must_have_an_initializer: { code: 1182, category: DiagnosticCategory.Error, key: "A destructuring declaration must have an initializer." },
Destructuring_declarations_are_not_allowed_in_ambient_contexts: { code: 1183, 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." },
@ -232,8 +236,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." },
@ -289,6 +291,9 @@ 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}'" },
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_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_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." },
Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." },

View file

@ -552,6 +552,22 @@
"category": "Error",
"code": 1179
},
"Property destructuring pattern expected.": {
"category": "Error",
"code": 1180
},
"Array element destructuring pattern expected.": {
"category": "Error",
"code": 1181
},
"A destructuring declaration must have an initializer.": {
"category": "Error",
"code": 1182
},
"Destructuring declarations are not allowed in ambient contexts.": {
"category": "Error",
"code": 1183
},
"Duplicate identifier '{0}'.": {
"category": "Error",
@ -921,14 +937,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
@ -1153,6 +1161,18 @@
"category": "Error",
"code": 2458
},
"Type '{0}' has no property '{1}' and no string index signature.": {
"category": "Error",
"code": 2459
},
"Type '{0}' has no property '{1}'.": {
"category": "Error",
"code": 2460
},
"Type '{0}' is not an array type.": {
"category": "Error",
"code": 2461
},
"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",

View file

@ -441,7 +441,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) {
@ -1003,7 +1003,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
@ -1263,7 +1263,12 @@ module ts {
if (node.dotDotDotToken) {
write("...");
}
writeTextOfNode(currentSourceFile, node.name);
if (isBindingPattern(node.name)) {
write("_" + indexOf((<FunctionLikeDeclaration>node.parent).parameters, node));
}
else {
writeTextOfNode(currentSourceFile, node.name);
}
if (node.initializer || hasQuestionToken(node)) {
write("?");
}
@ -1490,6 +1495,9 @@ module ts {
var currentSourceFile: SourceFile;
var extendsEmitted = false;
var tempCount = 0;
var tempVariables: Identifier[];
var tempParameters: Identifier[];
/** write emitted output to disk*/
var writeEmittedFiles = writeJavaScriptFile;
@ -1885,6 +1893,44 @@ module ts {
writeFile(compilerHost, diagnostics, jsFilePath, emitOutput, writeByteOrderMark);
}
// 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++;
}
var result = <Identifier>createNode(SyntaxKind.Identifier);
result.text = name;
return result;
}
function recordTempDeclaration(name: Identifier) {
if (!tempVariables) {
tempVariables = [];
}
tempVariables.push(name);
}
function emitTempDeclarations(newLine: boolean) {
if (tempVariables) {
if (newLine) {
writeLine();
}
else {
write(" ");
}
write("var ");
emitCommaList(tempVariables);
write(";");
}
}
function emitTokenText(tokenKind: SyntaxKind, startPos: number, emitFn?: () => void) {
var tokenString = tokenToString(tokenKind);
if (emitFn) {
@ -1903,16 +1949,13 @@ module ts {
}
}
function emitTrailingCommaIfPresent(nodeList: NodeArray<Node>, isMultiline: boolean): void {
function emitTrailingCommaIfPresent(nodeList: NodeArray<Node>): void {
if (nodeList.hasTrailingComma) {
write(",");
if (isMultiline) {
writeLine();
}
}
}
function emitCommaList(nodes: NodeArray<Node>, includeTrailingComma: boolean, count?: number) {
function emitCommaList(nodes: Node[], count?: number) {
if (!(count >= 0)) {
count = nodes.length;
}
@ -1923,14 +1966,10 @@ module ts {
}
emit(nodes[i]);
}
if (includeTrailingComma) {
emitTrailingCommaIfPresent(nodes, /*isMultiline*/ false);
}
}
}
function emitMultiLineList(nodes: NodeArray<Node>, includeTrailingComma: boolean) {
function emitMultiLineList(nodes: Node[]) {
if (nodes) {
for (var i = 0; i < nodes.length; i++) {
if (i) {
@ -1939,10 +1978,6 @@ module ts {
writeLine();
emit(nodes[i]);
}
if (includeTrailingComma) {
emitTrailingCommaIfPresent(nodes, /*isMultiline*/ true);
}
}
}
@ -1970,8 +2005,9 @@ module ts {
}
function emitLiteral(node: LiteralExpression) {
var text = getLiteralText();
var text = compilerOptions.target < ScriptTarget.ES6 && isTemplateLiteralKind(node.kind) ? getTemplateLiteralAsStringLiteral(node) :
node.parent ? getSourceTextOfNodeFromSourceFile(currentSourceFile, node) :
node.text;
if (compilerOptions.sourceMap && (node.kind === SyntaxKind.StringLiteral || isTemplateLiteralKind(node.kind))) {
writer.writeLiteral(text);
}
@ -1982,14 +2018,6 @@ module ts {
else {
write(text);
}
function getLiteralText() {
if (compilerOptions.target < ScriptTarget.ES6 && isTemplateLiteralKind(node.kind)) {
return getTemplateLiteralAsStringLiteral(node)
}
return getSourceTextOfNodeFromSourceFile(currentSourceFile, node);
}
}
function getTemplateLiteralAsStringLiteral(node: LiteralExpression): string {
@ -2133,6 +2161,7 @@ module ts {
switch (parent.kind) {
case SyntaxKind.Parameter:
case SyntaxKind.VariableDeclaration:
case SyntaxKind.BindingElement:
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.PropertySignature:
case SyntaxKind.PropertyAssignment:
@ -2171,7 +2200,10 @@ module ts {
}
function emitIdentifier(node: Identifier) {
if (!isNotExpressionIdentifier(node)) {
if (!node.parent) {
write(node.text);
}
else if (!isNotExpressionIdentifier(node)) {
emitExpressionIdentifier(node);
}
else {
@ -2201,18 +2233,34 @@ module ts {
}
}
function emitObjectBindingPattern(node: BindingPattern) {
write("{ ");
emitCommaList(node.elements);
emitTrailingCommaIfPresent(node.elements);
write(" }");
}
function emitArrayBindingPattern(node: BindingPattern) {
write("[");
emitCommaList(node.elements);
emitTrailingCommaIfPresent(node.elements);
write("]");
}
function emitArrayLiteral(node: ArrayLiteralExpression) {
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("]");
}
}
@ -2224,14 +2272,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(" }");
}
}
@ -2242,30 +2296,19 @@ module ts {
write("]");
}
function emitDownlevelMethod(node: MethodDeclaration) {
if (!isObjectLiteralMethod(node)) {
return;
}
emitLeadingComments(node);
emit(node.name);
write(": ");
write("function ");
emitSignatureAndBody(node);
emitTrailingComments(node);
}
function emitMethod(node: MethodDeclaration) {
if (!isObjectLiteralMethod(node)) {
return;
}
emitLeadingComments(node);
emit(node.name);
if (compilerOptions.target < ScriptTarget.ES6) {
write(": function ");
}
emitSignatureAndBody(node);
emitTrailingComments(node);
}
function emitPropertyAssignment(node: PropertyDeclaration) {
emitLeadingComments(node);
emit(node.name);
@ -2274,18 +2317,9 @@ module ts {
emitTrailingComments(node);
}
function emitDownlevelShorthandPropertyAssignment(node: ShorthandPropertyAssignment) {
emitLeadingComments(node);
// Emit identifier as an identifier
emit(node.name);
write(": ");
// Even though this is stored as identifier treat it as an expression
// Short-hand, { x }, is equivalent of normal form { x: x }
emitExpressionIdentifier(node.name);
emitTrailingComments(node);
}
function emitShorthandPropertyAssignment(node: ShorthandPropertyAssignment) {
emitLeadingComments(node);
emit(node.name);
// If short-hand property has a prefix, then regardless of the target version, we will emit it as normal property assignment. For example:
// module m {
// export var y;
@ -2294,16 +2328,14 @@ module ts {
// export var obj = { y };
// }
// The short-hand property in obj need to emit as such ... = { y : m.y } regardless of the TargetScript version
var prefix = resolver.getExpressionNamePrefix(node.name);
if (prefix) {
emitDownlevelShorthandPropertyAssignment(node);
}
// If short-hand property has no prefix, emit it as short-hand.
else {
emitLeadingComments(node);
emit(node.name);
emitTrailingComments(node);
if (compilerOptions.target < ScriptTarget.ES6 || resolver.getExpressionNamePrefix(node.name)) {
// Emit identifier as an identifier
write(": ");
// Even though this is stored as identifier treat it as an expression
// Short-hand, { x }, is equivalent of normal form { x: x }
emitExpressionIdentifier(node.name);
}
emitTrailingComments(node);
}
function tryEmitConstantValue(node: PropertyAccessExpression | ElementAccessExpression): boolean {
@ -2356,13 +2388,13 @@ module ts {
emitThis(node.expression);
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(")");
}
}
@ -2372,7 +2404,7 @@ module ts {
emit(node.expression);
if (node.arguments) {
write("(");
emitCommaList(node.arguments, /*includeTrailingComma*/ false);
emitCommaList(node.arguments);
write(")");
}
}
@ -2470,11 +2502,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.ObjectLiteralExpression || node.left.kind === SyntaxKind.ArrayLiteralExpression)) {
emitDestructuring(node);
}
else {
emit(node.left);
if (node.operator !== SyntaxKind.CommaToken) write(" ");
write(tokenToString(node.operator));
write(" ");
emit(node.right);
}
}
function emitConditionalExpression(node: ConditionalExpression) {
@ -2494,6 +2531,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);
@ -2581,7 +2621,7 @@ module ts {
emitToken(SyntaxKind.VarKeyword, endPos);
}
write(" ");
emitCommaList(node.declarations, /*includeTrailingComma*/ false);
emitCommaList(node.declarations);
}
if (node.initializer) {
emit(node.initializer);
@ -2738,10 +2778,214 @@ module ts {
emitEnd(node.name);
}
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
var isDeclaration = (root.kind === SyntaxKind.VariableDeclaration && !(root.flags & NodeFlags.Export)) || root.kind === SyntaxKind.Parameter;
if (root.kind === SyntaxKind.BinaryExpression) {
emitAssignmentExpression(<BinaryExpression>root);
}
else {
emitBindingElement(<BindingElement>root, value);
}
function emitAssignment(name: Identifier, value: Expression) {
if (emitCount++) {
write(", ");
}
if (name.parent && (name.parent.kind === SyntaxKind.VariableDeclaration || name.parent.kind === SyntaxKind.BindingElement)) {
emitModuleMemberName(<Declaration>name.parent);
}
else {
emit(name);
}
write(" = ");
emit(value);
}
function ensureIdentifier(expr: Expression): Expression {
if (expr.kind !== SyntaxKind.Identifier) {
var identifier = createTempVariable(root);
if (!isDeclaration) {
recordTempDeclaration(identifier);
}
emitAssignment(identifier, expr);
expr = identifier;
}
return expr;
}
function createVoidZero(): Expression {
var zero = <LiteralExpression>createNode(SyntaxKind.NumericLiteral);
zero.text = "0";
var result = <PrefixUnaryExpression>createNode(SyntaxKind.PrefixUnaryExpression);
result.operator = SyntaxKind.VoidKeyword;
result.operand = zero;
return result;
}
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 = ensureIdentifier(value);
// Return the expression 'value === void 0 ? defaultValue : value'
var equals = <BinaryExpression>createNode(SyntaxKind.BinaryExpression);
equals.left = value;
equals.operator = SyntaxKind.EqualsEqualsEqualsToken;
equals.right = createVoidZero();
var cond = <ConditionalExpression>createNode(SyntaxKind.ConditionalExpression);
cond.condition = equals;
cond.whenTrue = defaultValue;
cond.whenFalse = value;
return cond;
}
function createNumericLiteral(value: number) {
var node = <LiteralExpression>createNode(SyntaxKind.NumericLiteral);
node.text = "" + value;
return node;
}
function parenthesizeForAccess(expr: Expression): LeftHandSideExpression {
if (expr.kind === SyntaxKind.Identifier || expr.kind === SyntaxKind.PropertyAccessExpression || expr.kind === SyntaxKind.ElementAccessExpression) {
return <LeftHandSideExpression>expr;
}
var node = <ParenthesizedExpression>createNode(SyntaxKind.ParenthesizedExpression);
node.expression = expr;
return node;
}
function createPropertyAccess(object: Expression, propName: Identifier): Expression {
if (propName.kind !== SyntaxKind.Identifier) {
return createElementAccess(object, propName);
}
var node = <PropertyAccessExpression>createNode(SyntaxKind.PropertyAccessExpression);
node.expression = parenthesizeForAccess(object);
node.name = propName;
return node;
}
function createElementAccess(object: Expression, index: Expression): Expression {
var node = <ElementAccessExpression>createNode(SyntaxKind.ElementAccessExpression);
node.expression = parenthesizeForAccess(object);
node.argumentExpression = index;
return node;
}
function emitObjectLiteralAssignment(target: ObjectLiteralExpression, 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 = ensureIdentifier(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 = <Identifier>((<PropertyAssignment>p).name);
emitDestructuringAssignment((<PropertyAssignment>p).initializer || propName, createPropertyAccess(value, propName));
}
}
}
function emitArrayLiteralAssignment(target: ArrayLiteralExpression, 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 = ensureIdentifier(value);
}
for (var i = 0; i < elements.length; i++) {
var e = elements[i];
if (e.kind !== SyntaxKind.OmittedExpression) {
emitDestructuringAssignment(e, createElementAccess(value, createNumericLiteral(i)));
}
}
}
function emitDestructuringAssignment(target: Expression, value: Expression) {
if (target.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>target).operator === SyntaxKind.EqualsToken) {
value = createDefaultValueCheck(value,(<BinaryExpression>target).right);
target = (<BinaryExpression>target).left;
}
if (target.kind === SyntaxKind.ObjectLiteralExpression) {
emitObjectLiteralAssignment(<ObjectLiteralExpression>target, value);
}
else if (target.kind === SyntaxKind.ArrayLiteralExpression) {
emitArrayLiteralAssignment(<ArrayLiteralExpression>target, value);
}
else {
emitAssignment(<Identifier>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.ParenthesizedExpression) {
write("(");
}
value = ensureIdentifier(value);
emitDestructuringAssignment(target, value);
write(", ");
emit(value);
if (root.parent.kind !== SyntaxKind.ParenthesizedExpression) {
write(")");
}
}
}
function emitBindingElement(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 = <BindingPattern>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 = ensureIdentifier(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 || <Identifier>element.name;
emitBindingElement(element, createPropertyAccess(value, propName));
}
else if (element.kind !== SyntaxKind.OmittedExpression) {
// Rewrite element to a declaration that accesses array element at index i
emitBindingElement(element, createElementAccess(value, createNumericLiteral(i)));
}
}
}
else {
emitAssignment(<Identifier>target.name, value);
}
}
}
function emitVariableDeclaration(node: VariableDeclaration) {
emitLeadingComments(node);
emitModuleMemberName(node);
emitOptional(" = ", node.initializer);
if (isBindingPattern(node.name)) {
emitDestructuring(node);
}
else {
emitModuleMemberName(node);
emitOptional(" = ", node.initializer);
}
emitTrailingComments(node);
}
@ -2758,32 +3002,57 @@ module ts {
write("var ");
}
}
emitCommaList(node.declarations, /*includeTrailingComma*/ false);
emitCommaList(node.declarations);
write(";");
emitTrailingComments(node);
}
function emitParameter(node: ParameterDeclaration) {
emitLeadingComments(node);
emit(node.name);
if (isBindingPattern(node.name)) {
var name = createTempVariable(node);
if (!tempParameters) {
tempParameters = [];
}
tempParameters.push(name);
emit(name);
}
else {
emit(node.name);
}
// 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("; }");
}
});
@ -2793,6 +3062,7 @@ module ts {
if (hasRestParameters(node)) {
var restIndex = node.parameters.length - 1;
var restParam = node.parameters[restIndex];
var tempName = createTempVariable(node, /*forLoopVariable*/ true).text;
writeLine();
emitLeadingComments(restParam);
emitStart(restParam);
@ -2804,22 +3074,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();
@ -2867,13 +3137,19 @@ 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();
}
function emitSignatureAndBody(node: FunctionLikeDeclaration) {
var saveTempCount = tempCount;
var saveTempVariables = tempVariables;
var saveTempParameters = tempParameters;
tempCount = 0;
tempVariables = undefined;
tempParameters = undefined;
emitSignatureParameters(node);
write(" {");
scopeEmitStart(node);
@ -2896,7 +3172,9 @@ module ts {
write("return ");
emitNode(node.body);
emitEnd(node.body);
write("; ");
write(";");
emitTempDeclarations(/*newLine*/ false);
write(" ");
emitStart(node.body);
write("}");
emitEnd(node.body);
@ -2913,11 +3191,12 @@ module ts {
write(";");
emitTrailingComments(node.body);
}
emitTempDeclarations(/*newLine*/ true);
writeLine();
if (node.body.kind === SyntaxKind.Block) {
emitLeadingCommentsOfPosition((<Block>node.body).statements.end);
decreaseIndent();
emitToken(SyntaxKind.CloseBraceToken, (<Block>node.body).statements.end);
emitToken(SyntaxKind.CloseBraceToken,(<Block>node.body).statements.end);
}
else {
decreaseIndent();
@ -2936,6 +3215,9 @@ module ts {
emitEnd(node);
write(";");
}
tempCount = saveTempCount;
tempVariables = saveTempVariables;
tempParameters = saveTempParameters;
}
function findInitialSuperCall(ctor: ConstructorDeclaration): ExpressionStatement {
@ -3139,6 +3421,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 && !(<ConstructorDeclaration>member).body) {
@ -3187,6 +3475,7 @@ module ts {
if (superCall) statements = statements.slice(1);
emitLines(statements);
}
emitTempDeclarations(/*newLine*/ true);
writeLine();
if (ctor) {
emitLeadingCommentsOfPosition((<Block>ctor.body).statements.end);
@ -3198,6 +3487,9 @@ module ts {
if (ctor) {
emitTrailingComments(ctor);
}
tempCount = saveTempCount;
tempVariables = saveTempVariables;
tempParameters = saveTempParameters;
}
}
@ -3305,7 +3597,13 @@ module ts {
emitEnd(node.name);
write(") ");
if (node.body.kind === SyntaxKind.ModuleBlock) {
var saveTempCount = tempCount;
var saveTempVariables = tempVariables;
tempCount = 0;
tempVariables = undefined;
emit(node.body);
tempCount = saveTempCount;
tempVariables = saveTempVariables;
}
else {
write("{");
@ -3521,17 +3819,18 @@ module ts {
if (!node) {
return;
}
if (node.flags & NodeFlags.Ambient) {
return emitPinnedOrTripleSlashComments(node);
}
// Check if the node can be emitted regardless of the ScriptTarget
switch (node.kind) {
case SyntaxKind.Identifier:
return emitIdentifier(<Identifier>node);
case SyntaxKind.Parameter:
return emitParameter(<ParameterDeclaration>node);
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
return emitMethod(<MethodDeclaration>node);
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
return emitAccessor(<AccessorDeclaration>node);
@ -3559,12 +3858,18 @@ module ts {
return emitTemplateSpan(<TemplateSpan>node);
case SyntaxKind.QualifiedName:
return emitQualifiedName(<QualifiedName>node);
case SyntaxKind.ObjectBindingPattern:
return emitObjectBindingPattern(<BindingPattern>node);
case SyntaxKind.ArrayBindingPattern:
return emitArrayBindingPattern(<BindingPattern>node);
case SyntaxKind.ArrayLiteralExpression:
return emitArrayLiteral(<ArrayLiteralExpression>node);
case SyntaxKind.ObjectLiteralExpression:
return emitObjectLiteral(<ObjectLiteralExpression>node);
case SyntaxKind.PropertyAssignment:
return emitPropertyAssignment(<PropertyDeclaration>node);
case SyntaxKind.ShorthandPropertyAssignment:
return emitShorthandPropertyAssignment(<ShorthandPropertyAssignment>node);
case SyntaxKind.ComputedPropertyName:
return emitComputedPropertyName(<ComputedPropertyName>node);
case SyntaxKind.PropertyAccessExpression:
@ -3659,29 +3964,6 @@ module ts {
case SyntaxKind.SourceFile:
return emitSourceFile(<SourceFile>node);
}
// Emit node which needs to be emitted differently depended on ScriptTarget
if (compilerOptions.target < ScriptTarget.ES6) {
// Emit node down-level
switch (node.kind) {
case SyntaxKind.ShorthandPropertyAssignment:
return emitDownlevelShorthandPropertyAssignment(<ShorthandPropertyAssignment>node);
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
return emitDownlevelMethod(<MethodDeclaration>node);
}
}
else {
// Emit node natively
Debug.assert(compilerOptions.target >= ScriptTarget.ES6, "Invalid ScriptTarget. We should emit as ES6 or above");
switch (node.kind) {
case SyntaxKind.ShorthandPropertyAssignment:
return emitShorthandPropertyAssignment(<ShorthandPropertyAssignment>node);
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
return emitMethod(<MethodDeclaration>node);
}
}
}
function hasDetachedComments(pos: number) {

View file

@ -40,12 +40,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))();
}
export function getSourceFileOfNode(node: Node): SourceFile {
@ -140,6 +136,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:
@ -260,21 +257,19 @@ module ts {
return child((<TypeParameterDeclaration>node).name) ||
child((<TypeParameterDeclaration>node).constraint);
case SyntaxKind.Parameter:
return children(node.modifiers) ||
child((<ParameterDeclaration>node).dotDotDotToken) ||
child((<ParameterDeclaration>node).name) ||
child((<ParameterDeclaration>node).questionToken) ||
child((<ParameterDeclaration>node).type) ||
child((<ParameterDeclaration>node).initializer);
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.PropertySignature:
case SyntaxKind.PropertyAssignment:
case SyntaxKind.ShorthandPropertyAssignment:
case SyntaxKind.VariableDeclaration:
case SyntaxKind.BindingElement:
return children(node.modifiers) ||
child((<PropertyDeclaration>node).name) ||
child((<PropertyDeclaration>node).questionToken) ||
child((<PropertyDeclaration>node).type) ||
child((<PropertyDeclaration>node).initializer);
child((<VariableLikeDeclaration>node).propertyName) ||
child((<VariableLikeDeclaration>node).dotDotDotToken) ||
child((<VariableLikeDeclaration>node).name) ||
child((<VariableLikeDeclaration>node).questionToken) ||
child((<VariableLikeDeclaration>node).type) ||
child((<VariableLikeDeclaration>node).initializer);
case SyntaxKind.FunctionType:
case SyntaxKind.ConstructorType:
case SyntaxKind.CallSignature:
@ -315,6 +310,9 @@ module ts {
return children((<UnionTypeNode>node).types);
case SyntaxKind.ParenthesizedType:
return child((<ParenthesizedTypeNode>node).type);
case SyntaxKind.ObjectBindingPattern:
case SyntaxKind.ArrayBindingPattern:
return children((<BindingPattern>node).elements);
case SyntaxKind.ArrayLiteralExpression:
return children((<ArrayLiteralExpression>node).elements);
case SyntaxKind.ObjectLiteralExpression:
@ -421,11 +419,6 @@ module ts {
return child((<CatchClause>node).name) ||
child((<CatchClause>node).type) ||
child((<CatchClause>node).block);
case SyntaxKind.VariableDeclaration:
return children(node.modifiers) ||
child((<VariableDeclaration>node).name) ||
child((<VariableDeclaration>node).type) ||
child((<VariableDeclaration>node).initializer);
case SyntaxKind.ClassDeclaration:
return children(node.modifiers) ||
child((<ClassDeclaration>node).name) ||
@ -506,6 +499,7 @@ module ts {
export function isAnyFunction(node: Node): boolean {
if (node) {
switch (node.kind) {
case SyntaxKind.Constructor:
case SyntaxKind.FunctionExpression:
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.ArrowFunction:
@ -513,7 +507,14 @@ module ts {
case SyntaxKind.MethodSignature:
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;
}
}
@ -522,11 +523,11 @@ module ts {
}
export function isFunctionBlock(node: Node) {
return node !== undefined && node.kind === SyntaxKind.Block && isAnyFunction(node.parent);
return node && node.kind === SyntaxKind.Block && isAnyFunction(node.parent);
}
export function isObjectLiteralMethod(node: Node) {
return node !== undefined && node.kind === SyntaxKind.MethodDeclaration && node.parent.kind === SyntaxKind.ObjectLiteralExpression;
return node && node.kind === SyntaxKind.MethodDeclaration && node.parent.kind === SyntaxKind.ObjectLiteralExpression;
}
export function getContainingFunction(node: Node): FunctionLikeDeclaration {
@ -646,7 +647,8 @@ module ts {
case SyntaxKind.PropertySignature:
case SyntaxKind.EnumMember:
case SyntaxKind.PropertyAssignment:
return (<VariableDeclaration>parent).initializer === node;
case SyntaxKind.BindingElement:
return (<VariableLikeDeclaration>parent).initializer === node;
case SyntaxKind.ExpressionStatement:
case SyntaxKind.IfStatement:
case SyntaxKind.DoStatement:
@ -730,6 +732,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;
@ -743,6 +749,7 @@ module ts {
case SyntaxKind.TypeParameter:
case SyntaxKind.Parameter:
case SyntaxKind.VariableDeclaration:
case SyntaxKind.BindingElement:
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.PropertySignature:
case SyntaxKind.PropertyAssignment:
@ -889,6 +896,8 @@ module ts {
EnumMembers, // Members in enum declaration
TypeReferences, // 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
@ -918,6 +927,8 @@ module ts {
case ParsingContext.EnumMembers: return Diagnostics.Enum_member_expected;
case ParsingContext.TypeReferences: return Diagnostics.Type_reference_expected;
case ParsingContext.VariableDeclarations: return Diagnostics.Variable_declaration_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;
@ -1087,17 +1098,20 @@ module ts {
// Note: any errors at the end of the file that do not precede a regular node, should get
// attached to the EOF token.
var parseErrorBeforeNextFinishedNode = false;
var sourceFile = <SourceFile>createRootNode(SyntaxKind.SourceFile, 0, sourceText.length,
fileExtensionIs(filename, ".d.ts") ? NodeFlags.DeclarationFile : 0);
var sourceFile = <SourceFile>createNode(SyntaxKind.SourceFile, 0);
if (fileExtensionIs(filename, ".d.ts")) {
sourceFile.flags = NodeFlags.DeclarationFile;
}
sourceFile.end = sourceText.length;
sourceFile.filename = normalizePath(filename);
sourceFile.text = sourceText;
sourceFile.getLineAndCharacterFromPosition = getLineAndCharacterFromSourcePosition;
sourceFile.getPositionFromLineAndCharacter = getPositionFromSourceLineAndCharacter;
sourceFile.getLineStarts = getLineStarts;
sourceFile.getSyntacticDiagnostics = getSyntacticDiagnostics;
sourceFile.filename = normalizePath(filename);
sourceFile.text = sourceText;
sourceFile.referenceDiagnostics = [];
sourceFile.parseDiagnostics = [];
sourceFile.grammarDiagnostics = [];
@ -1559,11 +1573,16 @@ module ts {
return token === SyntaxKind.OpenBracketToken || isLiteralPropertyName();
case ParsingContext.ObjectLiteralMembers:
return token === SyntaxKind.OpenBracketToken || token === SyntaxKind.AsteriskToken || isLiteralPropertyName();
case ParsingContext.ObjectBindingElements:
return isLiteralPropertyName();
case ParsingContext.TypeReferences:
// We want to make sure that the "extends" in "extends foo" or the "implements" in
// "implements foo" is not considered a type name.
return isIdentifier() && !isNotHeritageClauseTypeName();
case ParsingContext.VariableDeclarations:
return isIdentifierOrPattern();
case ParsingContext.ArrayBindingElements:
return token === SyntaxKind.CommaToken || isIdentifierOrPattern();
case ParsingContext.TypeParameters:
return isIdentifier();
case ParsingContext.ArgumentExpressions:
@ -1612,6 +1631,7 @@ module ts {
case ParsingContext.ClassMembers:
case ParsingContext.EnumMembers:
case ParsingContext.ObjectLiteralMembers:
case ParsingContext.ObjectBindingElements:
return token === SyntaxKind.CloseBraceToken;
case ParsingContext.SwitchClauseStatements:
return token === SyntaxKind.CloseBraceToken || token === SyntaxKind.CaseKeyword || token === SyntaxKind.DefaultKeyword;
@ -1627,10 +1647,11 @@ module ts {
return token === SyntaxKind.CloseParenToken || token === SyntaxKind.SemicolonToken;
case ParsingContext.ArrayLiteralMembers:
case ParsingContext.TupleElementTypes:
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
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;
@ -1966,10 +1987,10 @@ module ts {
}
}
function parseParameterType(): TypeNode | StringLiteralExpression {
function parseParameterType(): TypeNode {
if (parseOptional(SyntaxKind.ColonToken)) {
return token === SyntaxKind.StringLiteral
? <StringLiteralExpression>parseLiteralNode(/*internName:*/ true)
? <StringLiteralTypeNode>parseLiteralNode(/*internName:*/ true)
: parseType();
}
@ -1977,7 +1998,7 @@ module ts {
}
function isStartOfParameter(): boolean {
return token === SyntaxKind.DotDotDotToken || isIdentifier() || isModifier(token);
return token === SyntaxKind.DotDotDotToken || isIdentifierOrPattern() || isModifier(token);
}
function setModifiers(node: Node, modifiers: ModifiersArray) {
@ -1996,9 +2017,7 @@ module ts {
// [+GeneratorParameter]BindingIdentifier[Yield]Initializer[In]opt
// [~GeneratorParameter]BindingIdentifier[?Yield]Initializer[In, ?Yield]opt
node.name = inGeneratorParameterContext()
? doInYieldContext(parseIdentifier)
: parseIdentifier();
node.name = inGeneratorParameterContext() ? doInYieldContext(parseIdentifierOrPattern) : parseIdentifierOrPattern();
if (getFullWidth(node.name) === 0 && node.flags === 0 && isModifier(token)) {
// in cases like
@ -2014,9 +2033,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
@ -3841,20 +3858,81 @@ module ts {
// DECLARATIONS
function parseBindingElement(context: ParsingContext): BindingElement {
if (context === ParsingContext.ArrayBindingElements && token === SyntaxKind.CommaToken) {
return <BindingElement>createNode(SyntaxKind.OmittedExpression);
}
var node = <BindingElement>createNode(SyntaxKind.BindingElement);
if (context === ParsingContext.ObjectBindingElements) {
// TODO(andersh): Handle computed properties
var id = parsePropertyName();
if (id.kind === SyntaxKind.Identifier && token !== SyntaxKind.ColonToken) {
node.name = <Identifier>id;
}
else {
parseExpected(SyntaxKind.ColonToken);
node.propertyName = <Identifier>id;
node.name = parseIdentifierOrPattern();
}
}
else {
node.name = parseIdentifierOrPattern();
}
node.initializer = parseInitializer(/*inParameter*/ false);
return finishNode(node);
}
function parseBindingList(context: ParsingContext): NodeArray<BindingElement> {
return parseDelimitedList(context, () => parseBindingElement(context));
}
function parseObjectBindingPattern(): BindingPattern {
var node = <BindingPattern>createNode(SyntaxKind.ObjectBindingPattern);
parseExpected(SyntaxKind.OpenBraceToken);
node.elements = parseBindingList(ParsingContext.ObjectBindingElements);
parseExpected(SyntaxKind.CloseBraceToken);
return finishNode(node);
}
function parseArrayBindingPattern(): BindingPattern {
var node = <BindingPattern>createNode(SyntaxKind.ArrayBindingPattern);
parseExpected(SyntaxKind.OpenBracketToken);
node.elements = parseBindingList(ParsingContext.ArrayBindingElements);
parseExpected(SyntaxKind.CloseBracketToken);
return finishNode(node);
}
function isIdentifierOrPattern() {
return token === SyntaxKind.OpenBraceToken || token === SyntaxKind.OpenBracketToken || isIdentifier();
}
function parseIdentifierOrPattern(): Identifier | BindingPattern {
if (token === SyntaxKind.OpenBracketToken) {
return parseArrayBindingPattern();
}
if (token === SyntaxKind.OpenBraceToken) {
return parseObjectBindingPattern();
}
return parseIdentifier();
}
function parseVariableDeclaration(): VariableDeclaration {
var node = <VariableDeclaration>createNode(SyntaxKind.VariableDeclaration);
node.name = parseIdentifier();
node.name = parseIdentifierOrPattern();
node.type = parseTypeAnnotation();
node.initializer = parseInitializer(/*inParameter*/ false);
return finishNode(node);
}
function setFlag(array: NodeArray<VariableDeclaration>, flag: NodeFlags): NodeArray<VariableDeclaration> {
for (var i = 0, n = array.length; i < n; i++) {
array[i].flags |= flag;
function setFlag(nodes: NodeArray<VariableDeclaration>, flag: NodeFlags): NodeArray<VariableDeclaration> {
for (var i = 0; i < nodes.length; i++) {
var node = nodes[i];
node.flags |= flag;
if (node.name && isBindingPattern(node.name)) {
setFlag((<BindingPattern>node.name).elements, flag);
}
}
return array;
return nodes;
}
function parseVariableDeclarationList(): NodeArray<VariableDeclaration> {
@ -4562,6 +4640,7 @@ module ts {
case SyntaxKind.EnumDeclaration: return checkEnumDeclaration(<EnumDeclaration>node);
case SyntaxKind.BinaryExpression: return checkBinaryExpression(<BinaryExpression>node);
case SyntaxKind.BindingElement: return checkBindingElement(<BindingElement>node);
case SyntaxKind.CatchClause: return checkCatchClause(<CatchClause>node);
case SyntaxKind.ClassDeclaration: return checkClassDeclaration(<ClassDeclaration>node);
case SyntaxKind.ComputedPropertyName: return checkComputedPropertyName(<ComputedPropertyName>node);
@ -5386,7 +5465,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 (node.parserContextFlags & ParserContextFlags.StrictMode && isEvalOrArgumentsIdentifier(node.name)) {
return reportInvalidUseInStrictMode(node.name);
return reportInvalidUseInStrictMode(<Identifier>node.name);
}
}
@ -5658,18 +5737,38 @@ module ts {
return checkTypeArguments(node.typeArguments);
}
function checkVariableDeclaration(node: VariableDeclaration) {
if (inAmbientContext && 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);
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(<Identifier>node.name);
}
if (!inAmbientContext && !node.initializer && isConst(node)) {
return grammarErrorOnNode(node, Diagnostics.const_declarations_must_be_initialized);
}
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) {
// 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 {
if (!node.initializer) {
if (isBindingPattern(node.name) && !isBindingPattern(node.parent)) {
return grammarErrorOnNode(node, Diagnostics.A_destructuring_declaration_must_have_an_initializer);
}
if (isConst(node)) {
return grammarErrorOnNode(node, Diagnostics.const_declarations_must_be_initialized);
}
}
}
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);
return reportInvalidUseInStrictMode(<Identifier>node.name);
}
}

View file

@ -167,6 +167,10 @@ module ts {
TupleType,
UnionType,
ParenthesizedType,
// Binding patterns
ObjectBindingPattern,
ArrayBindingPattern,
BindingElement,
// Expression
ArrayLiteralExpression,
ObjectLiteralExpression,
@ -353,7 +357,8 @@ module ts {
}
export type EntityName = Identifier | QualifiedName;
export type DeclarationName = Identifier | LiteralExpression | ComputedPropertyName;
export type DeclarationName = Identifier | LiteralExpression | ComputedPropertyName | BindingPattern;
export interface Declaration extends Node {
_declarationBrand: any;
@ -378,39 +383,43 @@ module ts {
type?: TypeNode;
}
// SyntaxKind.VariableDeclaration
export interface VariableDeclaration extends Declaration {
name: Identifier;
type?: TypeNode;
initializer?: Expression;
name: Identifier | BindingPattern; // Declared variable name
type?: TypeNode; // Optional type annotation
initializer?: Expression; // Optional initializer
}
// SyntaxKind.Parameter
export interface ParameterDeclaration extends Declaration {
dotDotDotToken?: Node;
name: Identifier;
questionToken?: Node;
type?: TypeNode | StringLiteralExpression;
initializer?: Expression;
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
}
// 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
export interface PropertyDeclaration extends Declaration, ClassElement {
_propertyDeclarationBrand: any;
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;
export interface ObjectLiteralElement extends Declaration {
_objectLiteralBrandBrand: any;
}
export interface ShorthandPropertyAssignment extends ObjectLiteralElement {
name: Identifier;
questionToken?: Node;
}
// SyntaxKind.PropertyAssignment
export interface PropertyAssignment extends ObjectLiteralElement {
_propertyAssignmentBrand: any;
name: DeclarationName;
@ -418,6 +427,32 @@ module ts {
initializer: Expression;
}
// SyntaxKind.ShorthandPropertyAssignment
export interface ShorthandPropertyAssignment extends ObjectLiteralElement {
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<BindingElement>;
}
/**
* Several node kinds share function-like features such as a signature,
* a name, and a body. These nodes should extend FunctionLikeDeclaration.
@ -505,6 +540,8 @@ module ts {
type: TypeNode;
}
export interface StringLiteralTypeNode extends LiteralExpression, TypeNode { }
// Note: 'brands' in our syntax nodes serve to give us a small amount of nominal typing.
// Consider 'Expression'. Without the brand, 'Expression' is actually no different
// (structurally) than 'Node'. Because of this you can pass any Node to a function that
@ -1034,13 +1071,14 @@ 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;
// Returns the constant value this property access resolves to, or 'undefined' for a non-constant
getConstantValue(node: PropertyAccessExpression | ElementAccessExpression): number;
isEmitBlocked(sourceFile?: SourceFile): boolean;
isUnknownIdentifier(location: Node, name: string): boolean;
}
export const enum SymbolFlags {
@ -1061,35 +1099,33 @@ 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,
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,
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
// 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
@ -1198,6 +1234,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,

View file

@ -37,26 +37,50 @@ module ts.NavigationBar {
return indent;
}
function getChildNodes(nodes: Node[]): Node[] {
var childNodes: 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) {
childNodes.push(node);
}
else if (node.kind === SyntaxKind.VariableStatement) {
childNodes.push.apply(childNodes, (<VariableStatement>node).declarations);
function visit(node: Node) {
switch (node.kind) {
case SyntaxKind.VariableStatement:
forEach((<VariableStatement>node).declarations, visit);
break;
case SyntaxKind.ObjectBindingPattern:
case SyntaxKind.ArrayBindingPattern:
forEach((<BindingPattern>node).elements, visit);
break;
case SyntaxKind.VariableDeclaration:
if (isBindingPattern(node)) {
visit((<VariableDeclaration>node).name);
break;
}
// Fall through
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, (<VariableStatement>node).declarations);
// }
//}
forEach(nodes, visit);
return sortNodes(childNodes);
}
@ -200,6 +224,9 @@ module ts.NavigationBar {
function createChildItem(node: Node): ts.NavigationBarItem {
switch (node.kind) {
case SyntaxKind.Parameter:
if (isBindingPattern((<ParameterDeclaration>node).name)) {
break;
}
if ((node.flags & NodeFlags.Modifier) === 0) {
return undefined;
}
@ -235,6 +262,9 @@ module ts.NavigationBar {
return createItem(node, getTextOfNode((<FunctionLikeDeclaration>node).name), ts.ScriptElementKind.functionElement);
case SyntaxKind.VariableDeclaration:
if (isBindingPattern((<VariableDeclaration>node).name)) {
break;
}
if (isConst(node)) {
return createItem(node, getTextOfNode((<VariableDeclaration>node).name), ts.ScriptElementKind.constElement);
}

View file

@ -806,6 +806,8 @@ module ts {
// fall through
case SyntaxKind.Constructor:
case SyntaxKind.VariableStatement:
case SyntaxKind.ObjectBindingPattern:
case SyntaxKind.ArrayBindingPattern:
case SyntaxKind.ModuleBlock:
forEachChild(node, visit);
break;
@ -823,6 +825,11 @@ module ts {
}
// fall through
case SyntaxKind.VariableDeclaration:
case SyntaxKind.BindingElement:
if (isBindingPattern((<VariableDeclaration>node).name)) {
forEachChild((<VariableDeclaration>node).name, visit);
break;
}
case SyntaxKind.EnumMember:
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.PropertySignature:
@ -4746,6 +4753,7 @@ module ts {
switch (node.kind) {
case SyntaxKind.Parameter:
case SyntaxKind.VariableDeclaration:
case SyntaxKind.BindingElement:
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.PropertySignature:
case SyntaxKind.PropertyAssignment:

View file

@ -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(54,1): error TS2364: Invalid left-hand side of assignment expression.
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(57,1): error TS2364: Invalid left-hand side of assignment expression.
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(58,1): error TS2364: Invalid left-hand side of assignment expression.
@ -37,7 +38,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 (37 errors) ====
==== tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts (38 errors) ====
// expected error for all the LHS of assignments
var value;
@ -108,7 +109,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

View file

@ -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
}

View file

@ -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 _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 _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 _i = 10; // No Error
};

View file

@ -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
}

View file

@ -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
}

View file

@ -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 _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 _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 _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 _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 _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 _i; // no error
}

View file

@ -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
}

View file

@ -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
}
}

View file

@ -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 _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 _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 _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 _a = 0; _a < arguments.length; _a++) {
restParameters[_a - 0] = arguments[_a];
}
var _i = 10; // no error
};

View file

@ -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
}
}

View file

@ -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

View file

@ -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 _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 _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 _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 _a = 1; _a < arguments.length; _a++) {
rest[_a - 1] = arguments[_a];
}
}
function f4NoError(_i) {

View file

@ -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

View file

@ -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
}
}

View file

@ -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 _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 _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 _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 _a = 1; _a < arguments.length; _a++) {
rest[_a - 1] = arguments[_a];
}
}
function f4NoError(_i) {

View file

@ -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
}
}

View file

@ -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();

View file

@ -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 _a = 0; _a < arguments.length; _a++) {
args[_a - 0] = arguments[_a];
}
console.log(_i); // This should result in error
}

View file

@ -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

View file

@ -0,0 +1,12 @@
tests/cases/conformance/es6/destructuring/declarationInAmbientContext.ts(1,13): error TS1183: Destructuring declarations are not allowed in ambient contexts.
tests/cases/conformance/es6/destructuring/declarationInAmbientContext.ts(2,13): error TS1183: 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 TS1183: Destructuring declarations are not allowed in ambient contexts.
declare var {c, d}; // Error, destructuring declaration not allowed in ambient context
~~~~~~
!!! error TS1183: Destructuring declarations are not allowed in ambient contexts.

View file

@ -0,0 +1,12 @@
tests/cases/conformance/es6/destructuring/declarationWithNoInitializer.ts(1,5): error TS1182: A destructuring declaration must have an initializer.
tests/cases/conformance/es6/destructuring/declarationWithNoInitializer.ts(2,5): error TS1182: A destructuring declaration must have an initializer.
==== tests/cases/conformance/es6/destructuring/declarationWithNoInitializer.ts (2 errors) ====
var [a, b]; // Error, no initializer
~~~~~~
!!! error TS1182: A destructuring declaration must have an initializer.
var {c, d}; // Error, no initializer
~~~~~~
!!! error TS1182: A destructuring declaration must have an initializer.

View file

@ -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]);
}

View file

@ -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 === void0 ? 0 : _b, _c = _a[1], y = _c === void0 ? "" : _c;
var x;
var y;
}
function f7() {
var _a = [1, "hello"], _b = _a[0], x = _b === void0 ? 0 : _b, _c = _a[1], y = _c === void0 ? 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 === void0 ? ["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 === void0 ? 1 : _b, _c = _a[1], _d = _c[0], b = _d === void0 ? "hello" : _d, _e = _c[1], x = _e.x, _f = _e.y, c = _f === void0 ? 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 === void0 ? "" : _b, _c = _a.b, b = _c === void0 ? 0 : _c, _d = _a.c, c = _d === void0 ? 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 === void0 ? 1 : _f, _g = _e[1], b = _g === void0 ? "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 === void0 ? [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;
}

View file

@ -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 : <T extends Base, U extends Base>(a: { x: T; y: U; }) => (T | U)[]
>{ x: new Base(), y: new Derived2() } : { x: Base; y: Derived2; }

View file

@ -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.
}
!!! error TS1005: ',' expected.
~
!!! error TS2391: Function implementation is missing or not immediately following the declaration.
}
!!! error TS1005: ')' expected.

View file

@ -1,8 +1,11 @@
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 (1 errors) ====
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList2.ts (2 errors) ====
function f(a, {
~
!!! error TS1005: ')' expected.
}
~
!!! error TS2391: Function implementation is missing or not immediately following the declaration.
}
!!! error TS1005: ')' expected.

View file

@ -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.

View file

@ -0,0 +1,25 @@
tests/cases/conformance/types/union/unionTypeEquivalence.ts(5,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'C', but here has type 'C | D'.
==== tests/cases/conformance/types/union/unionTypeEquivalence.ts (1 errors) ====
// A | B is equivalent to A if B is a subtype of A
class C { }
class D extends C { foo() { } }
var x: C;
var x : C | D;
~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'C', but here has type 'C | D'.
// A | B is equivalent to B | A.
var y: string | number;
var y : number | string;
// AB | C is equivalent to A | BC, where AB is A | B and BC is B | C.
var z : string | number | boolean;
var z : (string | number) | boolean;
var z : string | (number | boolean);
var AB : string | number;
var BC : number | boolean;
var z1: typeof AB | boolean;
var z1: string | typeof BC;

View file

@ -1,50 +0,0 @@
=== tests/cases/conformance/types/union/unionTypeEquivalence.ts ===
// A | B is equivalent to A if B is a subtype of A
class C { }
>C : C
class D extends C { foo() { } }
>D : D
>C : C
>foo : () => void
var x: C;
>x : C
>C : C
var x : C | D;
>x : C
>C : C
>D : D
// A | B is equivalent to B | A.
var y: string | number;
>y : string | number
var y : number | string;
>y : string | number
// AB | C is equivalent to A | BC, where AB is A | B and BC is B | C.
var z : string | number | boolean;
>z : string | number | boolean
var z : (string | number) | boolean;
>z : string | number | boolean
var z : string | (number | boolean);
>z : string | number | boolean
var AB : string | number;
>AB : string | number
var BC : number | boolean;
>BC : number | boolean
var z1: typeof AB | boolean;
>z1 : string | number | boolean
>AB : string | number
var z1: string | typeof BC;
>z1 : string | number | boolean
>BC : number | boolean

View file

@ -0,0 +1,24 @@
tests/cases/conformance/types/specifyingTypes/typeLiterals/unionTypeLiterals.ts(11,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'unionOfFunctionType' must be of type '(() => string) | (() => number)', but here has type '() => string | number'.
tests/cases/conformance/types/specifyingTypes/typeLiterals/unionTypeLiterals.ts(15,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'unionOfConstructorType' must be of type '(new () => string) | (new () => number)', but here has type 'new () => string | number'.
==== tests/cases/conformance/types/specifyingTypes/typeLiterals/unionTypeLiterals.ts (2 errors) ====
// basic valid forms of union literals
var simpleUnion: string | number;
var unionOfUnion: string | number | boolean;
var arrayOfUnions: (string | number)[];
var arrayOfUnions: Array<string | number>;
var unionOfFunctionType: (() => string) | (() => number);
var unionOfFunctionType: { (): string } | { (): number };
var unionOfFunctionType: () => string | number;
~~~~~~~~~~~~~~~~~~~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'unionOfFunctionType' must be of type '(() => string) | (() => number)', but here has type '() => string | number'.
var unionOfConstructorType: (new () => string) | (new () => number);
var unionOfConstructorType: { new (): string } | { new (): number };
var unionOfConstructorType: new () => string | number;
~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'unionOfConstructorType' must be of type '(new () => string) | (new () => number)', but here has type 'new () => string | number'.

View file

@ -1,34 +0,0 @@
=== tests/cases/conformance/types/specifyingTypes/typeLiterals/unionTypeLiterals.ts ===
// basic valid forms of union literals
var simpleUnion: string | number;
>simpleUnion : string | number
var unionOfUnion: string | number | boolean;
>unionOfUnion : string | number | boolean
var arrayOfUnions: (string | number)[];
>arrayOfUnions : (string | number)[]
var arrayOfUnions: Array<string | number>;
>arrayOfUnions : (string | number)[]
>Array : T[]
var unionOfFunctionType: (() => string) | (() => number);
>unionOfFunctionType : (() => string) | (() => number)
var unionOfFunctionType: { (): string } | { (): number };
>unionOfFunctionType : (() => string) | (() => number)
var unionOfFunctionType: () => string | number;
>unionOfFunctionType : (() => string) | (() => number)
var unionOfConstructorType: (new () => string) | (new () => number);
>unionOfConstructorType : (new () => string) | (new () => number)
var unionOfConstructorType: { new (): string } | { new (): number };
>unionOfConstructorType : (new () => string) | (new () => number)
var unionOfConstructorType: new () => string | number;
>unionOfConstructorType : (new () => string) | (new () => number)

View file

@ -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

View file

@ -0,0 +1,2 @@
var [a, b]; // Error, no initializer
var {c, d}; // Error, no initializer

View file

@ -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]);
}

View file

@ -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");

View file

@ -1,8 +0,0 @@
/// <reference path="fourslash.ts" />
////function alpha( {}
/////**/
////function beta() { alpha(); }
////
verify.not.errorExistsAfterMarker();