mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-13 20:45:51 -05:00
Migrated to NodeStack for transforms
This commit is contained in:
@@ -31,9 +31,9 @@ if (process.env.path !== undefined) {
|
||||
}
|
||||
|
||||
var compilerSources = [
|
||||
"types.ts",
|
||||
"core.ts",
|
||||
"sys.ts",
|
||||
"types.ts",
|
||||
"scanner.ts",
|
||||
"factory.ts",
|
||||
"factory.generated.ts",
|
||||
@@ -60,6 +60,8 @@ var servicesSources = [
|
||||
"sys.ts",
|
||||
"types.ts",
|
||||
"scanner.ts",
|
||||
"factory.ts",
|
||||
"factory.generated.ts",
|
||||
"parser.ts",
|
||||
"utilities.ts",
|
||||
"binder.ts",
|
||||
|
||||
@@ -404,8 +404,6 @@ function generateFactory(outputFile: string) {
|
||||
let writer = createLineWrappingTextWriter(host.getNewLine(), columnWrap);
|
||||
writer.write(`// <auto-generated />`);
|
||||
writer.writeLine();
|
||||
writer.write(`/// <reference path="parser.ts" />`);
|
||||
writer.writeLine();
|
||||
writer.write(`/// <reference path="factory.ts" />`);
|
||||
writer.writeLine();
|
||||
writer.write(`namespace ts {`);
|
||||
|
||||
@@ -2814,9 +2814,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
return;
|
||||
}
|
||||
|
||||
let parentNode = nodeStack.getParent();
|
||||
emitToken(SyntaxKind.OpenBraceToken, node.pos);
|
||||
increaseIndent();
|
||||
|
||||
let parentNode = nodeStack.getParent();
|
||||
scopeEmitStart(parentNode);
|
||||
if (node.kind === SyntaxKind.ModuleBlock) {
|
||||
Debug.assert(parentNode.kind === SyntaxKind.ModuleDeclaration);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// <auto-generated />
|
||||
/// <reference path="parser.ts" />
|
||||
/// <reference path="factory.ts" />
|
||||
namespace ts {
|
||||
export namespace factory {
|
||||
@@ -2889,6 +2888,9 @@ namespace ts {
|
||||
export function isEnumMember(node: Node): node is EnumMember {
|
||||
return node && node.kind === SyntaxKind.EnumMember;
|
||||
}
|
||||
export function isSourceFile(node: Node): node is SourceFile {
|
||||
return node && node.kind === SyntaxKind.SourceFile;
|
||||
}
|
||||
export function isJSDocTypeExpression(node: Node): node is JSDocTypeExpression {
|
||||
return node && node.kind === SyntaxKind.JSDocTypeExpression;
|
||||
}
|
||||
@@ -3187,6 +3189,7 @@ namespace ts {
|
||||
case SyntaxKind.JSDocReturnTag:
|
||||
case SyntaxKind.JSDocTypeTag:
|
||||
case SyntaxKind.JSDocParameterTag:
|
||||
case SyntaxKind.SourceFile:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace ts {
|
||||
export function createNode<T extends Node>(kind: SyntaxKind): T {
|
||||
return factory.createNode<T>(kind);
|
||||
}
|
||||
|
||||
|
||||
// @internal
|
||||
export namespace factory {
|
||||
export function setNodeFlags<T extends Node>(node: T, flags: NodeFlags): T {
|
||||
@@ -129,6 +129,16 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateSourceFile(node: SourceFile, statements: NodeArray<Statement>, endOfFileToken: Node): SourceFile {
|
||||
if (statements !== node.statements || endOfFileToken !== node.endOfFileToken) {
|
||||
let newNode = createSourceFile();
|
||||
newNode.statements = statements;
|
||||
newNode.endOfFileToken = endOfFileToken;
|
||||
return updateFrom(node, newNode);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createNumericLiteral2(value: number, location?: TextRange, flags?: NodeFlags): LiteralExpression {
|
||||
let node = factory.createNumericLiteral(String(value), location, flags);
|
||||
return node;
|
||||
|
||||
@@ -600,6 +600,11 @@ namespace ts.transform {
|
||||
<EnumMember>node,
|
||||
<DeclarationName>visitNode((<EnumMember>node).name, visitor),
|
||||
<Expression>visitNode((<EnumMember>node).initializer, visitor)));
|
||||
case SyntaxKind.SourceFile:
|
||||
return write(factory.updateSourceFile(
|
||||
<SourceFile>node,
|
||||
<NodeArray<Statement>>visitNodes((<SourceFile>node).statements, visitor),
|
||||
(<SourceFile>node).endOfFileToken));
|
||||
case SyntaxKind.JSDocTypeExpression:
|
||||
return write(factory.updateJSDocTypeExpression(
|
||||
<JSDocTypeExpression>node,
|
||||
|
||||
@@ -4,14 +4,6 @@ const FORCE_TRANSFORMS = false;
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
|
||||
// Flags enum to track count of temp variables and a few dedicated names
|
||||
const enum TempFlags {
|
||||
Auto = 0x00000000, // No preferred name
|
||||
CountMask = 0x0FFFFFFF, // Temp variable counter
|
||||
_i = 0x10000000, // Use/preference flag for '_i'
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the transform flags for a node, given the transform flags of its subtree
|
||||
* @param node The node to analyze
|
||||
@@ -261,8 +253,23 @@ namespace ts {
|
||||
_compilerOptions: CompilerOptions, _currentSourceFile: SourceFile, _resolver: EmitResolver, _generatedNameSet: Map<string>, _nodeToGeneratedName: string[]) {
|
||||
return transform.runTransformationChain(statements, chain, _compilerOptions, _currentSourceFile, _resolver, _generatedNameSet, _nodeToGeneratedName);
|
||||
}
|
||||
|
||||
|
||||
export type Visitor = (input: Node, output: (node: Node) => void) => void;
|
||||
|
||||
export const enum VisitorFlags {
|
||||
NewLexicalEnvironment = 1 << 1,
|
||||
PreserveStack = 1 << 2,
|
||||
ReturnUndefinedIfEmpty = 1 << 3,
|
||||
}
|
||||
|
||||
export namespace transform {
|
||||
// Flags enum to track count of temp variables and a few dedicated names
|
||||
const enum TempFlags {
|
||||
Auto = 0x00000000, // No preferred name
|
||||
CountMask = 0x0FFFFFFF, // Temp variable counter
|
||||
_i = 0x10000000, // Use/preference flag for '_i'
|
||||
}
|
||||
|
||||
let transformationRunning: boolean;
|
||||
let transformFlags: TransformFlags;
|
||||
let generatedNameSet: Map<string>;
|
||||
@@ -277,10 +284,7 @@ namespace ts {
|
||||
let resolver: EmitResolver;
|
||||
|
||||
// node stack
|
||||
let nodeStackSize: number;
|
||||
let ancestorStack: Node[];
|
||||
let parentNode: Node;
|
||||
let currentNode: Node;
|
||||
let nodeStack: NodeStack;
|
||||
|
||||
// single node transform
|
||||
let updatedNode: Node;
|
||||
@@ -315,9 +319,8 @@ namespace ts {
|
||||
generatedNameSet = _generatedNameSet;
|
||||
nodeToGeneratedName = _nodeToGeneratedName;
|
||||
nodeToGeneratedIdentifier = [];
|
||||
ancestorStack = [];
|
||||
nodeStackSize = 1;
|
||||
currentNode = _currentSourceFile;
|
||||
nodeStack = createNodeStack();
|
||||
nodeStack.pushNode(_currentSourceFile);
|
||||
transformationRunning = true;
|
||||
}
|
||||
|
||||
@@ -329,18 +332,14 @@ namespace ts {
|
||||
generatedNameSet = undefined;
|
||||
nodeToGeneratedName = undefined;
|
||||
nodeToGeneratedIdentifier = undefined;
|
||||
ancestorStack = undefined;
|
||||
nodeStackSize = undefined;
|
||||
currentNode = undefined;
|
||||
nodeStack = undefined;
|
||||
transformationRunning = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Return the next available name in the pattern _a ... _z, _0, _1, ...
|
||||
// TempFlags._i or TempFlags._n may be used to express a preference for that dedicated name.
|
||||
// Note that names generated by makeTempVariableName and makeUniqueName will never conflict.
|
||||
export function makeTempVariableName(flags: TempFlags): string {
|
||||
function makeTempVariableName(flags: TempFlags): string {
|
||||
if (flags && !(tempFlags & flags)) {
|
||||
let name = flags === TempFlags._i ? "_i" : "_n";
|
||||
if (isUniqueName(name)) {
|
||||
@@ -458,21 +457,6 @@ namespace ts {
|
||||
return makeUniqueName("class");
|
||||
}
|
||||
|
||||
function pushNode(node: Node): void {
|
||||
nodeStackSize++;
|
||||
if (nodeStackSize > 2) {
|
||||
ancestorStack.push(parentNode);
|
||||
}
|
||||
parentNode = currentNode;
|
||||
currentNode = node;
|
||||
}
|
||||
|
||||
function popNode(): void {
|
||||
currentNode = parentNode;
|
||||
parentNode = nodeStackSize > 2 ? ancestorStack.pop() : undefined;
|
||||
nodeStackSize--;
|
||||
}
|
||||
|
||||
export function getEmitResolver(): EmitResolver {
|
||||
return resolver;
|
||||
}
|
||||
@@ -481,32 +465,22 @@ namespace ts {
|
||||
return compilerOptions;
|
||||
}
|
||||
|
||||
export function createParentNavigator(): ParentNavigator {
|
||||
return nodeStack.createParentNavigator();
|
||||
}
|
||||
|
||||
export function getCurrentNode(): Node {
|
||||
return currentNode;
|
||||
return nodeStack.getNode();
|
||||
}
|
||||
|
||||
export function getParentNode(): Node {
|
||||
return parentNode;
|
||||
return nodeStack.getParent();
|
||||
}
|
||||
|
||||
export function peekNode(offset: number): Node {
|
||||
switch (offset) {
|
||||
case 0: return currentNode;
|
||||
case 1: return parentNode;
|
||||
default: return nodeStackSize > 2 ? ancestorStack[nodeStackSize - 1 - offset] : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export function findAncestorNode<T extends Node>(match: (node: Node) => node is T): T;
|
||||
export function findAncestorNode(match: (node: Node) => boolean): Node;
|
||||
export function findAncestorNode(match: (node: Node) => boolean) {
|
||||
for (let i = 1; i < nodeStackSize; i++) {
|
||||
let node = peekNode(i);
|
||||
if (match(node)) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
return nodeStack.findAncestorNode(match);
|
||||
}
|
||||
|
||||
export function getDeclarationName(node: DeclarationStatement): Identifier;
|
||||
@@ -698,12 +672,12 @@ namespace ts {
|
||||
updatedNodes.push(node);
|
||||
}
|
||||
|
||||
function readNodeArray(returnUndefinedIfEmpty?: boolean): NodeArray<Node> {
|
||||
function readNodeArray(flags: VisitorFlags): NodeArray<Node> {
|
||||
if (updatedNodes) {
|
||||
return factory.createNodeArray(updatedNodes, /*location*/ <NodeArray<Node>>originalNodes);
|
||||
}
|
||||
else if (offsetWritten !== originalNodes.length) {
|
||||
if (offsetWritten === 0 && returnUndefinedIfEmpty) {
|
||||
if (offsetWritten === 0 && (flags & VisitorFlags.ReturnUndefinedIfEmpty)) {
|
||||
return undefined;
|
||||
}
|
||||
else {
|
||||
@@ -715,31 +689,42 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
type Visitor = (input: Node, output: (node: Node) => void) => void;
|
||||
|
||||
function pipeOne(input: Node, output: (node: Node) => void, visitor: Visitor): void {
|
||||
pushNode(input);
|
||||
visitor(input, output);
|
||||
popNode();
|
||||
}
|
||||
|
||||
function pipeMany(input: Node[], output: (node: Node) => void, visitor: Visitor): void {
|
||||
// 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`.
|
||||
pushNode(/*node*/ undefined);
|
||||
|
||||
// Visit each input node
|
||||
for (let i = 0, l = input.length; i < l; ++i) {
|
||||
currentNode = input[i];
|
||||
visitor(currentNode, output);
|
||||
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);
|
||||
}
|
||||
|
||||
// For the perf reasons mentioned above, we pop the current node at the end of the loop.
|
||||
popNode();
|
||||
}
|
||||
|
||||
function pipeOneOrMany<T extends Node | Node[]>(input: T, output: (node: Node) => void, visitor: Visitor, newLexicalEnvironment: boolean, pipe: (input: T, output: (node: Node) => void, visitor: Visitor) => void): void {
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
@@ -751,7 +736,7 @@ namespace ts {
|
||||
|
||||
// If we are starting a new lexical environment, we need to reinitialize the lexical
|
||||
// environment state as well
|
||||
if (newLexicalEnvironment) {
|
||||
if (flags & VisitorFlags.NewLexicalEnvironment) {
|
||||
savedTempFlags = tempFlags;
|
||||
savedHoistedVariableDeclarations = hoistedVariableDeclarations;
|
||||
savedHoistedFunctionDeclarations = hoistedFunctionDeclarations;
|
||||
@@ -761,11 +746,11 @@ namespace ts {
|
||||
hoistedFunctionDeclarations = undefined;
|
||||
}
|
||||
|
||||
pipe(input, output, visitor);
|
||||
pipe(input, output, visitor, flags & ~VisitorFlags.NewLexicalEnvironment);
|
||||
|
||||
// If we established a new lexical environment, we need to write any hoisted variables or
|
||||
// function declarations to the end of the output.
|
||||
if (newLexicalEnvironment) {
|
||||
if (flags & VisitorFlags.NewLexicalEnvironment) {
|
||||
if (hoistedVariableDeclarations) {
|
||||
output(factory.createVariableStatement2(
|
||||
factory.createVariableDeclarationList(
|
||||
@@ -793,8 +778,8 @@ namespace ts {
|
||||
* @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, newLexicalEnvironment?: boolean): void {
|
||||
pipeOneOrMany(input, output, visitor, newLexicalEnvironment, pipeOne);
|
||||
export function pipeNode(input: Node, output: (node: Node) => void, visitor: Visitor, flags?: VisitorFlags): void {
|
||||
pipeOneOrMany(input, output, visitor, flags, pipeOne);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -804,11 +789,11 @@ namespace ts {
|
||||
* @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, newLexicalEnvironment?: boolean): void {
|
||||
pipeOneOrMany(input, output, visitor, newLexicalEnvironment, pipeMany);
|
||||
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, newLexicalEnvironment: boolean, pipe: (input: T, output: (node: Node) => void, visitor: Visitor, newLexicalEnvironment: boolean) => void): void {
|
||||
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 {
|
||||
// Exit early if we have nothing to do
|
||||
if (!input) {
|
||||
return;
|
||||
@@ -826,7 +811,7 @@ namespace ts {
|
||||
offsetWritten = 0;
|
||||
writeNodeToNodeArrayFastOrSlow = writeNodeToNodeArrayFast;
|
||||
|
||||
pipe(input, writeNodeToNodeArray, visitor, newLexicalEnvironment);
|
||||
pipe(input, writeNodeToNodeArray, visitor, flags | VisitorFlags.PreserveStack);
|
||||
|
||||
// Restore previous environment
|
||||
originalNodes = savedOriginalNodes;
|
||||
@@ -842,8 +827,8 @@ namespace ts {
|
||||
* @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 emitNode(input: Node, output: Node[], visitor: (input: Node, write: (output: Node) => void) => void, newLexicalEnvironment?: boolean): void {
|
||||
emitOneOrMany(input, output, visitor, newLexicalEnvironment, pipeOne);
|
||||
export function emitNode(input: Node, output: Node[], visitor: (input: Node, write: (output: Node) => void) => void, flags?: VisitorFlags): void {
|
||||
emitOneOrMany(input, output, visitor, flags, pipeOne);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -853,13 +838,15 @@ namespace ts {
|
||||
* @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 emitNodes(input: Node[], output: Node[], visitor: (input: Node, write: (output: Node) => void) => void, newLexicalEnvironment?: boolean): void {
|
||||
emitOneOrMany(input, output, visitor, newLexicalEnvironment, pipeMany);
|
||||
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 visitNode<T extends Node>(node: T, visitor: (input: Node, write: (node: Node) => void) => void): T {
|
||||
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 {
|
||||
if (!node) {
|
||||
return node;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let savedUpdatedNode = updatedNode;
|
||||
@@ -867,16 +854,16 @@ namespace ts {
|
||||
updatedNode = undefined;
|
||||
writeNodeFastOrSlow = writeNodeSlow;
|
||||
|
||||
pipeNode(node, writeNode, visitor);
|
||||
pipeNode(node, writeNode, visitor, flags);
|
||||
|
||||
let visited = <T>readNode();
|
||||
let visited = <TOut>readNode();
|
||||
updatedNode = savedUpdatedNode;
|
||||
writeNodeFastOrSlow = savedWriteOneNode;
|
||||
|
||||
return visited;
|
||||
}
|
||||
|
||||
export function visitStatement(node: Statement, visitor: (input: Node, write: (node: Node) => void) => void) {
|
||||
export function visitStatement(node: Statement, visitor: (input: Node, write: (node: Node) => void) => void, flags?: VisitorFlags) {
|
||||
if (!node) {
|
||||
return node;
|
||||
}
|
||||
@@ -889,7 +876,7 @@ namespace ts {
|
||||
updatedBlock = undefined;
|
||||
writeStatementFastOrSlow = writeStatementSlow;
|
||||
|
||||
pipeNode(node, writeStatement, visitor);
|
||||
pipeNode(node, writeStatement, visitor, flags);
|
||||
|
||||
let visited = readStatement();
|
||||
updatedStatement = savedUpdatedStatement;
|
||||
@@ -899,10 +886,9 @@ namespace ts {
|
||||
return visited;
|
||||
}
|
||||
|
||||
export function visitNodes(nodes: Statement[], visitor: (input: Node, output: (node: Node) => void) => void, newLexicalEnvironment: boolean): NodeArray<Statement>;
|
||||
export function visitNodes<T extends Node>(nodes: T[], visitor: (input: Node, output: (node: Node) => void) => void): NodeArray<T>;
|
||||
export function visitNodes<TIn extends Node, TOut extends Node>(nodes: TIn[], visitor: (input: TIn, output: (node: TOut) => void) => void, newLexicalEnvironment?: boolean, returnUndefinedIfEmpty?: boolean): NodeArray<TOut>;
|
||||
export function visitNodes<TIn extends Node, TOut extends Node>(nodes: TIn[], visitor: (input: TIn, output: (node: TOut) => void) => void, newLexicalEnvironment?: boolean, returnUndefinedIfEmpty?: boolean): NodeArray<TOut> {
|
||||
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> {
|
||||
// Exit early if we have nothing to do
|
||||
if (!nodes) {
|
||||
return undefined;
|
||||
@@ -921,9 +907,9 @@ namespace ts {
|
||||
writeNodeToNodeArrayFastOrSlow = writeNodeToNodeArraySlow;
|
||||
|
||||
// Pipe each node from input into output
|
||||
pipeNodes(originalNodes, writeNodeToNodeArray, visitor, newLexicalEnvironment);
|
||||
pipeNodes(originalNodes, writeNodeToNodeArray, visitor, flags);
|
||||
|
||||
let visited = readNodeArray(returnUndefinedIfEmpty);
|
||||
let visited = readNodeArray(flags);
|
||||
|
||||
// Restore previous environment
|
||||
originalNodes = savedOriginalNodes;
|
||||
@@ -973,13 +959,13 @@ namespace ts {
|
||||
case SyntaxKind.Block:
|
||||
return factory.updateBlock(
|
||||
<Block>node,
|
||||
visitNodes((<Block>node).statements, visitor, /*newLexicalEnvironment*/ true)
|
||||
visitNodes((<Block>node).statements, visitor, VisitorFlags.NewLexicalEnvironment)
|
||||
);
|
||||
|
||||
case SyntaxKind.ModuleBlock:
|
||||
return factory.updateModuleBlock(
|
||||
<ModuleBlock>node,
|
||||
visitNodes((<ModuleBlock>node).statements, visitor, /*newLexicalEnvironment*/ true)
|
||||
visitNodes((<ModuleBlock>node).statements, visitor, VisitorFlags.NewLexicalEnvironment)
|
||||
);
|
||||
|
||||
default:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/*@internal*/
|
||||
namespace ts.transform {
|
||||
export function toES5(statements: NodeArray<Statement>) {
|
||||
return visitNodes(statements, transformNode, /*newLexicalEnvironment*/ true);
|
||||
return visitNodes(statements, transformNode, VisitorFlags.NewLexicalEnvironment);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -153,7 +153,7 @@ namespace ts.transform {
|
||||
let body = factory.createBlock([]);
|
||||
|
||||
if (constructor) {
|
||||
emitNode(constructor, body.statements, transformConstructor, /*newLexicalEnvironment*/ true);
|
||||
emitNode(constructor, body.statements, transformConstructor, VisitorFlags.NewLexicalEnvironment);
|
||||
}
|
||||
else if (baseTypeNode) {
|
||||
let superCall = createDefaultSuperCall();
|
||||
@@ -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, /*newLexicalEnvironment*/ true);
|
||||
emitNode(node, body.statements, transformFunctionBody, 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, /*newLexicalEnvironment*/ true);
|
||||
emitNode(node, body.statements, transformFunctionBody, 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, /*newLexicalEnvironment*/ true);
|
||||
emitNode(node, newBody.statements, transformFunctionBody, VisitorFlags.NewLexicalEnvironment);
|
||||
|
||||
let func = createfn(name, parameters, newBody, location);
|
||||
return func;
|
||||
@@ -526,7 +526,7 @@ namespace ts.transform {
|
||||
}
|
||||
|
||||
function transformThisKeyword(node: LeftHandSideExpression): LeftHandSideExpression {
|
||||
let container = getThisContainer(node, /*includeArrowFunctions*/ true);
|
||||
let container = getThisContainer(transform, /*includeArrowFunctions*/ true);
|
||||
if (isArrowFunction(container)) {
|
||||
let thisName = factory.createIdentifier("_this");
|
||||
return thisName;
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace ts.transform {
|
||||
resolver = getEmitResolver();
|
||||
compilerOptions = getCompilerOptions();
|
||||
languageVersion = compilerOptions.target || ScriptTarget.ES3;
|
||||
return visitNodes(statements, transformNode, /*newLexicalEnvironment*/ true);
|
||||
return visitNodes(statements, transformNode, VisitorFlags.NewLexicalEnvironment);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,24 +74,6 @@ namespace ts.transform {
|
||||
}
|
||||
|
||||
switch (node.kind) {
|
||||
// case SyntaxKind.Block:
|
||||
// case SyntaxKind.ModuleBlock:
|
||||
// case SyntaxKind.CaseClause:
|
||||
// case SyntaxKind.DefaultClause:
|
||||
// // These nodes contain statement lists which may need to be expanded to include multiple statements...
|
||||
// // See NodeArraywrite in transform.ts for approach
|
||||
|
||||
// case SyntaxKind.DoStatement:
|
||||
// case SyntaxKind.WhileStatement:
|
||||
// case SyntaxKind.ForStatement:
|
||||
// case SyntaxKind.ForInStatement:
|
||||
// case SyntaxKind.ForOfStatement:
|
||||
// case SyntaxKind.IfStatement:
|
||||
// case SyntaxKind.LabeledStatement:
|
||||
// case SyntaxKind.WithStatement:
|
||||
// // These nodes contain single statement nodes that may need to be switched to a block if a child node needs multiple statements...
|
||||
// // See Statementwrite in transform.ts for approach
|
||||
|
||||
case SyntaxKind.PublicKeyword:
|
||||
case SyntaxKind.PrivateKeyword:
|
||||
case SyntaxKind.ProtectedKeyword:
|
||||
@@ -100,6 +82,7 @@ namespace ts.transform {
|
||||
case SyntaxKind.ConstKeyword:
|
||||
case SyntaxKind.DeclareKeyword:
|
||||
// TypeScript accessibility modifiers are elided.
|
||||
return;
|
||||
|
||||
case SyntaxKind.ArrayType:
|
||||
case SyntaxKind.TupleType:
|
||||
@@ -118,31 +101,37 @@ namespace ts.transform {
|
||||
case SyntaxKind.UnionType:
|
||||
case SyntaxKind.IntersectionType:
|
||||
// TypeScript type nodes are elided.
|
||||
return;
|
||||
|
||||
case SyntaxKind.IndexSignature:
|
||||
// TypeScript index signatures are elided.
|
||||
return;
|
||||
|
||||
case SyntaxKind.Decorator:
|
||||
// TypeScript decorators are elided. They will be emitted as part of transformClassDeclaration.
|
||||
return;
|
||||
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
// TypeScript type-only declarations are elided
|
||||
return;
|
||||
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
// 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`.
|
||||
return;
|
||||
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
// TypeScript interfaces and type aliases are elided.
|
||||
|
||||
return;
|
||||
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
@@ -233,9 +222,9 @@ namespace ts.transform {
|
||||
// TypeScript 'await' expressions must be transformed.
|
||||
return transformAwaitExpression(<AwaitExpression>node, write);
|
||||
|
||||
// case SyntaxKind.VariableStatement:
|
||||
// // TypeScript namespace exports for variable statements must be transformed.
|
||||
// return transformVariableStatement(<VariableStatement>node, write);
|
||||
case SyntaxKind.VariableStatement:
|
||||
// TypeScript namespace exports for variable statements must be transformed.
|
||||
return transformVariableStatement(<VariableStatement>node, write);
|
||||
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
// TypeScript namespace declarations must be transformed.
|
||||
@@ -362,7 +351,7 @@ namespace ts.transform {
|
||||
let name = <Identifier>getDeclarationName(node);
|
||||
Debug.assert(isIdentifier(name));
|
||||
|
||||
if (getCombinedNodeFlags(node) & NodeFlags.Export) {
|
||||
if (getCombinedNodeFlags(transform) & NodeFlags.Export) {
|
||||
let container = getContainingModuleName();
|
||||
let propExpr = factory.createPropertyAccessExpression2(container, name);
|
||||
return propExpr;
|
||||
@@ -788,16 +777,27 @@ namespace ts.transform {
|
||||
}
|
||||
|
||||
function transformVariableDeclarationList(node: VariableDeclarationList, write: (node: Statement) => void) {
|
||||
let expressions = visitNodes<VariableDeclaration, Expression>(node.declarations, transformVariableDeclaration, /*newLexicalEnvironment*/ false, /*returnUndefinedIfEmpty*/ true);
|
||||
if (expressions) {
|
||||
let expressions: Expression[] = [];
|
||||
emitNodes(node.declarations, expressions, transformVariableDeclaration);
|
||||
|
||||
if (expressions.length) {
|
||||
let exprStmt = factory.createExpressionStatement(factory.inlineExpressions(expressions));
|
||||
write(exprStmt);
|
||||
}
|
||||
}
|
||||
|
||||
function transformVariableDeclaration(node: VariableDeclaration, write: (node: Expression) => void) {
|
||||
if (isBindingPattern(node.name)) {
|
||||
Debug.fail("Transform not yet supported.");
|
||||
if (!node.initializer) {
|
||||
return;
|
||||
}
|
||||
|
||||
let name = node.name;
|
||||
if (isBindingPattern(name)) {
|
||||
let expr = visitNode<BindingPattern, Expression>(name, transformBindingPatternToExpression);
|
||||
let initializer = visitNode(node.initializer, transformNode);
|
||||
let assignExpr = factory.createAssignmentExpression(expr, initializer);
|
||||
let parenExpr = factory.createParenthesizedExpression(assignExpr);
|
||||
write(parenExpr);
|
||||
}
|
||||
else {
|
||||
let name = getModuleMemberName(node);
|
||||
@@ -806,6 +806,27 @@ namespace ts.transform {
|
||||
write(assignExpr);
|
||||
}
|
||||
}
|
||||
|
||||
function transformBindingPatternToExpression(node: BindingPattern, write: (node: Expression) => void) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ObjectBindingPattern:
|
||||
return transformObjectBindingPatternToExpression(<ObjectBindingPattern>node, write);
|
||||
|
||||
case SyntaxKind.ArrayBindingPattern:
|
||||
return transformArrayBindingPatternToExpression(<ObjectBindingPattern>node, write);
|
||||
}
|
||||
}
|
||||
|
||||
function transformObjectBindingPatternToExpression(node: ObjectBindingPattern, write: (node: Expression) => void) {
|
||||
let properties: ObjectLiteralElement[] = [];
|
||||
|
||||
write(factory.createObjectLiteralExpression2(properties));
|
||||
}
|
||||
|
||||
function transformArrayBindingPatternToExpression(node: ArrayBindingPattern, write: (node: Expression) => void) {
|
||||
let elements: Expression[] = [];
|
||||
write(factory.createArrayLiteralExpression(elements));
|
||||
}
|
||||
|
||||
function transformModuleDeclaration(node: ModuleDeclaration, write: (node: Statement) => void) {
|
||||
if (!shouldEmitModuleDeclaration(node)) {
|
||||
|
||||
@@ -1830,8 +1830,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Source files are declarations when they are external modules.
|
||||
// @kind(SyntaxKind.SourceFile)
|
||||
// @factoryhidden
|
||||
// @kind(SyntaxKind.SourceFile, { create: false, update: false })
|
||||
// @factoryhidden("decorators")
|
||||
// @factoryhidden("modifiers")
|
||||
// @factoryhidden("name")
|
||||
export interface SourceFile extends Declaration {
|
||||
statements: NodeArray<Statement>;
|
||||
endOfFileToken: Node;
|
||||
@@ -1861,6 +1863,7 @@ namespace ts {
|
||||
languageVersion: ScriptTarget;
|
||||
|
||||
// The first node that causes this file to be an external module
|
||||
// @factoryhidden
|
||||
/* @internal */ externalModuleIndicator: Node;
|
||||
|
||||
/* @internal */ isDefaultLib: boolean;
|
||||
|
||||
@@ -391,7 +391,7 @@ namespace ts {
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
export function isConst(navigable: ParentNavigable): boolean {
|
||||
return !!(getCombinedNodeFlags(navigable) & NodeFlags.Const);
|
||||
}
|
||||
@@ -717,7 +717,7 @@ namespace ts {
|
||||
break;
|
||||
case SyntaxKind.Decorator:
|
||||
// Decorators are always applied outside of the body of a class or method.
|
||||
if (nav.getParent().kind === SyntaxKind.Parameter && isClassElement(nav.getGrandparent())) {
|
||||
if (isParameter(nav.getParent()) && isClassElement(nav.getGrandparent())) {
|
||||
// If the decorator's parent is a Parameter, we resolve the this container from
|
||||
// the grandparent class declaration.
|
||||
nav.moveToParent();
|
||||
@@ -773,7 +773,8 @@ namespace ts {
|
||||
break;
|
||||
case SyntaxKind.Decorator:
|
||||
// Decorators are always applied outside of the body of a class or method.
|
||||
if (nav.getParent().kind === SyntaxKind.Parameter && isClassElement(nav.getGrandparent())) {
|
||||
if (isParameter(nav.getParent())
|
||||
&& isClassElement(nav.getGrandparent())) {
|
||||
// If the decorator's parent is a Parameter, we resolve the this container from
|
||||
// the grandparent class declaration.
|
||||
nav.moveToParent();
|
||||
|
||||
@@ -225,7 +225,7 @@ namespace ts {
|
||||
public getText(sourceFile?: SourceFile): string {
|
||||
return (sourceFile || this.getSourceFile()).text.substring(this.getStart(), this.getEnd());
|
||||
}
|
||||
|
||||
|
||||
private addSyntheticNodes(nodes: Node[], pos: number, end: number): number {
|
||||
scanner.setTextPos(pos);
|
||||
while (pos < end) {
|
||||
|
||||
Reference in New Issue
Block a user