UNPKG

babel-plugin-transform-adana

Version:
1 lines 73 kB
{"src/meta.js":{"source":"\nexport default function meta(state, value) {\n if (arguments.length > 1) {\n state.file.metadata.coverage = value;\n }\n return state.file.metadata.coverage;\n}\n","path":"src/meta.js","locations":[{"id":0,"loc":{"start":{"line":2,"column":15},"end":{"line":7,"column":1}},"tags":["function"],"name":"meta","count":11},{"id":1,"loc":{"start":{"line":3,"column":28},"end":{"line":5,"column":3}},"tags":["branch","line","if"],"group":"3:2","count":1},{"id":2,"loc":{"start":{"line":5,"column":3},"end":{"line":5,"column":3}},"tags":["branch","if"],"group":"3:2","count":10},{"id":3,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":41}},"tags":["statement","line"],"count":1},{"id":4,"loc":{"start":{"line":6,"column":9},"end":{"line":6,"column":37}},"tags":["line","statement"],"count":11}]},"src/prelude.js":{"source":"/* global __dirname */\n\nimport {readFileSync} from 'fs';\nimport path from 'path';\nimport template from '@babel/template';\nimport astify from 'babel-literal-to-ast';\nimport meta from './meta';\n\nconst render = template(readFileSync(\n path.join(__dirname, '..', 'share', 'prelude.js'), 'utf8'\n));\n\nexport default function prelude(state) {\n const coverage = meta(state);\n const global = (state.opts && state.opts.global) || '__coverage__';\n return render({\n GLOBAL: astify(global),\n SOURCE: astify(coverage.source),\n VARIABLE: coverage.variable,\n FILE: astify(coverage.name),\n LOCATIONS: astify(coverage.entries),\n });\n}\n","path":"src/prelude.js","locations":[{"id":0,"loc":{"start":{"line":9,"column":15},"end":{"line":11,"column":2}},"tags":["statement","variable","line"],"count":1},{"id":1,"loc":{"start":{"line":13,"column":15},"end":{"line":23,"column":1}},"tags":["function"],"name":"prelude","count":1},{"id":2,"loc":{"start":{"line":14,"column":19},"end":{"line":14,"column":30}},"tags":["statement","variable","line"],"count":1},{"id":3,"loc":{"start":{"line":15,"column":17},"end":{"line":15,"column":68}},"tags":["statement","variable","line"],"count":1},{"id":4,"loc":{"start":{"line":15,"column":18},"end":{"line":15,"column":49}},"tags":["branch","logic"],"group":"15:17","count":1},{"id":5,"loc":{"start":{"line":15,"column":54},"end":{"line":15,"column":68}},"tags":["branch","logic"],"group":"15:17","count":1},{"id":6,"loc":{"start":{"line":15,"column":18},"end":{"line":15,"column":28}},"tags":["branch","logic"],"group":"15:18","count":1},{"id":7,"loc":{"start":{"line":15,"column":32},"end":{"line":15,"column":49}},"tags":["branch","logic"],"group":"15:18","count":1},{"id":8,"loc":{"start":{"line":16,"column":9},"end":{"line":22,"column":4}},"tags":["line","statement"],"count":1},{"id":9,"loc":{"start":{"line":17,"column":12},"end":{"line":17,"column":26}},"tags":["line"],"count":1},{"id":10,"loc":{"start":{"line":18,"column":12},"end":{"line":18,"column":35}},"tags":["line"],"count":1},{"id":11,"loc":{"start":{"line":19,"column":14},"end":{"line":19,"column":31}},"tags":["line"],"count":1},{"id":12,"loc":{"start":{"line":20,"column":10},"end":{"line":20,"column":31}},"tags":["line"],"count":1},{"id":13,"loc":{"start":{"line":21,"column":15},"end":{"line":21,"column":39}},"tags":["line"],"count":1}]},"src/tags.js":{"source":"import meta from './meta';\n\nconst COMMENT_PATTERN = /^\\s*@?(adana|coverage|test|istanbul):?\\s*(.*)\\s*/;\n\nfunction within(a, b) {\n return a.start.line >= b.start.line &&\n a.start.column >= b.start.column &&\n a.end.line <= b.end.line &&\n a.end.column <= b.end.column;\n}\n\nexport function applyRules(state) {\n const coverage = meta(state);\n coverage.entries.forEach((entry) => {\n const result = { };\n const output = [];\n entry.tags.forEach((tag) => {\n result[tag] = true;\n });\n coverage.rules.forEach((rule) => {\n if (within(rule.loc, entry.loc)) {\n result[rule.tag] = rule.value;\n }\n });\n Object.keys(result).forEach((tag) => {\n const value = result[tag];\n if (value) {\n output.push(tag);\n }\n });\n entry.tags = output;\n });\n}\n\nexport function extract(comment) {\n const output = { };\n const result = COMMENT_PATTERN.exec(comment);\n if (result) {\n const entries = result[2].split(/\\s+/);\n entries.forEach((entry) => {\n switch (entry.charAt(0)) {\n case '+':\n output[entry.substr(1)] = true;\n break;\n case '-':\n output[entry.substr(1)] = false;\n break;\n default:\n break;\n }\n });\n }\n return output;\n}\n\nexport function addRules(state, loc, comments) {\n if (comments) {\n const coverage = meta(state);\n comments.forEach((comment) => {\n const values = extract(comment.value);\n Object.keys(values).forEach((tag) => {\n coverage.rules.push({\n tag,\n value: values[tag],\n loc,\n });\n });\n });\n }\n}\n","path":"src/tags.js","locations":[{"id":0,"loc":{"start":{"line":3,"column":24},"end":{"line":3,"column":74}},"tags":["statement","variable","line"],"count":1},{"id":1,"loc":{"start":{"line":5,"column":0},"end":{"line":10,"column":1}},"tags":["function"],"name":"within","count":0},{"id":2,"loc":{"start":{"line":6,"column":9},"end":{"line":9,"column":32}},"tags":["line","statement"],"count":0},{"id":3,"loc":{"start":{"line":6,"column":9},"end":{"line":8,"column":28}},"tags":["branch","logic"],"group":"6:9","count":0},{"id":4,"loc":{"start":{"line":9,"column":4},"end":{"line":9,"column":32}},"tags":["branch","logic"],"group":"6:9","count":0},{"id":5,"loc":{"start":{"line":6,"column":9},"end":{"line":7,"column":36}},"tags":["branch","logic"],"group":"6:9","count":0},{"id":6,"loc":{"start":{"line":8,"column":4},"end":{"line":8,"column":28}},"tags":["branch","logic"],"group":"6:9","count":0},{"id":7,"loc":{"start":{"line":6,"column":9},"end":{"line":6,"column":37}},"tags":["branch","logic"],"group":"6:9","count":0},{"id":8,"loc":{"start":{"line":7,"column":4},"end":{"line":7,"column":36}},"tags":["branch","logic"],"group":"6:9","count":0},{"id":9,"loc":{"start":{"line":12,"column":7},"end":{"line":33,"column":1}},"tags":["function"],"name":"applyRules","count":1},{"id":10,"loc":{"start":{"line":13,"column":19},"end":{"line":13,"column":30}},"tags":["statement","variable","line"],"count":1},{"id":11,"loc":{"start":{"line":14,"column":2},"end":{"line":32,"column":5}},"tags":["statement","line"],"count":1},{"id":12,"loc":{"start":{"line":14,"column":27},"end":{"line":32,"column":3}},"tags":["function"],"name":"@14:27","count":8},{"id":13,"loc":{"start":{"line":15,"column":19},"end":{"line":15,"column":22}},"tags":["statement","variable","line"],"count":8},{"id":14,"loc":{"start":{"line":16,"column":19},"end":{"line":16,"column":21}},"tags":["statement","variable","line"],"count":8},{"id":15,"loc":{"start":{"line":17,"column":4},"end":{"line":19,"column":7}},"tags":["statement","line"],"count":8},{"id":16,"loc":{"start":{"line":17,"column":23},"end":{"line":19,"column":5}},"tags":["function"],"name":"@17:23","count":17},{"id":17,"loc":{"start":{"line":18,"column":6},"end":{"line":18,"column":25}},"tags":["statement","line"],"count":17},{"id":18,"loc":{"start":{"line":20,"column":4},"end":{"line":24,"column":7}},"tags":["statement","line"],"count":8},{"id":19,"loc":{"start":{"line":20,"column":27},"end":{"line":24,"column":5}},"tags":["function"],"name":"@20:27","count":0},{"id":20,"loc":{"start":{"line":21,"column":39},"end":{"line":23,"column":7}},"tags":["branch","line","if"],"group":"21:6","count":0},{"id":21,"loc":{"start":{"line":23,"column":7},"end":{"line":23,"column":7}},"tags":["branch","if"],"group":"21:6","count":0},{"id":22,"loc":{"start":{"line":22,"column":8},"end":{"line":22,"column":38}},"tags":["statement","line"],"count":0},{"id":23,"loc":{"start":{"line":25,"column":4},"end":{"line":30,"column":7}},"tags":["statement","line"],"count":8},{"id":24,"loc":{"start":{"line":25,"column":32},"end":{"line":30,"column":5}},"tags":["function"],"name":"@25:32","count":17},{"id":25,"loc":{"start":{"line":26,"column":20},"end":{"line":26,"column":31}},"tags":["statement","variable","line"],"count":17},{"id":26,"loc":{"start":{"line":27,"column":17},"end":{"line":29,"column":7}},"tags":["branch","line","if"],"group":"27:6","count":17},{"id":27,"loc":{"start":{"line":29,"column":7},"end":{"line":29,"column":7}},"tags":["branch","if"],"group":"27:6","count":0},{"id":28,"loc":{"start":{"line":28,"column":8},"end":{"line":28,"column":25}},"tags":["statement","line"],"count":17},{"id":29,"loc":{"start":{"line":31,"column":4},"end":{"line":31,"column":24}},"tags":["statement","line"],"count":8},{"id":30,"loc":{"start":{"line":35,"column":7},"end":{"line":54,"column":1}},"tags":["function"],"name":"extract","count":0},{"id":31,"loc":{"start":{"line":36,"column":17},"end":{"line":36,"column":20}},"tags":["statement","variable","line"],"count":0},{"id":32,"loc":{"start":{"line":37,"column":17},"end":{"line":37,"column":46}},"tags":["statement","variable","line"],"count":0},{"id":33,"loc":{"start":{"line":38,"column":14},"end":{"line":52,"column":3}},"tags":["branch","line","if"],"group":"38:2","count":0},{"id":34,"loc":{"start":{"line":52,"column":3},"end":{"line":52,"column":3}},"tags":["branch","if"],"group":"38:2","count":0},{"id":35,"loc":{"start":{"line":39,"column":20},"end":{"line":39,"column":42}},"tags":["statement","variable","line"],"count":0},{"id":36,"loc":{"start":{"line":40,"column":4},"end":{"line":51,"column":7}},"tags":["statement","line"],"count":0},{"id":37,"loc":{"start":{"line":40,"column":20},"end":{"line":51,"column":5}},"tags":["function"],"name":"@40:20","count":0},{"id":38,"loc":{"start":{"line":42,"column":6},"end":{"line":44,"column":14}},"tags":["branch","switch"],"group":"41:6","count":0},{"id":39,"loc":{"start":{"line":45,"column":6},"end":{"line":47,"column":14}},"tags":["branch","switch"],"group":"41:6","count":0},{"id":40,"loc":{"start":{"line":48,"column":6},"end":{"line":49,"column":14}},"tags":["branch","switch"],"group":"41:6","count":0},{"id":41,"loc":{"start":{"line":43,"column":8},"end":{"line":43,"column":39}},"tags":["statement","line"],"count":0},{"id":42,"loc":{"start":{"line":44,"column":8},"end":{"line":44,"column":14}},"tags":["statement","line"],"count":0},{"id":43,"loc":{"start":{"line":46,"column":8},"end":{"line":46,"column":40}},"tags":["statement","line"],"count":0},{"id":44,"loc":{"start":{"line":47,"column":8},"end":{"line":47,"column":14}},"tags":["statement","line"],"count":0},{"id":45,"loc":{"start":{"line":49,"column":8},"end":{"line":49,"column":14}},"tags":["statement","line"],"count":0},{"id":46,"loc":{"start":{"line":53,"column":9},"end":{"line":53,"column":15},"identifierName":"output"},"tags":["line","statement"],"count":0},{"id":47,"loc":{"start":{"line":56,"column":7},"end":{"line":70,"column":1}},"tags":["function"],"name":"addRules","count":0},{"id":48,"loc":{"start":{"line":57,"column":16},"end":{"line":69,"column":3}},"tags":["branch","line","if"],"group":"57:2","count":0},{"id":49,"loc":{"start":{"line":69,"column":3},"end":{"line":69,"column":3}},"tags":["branch","if"],"group":"57:2","count":0},{"id":50,"loc":{"start":{"line":58,"column":21},"end":{"line":58,"column":32}},"tags":["statement","variable","line"],"count":0},{"id":51,"loc":{"start":{"line":59,"column":4},"end":{"line":68,"column":7}},"tags":["statement","line"],"count":0},{"id":52,"loc":{"start":{"line":59,"column":21},"end":{"line":68,"column":5}},"tags":["function"],"name":"@59:21","count":0},{"id":53,"loc":{"start":{"line":60,"column":21},"end":{"line":60,"column":43}},"tags":["statement","variable","line"],"count":0},{"id":54,"loc":{"start":{"line":61,"column":6},"end":{"line":67,"column":9}},"tags":["statement","line"],"count":0},{"id":55,"loc":{"start":{"line":61,"column":34},"end":{"line":67,"column":7}},"tags":["function"],"name":"@61:34","count":0},{"id":56,"loc":{"start":{"line":62,"column":8},"end":{"line":66,"column":11}},"tags":["statement","line"],"count":0},{"id":57,"loc":{"start":{"line":64,"column":17},"end":{"line":64,"column":28}},"tags":["line"],"count":0}]},"src/instrumenter.js":{"source":"import * as types from '@babel/types';\nimport micromatch from 'micromatch';\nimport {relative} from 'path';\n\nimport prelude from './prelude';\nimport meta from './meta';\nimport {applyRules, addRules} from './tags';\n\nexport function skip({ignore, only}, file) {\n if (only) {\n return micromatch(\n [file],\n Array.isArray(only) ? only : [only],\n {nocase: true}\n ).length <= 0;\n }\n if (ignore) {\n return micromatch(\n [file],\n Array.isArray(ignore) ? ignore : [ignore],\n {nocase: true}\n ).length > 0;\n }\n return false;\n}\n\n/**\n * Create an opaque, unique key for a given node. Useful for tagging the node\n * in separate places.\n * @param {Object} path Babel path to derive key from.\n * @returns {String} String key.\n */\nexport function key(path) {\n const node = path.node;\n if (node.loc) {\n const location = node.loc.start;\n return `${location.line}:${location.column}`;\n }\n throw new TypeError('Path must have valid location.');\n}\n\n/**\n * Some nodes need to marked as non-instrumentable; since babel will apply\n * our plugin to nodes we create, we have to be careful to not put ourselves\n * into an infinite loop.\n * @param {Object} node Babel AST node.\n * @returns {Object} Babel AST node that won't be instrumented.\n */\nfunction X(node) {\n node.__adana = true;\n return node;\n}\n\nfunction ignore(path) {\n return (!path.node || !path.node.loc || path.node.__adana);\n}\n\nfunction standardize(listener) {\n return (path, state) => ignore(path) ? undefined : listener(path, state);\n}\n\n/**\n * Create the transform-adana babel plugin.\n * @returns {Object} `babel` plugin object.\n */\nexport default function instrumenter() {\n /**\n * Create a chunk of code that marks the specified node as having\n * been executed.\n * @param {Object} state `babel` state for the path that's being walked.\n * @param {Object} options Configure how the marker behaves.\n * @returns {Object} AST node for marking coverage.\n */\n function createMarker(state, options) {\n const {tags, loc, name, group} = options;\n const coverage = meta(state);\n const id = coverage.entries.length;\n\n coverage.entries.push({\n id,\n loc,\n tags,\n name,\n group,\n count: 0,\n });\n\n // Maker is simply a statement incrementing a coverage variable.\n return X(types.updateExpression('++', types.memberExpression(\n types.memberExpression(\n coverage.variable,\n types.numericLiteral(id),\n true\n ),\n types.stringLiteral('count'),\n true\n ), true));\n }\n\n /**\n * [isInstrumentableStatement description]\n * @param {[type]} path [description]\n * @returns {Boolean} [description]\n */\n function isInstrumentableStatement(path) {\n const parent = path.parentPath;\n return !parent.isReturnStatement() &&\n !parent.isVariableDeclaration() &&\n !parent.isExportDeclaration() &&\n !parent.isFunctionDeclaration() &&\n !parent.isIfStatement();\n }\n\n /**\n * Inject a marker that measures whether the node for the given path has\n * been run or not.\n * @param {Object} path [description]\n * @param {Object} state [description]\n * @param {Object} options [description]\n * @returns {void}\n */\n function instrument(path, state, options) {\n // This function is here because isInstrumentableStatement() is being\n // called; we can't create the marker without knowing the result of that,\n // otherwise dead markers will be created.\n function marker() {\n return createMarker(state, {\n loc: path.node.loc,\n ...options,\n });\n }\n\n if (path.isBlockStatement()) {\n path.unshiftContainer('body', X(types.expressionStatement(marker())));\n } else if (path.isExpression()) {\n path.replaceWith(X(types.sequenceExpression([marker(), path.node])));\n } else if (path.isStatement()) {\n if (isInstrumentableStatement(path)) {\n path.insertBefore(X(types.expressionStatement(marker())));\n }\n }\n }\n\n /**\n * [visitStatement description]\n * @param {[type]} path [description]\n * @param {[type]} state [description]\n * @returns {void}\n */\n function visitStatement(path, state) {\n instrument(path, state, {\n tags: ['statement', 'line'],\n loc: path.node.loc,\n });\n }\n\n /**\n * The function visitor is mainly to track the definitions of functions;\n * being able ensure how many of your functions have actually been invoked.\n * @param {[type]} path [description]\n * @param {[type]} state [description]\n * @returns {void}\n */\n function visitFunction(path, state) {\n instrument(path.get('body'), state, {\n tags: ['function'],\n name: path.node.id ? path.node.id.name : `@${key(path)}`,\n loc: path.node.loc,\n });\n }\n\n /**\n * Multiple branches based on the result of `case _` and `default`. If you\n * do not provide a `default` one will be intelligently added for you,\n * forcing you to cover that case.\n * @param {[type]} path [description]\n * @param {[type]} state [description]\n * @returns {void}\n */\n function visitSwitchStatement(path, state) {\n let hasDefault = false;\n path.get('cases').forEach((entry) => {\n if (entry.node.test) {\n addRules(state, entry.node.loc, entry.node.test.trailingComments);\n }\n if (entry.node.consequent.length > 1) {\n addRules(\n state,\n entry.node.loc,\n entry.node.consequent[0].leadingComments\n );\n }\n\n if (entry.node.test === null) {\n hasDefault = true;\n }\n entry.unshiftContainer('consequent', createMarker(state, {\n tags: ['branch', 'switch'],\n loc: entry.node.loc,\n group: key(path),\n }));\n });\n\n // Default is technically a branch, just like if statements without\n // else's are also technically a branch.\n if (!hasDefault) {\n // Add an extra break to the end of the last case in case some idiot\n // forgot to add it.\n const cases = path.get('cases');\n if (cases.length > 0) {\n cases[cases.length - 1].pushContainer(\n 'consequent',\n types.breakStatement()\n );\n }\n // Finally add the default case.\n path.pushContainer('cases', types.switchCase(null, [\n types.expressionStatement(createMarker(state, {\n tags: ['branch', 'switch'],\n loc: {\n start: path.node.loc.end,\n end: path.node.loc.end,\n },\n group: key(path),\n })),\n types.breakStatement(),\n ]));\n }\n }\n\n /**\n * [visitVariableDeclaration description]\n * @param {[type]} path [description]\n * @param {[type]} state [description]\n * @returns {void}\n */\n function visitVariableDeclaration(path, state) {\n path.get('declarations').forEach((decl) => {\n if (decl.has('init')) {\n instrument(decl.get('init'), state, {\n tags: ['statement', 'variable', 'line'],\n });\n }\n });\n }\n\n /**\n * Includes both while and do-while loops. They contain a single branch which\n * tests the loop condition.\n * @param {[type]} path [description]\n * @param {[type]} state [description]\n * @returns {void}\n */\n function visitWhileLoop(path, state) {\n const test = path.get('test');\n const group = key(path);\n // This is a particularly clever use of the fact JS operators are short-\n // circuiting. To instrument a loop one _cannot_ add a marker on the outside\n // of the loop body due to weird cases of things where loops are in non-\n // block if statements. So instead, create the following mechanism:\n // ((condition && A) || !B) where A and B are markers. Since markers are\n // postfix, they're always true. Ergo, A is only incremented when condition\n // is true, B only when it's false and the truth value of the whole\n // statement is preserved. Neato.\n test.replaceWith(types.logicalExpression(\n '||',\n types.logicalExpression(\n '&&',\n X(test.node),\n createMarker(state, {\n tags: ['branch', 'line', 'statement', 'loop', 'while'],\n loc: test.node.loc,\n group,\n })\n ),\n types.unaryExpression(\n '!',\n createMarker(state, {\n tags: ['branch', 'line', 'loop', 'while'],\n loc: test.node.loc,\n group,\n })\n )\n ));\n }\n\n /**\n * The try block can either fully succeed (no error) or it can throw. Both\n * cases are accounted for.\n * @param {[type]} path [description]\n * @param {[type]} state [description]\n * @returns {void}\n */\n function visitTryStatement(path, state) {\n const group = key(path);\n const body = path.get('block');\n const trigger = path.scope.generateDeclaredUidIdentifier('_exception');\n addRules(state, body.node.loc, body.node.leadingComments);\n path.get('block').unshiftContainer('body', types.expressionStatement(\n types.assignmentExpression('=', trigger, types.booleanLiteral(true)),\n ));\n const handlerExpression = types.expressionStatement(\n types.assignmentExpression('=', trigger, types.booleanLiteral(false)),\n );\n let handlerLoc;\n if (path.has('handler')) {\n const handler = path.get('handler').node;\n handlerLoc = handler.loc;\n addRules(state, handler.loc, handler.body.leadingComments);\n path.get('handler.body').unshiftContainer(\n 'body',\n handlerExpression\n );\n } else {\n const loc = path.get('block').node.loc.end;\n handlerLoc = {start: loc, end: loc};\n path.get('handler').replaceWith(types.catchClause(\n types.identifier('err'), types.blockStatement([\n handlerExpression,\n types.throwStatement(\n types.identifier('err')\n ),\n ])\n ));\n }\n\n const guard = types.ifStatement(\n trigger,\n types.expressionStatement(\n createMarker(state, {\n tags: ['branch', 'line', 'exception'],\n loc: path.get('block').node.loc,\n group,\n })\n ),\n types.expressionStatement(\n createMarker(state, {\n tags: ['branch', 'line', 'exception'],\n loc: handlerLoc,\n group,\n })\n )\n );\n\n if (path.has('finalizer')) {\n path.get('finalizer').unshiftContainer('body', guard);\n } else {\n path.get('finalizer').replaceWith(types.blockStatement([guard]));\n }\n }\n\n /**\n * Return statements are instrumented by marking the next block they return.\n * This helps ensure multi-line expressions for return statements are\n * accurately captured.\n * @param {[type]} path [description]\n * @param {[type]} state [description]\n * @returns {[type]} [description]\n */\n function visitReturnStatement(path, state) {\n if (!path.has('argument')) {\n path.get('argument').replaceWith(types.sequenceExpression([\n createMarker(state, {\n loc: path.node.loc,\n tags: ['line', 'statement'],\n }),\n types.identifier('undefined'),\n ]));\n } else {\n instrument(path.get('argument'), state, {\n tags: ['line', 'statement'],\n });\n }\n }\n\n /**\n * For multi-line reporting (and objects do tend to span multiple lines) this\n * is required to know which parts of the object where actually executed.\n * Ignore shorthand property that look like `{ this }`.\n * @param {[type]} path [description]\n * @param {[type]} state [description]\n * @returns {[type]} [description]\n */\n function visitObjectProperty(path, state) {\n if (!path.node.shorthand && !path.parentPath.isPattern()) {\n const key = path.get('key');\n const value = path.get('value');\n if (path.node.computed) {\n instrument(key, state, {\n tags: ['line'],\n });\n }\n instrument(value, state, {\n tags: ['line'],\n });\n }\n }\n\n /**\n * For multi-line reporting (and arrays do tend to span multiple lines) this\n * is required to know which parts of the array where actually executed.\n * This does _not_ include destructed arrays.\n * @param {[type]} path [description]\n * @param {[type]} state [description]\n * @returns {[type]} [description]\n */\n function visitArrayExpression(path, state) {\n if (!path.parentPath.isPattern()) {\n path.get('elements').forEach((element) => {\n instrument(element, state, {\n tags: ['line'],\n });\n });\n }\n }\n\n /**\n * Logical expressions are those using logic operators like `&&` and `||`.\n * Since logic expressions short-circuit in JS they are effectively branches\n * and will be treated as such here.\n * @param {[type]} path [description]\n * @param {[type]} state [description]\n * @returns {void}\n */\n function visitLogicalExpression(path, state) {\n const group = key(path);\n const left = path.get('left').node;\n const right = path.get('right').node;\n path.replaceWith(X(types.logicalExpression(\n path.node.operator,\n types.sequenceExpression([createMarker(state, {\n tags: ['branch', 'logic'],\n loc: left.loc,\n group,\n }), left]),\n types.sequenceExpression([createMarker(state, {\n tags: ['branch', 'logic'],\n loc: right.loc,\n group,\n }), right])\n )));\n }\n\n /**\n * Conditionals are either if/else statements or tenaiary expressions. They\n * have a test case and two choices (based on the test result). Both cases\n * are always accounted for, even if the code does not exist for the alternate\n * case.\n * @param {[type]} path [description]\n * @param {[type]} state [description]\n * @returns {void}\n */\n function visitConditional(path, state) {\n // Branches can be grouped together so that each of the possible branch\n // destinations is accounted for under one group. For if statements, this\n // refers to all the blocks that fall under a single if.. else if.. else..\n // grouping.\n const root = path.findParent((search) => {\n return search.node.type === path.node.type &&\n !ignore(search) &&\n (!search.parentPath || search.parentPath.node.type !== path.node.type);\n }) || path;\n\n // Create the group name based on the root `if` statement.\n const group = key(root);\n\n function tagBranch(path) {\n addRules(state, path.node.loc, path.node.leadingComments);\n if (path.isBlockStatement() && path.node.body.length > 0) {\n addRules(state, path.node.loc, path.node.body[0].leadingComments);\n }\n }\n\n tagBranch(path.get('consequent'));\n if (path.has('alternate')) {\n tagBranch(path.get('alternate'));\n }\n\n instrument(path.get('consequent'), state, {\n tags: ['branch', 'line', 'if'],\n loc: path.node.consequent.loc,\n group,\n });\n\n if (path.has('alternate') && !path.get('alternate').isIfStatement()) {\n instrument(path.get('alternate'), state, {\n tags: ['branch', 'line', 'if'],\n loc: path.node.alternate.loc,\n group,\n });\n } else if (!path.has('alternate')) {\n path.get('alternate').replaceWith(types.expressionStatement(\n createMarker(state, {\n tags: ['branch', 'if'],\n loc: {\n start: path.node.loc.end,\n end: path.node.loc.end,\n },\n group,\n }))\n );\n }\n }\n\n function noInstrument(path) {\n if (\n path.node &&\n path.node.leadingComments &&\n path.node.leadingComments.some(\n (comment) => /^\\s*adana-no-instrument\\s*$/.exec(comment.value)\n )\n ) {\n path.skip();\n return;\n }\n }\n\n const visitor = {\n // Expressions\n ArrowFunctionExpression: visitFunction,\n FunctionExpression: visitFunction,\n ObjectMethod: visitFunction,\n ClassMethod: visitFunction,\n LogicalExpression: visitLogicalExpression,\n ConditionalExpression: visitConditional,\n ObjectProperty: visitObjectProperty,\n ArrayExpression: visitArrayExpression,\n\n // Declarations\n FunctionDeclaration: visitFunction,\n VariableDeclaration: visitVariableDeclaration,\n\n // Statements\n ContinueStatement: visitStatement,\n BreakStatement: visitStatement,\n ExpressionStatement: visitStatement,\n ThrowStatement: visitStatement,\n ReturnStatement: visitReturnStatement,\n TryStatement: visitTryStatement,\n WhileStatement: visitWhileLoop,\n DoWhileStatement: visitWhileLoop,\n IfStatement: visitConditional,\n SwitchStatement: visitSwitchStatement,\n\n // Generics\n enter: noInstrument,\n };\n\n Object.keys(visitor).forEach((key) => {\n visitor[key] = standardize(visitor[key]);\n });\n\n // Create the actual babel plugin object.\n return {\n visitor: {\n Program(path, state) {\n const {opts, filename, file: {opts: {cwd}}} = state;\n // Check if file should be instrumented or not.\n const name = filename ? relative(cwd, filename) : '<source>';\n if (filename && skip(opts, name)) {\n return;\n }\n meta(state, {\n source: state.file.code,\n entries: [],\n rules: [],\n tags: {},\n variable: path.scope.generateUidIdentifier('coverage'),\n name,\n });\n path.traverse(visitor, state);\n applyRules(state);\n path.unshiftContainer('body', prelude(state));\n },\n },\n };\n}\n","path":"src/instrumenter.js","locations":[{"id":0,"loc":{"start":{"line":9,"column":7},"end":{"line":25,"column":1}},"tags":["function"],"name":"skip","count":1},{"id":1,"loc":{"start":{"line":10,"column":12},"end":{"line":16,"column":3}},"tags":["branch","line","if"],"group":"10:2","count":0},{"id":2,"loc":{"start":{"line":16,"column":3},"end":{"line":16,"column":3}},"tags":["branch","if"],"group":"10:2","count":1},{"id":3,"loc":{"start":{"line":11,"column":11},"end":{"line":15,"column":17}},"tags":["line","statement"],"count":0},{"id":4,"loc":{"start":{"line":12,"column":7},"end":{"line":12,"column":11},"identifierName":"file"},"tags":["line"],"count":0},{"id":5,"loc":{"start":{"line":13,"column":28},"end":{"line":13,"column":32},"identifierName":"only"},"tags":["branch","line","if"],"group":"13:6","count":0},{"id":6,"loc":{"start":{"line":13,"column":35},"end":{"line":13,"column":41}},"tags":["branch","line","if"],"group":"13:6","count":0},{"id":7,"loc":{"start":{"line":13,"column":36},"end":{"line":13,"column":40},"identifierName":"only"},"tags":["line"],"count":0},{"id":8,"loc":{"start":{"line":14,"column":15},"end":{"line":14,"column":19}},"tags":["line"],"count":0},{"id":9,"loc":{"start":{"line":17,"column":14},"end":{"line":23,"column":3}},"tags":["branch","line","if"],"group":"17:2","count":1},{"id":10,"loc":{"start":{"line":23,"column":3},"end":{"line":23,"column":3}},"tags":["branch","if"],"group":"17:2","count":0},{"id":11,"loc":{"start":{"line":18,"column":11},"end":{"line":22,"column":16}},"tags":["line","statement"],"count":1},{"id":12,"loc":{"start":{"line":19,"column":7},"end":{"line":19,"column":11},"identifierName":"file"},"tags":["line"],"count":1},{"id":13,"loc":{"start":{"line":20,"column":30},"end":{"line":20,"column":36},"identifierName":"ignore"},"tags":["branch","line","if"],"group":"20:6","count":0},{"id":14,"loc":{"start":{"line":20,"column":39},"end":{"line":20,"column":47}},"tags":["branch","line","if"],"group":"20:6","count":1},{"id":15,"loc":{"start":{"line":20,"column":40},"end":{"line":20,"column":46},"identifierName":"ignore"},"tags":["line"],"count":1},{"id":16,"loc":{"start":{"line":21,"column":15},"end":{"line":21,"column":19}},"tags":["line"],"count":1},{"id":17,"loc":{"start":{"line":24,"column":9},"end":{"line":24,"column":14}},"tags":["line","statement"],"count":0},{"id":18,"loc":{"start":{"line":33,"column":7},"end":{"line":40,"column":1}},"tags":["function"],"name":"key","count":3},{"id":19,"loc":{"start":{"line":34,"column":15},"end":{"line":34,"column":24}},"tags":["statement","variable","line"],"count":3},{"id":20,"loc":{"start":{"line":35,"column":16},"end":{"line":38,"column":3}},"tags":["branch","line","if"],"group":"35:2","count":3},{"id":21,"loc":{"start":{"line":38,"column":3},"end":{"line":38,"column":3}},"tags":["branch","if"],"group":"35:2","count":0},{"id":22,"loc":{"start":{"line":36,"column":21},"end":{"line":36,"column":35}},"tags":["statement","variable","line"],"count":3},{"id":23,"loc":{"start":{"line":37,"column":11},"end":{"line":37,"column":48}},"tags":["line","statement"],"count":3},{"id":24,"loc":{"start":{"line":39,"column":2},"end":{"line":39,"column":56}},"tags":["statement","line"],"count":0},{"id":25,"loc":{"start":{"line":49,"column":0},"end":{"line":52,"column":1}},"tags":["function"],"name":"X","count":13},{"id":26,"loc":{"start":{"line":50,"column":2},"end":{"line":50,"column":22}},"tags":["statement","line"],"count":13},{"id":27,"loc":{"start":{"line":51,"column":9},"end":{"line":51,"column":13},"identifierName":"node"},"tags":["line","statement"],"count":13},{"id":28,"loc":{"start":{"line":54,"column":0},"end":{"line":56,"column":1}},"tags":["function"],"name":"ignore","count":83},{"id":29,"loc":{"start":{"line":55,"column":10},"end":{"line":55,"column":59}},"tags":["line","statement"],"count":83},{"id":30,"loc":{"start":{"line":55,"column":10},"end":{"line":55,"column":38}},"tags":["branch","logic"],"group":"55:10","count":83},{"id":31,"loc":{"start":{"line":55,"column":42},"end":{"line":55,"column":59}},"tags":["branch","logic"],"group":"55:10","count":20},{"id":32,"loc":{"start":{"line":55,"column":10},"end":{"line":55,"column":20}},"tags":["branch","logic"],"group":"55:10","count":83},{"id":33,"loc":{"start":{"line":55,"column":24},"end":{"line":55,"column":38}},"tags":["branch","logic"],"group":"55:10","count":83},{"id":34,"loc":{"start":{"line":58,"column":0},"end":{"line":60,"column":1}},"tags":["function"],"name":"standardize","count":21},{"id":35,"loc":{"start":{"line":59,"column":9},"end":{"line":59,"column":74}},"tags":["line","statement"],"count":21},{"id":36,"loc":{"start":{"line":59,"column":9},"end":{"line":59,"column":74}},"tags":["function"],"name":"@59:9","count":83},{"id":37,"loc":{"start":{"line":59,"column":41},"end":{"line":59,"column":50},"identifierName":"undefined"},"tags":["branch","line","if"],"group":"59:26","count":63},{"id":38,"loc":{"start":{"line":59,"column":53},"end":{"line":59,"column":74}},"tags":["branch","line","if"],"group":"59:26","count":20},{"id":39,"loc":{"start":{"line":66,"column":15},"end":{"line":577,"column":1}},"tags":["function"],"name":"instrumenter","count":1},{"id":40,"loc":{"start":{"line":74,"column":2},"end":{"line":98,"column":3}},"tags":["function"],"name":"createMarker","count":8},{"id":41,"loc":{"start":{"line":75,"column":37},"end":{"line":75,"column":44},"identifierName":"options"},"tags":["statement","variable","line"],"count":8},{"id":42,"loc":{"start":{"line":76,"column":21},"end":{"line":76,"column":32}},"tags":["statement","variable","line"],"count":8},{"id":43,"loc":{"start":{"line":77,"column":15},"end":{"line":77,"column":38}},"tags":["statement","variable","line"],"count":8},{"id":44,"loc":{"start":{"line":79,"column":4},"end":{"line":86,"column":7}},"tags":["statement","line"],"count":8},{"id":45,"loc":{"start":{"line":85,"column":13},"end":{"line":85,"column":14}},"tags":["line"],"count":8},{"id":46,"loc":{"start":{"line":89,"column":11},"end":{"line":97,"column":13}},"tags":["line","statement"],"count":8},{"id":47,"loc":{"start":{"line":105,"column":2},"end":{"line":112,"column":3}},"tags":["function"],"name":"isInstrumentableStatement","count":1},{"id":48,"loc":{"start":{"line":106,"column":19},"end":{"line":106,"column":34}},"tags":["statement","variable","line"],"count":1},{"id":49,"loc":{"start":{"line":107,"column":11},"end":{"line":111,"column":29}},"tags":["line","statement"],"count":1},{"id":50,"loc":{"start":{"line":107,"column":11},"end":{"line":110,"column":37}},"tags":["branch","logic"],"group":"107:11","count":1},{"id":51,"loc":{"start":{"line":111,"column":6},"end":{"line":111,"column":29}},"tags":["branch","logic"],"group":"107:11","count":1},{"id":52,"loc":{"start":{"line":107,"column":11},"end":{"line":109,"column":35}},"tags":["branch","logic"],"group":"107:11","count":1},{"id":53,"loc":{"start":{"line":110,"column":6},"end":{"line":110,"column":37}},"tags":["branch","logic"],"group":"107:11","count":1},{"id":54,"loc":{"start":{"line":107,"column":11},"end":{"line":108,"column":37}},"tags":["branch","logic"],"group":"107:11","count":1},{"id":55,"loc":{"start":{"line":109,"column":6},"end":{"line":109,"column":35}},"tags":["branch","logic"],"group":"107:11","count":1},{"id":56,"loc":{"start":{"line":107,"column":11},"end":{"line":107,"column":38}},"tags":["branch","logic"],"group":"107:11","count":1},{"id":57,"loc":{"start":{"line":108,"column":6},"end":{"line":108,"column":37}},"tags":["branch","logic"],"group":"107:11","count":1},{"id":58,"loc":{"start":{"line":122,"column":2},"end":{"line":142,"column":3}},"tags":["function"],"name":"instrument","count":2},{"id":59,"loc":{"start":{"line":126,"column":4},"end":{"line":131,"column":5}},"tags":["function"],"name":"marker","count":2},{"id":60,"loc":{"start":{"line":127,"column":13},"end":{"line":130,"column":8}},"tags":["line","statement"],"count":2},{"id":61,"loc":{"start":{"line":128,"column":13},"end":{"line":128,"column":26}},"tags":["line"],"count":2},{"id":62,"loc":{"start":{"line":133,"column":33},"end":{"line":135,"column":5}},"tags":["branch","line","if"],"group":"133:4","count":0},{"id":63,"loc":{"start":{"line":134,"column":6},"end":{"line":134,"column":76}},"tags":["statement","line"],"count":0},{"id":64,"loc":{"start":{"line":135,"column":36},"end":{"line":137,"column":5}},"tags":["branch","line","if"],"group":"133:4","count":1},{"id":65,"loc":{"start":{"line":136,"column":6},"end":{"line":136,"column":75}},"tags":["statement","line"],"count":1},{"id":66,"loc":{"start":{"line":136,"column":51},"end":{"line":136,"column":59}},"tags":["line"],"count":1},{"id":67,"loc":{"start":{"line":136,"column":61},"end":{"line":136,"column":70}},"tags":["line"],"count":1},{"id":68,"loc":{"start":{"line":137,"column":35},"end":{"line":141,"column":5}},"tags":["branch","line","if"],"group":"133:4","count":1},{"id":69,"loc":{"start":{"line":141,"column":5},"end":{"line":141,"column":5}},"tags":["branch","if"],"group":"133:4","count":0},{"id":70,"loc":{"start":{"line":138,"column":43},"end":{"line":140,"column":7}},"tags":["branch","line","if"],"group":"133:4","count":1},{"id":71,"loc":{"start":{"line":140,"column":7},"end":{"line":140,"column":7}},"tags":["branch","if"],"group":"133:4","count":0},{"id":72,"loc":{"start":{"line":139,"column":8},"end":{"line":139,"column":66}},"tags":["statement","line"],"count":1},{"id":73,"loc":{"start":{"line":150,"column":2},"end":{"line":155,"column":3}},"tags":["function"],"name":"visitStatement","count":1},{"id":74,"loc":{"start":{"line":151,"column":4},"end":{"line":154,"column":7}},"tags":["statement","line"],"count":1},{"id":75,"loc":{"start":{"line":152,"column":12},"end":{"line":152,"column":33}},"tags":["line"],"count":1},{"id":76,"loc":{"start":{"line":152,"column":13},"end":{"line":152,"column":24}},"tags":["line"],"count":1},{"id":77,"loc":{"start":{"line":152,"column":26},"end":{"line":152,"column":32}},"tags":["line"],"count":1},{"id":78,"loc":{"start":{"line":153,"column":11},"end":{"line":153,"column":24}},"tags":["line"],"count":1},{"id":79,"loc":{"start":{"line":164,"column":2},"end":{"line":170,"column":3}},"tags":["function"],"name":"visitFunction","count":0},{"id":80,"loc":{"start":{"line":165,"column":4},"end":{"line":169,"column":7}},"tags":["statement","line"],"count":0},{"id":81,"loc":{"start":{"line":166,"column":12},"end":{"line":166,"column":24}},"tags":["line"],"count":0},{"id":82,"loc":{"start":{"line":166,"column":13},"end":{"line":166,"column":23}},"tags":["line"],"count":0},{"id":83,"loc":{"start":{"line":167,"column":12},"end":{"line":167,"column":62}},"tags":["line"],"count":0},{"id":84,"loc":{"start":{"line":167,"column":27},"end":{"line":167,"column":44}},"tags":["branch","line","if"],"group":"167:12","count":0},{"id":85,"loc":{"start":{"line":167,"column":47},"end":{"line":167,"column":62}},"tags":["branch","line","if"],"group":"167:12","count":0},{"id":86,"loc":{"start":{"line":168,"column":11},"end":{"line":168,"column":24}},"tags":["line"],"count":0},{"id":87,"loc":{"start":{"line":180,"column":2},"end":{"line":229,"column":3}},"tags":["function"],"name":"visitSwitchStatement","count":0},{"id":88,"loc":{"start":{"line":181,"column":21},"end":{"line":181,"column":26}},"tags":["statement","variable","line"],"count":0},{"id":89,"loc":{"start":{"line":182,"column":4},"end":{"line":202,"column":7}},"tags":["statement","line"],"count":0},{"id":90,"loc":{"start":{"line":182,"column":30},"end":{"line":202,"column":5}},"tags":["function"],"name":"@182:30","count":0},{"id":91,"loc":{"start":{"line":183,"column":27},"end":{"line":185,"column":7}},"tags":["branch","line","if"],"group":"183:6","count":0},{"id":92,"loc":{"start":{"line":185,"column":7},"end":{"line":185,"column":7}},"tags":["branch","if"],"group":"183:6","count":0},{"id":93,"loc":{"start":{"line":184,"column":8},"end":{"line":184,"column":74}},"tags":["statement","line"],"count":0},{"id":94,"loc":{"start":{"line":186,"column":44},"end":{"line":192,"column":7}},"tags":["branch","line","if"],"group":"186:6","count":0},{"id":95,"loc":{"start":{"line":192,"column":7},"end":{"line":192,"column":7}},"tags":["branch","if"],"group":"186:6","count":0},{"id":96,"loc":{"start":{"line":187,"column":8},"end":{"line":191,"column":10}},"tags":["statement","line"],"count":0},{"id":97,"loc":{"start":{"line":194,"column":36},"end":{"line":196,"column":7}},"tags":["branch","line","if"],"group":"194:6","count":0},{"id":98,"loc":{"start":{"line":196,"column":7},"end":{"line":196,"column":7}},"tags":["branch","if"],"group":"194:6","count":0},{"id":99,"loc":{"start":{"line":195,"column":8},"end":{"line":195,"column":26}},"tags":["statement","line"],"count":0},{"id":100,"loc":{"start":{"line":197,"column":6},"end":{"line":201,"column":10}},"tags":["statement","line"],"count":0},{"id":101,"loc":{"start":{"line":198,"column":14},"end":{"line":198,"column":34}},"tags":["line"],"count":0},{"id":102,"loc":{"start":{"line":198,"column":15},"end":{"line":198,"column":23}},"tags":["line"],"count":0},{"id":103,"loc":{"start":{"line":198,"column":25},"end":{"line":198,"column":33}},"tags":["line"],"count":0},{"id":104,"loc":{"start":{"line":199,"column":13},"end":{"line":199,"column":27}},"tags":["line"],"count":0},{"id":105,"loc":{"start":{"line":200,"column":15},"end":{"line":200,"column":24}},"tags":["line"],"count":0},{"id":106,"loc":{"start":{"line":206,"column":21},"end":{"line":228,"column":5}},"tags":["branch","line","if"],"group":"206:4","count":0},{"id":107,"loc":{"start":{"line":228,"column":5},"end":{"line":228,"column":5}},"tags":["branch","if"],"group":"206:4","count":0},{"id":108,"loc":{"start":{"line":209,"column":20},"end":{"line":209,"column":37}},"tags":["statement","variable","line"],"count":0},{"id":109,"loc":{"start":{"line":210,"column":28},"end":{"line":215,"column":7}},"tags":["branch","line","if"],"group":"206:4","count":0},{"id":110,"loc":{"start":{"line":215,"column":7},"end":{"line":215,"column":7}},"tags":["branch","if"],"group":"206:4","count":0},{"id":111,"loc":{"start":{"line":211,"column":8},"end":{"line":214,"column":10}},"tags":["statement","line"],"count":0},{"id":112,"loc":{"start":{"line":217,"column":6},"end":{"line":227,"column":10}},"tags":["statement","line"],"count":0},{"id":113,"loc":{"start":{"line":218,"column":8},"end":{"line":225,"column":11}},"tags":["line"],"count":0},{"id":114,"loc":{"start":{"line":226,"column":8},"end":{"line":226,"column":30}},"tags":["line"],"count":0},{"id":115,"loc":{"start":{"line":219,"column":16},"end":{"line":219,"column":36}},"tags":["line"],"count":0},{"id":116,"loc":{"start":{"line":219,"column":17},"end":{"line":219,"column":25}},"tags":["line"],"count":0},{"id":117,"loc":{"start":{"line":219,"column":27},"end":{"line":219,"column":35}},"tags":["line"],"count":0},{"id":118,"loc":{"start":{"line":220,"column":15},"end":{"line":223,"column":11}},"tags":["line"],"count":0},{"id":119,"loc":{"start":{"line":221,"column":19},"end":{"line":221,"column":36}},"tags":["line"],"count":0},{"id":120,"loc":{"start":{"line":222,"column":17},"end":{"line":222,"column":34}},"tags":["line"],"count":0},{"id":121,"loc":{"start":{"line":224,"column":17},"end":{"line":224,"column":26}},"tags":["line"],"count":0},{"id":122,"loc":{"start":{"line":237,"column":2},"end":{"line":245,"column":3}},"tags":["function"],"name":"visitVariableDeclaration","count":1},{"id":123,"loc":{"start":{"line":238,"column":4},"end":{"line":244,"column":7}},"tags":["statement","line"],"count":1},{"id":124,"loc":{"start":{"line":238,"column":37},"end":{"line":244,"column":5}},"tags":["function"],"name":"@238:37","count":1},{"id":125,"loc":{"start":{"line":239,"column":28},"end":{"line":243,"column":7}},"tags":["branch","line","if"],"group":"239:6","count":1},{"id":126,"loc":{"start":{"line":243,"column":7},"end":{"line":243,"column":7}},"tags":["branch","if"],"group":"239:6","count":0},{"id":127,"loc":{"start":{"line":240,"column":8},"end":{"line":242,"column":11}},"tags":["statement","line"],"count":1},{"id":128,"loc":{"start":{"line":241,"column":16},"end":{"line":241,"column":49}},"tags":["line"],"count":1},{"id":129,"loc":{"start":{"line":241,"column":17},"end":{"line":241,"column":28}},"tags":["line"],"count":1},{"id":130,"loc":{"start":{"line":241,"column":30},"end":{"line":241,"column":40}},"tags":["line"],"count":1},{"id":131,"loc":{"start":{"line":241,"column":42},"end":{"line":241,"column":48}},"tags":["line"],"count":1},{"id":132,"loc":{"start":{"line":254,"column":2},"end":{"line":285,"column":3}},"tags":["function"],"name":"visitWhileLoop","count":0},{"id":133,"loc":{"start":{"line":255,"column":17},"end":{"line":255,"column":33}},"tags":["statement","variable","line"],"count":0},{"id":134,"loc":{"start":{"line":256,"column":18},"end":{"line":256,"column":27}},"tags":["statement","variable","line"],"count":0},{"id":135,"loc":{"start":{"line":265,"column":4},"end":{"line":284,"column":7}},"tags":["statement","line"],"count":0},{"id":136,"loc":{"start":{"line":271,"column":16},"end":{"line":271,"column":64}},"tags":["line"],"count":0},{"id":137,"loc":{"start":{"line":271,"column":17},"end":{"line":271,"column":25}},"tags":["line"],"count":0},{"id":138,"loc":{"start":{"line":271,"column":27},"end":{"line":271,"column":33}},"tags":["line"],"count":0},{"id":139,"loc":{"start":{"line":271,"column":35},"end":{"line":271,"column":46}},"tags":["line"],"count":0},{"id":140,"loc":{"start":{"line":271,"column":48},"end":{"line":271,"column":54}},"tags":["line"],"count":0},{"id":141,"loc":{"start":{"line":271,"column":56},"end":{"line":271,"column":63}},"tags":["line"],"count":0},{"id":142,"loc":{"start":{"line":272,"column":15},"end":{"line":272,"column":28}},"tags":["line"],"count":0},{"id":143,"loc":{"start":{"line":279,"column":16},"end":{"line":279,"column":51}},"tags":["line"],"count":0},{"id":144,"loc":{"start":{"line":279,"column":17},"end":{"line":279,"column":25}},"tags":["line"],"count":0},{"id":145,"loc":{"start":{"line":279,"column":27},"end":{"line":279,"column":33}},"tags":["line"],"count":0},{"id":146,"loc":{"start":{"line":279,"column":35},"end":{"line":279,"column":41}},"tags":["line"],"count":0},{"id":147,"loc":{"start":{"line":279,"column":43},"end":{"line":279,"column":50}},"tags":["line"],"count":0},{"id":148,"loc":{"start":{"line":280,"column":15},"end":{"line":280,"column":28}},"tags":["line"],"count":0},{"id":149,"loc":{"start":{"line":294,"column":2},"end":{"line":350,"column":3}},"tags":["function"],"name":"visitTryStatement","count":0},{"id":150,"loc":{"start":{"line":295,"column":18},"end":{"line":295,"column":27}},"tags":["statement","variable","line"],"count":0},{"id":151,"loc":{"start":{"line":296,"column":17},"end":{"line":296,"column":34}},"tags":["statement","variable","line"],"count":0},{"id":152,"loc":{"start":{"line":297,"column":20},"end":{"line":297,"column":74}},"tags":["statement","variable","line"],"count":0},{"id":153,"loc":{"start":{"line":298,"column":4},"end":{"line":298,"column":62}},"tags":["statement","line"],"count":0},{"id":154,"loc":{"start":{"line":299,"column":4},"end":{"line":301,"column":7}},"tags":["statement","line"],"count":0},{"id":155,"loc":{"start":{"line":302,"column":30},"end":{"line":304,"column":5}},"tags":["statement","variable","line"],"count":0},{"id":156,"loc":{"start":{"line":306,"column":29},"end":{"line":314,"column":5}},"tags":["branch","line","if"],"group":"306:4","count":0},{"id":157,"loc":{"start":{"line":314,"column":11},"end":{"line":325,"column":5}},"tags":["branch","line","if"],"group":"306:4","count":0},{"id":158,"loc":{"start":{"line":307,"column":22},"end":{"line":307,"column":46}},"tags":["statement","variable","line"],"count":0},{"id":159,"loc":{"start":{"line":308,"column":6},"end":{"line":308,"column":31}},"tags":["statement","line"],"count":0