@teamscale/lib-instrument 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.d.mts DELETED
@@ -1,45 +0,0 @@
1
- import { NodePath } from "@babel/core";
2
- import { RawSourceMap, SourceMapConsumer } from "source-map";
3
- import * as _babel_types0 from "@babel/types";
4
- import { Program, SourceLocation } from "@babel/types";
5
- import { ParserPlugin } from "@babel/parser";
6
-
7
- //#region src/utils.d.ts
8
- type InstrumentationOptions = Partial<{
9
- reportLogic: boolean;
10
- coverageGlobalScopeFunc: boolean;
11
- ignoreClassMethods: string[];
12
- inputSourceMap?: RawSourceMap;
13
- isInstrumentedToken?: string;
14
- codeToPrepend?: string;
15
- shouldInstrumentCallback?: (path: NodePath, loc: SourceLocation) => boolean;
16
- }>;
17
- //#endregion
18
- //#region src/instrumenter.d.ts
19
- type InstrumenterOptions = InstrumentationOptions & Partial<{
20
- preserveComments: boolean;
21
- compact: boolean;
22
- esModules: boolean;
23
- autoWrap: boolean;
24
- produceSourceMap: 'none' | 'inline' | 'external';
25
- debug: boolean;
26
- parserPlugins: ParserPlugin[];
27
- }>;
28
- declare class Instrumenter {
29
- private readonly opts;
30
- constructor(opts?: Partial<InstrumenterOptions>);
31
- instrument(code: string, filename: string | undefined, inputSourceMap: RawSourceMap | undefined, shouldInstrumentCallback?: (path: NodePath, location: SourceLocation) => boolean): Promise<string>;
32
- }
33
- //#endregion
34
- //#region src/visitor.d.ts
35
- type BabelTypes = typeof _babel_types0;
36
- declare function programVisitor(types: BabelTypes, inputSourceMapConsumer: SourceMapConsumer | undefined, opts: InstrumentationOptions): {
37
- enter(path: NodePath<Program>): void;
38
- exit(path: NodePath<Program>): void;
39
- };
40
- //#endregion
41
- //#region src/index.d.ts
42
- declare function createInstrumenter(opts: InstrumenterOptions): Instrumenter;
43
- //#endregion
44
- export { type InstrumenterOptions, createInstrumenter, programVisitor };
45
- //# sourceMappingURL=index.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/utils.ts","../src/instrumenter.ts","../src/visitor.ts","../src/index.ts"],"mappings":";;;;;;;KAOY,sBAAA,GAAyB,OAAA;EAAA,WAAA;EAAA,uBAAA;EAAA,kBAAA;EAAA,cAAA,GAWhB,YAAA;EAAA,mBAAA;EAAA,aAAA;EAAA,wBAAA,IAAA,IAAA,EASiB,QAAA,EAAA,GAAA,EAAe,cAAA;AAAA;;;KCZzC,mBAAA,GAAsB,sBAAA,GAAyB,OAAA;EAAA,gBAAA;EAAA,OAAA;EAAA,SAAA;EAAA,QAAA;EAAA,gBAAA;EAAA,KAAA;EAAA,aAAA,EAoBxC,YAAA;AAAA;AAAA,cAgBN,YAAA;EAAA,iBAAA,IAAA;EAAA,YAAA,IAAA,GAIU,OAAA,CAAQ,mBAAA;EAAA,WAAA,IAAA,UAAA,QAAA,sBAAA,cAAA,EAgBkD,YAAA,cAAA,wBAAA,IAAA,IAAA,EAC1B,QAAA,EAAA,QAAA,EAAoB,cAAA,eAA6B,OAAA;AAAA;;;KC7DnG,UAAA,UAAU,aAAA;AAAA,iBA6nBC,cAAA,CAAA,KAAA,EAAsB,UAAA,EAAA,sBAAA,EACiB,iBAAA,cAAA,IAAA,EAClB,sBAAA;EAAA,KAAA,CAAA,IAAA,EAYjB,QAAA,CAAS,OAAA;EAAA,IAAA,CAAA,IAAA,EASV,QAAA,CAAS,OAAA;AAAA;;;iBCrpBZ,kBAAA,CAAA,IAAA,EAAyB,mBAAA,GAAsB,YAAA"}
package/lib/index.mjs.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/origins.ts","../src/visitor.ts","../src/instrumenter.ts","../src/index.ts"],"sourcesContent":["import {SourceLocation} from \"@babel/types\";\nimport {NullableMappedPosition, SourceMapConsumer} from \"source-map\";\n\n/**\n * Generator for identifiers that are unique across files to instrument.\n * Relevant in case no Ecmascript modules are used.\n *\n * We assume that the files to be executed in a browser can\n * stem from different runs of the instrumenter. We have to decrease\n * the probability of colliding identifiers.\n */\nexport const fileIdSeqGenerator: { next: () => string } = (() => {\n const instrumenterRunId = process.pid;\n let fileIdSeq = 0;\n\n return {\n next: () => {\n fileIdSeq++;\n let num: number;\n if (fileIdSeq < 10000) {\n num = instrumenterRunId * 10000 + fileIdSeq;\n } else if (fileIdSeq < 100000) {\n num = instrumenterRunId * 100000 + fileIdSeq;\n } else {\n throw new Error(`Not more that 100k files supported to be instrumented in one run.`);\n }\n return num.toString(36);\n }\n };\n})();\n\n/**\n * Mapping source locations to their origins, before the last transpilation,\n * based on the source map.\n */\nexport class SourceOrigins {\n\n private readonly sourceMap?: SourceMapConsumer;\n\n /**\n * The mapping of file ids to the file names in the transpiler origin,\n * that is, the file names found in the source map.\n */\n public readonly originToIdMap: Map<string, string>;\n\n constructor(sourceMap: SourceMapConsumer | undefined) {\n this.originToIdMap = new Map();\n this.sourceMap = sourceMap;\n }\n\n /**\n * Register source origin file and retrieve a unique identifier for it; furthermore, map\n * the given location to the location in the origin.\n */\n ensureKnownOrigin(loc: SourceLocation): [string, SourceLocation] {\n let startPos: NullableMappedPosition | undefined = undefined;\n let endPos: NullableMappedPosition | undefined = undefined;\n let filename = loc.filename ?? '';\n\n if (this.sourceMap) {\n startPos = this.sourceMap.originalPositionFor({line: loc.start.line, column: loc.start.column});\n endPos = this.sourceMap.originalPositionFor({line: loc.end.line, column: loc.end.column});\n filename = startPos.source ?? loc.filename;\n }\n\n if (!startPos || !endPos) {\n startPos = { line: loc.start.line, column: loc.start.column, source: null, name: null };\n endPos = { line: loc.end.line, column: loc.end.column, source: null, name: null }\n }\n\n let id = this.originToIdMap.get(filename)\n if (!id) {\n id = `_$o${fileIdSeqGenerator.next()}`;\n this.originToIdMap.set(filename, id);\n }\n\n return [id, {\n start: { line: startPos.line!, column: startPos.column!, index: -1 },\n end: { line: endPos.line!, column: endPos.column!, index: -1 },\n filename,\n identifierName: startPos.name }];\n }\n\n}","import {Node, NodePath, parse} from '@babel/core';\nimport {Visitor} from \"@babel/traverse\";\nimport {\n ArrowFunctionExpression,\n BlockStatement, CallExpression, ClassMethod, Comment, ConditionalExpression,\n Expression, FunctionDeclaration, FunctionExpression,\n Identifier, IfStatement,\n LogicalExpression, NumericLiteral, ObjectMethod, Program,\n SourceLocation, Statement, SwitchCase, VariableDeclaration\n} from \"@babel/types\";\n\ntype BabelTypes = typeof import(\"@babel/types\")\n\nimport {SourceMapConsumer} from \"source-map\";\nimport {CodeRange} from \"./utils\";\nimport {SourceOrigins} from \"./origins\";\nimport {InstrumentationOptions} from \"./utils\";\n\n// Pattern for istanbul to ignore a section\nconst COMMENT_RE = /^\\s*istanbul\\s+ignore\\s+(if|else|next)(?=\\W|$)/;\n\n// Pattern for istanbul to ignore the whole file\nconst COMMENT_FILE_RE = /^\\s*istanbul\\s+ignore\\s+(file)(?=\\W|$)/;\n\ntype CovNode = Node & { __cov__?: Record<string, unknown> };\n\ntype LeafNode = { node: Node, parent: Node, property: string };\n\n/**\n * `VisitState` holds the state of the visitor, provides helper functions\n * and is the `this` for the individual coverage visitors.\n */\nclass VisitState {\n\n types: BabelTypes;\n attrs: Record<string, unknown>;\n nextIgnore: Node | null;\n ignoreClassMethods: string[];\n reportLogic: boolean;\n\n /** Callback to determine if the given source location should be instrumented. */\n shouldInstrumentCallback?: (path: NodePath, loc: SourceLocation) => boolean;\n\n /** Object that manages the mapping to the original code, using source maps. */\n public readonly origins: SourceOrigins;\n\n constructor(\n types: BabelTypes,\n inputSourceMapConsumer: SourceMapConsumer | undefined,\n ignoreClassMethods: string[] = [],\n reportLogic = false,\n shouldInstrumentCallback?: (path: NodePath, loc: SourceLocation) => boolean\n ) {\n this.attrs = {};\n this.nextIgnore = null;\n this.ignoreClassMethods = ignoreClassMethods;\n this.types = types;\n this.reportLogic = reportLogic;\n this.shouldInstrumentCallback = shouldInstrumentCallback;\n this.origins = new SourceOrigins(inputSourceMapConsumer);\n }\n\n /**\n * Use the configured callback, if available, to check if the given source\n * location should be instrumented.\n */\n shouldInstrument(path: NodePath, loc: SourceLocation): boolean {\n if (this.shouldInstrumentCallback) {\n return this.shouldInstrumentCallback(path, loc);\n }\n return true;\n }\n\n /** Should we ignore the node? Yes, if specifically ignoring or if the node is generated. */\n shouldIgnore(path: NodePath): boolean {\n return this.nextIgnore !== null || !path.node.loc;\n }\n\n /** Extract the ignore comment hint (next|if|else) or null. */\n hintFor(node: Node): string | null {\n let hint: string | null = null;\n if (node.leadingComments) {\n node.leadingComments.forEach(c => {\n const v = (c.value || '').trim();\n const groups = COMMENT_RE.exec(v);\n if (groups) {\n hint = groups[1];\n }\n });\n }\n return hint;\n }\n\n /**\n * For these expressions the statement counter needs to be hoisted, so\n * function name inference can be preserved.\n */\n counterNeedsHoisting(path: NodePath): boolean {\n return (\n path.isFunctionExpression() ||\n path.isArrowFunctionExpression() ||\n path.isClassExpression()\n );\n }\n\n /** All the generic stuff that needs to be done on enter for every node. */\n onEnter(path: NodePath) {\n const n = path.node;\n\n // if already ignoring, nothing more to do\n if (this.nextIgnore !== null) {\n return;\n }\n\n // check hint to see if ignore should be turned on\n const hint = this.hintFor(n);\n if (hint === 'next') {\n this.nextIgnore = n;\n return;\n }\n\n // else check custom node attribute set by a prior visitor\n if (this.getAttr(path.node, 'skip-all') !== null) {\n this.nextIgnore = n;\n }\n\n // else check for ignored class methods\n if (\n path.isFunctionExpression() &&\n this.ignoreClassMethods.some(\n name => name === path.node.id?.name\n )\n ) {\n this.nextIgnore = n;\n return;\n }\n\n if (\n path.isClassMethod() &&\n this.ignoreClassMethods.some(name => name === (path.node.key as Identifier).name)\n ) {\n this.nextIgnore = n;\n return;\n }\n }\n\n /**\n * All the generic stuff on exit of a node, including resetting ignores and custom node attrs.\n */\n onExit(path: NodePath) {\n // restore ignore status, if needed\n if (path.node === this.nextIgnore) {\n this.nextIgnore = null;\n }\n // nuke all attributes for the node\n delete (path.node as CovNode).__cov__;\n }\n\n /** Set a node attribute for the supplied node. */\n setAttr(node: CovNode, name: string, value: unknown) {\n node.__cov__ = node.__cov__ || {};\n node.__cov__[name] = value;\n }\n\n /** Retrieve a node attribute for the supplied node or null. */\n getAttr(node: CovNode, name: string): unknown {\n const c = node.__cov__;\n if (!c) {\n return null;\n }\n return c[name];\n }\n\n insertCounter(path: NodePath, increment: Expression): void {\n const T = this.types;\n if (path.isBlockStatement()) {\n path.node.body.unshift(T.expressionStatement(increment));\n } else if (path.isStatement()) {\n path.insertBefore(T.expressionStatement(increment));\n } else if (\n this.counterNeedsHoisting(path) &&\n T.isVariableDeclarator(path.parent)\n ) {\n // make an attempt to hoist the statement counter, so that\n // function names are maintained.\n const grandParentPath = path.parentPath?.parentPath;\n if (grandParentPath && T.isExportNamedDeclaration(grandParentPath.parent)) {\n grandParentPath.parentPath?.insertBefore(\n T.expressionStatement(increment)\n );\n } else if (\n grandParentPath &&\n (T.isProgram(grandParentPath.parent) ||\n T.isBlockStatement(grandParentPath.parent))\n ) {\n grandParentPath.insertBefore(T.expressionStatement(increment));\n } else {\n path.replaceWith(T.sequenceExpression([increment, path.node as Expression]));\n }\n } else if (\n path.isExpression()\n ) {\n path.replaceWith(T.sequenceExpression([increment, path.node]));\n } else {\n console.error(\n 'Unable to insert counter for node type:',\n path.node.type\n );\n }\n }\n\n insertFunctionCounter(path: NodePath<CallableNode>) {\n const T = this.types;\n\n if (!(path.node?.loc)) {\n return;\n }\n const n = path.node;\n\n let declarationLocation: SourceLocation | undefined;\n switch (n.type) {\n case 'FunctionDeclaration':\n case 'FunctionExpression':\n if (n.id) {\n declarationLocation = n.id.loc ?? undefined;\n }\n break;\n }\n\n const body = path.get('body') as NodePath;\n const loc = path.node.loc ?? declarationLocation;\n const [originFileId, originPos] = this.origins.ensureKnownOrigin(loc);\n\n if (body.isBlockStatement() && this.shouldInstrument(path, originPos)) {\n // For functions, we only cover the first line of its body.\n originPos.end = originPos.start;\n const increment = newLineCoverageExpression(originFileId, originPos);\n body.node.body.unshift(T.expressionStatement(increment));\n }\n }\n\n insertStatementCounter(path: NodePath) {\n const loc = path.node?.loc;\n if (!loc) {\n return;\n }\n\n const [originFileId, originPos] = this.origins.ensureKnownOrigin(loc);\n if (!this.shouldInstrument(path, originPos)) {\n return;\n }\n\n const increment = newLineCoverageExpression(originFileId, originPos);\n this.insertCounter(path, increment);\n }\n\n insertBranchCounter(path: NodePath, loc: SourceLocation | null | undefined) {\n loc = loc ?? path.node.loc!;\n if (!loc) {\n return;\n }\n\n const [originFileId, originPos] = this.origins.ensureKnownOrigin(loc);\n if (this.shouldInstrument(path, originPos)) {\n const increment = newLineCoverageExpression(originFileId, originPos)\n this.insertCounter(path, increment);\n }\n }\n\n findLeaves(node: Node, accumulator: LeafNode[], parent: Node | undefined, property: string | undefined) {\n if (!node) {\n return;\n }\n\n if (node.type === 'LogicalExpression') {\n const hint = this.hintFor(node);\n if (hint !== 'next') {\n this.findLeaves(node.left, accumulator, node, 'left');\n this.findLeaves(node.right, accumulator, node, 'right');\n }\n } else {\n accumulator.push({\n node,\n parent: parent!,\n property: property!\n });\n }\n }\n}\n\n/**\n * Create a line coverage reporting statement node.\n */\nfunction newLineCoverageExpression(\n originFileId: string,\n range: CodeRange\n): CallExpression {\n const argumentList = [\n { type: 'Identifier', name: originFileId } as Identifier,\n { type: 'NumericLiteral', value: range.start.line } as NumericLiteral\n ];\n\n // Only pass end line argument if they are different.\n // See also https://v8.dev/blog/adaptor-frame for performance considerations\n if (range.start.line !== range.end.line) {\n argumentList.push({ type: 'NumericLiteral', value: range.end.line } as NumericLiteral)\n }\n\n return {\n type: 'CallExpression',\n callee: { type: 'Identifier', name: '_$l' } as Identifier,\n arguments: argumentList\n };\n}\n\n/**\n * Creates a new string constant AST node.\n */\nfunction newStringConstDeclarationNode(name: string, value: string): VariableDeclaration {\n return {\n type: 'VariableDeclaration',\n kind: 'const',\n declarations: [\n {\n type: 'VariableDeclarator',\n id: {\n type: 'Identifier',\n name\n },\n init: {\n type: 'StringLiteral',\n value\n }\n }\n ]\n };\n}\n\n/**\n * Generic function that takes a set of visitor methods and\n * returns a visitor object with `enter` and `exit` properties,\n * such that:\n *\n * - standard entry processing is done\n * - the supplied visitors are called only when ignore is not in effect;\n * it relieves them from worrying about ignore states and generated nodes.\n * - standard exit processing is done\n */\nfunction entries(...enter) {\n // the enter function\n const wrappedEntry = function (this: VisitState, path: NodePath, node: Node) {\n this.onEnter(path);\n if (this.shouldIgnore(path)) {\n return;\n }\n enter.forEach(e => {\n e.call(this, path, node);\n });\n };\n const exit = function (this: VisitState, path: NodePath) {\n this.onExit(path);\n };\n return {\n enter: wrappedEntry,\n exit\n };\n}\n\nfunction coverStatement(this: VisitState, path: NodePath) {\n this.insertStatementCounter(path);\n}\n\nfunction coverAssignmentPattern(this: VisitState, path: NodePath) {\n this.insertBranchCounter(path.get('right') as NodePath, undefined);\n}\n\ntype CallableNode = ArrowFunctionExpression\n | ClassMethod\n | ObjectMethod\n | FunctionDeclaration\n | FunctionExpression;\n\nfunction coverFunction(this: VisitState, path: NodePath<CallableNode>) {\n this.insertFunctionCounter(path);\n}\n\nfunction coverVariableDeclarator(this: VisitState, path: NodePath) {\n this.insertStatementCounter(path.get('init') as NodePath);\n}\n\nfunction coverClassPropDeclarator(this: VisitState, path: NodePath) {\n this.insertStatementCounter(path.get('value') as NodePath);\n}\n\nfunction coverSequenceExpression(this: VisitState, path: NodePath) {\n const T = this.types;\n if (!path.isSequenceExpression()) {\n return;\n }\n const newExpressions: Expression[] = [];\n for (const expression of path.node.expressions) {\n const [originFileId, originPos] = this.origins.ensureKnownOrigin(expression.loc!);\n if (this.shouldInstrument(path, originPos)) {\n const increment = newLineCoverageExpression(originFileId, originPos);\n newExpressions.push(increment);\n }\n // We must add the expression to be evaluated after the coverage increment\n // to not change the return value of the sequence expression.\n newExpressions.push(expression);\n }\n path.replaceWith(T.sequenceExpression(newExpressions));\n}\n\nfunction makeBlock(this: VisitState, path: NodePath) {\n const T = this.types;\n if (!path.node) {\n path.replaceWith(T.blockStatement([]));\n }\n\n if (path.isSequenceExpression()) {\n coverSequenceExpression.call(this, path);\n } else if (!path.isBlockStatement()) {\n path.replaceWith(T.blockStatement([path.node as Statement]));\n\n const block = path.node as BlockStatement;\n path.node.loc = block.body[0].loc;\n block.body[0].leadingComments = path.node.leadingComments;\n path.node.leadingComments = undefined;\n }\n}\n\nfunction blockProp(prop) {\n return function (this: VisitState, path: NodePath) {\n makeBlock.call(this, path.get(prop) as NodePath);\n };\n}\n\nfunction makeParenthesizedExpressionForNonIdentifier(this: VisitState, path: NodePath) {\n const T = this.types;\n if (path.node && !path.isIdentifier()) {\n path.replaceWith(T.parenthesizedExpression(path.node as Expression));\n }\n}\n\nfunction parenthesizedExpressionProp(prop) {\n return function (this: VisitState, path: NodePath) {\n makeParenthesizedExpressionForNonIdentifier.call(this, path.get(prop) as NodePath);\n };\n}\n\nfunction convertArrowExpression(this: VisitState, path: NodePath<ArrowFunctionExpression>) {\n const node = path.node;\n const T = this.types;\n if (!T.isBlockStatement(node.body)) {\n const bloc = node.body.loc;\n if (node.expression) {\n node.expression = false;\n }\n node.body = T.blockStatement([T.returnStatement(node.body)]);\n // restore body location\n node.body.loc = bloc;\n // set up the location for the return statement so it gets\n // instrumented\n node.body.body[0].loc = bloc;\n }\n}\n\nfunction coverIfBranches(this: VisitState, path: NodePath<IfStatement>) {\n const n = path.node;\n const hint = this.hintFor(n);\n const ignoreIf = hint === 'if';\n const ignoreElse = hint === 'else';\n\n if (ignoreIf) {\n this.setAttr(n.consequent, 'skip-all', true);\n } else {\n this.insertBranchCounter(path.get('consequent'), n.loc);\n }\n\n if (ignoreElse) {\n this.setAttr(n.alternate!, 'skip-all', true);\n } else {\n this.insertBranchCounter(path.get('alternate') as NodePath, undefined);\n }\n}\n\nfunction createSwitchBranch(this: VisitState) {\n // Intentionally left blank\n}\n\nfunction coverSwitchCase(this: VisitState, path: NodePath<SwitchCase>) {\n const T = this.types;\n const loc = path.node.loc;\n if (!loc) {\n return;\n }\n\n const [originFileId, originPos] = this.origins.ensureKnownOrigin(loc);\n if (this.shouldInstrument(path, originPos)) {\n const increment = newLineCoverageExpression(originFileId, originPos);\n path.node.consequent.unshift(T.expressionStatement(increment));\n }\n}\n\nfunction coverTernary(this: VisitState, path: NodePath<ConditionalExpression>) {\n const n = path.node;\n const cHint = this.hintFor(n.consequent);\n const aHint = this.hintFor(n.alternate);\n\n if (cHint !== 'next') {\n this.insertBranchCounter(path.get('consequent'), undefined);\n }\n\n if (aHint !== 'next') {\n this.insertBranchCounter(path.get('alternate'), undefined);\n }\n}\n\nfunction coverLogicalExpression(this: VisitState, path: NodePath<LogicalExpression>) {\n const T = this.types;\n if (path.parentPath.node.type === 'LogicalExpression') {\n return; // already processed\n }\n\n const leaves: LeafNode[] = [];\n this.findLeaves(path.node, leaves, undefined, undefined);\n\n for (const leaf of leaves) {\n const hint = this.hintFor(leaf.node);\n if (hint === 'next') {\n continue;\n }\n\n\n const loc = path.node.loc;\n if (!loc) {\n continue;\n }\n\n const [originFileId, originPos] = this.origins.ensureKnownOrigin(loc);\n if (!this.shouldInstrument(path, originPos)) {\n continue;\n }\n\n const increment = newLineCoverageExpression(originFileId, originPos);\n if (!increment) {\n continue;\n }\n\n leaf.parent[leaf.property] = T.sequenceExpression([\n increment,\n leaf.node as Expression\n ]);\n }\n}\n\nconst codeVisitor: Visitor = {\n ArrowFunctionExpression: entries(convertArrowExpression, coverFunction),\n AssignmentPattern: entries(coverAssignmentPattern),\n BlockStatement: entries(), // ignore processing only\n ExportDefaultDeclaration: entries(), // ignore processing only\n ExportNamedDeclaration: entries(), // ignore processing only\n ClassMethod: entries(coverFunction),\n ClassDeclaration: entries(parenthesizedExpressionProp('superClass')),\n ClassProperty: entries(coverClassPropDeclarator),\n ClassPrivateProperty: entries(coverClassPropDeclarator),\n ObjectMethod: entries(coverFunction),\n ExpressionStatement: entries(coverStatement),\n BreakStatement: entries(coverStatement),\n ContinueStatement: entries(coverStatement),\n DebuggerStatement: entries(coverStatement),\n ReturnStatement: entries(coverStatement),\n ThrowStatement: entries(coverStatement),\n TryStatement: entries(coverStatement),\n VariableDeclaration: entries(), // ignore processing only\n VariableDeclarator: entries(coverVariableDeclarator),\n IfStatement: entries(\n blockProp('consequent'),\n blockProp('alternate'),\n coverStatement,\n coverIfBranches\n ),\n ForStatement: entries(blockProp('body'), coverStatement),\n ForInStatement: entries(blockProp('body'), coverStatement),\n ForOfStatement: entries(blockProp('body'), coverStatement),\n WhileStatement: entries(blockProp('body'), coverStatement),\n DoWhileStatement: entries(blockProp('body'), coverStatement),\n SwitchStatement: entries(createSwitchBranch, coverStatement),\n SwitchCase: entries(coverSwitchCase),\n WithStatement: entries(blockProp('body'), coverStatement),\n FunctionDeclaration: entries(coverFunction),\n FunctionExpression: entries(coverFunction),\n LabeledStatement: entries(coverStatement),\n ConditionalExpression: entries(coverTernary),\n LogicalExpression: entries(coverLogicalExpression),\n SequenceExpression: entries(coverSequenceExpression),\n};\n\n/**\n * The rewire plugin (and potentially other babel middleware)\n * may cause files to be instrumented twice, see:\n * https://github.com/istanbuljs/babel-plugin-istanbul/issues/94\n * we should only instrument code for coverage the first time\n * it's run through lib-instrument.\n */\nfunction alreadyInstrumented(path: NodePath, visitState): boolean {\n return path.scope.hasBinding(visitState.varName);\n}\n\nfunction getParentComments(path: NodePath | null): Array<Comment> {\n if (!path?.parent) {\n return [];\n }\n\n if (!('comments' in path.parent)) {\n return [];\n }\n\n return path.parent.comments as Array<Comment>;\n}\n\nfunction shouldIgnoreFile(programNodePath: NodePath | null): boolean {\n if (!programNodePath) {\n return false;\n }\n\n return getParentComments(programNodePath).some(c => COMMENT_FILE_RE.test(c.value));\n}\n\n/**\n * `programVisitor` is a `babel` adaptor for instrumentation.\n *\n * It returns an object with two methods `enter` and `exit`.\n * These should be assigned to or called from `Program` entry and exit functions\n * in a babel visitor.\n *\n * These functions do not make assumptions about the state set by Babel and thus\n * can be used in a context other than a Babel plugin.\n *\n * The exit function returns an object that currently has the following keys:\n *\n * `fileCoverage` - the file coverage object created for the source file.\n * `sourceMappingURL` - any source mapping URL found when processing the file.\n *\n * @param types - an instance of babel-types.\n * @param inputSourceMapConsumer - access object for the source map of the input.\n * @param opts - additional options.\n */\nexport function programVisitor(types: BabelTypes,\n inputSourceMapConsumer: SourceMapConsumer | undefined,\n opts: InstrumentationOptions) {\n opts = {...opts};\n\n const visitState = new VisitState(\n types,\n inputSourceMapConsumer,\n opts.ignoreClassMethods,\n opts.reportLogic,\n opts.shouldInstrumentCallback\n );\n\n return {\n enter(path: NodePath<Program>): void {\n if (shouldIgnoreFile(path.find(p => p.isProgram()))) {\n return;\n }\n if (alreadyInstrumented(path, visitState)) {\n return;\n }\n path.traverse(codeVisitor, visitState);\n },\n exit(path: NodePath<Program>) {\n if (alreadyInstrumented(path, visitState)) {\n return;\n }\n\n const originData = visitState.origins;\n if (shouldIgnoreFile(path.find(p => p.isProgram()))) {\n return;\n }\n\n const body = path.node.body;\n\n if (opts.codeToPrepend) {\n const codeToPrependAst = parse(opts.codeToPrepend, {sourceType: 'script'});\n if (codeToPrependAst !== null) {\n body.unshift(...codeToPrependAst.program.body);\n }\n }\n\n // Add a variable definition for each origin file on top of the file.\n for (const [originPath, originId] of originData.originToIdMap.entries()) {\n const declaration = newStringConstDeclarationNode(originId, originPath);\n body.unshift(declaration);\n }\n\n // Add a token for signaling that the file has been instrumented.\n if (opts.isInstrumentedToken) {\n types.addComment(path.node, 'leading', opts.isInstrumentedToken, false);\n }\n }\n };\n}\n","/*\n Copyright 2012-2015, Yahoo Inc.\n Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.\n */\nimport {NodePath, transformSync} from '@babel/core';\nimport {SourceLocation} from \"@babel/types\";\nimport {ParserPlugin as PluginConfig} from '@babel/parser';\nimport {RawSourceMap, SourceMapConsumer} from \"source-map\";\n\nimport {programVisitor} from './visitor';\nimport {InstrumentationOptions} from \"./utils\";\n\n/**\n * Options for configuring the coverage instrumenter.\n */\nexport type InstrumenterOptions = InstrumentationOptions & Partial<{\n /** Preserve comments in output */\n preserveComments: boolean;\n\n /** Generate compact code */\n compact: boolean;\n\n /** Set to true to instrument ES6 modules */\n esModules: boolean;\n\n /** Set to true to allow `return` statements outside of functions */\n autoWrap: boolean;\n\n /** Approach to produce a source map for the instrumented code */\n produceSourceMap: 'none' | 'inline' | 'external';\n\n /** Turn debugging on */\n debug: boolean;\n\n /** Set babel parser plugins */\n parserPlugins: PluginConfig[];\n}>;\n\nfunction mapSourceMapsOption(produceSourceMap: \"none\" | \"inline\" | \"external\" | undefined): boolean | \"inline\" | \"both\" | null | undefined {\n if (produceSourceMap === \"none\") {\n return false;\n }\n if (produceSourceMap === \"external\") {\n return \"both\";\n }\n return produceSourceMap;\n}\n\n/**\n * The main class of the instrumenter.\n */\nexport class Instrumenter {\n\n private readonly opts: InstrumenterOptions;\n\n constructor(opts?: Partial<InstrumenterOptions>) {\n this.opts = {...opts};\n }\n\n /**\n * Instrument the supplied code with coverage statements.\n * To instrument EcmaScript modules, make sure to set the\n * `esModules` option to `true` when creating the instrumenter.\n *\n * @param code - the code to instrument\n * @param filename - the name of the file the code stems from.\n * @param inputSourceMap - the source map that maps the not instrumented code back to its original\n * @param shouldInstrumentCallback - a callback to decide if a given code fragment should be instrumented\n *\n * @returns the instrumented code.\n */\n async instrument(code: string, filename: string | undefined, inputSourceMap: RawSourceMap | undefined,\n shouldInstrumentCallback?: (path: NodePath, location: SourceLocation) => boolean): Promise<string> {\n filename = filename ?? String(new Date().getTime()) + '.js';\n\n const {opts} = this;\n\n const sourceMapToUse = inputSourceMap ?? opts.inputSourceMap;\n let inputSourceMapConsumer: SourceMapConsumer | undefined = undefined;\n if (sourceMapToUse) {\n inputSourceMapConsumer = await new SourceMapConsumer(sourceMapToUse);\n }\n\n const babelOpts = {\n configFile: false,\n babelrc: false,\n ast: true,\n filename,\n inputSourceMap,\n sourceMaps: mapSourceMapsOption(opts.produceSourceMap),\n compact: opts.compact,\n comments: opts.preserveComments,\n parserOpts: {\n allowAwaitOutsideFunction: true,\n allowReturnOutsideFunction: opts.autoWrap,\n sourceType: (opts.esModules ? 'module' : 'script') as \"module\" | \"script\" | \"unambiguous\" | undefined,\n plugins: opts.parserPlugins\n },\n plugins: [\n [\n ({types}) => {\n const ee = programVisitor(types, inputSourceMapConsumer, {\n reportLogic: opts.reportLogic,\n coverageGlobalScopeFunc:\n opts.coverageGlobalScopeFunc,\n ignoreClassMethods: opts.ignoreClassMethods,\n inputSourceMap,\n isInstrumentedToken: opts.isInstrumentedToken,\n codeToPrepend: opts.codeToPrepend,\n shouldInstrumentCallback: shouldInstrumentCallback ?? opts.shouldInstrumentCallback\n });\n\n return {\n visitor: {\n Program: {\n enter: ee.enter,\n exit(path) {\n ee.exit(path);\n }\n }\n }\n };\n }\n ]\n ]\n };\n\n return transformSync(code, babelOpts)!.code!;\n }\n\n}\n","import {Instrumenter, InstrumenterOptions} from './instrumenter';\n\nexport type {InstrumenterOptions} from './instrumenter';\nexport {programVisitor} from './visitor';\n\n/**\n * Creates a new coverage instrumenter.\n *\n * @param opts - instrumenter options\n */\nexport function createInstrumenter(opts: InstrumenterOptions): Instrumenter {\n return new Instrumenter(opts);\n}\n"],"mappings":"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"}