mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 04:43:37 -05:00
Merge branch 'master' into fix11038
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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; };
|
||||
}); };
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
|
||||
13
tests/baselines/reference/forOfTransformsExpression.js
Normal file
13
tests/baselines/reference/forOfTransformsExpression.js
Normal 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];
|
||||
}
|
||||
25
tests/baselines/reference/forOfTransformsExpression.symbols
Normal file
25
tests/baselines/reference/forOfTransformsExpression.symbols
Normal 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))
|
||||
|
||||
}
|
||||
35
tests/baselines/reference/forOfTransformsExpression.types
Normal file
35
tests/baselines/reference/forOfTransformsExpression.types
Normal 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
|
||||
|
||||
}
|
||||
@@ -7,5 +7,5 @@
|
||||
|
||||
//// [functionsWithModifiersInBlocks1.js]
|
||||
{
|
||||
function f() { }
|
||||
export function f() { }
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -8,7 +8,7 @@ export function foo() {
|
||||
//// [parserModifierOnStatementInBlock3.js]
|
||||
"use strict";
|
||||
function foo() {
|
||||
function bar() {
|
||||
export function bar() {
|
||||
}
|
||||
}
|
||||
exports.foo = foo;
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
|
||||
//// [parserModifierOnStatementInBlock4.js]
|
||||
{
|
||||
function bar() {
|
||||
export function bar() {
|
||||
}
|
||||
}
|
||||
|
||||
5
tests/cases/compiler/forOfTransformsExpression.ts
Normal file
5
tests/cases/compiler/forOfTransformsExpression.ts
Normal 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))) {
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user