mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-16 05:58:32 -06:00
cleaned up assertions and removed flattenNodes.
This commit is contained in:
parent
2699bf923b
commit
94018a13e6
@ -1035,7 +1035,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
export namespace Debug {
|
||||
const currentAssertionLevel = AssertionLevel.None;
|
||||
declare var process: any;
|
||||
declare var require: any;
|
||||
|
||||
const currentAssertionLevel = getDevelopmentMode() === "development"
|
||||
? AssertionLevel.Normal
|
||||
: AssertionLevel.None;
|
||||
|
||||
export function shouldAssert(level: AssertionLevel): boolean {
|
||||
return currentAssertionLevel >= level;
|
||||
@ -1055,6 +1060,17 @@ namespace ts {
|
||||
export function fail(message?: string): void {
|
||||
Debug.assert(/*expression*/ false, message);
|
||||
}
|
||||
|
||||
function getDevelopmentMode() {
|
||||
return typeof require !== "undefined"
|
||||
&& typeof process !== "undefined"
|
||||
&& !process.browser
|
||||
&& process.nextTick
|
||||
&& process.env
|
||||
&& process.env.NODE_ENV
|
||||
? String(process.env.NODE_ENV).toLowerCase()
|
||||
: undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export function copyListRemovingItem<T>(item: T, list: T[]) {
|
||||
|
||||
@ -16,7 +16,7 @@ namespace ts {
|
||||
node: BinaryExpression,
|
||||
needsValue: boolean,
|
||||
recordTempVariable: (node: Identifier) => void,
|
||||
visitor?: (node: Node) => OneOrMany<Node>) {
|
||||
visitor?: (node: Node) => VisitResult<Node>) {
|
||||
|
||||
if (isEmptyObjectLiteralOrArrayLiteral(node.left)) {
|
||||
return node.right;
|
||||
@ -79,7 +79,7 @@ namespace ts {
|
||||
* @param value The rhs value for the binding pattern.
|
||||
* @param visitor An optional visitor to use to visit expressions.
|
||||
*/
|
||||
export function flattenParameterDestructuring(node: ParameterDeclaration, value: Expression, visitor?: (node: Node) => OneOrMany<Node>) {
|
||||
export function flattenParameterDestructuring(node: ParameterDeclaration, value: Expression, visitor?: (node: Node) => VisitResult<Node>) {
|
||||
const declarations: VariableDeclaration[] = [];
|
||||
|
||||
flattenDestructuring(node, value, node, emitAssignment, emitTempVariableAssignment, visitor);
|
||||
@ -110,7 +110,7 @@ namespace ts {
|
||||
* @param value An optional rhs value for the binding pattern.
|
||||
* @param visitor An optional visitor to use to visit expressions.
|
||||
*/
|
||||
export function flattenVariableDestructuring(node: VariableDeclaration, value?: Expression, visitor?: (node: Node) => OneOrMany<Node>) {
|
||||
export function flattenVariableDestructuring(node: VariableDeclaration, value?: Expression, visitor?: (node: Node) => VisitResult<Node>) {
|
||||
const declarations: VariableDeclaration[] = [];
|
||||
|
||||
flattenDestructuring(node, value, node, emitAssignment, emitTempVariableAssignment, visitor);
|
||||
@ -151,7 +151,7 @@ namespace ts {
|
||||
node: VariableDeclaration,
|
||||
recordTempVariable: (name: Identifier) => void,
|
||||
nameSubstitution?: (name: Identifier) => Expression,
|
||||
visitor?: (node: Node) => OneOrMany<Node>) {
|
||||
visitor?: (node: Node) => VisitResult<Node>) {
|
||||
|
||||
const pendingAssignments: Expression[] = [];
|
||||
|
||||
@ -191,7 +191,7 @@ namespace ts {
|
||||
location: TextRange,
|
||||
emitAssignment: (name: Identifier, value: Expression, location: TextRange, original: Node) => void,
|
||||
emitTempVariableAssignment: (value: Expression, location: TextRange) => Identifier,
|
||||
visitor?: (node: Node) => OneOrMany<Node>) {
|
||||
visitor?: (node: Node) => VisitResult<Node>) {
|
||||
if (value && visitor) {
|
||||
value = visitNode(value, visitor, isExpression);
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@ namespace ts {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function visitor(node: Node): OneOrMany<Node> {
|
||||
function visitor(node: Node): VisitResult<Node> {
|
||||
const savedContainingNonArrowFunction = containingNonArrowFunction;
|
||||
const savedCurrentParent = currentParent;
|
||||
const savedCurrentNode = currentNode;
|
||||
@ -74,7 +74,7 @@ namespace ts {
|
||||
return visited;
|
||||
}
|
||||
|
||||
function visitorWorker(node: Node): OneOrMany<Node> {
|
||||
function visitorWorker(node: Node): VisitResult<Node> {
|
||||
if (node.transformFlags & TransformFlags.ES6) {
|
||||
return visitJavaScript(node);
|
||||
}
|
||||
@ -86,7 +86,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function visitJavaScript(node: Node): OneOrMany<Node> {
|
||||
function visitJavaScript(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
return visitClassDeclaration(<ClassDeclaration>node);
|
||||
@ -174,9 +174,12 @@ namespace ts {
|
||||
|
||||
case SyntaxKind.SourceFile:
|
||||
return visitSourceFileNode(<SourceFile>node);
|
||||
|
||||
default:
|
||||
Debug.failBadSyntaxKind(node);
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
Debug.fail(`Unexpected node kind: ${formatSyntaxKind(node.kind)}.`);
|
||||
}
|
||||
|
||||
function onBeforeVisitNode(node: Node) {
|
||||
@ -695,7 +698,7 @@ namespace ts {
|
||||
break;
|
||||
|
||||
default:
|
||||
Debug.fail(`Unexpected node kind: ${formatSyntaxKind(node.kind)}.`);
|
||||
Debug.failBadSyntaxKind(node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -936,7 +939,7 @@ namespace ts {
|
||||
enableSubstitutionsForBlockScopedBindings();
|
||||
return setOriginalNode(
|
||||
createVariableDeclarationList(
|
||||
flattenNodes(map(node.declarations, visitVariableDeclarationInLetDeclarationList)),
|
||||
flatten(map(node.declarations, visitVariableDeclarationInLetDeclarationList)),
|
||||
/*location*/ node
|
||||
),
|
||||
node
|
||||
@ -1043,7 +1046,7 @@ namespace ts {
|
||||
*
|
||||
* @param node A VariableDeclaration node.
|
||||
*/
|
||||
function visitVariableDeclaration(node: VariableDeclaration): OneOrMany<VariableDeclaration> {
|
||||
function visitVariableDeclaration(node: VariableDeclaration): VisitResult<VariableDeclaration> {
|
||||
// If we are here it is because the name contains a binding pattern.
|
||||
Debug.assert(isBindingPattern(node.name));
|
||||
|
||||
@ -1293,7 +1296,7 @@ namespace ts {
|
||||
break;
|
||||
|
||||
default:
|
||||
Debug.fail(`Unexpected node kind: ${formatSyntaxKind(node.kind)}.`);
|
||||
Debug.failBadSyntaxKind(node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@ namespace ts {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function visitor(node: Node): OneOrMany<Node> {
|
||||
function visitor(node: Node): VisitResult<Node> {
|
||||
if (node.transformFlags & TransformFlags.ES7) {
|
||||
return visitorWorker(node);
|
||||
}
|
||||
@ -24,13 +24,15 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function visitorWorker(node: Node): OneOrMany<Node> {
|
||||
function visitorWorker(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.BinaryExpression:
|
||||
return visitBinaryExpression(<BinaryExpression>node);
|
||||
}
|
||||
|
||||
Debug.fail(`Unexpected node kind: ${formatSyntaxKind(node.kind)}.`);
|
||||
default:
|
||||
Debug.failBadSyntaxKind(node);
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
}
|
||||
|
||||
function visitBinaryExpression(node: BinaryExpression): Expression {
|
||||
@ -90,7 +92,8 @@ namespace ts {
|
||||
return createMathPow(left, right, /*location*/ node);
|
||||
}
|
||||
else {
|
||||
Debug.fail(`Unexpected operator kind: ${formatSyntaxKind(node.operatorToken.kind)}.`);
|
||||
Debug.failBadSyntaxKind(node);
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ namespace ts {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function visitor(node: Node): OneOrMany<Node> {
|
||||
function visitor(node: Node): VisitResult<Node> {
|
||||
if (node.transformFlags & TransformFlags.Jsx) {
|
||||
return visitorWorker(node);
|
||||
}
|
||||
@ -30,16 +30,18 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function visitorWorker(node: Node): OneOrMany<Node> {
|
||||
function visitorWorker(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.JsxElement:
|
||||
return visitJsxElement(<JsxElement>node);
|
||||
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
return visitJsxSelfClosingElement(<JsxSelfClosingElement>node);
|
||||
}
|
||||
|
||||
Debug.fail(`Unexpected node kind: ${formatSyntaxKind(node.kind)}.`);
|
||||
default:
|
||||
Debug.failBadSyntaxKind(node);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function transformJsxChildToExpression(node: JsxChild): Expression {
|
||||
@ -55,9 +57,11 @@ namespace ts {
|
||||
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
return visitJsxSelfClosingElement(<JsxSelfClosingElement>node);
|
||||
}
|
||||
|
||||
Debug.fail(`Unexpected node kind: ${formatSyntaxKind(node.kind)}.`);
|
||||
default:
|
||||
Debug.failBadSyntaxKind(node);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function visitJsxElement(node: JsxElement) {
|
||||
|
||||
@ -123,7 +123,7 @@ namespace ts {
|
||||
createStatement(
|
||||
createCall(
|
||||
define,
|
||||
flattenNodes([
|
||||
flatten([
|
||||
// Add the module name (if provided).
|
||||
moduleName,
|
||||
|
||||
@ -142,7 +142,7 @@ namespace ts {
|
||||
setNodeEmitFlags(
|
||||
setMultiLine(
|
||||
createBlock(
|
||||
flattenNodes([
|
||||
flatten([
|
||||
// Visit each statement of the module body.
|
||||
...visitNodes(node.statements, visitor, isStatement),
|
||||
|
||||
@ -173,7 +173,7 @@ namespace ts {
|
||||
*
|
||||
* @param node The node.
|
||||
*/
|
||||
function visitor(node: Node): OneOrMany<Node> {
|
||||
function visitor(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
return visitImportDeclaration(<ImportDeclaration>node);
|
||||
@ -208,7 +208,7 @@ namespace ts {
|
||||
*
|
||||
* @param node The ImportDeclaration node.
|
||||
*/
|
||||
function visitImportDeclaration(node: ImportDeclaration): OneOrMany<Statement> {
|
||||
function visitImportDeclaration(node: ImportDeclaration): VisitResult<Statement> {
|
||||
if (contains(externalImports, node)) {
|
||||
const statements: Statement[] = [];
|
||||
const namespaceDeclaration = getNamespaceDeclarationNode(node);
|
||||
@ -287,7 +287,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): OneOrMany<Statement> {
|
||||
function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult<Statement> {
|
||||
if (contains(externalImports, node)) {
|
||||
const statements: Statement[] = [];
|
||||
if (moduleKind !== ModuleKind.AMD) {
|
||||
@ -335,7 +335,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function visitExportDeclaration(node: ExportDeclaration): OneOrMany<Statement> {
|
||||
function visitExportDeclaration(node: ExportDeclaration): VisitResult<Statement> {
|
||||
if (contains(externalImports, node)) {
|
||||
const generatedName = getGeneratedNameForNode(node);
|
||||
if (node.exportClause) {
|
||||
@ -391,7 +391,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function visitExportAssignment(node: ExportAssignment): OneOrMany<Statement> {
|
||||
function visitExportAssignment(node: ExportAssignment): VisitResult<Statement> {
|
||||
if (!node.isExportEquals && resolver.isValueAliasDeclaration(node)) {
|
||||
const statements: Statement[] = [];
|
||||
addExportDefault(statements, node.expression, /*location*/ node);
|
||||
@ -470,7 +470,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function visitVariableStatement(node: VariableStatement): OneOrMany<Statement> {
|
||||
function visitVariableStatement(node: VariableStatement): VisitResult<Statement> {
|
||||
const variables = getInitializedVariables(node.declarationList);
|
||||
if (variables.length === 0) {
|
||||
// elide statement if there are no initialized variables
|
||||
@ -502,7 +502,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function visitFunctionDeclaration(node: FunctionDeclaration): OneOrMany<Statement> {
|
||||
function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult<Statement> {
|
||||
const statements: Statement[] = [];
|
||||
if (node.name) {
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
@ -543,7 +543,7 @@ namespace ts {
|
||||
return statements;
|
||||
}
|
||||
|
||||
function visitClassDeclaration(node: ClassDeclaration): OneOrMany<Statement> {
|
||||
function visitClassDeclaration(node: ClassDeclaration): VisitResult<Statement> {
|
||||
const statements: Statement[] = [];
|
||||
if (node.name) {
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
|
||||
@ -408,7 +408,7 @@ namespace ts {
|
||||
return createArrayLiteral(setters);
|
||||
}
|
||||
|
||||
function visitSourceElement(node: Node): OneOrMany<Node> {
|
||||
function visitSourceElement(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
return visitImportDeclaration(<ImportDeclaration>node);
|
||||
@ -427,7 +427,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function visitNestedNode(node: Node): OneOrMany<Node> {
|
||||
function visitNestedNode(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.VariableStatement:
|
||||
return visitVariableStatement(<VariableStatement>node);
|
||||
@ -502,7 +502,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function visitExportDeclaration(node: ExportDeclaration): OneOrMany<Statement> {
|
||||
function visitExportDeclaration(node: ExportDeclaration): VisitResult<Statement> {
|
||||
if (!node.moduleSpecifier) {
|
||||
const statements: Statement[] = [];
|
||||
addNodes(statements, map(node.exportClause.elements, visitExportSpecifier));
|
||||
@ -541,7 +541,7 @@ namespace ts {
|
||||
*
|
||||
* @param node The variable statement to visit.
|
||||
*/
|
||||
function visitVariableStatement(node: VariableStatement): OneOrMany<Statement> {
|
||||
function visitVariableStatement(node: VariableStatement): VisitResult<Statement> {
|
||||
const isExported = hasModifier(node, ModifierFlags.Export);
|
||||
const expressions: Expression[] = [];
|
||||
for (const variable of node.declarationList.declarations) {
|
||||
@ -616,7 +616,7 @@ namespace ts {
|
||||
*
|
||||
* @param node The class declaration to visit.
|
||||
*/
|
||||
function visitClassDeclaration(node: ClassDeclaration): OneOrMany<Statement> {
|
||||
function visitClassDeclaration(node: ClassDeclaration): VisitResult<Statement> {
|
||||
// Hoist the name of the class declaration to the outer module body function.
|
||||
const name = getDeclarationName(node);
|
||||
hoistVariableDeclaration(name);
|
||||
|
||||
@ -92,7 +92,7 @@ namespace ts {
|
||||
*
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function visitWithStack(node: Node, visitor: (node: Node) => OneOrMany<Node>): OneOrMany<Node> {
|
||||
function visitWithStack(node: Node, visitor: (node: Node) => VisitResult<Node>): VisitResult<Node> {
|
||||
// Save state
|
||||
const savedCurrentNamespace = currentNamespace;
|
||||
const savedCurrentScope = currentScope;
|
||||
@ -118,7 +118,7 @@ namespace ts {
|
||||
*
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function visitor(node: Node): OneOrMany<Node> {
|
||||
function visitor(node: Node): VisitResult<Node> {
|
||||
return visitWithStack(node, visitorWorker);
|
||||
}
|
||||
|
||||
@ -127,7 +127,7 @@ namespace ts {
|
||||
*
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function visitorWorker(node: Node): OneOrMany<Node> {
|
||||
function visitorWorker(node: Node): VisitResult<Node> {
|
||||
if (node.transformFlags & TransformFlags.TypeScript) {
|
||||
// This node is explicitly marked as TypeScript, so we should transform the node.
|
||||
return visitTypeScript(node);
|
||||
@ -145,7 +145,7 @@ namespace ts {
|
||||
*
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function namespaceElementVisitor(node: Node): OneOrMany<Node> {
|
||||
function namespaceElementVisitor(node: Node): VisitResult<Node> {
|
||||
return visitWithStack(node, namespaceElementVisitorWorker);
|
||||
}
|
||||
|
||||
@ -154,7 +154,7 @@ namespace ts {
|
||||
*
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function namespaceElementVisitorWorker(node: Node): OneOrMany<Node> {
|
||||
function namespaceElementVisitorWorker(node: Node): VisitResult<Node> {
|
||||
if (node.transformFlags & TransformFlags.TypeScript || isExported(node)) {
|
||||
// This node is explicitly marked as TypeScript, or is exported at the namespace
|
||||
// level, so we should transform the node.
|
||||
@ -173,7 +173,7 @@ namespace ts {
|
||||
*
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function classElementVisitor(node: Node): OneOrMany<Node> {
|
||||
function classElementVisitor(node: Node): VisitResult<Node> {
|
||||
return visitWithStack(node, classElementVisitorWorker);
|
||||
}
|
||||
|
||||
@ -182,7 +182,7 @@ namespace ts {
|
||||
*
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function classElementVisitorWorker(node: Node): OneOrMany<Node> {
|
||||
function classElementVisitorWorker(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.Constructor:
|
||||
// TypeScript constructors are transformed in `transformClassDeclaration`.
|
||||
@ -202,8 +202,8 @@ namespace ts {
|
||||
return node;
|
||||
|
||||
default:
|
||||
Debug.fail(`Unexpected node kind: ${formatSyntaxKind(node.kind)}.`);
|
||||
break;
|
||||
Debug.failBadSyntaxKind(node);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@ -212,7 +212,7 @@ namespace ts {
|
||||
*
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function visitTypeScript(node: Node): OneOrMany<Node> {
|
||||
function visitTypeScript(node: Node): VisitResult<Node> {
|
||||
if (hasModifier(node, ModifierFlags.Ambient)) {
|
||||
// TypeScript ambient declarations are elided.
|
||||
return undefined;
|
||||
@ -373,8 +373,8 @@ namespace ts {
|
||||
return visitImportEqualsDeclaration(<ImportEqualsDeclaration>node);
|
||||
|
||||
default:
|
||||
Debug.fail(`Unexpected node kind: ${formatSyntaxKind(node.kind)}.`);
|
||||
break;
|
||||
Debug.failBadSyntaxKind(node);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@ -408,7 +408,7 @@ namespace ts {
|
||||
*
|
||||
* @param node The node to transform.
|
||||
*/
|
||||
function visitClassDeclaration(node: ClassDeclaration): OneOrMany<Statement> {
|
||||
function visitClassDeclaration(node: ClassDeclaration): VisitResult<Statement> {
|
||||
const staticProperties = getInitializedProperties(node, /*isStatic*/ true);
|
||||
const hasExtendsClause = getClassExtendsHeritageClauseElement(node) !== undefined;
|
||||
|
||||
@ -1553,7 +1553,7 @@ namespace ts {
|
||||
break;
|
||||
|
||||
default:
|
||||
Debug.fail(`Unexpected node kind: ${formatSyntaxKind(node.kind)}.`);
|
||||
Debug.failBadSyntaxKind(node);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1855,7 +1855,7 @@ namespace ts {
|
||||
*
|
||||
* @param node The function node.
|
||||
*/
|
||||
function visitFunctionDeclaration(node: FunctionDeclaration): OneOrMany<Statement> {
|
||||
function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult<Statement> {
|
||||
if (shouldElideFunctionLikeDeclaration(node)) {
|
||||
return undefined;
|
||||
}
|
||||
@ -2150,7 +2150,7 @@ namespace ts {
|
||||
*
|
||||
* @param node The enum declaration node.
|
||||
*/
|
||||
function visitEnumDeclaration(node: EnumDeclaration): OneOrMany<Statement> {
|
||||
function visitEnumDeclaration(node: EnumDeclaration): VisitResult<Statement> {
|
||||
if (shouldElideEnumDeclaration(node)) {
|
||||
return undefined;
|
||||
}
|
||||
@ -2362,7 +2362,7 @@ namespace ts {
|
||||
*
|
||||
* @param node The module declaration node.
|
||||
*/
|
||||
function visitModuleDeclaration(node: ModuleDeclaration): OneOrMany<Statement> {
|
||||
function visitModuleDeclaration(node: ModuleDeclaration): VisitResult<Statement> {
|
||||
if (shouldElideModuleDeclaration(node)) {
|
||||
return undefined;
|
||||
}
|
||||
@ -2481,7 +2481,7 @@ namespace ts {
|
||||
*
|
||||
* @param node The import equals declaration node.
|
||||
*/
|
||||
function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): OneOrMany<Statement> {
|
||||
function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult<Statement> {
|
||||
Debug.assert(!isExternalModuleImportEqualsDeclaration(node));
|
||||
if (shouldElideImportEqualsDeclaration(node)) {
|
||||
return undefined;
|
||||
|
||||
@ -2735,6 +2735,8 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export const enum TransformFlags {
|
||||
None = 0,
|
||||
|
||||
// Facts
|
||||
// - Flags used to indicate that a node or subtree contains syntax that requires transformation.
|
||||
TypeScript = 1 << 0,
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
export type OneOrMany<T extends Node> = T | T[];
|
||||
export type VisitResult<T extends Node> = T | T[];
|
||||
|
||||
/**
|
||||
* Describes an edge of a Node, used when traversing a syntax tree.
|
||||
@ -448,7 +448,7 @@ namespace ts {
|
||||
* @param f The callback function
|
||||
* @param initial The initial value to supply to the reduction.
|
||||
*/
|
||||
export function reduceEachChild<T>(node: Node, f: (memo: T, node: Node) => T, initial: T) {
|
||||
export function reduceEachChild<T>(node: Node, f: (memo: T, node: Node) => T, initial: T): T {
|
||||
if (node === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
@ -478,7 +478,7 @@ namespace ts {
|
||||
* @param optional An optional value indicating whether the Node is itself optional.
|
||||
* @param lift An optional callback to execute to lift a NodeArrayNode into a valid Node.
|
||||
*/
|
||||
export function visitNode<T extends Node>(node: T, visitor: (node: Node) => OneOrMany<Node>, test: (node: Node) => boolean, optional?: boolean, lift?: (node: NodeArray<Node>) => T): T {
|
||||
export function visitNode<T extends Node>(node: T, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, optional?: boolean, lift?: (node: NodeArray<Node>) => T): T {
|
||||
return <T>visitNodeWorker(node, visitor, test, optional, lift, /*parenthesize*/ undefined, /*parentNode*/ undefined);
|
||||
}
|
||||
|
||||
@ -493,24 +493,26 @@ namespace ts {
|
||||
* @param parenthesize A callback used to parenthesize the node if needed.
|
||||
* @param parentNode A parentNode for the node.
|
||||
*/
|
||||
function visitNodeWorker(node: Node, visitor: (node: Node) => OneOrMany<Node>, test: (node: Node) => boolean, optional: boolean, lift: (node: NodeArray<Node>) => Node, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node): Node {
|
||||
function visitNodeWorker(node: Node, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, optional: boolean, lift: (node: Node[]) => Node, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node): Node {
|
||||
if (node === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let visited = visitor(node);
|
||||
const visited = visitor(node);
|
||||
if (visited === node) {
|
||||
return node;
|
||||
}
|
||||
|
||||
let visitedNode: Node;
|
||||
if (visited === undefined) {
|
||||
Debug.assert(optional, "Node not optional.");
|
||||
if (!optional) {
|
||||
Debug.failNotOptional();
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let visitedNode: Node;
|
||||
if (isArray(visited)) {
|
||||
visitedNode = (lift || extractSingleNode)(<NodeArray<Node>>visited);
|
||||
else if (isArray(visited)) {
|
||||
visitedNode = (lift || extractSingleNode)(visited);
|
||||
}
|
||||
else {
|
||||
visitedNode = visited;
|
||||
@ -520,7 +522,7 @@ namespace ts {
|
||||
visitedNode = parenthesize(visitedNode, parentNode);
|
||||
}
|
||||
|
||||
Debug.assert(test === undefined || test(visitedNode), "Wrong node type after visit.", () => `Node ${formatSyntaxKind(visitedNode.kind)} did not pass test ${(<any>test).name}.`);
|
||||
Debug.assertNode(visitedNode, test);
|
||||
aggregateTransformFlags(visitedNode);
|
||||
return visitedNode;
|
||||
}
|
||||
@ -534,7 +536,7 @@ namespace ts {
|
||||
* @param start An optional value indicating the starting offset at which to start visiting.
|
||||
* @param count An optional value indicating the maximum number of nodes to visit.
|
||||
*/
|
||||
export function visitNodes<T extends Node, TArray extends NodeArray<T>>(nodes: TArray, visitor: (node: Node) => OneOrMany<Node>, test: (node: Node) => boolean, start?: number, count?: number): TArray {
|
||||
export function visitNodes<T extends Node, TArray extends NodeArray<T>>(nodes: TArray, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, start?: number, count?: number): TArray {
|
||||
return <TArray>visitNodesWorker(nodes, visitor, test, /*parenthesize*/ undefined, /*parentNode*/ undefined, start, count);
|
||||
}
|
||||
|
||||
@ -547,12 +549,12 @@ namespace ts {
|
||||
* @param start An optional value indicating the starting offset at which to start visiting.
|
||||
* @param count An optional value indicating the maximum number of nodes to visit.
|
||||
*/
|
||||
function visitNodesWorker(nodes: NodeArray<Node>, visitor: (node: Node) => OneOrMany<Node>, test: (node: Node) => boolean, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node, start: number, count: number): NodeArray<Node> {
|
||||
function visitNodesWorker(nodes: NodeArray<Node>, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node, start: number, count: number): NodeArray<Node> {
|
||||
if (nodes === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let updated: Node[];
|
||||
let updated: NodeArray<Node>;
|
||||
|
||||
// Ensure start and count have valid values
|
||||
const length = nodes.length;
|
||||
@ -564,9 +566,12 @@ namespace ts {
|
||||
count = length - start;
|
||||
}
|
||||
|
||||
// If we are not visiting all of the original nodes, we must always create a new array.
|
||||
if (start > 0 || count < length) {
|
||||
updated = [];
|
||||
// If we are not visiting all of the original nodes, we must always create a new array.
|
||||
// Since this is a fragment of a node array, we do not copy over the previous location
|
||||
// and will only copy over `hasTrailingComma` if we are including the last element.
|
||||
updated = createNodeArray<Node>([], /*location*/ undefined,
|
||||
/*hasTrailingComma*/ nodes.hasTrailingComma && start + count === length);
|
||||
}
|
||||
|
||||
// Visit each original node.
|
||||
@ -576,18 +581,14 @@ namespace ts {
|
||||
if (updated !== undefined || visited === undefined || visited !== node) {
|
||||
if (updated === undefined) {
|
||||
// Ensure we have a copy of `nodes`, up to the current index.
|
||||
updated = nodes.slice(0, i);
|
||||
updated = createNodeArray(nodes.slice(0, i), /*location*/ nodes, nodes.hasTrailingComma);
|
||||
}
|
||||
|
||||
addNodeWorker(updated, visited, /*addOnNewLine*/ undefined, test, parenthesize, parentNode, /*isVisiting*/ visited !== node);
|
||||
}
|
||||
}
|
||||
|
||||
if (updated !== undefined) {
|
||||
return createNodeArray(updated, nodes, nodes.hasTrailingComma);
|
||||
}
|
||||
|
||||
return nodes;
|
||||
return updated || nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -597,8 +598,8 @@ namespace ts {
|
||||
* @param visitor The callback used to visit each child.
|
||||
* @param context A lexical environment context for the visitor.
|
||||
*/
|
||||
export function visitEachChild<T extends Node>(node: T, visitor: (node: Node) => OneOrMany<Node>, context: LexicalEnvironment): T;
|
||||
export function visitEachChild<T extends Node>(node: T & Map<any>, visitor: (node: Node) => OneOrMany<Node>, context: LexicalEnvironment): T {
|
||||
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 {
|
||||
if (node === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
@ -657,33 +658,13 @@ namespace ts {
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flattens an array of nodes that could contain NodeArrayNodes.
|
||||
*/
|
||||
export function flattenNodes<T extends Node>(nodes: OneOrMany<T>[]): T[] {
|
||||
let result: T[];
|
||||
if (nodes) {
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
const node = nodes[i];
|
||||
if (result || node === undefined || isArray(node)) {
|
||||
if (!result) {
|
||||
result = <T[]>nodes.slice(0, i);
|
||||
}
|
||||
addNode(result, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result || <T[]>nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a node to an array.
|
||||
*
|
||||
* @param to The destination array.
|
||||
* @param from The source Node or NodeArrayNode.
|
||||
*/
|
||||
export function addNode<T extends Node>(to: T[], from: OneOrMany<T>, startOnNewLine?: boolean) {
|
||||
export function addNode<T extends Node>(to: T[], from: VisitResult<T>, startOnNewLine?: boolean): void {
|
||||
addNodeWorker(to, from, startOnNewLine, /*test*/ undefined, /*parenthesize*/ undefined, /*parentNode*/ undefined, /*isVisiting*/ false);
|
||||
}
|
||||
|
||||
@ -693,18 +674,21 @@ namespace ts {
|
||||
* @param to The destination NodeArray.
|
||||
* @param from The source array of Node or NodeArrayNode.
|
||||
*/
|
||||
export function addNodes<T extends Node>(to: T[], from: OneOrMany<T>[], startOnNewLine?: boolean) {
|
||||
export function addNodes<T extends Node>(to: T[], from: VisitResult<T>[], startOnNewLine?: boolean): void {
|
||||
addNodesWorker(to, from, startOnNewLine, /*test*/ undefined, /*parenthesize*/ undefined, /*parentNode*/ undefined, /*isVisiting*/ false);
|
||||
}
|
||||
|
||||
function addNodeWorker(to: Node[], from: OneOrMany<Node>, startOnNewLine: boolean, test: (node: Node) => boolean, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node, isVisiting: boolean) {
|
||||
function addNodeWorker(to: Node[], from: VisitResult<Node>, startOnNewLine: boolean, test: (node: Node) => boolean, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node, isVisiting: boolean): void {
|
||||
if (to && from) {
|
||||
if (isArray(from)) {
|
||||
addNodesWorker(to, from, startOnNewLine, test, parenthesize, parentNode, isVisiting);
|
||||
}
|
||||
else {
|
||||
const node = parenthesize !== undefined ? parenthesize(from, parentNode) : from;
|
||||
Debug.assert(test === undefined || test(node), "Wrong node type after visit.", () => `Node ${formatSyntaxKind(node.kind)} did not pass test ${(<any>test).name}.`);
|
||||
const node = parenthesize !== undefined
|
||||
? parenthesize(from, parentNode)
|
||||
: from;
|
||||
|
||||
Debug.assertNode(node, test);
|
||||
|
||||
if (startOnNewLine) {
|
||||
node.startsOnNewLine = true;
|
||||
@ -719,7 +703,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function addNodesWorker(to: Node[], from: OneOrMany<Node>[], startOnNewLine: boolean, test: (node: Node) => boolean, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node, isVisiting: boolean) {
|
||||
function addNodesWorker(to: Node[], from: VisitResult<Node>[], startOnNewLine: boolean, test: (node: Node) => boolean, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node, isVisiting: boolean): void {
|
||||
if (to && from) {
|
||||
for (const node of from) {
|
||||
addNodeWorker(to, node, startOnNewLine, test, parenthesize, parentNode, isVisiting);
|
||||
@ -760,7 +744,7 @@ namespace ts {
|
||||
* @param node The SourceFile node.
|
||||
* @param declarations The generated lexical declarations.
|
||||
*/
|
||||
export function mergeSourceFileLexicalEnvironment(node: SourceFile, declarations: Statement[]) {
|
||||
export function mergeSourceFileLexicalEnvironment(node: SourceFile, declarations: Statement[]): SourceFile {
|
||||
if (declarations !== undefined && declarations.length) {
|
||||
const mutableNode = getMutableClone(node);
|
||||
mutableNode.statements = mergeStatements(mutableNode.statements, declarations);
|
||||
@ -776,7 +760,7 @@ namespace ts {
|
||||
* @param node The ModuleDeclaration node.
|
||||
* @param declarations The generated lexical declarations.
|
||||
*/
|
||||
export function mergeModuleDeclarationLexicalEnvironment(node: ModuleDeclaration, declarations: Statement[]) {
|
||||
export function mergeModuleDeclarationLexicalEnvironment(node: ModuleDeclaration, declarations: Statement[]): ModuleDeclaration {
|
||||
Debug.assert(node.body.kind === SyntaxKind.ModuleBlock);
|
||||
if (declarations !== undefined && declarations.length) {
|
||||
const mutableNode = getMutableClone(node);
|
||||
@ -793,7 +777,7 @@ namespace ts {
|
||||
* @param node The function-like node.
|
||||
* @param declarations The generated lexical declarations.
|
||||
*/
|
||||
function mergeFunctionLikeLexicalEnvironment(node: FunctionLikeDeclaration, declarations: Statement[]) {
|
||||
function mergeFunctionLikeLexicalEnvironment(node: FunctionLikeDeclaration, declarations: Statement[]): FunctionLikeDeclaration {
|
||||
Debug.assert(node.body !== undefined);
|
||||
if (declarations !== undefined && declarations.length) {
|
||||
const mutableNode = getMutableClone(node);
|
||||
@ -810,7 +794,7 @@ namespace ts {
|
||||
* @param node The ConciseBody of an arrow function.
|
||||
* @param declarations The lexical declarations to merge.
|
||||
*/
|
||||
export function mergeFunctionBodyLexicalEnvironment(body: FunctionBody, declarations: Statement[]) {
|
||||
export function mergeFunctionBodyLexicalEnvironment(body: FunctionBody, declarations: Statement[]): FunctionBody {
|
||||
if (declarations !== undefined && declarations.length > 0) {
|
||||
return mergeBlockLexicalEnvironment(body, declarations);
|
||||
}
|
||||
@ -824,7 +808,7 @@ namespace ts {
|
||||
* @param node The ConciseBody of an arrow function.
|
||||
* @param declarations The lexical declarations to merge.
|
||||
*/
|
||||
export function mergeConciseBodyLexicalEnvironment(body: ConciseBody, declarations: Statement[]) {
|
||||
export function mergeConciseBodyLexicalEnvironment(body: ConciseBody, declarations: Statement[]): ConciseBody {
|
||||
if (declarations !== undefined && declarations.length > 0) {
|
||||
if (isBlock(body)) {
|
||||
return mergeBlockLexicalEnvironment(body, declarations);
|
||||
@ -846,7 +830,7 @@ namespace ts {
|
||||
* @param node The block into which to merge lexical declarations.
|
||||
* @param declarations The lexical declarations to merge.
|
||||
*/
|
||||
function mergeBlockLexicalEnvironment<T extends Block>(node: T, declarations: Statement[]) {
|
||||
function mergeBlockLexicalEnvironment<T extends Block>(node: T, declarations: Statement[]): T {
|
||||
const mutableNode = getMutableClone(node);
|
||||
mutableNode.statements = mergeStatements(node.statements, declarations);
|
||||
return mutableNode;
|
||||
@ -858,7 +842,7 @@ namespace ts {
|
||||
* @param statements The node array to concatentate with the supplied lexical declarations.
|
||||
* @param declarations The lexical declarations to merge.
|
||||
*/
|
||||
function mergeStatements(statements: NodeArray<Statement>, declarations: Statement[]) {
|
||||
function mergeStatements(statements: NodeArray<Statement>, declarations: Statement[]): NodeArray<Statement> {
|
||||
return createNodeArray(concatenate(statements, declarations), /*location*/ statements);
|
||||
}
|
||||
|
||||
@ -867,7 +851,7 @@ namespace ts {
|
||||
*
|
||||
* @param nodes The NodeArray.
|
||||
*/
|
||||
export function liftToBlock(nodes: NodeArray<Node>) {
|
||||
export function liftToBlock(nodes: Node[]): Block {
|
||||
Debug.assert(every(nodes, isStatement), "Cannot lift nodes to a Block.");
|
||||
return createBlock(<NodeArray<Statement>>nodes);
|
||||
}
|
||||
@ -877,9 +861,9 @@ namespace ts {
|
||||
*
|
||||
* @param nodes The NodeArray.
|
||||
*/
|
||||
function extractSingleNode(nodes: NodeArray<Node>) {
|
||||
function extractSingleNode(nodes: Node[]): Node {
|
||||
Debug.assert(nodes.length <= 1, "Too many nodes written to output.");
|
||||
return nodes.length > 0 ? nodes[0] : undefined;
|
||||
return singleOrUndefined(nodes);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -916,11 +900,11 @@ namespace ts {
|
||||
// We do not transform ambient declarations or types, so there is no need to
|
||||
// recursively aggregate transform flags.
|
||||
if (hasModifier(node, ModifierFlags.Ambient) || isTypeNode(node)) {
|
||||
return <TransformFlags>0;
|
||||
return TransformFlags.None;
|
||||
}
|
||||
|
||||
// Aggregate the transform flags of each child.
|
||||
return reduceEachChild<TransformFlags>(node, aggregateTransformFlagsForChildNode, 0);
|
||||
return reduceEachChild(node, aggregateTransformFlagsForChildNode, TransformFlags.None);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -930,4 +914,43 @@ namespace ts {
|
||||
function aggregateTransformFlagsForChildNode(transformFlags: TransformFlags, child: Node): TransformFlags {
|
||||
return transformFlags | aggregateTransformFlagsForNode(child);
|
||||
}
|
||||
|
||||
export namespace Debug {
|
||||
export function failNotOptional(message?: string) {
|
||||
if (shouldAssert(AssertionLevel.Normal)) {
|
||||
Debug.assert(false, message || "Node not optional.");
|
||||
}
|
||||
}
|
||||
|
||||
export function failBadSyntaxKind(node: Node, message?: string) {
|
||||
if (shouldAssert(AssertionLevel.Normal)) {
|
||||
Debug.assert(false,
|
||||
message || "Unexpected node.",
|
||||
() => `Node ${formatSyntaxKind(node.kind)} was unexpected.`);
|
||||
}
|
||||
}
|
||||
|
||||
export function assertNode<T extends Node>(node: Node, test: (node: Node) => boolean, message?: string): void {
|
||||
if (shouldAssert(AssertionLevel.Normal)) {
|
||||
Debug.assert(
|
||||
test === undefined || test(node),
|
||||
message || "Unexpected node.",
|
||||
() => `Node ${formatSyntaxKind(node.kind)} did not pass test '${getFunctionName(test)}'.`);
|
||||
};
|
||||
}
|
||||
|
||||
function getFunctionName(func: Function) {
|
||||
if (typeof func !== "function") {
|
||||
return "";
|
||||
}
|
||||
else if (func.hasOwnProperty("name")) {
|
||||
return (<any>func).name;
|
||||
}
|
||||
else {
|
||||
const text = Function.prototype.toString.call(func);
|
||||
const match = /^function\s+([\w\$]+)\s*\(/.exec(text);
|
||||
return match ? match[1] : "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user