Merge branch 'master' into fix11038

This commit is contained in:
Ron Buckton
2016-09-25 11:09:51 -07:00
14 changed files with 150 additions and 23 deletions

View File

@@ -126,14 +126,22 @@ namespace ts {
context: TransformationContext,
node: VariableDeclaration,
value?: Expression,
visitor?: (node: Node) => VisitResult<Node>) {
visitor?: (node: Node) => VisitResult<Node>,
recordTempVariable?: (node: Identifier) => void) {
const declarations: VariableDeclaration[] = [];
let pendingAssignments: Expression[];
flattenDestructuring(context, node, value, node, emitAssignment, emitTempVariableAssignment, visitor);
return declarations;
function emitAssignment(name: Identifier, value: Expression, location: TextRange, original: Node) {
if (pendingAssignments) {
pendingAssignments.push(value);
value = inlineExpressions(pendingAssignments);
pendingAssignments = undefined;
}
const declaration = createVariableDeclaration(name, /*type*/ undefined, value, location);
declaration.original = original;
@@ -146,8 +154,19 @@ namespace ts {
}
function emitTempVariableAssignment(value: Expression, location: TextRange) {
const name = createTempVariable(/*recordTempVariable*/ undefined);
emitAssignment(name, value, location, /*original*/ undefined);
const name = createTempVariable(recordTempVariable);
if (recordTempVariable) {
const assignment = createAssignment(name, value, location);
if (pendingAssignments) {
pendingAssignments.push(assignment);
}
else {
pendingAssignments = [assignment];
}
}
else {
emitAssignment(name, value, location, /*original*/ undefined);
}
return name;
}
}

View File

@@ -163,6 +163,7 @@ namespace ts {
let currentText: string;
let currentParent: Node;
let currentNode: Node;
let enclosingVariableStatement: VariableStatement;
let enclosingBlockScopeContainer: Node;
let enclosingBlockScopeContainerParent: Node;
let enclosingFunction: FunctionLikeDeclaration;
@@ -205,6 +206,7 @@ namespace ts {
const savedEnclosingNonAsyncFunctionBody = enclosingNonAsyncFunctionBody;
const savedEnclosingBlockScopeContainer = enclosingBlockScopeContainer;
const savedEnclosingBlockScopeContainerParent = enclosingBlockScopeContainerParent;
const savedEnclosingVariableStatement = enclosingVariableStatement;
const savedCurrentParent = currentParent;
const savedCurrentNode = currentNode;
const savedConvertedLoopState = convertedLoopState;
@@ -222,6 +224,7 @@ namespace ts {
enclosingNonAsyncFunctionBody = savedEnclosingNonAsyncFunctionBody;
enclosingBlockScopeContainer = savedEnclosingBlockScopeContainer;
enclosingBlockScopeContainerParent = savedEnclosingBlockScopeContainerParent;
enclosingVariableStatement = savedEnclosingVariableStatement;
currentParent = savedCurrentParent;
currentNode = savedCurrentNode;
return visited;
@@ -306,7 +309,7 @@ namespace ts {
return visitFunctionExpression(<FunctionExpression>node);
case SyntaxKind.VariableDeclaration:
return visitVariableDeclaration(<VariableDeclaration>node, /*offset*/ undefined);
return visitVariableDeclaration(<VariableDeclaration>node);
case SyntaxKind.Identifier:
return visitIdentifier(<Identifier>node);
@@ -410,6 +413,25 @@ namespace ts {
}
}
}
// keep track of the enclosing variable statement when in the context of
// variable statements, variable declarations, binding elements, and binding
// patterns.
switch (currentNode.kind) {
case SyntaxKind.VariableStatement:
enclosingVariableStatement = <VariableStatement>currentNode;
break;
case SyntaxKind.VariableDeclarationList:
case SyntaxKind.VariableDeclaration:
case SyntaxKind.BindingElement:
case SyntaxKind.ObjectBindingPattern:
case SyntaxKind.ArrayBindingPattern:
break;
default:
enclosingVariableStatement = undefined;
}
}
currentParent = currentNode;
@@ -1309,7 +1331,7 @@ namespace ts {
return setOriginalNode(
createFunctionDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
node.modifiers,
node.asteriskToken,
node.name,
/*typeParameters*/ undefined,
@@ -1638,13 +1660,13 @@ namespace ts {
*
* @param node A VariableDeclaration node.
*/
function visitVariableDeclarationInLetDeclarationList(node: VariableDeclaration, offset: number) {
function visitVariableDeclarationInLetDeclarationList(node: VariableDeclaration) {
// For binding pattern names that lack initializers there is no point to emit
// explicit initializer since downlevel codegen for destructuring will fail
// in the absence of initializer so all binding elements will say uninitialized
const name = node.name;
if (isBindingPattern(name)) {
return visitVariableDeclaration(node, offset);
return visitVariableDeclaration(node);
}
if (!node.initializer && shouldEmitExplicitInitializerForLetDeclaration(node)) {
@@ -1661,10 +1683,13 @@ namespace ts {
*
* @param node A VariableDeclaration node.
*/
function visitVariableDeclaration(node: VariableDeclaration, offset: number): VisitResult<VariableDeclaration> {
function visitVariableDeclaration(node: VariableDeclaration): VisitResult<VariableDeclaration> {
// If we are here it is because the name contains a binding pattern.
if (isBindingPattern(node.name)) {
return flattenVariableDestructuring(context, node, /*value*/ undefined, visitor);
const recordTempVariablesInLine = !enclosingVariableStatement
|| !hasModifier(enclosingVariableStatement, ModifierFlags.Export);
return flattenVariableDestructuring(context, node, /*value*/ undefined, visitor,
recordTempVariablesInLine ? undefined : hoistVariableDeclaration);
}
return visitEachChild(node, visitor, context);
@@ -1740,7 +1765,7 @@ namespace ts {
// Note also that because an extra statement is needed to assign to the LHS,
// for-of bodies are always emitted as blocks.
const expression = node.expression;
const expression = visitNode(node.expression, visitor, isExpression);
const initializer = node.initializer;
const statements: Statement[] = [];
@@ -1989,7 +2014,7 @@ namespace ts {
case SyntaxKind.ForOfStatement:
const initializer = (<ForStatement | ForInStatement | ForOfStatement>node).initializer;
if (initializer && initializer.kind === SyntaxKind.VariableDeclarationList) {
loopInitializer = <VariableDeclarationList>(<ForStatement | ForInStatement | ForOfStatement>node).initializer;
loopInitializer = <VariableDeclarationList>initializer;
}
break;
}

View File

@@ -573,11 +573,11 @@ namespace ts {
operationLocations = undefined;
state = createTempVariable(/*recordTempVariable*/ undefined);
const statementOffset = addPrologueDirectives(statements, body.statements, /*ensureUseStrict*/ false, visitor);
// Build the generator
startLexicalEnvironment();
const statementOffset = addPrologueDirectives(statements, body.statements, /*ensureUseStrict*/ false, visitor);
transformAndEmitStatements(body.statements, statementOffset);
const buildResult = build();
@@ -615,6 +615,11 @@ namespace ts {
return undefined;
}
else {
// Do not hoist custom prologues.
if (node.emitFlags & NodeEmitFlags.CustomPrologue) {
return node;
}
for (const variable of node.declarationList.declarations) {
hoistVariableDeclaration(<Identifier>variable.name);
}

View File

@@ -9,7 +9,7 @@ var bar = async (): Promise<void> => {
//// [asyncArrowFunction7_es5.js]
var _this = this;
var bar = function () { return __awaiter(_this, void 0, void 0, function () {
_this = this;
var _this = this;
var foo;
return __generator(this, function (_a) {
foo = function (a) {
@@ -22,4 +22,4 @@ var bar = function () { return __awaiter(_this, void 0, void 0, function () {
};
return [2 /*return*/];
});
}); var _this; };
}); };

View File

@@ -11,15 +11,15 @@ export default function f3(d = 0) {
//// [es6modulekindWithES5Target6.js]
function f1(d) {
export function f1(d) {
if (d === void 0) { d = 0; }
}
function f2() {
export function f2() {
var arg = [];
for (var _i = 0; _i < arguments.length; _i++) {
arg[_i - 0] = arguments[_i];
}
}
function f3(d) {
export default function f3(d) {
if (d === void 0) { d = 0; }
}

View File

@@ -0,0 +1,13 @@
//// [forOfTransformsExpression.ts]
// https://github.com/Microsoft/TypeScript/issues/11024
let items = [{ name: "A" }, { name: "C" }, { name: "B" }];
for (var item of items.sort((a, b) => a.name.localeCompare(b.name))) {
}
//// [forOfTransformsExpression.js]
// https://github.com/Microsoft/TypeScript/issues/11024
var items = [{ name: "A" }, { name: "C" }, { name: "B" }];
for (var _i = 0, _a = items.sort(function (a, b) { return a.name.localeCompare(b.name); }); _i < _a.length; _i++) {
var item = _a[_i];
}

View File

@@ -0,0 +1,25 @@
=== tests/cases/compiler/forOfTransformsExpression.ts ===
// https://github.com/Microsoft/TypeScript/issues/11024
let items = [{ name: "A" }, { name: "C" }, { name: "B" }];
>items : Symbol(items, Decl(forOfTransformsExpression.ts, 1, 3))
>name : Symbol(name, Decl(forOfTransformsExpression.ts, 1, 14))
>name : Symbol(name, Decl(forOfTransformsExpression.ts, 1, 29))
>name : Symbol(name, Decl(forOfTransformsExpression.ts, 1, 44))
for (var item of items.sort((a, b) => a.name.localeCompare(b.name))) {
>item : Symbol(item, Decl(forOfTransformsExpression.ts, 2, 8))
>items.sort : Symbol(Array.sort, Decl(lib.d.ts, --, --))
>items : Symbol(items, Decl(forOfTransformsExpression.ts, 1, 3))
>sort : Symbol(Array.sort, Decl(lib.d.ts, --, --))
>a : Symbol(a, Decl(forOfTransformsExpression.ts, 2, 29))
>b : Symbol(b, Decl(forOfTransformsExpression.ts, 2, 31))
>a.name.localeCompare : Symbol(String.localeCompare, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>a.name : Symbol(name, Decl(forOfTransformsExpression.ts, 1, 14))
>a : Symbol(a, Decl(forOfTransformsExpression.ts, 2, 29))
>name : Symbol(name, Decl(forOfTransformsExpression.ts, 1, 14))
>localeCompare : Symbol(String.localeCompare, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>b.name : Symbol(name, Decl(forOfTransformsExpression.ts, 1, 14))
>b : Symbol(b, Decl(forOfTransformsExpression.ts, 2, 31))
>name : Symbol(name, Decl(forOfTransformsExpression.ts, 1, 14))
}

View File

@@ -0,0 +1,35 @@
=== tests/cases/compiler/forOfTransformsExpression.ts ===
// https://github.com/Microsoft/TypeScript/issues/11024
let items = [{ name: "A" }, { name: "C" }, { name: "B" }];
>items : { name: string; }[]
>[{ name: "A" }, { name: "C" }, { name: "B" }] : { name: string; }[]
>{ name: "A" } : { name: string; }
>name : string
>"A" : "A"
>{ name: "C" } : { name: string; }
>name : string
>"C" : "C"
>{ name: "B" } : { name: string; }
>name : string
>"B" : "B"
for (var item of items.sort((a, b) => a.name.localeCompare(b.name))) {
>item : { name: string; }
>items.sort((a, b) => a.name.localeCompare(b.name)) : { name: string; }[]
>items.sort : (compareFn?: (a: { name: string; }, b: { name: string; }) => number) => { name: string; }[]
>items : { name: string; }[]
>sort : (compareFn?: (a: { name: string; }, b: { name: string; }) => number) => { name: string; }[]
>(a, b) => a.name.localeCompare(b.name) : (a: { name: string; }, b: { name: string; }) => number
>a : { name: string; }
>b : { name: string; }
>a.name.localeCompare(b.name) : number
>a.name.localeCompare : { (that: string): number; (that: string, locales?: string | string[], options?: Intl.CollatorOptions): number; }
>a.name : string
>a : { name: string; }
>name : string
>localeCompare : { (that: string): number; (that: string, locales?: string | string[], options?: Intl.CollatorOptions): number; }
>b.name : string
>b : { name: string; }
>name : string
}

View File

@@ -7,5 +7,5 @@
//// [functionsWithModifiersInBlocks1.js]
{
function f() { }
export function f() { }
}

View File

@@ -45,7 +45,7 @@
return C;
}());
export default C;
function bee() { }
export function bee() { }
import I2 = require("foo");
import * as Foo from "ambient";
import bar from "ambient";

View File

@@ -45,7 +45,7 @@ function blah() {
return C;
}());
export default C;
function bee() { }
export function bee() { }
import I2 = require("foo");
import * as Foo from "ambient";
import bar from "ambient";

View File

@@ -8,7 +8,7 @@ export function foo() {
//// [parserModifierOnStatementInBlock3.js]
"use strict";
function foo() {
function bar() {
export function bar() {
}
}
exports.foo = foo;

View File

@@ -7,6 +7,6 @@
//// [parserModifierOnStatementInBlock4.js]
{
function bar() {
export function bar() {
}
}

View File

@@ -0,0 +1,5 @@
// https://github.com/Microsoft/TypeScript/issues/11024
let items = [{ name: "A" }, { name: "C" }, { name: "B" }];
for (var item of items.sort((a, b) => a.name.localeCompare(b.name))) {
}