Merge branch 'master' of https://github.com/Microsoft/TypeScript into feature/eslint

This commit is contained in:
Alexander T
2019-07-23 13:10:04 +03:00
115 changed files with 348 additions and 175 deletions
+2 -1
View File
@@ -775,10 +775,11 @@ namespace ts {
priority: 5,
text: `
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};`
+28 -3
View File
@@ -229,14 +229,39 @@ namespace ts {
if (node.transformFlags & TransformFlags.ContainsObjectRestOrSpread) {
// spread elements emit like so:
// non-spread elements are chunked together into object literals, and then all are passed to __assign:
// { a, ...o, b } => __assign({a}, o, {b});
// { a, ...o, b } => __assign(__assign({a}, o), {b});
// If the first element is a spread element, then the first argument to __assign is {}:
// { ...o, a, b, ...o2 } => __assign({}, o, {a, b}, o2)
// { ...o, a, b, ...o2 } => __assign(__assign(__assign({}, o), {a, b}), o2)
//
// We cannot call __assign with more than two elements, since any element could cause side effects. For
// example:
// var k = { a: 1, b: 2 };
// var o = { a: 3, ...k, b: k.a++ };
// // expected: { a: 1, b: 1 }
// If we translate the above to `__assign({ a: 3 }, k, { b: k.a++ })`, the `k.a++` will evaluate before
// `k` is spread and we end up with `{ a: 2, b: 1 }`.
//
// This also occurs for spread elements, not just property assignments:
// var k = { a: 1, get b() { l = { z: 9 }; return 2; } };
// var l = { c: 3 };
// var o = { ...k, ...l };
// // expected: { a: 1, b: 2, z: 9 }
// If we translate the above to `__assign({}, k, l)`, the `l` will evaluate before `k` is spread and we
// end up with `{ a: 1, b: 2, c: 3 }`
const objects = chunkObjectLiteralElements(node.properties);
if (objects.length && objects[0].kind !== SyntaxKind.ObjectLiteralExpression) {
objects.unshift(createObjectLiteral());
}
return createAssignHelper(context, objects);
let expression: Expression = objects[0];
if (objects.length > 1) {
for (let i = 1; i < objects.length; i++) {
expression = createAssignHelper(context, [expression, objects[i]]);
}
return expression;
}
else {
return createAssignHelper(context, objects);
}
}
return visitEachChild(node, visitor, context);
}
+2
View File
@@ -73,7 +73,9 @@
"unittests/config/tsconfigParsing.ts",
"unittests/evaluation/asyncArrow.ts",
"unittests/evaluation/asyncGenerator.ts",
"unittests/evaluation/awaiter.ts",
"unittests/evaluation/forAwaitOf.ts",
"unittests/evaluation/objectRest.ts",
"unittests/services/cancellableLanguageServiceOperations.ts",
"unittests/services/colorization.ts",
"unittests/services/convertToAsyncFunction.ts",
@@ -0,0 +1,24 @@
describe("unittests:: evaluation:: awaiter", () => {
// NOTE: This could break if the ECMAScript spec ever changes the timing behavior for Promises (again)
it("await (es5)", async () => {
const result = evaluator.evaluateTypeScript(`
async function a(msg: string) {
await Promise.resolve();
output.push(msg);
}
function b(msg: string) {
return Promise.resolve().then(() => {
output.push(msg);
});
}
export const output: string[] = [];
export async function main() {
const p1 = a('1');
const p2 = b('2');
await Promise.all([p1, p2]);
}
`);
await result.main();
assert.deepEqual(result.output, ["1", "2"]);
});
});
@@ -0,0 +1,28 @@
describe("unittests:: evaluation:: objectRest", () => {
// https://github.com/microsoft/TypeScript/issues/31469
it("side effects in property assignment", async () => {
const result = evaluator.evaluateTypeScript(`
const k = { a: 1, b: 2 };
const o = { a: 3, ...k, b: k.a++ };
export const output = o;
`);
assert.deepEqual(result.output, { a: 1, b: 1 });
});
it("side effects in during spread", async () => {
const result = evaluator.evaluateTypeScript(`
const k = { a: 1, get b() { l = { c: 9 }; return 2; } };
let l = { c: 3 };
const o = { ...k, ...l };
export const output = o;
`);
assert.deepEqual(result.output, { a: 1, b: 2, c: 9 });
});
it("trailing literal-valued object-literal", async () => {
const result = evaluator.evaluateTypeScript(`
const k = { a: 1 }
const o = { ...k, ...{ b: 2 } };
export const output = o;
`);
assert.deepEqual(result.output, { a: 1, b: 2 });
});
});