Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
4ea5786
[ts-frontend] M1: scaffold, EtsIR DTO mirrors, serializer, invariant …
CaelmBleidd Jul 2, 2026
6beec1a
[ts-frontend] M2: TypeScript type -> TypeDto conversion
CaelmBleidd Jul 2, 2026
f3c8fd6
[ts-frontend] M3: straight-line lowering to three-address code
CaelmBleidd Jul 2, 2026
b6d05d7
[ts-frontend] M4: control-flow lowering (CFG)
CaelmBleidd Jul 2, 2026
a251ff6
[ts-frontend] M5: classes, interfaces, enums, namespaces
CaelmBleidd Jul 2, 2026
f82c1f5
[ts-frontend] M6: try/catch/finally and import/export infos
CaelmBleidd Jul 2, 2026
162fe37
[ts-frontend] M7: closures, object literals, destructuring, optional …
CaelmBleidd Jul 2, 2026
77d61fd
[ts-frontend] M8: provider selection, project/multi CLI modes, Gradle…
CaelmBleidd Jul 2, 2026
deb6c07
[ts-frontend] M9: CI integration and documentation
CaelmBleidd Jul 2, 2026
14f7665
[ts-frontend] Expand README with full usage documentation
CaelmBleidd Jul 2, 2026
b356509
[ts-frontend] Fix ci-ets: unbreak ArkAnalyzer setup and make it best-…
CaelmBleidd Jul 3, 2026
ab85ff1
[ts-frontend] Fix ArkAnalyzer setup: pin @types/node via the manifest
CaelmBleidd Jul 3, 2026
cbc8e5e
[ts-frontend] Review fixes: PtrCallExpr.ptr validation, inc/dec seman…
CaelmBleidd Jul 3, 2026
6758a43
[ts-frontend] Hoist raw fallback values into temps
CaelmBleidd Jul 3, 2026
9b6ca2a
[ts-frontend] Duplicate finally blocks on abrupt exits
CaelmBleidd Jul 3, 2026
525637f
[ts-frontend] Review fixes: cast-stripped LHS in raw-value check, ci.…
CaelmBleidd Jul 3, 2026
ba04250
[ts-frontend] Preserve source origins in EtsIR
CaelmBleidd Jul 17, 2026
ed94d48
[ts-frontend] Preserve array element types in lowering
CaelmBleidd Jul 18, 2026
cb4eb99
[ts-frontend] Preserve expression and scope semantics
CaelmBleidd Jul 19, 2026
a42c8a4
[ts-frontend] Model closures and derived constructors
CaelmBleidd Jul 19, 2026
8df790e
[ts-frontend] Bundle runtime and honor project config
CaelmBleidd Jul 19, 2026
368bf8a
[ts-frontend] Preserve inferred collection structure
CaelmBleidd Jul 19, 2026
00209b1
[ts-frontend] Finalize production frontend semantics
CaelmBleidd Jul 22, 2026
6ea830c
[ts-frontend] Fix reviewed lowering semantics
Jul 22, 2026
26eb87f
Fix review findings in the native TypeScript frontend
CaelmBleidd Aug 2, 2026
28236fb
Fix JDK 8 build failure: avoid Java 9+ Redirect.DISCARD
CaelmBleidd Aug 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 45 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
with:
# Only write to the cache for builds on the specific branches. (Default is 'main' only.)
# Builds on other branches will only read existing entries from the cache.
cache-read-only: ${{ github.ref != 'refs/heads/develop' && github.ref != 'ref/heads/neo' }}
cache-read-only: ${{ github.ref != 'refs/heads/develop' && github.ref != 'refs/heads/neo' }}

- name: Build and run tests
run: ./gradlew --scan build -x :jacodb-ets:build
Expand Down Expand Up @@ -108,31 +108,57 @@ jobs:
with:
# Only write to the cache for builds on the specific branches. (Default is 'main' only.)
# Builds on other branches will only read existing entries from the cache.
cache-read-only: ${{ github.ref != 'refs/heads/develop' && github.ref != 'ref/heads/neo' }}
cache-read-only: ${{ github.ref != 'refs/heads/develop' && github.ref != 'refs/heads/neo' }}

- name: Set up ArkAnalyzer
- name: Set up Node.js
uses: actions/setup-node@v4
with:
# Single source of truth, shared with the publish workflows.
node-version-file: jacodb-ets/ts-frontend/.nvmrc
cache: npm
cache-dependency-path: jacodb-ets/ts-frontend/package-lock.json

- name: Build and test ts-frontend
working-directory: jacodb-ets/ts-frontend
run: |
npm ci
npm run build
npm test

# The legacy ArkAnalyzer provider stays supported (selectable via
# ETS_IR_PROVIDER=arkanalyzer); setting ARKANALYZER_DIR here enables
# the provider-parity test in EtsTsFrontendTest.
#
# This step is BLOCKING on purpose: with `continue-on-error` a failure here
# left ARKANALYZER_DIR unset and the parity test silently skipped itself
# (assumeTrue), so ts-frontend/ArkAnalyzer regressions went unnoticed.
- name: Set up ArkAnalyzer (legacy provider)
run: |
REPO_URL="https://gitcode.com/Lipen/arkanalyzer"
DEST_DIR="arkanalyzer"
MAX_RETRIES=10
RETRY_DELAY=3 # Delay between retries in seconds
BRANCH="neo/2025-09-03"
# Pinned commit of branch neo/2025-09-03: a third-party repository must not be
# able to change the code executed on the runner under our feet.
COMMIT="d9d7d5ffddb1f4081f90a73836c865794ec6a88c"

mkdir -p "$DEST_DIR"
cd "$DEST_DIR"
git init -q
git remote add origin "$REPO_URL"

for ((i=1; i<=MAX_RETRIES; i++)); do
git clone --depth=1 --branch $BRANCH $REPO_URL $DEST_DIR && break
echo "Clone failed, retrying in $RETRY_DELAY seconds..."
git fetch --depth=1 origin "$COMMIT" && break
echo "Fetch failed, retrying in $RETRY_DELAY seconds..."
sleep "$RETRY_DELAY"
done

if [[ $i -gt $MAX_RETRIES ]]; then
echo "Failed to clone the repository after $MAX_RETRIES attempts."
echo "Failed to fetch the repository after $MAX_RETRIES attempts."
exit 1
else
echo "Repository cloned successfully."
fi

echo "ARKANALYZER_DIR=$(realpath $DEST_DIR)" >> $GITHUB_ENV
cd $DEST_DIR
git checkout -q FETCH_HEAD
echo "Repository checked out at $COMMIT."

# ArkAnalyzer's bundled TypeScript (ohos-typescript 4.9.5) cannot parse
# the d.ts files of the latest floating @types/node (e.g. ffi.d.ts uses
Expand All @@ -141,10 +167,17 @@ jobs:
# NB: do not run a second `npm install <pkg>` afterwards — it re-resolves
# the tree and prunes ohos-typescript, which the postinstall script adds
# with --no-save (i.e. it is absent from package.json).
#
# `--ignore-scripts` is NOT usable here for exactly that reason: ohos-typescript
# is installed by the postinstall hook and the build fails without it. The
# exposure is bounded by the pinned commit fetched above.
npm pkg set 'devDependencies.@types/node=18'
npm install
npm run build

# Export only after a successful build so a broken checkout is never used.
echo "ARKANALYZER_DIR=$(realpath .)" >> $GITHUB_ENV

- name: Run ETS tests
run: ./gradlew --scan :jacodb-ets:generateTestResources :jacodb-ets:test

Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/nightly-builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ jobs:
with:
java-version: '11'
distribution: 'temurin'
# `publish` builds the bundled ts-frontend runtime via npm, so the Node
# version baked into the published artifact must be pinned explicitly.
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version-file: jacodb-ets/ts-frontend/.nvmrc
cache: npm
cache-dependency-path: jacodb-ets/ts-frontend/package-lock.json
- name: Publish package
uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1
with:
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/publish-snapshot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ jobs:
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4

# `publish` builds the bundled ts-frontend runtime via npm, so the Node
# version baked into the published artifact must be pinned explicitly.
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version-file: jacodb-ets/ts-frontend/.nvmrc
cache: npm
cache-dependency-path: jacodb-ets/ts-frontend/package-lock.json

- name: Generate snapshot version
id: version
run: |
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ jobs:
with:
java-version: '11'
distribution: 'temurin'
# `publish` builds the bundled ts-frontend runtime via npm, so the Node
# version baked into the published artifact must be pinned explicitly.
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version-file: jacodb-ets/ts-frontend/.nvmrc
cache: npm
cache-dependency-path: jacodb-ets/ts-frontend/package-lock.json
- name: Publish package
uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1
with:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ build/
idea-community
*.db
/generated/
.tasks/
6 changes: 6 additions & 0 deletions jacodb-ets/ARKANALYZER.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# ArkAnalyzer

> **Note:** ArkAnalyzer is now the LEGACY EtsIR provider. The default provider
> is the native TypeScript frontend in [`ts-frontend`](ts-frontend/README.md),
> which requires no external checkout. ArkAnalyzer remains fully supported:
> select it with `ETS_IR_PROVIDER=arkanalyzer` (plus `ARKANALYZER_DIR`) or by
> passing `EtsIrProvider.ARKANALYZER` to the `loadEts*AutoConvert` functions.

## Installation

Clone and install the ArkAnalyzer via NPM:
Expand Down
39 changes: 39 additions & 0 deletions jacodb-ets/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# jacodb-ets changelog

## Unreleased

### Added

- Native TypeScript frontend (`jacodb-ets/ts-frontend`) bundled into the `jacodb-ets` JAR
and used by default for TS/JS input. ArkTS (`.ets`) and SDK trees keep using the legacy
ArkAnalyzer provider. The provider can be forced with the `ETS_IR_PROVIDER` environment
variable (`ts-frontend` / `arkanalyzer`).
- `EtsStmtLocation.origin` (`EtsSourceSpan`): the source range a statement was lowered from.
Only the TS frontend emits origins; with ArkAnalyzer it is always `null`.
It is a mutable property outside the primary constructor and therefore does NOT participate
in `equals` / `hashCode` of `EtsStmtLocation` or of any `EtsStmt`. For the same reason the
generated `EtsStmtLocation.copy()` does not carry `origin` (a copy always has `origin == null`);
use the three-argument constructor or `EtsStmtLocation.stub(...)` to preserve it.

### Changed (breaking)

- `EtsClosureFieldRef` now implements `EtsLValue`, so it can legally appear as
`EtsAssignStmt.lhv`. `EtsLValue` is not sealed, so nothing inside the repository breaks,
but **external analyses with an exhaustive `when` over LHV kinds and an `else -> error()`
branch must handle `EtsClosureFieldRef`.**
- `generateEtsIR` no longer logs a failure and returns the output path: it now throws
`EtsIrGenerationException` on a non-zero exit code or a timeout. Partial output is kept
on disk (its path is included in the exception message) and the full stdout/stderr is
written to the log; the exception message itself is truncated.
- The default `generateEtsIR` timeout is no longer 10 seconds: it is 60 seconds for a single
file and 10 minutes in project mode, and it can be overridden with the
`ETS_IR_GENERATION_TIMEOUT_SEC` environment variable.
- `loadEtsProjectAutoConvert` now resolves its default provider with `defaultProviderFor(...)`
(consistent with `generateEtsIR` / `loadEtsFileAutoConvert`), so an ArkTS project is no
longer silently converted into an empty `EtsScene`.
- `generateSdkIR` explicitly forces the ArkAnalyzer provider: SDK trees consist of declaration
files, which the native frontend deliberately skips.
- Binary compatibility: `EtsMethodBuilder`, `EtsStmtLocation` and the `loadEts*AutoConvert`
helpers changed their signatures; recompilation of downstream consumers is required.
- `SourceSpanDto.fileName` is now optional in the wire format: frontends omit it for spans
belonging to the enclosing file, and the Kotlin side falls back to the file signature.
Loading
Loading