ES6 cleanup
This commit is contained in:
parent
88e17728d6
commit
30433c2c67
10 changed files with 1053 additions and 507 deletions
|
@ -1930,7 +1930,8 @@ namespace ts {
|
|||
case SyntaxKind.CallExpression:
|
||||
excludeFlags = TransformFlags.ArrayLiteralOrCallOrNewExcludes;
|
||||
if (subtreeFlags & TransformFlags.ContainsSpreadElementExpression
|
||||
|| isSuperCall(node)) {
|
||||
|| isSuperCall(node)
|
||||
|| isSuperPropertyCall(node)) {
|
||||
// If the this node contains a SpreadElementExpression, or is a super call, then it is an ES6
|
||||
// node.
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
|
@ -1969,12 +1970,18 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
// If the expression of a ParenthesizedExpression is a destructuring assignment,
|
||||
// then the ParenthesizedExpression is a destructuring assignment.
|
||||
if ((<ParenthesizedExpression>node).expression.transformFlags & TransformFlags.DestructuringAssignment) {
|
||||
transformFlags |= TransformFlags.DestructuringAssignment;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SyntaxKind.BinaryExpression:
|
||||
if (isDestructuringAssignment(node)) {
|
||||
// Destructuring assignments are ES6 syntax.
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
transformFlags |= TransformFlags.AssertES6 | TransformFlags.DestructuringAssignment;
|
||||
}
|
||||
else if ((<BinaryExpression>node).operatorToken.kind === SyntaxKind.AsteriskAsteriskToken
|
||||
|| (<BinaryExpression>node).operatorToken.kind === SyntaxKind.AsteriskAsteriskEqualsToken) {
|
||||
|
@ -1984,6 +1991,16 @@ namespace ts {
|
|||
|
||||
break;
|
||||
|
||||
case SyntaxKind.ExpressionStatement:
|
||||
// If the expression of an expression statement is a destructuring assignment,
|
||||
// then we treat the statement as ES6 so that we can indicate that we do not
|
||||
// need to hold on to the right-hand side.
|
||||
if ((<ExpressionStatement>node).expression.transformFlags & TransformFlags.DestructuringAssignment) {
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SyntaxKind.Parameter:
|
||||
// If the parameter has a question token, then it is TypeScript syntax.
|
||||
if ((<ParameterDeclaration>node).questionToken) {
|
||||
|
|
|
@ -7495,7 +7495,7 @@ namespace ts {
|
|||
// This is required for destructuring assignments, as a call expression cannot be used as the target of a destructuring assignment
|
||||
// while a property access can.
|
||||
if (container.kind === SyntaxKind.MethodDeclaration && container.flags & NodeFlags.Async) {
|
||||
if (isSuperPropertyOrElementAccess(node.parent) && isAssignmentTarget(node.parent)) {
|
||||
if (isSuperProperty(node.parent) && isAssignmentTarget(node.parent)) {
|
||||
getNodeLinks(container).flags |= NodeCheckFlags.AsyncMethodWithSuperBinding;
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -220,6 +220,23 @@ namespace ts {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the first matching span of elements and returns a tuple of the first span
|
||||
* and the remaining elements.
|
||||
*/
|
||||
export function span<T>(array: T[], f: (x: T, i: number) => boolean): [T[], T[]] {
|
||||
if (array) {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
if (!f(array[i], i)) {
|
||||
return [array.slice(0, i), array.slice(i)];
|
||||
}
|
||||
}
|
||||
return [array.slice(0), []];
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps contiguous spans of values with the same key.
|
||||
*
|
||||
|
|
|
@ -2339,7 +2339,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||
superCall = true;
|
||||
}
|
||||
else {
|
||||
superCall = isSuperPropertyOrElementAccess(expression);
|
||||
superCall = isSuperProperty(expression);
|
||||
isAsyncMethodWithSuper = superCall && isInAsyncMethodWithSuperInES6(node);
|
||||
emit(expression);
|
||||
}
|
||||
|
|
|
@ -152,7 +152,7 @@ namespace ts {
|
|||
/**
|
||||
* Creates a shallow, memberwise clone of a node for mutation.
|
||||
*/
|
||||
export function getMutableNode<T extends Node>(node: T): T {
|
||||
export function getMutableClone<T extends Node>(node: T): T {
|
||||
return cloneNode(node, /*location*/ node, node.flags, /*parent*/ undefined, /*original*/ node);
|
||||
}
|
||||
|
||||
|
@ -320,15 +320,21 @@ namespace ts {
|
|||
|
||||
// Expression
|
||||
|
||||
export function createArrayLiteral(elements?: Expression[]) {
|
||||
const node = <ArrayLiteralExpression>createNode(SyntaxKind.ArrayLiteralExpression);
|
||||
export function createArrayLiteral(elements?: Expression[], location?: TextRange, multiLine?: boolean) {
|
||||
const node = <ArrayLiteralExpression>createNode(SyntaxKind.ArrayLiteralExpression, location);
|
||||
node.elements = parenthesizeListElements(createNodeArray(elements));
|
||||
if (multiLine) {
|
||||
node.multiLine = multiLine;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createObjectLiteral(properties?: ObjectLiteralElement[], location?: TextRange) {
|
||||
export function createObjectLiteral(properties?: ObjectLiteralElement[], location?: TextRange, multiLine?: boolean) {
|
||||
const node = <ObjectLiteralExpression>createNode(SyntaxKind.ObjectLiteralExpression, location);
|
||||
node.properties = createNodeArray(properties);
|
||||
if (multiLine) {
|
||||
node.multiLine = multiLine;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -356,7 +362,7 @@ namespace ts {
|
|||
|
||||
export function createNew(expression: Expression, argumentsArray: Expression[], location?: TextRange) {
|
||||
const node = <NewExpression>createNode(SyntaxKind.NewExpression, location);
|
||||
node.expression = parenthesizeForAccess(expression);
|
||||
node.expression = parenthesizeForNew(expression);
|
||||
node.arguments = argumentsArray
|
||||
? parenthesizeListElements(createNodeArray(argumentsArray))
|
||||
: undefined;
|
||||
|
@ -369,7 +375,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function createFunctionExpression(asteriskToken: Node, name: string | Identifier, parameters: ParameterDeclaration[], body: Block, location?: TextRange) {
|
||||
export function createFunctionExpression(asteriskToken: Node, name: string | Identifier, parameters: ParameterDeclaration[], body: Block, location?: TextRange, original?: Node) {
|
||||
const node = <FunctionExpression>createNode(SyntaxKind.FunctionExpression, location);
|
||||
node.modifiers = undefined;
|
||||
node.asteriskToken = asteriskToken;
|
||||
|
@ -378,6 +384,10 @@ namespace ts {
|
|||
node.parameters = createNodeArray(parameters);
|
||||
node.type = undefined;
|
||||
node.body = body;
|
||||
if (original) {
|
||||
node.original = original;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -468,9 +478,12 @@ namespace ts {
|
|||
|
||||
// Element
|
||||
|
||||
export function createBlock(statements: Statement[], location?: TextRange): Block {
|
||||
export function createBlock(statements: Statement[], location?: TextRange, multiLine?: boolean): Block {
|
||||
const block = <Block>createNode(SyntaxKind.Block, location);
|
||||
block.statements = createNodeArray(statements);
|
||||
if (multiLine) {
|
||||
block.multiLine = true;
|
||||
}
|
||||
return block;
|
||||
}
|
||||
|
||||
|
@ -573,7 +586,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function createFunctionDeclaration(modifiers: Modifier[], asteriskToken: Node, name: string | Identifier, parameters: ParameterDeclaration[], body: Block, location?: TextRange) {
|
||||
export function createFunctionDeclaration(modifiers: Modifier[], asteriskToken: Node, name: string | Identifier, parameters: ParameterDeclaration[], body: Block, location?: TextRange, original?: Node) {
|
||||
const node = <FunctionDeclaration>createNode(SyntaxKind.FunctionDeclaration, location);
|
||||
node.decorators = undefined;
|
||||
setModifiers(node, modifiers);
|
||||
|
@ -583,6 +596,9 @@ namespace ts {
|
|||
node.parameters = createNodeArray(parameters);
|
||||
node.type = undefined;
|
||||
node.body = body;
|
||||
if (original) {
|
||||
node.original = original;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -1068,6 +1084,68 @@ namespace ts {
|
|||
);
|
||||
}
|
||||
|
||||
export interface CallBinding {
|
||||
target: LeftHandSideExpression;
|
||||
thisArg: Expression;
|
||||
}
|
||||
|
||||
export function createCallBinding(expression: Expression, languageVersion?: ScriptTarget): CallBinding {
|
||||
const callee = skipParentheses(expression);
|
||||
let thisArg: Expression;
|
||||
let target: LeftHandSideExpression;
|
||||
if (isSuperProperty(callee)) {
|
||||
thisArg = createThis(/*location*/ callee.expression);
|
||||
target = callee;
|
||||
}
|
||||
else if (isSuperCall(callee)) {
|
||||
thisArg = createThis(/*location*/ callee);
|
||||
target = languageVersion < ScriptTarget.ES6 ? createIdentifier("_super", /*location*/ callee) : callee;
|
||||
}
|
||||
else {
|
||||
switch (callee.kind) {
|
||||
case SyntaxKind.PropertyAccessExpression: {
|
||||
// for `a.b()` target is `(_a = a).b` and thisArg is `_a`
|
||||
thisArg = createTempVariable();
|
||||
target = createPropertyAccess(
|
||||
createAssignment(
|
||||
thisArg,
|
||||
(<PropertyAccessExpression>callee).expression,
|
||||
/*location*/ (<PropertyAccessExpression>callee).expression
|
||||
),
|
||||
(<PropertyAccessExpression>callee).name,
|
||||
/*location*/ callee
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case SyntaxKind.ElementAccessExpression: {
|
||||
// for `a[b]()` target is `(_a = a)[b]` and thisArg is `_a`
|
||||
thisArg = createTempVariable();
|
||||
target = createElementAccess(
|
||||
createAssignment(
|
||||
thisArg,
|
||||
(<ElementAccessExpression>callee).expression,
|
||||
/*location*/ (<ElementAccessExpression>callee).expression
|
||||
),
|
||||
(<ElementAccessExpression>callee).argumentExpression,
|
||||
/*location*/ callee
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
// for `a()` target is `a` and thisArg is `void 0`
|
||||
thisArg = createVoidZero();
|
||||
target = parenthesizeForAccess(expression);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { target, thisArg };
|
||||
}
|
||||
|
||||
export function inlineExpressions(expressions: Expression[]) {
|
||||
return reduceLeft(expressions, createComma);
|
||||
}
|
||||
|
@ -1206,6 +1284,23 @@ namespace ts {
|
|||
|| binaryOperator === SyntaxKind.CaretToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps an expression in parentheses if it is needed in order to use the expression
|
||||
* as the expression of a NewExpression node.
|
||||
*
|
||||
* @param expression The Expression node.
|
||||
*/
|
||||
export function parenthesizeForNew(expression: Expression): LeftHandSideExpression {
|
||||
const lhs = parenthesizeForAccess(expression);
|
||||
switch (lhs.kind) {
|
||||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
return createParen(lhs);
|
||||
}
|
||||
|
||||
return lhs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps an expression in parentheses if it is needed in order to use the expression for
|
||||
* property or element access.
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -44,7 +44,6 @@ namespace ts {
|
|||
let currentScope: SourceFile | Block | ModuleBlock | CaseBlock;
|
||||
let currentParent: Node;
|
||||
let currentNode: Node;
|
||||
let combinedNodeFlags: NodeFlags;
|
||||
|
||||
/**
|
||||
* Keeps track of whether expression substitution has been enabled for specific edge cases.
|
||||
|
@ -104,7 +103,6 @@ namespace ts {
|
|||
const savedCurrentScope = currentScope;
|
||||
const savedCurrentParent = currentParent;
|
||||
const savedCurrentNode = currentNode;
|
||||
const savedCombinedNodeFlags = combinedNodeFlags;
|
||||
|
||||
// Handle state changes before visiting a node.
|
||||
onBeforeVisitNode(node);
|
||||
|
@ -116,7 +114,6 @@ namespace ts {
|
|||
currentScope = savedCurrentScope;
|
||||
currentParent = savedCurrentParent;
|
||||
currentNode = savedCurrentNode;
|
||||
combinedNodeFlags = savedCombinedNodeFlags;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
@ -392,8 +389,6 @@ namespace ts {
|
|||
currentParent = currentNode;
|
||||
currentNode = node;
|
||||
|
||||
combinedNodeFlags = combineNodeFlags(currentNode, currentParent, combinedNodeFlags);
|
||||
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.SourceFile:
|
||||
case SyntaxKind.CaseBlock:
|
||||
|
@ -2758,7 +2753,7 @@ namespace ts {
|
|||
|
||||
function substituteCallExpression(node: CallExpression): Expression {
|
||||
const expression = node.expression;
|
||||
if (isSuperPropertyOrElementAccess(expression)) {
|
||||
if (isSuperProperty(expression)) {
|
||||
const flags = getSuperContainerAsyncMethodFlags();
|
||||
if (flags) {
|
||||
const argumentExpression = isPropertyAccessExpression(expression)
|
||||
|
|
|
@ -2761,18 +2761,19 @@ namespace ts {
|
|||
ContainsES7 = 1 << 5,
|
||||
ES6 = 1 << 6,
|
||||
ContainsES6 = 1 << 7,
|
||||
DestructuringAssignment = 1 << 8,
|
||||
|
||||
// Markers
|
||||
// - Flags used to indicate that a subtree contains a specific transformation.
|
||||
ContainsDecorators = 1 << 8,
|
||||
ContainsPropertyInitializer = 1 << 9,
|
||||
ContainsLexicalThis = 1 << 10,
|
||||
ContainsCapturedLexicalThis = 1 << 11,
|
||||
ContainsDefaultValueAssignments = 1 << 12,
|
||||
ContainsParameterPropertyAssignments = 1 << 13,
|
||||
ContainsSpreadElementExpression = 1 << 14,
|
||||
ContainsComputedPropertyName = 1 << 15,
|
||||
ContainsBlockScopedBinding = 1 << 16,
|
||||
ContainsDecorators = 1 << 9,
|
||||
ContainsPropertyInitializer = 1 << 10,
|
||||
ContainsLexicalThis = 1 << 11,
|
||||
ContainsCapturedLexicalThis = 1 << 12,
|
||||
ContainsDefaultValueAssignments = 1 << 13,
|
||||
ContainsParameterPropertyAssignments = 1 << 14,
|
||||
ContainsSpreadElementExpression = 1 << 15,
|
||||
ContainsComputedPropertyName = 1 << 16,
|
||||
ContainsBlockScopedBinding = 1 << 17,
|
||||
|
||||
// Assertions
|
||||
// - Bitmasks that are used to assert facts about the syntax of a node and its subtree.
|
||||
|
@ -2784,7 +2785,7 @@ namespace ts {
|
|||
// Scope Exclusions
|
||||
// - Bitmasks that exclude flags from propagating out of a specific context
|
||||
// into the subtree flags of their container.
|
||||
NodeExcludes = TypeScript | Jsx | ES7 | ES6,
|
||||
NodeExcludes = TypeScript | Jsx | ES7 | ES6 | DestructuringAssignment,
|
||||
ArrowFunctionExcludes = ContainsDecorators | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsParameterPropertyAssignments | ContainsBlockScopedBinding,
|
||||
FunctionExcludes = ContainsDecorators | ContainsDefaultValueAssignments | ContainsCapturedLexicalThis | ContainsLexicalThis | ContainsParameterPropertyAssignments | ContainsBlockScopedBinding,
|
||||
ConstructorExcludes = ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding,
|
||||
|
|
|
@ -491,19 +491,6 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines the flags of a node with the combined flags of its parent if they can be combined.
|
||||
*/
|
||||
export function combineNodeFlags(node: Node, parentNode: Node, previousNodeFlags: NodeFlags) {
|
||||
if ((node.kind === SyntaxKind.VariableDeclarationList && parentNode.kind === SyntaxKind.VariableStatement) ||
|
||||
(node.kind === SyntaxKind.VariableDeclaration && parentNode.kind === SyntaxKind.VariableDeclarationList) ||
|
||||
(node.kind === SyntaxKind.BindingElement)) {
|
||||
return node.flags | previousNodeFlags;
|
||||
}
|
||||
|
||||
return node.flags;
|
||||
}
|
||||
|
||||
// Returns the node flags for this node and all relevant parent nodes. This is done so that
|
||||
// nodes like variable declarations and binding elements can returned a view of their flags
|
||||
// that includes the modifiers from their container. i.e. flags like export/declare aren't
|
||||
|
@ -948,19 +935,20 @@ namespace ts {
|
|||
/**
|
||||
* Determines whether a node is a property or element access expression for super.
|
||||
*/
|
||||
export function isSuperPropertyOrElementAccess(node: Node): node is (PropertyAccessExpression | ElementAccessExpression) {
|
||||
export function isSuperProperty(node: Node): node is (PropertyAccessExpression | ElementAccessExpression) {
|
||||
return (node.kind === SyntaxKind.PropertyAccessExpression
|
||||
|| node.kind === SyntaxKind.ElementAccessExpression)
|
||||
&& (<PropertyAccessExpression | ElementAccessExpression>node).expression.kind === SyntaxKind.SuperKeyword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a node is a call to either `super`, or a super property or element access.
|
||||
*/
|
||||
export function isSuperPropertyCall(node: Node): node is CallExpression {
|
||||
return node.kind === SyntaxKind.CallExpression
|
||||
&& <boolean>isSuperProperty((<CallExpression>node).expression);
|
||||
}
|
||||
|
||||
export function isSuperCall(node: Node): node is CallExpression {
|
||||
return node.kind === SyntaxKind.CallExpression
|
||||
&& ((<CallExpression>node).expression.kind === SyntaxKind.SuperKeyword
|
||||
|| isSuperPropertyOrElementAccess((<CallExpression>node).expression));
|
||||
&& (<CallExpression>node).expression.kind === SyntaxKind.SuperKeyword;
|
||||
}
|
||||
|
||||
export function getEntityNameFromTypeNode(node: TypeNode): EntityName | Expression {
|
||||
|
|
|
@ -134,7 +134,7 @@ namespace ts {
|
|||
{ name: "arguments", test: isExpression },
|
||||
],
|
||||
[SyntaxKind.NewExpression]: [
|
||||
{ name: "expression", test: isLeftHandSideExpression, parenthesize: parenthesizeForAccess },
|
||||
{ name: "expression", test: isLeftHandSideExpression, parenthesize: parenthesizeForNew },
|
||||
{ name: "typeArguments", test: isTypeNode },
|
||||
{ name: "arguments", test: isExpression },
|
||||
],
|
||||
|
@ -630,7 +630,7 @@ namespace ts {
|
|||
|
||||
if (updated !== undefined || visited !== value) {
|
||||
if (updated === undefined) {
|
||||
updated = getMutableNode(node);
|
||||
updated = getMutableClone(node);
|
||||
updated.flags &= ~NodeFlags.Modifier;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue