Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

Perry is a native TypeScript compiler written in Rust that compiles TypeScript source code directly to native executables. It uses SWC for TypeScript parsing and LLVM for code generation.

**Current Version:** 0.5.493
**Current Version:** 0.5.494


## TypeScript Parity Status
Expand Down Expand Up @@ -150,6 +150,7 @@ First-resolved directory cached in `compile_package_dirs`; subsequent imports re

Keep entries to 1-2 lines max. Full details in CHANGELOG.md.

- **v0.5.494** — Two fixes that together unblock `perry compile` for GTK4 GUI apps on Ubuntu / Debian / Fedora hosts. **(1) perry-hir lib.rs**: commit `66c5e74f` (v0.5.489) added `lower_module_with_class_id_types_and_seed,` to the `pub use lower::{...}` block in `crates/perry-hir/src/lib.rs:29` but the function definition was never pushed to `main` (it lives in an in-progress branch). Result: `cargo build -p perry-hir` on `origin/main` HEAD failed with `error[E0432]: unresolved import lower::lower_module_with_class_id_types_and_seed`, so any source build of perry from main was broken — local devs and CI could only build via the cached optimized libs. Fix: drop the stale export line. No callers on main reference the function yet (the matching `collect_modules.rs` call site is also in the in-progress branch), so the removal is a no-op for behavior. The function will return when the larger feature it belongs to is ready to land. **(2) Closes #423**: `perry compile src/main.ts` for a basic GTK4 GUI app on Ubuntu 25.10 failed at link with `undefined reference to symbol 'gst_message_parse_buffering'` + `/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0: error adding symbols: DSO missing from command line` even with `libgtk-4-dev` + `libgstreamer1.0-dev` installed. Root cause: v0.5.440 (#371) added `gstreamer = "0.23"` to `crates/perry-ui-gtk4/Cargo.toml` for the perry/media playbin backend, so the trimmed `libperry_ui_gtk4.a` retains the gstreamer-rs objects regardless of whether the user's program imports `perry/media`. But the Linux GTK4 link branch in `crates/perry/src/commands/compile/link.rs:1283-1361` only emitted GTK4 libs (`-lgtk-4 -lgio-2.0 ...`) — `pkg-config --libs gtk4` doesn't transitively reference the gstreamer-1.0 sonames, and the user's `RUSTFLAGS=-l gstreamer-1.0 ...` workaround was a dead-end since `perry compile` invokes `cc` directly for the final link (RUSTFLAGS is dropped). **Fix in one place** (link.rs, immediately after the existing `-lpulse-simple -lpulse` line): try `pkg-config --libs gstreamer-1.0 gstreamer-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0 gstreamer-audio-1.0` and append the result; on pkg-config failure fall back to hardcoded `-lgstreamer-1.0 -lgstbase-1.0 -lgstapp-1.0 -lgstvideo-1.0 -lgstaudio-1.0` (the actual library short-names — Debian/Ubuntu ship `libgstbase-1.0.so.0`, not `libgstreamer-base-1.0.so.0`, despite the pkg-config name being `gstreamer-base-1.0`). The 5 libs cover what gstreamer-rs's playbin path touches (the `query_position` / `query_duration` / message-bus iteration / appsink / video-overlay / audio-sink calls in `media_playback.rs`). Same pkg-config → hardcoded-fallback shape as the existing GTK4 block above. Fallback path emits a warning that names the apt + dnf packages (`libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev` / `gstreamer1-devel gstreamer1-plugins-base-devel`). The `[strip-dedup] rlib NOT found` line the user also reported is benign — it's a fallback path that triggers symbol-based dedup instead, exactly what strip-dedup is designed to do when the companion .rlib isn't shipped (and we don't ship it). Verified: `cargo build --release -p perry` clean. End-to-end on Ubuntu 25.10 needs the user's host since GitHub runners are 22.04/24.04 — the fix matches the gstreamer-rs build's link expectations and the pre-existing GTK4 pkg-config probe shape that's been load-bearing on Linux since v0.5.181.
- **v0.5.493** — codegen-arkts: button styling fidelity on HarmonyOS to match the macOS Apple-style reference. Three concrete fixes in `crates/perry-codegen-arkts/src/lib.rs`. (1) **`mutator_background_color` now takes `bindings` and uses `numeric_arg_resolved`**: pre-fix it only matched bare `Lit::Num` literals at each of the 4 channel positions, so Mango's `widgetSetBackgroundColor(btn, moR, moG, moB, 1.0)` (where `moR/moG/moB` are const-bindings holding the 0.99/0.62/0.10 mango-orange channels) silently dropped the modifier — Mango's "+ New Connection" button rendered with ArkUI's default blue Capsule. Now resolves through const-bindings + Conditional folding via the existing 16-hop chaser: emits `.backgroundColor('rgba(255, 159, 28, 1)')` correctly. (2) **New `buttonSetTextColor` handler**: emits `.fontColor('rgba(R,G,B,A)')` resolved through bindings. Mango's white-on-orange button text now visible. (3) **New `buttonSetBordered(btn, 0)` handler**: emits `.backgroundColor(Color.Transparent)` when bordered=0; truthy is a no-op (default is the bordered Capsule). Mango's About button now flat instead of the default blue ArkUI Capsule. New no-op `buttonSetTitle` handler so the trace doesn't leak `// perry/ui mutator buttonSetTitle not yet handled` comments — title is set at construction time on harmonyos. **End-to-end on Mango via OHOS Pura emulator** (visual screenshot match against macOS reference): orange "+ New Connection" CTA with white text, flat About button (no blue), feature pills with orange-tinted backgrounds, white welcome card on cream background. The 4 remaining `[unrecognized body]` placeholders are deep inside browser/info screens (only visible after a connection is added — out of scope for the welcome-screen pass). cargo test passing.
- **v0.5.492** — codegen-arkts polish that gets Mango's welcome screen to a pixel-perfect render on HarmonyOS. Three concrete defects: (1) **`textSetFontWeight` arg semantics**: Perry's signature is `(widget, size: number, weight: number)` mirroring Apple's `systemFont(ofSize:weight:)` where `weight` is a 0..1 normalized scale (0=Thin/100, 0.5=Regular/400, 1.0=Bold/900). My v0.5.485 impl read arg[1] (the size, e.g. 24) AS the weight and emitted `.fontWeight(24)` which ArkUI's strict 100..900 range clamped to 100 (lightest). Mango's "Welcome to Mango" rendered translucent because of this. Fix: read arg[1] as size + arg[2] as weight scale; map 0..1 → 100..900 rounded to nearest 100; emit `.fontSize(N).fontWeight(M)` together. (2) **`resolve()` chases LocalGet chains**: pre-fix it did one resolution step. Phase B of the inliner introduces aliasing chains — `const disconnectBtn = makeDangerBtn(...)` becomes `const disconnectBtn = LocalGet(remapped_btn)` after the call gets inlined; emit_widget needs to chase past these aliases to find the actual NativeMethodCall(Button, ...). 16-hop cap mirrors the other resolvers. Fixed 6 of the 10 `[unrecognized body]` islands in Mango's emit. (3) **HarmonyOS-stubbed function recognition**: `evaluate_condition` and `numeric_arg_resolved` now recognize calls to `isDarkMode` / `getDeviceIdiom` / `getDeviceModel` / `getDeviceOSVersion` / `isHighContrast` / `isReducedMotion` / `getNotchHeight` (the v0.5.477 build.rs auto-stubs all return zero on HarmonyOS) and treat them as `Lit::Num(0.0)`. Mango's `const dark = isDarkMode()` now folds to `dark = false`, so theme color resolution `txR = dark ? 0.91 : 0.17` picks the light-mode branch instead of the heuristic-pick-then-branch fallback. Was: dark text `rgba(232, 233, 237, 1)` (white-ish) on white background = invisible. Now: light-theme text `rgba(43, 45, 66, 1)` (proper dark gray) clearly readable. **`is_harmonyos_zero_fn` allowlist** + matching arms in `to_lit` (Expr::Call → ExternFuncRef + Expr::NativeMethodCall → perry/system module). **Inline budget bumped 32 → 256** for completeness; Mango uses well under that. **End-to-end on Mango via OHOS Pura emulator**: 10 → 4 unrecognized-body placeholders (the remaining 4 are deep inside browser/info screens that aren't visible from the welcome state — accessed only after a connection is added). Welcome screen visually matches macOS reference: brand toolbar with logo, bold dark "Welcome to Mango" title, description text, all 4 feature pills, "+ New Connection" CTA, analytics notice, About button. One pre-existing test updated (`text_styling_mutators_emit_arkui_modifiers`) for the new textSetFontWeight signature: pass `Number(28.0), Number(1.0)` instead of `Number(700.0)`, assert `.fontWeight(900)` instead of `.fontWeight(700)`. cargo test 95+2=97 passing.
- **v0.5.491** — codegen-arkts: four follow-ups to v0.5.489's harvest inliner that complete the welcome-screen rendering on Mango/HarmonyOS. (1) **Dead-branch elim for unfoldable conditions**: `collect_mutations_in_stmt` now treats Stmt::If as folded-true (walks only the then-branch) when the condition can't be evaluated AND won't serialize cleanly via `is_cleanly_serializable_condition`. Pre-fix both branches were recorded as conditional mutations and rendered as `if (true) { ... } else { ... }`, producing duplicate-content emission (Mango's "+ New Connection" appearing twice — once from the welcome card's CTA button in the then-branch, once from the addMoreBtn in the post-if siblings). (2) **i18n `t()` unwrapping**: `resolve_string_arg` now follows `Expr::I18nString { key, ... }` (perry/i18n's namespaced-import shape) and `Expr::NativeMethodCall { module: "perry/i18n", method: "t", args: [I18nString] }` (the destructured-import shape) to their underlying string. For Mango (and most apps using Perry's i18n) the English source text doubles as the key, so this gives readable English text on platforms where dynamic locale switching isn't wired yet. (3) **Recursive expression-level inlining (Phase B of inliner)**: walks every Stmt's expressions and substitutes `Expr::Call { callee: FuncRef(id) }` AND `Expr::Call { callee: LocalGet(id) where bindings[id] = Expr::Closure }` with the function's return value, hoisting the function body's let-and-mutator statements BEFORE the enclosing Stmt. Mango's `function makePill(label) { ... return pill; }` is declared INSIDE refreshConnectionList (so it's a `Stmt::Let { id, init: Closure }` not a module-level function); the four `makePill('Databases & Collections')` etc. calls in the welcome card now inline correctly, surfacing the feature-pill text. Simple-return shape constraint (last `Stmt::Return(Some(LocalGet(id)))`) covers makePill's pattern; more complex returning-fns punt. (4) **Early-return → if/else rewrite**: `rewrite_early_returns` runs on each cloned function body before the local-id remap. Pattern `if (cond) { ...; return; } <rest>` rewrites to `if (cond) { ... } else { <rest> }` so the dead-branch elim's then-branch pick correctly drops `<rest>` (Mango's refreshConnectionList: the welcome card branch had a trailing `return`, the connection-list build code lived as siblings AFTER the if; without this rewrite the after-if code emitted unconditionally alongside the welcome card content). The rewrite recurses into nested if/while/for/do-while bodies. **`emit_text` now uses bindings**: `Text(t('Welcome to Mango'))` previously fell through to `[non-literal Text arg]` because the resolved string-arg path required a String literal at the leaf. Now it falls through `resolve_string_arg` (with the new i18n unwrap arms). Two pre-existing tests updated to match the new dead-branch-elim semantics: `issue_408_conditional_widget_add_child_emits_if_else` (was pinning both-branches-emit, now asserts then-branch-only) and `issue_413_addchild_inside_unfoldable_runtime_condition_still_emits_if` (renamed to `issue_490_unfoldable_unresolvable_condition_walks_only_then_branch`). End-to-end on Mango via the OHOS Pura emulator: cumulative harvest output 28667 → 25329 bytes (slight shrink from removing duplicate else-branch content), 14 → 10 unrecognized-body placeholders, 8 → 7 closure registrations. Visible welcome screen: brand toolbar with logo + title, "Welcome to Mango" header, "Connect to your MongoDB instance..." hint, all 4 feature pills (Databases & Collections / Query & Filter / Edit & Insert / Index Viewer), "+ New Connection" CTA (single occurrence), analytics notice, About button — visually matches the macOS reference. cargo test 95+2=97 passing.
Expand Down
60 changes: 30 additions & 30 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ opt-level = "s" # Optimize for size in stdlib
opt-level = 3

[workspace.package]
version = "0.5.493"
version = "0.5.494"
edition = "2021"
license = "MIT"
repository = "https://github.com/PerryTS/perry"
Expand Down
1 change: 0 additions & 1 deletion crates/perry-hir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,5 @@ pub use js_transform::{
};
pub use lower::{
lower_module, lower_module_with_class_id, lower_module_with_class_id_and_types,
lower_module_with_class_id_types_and_seed,
};
pub use monomorph::monomorphize_module;
Loading
Loading