Merge pull request #14090 from Microsoft/es5-emit-param-initialiser-before-object-rest

ES5:Emit parameter initialiser before object rest destructuring
This commit is contained in:
Nathan Shively-Sanders
2017-04-13 13:43:13 -07:00
committed by GitHub
21 changed files with 558 additions and 20 deletions

View File

@@ -3058,7 +3058,18 @@ namespace ts {
* @param ensureUseStrict: boolean determining whether the function need to add prologue-directives
* @param visitor: Optional callback used to visit any custom prologue directives.
*/
export function addPrologueDirectives(target: Statement[], source: Statement[], ensureUseStrict?: boolean, visitor?: (node: Node) => VisitResult<Node>): number {
export function addPrologue(target: Statement[], source: Statement[], ensureUseStrict?: boolean, visitor?: (node: Node) => VisitResult<Node>): number {
const offset = addStandardPrologue(target, source, ensureUseStrict);
return addCustomPrologue(target, source, offset, visitor);
}
/**
* Add just the standard (string-expression) prologue-directives into target statement-array.
* The function needs to be called during each transformation step.
* This function needs to be called whenever we transform the statement
* list of a source file, namespace, or function-like body.
*/
export function addStandardPrologue(target: Statement[], source: Statement[], ensureUseStrict?: boolean): number {
Debug.assert(target.length === 0, "Prologue directives should be at the first statement in the target statements array");
let foundUseStrict = false;
let statementOffset = 0;
@@ -3066,7 +3077,7 @@ namespace ts {
while (statementOffset < numStatements) {
const statement = source[statementOffset];
if (isPrologueDirective(statement)) {
if (isUseStrictPrologue(statement as ExpressionStatement)) {
if (isUseStrictPrologue(statement)) {
foundUseStrict = true;
}
target.push(statement);
@@ -3079,6 +3090,17 @@ namespace ts {
if (ensureUseStrict && !foundUseStrict) {
target.push(startOnNewLine(createStatement(createLiteral("use strict"))));
}
return statementOffset;
}
/**
* Add just the custom prologue-directives into target statement-array.
* The function needs to be called during each transformation step.
* This function needs to be called whenever we transform the statement
* list of a source file, namespace, or function-like body.
*/
export function addCustomPrologue(target: Statement[], source: Statement[], statementOffset: number, visitor?: (node: Node) => VisitResult<Node>): number {
const numStatements = source.length;
while (statementOffset < numStatements) {
const statement = source[statementOffset];
if (getEmitFlags(statement) & EmitFlags.CustomPrologue) {

View File

@@ -515,8 +515,9 @@ namespace ts {
const ancestorFacts = enterSubtree(HierarchyFacts.SourceFileExcludes, HierarchyFacts.SourceFileIncludes);
const statements: Statement[] = [];
startLexicalEnvironment();
const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ false, visitor);
let statementOffset = addStandardPrologue(statements, node.statements, /*ensureUseStrict*/ false);
addCaptureThisForNodeIfNeeded(statements, node);
statementOffset = addCustomPrologue(statements, node.statements, statementOffset, visitor);
addRange(statements, visitNodes(node.statements, visitor, isStatement, statementOffset));
addRange(statements, endLexicalEnvironment());
exitSubtree(ancestorFacts, HierarchyFacts.None, HierarchyFacts.None);
@@ -924,13 +925,16 @@ namespace ts {
statementOffset = 0;
}
else if (constructor) {
// Otherwise, try to emit all potential prologue directives first.
statementOffset = addPrologueDirectives(statements, constructor.body.statements, /*ensureUseStrict*/ false, visitor);
statementOffset = addStandardPrologue(statements, constructor.body.statements, /*ensureUseStrict*/ false);
}
if (constructor) {
addDefaultValueAssignmentsIfNeeded(statements, constructor);
addRestParameterIfNeeded(statements, constructor, hasSynthesizedSuper);
if (!hasSynthesizedSuper) {
// If no super call has been synthesized, emit custom prologue directives.
statementOffset = addCustomPrologue(statements, constructor.body.statements, statementOffset, visitor);
}
Debug.assert(statementOffset >= 0, "statementOffset not initialized correctly!");
}
@@ -1821,8 +1825,8 @@ namespace ts {
resumeLexicalEnvironment();
if (isBlock(body)) {
// ensureUseStrict is false because no new prologue-directive should be added.
// addPrologueDirectives will simply put already-existing directives at the beginning of the target statement-array
statementOffset = addPrologueDirectives(statements, body.statements, /*ensureUseStrict*/ false, visitor);
// addStandardPrologue will put already-existing directives at the beginning of the target statement-array
statementOffset = addStandardPrologue(statements, body.statements, /*ensureUseStrict*/ false);
}
addCaptureThisForNodeIfNeeded(statements, node);
@@ -1835,6 +1839,9 @@ namespace ts {
}
if (isBlock(body)) {
// addCustomPrologue puts already-existing directives at the beginning of the target statement-array
statementOffset = addCustomPrologue(statements, body.statements, statementOffset, visitor);
statementsLocation = body.statements;
addRange(statements, visitNodes(body.statements, visitor, isStatement, statementOffset));

View File

@@ -222,7 +222,7 @@ namespace ts {
if (!isArrowFunction) {
const statements: Statement[] = [];
const statementOffset = addPrologueDirectives(statements, (<Block>node.body).statements, /*ensureUseStrict*/ false, visitor);
const statementOffset = addPrologue(statements, (<Block>node.body).statements, /*ensureUseStrict*/ false, visitor);
statements.push(
createReturn(
createAwaiterHelper(

View File

@@ -618,7 +618,7 @@ namespace ts {
function transformAsyncGeneratorFunctionBody(node: MethodDeclaration | AccessorDeclaration | FunctionDeclaration | FunctionExpression): FunctionBody {
resumeLexicalEnvironment();
const statements: Statement[] = [];
const statementOffset = addPrologueDirectives(statements, node.body.statements, /*ensureUseStrict*/ false, visitor);
const statementOffset = addPrologue(statements, node.body.statements, /*ensureUseStrict*/ false, visitor);
appendObjectRestAssignmentsIfNeeded(statements, node);
statements.push(
@@ -663,12 +663,19 @@ namespace ts {
function transformFunctionBody(node: ArrowFunction): ConciseBody;
function transformFunctionBody(node: FunctionLikeDeclaration): ConciseBody {
resumeLexicalEnvironment();
const leadingStatements = appendObjectRestAssignmentsIfNeeded(/*statements*/ undefined, node);
let statementOffset = 0;
const statements: Statement[] = [];
const body = visitNode(node.body, visitor, isConciseBody);
if (isBlock(body)) {
statementOffset = addPrologue(statements, body.statements, /*ensureUseStrict*/ false, visitor);
}
addRange(statements, appendObjectRestAssignmentsIfNeeded(/*statements*/ undefined, node));
const trailingStatements = endLexicalEnvironment();
if (some(leadingStatements) || some(trailingStatements)) {
if (statementOffset > 0 || some(statements) || some(trailingStatements)) {
const block = convertToFunctionBody(body, /*multiLine*/ true);
return updateBlock(block, setTextRange(createNodeArray(concatenate(concatenate(leadingStatements, block.statements), trailingStatements)), block.statements));
addRange(statements, block.statements.slice(statementOffset));
addRange(statements, trailingStatements);
return updateBlock(block, setTextRange(createNodeArray(statements), block.statements));
}
return body;
}

View File

@@ -587,7 +587,7 @@ namespace ts {
// Build the generator
resumeLexicalEnvironment();
const statementOffset = addPrologueDirectives(statements, body.statements, /*ensureUseStrict*/ false, visitor);
const statementOffset = addPrologue(statements, body.statements, /*ensureUseStrict*/ false, visitor);
transformAndEmitStatements(body.statements, statementOffset);

View File

@@ -24,7 +24,7 @@ namespace ts {
const externalHelpersModuleName = getOrCreateExternalHelpersModuleNameIfNeeded(node, compilerOptions);
if (externalHelpersModuleName) {
const statements: Statement[] = [];
const statementOffset = addPrologueDirectives(statements, node.statements);
const statementOffset = addPrologue(statements, node.statements);
append(statements,
createImportDeclaration(
/*decorators*/ undefined,

View File

@@ -90,7 +90,7 @@ namespace ts {
const statements: Statement[] = [];
const ensureUseStrict = compilerOptions.alwaysStrict || (!compilerOptions.noImplicitUseStrict && isExternalModule(currentSourceFile));
const statementOffset = addPrologueDirectives(statements, node.statements, ensureUseStrict, sourceElementVisitor);
const statementOffset = addPrologue(statements, node.statements, ensureUseStrict, sourceElementVisitor);
if (shouldEmitUnderscoreUnderscoreESModule()) {
append(statements, createUnderscoreUnderscoreESModule());
@@ -388,7 +388,7 @@ namespace ts {
startLexicalEnvironment();
const statements: Statement[] = [];
const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, sourceElementVisitor);
const statementOffset = addPrologue(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, sourceElementVisitor);
if (shouldEmitUnderscoreUnderscoreESModule()) {
append(statements, createUnderscoreUnderscoreESModule());

View File

@@ -228,7 +228,7 @@ namespace ts {
// Add any prologue directives.
const ensureUseStrict = compilerOptions.alwaysStrict || (!compilerOptions.noImplicitUseStrict && isExternalModule(currentSourceFile));
const statementOffset = addPrologueDirectives(statements, node.statements, ensureUseStrict, sourceElementVisitor);
const statementOffset = addPrologue(statements, node.statements, ensureUseStrict, sourceElementVisitor);
// var __moduleName = context_1 && context_1.id;
statements.push(

View File

@@ -954,7 +954,7 @@ namespace ts {
if (ctor.body) {
const statements = ctor.body.statements;
// add prologue directives to the list (if any)
const index = addPrologueDirectives(result, statements, /*ensureUseStrict*/ false, visitor);
const index = addPrologue(result, statements, /*ensureUseStrict*/ false, visitor);
if (index === statements.length) {
// list contains nothing but prologue directives (or empty) - exit
return index;

View File

@@ -14,7 +14,11 @@ class C {
// actually, never mind, don't clone
}
}
function foobar({ bar={}, ...opts }: any = {}) {
}
foobar();
foobar({ baz: 'hello' });
foobar({ bar: { greeting: 'hello' } });
//// [objectRestParameter.js]
@@ -48,3 +52,9 @@ class C {
// actually, never mind, don't clone
}
}
function foobar(_a = {}) {
var { bar = {} } = _a, opts = __rest(_a, ["bar"]);
}
foobar();
foobar({ baz: 'hello' });
foobar({ bar: { greeting: 'hello' } });

View File

@@ -64,5 +64,20 @@ class C {
// actually, never mind, don't clone
}
}
function foobar({ bar={}, ...opts }: any = {}) {
>foobar : Symbol(foobar, Decl(objectRestParameter.ts, 14, 1))
>bar : Symbol(bar, Decl(objectRestParameter.ts, 15, 17))
>opts : Symbol(opts, Decl(objectRestParameter.ts, 15, 25))
}
foobar();
>foobar : Symbol(foobar, Decl(objectRestParameter.ts, 14, 1))
foobar({ baz: 'hello' });
>foobar : Symbol(foobar, Decl(objectRestParameter.ts, 14, 1))
>baz : Symbol(baz, Decl(objectRestParameter.ts, 18, 8))
foobar({ bar: { greeting: 'hello' } });
>foobar : Symbol(foobar, Decl(objectRestParameter.ts, 14, 1))
>bar : Symbol(bar, Decl(objectRestParameter.ts, 19, 8))
>greeting : Symbol(greeting, Decl(objectRestParameter.ts, 19, 15))

View File

@@ -75,5 +75,30 @@ class C {
// actually, never mind, don't clone
}
}
function foobar({ bar={}, ...opts }: any = {}) {
>foobar : ({bar, ...opts}?: any) => void
>bar : {}
>{} : {}
>opts : any
>{} : {}
}
foobar();
>foobar() : void
>foobar : ({bar, ...opts}?: any) => void
foobar({ baz: 'hello' });
>foobar({ baz: 'hello' }) : void
>foobar : ({bar, ...opts}?: any) => void
>{ baz: 'hello' } : { baz: string; }
>baz : string
>'hello' : "hello"
foobar({ bar: { greeting: 'hello' } });
>foobar({ bar: { greeting: 'hello' } }) : void
>foobar : ({bar, ...opts}?: any) => void
>{ bar: { greeting: 'hello' } } : { bar: { greeting: string; }; }
>bar : { greeting: string; }
>{ greeting: 'hello' } : { greeting: string; }
>greeting : string
>'hello' : "hello"

View File

@@ -0,0 +1,69 @@
//// [objectRestParameterES5.ts]
function cloneAgain({ a, ...clone }: { a: number, b: string }): void {
}
declare function suddenly(f: (a: { x: { z, ka }, y: string }) => void);
suddenly(({ x: a, ...rest }) => rest.y);
suddenly(({ x: { z = 12, ...nested }, ...rest } = { x: { z: 1, ka: 1 }, y: 'noo' }) => rest.y + nested.ka);
class C {
m({ a, ...clone }: { a: number, b: string}): void {
// actually, never mind, don't clone
}
set p({ a, ...clone }: { a: number, b: string}) {
// actually, never mind, don't clone
}
}
function foobar({ bar={}, ...opts }: any = {}) {
}
foobar();
foobar({ baz: 'hello' });
foobar({ bar: { greeting: 'hello' } });
//// [objectRestParameterES5.js]
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
t[p[i]] = s[p[i]];
return t;
};
function cloneAgain(_a) {
var a = _a.a, clone = __rest(_a, ["a"]);
}
suddenly(function (_a) {
var a = _a.x, rest = __rest(_a, ["x"]);
return rest.y;
});
suddenly(function (_a) {
if (_a === void 0) { _a = { x: { z: 1, ka: 1 }, y: 'noo' }; }
var _b = _a.x, _c = _b.z, z = _c === void 0 ? 12 : _c, nested = __rest(_b, ["z"]), rest = __rest(_a, ["x"]);
return rest.y + nested.ka;
});
var C = (function () {
function C() {
}
C.prototype.m = function (_a) {
var a = _a.a, clone = __rest(_a, ["a"]);
// actually, never mind, don't clone
};
Object.defineProperty(C.prototype, "p", {
set: function (_a) {
var a = _a.a, clone = __rest(_a, ["a"]);
// actually, never mind, don't clone
},
enumerable: true,
configurable: true
});
return C;
}());
function foobar(_a) {
if (_a === void 0) { _a = {}; }
var _b = _a.bar, bar = _b === void 0 ? {} : _b, opts = __rest(_a, ["bar"]);
}
foobar();
foobar({ baz: 'hello' });
foobar({ bar: { greeting: 'hello' } });

View File

@@ -0,0 +1,83 @@
=== tests/cases/conformance/types/rest/objectRestParameterES5.ts ===
function cloneAgain({ a, ...clone }: { a: number, b: string }): void {
>cloneAgain : Symbol(cloneAgain, Decl(objectRestParameterES5.ts, 0, 0))
>a : Symbol(a, Decl(objectRestParameterES5.ts, 0, 21))
>clone : Symbol(clone, Decl(objectRestParameterES5.ts, 0, 24))
>a : Symbol(a, Decl(objectRestParameterES5.ts, 0, 38))
>b : Symbol(b, Decl(objectRestParameterES5.ts, 0, 49))
}
declare function suddenly(f: (a: { x: { z, ka }, y: string }) => void);
>suddenly : Symbol(suddenly, Decl(objectRestParameterES5.ts, 1, 1))
>f : Symbol(f, Decl(objectRestParameterES5.ts, 3, 26))
>a : Symbol(a, Decl(objectRestParameterES5.ts, 3, 30))
>x : Symbol(x, Decl(objectRestParameterES5.ts, 3, 34))
>z : Symbol(z, Decl(objectRestParameterES5.ts, 3, 39))
>ka : Symbol(ka, Decl(objectRestParameterES5.ts, 3, 42))
>y : Symbol(y, Decl(objectRestParameterES5.ts, 3, 48))
suddenly(({ x: a, ...rest }) => rest.y);
>suddenly : Symbol(suddenly, Decl(objectRestParameterES5.ts, 1, 1))
>x : Symbol(x, Decl(objectRestParameterES5.ts, 3, 34))
>a : Symbol(a, Decl(objectRestParameterES5.ts, 4, 11))
>rest : Symbol(rest, Decl(objectRestParameterES5.ts, 4, 17))
>rest.y : Symbol(y, Decl(objectRestParameterES5.ts, 3, 48))
>rest : Symbol(rest, Decl(objectRestParameterES5.ts, 4, 17))
>y : Symbol(y, Decl(objectRestParameterES5.ts, 3, 48))
suddenly(({ x: { z = 12, ...nested }, ...rest } = { x: { z: 1, ka: 1 }, y: 'noo' }) => rest.y + nested.ka);
>suddenly : Symbol(suddenly, Decl(objectRestParameterES5.ts, 1, 1))
>x : Symbol(x, Decl(objectRestParameterES5.ts, 3, 34))
>z : Symbol(z, Decl(objectRestParameterES5.ts, 5, 16))
>nested : Symbol(nested, Decl(objectRestParameterES5.ts, 5, 24))
>rest : Symbol(rest, Decl(objectRestParameterES5.ts, 5, 37))
>x : Symbol(x, Decl(objectRestParameterES5.ts, 5, 51))
>z : Symbol(z, Decl(objectRestParameterES5.ts, 5, 56))
>ka : Symbol(ka, Decl(objectRestParameterES5.ts, 5, 62))
>y : Symbol(y, Decl(objectRestParameterES5.ts, 5, 71))
>rest.y : Symbol(y, Decl(objectRestParameterES5.ts, 3, 48))
>rest : Symbol(rest, Decl(objectRestParameterES5.ts, 5, 37))
>y : Symbol(y, Decl(objectRestParameterES5.ts, 3, 48))
>nested.ka : Symbol(ka, Decl(objectRestParameterES5.ts, 3, 42))
>nested : Symbol(nested, Decl(objectRestParameterES5.ts, 5, 24))
>ka : Symbol(ka, Decl(objectRestParameterES5.ts, 3, 42))
class C {
>C : Symbol(C, Decl(objectRestParameterES5.ts, 5, 107))
m({ a, ...clone }: { a: number, b: string}): void {
>m : Symbol(C.m, Decl(objectRestParameterES5.ts, 7, 9))
>a : Symbol(a, Decl(objectRestParameterES5.ts, 8, 7))
>clone : Symbol(clone, Decl(objectRestParameterES5.ts, 8, 10))
>a : Symbol(a, Decl(objectRestParameterES5.ts, 8, 24))
>b : Symbol(b, Decl(objectRestParameterES5.ts, 8, 35))
// actually, never mind, don't clone
}
set p({ a, ...clone }: { a: number, b: string}) {
>p : Symbol(C.p, Decl(objectRestParameterES5.ts, 10, 5))
>a : Symbol(a, Decl(objectRestParameterES5.ts, 11, 11))
>clone : Symbol(clone, Decl(objectRestParameterES5.ts, 11, 14))
>a : Symbol(a, Decl(objectRestParameterES5.ts, 11, 28))
>b : Symbol(b, Decl(objectRestParameterES5.ts, 11, 39))
// actually, never mind, don't clone
}
}
function foobar({ bar={}, ...opts }: any = {}) {
>foobar : Symbol(foobar, Decl(objectRestParameterES5.ts, 14, 1))
>bar : Symbol(bar, Decl(objectRestParameterES5.ts, 15, 17))
>opts : Symbol(opts, Decl(objectRestParameterES5.ts, 15, 25))
}
foobar();
>foobar : Symbol(foobar, Decl(objectRestParameterES5.ts, 14, 1))
foobar({ baz: 'hello' });
>foobar : Symbol(foobar, Decl(objectRestParameterES5.ts, 14, 1))
>baz : Symbol(baz, Decl(objectRestParameterES5.ts, 18, 8))
foobar({ bar: { greeting: 'hello' } });
>foobar : Symbol(foobar, Decl(objectRestParameterES5.ts, 14, 1))
>bar : Symbol(bar, Decl(objectRestParameterES5.ts, 19, 8))
>greeting : Symbol(greeting, Decl(objectRestParameterES5.ts, 19, 15))

View File

@@ -0,0 +1,104 @@
=== tests/cases/conformance/types/rest/objectRestParameterES5.ts ===
function cloneAgain({ a, ...clone }: { a: number, b: string }): void {
>cloneAgain : ({a, ...clone}: { a: number; b: string; }) => void
>a : number
>clone : { b: string; }
>a : number
>b : string
}
declare function suddenly(f: (a: { x: { z, ka }, y: string }) => void);
>suddenly : (f: (a: { x: { z: any; ka: any; }; y: string; }) => void) => any
>f : (a: { x: { z: any; ka: any; }; y: string; }) => void
>a : { x: { z: any; ka: any; }; y: string; }
>x : { z: any; ka: any; }
>z : any
>ka : any
>y : string
suddenly(({ x: a, ...rest }) => rest.y);
>suddenly(({ x: a, ...rest }) => rest.y) : any
>suddenly : (f: (a: { x: { z: any; ka: any; }; y: string; }) => void) => any
>({ x: a, ...rest }) => rest.y : ({x: a, ...rest}: { x: { z: any; ka: any; }; y: string; }) => string
>x : any
>a : { z: any; ka: any; }
>rest : { y: string; }
>rest.y : string
>rest : { y: string; }
>y : string
suddenly(({ x: { z = 12, ...nested }, ...rest } = { x: { z: 1, ka: 1 }, y: 'noo' }) => rest.y + nested.ka);
>suddenly(({ x: { z = 12, ...nested }, ...rest } = { x: { z: 1, ka: 1 }, y: 'noo' }) => rest.y + nested.ka) : any
>suddenly : (f: (a: { x: { z: any; ka: any; }; y: string; }) => void) => any
>({ x: { z = 12, ...nested }, ...rest } = { x: { z: 1, ka: 1 }, y: 'noo' }) => rest.y + nested.ka : ({x: {z, ...nested}, ...rest}?: { x: { z: any; ka: any; }; y: string; }) => string
>x : any
>z : any
>12 : 12
>nested : { ka: any; }
>rest : { y: string; }
>{ x: { z: 1, ka: 1 }, y: 'noo' } : { x: { z: number; ka: number; }; y: string; }
>x : { z: number; ka: number; }
>{ z: 1, ka: 1 } : { z: number; ka: number; }
>z : number
>1 : 1
>ka : number
>1 : 1
>y : string
>'noo' : "noo"
>rest.y + nested.ka : string
>rest.y : string
>rest : { y: string; }
>y : string
>nested.ka : any
>nested : { ka: any; }
>ka : any
class C {
>C : C
m({ a, ...clone }: { a: number, b: string}): void {
>m : ({a, ...clone}: { a: number; b: string; }) => void
>a : number
>clone : { b: string; }
>a : number
>b : string
// actually, never mind, don't clone
}
set p({ a, ...clone }: { a: number, b: string}) {
>p : { a: number; b: string; }
>a : number
>clone : { b: string; }
>a : number
>b : string
// actually, never mind, don't clone
}
}
function foobar({ bar={}, ...opts }: any = {}) {
>foobar : ({bar, ...opts}?: any) => void
>bar : {}
>{} : {}
>opts : any
>{} : {}
}
foobar();
>foobar() : void
>foobar : ({bar, ...opts}?: any) => void
foobar({ baz: 'hello' });
>foobar({ baz: 'hello' }) : void
>foobar : ({bar, ...opts}?: any) => void
>{ baz: 'hello' } : { baz: string; }
>baz : string
>'hello' : "hello"
foobar({ bar: { greeting: 'hello' } });
>foobar({ bar: { greeting: 'hello' } }) : void
>foobar : ({bar, ...opts}?: any) => void
>{ bar: { greeting: 'hello' } } : { bar: { greeting: string; }; }
>bar : { greeting: string; }
>{ greeting: 'hello' } : { greeting: string; }
>greeting : string
>'hello' : "hello"

View File

@@ -0,0 +1,49 @@
//// [parameterInitializerBeforeDestructuringEmit.ts]
interface Foo {
bar?: any;
baz?: any;
}
function foobar({ bar = {}, ...opts }: Foo = {}) {
"use strict";
"Some other prologue";
opts.baz(bar);
}
class C {
constructor({ bar = {}, ...opts }: Foo = {}) {
"use strict";
"Some other prologue";
opts.baz(bar);
}
}
//// [parameterInitializerBeforeDestructuringEmit.js]
"use strict";
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
t[p[i]] = s[p[i]];
return t;
};
function foobar(_a) {
"use strict";
"Some other prologue";
if (_a === void 0) { _a = {}; }
var _b = _a.bar, bar = _b === void 0 ? {} : _b, opts = __rest(_a, ["bar"]);
opts.baz(bar);
}
var C = (function () {
function C(_a) {
"use strict";
"Some other prologue";
if (_a === void 0) { _a = {}; }
var _b = _a.bar, bar = _b === void 0 ? {} : _b, opts = __rest(_a, ["bar"]);
opts.baz(bar);
}
return C;
}());

View File

@@ -0,0 +1,44 @@
=== tests/cases/compiler/parameterInitializerBeforeDestructuringEmit.ts ===
interface Foo {
>Foo : Symbol(Foo, Decl(parameterInitializerBeforeDestructuringEmit.ts, 0, 0))
bar?: any;
>bar : Symbol(Foo.bar, Decl(parameterInitializerBeforeDestructuringEmit.ts, 0, 15))
baz?: any;
>baz : Symbol(Foo.baz, Decl(parameterInitializerBeforeDestructuringEmit.ts, 1, 14))
}
function foobar({ bar = {}, ...opts }: Foo = {}) {
>foobar : Symbol(foobar, Decl(parameterInitializerBeforeDestructuringEmit.ts, 3, 1))
>bar : Symbol(bar, Decl(parameterInitializerBeforeDestructuringEmit.ts, 5, 17))
>opts : Symbol(opts, Decl(parameterInitializerBeforeDestructuringEmit.ts, 5, 27))
>Foo : Symbol(Foo, Decl(parameterInitializerBeforeDestructuringEmit.ts, 0, 0))
"use strict";
"Some other prologue";
opts.baz(bar);
>opts.baz : Symbol(Foo.baz, Decl(parameterInitializerBeforeDestructuringEmit.ts, 1, 14))
>opts : Symbol(opts, Decl(parameterInitializerBeforeDestructuringEmit.ts, 5, 27))
>baz : Symbol(Foo.baz, Decl(parameterInitializerBeforeDestructuringEmit.ts, 1, 14))
>bar : Symbol(bar, Decl(parameterInitializerBeforeDestructuringEmit.ts, 5, 17))
}
class C {
>C : Symbol(C, Decl(parameterInitializerBeforeDestructuringEmit.ts, 9, 1))
constructor({ bar = {}, ...opts }: Foo = {}) {
>bar : Symbol(bar, Decl(parameterInitializerBeforeDestructuringEmit.ts, 12, 17))
>opts : Symbol(opts, Decl(parameterInitializerBeforeDestructuringEmit.ts, 12, 27))
>Foo : Symbol(Foo, Decl(parameterInitializerBeforeDestructuringEmit.ts, 0, 0))
"use strict";
"Some other prologue";
opts.baz(bar);
>opts.baz : Symbol(Foo.baz, Decl(parameterInitializerBeforeDestructuringEmit.ts, 1, 14))
>opts : Symbol(opts, Decl(parameterInitializerBeforeDestructuringEmit.ts, 12, 27))
>baz : Symbol(Foo.baz, Decl(parameterInitializerBeforeDestructuringEmit.ts, 1, 14))
>bar : Symbol(bar, Decl(parameterInitializerBeforeDestructuringEmit.ts, 12, 17))
}
}

View File

@@ -0,0 +1,58 @@
=== tests/cases/compiler/parameterInitializerBeforeDestructuringEmit.ts ===
interface Foo {
>Foo : Foo
bar?: any;
>bar : any
baz?: any;
>baz : any
}
function foobar({ bar = {}, ...opts }: Foo = {}) {
>foobar : ({bar, ...opts}?: Foo) => void
>bar : any
>{} : {}
>opts : { baz?: any; }
>Foo : Foo
>{} : {}
"use strict";
>"use strict" : "use strict"
"Some other prologue";
>"Some other prologue" : "Some other prologue"
opts.baz(bar);
>opts.baz(bar) : any
>opts.baz : any
>opts : { baz?: any; }
>baz : any
>bar : any
}
class C {
>C : C
constructor({ bar = {}, ...opts }: Foo = {}) {
>bar : any
>{} : {}
>opts : { baz?: any; }
>Foo : Foo
>{} : {}
"use strict";
>"use strict" : "use strict"
"Some other prologue";
>"Some other prologue" : "Some other prologue"
opts.baz(bar);
>opts.baz(bar) : any
>opts.baz : any
>opts : { baz?: any; }
>baz : any
>bar : any
}
}

View File

@@ -0,0 +1,20 @@
// @noImplicitUseStrict: false
// @alwaysStrict: true
interface Foo {
bar?: any;
baz?: any;
}
function foobar({ bar = {}, ...opts }: Foo = {}) {
"use strict";
"Some other prologue";
opts.baz(bar);
}
class C {
constructor({ bar = {}, ...opts }: Foo = {}) {
"use strict";
"Some other prologue";
opts.baz(bar);
}
}

View File

@@ -14,4 +14,8 @@ class C {
// actually, never mind, don't clone
}
}
function foobar({ bar={}, ...opts }: any = {}) {
}
foobar();
foobar({ baz: 'hello' });
foobar({ bar: { greeting: 'hello' } });

View File

@@ -0,0 +1,21 @@
// @target: es5
function cloneAgain({ a, ...clone }: { a: number, b: string }): void {
}
declare function suddenly(f: (a: { x: { z, ka }, y: string }) => void);
suddenly(({ x: a, ...rest }) => rest.y);
suddenly(({ x: { z = 12, ...nested }, ...rest } = { x: { z: 1, ka: 1 }, y: 'noo' }) => rest.y + nested.ka);
class C {
m({ a, ...clone }: { a: number, b: string}): void {
// actually, never mind, don't clone
}
set p({ a, ...clone }: { a: number, b: string}) {
// actually, never mind, don't clone
}
}
function foobar({ bar={}, ...opts }: any = {}) {
}
foobar();
foobar({ baz: 'hello' });
foobar({ bar: { greeting: 'hello' } });