Files
scriptc/docs/content/docs/coverage.mdx
Chris Tate 5aa450c6b2 docs: migrate to Geistdocs (#611)
* docs: migrate to Geistdocs

* Restore compiler files to main
2026-10-02 00:58:25 -05:00

161 lines
6.3 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: "Coverage Reports"
---
`scriptc coverage` analyzes a program without building an executable. It reports how many executable statements compile statically, which operations require the embedded JavaScript engine, and which operations are unsupported.
The counts apply to the program being analyzed, not to JavaScript or Node.js support in general. Dependency implementation statements are excluded from these totals.
## Static programs
The following program compiles entirely to native code:
```console
$ cat hello.ts
const who: string = process.argv.length > 2 ? process.argv[2] : "world";
console.log(`hello, ${who}`);
$ scriptc coverage hello.ts
statements analyzed 2
compile statically 2 (100%)
fully static — this program has no dynamic remainder.
```
A static executable does not include a JavaScript engine.
## Programs that require dynamic execution
This program imports an npm package whose JavaScript requires the embedded engine:
```console
$ cat cli.ts
import pc from "picocolors";
console.log(pc.green("hello"));
$ scriptc coverage cli.ts
statements analyzed 1
compile statically 0 (0%)
runs with --dynamic 2 sites
×1 importing 'picocolors' requires the embedded dynamic engine, which this build does not include — the package's implementation runs there SC2013
×1 values from the 'picocolors' package run in the embedded dynamic engine, which this build does not include SC2013
```
The package must be installed before analysis; the quickstart shows [how to install and use it](/docs/quickstart#use-an-npm-dependency).
### Report fields
<table>
<thead>
<tr>
<th>Field</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>statements analyzed</code></td>
<td>Executable statements in the program, excluding dependency implementation code.</td>
</tr>
<tr>
<td><code>compile statically</code></td>
<td>Statements that compile to native code.</td>
</tr>
<tr>
<td><code>runs with --dynamic</code></td>
<td>Sites that require the embedded engine. Without <code>--dynamic</code>, these sites are compilation errors. Site counts can differ from statement counts.</td>
</tr>
<tr>
<td><code>blockers</code></td>
<td>Unsupported operations, listed with a count, reason, and diagnostic code. Enabling <code>--dynamic</code> does not resolve these blockers.</td>
</tr>
</tbody>
</table>
## Analyze with --dynamic
Add `--dynamic` to include dynamic execution in the analysis:
```console
$ cat cli.ts
import pc from "picocolors";
console.log(pc.green("hello"));
$ scriptc coverage cli.ts --dynamic
statements analyzed 1
compile statically 0 (0%)
compile dynamically 1 (100%) (island sites — the embedded engine runs them)
builds with --dynamic — no remaining blockers (the island sites above run in the embedded engine).
```
The final line indicates whether the program can build with `--dynamic`. Any remaining blockers are listed in the report.
## Embedded Node.js builtins
When embedded dependencies import Node.js builtin modules, the dynamic report lists each module, its shim status, and the package that imports it.
The [commander example](/docs/dependencies#use-a-package) uses the following source:
```console
$ cat tool.ts
import { Command } from "commander";
const program = new Command();
program
.name("greet")
.argument("<name>", "who to greet")
.option("-u, --upper", "use uppercase")
.action((name: string, opts: { upper?: boolean }) => {
const text = `hello, ${name}`;
console.log(opts.upper ? text.toUpperCase() : text);
});
program.parse();
$ scriptc coverage tool.ts --dynamic
statements analyzed 5
compile statically 2 (40%)
compile dynamically 3 (60%) (island sites — the embedded engine runs them)
embedded npm code imports Node builtins:
node:child_process shimmed (commander)
node:events shimmed (commander)
node:fs shimmed (commander)
node:path shimmed (commander)
node:process shimmed (commander)
node:util shimmed (commander)
builds with --dynamic — no remaining blockers (the island sites above run in the embedded engine).
```
Shims provide supported Node.js APIs inside the embedded engine. They are separate implementations from Node.js's modules. See [npm Dependencies](/docs/dependencies#runtime-behavior) and the [Node.js compatibility reference](/compatibility) for their restrictions.
## Diagnostic codes
Coverage uses the same diagnostic codes as `scriptc build`. Common examples include:
- `SC2020`: a declared standard-library or Node.js API has no supported compiler implementation. Use the diagnostic's suggested alternative where available.
- `SC2013`: a package import or package value requires the embedded engine. Enable `--dynamic`, remove the dependency, or evaluate the experimental [static package options](/docs/dependencies#static-package-compilation-experimental).
- `SC1100`: a value crosses an unsupported `unknown`/`any` boundary. Narrow or cast the value as directed by the diagnostic.
## Type errors
Coverage requires a program that typechecks. If type checking fails, the report identifies the errors instead of producing statement counts. Fix those errors before interpreting compilation coverage.
## External host type declarations
An embedder may provide modules that are absent from `node_modules`. Use `--external-types` to map an exact bare module specifier to the embedder's declaration file during analysis. For example: `scriptc coverage src/core.ts --external-types @native-sdk/core=types/native-sdk-core.d.ts`.
The option is repeatable. Relative declaration paths resolve from the current working directory. Supported declaration extensions are `.d.ts`, `.d.mts`, and `.d.cts`. Relative declaration imports and re-exports are included, so the mapped file can be an `index.d.ts` barrel. Project-owned code using these types participates in coverage; type-only imports add no runtime boundary.
The mapping supplies types for analysis, not a runtime implementation. Value imports and uses remain `SC1010` external-host blockers while analysis counts the rest of the application. This option is available only for coverage; builds require a module implementation or runtime integration.