diff --git a/packages/pug-code-gen/index.js b/packages/pug-code-gen/index.js index a75929ce9..02d3d61c1 100644 --- a/packages/pug-code-gen/index.js +++ b/packages/pug-code-gen/index.js @@ -8,7 +8,14 @@ var compileAttrs = require('pug-attrs'); var selfClosing = require('void-elements'); var constantinople = require('constantinople'); var stringify = require('js-stringify'); -var addWith = require('with'); + +var findGlobals = require('with/lib/globals.js').default; + +var t = require('@babel/types'); +var gen = require('@babel/generator'); +var babylon = require('@babel/parser'); +var babelTemplate = require('@babel/template').default; +var babel = require('@babel/core'); // This is used to prevent pretty printing inside certain tags var WHITE_SPACE_SENSITIVE_TAGS = { @@ -26,6 +33,22 @@ var INTERNAL_VARIABLES = [ 'pug_html', ]; +var push = Array.prototype.push; +var unshift = Array.prototype.unshift; +var concat = Array.prototype.concat; + +var tpl_json_interp = JSON.stringify( + babelTemplate.ast(`null == (pug_interp = VALUE) ? "" : pug_interp`) +); + +var tpl_json_interp_escape = JSON.stringify( + babelTemplate.ast(`escape(null == (pug_interp = VALUE) ? "" : pug_interp)`) +); + +var tpl_json_buffer = JSON.stringify( + babelTemplate.ast(`pug_html = pug_html + placeholder`) +); + module.exports = generateCode; module.exports.CodeGenerator = Compiler; function generateCode(ast, options) { @@ -50,7 +73,6 @@ function toConstant(src) { function Compiler(node, options) { this.options = options = options || {}; this.node = node; - this.bufferedConcatenationCount = 0; this.hasCompiledDoctype = false; this.hasCompiledTag = false; this.pp = options.pretty || false; @@ -70,6 +92,12 @@ function Compiler(node, options) { if (this.debug && this.inlineRuntimeFunctions) { this.runtimeFunctionsUsed.push('rethrow'); } + this.codeBuffer = 'plug=function*(){'; + this.codeMarker = {}; + this.codeIndex = -1; + + this.useGenerators = false; + this.templateVars = ['locals']; } /** @@ -77,12 +105,14 @@ function Compiler(node, options) { */ Compiler.prototype = { - runtime: function(name) { + runtime: function(name, asAST) { if (this.inlineRuntimeFunctions) { this.runtimeFunctionsUsed.push(name); - return 'pug_' + name; + return asAST ? t.identifier('pug_' + name) : 'pug_' + name; } else { - return 'pug.' + name; + return asAST + ? t.memberExpression(t.identifier('pug'), t.identifier(name)) + : 'pug.' + name; } }, @@ -95,6 +125,192 @@ Compiler.prototype = { throw err; }, + parseExpr: function(expr) { + //return babylon.parse('function*g(){return e='+expr+'}').program.body[0].body.body[0].argument.right; + return babylon.parseExpression(expr); + }, + parseArgs: function(args) { + return babylon.parse('a(' + args + ')').program.body.pop().expression + .arguments; + }, + ast_variableDeclaration: function() { + return t.variableDeclaration('var', [ + t.variableDeclarator(t.identifier('pug_html'), t.stringLiteral('')), + t.variableDeclarator(t.identifier('pug_mixins'), t.objectExpression([])), + t.variableDeclarator(t.identifier('pug_interp'), null), + ]); + }, + ast_return: function() { + return [t.returnStatement(t.identifier('pug_html'))]; + }, + wrapCallExpression: function(node) { + return node; + }, + ast_buffer: function(ast) { + const o = JSON.parse(tpl_json_buffer); + o.expression.right.right = ast; + return o; + }, + ast_with: function(ast) { + let exclude = this.options.globals + ? this.options.globals.concat(INTERNAL_VARIABLES) + : INTERNAL_VARIABLES; + exclude = exclude.concat( + this.runtimeFunctionsUsed.map(function(name) { + return 'pug_' + name; + }) + ); + exclude.push('undefined', 'this', 'locals'); + let vars = findGlobals(t.program(ast)) + .map(function(v) { + return v.name; + }) + .filter(function(v) { + return exclude.indexOf(v) === -1; + }); + if (vars.length > 0) { + let bag = 'locals'; + ast = [ + t.expressionStatement( + t.callExpression( + t.memberExpression( + t.functionExpression( + null, + vars.map(function(v) { + return t.identifier(v); + }), + t.blockStatement(ast) + ), + t.identifier('call') + ), + [t.thisExpression()].concat( + vars.map(function(v) { + return t.conditionalExpression( + t.binaryExpression( + 'in', + t.stringLiteral(v), + t.logicalExpression( + '||', + t.identifier(bag), + t.objectExpression([]) + ) + ), + t.memberExpression( + t.logicalExpression( + '||', + t.identifier(bag), + t.objectExpression([]) + ), + t.identifier(v) + ), + t.conditionalExpression( + t.binaryExpression( + '!==', + t.unaryExpression('typeof', t.identifier(v)), + t.stringLiteral('undefined') + ), + t.identifier(v), + t.identifier('undefined') + ) + ); + }) + ) + ) + ), + ]; + } + return ast; + }, + /** + * This method is called once the AST is built in + * order to apply transformations + * nb: a custom AST walk/replace was written because + * the babel plugin architecture + * Currently it this transformation : + * - compacts sequential pug_html = pug_html + any (max of 100) + * - further compacts sequential pug_html = pug_html + stringLiteral + */ + + ast_postprocess: function(ast) { + let needCompaction = function(c) { + return ( + t.isExpressionStatement(c) && + t.isAssignmentExpression(c.expression) && + c.expression.left.name === 'pug_html' && + t.isBinaryExpression(c.expression.right) && + c.expression.right.left.name === 'pug_html' + ); + }; + + let walk = function(node) { + Object.keys(node).forEach(function(k) { + var child = node[k]; + if (child && typeof child === 'object' && child.length) { + let i, j; + for (i = 0; i < child.length; i++) { + let start, end; + let fragment = [t.identifier('pug_html')]; + if (needCompaction(child[i])) { + start = i; + end = i; + // locate sequential buffer operations + while ( + needCompaction(child[end]) && + end < child.length && + fragment.length < 101 + ) { + fragment.push(child[end].expression.right.right); + end++; + } + + // join adjacent stringLiterals + for (j = 0; j < fragment.length; j++) { + let start, end; + if (t.isStringLiteral(fragment[j])) { + start = j; + end = j; + while ( + t.isStringLiteral(fragment[end]) && + end < fragment.length + ) { + end++; + } + let lit = t.stringLiteral( + fragment + .slice(start, end) + .map(function(v) { + return v.value; + }) + .join('') + ); + //lit.extra = {rawValue: lit.value, raw: stringify(lit.value)}; + fragment.splice(start, end - start, lit); + } + } + + // join fragments + let expr = t.expressionStatement( + t.assignmentExpression( + '=', + t.identifier('pug_html'), + fragment.reduce(function(acc, val) { + return t.binaryExpression('+', acc, val); + }) + ) + ); + child.splice(start, end - start, expr); + } else if (child[i] && typeof child[i].type === 'string') { + walk(child[i]); + } + } + } else if (child && typeof child.type === 'string') { + walk(child); + } + }); + }; + walk(ast); + return ast; + }, /** * Compile parse tree to JavaScript. * @@ -102,10 +318,17 @@ Compiler.prototype = { */ compile: function() { - this.buf = []; - if (this.pp) this.buf.push('var pug_indent = [];'); - this.lastBufferedIdx = -1; - this.visit(this.node); + var ast = []; + if (this.pp) { + ast.push( + t.variableDeclaration('var', [ + t.variableDeclarator(t.identifier('pug_indent'), t.arrayExpression()), + ]) + ); + } + + push.apply(ast, this.visit(this.node)); + if (!this.dynamicMixins) { // if there are no dynamic mixins we can remove any un-used mixins var mixinNames = Object.keys(this.mixins); @@ -113,62 +336,100 @@ Compiler.prototype = { var mixin = this.mixins[mixinNames[i]]; if (!mixin.used) { for (var x = 0; x < mixin.instances.length; x++) { - for ( - var y = mixin.instances[x].start; - y < mixin.instances[x].end; - y++ - ) { - this.buf[y] = ''; - } + mixin.instances[x].stmt.type = 'EmptyStatement'; + delete mixin.instances[x].stmt.expression; } } } } - var js = this.buf.join('\n'); - var globals = this.options.globals - ? this.options.globals.concat(INTERNAL_VARIABLES) - : INTERNAL_VARIABLES; + if (this.options.self) { - js = 'var self = locals || {};' + js; + ast = [ + t.variableDeclaration('var', [ + t.variableDeclarator( + t.identifier('self'), + t.logicalExpression( + '||', + t.identifier('locals'), + t.objectExpression([]) + ) + ), + ]), + ].concat(ast); } else { - js = addWith( - 'locals || {}', - js, - globals.concat( - this.runtimeFunctionsUsed.map(function(name) { - return 'pug_' + name; - }) - ) - ); + // transform `ast` into `with(locals || {}) { ast }` + ast = this.ast_with(ast); } + if (this.debug) { if (this.options.includeSources) { - js = - 'var pug_debug_sources = ' + - stringify(this.options.includeSources) + - ';\n' + - js; + ast.unshift( + t.variableDeclaration('var', [ + t.variableDeclarator( + t.identifier('pug_debug_sources'), + this.parseExpr(stringify(this.options.includeSources)) + ), + ]) + ); + } + + var rethrowArgs = [ + t.identifier('err'), + t.identifier('pug_debug_filename'), + t.identifier('pug_debug_line'), + ]; + if (this.options.includeSources) { + rethrowArgs.push( + t.memberExpression( + t.identifier('pug_debug_sources'), + t.identifier('pug_debug_filename'), + true + ) + ); } - js = - 'var pug_debug_filename, pug_debug_line;' + - 'try {' + - js + - '} catch (err) {' + - (this.inlineRuntimeFunctions ? 'pug_rethrow' : 'pug.rethrow') + - '(err, pug_debug_filename, pug_debug_line' + - (this.options.includeSources - ? ', pug_debug_sources[pug_debug_filename]' - : '') + - ');' + - '}'; + ast = [ + t.variableDeclaration('var', [ + t.variableDeclarator(t.identifier('pug_debug_filename'), null), + t.variableDeclarator(t.identifier('pug_debug_line'), null), + ]), + t.tryStatement( + t.blockStatement(ast), + t.catchClause( + t.identifier('err'), + t.blockStatement([ + t.expressionStatement( + t.callExpression( + this.inlineRuntimeFunctions + ? t.identifier('pug_rethrow') + : t.memberExpression( + t.identifier('pug'), + t.identifier('rethrow') + ), + rethrowArgs + ) + ), + ]) + ) + ), + ]; } + + ast = t.functionDeclaration( + t.identifier(this.options.templateName || 'template'), + this.templateVars.map(function(v) { + return t.identifier(v); + }), + t.blockStatement( + [this.ast_variableDeclaration()].concat(ast, this.ast_return()) + ) + ); + + ast = this.ast_postprocess(ast); + return ( buildRuntime(this.runtimeFunctionsUsed) + - 'function ' + - (this.options.templateName || 'template') + - '(locals) {var pug_html = "", pug_mixins = {}, pug_interp;' + - js + - ';return pug_html;}' + gen.default(ast, {compact: true, jsescOption: {isScriptContext: true}}) + .code ); }, @@ -196,34 +457,9 @@ Compiler.prototype = { */ buffer: function(str) { - var self = this; - - str = stringify(str); - str = str.substr(1, str.length - 2); - - if ( - this.lastBufferedIdx == this.buf.length && - this.bufferedConcatenationCount < 100 - ) { - if (this.lastBufferedType === 'code') { - this.lastBuffered += ' + "'; - this.bufferedConcatenationCount++; - } - this.lastBufferedType = 'text'; - this.lastBuffered += str; - this.buf[this.lastBufferedIdx - 1] = - 'pug_html = pug_html + ' + - this.bufferStartChar + - this.lastBuffered + - '";'; - } else { - this.bufferedConcatenationCount = 0; - this.buf.push('pug_html = pug_html + "' + str + '";'); - this.lastBufferedType = 'text'; - this.bufferStartChar = '"'; - this.lastBuffered = str; - this.lastBufferedIdx = this.buf.length; - } + const lit = t.stringLiteral(str); + //lit.extra = {rawValue: lit.value, raw: stringify(lit.value)}; + return this.ast_buffer(lit); }, /** @@ -237,27 +473,13 @@ Compiler.prototype = { if (isConstant(src)) { return this.buffer(toConstant(src) + ''); } - if ( - this.lastBufferedIdx == this.buf.length && - this.bufferedConcatenationCount < 100 - ) { - this.bufferedConcatenationCount++; - if (this.lastBufferedType === 'text') this.lastBuffered += '"'; - this.lastBufferedType = 'code'; - this.lastBuffered += ' + (' + src + ')'; - this.buf[this.lastBufferedIdx - 1] = - 'pug_html = pug_html + (' + - this.bufferStartChar + - this.lastBuffered + - ');'; - } else { - this.bufferedConcatenationCount = 0; - this.buf.push('pug_html = pug_html + (' + src + ');'); - this.lastBufferedType = 'code'; - this.bufferStartChar = ''; - this.lastBuffered = '(' + src + ')'; - this.lastBufferedIdx = this.buf.length; - } + var body = this.parseExpr(src); + var ast = this.ast_buffer(body); + return ast; + }, + + bufferAST: function(ast) { + return this.ast_buffer(ast); }, /** @@ -270,11 +492,27 @@ Compiler.prototype = { */ prettyIndent: function(offset, newline) { + var ast; offset = offset || 0; newline = newline ? '\n' : ''; - this.buffer(newline + Array(this.indents + offset).join(this.pp)); - if (this.parentIndents) - this.buf.push('pug_html = pug_html + pug_indent.join("");'); + ast = concat.apply( + [], + [ + this.buffer(newline + Array(this.indents + offset).join(this.pp)), + this.parentIndents + ? this.ast_buffer( + t.callExpression( + t.memberExpression( + t.identifier('pug_indent'), + t.identifier('join') + ), + [t.stringLiteral('')] + ) + ) + : [], + ] + ); + return ast; }, /** @@ -284,9 +522,13 @@ Compiler.prototype = { * @api public */ + visitCacheLine: JSON.stringify(babelTemplate.ast(`pug_debug_line = 1;`)), + visitCacheFilename: JSON.stringify( + babelTemplate.ast(`pug_debug_filename = "";`) + ), visit: function(node, parent) { + var ast = []; var debug = this.debug; - if (!node) { var msg; if (parent) { @@ -307,10 +549,17 @@ Compiler.prototype = { if (debug && node.debug !== false && node.type !== 'Block') { if (node.line) { - var js = ';pug_debug_line = ' + node.line; - if (node.filename) - js += ';pug_debug_filename = ' + stringify(node.filename); - this.buf.push(js + ';'); + const astLine = JSON.parse(this.visitCacheLine); + astLine.expression.right.value = node.line; + astLine.expression.right.extra = null; + ast.push(astLine); + + if (node.filename) { + const astFile = JSON.parse(this.visitCacheFilename); + astFile.expression.right.value = node.filename; + astFile.expression.right.extra = null; + ast.push(astFile); + } } } @@ -345,7 +594,9 @@ Compiler.prototype = { throw new TypeError(msg); } - this.visitNode(node); + const res = this.visitNode(node, parent); + unshift.apply(res, ast); + return res; }, /** @@ -355,8 +606,9 @@ Compiler.prototype = { * @api public */ - visitNode: function(node) { - return this['visit' + node.type](node); + visitNode: function(node, parent) { + //console.log('visit', node.type) + return this['visit' + node.type](node, parent); }, /** @@ -367,9 +619,11 @@ Compiler.prototype = { */ visitCase: function(node) { - this.buf.push('switch (' + node.expr + '){'); - this.visit(node.block, node); - this.buf.push('}'); + var stmt = t.switchStatement( + node.astExpr || this.parseExpr(node.expr), + this.visit(node.block, node) + ); + return [stmt]; }, /** @@ -380,15 +634,17 @@ Compiler.prototype = { */ visitWhen: function(node) { - if ('default' == node.expr) { - this.buf.push('default:'); - } else { - this.buf.push('case ' + node.expr + ':'); + var test = null; + if ('default' != node.expr) { + test = node.astExpr || this.parseExpr(node.expr); } + var consequent = []; if (node.block) { - this.visit(node.block, node); - this.buf.push(' break;'); + consequent = this.visit(node.block, node); + consequent.push(t.breakStatement()); } + var c = t.switchCase(test, consequent); + return [c]; }, /** @@ -399,7 +655,7 @@ Compiler.prototype = { */ visitLiteral: function(node) { - this.buffer(node.str); + return this.buffer(node.str); }, visitNamedBlock: function(block) { @@ -415,7 +671,7 @@ Compiler.prototype = { visitBlock: function(block) { var escapePrettyMode = this.escapePrettyMode; var pp = this.pp; - + var ast = []; // Pretty print multi-line text if ( pp && @@ -424,10 +680,13 @@ Compiler.prototype = { block.nodes[0].type === 'Text' && block.nodes[1].type === 'Text' ) { - this.prettyIndent(1, true); + push.apply(ast, this.prettyIndent(1, true)); } + //console.log('start block') + const blocks = Array(2 * block.nodes.length); for (var i = 0; i < block.nodes.length; ++i) { // Pretty print text + blocks[2 * i] = []; if ( pp && i > 0 && @@ -436,10 +695,13 @@ Compiler.prototype = { block.nodes[i - 1].type === 'Text' && /\n$/.test(block.nodes[i - 1].val) ) { - this.prettyIndent(1, false); + blocks[2 * i] = this.prettyIndent(1, false); } - this.visit(block.nodes[i], block); + const b = this.visit(block.nodes[i], block); + blocks[2 * i + 1] = b; } + ast = ast.concat.apply(ast, blocks); + return ast; }, /** @@ -450,12 +712,40 @@ Compiler.prototype = { */ visitMixinBlock: function(block) { - if (this.pp) - this.buf.push( - "pug_indent.push('" + Array(this.indents + 1).join(this.pp) + "');" + var ast = []; + if (this.pp) { + ast.push( + t.expressionStatement( + t.callExpression( + t.memberExpression( + t.identifier('pug_indent'), + t.identifier('push') + ), + [t.stringLiteral(Array(this.indents + 1).join(this.pp))] + ) + ) + ); + } + ast.push( + t.expressionStatement( + t.logicalExpression( + '&&', + t.identifier('block'), + this.wrapCallExpression(t.callExpression(t.identifier('block'), [])) + ) + ) + ); + if (this.pp) { + ast.push( + t.expressionStatement( + t.callExpression( + t.memberExpression(t.identifier('pug_indent'), t.identifier('pop')), + [] + ) + ) ); - this.buf.push('block && block();'); - if (this.pp) this.buf.push('pug_indent.pop();'); + } + return ast; }, /** @@ -468,12 +758,14 @@ Compiler.prototype = { */ visitDoctype: function(doctype) { + var ast = []; if (doctype && (doctype.val || !this.doctype)) { this.setDoctype(doctype.val || 'html'); } - if (this.doctype) this.buffer(this.doctype); + if (this.doctype) ast = [this.buffer(this.doctype)]; this.hasCompiledDoctype = true; + return ast; }, /** @@ -485,6 +777,8 @@ Compiler.prototype = { */ visitMixin: function(mixin) { + var ast = []; + var self = this; var name = 'pug_mixins['; var args = mixin.args || ''; var block = mixin.block; @@ -498,33 +792,77 @@ Compiler.prototype = { (dynamic ? mixin.name.substr(2, mixin.name.length - 3) : '"' + mixin.name + '"') + ']'; - + var mixinName = dynamic + ? mixin.astName || + this.parseExpr(mixin.name.substr(2, mixin.name.length - 3)) + : t.stringLiteral(mixin.name); this.mixins[key] = this.mixins[key] || {used: false, instances: []}; + + // mixin invocation if (mixin.call) { this.mixins[key].used = true; - if (pp) - this.buf.push( - "pug_indent.push('" + Array(this.indents + 1).join(pp) + "');" + if (pp) { + ast.push( + t.expressionStatement( + t.callExpression( + t.memberExpression( + t.identifier('pug_indent'), + t.identifier('push') + ), + [t.stringLiteral(Array(this.indents + 1).join(pp))] + ) + ) ); + } if (block || attrs.length || attrsBlocks.length) { - this.buf.push(name + '.call({'); + var astArgs = []; + ast.push( + t.expressionStatement( + this.wrapCallExpression( + t.callExpression( + t.memberExpression( + t.memberExpression( + t.identifier('pug_mixins'), + mixinName, + true + ), + t.identifier('call') + ), + astArgs + ) + ) + ) + ); + + var astObj, astKey; + if (block || attrsBlocks.length || attrs.length) { + astKey = []; + astObj = t.objectExpression(astKey); + astArgs.push(astObj); + } if (block) { - this.buf.push('block: function(){'); + var astFunc = []; // Render block with no indents, dynamically added when rendered this.parentIndents++; var _indents = this.indents; this.indents = 0; - this.visit(mixin.block, mixin); + push.apply(astFunc, this.visit(mixin.block, mixin)); this.indents = _indents; this.parentIndents--; - if (attrs.length || attrsBlocks.length) { - this.buf.push('},'); - } else { - this.buf.push('}'); - } + astKey.push( + t.objectProperty( + t.identifier('block'), + t.functionExpression( + null, + [], + t.blockStatement(astFunc), + this.useGenerators + ) + ) + ); } if (attrsBlocks.length) { @@ -533,32 +871,68 @@ Compiler.prototype = { attrsBlocks.unshift(val); } if (attrsBlocks.length > 1) { - this.buf.push( - 'attributes: ' + - this.runtime('merge') + - '([' + - attrsBlocks.join(',') + - '])' + astKey.push( + t.objectProperty( + t.identifier('attributes'), + t.callExpression( + this.runtime('merge', true), + attrsBlocks.map(function(b) { + return self.parseExpr(b); + }) + ) + ) ); } else { - this.buf.push('attributes: ' + attrsBlocks[0]); + astKey.push( + t.objectProperty( + t.identifier('attributes'), + this.parseExpr(attrsBlocks[0]) + ) + ); } } else if (attrs.length) { var val = this.attrs(attrs); - this.buf.push('attributes: ' + val); + astKey.push( + t.objectProperty(t.identifier('attributes'), this.parseExpr(val)) + ); } if (args) { - this.buf.push('}, ' + args + ');'); - } else { - this.buf.push('});'); + args = args ? args.split(',') : []; + Array.prototype.push.apply( + astArgs, + mixin.astArgs || this.parseArgs(args) + ); } } else { - this.buf.push(name + '(' + args + ');'); + var astArgs = mixin.astArgs || this.parseArgs(args); + ast.push( + t.expressionStatement( + this.wrapCallExpression( + t.callExpression( + t.memberExpression(t.identifier('pug_mixins'), mixinName, true), + astArgs + ) + ) + ) + ); } - if (pp) this.buf.push('pug_indent.pop();'); - } else { - var mixin_start = this.buf.length; + if (pp) { + ast.push( + t.expressionStatement( + t.callExpression( + t.memberExpression( + t.identifier('pug_indent'), + t.identifier('pop') + ), + [] + ) + ) + ); + } + } + // mixin definition + else { args = args ? args.split(',') : []; var rest; if (args.length && /^\.\.\./.test(args[args.length - 1].trim())) { @@ -567,29 +941,104 @@ Compiler.prototype = { .trim() .replace(/^\.\.\./, ''); } + var astArgs = args.map(function(arg) { + return t.identifier(arg.trim()); + }); // we need use pug_interp here for v8: https://code.google.com/p/v8/issues/detail?id=4165 // once fixed, use this: this.buf.push(name + ' = function(' + args.join(',') + '){'); - this.buf.push(name + ' = pug_interp = function(' + args.join(',') + '){'); - this.buf.push( - 'var block = (this && this.block), attributes = (this && this.attributes) || {};' + var astMixin = []; + + astMixin.push( + t.variableDeclaration('var', [ + t.variableDeclarator( + t.identifier('block'), + t.logicalExpression( + '&&', + t.thisExpression(), + t.memberExpression(t.thisExpression(), t.identifier('block')) + ) + ), + t.variableDeclarator( + t.identifier('attributes'), + t.logicalExpression( + '||', + t.logicalExpression( + '&&', + t.thisExpression(), + t.memberExpression( + t.thisExpression(), + t.identifier('attributes') + ) + ), + t.objectExpression([]) + ) + ), + ]) ); + if (rest) { - this.buf.push('var ' + rest + ' = [];'); - this.buf.push( - 'for (pug_interp = ' + - args.length + - '; pug_interp < arguments.length; pug_interp++) {' + astMixin.push( + t.variableDeclaration('var', [ + t.variableDeclarator(t.identifier(rest), t.arrayExpression([])), + ]) + ); + astMixin.push( + t.forStatement( + t.assignmentExpression( + '=', + t.identifier('pug_interp'), + t.numericLiteral(args.length) + ), + t.binaryExpression( + '<', + t.identifier('pug_interp'), + t.memberExpression( + t.identifier('arguments'), + t.identifier('length') + ) + ), + t.updateExpression('++', t.identifier('pug_interp'), false), + t.expressionStatement( + t.callExpression( + t.memberExpression(t.identifier(rest), t.identifier('push')), + [ + t.memberExpression( + t.identifier('arguments'), + t.identifier('pug_interp'), + true + ), + ] + ) + ) + ) ); - this.buf.push(' ' + rest + '.push(arguments[pug_interp]);'); - this.buf.push('}'); } + this.parentIndents++; - this.visit(block, mixin); + push.apply(astMixin, this.visit(block, mixin)); this.parentIndents--; - this.buf.push('};'); - var mixin_end = this.buf.length; - this.mixins[key].instances.push({start: mixin_start, end: mixin_end}); + + var mixinStmt = t.expressionStatement( + t.assignmentExpression( + '=', + t.memberExpression(t.identifier('pug_mixins'), mixinName, true), + t.assignmentExpression( + '=', + t.identifier('pug_interp'), + t.functionExpression( + null, + astArgs, + t.blockStatement(astMixin), + this.useGenerators + ) + ) + ) + ); + ast.push(mixinStmt); + + this.mixins[key].instances.push({stmt: mixinStmt}); } + return ast; }, /** @@ -601,15 +1050,18 @@ Compiler.prototype = { * @api public */ - visitTag: function(tag, interpolated) { + visitTag: function(tag, parent, interpolated) { this.indents++; var name = tag.name, pp = this.pp, self = this; + var ast = []; function bufferName() { - if (interpolated) self.bufferExpression(tag.expr); - else self.buffer(name); + if (interpolated) { + if (tag.astExpr) return self.bufferAST(tag.astExpr); + return self.bufferExpression(tag.expr); + } else return self.buffer(name); } if (WHITE_SPACE_SENSITIVE_TAGS[tag.name] === true) @@ -617,25 +1069,23 @@ Compiler.prototype = { if (!this.hasCompiledTag) { if (!this.hasCompiledDoctype && 'html' == name) { - this.visitDoctype(); + push.apply(ast, this.visitDoctype()); } this.hasCompiledTag = true; } - // pretty print - if (pp && !tag.isInline) this.prettyIndent(0, true); + if (pp && !tag.isInline) push.apply(ast, this.prettyIndent(0, true)); if (tag.selfClosing || (!this.xml && selfClosing[tag.name])) { - this.buffer('<'); - bufferName(); - this.visitAttributes( - tag.attrs, - this.attributeBlocks(tag.attributeBlocks) - ); - if (this.terse && !tag.selfClosing) { - this.buffer('>'); - } else { - this.buffer('/>'); - } + ast = concat.apply(ast, [ + this.buffer('<'), + bufferName(), + this.visitAttributes( + tag.attrs, + this.attributeBlocks(tag.attributeBlocks) + ), + this.buffer(this.terse && !tag.selfClosing ? '>' : '/>'), + ]); + // if it is non-empty throw an error if ( tag.code || @@ -656,36 +1106,46 @@ Compiler.prototype = { } } else { // Optimize attributes buffering - this.buffer('<'); - bufferName(); - this.visitAttributes( - tag.attrs, - this.attributeBlocks(tag.attributeBlocks) - ); - this.buffer('>'); - if (tag.code) this.visitCode(tag.code); - this.visit(tag.block, tag); - - // pretty print - if ( + ast = concat.apply(ast, [ + this.buffer('<'), + bufferName(), + this.visitAttributes( + tag.attrs, + this.attributeBlocks(tag.attributeBlocks) + ), + this.buffer('>'), + tag.code ? this.visitCode(tag.code) : [], + this.visit(tag.block, tag), pp && !tag.isInline && WHITE_SPACE_SENSITIVE_TAGS[tag.name] !== true && !tagCanInline(tag) - ) - this.prettyIndent(0, true); - - this.buffer(''); + ? this.prettyIndent(0, true) + : [], + this.buffer(''), + ]); } if (WHITE_SPACE_SENSITIVE_TAGS[tag.name] === true) this.escapePrettyMode = false; this.indents--; + return ast; }, + /** + * Compile attribute blocks. + */ + attributeBlocks: function(attributeBlocks) { + return ( + attributeBlocks && + attributeBlocks.slice().map(function(attrBlock) { + return attrBlock.val; + }) + ); + }, /** * Visit InterpolatedTag. * @@ -693,8 +1153,8 @@ Compiler.prototype = { * @api public */ - visitInterpolatedTag: function(tag) { - return this.visitTag(tag, true); + visitInterpolatedTag: function(tag, parent) { + return this.visitTag(tag, parent, true); }, /** @@ -705,7 +1165,7 @@ Compiler.prototype = { */ visitText: function(text) { - this.buffer(text.val); + return this.buffer(text.val); }, /** @@ -717,8 +1177,13 @@ Compiler.prototype = { visitComment: function(comment) { if (!comment.buffer) return; - if (this.pp) this.prettyIndent(1, true); - this.buffer(''); + return concat.apply( + [], + [ + this.pp ? this.prettyIndent(1, true) : [], + this.buffer(''), + ] + ); }, /** @@ -730,7 +1195,9 @@ Compiler.prototype = { * @api public */ - visitYieldBlock: function(block) {}, + visitYieldBlock: function(block) { + return []; + }, /** * Visit a `BlockComment`. @@ -740,12 +1207,16 @@ Compiler.prototype = { */ visitBlockComment: function(comment) { + var ast = []; if (!comment.buffer) return; - if (this.pp) this.prettyIndent(1, true); - this.buffer(''); + ast = ast.concat.apply(ast, [ + this.pp ? this.prettyIndent(1, true) : [], + this.buffer(''), + ]); + return ast; }, /** @@ -757,28 +1228,84 @@ Compiler.prototype = { * @api public */ - visitCode: function(code) { + visitCode: function(code, ctx) { // Wrap code blocks with {}. // we only wrap unbuffered code blocks ATM // since they are usually flow control - // Buffer code + // + var ast = []; if (code.buffer) { var val = code.val.trim(); - val = 'null == (pug_interp = ' + val + ') ? "" : pug_interp'; - if (code.mustEscape !== false) - val = this.runtime('escape') + '(' + val + ')'; - this.bufferExpression(val); + if (code.mustEscape !== false) { + ast = JSON.parse(tpl_json_interp_escape).expression; + ast.callee = this.runtime('escape', true); + ast.arguments[0].test.right.right = + code.astVal || this.parseExpr(code.val); + } else { + ast = JSON.parse(tpl_json_interp).expression; + ast.test.right.right = code.astVal || this.parseExpr(code.val); + } + ast = [this.bufferAST(ast)]; } else { - this.buf.push(code.val); - } + var val = code.val.trim(); + this.codeBuffer += '\n' + val; + + if (code.block) { + this.codeIndex++; + var marker = 'PUGMARKER' + this.codeIndex; + this.codeBuffer += '\n{' + marker + '}\n'; + // snaphsot current unbuffered code level + // this is necessary to accept embedded code blocks + // - if (true) { + // - var a = 1; + // - } + // but breaks the "should be reasonably fast" compile test + // note: we should add a test for this in pug + var savedCodeBuffer = this.codeBuffer; + var savedCodeMarker = this.codeMarker; + var savedCodeIndex = this.codeIndex; + + this.codeBuffer = 'plug=function*(){'; + this.codeMarker = {}; + this.codeIndex = -1; + + var body = this.visit(code.block, code); + + this.codeBuffer = savedCodeBuffer; + this.codeMarker = savedCodeMarker; + this.codeIndex = savedCodeIndex; + + this.codeMarker[marker] = body; + } - // Block support - if (code.block) { - if (!code.buffer) this.buf.push('{'); - this.visit(code.block, code); - if (!code.buffer) this.buf.push('}'); + var idx = ctx.nodes.indexOf(code) + 1; + if ( + idx == ctx.nodes.length || + ctx.nodes[idx].type != 'Code' || + ctx.nodes[idx].buffer + ) { + try { + var src = this.codeBuffer + '}'; + var tpl = babelTemplate(src); + push.apply(ast, tpl(this.codeMarker).expression.right.body.body); + this.codeBuffer = 'plug=function*(){'; + this.codeIndex = -1; + this.codeMarker = {}; + } catch (e) { + var codeError = this.codeBuffer.substr(14).trim(); + this.error( + 'Unbuffered code structure could not be parsed; ' + + e.message + + ' in ' + + codeError, + codeError, + code + ); + } + } } + return ast; }, /** @@ -790,19 +1317,22 @@ Compiler.prototype = { visitConditional: function(cond) { var test = cond.test; - this.buf.push('if (' + test + ') {'); - this.visit(cond.consequent, cond); - this.buf.push('}'); + + var blockConsequent = this.visit(cond.consequent, cond); + var c = t.ifStatement( + cond.astTest || this.parseExpr(test), + t.blockStatement(blockConsequent) + ); + if (cond.alternate) { if (cond.alternate.type === 'Conditional') { - this.buf.push('else'); - this.visitConditional(cond.alternate); + c.alternate = this.visitConditional(cond.alternate)[0]; } else { - this.buf.push('else {'); - this.visit(cond.alternate, cond); - this.buf.push('}'); + var blockAlternate = this.visit(cond.alternate, cond); + c.alternate = t.blockStatement(blockAlternate); } } + return [c]; }, /** @@ -814,9 +1344,12 @@ Compiler.prototype = { visitWhile: function(loop) { var test = loop.test; - this.buf.push('while (' + test + ') {'); - this.visit(loop.block, loop); - this.buf.push('}'); + var whileBlock = this.visit(loop.block, loop); + var w = t.whileStatement( + loop.astTest || this.parseExpr(test), + t.blockStatement(whileBlock) + ); + return [w]; }, /** @@ -827,93 +1360,148 @@ Compiler.prototype = { */ visitEach: function(each) { + var ast = []; var indexVarName = each.key || 'pug_index' + this.eachCount; this.eachCount++; - this.buf.push( - '' + - '// iterate ' + - each.obj + - '\n' + - ';(function(){\n' + - ' var $$obj = ' + - each.obj + - ';\n' + - " if ('number' == typeof $$obj.length) {" + var body = [ + t.variableDeclaration('var', [ + t.variableDeclarator( + t.identifier('$$obj'), + each.astObj || this.parseExpr(each.obj) + ), + ]), + ]; + + var func = t.expressionStatement( + this.wrapCallExpression( + t.callExpression( + t.memberExpression( + t.functionExpression( + null, + [], + t.blockStatement(body), + this.useGenerators + ), + t.identifier('call') + ), + [t.thisExpression()] + ) + ) ); + ast.push(func); + + var blockEach = [ + t.variableDeclaration('var', [ + t.variableDeclarator( + t.identifier(each.val), + t.memberExpression( + t.identifier('$$obj'), + t.identifier(indexVarName), + true + ) + ), + ]), + ]; + var blockAlt = []; + + push.apply(blockEach, this.visit(each.block, each)); + var arrayLoop = t.blockStatement([ + t.forStatement( + t.variableDeclaration('var', [ + t.variableDeclarator(t.identifier(indexVarName), t.numericLiteral(0)), + t.variableDeclarator( + t.identifier('$$l'), + t.memberExpression(t.identifier('$$obj'), t.identifier('length')) + ), + ]), + t.binaryExpression( + '<', + t.identifier(indexVarName), + t.identifier('$$l') + ), + t.updateExpression('++', t.identifier(indexVarName), false), + t.blockStatement(blockEach) + ), + ]); + + var blockObj = [ + t.expressionStatement( + t.updateExpression('++', t.identifier('$$l'), false) + ), + t.variableDeclaration('var', [ + t.variableDeclarator( + t.identifier(each.val), + t.memberExpression( + t.identifier('$$obj'), + t.identifier(indexVarName), + true + ) + ), + ]), + ]; + var blockObjAlt = []; + + push.apply(blockObj, this.visit(each.block, each)); + var objectLoop = t.blockStatement([ + t.variableDeclaration('var', [ + t.variableDeclarator(t.identifier('$$l'), t.numericLiteral(0)), + ]), + t.forInStatement( + t.variableDeclaration('var', [ + t.variableDeclarator(t.identifier(indexVarName)), + ]), + t.identifier('$$obj'), + t.blockStatement(blockObj) + ), + ]); if (each.alternate) { - this.buf.push(' if ($$obj.length) {'); + push.apply(blockAlt, this.visit(each.alternate, each)); + arrayLoop = t.ifStatement( + t.memberExpression(t.identifier('$$obj'), t.identifier('length')), + arrayLoop, + t.blockStatement(blockAlt) + ); } - this.buf.push( - '' + - ' for (var ' + - indexVarName + - ' = 0, $$l = $$obj.length; ' + - indexVarName + - ' < $$l; ' + - indexVarName + - '++) {\n' + - ' var ' + - each.val + - ' = $$obj[' + - indexVarName + - '];' - ); - - this.visit(each.block, each); - - this.buf.push(' }'); - if (each.alternate) { - this.buf.push(' } else {'); - this.visit(each.alternate, each); - this.buf.push(' }'); + push.apply(blockObjAlt, this.visit(each.alternate, each)); + objectLoop.body.push( + t.ifStatement( + t.binaryExpression('===', t.identifier('$$l'), t.numericLiteral(0)), + t.blockStatement(blockObjAlt) + ) + ); } - this.buf.push( - '' + - ' } else {\n' + - ' var $$l = 0;\n' + - ' for (var ' + - indexVarName + - ' in $$obj) {\n' + - ' $$l++;\n' + - ' var ' + - each.val + - ' = $$obj[' + - indexVarName + - '];' + var it = t.ifStatement( + t.binaryExpression( + '==', + t.stringLiteral('number'), + t.unaryExpression( + 'typeof', + t.memberExpression(t.identifier('$$obj'), t.identifier('length')) + ) + ), + arrayLoop, + objectLoop ); + body.push(it); - this.visit(each.block, each); - - this.buf.push(' }'); - if (each.alternate) { - this.buf.push(' if ($$l === 0) {'); - this.visit(each.alternate, each); - this.buf.push(' }'); - } - this.buf.push(' }\n}).call(this);\n'); + return ast; }, visitEachOf: function(each) { - this.buf.push( - '' + - '// iterate ' + - each.obj + - '\n' + - 'for (const ' + - each.val + - ' of ' + - each.obj + - ') {\n' + const forOfBlock = this.visit(each.block, each); + const forOf = t.forOfStatement( + t.variableDeclaration('var', [ + t.variableDeclarator(t.identifier(each.val)), + ]), + t.identifier(each.obj), + t.blockStatement(forOfBlock) ); - - this.visit(each.block, each); - - this.buf.push('}\n'); + return forOf; }, /** @@ -924,13 +1512,14 @@ Compiler.prototype = { */ visitAttributes: function(attrs, attributeBlocks) { + let ast = []; if (attributeBlocks.length) { if (attrs.length) { var val = this.attrs(attrs); attributeBlocks.unshift(val); } if (attributeBlocks.length > 1) { - this.bufferExpression( + ast = this.bufferExpression( this.runtime('attrs') + '(' + this.runtime('merge') + @@ -941,7 +1530,7 @@ Compiler.prototype = { ')' ); } else { - this.bufferExpression( + ast = this.bufferExpression( this.runtime('attrs') + '(' + attributeBlocks[0] + @@ -951,8 +1540,9 @@ Compiler.prototype = { ); } } else if (attrs.length) { - this.attrs(attrs, true); + ast = this.bufferExpression(this.attrs(attrs, true)); } + return ast; }, /** @@ -965,24 +1555,8 @@ Compiler.prototype = { format: buffer ? 'html' : 'object', runtime: this.runtime.bind(this), }); - if (buffer) { - this.bufferExpression(res); - } return res; }, - - /** - * Compile attribute blocks. - */ - - attributeBlocks: function(attributeBlocks) { - return ( - attributeBlocks && - attributeBlocks.slice().map(function(attrBlock) { - return attrBlock.val; - }) - ); - }, }; function tagCanInline(tag) { diff --git a/packages/pug-code-gen/package.json b/packages/pug-code-gen/package.json index e0f3d9991..0ef4e8066 100644 --- a/packages/pug-code-gen/package.json +++ b/packages/pug-code-gen/package.json @@ -6,6 +6,11 @@ "pug" ], "dependencies": { + "@babel/core": "^7.10.2", + "@babel/generator": "^7.10.2", + "@babel/template": "^7.10.1", + "@babel/types": "^7.10.2", + "@babel/parser": "^7.10.2", "constantinople": "^4.0.1", "doctypes": "^1.1.0", "js-stringify": "^1.0.2", @@ -13,7 +18,7 @@ "pug-error": "^1.3.3", "pug-runtime": "^2.0.5", "void-elements": "^3.1.0", - "with": "^7.0.0" + "with": "^7.0.2" }, "files": [ "index.js" diff --git a/packages/pug-lexer/index.js b/packages/pug-lexer/index.js index 07afac50e..fda17706c 100644 --- a/packages/pug-lexer/index.js +++ b/packages/pug-lexer/index.js @@ -1,7 +1,7 @@ 'use strict'; var assert = require('assert'); -var isExpression = require('is-expression'); +var babylon = require('@babel/parser'); var characterParser = require('character-parser'); var error = require('pug-error'); @@ -72,21 +72,17 @@ Lexer.prototype = { if (!value) this.error('ASSERT_FAILED', message); }, - isExpression: function(exp) { - return isExpression(exp, { - throw: true, - }); + parseExpression: function(exp) { + return babylon.parseExpression(exp); }, assertExpression: function(exp, noThrow) { //this verifies that a JavaScript expression is valid try { - this.callLexerFunction('isExpression', exp); - return true; + return this.callLexerFunction('parseExpression', exp); } catch (ex) { if (noThrow) return false; - // not coming from acorn if (!ex.loc) throw ex; this.incrementLine(ex.loc.line - 1); @@ -118,7 +114,7 @@ Lexer.prototype = { * @api private */ - tok: function(type, val) { + tok: function(type, val, ast) { var res = { type: type, loc: { @@ -131,6 +127,7 @@ Lexer.prototype = { }; if (val !== undefined) res.val = val; + if (ast !== undefined) res.ast = ast; return res; }, @@ -367,13 +364,14 @@ Lexer.prototype = { */ interpolation: function() { + var ast; if (/^#\{/.test(this.input)) { var match = this.bracketExpression(1); this.consume(match.end + 1); - var tok = this.tok('interpolation', match.src); + ast = this.assertExpression(match.src); + var tok = this.tok('interpolation', match.src, ast); this.tokens.push(tok); this.incrementColumn(2); // '#{' - this.assertExpression(match.src); var splitted = match.src.split('\n'); var lines = splitted.length - 1; @@ -619,7 +617,7 @@ Lexer.prototype = { tok.mustEscape = matchOfStringInterp[2] === '#'; tok.buffer = true; tok.val = range.src; - this.assertExpression(range.src); + tok.ast = this.assertExpression(range.src); if (range.end + 1 < rest.length) { rest = rest.substr(range.end + 1); @@ -851,7 +849,7 @@ Lexer.prototype = { var tok = this.scanEndOfLine(/^case +([^\n]+)/, 'case'); if (tok) { this.incrementColumn(-tok.val.length); - this.assertExpression(tok.val); + tok.ast = this.assertExpression(tok.val); this.incrementColumn(tok.val.length); this.tokens.push(this.tokEnd(tok)); return true; @@ -880,7 +878,7 @@ Lexer.prototype = { } this.incrementColumn(-tok.val.length); - this.assertExpression(tok.val); + tok.ast = this.assertExpression(tok.val); this.incrementColumn(tok.val.length); this.tokens.push(this.tokEnd(tok)); return true; @@ -913,7 +911,7 @@ Lexer.prototype = { */ call: function() { - var tok, captures, increment; + var tok, ast, captures, increment; if ((captures = /^\+(\s*)(([-\w]+)|(#\{))/.exec(this.input))) { // try to consume simple or interpolated call if (captures[3]) { @@ -926,8 +924,8 @@ Lexer.prototype = { var match = this.bracketExpression(2 + captures[1].length); increment = match.end + 1; this.consume(increment); - this.assertExpression(match.src); - tok = this.tok('call', '#{' + match.src + '}'); + ast = this.assertExpression(match.src); + tok = this.tok('call', '#{' + match.src + '}', ast); } this.incrementColumn(increment); @@ -941,7 +939,7 @@ Lexer.prototype = { this.incrementColumn(1); this.consume(range.end + 1); tok.args = range.src; - this.assertExpression('[' + tok.args + ']'); + tok.ast_args = this.assertExpression('[' + tok.args + ']').elements; for (var i = 0; i <= tok.args.length; i++) { if (tok.args[i] === '\n') { this.incrementLine(1); @@ -989,11 +987,11 @@ Lexer.prototype = { switch (type) { case 'if': case 'else-if': - this.assertExpression(js); + tok.ast = this.assertExpression(js); break; case 'unless': - this.assertExpression(js); tok.val = '!(' + js + ')'; + tok.ast = this.assertExpression(tok.val); tok.type = 'if'; break; case 'else': @@ -1016,11 +1014,11 @@ Lexer.prototype = { */ while: function() { - var captures, tok; + var captures, ast, tok; if ((captures = /^while +([^\n]+)/.exec(this.input))) { this.consume(captures[0].length); - this.assertExpression(captures[1]); - tok = this.tok('while', captures[1]); + ast = this.assertExpression(captures[1]); + tok = this.tok('while', captures[1], ast); this.incrementColumn(captures[0].length); this.tokens.push(this.tokEnd(tok)); return true; @@ -1045,7 +1043,7 @@ Lexer.prototype = { var tok = this.tok('each', captures[1]); tok.key = captures[2] || null; this.incrementColumn(captures[0].length - captures[3].length); - this.assertExpression(captures[3]); + tok.ast = this.assertExpression(captures[3]); tok.code = captures[3]; this.incrementColumn(captures[3].length); this.tokens.push(this.tokEnd(tok)); @@ -1172,7 +1170,7 @@ Lexer.prototype = { // ---- captures[0] - captures[2] // ^ after colno this.incrementColumn(captures[0].length - captures[2].length); - if (tok.buffer) this.assertExpression(code); + if (tok.buffer) tok.ast = this.assertExpression(code); this.tokens.push(tok); // p #[!= abc] hey @@ -1271,6 +1269,7 @@ Lexer.prototype = { if (valueResponse.val) { tok.val = valueResponse.val; + tok.ast = valueResponse.ast; tok.mustEscape = valueResponse.mustEscape; } else { // was a boolean attribute (ex: `input(disabled)`) @@ -1312,6 +1311,7 @@ Lexer.prototype = { var state = characterParser.defaultState(); var col = this.colno; var line = this.lineno; + var ast; // consume all whitespace before the equals sign for (i = 0; i < str.length; i++) { @@ -1420,12 +1420,17 @@ Lexer.prototype = { } } - this.assertExpression(val); + ast = this.assertExpression(val); this.lineno = line; this.colno = col; - return {val: val, mustEscape: escapeAttr, remainingSource: str.substr(i)}; + return { + val: val, + ast: ast, + mustEscape: escapeAttr, + remainingSource: str.substr(i), + }; }, /** diff --git a/packages/pug-lexer/package.json b/packages/pug-lexer/package.json index 42b120792..5029d0643 100644 --- a/packages/pug-lexer/package.json +++ b/packages/pug-lexer/package.json @@ -6,13 +6,11 @@ "pug" ], "dependencies": { + "@babel/parser": "^7.10.2", "character-parser": "^2.2.0", - "is-expression": "^4.0.0", "pug-error": "^1.3.3" }, "devDependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" }, "files": [ "index.js", diff --git a/packages/pug-lexer/test/__snapshots__/index.test.js.snap b/packages/pug-lexer/test/__snapshots__/index.test.js.snap index caea3836a..0fb474613 100644 --- a/packages/pug-lexer/test/__snapshots__/index.test.js.snap +++ b/packages/pug-lexer/test/__snapshots__/index.test.js.snap @@ -78,6 +78,84 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 66, + "errors": Array [], + "expressions": Array [ + Object { + "end": 63, + "loc": Object { + "end": Object { + "column": 63, + "line": 1, + }, + "identifierName": "avatar", + "start": Object { + "column": 57, + "line": 1, + }, + }, + "name": "avatar", + "start": 57, + "type": "Identifier", + }, + ], + "loc": Object { + "end": Object { + "column": 66, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "quasis": Array [ + Object { + "end": 55, + "loc": Object { + "end": Object { + "column": 55, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "start": 1, + "tail": false, + "type": "TemplateElement", + "value": Object { + "cooked": "background-image: url(https://www.gravatar.com/avatar/", + "raw": "background-image: url(https://www.gravatar.com/avatar/", + }, + }, + Object { + "end": 65, + "loc": Object { + "end": Object { + "column": 65, + "line": 1, + }, + "start": Object { + "column": 64, + "line": 1, + }, + }, + "start": 64, + "tail": true, + "type": "TemplateElement", + "value": Object { + "cooked": ")", + "raw": ")", + }, + }, + ], + "start": 0, + "type": "TemplateLiteral", + }, "loc": Object { "end": Object { "column": 88, @@ -245,6 +323,61 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 13, + "errors": Array [], + "left": Object { + "end": 8, + "extra": Object { + "raw": "'/user/'", + "rawValue": "/user/", + }, + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "/user/", + }, + "loc": Object { + "end": Object { + "column": 13, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "operator": "+", + "right": Object { + "end": 13, + "loc": Object { + "end": Object { + "column": 13, + "line": 1, + }, + "identifierName": "id", + "start": Object { + "column": 11, + "line": 1, + }, + }, + "name": "id", + "start": 11, + "type": "Identifier", + }, + "start": 0, + "type": "BinaryExpression", + }, "loc": Object { "end": Object { "column": 21, @@ -262,6 +395,28 @@ Array [ "val": "'/user/' + id", }, Object { + "ast": Object { + "comments": Array [], + "end": 8, + "errors": Array [], + "extra": Object { + "raw": "'button'", + "rawValue": "button", + }, + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "button", + }, "loc": Object { "end": Object { "column": 37, @@ -336,6 +491,61 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 13, + "errors": Array [], + "left": Object { + "end": 8, + "extra": Object { + "raw": "'/user/'", + "rawValue": "/user/", + }, + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "/user/", + }, + "loc": Object { + "end": Object { + "column": 13, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "operator": "+", + "right": Object { + "end": 13, + "loc": Object { + "end": Object { + "column": 13, + "line": 1, + }, + "identifierName": "id", + "start": Object { + "column": 11, + "line": 1, + }, + }, + "name": "id", + "start": 11, + "type": "Identifier", + }, + "start": 0, + "type": "BinaryExpression", + }, "loc": Object { "end": Object { "column": 25, @@ -353,6 +563,28 @@ Array [ "val": "'/user/' + id", }, Object { + "ast": Object { + "comments": Array [], + "end": 8, + "errors": Array [], + "extra": Object { + "raw": "'button'", + "rawValue": "button", + }, + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "button", + }, "loc": Object { "end": Object { "column": 45, @@ -427,6 +659,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 8, + "errors": Array [], + "extra": Object { + "raw": "'answer'", + "rawValue": "answer", + }, + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "answer", + }, "loc": Object { "end": Object { "column": 18, @@ -444,6 +698,41 @@ Array [ "val": "'answer'", }, Object { + "ast": Object { + "arguments": Array [], + "callee": Object { + "end": 6, + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "identifierName": "answer", + "start": Object { + "column": 0, + "line": 1, + }, + }, + "name": "answer", + "start": 0, + "type": "Identifier", + }, + "comments": Array [], + "end": 8, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "CallExpression", + }, "loc": Object { "end": Object { "column": 34, @@ -518,6 +807,65 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "elements": Array [ + Object { + "end": 9, + "extra": Object { + "raw": "'class1'", + "rawValue": "class1", + }, + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "start": 1, + "type": "StringLiteral", + "value": "class1", + }, + Object { + "end": 19, + "extra": Object { + "raw": "'class2'", + "rawValue": "class2", + }, + "loc": Object { + "end": Object { + "column": 19, + "line": 1, + }, + "start": Object { + "column": 11, + "line": 1, + }, + }, + "start": 11, + "type": "StringLiteral", + "value": "class2", + }, + ], + "end": 20, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 20, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "ArrayExpression", + }, "loc": Object { "end": Object { "column": 31, @@ -607,6 +955,65 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "elements": Array [ + Object { + "end": 9, + "extra": Object { + "raw": "'class1'", + "rawValue": "class1", + }, + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "start": 1, + "type": "StringLiteral", + "value": "class1", + }, + Object { + "end": 19, + "extra": Object { + "raw": "'class2'", + "rawValue": "class2", + }, + "loc": Object { + "end": Object { + "column": 19, + "line": 1, + }, + "start": Object { + "column": 11, + "line": 1, + }, + }, + "start": 11, + "type": "StringLiteral", + "value": "class2", + }, + ], + "end": 20, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 20, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "ArrayExpression", + }, "loc": Object { "end": Object { "column": 41, @@ -681,6 +1088,61 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 13, + "errors": Array [], + "left": Object { + "end": 8, + "extra": Object { + "raw": "'/user/'", + "rawValue": "/user/", + }, + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "/user/", + }, + "loc": Object { + "end": Object { + "column": 13, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "operator": "+", + "right": Object { + "end": 13, + "loc": Object { + "end": Object { + "column": 13, + "line": 1, + }, + "identifierName": "id", + "start": Object { + "column": 11, + "line": 1, + }, + }, + "name": "id", + "start": 11, + "type": "Identifier", + }, + "start": 0, + "type": "BinaryExpression", + }, "loc": Object { "end": Object { "column": 21, @@ -698,6 +1160,28 @@ Array [ "val": "'/user/' + id", }, Object { + "ast": Object { + "comments": Array [], + "end": 8, + "errors": Array [], + "extra": Object { + "raw": "'button'", + "rawValue": "button", + }, + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "button", + }, "loc": Object { "end": Object { "column": 36, @@ -772,6 +1256,61 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 13, + "errors": Array [], + "left": Object { + "end": 8, + "extra": Object { + "raw": "'/user/'", + "rawValue": "/user/", + }, + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "/user/", + }, + "loc": Object { + "end": Object { + "column": 13, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "operator": "+", + "right": Object { + "end": 13, + "loc": Object { + "end": Object { + "column": 13, + "line": 1, + }, + "identifierName": "id", + "start": Object { + "column": 11, + "line": 1, + }, + }, + "name": "id", + "start": 11, + "type": "Identifier", + }, + "start": 0, + "type": "BinaryExpression", + }, "loc": Object { "end": Object { "column": 25, @@ -789,6 +1328,28 @@ Array [ "val": "'/user/' + id", }, Object { + "ast": Object { + "comments": Array [], + "end": 8, + "errors": Array [], + "extra": Object { + "raw": "'button'", + "rawValue": "button", + }, + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "button", + }, "loc": Object { "end": Object { "column": 44, @@ -863,6 +1424,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 8, + "errors": Array [], + "extra": Object { + "raw": "'answer'", + "rawValue": "answer", + }, + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "answer", + }, "loc": Object { "end": Object { "column": 18, @@ -880,6 +1463,41 @@ Array [ "val": "'answer'", }, Object { + "ast": Object { + "arguments": Array [], + "callee": Object { + "end": 6, + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "identifierName": "answer", + "start": Object { + "column": 0, + "line": 1, + }, + }, + "name": "answer", + "start": 0, + "type": "Identifier", + }, + "comments": Array [], + "end": 8, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "CallExpression", + }, "loc": Object { "end": Object { "column": 33, @@ -954,6 +1572,65 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "elements": Array [ + Object { + "end": 9, + "extra": Object { + "raw": "'class1'", + "rawValue": "class1", + }, + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "start": 1, + "type": "StringLiteral", + "value": "class1", + }, + Object { + "end": 19, + "extra": Object { + "raw": "'class2'", + "rawValue": "class2", + }, + "loc": Object { + "end": Object { + "column": 19, + "line": 1, + }, + "start": Object { + "column": 11, + "line": 1, + }, + }, + "start": 11, + "type": "StringLiteral", + "value": "class2", + }, + ], + "end": 20, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 20, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "ArrayExpression", + }, "loc": Object { "end": Object { "column": 31, @@ -1043,6 +1720,65 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "elements": Array [ + Object { + "end": 9, + "extra": Object { + "raw": "'class1'", + "rawValue": "class1", + }, + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "start": 1, + "type": "StringLiteral", + "value": "class1", + }, + Object { + "end": 19, + "extra": Object { + "raw": "'class2'", + "rawValue": "class2", + }, + "loc": Object { + "end": Object { + "column": 19, + "line": 1, + }, + "start": Object { + "column": 11, + "line": 1, + }, + }, + "start": 11, + "type": "StringLiteral", + "value": "class2", + }, + ], + "end": 20, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 20, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "ArrayExpression", + }, "loc": Object { "end": Object { "column": 41, @@ -1117,6 +1853,25 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 2, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 2, + "line": 1, + }, + "identifierName": "id", + "start": Object { + "column": 0, + "line": 1, + }, + }, + "name": "id", + "start": 0, + "type": "Identifier", + }, "loc": Object { "end": Object { "column": 10, @@ -1237,6 +1992,23 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 4, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 4, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "NullLiteral", + }, "loc": Object { "end": Object { "column": 13, @@ -1254,6 +2026,25 @@ Array [ "val": "null", }, Object { + "ast": Object { + "comments": Array [], + "end": 3, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 3, + "line": 1, + }, + "identifierName": "bar", + "start": Object { + "column": 0, + "line": 1, + }, + }, + "name": "bar", + "start": 0, + "type": "Identifier", + }, "loc": Object { "end": Object { "column": 21, @@ -1434,6 +2225,28 @@ Array [ "val": true, }, Object { + "ast": Object { + "comments": Array [], + "end": 7, + "errors": Array [], + "extra": Object { + "raw": "\\"after\\"", + "rawValue": "after", + }, + "loc": Object { + "end": Object { + "column": 7, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "after", + }, "loc": Object { "end": Object { "column": 28, @@ -1508,6 +2321,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 8, + "errors": Array [], + "extra": Object { + "raw": "\\"before\\"", + "rawValue": "before", + }, + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "before", + }, "loc": Object { "end": Object { "column": 20, @@ -1599,6 +2434,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 8, + "errors": Array [], + "extra": Object { + "raw": "\\"before\\"", + "rawValue": "before", + }, + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "before", + }, "loc": Object { "end": Object { "column": 20, @@ -1633,6 +2490,28 @@ Array [ "val": true, }, Object { + "ast": Object { + "comments": Array [], + "end": 7, + "errors": Array [], + "extra": Object { + "raw": "\\"after\\"", + "rawValue": "after", + }, + "loc": Object { + "end": Object { + "column": 7, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "after", + }, "loc": Object { "end": Object { "column": 44, @@ -1726,6 +2605,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 10, + "errors": Array [], + "extra": Object { + "raw": "'/contact'", + "rawValue": "/contact", + }, + "loc": Object { + "end": Object { + "column": 10, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "/contact", + }, "loc": Object { "end": Object { "column": 18, @@ -1815,6 +2716,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 7, + "errors": Array [], + "extra": Object { + "raw": "'/save'", + "rawValue": "/save", + }, + "loc": Object { + "end": Object { + "column": 7, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "/save", + }, "loc": Object { "end": Object { "column": 15, @@ -2027,6 +2950,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 15, + "errors": Array [], + "extra": Object { + "raw": "'foo, bar, baz'", + "rawValue": "foo, bar, baz", + }, + "loc": Object { + "end": Object { + "column": 15, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "foo, bar, baz", + }, "loc": Object { "end": Object { "column": 22, @@ -2044,6 +2989,28 @@ Array [ "val": "'foo, bar, baz'", }, Object { + "ast": Object { + "comments": Array [], + "end": 1, + "errors": Array [], + "extra": Object { + "raw": "1", + "rawValue": 1, + }, + "loc": Object { + "end": Object { + "column": 1, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "NumericLiteral", + "value": 1, + }, "loc": Object { "end": Object { "column": 29, @@ -2118,6 +3085,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 9, + "errors": Array [], + "extra": Object { + "raw": "'((foo))'", + "rawValue": "((foo))", + }, + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "((foo))", + }, "loc": Object { "end": Object { "column": 16, @@ -2135,6 +3124,85 @@ Array [ "val": "'((foo))'", }, Object { + "ast": Object { + "alternate": Object { + "end": 11, + "extra": Object { + "raw": "0", + "rawValue": 0, + }, + "loc": Object { + "end": Object { + "column": 11, + "line": 1, + }, + "start": Object { + "column": 10, + "line": 1, + }, + }, + "start": 10, + "type": "NumericLiteral", + "value": 0, + }, + "comments": Array [], + "consequent": Object { + "end": 7, + "extra": Object { + "raw": "1", + "rawValue": 1, + }, + "loc": Object { + "end": Object { + "column": 7, + "line": 1, + }, + "start": Object { + "column": 6, + "line": 1, + }, + }, + "start": 6, + "type": "NumericLiteral", + "value": 1, + }, + "end": 11, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 11, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "test": Object { + "end": 2, + "extra": Object { + "parenStart": 0, + "parenthesized": true, + "raw": "1", + "rawValue": 1, + }, + "loc": Object { + "end": Object { + "column": 2, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "start": 1, + "type": "NumericLiteral", + "value": 1, + }, + "type": "ConditionalExpression", + }, "loc": Object { "end": Object { "column": 34, @@ -2239,6 +3307,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 5, + "errors": Array [], + "extra": Object { + "raw": "'foo'", + "rawValue": "foo", + }, + "loc": Object { + "end": Object { + "column": 5, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "foo", + }, "loc": Object { "end": Object { "column": 21, @@ -2362,6 +3452,28 @@ Array [ "val": true, }, Object { + "ast": Object { + "comments": Array [], + "end": 5, + "errors": Array [], + "extra": Object { + "raw": "'bar'", + "rawValue": "bar", + }, + "loc": Object { + "end": Object { + "column": 5, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "bar", + }, "loc": Object { "end": Object { "column": 31, @@ -2451,6 +3563,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 8, + "errors": Array [], + "extra": Object { + "raw": "\\"class:\\"", + "rawValue": "class:", + }, + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "class:", + }, "loc": Object { "end": Object { "column": 15, @@ -2525,6 +3659,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 6, + "errors": Array [], + "extra": Object { + "raw": "'\\\\\\\\S+'", + "rawValue": "\\\\S+", + }, + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "\\\\S+", + }, "loc": Object { "end": Object { "column": 21, @@ -2599,6 +3755,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 10, + "errors": Array [], + "extra": Object { + "raw": "'/contact'", + "rawValue": "/contact", + }, + "loc": Object { + "end": Object { + "column": 10, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "/contact", + }, "loc": Object { "end": Object { "column": 18, @@ -2688,6 +3866,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 7, + "errors": Array [], + "extra": Object { + "raw": "'/save'", + "rawValue": "/save", + }, + "loc": Object { + "end": Object { + "column": 7, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "/save", + }, "loc": Object { "end": Object { "column": 15, @@ -2900,6 +4100,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 15, + "errors": Array [], + "extra": Object { + "raw": "'foo, bar, baz'", + "rawValue": "foo, bar, baz", + }, + "loc": Object { + "end": Object { + "column": 15, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "foo, bar, baz", + }, "loc": Object { "end": Object { "column": 22, @@ -2917,6 +4139,28 @@ Array [ "val": "'foo, bar, baz'", }, Object { + "ast": Object { + "comments": Array [], + "end": 1, + "errors": Array [], + "extra": Object { + "raw": "1", + "rawValue": 1, + }, + "loc": Object { + "end": Object { + "column": 1, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "NumericLiteral", + "value": 1, + }, "loc": Object { "end": Object { "column": 28, @@ -2991,6 +4235,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 9, + "errors": Array [], + "extra": Object { + "raw": "'((foo))'", + "rawValue": "((foo))", + }, + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "((foo))", + }, "loc": Object { "end": Object { "column": 16, @@ -3008,6 +4274,85 @@ Array [ "val": "'((foo))'", }, Object { + "ast": Object { + "alternate": Object { + "end": 11, + "extra": Object { + "raw": "0", + "rawValue": 0, + }, + "loc": Object { + "end": Object { + "column": 11, + "line": 1, + }, + "start": Object { + "column": 10, + "line": 1, + }, + }, + "start": 10, + "type": "NumericLiteral", + "value": 0, + }, + "comments": Array [], + "consequent": Object { + "end": 7, + "extra": Object { + "raw": "1", + "rawValue": 1, + }, + "loc": Object { + "end": Object { + "column": 7, + "line": 1, + }, + "start": Object { + "column": 6, + "line": 1, + }, + }, + "start": 6, + "type": "NumericLiteral", + "value": 1, + }, + "end": 11, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 11, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "test": Object { + "end": 2, + "extra": Object { + "parenStart": 0, + "parenthesized": true, + "raw": "1", + "rawValue": 1, + }, + "loc": Object { + "end": Object { + "column": 2, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "start": 1, + "type": "NumericLiteral", + "value": 1, + }, + "type": "ConditionalExpression", + }, "loc": Object { "end": Object { "column": 33, @@ -3112,6 +4457,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 5, + "errors": Array [], + "extra": Object { + "raw": "'foo'", + "rawValue": "foo", + }, + "loc": Object { + "end": Object { + "column": 5, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "foo", + }, "loc": Object { "end": Object { "column": 21, @@ -3235,6 +4602,28 @@ Array [ "val": true, }, Object { + "ast": Object { + "comments": Array [], + "end": 5, + "errors": Array [], + "extra": Object { + "raw": "'bar'", + "rawValue": "bar", + }, + "loc": Object { + "end": Object { + "column": 5, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "bar", + }, "loc": Object { "end": Object { "column": 30, @@ -3324,6 +4713,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 8, + "errors": Array [], + "extra": Object { + "raw": "\\"class:\\"", + "rawValue": "class:", + }, + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "class:", + }, "loc": Object { "end": Object { "column": 15, @@ -3398,6 +4809,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 6, + "errors": Array [], + "extra": Object { + "raw": "'\\\\\\\\S+'", + "rawValue": "\\\\S+", + }, + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "\\\\S+", + }, "loc": Object { "end": Object { "column": 21, @@ -3472,6 +4905,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 6, + "errors": Array [], + "extra": Object { + "raw": "\\"true\\"", + "rawValue": "true", + }, + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "true", + }, "loc": Object { "end": Object { "column": 17, @@ -3546,6 +5001,62 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "arguments": Array [ + Object { + "end": 10, + "extra": Object { + "raw": "0", + "rawValue": 0, + }, + "loc": Object { + "end": Object { + "column": 10, + "line": 1, + }, + "start": Object { + "column": 9, + "line": 1, + }, + }, + "start": 9, + "type": "NumericLiteral", + "value": 0, + }, + ], + "callee": Object { + "end": 8, + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "identifierName": "Date", + "start": Object { + "column": 4, + "line": 1, + }, + }, + "name": "Date", + "start": 4, + "type": "Identifier", + }, + "comments": Array [], + "end": 11, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 11, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "NewExpression", + }, "loc": Object { "end": Object { "column": 21, @@ -4241,6 +5752,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 5, + "errors": Array [], + "extra": Object { + "raw": "'foo'", + "rawValue": "foo", + }, + "loc": Object { + "end": Object { + "column": 5, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "foo", + }, "loc": Object { "end": Object { "column": 12, @@ -4258,6 +5791,28 @@ Array [ "val": "'foo'", }, Object { + "ast": Object { + "comments": Array [], + "end": 5, + "errors": Array [], + "extra": Object { + "raw": "\\"bar\\"", + "rawValue": "bar", + }, + "loc": Object { + "end": Object { + "column": 5, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "bar", + }, "loc": Object { "end": Object { "column": 24, @@ -4332,6 +5887,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 5, + "errors": Array [], + "extra": Object { + "raw": "'foo'", + "rawValue": "foo", + }, + "loc": Object { + "end": Object { + "column": 5, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "foo", + }, "loc": Object { "end": Object { "column": 12, @@ -4349,6 +5926,28 @@ Array [ "val": "'foo'", }, Object { + "ast": Object { + "comments": Array [], + "end": 5, + "errors": Array [], + "extra": Object { + "raw": "'bar'", + "rawValue": "bar", + }, + "loc": Object { + "end": Object { + "column": 5, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "bar", + }, "loc": Object { "end": Object { "column": 24, @@ -4442,6 +6041,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 17, + "errors": Array [], + "extra": Object { + "raw": "'text/x-template'", + "rawValue": "text/x-template", + }, + "loc": Object { + "end": Object { + "column": 17, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "text/x-template", + }, "loc": Object { "end": Object { "column": 30, @@ -4517,6 +6138,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 21, + "errors": Array [], + "extra": Object { + "raw": "'user-<%= user.id %>'", + "rawValue": "user-<%= user.id %>", + }, + "loc": Object { + "end": Object { + "column": 21, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "user-<%= user.id %>", + }, "loc": Object { "end": Object { "column": 32, @@ -4700,6 +6343,25 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 4, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 4, + "line": 1, + }, + "identifierName": "user", + "start": Object { + "column": 0, + "line": 1, + }, + }, + "name": "user", + "start": 0, + "type": "Identifier", + }, "loc": Object { "end": Object { "column": 19, @@ -4774,6 +6436,85 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "elements": Array [ + Object { + "end": 2, + "extra": Object { + "raw": "1", + "rawValue": 1, + }, + "loc": Object { + "end": Object { + "column": 2, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "start": 1, + "type": "NumericLiteral", + "value": 1, + }, + Object { + "end": 4, + "extra": Object { + "raw": "2", + "rawValue": 2, + }, + "loc": Object { + "end": Object { + "column": 4, + "line": 1, + }, + "start": Object { + "column": 3, + "line": 1, + }, + }, + "start": 3, + "type": "NumericLiteral", + "value": 2, + }, + Object { + "end": 6, + "extra": Object { + "raw": "3", + "rawValue": 3, + }, + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "start": Object { + "column": 5, + "line": 1, + }, + }, + "start": 5, + "type": "NumericLiteral", + "value": 3, + }, + ], + "end": 7, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 7, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "ArrayExpression", + }, "loc": Object { "end": Object { "column": 23, @@ -4848,6 +6589,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 6, + "errors": Array [], + "extra": Object { + "raw": "'tobi'", + "rawValue": "tobi", + }, + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "tobi", + }, "loc": Object { "end": Object { "column": 25, @@ -4922,6 +6685,80 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 24, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 24, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "properties": Array [ + Object { + "computed": false, + "end": 23, + "key": Object { + "end": 8, + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "identifierName": "message", + "start": Object { + "column": 1, + "line": 1, + }, + }, + "name": "message", + "start": 1, + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 23, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "method": false, + "shorthand": false, + "start": 1, + "type": "ObjectProperty", + "value": Object { + "end": 23, + "extra": Object { + "raw": "\\"Let's rock!\\"", + "rawValue": "Let's rock!", + }, + "loc": Object { + "end": Object { + "column": 23, + "line": 1, + }, + "start": Object { + "column": 10, + "line": 1, + }, + }, + "start": 10, + "type": "StringLiteral", + "value": "Let's rock!", + }, + }, + ], + "start": 0, + "type": "ObjectExpression", + }, "loc": Object { "end": Object { "column": 42, @@ -4996,6 +6833,80 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 40, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 40, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "properties": Array [ + Object { + "computed": false, + "end": 39, + "key": Object { + "end": 8, + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "identifierName": "message", + "start": Object { + "column": 1, + "line": 1, + }, + }, + "name": "message", + "start": 1, + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 39, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "method": false, + "shorthand": false, + "start": 1, + "type": "ObjectProperty", + "value": Object { + "end": 39, + "extra": Object { + "raw": "\\"a quote: " this & that\\"", + "rawValue": "a quote: " this & that", + }, + "loc": Object { + "end": Object { + "column": 39, + "line": 1, + }, + "start": Object { + "column": 10, + "line": 1, + }, + }, + "start": 10, + "type": "StringLiteral", + "value": "a quote: " this & that", + }, + }, + ], + "start": 0, + "type": "ObjectExpression", + }, "loc": Object { "end": Object { "column": 60, @@ -5070,6 +6981,62 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "arguments": Array [ + Object { + "end": 10, + "extra": Object { + "raw": "0", + "rawValue": 0, + }, + "loc": Object { + "end": Object { + "column": 10, + "line": 1, + }, + "start": Object { + "column": 9, + "line": 1, + }, + }, + "start": 9, + "type": "NumericLiteral", + "value": 0, + }, + ], + "callee": Object { + "end": 8, + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "identifierName": "Date", + "start": Object { + "column": 4, + "line": 1, + }, + }, + "name": "Date", + "start": 4, + "type": "Identifier", + }, + "comments": Array [], + "end": 11, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 11, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "NewExpression", + }, "loc": Object { "end": Object { "column": 26, @@ -5624,6 +7591,25 @@ Array [ "type": "newline", }, Object { + "ast": Object { + "comments": Array [], + "end": 4, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 4, + "line": 1, + }, + "identifierName": "list", + "start": Object { + "column": 0, + "line": 1, + }, + }, + "name": "list", + "start": 0, + "type": "Identifier", + }, "code": "list", "key": null, "loc": Object { @@ -5829,6 +7815,25 @@ Array [ "val": "li", }, Object { + "ast": Object { + "comments": Array [], + "end": 6, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "identifierName": "string", + "start": Object { + "column": 0, + "line": 1, + }, + }, + "name": "string", + "start": 0, + "type": "Identifier", + }, "buffer": true, "loc": Object { "end": Object { @@ -5967,6 +7972,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 3, + "errors": Array [], + "extra": Object { + "raw": "'#'", + "rawValue": "#", + }, + "loc": Object { + "end": Object { + "column": 3, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "#", + }, "loc": Object { "end": Object { "column": 17, @@ -6085,6 +8112,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 3, + "errors": Array [], + "extra": Object { + "raw": "'#'", + "rawValue": "#", + }, + "loc": Object { + "end": Object { + "column": 3, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "#", + }, "loc": Object { "end": Object { "column": 17, @@ -7041,6 +9090,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 6, + "errors": Array [], + "extra": Object { + "raw": "'utf8'", + "rawValue": "utf8", + }, + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "utf8", + }, "loc": Object { "end": Object { "column": 33, @@ -7401,6 +9472,25 @@ Array [ "type": "newline", }, Object { + "ast": Object { + "comments": Array [], + "end": 7, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 7, + "line": 1, + }, + "identifierName": "friends", + "start": Object { + "column": 0, + "line": 1, + }, + }, + "name": "friends", + "start": 0, + "type": "Identifier", + }, "loc": Object { "end": Object { "column": 17, @@ -7431,6 +9521,28 @@ Array [ "val": 6, }, Object { + "ast": Object { + "comments": Array [], + "end": 1, + "errors": Array [], + "extra": Object { + "raw": "0", + "rawValue": 0, + }, + "loc": Object { + "end": Object { + "column": 1, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "NumericLiteral", + "value": 0, + }, "loc": Object { "end": Object { "column": 13, @@ -7504,6 +9616,28 @@ Array [ "type": "newline", }, Object { + "ast": Object { + "comments": Array [], + "end": 1, + "errors": Array [], + "extra": Object { + "raw": "1", + "rawValue": 1, + }, + "loc": Object { + "end": Object { + "column": 1, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "NumericLiteral", + "value": 1, + }, "loc": Object { "end": Object { "column": 13, @@ -7635,6 +9769,25 @@ Array [ "val": "you have ", }, Object { + "ast": Object { + "comments": Array [], + "end": 7, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 7, + "line": 1, + }, + "identifierName": "friends", + "start": Object { + "column": 0, + "line": 1, + }, + }, + "name": "friends", + "start": 0, + "type": "Identifier", + }, "buffer": true, "loc": Object { "end": Object { @@ -7712,6 +9865,25 @@ Array [ "type": "newline", }, Object { + "ast": Object { + "comments": Array [], + "end": 7, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 7, + "line": 1, + }, + "identifierName": "friends", + "start": Object { + "column": 0, + "line": 1, + }, + }, + "name": "friends", + "start": 0, + "type": "Identifier", + }, "loc": Object { "end": Object { "column": 17, @@ -7742,6 +9914,28 @@ Array [ "val": 6, }, Object { + "ast": Object { + "comments": Array [], + "end": 1, + "errors": Array [], + "extra": Object { + "raw": "0", + "rawValue": 0, + }, + "loc": Object { + "end": Object { + "column": 1, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "NumericLiteral", + "value": 0, + }, "loc": Object { "end": Object { "column": 13, @@ -7771,6 +9965,28 @@ Array [ "type": "newline", }, Object { + "ast": Object { + "comments": Array [], + "end": 1, + "errors": Array [], + "extra": Object { + "raw": "1", + "rawValue": 1, + }, + "loc": Object { + "end": Object { + "column": 1, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "NumericLiteral", + "value": 1, + }, "loc": Object { "end": Object { "column": 13, @@ -7904,6 +10120,25 @@ Array [ "val": "you have ", }, Object { + "ast": Object { + "comments": Array [], + "end": 7, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 7, + "line": 1, + }, + "identifierName": "friends", + "start": Object { + "column": 0, + "line": 1, + }, + }, + "name": "friends", + "start": 0, + "type": "Identifier", + }, "buffer": true, "loc": Object { "end": Object { @@ -7995,6 +10230,25 @@ Array [ "type": "newline", }, Object { + "ast": Object { + "comments": Array [], + "end": 6, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "identifierName": "friend", + "start": Object { + "column": 0, + "line": 1, + }, + }, + "name": "friend", + "start": 0, + "type": "Identifier", + }, "loc": Object { "end": Object { "column": 16, @@ -8025,6 +10279,28 @@ Array [ "val": 6, }, Object { + "ast": Object { + "comments": Array [], + "end": 7, + "errors": Array [], + "extra": Object { + "raw": "'Tim:G'", + "rawValue": "Tim:G", + }, + "loc": Object { + "end": Object { + "column": 7, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "Tim:G", + }, "loc": Object { "end": Object { "column": 19, @@ -8098,6 +10374,80 @@ Array [ "type": "newline", }, Object { + "ast": Object { + "comments": Array [], + "end": 10, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 10, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "properties": Array [ + Object { + "computed": false, + "end": 9, + "key": Object { + "end": 4, + "loc": Object { + "end": Object { + "column": 4, + "line": 1, + }, + "identifierName": "tim", + "start": Object { + "column": 1, + "line": 1, + }, + }, + "name": "tim", + "start": 1, + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "method": false, + "shorthand": false, + "start": 1, + "type": "ObjectProperty", + "value": Object { + "end": 9, + "extra": Object { + "raw": "'g'", + "rawValue": "g", + }, + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "start": Object { + "column": 6, + "line": 1, + }, + }, + "start": 6, + "type": "StringLiteral", + "value": "g", + }, + }, + ], + "start": 0, + "type": "ObjectExpression", + }, "loc": Object { "end": Object { "column": 22, @@ -8309,6 +10659,25 @@ Array [ "type": "newline", }, Object { + "ast": Object { + "comments": Array [], + "end": 7, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 7, + "line": 1, + }, + "identifierName": "friends", + "start": Object { + "column": 0, + "line": 1, + }, + }, + "name": "friends", + "start": 0, + "type": "Identifier", + }, "loc": Object { "end": Object { "column": 17, @@ -8339,6 +10708,28 @@ Array [ "val": 6, }, Object { + "ast": Object { + "comments": Array [], + "end": 1, + "errors": Array [], + "extra": Object { + "raw": "0", + "rawValue": 0, + }, + "loc": Object { + "end": Object { + "column": 1, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "NumericLiteral", + "value": 0, + }, "loc": Object { "end": Object { "column": 13, @@ -8413,6 +10804,28 @@ Array [ "type": "outdent", }, Object { + "ast": Object { + "comments": Array [], + "end": 1, + "errors": Array [], + "extra": Object { + "raw": "1", + "rawValue": 1, + }, + "loc": Object { + "end": Object { + "column": 1, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "NumericLiteral", + "value": 1, + }, "loc": Object { "end": Object { "column": 13, @@ -8546,6 +10959,25 @@ Array [ "val": "you have ", }, Object { + "ast": Object { + "comments": Array [], + "end": 7, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 7, + "line": 1, + }, + "identifierName": "friends", + "start": Object { + "column": 0, + "line": 1, + }, + }, + "name": "friends", + "start": 0, + "type": "Identifier", + }, "buffer": true, "loc": Object { "end": Object { @@ -8700,6 +11132,85 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "elements": Array [ + Object { + "end": 6, + "extra": Object { + "raw": "'foo'", + "rawValue": "foo", + }, + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "start": 1, + "type": "StringLiteral", + "value": "foo", + }, + Object { + "end": 13, + "extra": Object { + "raw": "'bar'", + "rawValue": "bar", + }, + "loc": Object { + "end": Object { + "column": 13, + "line": 1, + }, + "start": Object { + "column": 8, + "line": 1, + }, + }, + "start": 8, + "type": "StringLiteral", + "value": "bar", + }, + Object { + "end": 20, + "extra": Object { + "raw": "'baz'", + "rawValue": "baz", + }, + "loc": Object { + "end": Object { + "column": 20, + "line": 1, + }, + "start": Object { + "column": 15, + "line": 1, + }, + }, + "start": 15, + "type": "StringLiteral", + "value": "baz", + }, + ], + "end": 21, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 21, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "ArrayExpression", + }, "loc": Object { "end": Object { "column": 30, @@ -8789,6 +11300,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 5, + "errors": Array [], + "extra": Object { + "raw": "'bar'", + "rawValue": "bar", + }, + "loc": Object { + "end": Object { + "column": 5, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "bar", + }, "loc": Object { "end": Object { "column": 18, @@ -8922,6 +11455,178 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 34, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 34, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "properties": Array [ + Object { + "computed": false, + "end": 10, + "key": Object { + "end": 4, + "loc": Object { + "end": Object { + "column": 4, + "line": 1, + }, + "identifierName": "foo", + "start": Object { + "column": 1, + "line": 1, + }, + }, + "name": "foo", + "start": 1, + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 10, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "method": false, + "shorthand": false, + "start": 1, + "type": "ObjectProperty", + "value": Object { + "end": 10, + "loc": Object { + "end": Object { + "column": 10, + "line": 1, + }, + "start": Object { + "column": 6, + "line": 1, + }, + }, + "start": 6, + "type": "BooleanLiteral", + "value": true, + }, + }, + Object { + "computed": false, + "end": 22, + "key": Object { + "end": 15, + "loc": Object { + "end": Object { + "column": 15, + "line": 1, + }, + "identifierName": "bar", + "start": Object { + "column": 12, + "line": 1, + }, + }, + "name": "bar", + "start": 12, + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 22, + "line": 1, + }, + "start": Object { + "column": 12, + "line": 1, + }, + }, + "method": false, + "shorthand": false, + "start": 12, + "type": "ObjectProperty", + "value": Object { + "end": 22, + "loc": Object { + "end": Object { + "column": 22, + "line": 1, + }, + "start": Object { + "column": 17, + "line": 1, + }, + }, + "start": 17, + "type": "BooleanLiteral", + "value": false, + }, + }, + Object { + "computed": false, + "end": 33, + "key": Object { + "end": 27, + "loc": Object { + "end": Object { + "column": 27, + "line": 1, + }, + "identifierName": "baz", + "start": Object { + "column": 24, + "line": 1, + }, + }, + "name": "baz", + "start": 24, + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 33, + "line": 1, + }, + "start": Object { + "column": 24, + "line": 1, + }, + }, + "method": false, + "shorthand": false, + "start": 24, + "type": "ObjectProperty", + "value": Object { + "end": 33, + "loc": Object { + "end": Object { + "column": 33, + "line": 1, + }, + "start": Object { + "column": 29, + "line": 1, + }, + }, + "start": 29, + "type": "BooleanLiteral", + "value": true, + }, + }, + ], + "start": 0, + "type": "ObjectExpression", + }, "loc": Object { "end": Object { "column": 43, @@ -9103,6 +11808,28 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 2, + "errors": Array [], + "extra": Object { + "raw": "''", + "rawValue": "", + }, + "loc": Object { + "end": Object { + "column": 2, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "", + }, "loc": Object { "end": Object { "column": 11, @@ -9177,6 +11904,23 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 4, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 4, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "NullLiteral", + }, "loc": Object { "end": Object { "column": 13, @@ -9251,6 +11995,25 @@ Array [ "type": "start-attributes", }, Object { + "ast": Object { + "comments": Array [], + "end": 9, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "identifierName": "undefined", + "start": Object { + "column": 0, + "line": 1, + }, + }, + "name": "undefined", + "start": 0, + "type": "Identifier", + }, "loc": Object { "end": Object { "column": 18, @@ -9650,6 +12413,24 @@ Array [ "type": "newline", }, Object { + "ast": Object { + "comments": Array [], + "end": 4, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 4, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "BooleanLiteral", + "value": true, + }, "loc": Object { "end": Object { "column": 8, @@ -9886,6 +12667,45 @@ Array [ "type": "outdent", }, Object { + "ast": Object { + "argument": Object { + "end": 6, + "extra": Object { + "parenStart": 1, + "parenthesized": true, + }, + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "start": Object { + "column": 2, + "line": 1, + }, + }, + "start": 2, + "type": "BooleanLiteral", + "value": true, + }, + "comments": Array [], + "end": 7, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 7, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "operator": "!", + "prefix": true, + "start": 0, + "type": "UnaryExpression", + }, "loc": Object { "end": Object { "column": 12, @@ -10034,6 +12854,28 @@ Array [ "type": "outdent", }, Object { + "ast": Object { + "comments": Array [], + "end": 8, + "errors": Array [], + "extra": Object { + "raw": "'nested'", + "rawValue": "nested", + }, + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "nested", + }, "loc": Object { "end": Object { "column": 12, @@ -10064,6 +12906,28 @@ Array [ "val": 2, }, Object { + "ast": Object { + "comments": Array [], + "end": 7, + "errors": Array [], + "extra": Object { + "raw": "'works'", + "rawValue": "works", + }, + "loc": Object { + "end": Object { + "column": 7, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "StringLiteral", + "value": "works", + }, "loc": Object { "end": Object { "column": 13, @@ -10182,6 +13046,24 @@ Array [ "type": "newline", }, Object { + "ast": Object { + "comments": Array [], + "end": 5, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 5, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "BooleanLiteral", + "value": false, + }, "loc": Object { "end": Object { "column": 9, @@ -10270,6 +13152,24 @@ Array [ "type": "outdent", }, Object { + "ast": Object { + "comments": Array [], + "end": 4, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 4, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "BooleanLiteral", + "value": true, + }, "loc": Object { "end": Object { "column": 8, @@ -10387,6 +13287,24 @@ Array [ "type": "newline", }, Object { + "ast": Object { + "comments": Array [], + "end": 5, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 5, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "BooleanLiteral", + "value": false, + }, "loc": Object { "end": Object { "column": 9, @@ -10446,6 +13364,24 @@ Array [ "type": "outdent", }, Object { + "ast": Object { + "comments": Array [], + "end": 5, + "errors": Array [], + "loc": Object { + "end": Object { + "column": 5, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "BooleanLiteral", + "value": false, + }, "loc": Object { "end": Object { "column": 14, @@ -10598,6 +13534,28 @@ Array [ "val": "p", }, Object { + "ast": Object { + "comments": Array [], + "end": 10, + "errors": Array [], + "extra": Object { + "raw": "'