1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
//! Istanbul-compatible JavaScript/TypeScript coverage instrumentation using the Oxc AST.
//!
//! This crate parses JS/TS source with [`oxc_parser`], identifies statements,
//! functions, and branches, injects coverage counter expressions, and emits
//! instrumented code. The coverage map output is compatible with Istanbul's
//! `coverage-final.json` format (consumed by Jest, Vitest, c8, nyc, Codecov).
//!
//! ## Example
//!
//! ```
//! use oxc_coverage_instrument::{instrument, InstrumentOptions};
//!
//! let source = "function add(a, b) { return a + b; }";
//! let result = instrument(source, "add.js", &InstrumentOptions::default()).unwrap();
//!
//! println!("Instrumented code:\n{}", result.code);
//! println!("Functions found: {}", result.coverage_map.fn_map.len());
//! ```
//!
//! ## Coverage model
//!
//! The coverage map tracks three dimensions:
//!
//! - **Statements**: every executable statement gets a counter
//! - **Functions**: every function declaration, expression, arrow, and method
//! - **Branches**: if/else, ternary, switch cases, logical &&/||
//!
//! Function names are inferred from the binding an anonymous function is
//! attached to (declarator, property key, assignment target) where
//! `istanbul-lib-instrument` emits `(anonymous_N)`. See the README section
//! "Differences from istanbul-lib-instrument" for the full list.
//!
//! ## Options
//!
//! [`InstrumentOptions`] defaults to Istanbul-compatible behaviour. The fields
//! whose semantics do not fit on a single line are expanded below.
//!
//! ### Composing an input source map
//!
//! [`InstrumentOptions::compose_input_source_map`] folds
//! [`InstrumentOptions::input_source_map`] into the coverage map during
//! instrumentation instead of embedding it for downstream composition.
//!
//! The resulting [`FileCoverage`] (and the `coverageData` literal baked into
//! the instrumented code's preamble, hence the runtime coverage variable)
//! carries original-source positions, is re-keyed by the original source
//! `path`, and has no `inputSourceMap` field. A subsequent [`remap_coverage`]
//! / `remapCoverageMap` on the result is a no-op. This trades the
//! per-collection remap round-trip (instrument, then walk every entry through
//! its embedded map at report time) for a one-time composition at instrument
//! time.
//!
//! A coverage point whose positions do not remap through the input source map
//! is not instrumented at all: it gets no `statementMap` / `fnMap` /
//! `branchMap` entry and no counter in the emitted code, so the runtime
//! `__coverage__` object and the emitted counters cannot disagree. Composition
//! is then a pure remap of the surviving positions, and never emits past-EOF
//! entries.
//!
//! If the input map is unusable (declares no source, fails to parse) the gate
//! is off and the embedded `inputSourceMap` is left in place so the lazy remap
//! path still works.
//!
//! ### TypeScript and decorators
//!
//! [`InstrumentOptions::strip_typescript`] runs `oxc_transformer`'s
//! TypeScript-strip pass on the parsed AST before coverage instrumentation.
//! Set it when passing raw TypeScript that has not been pre-transformed by
//! Babel / tsc / esbuild. The output is instrumented JavaScript whose
//! `statementMap` / `branchMap` positions reference the original TypeScript
//! byte offsets, because surviving AST nodes retain their `Span` through the
//! strip pass. **If it is left off and raw TypeScript is passed, the output
//! contains TypeScript syntax and is not executable as JavaScript** (no error
//! is returned). JSX is preserved verbatim on `.tsx` files: the codegen pass
//! emits it unchanged.
//!
//! By default, decorator syntax (Stage 3 and legacy `experimentalDecorators`
//! alike) flows through unchanged. NestJS / Angular / TypeORM users who need
//! `@Injectable()` / `@Controller()` classes lowered into `_decorate(...)`
//! calls, with or without `design:type` / `design:paramtypes` metadata, set
//! [`InstrumentOptions::decorator_mode`] to [`DecoratorMode::Experimental`] or
//! [`DecoratorMode::ExperimentalWithMetadata`].
//!
//! [`InstrumentOptions::strict_null_checks`] is only consulted under
//! [`DecoratorMode::ExperimentalWithMetadata`], where it decides how a
//! nullable union is written into the emitted `design:type` metadata. With
//! `true`, `foo: string | null` emits `Object`, matching what `tsc` does under
//! `strictNullChecks`. With `false`, `null` and `undefined` are elided from
//! the union first, so the same property emits `String`. Getting this wrong is
//! silent: the instrumented code still runs, but NestJS dependency injection,
//! TypeORM column inference, and class-validator all read that metadata and
//! will see a different type than `tsc` would have produced. Set it to match
//! the `tsconfig.json` the source is compiled with.
//!
//! ### Naming callback arguments
//!
//! [`InstrumentOptions::name_callback_arguments`] names a function or arrow
//! expression that is a direct argument of a call or `new` expression and has
//! no other inferable name, deriving the name from the callee:
//! `arr.map(x => x)` gives `"map"`, `el.addEventListener("click", () => {})`
//! gives `"addEventListener"`, `new Promise((res) => {})` gives `"Promise"`.
//! `istanbul-lib-instrument` leaves these `(anonymous_N)`, so this is an
//! opt-in enhancement rather than the default. Names inferred from a binding
//! (variable declarator, property key, assignment target, default value) still
//! take precedence; only the `(anonymous_N)` fallback is replaced. Because the
//! name comes from the callee it is stable across rebuilds, where the
//! `(anonymous_N)` counter renumbers as unrelated functions are added, which
//! matters for downstream tools that key function identity on the name.
//!
//! Only the callee is used, never a sibling string argument such as a route
//! path or a test description: the traversal ancestor for an argument position
//! exposes the callee but not the other arguments.
//!
//! ## References
//!
//! - <https://github.com/istanbuljs/istanbuljs/tree/istanbul-lib-instrument-v6.0.3/packages/istanbul-lib-instrument>
pub use ;
pub use ;
pub use ;
pub use ;