From 79e826fcc820e16dd6a309e748f6962455fa4ec5 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sat, 30 May 2015 22:02:29 -0400 Subject: [PATCH] attempt to optimise node printing by shifting it into a class --- src/babel/generation/generators/base.js | 2 +- src/babel/generation/generators/classes.js | 16 +-- .../generation/generators/comprehensions.js | 8 +- .../generation/generators/expressions.js | 42 ++++---- src/babel/generation/generators/flow.js | 66 ++++++------ src/babel/generation/generators/jsx.js | 26 ++--- src/babel/generation/generators/methods.js | 20 ++-- src/babel/generation/generators/modules.js | 30 +++--- src/babel/generation/generators/statements.js | 50 ++++----- .../generators/template-literals.js | 8 +- src/babel/generation/generators/types.js | 12 +-- src/babel/generation/index.js | 101 +++++++----------- src/babel/generation/node/printer.js | 32 ++++++ 13 files changed, 210 insertions(+), 203 deletions(-) create mode 100644 src/babel/generation/node/printer.js diff --git a/src/babel/generation/generators/base.js b/src/babel/generation/generators/base.js index 1036b80e30..0a698e10cb 100644 --- a/src/babel/generation/generators/base.js +++ b/src/babel/generation/generators/base.js @@ -1,5 +1,5 @@ export function File(node, print) { - print(node.program); + print.plain(node.program); } export function Program(node, print) { diff --git a/src/babel/generation/generators/classes.js b/src/babel/generation/generators/classes.js index a4d3fd1969..cd8b67ada5 100644 --- a/src/babel/generation/generators/classes.js +++ b/src/babel/generation/generators/classes.js @@ -4,15 +4,15 @@ export function ClassDeclaration(node, print) { if (node.id) { this.push(" "); - print(node.id); + print.plain(node.id); } - print(node.typeParameters); + print.plain(node.typeParameters); if (node.superClass) { this.push(" extends "); - print(node.superClass); - print(node.superTypeParameters); + print.plain(node.superClass); + print.plain(node.superTypeParameters); } if (node.implements) { @@ -21,7 +21,7 @@ export function ClassDeclaration(node, print) { } this.space(); - print(node.body); + print.plain(node.body); } export { ClassDeclaration as ClassExpression }; @@ -46,13 +46,13 @@ export function ClassProperty(node, print) { print.list(node.decorators); if (node.static) this.push("static "); - print(node.key); - print(node.typeAnnotation); + print.plain(node.key); + print.plain(node.typeAnnotation); if (node.value) { this.space(); this.push("="); this.space(); - print(node.value); + print.plain(node.value); } this.semicolon(); } diff --git a/src/babel/generation/generators/comprehensions.js b/src/babel/generation/generators/comprehensions.js index dce50114ae..29b7029cb1 100644 --- a/src/babel/generation/generators/comprehensions.js +++ b/src/babel/generation/generators/comprehensions.js @@ -1,9 +1,9 @@ export function ComprehensionBlock(node, print) { this.keyword("for"); this.push("("); - print(node.left); + print.plain(node.left); this.push(" of "); - print(node.right); + print.plain(node.right); this.push(")"); } @@ -16,12 +16,12 @@ export function ComprehensionExpression(node, print) { if (node.filter) { this.keyword("if"); this.push("("); - print(node.filter); + print.plain(node.filter); this.push(")"); this.space(); } - print(node.body); + print.plain(node.body); this.push(node.generator ? ")" : "]"); } diff --git a/src/babel/generation/generators/expressions.js b/src/babel/generation/generators/expressions.js index 38a8ca30aa..b58b162f62 100644 --- a/src/babel/generation/generators/expressions.js +++ b/src/babel/generation/generators/expressions.js @@ -16,40 +16,40 @@ export function UnaryExpression(node, print) { this.push(node.operator); if (hasSpace) this.push(" "); - print(node.argument); + print.plain(node.argument); } export function DoExpression(node, print) { this.push("do"); this.space(); - print(node.body); + print.plain(node.body); } export function UpdateExpression(node, print) { if (node.prefix) { this.push(node.operator); - print(node.argument); + print.plain(node.argument); } else { - print(node.argument); + print.plain(node.argument); this.push(node.operator); } } export function ConditionalExpression(node, print) { - print(node.test); + print.plain(node.test); this.space(); this.push("?"); this.space(); - print(node.consequent); + print.plain(node.consequent); this.space(); this.push(":"); this.space(); - print(node.alternate); + print.plain(node.alternate); } export function NewExpression(node, print) { this.push("new "); - print(node.callee); + print.plain(node.callee); this.push("("); print.list(node.arguments); this.push(")"); @@ -69,11 +69,11 @@ export function Super() { export function Decorator(node, print) { this.push("@"); - print(node.expression); + print.plain(node.expression); } export function CallExpression(node, print) { - print(node.callee); + print.plain(node.callee); this.push("("); @@ -109,7 +109,7 @@ var buildYieldAwait = function (keyword) { if (node.argument) { this.push(" "); - print(node.argument); + print.plain(node.argument); } }; }; @@ -122,23 +122,23 @@ export function EmptyStatement() { } export function ExpressionStatement(node, print) { - print(node.expression); + print.plain(node.expression); this.semicolon(); } export function AssignmentExpression(node, print) { // todo: add cases where the spaces can be dropped when in compact mode - print(node.left); + print.plain(node.left); this.push(" "); this.push(node.operator); this.push(" "); - print(node.right); + print.plain(node.right); } export function BindExpression(node, print) { - print(node.object); + print.plain(node.object); this.push("::"); - print(node.callee); + print.plain(node.callee); } export { @@ -151,7 +151,7 @@ var SCIENTIFIC_NOTATION = /e/i; export function MemberExpression(node, print) { var obj = node.object; - print(obj); + print.plain(obj); if (!node.computed && t.isMemberExpression(node.property)) { throw new TypeError("Got a MemberExpression for MemberExpression property"); @@ -164,7 +164,7 @@ export function MemberExpression(node, print) { if (computed) { this.push("["); - print(node.property); + print.plain(node.property); this.push("]"); } else { // 5..toFixed(2); @@ -173,12 +173,12 @@ export function MemberExpression(node, print) { } this.push("."); - print(node.property); + print.plain(node.property); } } export function MetaProperty(node, print) { - print(node.meta); + print.plain(node.meta); this.push("."); - print(node.property); + print.plain(node.property); } diff --git a/src/babel/generation/generators/flow.js b/src/babel/generation/generators/flow.js index 7a2e30f4c0..44c147e65d 100644 --- a/src/babel/generation/generators/flow.js +++ b/src/babel/generation/generators/flow.js @@ -5,7 +5,7 @@ export function AnyTypeAnnotation() { } export function ArrayTypeAnnotation(node, print) { - print(node.elementType); + print.plain(node.elementType); this.push("["); this.push("]"); } @@ -21,27 +21,27 @@ export function DeclareClass(node, print) { export function DeclareFunction(node, print) { this.push("declare function "); - print(node.id); - print(node.id.typeAnnotation.typeAnnotation); + print.plain(node.id); + print.plain(node.id.typeAnnotation.typeAnnotation); this.semicolon(); } export function DeclareModule(node, print) { this.push("declare module "); - print(node.id); + print.plain(node.id); this.space(); - print(node.body); + print.plain(node.body); } export function DeclareVariable(node, print) { this.push("declare var "); - print(node.id); - print(node.id.typeAnnotation); + print.plain(node.id); + print.plain(node.id.typeAnnotation); this.semicolon(); } export function FunctionTypeAnnotation(node, print, parent) { - print(node.typeParameters); + print.plain(node.typeParameters); this.push("("); print.list(node.params); @@ -51,7 +51,7 @@ export function FunctionTypeAnnotation(node, print, parent) { this.space(); } this.push("..."); - print(node.rest); + print.plain(node.rest); } this.push(")"); @@ -65,33 +65,33 @@ export function FunctionTypeAnnotation(node, print, parent) { } this.space(); - print(node.returnType); + print.plain(node.returnType); } export function FunctionTypeParam(node, print) { - print(node.name); + print.plain(node.name); if (node.optional) this.push("?"); this.push(":"); this.space(); - print(node.typeAnnotation); + print.plain(node.typeAnnotation); } export function InterfaceExtends(node, print) { - print(node.id); - print(node.typeParameters); + print.plain(node.id); + print.plain(node.typeParameters); } export { InterfaceExtends as ClassImplements, InterfaceExtends as GenericTypeAnnotation }; export function _interfaceish(node, print) { - print(node.id); - print(node.typeParameters); + print.plain(node.id); + print.plain(node.typeParameters); if (node.extends.length) { this.push(" extends "); print.join(node.extends, { separator: ", " }); } this.space(); - print(node.body); + print.plain(node.body); } export function InterfaceDeclaration(node, print) { @@ -105,7 +105,7 @@ export function IntersectionTypeAnnotation(node, print) { export function NullableTypeAnnotation(node, print) { this.push("?"); - print(node.typeAnnotation); + print.plain(node.typeAnnotation); } export function NumberTypeAnnotation() { @@ -128,17 +128,17 @@ export function TupleTypeAnnotation(node, print) { export function TypeofTypeAnnotation(node, print) { this.push("typeof "); - print(node.argument); + print.plain(node.argument); } export function TypeAlias(node, print) { this.push("type "); - print(node.id); - print(node.typeParameters); + print.plain(node.id); + print.plain(node.typeParameters); this.space(); this.push("="); this.space(); - print(node.right); + print.plain(node.right); this.semicolon(); } @@ -146,7 +146,7 @@ export function TypeAnnotation(node, print) { this.push(":"); this.space(); if (node.optional) this.push("?"); - print(node.typeAnnotation); + print.plain(node.typeAnnotation); } export function TypeParameterInstantiation(node, print) { @@ -183,37 +183,37 @@ export function ObjectTypeAnnotation(node, print) { export function ObjectTypeCallProperty(node, print) { if (node.static) this.push("static "); - print(node.value); + print.plain(node.value); } export function ObjectTypeIndexer(node, print) { if (node.static) this.push("static "); this.push("["); - print(node.id); + print.plain(node.id); this.push(":"); this.space(); - print(node.key); + print.plain(node.key); this.push("]"); this.push(":"); this.space(); - print(node.value); + print.plain(node.value); } export function ObjectTypeProperty(node, print) { if (node.static) this.push("static "); - print(node.key); + print.plain(node.key); if (node.optional) this.push("?"); if (!t.isFunctionTypeAnnotation(node.value)) { this.push(":"); this.space(); } - print(node.value); + print.plain(node.value); } export function QualifiedTypeIdentifier(node, print) { - print(node.qualification); + print.plain(node.qualification); this.push("."); - print(node.id); + print.plain(node.id); } export function UnionTypeAnnotation(node, print) { @@ -222,8 +222,8 @@ export function UnionTypeAnnotation(node, print) { export function TypeCastExpression(node, print) { this.push("("); - print(node.expression); - print(node.typeAnnotation); + print.plain(node.expression); + print.plain(node.typeAnnotation); this.push(")"); } diff --git a/src/babel/generation/generators/jsx.js b/src/babel/generation/generators/jsx.js index 3dee3c683e..8c9508dcd8 100644 --- a/src/babel/generation/generators/jsx.js +++ b/src/babel/generation/generators/jsx.js @@ -1,10 +1,10 @@ import * as t from "../../types"; export function JSXAttribute(node, print) { - print(node.name); + print.plain(node.name); if (node.value) { this.push("="); - print(node.value); + print.plain(node.value); } } @@ -13,32 +13,32 @@ export function JSXIdentifier(node) { } export function JSXNamespacedName(node, print) { - print(node.namespace); + print.plain(node.namespace); this.push(":"); - print(node.name); + print.plain(node.name); } export function JSXMemberExpression(node, print) { - print(node.object); + print.plain(node.object); this.push("."); - print(node.property); + print.plain(node.property); } export function JSXSpreadAttribute(node, print) { this.push("{..."); - print(node.argument); + print.plain(node.argument); this.push("}"); } export function JSXExpressionContainer(node, print) { this.push("{"); - print(node.expression); + print.plain(node.expression); this.push("}"); } export function JSXElement(node, print) { var open = node.openingElement; - print(open); + print.plain(open); if (open.selfClosing) return; this.indent(); @@ -46,17 +46,17 @@ export function JSXElement(node, print) { if (t.isLiteral(child)) { this.push(child.value, true); } else { - print(child); + print.plain(child); } } this.dedent(); - print(node.closingElement); + print.plain(node.closingElement); } export function JSXOpeningElement(node, print) { this.push("<"); - print(node.name); + print.plain(node.name); if (node.attributes.length > 0) { this.push(" "); print.join(node.attributes, { separator: " " }); @@ -66,7 +66,7 @@ export function JSXOpeningElement(node, print) { export function JSXClosingElement(node, print) { this.push(""); } diff --git a/src/babel/generation/generators/methods.js b/src/babel/generation/generators/methods.js index 933282f500..22e6c76c4f 100644 --- a/src/babel/generation/generators/methods.js +++ b/src/babel/generation/generators/methods.js @@ -1,18 +1,18 @@ import * as t from "../../types"; export function _params(node, print) { - print(node.typeParameters); + print.plain(node.typeParameters); this.push("("); print.list(node.params, { iterator: (node) =>{ if (node.optional) this.push("?"); - print(node.typeAnnotation); + print.plain(node.typeAnnotation); } }); this.push(")"); if (node.returnType) { - print(node.returnType); + print.plain(node.returnType); } } @@ -35,15 +35,15 @@ export function _method(node, print) { if (node.computed) { this.push("["); - print(key); + print.plain(key); this.push("]"); } else { - print(key); + print.plain(key); } this._params(value, print); this.push(" "); - print(value.body); + print.plain(value.body); } export function FunctionExpression(node, print) { @@ -53,14 +53,14 @@ export function FunctionExpression(node, print) { if (node.id) { this.push(" "); - print(node.id); + print.plain(node.id); } else { this.space(); } this._params(node, print); this.space(); - print(node.body); + print.plain(node.body); } export { FunctionExpression as FunctionDeclaration }; @@ -69,7 +69,7 @@ export function ArrowFunctionExpression(node, print) { if (node.async) this.push("async "); if (node.params.length === 1 && t.isIdentifier(node.params[0])) { - print(node.params[0]); + print.plain(node.params[0]); } else { this._params(node, print); } @@ -82,7 +82,7 @@ export function ArrowFunctionExpression(node, print) { this.push("("); } - print(node.body); + print.plain(node.body); if (bodyNeedsParens) { this.push(")"); diff --git a/src/babel/generation/generators/modules.js b/src/babel/generation/generators/modules.js index 00a66a07db..27578e9dd3 100644 --- a/src/babel/generation/generators/modules.js +++ b/src/babel/generation/generators/modules.js @@ -1,42 +1,42 @@ import * as t from "../../types"; export function ImportSpecifier(node, print) { - print(node.imported); + print.plain(node.imported); if (node.local && node.local.name !== node.imported.name) { this.push(" as "); - print(node.local); + print.plain(node.local); } } export function ImportDefaultSpecifier(node, print) { - print(node.local); + print.plain(node.local); } export function ExportDefaultSpecifier(node, print) { - print(node.exported); + print.plain(node.exported); } export function ExportSpecifier(node, print) { - print(node.local); + print.plain(node.local); if (node.exported && node.local.name !== node.exported.name) { this.push(" as "); - print(node.exported); + print.plain(node.exported); } } export function ExportNamespaceSpecifier(node, print) { this.push("* as "); - print(node.exported); + print.plain(node.exported); } export function ExportAllDeclaration(node, print) { this.push("export *"); if (node.exported) { this.push(" as "); - print(node.exported); + print.plain(node.exported); } this.push(" from "); - print(node.source); + print.plain(node.source); this.semicolon(); } @@ -55,14 +55,14 @@ function ExportDeclaration(node, print) { if (node.declaration) { var declar = node.declaration; - print(declar); + print.plain(declar); if (t.isStatement(declar) || t.isFunction(declar) || t.isClass(declar)) return; } else { var first = specifiers[0]; var hasSpecial = false; if (t.isExportDefaultSpecifier(first) || t.isExportNamespaceSpecifier(first)) { hasSpecial = true; - print(specifiers.shift()); + print.plain(specifiers.shift()); if (specifiers.length) { this.push(", "); } @@ -80,7 +80,7 @@ function ExportDeclaration(node, print) { if (node.source) { this.push(" from "); - print(node.source); + print.plain(node.source); } } @@ -98,7 +98,7 @@ export function ImportDeclaration(node, print) { if (specfiers && specfiers.length) { var first = node.specifiers[0]; if (t.isImportDefaultSpecifier(first) || t.isImportNamespaceSpecifier(first)) { - print(node.specifiers.shift()); + print.plain(node.specifiers.shift()); if (node.specifiers.length) { this.push(", "); } @@ -115,11 +115,11 @@ export function ImportDeclaration(node, print) { this.push(" from "); } - print(node.source); + print.plain(node.source); this.semicolon(); } export function ImportNamespaceSpecifier(node, print) { this.push("* as "); - print(node.local); + print.plain(node.local); } diff --git a/src/babel/generation/generators/statements.js b/src/babel/generation/generators/statements.js index 4f0362a38c..81ebe56522 100644 --- a/src/babel/generation/generators/statements.js +++ b/src/babel/generation/generators/statements.js @@ -4,7 +4,7 @@ import * as t from "../../types"; export function WithStatement(node, print) { this.keyword("with"); this.push("("); - print(node.object); + print.plain(node.object); this.push(")"); print.block(node.body); } @@ -12,7 +12,7 @@ export function WithStatement(node, print) { export function IfStatement(node, print) { this.keyword("if"); this.push("("); - print(node.test); + print.plain(node.test); this.push(")"); this.space(); @@ -29,18 +29,18 @@ export function ForStatement(node, print) { this.keyword("for"); this.push("("); - print(node.init); + print.plain(node.init); this.push(";"); if (node.test) { this.push(" "); - print(node.test); + print.plain(node.test); } this.push(";"); if (node.update) { this.push(" "); - print(node.update); + print.plain(node.update); } this.push(")"); @@ -50,7 +50,7 @@ export function ForStatement(node, print) { export function WhileStatement(node, print) { this.keyword("while"); this.push("("); - print(node.test); + print.plain(node.test); this.push(")"); print.block(node.body); } @@ -59,9 +59,9 @@ var buildForXStatement = function (op) { return function (node, print) { this.keyword("for"); this.push("("); - print(node.left); + print.plain(node.left); this.push(` ${op} `); - print(node.right); + print.plain(node.right); this.push(")"); print.block(node.body); }; @@ -72,11 +72,11 @@ export var ForOfStatement = buildForXStatement("of"); export function DoWhileStatement(node, print) { this.push("do "); - print(node.body); + print.plain(node.body); this.space(); this.keyword("while"); this.push("("); - print(node.test); + print.plain(node.test); this.push(");"); } @@ -87,7 +87,7 @@ var buildLabelStatement = function (prefix, key) { var label = node[key || "label"]; if (label) { this.push(" "); - print(label); + print.plain(label); } this.semicolon(); @@ -99,50 +99,50 @@ export var ReturnStatement = buildLabelStatement("return", "argument"); export var BreakStatement = buildLabelStatement("break"); export function LabeledStatement(node, print) { - print(node.label); + print.plain(node.label); this.push(": "); - print(node.body); + print.plain(node.body); } export function TryStatement(node, print) { this.keyword("try"); - print(node.block); + print.plain(node.block); this.space(); // Esprima bug puts the catch clause in a `handlers` array. // see https://code.google.com/p/esprima/issues/detail?id=433 // We run into this from regenerator generated ast. if (node.handlers) { - print(node.handlers[0]); + print.plain(node.handlers[0]); } else { - print(node.handler); + print.plain(node.handler); } if (node.finalizer) { this.space(); this.push("finally "); - print(node.finalizer); + print.plain(node.finalizer); } } export function CatchClause(node, print) { this.keyword("catch"); this.push("("); - print(node.param); + print.plain(node.param); this.push(") "); - print(node.body); + print.plain(node.body); } export function ThrowStatement(node, print) { this.push("throw "); - print(node.argument); + print.plain(node.argument); this.semicolon(); } export function SwitchStatement(node, print) { this.keyword("switch"); this.push("("); - print(node.discriminant); + print.plain(node.discriminant); this.push(")"); this.space(); this.push("{"); @@ -160,7 +160,7 @@ export function SwitchStatement(node, print) { export function SwitchCase(node, print) { if (node.test) { this.push("case "); - print(node.test); + print.plain(node.test); this.push(":"); } else { this.push("default:"); @@ -207,12 +207,12 @@ export function VariableDeclaration(node, print, parent) { } export function VariableDeclarator(node, print) { - print(node.id); - print(node.id.typeAnnotation); + print.plain(node.id); + print.plain(node.id.typeAnnotation); if (node.init) { this.space(); this.push("="); this.space(); - print(node.init); + print.plain(node.init); } } diff --git a/src/babel/generation/generators/template-literals.js b/src/babel/generation/generators/template-literals.js index da2bdc8d3a..1bd78796dd 100644 --- a/src/babel/generation/generators/template-literals.js +++ b/src/babel/generation/generators/template-literals.js @@ -1,6 +1,6 @@ export function TaggedTemplateExpression(node, print) { - print(node.tag); - print(node.quasi); + print.plain(node.tag); + print.plain(node.quasi); } export function TemplateElement(node) { @@ -14,11 +14,11 @@ export function TemplateLiteral(node, print) { var len = quasis.length; for (var i = 0; i < len; i++) { - print(quasis[i]); + print.plain(quasis[i]); if (i + 1 < len) { this.push("${ "); - print(node.expressions[i]); + print.plain(node.expressions[i]); this.push(" }"); } } diff --git a/src/babel/generation/generators/types.js b/src/babel/generation/generators/types.js index 9d826f12dc..809a38b783 100644 --- a/src/babel/generation/generators/types.js +++ b/src/babel/generation/generators/types.js @@ -8,7 +8,7 @@ export function Identifier(node) { export function RestElement(node, print) { this.push("..."); - print(node.argument); + print.plain(node.argument); } export { RestElement as SpreadElement, RestElement as SpreadProperty }; @@ -37,16 +37,16 @@ export function Property(node, print) { } else { if (node.computed) { this.push("["); - print(node.key); + print.plain(node.key); this.push("]"); } else { // print `({ foo: foo = 5 } = {})` as `({ foo = 5 } = {});` if (t.isAssignmentPattern(node.value) && t.isIdentifier(node.key) && node.key.name === node.value.left.name) { - print(node.value); + print.plain(node.value); return; } - print(node.key); + print.plain(node.key); // shorthand! if (node.shorthand && @@ -59,7 +59,7 @@ export function Property(node, print) { this.push(":"); this.space(); - print(node.value); + print.plain(node.value); } } @@ -80,7 +80,7 @@ export function ArrayExpression(node, print) { this.push(","); } else { if (i > 0) this.push(" "); - print(elem); + print.plain(elem); if (i < len - 1) this.push(","); } } diff --git a/src/babel/generation/index.js b/src/babel/generation/index.js index fb7a0b9e55..90518b17e6 100644 --- a/src/babel/generation/index.js +++ b/src/babel/generation/index.js @@ -1,5 +1,6 @@ import detectIndent from "detect-indent"; import Whitespace from "./whitespace"; +import NodePrinter from "./node/printer"; import repeating from "repeating"; import SourceMap from "./source-map"; import Position from "./position"; @@ -67,7 +68,6 @@ class CodeGenerator { for (var i = 0; i < tokens.length; i++) { var token = tokens[i]; if (token.type.label !== "string") continue; - if (checked >= 3) continue; var raw = code.slice(token.start, token.end); if (raw[0] === "'") { @@ -77,6 +77,7 @@ class CodeGenerator { } checked++; + if (checked >= 3) break; } if (occurences.single > occurences.double) { @@ -120,33 +121,7 @@ class CodeGenerator { } buildPrint(parent) { - var print = (node, opts) => { - return this.print(node, parent, opts); - }; - - print.sequence = (nodes, opts = {}) => { - opts.statement = true; - return this.printJoin(print, nodes, opts); - }; - - print.join = (nodes, opts) => { - return this.printJoin(print, nodes, opts); - }; - - print.list = function (items, opts = {}) { - if (opts.separator == null) opts.separator = ", "; - print.join(items, opts); - }; - - print.block = (node) => { - return this.printBlock(print, node); - }; - - print.indentOnComments = (node) => { - return this.printAndIndentOnComments(print, node); - }; - - return print; + return new NodePrinter(this, parent); } catchUp(node, parent, leftParenPrinted) { @@ -166,6 +141,36 @@ class CodeGenerator { return false; } + _printNewline(leading, node, parent, opts) { + if (!opts.statement && !n.isUserWhitespacable(node, parent)) { + return; + } + + var lines = 0; + + if (node.start != null && !node._ignoreUserWhitespace) { + // user node + if (leading) { + lines = this.whitespace.getNewlinesBefore(node); + } else { + lines = this.whitespace.getNewlinesAfter(node); + } + } else { + // generated node + if (!leading) lines++; // always include at least a single line after + if (opts.addNewlines) lines += opts.addNewlines(leading, node) || 0; + + var needs = n.needsWhitespaceAfter; + if (leading) needs = n.needsWhitespaceBefore; + if (needs(node, parent)) lines++; + + // generated nodes can't add starting file whitespace + if (!this.buffer.buf) lines = 0; + } + + this.newline(lines); + } + print(node, parent, opts = {}) { if (!node) return; @@ -178,36 +183,6 @@ class CodeGenerator { this.format.concise = true; } - var newline = (leading) => { - if (!opts.statement && !n.isUserWhitespacable(node, parent)) { - return; - } - - var lines = 0; - - if (node.start != null && !node._ignoreUserWhitespace) { - // user node - if (leading) { - lines = this.whitespace.getNewlinesBefore(node); - } else { - lines = this.whitespace.getNewlinesAfter(node); - } - } else { - // generated node - if (!leading) lines++; // always include at least a single line after - if (opts.addNewlines) lines += opts.addNewlines(leading, node) || 0; - - var needs = n.needsWhitespaceAfter; - if (leading) needs = n.needsWhitespaceBefore; - if (needs(node, parent)) lines++; - - // generated nodes can't add starting file whitespace - if (!this.buffer.buf) lines = 0; - } - - this.newline(lines); - }; - if (this[node.type]) { var needsNoLineTermParens = n.needsParensNoLineTerminator(node, parent); var needsParens = needsNoLineTermParens || n.needsParens(node, parent); @@ -219,7 +194,7 @@ class CodeGenerator { var needsParensFromCatchup = this.catchUp(node, parent, needsParens); - newline(true); + this._printNewline(true, node, parent, opts); if (opts.before) opts.before(); this.map.mark(node, "start"); @@ -237,7 +212,7 @@ class CodeGenerator { this.format.concise = oldConcise; - newline(false); + this._printNewline(false, node, parent, opts); this.printTrailingComments(node, parent); } else { @@ -268,7 +243,7 @@ class CodeGenerator { for (var i = 0; i < nodes.length; i++) { var node = nodes[i]; - print(node, printOpts); + print.plain(node, printOpts); } if (opts.indent) this.dedent(); @@ -277,7 +252,7 @@ class CodeGenerator { printAndIndentOnComments(print, node) { var indent = !!node.leadingComments; if (indent) this.indent(); - print(node); + print.plain(node); if (indent) this.dedent(); } @@ -286,7 +261,7 @@ class CodeGenerator { this.semicolon(); } else { this.push(" "); - print(node); + print.plain(node); } } diff --git a/src/babel/generation/node/printer.js b/src/babel/generation/node/printer.js new file mode 100644 index 0000000000..e5addcaa62 --- /dev/null +++ b/src/babel/generation/node/printer.js @@ -0,0 +1,32 @@ +export default class NodePrinter { + constructor(generator, parent) { + this.generator = generator; + this.parent = parent; + } + + plain(node, opts) { + return this.generator.print(node, this.parent, opts); + } + + sequence(nodes, opts = {}) { + opts.statement = true; + return this.generator.printJoin(this, nodes, opts); + } + + join(nodes, opts) { + return this.generator.printJoin(this, nodes, opts); + } + + list(items, opts = {}) { + if (opts.separator == null) opts.separator = ", "; + return this.join(items, opts); + } + + block(node) { + return this.generator.printBlock(this, node); + } + + indentOnComments(node) { + return this.generator.printAndIndentOnComments(this, node); + } +}