aboutsummaryrefslogtreecommitdiffstats
path: root/vanilla/node_modules/ast-v8-to-istanbul/dist
diff options
context:
space:
mode:
authorAdam Mathes <adam@adammathes.com>2026-02-13 21:34:48 -0800
committerAdam Mathes <adam@adammathes.com>2026-02-13 21:34:48 -0800
commit76cb9c2a39d477a64824a985ade40507e3bbade1 (patch)
tree41e997aa9c6f538d3a136af61dae9424db2005a9 /vanilla/node_modules/ast-v8-to-istanbul/dist
parent819a39a21ac992b1393244a4c283bbb125208c69 (diff)
downloadneko-76cb9c2a39d477a64824a985ade40507e3bbade1.tar.gz
neko-76cb9c2a39d477a64824a985ade40507e3bbade1.tar.bz2
neko-76cb9c2a39d477a64824a985ade40507e3bbade1.zip
feat(vanilla): add testing infrastructure and tests (NK-wjnczv)
Diffstat (limited to 'vanilla/node_modules/ast-v8-to-istanbul/dist')
-rw-r--r--vanilla/node_modules/ast-v8-to-istanbul/dist/index.d.mts568
-rw-r--r--vanilla/node_modules/ast-v8-to-istanbul/dist/index.mjs848
2 files changed, 1416 insertions, 0 deletions
diff --git a/vanilla/node_modules/ast-v8-to-istanbul/dist/index.d.mts b/vanilla/node_modules/ast-v8-to-istanbul/dist/index.d.mts
new file mode 100644
index 0000000..9d69ea5
--- /dev/null
+++ b/vanilla/node_modules/ast-v8-to-istanbul/dist/index.d.mts
@@ -0,0 +1,568 @@
+import { EncodedSourceMap } from "@jridgewell/trace-mapping";
+import { CoverageMapData } from "istanbul-lib-coverage";
+import { Profiler } from "node:inspector";
+
+//#region node_modules/.pnpm/@types+estree@1.0.8/node_modules/@types/estree/index.d.ts
+// This definition file follows a somewhat unusual format. ESTree allows
+// runtime type checks based on the `type` parameter. In order to explain this
+// to typescript we want to use discriminated union types:
+// https://github.com/Microsoft/TypeScript/pull/9163
+//
+// For ESTree this is a bit tricky because the high level interfaces like
+// Node or Function are pulling double duty. We want to pass common fields down
+// to the interfaces that extend them (like Identifier or
+// ArrowFunctionExpression), but you can't extend a type union or enforce
+// common fields on them. So we've split the high level interfaces into two
+// types, a base type which passes down inherited fields, and a type union of
+// all types which extend the base type. Only the type union is exported, and
+// the union is how other types refer to the collection of inheriting types.
+//
+// This makes the definitions file here somewhat more difficult to maintain,
+// but it has the notable advantage of making ESTree much easier to use as
+// an end user.
+interface BaseNodeWithoutComments {
+ // Every leaf interface that extends BaseNode must specify a type property.
+ // The type property should be a string literal. For example, Identifier
+ // has: `type: "Identifier"`
+ type: string;
+ loc?: SourceLocation | null | undefined;
+ range?: [number, number] | undefined;
+}
+interface BaseNode extends BaseNodeWithoutComments {
+ leadingComments?: Comment[] | undefined;
+ trailingComments?: Comment[] | undefined;
+}
+interface NodeMap {
+ AssignmentProperty: AssignmentProperty;
+ CatchClause: CatchClause;
+ Class: Class;
+ ClassBody: ClassBody;
+ Expression: Expression;
+ Function: Function;
+ Identifier: Identifier;
+ Literal: Literal;
+ MethodDefinition: MethodDefinition;
+ ModuleDeclaration: ModuleDeclaration;
+ ModuleSpecifier: ModuleSpecifier;
+ Pattern: Pattern;
+ PrivateIdentifier: PrivateIdentifier;
+ Program: Program;
+ Property: Property;
+ PropertyDefinition: PropertyDefinition;
+ SpreadElement: SpreadElement;
+ Statement: Statement;
+ Super: Super;
+ SwitchCase: SwitchCase;
+ TemplateElement: TemplateElement;
+ VariableDeclarator: VariableDeclarator;
+}
+type Node = NodeMap[keyof NodeMap];
+interface Comment extends BaseNodeWithoutComments {
+ type: "Line" | "Block";
+ value: string;
+}
+interface SourceLocation {
+ source?: string | null | undefined;
+ start: Position;
+ end: Position;
+}
+interface Position {
+ /** >= 1 */
+ line: number;
+ /** >= 0 */
+ column: number;
+}
+interface Program extends BaseNode {
+ type: "Program";
+ sourceType: "script" | "module";
+ body: Array<Directive | Statement | ModuleDeclaration>;
+ comments?: Comment[] | undefined;
+}
+interface Directive extends BaseNode {
+ type: "ExpressionStatement";
+ expression: Literal;
+ directive: string;
+}
+interface BaseFunction extends BaseNode {
+ params: Pattern[];
+ generator?: boolean | undefined;
+ async?: boolean | undefined; // The body is either BlockStatement or Expression because arrow functions
+ // can have a body that's either. FunctionDeclarations and
+ // FunctionExpressions have only BlockStatement bodies.
+ body: BlockStatement | Expression;
+}
+type Function = FunctionDeclaration | FunctionExpression | ArrowFunctionExpression;
+type Statement = ExpressionStatement | BlockStatement | StaticBlock | EmptyStatement | DebuggerStatement | WithStatement | ReturnStatement | LabeledStatement | BreakStatement | ContinueStatement | IfStatement | SwitchStatement | ThrowStatement | TryStatement | WhileStatement | DoWhileStatement | ForStatement | ForInStatement | ForOfStatement | Declaration;
+interface BaseStatement extends BaseNode {}
+interface EmptyStatement extends BaseStatement {
+ type: "EmptyStatement";
+}
+interface BlockStatement extends BaseStatement {
+ type: "BlockStatement";
+ body: Statement[];
+ innerComments?: Comment[] | undefined;
+}
+interface StaticBlock extends Omit<BlockStatement, "type"> {
+ type: "StaticBlock";
+}
+interface ExpressionStatement extends BaseStatement {
+ type: "ExpressionStatement";
+ expression: Expression;
+}
+interface IfStatement extends BaseStatement {
+ type: "IfStatement";
+ test: Expression;
+ consequent: Statement;
+ alternate?: Statement | null | undefined;
+}
+interface LabeledStatement extends BaseStatement {
+ type: "LabeledStatement";
+ label: Identifier;
+ body: Statement;
+}
+interface BreakStatement extends BaseStatement {
+ type: "BreakStatement";
+ label?: Identifier | null | undefined;
+}
+interface ContinueStatement extends BaseStatement {
+ type: "ContinueStatement";
+ label?: Identifier | null | undefined;
+}
+interface WithStatement extends BaseStatement {
+ type: "WithStatement";
+ object: Expression;
+ body: Statement;
+}
+interface SwitchStatement extends BaseStatement {
+ type: "SwitchStatement";
+ discriminant: Expression;
+ cases: SwitchCase[];
+}
+interface ReturnStatement extends BaseStatement {
+ type: "ReturnStatement";
+ argument?: Expression | null | undefined;
+}
+interface ThrowStatement extends BaseStatement {
+ type: "ThrowStatement";
+ argument: Expression;
+}
+interface TryStatement extends BaseStatement {
+ type: "TryStatement";
+ block: BlockStatement;
+ handler?: CatchClause | null | undefined;
+ finalizer?: BlockStatement | null | undefined;
+}
+interface WhileStatement extends BaseStatement {
+ type: "WhileStatement";
+ test: Expression;
+ body: Statement;
+}
+interface DoWhileStatement extends BaseStatement {
+ type: "DoWhileStatement";
+ body: Statement;
+ test: Expression;
+}
+interface ForStatement extends BaseStatement {
+ type: "ForStatement";
+ init?: VariableDeclaration | Expression | null | undefined;
+ test?: Expression | null | undefined;
+ update?: Expression | null | undefined;
+ body: Statement;
+}
+interface BaseForXStatement extends BaseStatement {
+ left: VariableDeclaration | Pattern;
+ right: Expression;
+ body: Statement;
+}
+interface ForInStatement extends BaseForXStatement {
+ type: "ForInStatement";
+}
+interface DebuggerStatement extends BaseStatement {
+ type: "DebuggerStatement";
+}
+type Declaration = FunctionDeclaration | VariableDeclaration | ClassDeclaration;
+interface BaseDeclaration extends BaseStatement {}
+interface MaybeNamedFunctionDeclaration extends BaseFunction, BaseDeclaration {
+ type: "FunctionDeclaration";
+ /** It is null when a function declaration is a part of the `export default function` statement */
+ id: Identifier | null;
+ body: BlockStatement;
+}
+interface FunctionDeclaration extends MaybeNamedFunctionDeclaration {
+ id: Identifier;
+}
+interface VariableDeclaration extends BaseDeclaration {
+ type: "VariableDeclaration";
+ declarations: VariableDeclarator[];
+ kind: "var" | "let" | "const" | "using" | "await using";
+}
+interface VariableDeclarator extends BaseNode {
+ type: "VariableDeclarator";
+ id: Pattern;
+ init?: Expression | null | undefined;
+}
+interface ExpressionMap {
+ ArrayExpression: ArrayExpression;
+ ArrowFunctionExpression: ArrowFunctionExpression;
+ AssignmentExpression: AssignmentExpression;
+ AwaitExpression: AwaitExpression;
+ BinaryExpression: BinaryExpression;
+ CallExpression: CallExpression;
+ ChainExpression: ChainExpression;
+ ClassExpression: ClassExpression;
+ ConditionalExpression: ConditionalExpression;
+ FunctionExpression: FunctionExpression;
+ Identifier: Identifier;
+ ImportExpression: ImportExpression;
+ Literal: Literal;
+ LogicalExpression: LogicalExpression;
+ MemberExpression: MemberExpression;
+ MetaProperty: MetaProperty;
+ NewExpression: NewExpression;
+ ObjectExpression: ObjectExpression;
+ SequenceExpression: SequenceExpression;
+ TaggedTemplateExpression: TaggedTemplateExpression;
+ TemplateLiteral: TemplateLiteral;
+ ThisExpression: ThisExpression;
+ UnaryExpression: UnaryExpression;
+ UpdateExpression: UpdateExpression;
+ YieldExpression: YieldExpression;
+}
+type Expression = ExpressionMap[keyof ExpressionMap];
+interface BaseExpression extends BaseNode {}
+type ChainElement = SimpleCallExpression | MemberExpression;
+interface ChainExpression extends BaseExpression {
+ type: "ChainExpression";
+ expression: ChainElement;
+}
+interface ThisExpression extends BaseExpression {
+ type: "ThisExpression";
+}
+interface ArrayExpression extends BaseExpression {
+ type: "ArrayExpression";
+ elements: Array<Expression | SpreadElement | null>;
+}
+interface ObjectExpression extends BaseExpression {
+ type: "ObjectExpression";
+ properties: Array<Property | SpreadElement>;
+}
+interface PrivateIdentifier extends BaseNode {
+ type: "PrivateIdentifier";
+ name: string;
+}
+interface Property extends BaseNode {
+ type: "Property";
+ key: Expression | PrivateIdentifier;
+ value: Expression | Pattern; // Could be an AssignmentProperty
+ kind: "init" | "get" | "set";
+ method: boolean;
+ shorthand: boolean;
+ computed: boolean;
+}
+interface PropertyDefinition extends BaseNode {
+ type: "PropertyDefinition";
+ key: Expression | PrivateIdentifier;
+ value?: Expression | null | undefined;
+ computed: boolean;
+ static: boolean;
+}
+interface FunctionExpression extends BaseFunction, BaseExpression {
+ id?: Identifier | null | undefined;
+ type: "FunctionExpression";
+ body: BlockStatement;
+}
+interface SequenceExpression extends BaseExpression {
+ type: "SequenceExpression";
+ expressions: Expression[];
+}
+interface UnaryExpression extends BaseExpression {
+ type: "UnaryExpression";
+ operator: UnaryOperator;
+ prefix: true;
+ argument: Expression;
+}
+interface BinaryExpression extends BaseExpression {
+ type: "BinaryExpression";
+ operator: BinaryOperator;
+ left: Expression | PrivateIdentifier;
+ right: Expression;
+}
+interface AssignmentExpression extends BaseExpression {
+ type: "AssignmentExpression";
+ operator: AssignmentOperator;
+ left: Pattern | MemberExpression;
+ right: Expression;
+}
+interface UpdateExpression extends BaseExpression {
+ type: "UpdateExpression";
+ operator: UpdateOperator;
+ argument: Expression;
+ prefix: boolean;
+}
+interface LogicalExpression extends BaseExpression {
+ type: "LogicalExpression";
+ operator: LogicalOperator;
+ left: Expression;
+ right: Expression;
+}
+interface ConditionalExpression extends BaseExpression {
+ type: "ConditionalExpression";
+ test: Expression;
+ alternate: Expression;
+ consequent: Expression;
+}
+interface BaseCallExpression extends BaseExpression {
+ callee: Expression | Super;
+ arguments: Array<Expression | SpreadElement>;
+}
+type CallExpression = SimpleCallExpression | NewExpression;
+interface SimpleCallExpression extends BaseCallExpression {
+ type: "CallExpression";
+ optional: boolean;
+}
+interface NewExpression extends BaseCallExpression {
+ type: "NewExpression";
+}
+interface MemberExpression extends BaseExpression, BasePattern {
+ type: "MemberExpression";
+ object: Expression | Super;
+ property: Expression | PrivateIdentifier;
+ computed: boolean;
+ optional: boolean;
+}
+type Pattern = Identifier | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | MemberExpression;
+interface BasePattern extends BaseNode {}
+interface SwitchCase extends BaseNode {
+ type: "SwitchCase";
+ test?: Expression | null | undefined;
+ consequent: Statement[];
+}
+interface CatchClause extends BaseNode {
+ type: "CatchClause";
+ param: Pattern | null;
+ body: BlockStatement;
+}
+interface Identifier extends BaseNode, BaseExpression, BasePattern {
+ type: "Identifier";
+ name: string;
+}
+type Literal = SimpleLiteral | RegExpLiteral | BigIntLiteral;
+interface SimpleLiteral extends BaseNode, BaseExpression {
+ type: "Literal";
+ value: string | boolean | number | null;
+ raw?: string | undefined;
+}
+interface RegExpLiteral extends BaseNode, BaseExpression {
+ type: "Literal";
+ value?: RegExp | null | undefined;
+ regex: {
+ pattern: string;
+ flags: string;
+ };
+ raw?: string | undefined;
+}
+interface BigIntLiteral extends BaseNode, BaseExpression {
+ type: "Literal";
+ value?: bigint | null | undefined;
+ bigint: string;
+ raw?: string | undefined;
+}
+type UnaryOperator = "-" | "+" | "!" | "~" | "typeof" | "void" | "delete";
+type BinaryOperator = "==" | "!=" | "===" | "!==" | "<" | "<=" | ">" | ">=" | "<<" | ">>" | ">>>" | "+" | "-" | "*" | "/" | "%" | "**" | "|" | "^" | "&" | "in" | "instanceof";
+type LogicalOperator = "||" | "&&" | "??";
+type AssignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "**=" | "<<=" | ">>=" | ">>>=" | "|=" | "^=" | "&=" | "||=" | "&&=" | "??=";
+type UpdateOperator = "++" | "--";
+interface ForOfStatement extends BaseForXStatement {
+ type: "ForOfStatement";
+ await: boolean;
+}
+interface Super extends BaseNode {
+ type: "Super";
+}
+interface SpreadElement extends BaseNode {
+ type: "SpreadElement";
+ argument: Expression;
+}
+interface ArrowFunctionExpression extends BaseExpression, BaseFunction {
+ type: "ArrowFunctionExpression";
+ expression: boolean;
+ body: BlockStatement | Expression;
+}
+interface YieldExpression extends BaseExpression {
+ type: "YieldExpression";
+ argument?: Expression | null | undefined;
+ delegate: boolean;
+}
+interface TemplateLiteral extends BaseExpression {
+ type: "TemplateLiteral";
+ quasis: TemplateElement[];
+ expressions: Expression[];
+}
+interface TaggedTemplateExpression extends BaseExpression {
+ type: "TaggedTemplateExpression";
+ tag: Expression;
+ quasi: TemplateLiteral;
+}
+interface TemplateElement extends BaseNode {
+ type: "TemplateElement";
+ tail: boolean;
+ value: {
+ /** It is null when the template literal is tagged and the text has an invalid escape (e.g. - tag`\unicode and \u{55}`) */cooked?: string | null | undefined;
+ raw: string;
+ };
+}
+interface AssignmentProperty extends Property {
+ value: Pattern;
+ kind: "init";
+ method: boolean; // false
+}
+interface ObjectPattern extends BasePattern {
+ type: "ObjectPattern";
+ properties: Array<AssignmentProperty | RestElement>;
+}
+interface ArrayPattern extends BasePattern {
+ type: "ArrayPattern";
+ elements: Array<Pattern | null>;
+}
+interface RestElement extends BasePattern {
+ type: "RestElement";
+ argument: Pattern;
+}
+interface AssignmentPattern extends BasePattern {
+ type: "AssignmentPattern";
+ left: Pattern;
+ right: Expression;
+}
+type Class = ClassDeclaration | ClassExpression;
+interface BaseClass extends BaseNode {
+ superClass?: Expression | null | undefined;
+ body: ClassBody;
+}
+interface ClassBody extends BaseNode {
+ type: "ClassBody";
+ body: Array<MethodDefinition | PropertyDefinition | StaticBlock>;
+}
+interface MethodDefinition extends BaseNode {
+ type: "MethodDefinition";
+ key: Expression | PrivateIdentifier;
+ value: FunctionExpression;
+ kind: "constructor" | "method" | "get" | "set";
+ computed: boolean;
+ static: boolean;
+}
+interface MaybeNamedClassDeclaration extends BaseClass, BaseDeclaration {
+ type: "ClassDeclaration";
+ /** It is null when a class declaration is a part of the `export default class` statement */
+ id: Identifier | null;
+}
+interface ClassDeclaration extends MaybeNamedClassDeclaration {
+ id: Identifier;
+}
+interface ClassExpression extends BaseClass, BaseExpression {
+ type: "ClassExpression";
+ id?: Identifier | null | undefined;
+}
+interface MetaProperty extends BaseExpression {
+ type: "MetaProperty";
+ meta: Identifier;
+ property: Identifier;
+}
+type ModuleDeclaration = ImportDeclaration | ExportNamedDeclaration | ExportDefaultDeclaration | ExportAllDeclaration;
+interface BaseModuleDeclaration extends BaseNode {}
+type ModuleSpecifier = ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier;
+interface BaseModuleSpecifier extends BaseNode {
+ local: Identifier;
+}
+interface ImportDeclaration extends BaseModuleDeclaration {
+ type: "ImportDeclaration";
+ specifiers: Array<ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier>;
+ attributes: ImportAttribute[];
+ source: Literal;
+}
+interface ImportSpecifier extends BaseModuleSpecifier {
+ type: "ImportSpecifier";
+ imported: Identifier | Literal;
+}
+interface ImportAttribute extends BaseNode {
+ type: "ImportAttribute";
+ key: Identifier | Literal;
+ value: Literal;
+}
+interface ImportExpression extends BaseExpression {
+ type: "ImportExpression";
+ source: Expression;
+ options?: Expression | null | undefined;
+}
+interface ImportDefaultSpecifier extends BaseModuleSpecifier {
+ type: "ImportDefaultSpecifier";
+}
+interface ImportNamespaceSpecifier extends BaseModuleSpecifier {
+ type: "ImportNamespaceSpecifier";
+}
+interface ExportNamedDeclaration extends BaseModuleDeclaration {
+ type: "ExportNamedDeclaration";
+ declaration?: Declaration | null | undefined;
+ specifiers: ExportSpecifier[];
+ attributes: ImportAttribute[];
+ source?: Literal | null | undefined;
+}
+interface ExportSpecifier extends Omit<BaseModuleSpecifier, "local"> {
+ type: "ExportSpecifier";
+ local: Identifier | Literal;
+ exported: Identifier | Literal;
+}
+interface ExportDefaultDeclaration extends BaseModuleDeclaration {
+ type: "ExportDefaultDeclaration";
+ declaration: MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration | Expression;
+}
+interface ExportAllDeclaration extends BaseModuleDeclaration {
+ type: "ExportAllDeclaration";
+ exported: Identifier | Literal | null;
+ attributes: ImportAttribute[];
+ source: Literal;
+}
+interface AwaitExpression extends BaseExpression {
+ type: "AwaitExpression";
+ argument: Expression;
+}
+//#endregion
+//#region src/types.d.ts
+interface Options<T = Node, Program = T & {
+ type: "Program";
+}> {
+ /** Code of the executed runtime file, not the original source file */
+ code: string;
+ /** Length of the execution wrapper, e.g. wrapper used in node:vm */
+ wrapperLength?: number;
+ /** Source map for the current file */
+ sourceMap?: Omit<EncodedSourceMap, "version"> & {
+ version: number;
+ };
+ /** ScriptCoverage for the current file */
+ coverage: Pick<Profiler.ScriptCoverage, "functions" | "url">;
+ /** AST for the transpiled file that matches the coverage results */
+ ast: Program | Promise<Program>;
+ /** Class method names to ignore for coverage, identical to https://github.com/istanbuljs/nyc?tab=readme-ov-file#ignoring-methods */
+ ignoreClassMethods?: string[];
+ /** Filter to ignore code based on AST nodes */
+ ignoreNode?: (node: T, type: "function" | "statement" | "branch") => boolean | "ignore-this-and-nested-nodes" | void;
+ /**
+ * Filter to ignore code based on source code
+ * - Note that this is slower than `ignoreNode` as exclusion happens after remapping
+ */
+ ignoreSourceCode?: (code: string, type: "function" | "statement" | "branch", location: Record<"start" | "end", {
+ line: number;
+ column: number;
+ }>) => boolean | void;
+}
+//#endregion
+//#region src/index.d.ts
+/**
+ * Maps V8 `ScriptCoverage` to Istanbul's `CoverageMap`.
+ * Results are identical with `istanbul-lib-instrument`.
+ */
+declare function convert<T = Node, Program = T & {
+ type: "Program";
+}>(options: Options<T, Program>): Promise<CoverageMapData>;
+//#endregion
+export { Options, convert, convert as default }; \ No newline at end of file
diff --git a/vanilla/node_modules/ast-v8-to-istanbul/dist/index.mjs b/vanilla/node_modules/ast-v8-to-istanbul/dist/index.mjs
new file mode 100644
index 0000000..8b66bc3
--- /dev/null
+++ b/vanilla/node_modules/ast-v8-to-istanbul/dist/index.mjs
@@ -0,0 +1,848 @@
+import { asyncWalk } from "estree-walker";
+import { dirname, resolve } from "node:path";
+import { fileURLToPath } from "node:url";
+import { LEAST_UPPER_BOUND, TraceMap, allGeneratedPositionsFor, originalPositionFor, sourceContentFor } from "@jridgewell/trace-mapping";
+import { readFileSync } from "node:fs";
+import { readFile } from "node:fs/promises";
+import jsTokens from "js-tokens";
+
+//#region src/ast.ts
+function getWalker() {
+ let nextIgnore = false;
+ function onIgnore(node) {
+ nextIgnore = node;
+ }
+ async function walk(ast, ignoreHints, ignoreClassMethods, visitors) {
+ return await asyncWalk(ast, {
+ async enter(node) {
+ if (nextIgnore !== false) return;
+ const hint = getIgnoreHint(node);
+ if (hint === "next") return onIgnore(node);
+ if (isSkipped(node)) onIgnore(node);
+ switch (node.type) {
+ case "FunctionDeclaration": return visitors.onFunctionDeclaration(node);
+ case "FunctionExpression":
+ if (ignoreClassMethods && node.id?.name) {
+ if (ignoreClassMethods.includes(node.id.name)) return onIgnore(node);
+ }
+ return visitors.onFunctionExpression(node);
+ case "MethodDefinition": return visitors.onMethodDefinition(node);
+ case "Property": return visitors.onProperty(node);
+ case "ArrowFunctionExpression":
+ if (node.body?.type === "ParenthesizedExpression") node.body = node.body.expression;
+ return visitors.onArrowFunctionExpression(node);
+ case "ExpressionStatement": return visitors.onExpressionStatement(node);
+ case "BreakStatement": return visitors.onBreakStatement(node);
+ case "ContinueStatement": return visitors.onContinueStatement(node);
+ case "DebuggerStatement": return visitors.onDebuggerStatement(node);
+ case "ReturnStatement": return visitors.onReturnStatement(node);
+ case "ThrowStatement": return visitors.onThrowStatement(node);
+ case "TryStatement": return visitors.onTryStatement(node);
+ case "ForStatement": return visitors.onForStatement(node);
+ case "ForInStatement": return visitors.onForInStatement(node);
+ case "ForOfStatement": return visitors.onForOfStatement(node);
+ case "WhileStatement": return visitors.onWhileStatement(node);
+ case "DoWhileStatement": return visitors.onDoWhileStatement(node);
+ case "WithStatement": return visitors.onWithStatement(node);
+ case "LabeledStatement": return visitors.onLabeledStatement(node);
+ case "VariableDeclarator": return visitors.onVariableDeclarator(node);
+ case "ClassBody": {
+ const classBody = node;
+ if (ignoreClassMethods) {
+ for (const child of classBody.body) if (child.type === "MethodDefinition" || child.type === "ClassMethod") {
+ const name = child.key.type === "Identifier" && child.key.name;
+ if (name && ignoreClassMethods.includes(name)) setSkipped(child);
+ }
+ classBody.body = classBody.body.filter((child) => !isSkipped(child));
+ }
+ return visitors.onClassBody(classBody);
+ }
+ case "IfStatement": {
+ const branches = [];
+ if (node.consequent.type !== "BlockStatement") node.consequent = {
+ type: "BlockStatement",
+ body: [node.consequent],
+ start: node.consequent.start,
+ end: node.consequent.end
+ };
+ if (node.alternate && node.alternate.type !== "BlockStatement") node.alternate = {
+ type: "BlockStatement",
+ body: [node.alternate],
+ start: node.alternate.start,
+ end: node.alternate.end
+ };
+ if (hint === "if") setSkipped(node.consequent);
+ else branches.push(node.consequent);
+ if (hint === "else" && node.alternate) setSkipped(node.alternate);
+ else if (hint !== "if" && hint !== "else") branches.push(node.alternate);
+ return visitors.onIfStatement(node, branches);
+ }
+ case "SwitchStatement": {
+ const cases = [];
+ for (const _case of node.cases) if (getIgnoreHint(_case) !== "next") cases.push(_case);
+ return visitors.onSwitchStatement(node, cases);
+ }
+ case "ConditionalExpression": {
+ const branches = [];
+ if (node.consequent.type === "ParenthesizedExpression") node.consequent = node.consequent.expression;
+ if (node.alternate.type === "ParenthesizedExpression") node.alternate = node.alternate.expression;
+ if (getIgnoreHint(node.consequent) === "next") setSkipped(node.consequent);
+ else branches.push(node.consequent);
+ if (getIgnoreHint(node.alternate) === "next") setSkipped(node.alternate);
+ else branches.push(node.alternate);
+ return visitors.onConditionalExpression(node, branches);
+ }
+ case "LogicalExpression": {
+ if (isSkipped(node)) return;
+ const branches = [];
+ function visit(child) {
+ if (child.type === "LogicalExpression") {
+ setSkipped(child);
+ if (getIgnoreHint(child) !== "next") {
+ visit(child.left);
+ return visit(child.right);
+ }
+ }
+ branches.push(child);
+ }
+ visit(node);
+ return visitors.onLogicalExpression(node, branches);
+ }
+ case "AssignmentPattern": return visitors.onAssignmentPattern(node);
+ case "ClassMethod": return visitors.onClassMethod(node);
+ case "ObjectMethod": return visitors.onObjectMethod(node);
+ }
+ },
+ async leave(node) {
+ if (node === nextIgnore) nextIgnore = false;
+ }
+ });
+ function getIgnoreHint(node) {
+ for (const hint of ignoreHints) if (hint.loc.end === node.start) return hint.type;
+ return null;
+ }
+ }
+ return {
+ walk,
+ onIgnore
+ };
+}
+const skippedNodes = /* @__PURE__ */ new WeakSet();
+function getFunctionName(node) {
+ if (node.type === "Identifier") return node.name;
+ if ("id" in node && node.id) return getFunctionName(node.id);
+}
+function setSkipped(node) {
+ skippedNodes.add(node);
+}
+function isSkipped(node) {
+ return skippedNodes.has(node);
+}
+
+//#endregion
+//#region src/coverage-map.ts
+function createCoverageMapData(filename, sourceMap) {
+ const data = {};
+ const directory = dirname(filename);
+ for (const source of sourceMap.sources) {
+ let path = filename;
+ if (source) if (source.startsWith("file://")) path = fileURLToPath(source);
+ else path = resolve(directory, source);
+ data[path] = {
+ path,
+ statementMap: {},
+ fnMap: {},
+ branchMap: {},
+ s: {},
+ f: {},
+ b: {},
+ meta: {
+ lastBranch: 0,
+ lastFunction: 0,
+ lastStatement: 0,
+ seen: {}
+ }
+ };
+ }
+ return data;
+}
+function addFunction(options) {
+ const fileCoverage = options.coverageMapData[options.filename];
+ const meta = fileCoverage.meta;
+ const key = `f:${cacheKey(options.decl)}`;
+ let index = meta.seen[key];
+ if (index == null) {
+ index = meta.lastFunction;
+ meta.lastFunction++;
+ meta.seen[key] = index;
+ fileCoverage.fnMap[index] = {
+ name: options.name || `(anonymous_${index})`,
+ decl: pickLocation(options.decl),
+ loc: pickLocation(options.loc),
+ line: options.loc.start.line
+ };
+ }
+ fileCoverage.f[index] ||= 0;
+ fileCoverage.f[index] += options.covered || 0;
+}
+function addStatement(options) {
+ const fileCoverage = options.coverageMapData[options.filename];
+ const meta = fileCoverage.meta;
+ const key = `s:${cacheKey(options.loc)}`;
+ let index = meta.seen[key];
+ if (index == null) {
+ index = meta.lastStatement;
+ meta.lastStatement++;
+ meta.seen[key] = index;
+ fileCoverage.statementMap[index] = pickLocation(options.loc);
+ }
+ fileCoverage.s[index] = options.covered || 0;
+}
+function addBranch(options) {
+ const fileCoverage = options.coverageMapData[options.filename];
+ const meta = fileCoverage.meta;
+ const key = ["b", ...options.locations.map(cacheKey)].join(":");
+ let index = meta.seen[key];
+ if (index == null) {
+ index = meta.lastBranch;
+ meta.lastBranch++;
+ meta.seen[key] = index;
+ fileCoverage.branchMap[index] = {
+ loc: pickLocation(options.loc),
+ type: options.type,
+ locations: options.locations.map((loc) => pickLocation(loc)),
+ line: options.loc.start.line
+ };
+ }
+ if (!fileCoverage.b[index]) fileCoverage.b[index] = Array(options.locations.length).fill(0);
+ options.covered?.forEach((hit, i) => {
+ fileCoverage.b[index][i] += hit;
+ });
+}
+function pickLocation(loc) {
+ return {
+ start: {
+ line: loc.start.line,
+ column: loc.start.column
+ },
+ end: {
+ line: loc.end.line,
+ column: loc.end.column
+ }
+ };
+}
+function cacheKey(loc) {
+ return `${loc.start.line}:${loc.start.column}:${loc.end.line}:${loc.end.column}`;
+}
+
+//#endregion
+//#region src/ignore-hints.ts
+const IGNORE_PATTERN = /^\s*(?:istanbul|[cv]8|node:coverage)\s+ignore\s+(if|else|next|file)(?=\W|$)/;
+const IGNORE_LINES_PATTERN = /\s*(?:istanbul|[cv]8|node:coverage)\s+ignore\s+(start|stop)(?=\W|$)/;
+const EOL_PATTERN = /\r?\n/g;
+/**
+* Parse ignore hints from **Javascript** code based on AST
+* - Most AST parsers don't emit comments in AST like Acorn does, so parse comments manually instead.
+*/
+function getIgnoreHints(code) {
+ const ignoreHints = [];
+ const tokens = jsTokens(code);
+ let current = 0;
+ let previousTokenWasIgnoreHint = false;
+ for (const token of tokens) {
+ if (previousTokenWasIgnoreHint && token.type !== "WhiteSpace" && token.type !== "LineTerminatorSequence") {
+ const previous = ignoreHints.at(-1);
+ if (previous) previous.loc.end = current;
+ previousTokenWasIgnoreHint = false;
+ }
+ if (token.type === "SingleLineComment" || token.type === "MultiLineComment") {
+ const loc = {
+ start: current,
+ end: current + token.value.length
+ };
+ const type = token.value.replace(/^\/\*\*/, "").replace(/^\/\*/, "").replace(/\*\*\/$/, "").replace(/\*\/$/, "").replace(/^\/\//, "").match(IGNORE_PATTERN)?.[1];
+ if (type === "file") return [{
+ type: "file",
+ loc: {
+ start: 0,
+ end: 0
+ }
+ }];
+ if (type === "if" || type === "else" || type === "next") {
+ ignoreHints.push({
+ type,
+ loc
+ });
+ previousTokenWasIgnoreHint = true;
+ }
+ }
+ current += token.value.length;
+ }
+ return ignoreHints;
+}
+/**
+* Parse ignore start/stop hints from **text file** based on regular expressions
+* - Does not understand what a comment is in Javascript (or JSX, Vue, Svelte)
+* - Parses source code (JS, TS, Vue, Svelte, anything) based on text search by
+* matching for `/* <name> ignore start *\/` pattern - not by looking for real comments
+*
+* ```js
+* /* v8 ignore start *\/
+* <!-- /* v8 ignore start *\/ -->
+* <SomeFrameworkComment content="/* v8 ignore start *\/">
+* ```
+*/
+function getIgnoredLines(text) {
+ if (!text) return /* @__PURE__ */ new Set();
+ const ranges = [];
+ let lineNumber = 0;
+ for (const line of text.split(EOL_PATTERN)) {
+ lineNumber++;
+ const match = line.match(IGNORE_LINES_PATTERN);
+ if (match) {
+ if (match[1] === "stop") {
+ const previous = ranges.at(-1);
+ if (previous && previous.stop === Infinity) previous.stop = lineNumber;
+ continue;
+ }
+ ranges.push({
+ start: lineNumber,
+ stop: Infinity
+ });
+ }
+ }
+ const ignoredLines = /* @__PURE__ */ new Set();
+ for (const range of ranges) for (let line = range.start; line <= range.stop; line++) {
+ ignoredLines.add(line);
+ if (line >= lineNumber) break;
+ }
+ return ignoredLines;
+}
+
+//#endregion
+//#region src/location.ts
+const WORD_PATTERN = /(\w+|\s|[^\w\s])/g;
+const INLINE_MAP_PATTERN = /#\s*sourceMappingURL=(.*)\s*$/m;
+const BASE_64_PREFIX = "data:application/json;base64,";
+/** How often should offset calculations be cached */
+const CACHE_THRESHOLD = 250;
+var Locator = class {
+ #cache = /* @__PURE__ */ new Map();
+ #codeParts;
+ #map;
+ #directory;
+ #ignoredLines = /* @__PURE__ */ new Map();
+ constructor(code, map, directory) {
+ this.#codeParts = code.split("");
+ this.#map = map;
+ this.#directory = directory;
+ }
+ reset() {
+ this.#cache.clear();
+ this.#ignoredLines.clear();
+ this.#codeParts = [];
+ }
+ offsetToNeedle(offset) {
+ const closestThreshold = Math.floor(offset / CACHE_THRESHOLD) * CACHE_THRESHOLD;
+ const cacheHit = this.#cache.get(closestThreshold);
+ let current = cacheHit ? closestThreshold : 0;
+ let line = cacheHit?.line ?? 1;
+ let column = cacheHit?.column ?? 0;
+ for (let i = current; i <= this.#codeParts.length; i++) {
+ if (current === offset) return {
+ line,
+ column
+ };
+ if (current % CACHE_THRESHOLD === 0) this.#cache.set(current, {
+ line,
+ column
+ });
+ if (this.#codeParts[i] === "\n") {
+ line++;
+ column = 0;
+ } else column++;
+ current++;
+ }
+ return {
+ line,
+ column
+ };
+ }
+ getLoc(node) {
+ const startNeedle = this.offsetToNeedle(node.start);
+ const start = getPosition(startNeedle, this.#map);
+ if (start === null) return null;
+ const endNeedle = this.offsetToNeedle(node.end);
+ endNeedle.column -= 1;
+ let end = getPosition(endNeedle, this.#map);
+ if (end === null) {
+ for (let line = endNeedle.line; line >= startNeedle.line && end === null; line--) end = getPosition({
+ line,
+ column: Infinity
+ }, this.#map);
+ if (end === null) return null;
+ }
+ const loc = {
+ start,
+ end
+ };
+ const afterEndMappings = allGeneratedPositionsFor(this.#map, {
+ source: loc.end.filename,
+ line: loc.end.line,
+ column: loc.end.column + 1,
+ bias: LEAST_UPPER_BOUND
+ });
+ if (afterEndMappings.length === 0) loc.end.column = Infinity;
+ else for (const mapping of afterEndMappings) {
+ if (mapping.line === null) continue;
+ const original = originalPositionFor(this.#map, mapping);
+ if (original.line === loc.end.line) {
+ loc.end = {
+ ...original,
+ filename: original.source
+ };
+ break;
+ }
+ }
+ const filename = loc.start.filename;
+ let ignoredLines = this.#ignoredLines.get(filename);
+ if (!ignoredLines) {
+ ignoredLines = getIgnoredLines(sourceContentFor(this.#map, filename) ?? tryReadFileSync(filename));
+ this.#ignoredLines.set(filename, ignoredLines);
+ }
+ if (ignoredLines.has(loc.start.line)) return null;
+ return loc;
+ }
+ getSourceLines(loc, filename) {
+ const index = this.#map.resolvedSources.findIndex((source) => source === filename || resolve(this.#directory, source) === filename);
+ const sourcesContent = this.#map.sourcesContent?.[index];
+ if (sourcesContent == null) return null;
+ const lines = sourcesContent.split("\n").slice(loc.start.line - 1, loc.end.line);
+ lines[0] = lines[0].slice(loc.start.column);
+ lines[lines.length - 1] = lines[lines.length - 1].slice(0, loc.end.column);
+ return lines.join("\n");
+ }
+};
+function getPosition(needle, map) {
+ let position = originalPositionFor(map, needle);
+ if (position.source == null) position = originalPositionFor(map, {
+ column: needle.column,
+ line: needle.line,
+ bias: LEAST_UPPER_BOUND
+ });
+ if (position.source == null) return null;
+ return {
+ line: position.line,
+ column: position.column,
+ filename: position.source
+ };
+}
+function createEmptySourceMap(filename, code) {
+ const mappings = [];
+ for (const [line, content] of code.split("\n").entries()) {
+ const parts = content.match(WORD_PATTERN) || [];
+ const segments = [];
+ let column = 0;
+ for (const part of parts) {
+ segments.push([
+ column,
+ 0,
+ line,
+ column
+ ]);
+ column += part.length;
+ }
+ mappings.push(segments);
+ }
+ return {
+ version: 3,
+ mappings,
+ file: filename,
+ sources: [filename],
+ sourcesContent: [code],
+ names: []
+ };
+}
+async function getInlineSourceMap(filename, code) {
+ const match = code.match(INLINE_MAP_PATTERN)?.[1];
+ if (!match) return null;
+ try {
+ if (match.includes(BASE_64_PREFIX)) {
+ const encoded = match.split(BASE_64_PREFIX).at(-1) || "";
+ const decoded = atob(encoded);
+ return JSON.parse(decoded);
+ }
+ const content = await readFile(resolve(dirname(filename), match), "utf-8");
+ return JSON.parse(content);
+ } catch {
+ return null;
+ }
+}
+function tryReadFileSync(filename) {
+ try {
+ return readFileSync(filename, "utf8");
+ } catch {
+ return;
+ }
+}
+
+//#endregion
+//#region src/script-coverage.ts
+function normalize(scriptCoverage) {
+ if (scriptCoverage.functions.length === 0) return [];
+ const ranges = scriptCoverage.functions.flatMap((fn) => fn.ranges.map((range) => ({
+ start: range.startOffset,
+ end: range.endOffset,
+ count: range.count,
+ area: range.endOffset - range.startOffset
+ }))).sort((a, b) => {
+ const diff = b.area - a.area;
+ if (diff !== 0) return diff;
+ return a.end - b.end;
+ });
+ let maxEnd = 0;
+ for (const r of ranges) if (r.end > maxEnd) maxEnd = r.end;
+ const hits = new Uint32Array(maxEnd + 1);
+ for (const range of ranges) hits.fill(range.count, range.start, range.end + 1);
+ const normalized = [];
+ let start = 0;
+ for (let end = 1; end <= hits.length; end++) {
+ const isLast = end === hits.length;
+ const current = isLast ? null : hits[end];
+ const previous = hits[start];
+ if (current !== previous || isLast) {
+ normalized.push({
+ start,
+ end: end - 1,
+ count: previous
+ });
+ start = end;
+ }
+ }
+ return normalized;
+}
+function getCount(offset, coverages) {
+ let low = 0;
+ let high = coverages.length - 1;
+ while (low <= high) {
+ const mid = Math.floor((low + high) / 2);
+ const coverage = coverages[mid];
+ if (coverage.start <= offset.startOffset && offset.startOffset <= coverage.end) return coverage.count;
+ else if (offset.startOffset < coverage.start) high = mid - 1;
+ else low = mid + 1;
+ }
+ return 0;
+}
+
+//#endregion
+//#region src/coverage-mapper.ts
+var CoverageMapper = class CoverageMapper {
+ constructor(locator, coverageMapData, ranges, wrapperLength, directory, onIgnoreNode, ignoreNode, ignoreSourceCode) {
+ this.locator = locator;
+ this.coverageMapData = coverageMapData;
+ this.ranges = ranges;
+ this.wrapperLength = wrapperLength;
+ this.directory = directory;
+ this.onIgnoreNode = onIgnoreNode;
+ this.ignoreNode = ignoreNode;
+ this.ignoreSourceCode = ignoreSourceCode;
+ }
+ static async create(options, onIgnoreNode) {
+ const filename = fileURLToPath(options.coverage.url);
+ const directory = dirname(filename);
+ const map = new TraceMap(options.sourceMap || await getInlineSourceMap(filename, options.code) || createEmptySourceMap(filename, options.code));
+ return new CoverageMapper(new Locator(options.code, map, directory), createCoverageMapData(filename, map), normalize(options.coverage), options.wrapperLength || 0, directory, onIgnoreNode, options.ignoreNode, options.ignoreSourceCode);
+ }
+ onFunction(node, positions) {
+ if (this.#onIgnore(node, "function")) return;
+ const loc = this.locator.getLoc(positions.loc);
+ if (loc === null) return;
+ const decl = this.locator.getLoc(positions.decl);
+ if (decl === null) return;
+ const covered = getCount({
+ startOffset: node.start + this.wrapperLength,
+ endOffset: node.end + this.wrapperLength
+ }, this.ranges);
+ if (this.ignoreSourceCode) {
+ const current = this.locator.getLoc(node) || loc;
+ const sources = this.locator.getSourceLines(current, this.#getSourceFilename(current));
+ if (sources != null && this.ignoreSourceCode(sources, "function", {
+ start: {
+ line: current.start.line,
+ column: current.start.column
+ },
+ end: {
+ line: current.end.line,
+ column: current.end.column
+ }
+ })) return;
+ }
+ addFunction({
+ coverageMapData: this.coverageMapData,
+ covered,
+ loc,
+ decl,
+ filename: this.#getSourceFilename(loc),
+ name: getFunctionName(node)
+ });
+ }
+ onStatement(node, parent) {
+ if (this.#onIgnore(parent || node, "statement")) return;
+ const loc = this.locator.getLoc(node);
+ if (loc === null) return;
+ const covered = getCount({
+ startOffset: (parent || node).start + this.wrapperLength,
+ endOffset: (parent || node).end + this.wrapperLength
+ }, this.ranges);
+ if (this.ignoreSourceCode) {
+ const current = parent && this.locator.getLoc(parent) || loc;
+ const sources = this.locator.getSourceLines(current, this.#getSourceFilename(current));
+ if (sources != null && this.ignoreSourceCode(sources, "statement", {
+ start: {
+ line: current.start.line,
+ column: current.start.column
+ },
+ end: {
+ line: current.end.line,
+ column: current.end.column
+ }
+ })) return;
+ }
+ addStatement({
+ coverageMapData: this.coverageMapData,
+ loc,
+ covered,
+ filename: this.#getSourceFilename(loc)
+ });
+ }
+ onBranch(type, node, branches) {
+ if (this.#onIgnore(node, "branch")) return;
+ const loc = this.locator.getLoc(node);
+ if (loc === null) return;
+ const locations = [];
+ const covered = [];
+ for (const branch of branches) {
+ if (!branch) {
+ locations.push({
+ start: {
+ line: void 0,
+ column: void 0
+ },
+ end: {
+ line: void 0,
+ column: void 0
+ }
+ });
+ const count = getCount({
+ startOffset: node.start + this.wrapperLength,
+ endOffset: node.end + this.wrapperLength
+ }, this.ranges);
+ const previous = covered.at(-1) || 0;
+ covered.push(count - previous);
+ continue;
+ }
+ const location = this.locator.getLoc(branch);
+ if (location !== null) locations.push(location);
+ const bias = branch.type === "BlockStatement" ? 1 : 0;
+ covered.push(getCount({
+ startOffset: branch.start + bias + this.wrapperLength,
+ endOffset: branch.end - bias + this.wrapperLength
+ }, this.ranges));
+ }
+ if (type === "if") {
+ if (locations.length > 0) locations[0] = loc;
+ }
+ if (locations.length === 0) return;
+ if (this.ignoreSourceCode) {
+ const sources = this.locator.getSourceLines(loc, this.#getSourceFilename(loc));
+ if (sources != null && this.ignoreSourceCode(sources, "branch", {
+ start: {
+ line: loc.start.line,
+ column: loc.start.column
+ },
+ end: {
+ line: loc.end.line,
+ column: loc.end.column
+ }
+ })) return;
+ }
+ addBranch({
+ coverageMapData: this.coverageMapData,
+ loc,
+ locations,
+ type,
+ covered,
+ filename: this.#getSourceFilename(loc)
+ });
+ }
+ generate() {
+ this.locator.reset();
+ return this.coverageMapData;
+ }
+ #getSourceFilename(position) {
+ const sourceFilename = position.start.filename || position.end.filename;
+ if (!sourceFilename) throw new Error(`Missing original filename for ${JSON.stringify(position, null, 2)}`);
+ if (sourceFilename.startsWith("file://")) return fileURLToPath(sourceFilename);
+ return resolve(this.directory, sourceFilename);
+ }
+ #onIgnore(node, type) {
+ if (!this.ignoreNode) return false;
+ const scope = this.ignoreNode(node, type);
+ if (scope === "ignore-this-and-nested-nodes") this.onIgnoreNode(node);
+ return scope;
+ }
+};
+
+//#endregion
+//#region src/index.ts
+/**
+* Maps V8 `ScriptCoverage` to Istanbul's `CoverageMap`.
+* Results are identical with `istanbul-lib-instrument`.
+*/
+async function convert(options) {
+ const ignoreHints = getIgnoreHints(options.code);
+ if (ignoreHints.length === 1 && ignoreHints[0].type === "file") return {};
+ const walker = getWalker();
+ const mapper = await CoverageMapper.create(options, walker.onIgnore);
+ const ast = await options.ast;
+ await walker.walk(ast, ignoreHints, options.ignoreClassMethods, {
+ onFunctionDeclaration(node) {
+ mapper.onFunction(node, {
+ loc: node.body,
+ decl: node.id || {
+ ...node,
+ end: node.start + 1
+ }
+ });
+ },
+ onFunctionExpression(node) {
+ if (isCovered(node)) return;
+ mapper.onFunction(node, {
+ loc: node.body,
+ decl: node.id || {
+ ...node,
+ end: node.start + 1
+ }
+ });
+ },
+ onArrowFunctionExpression(node) {
+ mapper.onFunction(node, {
+ loc: node.body,
+ decl: {
+ ...node,
+ end: node.start + 1
+ }
+ });
+ if (node.body.type !== "BlockStatement") mapper.onStatement(node.body, node);
+ },
+ onMethodDefinition(node) {
+ if (node.value.type === "FunctionExpression") setCovered(node.value);
+ mapper.onFunction(node, {
+ loc: node.value.body,
+ decl: node.key
+ });
+ },
+ onProperty(node) {
+ if (node.value.type === "FunctionExpression") {
+ setCovered(node.value);
+ mapper.onFunction(node, {
+ loc: node.value.body,
+ decl: node.key
+ });
+ }
+ },
+ onClassMethod(babelNode) {
+ const node = {
+ type: "FunctionExpression",
+ start: babelNode.start,
+ end: babelNode.end,
+ body: {
+ type: "BlockStatement",
+ start: babelNode.body.start,
+ end: babelNode.body.end,
+ body: []
+ },
+ params: []
+ };
+ mapper.onFunction(node, {
+ loc: node.body,
+ decl: {
+ start: babelNode.key.start,
+ end: babelNode.key.end
+ }
+ });
+ },
+ onObjectMethod(babelNode) {
+ const node = {
+ type: "FunctionExpression",
+ start: babelNode.start,
+ end: babelNode.end,
+ body: {
+ type: "BlockStatement",
+ start: babelNode.body.start,
+ end: babelNode.body.end,
+ body: []
+ },
+ params: []
+ };
+ mapper.onFunction(node, {
+ loc: node.body,
+ decl: {
+ start: babelNode.key.start,
+ end: babelNode.key.end
+ }
+ });
+ },
+ onBreakStatement: (node) => mapper.onStatement(node),
+ onContinueStatement: (node) => mapper.onStatement(node),
+ onDebuggerStatement: (node) => mapper.onStatement(node),
+ onReturnStatement: (node) => mapper.onStatement(node),
+ onThrowStatement: (node) => mapper.onStatement(node),
+ onTryStatement: (node) => mapper.onStatement(node),
+ onForStatement: (node) => mapper.onStatement(node),
+ onForInStatement: (node) => mapper.onStatement(node),
+ onForOfStatement: (node) => mapper.onStatement(node),
+ onWhileStatement: (node) => mapper.onStatement(node),
+ onDoWhileStatement: (node) => mapper.onStatement(node),
+ onWithStatement: (node) => mapper.onStatement(node),
+ onLabeledStatement: (node) => mapper.onStatement(node),
+ onExpressionStatement(node) {
+ if (node.expression.type === "Literal" && node.expression.value === "use strict") return;
+ mapper.onStatement(node);
+ },
+ onVariableDeclarator(node) {
+ if (node.init) mapper.onStatement(node.init, node);
+ },
+ onClassBody(node) {
+ for (const child of node.body) if ((child.type === "PropertyDefinition" || child.type === "ClassProperty" || child.type === "ClassPrivateProperty") && child.value) mapper.onStatement(child.value);
+ },
+ onIfStatement(node, branches) {
+ mapper.onBranch("if", node, branches);
+ mapper.onStatement(node);
+ },
+ onConditionalExpression(node, branches) {
+ mapper.onBranch("cond-expr", node, branches);
+ },
+ onLogicalExpression(node, branches) {
+ mapper.onBranch("binary-expr", node, branches);
+ },
+ onSwitchStatement(node, cases) {
+ mapper.onBranch("switch", node, cases);
+ mapper.onStatement(node);
+ },
+ onAssignmentPattern(node) {
+ mapper.onBranch("default-arg", node, [node.right]);
+ }
+ });
+ return mapper.generate();
+}
+const coveredNodes = /* @__PURE__ */ new WeakSet();
+function setCovered(node) {
+ coveredNodes.add(node);
+}
+function isCovered(node) {
+ return coveredNodes.has(node);
+}
+
+//#endregion
+export { convert, convert as default }; \ No newline at end of file