UNPKG

nodent-compiler

Version:

NoDent - Asynchronous Javascript language extensions

935 lines (925 loc) 34.5 kB
'use strict'; // This module is derived from Astring by David Bonnet (see below), but heavily // modified to support source-maps & es7 as specified in // https://github.com/estree/estree/blob/master/experimental/async-functions.md // -------------------- // Astring is a tiny and fast JavaScript code generator from an ESTree-compliant AST. // // Astring was written by David Bonnet and released under an MIT license. // // The Git repository for Astring is available at: // https://github.com/davidbonnet/astring.git // // Please use the GitHub bug tracker to report issues: // https://github.com/davidbonnet/astring/issues var SourceMapGenerator = require('source-map').SourceMapGenerator; var ForInStatement, RestElement, BinaryExpression, ArrayExpression, BlockStatement; var repeat ; if ("".repeat) { repeat = function(str,count){ return count && str ? str.repeat(count):"" ; } ; } else { var cache = {} ; repeat = function(str,count) { if (!count || !str) return "" ; var k = ""+str+count ; if (!cache[k]) { var out = []; while (count--) { out.push(str); } cache[k] = out.join(''); } return cache[k] ; } } var OPERATORS_PRECEDENCE = { 'ExpressionStatement': -1, // Use to parenthesize FunctionExpressions as statements 'Identifier': 21, 'Literal': 21, 'BooleanLiteral':21, 'RegExpLiteral':21, 'NumericLiteral':21, 'StringLiteral':21, 'NullLiteral':21, 'ThisExpression': 21, 'SuperExpression': 21, 'ObjectExpression': 21, 'ClassExpression': 21, // '(_)':20, // Parens 'MemberExpression': 19, // 'new()':19, 'CallExpression': 18, 'NewExpression': 18, 'ArrayExpression': 17.5, 'FunctionExpression': 17.5, 'FunctionDeclaration': 17.5, 'ArrowFunctionExpression': 17.5, 'UpdateExpression++': 17, // Postfix is 17, prefix is 16 'UpdateExpression--': 17, // Postfix is 17, prefix is 16 'UpdateExpression++prefix': 16, // Postfix is 17, prefix is 16 'UpdateExpression--prefix': 16, // Postfix is 17, prefix is 16 'UnaryExpression':16, // ! ~ + - typeof void delete 'AwaitExpression': 16, 'BinaryExpression**': 15, 'BinaryExpression*': 15, 'BinaryExpression/': 15, 'BinaryExpression%': 15, 'BinaryExpression+': 14, 'BinaryExpression-': 14, 'BinaryExpression<<': 13, 'BinaryExpression>>': 13, 'BinaryExpression>>>': 13, 'BinaryExpression<': 12, 'BinaryExpression<=': 12, 'BinaryExpression>': 12, 'BinaryExpression>=': 12, 'BinaryExpressionin': 12, 'BinaryExpressioninstanceof': 12, 'BinaryExpression==': 11, 'BinaryExpression===': 11, 'BinaryExpression!=': 11, 'BinaryExpression!==': 11, 'BinaryExpression&': 10, 'BinaryExpression^': 9, 'BinaryExpression|': 8, 'LogicalExpression&&': 7, 'LogicalExpression||': 6, 'ConditionalExpression': 5, 'AssignmentPattern': 4, 'AssignmentExpression': 4, 'yield': 3, 'YieldExpression': 3, 'SpreadElement': 2, 'comma-separated-list':1.5, 'SequenceExpression': 1 }; var CommaList = {type:'comma-separated-list'} ; function precedence(node) { if (node.type==='NewExpression' && node.arguments && node.arguments.length) return 19 ; var p = OPERATORS_PRECEDENCE[node.type] || OPERATORS_PRECEDENCE[node.type+node.operator] || OPERATORS_PRECEDENCE[node.type+node.operator+(node.prefix?"prefix":"")]; if (p !== undefined) return p; //console.log("Precedence?",node.type,node.operator) ; return 20; } function out(node,state,type) { var f = this[type || node.type] ; if (f) { /* try { var attr = Object.keys(node).filter(k=>k[0]==='$').map(k=>k+(node[k]?"+":"-")) ; if (attr.length) state.write(node,"/*"+attr.join(", ")+"\u002A/ ") ; } catch (ex) {} ; */ f.call(this, node, state); } else { // Unknown node type - just spew its source state.write(node,"/*"+node.type+"?*/ "+state.sourceAt(node.start,node.end)) ; } } function expr(state, parent, node, assoc) { if (assoc===2 || precedence(node) < precedence(parent) || (precedence(node) == precedence(parent) && (assoc || parent.right === node))) { state.write(null, '('); this.out(node, state,node.type); state.write(null, ')'); } else { this.out(node, state,node.type); } } function formatParameters(params, state) { var param; state.write(null, '('); if (params != null && params.length > 0) { this.out(params[0], state,params[0].type); for (var i = 1, length = params.length; i < length; i++) { param = params[i]; state.write(param, ', '); this.out(param, state,param.type); } } state.write(null, ') '); } function argumentList(node, state) { state.write(node, '('); var args = node['arguments']; if (args.length > 0) { var length = args.length; for (var i = 0; i < length; i++) { if (i!=0) state.write(null, ', '); this.expr(state,CommaList,args[i]) ; } } state.write(null, ')'); }; var traveler = { out: out, expr: expr, argumentList: argumentList, formatParameters: formatParameters, Program: function (node, state) { var statements, statement; var indent = repeat(state.indent, state.indentLevel); var lineEnd = state.lineEnd; statements = node.body; for (var i = 0, length = statements.length; i < length; i++) { statement = statements[i]; state.write(null, indent); this.out(statement, state,statement.type); state.write(null, lineEnd); } }, BlockStatement: BlockStatement = function (node, state) { var statements, statement; var indent = repeat(state.indent, state.indentLevel++); var lineEnd = state.lineEnd; var statementIndent = indent + state.indent; state.write(node, '{'); statements = node.body; if (statements != null && statements.length > 0) { state.write(null, lineEnd); for (var i = 0, length = statements.length; i < length; i++) { statement = statements[i]; state.write(null, statementIndent); this.out(statement, state,statement.type); state.write(null, lineEnd); } state.write(null, indent); } state.write(node.loc ? { loc: { start: { line: node.loc.end.line, column: 0 } } } : null, '}'); state.indentLevel--; }, ClassBody: BlockStatement, EmptyStatement: function (node, state) { state.write(node, ';'); }, ParenthesizedExpression: function (node, state) { this.expr(state, node, node.expression, 2); }, ExpressionStatement: function (node, state) { if (node.expression.type === 'FunctionExpression' || node.expression.type === 'ObjectExpression') { state.write(null, '('); this.expr(state, node, node.expression); state.write(null, ')'); } else { this.expr(state, node, node.expression); } state.write(null, ';'); }, IfStatement: function (node, state) { state.write(node, 'if ('); this.out(node.test, state,node.test.type); state.write(null, ') '); if (node.consequent.type !== 'BlockStatement') state.write(null, state.lineEnd, repeat(state.indent, state.indentLevel + 1)); this.out(node.consequent, state,node.consequent.type); if (node.alternate != null) { if (node.consequent.type !== 'BlockStatement') state.write(null, state.lineEnd, repeat(state.indent, state.indentLevel)); state.write(null, ' else '); if (node.alternate.type !== 'BlockStatement' && node.alternate.type !== 'IfStatement') state.write(null, state.lineEnd, repeat(state.indent, state.indentLevel + 1)); this.out(node.alternate, state,node.alternate.type); } }, LabeledStatement: function (node, state) { this.out(node.label, state,node.label.type); state.write(null, ':'); this.out(node.body, state,node.body.type); }, BreakStatement: function (node, state) { state.write(node, 'break'); if (node.label) { state.write(null, ' '); this.out(node.label, state,node.label.type); } state.write(null, ';'); }, ContinueStatement: function (node, state) { state.write(node, 'continue'); if (node.label) { state.write(null, ' '); this.out(node.label, state,node.label.type); } state.write(null, ';'); }, WithStatement: function (node, state) { state.write(node, 'with ('); this.out(node.object, state,node.object.type); state.write(null, ') '); this.out(node.body, state,node.body.type); }, SwitchStatement: function (node, state) { var occurence, consequent, statement; var indent = repeat(state.indent, state.indentLevel++); var lineEnd = state.lineEnd; state.indentLevel++; var caseIndent = indent + state.indent; var statementIndent = caseIndent + state.indent; state.write(node, 'switch ('); this.out(node.discriminant, state,node.discriminant.type); state.write(null, ') {', lineEnd); var occurences = node.cases; for (var i = 0; i < occurences.length; i++) { occurence = occurences[i]; if (occurence.test) { state.write(occurence, caseIndent, 'case '); this.out(occurence.test, state,occurence.test.type); state.write(null, ':', lineEnd); } else { state.write(occurence, caseIndent, 'default:', lineEnd); } consequent = occurence.consequent; for (var j = 0; j < consequent.length; j++) { statement = consequent[j]; state.write(null, statementIndent); this.out(statement, state,statement.type); state.write(null, lineEnd); } } state.indentLevel -= 2; state.write(null, indent, '}'); }, ReturnStatement: function (node, state) { if (node.async) state.write(node, ' async '); state.write(node, 'return'); if (node.argument) { state.write(null, ' '); this.out(node.argument, state,node.argument.type); } state.write(null, ';'); }, ThrowStatement: function (node, state) { if (node.async) state.write(node, ' async '); state.write(node, 'throw '); this.out(node.argument, state,node.argument.type); state.write(null, ';'); }, TryStatement: function (node, state) { var handler; state.write(node, 'try '); this.out(node.block, state,node.block.type); if (node.handler) { this.out(node.handler, state, node.handler.type) } if (node.finalizer) { state.write(node.finalizer, ' finally '); this.out(node.finalizer, state,node.finalizer.type); } }, CatchClause: function (node, state) { state.write(node, ' catch ('); this.out(node.param, state, node.param.type); state.write(null, ') '); this.out(node.body, state, node.body.type); }, WhileStatement: function (node, state) { state.write(node, 'while ('); this.out(node.test, state,node.test.type); state.write(null, ') '); if (node.body.type !== 'BlockStatement') state.write(null, state.lineEnd, repeat(state.indent, state.indentLevel + 1)); this.out(node.body, state,node.body.type); }, DoWhileStatement: function (node, state) { state.write(node, 'do '); if (node.body.type !== 'BlockStatement') state.write(null, state.lineEnd, repeat(state.indent, state.indentLevel + 1)); this.out(node.body, state,node.body.type); state.write(null, ' while ('); this.out(node.test, state,node.test.type); state.write(null, ');'); }, ForStatement: function (node, state) { state.write(node, 'for ('); if (node.init != null) { var init = node.init, type = init.type; state.inForInit++ ; this.out(init, state,type); state.inForInit-- ; if (type !== 'VariableDeclaration') state.write(null, '; '); } else { state.write(null, '; '); } if (node.test) this.out(node.test, state,node.test.type); state.write(null, '; '); if (node.update) this.out(node.update, state,node.update.type); state.write(null, ') '); if (node.body.type !== 'BlockStatement') state.write(null, state.lineEnd, repeat(state.indent, state.indentLevel + 1)); this.out(node.body, state,node.body.type); }, ForInStatement: ForInStatement = function (node, state) { state.write(node, 'for ('); var left = node.left, type = left.type; state.inForInit++ ; this.out(left, state,type); if (type[0] === 'V' && type.length === 19) { state.back(); } state.inForInit-- ; state.write(null, node.type[3] === 'I' ? ' in ' : ' of '); this.out(node.right, state,node.right.type); state.write(null, ') '); if (node.body.type !== 'BlockStatement') state.write(null, state.lineEnd, repeat(state.indent, state.indentLevel + 1)); this.out(node.body, state,node.body.type); }, ForOfStatement: ForInStatement, DebuggerStatement: function (node, state) { state.write(node, 'debugger;'); }, Function: function (node, state) { if (node.async) state.write(node, 'async '); state.write(node, node.generator ? 'function* ' : 'function '); if (node.id) state.write(node.id, node.id.name); this.formatParameters(node.params, state); this.out(node.body, state,node.body.type); }, FunctionDeclaration: function (node, state) { this.Function(node, state); state.write(null, state.lineEnd, repeat(state.indent, state.indentLevel)); }, FunctionExpression: function (node, state) { this.Function(node, state); }, VariableDeclaration: function (node, state) { var declarations = node.declarations; state.write(node, node.kind, ' '); var length = declarations.length; if (length > 0) { this.out(declarations[0], state,'VariableDeclarator'); for (var i = 1; i < length; i++) { state.write(null, ', '); this.out(declarations[i], state,'VariableDeclarator'); } } state.write(null, ';'); }, VariableDeclarator: function (node, state) { this.out(node.id, state,node.id.type); if (node.init != null) { state.write(null, ' = '); this.expr(state,CommaList,node.init) ; } }, ClassDeclaration: function (node, state) { state.write(node, 'class '); if (node.id) { state.write(node.id, node.id.name + ' '); } if (node.superClass) { state.write(null, 'extends '); this.out(node.superClass, state,node.superClass.type); state.write(null, ' '); } this.out(node.body, state,'BlockStatement'); }, ImportSpecifier: function (node, state) { if (node.local.name == node.imported.name) { this.out(node.local, state,node.local.type); } else { this.out(node.imported, state,node.imported.type); state.write(null, ' as '); this.out(node.local, state,node.local.type); } }, ImportDefaultSpecifier: function (node, state) { this.out(node.local, state,node.local.type); }, ImportNamespaceSpecifier: function (node, state) { state.write(null, '* as '); this.out(node.local, state,node.local.type); }, ImportDeclaration: function (node, state) { var i, specifier, name; state.write(node, 'import '); var specifiers = node.specifiers; var length = specifiers.length; var block = true; if (length > 0) { for (var i = 0; i < length; i++) { if (specifiers[i].type === 'ImportSpecifier' && block) { block = false; state.write(null, '{'); } this.out(specifiers[i], state,specifiers[i].type); if (i < length - 1) state.write(null, ', '); } if (specifiers[length - 1].type === 'ImportSpecifier') state.write(null, '}'); state.write(null, ' from '); } state.write(node.source, node.source.raw); state.write(null, ';'); }, ExportDefaultDeclaration: function (node, state) { state.write(node, 'export default '); this.out(node.declaration, state,node.declaration.type); }, ExportSpecifier: function (node, state) { if (node.local.name == node.exported.name) { this.out(node.local, state,node.local.type); } else { this.out(node.local, state,node.local.type); state.write(null, ' as '); this.out(node.exported, state,node.exported.type); } }, ExportNamedDeclaration: function (node, state) { var specifier, name; state.write(node, 'export '); if (node.declaration) { this.out(node.declaration, state,node.declaration.type); } else { var specifiers = node.specifiers; state.write(node, '{'); if (specifiers && specifiers.length > 0) { for (var i = 0; i < specifiers.length; i++) { this.out(specifiers[i], state,specifiers[i].type); if (i < specifiers.length - 1) state.write(null, ', '); } } state.write(null, '}'); if (node.source) { state.write(node.source, ' from ', node.source.raw); } state.write(null, ';'); } }, ExportAllDeclaration: function (node, state) { state.write(node, 'export * from '); state.write(node.source, node.source.raw, ';'); }, MethodDefinition: function (node, state) { if (node.value.async) state.write(node, 'async '); if (node.static) state.write(node, 'static '); switch (node.kind) { case 'get': case 'set': state.write(node, node.kind, ' '); break; default: break; } if (node.value.generator) state.write(null, '*'); if (node.computed) { state.write(null, '['); this.out(node.key, state,node.key.type); state.write(null, ']'); } else { this.out(node.key, state,node.key.type); } this.formatParameters(node.value.params, state); this.out(node.value.body, state,node.value.body.type); }, ClassMethod: function (node,state){ if (node.async) state.write(node, 'async '); if (node.static) state.write(node, 'static '); switch (node.kind) { case 'get': case 'set': state.write(node, node.kind, ' '); break; default: break; } if (node.generator) state.write(null, '*'); if (node.computed) { state.write(null, '['); this.out(node.key, state,node.key.type); state.write(null, ']'); } else { this.out(node.key, state,node.key.type); } this.formatParameters(node.params, state); this.out(node.body, state, node.body.type); }, ClassExpression: function (node, state) { this.out(node, state,'ClassDeclaration'); }, ArrowFunctionExpression: function (node, state) { if (node.async) state.write(node, 'async '); if (node.params.length===1 && node.params[0].type==='Identifier') { this.out(node.params[0], state, node.params[0].type) ; state.write(node, ' => '); } else { this.formatParameters(node.params, state); state.write(node, '=> '); } if (node.body.type === 'ObjectExpression' || node.body.type === 'SequenceExpression') { state.write(null, '('); this.out(node.body, state,node.body.type); state.write(null, ')'); } else { this.out(node.body, state,node.body.type); } }, ThisExpression: function (node, state) { state.write(node, 'this'); }, Super: function (node, state) { state.write(node, 'super'); }, RestElement: RestElement = function (node, state) { state.write(node, '...'); this.out(node.argument, state,node.argument.type); }, SpreadElement: RestElement, YieldExpression: function (node, state) { state.write(node, node.delegate ? 'yield*' : 'yield'); if (node.argument) { state.write(null, ' '); this.expr(state, node, node.argument); } }, AwaitExpression: function (node, state) { state.write(node, 'await '); this.expr(state, node, node.argument); }, TemplateLiteral: function (node, state) { var expression; var quasis = node.quasis, expressions = node.expressions; state.write(node, '`'); for (var i = 0, length = expressions.length; i < length; i++) { expression = expressions[i]; state.write(quasis[i].value, quasis[i].value.raw); state.write(null, '${'); this.out(expression, state,expression.type); state.write(null, '}'); } state.write(quasis[quasis.length - 1].value, quasis[quasis.length - 1].value.raw); state.write(node, '`'); }, TaggedTemplateExpression: function (node, state) { this.out(node.tag, state,node.tag.type); this.out(node.quasi, state,node.quasi.type); }, ArrayExpression: ArrayExpression = function (node, state) { state.write(node, '['); if (node.elements.length > 0) { var elements = node.elements, length = elements.length; for (var i = 0; ; ) { var element = elements[i]; element && this.expr(state,CommaList,element) ; i += 1 ; if (i < length || element===null) state.write(null, ','); if (i >= length) break; if (state.lineLength() > state.wrapColumn) state.write(null, state.lineEnd, repeat(state.indent, state.indentLevel + 1)); } } state.write(null, ']'); }, ArrayPattern: ArrayExpression, ObjectExpression: function (node, state) { var property; var indent = repeat(state.indent, state.indentLevel++); var lineEnd = state.lineEnd; var propertyIndent = indent + state.indent; state.write(node, '{'); if (node.properties.length > 0) { state.write(null, lineEnd); var properties = node.properties, length = properties.length; for (var i = 0; ; ) { property = properties[i]; state.write(null, propertyIndent); this.out(property, state, property.type); if (++i < length) state.write(node, ',', lineEnd); else break; if (state.lineLength() > state.wrapColumn) state.write(null, state.lineEnd, repeat(state.indent, state.indentLevel + 1)); } state.write(null, lineEnd, indent, '}'); } else { state.write(null, '}'); } state.indentLevel--; }, Property: function (node, state) { if (node.method || (node.kind === 'get' || node.kind === 'set')) { this.MethodDefinition(node, state); } else { if (!node.shorthand) { if (node.computed) { state.write(null, '['); this.out(node.key, state,node.key.type); state.write(null, ']'); } else { this.out(node.key, state,node.key.type); } state.write(null, ': '); } this.expr(state,CommaList,node.value); } }, ObjectPattern: function (node, state) { state.write(node, '{'); if (node.properties.length > 0) { var properties = node.properties, length = properties.length; for (var i = 0; ; ) { this.out(properties[i], state, properties[i].type); if (++i < length) state.write(null, ', '); else break; } } state.write(null, '}'); }, SequenceExpression: function (node, state) { var expression; var expressions = node.expressions; if (expressions.length > 0) { var length = expressions.length; for (var i = 0; i<length; i++) { expression = expressions[i]; if (i) state.write(null, ', ') ; this.expr(state,CommaList,expression) ; } } }, UnaryExpression: function (node, state) { if (node.prefix) { state.write(node, node.operator); if (node.operator.length > 1) state.write(node, ' '); this.expr(state, node, node.argument, true); } else { this.expr(state, node, node.argument); state.write(node, node.operator); } }, UpdateExpression: function (node, state) { if (node.prefix) { state.write(node, node.operator); this.out(node.argument, state,node.argument.type); } else { this.out(node.argument, state,node.argument.type); state.write(node, node.operator); } }, BinaryExpression: BinaryExpression = function (node, state) { var operator = node.operator; if (operator==='in' && state.inForInit) state.write(null, '('); this.expr(state, node, node.left); state.write(node, ' ', operator, ' '); this.expr(state, node, node.right, node.right.type==='ArrowFunctionExpression'?2:0); if (operator==='in' && state.inForInit) state.write(null, ')'); }, LogicalExpression: BinaryExpression, AssignmentExpression: function (node, state) { if (node.left.type==='ObjectPattern') state.write(null,'('); this.BinaryExpression(node,state); if (node.left.type==='ObjectPattern') state.write(null,')'); }, AssignmentPattern: function (node, state) { this.expr(state, node, node.left); state.write(node, ' = '); this.expr(state, node, node.right); }, ConditionalExpression: function (node, state) { this.expr(state, node, node.test, true); state.write(node, ' ? '); this.expr(state, node, node.consequent); state.write(null, ' : '); this.expr(state, node, node.alternate); }, NewExpression: function (node, state) { state.write(node, 'new '); this.expr(state, node, node.callee, (node.callee.type === 'CallExpression' || node.callee.type==='ObjectExpression')?2:0); this.argumentList(node,state) ; }, CallExpression: function (node, state) { this.expr(state, node, node.callee, node.callee.type==='ObjectExpression'?2:0); this.argumentList(node,state) ; }, MemberExpression: function (node, state) { var requireParens = (node.object.type === 'ObjectExpression' || (node.object.type.match(/Literal$/) && node.object.raw && node.object.raw.match(/^[0-9]/))) ; var noParens = !requireParens && ((node.object.type === 'ArrayExpression' || node.object.type === 'CallExpression' || node.object.type === 'NewExpression') || precedence(node) <= precedence(node.object)); if (noParens) { this.out(node.object, state,node.object.type); } else { state.write(null, '('); this.out(node.object, state,node.object.type); state.write(null, ')'); } if (node.computed) { state.write(node, '['); this.out(node.property, state,node.property.type); state.write(null, ']'); } else { state.write(node, '.'); this.out(node.property, state,node.property.type); } }, Identifier: function (node, state) { state.write(node, node.name); }, Literal: function (node, state) { state.write(node, node.raw); }, NullLiteral:function (node, state) { state.write(node, 'null'); }, BooleanLiteral:function (node, state) { state.write(node, JSON.stringify(node.value)); }, StringLiteral:function (node, state) { state.write(node, JSON.stringify(node.value)); }, RegExpLiteral:function (node, state) { state.write(node, node.extra.raw || ('/'+node.pattern+'/'+node.flags)); }, NumericLiteral:function (node, state) { state.write(node, JSON.stringify(node.value)); }, }; module.exports = function (node, options, originalSource) { options = options || {}; var buffer = "", lines = []; var map = options.map && new SourceMapGenerator(options.map); if (map && options.map.sourceContent) { map.setSourceContent(options.map.file, options.map.sourceContent); } var backBy = ""; var leadingComments = []; var trailingComments = []; function write(node) { backBy = arguments[arguments.length - 1] ; for (var i = 1; i < arguments.length; i++) { if (map && node && node.loc && node.loc.start) { var startOfLine = false; map.addMapping({ source: options.map.file, original: { line: node.loc.start.line, column: startOfLine ? 0 : node.loc.start.column }, generated: { line: options.map.startLine + lines.length + 1, column: startOfLine ? 0 : buffer.length } }); } if (arguments[i] === st.lineEnd) { if (trailingComments.length) { trailingComments.forEach(function (c) { if (c.type === 'Line') buffer += " // " + c.value; else { (" /*" + c.value + "*/").split("\n").forEach(function (v) { buffer += v; lines.push(buffer); buffer = ""; }); buffer = lines.pop(); } }); trailingComments = []; } lines.push(buffer); buffer = ""; if (leadingComments.length) { var preceeding = lines.pop(); leadingComments.forEach(function (c) { var indent = repeat(st.indent, c.indent); if (c.type === "Line") lines.push(indent + "//" + c.value); else (indent + "/*" + c.value + "*/").split("\n").forEach(function (l) { lines.push(l); }); }); lines.push(preceeding); leadingComments = []; } } else { buffer += arguments[i]; if (node && node.$comments) { node.$comments.forEach(function (c) { var trailing = node.loc.start.column < c.loc.start.column; c.indent = st.indentLevel; if (trailing) { trailingComments.push(c); } else { leadingComments.push(c); } }); node.$comments = null; } } } } function lineLength() { return buffer.length; } function sourceAt(start, end) { return originalSource?originalSource.substring(start,end):"/* Omitted Non-standard node */" ; } function back() { buffer = buffer.substring(0, buffer.length - backBy.length); } var st = { inForInit: 0, lineLength: lineLength, sourceAt:sourceAt, write: write, back: back, indent: " ", lineEnd: "\n", indentLevel: 0, wrapColumn: 80 }; traveler.out(node, st); trailingComments = node.$comments || []; st.write(node, st.lineEnd); var result = lines.join(st.lineEnd); if (options && options.map) { return { code: result, map: map }; } return result; };