Merge pull request #8873 from Microsoft/transforms-visitEachChildPerf

[Transforms] Optimize frequent paths in `visitEachChild`.
This commit is contained in:
Ron Buckton 2016-05-31 11:06:04 -07:00
commit 1b7a67e5a1
13 changed files with 908 additions and 184 deletions

View File

@ -296,7 +296,7 @@ namespace ts {
},
emitTrailingComments(range: TextRange, comments: CommentRange[]): void {
const commentStart = performance.mark();
emitLeadingComments(range, comments);
emitTrailingComments(range, comments);
performance.measure("commentTime", commentStart);
},
emitLeadingDetachedComments(range: TextRange, contextNode?: Node, ignoreNodeCallback?: (contextNode: Node) => boolean): void {
@ -324,8 +324,8 @@ namespace ts {
function setSourceFile(sourceFile: SourceFile) {
currentSourceFile = sourceFile;
currentText = sourceFile.text;
currentLineMap = getLineStarts(sourceFile);
currentText = currentSourceFile.text;
currentLineMap = getLineStarts(currentSourceFile);
detachedCommentsInfo = undefined;
consumedCommentRanges = {};
leadingCommentRangePositions = {};

View File

@ -3,8 +3,6 @@
/* @internal */
namespace ts {
const synthesizedLocation: TextRange = { pos: -1, end: -1 };
let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
let SourceFileConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
@ -22,6 +20,20 @@ namespace ts {
return node;
}
function updateNode<T extends Node>(updated: T, original: T): T {
updated.original = original;
if (original.transformId) {
updated.transformId = original.transformId;
updated.emitFlags = original.emitFlags;
updated.commentRange = original.commentRange;
updated.sourceMapRange = original.sourceMapRange;
}
if (original.startsOnNewLine) {
updated.startsOnNewLine = true;
}
return updated;
}
export function createNodeArray<T extends Node>(elements?: T[], location?: TextRange, hasTrailingComma?: boolean): NodeArray<T> {
if (elements) {
if (isNodeArray(elements)) {
@ -137,7 +149,8 @@ namespace ts {
name.text = "";
name.originalKeywordKind = SyntaxKind.Unknown;
name.autoGenerateKind = GeneratedIdentifierKind.Auto;
name.autoGenerateId = nextAutoGenerateId++;
name.autoGenerateId = nextAutoGenerateId;
nextAutoGenerateId++;
if (recordTempVariable) {
recordTempVariable(name);
}
@ -149,7 +162,8 @@ namespace ts {
name.text = "";
name.originalKeywordKind = SyntaxKind.Unknown;
name.autoGenerateKind = GeneratedIdentifierKind.Loop;
name.autoGenerateId = nextAutoGenerateId++;
name.autoGenerateId = nextAutoGenerateId;
nextAutoGenerateId++;
return name;
}
@ -158,7 +172,8 @@ namespace ts {
name.text = text;
name.originalKeywordKind = SyntaxKind.Unknown;
name.autoGenerateKind = GeneratedIdentifierKind.Unique;
name.autoGenerateId = nextAutoGenerateId++;
name.autoGenerateId = nextAutoGenerateId;
nextAutoGenerateId++;
return name;
}
@ -168,7 +183,8 @@ namespace ts {
name.text = "";
name.originalKeywordKind = SyntaxKind.Unknown;
name.autoGenerateKind = GeneratedIdentifierKind.Node;
name.autoGenerateId = nextAutoGenerateId++;
name.autoGenerateId = nextAutoGenerateId;
nextAutoGenerateId++;
return name;
}
@ -199,22 +215,30 @@ namespace ts {
// Type members
export function createMethod(modifiers: Modifier[], asteriskToken: Node, name: string | PropertyName, parameters: ParameterDeclaration[], body: Block, location?: TextRange) {
const node = <MethodDeclaration>createNode(SyntaxKind.MethodDeclaration, location);
node.decorators = undefined;
export function createMethod(decorators: Decorator[], modifiers: Modifier[], asteriskToken: Node, name: string | PropertyName, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
const node = <MethodDeclaration>createNode(SyntaxKind.MethodDeclaration, location, flags);
node.decorators = decorators ? createNodeArray(decorators) : undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
node.asteriskToken = asteriskToken;
node.name = typeof name === "string" ? createIdentifier(name) : name;
node.typeParameters = undefined;
node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined;
node.parameters = createNodeArray(parameters);
node.type = type;
node.body = body;
return node;
}
export function createConstructor(parameters: ParameterDeclaration[], body: Block, location?: TextRange) {
const node = <ConstructorDeclaration>createNode(SyntaxKind.Constructor, location);
node.decorators = undefined;
node.modifiers = undefined;
export function updateMethod(node: MethodDeclaration, decorators: Decorator[], modifiers: Modifier[], asteriskToken: Node, name: PropertyName, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) {
if (node.decorators !== decorators || node.modifiers !== modifiers || node.asteriskToken !== asteriskToken || node.name !== name || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.body !== body) {
return updateNode(createMethod(decorators, modifiers, asteriskToken, name, typeParameters, parameters, type, body, /*location*/ node, node.flags), node);
}
return node;
}
export function createConstructor(decorators: Decorator[], modifiers: Modifier[], parameters: ParameterDeclaration[], body: Block, location?: TextRange, flags?: NodeFlags) {
const node = <ConstructorDeclaration>createNode(SyntaxKind.Constructor, location, flags);
node.decorators = decorators ? createNodeArray(decorators) : undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
node.typeParameters = undefined;
node.parameters = createNodeArray(parameters);
node.type = undefined;
@ -222,9 +246,35 @@ namespace ts {
return node;
}
export function createGetAccessor(modifiers: Modifier[], name: string | PropertyName, parameters: ParameterDeclaration[], body: Block, location?: TextRange) {
const node = <GetAccessorDeclaration>createNode(SyntaxKind.GetAccessor, location);
node.decorators = undefined;
export function updateConstructor(node: ConstructorDeclaration, decorators: Decorator[], modifiers: Modifier[], parameters: ParameterDeclaration[], body: Block) {
if (node.decorators !== decorators || node.modifiers !== modifiers || node.parameters !== parameters || node.body !== body) {
return updateNode(createConstructor(decorators, modifiers, parameters, body, /*location*/ node, node.flags), node);
}
return node;
}
export function createGetAccessor(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
const node = <GetAccessorDeclaration>createNode(SyntaxKind.GetAccessor, location, flags);
node.decorators = decorators ? createNodeArray(decorators) : undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
node.name = typeof name === "string" ? createIdentifier(name) : name;
node.typeParameters = undefined;
node.parameters = createNodeArray(parameters);
node.type = type;
node.body = body;
return node;
}
export function updateGetAccessor(node: GetAccessorDeclaration, decorators: Decorator[], modifiers: Modifier[], name: PropertyName, parameters: ParameterDeclaration[], type: TypeNode, body: Block) {
if (node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.parameters !== parameters || node.type !== type || node.body !== body) {
return updateNode(createGetAccessor(decorators, modifiers, name, parameters, type, body, /*location*/ node, node.flags), node);
}
return node;
}
export function createSetAccessor(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, parameters: ParameterDeclaration[], body: Block, location?: TextRange, flags?: NodeFlags) {
const node = <SetAccessorDeclaration>createNode(SyntaxKind.SetAccessor, location, flags);
node.decorators = decorators ? createNodeArray(decorators) : undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
node.name = typeof name === "string" ? createIdentifier(name) : name;
node.typeParameters = undefined;
@ -233,33 +283,46 @@ namespace ts {
return node;
}
export function createSetAccessor(modifiers: Modifier[], name: string | PropertyName, parameters: ParameterDeclaration[], body: Block, location?: TextRange) {
const node = <SetAccessorDeclaration>createNode(SyntaxKind.SetAccessor, location);
node.decorators = undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
node.name = typeof name === "string" ? createIdentifier(name) : name;
node.typeParameters = undefined;
node.parameters = createNodeArray(parameters);
node.body = body;
export function updateSetAccessor(node: SetAccessorDeclaration, decorators: Decorator[], modifiers: Modifier[], name: PropertyName, parameters: ParameterDeclaration[], body: Block) {
if (node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.parameters !== parameters || node.body !== body) {
return updateNode(createSetAccessor(decorators, modifiers, name, parameters, body, /*location*/ node, node.flags), node);
}
return node;
}
export function createParameter(name: string | Identifier | BindingPattern, initializer?: Expression, location?: TextRange) {
return createParameterWithDotDotDotToken(/*dotDotDotToken*/ undefined, name, initializer, location);
return createParameterDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*dotDotDotToken*/ undefined,
name,
/*questionToken*/ undefined,
/*type*/ undefined,
initializer,
location
);
}
export function createParameterWithDotDotDotToken(dotDotDotToken: Node, name: string | Identifier | BindingPattern, initializer?: Expression, location?: TextRange) {
const node = <ParameterDeclaration>createNode(SyntaxKind.Parameter, location);
node.decorators = undefined;
node.modifiers = undefined;
export function createParameterDeclaration(decorators: Decorator[], modifiers: Modifier[], dotDotDotToken: Node, name: string | Identifier | BindingPattern, questionToken: Node, type: TypeNode, initializer: Expression, location?: TextRange, flags?: NodeFlags) {
const node = <ParameterDeclaration>createNode(SyntaxKind.Parameter, location, flags);
node.decorators = decorators ? createNodeArray(decorators) : undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
node.dotDotDotToken = dotDotDotToken;
node.name = typeof name === "string" ? createIdentifier(name) : name;
node.questionToken = undefined;
node.type = undefined;
node.questionToken = questionToken;
node.type = type;
node.initializer = initializer ? parenthesizeExpressionForList(initializer) : undefined;
return node;
}
export function updateParameterDeclaration(node: ParameterDeclaration, decorators: Decorator[], modifiers: Modifier[], dotDotDotToken: Node, name: BindingName, questionToken: Node, type: TypeNode, initializer: Expression) {
if (node.decorators !== decorators || node.modifiers !== modifiers || node.dotDotDotToken !== dotDotDotToken || node.name !== name || node.questionToken !== questionToken || node.type !== type || node.initializer !== initializer) {
return updateNode(createParameterDeclaration(decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer, /*location*/ node, /*flags*/ node.flags), node);
}
return node;
}
// Expression
export function createArrayLiteral(elements?: Expression[], location?: TextRange, multiLine?: boolean) {
@ -281,13 +344,24 @@ namespace ts {
}
export function createPropertyAccess(expression: Expression, name: string | Identifier, location?: TextRange) {
const node = <PropertyAccessExpression>createNode(SyntaxKind.PropertyAccessExpression, location, /*flags*/ undefined);
return createPropertyAccessWithDotToken(expression, createSynthesizedNode(SyntaxKind.DotToken), name, location, /*flags*/ undefined);
}
export function createPropertyAccessWithDotToken(expression: Expression, dotToken: Node, name: string | Identifier, location?: TextRange, flags?: NodeFlags) {
const node = <PropertyAccessExpression>createNode(SyntaxKind.PropertyAccessExpression, location, flags);
node.expression = parenthesizeForAccess(expression);
node.dotToken = createSynthesizedNode(SyntaxKind.DotToken);
node.dotToken = dotToken;
node.name = typeof name === "string" ? createIdentifier(name) : name;
return node;
}
export function updatePropertyAccess(node: PropertyAccessExpression, expression: Expression, name: Identifier) {
if (node.expression !== expression || node.name !== name) {
return updateNode(createPropertyAccessWithDotToken(expression, node.dotToken, name, /*location*/ node, node.flags), node);
}
return node;
}
export function createElementAccess(expression: Expression, index: number | Expression, location?: TextRange) {
const node = <ElementAccessExpression>createNode(SyntaxKind.ElementAccessExpression, location);
node.expression = parenthesizeForAccess(expression);
@ -295,19 +369,37 @@ namespace ts {
return node;
}
export function createCall(expression: Expression, argumentsArray: Expression[], location?: TextRange) {
const node = <CallExpression>createNode(SyntaxKind.CallExpression, location);
export function createCall(expression: Expression, typeArguments: TypeNode[], argumentsArray: Expression[], location?: TextRange, flags?: NodeFlags) {
const node = <CallExpression>createNode(SyntaxKind.CallExpression, location, flags);
node.expression = parenthesizeForAccess(expression);
if (typeArguments) {
node.typeArguments = createNodeArray(typeArguments);
}
node.arguments = parenthesizeListElements(createNodeArray(argumentsArray));
return node;
}
export function createNew(expression: Expression, argumentsArray: Expression[], location?: TextRange) {
const node = <NewExpression>createNode(SyntaxKind.NewExpression, location);
export function updateCall(node: CallExpression, expression: Expression, typeArguments: TypeNode[], argumentsArray: Expression[]) {
if (expression !== node.expression || typeArguments !== node.typeArguments || argumentsArray !== node.arguments) {
return updateNode(createCall(expression, typeArguments, argumentsArray, /*location*/ node, node.flags), node);
}
return node;
}
export function createNew(expression: Expression, typeArguments: TypeNode[], argumentsArray: Expression[], location?: TextRange, flags?: NodeFlags) {
const node = <NewExpression>createNode(SyntaxKind.NewExpression, location, flags);
node.expression = parenthesizeForNew(expression);
node.arguments = argumentsArray
? parenthesizeListElements(createNodeArray(argumentsArray))
: undefined;
node.typeArguments = typeArguments ? createNodeArray(typeArguments) : undefined;
node.arguments = argumentsArray ? parenthesizeListElements(createNodeArray(argumentsArray)) : undefined;
return node;
}
export function updateNew(node: NewExpression, expression: Expression, typeArguments: TypeNode[], argumentsArray: Expression[]) {
if (node.expression !== expression || node.typeArguments !== typeArguments || node.arguments !== argumentsArray) {
return updateNode(createNew(expression, typeArguments, argumentsArray, /*location*/ node, node.flags), node);
}
return node;
}
@ -317,33 +409,43 @@ namespace ts {
return node;
}
export function createFunctionExpression(asteriskToken: Node, name: string | Identifier, parameters: ParameterDeclaration[], body: Block, location?: TextRange, original?: Node) {
const node = <FunctionExpression>createNode(SyntaxKind.FunctionExpression, location);
export function createFunctionExpression(asteriskToken: Node, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
const node = <FunctionExpression>createNode(SyntaxKind.FunctionExpression, location, flags);
node.modifiers = undefined;
node.asteriskToken = asteriskToken;
node.name = typeof name === "string" ? createIdentifier(name) : name;
node.typeParameters = undefined;
node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined;
node.parameters = createNodeArray(parameters);
node.type = undefined;
node.type = type;
node.body = body;
if (original) {
node.original = original;
}
return node;
}
export function createArrowFunction(parameters: ParameterDeclaration[], body: Expression | Block, location?: TextRange) {
const node = <ArrowFunction>createNode(SyntaxKind.ArrowFunction, location);
node.modifiers = undefined;
node.typeParameters = undefined;
export function updateFunctionExpression(node: FunctionExpression, name: Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) {
if (node.name !== name || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.body !== body) {
return updateNode(createFunctionExpression(node.asteriskToken, name, typeParameters, parameters, type, body, /*location*/ node, node.flags), node);
}
return node;
}
export function createArrowFunction(modifiers: Modifier[], typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, equalsGreaterThanToken: Node, body: ConciseBody, location?: TextRange, flags?: NodeFlags) {
const node = <ArrowFunction>createNode(SyntaxKind.ArrowFunction, location, flags);
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined;
node.parameters = createNodeArray(parameters);
node.type = undefined;
node.equalsGreaterThanToken = createNode(SyntaxKind.EqualsGreaterThanToken);
node.type = type;
node.equalsGreaterThanToken = equalsGreaterThanToken || createNode(SyntaxKind.EqualsGreaterThanToken);
node.body = parenthesizeConciseBody(body);
return node;
}
export function updateArrowFunction(node: ArrowFunction, modifiers: Modifier[], typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: ConciseBody) {
if (node.modifiers !== modifiers || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.body !== body) {
return updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, node.equalsGreaterThanToken, body, /*location*/ node, node.flags), node);
}
return node;
}
export function createTypeOf(expression: Expression) {
const node = <TypeOfExpression>createNode(SyntaxKind.TypeOfExpression);
node.expression = parenthesizePrefixOperand(expression);
@ -371,10 +473,21 @@ namespace ts {
}
export function createBinary(left: Expression, operator: SyntaxKind, right: Expression, location?: TextRange) {
return createBinaryWithOperatorToken(left, createSynthesizedNode(operator), right, location);
}
export function createBinaryWithOperatorToken(left: Expression, operatorToken: Node, right: Expression, location?: TextRange) {
const node = <BinaryExpression>createNode(SyntaxKind.BinaryExpression, location);
node.left = parenthesizeBinaryOperand(operator, left, /*isLeftSideOfBinary*/ true, /*leftOperand*/ undefined);
node.operatorToken = createSynthesizedNode(operator);
node.right = parenthesizeBinaryOperand(operator, right, /*isLeftSideOfBinary*/ false, node.left);
node.left = parenthesizeBinaryOperand(operatorToken.kind, left, /*isLeftSideOfBinary*/ true, /*leftOperand*/ undefined);
node.operatorToken = operatorToken;
node.right = parenthesizeBinaryOperand(operatorToken.kind, right, /*isLeftSideOfBinary*/ false, node.left);
return node;
}
export function updateBinary(node: BinaryExpression, left: Expression, right: Expression) {
if (node.left !== left || node.right !== right) {
return updateNode(createBinaryWithOperatorToken(left, node.operatorToken, right, /*location*/ node), node);
}
return node;
}
@ -425,8 +538,8 @@ namespace ts {
// Element
export function createBlock(statements: Statement[], location?: TextRange, multiLine?: boolean): Block {
const block = <Block>createNode(SyntaxKind.Block, location);
export function createBlock(statements: Statement[], location?: TextRange, multiLine?: boolean, flags?: NodeFlags): Block {
const block = <Block>createNode(SyntaxKind.Block, location, flags);
block.statements = createNodeArray(statements);
if (multiLine) {
block.multiLine = true;
@ -434,20 +547,42 @@ namespace ts {
return block;
}
export function createVariableStatement(modifiers: Modifier[], declarationList: VariableDeclarationList | VariableDeclaration[], location?: TextRange): VariableStatement {
const node = <VariableStatement>createNode(SyntaxKind.VariableStatement, location);
export function updateBlock(node: Block, statements: Statement[]) {
if (statements !== node.statements) {
return updateNode(createBlock(statements, /*location*/ node, node.multiLine, node.flags), node);
}
return node;
}
export function createVariableStatement(modifiers: Modifier[], declarationList: VariableDeclarationList | VariableDeclaration[], location?: TextRange, flags?: NodeFlags): VariableStatement {
const node = <VariableStatement>createNode(SyntaxKind.VariableStatement, location, flags);
node.decorators = undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
node.declarationList = isArray(declarationList) ? createVariableDeclarationList(declarationList) : declarationList;
return node;
}
export function updateVariableStatement(node: VariableStatement, modifiers: Modifier[], declarationList: VariableDeclarationList): VariableStatement {
if (node.modifiers !== modifiers || node.declarationList !== declarationList) {
return updateNode(createVariableStatement(modifiers, declarationList, /*location*/ node, node.flags), node);
}
return node;
}
export function createVariableDeclarationList(declarations: VariableDeclaration[], location?: TextRange, flags?: NodeFlags): VariableDeclarationList {
const node = <VariableDeclarationList>createNode(SyntaxKind.VariableDeclarationList, location, flags);
node.declarations = createNodeArray(declarations);
return node;
}
export function updateVariableDeclarationList(node: VariableDeclarationList, declarations: VariableDeclaration[]) {
if (node.declarations !== declarations) {
return updateNode(createVariableDeclarationList(declarations, /*location*/ node, node.flags), node);
}
return node;
}
export function createLetDeclarationList(declarations: VariableDeclaration[], location?: TextRange) {
return createVariableDeclarationList(declarations, location, NodeFlags.Let);
}
@ -456,32 +591,51 @@ namespace ts {
return createVariableDeclarationList(declarations, location, NodeFlags.Const);
}
export function createVariableDeclaration(name: string | BindingPattern | Identifier, initializer?: Expression, location?: TextRange): VariableDeclaration {
const node = <VariableDeclaration>createNode(SyntaxKind.VariableDeclaration, location);
export function createVariableDeclaration(name: string | BindingPattern | Identifier, type?: TypeNode, initializer?: Expression, location?: TextRange, flags?: NodeFlags): VariableDeclaration {
const node = <VariableDeclaration>createNode(SyntaxKind.VariableDeclaration, location, flags);
node.name = typeof name === "string" ? createIdentifier(name) : name;
node.type = type;
node.initializer = initializer !== undefined ? parenthesizeExpressionForList(initializer) : undefined;
return node;
}
export function updateVariableDeclaration(node: VariableDeclaration, name: BindingName, type: TypeNode, initializer: Expression) {
if (node.name !== name || node.type !== type || node.initializer !== initializer) {
return updateNode(createVariableDeclaration(name, type, initializer, /*location*/ node, node.flags), node);
}
return node;
}
export function createEmptyStatement(location: TextRange) {
return <EmptyStatement>createNode(SyntaxKind.EmptyStatement, location);
}
export function createStatement(expression: Expression, location?: TextRange): ExpressionStatement {
const node = <ExpressionStatement>createNode(SyntaxKind.ExpressionStatement, location);
export function createStatement(expression: Expression, location?: TextRange, flags?: NodeFlags): ExpressionStatement {
const node = <ExpressionStatement>createNode(SyntaxKind.ExpressionStatement, location, flags);
node.expression = parenthesizeExpressionForExpressionStatement(expression);
return node;
}
export function createIf(expression: Expression, thenStatement: Statement, elseStatement?: Statement, location?: TextRange, options?: { startOnNewLine?: boolean; }) {
export function updateStatement(node: ExpressionStatement, expression: Expression) {
if (node.expression !== expression) {
return updateNode(createStatement(expression, /*location*/ node, node.flags), node);
}
return node;
}
export function createIf(expression: Expression, thenStatement: Statement, elseStatement?: Statement, location?: TextRange) {
const node = <IfStatement>createNode(SyntaxKind.IfStatement, location);
node.expression = expression;
node.thenStatement = thenStatement;
node.elseStatement = elseStatement;
if (options && options.startOnNewLine) {
node.startsOnNewLine = true;
}
return node;
}
export function updateIf(node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement) {
if (node.expression !== expression || node.thenStatement !== thenStatement || node.elseStatement !== elseStatement) {
return updateNode(createIf(expression, thenStatement, elseStatement, /*location*/ node), node);
}
return node;
}
@ -550,18 +704,29 @@ namespace ts {
return node;
}
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;
export function updateReturn(node: ReturnStatement, expression: Expression) {
if (node.expression !== expression) {
return updateNode(createReturn(expression, /*location*/ node), node);
}
return node;
}
export function createFunctionDeclaration(decorators: Decorator[], modifiers: Modifier[], asteriskToken: Node, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
const node = <FunctionDeclaration>createNode(SyntaxKind.FunctionDeclaration, location, flags);
node.decorators = decorators ? createNodeArray(decorators) : undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
node.asteriskToken = asteriskToken;
node.name = typeof name === "string" ? createIdentifier(name) : name;
node.typeParameters = undefined;
node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined;
node.parameters = createNodeArray(parameters);
node.type = undefined;
node.type = type;
node.body = body;
if (original) {
node.original = original;
return node;
}
export function updateFunctionDeclaration(node: FunctionDeclaration, decorators: Decorator[], modifiers: Modifier[], name: Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) {
if (node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.body !== body) {
return updateNode(createFunctionDeclaration(decorators, modifiers, node.asteriskToken, name, typeParameters, parameters, type, body, /*location*/ node, node.flags), node);
}
return node;
}
@ -630,6 +795,46 @@ namespace ts {
return node;
}
// Top-level nodes
export function updateSourceFileNode(node: SourceFile, statements: Statement[]) {
if (node.statements !== statements) {
const updated = <SourceFile>createNode(SyntaxKind.SourceFile, /*location*/ node, node.flags);
updated.statements = createNodeArray(statements);
updated.endOfFileToken = node.endOfFileToken;
updated.fileName = node.fileName;
updated.path = node.path;
updated.text = node.text;
updated.amdDependencies = node.amdDependencies;
updated.moduleName = node.moduleName;
updated.referencedFiles = node.referencedFiles;
updated.typeReferenceDirectives = node.typeReferenceDirectives;
updated.languageVariant = node.languageVariant;
updated.isDeclarationFile = node.isDeclarationFile;
updated.renamedDependencies = node.renamedDependencies;
updated.hasNoDefaultLib = node.hasNoDefaultLib;
updated.languageVersion = node.languageVersion;
updated.scriptKind = node.scriptKind;
updated.externalModuleIndicator = node.externalModuleIndicator;
updated.commonJsModuleIndicator = node.commonJsModuleIndicator;
updated.identifiers = node.identifiers;
updated.nodeCount = node.nodeCount;
updated.identifierCount = node.identifierCount;
updated.symbolCount = node.symbolCount;
updated.parseDiagnostics = node.parseDiagnostics;
updated.bindDiagnostics = node.bindDiagnostics;
updated.lineMap = node.lineMap;
updated.classifiableNames = node.classifiableNames;
updated.resolvedModules = node.resolvedModules;
updated.resolvedTypeReferenceDirectiveNames = node.resolvedTypeReferenceDirectiveNames;
updated.imports = node.imports;
updated.moduleAugmentations = node.moduleAugmentations;
return updateNode(updated, node);
}
return node;
}
// Transformation nodes
/**
@ -744,13 +949,21 @@ namespace ts {
}
export function createRestParameter(name: string | Identifier) {
const node = createParameterWithDotDotDotToken(createSynthesizedNode(SyntaxKind.DotDotDotToken), name, /*initializer*/ undefined);
return node;
return createParameterDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
createSynthesizedNode(SyntaxKind.DotDotDotToken),
name,
/*questionToken*/ undefined,
/*type*/ undefined,
/*initializer*/ undefined
);
}
export function createFunctionCall(func: Expression, thisArg: Expression, argumentsList: Expression[], location?: TextRange) {
return createCall(
createPropertyAccess(func, "call"),
/*typeArguments*/ undefined,
[
thisArg,
...argumentsList
@ -778,6 +991,7 @@ namespace ts {
export function createFunctionApply(func: Expression, thisArg: Expression, argumentsExpression: Expression, location?: TextRange) {
return createCall(
createPropertyAccess(func, "apply"),
/*typeArguments*/ undefined,
[
thisArg,
argumentsExpression
@ -792,12 +1006,13 @@ namespace ts {
argumentsList.push(typeof start === "number" ? createLiteral(start) : start);
}
return createCall(createPropertyAccess(array, "slice"), argumentsList);
return createCall(createPropertyAccess(array, "slice"), /*typeArguments*/ undefined, argumentsList);
}
export function createArrayConcat(array: Expression, values: Expression[]) {
return createCall(
createPropertyAccess(array, "concat"),
/*typeArguments*/ undefined,
values
);
}
@ -805,6 +1020,7 @@ namespace ts {
export function createMathPow(left: Expression, right: Expression, location?: TextRange) {
return createCall(
createPropertyAccess(createIdentifier("Math"), "pow"),
/*typeArguments*/ undefined,
[left, right],
location
);
@ -839,6 +1055,7 @@ namespace ts {
createReactNamespace(reactNamespace, parentElement),
"createElement"
),
/*typeArguments*/ undefined,
argumentsList,
location
);
@ -849,6 +1066,7 @@ namespace ts {
export function createExtendsHelper(name: Identifier) {
return createCall(
createIdentifier("__extends"),
/*typeArguments*/ undefined,
[
name,
createIdentifier("_super")
@ -859,6 +1077,7 @@ namespace ts {
export function createAssignHelper(attributesSegments: Expression[]) {
return createCall(
createIdentifier("__assign"),
/*typeArguments*/ undefined,
attributesSegments
);
}
@ -866,6 +1085,7 @@ namespace ts {
export function createParamHelper(expression: Expression, parameterOffset: number, location?: TextRange) {
return createCall(
createIdentifier("__param"),
/*typeArguments*/ undefined,
[
createLiteral(parameterOffset),
expression
@ -877,6 +1097,7 @@ namespace ts {
export function createMetadataHelper(metadataKey: string, metadataValue: Expression) {
return createCall(
createIdentifier("__metadata"),
/*typeArguments*/ undefined,
[
createLiteral(metadataKey),
metadataValue
@ -895,12 +1116,13 @@ namespace ts {
}
}
return createCall(createIdentifier("__decorate"), argumentsArray, location);
return createCall(createIdentifier("__decorate"), /*typeArguments*/ undefined, argumentsArray, location);
}
export function createAwaiterHelper(hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression, body: Block) {
return createCall(
createIdentifier("__awaiter"),
/*typeArguments*/ undefined,
[
createThis(),
hasLexicalArguments ? createIdentifier("arguments") : createVoidZero(),
@ -908,7 +1130,9 @@ namespace ts {
createFunctionExpression(
createNode(SyntaxKind.AsteriskToken),
/*name*/ undefined,
[],
/*typeParameters*/ undefined,
/*parameters*/ [],
/*type*/ undefined,
body
)
]
@ -918,6 +1142,7 @@ namespace ts {
export function createHasOwnProperty(target: LeftHandSideExpression, propertyName: Expression) {
return createCall(
createPropertyAccess(target, "hasOwnProperty"),
/*typeArguments*/ undefined,
[propertyName]
);
}
@ -925,6 +1150,7 @@ namespace ts {
function createObjectCreate(prototype: Expression) {
return createCall(
createPropertyAccess(createIdentifier("Object"), "create"),
/*typeArguments*/ undefined,
[prototype]
);
}
@ -932,7 +1158,11 @@ namespace ts {
function createGeti(target: LeftHandSideExpression) {
// name => super[name]
return createArrowFunction(
/*modifiers*/ undefined,
/*typeParameters*/ undefined,
[createParameter("name")],
/*type*/ undefined,
/*equalsGreaterThanToken*/ undefined,
createElementAccess(
target,
createIdentifier("name")
@ -943,10 +1173,14 @@ namespace ts {
function createSeti(target: LeftHandSideExpression) {
// (name, value) => super[name] = value
return createArrowFunction(
/*modifiers*/ undefined,
/*typeParameters*/ undefined,
[
createParameter("name"),
createParameter("value")
],
/*type*/ undefined,
/*equalsGreaterThanToken*/ undefined,
createAssignment(
createElementAccess(
target,
@ -969,6 +1203,7 @@ namespace ts {
createConstDeclarationList([
createVariableDeclaration(
"cache",
/*type*/ undefined,
createObjectCreate(createNull())
)
])
@ -976,13 +1211,16 @@ namespace ts {
// get value() { return geti(name); }
const getter = createGetAccessor(
/*decorators*/ undefined,
/*modifiers*/ undefined,
"value",
[],
/*parameters*/ [],
/*type*/ undefined,
createBlock([
createReturn(
createCall(
createIdentifier("geti"),
/*typeArguments*/ undefined,
[createIdentifier("name")]
)
)
@ -991,6 +1229,7 @@ namespace ts {
// set value(v) { seti(name, v); }
const setter = createSetAccessor(
/*decorators*/ undefined,
/*modifiers*/ undefined,
"value",
[createParameter("v")],
@ -998,6 +1237,7 @@ namespace ts {
createStatement(
createCall(
createIdentifier("seti"),
/*typeArguments*/ undefined,
[
createIdentifier("name"),
createIdentifier("v")
@ -1010,7 +1250,11 @@ namespace ts {
// return name => cache[name] || ...
const getOrCreateAccessorsForName = createReturn(
createArrowFunction(
/*modifiers*/ undefined,
/*typeParameters*/ undefined,
[createParameter("name")],
/*type*/ undefined,
/*equalsGreaterThanToken*/ undefined,
createLogicalOr(
createElementAccess(
createIdentifier("cache"),
@ -1041,21 +1285,25 @@ namespace ts {
createConstDeclarationList([
createVariableDeclaration(
"_super",
/*type*/ undefined,
createCall(
createParen(
createFunctionExpression(
/*asteriskToken*/ undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
[
createParameter("geti"),
createParameter("seti")
],
/*type*/ undefined,
createBlock([
createCache,
getOrCreateAccessorsForName
])
)
),
/*typeArguments*/ undefined,
[
createGeti(createSuper()),
createSeti(createSuper())
@ -1072,6 +1320,7 @@ namespace ts {
createConstDeclarationList([
createVariableDeclaration(
"_super",
/*type*/ undefined,
createGeti(createSuper())
)
])

View File

@ -508,10 +508,6 @@ namespace ts {
return skipTrivia(currentSourceText, rangeHasDecorators ? (range as Node).decorators.end : range.pos);
}
function getStartPos(range: TextRange) {
return skipTrivia(currentSourceText, range.pos);
}
/**
* Emits a mapping for the start of a range.
*
@ -701,7 +697,7 @@ namespace ts {
*/
function setSourceFile(sourceFile: SourceFile) {
currentSourceFile = sourceFile;
currentSourceText = sourceFile.text;
currentSourceText = currentSourceFile.text;
// Add the file to tsFilePaths
// If sourceroot option: Use the relative path corresponding to the common directory path
@ -720,10 +716,10 @@ namespace ts {
sourceMapData.sourceMapSources.push(source);
// The one that can be used from program to get the actual source file
sourceMapData.inputSourceFileNames.push(sourceFile.fileName);
sourceMapData.inputSourceFileNames.push(currentSourceFile.fileName);
if (compilerOptions.inlineSources) {
sourceMapData.sourceMapSourcesContent.push(sourceFile.text);
sourceMapData.sourceMapSourcesContent.push(currentSourceFile.text);
}
}
}

View File

@ -156,7 +156,9 @@ namespace ts {
* @param transforms An array of Transformers.
*/
export function transformFiles(resolver: EmitResolver, host: EmitHost, sourceFiles: SourceFile[], transformers: Transformer[]) {
const transformId = nextTransformId++;
const transformId = nextTransformId;
nextTransformId++;
const tokenSourceMapRanges: Map<TextRange> = { };
const lexicalEnvironmentVariableDeclarationsStack: VariableDeclaration[][] = [];
const lexicalEnvironmentFunctionDeclarationsStack: FunctionDeclaration[][] = [];

View File

@ -98,7 +98,7 @@ namespace ts {
return declarations;
function emitAssignment(name: Identifier, value: Expression, location: TextRange) {
const declaration = createVariableDeclaration(name, value, location);
const declaration = createVariableDeclaration(name, /*type*/ undefined, value, location);
// NOTE: this completely disables source maps, but aligns with the behavior of
// `emitAssignment` in the old emitter.
@ -134,7 +134,7 @@ namespace ts {
return declarations;
function emitAssignment(name: Identifier, value: Expression, location: TextRange, original: Node) {
const declaration = createVariableDeclaration(name, value, location);
const declaration = createVariableDeclaration(name, /*type*/ undefined, value, location);
declaration.original = original;
// NOTE: this completely disables source maps, but aligns with the behavior of

View File

@ -554,6 +554,7 @@ namespace ts {
createVariableDeclarationList([
createVariableDeclaration(
getDeclarationName(node, /*allowComments*/ true),
/*type*/ undefined,
transformClassLikeDeclarationToExpression(node)
)
]),
@ -621,7 +622,9 @@ namespace ts {
const classFunction = createFunctionExpression(
/*asteriskToken*/ undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
extendsClauseElement ? [createParameter("_super")] : [],
/*type*/ undefined,
transformClassBody(node, extendsClauseElement)
);
@ -645,6 +648,7 @@ namespace ts {
return createParen(
createCall(
outer,
/*typeArguments*/ undefined,
extendsClauseElement
? [visitNode(extendsClauseElement.expression, visitor, isExpression)]
: []
@ -717,10 +721,13 @@ namespace ts {
const hasSynthesizedSuper = hasSynthesizedDefaultSuperCall(constructor, extendsClauseElement !== undefined);
statements.push(
createFunctionDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*asteriskToken*/ undefined,
getDeclarationName(node),
/*typeParameters*/ undefined,
transformConstructorParameters(constructor, hasSynthesizedSuper),
/*type*/ undefined,
transformConstructorBody(constructor, node, extendsClauseElement, hasSynthesizedSuper),
/*location*/ constructor || node
)
@ -967,10 +974,9 @@ namespace ts {
NodeEmitFlags.SingleLine | NodeEmitFlags.NoTrailingSourceMap | NodeEmitFlags.NoTokenSourceMaps
),
/*elseStatement*/ undefined,
/*location*/ parameter,
{ startOnNewLine: true }
/*location*/ parameter
);
statement.startsOnNewLine = true;
setNodeEmitFlags(statement, NodeEmitFlags.NoTokenSourceMaps | NodeEmitFlags.NoTrailingSourceMap);
statements.push(statement);
}
@ -1018,6 +1024,7 @@ namespace ts {
createVariableDeclarationList([
createVariableDeclaration(
declarationName,
/*type*/ undefined,
createArrayLiteral([])
)
]),
@ -1030,7 +1037,7 @@ namespace ts {
// }
const forStatement = createFor(
createVariableDeclarationList([
createVariableDeclaration(temp, createLiteral(restIndex))
createVariableDeclaration(temp, /*type*/ undefined, createLiteral(restIndex))
], /*location*/ parameter),
createLessThan(
temp,
@ -1073,6 +1080,7 @@ namespace ts {
createVariableDeclarationList([
createVariableDeclaration(
"_this",
/*type*/ undefined,
createThis()
)
])
@ -1228,6 +1236,7 @@ namespace ts {
return createCall(
createPropertyAccess(createIdentifier("Object"), "defineProperty"),
/*typeArguments*/ undefined,
[
target,
propertyName,
@ -1271,15 +1280,19 @@ namespace ts {
* @param node a FunctionDeclaration node.
*/
function visitFunctionDeclaration(node: FunctionDeclaration): FunctionDeclaration {
return createFunctionDeclaration(
/*modifiers*/ undefined,
node.asteriskToken,
node.name,
visitNodes(node.parameters, visitor, isParameter),
transformFunctionBody(node),
/*location*/ node,
/*original*/ node
);
return setOriginalNode(
createFunctionDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
node.asteriskToken,
node.name,
/*typeParameters*/ undefined,
visitNodes(node.parameters, visitor, isParameter),
/*type*/ undefined,
transformFunctionBody(node),
/*location*/ node
),
/*original*/ node);
}
/**
@ -1295,12 +1308,16 @@ namespace ts {
containingNonArrowFunction = node;
}
const expression = createFunctionExpression(
node.asteriskToken,
name,
visitNodes(node.parameters, visitor, isParameter),
saveStateAndInvoke(node, transformFunctionBody),
location,
const expression = setOriginalNode(
createFunctionExpression(
node.asteriskToken,
name,
/*typeParameters*/ undefined,
visitNodes(node.parameters, visitor, isParameter),
/*type*/ undefined,
saveStateAndInvoke(node, transformFunctionBody),
location
),
/*original*/ node
);
@ -1755,6 +1772,7 @@ namespace ts {
createVariableDeclarationList([
createVariableDeclaration(
firstOriginalDeclaration ? firstOriginalDeclaration.name : createTempVariable(/*recordTempVariable*/ undefined),
/*type*/ undefined,
createElementAccess(rhsReference, counter)
)
], /*location*/ moveRangePos(initializer, -1)),
@ -1818,8 +1836,8 @@ namespace ts {
const forStatement = createFor(
createVariableDeclarationList([
createVariableDeclaration(counter, createLiteral(0), /*location*/ moveRangePos(node.expression, -1)),
createVariableDeclaration(rhsReference, expression, /*location*/ node.expression)
createVariableDeclaration(counter, /*type*/ undefined, createLiteral(0), /*location*/ moveRangePos(node.expression, -1)),
createVariableDeclaration(rhsReference, /*type*/ undefined, expression, /*location*/ node.expression)
], /*location*/ node.expression),
createLessThan(
counter,
@ -1996,11 +2014,14 @@ namespace ts {
[
createVariableDeclaration(
functionName,
/*type*/ undefined,
setNodeEmitFlags(
createFunctionExpression(
/*asteriskToken*/ undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
loopParameters,
/*type*/ undefined,
<Block>loopBody
),
currentState.containsLexicalThis
@ -2027,6 +2048,7 @@ namespace ts {
(extraVariableDeclarations || (extraVariableDeclarations = [])).push(
createVariableDeclaration(
currentState.argumentsName,
/*type*/ undefined,
createIdentifier("arguments")
)
);
@ -2047,8 +2069,9 @@ namespace ts {
(extraVariableDeclarations || (extraVariableDeclarations = [])).push(
createVariableDeclaration(
currentState.thisName,
/*type*/ undefined,
createIdentifier("this")
)
)
);
}
}
@ -2140,7 +2163,7 @@ namespace ts {
!state.labeledNonLocalBreaks &&
!state.labeledNonLocalContinues;
const call = createCall(loopFunctionExpressionName, map(parameters, p => <Identifier>p.name));
const call = createCall(loopFunctionExpressionName, /*typeArguments*/ undefined, map(parameters, p => <Identifier>p.name));
if (isSimpleLoop) {
statements.push(createStatement(call));
copyOutParameters(state.loopOutParameters, CopyDirection.ToOriginal, statements);
@ -2150,7 +2173,7 @@ namespace ts {
const stateVariable = createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList(
[createVariableDeclaration(loopResultName, call)]
[createVariableDeclaration(loopResultName, /*type*/ undefined, call)]
)
);
statements.push(stateVariable);
@ -2474,6 +2497,7 @@ namespace ts {
thisArg,
transformAndSpreadElements(createNodeArray([createVoidZero(), ...node.arguments]), /*needsUniqueCopy*/ false, /*multiLine*/ false, /*hasTrailingComma*/ false)
),
/*typeArguments*/ undefined,
[]
);
}
@ -2586,7 +2610,7 @@ namespace ts {
inlineExpressions([
createAssignment(temp, createArrayLiteral(cookedStrings)),
createAssignment(createPropertyAccess(temp, "raw"), createArrayLiteral(rawStrings)),
createCall(tag, templateArguments)
createCall(tag, /*typeArguments*/ undefined, templateArguments)
])
);
}
@ -2894,20 +2918,6 @@ namespace ts {
return getDeclarationName(node, allowComments, allowSourceMaps, NodeEmitFlags.LocalName);
}
/**
* Gets the export name for a declaration for use in expressions.
*
* An export name will *always* be prefixed with an module or namespace export modifier
* like "exports." if one is required.
*
* @param node The declaration.
* @param allowComments A value indicating whether comments may be emitted for the name.
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
*/
function getExportName(node: ClassDeclaration | ClassExpression | FunctionDeclaration, allowComments?: boolean, allowSourceMaps?: boolean) {
return getDeclarationName(node, allowComments, allowSourceMaps, NodeEmitFlags.ExportName);
}
/**
* Gets the name of a declaration, without source map or comments.
*

View File

@ -50,7 +50,7 @@ namespace ts {
return undefined; // do not emit export equals for ES6
}
const original = getOriginalNode(node);
return nodeIsSynthesized(original) || resolver.isValueAliasDeclaration(original) ? node: undefined;
return nodeIsSynthesized(original) || resolver.isValueAliasDeclaration(original) ? node : undefined;
}
function visitExportDeclaration(node: ExportDeclaration): ExportDeclaration {
@ -64,7 +64,7 @@ namespace ts {
if (node.exportClause === newExportClause) {
return node;
}
return newExportClause
return newExportClause
? createExportDeclaration(newExportClause, node.moduleSpecifier)
: undefined;
}
@ -106,12 +106,12 @@ namespace ts {
const newNamedBindings = visitNode(node.namedBindings, visitor, isNamedImportBindings, /*optional*/ true);
return newDefaultImport !== node.name || newNamedBindings !== node.namedBindings
? createImportClause(newDefaultImport, newNamedBindings)
: node;
: node;
}
function visitNamedBindings(node: NamedImportBindings): VisitResult<NamedImportBindings> {
if (node.kind === SyntaxKind.NamespaceImport) {
return resolver.isReferencedAliasDeclaration(node) ? node: undefined;
return resolver.isReferencedAliasDeclaration(node) ? node : undefined;
}
else {
const newNamedImportElements = visitNodes((<NamedImports>node).elements, visitor, isImportSpecifier);

View File

@ -147,6 +147,7 @@ namespace ts {
createStatement(
createCall(
define,
/*typeArguments*/ undefined,
[
// Add the module name (if provided).
...(moduleName ? [moduleName] : []),
@ -167,11 +168,13 @@ namespace ts {
createFunctionExpression(
/*asteriskToken*/ undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
[
createParameter("require"),
createParameter("exports"),
...importAliasNames
],
/*type*/ undefined,
transformAsynchronousModuleBody(node)
)
]
@ -307,6 +310,7 @@ namespace ts {
variables.push(
createVariableDeclaration(
getSynthesizedClone(namespaceDeclaration.name),
/*type*/ undefined,
createRequireCall(node)
)
);
@ -319,6 +323,7 @@ namespace ts {
variables.push(
createVariableDeclaration(
getGeneratedNameForNode(node),
/*type*/ undefined,
createRequireCall(node)
)
);
@ -327,6 +332,7 @@ namespace ts {
variables.push(
createVariableDeclaration(
getSynthesizedClone(namespaceDeclaration.name),
/*type*/ undefined,
getGeneratedNameForNode(node)
)
);
@ -350,6 +356,7 @@ namespace ts {
createVariableDeclarationList([
createVariableDeclaration(
getSynthesizedClone(namespaceDeclaration.name),
/*type*/ undefined,
getGeneratedNameForNode(node),
/*location*/ node
)
@ -390,6 +397,7 @@ namespace ts {
createVariableDeclarationList([
createVariableDeclaration(
getSynthesizedClone(node.name),
/*type*/ undefined,
createRequireCall(node)
)
],
@ -431,6 +439,7 @@ namespace ts {
createVariableDeclarationList([
createVariableDeclaration(
generatedName,
/*type*/ undefined,
createRequireCall(node)
)
]),
@ -460,6 +469,7 @@ namespace ts {
return createStatement(
createCall(
createIdentifier("__export"),
/*typeArguments*/ undefined,
[
moduleKind !== ModuleKind.AMD
? createRequireCall(node)
@ -517,6 +527,7 @@ namespace ts {
createStatement(
createCall(
createPropertyAccess(createIdentifier("Object"), "defineProperty"),
/*typeArguments*/ undefined,
[
createIdentifier("exports"),
createLiteral("__esModule"),
@ -608,7 +619,7 @@ namespace ts {
if (hasModifier(node, ModifierFlags.Export)) {
const variables = getInitializedVariables(node.declarationList);
if (variables.length > 0) {
let inlineAssignments = createStatement(
const inlineAssignments = createStatement(
inlineExpressions(
map(variables, transformInitializedVariable)
),
@ -637,7 +648,7 @@ namespace ts {
function addExportMemberAssignmentsForBindingName(resultStatements: Statement[], name: BindingName): void {
if (isBindingPattern(name)) {
for (const element of name.elements) {
addExportMemberAssignmentsForBindingName(resultStatements, element.name)
addExportMemberAssignmentsForBindingName(resultStatements, element.name);
}
}
else {
@ -671,10 +682,13 @@ namespace ts {
statements.push(
setOriginalNode(
createFunctionDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*asteriskToken*/ undefined,
name,
/*typeParameters*/ undefined,
node.parameters,
/*type*/ undefined,
node.body,
/*location*/ node
),
@ -772,6 +786,7 @@ namespace ts {
/*modifiers*/ undefined,
[createVariableDeclaration(
getDeclarationName(node),
/*type*/ undefined,
createPropertyAccess(createIdentifier("exports"), getDeclarationName(node))
)],
/*location*/ node
@ -907,7 +922,7 @@ namespace ts {
args.push(moduleName);
}
return createCall(createIdentifier("require"), args);
return createCall(createIdentifier("require"), /*typeArguments*/ undefined, args);
}
function createExportStatement(name: Identifier, value: Expression, location?: TextRange) {

View File

@ -12,10 +12,6 @@ namespace ts {
const {
getNodeEmitFlags,
setNodeEmitFlags,
getCommentRange,
setCommentRange,
getSourceMapRange,
setSourceMapRange,
startLexicalEnvironment,
endLexicalEnvironment,
hoistVariableDeclaration,
@ -114,10 +110,12 @@ namespace ts {
const body = createFunctionExpression(
/*asteriskToken*/ undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
[
createParameter(exportFunctionForFile),
createParameter(contextObjectForFile)
],
/*type*/ undefined,
setNodeEmitFlags(
createBlock(statements, /*location*/ undefined, /*multiLine*/ true),
NodeEmitFlags.EmitEmitHelpers
@ -131,6 +129,7 @@ namespace ts {
createStatement(
createCall(
createPropertyAccess(createIdentifier("System"), "register"),
/*typeArguments*/ undefined,
moduleName
? [moduleName, dependencies, body]
: [dependencies, body]
@ -204,6 +203,7 @@ namespace ts {
createVariableDeclarationList([
createVariableDeclaration(
"__moduleName",
/*type*/ undefined,
createLogicalAnd(
contextObjectForFile,
createPropertyAccess(contextObjectForFile, "id")
@ -244,7 +244,9 @@ namespace ts {
createFunctionExpression(
/*asteriskToken*/ undefined,
/*name*/ undefined,
[],
/*typeParameters*/ undefined,
/*parameters*/ [],
/*type*/ undefined,
createBlock(
executeStatements,
/*location*/ undefined,
@ -328,6 +330,7 @@ namespace ts {
createVariableDeclarationList([
createVariableDeclaration(
exportedNamesStorageRef,
/*type*/ undefined,
createObjectLiteral(exportedNames, /*location*/ undefined, /*multiline*/ true)
)
])
@ -397,6 +400,7 @@ namespace ts {
createStatement(
createCall(
exportFunctionForFile,
/*typeArguments*/ undefined,
[createObjectLiteral(properties, /*location*/ undefined, /*multiline*/ true)]
)
)
@ -412,6 +416,7 @@ namespace ts {
createStatement(
createCall(
exportStarFunction,
/*typeArguments*/ undefined,
[parameterName]
)
)
@ -425,7 +430,9 @@ namespace ts {
createFunctionExpression(
/*asteriskToken*/ undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
[createParameter(parameterName)],
/*type*/ undefined,
createBlock(statements, /*location*/ undefined, /*multiLine*/ true)
)
);
@ -651,10 +658,13 @@ namespace ts {
// If the function is exported, ensure it has a name and rewrite the function without any export flags.
const name = node.name || getGeneratedNameForNode(node);
const newNode = createFunctionDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
node.asteriskToken,
name,
/*typeParameters*/ undefined,
node.parameters,
/*type*/ undefined,
node.body,
/*location*/ node);
@ -1199,23 +1209,27 @@ namespace ts {
addNode(statements,
createFunctionDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*asteriskToken*/ undefined,
exportStarFunction,
/*typeParameters*/ undefined,
[createParameter(m)],
/*type*/ undefined,
createBlock([
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([
createVariableDeclaration(
exports,
/*type*/ undefined,
createObjectLiteral([])
)
])
),
createForIn(
createVariableDeclarationList([
createVariableDeclaration(n)
createVariableDeclaration(n, /*type*/ undefined)
]),
m,
createBlock([
@ -1236,6 +1250,7 @@ namespace ts {
createStatement(
createCall(
exportFunctionForFile,
/*typeArguments*/ undefined,
[exports]
)
)
@ -1255,7 +1270,7 @@ namespace ts {
*/
function createExportExpression(name: Identifier | StringLiteral, value: Expression) {
const exportName = isIdentifier(name) ? createLiteral(name.text) : name;
return createCall(exportFunctionForFile, [exportName, value]);
return createCall(exportFunctionForFile, /*typeArguments*/ undefined, [exportName, value]);
}
/**

View File

@ -675,6 +675,7 @@ namespace ts {
createLetDeclarationList([
createVariableDeclaration(
getDeclarationName(node, /*allowComments*/ true),
/*type*/ undefined,
classExpression
)
]),
@ -769,6 +770,8 @@ namespace ts {
return startOnNewLine(
setOriginalNode(
createConstructor(
/*decorators*/ undefined,
/*modifiers*/ undefined,
parameters,
body,
/*location*/ constructor || node
@ -836,6 +839,7 @@ namespace ts {
createStatement(
createCall(
createSuper(),
/*typeArguments*/ undefined,
[createSpread(<Identifier>parameters[0].name)]
)
)
@ -1478,13 +1482,13 @@ namespace ts {
if (compilerOptions.emitDecoratorMetadata) {
let properties: ObjectLiteralElement[];
if (shouldAddTypeMetadata(node)) {
(properties || (properties = [])).push(createPropertyAssignment("type", createArrowFunction([], serializeTypeOfNode(node))));
(properties || (properties = [])).push(createPropertyAssignment("type", createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, /*equalsGreaterThanToken*/ undefined, serializeTypeOfNode(node))));
}
if (shouldAddParamTypesMetadata(node)) {
(properties || (properties = [])).push(createPropertyAssignment("paramTypes", createArrowFunction([], serializeParameterTypesOfNode(node))));
(properties || (properties = [])).push(createPropertyAssignment("paramTypes", createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, /*equalsGreaterThanToken*/ undefined, serializeParameterTypesOfNode(node))));
}
if (shouldAddReturnTypeMetadata(node)) {
(properties || (properties = [])).push(createPropertyAssignment("returnType", createArrowFunction([], serializeReturnTypeOfNode(node))));
(properties || (properties = [])).push(createPropertyAssignment("returnType", createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, /*equalsGreaterThanToken*/ undefined, serializeReturnTypeOfNode(node))));
}
if (properties) {
decoratorExpressions.push(createMetadataHelper("design:typeinfo", createObjectLiteral(properties, /*location*/ undefined, /*multiLine*/ true)));
@ -1933,10 +1937,13 @@ namespace ts {
}
const method = createMethod(
/*decorators*/ undefined,
visitNodes(node.modifiers, visitor, isModifier),
node.asteriskToken,
visitPropertyNameOfClassElement(node),
/*typeParameters*/ undefined,
visitNodes(node.parameters, visitor, isParameter),
/*type*/ undefined,
transformFunctionBody(node),
/*location*/ node
);
@ -1975,9 +1982,11 @@ namespace ts {
}
const accessor = createGetAccessor(
/*decorators*/ undefined,
visitNodes(node.modifiers, visitor, isModifier),
visitPropertyNameOfClassElement(node),
visitNodes(node.parameters, visitor, isParameter),
/*type*/ undefined,
node.body ? visitEachChild(node.body, visitor, context) : createBlock([]),
/*location*/ node
);
@ -2006,6 +2015,7 @@ namespace ts {
}
const accessor = createSetAccessor(
/*decorators*/ undefined,
visitNodes(node.modifiers, visitor, isModifier),
visitPropertyNameOfClassElement(node),
visitNodes(node.parameters, visitor, isParameter),
@ -2038,10 +2048,13 @@ namespace ts {
}
const func = createFunctionDeclaration(
/*decorators*/ undefined,
visitNodes(node.modifiers, visitor, isModifier),
node.asteriskToken,
node.name,
/*typeParameters*/ undefined,
visitNodes(node.parameters, visitor, isParameter),
/*type*/ undefined,
transformFunctionBody(node),
/*location*/ node
);
@ -2072,7 +2085,9 @@ namespace ts {
const func = createFunctionExpression(
node.asteriskToken,
node.name,
/*typeParameters*/ undefined,
visitNodes(node.parameters, visitor, isParameter),
/*type*/ undefined,
transformFunctionBody(node),
/*location*/ node
);
@ -2089,7 +2104,11 @@ namespace ts {
*/
function visitArrowFunction(node: ArrowFunction) {
const func = createArrowFunction(
/*modifiers*/ undefined,
/*typeParameters*/ undefined,
visitNodes(node.parameters, visitor, isParameter),
/*type*/ undefined,
node.equalsGreaterThanToken,
transformConciseBody(node),
/*location*/ node
);
@ -2211,9 +2230,13 @@ namespace ts {
return undefined;
}
const parameter = createParameterWithDotDotDotToken(
const parameter = createParameterDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
node.dotDotDotToken,
visitNode(node.name, visitor, isBindingName),
/*questionToken*/ undefined,
/*type*/ undefined,
visitNode(node.initializer, visitor, isExpression),
/*location*/ moveRangePastModifiers(node)
);
@ -2358,6 +2381,7 @@ namespace ts {
/*modifiers*/ undefined,
[createVariableDeclaration(
getDeclarationName(node),
/*type*/ undefined,
getExportName(node)
)],
/*location*/ node
@ -2398,9 +2422,12 @@ namespace ts {
createFunctionExpression(
/*asteriskToken*/ undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
[createParameter(paramName)],
/*type*/ undefined,
transformEnumBody(node, innerName)
),
/*typeArguments*/ undefined,
[createLogicalOr(
exportName,
createAssignment(
@ -2532,8 +2559,7 @@ namespace ts {
: undefined,
[
createVariableDeclaration(
getDeclarationName(node, /*allowComments*/ false, /*allowSourceMaps*/ true),
/*initializer*/ undefined
getDeclarationName(node, /*allowComments*/ false, /*allowSourceMaps*/ true)
)
]
);
@ -2630,9 +2656,12 @@ namespace ts {
createFunctionExpression(
/*asteriskToken*/ undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
[createParameter(parameterName)],
/*type*/ undefined,
transformModuleBody(node, containerName)
),
/*typeArguments*/ undefined,
[moduleArg]
),
/*location*/ node
@ -2748,6 +2777,7 @@ namespace ts {
createVariableDeclarationList([
createVariableDeclaration(
node.name,
/*type*/ undefined,
moduleReference
)
]),
@ -2944,19 +2974,6 @@ namespace ts {
}
}
function getDeclarationNameExpression(node: DeclarationStatement) {
const name = getDeclarationName(node);
if (isNamespaceExport(node)) {
return getNamespaceMemberName(name);
}
else {
// We set the "ExportName" flag to indicate to any module transformer
// downstream that any `exports.` prefix should be added.
setNodeEmitFlags(name, getNodeEmitFlags(name) | NodeEmitFlags.ExportName);
return name;
}
}
function getClassPrototype(node: ClassExpression | ClassDeclaration) {
return createPropertyAccess(getDeclarationName(node), "prototype");
}
@ -3060,7 +3077,7 @@ namespace ts {
currentDecoratedClassAliases[getOriginalNodeId(node)] = decoratedClassAliases[getOriginalNodeId(node)];
}
else if (node.kind === SyntaxKind.Identifier) {
const declaration = resolver.getReferencedValueDeclaration(<Identifier>node)
const declaration = resolver.getReferencedValueDeclaration(<Identifier>node);
if (declaration && isClassWithDecorators(declaration)) {
currentDecoratedClassAliases[getOriginalNodeId(declaration)] = decoratedClassAliases[getOriginalNodeId(declaration)];
}
@ -3203,6 +3220,7 @@ namespace ts {
: substituteElementAccessExpression(expression);
return createCall(
createPropertyAccess(argumentExpression, "call"),
/*typeArguments*/ undefined,
[
createThis(),
...node.arguments
@ -3248,6 +3266,7 @@ namespace ts {
return createPropertyAccess(
createCall(
createIdentifier("_super"),
/*typeArguments*/ undefined,
[argumentExpression]
),
"value",
@ -3257,6 +3276,7 @@ namespace ts {
else {
return createCall(
createIdentifier("_super"),
/*typeArguments*/ undefined,
[argumentExpression],
location
);

View File

@ -6,6 +6,11 @@ namespace ts {
fileWatcher?: FileWatcher;
}
interface Statistic {
name: string;
value: string;
}
let reportDiagnostic = reportDiagnosticSimply;
function reportDiagnostics(diagnostics: Diagnostic[], host: CompilerHost): void {
@ -235,18 +240,6 @@ namespace ts {
return s;
}
function reportStatisticalValue(name: string, value: string) {
sys.write(padRight(name + ":", 20) + padLeft(value.toString(), 10) + sys.newLine);
}
function reportCountStatistic(name: string, count: number) {
reportStatisticalValue(name, "" + count);
}
function reportTimeStatistic(name: string, time: number) {
reportStatisticalValue(name, (time / 1000).toFixed(2) + "s");
}
function isJSONSupported() {
return typeof JSON === "object" && typeof JSON.parse === "function";
}
@ -554,8 +547,10 @@ namespace ts {
}
function compile(fileNames: string[], compilerOptions: CompilerOptions, compilerHost: CompilerHost) {
let statistics: Statistic[];
if (compilerOptions.diagnostics || compilerOptions.extendedDiagnostics) {
performance.enable();
statistics = [];
}
const program = createProgram(fileNames, compilerOptions, compilerHost);
@ -601,6 +596,7 @@ namespace ts {
reportTimeStatistic("Check time", checkTime);
reportTimeStatistic("Emit time", emitTime);
reportTimeStatistic("Total time", programTime + bindTime + checkTime + emitTime);
reportStatistics();
performance.disable();
}
@ -642,6 +638,36 @@ namespace ts {
}
return ExitStatus.Success;
}
function reportStatistics() {
let nameSize = 0;
let valueSize = 0;
for (const { name, value } of statistics) {
if (name.length > nameSize) {
nameSize = name.length;
}
if (value.length > valueSize) {
valueSize = value.length;
}
}
for (const { name, value } of statistics) {
sys.write(padRight(name + ":", nameSize + 2) + padLeft(value.toString(), valueSize) + sys.newLine);
}
}
function reportStatisticalValue(name: string, value: string) {
statistics.push({ name, value });
}
function reportCountStatistic(name: string, count: number) {
reportStatisticalValue(name, "" + count);
}
function reportTimeStatistic(name: string, time: number) {
reportStatisticalValue(name, (time / 1000).toFixed(2) + "s");
}
}
function printVersion() {

View File

@ -3110,12 +3110,18 @@ namespace ts {
return false;
}
const syntaxKindCache: Map<string> = {};
export function formatSyntaxKind(kind: SyntaxKind): string {
const syntaxKindEnum = (<any>ts).SyntaxKind;
if (syntaxKindEnum) {
if (syntaxKindCache[kind]) {
return syntaxKindCache[kind];
}
for (const name in syntaxKindEnum) {
if (syntaxKindEnum[name] === kind) {
return kind.toString() + " (" + name + ")";
return syntaxKindCache[kind] = kind.toString() + " (" + name + ")";
}
}
}

View File

@ -607,11 +607,393 @@ namespace ts {
* @param context A lexical environment context for the visitor.
*/
export function visitEachChild<T extends Node>(node: T, visitor: (node: Node) => VisitResult<Node>, context: LexicalEnvironment): T;
export function visitEachChild<T extends Node>(node: T & Map<any>, visitor: (node: Node) => VisitResult<Node>, context: LexicalEnvironment): T {
export function visitEachChild(node: Node, visitor: (node: Node) => VisitResult<Node>, context: LexicalEnvironment): Node {
if (node === undefined) {
return undefined;
}
const kind = node.kind;
// No need to visit nodes with no children.
if ((kind > SyntaxKind.FirstToken && kind <= SyntaxKind.LastToken)) {
return node;
}
// Special cases for frequent visitors to improve performance.
let visited: Node;
switch (kind) {
case SyntaxKind.ThisType:
case SyntaxKind.StringLiteralType:
case SyntaxKind.SemicolonClassElement:
case SyntaxKind.EmptyStatement:
case SyntaxKind.OmittedExpression:
case SyntaxKind.DebuggerStatement:
// No need to visit nodes with no children.
return node;
// Signature elements
case SyntaxKind.Parameter:
visited = visitEachChildOfParameter(<ParameterDeclaration>node, visitor);
break;
// Type member
case SyntaxKind.MethodDeclaration:
visited = visitEachChildOfMethod(<MethodDeclaration>node, visitor, context);
break;
case SyntaxKind.Constructor:
visited = visitEachChildOfConstructor(<ConstructorDeclaration>node, visitor, context);
break;
case SyntaxKind.GetAccessor:
visited = visitEachChildOfGetAccessor(<GetAccessorDeclaration>node, visitor, context);
break;
case SyntaxKind.SetAccessor:
visited = visitEachChildOfSetAccessor(<SetAccessorDeclaration>node, visitor, context);
break;
// Expression
case SyntaxKind.PropertyAccessExpression:
visited = visitEachChildOfPropertyAccess(<PropertyAccessExpression>node, visitor);
break;
case SyntaxKind.CallExpression:
visited = visitEachChildOfCall(<CallExpression>node, visitor);
break;
case SyntaxKind.NewExpression:
visited = visitEachChildOfNew(<NewExpression>node, visitor);
break;
case SyntaxKind.BinaryExpression:
visited = visitEachChildOfBinary(<BinaryExpression>node, visitor);
break;
case SyntaxKind.FunctionExpression:
visited = visitEachChildOfFunctionExpression(<FunctionExpression>node, visitor, context);
break;
case SyntaxKind.ArrowFunction:
visited = visitEachChildOfArrowFunction(<ArrowFunction>node, visitor, context);
break;
// Element
case SyntaxKind.Block:
visited = visitEachChildOfBlock(<Block>node, visitor);
break;
case SyntaxKind.VariableStatement:
visited = visitEachChildOfVaribleStatement(<VariableStatement>node, visitor);
break;
case SyntaxKind.ExpressionStatement:
visited = visitEachChildOfStatement(<ExpressionStatement>node, visitor);
break;
case SyntaxKind.IfStatement:
visited = visitEachChildOfIf(<IfStatement>node, visitor);
break;
case SyntaxKind.ReturnStatement:
visited = visitEachChildOfReturn(<ReturnStatement>node, visitor);
break;
case SyntaxKind.VariableDeclaration:
visited = visitEachChildOfVariableDeclaration(<VariableDeclaration>node, visitor);
break;
case SyntaxKind.VariableDeclarationList:
visited = visitEachChildOfVariableDeclarationList(<VariableDeclarationList>node, visitor);
break;
case SyntaxKind.FunctionDeclaration:
visited = visitEachChildOfFunctionDeclaration(<FunctionDeclaration>node, visitor, context);
break;
// Top-level nodes
case SyntaxKind.SourceFile:
visited = visitEachChildOfSourceFile(<SourceFile>node, visitor, context);
break;
default:
visited = visitEachChildOfNode(node, visitor, context);
break;
}
if (visited !== node) {
aggregateTransformFlags(visited);
}
return visited;
}
function visitEachChildOfSourceFile(node: SourceFile, visitor: (node: Node) => VisitResult<Node>, context: LexicalEnvironment) {
context.startLexicalEnvironment();
const statements = visitNodes(node.statements, visitor, isStatement);
const declarations = context.endLexicalEnvironment();
return updateSourceFileNode(node,
createNodeArray(concatenate(statements, declarations), statements)
);
}
function visitEachChildOfCall(node: CallExpression, visitor: (node: Node) => VisitResult<Node>) {
return updateCall(node,
visitNode(node.expression, visitor, isExpression),
visitNodes(node.typeArguments, visitor, isTypeNode),
visitNodes(node.arguments, visitor, isExpression)
);
}
function visitEachChildOfParameter(node: ParameterDeclaration, visitor: (node: Node) => VisitResult<Node>) {
return updateParameterDeclaration(node,
visitNodes(node.decorators, visitor, isDecorator),
visitNodes(node.modifiers, visitor, isModifier),
node.dotDotDotToken,
visitNode(node.name, visitor, isBindingName),
node.questionToken,
visitNode(node.type, visitor, isTypeNode, /*optional*/ true),
visitNode(node.initializer, visitor, isExpression, /*optional*/ true)
);
}
function visitEachChildOfStatement(node: ExpressionStatement, visitor: (node: Node) => VisitResult<Node>) {
return updateStatement(node,
visitNode(node.expression, visitor, isExpression)
);
}
function visitEachChildOfVaribleStatement(node: VariableStatement, visitor: (node: Node) => VisitResult<Node>) {
return updateVariableStatement(node,
visitNodes(node.modifiers, visitor, isModifier),
visitNode(node.declarationList, visitor, isVariableDeclarationList)
);
}
function visitEachChildOfVariableDeclarationList(node: VariableDeclarationList, visitor: (node: Node) => VisitResult<Node>) {
return updateVariableDeclarationList(node,
visitNodes(node.declarations, visitor, isVariableDeclaration)
);
}
function visitEachChildOfVariableDeclaration(node: VariableDeclaration, visitor: (node: Node) => VisitResult<Node>) {
return updateVariableDeclaration(node,
visitNode(node.name, visitor, isBindingName),
visitNode(node.type, visitor, isTypeNode, /*optional*/ true),
visitNode(node.initializer, visitor, isExpression, /*optional*/ true)
);
}
function visitEachChildOfConstructor(node: ConstructorDeclaration, visitor: (node: Node) => VisitResult<Node>, context: LexicalEnvironment) {
const decorators = visitNodes(node.decorators, visitor, isDecorator);
const modifiers = visitNodes(node.modifiers, visitor, isModifier);
context.startLexicalEnvironment();
const parameters = visitNodes(node.parameters, visitor, isParameter);
const body = visitNode(node.body, visitor, isFunctionBody, /*optional*/ true);
const declarations = context.endLexicalEnvironment();
return updateConstructor(node,
decorators,
modifiers,
parameters,
body ? updateBlock(body, createNodeArray(concatenate(body.statements, declarations), body.statements)) : undefined
);
}
function visitEachChildOfMethod(node: MethodDeclaration, visitor: (node: Node) => VisitResult<Node>, context: LexicalEnvironment) {
const decorators = visitNodes(node.decorators, visitor, isDecorator);
const modifiers = visitNodes(node.modifiers, visitor, isModifier);
const name = visitNode(node.name, visitor, isPropertyName);
const typeParameters = visitNodes(node.typeParameters, visitor, isTypeParameter);
context.startLexicalEnvironment();
const parameters = visitNodes(node.parameters, visitor, isParameter);
const type = visitNode(node.type, visitor, isTypeNode, /*optional*/ true);
const body = visitNode(node.body, visitor, isFunctionBody, /*optional*/ true);
const declarations = context.endLexicalEnvironment();
return updateMethod(node,
decorators,
modifiers,
node.asteriskToken,
name,
typeParameters,
parameters,
type,
body ? updateBlock(body, createNodeArray(concatenate(body.statements, declarations), body.statements)) : undefined
);
}
function visitEachChildOfGetAccessor(node: GetAccessorDeclaration, visitor: (node: Node) => VisitResult<Node>, context: LexicalEnvironment) {
const decorators = visitNodes(node.decorators, visitor, isDecorator);
const modifiers = visitNodes(node.modifiers, visitor, isModifier);
const name = visitNode(node.name, visitor, isPropertyName);
context.startLexicalEnvironment();
const parameters = visitNodes(node.parameters, visitor, isParameter);
const type = visitNode(node.type, visitor, isTypeNode, /*optional*/ true);
const body = visitNode(node.body, visitor, isFunctionBody, /*optional*/ true);
const declarations = context.endLexicalEnvironment();
return updateGetAccessor(node,
decorators,
modifiers,
name,
parameters,
type,
body ? updateBlock(body, createNodeArray(concatenate(body.statements, declarations), body.statements)) : undefined
);
}
function visitEachChildOfSetAccessor(node: SetAccessorDeclaration, visitor: (node: Node) => VisitResult<Node>, context: LexicalEnvironment) {
const decorators = visitNodes(node.decorators, visitor, isDecorator);
const modifiers = visitNodes(node.modifiers, visitor, isModifier);
const name = visitNode(node.name, visitor, isPropertyName);
context.startLexicalEnvironment();
const parameters = visitNodes(node.parameters, visitor, isParameter);
const body = visitNode(node.body, visitor, isFunctionBody, /*optional*/ true);
const declarations = context.endLexicalEnvironment();
return updateSetAccessor(node,
decorators,
modifiers,
name,
parameters,
body ? updateBlock(body, createNodeArray(concatenate(body.statements, declarations), body.statements)) : undefined
);
}
function visitEachChildOfBlock(node: Block, visitor: (node: Node) => VisitResult<Node>) {
return updateBlock(node,
visitNodes(node.statements, visitor, isStatement)
);
}
function visitEachChildOfPropertyAccess(node: PropertyAccessExpression, visitor: (node: Node) => VisitResult<Node>) {
return updatePropertyAccess(node,
visitNode(node.expression, visitor, isExpression),
visitNode(node.name, visitor, isIdentifier)
);
}
function visitEachChildOfIf(node: IfStatement, visitor: (node: Node) => VisitResult<Node>) {
return updateIf(node,
visitNode(node.expression, visitor, isExpression),
visitNode(node.thenStatement, visitor, isStatement, /*optional*/ false, liftToBlock),
visitNode(node.elseStatement, visitor, isStatement, /*optional*/ true, liftToBlock)
);
}
function visitEachChildOfBinary(node: BinaryExpression, visitor: (node: Node) => VisitResult<Node>) {
return updateBinary(node,
visitNode(node.left, visitor, isExpression),
visitNode(node.right, visitor, isExpression)
);
}
function visitEachChildOfReturn(node: ReturnStatement, visitor: (node: Node) => VisitResult<Node>) {
return updateReturn(node,
visitNode(node.expression, visitor, isExpression, /*optional*/ true)
);
}
function visitEachChildOfFunctionDeclaration(node: FunctionDeclaration, visitor: (node: Node) => VisitResult<Node>, context: LexicalEnvironment) {
const decorators = visitNodes(node.decorators, visitor, isDecorator);
const modifiers = visitNodes(node.modifiers, visitor, isModifier);
const name = visitNode(node.name, visitor, isIdentifier, /*optional*/ true);
const typeParameters = visitNodes(node.typeParameters, visitor, isTypeParameter);
context.startLexicalEnvironment();
const parameters = visitNodes(node.parameters, visitor, isParameter);
const type = visitNode(node.type, visitor, isTypeNode, /*optional*/ true);
const body = visitNode(node.body, visitor, isFunctionBody, /*optional*/ true);
const declarations = context.endLexicalEnvironment();
return updateFunctionDeclaration(node,
decorators,
modifiers,
name,
typeParameters,
parameters,
type,
body ? updateBlock(body, createNodeArray(concatenate(body.statements, declarations), body.statements)) : undefined
);
}
function visitEachChildOfFunctionExpression(node: FunctionExpression, visitor: (node: Node) => VisitResult<Node>, context: LexicalEnvironment) {
const name = visitNode(node.name, visitor, isIdentifier, /*optional*/ true);
const typeParameters = visitNodes(node.typeParameters, visitor, isTypeParameter);
context.startLexicalEnvironment();
const parameters = visitNodes(node.parameters, visitor, isParameter);
const type = visitNode(node.type, visitor, isTypeNode, /*optional*/ true);
const body = visitNode(node.body, visitor, isFunctionBody, /*optional*/ true);
const declarations = context.endLexicalEnvironment();
return updateFunctionExpression(node,
name,
typeParameters,
parameters,
type,
body ? updateBlock(body, createNodeArray(concatenate(body.statements, declarations), body.statements)) : undefined
);
}
function visitEachChildOfArrowFunction(node: ArrowFunction, visitor: (node: Node) => VisitResult<Node>, context: LexicalEnvironment) {
const modifiers = visitNodes(node.modifiers, visitor, isModifier);
const typeParameters = visitNodes(node.typeParameters, visitor, isTypeParameter);
context.startLexicalEnvironment();
const parameters = visitNodes(node.parameters, visitor, isParameter);
const type = visitNode(node.type, visitor, isTypeNode, /*optional*/ true);
let body = visitNode(node.body, visitor, isConciseBody, /*optional*/ true);
const declarations = context.endLexicalEnvironment();
if (declarations && declarations.length) {
const statements: Statement[] = [];
let statementsLocation: TextRange;
let multiLine = false;
if (isBlock(body)) {
addRange(statements, body.statements);
statementsLocation = body.statements;
multiLine = body.multiLine;
}
else {
statements.push(createReturn(body, /*location*/ body));
statementsLocation = body;
multiLine = true;
}
addRange(statements, declarations);
body = createBlock(
createNodeArray(statements, statementsLocation),
/*location*/ body,
multiLine
);
}
return updateArrowFunction(node,
modifiers,
typeParameters,
parameters,
type,
body
);
}
function visitEachChildOfNew(node: NewExpression, visitor: (node: Node) => VisitResult<Node>) {
return updateNew(node,
visitNode(node.expression, visitor, isExpression),
visitNodes(node.typeArguments, visitor, isTypeNode),
visitNodes(node.arguments, visitor, isExpression)
);
}
/**
* Visits each child of a Node using the supplied visitor, possibly returning a new Node of the same kind in its place.
*
* @param node The Node whose children will be visited.
* @param visitor The callback used to visit each child.
* @param context A lexical environment context for the visitor.
*/
function visitEachChildOfNode<T extends Node>(node: T, visitor: (node: Node) => VisitResult<Node>, context: LexicalEnvironment): T;
function visitEachChildOfNode<T extends Node>(node: T & Map<any>, visitor: (node: Node) => VisitResult<Node>, context: LexicalEnvironment): T {
// const markName = `visitEachChild-${formatSyntaxKind(node.kind)}`;
// const measureName = `visitEachChildTime-${formatSyntaxKind(node.kind)}`;
// performance.mark(markName);
let updated: T & Map<any>;
// If this node starts a new lexical environment, start a new lexical environment on the context.
@ -626,6 +1008,8 @@ namespace ts {
const value = <Node | NodeArray<Node>>node[edge.name];
if (value !== undefined) {
let visited: Node | NodeArray<Node>;
// performance.measure(measureName, markName);
if (isArray(value)) {
const visitedArray = visitNodesWorker(value, visitor, edge.test, edge.parenthesize, node, 0, value.length);
visited = visitedArray;
@ -634,6 +1018,7 @@ namespace ts {
visited = visitNodeWorker(<Node>value, visitor, edge.test, edge.optional, edge.lift, edge.parenthesize, node);
}
// performance.mark(markName);
if (updated !== undefined || visited !== value) {
if (updated === undefined) {
updated = getMutableClone(node);
@ -659,10 +1044,10 @@ namespace ts {
}
if (updated !== node) {
aggregateTransformFlags(updated);
updated.original = node;
}
// performance.measure(measureName, markName);
return updated;
}