Skip to content

JavaScript: migrate the TypeScript parser to native 7.1 - #22841

Draft
paldepind wants to merge 3 commits into
mainfrom
js/typescript-7.1
Draft

paldepind wants to merge 3 commits into
mainfrom
js/typescript-7.1

Conversation

@paldepind

@paldepind paldepind commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Migrate the JavaScript/TypeScript extractor from TypeScript 5.9.2 to the pinned native typescript@7.1.0-dev.20261015.1 npm package.

  • Port the parser wrapper to typescript/sync and typescript/ast, explicitly projecting native AST getters into the existing Java-facing JSON protocol.
  • Preserve syntax diagnostics, source positions, namespace flags, interface heritage, legacy import assertions, and token classifications. Intentionally fix the previously omitted import-attribute keys and values.
  • Package native executables separately from the common JavaScript API, including both macOS architectures, and preserve executable permissions during installation.
  • Bound native resources to each file, account for Node RSS when setting the native memory budget, and make reset, quit, EOF, and native failures release resources reliably.
  • Add production-wrapper, lifecycle, installed-package, and source-phase import regression coverage. Make the extraction-diagnostic failure test deterministic by terminating the native child.

Validation

  • Pinned TypeScript compiler build/type check and existing TSLint checks.
  • Seven compiled-wrapper tests under the production Node.js 18.15.0 runtime.
  • 23 parser compatibility/probe tests.
  • 500 Java extractor tests, using an adapter for the legacy fixture layout.
  • 68 TypeScript QL tests plus the syntax-error query test.
  • Both syntax-error and internal-error diagnostic integration tests.
  • Installed-package smoke tests on macOS arm64 and macOS x64 (the latter through Rosetta), without an external TypeScript installation.
  • All distribution runtime ZIPs assembled and inspected. CI integration tests additionally passed on Linux x64, Linux arm64, and Windows x64, including Windows 2022.

Only the reviewed import-attribute TRAP expectation changed; no existing QL expectations changed.

Performance tradeoff

On macOS arm64 with Node.js 18.15.0, median parser/protocol time over three runs increased from 0.237 s to 1.349 s for 103 tiny fixture files, and from 0.991 s to 1.116 s for five parses of a 588 KB declaration file. Sampled combined Node-plus-native RSS was slightly lower. The per-file native-process lifetime is retained deliberately to bound resources; this migration does not claim a speedup. Details and measurement scope are documented in the wrapper README.

Preserve the Java-facing extraction protocol while adopting the pinned native TypeScript API and platform-specific runtimes. Add compatibility, lifecycle, packaging, and syntax regression coverage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 86598cdc-5945-4d8e-9ea4-eeb4eb4356ba
@paldepind
paldepind requested review from a team as code owners October 19, 2026 09:59
Copilot AI max review requested due to automatic review settings October 19, 2026 09:59
Pass wrapper and native archive entries to Bazel zipper through response files instead of expanding every path on the command line.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 86598cdc-5945-4d8e-9ea4-eeb4eb4356ba

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The production parser and packaging overhaul still lacks Linux and Windows execution coverage and needs human review.

3 open issues
2 files not reviewed
  • javascript/extractor/lib/typescript/package-lock.json: Generated file
  • javascript/extractor/lib/typescript/ts7/package-lock.json: Generated file
What changed in this PR

Migrates the JavaScript extractor’s TypeScript parser to native 7.1 while preserving its Java-facing AST protocol.

Changes:

  • Ports AST projection and manages native resources per file.
  • Separates common JavaScript files from platform-specific executables.
  • Adds compatibility, lifecycle, packaging, and diagnostic coverage.
File Description
misc/​bazel/​pkg.bzl Supports architecture-specific imported ZIPs.
javascript/​ql/​test/​library-tests/​TypeScript/​SourceImports/​tst.ts Adds source-phase import fixture.
javascript/​ql/​test/​library-tests/​TypeScript/​SourceImports/​test.ql Checks imports and references.
javascript/​ql/​test/​library-tests/​TypeScript/​SourceImports/​test.expected Records expected bindings.
javascript/​ql/​integration-tests/​diagnostics/​internal-error/​test.py Enables injected native failure.
javascript/​ql/​integration-tests/​diagnostics/​internal-error/​fail-native.cjs Terminates the spawned child.
javascript/​extractor/​tests/​ts/​output/​trap/​import-attributes.ts.trap Records import-attribute extraction.
javascript/​extractor/​test/​com/​semmle/​js/​extractor/​test/​BUILD.bazel Adds native runtime test inputs.
javascript/​extractor/​test/​com/​semmle/​js/​extractor/​test/​AllTests.java Installs ZIPs with executable permissions.
javascript/​extractor/​lib/​typescript/​tsconfig.json Updates compilation for ESM.
javascript/​extractor/​lib/​typescript/​ts7/​wrapper.test.mjs Tests protocol compatibility.
javascript/​extractor/​lib/​typescript/​ts7/​probe.mjs Probes native API compatibility.
javascript/​extractor/​lib/​typescript/​ts7/​package.json Pins probe dependencies.
javascript/​extractor/​lib/​typescript/​ts7/​package-lock.json Locks probe packages.
javascript/​extractor/​lib/​typescript/​test/​package_test.py Tests installed runtime archives.
javascript/​extractor/​lib/​typescript/​test/​lifecycle.test.mjs Tests process lifecycle and failures.
javascript/​extractor/​lib/​typescript/​src/​virtual_source_root.ts Removes legacy source-root mapping.
javascript/​extractor/​lib/​typescript/​src/​typescript.js Loads native API entry points.
javascript/​extractor/​lib/​typescript/​src/​typescript.d.ts Declares native API exports.
javascript/​extractor/​lib/​typescript/​src/​main.ts Implements per-file native parsing.
javascript/​extractor/​lib/​typescript/​src/​common.ts Removes legacy project management.
javascript/​extractor/​lib/​typescript/​src/​ast_extractor.ts Projects native ASTs into JSON.
javascript/​extractor/​lib/​typescript/​README.md Documents migration and performance tradeoffs.
javascript/​extractor/​lib/​typescript/​package.json Updates runtime and build commands.
javascript/​extractor/​lib/​typescript/​package-runtime.mjs Selects and stages native executables.
javascript/​extractor/​lib/​typescript/​package-lock.json Locks production runtime packages.
javascript/​extractor/​lib/​typescript/​BUILD.bazel Builds split archives and packaging tests.
javascript/​BUILD.bazel Includes native packages in distributions.

Review effort: Max

Comment on lines +5 to +6
"engines": {
"node": ">=18.15.0"
assert.match(version, /^7\.1\.0-dev\./);
assert.equal(require("typescript").version, version);
assert.equal(require("typescript-legacy").version, "5.9.2");
const cli = join(dirname(require.resolve("typescript/package.json")), "bin/tsc");


def test(codeql, javascript, cwd):
os.environ["NODE_OPTIONS"] = f'--require "{cwd / "fail-native.cjs"}"'
Use the existing wrapper exit-code classification after IPC errors, avoiding a race between native prefetch failure and Java's next request. Preserve the communication-error fallback for a live wrapper. Record successful Linux and Windows runtime execution coverage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 86598cdc-5945-4d8e-9ea4-eeb4eb4356ba
@paldepind
paldepind marked this pull request as draft October 19, 2026 11:09
$end: node.end,
};
const properties = node as ts.Node & { [property: string]: unknown };
for (const property of astProperties) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looping over the whole astProperties array for every node seems very slow. Could we replace this with a guarded for..in loop or equivalent?

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants