diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3c0bf39f1fa..699d2f74a64 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12173,9 +12173,6 @@ module ts { function checkGrammarVariableDeclaration(node: VariableDeclaration) { if (node.parent.parent.kind !== SyntaxKind.ForInStatement && node.parent.parent.kind !== SyntaxKind.ForOfStatement) { if (isInAmbientContext(node)) { - 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 let equalsTokenLength = "=".length; diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index cf75467e1c5..3ba1cb0a1a3 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -993,7 +993,18 @@ module ts { } function emitBindingPattern(bindingPattern: BindingPattern) { - emitCommaList(bindingPattern.elements, emitBindingElement); + // Only select non-omitted expression from the bindingPattern's elements. + // We have to do this to avoid emitting trailing commas. + // For example: + // original: var [, c,,] = [ 2,3,4] + // emitted: declare var c: number; // instead of declare var c:number, ; + let elements: Node[] = []; + for (let element of bindingPattern.elements) { + if (element.kind !== SyntaxKind.OmittedExpression){ + elements.push(element); + } + } + emitCommaList(elements, emitBindingElement); } function emitBindingElement(bindingElement: BindingElement) { @@ -1291,7 +1302,10 @@ module ts { write("..."); } if (isBindingPattern(node.name)) { - write("_" + indexOf((node.parent).parameters, node)); + // For bindingPattern, we can't simply writeTextOfNode from the source file + // because we want to omit the initializer and using writeTextOfNode will result in initializer get emitted. + // Therefore, we will have to recursively emit each element in the bindingPattern. + emitBindingPattern(node.name); } else { writeTextOfNode(currentSourceFile, node.name); @@ -1311,41 +1325,46 @@ module ts { } function getParameterDeclarationTypeVisibilityError(symbolAccesibilityResult: SymbolAccessiblityResult): SymbolAccessibilityDiagnostic { - let diagnosticMessage: DiagnosticMessage; + let diagnosticMessage: DiagnosticMessage = getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccesibilityResult); + return diagnosticMessage !== undefined ? { + diagnosticMessage, + errorNode: node, + typeName: node.name + } : undefined; + } + + function getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccesibilityResult: SymbolAccessiblityResult): DiagnosticMessage { switch (node.parent.kind) { case SyntaxKind.Constructor: - diagnosticMessage = symbolAccesibilityResult.errorModuleName ? + return symbolAccesibilityResult.errorModuleName ? symbolAccesibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1; - break; case SyntaxKind.ConstructSignature: // Interfaces cannot have parameter types that cannot be named - diagnosticMessage = symbolAccesibilityResult.errorModuleName ? + return symbolAccesibilityResult.errorModuleName ? Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1; - break; case SyntaxKind.CallSignature: // Interfaces cannot have parameter types that cannot be named - diagnosticMessage = symbolAccesibilityResult.errorModuleName ? + return symbolAccesibilityResult.errorModuleName ? Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1; - break; case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: if (node.parent.flags & NodeFlags.Static) { - diagnosticMessage = symbolAccesibilityResult.errorModuleName ? + return symbolAccesibilityResult.errorModuleName ? symbolAccesibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1; } else if (node.parent.parent.kind === SyntaxKind.ClassDeclaration) { - diagnosticMessage = symbolAccesibilityResult.errorModuleName ? + return symbolAccesibilityResult.errorModuleName ? symbolAccesibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 : @@ -1353,30 +1372,99 @@ module ts { } else { // Interfaces cannot have parameter types that cannot be named - diagnosticMessage = symbolAccesibilityResult.errorModuleName ? + return symbolAccesibilityResult.errorModuleName ? Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1; } - break; case SyntaxKind.FunctionDeclaration: - diagnosticMessage = symbolAccesibilityResult.errorModuleName ? + return symbolAccesibilityResult.errorModuleName ? symbolAccesibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Parameter_0_of_exported_function_has_or_is_using_private_name_1; - break; default: Debug.fail("This is unknown parent for parameter: " + node.parent.kind); } - - return { - diagnosticMessage, - errorNode: node, - typeName: node.name - }; } + + function emitBindingPattern(bindingPattern: BindingPattern) { + // We have to explicitly emit square bracket and bracket because these tokens are not store inside the node. + if (bindingPattern.kind === SyntaxKind.ObjectBindingPattern) { + write("{"); + emitCommaList(bindingPattern.elements, emitBindingElement); + write("}"); + } + else if (bindingPattern.kind === SyntaxKind.ArrayBindingPattern) { + write("["); + let elements = bindingPattern.elements; + emitCommaList(elements, emitBindingElement); + if (elements && elements.hasTrailingComma) { + write(", "); + } + write("]"); + } + } + + function emitBindingElement(bindingElement: BindingElement) { + function getBindingElementTypeVisibilityError(symbolAccesibilityResult: SymbolAccessiblityResult): SymbolAccessibilityDiagnostic { + let diagnosticMessage = getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccesibilityResult); + return diagnosticMessage !== undefined ? { + diagnosticMessage, + errorNode: bindingElement, + typeName: bindingElement.name + } : undefined; + } + + if (bindingElement.kind === SyntaxKind.OmittedExpression) { + // If bindingElement is an omittedExpression (i.e. containing elision), + // we will emit blank space (although this may differ from users' original code, + // it allows emitSeparatedList to write separator appropriately) + // Example: + // original: function foo([, x, ,]) {} + // emit : function foo([ , x, , ]) {} + write(" "); + } + else if (bindingElement.kind === SyntaxKind.BindingElement) { + if (bindingElement.propertyName) { + // bindingElement has propertyName property in the following case: + // { y: [a,b,c] ...} -> bindingPattern will have a property called propertyName for "y" + // We have to explicitly emit the propertyName before descending into its binding elements. + // Example: + // original: function foo({y: [a,b,c]}) {} + // emit : declare function foo({y: [a, b, c]}: { y: [any, any, any] }) void; + writeTextOfNode(currentSourceFile, bindingElement.propertyName); + write(": "); + + // If bindingElement has propertyName property, then its name must be another bindingPattern of SyntaxKind.ObjectBindingPattern + emitBindingPattern(bindingElement.name); + } + else if (bindingElement.name) { + if (isBindingPattern(bindingElement.name)) { + // If it is a nested binding pattern, we will recursively descend into each element and emit each one separately. + // In the case of rest element, we will omit rest element. + // Example: + // original: function foo([a, [[b]], c] = [1,[["string"]], 3]) {} + // emit : declare function foo([a, [[b]], c]: [number, [[string]], number]): void; + // original with rest: function foo([a, ...c]) {} + // emit : declare function foo([a, ...c]): void; + emitBindingPattern(bindingElement.name); + } + else { + Debug.assert(bindingElement.name.kind === SyntaxKind.Identifier); + // If the node is just an identifier, we will simply emit the text associated with the node's name + // Example: + // original: function foo({y = 10, x}) {} + // emit : declare function foo({y, x}: {number, any}): void; + if (bindingElement.dotDotDotToken) { + write("..."); + } + writeTextOfNode(currentSourceFile, bindingElement.name); + } + } + } + } } function emitNode(node: Node) { diff --git a/tests/baselines/reference/declarationEmitDestructuring1.js b/tests/baselines/reference/declarationEmitDestructuring1.js new file mode 100644 index 00000000000..9ac08032a0d --- /dev/null +++ b/tests/baselines/reference/declarationEmitDestructuring1.js @@ -0,0 +1,37 @@ +//// [declarationEmitDestructuring1.ts] +function foo([a, b, c]: [string, string, string]): void { } +function far([a, [b], [[c]]]: [number, boolean[], string[][]]): void { } +function bar({a1, b1, c1}: { a1: number, b1: boolean, c1: string }): void { } +function baz({a2, b2: {b1, c1}}: { a2: number, b2: { b1: boolean, c1: string } }): void { } + + +//// [declarationEmitDestructuring1.js] +function foo(_a) { + var a = _a[0], b = _a[1], c = _a[2]; +} +function far(_a) { + var a = _a[0], b = _a[1][0], c = _a[2][0][0]; +} +function bar(_a) { + var a1 = _a.a1, b1 = _a.b1, c1 = _a.c1; +} +function baz(_a) { + var a2 = _a.a2, _b = _a.b2, b1 = _b.b1, c1 = _b.c1; +} + + +//// [declarationEmitDestructuring1.d.ts] +declare function foo([a, b, c]: [string, string, string]): void; +declare function far([a, [b], [[c]]]: [number, boolean[], string[][]]): void; +declare function bar({a1, b1, c1}: { + a1: number; + b1: boolean; + c1: string; +}): void; +declare function baz({a2, b2: {b1, c1}}: { + a2: number; + b2: { + b1: boolean; + c1: string; + }; +}): void; diff --git a/tests/baselines/reference/declarationEmitDestructuring1.types b/tests/baselines/reference/declarationEmitDestructuring1.types new file mode 100644 index 00000000000..6b22f25b54b --- /dev/null +++ b/tests/baselines/reference/declarationEmitDestructuring1.types @@ -0,0 +1,33 @@ +=== tests/cases/compiler/declarationEmitDestructuring1.ts === +function foo([a, b, c]: [string, string, string]): void { } +>foo : ([a, b, c]: [string, string, string]) => void +>a : string +>b : string +>c : string + +function far([a, [b], [[c]]]: [number, boolean[], string[][]]): void { } +>far : ([a, [b], [[c]]]: [number, boolean[], string[][]]) => void +>a : number +>b : boolean +>c : string + +function bar({a1, b1, c1}: { a1: number, b1: boolean, c1: string }): void { } +>bar : ({a1, b1, c1}: { a1: number; b1: boolean; c1: string; }) => void +>a1 : number +>b1 : boolean +>c1 : string +>a1 : number +>b1 : boolean +>c1 : string + +function baz({a2, b2: {b1, c1}}: { a2: number, b2: { b1: boolean, c1: string } }): void { } +>baz : ({a2, b2: {b1, c1}}: { a2: number; b2: { b1: boolean; c1: string; }; }) => void +>a2 : number +>b2 : unknown +>b1 : boolean +>c1 : string +>a2 : number +>b2 : { b1: boolean; c1: string; } +>b1 : boolean +>c1 : string + diff --git a/tests/baselines/reference/declarationEmitDestructuring2.js b/tests/baselines/reference/declarationEmitDestructuring2.js new file mode 100644 index 00000000000..eeabbf1ff37 --- /dev/null +++ b/tests/baselines/reference/declarationEmitDestructuring2.js @@ -0,0 +1,43 @@ +//// [declarationEmitDestructuring2.ts] +function f({x = 10, y: [a, b, c, d] = [1, 2, 3, 4]} = { x: 10, y: [2, 4, 6, 8] }) { } +function g([a, b, c, d] = [1, 2, 3, 4]) { } +function h([a, [b], [[c]], {x = 10, y: [a, b, c], z: {a1, b1}}]){ } +function h1([a, [b], [[c]], {x = 10, y = [1, 2, 3], z: {a1, b1}}]){ } + +//// [declarationEmitDestructuring2.js] +function f(_a) { + var _b = _a === void 0 ? { x: 10, y: [2, 4, 6, 8] } : _a, _c = _b.x, x = _c === void 0 ? 10 : _c, _d = _b.y, _e = _d === void 0 ? [1, 2, 3, 4] : _d, a = _e[0], b = _e[1], c = _e[2], d = _e[3]; +} +function g(_a) { + var _b = _a === void 0 ? [1, 2, 3, 4] : _a, a = _b[0], b = _b[1], c = _b[2], d = _b[3]; +} +function h(_a) { + var a = _a[0], b = _a[1][0], c = _a[2][0][0], _b = _a[3], _c = _b.x, x = _c === void 0 ? 10 : _c, _d = _b.y, a = _d[0], b = _d[1], c = _d[2], _e = _b.z, a1 = _e.a1, b1 = _e.b1; +} +function h1(_a) { + var a = _a[0], b = _a[1][0], c = _a[2][0][0], _b = _a[3], _c = _b.x, x = _c === void 0 ? 10 : _c, _d = _b.y, y = _d === void 0 ? [1, 2, 3] : _d, _e = _b.z, a1 = _e.a1, b1 = _e.b1; +} + + +//// [declarationEmitDestructuring2.d.ts] +declare function f({x, y: [a, b, c, d]}?: { + x: number; + y: [number, number, number, number]; +}): void; +declare function g([a, b, c, d]?: [number, number, number, number]): void; +declare function h([a, [b], [[c]], {x, y: [a, b, c], z: {a1, b1}}]: [any, [any], [[any]], { + x?: number; + y: [any, any, any]; + z: { + a1: any; + b1: any; + }; +}]): void; +declare function h1([a, [b], [[c]], {x, y, z: {a1, b1}}]: [any, [any], [[any]], { + x?: number; + y?: number[]; + z: { + a1: any; + b1: any; + }; +}]): void; diff --git a/tests/baselines/reference/declarationEmitDestructuring2.types b/tests/baselines/reference/declarationEmitDestructuring2.types new file mode 100644 index 00000000000..3368d4e72fd --- /dev/null +++ b/tests/baselines/reference/declarationEmitDestructuring2.types @@ -0,0 +1,49 @@ +=== tests/cases/compiler/declarationEmitDestructuring2.ts === +function f({x = 10, y: [a, b, c, d] = [1, 2, 3, 4]} = { x: 10, y: [2, 4, 6, 8] }) { } +>f : ({x = 10, y: [a, b, c, d] = [1, 2, 3, 4]}?: { x: number; y: [number, number, number, number]; }) => void +>x : number +>y : unknown +>a : number +>b : number +>c : number +>d : number +>[1, 2, 3, 4] : [number, number, number, number] +>{ x: 10, y: [2, 4, 6, 8] } : { x: number; y: [number, number, number, number]; } +>x : number +>y : [number, number, number, number] +>[2, 4, 6, 8] : [number, number, number, number] + +function g([a, b, c, d] = [1, 2, 3, 4]) { } +>g : ([a, b, c, d]?: [number, number, number, number]) => void +>a : number +>b : number +>c : number +>d : number +>[1, 2, 3, 4] : [number, number, number, number] + +function h([a, [b], [[c]], {x = 10, y: [a, b, c], z: {a1, b1}}]){ } +>h : ([a, [b], [[c]], {x = 10, y: [a, b, c], z: {a1, b1}}]: [any, [any], [[any]], { x?: number; y: [any, any, any]; z: { a1: any; b1: any; }; }]) => void +>a : any +>b : any +>c : any +>x : number +>y : unknown +>a : any +>b : any +>c : any +>z : unknown +>a1 : any +>b1 : any + +function h1([a, [b], [[c]], {x = 10, y = [1, 2, 3], z: {a1, b1}}]){ } +>h1 : ([a, [b], [[c]], {x = 10, y = [1, 2, 3], z: {a1, b1}}]: [any, [any], [[any]], { x?: number; y?: number[]; z: { a1: any; b1: any; }; }]) => void +>a : any +>b : any +>c : any +>x : number +>y : number[] +>[1, 2, 3] : number[] +>z : unknown +>a1 : any +>b1 : any + diff --git a/tests/baselines/reference/declarationEmitDestructuring3.js b/tests/baselines/reference/declarationEmitDestructuring3.js new file mode 100644 index 00000000000..b21c63203c8 --- /dev/null +++ b/tests/baselines/reference/declarationEmitDestructuring3.js @@ -0,0 +1,18 @@ +//// [declarationEmitDestructuring3.ts] +function bar([x, z, ...w]) { } +function foo([x, ...y] = [1, "string", true]) { } + + + +//// [declarationEmitDestructuring3.js] +function bar(_a) { + var x = _a[0], z = _a[1], w = _a.slice(2); +} +function foo(_a) { + var _b = _a === void 0 ? [1, "string", true] : _a, x = _b[0], y = _b.slice(1); +} + + +//// [declarationEmitDestructuring3.d.ts] +declare function bar([x, z, ...w]: any[]): void; +declare function foo([x, ...y]?: (string | number | boolean)[]): void; diff --git a/tests/baselines/reference/declarationEmitDestructuring3.types b/tests/baselines/reference/declarationEmitDestructuring3.types new file mode 100644 index 00000000000..57764f53eee --- /dev/null +++ b/tests/baselines/reference/declarationEmitDestructuring3.types @@ -0,0 +1,14 @@ +=== tests/cases/compiler/declarationEmitDestructuring3.ts === +function bar([x, z, ...w]) { } +>bar : ([x, z, ...w]: any[]) => void +>x : any +>z : any +>w : any[] + +function foo([x, ...y] = [1, "string", true]) { } +>foo : ([x, ...y]?: (string | number | boolean)[]) => void +>x : string | number | boolean +>y : (string | number | boolean)[] +>[1, "string", true] : (string | number | boolean)[] + + diff --git a/tests/baselines/reference/declarationEmitDestructuring4.js b/tests/baselines/reference/declarationEmitDestructuring4.js new file mode 100644 index 00000000000..f5d9df09175 --- /dev/null +++ b/tests/baselines/reference/declarationEmitDestructuring4.js @@ -0,0 +1,42 @@ +//// [declarationEmitDestructuring4.ts] +// For an array binding pattern with empty elements, +// we will not make any modification and will emit +// the similar binding pattern users' have written +function baz([]) { } +function baz1([] = [1,2,3]) { } +function baz2([[]] = [[1,2,3]]) { } + +function baz3({}) { } +function baz4({} = { x: 10 }) { } + + + +//// [declarationEmitDestructuring4.js] +// For an array binding pattern with empty elements, +// we will not make any modification and will emit +// the similar binding pattern users' have written +function baz(_a) { + var ; +} +function baz1(_a) { + var _b = _a === void 0 ? [1, 2, 3] : _a; +} +function baz2(_a) { + var _b = (_a === void 0 ? [[1, 2, 3]] : _a)[0]; +} +function baz3(_a) { + var ; +} +function baz4(_a) { + var _b = _a === void 0 ? { x: 10 } : _a; +} + + +//// [declarationEmitDestructuring4.d.ts] +declare function baz([]: any[]): void; +declare function baz1([]?: number[]): void; +declare function baz2([[]]?: [number[]]): void; +declare function baz3({}: {}): void; +declare function baz4({}?: { + x: number; +}): void; diff --git a/tests/baselines/reference/declarationEmitDestructuring4.types b/tests/baselines/reference/declarationEmitDestructuring4.types new file mode 100644 index 00000000000..6a90eda1702 --- /dev/null +++ b/tests/baselines/reference/declarationEmitDestructuring4.types @@ -0,0 +1,25 @@ +=== tests/cases/compiler/declarationEmitDestructuring4.ts === +// For an array binding pattern with empty elements, +// we will not make any modification and will emit +// the similar binding pattern users' have written +function baz([]) { } +>baz : ([]: any[]) => void + +function baz1([] = [1,2,3]) { } +>baz1 : ([]?: number[]) => void +>[1,2,3] : number[] + +function baz2([[]] = [[1,2,3]]) { } +>baz2 : ([[]]?: [number[]]) => void +>[[1,2,3]] : [number[]] +>[1,2,3] : number[] + +function baz3({}) { } +>baz3 : ({}: {}) => void + +function baz4({} = { x: 10 }) { } +>baz4 : ({}?: { x: number; }) => void +>{ x: 10 } : { x: number; } +>x : number + + diff --git a/tests/baselines/reference/declarationEmitDestructuring5.js b/tests/baselines/reference/declarationEmitDestructuring5.js new file mode 100644 index 00000000000..32c9b5667d1 --- /dev/null +++ b/tests/baselines/reference/declarationEmitDestructuring5.js @@ -0,0 +1,31 @@ +//// [declarationEmitDestructuring5.ts] +function baz([, z, , ]) { } +function foo([, b, ]: [any, any]): void { } +function bar([z, , , ]) { } +function bar1([z, , , ] = [1, 3, 4, 6, 7]) { } +function bar2([,,z, , , ]) { } + +//// [declarationEmitDestructuring5.js] +function baz(_a) { + var z = _a[1]; +} +function foo(_a) { + var b = _a[1]; +} +function bar(_a) { + var z = _a[0]; +} +function bar1(_a) { + var _b = _a === void 0 ? [1, 3, 4, 6, 7] : _a, z = _b[0]; +} +function bar2(_a) { + var z = _a[2]; +} + + +//// [declarationEmitDestructuring5.d.ts] +declare function baz([ , z, , ]: [any, any, any]): void; +declare function foo([ , b, ]: [any, any]): void; +declare function bar([z, , , ]: [any, any, any]): void; +declare function bar1([z, , , ]?: [number, number, number, number, number]): void; +declare function bar2([ , , z, , , ]: [any, any, any, any, any]): void; diff --git a/tests/baselines/reference/declarationEmitDestructuring5.types b/tests/baselines/reference/declarationEmitDestructuring5.types new file mode 100644 index 00000000000..375440bea0b --- /dev/null +++ b/tests/baselines/reference/declarationEmitDestructuring5.types @@ -0,0 +1,22 @@ +=== tests/cases/compiler/declarationEmitDestructuring5.ts === +function baz([, z, , ]) { } +>baz : ([, z, , ]: [any, any, any]) => void +>z : any + +function foo([, b, ]: [any, any]): void { } +>foo : ([, b, ]: [any, any]) => void +>b : any + +function bar([z, , , ]) { } +>bar : ([z, , , ]: [any, any, any]) => void +>z : any + +function bar1([z, , , ] = [1, 3, 4, 6, 7]) { } +>bar1 : ([z, , , ]?: [number, number, number, number, number]) => void +>z : number +>[1, 3, 4, 6, 7] : [number, number, number, number, number] + +function bar2([,,z, , , ]) { } +>bar2 : ([,,z, , , ]: [any, any, any, any, any]) => void +>z : any + diff --git a/tests/baselines/reference/declarationEmitDestructuringArrayPattern5.js b/tests/baselines/reference/declarationEmitDestructuringArrayPattern5.js new file mode 100644 index 00000000000..820864cc25a --- /dev/null +++ b/tests/baselines/reference/declarationEmitDestructuringArrayPattern5.js @@ -0,0 +1,15 @@ +//// [declarationEmitDestructuringArrayPattern5.ts] +var [, , z] = [1, 2, 4]; +var [, a, , ] = [3, 4, 5]; +var [, , [, b, ]] = [3,5,[0, 1]]; + +//// [declarationEmitDestructuringArrayPattern5.js] +var _a = [1, 2, 4], z = _a[2]; +var _b = [3, 4, 5], a = _b[1]; +var _c = [3, 5, [0, 1]], _d = _c[2], b = _d[1]; + + +//// [declarationEmitDestructuringArrayPattern5.d.ts] +declare var z: number; +declare var a: number; +declare var b: number; diff --git a/tests/baselines/reference/declarationEmitDestructuringArrayPattern5.types b/tests/baselines/reference/declarationEmitDestructuringArrayPattern5.types new file mode 100644 index 00000000000..6352917682e --- /dev/null +++ b/tests/baselines/reference/declarationEmitDestructuringArrayPattern5.types @@ -0,0 +1,14 @@ +=== tests/cases/compiler/declarationEmitDestructuringArrayPattern5.ts === +var [, , z] = [1, 2, 4]; +>z : number +>[1, 2, 4] : [number, number, number] + +var [, a, , ] = [3, 4, 5]; +>a : number +>[3, 4, 5] : [number, number, number] + +var [, , [, b, ]] = [3,5,[0, 1]]; +>b : number +>[3,5,[0, 1]] : [number, number, [number, number]] +>[0, 1] : [number, number] + diff --git a/tests/baselines/reference/declarationEmitDestructuringOptionalBindingParametersInOverloads.js b/tests/baselines/reference/declarationEmitDestructuringOptionalBindingParametersInOverloads.js index c907add11f7..a3cdee31222 100644 --- a/tests/baselines/reference/declarationEmitDestructuringOptionalBindingParametersInOverloads.js +++ b/tests/baselines/reference/declarationEmitDestructuringOptionalBindingParametersInOverloads.js @@ -25,8 +25,8 @@ function foo2() { //// [declarationEmitDestructuringOptionalBindingParametersInOverloads.d.ts] -declare function foo(_0?: [string, number, boolean]): any; -declare function foo2(_0?: { +declare function foo([x, y, z]?: [string, number, boolean]): any; +declare function foo2({x, y, z}?: { x: string; y: number; z: boolean; diff --git a/tests/baselines/reference/declarationEmitDestructuringParameterProperties.js b/tests/baselines/reference/declarationEmitDestructuringParameterProperties.js index cfe4acc1733..a98620c8529 100644 --- a/tests/baselines/reference/declarationEmitDestructuringParameterProperties.js +++ b/tests/baselines/reference/declarationEmitDestructuringParameterProperties.js @@ -43,12 +43,12 @@ var C3 = (function () { //// [declarationEmitDestructuringParameterProperties.d.ts] declare class C1 { x: string, y: string, z: string; - constructor(_0: string[]); + constructor([x, y, z]: string[]); } declare type TupleType1 = [string, number, boolean]; declare class C2 { x: string, y: number, z: boolean; - constructor(_0: TupleType1); + constructor([x, y, z]: TupleType1); } declare type ObjType1 = { x: number; @@ -57,5 +57,5 @@ declare type ObjType1 = { }; declare class C3 { x: number, y: string, z: boolean; - constructor(_0: ObjType1); + constructor({x, y, z}: ObjType1); } diff --git a/tests/baselines/reference/declarationEmitDestructuringWithOptionalBindingParameters.js b/tests/baselines/reference/declarationEmitDestructuringWithOptionalBindingParameters.js index 284cf107782..5c7f4d2cec5 100644 --- a/tests/baselines/reference/declarationEmitDestructuringWithOptionalBindingParameters.js +++ b/tests/baselines/reference/declarationEmitDestructuringWithOptionalBindingParameters.js @@ -14,8 +14,8 @@ function foo1(_a) { //// [declarationEmitDestructuringWithOptionalBindingParameters.d.ts] -declare function foo(_0?: [string, number, boolean]): void; -declare function foo1(_0?: { +declare function foo([x, y, z]?: [string, number, boolean]): void; +declare function foo1({x, y, z}?: { x: string; y: number; z: boolean; diff --git a/tests/baselines/reference/declarationInAmbientContext.errors.txt b/tests/baselines/reference/declarationInAmbientContext.errors.txt deleted file mode 100644 index 338da990a0b..00000000000 --- a/tests/baselines/reference/declarationInAmbientContext.errors.txt +++ /dev/null @@ -1,12 +0,0 @@ -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. - \ No newline at end of file diff --git a/tests/baselines/reference/declarationInAmbientContext.types b/tests/baselines/reference/declarationInAmbientContext.types new file mode 100644 index 00000000000..ecdd3b7c7eb --- /dev/null +++ b/tests/baselines/reference/declarationInAmbientContext.types @@ -0,0 +1,9 @@ +=== tests/cases/conformance/es6/destructuring/declarationInAmbientContext.ts === +declare var [a, b]; // Error, destructuring declaration not allowed in ambient context +>a : any +>b : any + +declare var {c, d}; // Error, destructuring declaration not allowed in ambient context +>c : any +>d : any + diff --git a/tests/cases/compiler/declarationEmitDestructuring1.ts b/tests/cases/compiler/declarationEmitDestructuring1.ts new file mode 100644 index 00000000000..c610e24f933 --- /dev/null +++ b/tests/cases/compiler/declarationEmitDestructuring1.ts @@ -0,0 +1,5 @@ +// @declaration: true +function foo([a, b, c]: [string, string, string]): void { } +function far([a, [b], [[c]]]: [number, boolean[], string[][]]): void { } +function bar({a1, b1, c1}: { a1: number, b1: boolean, c1: string }): void { } +function baz({a2, b2: {b1, c1}}: { a2: number, b2: { b1: boolean, c1: string } }): void { } diff --git a/tests/cases/compiler/declarationEmitDestructuring2.ts b/tests/cases/compiler/declarationEmitDestructuring2.ts new file mode 100644 index 00000000000..34441cd6c7b --- /dev/null +++ b/tests/cases/compiler/declarationEmitDestructuring2.ts @@ -0,0 +1,5 @@ +// @declaration: true +function f({x = 10, y: [a, b, c, d] = [1, 2, 3, 4]} = { x: 10, y: [2, 4, 6, 8] }) { } +function g([a, b, c, d] = [1, 2, 3, 4]) { } +function h([a, [b], [[c]], {x = 10, y: [a, b, c], z: {a1, b1}}]){ } +function h1([a, [b], [[c]], {x = 10, y = [1, 2, 3], z: {a1, b1}}]){ } \ No newline at end of file diff --git a/tests/cases/compiler/declarationEmitDestructuring3.ts b/tests/cases/compiler/declarationEmitDestructuring3.ts new file mode 100644 index 00000000000..78aeddb0e11 --- /dev/null +++ b/tests/cases/compiler/declarationEmitDestructuring3.ts @@ -0,0 +1,4 @@ +// @declaration: true +function bar([x, z, ...w]) { } +function foo([x, ...y] = [1, "string", true]) { } + diff --git a/tests/cases/compiler/declarationEmitDestructuring4.ts b/tests/cases/compiler/declarationEmitDestructuring4.ts new file mode 100644 index 00000000000..bd1a57af12e --- /dev/null +++ b/tests/cases/compiler/declarationEmitDestructuring4.ts @@ -0,0 +1,11 @@ +// @declaration: true +// For an array binding pattern with empty elements, +// we will not make any modification and will emit +// the similar binding pattern users' have written +function baz([]) { } +function baz1([] = [1,2,3]) { } +function baz2([[]] = [[1,2,3]]) { } + +function baz3({}) { } +function baz4({} = { x: 10 }) { } + diff --git a/tests/cases/compiler/declarationEmitDestructuring5.ts b/tests/cases/compiler/declarationEmitDestructuring5.ts new file mode 100644 index 00000000000..a02a21b5a50 --- /dev/null +++ b/tests/cases/compiler/declarationEmitDestructuring5.ts @@ -0,0 +1,6 @@ +// @declaration: true +function baz([, z, , ]) { } +function foo([, b, ]: [any, any]): void { } +function bar([z, , , ]) { } +function bar1([z, , , ] = [1, 3, 4, 6, 7]) { } +function bar2([,,z, , , ]) { } \ No newline at end of file diff --git a/tests/cases/compiler/declarationEmitDestructuringArrayPattern5.ts b/tests/cases/compiler/declarationEmitDestructuringArrayPattern5.ts new file mode 100644 index 00000000000..eeb5dd4bdca --- /dev/null +++ b/tests/cases/compiler/declarationEmitDestructuringArrayPattern5.ts @@ -0,0 +1,4 @@ +// @declaration: true +var [, , z] = [1, 2, 4]; +var [, a, , ] = [3, 4, 5]; +var [, , [, b, ]] = [3,5,[0, 1]]; \ No newline at end of file