mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Cleanup and organization
This commit is contained in:
+37
-3
@@ -532,7 +532,7 @@ function generateFactory(outputFile: string) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip the is function for this node if it is already defined
|
||||
// Skip the is function for this node if it is already defined
|
||||
if (resolveQualifiedName(factorySourceFile, `ts.is${syntaxNode.kindName}`, SymbolFlags.Function)) {
|
||||
return;
|
||||
}
|
||||
@@ -552,8 +552,24 @@ function generateFactory(outputFile: string) {
|
||||
return;
|
||||
}
|
||||
|
||||
let typeNames = splitTypeName(typeName);
|
||||
let nodeTestFunction: string;
|
||||
if (typeNames.length === 1) {
|
||||
let typeSymbol = resolveExportedQualifiedName(tsModuleSymbol, typeName, SymbolFlags.Type);
|
||||
if (typeSymbol) {
|
||||
let nodeTestAnnotation = findFirstAnnotation(typeSymbol, NodeTestAnnotation.match);
|
||||
if (nodeTestAnnotation) {
|
||||
nodeTestFunction = nodeTestAnnotation.functionName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!nodeTestFunction) {
|
||||
nodeTestFunction = `is${typeNameToMethodNameSuffix(typeName)}`;
|
||||
}
|
||||
|
||||
// Skip the is function for this type if it is already defined in factory.ts
|
||||
if (resolveQualifiedName(factorySourceFile, `ts.is${typeNameToMethodNameSuffix(typeName)}`, SymbolFlags.Function)) {
|
||||
if (resolveQualifiedName(factorySourceFile, `ts.${nodeTestFunction}`, SymbolFlags.Function)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -562,7 +578,7 @@ function generateFactory(outputFile: string) {
|
||||
return;
|
||||
}
|
||||
|
||||
writer.write(`export function is${typeNameToMethodNameSuffix(typeName)}(node: Node): node is ${typeName} {`);
|
||||
writer.write(`export function ${nodeTestFunction}(node: Node): node is ${typeName} {`);
|
||||
writer.writeLine();
|
||||
writer.increaseIndent();
|
||||
|
||||
@@ -1307,6 +1323,8 @@ function createLineWrappingTextWriter(newLine: string, maxWidth: number): EmitTe
|
||||
// Annotations
|
||||
//
|
||||
|
||||
function findFirstAnnotation<TAnnotation extends Annotation>(symbol: Symbol, match: (annotation: Annotation) => annotation is TAnnotation): TAnnotation;
|
||||
function findFirstAnnotation<TAnnotation extends Annotation>(symbol: Symbol, match: (annotation: Annotation) => boolean): TAnnotation;
|
||||
function findFirstAnnotation<TAnnotation extends Annotation>(symbol: Symbol, match: (annotation: Annotation) => boolean): TAnnotation {
|
||||
for (let annotation of getAnnotations(symbol)) {
|
||||
if (match(annotation)) {
|
||||
@@ -1317,6 +1335,8 @@ function findFirstAnnotation<TAnnotation extends Annotation>(symbol: Symbol, mat
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function findAllAnnotations<TAnnotation extends Annotation>(symbol: Symbol, match: (annotation: Annotation) => annotation is TAnnotation): TAnnotation[];
|
||||
function findAllAnnotations<TAnnotation extends Annotation>(symbol: Symbol, match: (annotation: Annotation) => boolean): TAnnotation[];
|
||||
function findAllAnnotations<TAnnotation extends Annotation>(symbol: Symbol, match: (annotation: Annotation) => boolean): TAnnotation[] {
|
||||
let annotations: TAnnotation[];
|
||||
for (let annotation of getAnnotations(symbol)) {
|
||||
@@ -1570,6 +1590,20 @@ class NewLexicalEnvironmentAnnotation extends Annotation {
|
||||
}
|
||||
}
|
||||
|
||||
@annotation("nodetest")
|
||||
class NodeTestAnnotation extends Annotation {
|
||||
public name = "nodetest";
|
||||
public functionName: string;
|
||||
constructor([functionName, ..._arguments]: [string, any]) {
|
||||
super(_arguments);
|
||||
this.functionName = functionName
|
||||
}
|
||||
|
||||
public static match(annotation: Annotation): annotation is NodeTestAnnotation {
|
||||
return annotation instanceof NodeTestAnnotation;
|
||||
}
|
||||
}
|
||||
|
||||
function createAnnotation(name: string, _arguments: any[]): Annotation {
|
||||
let ctor = getProperty(annotationConstructors, name);
|
||||
if (ctor) {
|
||||
|
||||
@@ -1400,7 +1400,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isEntityNameOrExpression(node: Node): node is EntityName | Expression {
|
||||
return isEntityName(node) || isExpression(node);
|
||||
return isEntityName(node) || isExpressionNode(node);
|
||||
}
|
||||
|
||||
function isEntityNameVisible(entityName: EntityName | Expression, enclosingDeclaration: Node): SymbolVisibilityResult {
|
||||
@@ -13951,7 +13951,7 @@ namespace ts {
|
||||
(entityName.parent.kind === SyntaxKind.JsxClosingElement)) {
|
||||
return getJsxElementTagSymbol(<JsxOpeningLikeElement>entityName.parent);
|
||||
}
|
||||
else if (isPartOfExpression(entityName)) {
|
||||
else if (isExpression(entityName)) {
|
||||
if (nodeIsMissing(entityName)) {
|
||||
// Missing entity name.
|
||||
return undefined;
|
||||
@@ -14089,7 +14089,7 @@ namespace ts {
|
||||
return getTypeFromTypeNode(<TypeNode>node);
|
||||
}
|
||||
|
||||
if (isPartOfExpression(node)) {
|
||||
if (isExpression(node)) {
|
||||
return getTypeOfExpression(<Expression>node);
|
||||
}
|
||||
|
||||
|
||||
+41
-33
@@ -189,6 +189,34 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function trimArray<T>(array: T[]): T[] {
|
||||
let result: T[];
|
||||
if (array) {
|
||||
result = [];
|
||||
for (let v of array) {
|
||||
if (v !== undefined) {
|
||||
result.push(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function append<T>(to: T[], ...values: T[]): T[] {
|
||||
let result: T[];
|
||||
if (to) {
|
||||
for (let v of values) {
|
||||
if (v !== undefined) {
|
||||
if (!result) {
|
||||
result = to.slice(0);
|
||||
}
|
||||
result.push(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result || to;
|
||||
}
|
||||
|
||||
export function rangeEquals<T>(array1: T[], array2: T[], pos: number, end: number) {
|
||||
while (pos < end) {
|
||||
@@ -835,16 +863,6 @@ namespace ts {
|
||||
* @param currentNode The current node for the navigator.
|
||||
*/
|
||||
export function createParentNavigator(currentNode: Node): ParentNavigator {
|
||||
/** Traverses the parent pointers for the current node to find the root node. */
|
||||
function getRoot() {
|
||||
let rootNode = currentNode;
|
||||
while (rootNode && rootNode.parent) {
|
||||
rootNode = rootNode.parent;
|
||||
}
|
||||
|
||||
return rootNode;
|
||||
}
|
||||
|
||||
/** Gets the grandparent of the current node, without moving the navigator. */
|
||||
function getGrandparent() {
|
||||
let parent = getParent();
|
||||
@@ -877,30 +895,17 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Navigates to the root node for the current node. */
|
||||
function moveToRoot(): boolean {
|
||||
let rootNode = getRoot();
|
||||
if (rootNode) {
|
||||
currentNode = rootNode;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Creates a new ParentNavigator from the current node. */
|
||||
function createParentNavigator() {
|
||||
return ts.createParentNavigator(currentNode);
|
||||
}
|
||||
|
||||
return {
|
||||
getRoot,
|
||||
getGrandparent,
|
||||
getParent,
|
||||
getNode,
|
||||
getKind,
|
||||
moveToParent,
|
||||
moveToRoot,
|
||||
createParentNavigator,
|
||||
};
|
||||
}
|
||||
@@ -915,11 +920,6 @@ namespace ts {
|
||||
let parentNode: Node;
|
||||
let currentNode: Node;
|
||||
|
||||
/** Gets the node at the bottom of the stack. */
|
||||
function getRoot() {
|
||||
return rootNode;
|
||||
}
|
||||
|
||||
/** Gets the node two steps back from the top of the stack. */
|
||||
function getGrandparent() {
|
||||
return peekNode(2);
|
||||
@@ -953,6 +953,16 @@ namespace ts {
|
||||
currentNode = node;
|
||||
}
|
||||
|
||||
/** Pushes a node onto the stack if it is not already at the top of the stack. */
|
||||
function tryPushNode(node: Node): boolean {
|
||||
if (currentNode !== node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
pushNode(node);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Pops the top node from the stack. */
|
||||
function popNode(): void {
|
||||
currentNode = parentNode;
|
||||
@@ -985,7 +995,7 @@ namespace ts {
|
||||
if (parentNode && match(parentNode)) {
|
||||
return parentNode;
|
||||
}
|
||||
for (let i = stack.length; i >= 0; i--) {
|
||||
for (let i = stack.length - 1; i >= 0; i--) {
|
||||
let node = stack[i];
|
||||
if (match(node)) {
|
||||
return node;
|
||||
@@ -1048,26 +1058,24 @@ namespace ts {
|
||||
}
|
||||
|
||||
return {
|
||||
getRoot,
|
||||
getGrandparent,
|
||||
getParent,
|
||||
getNode,
|
||||
getKind,
|
||||
moveToRoot,
|
||||
moveToParent,
|
||||
createParentNavigator,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
getRoot,
|
||||
getGrandparent,
|
||||
getParent,
|
||||
getNode,
|
||||
getKind,
|
||||
pushNode,
|
||||
popNode,
|
||||
tryPushNode,
|
||||
setNode,
|
||||
popNode,
|
||||
findAncestorNode,
|
||||
createParentNavigator,
|
||||
};
|
||||
|
||||
+13
-7
@@ -504,11 +504,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
}
|
||||
|
||||
function writeTextWithSpanRecord(tokenKind: SyntaxKind, startPos: number, emitFn?: () => void) {
|
||||
let tokenStartPos = ts.skipTrivia(currentSourceFile.text, startPos);
|
||||
recordSourceMapSpan(tokenStartPos);
|
||||
let tokenEndPos = emitTokenText(tokenKind, tokenStartPos, emitFn);
|
||||
recordSourceMapSpan(tokenEndPos);
|
||||
return tokenEndPos;
|
||||
if (!positionIsSynthesized(startPos)) {
|
||||
let tokenStartPos = skipTrivia(currentSourceFile.text, startPos);
|
||||
recordSourceMapSpan(tokenStartPos);
|
||||
let tokenEndPos = emitTokenText(tokenKind, tokenStartPos, emitFn);
|
||||
recordSourceMapSpan(tokenEndPos);
|
||||
return tokenEndPos;
|
||||
}
|
||||
else {
|
||||
emitTokenText(tokenKind, startPos, emitFn);
|
||||
}
|
||||
}
|
||||
|
||||
function recordNewSourceFileStart(node: SourceFile) {
|
||||
@@ -1112,7 +1117,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
let nav = nodeStack.createParentNavigator();
|
||||
nav.moveToParent();
|
||||
|
||||
let emitOuterParens = isPartOfExpression(nav) && templateNeedsParens(node);
|
||||
let emitOuterParens = isExpression(nav) && templateNeedsParens(node);
|
||||
if (emitOuterParens) {
|
||||
write("(");
|
||||
}
|
||||
@@ -4389,7 +4394,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
|
||||
pushNode(body);
|
||||
let preambleEmitted = writer.getTextPos() !== initialTextPos;
|
||||
if (!preambleEmitted && nodeEndIsOnSameLineAsNodeStart(body, body)
|
||||
if (!preambleEmitted && !nodeIsSynthesized(body)
|
||||
&& nodeEndIsOnSameLineAsNodeStart(body, body)
|
||||
&& !isBlockWithSynthesizedStatementsOnNewLine(body)
|
||||
&& (!nodeIsSynthesized(body) || isSingleLineSynthesizedBlock(body))) {
|
||||
for (let statement of body.statements) {
|
||||
|
||||
@@ -2967,7 +2967,7 @@ namespace ts {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
export function isExpression(node: Node): node is Expression {
|
||||
export function isExpressionNode(node: Node): node is Expression {
|
||||
if (node) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.OmittedExpression:
|
||||
@@ -3386,6 +3386,45 @@ namespace ts {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
export function isStatementNode(node: Node): node is Statement {
|
||||
if (node) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.Block:
|
||||
case SyntaxKind.EmptyStatement:
|
||||
case SyntaxKind.DebuggerStatement:
|
||||
case SyntaxKind.MissingDeclaration:
|
||||
case SyntaxKind.VariableStatement:
|
||||
case SyntaxKind.ExpressionStatement:
|
||||
case SyntaxKind.IfStatement:
|
||||
case SyntaxKind.DoStatement:
|
||||
case SyntaxKind.WhileStatement:
|
||||
case SyntaxKind.ForStatement:
|
||||
case SyntaxKind.ForInStatement:
|
||||
case SyntaxKind.ForOfStatement:
|
||||
case SyntaxKind.BreakStatement:
|
||||
case SyntaxKind.ContinueStatement:
|
||||
case SyntaxKind.ReturnStatement:
|
||||
case SyntaxKind.WithStatement:
|
||||
case SyntaxKind.SwitchStatement:
|
||||
case SyntaxKind.LabeledStatement:
|
||||
case SyntaxKind.ThrowStatement:
|
||||
case SyntaxKind.TryStatement:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
case SyntaxKind.ModuleBlock:
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
case SyntaxKind.ExportAssignment:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
export function isExpressionOrVariableDeclarationList(node: Node): node is Expression | VariableDeclarationList {
|
||||
if (node) {
|
||||
switch (node.kind) {
|
||||
|
||||
+82
-327
@@ -140,23 +140,20 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function createNumericLiteral2(value: number, location?: TextRange, flags?: NodeFlags): LiteralExpression {
|
||||
let node = factory.createNumericLiteral(String(value), location, flags);
|
||||
let node = createNumericLiteral(String(value), location, flags);
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createPropertyAccessExpression2(expression: Expression, name: Identifier, location?: TextRange, flags?: NodeFlags) {
|
||||
return factory.createPropertyAccessExpression(
|
||||
factory.parenthesizeForAccess(expression),
|
||||
factory.createNode(SyntaxKind.DotToken),
|
||||
name,
|
||||
location,
|
||||
flags
|
||||
);
|
||||
return createPropertyAccessExpression(parenthesizeForAccess(expression), createNode(SyntaxKind.DotToken), name, location, flags);
|
||||
}
|
||||
|
||||
export function createPropertyAccessExpression3(expression: Expression, name: string, location?: TextRange, flags?: NodeFlags) {
|
||||
return createPropertyAccessExpression(parenthesizeForAccess(expression), createNode(SyntaxKind.DotToken), createIdentifier(name), location, flags);
|
||||
}
|
||||
|
||||
export const enum BinaryOperand {
|
||||
Left,
|
||||
Right
|
||||
export function makeSynthesized<TNode extends Node>(node: TNode): TNode {
|
||||
return nodeIsSynthesized(node) ? node : cloneNode(node);
|
||||
}
|
||||
|
||||
export function parenthesizeForBinary(expr: Expression, operator: SyntaxKind) {
|
||||
@@ -175,7 +172,7 @@ namespace ts {
|
||||
let operatorPrecedence = getBinaryOperatorPrecedence(operator);
|
||||
if (exprPrecedence < operatorPrecedence) {
|
||||
// lower precedence, the expression needs parenthesis
|
||||
return factory.createParenthesizedExpression(expr);
|
||||
return createParenthesizedExpression(expr);
|
||||
}
|
||||
else {
|
||||
// higher precedence.
|
||||
@@ -205,25 +202,15 @@ namespace ts {
|
||||
return <LeftHandSideExpression>expr;
|
||||
}
|
||||
|
||||
return factory.createParenthesizedExpression(expr);
|
||||
return createParenthesizedExpression(expr);
|
||||
}
|
||||
|
||||
export function createCallExpression2(expression: Expression, _arguments?: Expression[], location?: TextRange, flags?: NodeFlags) {
|
||||
return factory.createCallExpression(
|
||||
parenthesizeForAccess(expression),
|
||||
/*typeArguments*/ undefined,
|
||||
_arguments,
|
||||
location,
|
||||
flags
|
||||
);
|
||||
return createCallExpression(parenthesizeForAccess(expression), undefined, _arguments, location, flags);
|
||||
}
|
||||
|
||||
export function createObjectLiteralExpression2(properties?: ObjectLiteralElement[]) {
|
||||
return createObjectLiteralExpression(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
createNodeArray(properties)
|
||||
);
|
||||
return createObjectLiteralExpression(undefined, undefined, createNodeArray(properties));
|
||||
}
|
||||
|
||||
export function createAssignmentExpression(left: Expression, right: Expression) {
|
||||
@@ -251,353 +238,150 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function createBinaryExpression2(left: Expression, operator: SyntaxKind, right: Expression) {
|
||||
return factory.createBinaryExpression(
|
||||
parenthesizeForBinary(left, operator),
|
||||
factory.createNode(operator),
|
||||
parenthesizeForBinary(right, operator)
|
||||
);
|
||||
return createBinaryExpression(parenthesizeForBinary(left, operator), createNode(operator), parenthesizeForBinary(right, operator));
|
||||
}
|
||||
|
||||
export function createConditionalExpression2(condition: Expression, whenTrue: Expression, whenFalse: Expression, location?: TextRange, flags?: NodeFlags) {
|
||||
return factory.createConditionalExpression(
|
||||
condition,
|
||||
factory.createNode(SyntaxKind.QuestionToken),
|
||||
whenTrue,
|
||||
factory.createNode(SyntaxKind.ColonToken),
|
||||
whenFalse,
|
||||
location,
|
||||
flags
|
||||
);
|
||||
return createConditionalExpression(condition, createNode(SyntaxKind.QuestionToken), whenTrue, createNode(SyntaxKind.ColonToken), whenFalse, location, flags);
|
||||
}
|
||||
|
||||
export function createParameter2(name: BindingPattern | Identifier, initializer?: Expression, location?: TextRange, flags?: NodeFlags) {
|
||||
return factory.createParameter(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
/*dotDotDotToken*/ undefined,
|
||||
name,
|
||||
/*questionToken*/ undefined,
|
||||
/*type*/ undefined,
|
||||
initializer,
|
||||
location,
|
||||
flags
|
||||
);
|
||||
return createParameter(undefined, undefined, undefined, name, undefined, undefined, initializer, location, flags);
|
||||
}
|
||||
|
||||
export function createRestParameter(name: Identifier, location?: TextRange, flags?: NodeFlags) {
|
||||
return factory.createParameter(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
factory.createNode(SyntaxKind.DotDotDotToken),
|
||||
name,
|
||||
/*questionToken*/ undefined,
|
||||
/*type*/ undefined,
|
||||
/*initializer*/ undefined,
|
||||
location,
|
||||
flags
|
||||
);
|
||||
}
|
||||
|
||||
export function createVariableStatement2(declarationList: VariableDeclarationList, location?: TextRange, flags?: NodeFlags) {
|
||||
return factory.createVariableStatement(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
declarationList,
|
||||
location,
|
||||
flags
|
||||
);
|
||||
return createParameter(undefined, undefined, createNode(SyntaxKind.DotDotDotToken), name, undefined, undefined, undefined, location, flags);
|
||||
}
|
||||
|
||||
export function createVariableDeclaration2(name: Identifier | BindingPattern, initializer?: Expression, location?: TextRange, flags?: NodeFlags) {
|
||||
return factory.createVariableDeclaration(
|
||||
name,
|
||||
/*type*/ undefined,
|
||||
initializer,
|
||||
location,
|
||||
flags
|
||||
);
|
||||
return createVariableDeclaration(name, undefined, initializer, location, flags);
|
||||
}
|
||||
|
||||
export function createClassDeclaration2(name: Identifier, heritageClause: HeritageClause, members: ClassElement[], location?: TextRange, flags?: NodeFlags): ClassDeclaration {
|
||||
return factory.createClassDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
name,
|
||||
/*typeParameters*/ undefined,
|
||||
heritageClause ? [heritageClause] : undefined,
|
||||
members,
|
||||
location,
|
||||
flags
|
||||
);
|
||||
export function createVariableStatement2(declarationList: VariableDeclarationList, location?: TextRange, flags?: NodeFlags) {
|
||||
return createVariableStatement(undefined, undefined, declarationList, location, flags);
|
||||
}
|
||||
|
||||
export function createSimpleLetStatement(name: Identifier, initializer: Expression, location?: TextRange, exported?: boolean) {
|
||||
let varDecl = createVariableDeclaration2(name, initializer);
|
||||
let varDeclList = createVariableDeclarationList([varDecl], undefined, NodeFlags.Let);
|
||||
let varStmt = createVariableStatement2(varDeclList, location, exported ? NodeFlags.Export : 0);
|
||||
return varStmt;
|
||||
}
|
||||
|
||||
export function createExportDefaultStatement(expression: Expression): ExportAssignment {
|
||||
return createExportAssignment(undefined, undefined, expression);
|
||||
}
|
||||
|
||||
function createClassHeritageClauses(baseTypeNode: ExpressionWithTypeArguments) {
|
||||
return baseTypeNode ? [createHeritageClause(SyntaxKind.ExtendsKeyword, [baseTypeNode])] : undefined;
|
||||
}
|
||||
|
||||
export function createClassExpression2(name: Identifier, heritageClause: HeritageClause, members: ClassElement[]): ClassExpression {
|
||||
return factory.createClassExpression(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
name,
|
||||
/*typeParameters*/ undefined,
|
||||
heritageClause ? [heritageClause] : undefined,
|
||||
members
|
||||
);
|
||||
export function createClassDeclaration2(name: Identifier, baseTypeNode: ExpressionWithTypeArguments, members: ClassElement[], location?: TextRange, flags?: NodeFlags): ClassDeclaration {
|
||||
return createClassDeclaration(undefined, undefined, name, undefined, createClassHeritageClauses(baseTypeNode), members, location, flags);
|
||||
}
|
||||
|
||||
export function createClassExpression2(name: Identifier, baseTypeNode: ExpressionWithTypeArguments, members: ClassElement[]): ClassExpression {
|
||||
return createClassExpression(undefined, undefined, name, undefined, createClassHeritageClauses(baseTypeNode), members);
|
||||
}
|
||||
|
||||
export function createClassExpression3(baseTypeNode: ExpressionWithTypeArguments, members: ClassElement[]): ClassExpression {
|
||||
return createClassExpression2(undefined, baseTypeNode, members);
|
||||
}
|
||||
|
||||
export function createConstructor2(parameters: Array<ParameterDeclaration>, body: Block, location?: TextRange, flags?: NodeFlags): ConstructorDeclaration {
|
||||
return factory.createConstructor(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
parameters,
|
||||
/*type*/ undefined,
|
||||
body,
|
||||
location,
|
||||
flags
|
||||
);
|
||||
return createConstructor(undefined, undefined, parameters, undefined, body, location, flags);
|
||||
}
|
||||
|
||||
|
||||
export function createMethodDeclaration2(name: PropertyName, parameters: Array<ParameterDeclaration>, body: Block, location?: TextRange, flags?: NodeFlags): MethodDeclaration {
|
||||
return factory.createMethodDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
/*asteriskToken*/ undefined,
|
||||
name,
|
||||
/*typeParameters*/ undefined,
|
||||
parameters,
|
||||
/*type*/ undefined,
|
||||
body,
|
||||
location,
|
||||
flags
|
||||
);
|
||||
return createMethodDeclaration(undefined, undefined, undefined, name, undefined, parameters, undefined, body, location, flags);
|
||||
}
|
||||
|
||||
export function createGetAccessor2(name: PropertyName, parameters: Array<ParameterDeclaration>, body: Block, location?: TextRange, flags?: NodeFlags): GetAccessorDeclaration {
|
||||
return factory.createGetAccessor(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
name,
|
||||
parameters,
|
||||
/*type*/ undefined,
|
||||
body,
|
||||
location,
|
||||
flags
|
||||
);
|
||||
return createGetAccessor(undefined, undefined, name, parameters, undefined, body, location, flags);
|
||||
}
|
||||
|
||||
export function createSetAccessor2(name: PropertyName, parameters: Array<ParameterDeclaration>, body: Block, location?: TextRange, flags?: NodeFlags): SetAccessorDeclaration {
|
||||
return factory.createSetAccessor(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
name,
|
||||
parameters,
|
||||
/*type*/ undefined,
|
||||
body,
|
||||
location,
|
||||
flags
|
||||
);
|
||||
return createSetAccessor(undefined, undefined, name, parameters, undefined, body, location, flags);
|
||||
}
|
||||
|
||||
export function createFunctionDeclaration2(name: Identifier, parameters: ParameterDeclaration[], body: Block, location?: TextRange, flags?: NodeFlags) {
|
||||
return factory.createFunctionDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
/*asteriskToken*/ undefined,
|
||||
name,
|
||||
/*typeParameters*/ undefined,
|
||||
parameters,
|
||||
/*type*/ undefined,
|
||||
body,
|
||||
location,
|
||||
flags
|
||||
);
|
||||
return createFunctionDeclaration(undefined, undefined, undefined, name, undefined, parameters, undefined, body, location, flags);
|
||||
}
|
||||
|
||||
export function createFunctionDeclaration3(asteriskToken: Node, name: Identifier, parameters: ParameterDeclaration[], body: Block, location?: TextRange, flags?: NodeFlags) {
|
||||
return factory.createFunctionDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
asteriskToken,
|
||||
name,
|
||||
/*typeParameters*/ undefined,
|
||||
parameters,
|
||||
/*type*/ undefined,
|
||||
body,
|
||||
location,
|
||||
flags
|
||||
);
|
||||
}
|
||||
return createFunctionDeclaration(undefined, undefined, asteriskToken, name, undefined, parameters, undefined, body, location, flags);
|
||||
}
|
||||
|
||||
export function createFunctionExpression2(name: Identifier, parameters: ParameterDeclaration[], body: Block, location?: TextRange, flags?: NodeFlags) {
|
||||
return factory.createFunctionExpression(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
/*asteriskToken*/ undefined,
|
||||
name,
|
||||
/*typeParameters*/ undefined,
|
||||
parameters,
|
||||
/*type*/ undefined,
|
||||
body,
|
||||
location,
|
||||
flags
|
||||
);
|
||||
return createFunctionExpression(undefined, undefined, undefined, name, undefined, parameters, undefined, body, location, flags);
|
||||
}
|
||||
|
||||
export function createFunctionExpression3(asteriskToken: Node, name: Identifier, parameters: ParameterDeclaration[], body: Block, location?: TextRange, flags?: NodeFlags) {
|
||||
return factory.createFunctionExpression(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
asteriskToken,
|
||||
name,
|
||||
/*typeParameters*/ undefined,
|
||||
parameters,
|
||||
/*type*/ undefined,
|
||||
body,
|
||||
location,
|
||||
flags
|
||||
);
|
||||
return createFunctionExpression(undefined, undefined, asteriskToken, name, undefined, parameters, undefined, body, location, flags);
|
||||
}
|
||||
|
||||
export function createGeneratorFunctionExpression(name: Identifier, parameters: ParameterDeclaration[], body: Block, location?: TextRange, flags?: NodeFlags) {
|
||||
return factory.createFunctionExpression(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
createNode(SyntaxKind.AsteriskToken),
|
||||
name,
|
||||
/*typeParameters*/ undefined,
|
||||
parameters,
|
||||
/*type*/ undefined,
|
||||
body,
|
||||
location,
|
||||
flags
|
||||
);
|
||||
export function createGeneratorFunctionExpression(parameters: ParameterDeclaration[], body: Block, location?: TextRange, flags?: NodeFlags) {
|
||||
return createFunctionExpression(undefined, undefined, createNode(SyntaxKind.AsteriskToken), undefined, undefined, parameters, undefined, body, location, flags);
|
||||
}
|
||||
|
||||
export function createVoidZeroExpression(location?: TextRange, flags?: NodeFlags): VoidExpression {
|
||||
return factory.createVoidExpression(
|
||||
factory.createNumericLiteral2(0),
|
||||
location,
|
||||
flags);
|
||||
return createVoidExpression(createNumericLiteral2(0), location, flags);
|
||||
}
|
||||
|
||||
|
||||
export function createPropertyOrElementAccessExpression(expression: Expression, propName: Identifier | LiteralExpression, location?: TextRange, flags?: NodeFlags): LeftHandSideExpression {
|
||||
if (!nodeIsSynthesized(propName)) {
|
||||
propName = cloneNode(propName);
|
||||
}
|
||||
|
||||
if (propName.kind !== SyntaxKind.Identifier) {
|
||||
return createElementAccessExpression2(expression, propName, location, flags);
|
||||
}
|
||||
|
||||
return createPropertyAccessExpression2(expression, <Identifier>propName, location, flags);
|
||||
return isIdentifier(propName)
|
||||
? createPropertyAccessExpression2(expression, makeSynthesized(propName), location, flags)
|
||||
: createElementAccessExpression2(expression, makeSynthesized(propName), location, flags);
|
||||
}
|
||||
|
||||
export function createElementAccessExpression2(expression: Expression, argumentExpression: Expression, location?: TextRange, flags?: NodeFlags): ElementAccessExpression {
|
||||
return factory.createElementAccessExpression(
|
||||
factory.parenthesizeForAccess(expression),
|
||||
argumentExpression,
|
||||
location,
|
||||
flags
|
||||
);
|
||||
return createElementAccessExpression(parenthesizeForAccess(expression), argumentExpression, location, flags);
|
||||
}
|
||||
|
||||
export function createElementAccessExpression3(expression: Expression, index: number, location?: TextRange, flags?: NodeFlags): ElementAccessExpression {
|
||||
return factory.createElementAccessExpression2(
|
||||
expression,
|
||||
factory.createNumericLiteral2(index),
|
||||
location,
|
||||
flags
|
||||
);
|
||||
return createElementAccessExpression2(expression, createNumericLiteral2(index), location, flags);
|
||||
}
|
||||
|
||||
export function createSliceCall(value: Expression, sliceIndex: number, location?: TextRange, flags?: NodeFlags): CallExpression {
|
||||
return factory.createCallExpression2(
|
||||
factory.createPropertyAccessExpression2(
|
||||
factory.parenthesizeForAccess(value),
|
||||
factory.createIdentifier("slice")
|
||||
),
|
||||
[factory.createNumericLiteral2(sliceIndex)],
|
||||
location,
|
||||
flags
|
||||
);
|
||||
return createCallExpression2(createPropertyAccessExpression3(value, "slice"), [createNumericLiteral2(sliceIndex)], location, flags);
|
||||
}
|
||||
|
||||
export function createApplyCall(target: Expression, thisArg: Expression, _arguments: Expression, location?: TextRange, flags?: NodeFlags) {
|
||||
let applyName = createIdentifier("apply");
|
||||
let propExpr = createPropertyAccessExpression2(target, applyName);
|
||||
return factory.createCallExpression2(propExpr, [thisArg, _arguments], location, flags);
|
||||
return factory.createCallExpression2(createPropertyAccessExpression3(target, "apply"), [thisArg, _arguments], location, flags);
|
||||
}
|
||||
|
||||
export function createExtendsHelperCall(name: Identifier) {
|
||||
let extendsName = factory.createIdentifier("__extends");
|
||||
let superName = factory.createIdentifier("_super");
|
||||
let callExpr = factory.createCallExpression2(extendsName, [name, superName]);
|
||||
return callExpr;
|
||||
return factory.createCallExpression2(createIdentifier("__extends"), [name, createIdentifier("_super")]);
|
||||
}
|
||||
|
||||
export function createAwaiterHelperCall(hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression, body: Block) {
|
||||
let thisExpr = factory.createThisKeyword();
|
||||
let awaiterName = factory.createIdentifier("__awaiter");
|
||||
let argumentsExpr = hasLexicalArguments ? factory.createIdentifier("arguments") : factory.createVoidZeroExpression();
|
||||
let promiseExpr = promiseConstructor ? convertEntityNameToExpression(promiseConstructor) : factory.createIdentifier("Promise");
|
||||
let generatorFunc = factory.createGeneratorFunctionExpression(/*name*/ undefined, [], body);
|
||||
let callExpr = factory.createCallExpression2(awaiterName, [thisExpr, argumentsExpr, promiseExpr, generatorFunc]);
|
||||
return callExpr;
|
||||
let argumentsExpr = hasLexicalArguments ? createIdentifier("arguments") : createVoidZeroExpression();
|
||||
let promiseExpr = promiseConstructor ? convertEntityNameToExpression(promiseConstructor) : createIdentifier("Promise");
|
||||
return createCallExpression2(createIdentifier("__awaiter"), [createThisKeyword(), argumentsExpr, promiseExpr, createGeneratorFunctionExpression([], body)]);
|
||||
}
|
||||
|
||||
function convertEntityNameToExpression(node: EntityName | Expression): Expression {
|
||||
if (isQualifiedName(node)) {
|
||||
let left = convertEntityNameToExpression(node.left);
|
||||
let right = factory.cloneNode(node.right);
|
||||
return factory.createPropertyAccessExpression2(left, right);
|
||||
}
|
||||
else {
|
||||
return factory.cloneNode(node);
|
||||
}
|
||||
return isQualifiedName(node) ? createPropertyAccessExpression2(convertEntityNameToExpression(node.left), cloneNode(node.right)) : cloneNode(node);
|
||||
}
|
||||
|
||||
export function createDecorateHelperCall(decoratorExpressions: Expression[], target: Expression, memberName?: Expression, descriptor?: Expression) {
|
||||
let _arguments: Expression[] = [
|
||||
factory.createArrayLiteralExpression(decoratorExpressions),
|
||||
target
|
||||
];
|
||||
if (memberName) {
|
||||
_arguments.push(memberName);
|
||||
if (descriptor) {
|
||||
_arguments.push(descriptor);
|
||||
}
|
||||
}
|
||||
let decorateHelperName = factory.createIdentifier("__decorate");
|
||||
let decoratorsExpr = factory.createArrayLiteralExpression(decoratorExpressions);
|
||||
let callExpr = factory.createCallExpression2(decorateHelperName, _arguments);
|
||||
return callExpr;
|
||||
return createCallExpression2(createIdentifier("__decorate"), append([createArrayLiteralExpression(decoratorExpressions), target], memberName, descriptor));
|
||||
}
|
||||
|
||||
export function createParamHelperCall(parameterIndex: number, decoratorExpression: Expression) {
|
||||
let paramHelperName = factory.createIdentifier("__param");
|
||||
let parameterIndexExpr = factory.createNumericLiteral(String(parameterIndex));
|
||||
let callExpr = factory.createCallExpression2(paramHelperName, [parameterIndexExpr, decoratorExpression]);
|
||||
return callExpr;
|
||||
return createCallExpression2(createIdentifier("__param"), [createNumericLiteral2(parameterIndex), decoratorExpression]);
|
||||
}
|
||||
|
||||
export function createMetadataHelperCall(metadataKey: string, metadataValue: Expression) {
|
||||
let metadataHelperName = factory.createIdentifier("__metadata");
|
||||
let metadataKeyExpr = factory.createStringLiteral(metadataKey);
|
||||
let callExpr = factory.createCallExpression2(metadataHelperName, [metadataKeyExpr, metadataValue]);
|
||||
return callExpr;
|
||||
return createCallExpression2(createIdentifier("__metadata"), [createStringLiteral(metadataKey), metadataValue]);
|
||||
}
|
||||
|
||||
export function createDefinePropertyCall(target: Expression, memberName: Expression, descriptor: Expression) {
|
||||
let globalObjectName = factory.createIdentifier("Object");
|
||||
let definePropertyName = factory.createIdentifier("defineProperty");
|
||||
let propExpr = factory.createPropertyAccessExpression(globalObjectName, factory.createNode(SyntaxKind.DotToken), definePropertyName);
|
||||
let callExpr = factory.createCallExpression2(propExpr, [target, memberName, descriptor]);
|
||||
return callExpr;
|
||||
return createCallExpression2(createPropertyAccessExpression3(createIdentifier("Object"), "defineProperty"), [target, memberName, descriptor]);
|
||||
}
|
||||
|
||||
export function createGetOwnPropertyDescriptorCall(target: Expression, memberName: Expression) {
|
||||
let globalObjectName = factory.createIdentifier("Object");
|
||||
let getOwnPropertyDescriptorName = factory.createIdentifier("getOwnPropertyDescriptor");
|
||||
let propExpr = factory.createPropertyAccessExpression(globalObjectName, factory.createNode(SyntaxKind.DotToken), getOwnPropertyDescriptorName);
|
||||
let callExpr = factory.createCallExpression2(propExpr, [target, memberName]);
|
||||
return callExpr;
|
||||
return createCallExpression2(createPropertyAccessExpression3(createIdentifier("Object"), "getOwnPropertyDescriptor"), [target, memberName]);
|
||||
}
|
||||
|
||||
export function createDefaultValueCheck(value: Expression, defaultValue: Expression, ensureIdentifier: (value: Expression) => Expression, location?: TextRange, flags?: NodeFlags): Expression {
|
||||
@@ -609,45 +393,16 @@ namespace ts {
|
||||
return factory.createConditionalExpression2(factory.createStrictEqualityExpression(value, factory.createVoidZeroExpression()), defaultValue, value, location, flags);
|
||||
}
|
||||
|
||||
export function createMemberAccessForPropertyName(target: Expression, memberName: DeclarationName, location?: TextRange, flags?: NodeFlags): MemberExpression {
|
||||
if (isStringLiteral(memberName) || isNumericLiteral(memberName)) {
|
||||
return factory.createElementAccessExpression2(
|
||||
target,
|
||||
cloneNode(memberName),
|
||||
location,
|
||||
flags
|
||||
);
|
||||
}
|
||||
else if (isComputedPropertyName(memberName)) {
|
||||
// TODO(rbuckton): Decorators? Will be handled higher in the stack I think.
|
||||
return factory.createElementAccessExpression2(
|
||||
target,
|
||||
cloneNode(memberName.expression),
|
||||
location,
|
||||
flags
|
||||
);
|
||||
}
|
||||
else {
|
||||
return factory.createPropertyAccessExpression2(
|
||||
target,
|
||||
cloneNode(<Identifier>memberName),
|
||||
location,
|
||||
flags
|
||||
)
|
||||
}
|
||||
export function createMemberAccessForPropertyName(target: Expression, memberName: PropertyName, location?: TextRange, flags?: NodeFlags): MemberExpression {
|
||||
return isIdentifier(memberName)
|
||||
? createPropertyAccessExpression2(target, cloneNode(memberName), location, flags)
|
||||
: isComputedPropertyName(memberName)
|
||||
? createElementAccessExpression2(target, cloneNode(memberName.expression), location, flags)
|
||||
: createElementAccessExpression2(target, cloneNode(memberName), location, flags);
|
||||
}
|
||||
|
||||
export function inlineExpressions(expressions: Expression[]) {
|
||||
let expression = expressions[0];
|
||||
for (let i = 1; i < expressions.length; i++) {
|
||||
expression = createBinaryExpression2(
|
||||
expression,
|
||||
SyntaxKind.CommaToken,
|
||||
expressions[i]
|
||||
);
|
||||
}
|
||||
|
||||
return expression;
|
||||
return reduceLeft(expressions, createCommaExpression);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -418,6 +418,10 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export function skipTrivia(text: string, pos: number, stopAfterLineBreak?: boolean): number {
|
||||
if (pos < 0) {
|
||||
return pos;
|
||||
}
|
||||
|
||||
// Keep in sync with couldStartTrivia
|
||||
while (true) {
|
||||
let ch = text.charCodeAt(pos);
|
||||
|
||||
+114
-91
@@ -1,6 +1,6 @@
|
||||
/// <reference path="factory.ts" />
|
||||
/// <reference path="transform.generated.ts" />
|
||||
const FORCE_TRANSFORMS = false;
|
||||
const FORCE_TRANSFORMS = true;
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
@@ -255,10 +255,13 @@ namespace ts {
|
||||
}
|
||||
|
||||
export type Visitor = (input: Node, output: (node: Node) => void) => void;
|
||||
export type PipelineOutput<TOut extends Node> = (node: TOut) => void;
|
||||
export type Pipeline<TIn extends Node, TOut extends Node> = (input: TIn, output: PipelineOutput<TOut>) => void;
|
||||
export type NodeTest<T extends Node> = (node: Node) => node is T;
|
||||
|
||||
|
||||
export const enum VisitorFlags {
|
||||
NewLexicalEnvironment = 1 << 1,
|
||||
PreserveStack = 1 << 2,
|
||||
ReturnUndefinedIfEmpty = 1 << 3,
|
||||
}
|
||||
|
||||
@@ -591,6 +594,24 @@ namespace ts {
|
||||
transformFlags |= aggregateTransformFlagsForThisNodeAndSubtree(child);
|
||||
}
|
||||
|
||||
function verifyNode<TOut extends Node>(node: Node, nodeTestCallback: (node: Node) => node is TOut): node is TOut {
|
||||
if (!nodeTestCallback(node)) {
|
||||
Debug.fail("Incorrect node kind after visit");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function writeNodeToPipeline<TOut extends Node>(node: Node, output: (node: TOut) => void, nodeTest: (node: Node) => node is TOut): void {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (verifyNode(node, nodeTest)) {
|
||||
output(node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A function passed to a visitor callback that can be used to write a single node.
|
||||
* @param node The node to write
|
||||
@@ -689,43 +710,20 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function pipeOne(input: Node, output: (node: Node) => void, visitor: Visitor, flags: VisitorFlags): void {
|
||||
if (!(flags & VisitorFlags.PreserveStack)) {
|
||||
nodeStack.pushNode(input);
|
||||
visitor(input, output);
|
||||
nodeStack.popNode();
|
||||
}
|
||||
else {
|
||||
visitor(input, output);
|
||||
}
|
||||
function addNodeTestToPipeline<TOut extends Node>(output: (node: TOut) => void, nodeTest: (node: Node) => node is TOut): (node: TOut) => void {
|
||||
return (node: Node) => writeNodeToPipeline<TOut>(node, output, nodeTest);
|
||||
}
|
||||
|
||||
function pipeMany(input: Node[], output: (node: Node) => void, visitor: Visitor, flags: VisitorFlags): void {
|
||||
if (!(flags & VisitorFlags.PreserveStack)) {
|
||||
// For perf reasons, we push `undefined` as the current node and set it to the correct
|
||||
// value for each iteration of the loop below. This avoids excessive push and pop
|
||||
// operations on `ancestorStack`.
|
||||
nodeStack.pushNode(/*node*/ undefined);
|
||||
|
||||
// Visit each input node
|
||||
for (let i = 0, l = input.length; i < l; ++i) {
|
||||
let currentNode = input[i];
|
||||
nodeStack.setNode(currentNode);
|
||||
visitor(currentNode, output);
|
||||
}
|
||||
|
||||
// For the perf reasons mentioned above, we pop the current node at the end of the loop.
|
||||
nodeStack.popNode();
|
||||
}
|
||||
else {
|
||||
for (let node of input) {
|
||||
visitor(node, output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function pipeOneOrMany<T extends Node | Node[]>(input: T, output: (node: Node) => void, visitor: Visitor, flags: VisitorFlags, pipe: (input: T, output: (node: Node) => void, visitor: Visitor, flags: VisitorFlags) => void): void {
|
||||
if (!input) {
|
||||
/**
|
||||
* Pipes an input node (or nodes) into an output callback by passing it through a visitor callback.
|
||||
* @remarks
|
||||
* The primary responsibility of `pipeOneOrMany` is to execute the `visitor` callback for each
|
||||
* input node, passing the input node and the output callback.
|
||||
* This function also manages when new lexical environments are introduced, and tracks temporary
|
||||
* variables and hoisted variable and function declarations.
|
||||
*/
|
||||
function pipeOneOrMany<TIn extends Node, TOut extends Node>(inputNode: TIn, inputNodes: TIn[], pipeline: Visitor, output: (node: TOut) => void, flags: VisitorFlags, nodeTest: (node: Node) => node is TOut): void {
|
||||
if (!inputNode && !inputNodes) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -746,21 +744,44 @@ namespace ts {
|
||||
hoistedFunctionDeclarations = undefined;
|
||||
}
|
||||
|
||||
pipe(input, output, visitor, flags & ~VisitorFlags.NewLexicalEnvironment);
|
||||
// If a node test was supplied, we need to wrap the output with an assertion
|
||||
if (nodeTest) {
|
||||
output = addNodeTestToPipeline(output, nodeTest);
|
||||
}
|
||||
|
||||
if (inputNode) {
|
||||
let nodeWasPushed = nodeStack.tryPushNode(inputNode);
|
||||
pipeline(inputNode, output);
|
||||
if (nodeWasPushed) {
|
||||
nodeStack.popNode();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// For perf reasons, we push `undefined` as the current node and set it to the correct
|
||||
// value for each iteration of the loop below. This avoids excessive push and pop
|
||||
// operations on `nodeStack`.
|
||||
nodeStack.pushNode(/*node*/ undefined);
|
||||
|
||||
// Visit each input node
|
||||
for (let node of inputNodes) {
|
||||
nodeStack.setNode(node);
|
||||
pipeline(node, output);
|
||||
}
|
||||
|
||||
// For the perf reasons mentioned above, we pop the current node at the end of the loop.
|
||||
nodeStack.popNode();
|
||||
}
|
||||
|
||||
// If we established a new lexical environment, we need to write any hoisted variables or
|
||||
// function declarations to the end of the output.
|
||||
if (flags & VisitorFlags.NewLexicalEnvironment) {
|
||||
if (hoistedVariableDeclarations) {
|
||||
output(factory.createVariableStatement2(
|
||||
factory.createVariableDeclarationList(
|
||||
hoistedVariableDeclarations
|
||||
)
|
||||
));
|
||||
var stmt = factory.createVariableStatement2(factory.createVariableDeclarationList(hoistedVariableDeclarations));
|
||||
output(<TOut><Node>stmt);
|
||||
}
|
||||
else if (hoistedFunctionDeclarations) {
|
||||
for (let decl of hoistedFunctionDeclarations) {
|
||||
output(decl);
|
||||
output(<TOut><Node>decl);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -770,33 +791,11 @@ namespace ts {
|
||||
hoistedFunctionDeclarations = savedHoistedFunctionDeclarations;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the result from visiting a single input node to an output node array.
|
||||
* @param input The source node to visit.
|
||||
* @param output The destination node array to which to write the results from visiting each node.
|
||||
* @param visitor The callback to execute as we visit each node in the source.
|
||||
* @param newLexicalEnvironment A value that indicates whether this pipeline starts a new lexical environment.
|
||||
*/
|
||||
export function pipeNode(input: Node, output: (node: Node) => void, visitor: Visitor, flags?: VisitorFlags): void {
|
||||
pipeOneOrMany(input, output, visitor, flags, pipeOne);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pipelines the results of visiting each node from an input source to an output callback function.
|
||||
* @param input The source nodes to visit.
|
||||
* @param output The callback passed to `visitor` (below) to write each visited node.
|
||||
* @param visitor The callback to execute as we visit each node in the source.
|
||||
* @param newLexicalEnvironment A value that indicates whether this pipeline starts a new lexical environment.
|
||||
*/
|
||||
export function pipeNodes(input: Node[], output: (node: Node) => void, visitor: Visitor, flags?: VisitorFlags): void {
|
||||
pipeOneOrMany(input, output, visitor, flags, pipeMany);
|
||||
}
|
||||
|
||||
function emitOneOrMany<T extends Node | Node[]>(input: T, output: Node[], visitor: Visitor, flags: VisitorFlags, pipe: (input: T, output: (node: Node) => void, visitor: Visitor, flags: VisitorFlags) => void): void {
|
||||
|
||||
function emitOneOrMany<TIn extends Node, TOut extends Node>(inputNode: TIn, inputNodes: TIn[], pipeline: Pipeline<TIn, TOut>, output: TOut[], flags: VisitorFlags, nodeTest: (node: Node) => node is TOut): TOut[] {
|
||||
// Exit early if we have nothing to do
|
||||
if (!input) {
|
||||
return;
|
||||
if (!inputNode && !inputNodes) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Preserve the current environment on the call stack as we descend into the tree
|
||||
@@ -811,40 +810,64 @@ namespace ts {
|
||||
offsetWritten = 0;
|
||||
writeNodeToNodeArrayFastOrSlow = writeNodeToNodeArrayFast;
|
||||
|
||||
pipe(input, writeNodeToNodeArray, visitor, flags | VisitorFlags.PreserveStack);
|
||||
pipeOneOrMany<TIn, TOut>(inputNode, inputNodes, pipeline, writeNodeToNodeArray, flags, nodeTest);
|
||||
|
||||
// Restore previous environment
|
||||
originalNodes = savedOriginalNodes;
|
||||
updatedNodes = savedUpdatedNodes;
|
||||
offsetWritten = savedOffsetWritten;
|
||||
writeNodeToNodeArrayFastOrSlow = savedWriteNodeToNodeArrayFastOrSlow;
|
||||
writeNodeToNodeArrayFastOrSlow = savedWriteNodeToNodeArrayFastOrSlow;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pipelines the results of visiting a single input node to an output callback function.
|
||||
* @param input The source node to visit.
|
||||
* @param pipeline The callback to execute as we visit each node in the source.
|
||||
* @param output The callback passed to `visitor` to write each visited node.
|
||||
* @param flags Flags that affect the pipeline.
|
||||
*/
|
||||
export function pipeNode<TIn extends Node, TOut extends Node>(input: TIn, pipeline: Pipeline<TIn, TOut>, output: PipelineOutput<TOut>, flags?: VisitorFlags, nodeTest?: NodeTest<TOut>): void {
|
||||
pipeOneOrMany(input, undefined, pipeline, output, flags, nodeTest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pipelines the results of visiting each node from an input source to an output callback function.
|
||||
* @param input The source nodes to visit.
|
||||
* @param pipeline The callback to execute as we visit each node in the source.
|
||||
* @param output The callback passed to `visitor` to write each visited node.
|
||||
* @param flags Flags that affect the pipeline.
|
||||
*/
|
||||
export function pipeNodes<TIn extends Node, TOut extends Node>(input: TIn[], pipeline: Pipeline<TIn, TOut>, output: PipelineOutput<TOut>, flags?: VisitorFlags, nodeTest?: NodeTest<TOut>): void {
|
||||
pipeOneOrMany(undefined, input, pipeline, output, flags, nodeTest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the result from visiting a single input node to an output node array.
|
||||
* @param input The source node to visit.
|
||||
* @param pipeline The callback to execute as we visit each node in the source.
|
||||
* @param output The destination node array to which to write the results from visiting each node.
|
||||
* @param visitor The callback to execute as we visit each node in the source.
|
||||
* @param newLexicalEnvironment A value that indicates whether this pipeline starts a new lexical environment.
|
||||
* @param flags Flags that affect the pipeline.
|
||||
*/
|
||||
export function emitNode(input: Node, output: Node[], visitor: (input: Node, write: (output: Node) => void) => void, flags?: VisitorFlags): void {
|
||||
emitOneOrMany(input, output, visitor, flags, pipeOne);
|
||||
export function emitNode<TIn extends Node, TOut extends Node>(input: TIn, pipeline: Pipeline<TIn, TOut>, output: TOut[], flags?: VisitorFlags, nodeTest?: NodeTest<TOut>): void {
|
||||
emitOneOrMany(input, undefined, pipeline, output, flags, nodeTest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the result from visiting each node from an input source to an output node array.
|
||||
* @param input The source nodes to visit.
|
||||
* @param pipeline The callback to execute as we visit each node in the source.
|
||||
* @param output The destination node array to which to write the results from visiting each node.
|
||||
* @param visitor The callback to execute as we visit each node in the source.
|
||||
* @param newLexicalEnvironment A value that indicates whether this pipeline starts a new lexical environment.
|
||||
* @param flags Flags that affect the pipeline.
|
||||
*/
|
||||
export function emitNodes(input: Node[], output: Node[], visitor: (input: Node, write: (output: Node) => void) => void, flags?: VisitorFlags): void {
|
||||
emitOneOrMany(input, output, visitor, flags, pipeMany);
|
||||
export function emitNodes<TIn extends Node, TOut extends Node>(input: TIn[], pipeline: Pipeline<TIn, TOut>, output: TOut[], flags?: VisitorFlags, nodeTest?: NodeTest<TOut>): void {
|
||||
emitOneOrMany(undefined, input, pipeline, output, flags, nodeTest);
|
||||
}
|
||||
|
||||
export function visitNode<T extends Node>(node: T, visitor: (input: Node, write: (node: Node) => void) => void, flags?: VisitorFlags): T;
|
||||
export function visitNode<TIn extends Node, TOut extends Node>(node: TIn, visitor: (input: TIn, write: (node: TOut) => void) => void, flags?: VisitorFlags): TOut;
|
||||
export function visitNode<TIn extends Node, TOut extends Node>(node: TIn, visitor: (input: TIn, write: (node: TOut) => void) => void, flags?: VisitorFlags): TOut {
|
||||
export function visitNode<T extends Node>(node: T, visitor: Visitor, flags?: VisitorFlags): T;
|
||||
export function visitNode<TIn extends Node, TOut extends Node>(node: TIn, visitor: Visitor, flags?: VisitorFlags, nodeTest?: (node: Node) => node is TOut): TOut;
|
||||
export function visitNode<TIn extends Node, TOut extends Node>(node: TIn, visitor: Visitor, flags?: VisitorFlags, nodeTest?: (node: Node) => node is TOut): TOut {
|
||||
if (!node) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -854,7 +877,7 @@ namespace ts {
|
||||
updatedNode = undefined;
|
||||
writeNodeFastOrSlow = writeNodeSlow;
|
||||
|
||||
pipeNode(node, writeNode, visitor, flags);
|
||||
pipeNode<TIn, TOut>(node, visitor, writeNode, flags, nodeTest);
|
||||
|
||||
let visited = <TOut>readNode();
|
||||
updatedNode = savedUpdatedNode;
|
||||
@@ -863,7 +886,7 @@ namespace ts {
|
||||
return visited;
|
||||
}
|
||||
|
||||
export function visitStatement(node: Statement, visitor: (input: Node, write: (node: Node) => void) => void, flags?: VisitorFlags) {
|
||||
export function visitStatement(node: Statement, visitor: Visitor, flags?: VisitorFlags) {
|
||||
if (!node) {
|
||||
return node;
|
||||
}
|
||||
@@ -876,7 +899,7 @@ namespace ts {
|
||||
updatedBlock = undefined;
|
||||
writeStatementFastOrSlow = writeStatementSlow;
|
||||
|
||||
pipeNode(node, writeStatement, visitor, flags);
|
||||
pipeNode<Statement, Statement>(node, visitor, writeStatement, flags, isStatementNode);
|
||||
|
||||
let visited = readStatement();
|
||||
updatedStatement = savedUpdatedStatement;
|
||||
@@ -886,9 +909,9 @@ namespace ts {
|
||||
return visited;
|
||||
}
|
||||
|
||||
export function visitNodes<T extends Node>(nodes: T[], visitor: (input: Node, output: (node: Node) => void) => void, flags?: VisitorFlags): NodeArray<T>;
|
||||
export function visitNodes<TIn extends Node, TOut extends Node>(nodes: TIn[], visitor: (input: TIn, output: (node: TOut) => void) => void, flags?: VisitorFlags): NodeArray<TOut>;
|
||||
export function visitNodes<TIn extends Node, TOut extends Node>(nodes: TIn[], visitor: (input: TIn, output: (node: TOut) => void) => void, flags?: VisitorFlags): NodeArray<TOut> {
|
||||
export function visitNodes<T extends Node>(nodes: T[], visitor: Visitor, flags?: VisitorFlags): NodeArray<T>;
|
||||
export function visitNodes<TIn extends Node, TOut extends Node>(nodes: TIn[], visitor: Visitor, flags?: VisitorFlags): NodeArray<TOut>;
|
||||
export function visitNodes<TIn extends Node, TOut extends Node>(nodes: TIn[], visitor: Visitor, flags?: VisitorFlags, nodeTest?: (node: Node) => node is TOut): NodeArray<TOut> {
|
||||
// Exit early if we have nothing to do
|
||||
if (!nodes) {
|
||||
return undefined;
|
||||
@@ -907,7 +930,7 @@ namespace ts {
|
||||
writeNodeToNodeArrayFastOrSlow = writeNodeToNodeArraySlow;
|
||||
|
||||
// Pipe each node from input into output
|
||||
pipeNodes(originalNodes, writeNodeToNodeArray, visitor, flags);
|
||||
pipeNodes<TIn, TOut>(nodes, visitor, writeNodeToNodeArray, flags, nodeTest);
|
||||
|
||||
let visited = readNodeArray(flags);
|
||||
|
||||
@@ -969,7 +992,7 @@ namespace ts {
|
||||
);
|
||||
|
||||
default:
|
||||
if (isExpression(node)) {
|
||||
if (isExpressionNode(node)) {
|
||||
return visitExpressionFunctionBodyInNewLexicalEnvironment(node, visitor);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -115,7 +115,7 @@ namespace ts.transform {
|
||||
function transformClassLikeDeclaration(node: ClassLikeDeclaration, name: Identifier): LeftHandSideExpression {
|
||||
let baseTypeNode = getClassExtendsHeritageClauseElement(node);
|
||||
let classBody = factory.createBlock([]);
|
||||
emitNode(node, classBody.statements, transformClassBody);
|
||||
emitNode(node, transformClassBody, classBody.statements);
|
||||
|
||||
let superExpr = baseTypeNode ? visitNode(baseTypeNode.expression, transformNode) : undefined;
|
||||
let superName = baseTypeNode ? factory.createIdentifier("_super") : undefined;
|
||||
@@ -153,7 +153,7 @@ namespace ts.transform {
|
||||
let body = factory.createBlock([]);
|
||||
|
||||
if (constructor) {
|
||||
emitNode(constructor, body.statements, transformConstructor, VisitorFlags.NewLexicalEnvironment);
|
||||
emitNode(constructor, transformConstructor, body.statements, VisitorFlags.NewLexicalEnvironment);
|
||||
}
|
||||
else if (baseTypeNode) {
|
||||
let superCall = createDefaultSuperCall();
|
||||
@@ -168,7 +168,7 @@ namespace ts.transform {
|
||||
emitCaptureThisForNode(constructor, write);
|
||||
emitDefaultValueAssignments(constructor, write);
|
||||
emitRestParameter(constructor, write);
|
||||
pipeNodes(constructor.body.statements, write, transformNode);
|
||||
pipeNodes(constructor.body.statements, transformNode, write);
|
||||
}
|
||||
|
||||
function transformParameter(node: ParameterDeclaration, write: (node: ParameterDeclaration) => void) {
|
||||
@@ -194,7 +194,7 @@ namespace ts.transform {
|
||||
|
||||
function emitDefaultValueAssignments(node: FunctionLikeDeclaration, write: (node: Statement) => void) {
|
||||
if (!(node.transformFlags & (TransformFlags.SubtreeContainsParameterInitializer | TransformFlags.SubtreeContainsParameterBindingPattern))) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
for (let parameter of node.parameters) {
|
||||
@@ -453,14 +453,14 @@ namespace ts.transform {
|
||||
function rewriteFunctionExpression(node: FunctionLikeDeclaration, name: Identifier, location: TextRange): FunctionExpression {
|
||||
let parameters = visitNodes(node.parameters, transformNode);
|
||||
let body = factory.createBlock([], node.body);
|
||||
emitNode(node, body.statements, transformFunctionBody, VisitorFlags.NewLexicalEnvironment);
|
||||
emitNode(node, transformFunctionBody, body.statements, VisitorFlags.NewLexicalEnvironment);
|
||||
return factory.createFunctionExpression2(name, parameters, body, location);
|
||||
}
|
||||
|
||||
function transformFunctionDeclaration(node: FunctionDeclaration, write: (node: Statement) => void): void {
|
||||
let parameters = visitNodes(node.parameters, transformNode);
|
||||
let body = factory.createBlock([], node.body);
|
||||
emitNode(node, body.statements, transformFunctionBody, VisitorFlags.NewLexicalEnvironment);
|
||||
emitNode(node, transformFunctionBody, body.statements, VisitorFlags.NewLexicalEnvironment);
|
||||
write(factory.createFunctionDeclaration2(node.name, parameters, body, /*location*/ node));
|
||||
}
|
||||
|
||||
@@ -469,7 +469,7 @@ namespace ts.transform {
|
||||
|
||||
let parameters = visitNodes(node.parameters, transformNode);
|
||||
let newBody = factory.createBlock([], /*location*/ isBlock(node.body) ? node.body : undefined);
|
||||
emitNode(node, newBody.statements, transformFunctionBody, VisitorFlags.NewLexicalEnvironment);
|
||||
emitNode(node, transformFunctionBody, newBody.statements, VisitorFlags.NewLexicalEnvironment);
|
||||
|
||||
let func = createfn(name, parameters, newBody, location);
|
||||
return func;
|
||||
@@ -482,7 +482,7 @@ namespace ts.transform {
|
||||
|
||||
let body = node.body;
|
||||
if (isBlock(body)) {
|
||||
pipeNodes(body.statements, write, transformNode);
|
||||
pipeNodes(body.statements, transformNode, write);
|
||||
}
|
||||
else {
|
||||
let expr = visitNode(body, transformNode);
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace ts.transform {
|
||||
* @param context Context information for the transform.
|
||||
* @param node The node to transform.
|
||||
*/
|
||||
function transformNodeWorker(node: Node, write?: (node: Node) => void): void {
|
||||
function transformNodeWorker(node: Node, write: (node: Node) => void): void {
|
||||
// TypeScript ambient declarations are elided.
|
||||
if (node.flags & NodeFlags.Ambient) {
|
||||
return;
|
||||
@@ -120,10 +120,6 @@ namespace ts.transform {
|
||||
// TypeScript property declarations are elided.
|
||||
return;
|
||||
|
||||
case SyntaxKind.IndexSignature:
|
||||
// TypeScript index signatures are elided.
|
||||
return;
|
||||
|
||||
case SyntaxKind.Constructor:
|
||||
// TypeScript constructors are elided. The constructor of a class will be
|
||||
// reordered to the start of the member list in `transformClassDeclaration`.
|
||||
@@ -240,36 +236,33 @@ namespace ts.transform {
|
||||
return accept(node, transformNode, write);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Transforms a TypeScript class declaration with syntax extensions into compatible ES6.
|
||||
* @param context Context information for the transform.
|
||||
* @param node The node to transform.
|
||||
*/
|
||||
function transformClassDeclaration(node: ClassDeclaration, write: (node: Statement) => void) {
|
||||
let thisNodeIsNamespaceExport = isNamespaceLevelExport(node);
|
||||
let name = getDeclarationName(node);
|
||||
let heritageClauses = visitNodes(node.heritageClauses, transformNode);
|
||||
let extendsClause = heritageClauses && firstOrUndefined(heritageClauses);
|
||||
let baseTypeNode = extendsClause && firstOrUndefined(extendsClause.types);
|
||||
let baseTypeNode = visitAndGetClassExtendsHeritageClauseElement(node);
|
||||
let classMembers: ClassElement[] = [];
|
||||
let constructor = transformConstructor(node, baseTypeNode);
|
||||
let members = visitNodes(node.members, transformNode);
|
||||
let classMembers: ClassElement[] = constructor ? [constructor, ...members] : members;
|
||||
|
||||
if (constructor) {
|
||||
classMembers.push(constructor);
|
||||
}
|
||||
|
||||
emitNodes(node.members, transformNode, classMembers);
|
||||
|
||||
if (nodeIsDecorated(node)) {
|
||||
let classExpr = factory.createClassExpression2(/*name*/ undefined, extendsClause, classMembers);
|
||||
let varDecl = factory.createVariableDeclaration2(name, classExpr);
|
||||
let varDeclList = factory.createVariableDeclarationList([varDecl], /*location*/ undefined, NodeFlags.Let);
|
||||
let exportFlags = isTopLevelNonDefaultExport(node) ? NodeFlags.Export : undefined;
|
||||
let varStmt = factory.createVariableStatement2(varDeclList, /*location*/ node, exportFlags);
|
||||
// If the class has been decorated, we need to emit the class as part of a `let` declaration
|
||||
// to avoid the pitfalls of the doubly-bound class name.
|
||||
let classExpr = factory.createClassExpression3(baseTypeNode, classMembers);
|
||||
let varStmt = factory.createSimpleLetStatement(getDeclarationName(node), classExpr, /*location*/ node, isTopLevelNonDefaultExport(node));
|
||||
varStmt.original = node;
|
||||
write(varStmt);
|
||||
}
|
||||
else {
|
||||
let exportFlags = thisNodeIsNamespaceExport
|
||||
? undefined
|
||||
: node.flags & (NodeFlags.Export | NodeFlags.Default);
|
||||
let classDecl = factory.createClassDeclaration2(name, extendsClause, classMembers, /*location*/ node, exportFlags);
|
||||
let exportFlags = isNamespaceLevelExport(node) ? undefined : node.flags & (NodeFlags.Export | NodeFlags.Default);
|
||||
let classDecl = factory.createClassDeclaration2(getDeclarationName(node), baseTypeNode, classMembers, /*location*/ node, exportFlags);
|
||||
classDecl.original = node;
|
||||
write(classDecl);
|
||||
}
|
||||
@@ -279,50 +272,49 @@ namespace ts.transform {
|
||||
transformDecoratorsOfMembers(node, /*isStatic*/ true, write);
|
||||
transformDecoratorsOfConstructor(node, write);
|
||||
|
||||
if (thisNodeIsNamespaceExport) {
|
||||
let namespaceExportExpr = factory.createAssignmentExpression(getModuleMemberName(node), name);
|
||||
let exprStmt = factory.createExpressionStatement(namespaceExportExpr);
|
||||
write(exprStmt);
|
||||
if (isNamespaceLevelExport(node)) {
|
||||
write(factory.createExpressionStatement(factory.createAssignmentExpression(getModuleMemberName(node), getDeclarationName(node))));
|
||||
}
|
||||
else if (isTopLevelDefaultExport(node) && nodeIsDecorated(node)) {
|
||||
let exportDefaultStmt = factory.createExportAssignment(/*decorators*/ undefined, /*modifiers*/ undefined, name);
|
||||
write(exportDefaultStmt);
|
||||
write(factory.createExportDefaultStatement(getDeclarationName(node)));
|
||||
}
|
||||
}
|
||||
|
||||
function transformClassExpression(node: ClassExpression, write: (node: LeftHandSideExpression) => void) {
|
||||
let name = getDeclarationName(node);
|
||||
let heritageClauses = visitNodes(node.heritageClauses, transformNode);
|
||||
let extendsClause = heritageClauses ? firstOrUndefined(heritageClauses) : undefined;
|
||||
let baseTypeNode = extendsClause ? firstOrUndefined(extendsClause.types) : undefined;
|
||||
let baseTypeNode = visitAndGetClassExtendsHeritageClauseElement(node);
|
||||
let classMembers: ClassElement[] = [];
|
||||
let constructor = transformConstructor(node, baseTypeNode);
|
||||
let members = visitNodes(node.members, transformNodeWorker);
|
||||
let classMembers = constructor ? [constructor, ...members] : members;
|
||||
|
||||
let newNode = factory.createClassExpression2(
|
||||
name,
|
||||
extendsClause,
|
||||
classMembers
|
||||
);
|
||||
if (constructor) {
|
||||
classMembers.push(constructor);
|
||||
}
|
||||
|
||||
emitNodes(node.members, transformNode, classMembers);
|
||||
|
||||
let classExpr = factory.createClassExpression2(getDeclarationName(node), baseTypeNode, classMembers);
|
||||
let staticPropertyAssignments = getInitializedProperties(node, /*isStatic*/ true);
|
||||
if (staticPropertyAssignments) {
|
||||
let expressions: Expression[] = [];
|
||||
let tempVar = declareLocal();
|
||||
let cacheExpr = factory.createAssignmentExpression(tempVar, newNode);
|
||||
let cacheExpr = factory.createAssignmentExpression(tempVar, classExpr);
|
||||
expressions.push(cacheExpr);
|
||||
transformPropertyDeclarationsToExpressions(node, staticPropertyAssignments, expressions);
|
||||
expressions.push(tempVar);
|
||||
write(factory.createParenthesizedExpression(factory.inlineExpressions(expressions)));
|
||||
}
|
||||
else {
|
||||
write(newNode);
|
||||
write(classExpr);
|
||||
}
|
||||
}
|
||||
|
||||
function visitAndGetClassExtendsHeritageClauseElement(node: ClassLikeDeclaration) {
|
||||
let heritageClauses = visitNodes(node.heritageClauses, transformNode);
|
||||
let extendsClause = heritageClauses && firstOrUndefined(heritageClauses);
|
||||
let baseTypeNode = extendsClause && firstOrUndefined(extendsClause.types);
|
||||
return baseTypeNode;
|
||||
}
|
||||
|
||||
function isTopLevelExport(node: Node) {
|
||||
return !!(node.flags & NodeFlags.Export) &&
|
||||
getParentNode().kind === SyntaxKind.SourceFile;
|
||||
return !!(node.flags & NodeFlags.Export) && isSourceFile(getParentNode());
|
||||
}
|
||||
|
||||
function isTopLevelDefaultExport(node: Node) {
|
||||
@@ -334,8 +326,7 @@ namespace ts.transform {
|
||||
}
|
||||
|
||||
function isNamespaceLevelExport(node: Node) {
|
||||
return !!(node.flags & NodeFlags.Export) &&
|
||||
getParentNode().kind !== SyntaxKind.SourceFile;
|
||||
return !!(node.flags & NodeFlags.Export) && !isSourceFile(getParentNode());
|
||||
}
|
||||
|
||||
function getContainingModule(): ModuleDeclaration {
|
||||
@@ -366,53 +357,29 @@ namespace ts.transform {
|
||||
let constructor = getFirstConstructorWithBody(node);
|
||||
let parameterPropertyAssignments = constructor ? getParametersWithPropertyAssignments(constructor) : undefined;
|
||||
let instancePropertyAssignments = getInitializedProperties(node, /*isStatic*/ false);
|
||||
// let leadingCommentRanges: CommentRange[];
|
||||
// let trailingCommentRanges: CommentRange[];
|
||||
// for (let member of node.members) {
|
||||
// if (isConstructor(member) && !member.body) {
|
||||
// let leadingCommentRangesOfMember = context.getLeadingCommentRanges(member, /*onlyPinnedOrTripleSlashComments*/ true);
|
||||
// leadingCommentRanges = concatenate(leadingCommentRanges, leadingCommentRangesOfMember);
|
||||
// }
|
||||
// }
|
||||
|
||||
// For target ES6 and above, if there is no property assignment
|
||||
// do not emit constructor in class declaration.
|
||||
if (!parameterPropertyAssignments && !instancePropertyAssignments) {
|
||||
// if (leadingCommentRanges) {
|
||||
// leadingCommentRanges = concatenate(leadingCommentRanges, context.getLeadingCommentRanges(ctor));
|
||||
// ctor = factory.cloneNode(ctor);
|
||||
// factory.attachCommentRanges(ctor, leadingCommentRanges, trailingCommentRanges);
|
||||
// }
|
||||
|
||||
return constructor;
|
||||
}
|
||||
|
||||
|
||||
let parameters =
|
||||
constructor ? visitNodes(constructor.parameters, transformNode) :
|
||||
baseTypeNode ? [factory.createRestParameter(factory.createIdentifier("args"), /*location*/ undefined, NodeFlags.GeneratedRest)] :
|
||||
[];
|
||||
|
||||
// let parameters =
|
||||
// constructor ? transformSignatureParameters(constructor.parameters) :
|
||||
// hasBaseType ? [factory.createRestParameter(tag_id`args`, /*location*/ undefined, NodeFlags.GeneratedRest)] :
|
||||
// [];
|
||||
|
||||
let parameters = constructor
|
||||
? visitNodes(constructor.parameters, transformNode)
|
||||
: baseTypeNode
|
||||
? [factory.createRestParameter(factory.createIdentifier("args"), /*location*/ undefined, NodeFlags.GeneratedRest)]
|
||||
: [];
|
||||
|
||||
let statements: Statement[] = [];
|
||||
let superCall: ExpressionStatement;
|
||||
if (constructor) {
|
||||
// leadingCommentRanges = concatenate(
|
||||
// leadingCommentRanges,
|
||||
// context.getLeadingCommentRanges(ctor)
|
||||
// );
|
||||
// trailingCommentRanges = context.getTrailingCommentRanges(ctor);
|
||||
|
||||
if (baseTypeNode) {
|
||||
superCall = findInitialSuperCall(constructor);
|
||||
if (superCall) {
|
||||
statements.push(superCall);
|
||||
}
|
||||
}
|
||||
|
||||
if (parameterPropertyAssignments) {
|
||||
for (let parameter of parameterPropertyAssignments) {
|
||||
let name = <Identifier>factory.cloneNode(parameter.name);
|
||||
@@ -438,19 +405,11 @@ namespace ts.transform {
|
||||
transformPropertyDeclarationsToStatements(node, instancePropertyAssignments, n => { statements.push(n); });
|
||||
|
||||
if (constructor) {
|
||||
let bodyStatements = superCall
|
||||
? constructor.body.statements.slice(1)
|
||||
: constructor.body.statements;
|
||||
statements.push(...visitNodes(bodyStatements, transformNode));
|
||||
let bodyStatements = constructor.body.statements;
|
||||
emitNodes(superCall ? bodyStatements.slice(1) : bodyStatements, transformNode, statements, VisitorFlags.NewLexicalEnvironment);
|
||||
}
|
||||
|
||||
let body = constructor
|
||||
? factory.updateBlock(constructor.body, statements)
|
||||
: factory.createBlock(statements);
|
||||
|
||||
let newConstructor = factory.createConstructor2(parameters, body, /*location*/ constructor);
|
||||
// factory.attachCommentRanges(newConstructor, leadingCommentRanges, trailingCommentRanges);
|
||||
return newConstructor;
|
||||
return factory.createConstructor2(parameters, factory.createBlock(statements), /*location*/ constructor);
|
||||
}
|
||||
|
||||
function transformHeritageClause(node: HeritageClause, write: (node: HeritageClause) => void) {
|
||||
@@ -772,13 +731,14 @@ namespace ts.transform {
|
||||
|
||||
function transformVariableStatement(node: VariableStatement, write: (node: Statement) => void) {
|
||||
// TODO(rbuckton): transform namespace exports for a variable declaration list
|
||||
Debug.assert(isNamespaceLevelExport(node), "Should only reach here for exported variables.");
|
||||
pipeNode(node.declarationList, write, transformVariableDeclarationList);
|
||||
// Debug.assert(isNamespaceLevelExport(node), "Should only reach here for exported variables." + node.declarationList.declarations[0].name);
|
||||
// pipeNode(node.declarationList, write, transformVariableDeclarationList);
|
||||
return accept(node, transformNode, write);
|
||||
}
|
||||
|
||||
function transformVariableDeclarationList(node: VariableDeclarationList, write: (node: Statement) => void) {
|
||||
let expressions: Expression[] = [];
|
||||
emitNodes(node.declarations, expressions, transformVariableDeclaration);
|
||||
emitNodes(node.declarations, transformVariableDeclaration, expressions);
|
||||
|
||||
if (expressions.length) {
|
||||
let exprStmt = factory.createExpressionStatement(factory.inlineExpressions(expressions));
|
||||
|
||||
+7
-7
@@ -561,13 +561,13 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
declare var global: any, require: any;
|
||||
if (typeof global !== "undefined" && Object.prototype.toString.call(global.process) === '[object process]') {
|
||||
try {
|
||||
require("source-map-support").install();
|
||||
}
|
||||
catch (e) { }
|
||||
}
|
||||
// declare var global: any, require: any;
|
||||
// if (typeof global !== "undefined" && Object.prototype.toString.call(global.process) === '[object process]') {
|
||||
// try {
|
||||
// require("source-map-support").install();
|
||||
// }
|
||||
// catch (e) { }
|
||||
// }
|
||||
}
|
||||
|
||||
ts.executeCommandLine(ts.sys.args);
|
||||
|
||||
@@ -638,8 +638,6 @@ namespace ts {
|
||||
|
||||
// @internal
|
||||
export interface ParentNavigator extends ParentNavigable {
|
||||
/** Gets the root node for the current node. */
|
||||
getRoot(): Node;
|
||||
/** Gets the grandparent node for the current node. */
|
||||
getGrandparent(): Node;
|
||||
/** Gets the parent node for the current node. */
|
||||
@@ -650,14 +648,10 @@ namespace ts {
|
||||
getKind(): SyntaxKind;
|
||||
/** Moves the navigator to the parent node of the current node. */
|
||||
moveToParent(): boolean;
|
||||
/** Moves the navigator to the root node of the current node. */
|
||||
moveToRoot(): boolean;
|
||||
}
|
||||
|
||||
// @internal
|
||||
export interface NodeStack extends ParentNavigable {
|
||||
/** Gets the node at the bottom of the stack. */
|
||||
getRoot(): Node;
|
||||
/** Gets the node two steps down from the top of the stack. */
|
||||
getGrandparent(): Node;
|
||||
/** Gets the node one step down from the top of the stack. */
|
||||
@@ -672,6 +666,8 @@ namespace ts {
|
||||
findAncestorNode(match: (node: Node) => boolean): Node;
|
||||
/** Pushes a node onto the stack. */
|
||||
pushNode(node: Node): void;
|
||||
/** Pushes a node onto the stack if it is not already at the top of the stack. */
|
||||
tryPushNode(node: Node): boolean;
|
||||
/** Replaces the node at the top of the stack. */
|
||||
setNode(node: Node): void;
|
||||
/** Pops the top node from the stack. */
|
||||
@@ -1102,6 +1098,7 @@ namespace ts {
|
||||
// checker actually thinks you have something of the right type. Note: the brands are
|
||||
// never actually given values. At runtime they have zero cost.
|
||||
// @kind(SyntaxKind.OmittedExpression)
|
||||
// @nodetest("isExpressionNode")
|
||||
export interface Expression extends Node {
|
||||
_expressionBrand: any;
|
||||
contextualType?: Type; // Used to temporarily assign a contextual type during overload resolution
|
||||
@@ -1372,6 +1369,7 @@ namespace ts {
|
||||
|
||||
export type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement;
|
||||
|
||||
// @nodetest("isStatementNode")
|
||||
export interface Statement extends Node {
|
||||
_statementBrand: any;
|
||||
}
|
||||
|
||||
@@ -918,7 +918,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
/** Returns whether the node is part of an expression. */
|
||||
export function isPartOfExpression(navigable: ParentNavigable): boolean {
|
||||
export function isExpression(navigable: ParentNavigable): boolean {
|
||||
let nav = navigable.createParentNavigator();
|
||||
while (true) {
|
||||
let node = nav.getNode();
|
||||
@@ -1702,6 +1702,10 @@ namespace ts {
|
||||
export function nodeIsSynthesized(node: Node): boolean {
|
||||
return node && node.pos === -1;
|
||||
}
|
||||
|
||||
export function positionIsSynthesized(pos: number): boolean {
|
||||
return pos === -1;
|
||||
}
|
||||
|
||||
export function createDiagnosticCollection(): DiagnosticCollection {
|
||||
let nonFileDiagnostics: Diagnostic[] = [];
|
||||
@@ -1957,7 +1961,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getLineOfLocalPosition(currentSourceFile: SourceFile, pos: number) {
|
||||
return getLineAndCharacterOfPosition(currentSourceFile, pos).line;
|
||||
return !positionIsSynthesized(pos) ? getLineAndCharacterOfPosition(currentSourceFile, pos).line : NaN;
|
||||
}
|
||||
|
||||
export function getFirstConstructorWithBody(node: ClassLikeDeclaration): ConstructorDeclaration {
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace ts.BreakpointResolver {
|
||||
|
||||
function spanInNode(node: Node): TextSpan {
|
||||
if (node) {
|
||||
if (isPartOfExpression(node)) {
|
||||
if (isExpression(node)) {
|
||||
if (node.parent.kind === SyntaxKind.DoStatement) {
|
||||
// Set span as if on while keyword
|
||||
return spanInPreviousNode(node);
|
||||
|
||||
@@ -744,7 +744,7 @@ namespace ts.formatting {
|
||||
}
|
||||
|
||||
static NodeIsInDecoratorContext(node: Node): boolean {
|
||||
while (isPartOfExpression(node)) {
|
||||
while (isExpression(node)) {
|
||||
node = node.parent;
|
||||
}
|
||||
return node.kind === SyntaxKind.Decorator;
|
||||
|
||||
Reference in New Issue
Block a user