diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index e174a6ca50..c94f801eab 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -48,46 +48,22 @@ jobs: tool: cargo-llvm-cov - name: Run coverage - # Mirrors the `cargo-test` job's exclude list (host-only UI - # backends). `--no-fail-fast` keeps the - # report comprehensive even if one crate's tests fail — - # this is a visibility job, not a gate. + # Uses the same centralized Linux test scope as `cargo-test`. + # Keep collecting and reporting partial coverage if a test fails — + # this is a visibility job, not a test gate. run: | - cargo llvm-cov --workspace --no-fail-fast \ - --exclude perry-doc-fixture-my-bindings \ - --exclude perry-ui-macos \ - --exclude perry-ui-ios \ - --exclude perry-ui-visionos \ - --exclude perry-ui-tvos \ - --exclude perry-ui-watchos \ - --exclude perry-ui-gtk4 \ - --exclude perry-ui-android \ - --exclude perry-ui-windows \ - --exclude perry-ui-windows-winui \ + mapfile -t excluded < <(python3 scripts/workspace_architecture.py \ + --print-excluded-scope linux-test) + exclude_args=() + for package in "${excluded[@]}"; do exclude_args+=(--exclude "$package"); done + cargo llvm-cov --workspace --no-fail-fast --ignore-run-fail \ + "${exclude_args[@]}" \ --html --output-dir target/llvm-cov-html - cargo llvm-cov report --no-fail-fast \ - --exclude perry-doc-fixture-my-bindings \ - --exclude perry-ui-macos \ - --exclude perry-ui-ios \ - --exclude perry-ui-visionos \ - --exclude perry-ui-tvos \ - --exclude perry-ui-watchos \ - --exclude perry-ui-gtk4 \ - --exclude perry-ui-android \ - --exclude perry-ui-windows \ - --exclude perry-ui-windows-winui \ + cargo llvm-cov report \ + "${exclude_args[@]}" \ --lcov --output-path target/lcov.info - cargo llvm-cov report --no-fail-fast \ - --exclude perry-doc-fixture-my-bindings \ - --exclude perry-ui-macos \ - --exclude perry-ui-ios \ - --exclude perry-ui-visionos \ - --exclude perry-ui-tvos \ - --exclude perry-ui-watchos \ - --exclude perry-ui-gtk4 \ - --exclude perry-ui-android \ - --exclude perry-ui-windows \ - --exclude perry-ui-windows-winui \ + cargo llvm-cov report \ + "${exclude_args[@]}" \ --summary-only > target/summary.txt # Don't fail the workflow on a non-zero exit — the artifacts # below are still useful, and a missing test in one crate diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 618c46c234..5b2405ffaa 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -126,6 +126,11 @@ jobs: - name: Check formatting run: cargo fmt --all -- --check + - name: Audit workspace architecture + run: | + python3 scripts/workspace_architecture.py --self-test + python3 scripts/workspace_architecture.py --check --print-summary + - name: Public benchmark evidence freshness run: | PYTHONPATH=. python3 tests/test_public_baseline.py @@ -167,13 +172,18 @@ jobs: # --------------------------------------------------------------------------- # Clippy — enforces the deny-level lints in [workspace.lints] (root # Cargo.toml). `cargo clippy` exits nonzero only on `deny` lints, so - # warn-level output is informational and never blocks a PR. Separate from - # `lint` because it compiles the whole default-member set (~30 min cold); - # `lint` stays the fast fmt/gates job. + # warn-level output is informational and never blocks a PR. The product leg + # gives fast feedback for the CLI; the host-compatible leg names every Linux + # package explicitly. Neither scope depends on Cargo default-members. # --------------------------------------------------------------------------- clippy: + name: Clippy (${{ matrix.scope }}) runs-on: ubuntu-latest timeout-minutes: 60 + strategy: + fail-fast: false + matrix: + scope: [product, host-compatible] env: RUSTC_WRAPPER: sccache SCCACHE_GHA_ENABLED: "false" @@ -206,8 +216,19 @@ jobs: shared-key: "${{ runner.os }}-perry" save-if: ${{ github.ref == 'refs/heads/main' }} - - name: Run clippy - run: cargo clippy + - name: Run clippy for explicit scope + run: | + if [[ "${{ matrix.scope }}" == "product" ]]; then + cargo clippy -p perry --bins + else + mapfile -t excluded < <(python3 scripts/workspace_architecture.py \ + --print-excluded-scope host-compatible) + cargo_args=(--workspace) + for package in "${excluded[@]}"; do + cargo_args+=(--exclude "$package") + done + cargo clippy "${cargo_args[@]}" + fi # --------------------------------------------------------------------------- # API docs drift gate (#465) @@ -306,9 +327,8 @@ jobs: # workaround). Each downstream job below builds in parallel directly. cargo-test: # Was macos-14 — moved to ubuntu-latest in v0.5.392 to drop the 10× - # billing weight. cargo-test's `--exclude` list already filters out - # every macOS-specific UI crate (perry-ui-{ios,visionos,tvos, - # watchos,gtk4,android,windows} per the comment block below), so + # billing weight. The centralized Linux test scope already filters out + # platform-specific UI crates, so # the platform-independent test set runs identically on Linux. The # macOS-host coverage we lose here is negligible — these tests # don't exercise any platform behavior; they're pure logic + @@ -392,7 +412,8 @@ jobs: rm -rf target/perry-auto-* target/debug/libperry_ext_*.a 2>/dev/null || true - name: Run cargo test - # Exclude UI backends that don't build on the ubuntu-latest CI image: + # The exclusions below are maintained once in + # workspace-architecture.json and consumed by ci_test_scope.py: # - perry-ui-macos / perry-ui-ios / perry-ui-tvos / perry-ui-watchos # / perry-ui-visionos: depend on `objc2` which only compiles on # Apple platforms (`compile_error!` in objc2/src/lib.rs:219). diff --git a/CLAUDE.md b/CLAUDE.md index 6e442e6604..87b1cf5d1b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -84,8 +84,7 @@ TypeScript (.ts) → Parse (SWC) → AST → Lower → HIR → Transform → Cod |-------|---------| | **perry** | CLI driver (parallel module codegen via rayon) | | **perry-parser** | SWC wrapper for TypeScript parsing | -| **perry-types** | Type system definitions | -| **perry-hir** | HIR data structures (`ir.rs`) and AST→HIR lowering (`lower.rs`) | +| **perry-hir** | HIR types and data structures, plus AST→HIR lowering | | **perry-transform** | IR passes (closure conversion, async lowering, inlining) | | **perry-codegen** | LLVM-based native code generation | | **perry-runtime** | Runtime: value.rs, object.rs, array.rs, string.rs, gc.rs, arena.rs, thread.rs | diff --git a/Cargo.lock b/Cargo.lock index 02a7c34c09..3b865a620d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5511,7 +5511,6 @@ dependencies = [ "perry-parser", "perry-runtime", "perry-transform", - "perry-types", "perry-updater", "rand 0.9.4", "rayon", @@ -5559,7 +5558,6 @@ dependencies = [ "perry-api-manifest", "perry-dispatch", "perry-hir", - "perry-types", "serde", "serde_json", "thiserror 1.0.69", @@ -5571,7 +5569,6 @@ version = "0.5.1264" dependencies = [ "anyhow", "perry-hir", - "perry-types", ] [[package]] @@ -5589,7 +5586,6 @@ dependencies = [ "anyhow", "perry-dispatch", "perry-hir", - "perry-types", ] [[package]] @@ -5598,7 +5594,6 @@ version = "0.5.1264" dependencies = [ "anyhow", "perry-hir", - "perry-types", ] [[package]] @@ -5610,7 +5605,6 @@ dependencies = [ "perry-codegen-js", "perry-dispatch", "perry-hir", - "perry-types", "wasm-encoder 0.253.0", ] @@ -6075,7 +6069,6 @@ dependencies = [ "perry-api-manifest", "perry-diagnostics", "perry-parser", - "perry-types", "perry-ui-model", "serde", "serde_json", @@ -6250,15 +6243,6 @@ version = "0.5.1264" dependencies = [ "anyhow", "perry-hir", - "perry-types", - "thiserror 1.0.69", -] - -[[package]] -name = "perry-types" -version = "0.5.1264" -dependencies = [ - "anyhow", "thiserror 1.0.69", ] diff --git a/Cargo.toml b/Cargo.toml index 83aa0142ce..2c33e6f60e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,6 @@ resolver = "2" members = [ "crates/perry", "crates/perry-parser", - "crates/perry-types", "crates/perry-api-manifest", "crates/perry-hir", "crates/perry-transform", @@ -43,6 +42,7 @@ members = [ "crates/perry-ext-ws", "crates/perry-ext-net", "crates/perry-ext-http", + "crates/perry-ext-http-server", "crates/perry-ext-streams", "crates/perry-ext-fastify", "crates/perry-ext-pdf", @@ -84,63 +84,6 @@ members = [ # explicitly with -p on their target platform. default-members = [ "crates/perry", - "crates/perry-parser", - "crates/perry-types", - "crates/perry-api-manifest", - "crates/perry-hir", - "crates/perry-transform", - "crates/perry-codegen", - "crates/perry-dispatch", - "crates/perry-runtime", - "crates/perry-ffi", - "crates/perry-ext-dotenv", - "crates/perry-ext-nanoid", - "crates/perry-ext-uuid", - "crates/perry-ext-slugify", - "crates/perry-ext-bcrypt", - "crates/perry-ext-argon2", - "crates/perry-ext-jsonwebtoken", - "crates/perry-ext-validator", - "crates/perry-ext-lru-cache", - "crates/perry-ext-better-sqlite3", - "crates/perry-ext-zlib", - "crates/perry-ext-exponential-backoff", - "crates/perry-ext-axios", - "crates/perry-ext-events", - "crates/perry-ext-decimal", - "crates/perry-ext-dayjs", - "crates/perry-ext-moment", - "crates/perry-ext-cheerio", - "crates/perry-ext-sharp", - "crates/perry-ext-ratelimit", - "crates/perry-ext-commander", - "crates/perry-ext-ethers", - "crates/perry-ext-nodemailer", - "crates/perry-ext-cron", - "crates/perry-ext-ioredis", - "crates/perry-ext-pg", - "crates/perry-ext-mysql2", - "crates/perry-ext-fetch", - "crates/perry-ext-mongodb", - "crates/perry-ext-ws", - "crates/perry-ext-net", - "crates/perry-ext-http", - "crates/perry-ext-streams", - "crates/perry-ext-fastify", - "crates/perry-ext-pdf", - "crates/perry-ext-ads", - "crates/perry-wasm-host", - "crates/perry-stdlib", - "crates/perry-diagnostics", - "crates/perry-ui", - "crates/perry-codegen-js", - "crates/perry-codegen-swiftui", - "crates/perry-codegen-arkts", - "crates/perry-codegen-glance", - "crates/perry-codegen-wear-tiles", - "crates/perry-codegen-wasm", - "crates/perry-updater", - "crates/perry-container-compose", ] # Aggressive release optimizations for small, fast binaries @@ -446,7 +389,6 @@ zstd = "0.13" # Internal crates perry-parser = { path = "crates/perry-parser" } -perry-types = { path = "crates/perry-types" } perry-api-manifest = { path = "crates/perry-api-manifest" } perry-hir = { path = "crates/perry-hir" } perry-transform = { path = "crates/perry-transform" } @@ -505,6 +447,7 @@ perry-ext-mongodb = { path = "crates/perry-ext-mongodb" } perry-ext-ws = { path = "crates/perry-ext-ws" } perry-ext-net = { path = "crates/perry-ext-net" } perry-ext-http = { path = "crates/perry-ext-http" } +perry-ext-http-server = { path = "crates/perry-ext-http-server" } perry-ext-streams = { path = "crates/perry-ext-streams" } perry-ext-fastify = { path = "crates/perry-ext-fastify" } perry-ext-pdf = { path = "crates/perry-ext-pdf" } diff --git a/changelog.d/6758-workspace-architecture.md b/changelog.d/6758-workspace-architecture.md new file mode 100644 index 0000000000..ea6a4ee01a --- /dev/null +++ b/changelog.d/6758-workspace-architecture.md @@ -0,0 +1 @@ +**Workspace architecture baseline:** make all 78 effective Cargo members explicit, reduce the default build to the Perry CLI and its 18-crate dependency closure, add a reproducible crate inventory and policy audit, and run Clippy against explicit product and host-compatible scopes. diff --git a/changelog.d/6760-merge-types-into-hir.md b/changelog.d/6760-merge-types-into-hir.md new file mode 100644 index 0000000000..b87a3da1ed --- /dev/null +++ b/changelog.d/6760-merge-types-into-hir.md @@ -0,0 +1 @@ +**Compiler architecture:** move the shared compiler type definitions into `perry_hir::types`, remove the standalone types crate, and reduce the Perry dependency closure from 18 crates to 17 crates. diff --git a/crates/perry-codegen-arkts/Cargo.toml b/crates/perry-codegen-arkts/Cargo.toml index 6235ad03b3..ea5fa0e675 100644 --- a/crates/perry-codegen-arkts/Cargo.toml +++ b/crates/perry-codegen-arkts/Cargo.toml @@ -10,8 +10,6 @@ workspace = true [dependencies] perry-hir.workspace = true -perry-types.workspace = true anyhow.workspace = true [dev-dependencies] -perry-types.workspace = true diff --git a/crates/perry-codegen-arkts/src/inline.rs b/crates/perry-codegen-arkts/src/inline.rs index ac4fc1f807..fcb24e86c0 100644 --- a/crates/perry-codegen-arkts/src/inline.rs +++ b/crates/perry-codegen-arkts/src/inline.rs @@ -20,7 +20,7 @@ use crate::*; /// same way as real top-level lets. pub(crate) fn inlined_analysis_init(module: &Module) -> Vec { use perry_hir::analysis::remap_local_ids_in_stmts; - use perry_types::FuncId; + use perry_hir::types::FuncId; use std::collections::HashSet; let mut function_map: HashMap = HashMap::new(); @@ -128,7 +128,7 @@ pub(crate) fn inlined_analysis_init(module: &Module) -> Vec { /// covers Mango's makePill but punts on more complex returning fns. pub(crate) fn expr_level_inline_pass( stmts: Vec, - function_map: &HashMap, + function_map: &HashMap, bindings: &HashMap, next_local: &mut u32, budget: &mut usize, @@ -156,7 +156,7 @@ pub(crate) fn expr_level_inline_pass( pub(crate) fn inline_calls_in_stmt( stmt: &mut Stmt, - function_map: &HashMap, + function_map: &HashMap, bindings: &HashMap, next_local: &mut u32, budget: &mut usize, @@ -210,7 +210,7 @@ pub(crate) fn inline_calls_in_stmt( pub(crate) fn inline_calls_in_expr( expr: &mut Expr, - function_map: &HashMap, + function_map: &HashMap, bindings: &HashMap, next_local: &mut u32, budget: &mut usize, @@ -327,7 +327,7 @@ pub(crate) fn inline_calls_in_expr( name: String::new(), type_params: Vec::new(), params, - return_type: perry_types::Type::Any, + return_type: perry_hir::types::Type::Any, body, is_strict, is_async: false, diff --git a/crates/perry-codegen-arkts/src/lib.rs b/crates/perry-codegen-arkts/src/lib.rs index 9ad0634e24..7041677e83 100644 --- a/crates/perry-codegen-arkts/src/lib.rs +++ b/crates/perry-codegen-arkts/src/lib.rs @@ -259,9 +259,9 @@ pub fn emit_index_ets(module: &mut Module) -> Result> { // expression substitutes the call. Without this, emit_widget // hits `[unrecognized body]` for every helper-wrapped Text / // Stack child. - let function_map_inline: HashMap = + let function_map_inline: HashMap = module.functions.iter().map(|f| (f.id, f.clone())).collect(); - let function_lookup: HashMap = + let function_lookup: HashMap = module.functions.iter().map(|f| (f.id, f)).collect(); // Start view-builder Phase B remap counter ABOVE the highest // LocalId already used by `analysis_init` (Phase A + B inlining diff --git a/crates/perry-codegen-arkts/src/tests.rs b/crates/perry-codegen-arkts/src/tests.rs index bc5b7ee8e5..1fedd244b6 100644 --- a/crates/perry-codegen-arkts/src/tests.rs +++ b/crates/perry-codegen-arkts/src/tests.rs @@ -76,9 +76,9 @@ pub(crate) fn app_with_body(body: Expr) -> Stmt { pub(crate) fn closure_stub() -> Expr { Expr::Closure { - func_id: 0 as perry_types::FuncId, + func_id: 0 as perry_hir::types::FuncId, params: vec![], - return_type: perry_types::Type::Any, + return_type: perry_hir::types::Type::Any, body: vec![], captures: vec![], mutable_captures: vec![], @@ -136,7 +136,7 @@ pub(crate) fn let_widget(id: LocalId, name: &str, init: Expr) -> Stmt { Stmt::Let { id, name: name.to_string(), - ty: perry_types::Type::Any, + ty: perry_hir::types::Type::Any, mutable: false, init: Some(init), } @@ -161,7 +161,7 @@ pub(crate) fn declare_const(id: LocalId, name: &str) -> Stmt { Stmt::Let { id, name: name.to_string(), - ty: perry_types::Type::Any, + ty: perry_hir::types::Type::Any, mutable: false, init: None, } diff --git a/crates/perry-codegen-arkts/src/tests/containers.rs b/crates/perry-codegen-arkts/src/tests/containers.rs index 6444599097..9265f7e1e9 100644 --- a/crates/perry-codegen-arkts/src/tests/containers.rs +++ b/crates/perry-codegen-arkts/src/tests/containers.rs @@ -110,7 +110,7 @@ fn navstack_emits_state_driven_branches() { m.init.push(Stmt::Let { id: 5, name: "route".to_string(), - ty: perry_types::Type::Any, + ty: perry_hir::types::Type::Any, mutable: false, init: Some(state_call(Expr::String("home".into()))), }); @@ -169,7 +169,7 @@ fn navstack_no_state_falls_back_to_first_route() { m.init.push(Stmt::Let { id: 7, name: "x".to_string(), - ty: perry_types::Type::Any, + ty: perry_hir::types::Type::Any, mutable: false, init: Some(Expr::String("home".into())), }); @@ -202,7 +202,7 @@ fn navstack_empty_routes_emits_empty_column_with_comment() { m.init.push(Stmt::Let { id: 5, name: "route".to_string(), - ty: perry_types::Type::Any, + ty: perry_hir::types::Type::Any, mutable: false, init: Some(state_call(Expr::String("home".into()))), }); @@ -224,7 +224,7 @@ fn navstack_set_in_closure_rewrites_to_settext() { m.init.push(Stmt::Let { id: 5, name: "route".to_string(), - ty: perry_types::Type::Any, + ty: perry_hir::types::Type::Any, mutable: false, init: Some(state_call(Expr::String("home".into()))), }); @@ -233,9 +233,9 @@ fn navstack_set_in_closure_rewrites_to_settext() { vec![ Expr::String("Go".into()), Expr::Closure { - func_id: 0 as perry_types::FuncId, + func_id: 0 as perry_hir::types::FuncId, params: vec![], - return_type: perry_types::Type::Any, + return_type: perry_hir::types::Type::Any, body: vec![Stmt::Expr(state_method_call( 5, "set", @@ -297,7 +297,7 @@ fn state_text_emits_reactive_text_with_synth_id() { m.init.push(Stmt::Let { id: 5, name: "count".to_string(), - ty: perry_types::Type::Any, + ty: perry_hir::types::Type::Any, mutable: false, init: Some(state_call(Expr::Number(0.0))), }); @@ -318,15 +318,15 @@ fn state_set_in_closure_rewrites_to_settext() { m.init.push(Stmt::Let { id: 5, name: "count".to_string(), - ty: perry_types::Type::Any, + ty: perry_hir::types::Type::Any, mutable: false, init: Some(state_call(Expr::Number(0.0))), }); // Closure body: Stmt::Expr(count.set(5)) let closure = Expr::Closure { - func_id: 0 as perry_types::FuncId, + func_id: 0 as perry_hir::types::FuncId, params: vec![], - return_type: perry_types::Type::Any, + return_type: perry_hir::types::Type::Any, body: vec![Stmt::Expr(state_method_call( 5, "set", @@ -372,14 +372,14 @@ fn multiple_state_decls_get_unique_ids() { m.init.push(Stmt::Let { id: 1, name: "count".to_string(), - ty: perry_types::Type::Any, + ty: perry_hir::types::Type::Any, mutable: false, init: Some(state_call(Expr::Number(0.0))), }); m.init.push(Stmt::Let { id: 2, name: "name".to_string(), - ty: perry_types::Type::Any, + ty: perry_hir::types::Type::Any, mutable: false, init: Some(state_call(Expr::String("Alice".into()))), }); @@ -489,7 +489,7 @@ fn lazyvstack_with_array_map_emits_lazy_for_each() { let item_param = perry_hir::ir::Param { id: 99, name: "item".to_string(), - ty: perry_types::Type::Any, + ty: perry_hir::types::Type::Any, default: None, decorators: Vec::new(), is_rest: false, @@ -502,9 +502,9 @@ fn lazyvstack_with_array_map_emits_lazy_for_each() { Expr::String("b".into()), ])), callback: Box::new(Expr::Closure { - func_id: 0 as perry_types::FuncId, + func_id: 0 as perry_hir::types::FuncId, params: vec![item_param], - return_type: perry_types::Type::Any, + return_type: perry_hir::types::Type::Any, body: vec![Stmt::Return(Some(inner_text))], captures: vec![], mutable_captures: vec![], @@ -842,9 +842,9 @@ fn media_call_inside_button_closure_also_triggers_glue() { // walker must descend into Closure bodies via stmt_uses → Closure. let mut m = empty_module(); let play_closure = Expr::Closure { - func_id: 0 as perry_types::FuncId, + func_id: 0 as perry_hir::types::FuncId, params: vec![], - return_type: perry_types::Type::Any, + return_type: perry_hir::types::Type::Any, body: vec![Stmt::Expr(media_call("play", vec![Expr::Number(1.0)]))], captures: vec![], mutable_captures: vec![], diff --git a/crates/perry-codegen-arkts/src/tests/mutations.rs b/crates/perry-codegen-arkts/src/tests/mutations.rs index 0a247927ec..822d53c497 100644 --- a/crates/perry-codegen-arkts/src/tests/mutations.rs +++ b/crates/perry-codegen-arkts/src/tests/mutations.rs @@ -445,7 +445,7 @@ fn phase2_v35_widget_set_hidden_in_closure_emits_state_binding() { let onclick = Expr::Closure { func_id: 0, params: vec![], - return_type: perry_types::Type::Any, + return_type: perry_hir::types::Type::Any, body: vec![mutator_stmt( "widgetSetHidden", vec![Expr::LocalGet(target_id), Expr::Number(0.0)], diff --git a/crates/perry-codegen-arkts/src/tests/widgets.rs b/crates/perry-codegen-arkts/src/tests/widgets.rs index d09f06efc5..7ee39fc1fd 100644 --- a/crates/perry-codegen-arkts/src/tests/widgets.rs +++ b/crates/perry-codegen-arkts/src/tests/widgets.rs @@ -207,7 +207,7 @@ fn local_get_escape_follows_const_binding() { m.init.push(Stmt::Let { id: 7, name: "t".to_string(), - ty: perry_types::Type::Any, + ty: perry_hir::types::Type::Any, mutable: false, init: Some(nmc("Text", vec![Expr::String("via let".into())])), }); @@ -545,7 +545,7 @@ fn for_each_lowers_array_map_in_vstack() { let item_param = perry_hir::ir::Param { id: 42, name: "item".to_string(), - ty: perry_types::Type::Any, + ty: perry_hir::types::Type::Any, default: None, decorators: Vec::new(), is_rest: false, @@ -559,9 +559,9 @@ fn for_each_lowers_array_map_in_vstack() { Expr::String("c".into()), ])), callback: Box::new(Expr::Closure { - func_id: 0 as perry_types::FuncId, + func_id: 0 as perry_hir::types::FuncId, params: vec![item_param], - return_type: perry_types::Type::Any, + return_type: perry_hir::types::Type::Any, body: vec![Stmt::Return(Some(inner_text))], captures: vec![], mutable_captures: vec![], diff --git a/crates/perry-codegen-arkts/src/types.rs b/crates/perry-codegen-arkts/src/types.rs index c7fc37c50d..fadf169628 100644 --- a/crates/perry-codegen-arkts/src/types.rs +++ b/crates/perry-codegen-arkts/src/types.rs @@ -3,7 +3,7 @@ use perry_hir::ir::Expr; // LocalId is `u32` upstream; re-import directly so we don't carry a -// transitive dep on perry-types just for the type alias. +// HIR owns the function identifier used by view builders. pub(crate) type LocalId = u32; /// Result of harvesting an `App({body: ...})` call: the emitted ArkUI @@ -197,7 +197,7 @@ pub(crate) struct VisibilityBinding { #[derive(Debug, Clone)] pub(crate) struct ViewBuilder { /// Function id (matches `Function::id` in the HIR). - pub(crate) func_id: perry_types::FuncId, + pub(crate) func_id: perry_hir::types::FuncId, /// Function name (used for the synth view id when sanitized). // #854: stashed on the harvest instance for a future diagnostic pass; the // view id is currently derived inline at emit time, not read back here. diff --git a/crates/perry-codegen-arkts/src/view_builders.rs b/crates/perry-codegen-arkts/src/view_builders.rs index 63060f5e6d..d71c00966e 100644 --- a/crates/perry-codegen-arkts/src/view_builders.rs +++ b/crates/perry-codegen-arkts/src/view_builders.rs @@ -35,7 +35,7 @@ pub(crate) fn collect_view_builders(module: &Module, next_group_id: &mut u32) -> // targets that are module-level. Pick the function's "primary target" // as the first matching one (Mango's pattern is one terminal target // per view-builder; multi-target view-builders aren't supported yet). - let mut primary_target: HashMap = HashMap::new(); + let mut primary_target: HashMap = HashMap::new(); for f in &module.functions { if f.is_async || f.is_generator { continue; @@ -54,7 +54,7 @@ pub(crate) fn collect_view_builders(module: &Module, next_group_id: &mut u32) -> // anywhere in the module (closures in module.init AND inside other // function bodies). Calls inside top-level Stmts of module.init or // function bodies that are NOT inside a closure don't count. - let mut called_from_closure: HashSet = HashSet::new(); + let mut called_from_closure: HashSet = HashSet::new(); walk_for_funcref_calls_in_closures_in_stmts(&module.init, &mut called_from_closure); for f in &module.functions { walk_for_funcref_calls_in_closures_in_stmts(&f.body, &mut called_from_closure); @@ -63,7 +63,7 @@ pub(crate) fn collect_view_builders(module: &Module, next_group_id: &mut u32) -> // Pass 4 — find functions called from module.init OR from a function // that's itself called from module.init. Used to EXCLUDE module-init // call paths from view-builder treatment (avoids duplicate emit). - let mut called_from_module_init: HashSet = HashSet::new(); + let mut called_from_module_init: HashSet = HashSet::new(); walk_for_funcref_calls_top_level_in_stmts(&module.init, &mut called_from_module_init); // Pass 5 — assemble ViewBuilders. Stable target_synth assignment by @@ -72,9 +72,10 @@ pub(crate) fn collect_view_builders(module: &Module, next_group_id: &mut u32) -> let mut next_target_synth: usize = 0; let mut builders: Vec = Vec::new(); - let function_lookup: HashMap = + let function_lookup: HashMap = module.functions.iter().map(|f| (f.id, f)).collect(); - let mut sorted_func_ids: Vec = primary_target.keys().copied().collect(); + let mut sorted_func_ids: Vec = + primary_target.keys().copied().collect(); sorted_func_ids.sort(); for func_id in sorted_func_ids { if !called_from_closure.contains(&func_id) { @@ -226,14 +227,14 @@ pub(crate) fn rewrite_view_builder_calls_in_stmts(stmts: &mut Vec, builder if builders.is_empty() { return; } - let lookup: HashMap = + let lookup: HashMap = builders.iter().map(|b| (b.func_id, b)).collect(); rewrite_view_builder_calls_in_stmts_with_lookup(stmts, &lookup); } pub(crate) fn rewrite_view_builder_calls_in_stmts_with_lookup( stmts: &mut Vec, - lookup: &HashMap, + lookup: &HashMap, ) { let mut i = 0; while i < stmts.len() { @@ -249,7 +250,7 @@ pub(crate) fn rewrite_view_builder_calls_in_stmts_with_lookup( pub(crate) fn rewrite_view_builder_calls_in_stmt( stmt: &mut Stmt, - lookup: &HashMap, + lookup: &HashMap, ) { match stmt { Stmt::Expr(e) | Stmt::Return(Some(e)) => { @@ -302,7 +303,7 @@ pub(crate) fn rewrite_view_builder_calls_in_stmt( pub(crate) fn rewrite_view_builder_calls_in_expr( e: &mut Expr, - lookup: &HashMap, + lookup: &HashMap, ) { // When we hit a closure: prepend a setContentView call for every // view-builder funcref called inside the closure's body, then recurse @@ -310,7 +311,7 @@ pub(crate) fn rewrite_view_builder_calls_in_expr( if let Expr::Closure { body, .. } = e { // Collect all view-builder funcrefs called inside this closure. let mut called_builders: Vec<&ViewBuilder> = Vec::new(); - let mut seen: std::collections::HashSet = + let mut seen: std::collections::HashSet = std::collections::HashSet::new(); scan_closure_body_for_view_builder_calls(body, lookup, &mut called_builders, &mut seen); if !called_builders.is_empty() { @@ -397,9 +398,9 @@ pub(crate) fn rewrite_view_builder_calls_in_expr( pub(crate) fn scan_closure_body_for_view_builder_calls<'a>( stmts: &[Stmt], - lookup: &HashMap, + lookup: &HashMap, out: &mut Vec<&'a ViewBuilder>, - seen: &mut std::collections::HashSet, + seen: &mut std::collections::HashSet, ) { for stmt in stmts { scan_closure_body_for_view_builder_calls_in_stmt(stmt, lookup, out, seen); @@ -408,9 +409,9 @@ pub(crate) fn scan_closure_body_for_view_builder_calls<'a>( pub(crate) fn scan_closure_body_for_view_builder_calls_in_stmt<'a>( stmt: &Stmt, - lookup: &HashMap, + lookup: &HashMap, out: &mut Vec<&'a ViewBuilder>, - seen: &mut std::collections::HashSet, + seen: &mut std::collections::HashSet, ) { match stmt { Stmt::Expr(e) | Stmt::Return(Some(e)) => { @@ -436,9 +437,9 @@ pub(crate) fn scan_closure_body_for_view_builder_calls_in_stmt<'a>( pub(crate) fn scan_closure_body_for_view_builder_calls_in_expr<'a>( e: &Expr, - lookup: &HashMap, + lookup: &HashMap, out: &mut Vec<&'a ViewBuilder>, - seen: &mut std::collections::HashSet, + seen: &mut std::collections::HashSet, ) { // Don't recurse into nested closures — their setContentView prepend // happens at their own level via `rewrite_view_builder_calls_in_expr`. diff --git a/crates/perry-codegen-arkts/src/widget_walks.rs b/crates/perry-codegen-arkts/src/widget_walks.rs index 732c83a3ce..2ecc8b4c72 100644 --- a/crates/perry-codegen-arkts/src/widget_walks.rs +++ b/crates/perry-codegen-arkts/src/widget_walks.rs @@ -286,7 +286,7 @@ pub(crate) fn extract_widget_set_hidden_target(e: &Expr) -> Option<(LocalId, boo pub(crate) fn walk_for_funcref_calls_in_closures_in_stmts( stmts: &[Stmt], - out: &mut std::collections::HashSet, + out: &mut std::collections::HashSet, ) { for stmt in stmts { walk_for_funcref_calls_in_closures_in_stmt(stmt, out); @@ -295,7 +295,7 @@ pub(crate) fn walk_for_funcref_calls_in_closures_in_stmts( pub(crate) fn walk_for_funcref_calls_in_closures_in_stmt( stmt: &Stmt, - out: &mut std::collections::HashSet, + out: &mut std::collections::HashSet, ) { match stmt { Stmt::Expr(e) | Stmt::Let { init: Some(e), .. } | Stmt::Return(Some(e)) => { @@ -323,7 +323,7 @@ pub(crate) fn walk_for_funcref_calls_in_closures_in_stmt( pub(crate) fn walk_for_funcref_calls_in_closures_in_expr( e: &Expr, - out: &mut std::collections::HashSet, + out: &mut std::collections::HashSet, ) { if let Expr::Closure { body, .. } = e { walk_for_funcref_calls_in_body(body, out); @@ -353,7 +353,7 @@ pub(crate) fn walk_for_funcref_calls_in_closures_in_expr( /// which functions are called transitively inside a closure body. pub(crate) fn walk_for_funcref_calls_in_body( stmts: &[Stmt], - out: &mut std::collections::HashSet, + out: &mut std::collections::HashSet, ) { for stmt in stmts { walk_for_funcref_calls_in_body_stmt(stmt, out); @@ -362,7 +362,7 @@ pub(crate) fn walk_for_funcref_calls_in_body( pub(crate) fn walk_for_funcref_calls_in_body_stmt( stmt: &Stmt, - out: &mut std::collections::HashSet, + out: &mut std::collections::HashSet, ) { match stmt { Stmt::Expr(e) | Stmt::Let { init: Some(e), .. } | Stmt::Return(Some(e)) => { @@ -390,7 +390,7 @@ pub(crate) fn walk_for_funcref_calls_in_body_stmt( pub(crate) fn walk_for_funcref_calls_in_body_expr( e: &Expr, - out: &mut std::collections::HashSet, + out: &mut std::collections::HashSet, ) { if let Expr::Call { callee, args, .. } = e { if let Expr::FuncRef(id) = callee.as_ref() { @@ -423,7 +423,7 @@ pub(crate) fn walk_for_funcref_calls_in_body_expr( /// top-level (Phase A inlining sees these and inlines them). pub(crate) fn walk_for_funcref_calls_top_level_in_stmts( stmts: &[Stmt], - out: &mut std::collections::HashSet, + out: &mut std::collections::HashSet, ) { for stmt in stmts { if let Stmt::Expr(e) = stmt { diff --git a/crates/perry-codegen-arkts/tests/phase2_full_app_smoke.rs b/crates/perry-codegen-arkts/tests/phase2_full_app_smoke.rs index 6d326784b1..e1dd5073cb 100644 --- a/crates/perry-codegen-arkts/tests/phase2_full_app_smoke.rs +++ b/crates/perry-codegen-arkts/tests/phase2_full_app_smoke.rs @@ -26,7 +26,7 @@ use perry_codegen_arkts::emit_index_ets; use perry_hir::ir::{Expr, Module, Param, Stmt}; -use perry_types::{FuncId, LocalId, Type}; +use perry_hir::types::{FuncId, LocalId, Type}; fn empty_module() -> Module { Module { diff --git a/crates/perry-codegen-js/Cargo.toml b/crates/perry-codegen-js/Cargo.toml index 31ddba4e63..7ff77a8e73 100644 --- a/crates/perry-codegen-js/Cargo.toml +++ b/crates/perry-codegen-js/Cargo.toml @@ -10,6 +10,5 @@ workspace = true [dependencies] perry-hir.workspace = true -perry-types.workspace = true perry-dispatch.workspace = true anyhow.workspace = true diff --git a/crates/perry-codegen-js/src/emit/mod.rs b/crates/perry-codegen-js/src/emit/mod.rs index 2ef53d9763..7908c5ec33 100644 --- a/crates/perry-codegen-js/src/emit/mod.rs +++ b/crates/perry-codegen-js/src/emit/mod.rs @@ -3,7 +3,7 @@ //! Recursively translates HIR statements and expressions into JavaScript source code. use perry_hir::ir::*; -use perry_types::{FuncId, GlobalId, LocalId}; +use perry_hir::types::{FuncId, GlobalId, LocalId}; use std::collections::{BTreeMap, BTreeSet}; /// App metadata baked into compile-time `perry/system` introspection APIs diff --git a/crates/perry-codegen-swiftui/Cargo.toml b/crates/perry-codegen-swiftui/Cargo.toml index 80de936fba..a8327aa49d 100644 --- a/crates/perry-codegen-swiftui/Cargo.toml +++ b/crates/perry-codegen-swiftui/Cargo.toml @@ -10,5 +10,4 @@ workspace = true [dependencies] perry-hir.workspace = true -perry-types.workspace = true anyhow.workspace = true diff --git a/crates/perry-codegen-wasm/Cargo.toml b/crates/perry-codegen-wasm/Cargo.toml index b3374554bb..df80b57fcd 100644 --- a/crates/perry-codegen-wasm/Cargo.toml +++ b/crates/perry-codegen-wasm/Cargo.toml @@ -10,7 +10,6 @@ workspace = true [dependencies] perry-hir.workspace = true -perry-types.workspace = true perry-codegen-js.workspace = true perry-dispatch.workspace = true anyhow.workspace = true diff --git a/crates/perry-codegen-wasm/src/emit/closures.rs b/crates/perry-codegen-wasm/src/emit/closures.rs index 525b0a1229..c4f402d812 100644 --- a/crates/perry-codegen-wasm/src/emit/closures.rs +++ b/crates/perry-codegen-wasm/src/emit/closures.rs @@ -3,7 +3,7 @@ //! Pure move: `collect_closures_from_stmts` / `collect_closures_from_expr`. use perry_hir::ir::*; -use perry_types::{FuncId, LocalId}; +use perry_hir::types::{FuncId, LocalId}; /// Recursively collect all Expr::Closure nodes from statements pub(super) fn collect_closures_from_stmts( diff --git a/crates/perry-codegen-wasm/src/emit/compile.rs b/crates/perry-codegen-wasm/src/emit/compile.rs index 1a8813fa04..2579e40a9d 100644 --- a/crates/perry-codegen-wasm/src/emit/compile.rs +++ b/crates/perry-codegen-wasm/src/emit/compile.rs @@ -654,7 +654,7 @@ impl WasmModuleEmitter { } seen_ffi.insert(name.clone()); let param_count = param_types.len(); - let has_return = !matches!(return_type, perry_types::Type::Void); + let has_return = !matches!(return_type, perry_hir::types::Type::Void); let params = vec![ValType::I64; param_count]; let results = if has_return { vec![ValType::I64] diff --git a/crates/perry-codegen-wasm/src/emit/expr/calls.rs b/crates/perry-codegen-wasm/src/emit/expr/calls.rs index 71bf784567..a765f36fdc 100644 --- a/crates/perry-codegen-wasm/src/emit/expr/calls.rs +++ b/crates/perry-codegen-wasm/src/emit/expr/calls.rs @@ -207,7 +207,7 @@ impl<'a> FuncEmitCtx<'a> { func.instruction(&Instruction::Call(idx)); // Void functions don't push a return value, but call // expressions always need a value on the stack. Push undefined. - if matches!(return_type, perry_types::Type::Void) + if matches!(return_type, perry_hir::types::Type::Void) || self.emitter.void_funcs.contains(&idx) { func.instruction(&Instruction::I64Const(TAG_UNDEFINED as i64)); diff --git a/crates/perry-codegen-wasm/src/emit/locals.rs b/crates/perry-codegen-wasm/src/emit/locals.rs index ed4cdf8adf..fca242c635 100644 --- a/crates/perry-codegen-wasm/src/emit/locals.rs +++ b/crates/perry-codegen-wasm/src/emit/locals.rs @@ -3,7 +3,7 @@ //! Pure move: `collect_module_let_ids`, `resolve_source_module_idx`, `collect_locals`. use perry_hir::ir::*; -use perry_types::LocalId; +use perry_hir::types::LocalId; use std::collections::BTreeMap; /// Recursively scan statements for local variable declarations @@ -353,7 +353,7 @@ pub(super) fn resolve_export_to_let( /// module i. pub(super) fn resolve_export_to_func( modules: &[(String, perry_hir::ir::Module)], - module_func_maps: &[std::collections::BTreeMap], + module_func_maps: &[std::collections::BTreeMap], name_to_idx: &std::collections::HashMap<&str, usize>, mod_idx: usize, name: &str, diff --git a/crates/perry-codegen-wasm/src/emit/mod.rs b/crates/perry-codegen-wasm/src/emit/mod.rs index 293481c9aa..c479ce49f8 100644 --- a/crates/perry-codegen-wasm/src/emit/mod.rs +++ b/crates/perry-codegen-wasm/src/emit/mod.rs @@ -40,7 +40,7 @@ mod ui_method_map; // Shared prelude — each sibling re-imports these via `use super::*;`. use perry_hir::ir::*; -use perry_types::{FuncId, GlobalId, LocalId}; +use perry_hir::types::{FuncId, GlobalId, LocalId}; use std::collections::BTreeMap; use wasm_encoder::{ CodeSection, DataSection, ElementSection, Elements, EntityType, ExportKind, ExportSection, diff --git a/crates/perry-codegen/Cargo.toml b/crates/perry-codegen/Cargo.toml index 97c4949f2b..c3fddb40ba 100644 --- a/crates/perry-codegen/Cargo.toml +++ b/crates/perry-codegen/Cargo.toml @@ -10,7 +10,6 @@ workspace = true [dependencies] perry-hir.workspace = true -perry-types.workspace = true perry-dispatch.workspace = true perry-api-manifest.workspace = true diff --git a/crates/perry-codegen/src/boxed_vars.rs b/crates/perry-codegen/src/boxed_vars.rs index 987f3001cf..1dde707cc3 100644 --- a/crates/perry-codegen/src/boxed_vars.rs +++ b/crates/perry-codegen/src/boxed_vars.rs @@ -1333,7 +1333,7 @@ fn collect_write_ids_in_expr(expr: &perry_hir::Expr, out: &mut HashSet) { /// having a handle on the enclosing function's context. pub(crate) fn collect_let_types_in_stmts( stmts: &[perry_hir::Stmt], - out: &mut HashMap, + out: &mut HashMap, ) { use perry_hir::Stmt; for s in stmts { @@ -1341,7 +1341,7 @@ pub(crate) fn collect_let_types_in_stmts( Stmt::Let { id, ty, init, .. } => { // Refine Any-typed lets from the init if possible, // so closures inherit the right type. - let refined_ty = if matches!(ty, perry_types::Type::Any) { + let refined_ty = if matches!(ty, perry_hir::types::Type::Any) { init.as_ref() .and_then(refine_type_from_init_simple) .unwrap_or_else(|| ty.clone()) @@ -1429,11 +1429,11 @@ fn collect_compiler_private_async_control_locals_in_stmts_inner( match (name.as_str(), ty) { ( "__gen_state" | "__gen_pending_type", - perry_types::Type::Number | perry_types::Type::Int32, + perry_hir::types::Type::Number | perry_hir::types::Type::Int32, ) => { i32_out.insert(*id); } - ("__gen_done" | "__gen_executing", perry_types::Type::Boolean) => { + ("__gen_done" | "__gen_executing", perry_hir::types::Type::Boolean) => { i1_out.insert(*id); } _ => {} @@ -1558,7 +1558,7 @@ fn collect_compiler_private_async_control_locals_in_expr( fn collect_closure_let_types_in_expr( expr: &perry_hir::Expr, - out: &mut HashMap, + out: &mut HashMap, ) { use perry_hir::Expr; match expr { @@ -1621,9 +1621,9 @@ fn collect_closure_let_types_in_expr( /// used at module-level type collection time before any FnCtx /// exists. Conservative: most generic runtime facts come from the shared HIR /// type-analysis spine; only codegen-specific/native escape facts remain here. -fn refine_type_from_init_simple(init: &perry_hir::Expr) -> Option { +fn refine_type_from_init_simple(init: &perry_hir::Expr) -> Option { + use perry_hir::types::Type; use perry_hir::Expr; - use perry_types::Type; match init { // `String.prototype.matchAll` returns an iterator, but the current // codegen collector only tracks broad escape-hatch value facts here. @@ -1644,15 +1644,15 @@ fn refine_type_from_init_simple(init: &perry_hir::Expr) -> Option Option { +fn infer_refinable_type_without_context(init: &perry_hir::Expr) -> Option { infer_refinable_expr_type(init, &()) } #[cfg(test)] mod tests { use super::*; + use perry_hir::types::Type; use perry_hir::Expr; - use perry_types::Type; #[test] fn simple_refinement_uses_shared_hir_inference_for_constructed_values() { diff --git a/crates/perry-codegen/src/codegen/artifacts.rs b/crates/perry-codegen/src/codegen/artifacts.rs index eef2fc3ec2..41fff64d1e 100644 --- a/crates/perry-codegen/src/codegen/artifacts.rs +++ b/crates/perry-codegen/src/codegen/artifacts.rs @@ -68,7 +68,7 @@ pub(super) struct ModuleArtifactsCtx<'a> { pub class_ids: &'a HashMap, pub enum_table: &'a HashMap<(String, String), perry_hir::EnumValue>, pub module_globals: &'a HashMap, - pub module_global_types: &'a HashMap, + pub module_global_types: &'a HashMap, pub static_field_globals: &'a HashMap<(String, String), String>, pub method_names: &'a HashMap<(String, String), String>, pub func_names: &'a HashMap, @@ -77,19 +77,19 @@ pub(super) struct ModuleArtifactsCtx<'a> { pub module_boxed_vars: &'a std::collections::HashSet, /// Typed-ABI capture-representation oracle: module-wide `Stmt::Let` types /// MINUS boxed ids (#5869). Only the typed closure clones read this. - pub module_local_types: &'a HashMap, + pub module_local_types: &'a HashMap, /// #6369: receiver-type oracle for closure bodies — the same module-wide /// `Stmt::Let` types with no representation filtering, mirroring the /// `module_global_types` seed that `compile_function` / `compile_method` /// already use. Feeds `FnCtx.local_types` only. - pub module_receiver_types: &'a HashMap, + pub module_receiver_types: &'a HashMap, pub closure_rest_params: &'a HashMap, pub closure_synthetic_arguments: &'a std::collections::HashSet, pub closure_rest_and_arguments: &'a std::collections::HashSet, pub closure_arities: &'a HashMap, pub closure_lengths: &'a HashMap, pub closure_arrow_functions: &'a std::collections::HashSet, - pub closures: &'a [(perry_types::FuncId, perry_hir::Expr)], + pub closures: &'a [(perry_hir::types::FuncId, perry_hir::Expr)], pub class_keys_init_data: &'a [(String, String, u32, Vec, Vec)], pub imported_class_stubs: &'a [perry_hir::Class], pub cross_module: &'a CrossModuleCtx, @@ -606,7 +606,7 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> { .map(|i| perry_hir::Param { id: 0xFFFF_0000 + i as u32, name: format!("__forward_arg{}", i), - ty: perry_types::Type::Any, + ty: perry_hir::types::Type::Any, default: None, decorators: Vec::new(), is_rest: false, @@ -622,7 +622,7 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> { name: format!("{}_constructor", class.name), type_params: Vec::new(), params: ctor_body.0, - return_type: perry_types::Type::Void, + return_type: perry_hir::types::Type::Void, body: ctor_body.1, is_async: false, is_generator: false, @@ -1747,7 +1747,7 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> { // (b) Closures bound to a top-level `let`/`const`. #2076: a named // function expression's own name takes precedence over the binding // name (`const bar = function namedBar(){}` ⇒ `"namedBar"`). - let mut named_inline_closure_ids: std::collections::HashSet = + let mut named_inline_closure_ids: std::collections::HashSet = std::collections::HashSet::new(); for stmt in &hir.init { if let perry_hir::Stmt::Let { name, init, .. } = stmt { @@ -1771,7 +1771,7 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> { // captured locals or used `this` and lowered to an inline Closure // instead of a FuncRef. Skip ids already covered above and any id // that hir.functions already produced a wrapper entry for. - let registered_fn_ids: std::collections::HashSet = + let registered_fn_ids: std::collections::HashSet = hir.functions.iter().map(|f| f.id).collect(); // #3527: only register a display name for a `perry_closure_*` symbol when // that closure was actually materialized as an LLVM global (i.e. it is in @@ -1782,7 +1782,7 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> { // a name for the stale fid emits a `js_register_function_name` call referencing // an undefined `@perry_closure_*` global, which makes `clang -c` fail with // "use of undefined value" (regression class of #318/#343). - let materialized_closure_ids: std::collections::HashSet = + let materialized_closure_ids: std::collections::HashSet = closures.iter().map(|(id, _)| *id).collect(); for (func_id, display) in &hir.closure_display_names { if !materialized_closure_ids.contains(func_id) { diff --git a/crates/perry-codegen/src/codegen/boxed_locals.rs b/crates/perry-codegen/src/codegen/boxed_locals.rs index 21de961b9c..fca5e14a87 100644 --- a/crates/perry-codegen/src/codegen/boxed_locals.rs +++ b/crates/perry-codegen/src/codegen/boxed_locals.rs @@ -92,8 +92,8 @@ pub(crate) fn collect_module_boxed_vars(hir: &HirModule) -> std::collections::Ha /// learn the types of captured vars from the enclosing scope. /// HIR LocalIds are globally unique within the module, so a /// single flat map works. -pub(crate) fn collect_module_local_types(hir: &HirModule) -> HashMap { - let mut module_local_types: HashMap = HashMap::new(); +pub(crate) fn collect_module_local_types(hir: &HirModule) -> HashMap { + let mut module_local_types: HashMap = HashMap::new(); collect_let_types_in_stmts(&hir.init, &mut module_local_types); for f in &hir.functions { for p in &f.params { diff --git a/crates/perry-codegen/src/codegen/closure.rs b/crates/perry-codegen/src/codegen/closure.rs index 63fee9e795..8a2cdb370e 100644 --- a/crates/perry-codegen/src/codegen/closure.rs +++ b/crates/perry-codegen/src/codegen/closure.rs @@ -104,7 +104,7 @@ fn emit_typed_closure_trampoline_fast_value( fn emit_public_typed_closure_trampoline( llmod: &mut LlModule, - func_id: perry_types::FuncId, + func_id: perry_hir::types::FuncId, closure_expr: &perry_hir::Expr, module_prefix: &str, generic_body_name: &str, @@ -283,10 +283,10 @@ pub(crate) fn emit_typed_string_capture_guard( pub(super) fn compile_typed_string_closure( llmod: &mut LlModule, - func_id: perry_types::FuncId, + func_id: perry_hir::types::FuncId, closure_expr: &perry_hir::Expr, module_prefix: &str, - module_local_types: &HashMap, + module_local_types: &HashMap, ) -> Result<()> { let (params, body) = match closure_expr { perry_hir::Expr::Closure { params, body, .. } => (params, body), @@ -335,10 +335,10 @@ pub(super) fn compile_typed_string_closure( pub(super) fn compile_typed_f64_closure( llmod: &mut LlModule, - func_id: perry_types::FuncId, + func_id: perry_hir::types::FuncId, closure_expr: &perry_hir::Expr, module_prefix: &str, - module_local_types: &HashMap, + module_local_types: &HashMap, ) -> Result<()> { let (params, body) = match closure_expr { perry_hir::Expr::Closure { params, body, .. } => (params, body), @@ -380,10 +380,10 @@ pub(super) fn compile_typed_f64_closure( pub(super) fn compile_typed_i1_closure( llmod: &mut LlModule, - func_id: perry_types::FuncId, + func_id: perry_hir::types::FuncId, closure_expr: &perry_hir::Expr, module_prefix: &str, - module_local_types: &HashMap, + module_local_types: &HashMap, ) -> Result<()> { let (params, body) = match closure_expr { perry_hir::Expr::Closure { params, body, .. } => (params, body), @@ -425,10 +425,10 @@ pub(super) fn compile_typed_i1_closure( pub(super) fn compile_typed_i32_closure( llmod: &mut LlModule, - func_id: perry_types::FuncId, + func_id: perry_hir::types::FuncId, closure_expr: &perry_hir::Expr, module_prefix: &str, - module_local_types: &HashMap, + module_local_types: &HashMap, ) -> Result<()> { let (params, body) = match closure_expr { perry_hir::Expr::Closure { params, body, .. } => (params, body), @@ -482,7 +482,7 @@ pub(super) fn compile_typed_i32_closure( #[allow(clippy::too_many_arguments)] pub(super) fn compile_closure( llmod: &mut LlModule, - func_id: perry_types::FuncId, + func_id: perry_hir::types::FuncId, closure_expr: &perry_hir::Expr, func_names: &HashMap, strings: &mut StringPool, @@ -501,7 +501,7 @@ pub(super) fn compile_closure( // Seeds `FnCtx.local_types` so a binding captured from an enclosing scope // keeps its declared type at its read sites. NOT the typed-ABI capture // map — the typed closure clones take `module_local_types` instead. - module_receiver_types: &HashMap, + module_receiver_types: &HashMap, closure_rest_params: &HashMap, cross_module: &CrossModuleCtx, ) -> Result<()> { @@ -619,7 +619,7 @@ pub(super) fn compile_closure( // their types available inside the body. Without this, closures // that capture an array `items` and do `items.length` miss the // typed fast path and return undefined. - let mut local_types: HashMap = + let mut local_types: HashMap = params.iter().map(|p| (p.id, p.ty.clone())).collect(); for (id, ty) in module_receiver_types.iter() { local_types.entry(*id).or_insert_with(|| ty.clone()); diff --git a/crates/perry-codegen/src/codegen/closure_collect.rs b/crates/perry-codegen/src/codegen/closure_collect.rs index b69d32951f..be80811d23 100644 --- a/crates/perry-codegen/src/codegen/closure_collect.rs +++ b/crates/perry-codegen/src/codegen/closure_collect.rs @@ -20,7 +20,7 @@ use super::spec_function_length; /// Result bundle of the module-wide closure collection pass. pub(crate) struct ModuleClosures { - pub closures: Vec<(perry_types::FuncId, perry_hir::Expr)>, + pub closures: Vec<(perry_hir::types::FuncId, perry_hir::Expr)>, pub closure_rest_params: HashMap, pub closure_synthetic_arguments: std::collections::HashSet, pub closure_rest_and_arguments: std::collections::HashSet, @@ -43,9 +43,9 @@ pub(crate) fn collect_module_closures(hir: &HirModule) -> ModuleClosures { // otherwise a closure body in (say) a `get size() { return arr.filter(...).length }` // ends up referenced by `js_closure_alloc(@perry_closure_*)` but // never defined, and clang errors with "use of undefined value". - let mut closures: Vec<(perry_types::FuncId, perry_hir::Expr)> = Vec::new(); + let mut closures: Vec<(perry_hir::types::FuncId, perry_hir::Expr)> = Vec::new(); { - let mut seen: std::collections::HashSet = + let mut seen: std::collections::HashSet = std::collections::HashSet::new(); for f in &hir.functions { collect_closures_in_stmts(&f.body, &mut seen, &mut closures); diff --git a/crates/perry-codegen/src/codegen/entry.rs b/crates/perry-codegen/src/codegen/entry.rs index 3dd22d3564..007792cfb6 100644 --- a/crates/perry-codegen/src/codegen/entry.rs +++ b/crates/perry-codegen/src/codegen/entry.rs @@ -664,7 +664,7 @@ pub(super) fn compile_module_entry( &cross_module.compile_time_constants, &cross_module.module_dispatch, ); - let mut init_local_types: HashMap = HashMap::new(); + let mut init_local_types: HashMap = HashMap::new(); crate::boxed_vars::collect_let_types_in_stmts(&hir.init, &mut init_local_types); let mut ctx = FnCtx { func: main, diff --git a/crates/perry-codegen/src/codegen/func_registry.rs b/crates/perry-codegen/src/codegen/func_registry.rs index 1d7b8bb4db..bad861ab88 100644 --- a/crates/perry-codegen/src/codegen/func_registry.rs +++ b/crates/perry-codegen/src/codegen/func_registry.rs @@ -77,7 +77,7 @@ pub(crate) fn build_func_registry(hir: &HirModule, module_prefix: &str) -> FuncR } let returns_number = matches!( f.return_type, - perry_types::Type::Number | perry_types::Type::Int32 + perry_hir::types::Type::Number | perry_hir::types::Type::Int32 ); func_signatures.insert( f.id, diff --git a/crates/perry-codegen/src/codegen/function.rs b/crates/perry-codegen/src/codegen/function.rs index fc6119a10d..ecb0a6179c 100644 --- a/crates/perry-codegen/src/codegen/function.rs +++ b/crates/perry-codegen/src/codegen/function.rs @@ -325,7 +325,7 @@ pub(super) fn compile_function( classes: &HashMap, methods: &HashMap<(String, String), String>, module_globals: &HashMap, - module_global_types: &HashMap, + module_global_types: &HashMap, import_function_prefixes: &HashMap, enums: &HashMap<(String, String), perry_hir::EnumValue>, static_field_globals: &HashMap<(String, String), String>, @@ -423,7 +423,7 @@ pub(super) fn compile_function( // concat detection on a `: string` parameter) works inside the body. // Also seed with module global types so functions that access module // globals see the correct declared types (e.g., Named("Editor")). - let mut local_types: HashMap = module_global_types + let mut local_types: HashMap = module_global_types .iter() .map(|(k, v)| (*k, v.clone())) .collect(); @@ -658,7 +658,7 @@ pub(super) fn compile_function( for p in &f.params { let is_buffer_typed = matches!( &p.ty, - perry_types::Type::Named(n) if n == "Buffer" + perry_hir::types::Type::Named(n) if n == "Buffer" ); if !is_buffer_typed { continue; diff --git a/crates/perry-codegen/src/codegen/method.rs b/crates/perry-codegen/src/codegen/method.rs index 96adc92abc..9a23c9a4f3 100644 --- a/crates/perry-codegen/src/codegen/method.rs +++ b/crates/perry-codegen/src/codegen/method.rs @@ -249,7 +249,7 @@ pub(super) fn compile_method( classes: &HashMap, methods: &HashMap<(String, String), String>, module_globals: &HashMap, - module_global_types: &HashMap, + module_global_types: &HashMap, import_function_prefixes: &HashMap, enums: &HashMap<(String, String), perry_hir::EnumValue>, static_field_globals: &HashMap<(String, String), String>, @@ -345,7 +345,7 @@ pub(super) fn compile_method( (this_slot, map) }; - let mut local_types: HashMap = module_global_types + let mut local_types: HashMap = module_global_types .iter() .map(|(k, v)| (*k, v.clone())) .collect(); @@ -1239,7 +1239,7 @@ pub(super) fn compile_static_method( classes: &HashMap, methods: &HashMap<(String, String), String>, module_globals: &HashMap, - module_global_types: &HashMap, + module_global_types: &HashMap, import_function_prefixes: &HashMap, enums: &HashMap<(String, String), perry_hir::EnumValue>, static_field_globals: &HashMap<(String, String), String>, @@ -1342,7 +1342,7 @@ pub(super) fn compile_static_method( // type-aware dispatch sites and the #6185 perry/thread worker-closure // check (`hazardous_module_global_ids`) were blind inside static // methods. Param types override on collision. - let mut local_types: HashMap = module_global_types + let mut local_types: HashMap = module_global_types .iter() .map(|(k, v)| (*k, v.clone())) .collect(); diff --git a/crates/perry-codegen/src/codegen/mod.rs b/crates/perry-codegen/src/codegen/mod.rs index d1c3a04d07..f926feaf85 100644 --- a/crates/perry-codegen/src/codegen/mod.rs +++ b/crates/perry-codegen/src/codegen/mod.rs @@ -345,7 +345,7 @@ pub fn compile_module(hir: &HirModule, opts: CompileOptions) -> Result> .map(|name| perry_hir::ClassField { name: name.clone(), key_expr: None, - ty: perry_types::Type::Any, + ty: perry_hir::types::Type::Any, init: None, is_private: false, is_readonly: false, @@ -383,7 +383,7 @@ pub fn compile_module(hir: &HirModule, opts: CompileOptions) -> Result> name: format!("get_{}", prop), type_params: Vec::new(), params: Vec::new(), - return_type: perry_types::Type::Any, + return_type: perry_hir::types::Type::Any, body: Vec::new(), is_async: false, is_generator: false, @@ -403,7 +403,7 @@ pub fn compile_module(hir: &HirModule, opts: CompileOptions) -> Result> name: format!("set_{}", prop), type_params: Vec::new(), params: Vec::new(), - return_type: perry_types::Type::Any, + return_type: perry_hir::types::Type::Any, body: Vec::new(), is_async: false, is_generator: false, @@ -444,7 +444,7 @@ pub fn compile_module(hir: &HirModule, opts: CompileOptions) -> Result> .field_types .get(i) .cloned() - .unwrap_or(perry_types::Type::Any), + .unwrap_or(perry_hir::types::Type::Any), init: None, is_private: false, is_readonly: false, @@ -460,7 +460,7 @@ pub fn compile_module(hir: &HirModule, opts: CompileOptions) -> Result> name: m.clone(), type_params: Vec::new(), params: Vec::new(), - return_type: perry_types::Type::Any, + return_type: perry_hir::types::Type::Any, body: Vec::new(), is_async: false, is_generator: false, @@ -1828,7 +1828,7 @@ pub fn compile_module(hir: &HirModule, opts: CompileOptions) -> Result> // closures). Only the typed-ABI *specialization* decision needs the // module-globals removed, so scope the filter to a dedicated copy — the // receiver oracle is `module_receiver_types` (#6369). - let typed_abi_local_types: std::collections::HashMap = + let typed_abi_local_types: std::collections::HashMap = module_local_types .iter() .filter(|(id, _)| !module_globals.contains_key(id)) diff --git a/crates/perry-codegen/src/codegen/module_globals_emit.rs b/crates/perry-codegen/src/codegen/module_globals_emit.rs index b130f554f8..97c9c36f5b 100644 --- a/crates/perry-codegen/src/codegen/module_globals_emit.rs +++ b/crates/perry-codegen/src/codegen/module_globals_emit.rs @@ -23,7 +23,7 @@ use super::ImportedClass; /// Result bundle of the module-global + static-field emission pass. pub(crate) struct ModuleGlobals { pub module_globals: HashMap, - pub module_global_types: HashMap, + pub module_global_types: HashMap, pub static_field_globals: HashMap<(String, String), String>, } @@ -127,8 +127,8 @@ pub(crate) fn emit_module_globals( // stale snapshot. Without this, the closure auto-capture sees // `f` is not yet declared and bails with "local not in scope". { - let mut closures: Vec<(perry_types::FuncId, perry_hir::Expr)> = Vec::new(); - let mut seen: std::collections::HashSet = + let mut closures: Vec<(perry_hir::types::FuncId, perry_hir::Expr)> = Vec::new(); + let mut seen: std::collections::HashSet = std::collections::HashSet::new(); for f in &hir.functions { collect_closures_in_stmts(&f.body, &mut seen, &mut closures); @@ -196,7 +196,7 @@ pub(crate) fn emit_module_globals( // in render.ts has its type only in the entry function's FnCtx, // so method calls in other functions fall through to the generic // dispatch instead of the class method registry. - let mut module_global_types: HashMap = HashMap::new(); + let mut module_global_types: HashMap = HashMap::new(); // Collect exported variable names so we can create external // globals + getter functions for cross-module access. let exported_var_names: std::collections::HashSet = @@ -243,7 +243,7 @@ pub(crate) fn emit_module_globals( if let perry_hir::Stmt::Let { id, name, ty, .. } = s { // Always record the declared type for module-level lets // so all functions see it (not just the entry function). - if !matches!(ty, perry_types::Type::Any) { + if !matches!(ty, perry_hir::types::Type::Any) { module_global_types.insert(*id, ty.clone()); } if referenced_from_fn.contains(id) || exported_var_names.contains(name) { diff --git a/crates/perry-codegen/src/codegen/opts.rs b/crates/perry-codegen/src/codegen/opts.rs index 21050cfbe0..c005b5cae6 100644 --- a/crates/perry-codegen/src/codegen/opts.rs +++ b/crates/perry-codegen/src/codegen/opts.rs @@ -216,7 +216,7 @@ pub struct CompileOptions { pub imported_async_funcs: std::collections::HashSet, /// Type alias map (name → Type) aggregated from all modules. Codegen /// uses this to resolve `Named` types in function signatures. - pub type_aliases: std::collections::HashMap, + pub type_aliases: std::collections::HashMap, /// Imported function parameter counts, keyed by function name. pub imported_func_param_counts: std::collections::HashMap, /// Issue #608 — imported function names whose source-side signature @@ -230,7 +230,7 @@ pub struct CompileOptions { /// just trailing), matching `arguments.length` semantics. pub imported_func_synthetic_arguments: std::collections::HashSet, /// Imported function return types, keyed by local function name. - pub imported_func_return_types: std::collections::HashMap, + pub imported_func_return_types: std::collections::HashMap, /// Names of imports that are exported VARIABLES (not functions). When an /// `ExternFuncRef` with one of these names appears as a value (not as a /// Call callee), the codegen calls the getter function to fetch the value @@ -530,7 +530,7 @@ pub struct ImportedClass { /// class returns `Type::Any` and the dispatch chain breaks at the /// first hop. Empty (or filled with `Type::Any`) is the legacy fallback /// when the source side hasn't been updated to populate it yet. - pub field_types: Vec, + pub field_types: Vec, /// Class id assigned by the source module. When present, the importing /// module reuses this id in its `class_ids` map so that `instanceof` /// on an imported class compares against the same id stamped onto @@ -598,7 +598,7 @@ pub(crate) struct CrossModuleCtx { /// sloppy/strict `this` resolution sees "no receiver" instead of a /// leaked receiver from an enclosing method dispatch (#3576). pub funcs_reading_dynamic_this: std::collections::HashSet, - pub type_aliases: std::collections::HashMap, + pub type_aliases: std::collections::HashMap, pub imported_func_param_counts: std::collections::HashMap, /// Issue #678: see `CompileOptions::import_function_origin_names`. /// Cloned from the same field so codegen helpers reachable via @@ -633,7 +633,7 @@ pub(crate) struct CrossModuleCtx { /// `arguments` rest. The cross-module call bundles ALL args into it (not /// just trailing), matching `arguments.length` semantics. pub imported_func_synthetic_arguments: std::collections::HashSet, - pub imported_func_return_types: std::collections::HashMap, + pub imported_func_return_types: std::collections::HashMap, /// Refs #915 (gap 3 / #321 follow-up): function ids in THIS module /// whose body unconditionally returns a `ClassRef` (or transitively /// returns another such factory). Maps function id → produced diff --git a/crates/perry-codegen/src/codegen/typed_abi.rs b/crates/perry-codegen/src/codegen/typed_abi.rs index 3fa36a542f..7e51497f6c 100644 --- a/crates/perry-codegen/src/codegen/typed_abi.rs +++ b/crates/perry-codegen/src/codegen/typed_abi.rs @@ -7,8 +7,8 @@ use std::collections::{HashMap, HashSet}; +use perry_hir::types::Type; use perry_hir::{BinaryOp, CompareOp, Expr, Function, LogicalOp, Stmt, UnaryOp}; -use perry_types::Type; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub(crate) enum TypedFunctionTrampolineKind { diff --git a/crates/perry-codegen/src/collectors/clamp_detect.rs b/crates/perry-codegen/src/collectors/clamp_detect.rs index 7e1db20eaa..1bfce7c446 100644 --- a/crates/perry-codegen/src/collectors/clamp_detect.rs +++ b/crates/perry-codegen/src/collectors/clamp_detect.rs @@ -4,7 +4,7 @@ pub fn detect_clamp3(f: &Function) -> Option<(u32, u32, u32)> { if f.is_async || f.is_generator || f.params.len() != 3 { return None; } - if !matches!(f.return_type, perry_types::Type::Number) { + if !matches!(f.return_type, perry_hir::types::Type::Number) { return None; } if f.body.len() != 3 { @@ -149,13 +149,13 @@ pub fn is_integer_specializable(f: &Function) -> bool { if f.is_async || f.is_generator { return false; } - if !matches!(f.return_type, perry_types::Type::Number) { + if !matches!(f.return_type, perry_hir::types::Type::Number) { return false; } if !f .params .iter() - .all(|p| matches!(p.ty, perry_types::Type::Number)) + .all(|p| matches!(p.ty, perry_hir::types::Type::Number)) { return false; } @@ -169,7 +169,7 @@ pub fn returns_integer(f: &Function) -> bool { if f.is_async || f.is_generator { return false; } - if !matches!(f.return_type, perry_types::Type::Number) { + if !matches!(f.return_type, perry_hir::types::Type::Number) { return false; } returns_int_stmts(&f.body) @@ -179,7 +179,7 @@ pub fn returns_i32_identity_arg(f: &Function) -> bool { if f.is_async || f.is_generator || f.params.len() != 1 { return false; } - if !matches!(f.return_type, perry_types::Type::Number) { + if !matches!(f.return_type, perry_hir::types::Type::Number) { return false; } let param_id = f.params[0].id; diff --git a/crates/perry-codegen/src/collectors/class_accessors.rs b/crates/perry-codegen/src/collectors/class_accessors.rs index d3f2380011..ab1b40b811 100644 --- a/crates/perry-codegen/src/collectors/class_accessors.rs +++ b/crates/perry-codegen/src/collectors/class_accessors.rs @@ -64,8 +64,8 @@ pub fn is_class_setter( #[cfg(test)] mod tests { use super::*; + use perry_hir::types::Type; use perry_hir::{Class, Function}; - use perry_types::Type; use std::collections::HashMap; fn function(name: &str) -> Function { diff --git a/crates/perry-codegen/src/collectors/closures.rs b/crates/perry-codegen/src/collectors/closures.rs index e062eb0f38..7f201a0632 100644 --- a/crates/perry-codegen/src/collectors/closures.rs +++ b/crates/perry-codegen/src/collectors/closures.rs @@ -2,8 +2,8 @@ use std::collections::HashSet; pub fn collect_closures_in_stmts( stmts: &[perry_hir::Stmt], - seen: &mut HashSet, - out: &mut Vec<(perry_types::FuncId, perry_hir::Expr)>, + seen: &mut HashSet, + out: &mut Vec<(perry_hir::types::FuncId, perry_hir::Expr)>, ) { for s in stmts { match s { @@ -91,8 +91,8 @@ pub fn collect_closures_in_stmts( pub fn collect_closures_in_expr( e: &perry_hir::Expr, - seen: &mut HashSet, - out: &mut Vec<(perry_types::FuncId, perry_hir::Expr)>, + seen: &mut HashSet, + out: &mut Vec<(perry_hir::types::FuncId, perry_hir::Expr)>, ) { use perry_hir::Expr; diff --git a/crates/perry-codegen/src/collectors/hir_facts.rs b/crates/perry-codegen/src/collectors/hir_facts.rs index 15a084c02b..229e44a4a1 100644 --- a/crates/perry-codegen/src/collectors/hir_facts.rs +++ b/crates/perry-codegen/src/collectors/hir_facts.rs @@ -304,7 +304,7 @@ pub(crate) fn collect_type_facts( arg_dependent_clamp_fn_ids: &HashSet, boxed_vars: &HashSet, module_globals: &HashMap, - binding_types: &HashMap, + binding_types: &HashMap, classes: &HashMap, compile_time_constants: &HashMap, module_dispatch: &super::ModuleDispatchFacts, @@ -421,7 +421,7 @@ pub(crate) fn collect_native_region_fact_graph( arg_dependent_clamp_fn_ids: &HashSet, boxed_vars: &HashSet, module_globals: &HashMap, - binding_types: &HashMap, + binding_types: &HashMap, classes: &HashMap, compile_time_constants: &HashMap, module_dispatch: &super::ModuleDispatchFacts, @@ -608,7 +608,7 @@ fn collect_array_facts( stmts: &[Stmt], params: &[perry_hir::Param], module_globals: &HashMap, - binding_types: &HashMap, + binding_types: &HashMap, ) -> (ArrayFacts, EffectFacts, MaterializationHazardFacts) { let mut collector = ArrayFactCollector::default(); collector.seed_params(params); @@ -674,7 +674,7 @@ impl ArrayFactCollector { fn seed_module_bindings( &mut self, module_globals: &HashMap, - binding_types: &HashMap, + binding_types: &HashMap, ) { for id in module_globals.keys() { if let Some(ty) = binding_types.get(id) { @@ -683,7 +683,7 @@ impl ArrayFactCollector { } } - fn seed_declared_array_type(&mut self, id: u32, ty: &perry_types::Type) { + fn seed_declared_array_type(&mut self, id: u32, ty: &perry_hir::types::Type) { let kind = array_kind_from_declared_type(ty); if matches!( kind, @@ -1257,32 +1257,40 @@ impl ArrayFactCollector { } } -fn array_kind_from_declared_type(ty: &perry_types::Type) -> ArrayKindFact { +fn array_kind_from_declared_type(ty: &perry_hir::types::Type) -> ArrayKindFact { match ty { - perry_types::Type::Array(elem) if matches!(elem.as_ref(), perry_types::Type::Int32) => { + perry_hir::types::Type::Array(elem) + if matches!(elem.as_ref(), perry_hir::types::Type::Int32) => + { ArrayKindFact::PackedI32 } - perry_types::Type::Array(elem) if matches!(elem.as_ref(), perry_types::Type::Named(name) if name == "PerryU32") => { + perry_hir::types::Type::Array(elem) if matches!(elem.as_ref(), perry_hir::types::Type::Named(name) if name == "PerryU32") => { ArrayKindFact::PackedU32 } - perry_types::Type::Array(elem) if matches!(elem.as_ref(), perry_types::Type::Number) => { + perry_hir::types::Type::Array(elem) + if matches!(elem.as_ref(), perry_hir::types::Type::Number) => + { ArrayKindFact::PackedF64 } - perry_types::Type::Array(_) => ArrayKindFact::PackedValue, + perry_hir::types::Type::Array(_) => ArrayKindFact::PackedValue, // #6011: `new Array(n)` declares/infers as // `Generic { base: "Array", type_args: [Number] }` rather than // `Array(Number)` — classify the generic spelling identically. - perry_types::Type::Generic { base, type_args } + perry_hir::types::Type::Generic { base, type_args } if base == "Array" && type_args.len() == 1 => { match &type_args[0] { - perry_types::Type::Int32 => ArrayKindFact::PackedI32, - perry_types::Type::Named(name) if name == "PerryU32" => ArrayKindFact::PackedU32, - perry_types::Type::Number => ArrayKindFact::PackedF64, + perry_hir::types::Type::Int32 => ArrayKindFact::PackedI32, + perry_hir::types::Type::Named(name) if name == "PerryU32" => { + ArrayKindFact::PackedU32 + } + perry_hir::types::Type::Number => ArrayKindFact::PackedF64, _ => ArrayKindFact::PackedValue, } } - perry_types::Type::Generic { base, .. } if base == "Array" => ArrayKindFact::PackedValue, + perry_hir::types::Type::Generic { base, .. } if base == "Array" => { + ArrayKindFact::PackedValue + } _ => ArrayKindFact::Unknown, } } @@ -1500,8 +1508,8 @@ fn meet_declared_array_kind(declared: ArrayKindFact, init: ArrayKindFact) -> Arr #[cfg(test)] mod tests { use super::*; + use perry_hir::types::Type; use perry_hir::BinaryOp; - use perry_types::Type; fn const_let(id: u32, init: Expr) -> Stmt { Stmt::Let { diff --git a/crates/perry-codegen/src/collectors/pointer_locals.rs b/crates/perry-codegen/src/collectors/pointer_locals.rs index 41f26e2578..93adc4b02a 100644 --- a/crates/perry-codegen/src/collectors/pointer_locals.rs +++ b/crates/perry-codegen/src/collectors/pointer_locals.rs @@ -1,5 +1,5 @@ +use perry_hir::types::{FunctionType, Type}; use perry_hir::{infer_expr_type, BinaryOp, Expr, HirTypeFacts}; -use perry_types::{FunctionType, Type}; use std::collections::{HashMap, HashSet}; #[derive(Clone)] diff --git a/crates/perry-codegen/src/collectors/scalar_method_dispatch.rs b/crates/perry-codegen/src/collectors/scalar_method_dispatch.rs index 964c7cdfa8..ced40005c3 100644 --- a/crates/perry-codegen/src/collectors/scalar_method_dispatch.rs +++ b/crates/perry-codegen/src/collectors/scalar_method_dispatch.rs @@ -408,8 +408,8 @@ fn for_each_expr_in_stmt(stmt: &Stmt, f: &mut dyn FnMut(&Expr)) { #[cfg(test)] mod tests { use super::*; + use perry_hir::types::Type; use perry_hir::{ClassField, Function}; - use perry_types::Type; const RECEIVER: u32 = 1; diff --git a/crates/perry-codegen/src/collectors/scalar_methods.rs b/crates/perry-codegen/src/collectors/scalar_methods.rs index eda90cc419..559338de8a 100644 --- a/crates/perry-codegen/src/collectors/scalar_methods.rs +++ b/crates/perry-codegen/src/collectors/scalar_methods.rs @@ -13,8 +13,8 @@ use std::collections::{HashMap, HashSet}; +use perry_hir::types::Type; use perry_hir::{BinaryOp, Class, CompareOp, Expr, Function, Stmt, UnaryOp}; -use perry_types::Type; #[derive(Clone, Copy)] enum ScalarMethodReturnKind { diff --git a/crates/perry-codegen/src/collectors/this_as_value.rs b/crates/perry-codegen/src/collectors/this_as_value.rs index 6d932da638..6c9c59b831 100644 --- a/crates/perry-codegen/src/collectors/this_as_value.rs +++ b/crates/perry-codegen/src/collectors/this_as_value.rs @@ -479,8 +479,8 @@ pub fn expr_uses_this_as_value(e: &perry_hir::Expr, fields: &HashSet) -> #[cfg(test)] mod tests { use super::*; + use perry_hir::types::Type; use perry_hir::{Class, ClassField, Expr, Function, Stmt}; - use perry_types::Type; use std::collections::HashMap; fn function(name: &str, body: Vec) -> Function { diff --git a/crates/perry-codegen/src/expr/array_methods.rs b/crates/perry-codegen/src/expr/array_methods.rs index 3354a400da..257e0760f5 100644 --- a/crates/perry-codegen/src/expr/array_methods.rs +++ b/crates/perry-codegen/src/expr/array_methods.rs @@ -47,7 +47,7 @@ pub(crate) fn lower(ctx: &mut FnCtx<'_>, expr: &Expr) -> Result { if let Some(ty) = crate::type_analysis::static_type_of(ctx, o) { if matches!( ty, - perry_types::Type::Array(_) | perry_types::Type::Tuple(_) + perry_hir::types::Type::Array(_) | perry_hir::types::Type::Tuple(_) ) { return Ok(double_literal(f64::from_bits(crate::nanbox::TAG_TRUE))); } @@ -56,14 +56,14 @@ pub(crate) fn lower(ctx: &mut FnCtx<'_>, expr: &Expr) -> Result { // object-class instances on the fast path. let definitely_not_array = matches!( ty, - perry_types::Type::Number - | perry_types::Type::Int32 - | perry_types::Type::String - | perry_types::Type::Boolean - | perry_types::Type::Null - | perry_types::Type::Void - | perry_types::Type::BigInt - | perry_types::Type::Symbol + perry_hir::types::Type::Number + | perry_hir::types::Type::Int32 + | perry_hir::types::Type::String + | perry_hir::types::Type::Boolean + | perry_hir::types::Type::Null + | perry_hir::types::Type::Void + | perry_hir::types::Type::BigInt + | perry_hir::types::Type::Symbol ); if definitely_not_array { return Ok(double_literal(f64::from_bits(crate::nanbox::TAG_FALSE))); diff --git a/crates/perry-codegen/src/expr/arrays_finds.rs b/crates/perry-codegen/src/expr/arrays_finds.rs index 09855a2e05..a2bb3780f4 100644 --- a/crates/perry-codegen/src/expr/arrays_finds.rs +++ b/crates/perry-codegen/src/expr/arrays_finds.rs @@ -5,8 +5,8 @@ //! `lower_expr`'s outer dispatch. use anyhow::{anyhow, bail, Result}; +use perry_hir::types::Type as HirType; use perry_hir::{BinaryOp, Expr}; -use perry_types::Type as HirType; use crate::nanbox::double_literal; use crate::native_value::{ diff --git a/crates/perry-codegen/src/expr/bigint_set.rs b/crates/perry-codegen/src/expr/bigint_set.rs index 9a0c497fb7..a9f613dd23 100644 --- a/crates/perry-codegen/src/expr/bigint_set.rs +++ b/crates/perry-codegen/src/expr/bigint_set.rs @@ -5,8 +5,8 @@ //! `lower_expr`'s outer dispatch. use anyhow::{anyhow, Result}; +use perry_hir::types::Type as HirType; use perry_hir::{BinaryOp, Expr}; -use perry_types::Type as HirType; use crate::nanbox::{double_literal, POINTER_MASK_I64}; use crate::type_analysis::{ diff --git a/crates/perry-codegen/src/expr/calls/helpers.rs b/crates/perry-codegen/src/expr/calls/helpers.rs index 34dc56817f..b76f277aa8 100644 --- a/crates/perry-codegen/src/expr/calls/helpers.rs +++ b/crates/perry-codegen/src/expr/calls/helpers.rs @@ -1,7 +1,7 @@ use super::*; +use perry_hir::types::Type as HirType; use perry_hir::Expr; -use perry_types::Type as HirType; use crate::nanbox::double_literal; use crate::type_analysis::static_type_of; diff --git a/crates/perry-codegen/src/expr/channel.rs b/crates/perry-codegen/src/expr/channel.rs index 6e770ff5b8..18760b304e 100644 --- a/crates/perry-codegen/src/expr/channel.rs +++ b/crates/perry-codegen/src/expr/channel.rs @@ -35,10 +35,10 @@ pub(crate) fn variant_name(e: &Expr) -> String { /// the outer record is still pre-shaped, and nested values go through /// `parse_value_generic` inside `parse_object_shaped`. pub(crate) fn extract_array_of_object_shape( - ty: &perry_types::Type, + ty: &perry_hir::types::Type, ordered_keys: Option<&[String]>, ) -> Option<(Vec, u32)> { - use perry_types::Type; + use perry_hir::types::Type; let elem = match ty { Type::Array(inner) => &**inner, Type::Generic { base, type_args } if base == "Array" && type_args.len() == 1 => { diff --git a/crates/perry-codegen/src/expr/compare.rs b/crates/perry-codegen/src/expr/compare.rs index effacec397..8c7a83842d 100644 --- a/crates/perry-codegen/src/expr/compare.rs +++ b/crates/perry-codegen/src/expr/compare.rs @@ -5,8 +5,8 @@ //! `lower_expr`'s outer dispatch. use anyhow::Result; +use perry_hir::types::Type as HirType; use perry_hir::{CompareOp, Expr}; -use perry_types::Type as HirType; use crate::type_analysis::{ expr_may_return_boxed_value_from_raw_f64_fallback, is_bigint_expr, is_bool_expr, diff --git a/crates/perry-codegen/src/expr/dyn_extern_i18n.rs b/crates/perry-codegen/src/expr/dyn_extern_i18n.rs index 082a474699..27da8e62a8 100644 --- a/crates/perry-codegen/src/expr/dyn_extern_i18n.rs +++ b/crates/perry-codegen/src/expr/dyn_extern_i18n.rs @@ -5,8 +5,8 @@ //! `lower_expr`'s outer dispatch. use anyhow::{anyhow, bail, Result}; +use perry_hir::types::Type as HirType; use perry_hir::Expr; -use perry_types::Type as HirType; use crate::nanbox::{double_literal, POINTER_MASK_I64}; use crate::types::{DOUBLE, I32, I64, PTR}; diff --git a/crates/perry-codegen/src/expr/env_clones.rs b/crates/perry-codegen/src/expr/env_clones.rs index 9b71a0c8f7..80dbfba215 100644 --- a/crates/perry-codegen/src/expr/env_clones.rs +++ b/crates/perry-codegen/src/expr/env_clones.rs @@ -62,7 +62,7 @@ pub(crate) fn lower(ctx: &mut FnCtx<'_>, expr: &Expr) -> Result { let inferred = crate::type_analysis::refine_type_from_init(ctx, d) .or_else(|| crate::type_analysis::static_type_of(ctx, d)); match inferred { - Some(perry_types::Type::Number) | Some(perry_types::Type::Int32) => { + Some(perry_hir::types::Type::Number) | Some(perry_hir::types::Type::Int32) => { let blk = ctx.block(); let handle = blk.call(I64, "js_number_to_locale_string", &[(DOUBLE, &v)]); Ok(nanbox_string_inline(blk, &handle)) diff --git a/crates/perry-codegen/src/expr/helpers.rs b/crates/perry-codegen/src/expr/helpers.rs index 6ea7f144e1..5e308f2e48 100644 --- a/crates/perry-codegen/src/expr/helpers.rs +++ b/crates/perry-codegen/src/expr/helpers.rs @@ -3,8 +3,8 @@ //! issue #1098. Pure move — no logic changes. use anyhow::Result; +use perry_hir::types::Type as HirType; use perry_hir::{BinaryOp, Expr, UnaryOp}; -use perry_types::Type as HirType; use super::{lower_expr, FnCtx}; use crate::block::LlBlock; diff --git a/crates/perry-codegen/src/expr/index_get.rs b/crates/perry-codegen/src/expr/index_get.rs index f185322980..8b2d05fb4c 100644 --- a/crates/perry-codegen/src/expr/index_get.rs +++ b/crates/perry-codegen/src/expr/index_get.rs @@ -5,8 +5,8 @@ //! `lower_expr`'s outer dispatch. use anyhow::Result; +use perry_hir::types::Type as HirType; use perry_hir::{BinaryOp, Expr}; -use perry_types::Type as HirType; use crate::nanbox::POINTER_MASK_I64; use crate::native_value::{ @@ -1640,7 +1640,7 @@ pub(crate) fn lower(ctx: &mut FnCtx<'_>, expr: &Expr) -> Result { let recv_ty = crate::type_analysis::static_type_of(ctx, object); let recv_unknown = matches!( recv_ty, - None | Some(perry_types::Type::Any) | Some(perry_types::Type::Unknown) + None | Some(perry_hir::types::Type::Any) | Some(perry_hir::types::Type::Unknown) ); // #5525: route every non-static-string/symbol read on an unknown // receiver through `js_dyn_index_get` (numeric, runtime-string, and diff --git a/crates/perry-codegen/src/expr/index_set.rs b/crates/perry-codegen/src/expr/index_set.rs index 812e9061fc..95a6f1eba0 100644 --- a/crates/perry-codegen/src/expr/index_set.rs +++ b/crates/perry-codegen/src/expr/index_set.rs @@ -866,7 +866,7 @@ pub(crate) fn lower(ctx: &mut FnCtx<'_>, expr: &Expr) -> Result { let recv_ty = crate::type_analysis::static_type_of(ctx, object); let recv_unknown = matches!( recv_ty, - None | Some(perry_types::Type::Any) | Some(perry_types::Type::Unknown) + None | Some(perry_hir::types::Type::Any) | Some(perry_hir::types::Type::Unknown) ); // The index may be numeric, a runtime string, or (rarely) a runtime // symbol — `js_dyn_index_set` triages all three. We only keep the diff --git a/crates/perry-codegen/src/expr/literals_vars.rs b/crates/perry-codegen/src/expr/literals_vars.rs index 5cf76f4b2b..1334882a67 100644 --- a/crates/perry-codegen/src/expr/literals_vars.rs +++ b/crates/perry-codegen/src/expr/literals_vars.rs @@ -5,8 +5,8 @@ //! `lower_expr`'s outer dispatch. use anyhow::{anyhow, Result}; +use perry_hir::types::Type as HirType; use perry_hir::{BinaryOp, Expr, UpdateOp}; -use perry_types::Type as HirType; use crate::lower_string_method::lower_string_self_append; use crate::nanbox::double_literal; diff --git a/crates/perry-codegen/src/expr/logical_collections.rs b/crates/perry-codegen/src/expr/logical_collections.rs index c4c94c904e..9b415ffc68 100644 --- a/crates/perry-codegen/src/expr/logical_collections.rs +++ b/crates/perry-codegen/src/expr/logical_collections.rs @@ -5,8 +5,8 @@ //! `lower_expr`'s outer dispatch. use anyhow::{bail, Result}; +use perry_hir::types::Type as HirType; use perry_hir::Expr; -use perry_types::Type as HirType; use crate::lower_conditional::lower_logical; use crate::nanbox::{double_literal, POINTER_MASK_I64, TAG_UNDEFINED}; diff --git a/crates/perry-codegen/src/expr/math_simple.rs b/crates/perry-codegen/src/expr/math_simple.rs index 45a11778e7..e1faf33f83 100644 --- a/crates/perry-codegen/src/expr/math_simple.rs +++ b/crates/perry-codegen/src/expr/math_simple.rs @@ -5,8 +5,8 @@ //! `lower_expr`'s outer dispatch. use anyhow::Result; +use perry_hir::types::Type as HirType; use perry_hir::{BinaryOp, Expr}; -use perry_types::Type as HirType; use crate::type_analysis::{is_definitely_string_expr, is_numeric_expr, map_static_type_args}; use crate::types::{DOUBLE, F32, I1, I32, I64}; diff --git a/crates/perry-codegen/src/expr/mod.rs b/crates/perry-codegen/src/expr/mod.rs index eaccab3247..bfe54b1625 100644 --- a/crates/perry-codegen/src/expr/mod.rs +++ b/crates/perry-codegen/src/expr/mod.rs @@ -9,8 +9,8 @@ //! one-line explanation instead of a silent broken binary. use anyhow::{anyhow, Result}; +use perry_hir::types::Type as HirType; use perry_hir::{BinaryOp, CompareOp, Expr, UnaryOp}; -use perry_types::Type as HirType; use crate::block::LlBlock; use crate::codegen::AppMetadata; @@ -487,7 +487,7 @@ pub(crate) struct FnCtx<'a> { pub funcs_reading_dynamic_this: &'a std::collections::HashSet, /// Type alias map (name → Type) aggregated from all modules. Used /// to resolve `Named` types in function signatures and dispatch. - pub type_aliases: &'a std::collections::HashMap, + pub type_aliases: &'a std::collections::HashMap, /// Imported function parameter counts, keyed by function name. /// Used for rest-param bundling on cross-module calls. pub imported_func_param_counts: &'a std::collections::HashMap, @@ -500,7 +500,7 @@ pub(crate) struct FnCtx<'a> { pub imported_func_synthetic_arguments: &'a std::collections::HashSet, /// Imported function return types, keyed by local function name. /// Used for type-aware dispatch on cross-module call results. - pub imported_func_return_types: &'a std::collections::HashMap, + pub imported_func_return_types: &'a std::collections::HashMap, /// Per-method explicit param counts, keyed by `(class_name, method_name)`. /// Built from BOTH local `hir.classes` AND `opts.imported_classes`. /// `lower_call.rs` dispatch sites use this to pad missing trailing args diff --git a/crates/perry-codegen/src/expr/native_memory.rs b/crates/perry-codegen/src/expr/native_memory.rs index 638ceb6454..9dbed12eab 100644 --- a/crates/perry-codegen/src/expr/native_memory.rs +++ b/crates/perry-codegen/src/expr/native_memory.rs @@ -1,6 +1,6 @@ use anyhow::Result; +use perry_hir::types::Type as HirType; use perry_hir::Expr; -use perry_types::Type as HirType; use crate::native_value::{ AliasState, BoundsProof, BoundsState, BufferAccessMode, BufferElem, BufferIndexUnit, diff --git a/crates/perry-codegen/src/expr/new_dynamic.rs b/crates/perry-codegen/src/expr/new_dynamic.rs index 1d42ac77b1..3f976316cd 100644 --- a/crates/perry-codegen/src/expr/new_dynamic.rs +++ b/crates/perry-codegen/src/expr/new_dynamic.rs @@ -5,8 +5,8 @@ //! `lower_expr`'s outer dispatch. use anyhow::Result; +use perry_hir::types::Type as HirType; use perry_hir::Expr; -use perry_types::Type as HirType; use crate::lower_call::lower_new; use crate::lower_conditional::lower_conditional; diff --git a/crates/perry-codegen/src/expr/object_literal.rs b/crates/perry-codegen/src/expr/object_literal.rs index e594b11ac8..43f895ba5d 100644 --- a/crates/perry-codegen/src/expr/object_literal.rs +++ b/crates/perry-codegen/src/expr/object_literal.rs @@ -2,8 +2,8 @@ //! Pure move — no logic changes. use anyhow::Result; +use perry_hir::types::Type as HirType; use perry_hir::Expr; -use perry_types::Type as HirType; use super::{lower_expr, nanbox_pointer_inline, FnCtx}; use crate::nanbox::POINTER_MASK_I64; @@ -127,7 +127,7 @@ fn is_number_type(ty: &HirType) -> bool { matches!(ty, HirType::Number) } -fn object_type_is_exact_xy_number(ty: &perry_types::ObjectType) -> bool { +fn object_type_is_exact_xy_number(ty: &perry_hir::types::ObjectType) -> bool { ty.index_signature.is_none() && ty.properties.len() == 2 && ty diff --git a/crates/perry-codegen/src/expr/pod_layout_constants.rs b/crates/perry-codegen/src/expr/pod_layout_constants.rs index 4f10e26af8..da2149e8ef 100644 --- a/crates/perry-codegen/src/expr/pod_layout_constants.rs +++ b/crates/perry-codegen/src/expr/pod_layout_constants.rs @@ -1,6 +1,6 @@ use anyhow::{bail, Result}; +use perry_hir::types::Type; use perry_hir::Expr; -use perry_types::Type; use crate::nanbox::double_literal; use crate::native_value::{layout_decision_for_type, PodLayoutDecision, PodLayoutManifest}; diff --git a/crates/perry-codegen/src/expr/property_get.rs b/crates/perry-codegen/src/expr/property_get.rs index 0d16756817..4413fb24c6 100644 --- a/crates/perry-codegen/src/expr/property_get.rs +++ b/crates/perry-codegen/src/expr/property_get.rs @@ -5,8 +5,8 @@ //! `lower_expr`'s outer dispatch. use anyhow::Result; +use perry_hir::types::Type as HirType; use perry_hir::Expr; -use perry_types::Type as HirType; use crate::nanbox::{double_literal, POINTER_MASK_I64}; use crate::native_value::{ diff --git a/crates/perry-codegen/src/expr/property_get/tests.rs b/crates/perry-codegen/src/expr/property_get/tests.rs index 7f81613c62..6b9a55c7a9 100644 --- a/crates/perry-codegen/src/expr/property_get/tests.rs +++ b/crates/perry-codegen/src/expr/property_get/tests.rs @@ -80,7 +80,7 @@ fn module_with_nullish_read() -> Module { Stmt::Let { id: 1, name: "o".to_string(), - ty: perry_types::Type::Any, + ty: perry_hir::types::Type::Any, mutable: false, init: Some(Expr::Undefined), }, diff --git a/crates/perry-codegen/src/expr/property_set.rs b/crates/perry-codegen/src/expr/property_set.rs index 0e6f8f345b..3495378038 100644 --- a/crates/perry-codegen/src/expr/property_set.rs +++ b/crates/perry-codegen/src/expr/property_set.rs @@ -5,8 +5,8 @@ //! `lower_expr`'s outer dispatch. use anyhow::Result; +use perry_hir::types::Type as HirType; use perry_hir::Expr; -use perry_types::Type as HirType; use crate::nanbox::POINTER_MASK_I64; use crate::native_value::{ diff --git a/crates/perry-codegen/src/expr/proxy_reflect.rs b/crates/perry-codegen/src/expr/proxy_reflect.rs index 47377ef3fd..b41ec6ce67 100644 --- a/crates/perry-codegen/src/expr/proxy_reflect.rs +++ b/crates/perry-codegen/src/expr/proxy_reflect.rs @@ -777,7 +777,7 @@ fn put_value_index_fast_path(ctx: &FnCtx<'_>, target: &Expr, key: &Expr, receive // typed receiver is unaffected — `recv_unknown` is false for them. let recv_unknown = matches!( crate::type_analysis::static_type_of(ctx, target), - None | Some(perry_types::Type::Any) | Some(perry_types::Type::Unknown) + None | Some(perry_hir::types::Type::Any) | Some(perry_hir::types::Type::Unknown) ); // Mirror `index_set::lower`'s `recv_unknown` arm: keep statically-known // string-literal / symbol keys on their dedicated routes; route everything diff --git a/crates/perry-codegen/src/expr/shadow_slot.rs b/crates/perry-codegen/src/expr/shadow_slot.rs index 03e45a9e8d..f65d293efe 100644 --- a/crates/perry-codegen/src/expr/shadow_slot.rs +++ b/crates/perry-codegen/src/expr/shadow_slot.rs @@ -5,8 +5,8 @@ //! `crate::expr::X` call paths resolve unchanged. use super::*; +use perry_hir::types::Type as HirType; use perry_hir::{BinaryOp, Expr}; -use perry_types::Type as HirType; use crate::types::{I32, I64, PTR}; diff --git a/crates/perry-codegen/src/expr/static_method.rs b/crates/perry-codegen/src/expr/static_method.rs index e7f797ede4..d56dbd2f8a 100644 --- a/crates/perry-codegen/src/expr/static_method.rs +++ b/crates/perry-codegen/src/expr/static_method.rs @@ -5,8 +5,8 @@ //! `lower_expr`'s outer dispatch. use anyhow::{bail, Result}; +use perry_hir::types::Type as HirType; use perry_hir::Expr; -use perry_types::Type as HirType; use crate::nanbox::double_literal; use crate::native_value::MaterializationReason; diff --git a/crates/perry-codegen/src/lower_call/buffer_intrinsic.rs b/crates/perry-codegen/src/lower_call/buffer_intrinsic.rs index 4c9d8c4303..767a874f08 100644 --- a/crates/perry-codegen/src/lower_call/buffer_intrinsic.rs +++ b/crates/perry-codegen/src/lower_call/buffer_intrinsic.rs @@ -576,7 +576,7 @@ mod shadow_scan_tests { ClassField { name: name.to_string(), key_expr: None, - ty: perry_types::Type::Any, + ty: perry_hir::types::Type::Any, init: Some(init), is_private: false, is_readonly: false, diff --git a/crates/perry-codegen/src/lower_call/closure_analysis.rs b/crates/perry-codegen/src/lower_call/closure_analysis.rs index 7e030f17ef..185c46ea16 100644 --- a/crates/perry-codegen/src/lower_call/closure_analysis.rs +++ b/crates/perry-codegen/src/lower_call/closure_analysis.rs @@ -17,7 +17,7 @@ /// NOT into nested closures: those have their own inner-id set. pub fn collect_closure_introduced_ids( stmt: &perry_hir::Stmt, - out: &mut std::collections::HashSet, + out: &mut std::collections::HashSet, ) { use perry_hir::Stmt; match stmt { @@ -92,8 +92,8 @@ pub fn collect_closure_introduced_ids( /// a threading primitive). pub fn find_outer_writes_stmt( stmt: &perry_hir::Stmt, - inner_ids: &std::collections::HashSet, - out: &mut Vec, + inner_ids: &std::collections::HashSet, + out: &mut Vec, ) { use perry_hir::Stmt; match stmt { @@ -196,8 +196,8 @@ pub fn find_outer_writes_stmt( fn find_outer_writes_expr( expr: &perry_hir::Expr, - inner_ids: &std::collections::HashSet, - out: &mut Vec, + inner_ids: &std::collections::HashSet, + out: &mut Vec, ) { use perry_hir::Expr; match expr { @@ -282,7 +282,7 @@ pub enum ThreadClosureHazard { /// type is not a thread-transferable primitive. Module globals live in /// process-wide slots and are read in place — they do NOT go through /// the capture deep-copy — so the worker aliases main-heap objects. - ModuleGlobalAccess(perry_types::LocalId), + ModuleGlobalAccess(perry_hir::types::LocalId), } /// Types whose module-global slot value can be read from a worker thread @@ -291,8 +291,8 @@ pub enum ThreadClosureHazard { /// rooted when they back a module global. `Any` / `Unknown` / type vars are /// allowed because this is a best-effort AST-level check — rejecting /// unprovable bindings would flag every untyped numeric global. -fn is_thread_transferable_global_type(ty: &perry_types::Type) -> bool { - use perry_types::Type; +fn is_thread_transferable_global_type(ty: &perry_hir::types::Type) -> bool { + use perry_hir::types::Type; match ty { Type::Void | Type::Null @@ -328,8 +328,8 @@ fn is_thread_transferable_global_type(ty: &perry_types::Type) -> bool { /// `local_types`, and `module_global_types` skips `Any`). pub fn hazardous_module_global_ids( module_globals: &std::collections::HashMap, - local_types: &std::collections::HashMap, -) -> std::collections::HashSet { + local_types: &std::collections::HashMap, +) -> std::collections::HashSet { module_globals .keys() .filter(|id| { @@ -353,7 +353,7 @@ pub fn hazardous_module_global_ids( /// (#6188/#6212) remain the backstop for what this walk can't prove. pub fn find_thread_hazard_in_body( body: &[perry_hir::Stmt], - hazardous_ids: &std::collections::HashSet, + hazardous_ids: &std::collections::HashSet, async_step_closures: &std::collections::HashSet, ) -> Option { body.iter() @@ -362,7 +362,7 @@ pub fn find_thread_hazard_in_body( fn find_thread_hazard_stmt( stmt: &perry_hir::Stmt, - hazardous_ids: &std::collections::HashSet, + hazardous_ids: &std::collections::HashSet, async_step_closures: &std::collections::HashSet, ) -> Option { use perry_hir::Stmt; @@ -425,7 +425,7 @@ fn find_thread_hazard_stmt( fn find_thread_hazard_expr( e: &perry_hir::Expr, - hazardous_ids: &std::collections::HashSet, + hazardous_ids: &std::collections::HashSet, async_step_closures: &std::collections::HashSet, ) -> Option { use perry_hir::Expr; diff --git a/crates/perry-codegen/src/lower_call/console_promise.rs b/crates/perry-codegen/src/lower_call/console_promise.rs index fa9753962d..9533033851 100644 --- a/crates/perry-codegen/src/lower_call/console_promise.rs +++ b/crates/perry-codegen/src/lower_call/console_promise.rs @@ -10,8 +10,8 @@ //! normalizes them to the `util/types` / `util.types` module keys. use anyhow::Result; +use perry_hir::types::Type as HirType; use perry_hir::Expr; -use perry_types::Type as HirType; use crate::expr::{ emit_typed_feedback_register_site, lower_expr, nanbox_pointer_inline, FnCtx, diff --git a/crates/perry-codegen/src/lower_call/early_branches.rs b/crates/perry-codegen/src/lower_call/early_branches.rs index 883b6373b0..737868951d 100644 --- a/crates/perry-codegen/src/lower_call/early_branches.rs +++ b/crates/perry-codegen/src/lower_call/early_branches.rs @@ -11,8 +11,8 @@ //! `Ok(None)` to let the caller try the next branch. use anyhow::{bail, Result}; +use perry_hir::types::Type as HirType; use perry_hir::Expr; -use perry_types::Type as HirType; use crate::expr::{ emit_typed_feedback_register_site, i32_bool_to_nanbox, lower_expr, nanbox_pointer_inline, diff --git a/crates/perry-codegen/src/lower_call/extern_func.rs b/crates/perry-codegen/src/lower_call/extern_func.rs index d43207f301..a272131c5f 100644 --- a/crates/perry-codegen/src/lower_call/extern_func.rs +++ b/crates/perry-codegen/src/lower_call/extern_func.rs @@ -9,8 +9,8 @@ use anyhow::{anyhow, Result}; use perry_api_manifest::{ NativeAbiType, NativeHandleAbi, NativeHandleOwnership, NativeHandleThreadAffinity, NativePodAbi, }; +use perry_hir::types::Type as HirType; use perry_hir::Expr; -use perry_types::Type as HirType; use crate::expr::{lower_expr, nanbox_pointer_inline, nanbox_string_inline, unbox_to_i64, FnCtx}; use crate::nanbox::{double_literal, POINTER_MASK_I64}; diff --git a/crates/perry-codegen/src/lower_call/func_ref.rs b/crates/perry-codegen/src/lower_call/func_ref.rs index f6d2af5587..d676137851 100644 --- a/crates/perry-codegen/src/lower_call/func_ref.rs +++ b/crates/perry-codegen/src/lower_call/func_ref.rs @@ -15,7 +15,7 @@ fn is_i32_expr(ctx: &FnCtx<'_>, arg: &Expr) -> bool { Expr::Integer(n) => (i64::from(i32::MIN)..=i64::from(i32::MAX)).contains(n), _ => matches!( crate::type_analysis::static_type_of(ctx, arg), - Some(perry_types::Type::Int32) + Some(perry_hir::types::Type::Int32) ), } } diff --git a/crates/perry-codegen/src/lower_call/native/mod.rs b/crates/perry-codegen/src/lower_call/native/mod.rs index 1e374eb909..7b06613dfa 100644 --- a/crates/perry-codegen/src/lower_call/native/mod.rs +++ b/crates/perry-codegen/src/lower_call/native/mod.rs @@ -23,8 +23,8 @@ use anyhow::{bail, Result}; use perry_dispatch::{ArgKind as UiArgKind, ReturnKind as UiReturnKind}; +use perry_hir::types::Type as HirType; use perry_hir::Expr; -use perry_types::Type as HirType; use crate::expr::{ emit_root_nanbox_store_on_block, lower_expr, nanbox_pointer_inline, unbox_to_i64, FnCtx, @@ -160,12 +160,13 @@ pub(crate) fn lower_native_method_call( body, .. } => { - let mut inner_ids: std::collections::HashSet = - params.iter().map(|p| p.id).collect(); + let mut inner_ids: std::collections::HashSet< + perry_hir::types::LocalId, + > = params.iter().map(|p| p.id).collect(); for stmt in body { collect_closure_introduced_ids(stmt, &mut inner_ids); } - let mut outer_writes: Vec = Vec::new(); + let mut outer_writes: Vec = Vec::new(); for stmt in body { find_outer_writes_stmt(stmt, &inner_ids, &mut outer_writes); } diff --git a/crates/perry-codegen/src/lower_call/new.rs b/crates/perry-codegen/src/lower_call/new.rs index 73049a1341..03afe736ed 100644 --- a/crates/perry-codegen/src/lower_call/new.rs +++ b/crates/perry-codegen/src/lower_call/new.rs @@ -6,8 +6,8 @@ //! in the sibling `field_init` module. use anyhow::Result; +use perry_hir::types::Type as HirType; use perry_hir::Expr; -use perry_types::Type as HirType; use super::field_init::{apply_field_initializers_recursive, FieldInitMode}; use super::lower_builtin_new; diff --git a/crates/perry-codegen/src/lower_call/new_ctor_args.rs b/crates/perry-codegen/src/lower_call/new_ctor_args.rs index 900eb466bf..420bc4523b 100644 --- a/crates/perry-codegen/src/lower_call/new_ctor_args.rs +++ b/crates/perry-codegen/src/lower_call/new_ctor_args.rs @@ -12,8 +12,8 @@ //! the former `new_site_args_carry_appended_caps` arg-shape heuristic. use anyhow::Result; +use perry_hir::types::Type as HirType; use perry_hir::{Expr, Param}; -use perry_types::Type as HirType; use super::new_helpers::effective_constructor_param_count; use crate::expr::{lower_expr, nanbox_pointer_inline, FnCtx}; diff --git a/crates/perry-codegen/src/lower_call/options/abort.rs b/crates/perry-codegen/src/lower_call/options/abort.rs index c292f51d8f..0307fe68cf 100644 --- a/crates/perry-codegen/src/lower_call/options/abort.rs +++ b/crates/perry-codegen/src/lower_call/options/abort.rs @@ -7,8 +7,8 @@ //! `AbortSignal.timeout(ms)`. use anyhow::Result; +use perry_hir::types::Type as HirType; use perry_hir::Expr; -use perry_types::Type as HirType; use crate::expr::{lower_expr, unbox_to_i64, FnCtx}; use crate::nanbox::double_literal; diff --git a/crates/perry-codegen/src/lower_call/property_get.rs b/crates/perry-codegen/src/lower_call/property_get.rs index 66ab6caf8a..e87dc93f58 100644 --- a/crates/perry-codegen/src/lower_call/property_get.rs +++ b/crates/perry-codegen/src/lower_call/property_get.rs @@ -161,7 +161,7 @@ pub fn try_lower_property_get_method_call( // go through dispatch_buffer_method via js_native_call_method. let is_buffer = matches!( crate::type_analysis::static_type_of(ctx, object), - Some(perry_types::Type::Named(ref n)) if n == "Uint8Array" || n == "Buffer" + Some(perry_hir::types::Type::Named(ref n)) if n == "Uint8Array" || n == "Buffer" ); // #1760: a dynamic native-module sub-namespace receiver // (`(path as any)[k]` → `path.win32`) is NOT a string, even though a diff --git a/crates/perry-codegen/src/lower_call/scalar_method.rs b/crates/perry-codegen/src/lower_call/scalar_method.rs index 9a01b7b6c8..1ba7c73fd9 100644 --- a/crates/perry-codegen/src/lower_call/scalar_method.rs +++ b/crates/perry-codegen/src/lower_call/scalar_method.rs @@ -3,8 +3,8 @@ use anyhow::{bail, Result}; use std::collections::HashMap; +use perry_hir::types::Type; use perry_hir::{BinaryOp, Expr, UnaryOp}; -use perry_types::Type; use crate::expr::{ emit_jsvalue_slot_store_on_block, i32_to_nanbox, lower_expr, lower_expr_as_i32, diff --git a/crates/perry-codegen/src/lower_string_method.rs b/crates/perry-codegen/src/lower_string_method.rs index 571cc733a5..756b4dcf94 100644 --- a/crates/perry-codegen/src/lower_string_method.rs +++ b/crates/perry-codegen/src/lower_string_method.rs @@ -4,8 +4,8 @@ //! `lower_string_coerce_concat`, and `lower_string_concat`. use anyhow::{anyhow, bail, Result}; +use perry_hir::types::Type as HirType; use perry_hir::Expr; -use perry_types::Type as HirType; use crate::expr::{ i32_bool_to_nanbox, lower_expr, nanbox_pointer_inline, nanbox_string_inline, unbox_str_handle, diff --git a/crates/perry-codegen/src/native_value/pod.rs b/crates/perry-codegen/src/native_value/pod.rs index 955220eef0..8470a6178c 100644 --- a/crates/perry-codegen/src/native_value/pod.rs +++ b/crates/perry-codegen/src/native_value/pod.rs @@ -1,6 +1,6 @@ use perry_api_manifest::{NativeAbiType, NativePodAbi}; +use perry_hir::types::{ObjectType, Type}; use perry_hir::Expr; -use perry_types::{ObjectType, Type}; use crate::expr::FnCtx; use crate::types::{DOUBLE, F32, I32, I64}; diff --git a/crates/perry-codegen/src/stmt/let_stmt.rs b/crates/perry-codegen/src/stmt/let_stmt.rs index 8533562dbd..4033eeea49 100644 --- a/crates/perry-codegen/src/stmt/let_stmt.rs +++ b/crates/perry-codegen/src/stmt/let_stmt.rs @@ -54,7 +54,7 @@ pub(crate) fn lower_let( id: u32, name: &str, init: Option<&perry_hir::Expr>, - ty: &perry_types::Type, + ty: &perry_hir::types::Type, mutable: bool, ) -> Result<()> { // `let C = SomeClass` aliases the local `C` to the class @@ -236,10 +236,10 @@ pub(crate) fn lower_let( // We only refine Any → something more specific; we don't // override declared types because the user may have written // `let x: Object = ...` deliberately. - let refined_ty = if matches!(ty, perry_types::Type::Any) { + let refined_ty = if matches!(ty, perry_hir::types::Type::Any) { init.and_then(|e| crate::type_analysis::refine_type_from_init(ctx, e)) .unwrap_or_else(|| ty.clone()) - } else if matches!(ty, perry_types::Type::Array(ref elem) if matches!(**elem, perry_types::Type::Any)) + } else if matches!(ty, perry_hir::types::Type::Array(ref elem) if matches!(**elem, perry_hir::types::Type::Any)) { // Also refine Array when the init provides more // specific element type info. Object.keys() returns @@ -1191,7 +1191,7 @@ pub(crate) fn lower_let( let needs_i32_slot = (ctx.integer_locals.contains(&id) || is_unsigned_i32_local) && i32_safe_local && init_in_i32_range - && !matches!(refined_ty, perry_types::Type::BigInt) + && !matches!(refined_ty, perry_hir::types::Type::BigInt) && !ctx.boxed_vars.contains(&id) && !ctx.module_globals.contains_key(&id) && !ctx.i32_counter_slots.contains_key(&id); @@ -1201,7 +1201,7 @@ pub(crate) fn lower_let( ctx.i32_counter_slots.insert(id, i32_slot); } if init.is_some() - && matches!(refined_ty, perry_types::Type::Boolean) + && matches!(refined_ty, perry_hir::types::Type::Boolean) && !ctx.boxed_vars.contains(&id) && !ctx.module_globals.contains_key(&id) && !ctx.i1_local_slots.contains_key(&id) @@ -1272,8 +1272,8 @@ pub(crate) fn lower_let( let v = if !used_i32_init { let native_init = if matches!( refined_ty, - perry_types::Type::Number | perry_types::Type::Int32 - ) || (matches!(refined_ty, perry_types::Type::Boolean) + perry_hir::types::Type::Number | perry_hir::types::Type::Int32 + ) || (matches!(refined_ty, perry_hir::types::Type::Boolean) && ctx.i1_local_slots.contains_key(&id)) { lower_expr_value(ctx, init_expr)? @@ -1382,7 +1382,10 @@ pub(crate) fn lower_let( // started returning `start-try-finally` instead of // `start-try`. if let perry_hir::Expr::LocalGet(src_id) = init_expr { - if matches!(ctx.local_types.get(src_id), Some(perry_types::Type::String)) { + if matches!( + ctx.local_types.get(src_id), + Some(perry_hir::types::Type::String) + ) { let blk = ctx.block(); let s_ptr = blk.call( crate::types::I64, @@ -1413,7 +1416,10 @@ pub(crate) fn lower_let( // started returning `start-try-finally` instead of // `start-try`. if let perry_hir::Expr::LocalGet(src_id) = init_expr { - if matches!(ctx.local_types.get(src_id), Some(perry_types::Type::String)) { + if matches!( + ctx.local_types.get(src_id), + Some(perry_hir::types::Type::String) + ) { let blk = ctx.block(); let s_ptr = blk.call( crate::types::I64, @@ -1437,7 +1443,7 @@ pub(crate) fn lower_let( if view_type.is_some() && matches!( refined_ty, - perry_types::Type::Any | perry_types::Type::Unknown + perry_hir::types::Type::Any | perry_hir::types::Type::Unknown ) => { crate::native_value::layout_for_pod_view_type( diff --git a/crates/perry-codegen/src/stmt/loops.rs b/crates/perry-codegen/src/stmt/loops.rs index d265c9c6c0..91d3d14a46 100644 --- a/crates/perry-codegen/src/stmt/loops.rs +++ b/crates/perry-codegen/src/stmt/loops.rs @@ -228,8 +228,8 @@ fn match_numeric_bulk_fill_loop( }; let is_numeric_array = matches!( ctx.local_types.get(&array_id), - Some(perry_types::Type::Array(elem)) - if matches!(elem.as_ref(), perry_types::Type::Number | perry_types::Type::Int32) + Some(perry_hir::types::Type::Array(elem)) + if matches!(elem.as_ref(), perry_hir::types::Type::Number | perry_hir::types::Type::Int32) ); if !is_numeric_array { return None; @@ -387,7 +387,7 @@ fn match_numeric_range_add_loop( if !matches!(index, Expr::LocalGet(id) if *id == counter_id) || !matches!( local_array_element_type(ctx, array_id), - Some(perry_types::Type::Any | perry_types::Type::Unknown) + Some(perry_hir::types::Type::Any | perry_hir::types::Type::Unknown) ) || !packed_loop_array_binding_storage_is_addressable(ctx, array_id) || ctx.scalar_replaced_arrays.contains_key(&array_id) @@ -3100,10 +3100,10 @@ fn match_packed_f64_versioned_loop( fn local_array_element_type<'t>( ctx: &'t FnCtx<'_>, local_id: u32, -) -> Option<&'t perry_types::Type> { +) -> Option<&'t perry_hir::types::Type> { match ctx.local_types.get(&local_id) { - Some(perry_types::Type::Array(elem)) => Some(elem.as_ref()), - Some(perry_types::Type::Generic { base, type_args }) + Some(perry_hir::types::Type::Array(elem)) => Some(elem.as_ref()), + Some(perry_hir::types::Type::Generic { base, type_args }) if base == "Array" && type_args.len() == 1 => { Some(&type_args[0]) @@ -3168,10 +3168,10 @@ pub(super) fn packed_loop_array_binding_storage_is_addressable( pub(super) fn local_is_number_array(ctx: &FnCtx<'_>, local_id: u32) -> bool { matches!( local_array_element_type(ctx, local_id), - Some(perry_types::Type::Number | perry_types::Type::Int32) + Some(perry_hir::types::Type::Number | perry_hir::types::Type::Int32) ) || matches!( local_array_element_type(ctx, local_id), - Some(perry_types::Type::Named(name)) if name == "PerryU32" + Some(perry_hir::types::Type::Named(name)) if name == "PerryU32" ) } @@ -3187,28 +3187,28 @@ pub(super) fn local_is_number_array(ctx: &FnCtx<'_>, local_id: u32) -> bool { pub(super) fn local_is_untyped_candidate(ctx: &FnCtx<'_>, local_id: u32) -> bool { matches!( ctx.local_types.get(&local_id), - None | Some(perry_types::Type::Any | perry_types::Type::Unknown) + None | Some(perry_hir::types::Type::Any | perry_hir::types::Type::Unknown) ) } fn local_allows_packed_f64_loop_store(ctx: &FnCtx<'_>, local_id: u32) -> bool { matches!( local_array_element_type(ctx, local_id), - Some(perry_types::Type::Number) + Some(perry_hir::types::Type::Number) ) } fn local_is_int32_array(ctx: &FnCtx<'_>, local_id: u32) -> bool { matches!( local_array_element_type(ctx, local_id), - Some(perry_types::Type::Int32) + Some(perry_hir::types::Type::Int32) ) } fn local_is_u32_array(ctx: &FnCtx<'_>, local_id: u32) -> bool { matches!( local_array_element_type(ctx, local_id), - Some(perry_types::Type::Named(name)) if name == "PerryU32" + Some(perry_hir::types::Type::Named(name)) if name == "PerryU32" ) } @@ -3381,7 +3381,7 @@ fn expr_is_packed_i32_loop_store_rhs_safe( fn local_is_int32_value(ctx: &FnCtx<'_>, local_id: u32) -> bool { matches!( ctx.local_types.get(&local_id), - Some(perry_types::Type::Int32) + Some(perry_hir::types::Type::Int32) ) || ctx.integer_locals.contains(&local_id) } @@ -5799,7 +5799,7 @@ pub(crate) fn stmt_preserves_array_length( fn is_static_buffer_receiver(ctx: &crate::expr::FnCtx<'_>, object: &perry_hir::Expr) -> bool { matches!( crate::type_analysis::static_type_of(ctx, object), - Some(perry_types::Type::Named(name)) if name == "Buffer" + Some(perry_hir::types::Type::Named(name)) if name == "Buffer" ) } diff --git a/crates/perry-codegen/src/stmt/masked_window_region.rs b/crates/perry-codegen/src/stmt/masked_window_region.rs index c9ac3e7bfd..fd2e5fb80c 100644 --- a/crates/perry-codegen/src/stmt/masked_window_region.rs +++ b/crates/perry-codegen/src/stmt/masked_window_region.rs @@ -161,7 +161,7 @@ fn expr_is_number_under( refined.contains(id) || matches!( ctx.local_types.get(id), - Some(perry_types::Type::Number | perry_types::Type::Int32) + Some(perry_hir::types::Type::Number | perry_hir::types::Type::Int32) ) } Expr::IndexGet { object, index } => { @@ -362,7 +362,7 @@ pub(super) fn try_match_masked_window_region( && !ctx.closure_captures.contains_key(&id) && !matches!( ctx.local_types.get(&id), - Some(perry_types::Type::Number | perry_types::Type::Int32) + Some(perry_hir::types::Type::Number | perry_hir::types::Type::Int32) ) }; for (offset, stmt) in stmts[..len].iter().enumerate() { @@ -430,7 +430,7 @@ fn lower_region_copy( .map(|refinement| refinement.local_id) .collect(); let mut privatized: Vec<(u32, String)> = Vec::new(); - let mut saved: Vec<(u32, Option)> = Vec::new(); + let mut saved: Vec<(u32, Option)> = Vec::new(); let mut saved_ids: std::collections::HashSet = std::collections::HashSet::new(); let mut result = Ok(()); 'stmts: for (offset, stmt) in region_stmts.iter().enumerate() { @@ -454,7 +454,7 @@ fn lower_region_copy( saved.push((id, ctx.local_types.get(&id).cloned())); } if set_number { - ctx.local_types.insert(id, perry_types::Type::Number); + ctx.local_types.insert(id, perry_hir::types::Type::Number); // The local now provably holds a number for the rest of the // copy (or until an unset): clear its shadow slot once and // suppress the per-statement shadow updates — numbers need diff --git a/crates/perry-codegen/src/stmt/unused_expr.rs b/crates/perry-codegen/src/stmt/unused_expr.rs index 971e0d7f68..f44fbbab1c 100644 --- a/crates/perry-codegen/src/stmt/unused_expr.rs +++ b/crates/perry-codegen/src/stmt/unused_expr.rs @@ -169,7 +169,7 @@ fn array_map_callback_is_discard_pure(callback: &perry_hir::Expr) -> bool { matches!(body.as_slice(), [perry_hir::Stmt::Return(Some(expr))] if discard_pure_expr(expr, param_id)) } -fn discard_pure_expr(expr: &perry_hir::Expr, param_id: perry_types::LocalId) -> bool { +fn discard_pure_expr(expr: &perry_hir::Expr, param_id: perry_hir::types::LocalId) -> bool { match expr { perry_hir::Expr::Undefined | perry_hir::Expr::Null diff --git a/crates/perry-codegen/src/type_analysis.rs b/crates/perry-codegen/src/type_analysis.rs index a2f009b57b..92e64badaa 100644 --- a/crates/perry-codegen/src/type_analysis.rs +++ b/crates/perry-codegen/src/type_analysis.rs @@ -10,9 +10,9 @@ pub(crate) use crate::type_analysis_facts::{ hir_inferred_static_type_from_locals, CodegenTypeFacts, }; #[cfg(test)] -use perry_hir::Expr; +use perry_hir::types::Type as HirType; #[cfg(test)] -use perry_types::Type as HirType; +use perry_hir::Expr; // Class-field layout / declared-type resolution lives in a sibling module // (file-size gate). Re-exported here so existing `type_analysis::*` call diff --git a/crates/perry-codegen/src/type_analysis/numeric.rs b/crates/perry-codegen/src/type_analysis/numeric.rs index 0f018e06c0..9febc50710 100644 --- a/crates/perry-codegen/src/type_analysis/numeric.rs +++ b/crates/perry-codegen/src/type_analysis/numeric.rs @@ -4,8 +4,8 @@ use super::*; +use perry_hir::types::Type as HirType; use perry_hir::{BinaryOp, Expr, UnaryOp}; -use perry_types::Type as HirType; use crate::expr::FnCtx; diff --git a/crates/perry-codegen/src/type_analysis/numeric/tests.rs b/crates/perry-codegen/src/type_analysis/numeric/tests.rs index 45296fa1da..8ff7e2f03c 100644 --- a/crates/perry-codegen/src/type_analysis/numeric/tests.rs +++ b/crates/perry-codegen/src/type_analysis/numeric/tests.rs @@ -6,10 +6,10 @@ //! BigInt-aware `js_dynamic_mul` routing from #5970. use crate::{compile_module, AppMetadata, CompileOptions}; +use perry_hir::types::Type; use perry_hir::{ BinaryOp, CompareOp, Expr, Function, Module, ModuleInitKind, Param, Stmt, UpdateOp, }; -use perry_types::Type; fn ir_opts() -> CompileOptions { CompileOptions { diff --git a/crates/perry-codegen/src/type_analysis/pod.rs b/crates/perry-codegen/src/type_analysis/pod.rs index b520f5f8e4..8337b84c0d 100644 --- a/crates/perry-codegen/src/type_analysis/pod.rs +++ b/crates/perry-codegen/src/type_analysis/pod.rs @@ -4,8 +4,8 @@ use super::*; +use perry_hir::types::Type as HirType; use perry_hir::Expr; -use perry_types::Type as HirType; use crate::expr::FnCtx; use crate::type_analysis_class_fields::{class_field_declared_type, declared_field_type}; diff --git a/crates/perry-codegen/src/type_analysis/predicates.rs b/crates/perry-codegen/src/type_analysis/predicates.rs index 2ef4fa9d47..8612d2c8b8 100644 --- a/crates/perry-codegen/src/type_analysis/predicates.rs +++ b/crates/perry-codegen/src/type_analysis/predicates.rs @@ -4,8 +4,8 @@ use super::*; +use perry_hir::types::Type as HirType; use perry_hir::Expr; -use perry_types::Type as HirType; use crate::expr::FnCtx; use crate::type_analysis_facts::{function_type_from_decl, hir_inferred_static_type}; @@ -539,7 +539,7 @@ pub(crate) fn static_type_of(ctx: &FnCtx<'_>, e: &Expr) -> Option { if let Some(method) = iface.methods.iter().find(|method| method.name == *property) { - return Some(HirType::Function(perry_types::FunctionType { + return Some(HirType::Function(perry_hir::types::FunctionType { params: method.params.clone(), return_type: Box::new(method.return_type.clone()), is_async: false, diff --git a/crates/perry-codegen/src/type_analysis/refine.rs b/crates/perry-codegen/src/type_analysis/refine.rs index b3bf247a40..7dc3a0a0ee 100644 --- a/crates/perry-codegen/src/type_analysis/refine.rs +++ b/crates/perry-codegen/src/type_analysis/refine.rs @@ -4,8 +4,8 @@ use super::*; +use perry_hir::types::Type as HirType; use perry_hir::{BinaryOp, Expr, UnaryOp}; -use perry_types::Type as HirType; use crate::expr::FnCtx; use crate::type_analysis_facts::hir_inferred_refinable_type; diff --git a/crates/perry-codegen/src/type_analysis/strings.rs b/crates/perry-codegen/src/type_analysis/strings.rs index dae13757b7..19d0b4a5b2 100644 --- a/crates/perry-codegen/src/type_analysis/strings.rs +++ b/crates/perry-codegen/src/type_analysis/strings.rs @@ -4,8 +4,8 @@ use super::*; +use perry_hir::types::Type as HirType; use perry_hir::{BinaryOp, Expr}; -use perry_types::Type as HirType; use crate::expr::FnCtx; use crate::type_analysis_class_fields::declared_field_type; diff --git a/crates/perry-codegen/src/type_analysis_class_fields.rs b/crates/perry-codegen/src/type_analysis_class_fields.rs index 8cbdf14bf2..9d3aaffee8 100644 --- a/crates/perry-codegen/src/type_analysis_class_fields.rs +++ b/crates/perry-codegen/src/type_analysis_class_fields.rs @@ -9,8 +9,8 @@ //! cycle — an unguarded walk would then CPU-hang or OOM. The walks bail on //! a repeated class name (and a depth cap) instead. +use perry_hir::types::Type as HirType; use perry_hir::Expr; -use perry_types::Type as HirType; use crate::expr::FnCtx; use crate::type_analysis::receiver_class_name; diff --git a/crates/perry-codegen/src/type_analysis_facts.rs b/crates/perry-codegen/src/type_analysis_facts.rs index 219bec9e4b..749a27044e 100644 --- a/crates/perry-codegen/src/type_analysis_facts.rs +++ b/crates/perry-codegen/src/type_analysis_facts.rs @@ -1,7 +1,7 @@ //! HIR-backed type facts for codegen type analysis. +use perry_hir::types::Type as HirType; use perry_hir::{infer_expr_type, infer_refinable_expr_type, Expr, HirTypeFacts}; -use perry_types::Type as HirType; use crate::expr::FnCtx; @@ -126,7 +126,7 @@ pub(crate) fn hir_inferred_static_type(ctx: &FnCtx<'_>, expr: &Expr) -> Option HirType { - HirType::Function(perry_types::FunctionType { + HirType::Function(perry_hir::types::FunctionType { params: function .params .iter() @@ -139,7 +139,7 @@ pub(crate) fn function_type_from_decl(function: &perry_hir::Function) -> HirType } fn interface_method_type(method: &perry_hir::InterfaceMethod) -> HirType { - HirType::Function(perry_types::FunctionType { + HirType::Function(perry_hir::types::FunctionType { params: method.params.clone(), return_type: Box::new(method.return_type.clone()), is_async: false, diff --git a/crates/perry-codegen/src/type_analysis_net.rs b/crates/perry-codegen/src/type_analysis_net.rs index 70833faf5d..847e57b12f 100644 --- a/crates/perry-codegen/src/type_analysis_net.rs +++ b/crates/perry-codegen/src/type_analysis_net.rs @@ -1,5 +1,5 @@ +use perry_hir::types::Type as HirType; use perry_hir::Expr; -use perry_types::Type as HirType; fn native_result_class(module: &str, method: &str) -> Option<&'static str> { if module.strip_prefix("node:").unwrap_or(module) != "net" { diff --git a/crates/perry-codegen/src/type_analysis_tests.rs b/crates/perry-codegen/src/type_analysis_tests.rs index 34ede2a938..4d18b6d635 100644 --- a/crates/perry-codegen/src/type_analysis_tests.rs +++ b/crates/perry-codegen/src/type_analysis_tests.rs @@ -363,7 +363,7 @@ fn hir_inferred_types_reuse_codegen_contextual_class_facts() { }, &facts, ), - HirType::Function(perry_types::FunctionType { + HirType::Function(perry_hir::types::FunctionType { params: Vec::new(), return_type: Box::new(HirType::Number), is_async: false, diff --git a/crates/perry-codegen/src/typed_shape.rs b/crates/perry-codegen/src/typed_shape.rs index af51ce6e4c..b38518fa4d 100644 --- a/crates/perry-codegen/src/typed_shape.rs +++ b/crates/perry-codegen/src/typed_shape.rs @@ -1,4 +1,4 @@ -use perry_types::Type; +use perry_hir::types::Type; pub(crate) fn type_is_pointer_bearing(ty: &Type) -> bool { match ty { diff --git a/crates/perry-codegen/tests/app_window_config_options.rs b/crates/perry-codegen/tests/app_window_config_options.rs index 520e54deb3..c8cd34171c 100644 --- a/crates/perry-codegen/tests/app_window_config_options.rs +++ b/crates/perry-codegen/tests/app_window_config_options.rs @@ -9,8 +9,8 @@ //! `perry_ui_app_set_*` FFI setter, and omitted keys must emit nothing. use perry_codegen::{compile_module, AppMetadata, CompileOptions}; +use perry_hir::types::Type; use perry_hir::{Expr, Function, Module, ModuleInitKind, Stmt}; -use perry_types::Type; fn empty_opts() -> CompileOptions { CompileOptions { diff --git a/crates/perry-codegen/tests/class_keys_gc_root.rs b/crates/perry-codegen/tests/class_keys_gc_root.rs index ce588b6972..0ed75d5505 100644 --- a/crates/perry-codegen/tests/class_keys_gc_root.rs +++ b/crates/perry-codegen/tests/class_keys_gc_root.rs @@ -23,8 +23,8 @@ //! `js_gc_register_global_root`. use perry_codegen::{compile_module, AppMetadata, CompileOptions}; +use perry_hir::types::Type; use perry_hir::{Class, ClassField, Module, ModuleInitKind}; -use perry_types::Type; fn entry_opts() -> CompileOptions { CompileOptions { diff --git a/crates/perry-codegen/tests/constructor_recursion.rs b/crates/perry-codegen/tests/constructor_recursion.rs index 815b32390a..eb372fffe1 100644 --- a/crates/perry-codegen/tests/constructor_recursion.rs +++ b/crates/perry-codegen/tests/constructor_recursion.rs @@ -1,6 +1,6 @@ use perry_codegen::{compile_module, AppMetadata, CompileOptions}; +use perry_hir::types::Type; use perry_hir::{Class, Expr, Function, Module, ModuleInitKind, Param, Stmt}; -use perry_types::Type; fn empty_opts() -> CompileOptions { CompileOptions { diff --git a/crates/perry-codegen/tests/i64_spec_ternary_recursion.rs b/crates/perry-codegen/tests/i64_spec_ternary_recursion.rs index 4626089591..a822814fc0 100644 --- a/crates/perry-codegen/tests/i64_spec_ternary_recursion.rs +++ b/crates/perry-codegen/tests/i64_spec_ternary_recursion.rs @@ -7,8 +7,8 @@ //! by the emitter's `as i64` lowering. use perry_codegen::{compile_module, AppMetadata, CompileOptions}; +use perry_hir::types::Type; use perry_hir::{BinaryOp, CompareOp, Expr, Function, Module, ModuleInitKind, Param, Stmt}; -use perry_types::Type; fn empty_opts() -> CompileOptions { CompileOptions { diff --git a/crates/perry-codegen/tests/large_object_barriers.rs b/crates/perry-codegen/tests/large_object_barriers.rs index 01ee01c103..ef342db57f 100644 --- a/crates/perry-codegen/tests/large_object_barriers.rs +++ b/crates/perry-codegen/tests/large_object_barriers.rs @@ -1,6 +1,6 @@ use perry_codegen::{compile_module, AppMetadata, CompileOptions}; +use perry_hir::types::Type; use perry_hir::{Expr, Function, Module, ModuleInitKind, Stmt}; -use perry_types::Type; fn empty_opts() -> CompileOptions { CompileOptions { diff --git a/crates/perry-codegen/tests/native_proof_buffer_views.rs b/crates/perry-codegen/tests/native_proof_buffer_views.rs index b19663998c..58463077c1 100644 --- a/crates/perry-codegen/tests/native_proof_buffer_views.rs +++ b/crates/perry-codegen/tests/native_proof_buffer_views.rs @@ -1,9 +1,9 @@ use perry_codegen::{compile_module, AppMetadata, CompileOptions}; +use perry_hir::types::{FunctionType, ObjectType, PropertyInfo, Type}; use perry_hir::{ BinaryOp, Class, ClassField, CompareOp, Expr, Function, Module, ModuleInitKind, Param, Stmt, UpdateOp, }; -use perry_types::{FunctionType, ObjectType, PropertyInfo, Type}; static ARTIFACT_ENV_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(()); diff --git a/crates/perry-codegen/tests/native_proof_regressions.rs b/crates/perry-codegen/tests/native_proof_regressions.rs index b90a08cc4f..3c7d75359d 100644 --- a/crates/perry-codegen/tests/native_proof_regressions.rs +++ b/crates/perry-codegen/tests/native_proof_regressions.rs @@ -1,10 +1,10 @@ use perry_codegen::{compile_module, AppMetadata, CompileOptions}; +use perry_hir::types::{ObjectType, PropertyInfo, Type, TypeParam}; use perry_hir::{ monomorphize_module, ArgumentsObjectMeta, BinaryOp, CallArg, Class, ClassComputedMember, ClassComputedMemberKind, ClassField, CompareOp, Expr, Function, LogicalOp, Module, ModuleInitKind, Param, Stmt, UnaryOp, UpdateOp, }; -use perry_types::{ObjectType, PropertyInfo, Type, TypeParam}; static ARTIFACT_ENV_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(()); @@ -8472,7 +8472,7 @@ fn typed_f64_closure_clone_module(case: &str) -> Module { Stmt::Let { id: 10, name: "adder".to_string(), - ty: Type::Function(perry_types::FunctionType { + ty: Type::Function(perry_hir::types::FunctionType { params: vec![ ("a".to_string(), Type::Number, false), ("b".to_string(), Type::Number, false), @@ -8527,7 +8527,7 @@ fn typed_i32_closure_clone_module(case: &str) -> Module { let mut prefix = Vec::new(); let mut captures = Vec::new(); let mut mutable_captures = Vec::new(); - let mut local_ty = Type::Function(perry_types::FunctionType { + let mut local_ty = Type::Function(perry_hir::types::FunctionType { params: vec![ ("a".to_string(), Type::Int32, false), ("b".to_string(), Type::Int32, false), @@ -8567,7 +8567,7 @@ fn typed_i32_closure_clone_module(case: &str) -> Module { } "number_param" => { params[0].ty = Type::Number; - local_ty = Type::Function(perry_types::FunctionType { + local_ty = Type::Function(perry_hir::types::FunctionType { params: vec![ ("a".to_string(), Type::Number, false), ("b".to_string(), Type::Int32, false), @@ -8579,7 +8579,7 @@ fn typed_i32_closure_clone_module(case: &str) -> Module { } "number_return" => { return_type = Type::Number; - local_ty = Type::Function(perry_types::FunctionType { + local_ty = Type::Function(perry_hir::types::FunctionType { params: vec![ ("a".to_string(), Type::Int32, false), ("b".to_string(), Type::Int32, false), @@ -8981,7 +8981,7 @@ fn typed_i1_closure_clone_module(case: &str) -> Module { let mut captures = Vec::new(); let mut mutable_captures = Vec::new(); let mut call_args = vec![Expr::Bool(true), Expr::Bool(false)]; - let mut local_ty = Type::Function(perry_types::FunctionType { + let mut local_ty = Type::Function(perry_hir::types::FunctionType { params: vec![ ("a".to_string(), Type::Boolean, false), ("b".to_string(), Type::Boolean, false), @@ -9008,7 +9008,7 @@ fn typed_i1_closure_clone_module(case: &str) -> Module { } "numeric_predicate" => { params = vec![param(31, "a", Type::Number), param(32, "b", Type::Number)]; - local_ty = Type::Function(perry_types::FunctionType { + local_ty = Type::Function(perry_hir::types::FunctionType { params: vec![ ("a".to_string(), Type::Number, false), ("b".to_string(), Type::Number, false), @@ -9119,7 +9119,7 @@ fn typed_string_closure_clone_module(case: &str) -> Module { let mut prefix = Vec::new(); let mut captures = Vec::new(); let mut mutable_captures = Vec::new(); - let mut local_ty = Type::Function(perry_types::FunctionType { + let mut local_ty = Type::Function(perry_hir::types::FunctionType { params: vec![("s".to_string(), Type::String, false)], return_type: Box::new(Type::String), is_async: false, diff --git a/crates/perry-codegen/tests/perry_builtin_name_collision.rs b/crates/perry-codegen/tests/perry_builtin_name_collision.rs index 0c0b84e23e..624517d880 100644 --- a/crates/perry-codegen/tests/perry_builtin_name_collision.rs +++ b/crates/perry-codegen/tests/perry_builtin_name_collision.rs @@ -16,8 +16,8 @@ //! and a genuine `perry/system` import must still reach the native one. use perry_codegen::{compile_module, AppMetadata, CompileOptions}; +use perry_hir::types::Type; use perry_hir::{Expr, Import, ImportSpecifier, Module, ModuleInitKind, ModuleKind, Stmt}; -use perry_types::Type; fn base_opts() -> CompileOptions { CompileOptions { diff --git a/crates/perry-codegen/tests/private_guard_declaring_class.rs b/crates/perry-codegen/tests/private_guard_declaring_class.rs index beebe49184..f232523a06 100644 --- a/crates/perry-codegen/tests/private_guard_declaring_class.rs +++ b/crates/perry-codegen/tests/private_guard_declaring_class.rs @@ -19,8 +19,8 @@ //! `class_ids[name]`. use perry_codegen::{compile_module, CompileOptions}; +use perry_hir::types::Type; use perry_hir::{Class, Expr, Function, Module, ModuleInitKind, Stmt}; -use perry_types::Type; fn ir_opts() -> CompileOptions { CompileOptions { diff --git a/crates/perry-codegen/tests/shadow_slot_hygiene.rs b/crates/perry-codegen/tests/shadow_slot_hygiene.rs index 0602a8082b..10b66d9159 100644 --- a/crates/perry-codegen/tests/shadow_slot_hygiene.rs +++ b/crates/perry-codegen/tests/shadow_slot_hygiene.rs @@ -1,6 +1,6 @@ use perry_codegen::{compile_module, AppMetadata, CompileOptions}; +use perry_hir::types::Type; use perry_hir::{Expr, Function, Module, ModuleInitKind, Stmt}; -use perry_types::Type; fn empty_opts() -> CompileOptions { CompileOptions { diff --git a/crates/perry-codegen/tests/static_symbol_hygiene.rs b/crates/perry-codegen/tests/static_symbol_hygiene.rs index 44b9c3dc9c..3c93cfd121 100644 --- a/crates/perry-codegen/tests/static_symbol_hygiene.rs +++ b/crates/perry-codegen/tests/static_symbol_hygiene.rs @@ -1,6 +1,6 @@ use perry_codegen::{compile_module, AppMetadata, CompileOptions}; +use perry_hir::types::Type; use perry_hir::{Class, Expr, Function, Module, ModuleInitKind, Stmt}; -use perry_types::Type; fn empty_opts() -> CompileOptions { CompileOptions { diff --git a/crates/perry-codegen/tests/typed_feedback.rs b/crates/perry-codegen/tests/typed_feedback.rs index c5a9241834..a0587c317a 100644 --- a/crates/perry-codegen/tests/typed_feedback.rs +++ b/crates/perry-codegen/tests/typed_feedback.rs @@ -1,6 +1,6 @@ use perry_codegen::{compile_module, AppMetadata, CompileOptions}; +use perry_hir::types::{FunctionType, Type}; use perry_hir::{BinaryOp, Class, ClassField, Expr, Function, Module, ModuleInitKind, Param, Stmt}; -use perry_types::{FunctionType, Type}; /// Serializes env-mutating tests so a concurrent test never observes a /// half-applied variable. Mirrors the guard in `typed_shape_descriptors.rs`. diff --git a/crates/perry-codegen/tests/typed_shape_descriptor.rs b/crates/perry-codegen/tests/typed_shape_descriptor.rs index 6f2d1cb824..d0902cbac5 100644 --- a/crates/perry-codegen/tests/typed_shape_descriptor.rs +++ b/crates/perry-codegen/tests/typed_shape_descriptor.rs @@ -1,6 +1,6 @@ use perry_codegen::{compile_module, AppMetadata, CompileOptions}; +use perry_hir::types::{ObjectType, Type}; use perry_hir::{Class, ClassField, Expr, Function, Module, ModuleInitKind, Stmt}; -use perry_types::{ObjectType, Type}; fn empty_opts() -> CompileOptions { CompileOptions { diff --git a/crates/perry-codegen/tests/typed_shape_descriptors.rs b/crates/perry-codegen/tests/typed_shape_descriptors.rs index ea07e4f7ee..d154d5317c 100644 --- a/crates/perry-codegen/tests/typed_shape_descriptors.rs +++ b/crates/perry-codegen/tests/typed_shape_descriptors.rs @@ -1,9 +1,9 @@ use perry_codegen::{compile_module, AppMetadata, CompileOptions}; +use perry_hir::types::{ObjectType, PropertyInfo, Type}; use perry_hir::{ ArrayElement, BinaryOp, CompareOp, Expr, Function, Interface, InterfaceProperty, Module, ModuleInitKind, Stmt, UpdateOp, }; -use perry_types::{ObjectType, PropertyInfo, Type}; static ENV_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(()); diff --git a/crates/perry-ext-http/Cargo.toml b/crates/perry-ext-http/Cargo.toml index a96ccd844e..a3fee1e391 100644 --- a/crates/perry-ext-http/Cargo.toml +++ b/crates/perry-ext-http/Cargo.toml @@ -18,7 +18,7 @@ perry-ffi.workspace = true # `js_node_http2_*` symbols flow through into libperry_ext_http.a so a # single staticlib registration in well_known_bindings.toml covers # both client and server. The crate split keeps the source layered. -perry-ext-http-server = { path = "../perry-ext-http-server" } +perry-ext-http-server.workspace = true # #2154: Agent argument validation throws `RangeError [ERR_OUT_OF_RANGE]` # via `js_throw` + `register_error_code_pub`, which are perry-runtime's # Rust-ABI helpers (not perry-ffi's). Stays consistent with perry-stdlib's diff --git a/crates/perry-hir/Cargo.toml b/crates/perry-hir/Cargo.toml index b4735e509a..84ecb4ef55 100644 --- a/crates/perry-hir/Cargo.toml +++ b/crates/perry-hir/Cargo.toml @@ -9,7 +9,6 @@ description = "High-level intermediate representation for Perry" workspace = true [dependencies] -perry-types.workspace = true perry-diagnostics.workspace = true perry-api-manifest.workspace = true perry-ui-model.workspace = true diff --git a/crates/perry-hir/examples/stable_hash_cross_process.rs b/crates/perry-hir/examples/stable_hash_cross_process.rs index 33c8c0f9d8..16c6877a13 100644 --- a/crates/perry-hir/examples/stable_hash_cross_process.rs +++ b/crates/perry-hir/examples/stable_hash_cross_process.rs @@ -13,7 +13,7 @@ use perry_hir::ir::*; use perry_hir::stable_hash::hash_module; -use perry_types::{ObjectType, PropertyInfo, Type}; +use perry_hir::types::{ObjectType, PropertyInfo, Type}; use std::collections::HashMap; fn build_canonical() -> Module { diff --git a/crates/perry-hir/src/analysis.rs b/crates/perry-hir/src/analysis.rs index c2d11bfeec..d0077d6bd3 100644 --- a/crates/perry-hir/src/analysis.rs +++ b/crates/perry-hir/src/analysis.rs @@ -3,7 +3,7 @@ //! Contains functions for collecting local references, tracking assigned locals, //! checking `this` usage, and identifying builtin functions. -use perry_types::LocalId; +use crate::types::LocalId; use crate::ir::*; use crate::walker::{walk_expr_children, walk_expr_children_mut}; diff --git a/crates/perry-hir/src/analysis/value_types.rs b/crates/perry-hir/src/analysis/value_types.rs index c7adfd652a..1112cfb037 100644 --- a/crates/perry-hir/src/analysis/value_types.rs +++ b/crates/perry-hir/src/analysis/value_types.rs @@ -9,7 +9,7 @@ use std::collections::{HashMap, HashSet}; use std::hash::BuildHasher; -use perry_types::{FuncId, GlobalId, LocalId, ObjectType, PropertyInfo, Type}; +use crate::types::{FuncId, GlobalId, LocalId, ObjectType, PropertyInfo, Type}; use crate::ir::*; use crate::walker::walk_expr_children; @@ -655,7 +655,7 @@ pub fn infer_expr_type(expr: &Expr, env: &F) -> Type { .extern_function_return_type(name) .filter(|ty| !matches!(ty, Type::Any | Type::Unknown)) .unwrap_or(return_type); - Type::Function(perry_types::FunctionType { + Type::Function(crate::types::FunctionType { params: param_types .iter() .enumerate() @@ -672,7 +672,7 @@ pub fn infer_expr_type(expr: &Expr, env: &F) -> Type { is_async, is_generator, .. - } => Type::Function(perry_types::FunctionType { + } => Type::Function(crate::types::FunctionType { params: params .iter() .map(|param| (param.name.clone(), param.ty.clone(), false)) @@ -1393,7 +1393,7 @@ pub fn infer_refinable_expr_type(expr: &Expr, env: &F) } fn function_type_for_return(return_type: Option<&Type>) -> Type { - Type::Function(perry_types::FunctionType { + Type::Function(crate::types::FunctionType { params: Vec::new(), return_type: Box::new(return_type.cloned().unwrap_or(Type::Any)), is_async: false, @@ -1402,7 +1402,7 @@ fn function_type_for_return(return_type: Option<&Type>) -> Type { } fn function_type_from_decl(function: &Function) -> Type { - Type::Function(perry_types::FunctionType { + Type::Function(crate::types::FunctionType { params: function .params .iter() @@ -1415,7 +1415,7 @@ fn function_type_from_decl(function: &Function) -> Type { } fn interface_method_type(method: &InterfaceMethod) -> Type { - Type::Function(perry_types::FunctionType { + Type::Function(crate::types::FunctionType { params: method.params.clone(), return_type: Box::new(method.return_type.clone()), is_async: false, diff --git a/crates/perry-hir/src/analysis/value_types_tests.rs b/crates/perry-hir/src/analysis/value_types_tests.rs index 878285844f..e12ac78bce 100644 --- a/crates/perry-hir/src/analysis/value_types_tests.rs +++ b/crates/perry-hir/src/analysis/value_types_tests.rs @@ -6,7 +6,7 @@ fn empty_env() -> HirTypeEnv { } fn function_type(return_type: Type) -> Type { - Type::Function(perry_types::FunctionType { + Type::Function(crate::types::FunctionType { params: Vec::new(), return_type: Box::new(return_type), is_async: false, diff --git a/crates/perry-hir/src/destructuring/mod.rs b/crates/perry-hir/src/destructuring/mod.rs index 108acc33c1..6ea392825e 100644 --- a/crates/perry-hir/src/destructuring/mod.rs +++ b/crates/perry-hir/src/destructuring/mod.rs @@ -14,8 +14,8 @@ //! - [`var_decl`] — full variable-declaration lowering, including the //! destructuring case. +use crate::types::{LocalId, Type}; use anyhow::{anyhow, Result}; -use perry_types::{LocalId, Type}; use swc_ecma_ast as ast; use crate::ir::*; diff --git a/crates/perry-hir/src/destructuring/var_decl/alias_tracking.rs b/crates/perry-hir/src/destructuring/var_decl/alias_tracking.rs index f11d9fd7f7..575122ec55 100644 --- a/crates/perry-hir/src/destructuring/var_decl/alias_tracking.rs +++ b/crates/perry-hir/src/destructuring/var_decl/alias_tracking.rs @@ -3,7 +3,7 @@ use super::*; -use perry_types::LocalId; +use crate::types::LocalId; use swc_ecma_ast as ast; use crate::lower::LoweringContext; diff --git a/crates/perry-hir/src/destructuring/var_decl/native_fetch.rs b/crates/perry-hir/src/destructuring/var_decl/native_fetch.rs index 78797e2850..a80ab80e7e 100644 --- a/crates/perry-hir/src/destructuring/var_decl/native_fetch.rs +++ b/crates/perry-hir/src/destructuring/var_decl/native_fetch.rs @@ -4,7 +4,7 @@ use super::*; -use perry_types::Type; +use crate::types::Type; use swc_ecma_ast as ast; use crate::lower::LoweringContext; diff --git a/crates/perry-hir/src/destructuring/var_decl/type_infer.rs b/crates/perry-hir/src/destructuring/var_decl/type_infer.rs index 9397a8ead3..1f7e2dbd34 100644 --- a/crates/perry-hir/src/destructuring/var_decl/type_infer.rs +++ b/crates/perry-hir/src/destructuring/var_decl/type_infer.rs @@ -2,7 +2,7 @@ //! `let/const/var` identifier binding (extracted from `var_decl.rs`'s //! `Pat::Ident` arm). -use perry_types::Type; +use crate::types::Type; use swc_ecma_ast as ast; use crate::lower::LoweringContext; diff --git a/crates/perry-hir/src/dynamic_import.rs b/crates/perry-hir/src/dynamic_import.rs index ce08acf102..e450fff0c3 100644 --- a/crates/perry-hir/src/dynamic_import.rs +++ b/crates/perry-hir/src/dynamic_import.rs @@ -18,8 +18,8 @@ //! Here we only fold the JS-level path *string*. use crate::ir::{BinaryOp, Export, Expr, Function, Module, Param, Stmt}; +use crate::types::Type; use crate::walker::walk_expr_children; -use perry_types::Type; use std::borrow::Borrow; use std::collections::{HashMap, HashSet}; diff --git a/crates/perry-hir/src/dynamic_import/tests.rs b/crates/perry-hir/src/dynamic_import/tests.rs index d0fc837840..604df46647 100644 --- a/crates/perry-hir/src/dynamic_import/tests.rs +++ b/crates/perry-hir/src/dynamic_import/tests.rs @@ -1,6 +1,6 @@ use super::*; use crate::ir::Module; -use perry_types::Type; +use crate::types::Type; #[test] fn resolve_string_literal() { @@ -495,14 +495,14 @@ fn collect_consts_skips_mutated() { m.init.push(Stmt::Let { id: 1, name: "stable".into(), - ty: perry_types::Type::String, + ty: crate::types::Type::String, mutable: false, init: Some(Expr::String("./a.ts".into())), }); m.init.push(Stmt::Let { id: 2, name: "mutated".into(), - ty: perry_types::Type::String, + ty: crate::types::Type::String, mutable: false, init: Some(Expr::String("./b.ts".into())), }); @@ -523,14 +523,14 @@ fn collect_includes_unreassigned_let_but_drops_reassigned() { m.init.push(Stmt::Let { id: 1, name: "stableLet".into(), - ty: perry_types::Type::String, + ty: crate::types::Type::String, mutable: true, init: Some(Expr::String("./a.ts".into())), }); m.init.push(Stmt::Let { id: 2, name: "reassignedLet".into(), - ty: perry_types::Type::String, + ty: crate::types::Type::String, mutable: true, init: Some(Expr::String("./b.ts".into())), }); @@ -550,7 +550,7 @@ fn resolve_unreassigned_let_ternary_union() { m.init.push(Stmt::Let { id: 5, name: "p".into(), - ty: perry_types::Type::String, + ty: crate::types::Type::String, mutable: true, init: Some(Expr::Conditional { condition: Box::new(Expr::Bool(true)), diff --git a/crates/perry-hir/src/ir/decl.rs b/crates/perry-hir/src/ir/decl.rs index 2dc95c4d22..7cf559c3f9 100644 --- a/crates/perry-hir/src/ir/decl.rs +++ b/crates/perry-hir/src/ir/decl.rs @@ -3,7 +3,7 @@ //! `super`. use super::*; -use perry_types::{FuncId, GlobalId, LocalId, Type, TypeParam}; +use crate::types::{FuncId, GlobalId, LocalId, Type, TypeParam}; /// An enum definition #[derive(Debug, Clone)] diff --git a/crates/perry-hir/src/ir/expr.rs b/crates/perry-hir/src/ir/expr.rs index 53962b9781..894cf18b01 100644 --- a/crates/perry-hir/src/ir/expr.rs +++ b/crates/perry-hir/src/ir/expr.rs @@ -3,7 +3,7 @@ //! mod.rs stays scannable. Re-exported from `super`. use super::*; -use perry_types::{FuncId, GlobalId, LocalId, Type}; +use crate::types::{FuncId, GlobalId, LocalId, Type}; /// Fallback when a dynamic `with` object environment does not bind the /// assignment target. The object lookup is performed before the RHS is diff --git a/crates/perry-hir/src/ir/module.rs b/crates/perry-hir/src/ir/module.rs index 8e0f115041..da1896ecf0 100644 --- a/crates/perry-hir/src/ir/module.rs +++ b/crates/perry-hir/src/ir/module.rs @@ -1,7 +1,7 @@ //! `Module` HIR struct + constructor. Re-exported from `super`. use super::*; -use perry_types::{FuncId, Type}; +use crate::types::{FuncId, Type}; /// A complete HIR module (corresponds to one TypeScript file) #[derive(Debug, Clone)] @@ -105,7 +105,7 @@ pub struct Module { /// to decide whether the closure body is already a state machine /// returning a Promise (no busy-wait pump needed). Populated by the /// transform pass; consumed by codegen. - pub async_step_closures: std::collections::HashSet, + pub async_step_closures: std::collections::HashSet, /// Issue #2076: display name overrides for `fn.name`/`console.log`. /// Populated at lowering for two cases the binding-name registration /// path can't see: @@ -113,7 +113,7 @@ pub struct Module { /// • object-literal shorthand/method properties (`{m(){}}` → `"m"`) /// Keyed by the closure/function's HIR FuncId; consumed by codegen /// when emitting `js_register_function_name` calls. - pub closure_display_names: std::collections::HashMap, + pub closure_display_names: std::collections::HashMap, /// #5592: user-visible `.name` overrides for classes whose HIR /// registration key differs from their JS name. The only producer /// today is a second anonymous class expression assigned to a binding @@ -129,7 +129,7 @@ pub struct Module { /// by codegen to emit `js_register_function_source` so `fn.toString()` /// (and `Function.prototype.toString.call(fn)`) reconstruct the source /// instead of returning the generic `"[object Object]"`. - pub closure_source_text: std::collections::HashMap, + pub closure_source_text: std::collections::HashMap, /// #3664: func_ids of `async function*` declarations and `async function*(){}` /// expressions. The generator transform clears `is_async`/`is_generator` /// before codegen, erasing the async-vs-sync distinction (both lower to a @@ -137,7 +137,7 @@ pub struct Module { /// register async-generator closures in the runtime's dedicated async- /// generator registry, which drives `%AsyncGeneratorFunction%` / `%Async /// Generator%` intrinsic resolution. Populated by `transform_generators`. - pub async_generator_funcs: std::collections::HashSet, + pub async_generator_funcs: std::collections::HashSet, /// Number of leading parameter-prologue statements (default-param guards + /// destructuring binding stmts) in each generator / async-generator /// function body, keyed by func_id. Per spec, generator parameter binding @@ -149,7 +149,7 @@ pub struct Module { /// outer wrapper (run-at-call) instead of state 0 of `.next()`. Absent / /// zero means no prologue (the common case — fully inert). Populated by /// lowering (`lower_fn_decl` / `lower_fn_expr`). - pub gen_param_prologue_len: std::collections::HashMap, + pub gen_param_prologue_len: std::collections::HashMap, } impl Module { diff --git a/crates/perry-hir/src/ir/stmt.rs b/crates/perry-hir/src/ir/stmt.rs index 847f2a4c54..04cecec5a9 100644 --- a/crates/perry-hir/src/ir/stmt.rs +++ b/crates/perry-hir/src/ir/stmt.rs @@ -2,7 +2,7 @@ //! `super`. use super::*; -use perry_types::{LocalId, Type}; +use crate::types::{LocalId, Type}; /// Statement in function body #[derive(Debug, Clone)] diff --git a/crates/perry-hir/src/js_transform/cross_module_natives.rs b/crates/perry-hir/src/js_transform/cross_module_natives.rs index c2ce6aca8e..e215b51efd 100644 --- a/crates/perry-hir/src/js_transform/cross_module_natives.rs +++ b/crates/perry-hir/src/js_transform/cross_module_natives.rs @@ -72,7 +72,7 @@ pub fn fix_cross_module_native_instances( // Scan for variables assigned from calls to native-returning functions // Maps LocalId -> (module_name, class_name) - let mut local_id_native_instances: HashMap = + let mut local_id_native_instances: HashMap = HashMap::new(); if !func_return_instances.is_empty() { @@ -240,7 +240,7 @@ pub fn scan_for_native_func_returns( stmt: &Stmt, func_return_instances: &HashMap, local_native_instances: &mut HashMap, - local_id_native_instances: &mut HashMap, + local_id_native_instances: &mut HashMap, ) { match stmt { Stmt::Let { id, name, init, .. } => { @@ -400,7 +400,7 @@ pub fn scan_for_native_func_returns( pub fn scan_for_ident_init_propagation( stmt: &Stmt, local_native_instances: &mut HashMap, - local_id_native_instances: &mut HashMap, + local_id_native_instances: &mut HashMap, ) -> bool { let mut changed = false; match stmt { @@ -523,7 +523,7 @@ pub fn scan_for_ident_init_propagation( pub fn lookup_native_from_init_ident( expr: &Expr, _local_native_instances: &HashMap, - local_id_native_instances: &HashMap, + local_id_native_instances: &HashMap, ) -> Option<(String, String)> { if let Expr::LocalGet(id) = expr { return local_id_native_instances.get(id).cloned(); @@ -538,7 +538,7 @@ pub fn scan_expr_for_closure_returns( expr: &Expr, func_return_instances: &HashMap, local_native_instances: &mut HashMap, - local_id_native_instances: &mut HashMap, + local_id_native_instances: &mut HashMap, ) { match expr { Expr::Closure { body, .. } => { @@ -655,7 +655,7 @@ pub fn scan_expr_for_closure_returns( pub fn fix_native_instance_stmt( stmt: &mut Stmt, native_instances: &HashMap, - local_id_instances: &HashMap, + local_id_instances: &HashMap, ) { match stmt { Stmt::Expr(expr) => fix_native_instance_expr(expr, native_instances, local_id_instances), @@ -758,7 +758,7 @@ pub fn fix_native_instance_stmt( pub fn resolve_native_instance<'a>( object: &Expr, native_instances: &'a HashMap, - local_id_instances: &'a HashMap, + local_id_instances: &'a HashMap, ) -> Option<(&'a String, &'a String)> { match object { Expr::ExternFuncRef { name, .. } => native_instances.get(name).map(|(m, c)| (m, c)), @@ -770,7 +770,7 @@ pub fn resolve_native_instance<'a>( pub fn fix_native_instance_expr( expr: &mut Expr, native_instances: &HashMap, - local_id_instances: &HashMap, + local_id_instances: &HashMap, ) { match expr { // The key case: method calls that might be on native instances diff --git a/crates/perry-hir/src/js_transform/imports.rs b/crates/perry-hir/src/js_transform/imports.rs index a070e98b30..ff92d49bd3 100644 --- a/crates/perry-hir/src/js_transform/imports.rs +++ b/crates/perry-hir/src/js_transform/imports.rs @@ -1,5 +1,5 @@ use crate::ir::{Expr, Module, ModuleKind, Stmt}; -use perry_types::LocalId; +use crate::types::LocalId; use std::collections::{HashMap, HashSet}; /// Information about a JavaScript module import diff --git a/crates/perry-hir/src/js_transform/local_natives.rs b/crates/perry-hir/src/js_transform/local_natives.rs index b0176b3965..0047a31149 100644 --- a/crates/perry-hir/src/js_transform/local_natives.rs +++ b/crates/perry-hir/src/js_transform/local_natives.rs @@ -1,5 +1,5 @@ use crate::ir::{Expr, Module, Stmt}; -use perry_types::LocalId; +use crate::types::LocalId; use std::collections::HashMap; /// Fix local native instance method calls within the same module diff --git a/crates/perry-hir/src/jsx.rs b/crates/perry-hir/src/jsx.rs index e64e96b49d..1f496749af 100644 --- a/crates/perry-hir/src/jsx.rs +++ b/crates/perry-hir/src/jsx.rs @@ -3,8 +3,8 @@ //! Contains functions for lowering JSX elements, fragments, attributes, //! and children into HIR expressions. +use crate::types::Type; use anyhow::Result; -use perry_types::Type; use swc_ecma_ast as ast; use crate::ir::*; diff --git a/crates/perry-hir/src/lib.rs b/crates/perry-hir/src/lib.rs index a3c23c9946..df90315ec6 100644 --- a/crates/perry-hir/src/lib.rs +++ b/crates/perry-hir/src/lib.rs @@ -25,6 +25,7 @@ pub(crate) mod lower_patterns; pub(crate) mod lower_types; pub mod monomorph; pub mod stable_hash; +pub mod types; pub mod walker; pub use analysis::{ diff --git a/crates/perry-hir/src/lower/closure_analysis.rs b/crates/perry-hir/src/lower/closure_analysis.rs index 0d57a842ea..8528fd21a5 100644 --- a/crates/perry-hir/src/lower/closure_analysis.rs +++ b/crates/perry-hir/src/lower/closure_analysis.rs @@ -4,7 +4,7 @@ //! visibility and are re-exported from `lower/mod.rs` so the existing //! `expr_*` submodules and the rest of the crate keep compiling unchanged. -use perry_types::LocalId; +use crate::types::LocalId; use crate::ir::*; diff --git a/crates/perry-hir/src/lower/const_fold_fn.rs b/crates/perry-hir/src/lower/const_fold_fn.rs index 0d491e1fc0..516f18d633 100644 --- a/crates/perry-hir/src/lower/const_fold_fn.rs +++ b/crates/perry-hir/src/lower/const_fold_fn.rs @@ -1185,7 +1185,7 @@ fn try_direct_eval_simple_assignment_fold(ctx: &mut LoweringContext, body: &str) } return Some(Expr::Undefined); } - let id = ctx.define_local(name, perry_types::Type::Any); + let id = ctx.define_local(name, crate::types::Type::Any); ctx.var_hoisted_ids.insert(id); return Some(Expr::Undefined); } @@ -1231,7 +1231,7 @@ fn try_direct_eval_simple_assignment_fold(ctx: &mut LoweringContext, body: &str) "eval assignment to undeclared identifier `{name}`" ))) } else { - let id = ctx.define_local(name.to_string(), perry_types::Type::Any); + let id = ctx.define_local(name.to_string(), crate::types::Type::Any); ctx.var_hoisted_ids.insert(id); Some(finish(Expr::LocalSet(id, Box::new(value)))) } diff --git a/crates/perry-hir/src/lower/context.rs b/crates/perry-hir/src/lower/context.rs index 7bc01cf66e..db28174b38 100644 --- a/crates/perry-hir/src/lower/context.rs +++ b/crates/perry-hir/src/lower/context.rs @@ -4,7 +4,7 @@ //! visibility and are re-exported from `lower/mod.rs` so the existing //! `expr_*` submodules and the rest of the crate keep compiling unchanged. -use perry_types::{FuncId, LocalId, Type, TypeParam}; +use crate::types::{FuncId, LocalId, Type, TypeParam}; use std::collections::{HashMap, HashSet}; use super::*; @@ -214,7 +214,7 @@ impl LoweringContext { // Constraint table mirrors the same scope so `is_type_param(name)` // and `resolve_type_param_constraint(name)` agree on visibility. // Only params with a declared upper bound contribute an entry. - let constraints: HashMap = type_params + let constraints: HashMap = type_params .iter() .filter_map(|p| { p.constraint @@ -248,7 +248,7 @@ impl LoweringContext { /// the chance to substitute a concrete type). /// /// Innermost scope wins (shadowing). - pub(crate) fn resolve_type_param_constraint(&self, name: &str) -> Option { + pub(crate) fn resolve_type_param_constraint(&self, name: &str) -> Option { for scope in self.type_param_constraints.iter().rev() { if let Some(ty) = scope.get(name) { // Only return constraints whose runtime shape is @@ -261,11 +261,11 @@ impl LoweringContext { // instance tagging / class-id propagation still work. let useful = matches!( ty, - perry_types::Type::String - | perry_types::Type::Number - | perry_types::Type::Boolean - | perry_types::Type::BigInt - | perry_types::Type::Array(_) + crate::types::Type::String + | crate::types::Type::Number + | crate::types::Type::Boolean + | crate::types::Type::BigInt + | crate::types::Type::Array(_) ); if useful { return Some(ty.clone()); @@ -281,7 +281,7 @@ impl LoweringContext { /// This is used during type extraction to resolve type aliases like /// `type BlockTag = 'latest' | number | string` so the compiler sees /// the underlying Union type instead of Named("BlockTag"). - pub(crate) fn resolve_type_alias(&self, name: &str) -> Option { + pub(crate) fn resolve_type_alias(&self, name: &str) -> Option { self.type_aliases .iter() .find(|(alias_name, _, type_params, _)| alias_name == name && type_params.is_empty()) diff --git a/crates/perry-hir/src/lower/decorators.rs b/crates/perry-hir/src/lower/decorators.rs index 25e0b2b656..37dc8532da 100644 --- a/crates/perry-hir/src/lower/decorators.rs +++ b/crates/perry-hir/src/lower/decorators.rs @@ -4,7 +4,7 @@ //! visibility and are re-exported from `lower/mod.rs` so the existing //! `expr_*` submodules and the rest of the crate keep compiling unchanged. -use perry_types::{FunctionType, Type}; +use crate::types::{FunctionType, Type}; use super::*; use crate::ir::*; diff --git a/crates/perry-hir/src/lower/eval_super_scan.rs b/crates/perry-hir/src/lower/eval_super_scan.rs index a985038771..5a520f561d 100644 --- a/crates/perry-hir/src/lower/eval_super_scan.rs +++ b/crates/perry-hir/src/lower/eval_super_scan.rs @@ -27,7 +27,7 @@ use std::collections::HashSet; -use perry_types::Type; +use crate::types::Type; use swc_ecma_ast as ast; use super::LoweringContext; diff --git a/crates/perry-hir/src/lower/expr_assign.rs b/crates/perry-hir/src/lower/expr_assign.rs index 61af0ac845..1b2b99a266 100644 --- a/crates/perry-hir/src/lower/expr_assign.rs +++ b/crates/perry-hir/src/lower/expr_assign.rs @@ -6,8 +6,8 @@ //! `[a, b] = arr` and `{a, b} = obj` (these last two desugar to a //! sequence expression of individual assignments). +use crate::types::{LocalId, Type}; use anyhow::{anyhow, Result}; -use perry_types::{LocalId, Type}; use swc_ecma_ast as ast; use crate::destructuring::lower_destructuring_assignment; @@ -590,8 +590,8 @@ fn lower_assignment_target( return Ok(Expr::Call { callee: Box::new(Expr::ExternFuncRef { name: "js_process_exit_code_set".to_string(), - param_types: vec![perry_types::Type::Number], - return_type: perry_types::Type::Number, + param_types: vec![crate::types::Type::Number], + return_type: crate::types::Type::Number, }), args: vec![*value], type_args: vec![], diff --git a/crates/perry-hir/src/lower/expr_call/array_only_methods.rs b/crates/perry-hir/src/lower/expr_call/array_only_methods.rs index a5928c3a2d..7b38ebc330 100644 --- a/crates/perry-hir/src/lower/expr_call/array_only_methods.rs +++ b/crates/perry-hir/src/lower/expr_call/array_only_methods.rs @@ -2,8 +2,8 @@ //! //! Extracted from `expr_call/mod.rs` as a mechanical move. +use crate::types::Type; use anyhow::Result; -use perry_types::Type; use swc_ecma_ast as ast; use crate::ir::*; diff --git a/crates/perry-hir/src/lower/expr_call/imported_array_methods.rs b/crates/perry-hir/src/lower/expr_call/imported_array_methods.rs index e334616cf7..7fab8f489c 100644 --- a/crates/perry-hir/src/lower/expr_call/imported_array_methods.rs +++ b/crates/perry-hir/src/lower/expr_call/imported_array_methods.rs @@ -2,8 +2,8 @@ //! //! Extracted from `expr_call/mod.rs` as a mechanical move. +use crate::types::Type; use anyhow::Result; -use perry_types::Type; use swc_ecma_ast as ast; use crate::ir::*; diff --git a/crates/perry-hir/src/lower/expr_call/intrinsics/apply_call.rs b/crates/perry-hir/src/lower/expr_call/intrinsics/apply_call.rs index 70599e17f7..9ab40b4bd3 100644 --- a/crates/perry-hir/src/lower/expr_call/intrinsics/apply_call.rs +++ b/crates/perry-hir/src/lower/expr_call/intrinsics/apply_call.rs @@ -1,7 +1,7 @@ use super::*; +use crate::types::Type; use anyhow::Result; -use perry_types::Type; use swc_ecma_ast as ast; use super::super::super::{lower_expr, LoweringContext}; diff --git a/crates/perry-hir/src/lower/expr_call/intrinsics/eval_strict.rs b/crates/perry-hir/src/lower/expr_call/intrinsics/eval_strict.rs index 0752e11138..01838eba97 100644 --- a/crates/perry-hir/src/lower/expr_call/intrinsics/eval_strict.rs +++ b/crates/perry-hir/src/lower/expr_call/intrinsics/eval_strict.rs @@ -1,7 +1,7 @@ use super::*; +use crate::types::Type; use anyhow::Result; -use perry_types::Type; use swc_ecma_ast as ast; use super::super::super::LoweringContext; diff --git a/crates/perry-hir/src/lower/expr_call/intrinsics/native_arena.rs b/crates/perry-hir/src/lower/expr_call/intrinsics/native_arena.rs index 1c79cf0dc4..5be149de1c 100644 --- a/crates/perry-hir/src/lower/expr_call/intrinsics/native_arena.rs +++ b/crates/perry-hir/src/lower/expr_call/intrinsics/native_arena.rs @@ -1,7 +1,7 @@ use super::*; +use crate::types::Type; use anyhow::Result; -use perry_types::Type; use swc_ecma_ast as ast; use crate::lower_types::extract_ts_type_with_ctx; @@ -247,8 +247,8 @@ fn is_native_arena_alloc_call(ctx: &LoweringContext, call: &ast::CallExpr) -> bo && !native_arena_global_is_shadowed(ctx) } -fn native_arena_owner_type(ty: &perry_types::Type) -> bool { - matches!(ty, perry_types::Type::Named(name) if name == "NativeArena" || name == "NativeArenaOwner") +fn native_arena_owner_type(ty: &crate::types::Type) -> bool { + matches!(ty, crate::types::Type::Named(name) if name == "NativeArena" || name == "NativeArenaOwner") } fn is_native_arena_owner_expr(ctx: &LoweringContext, expr: &ast::Expr) -> bool { diff --git a/crates/perry-hir/src/lower/expr_call/local_array_methods.rs b/crates/perry-hir/src/lower/expr_call/local_array_methods.rs index cb415cc191..4b9e22097b 100644 --- a/crates/perry-hir/src/lower/expr_call/local_array_methods.rs +++ b/crates/perry-hir/src/lower/expr_call/local_array_methods.rs @@ -2,8 +2,8 @@ //! //! Extracted from `expr_call/mod.rs` as a mechanical move. +use crate::types::Type; use anyhow::Result; -use perry_types::Type; use swc_ecma_ast as ast; use super::url_search_params::build_url_search_params_method_call; diff --git a/crates/perry-hir/src/lower/expr_call/module_class_static.rs b/crates/perry-hir/src/lower/expr_call/module_class_static.rs index 4d87058195..c578d688e8 100644 --- a/crates/perry-hir/src/lower/expr_call/module_class_static.rs +++ b/crates/perry-hir/src/lower/expr_call/module_class_static.rs @@ -2,8 +2,8 @@ //! //! Extracted from `expr_call/mod.rs` as a mechanical move. +use crate::types::Type; use anyhow::Result; -use perry_types::Type; use swc_ecma_ast as ast; use crate::ir::*; diff --git a/crates/perry-hir/src/lower/expr_call/module_static.rs b/crates/perry-hir/src/lower/expr_call/module_static.rs index 79c4de0537..1e41748f41 100644 --- a/crates/perry-hir/src/lower/expr_call/module_static.rs +++ b/crates/perry-hir/src/lower/expr_call/module_static.rs @@ -2,8 +2,8 @@ //! //! Extracted from `expr_call/mod.rs` as a mechanical move. +use crate::types::Type; use anyhow::Result; -use perry_types::Type; use swc_ecma_ast as ast; use super::static_receiver::static_receiver_class; diff --git a/crates/perry-hir/src/lower/expr_call/native_module.rs b/crates/perry-hir/src/lower/expr_call/native_module.rs index 304fa8bf66..523242d3c5 100644 --- a/crates/perry-hir/src/lower/expr_call/native_module.rs +++ b/crates/perry-hir/src/lower/expr_call/native_module.rs @@ -2,8 +2,8 @@ //! //! Extracted from `expr_call/mod.rs` as a mechanical move. +use crate::types::Type; use anyhow::Result; -use perry_types::Type; use swc_ecma_ast as ast; use super::super::unimpl_hints; diff --git a/crates/perry-hir/src/lower/expr_call/post_args_dispatch.rs b/crates/perry-hir/src/lower/expr_call/post_args_dispatch.rs index e07bf09926..9b374e28fd 100644 --- a/crates/perry-hir/src/lower/expr_call/post_args_dispatch.rs +++ b/crates/perry-hir/src/lower/expr_call/post_args_dispatch.rs @@ -6,7 +6,7 @@ //! `match &call.callee { ... }` dispatch. Extracted from //! `expr_call/mod.rs` as a mechanical move. -use perry_types::Type; +use crate::types::Type; use swc_ecma_ast as ast; use crate::ir::*; diff --git a/crates/perry-hir/src/lower/expr_call/regex_string.rs b/crates/perry-hir/src/lower/expr_call/regex_string.rs index 85bb1e3568..92f0fa11a6 100644 --- a/crates/perry-hir/src/lower/expr_call/regex_string.rs +++ b/crates/perry-hir/src/lower/expr_call/regex_string.rs @@ -2,8 +2,8 @@ //! //! Extracted from `expr_call/mod.rs` as a mechanical move. +use crate::types::Type; use anyhow::Result; -use perry_types::Type; use swc_ecma_ast as ast; use crate::ir::*; diff --git a/crates/perry-hir/src/lower/expr_call/static_receiver.rs b/crates/perry-hir/src/lower/expr_call/static_receiver.rs index 76abdffcfb..be7128f338 100644 --- a/crates/perry-hir/src/lower/expr_call/static_receiver.rs +++ b/crates/perry-hir/src/lower/expr_call/static_receiver.rs @@ -4,7 +4,7 @@ //! Extracted from `expr_call/mod.rs` in #1104 as a pure mechanical move; //! the function's only consumer is `lower_call_inner` inside this module. -use perry_types::Type; +use crate::types::Type; use swc_ecma_ast as ast; use super::super::LoweringContext; diff --git a/crates/perry-hir/src/lower/expr_call/textencoder.rs b/crates/perry-hir/src/lower/expr_call/textencoder.rs index c5a0f19edc..0eec830a6e 100644 --- a/crates/perry-hir/src/lower/expr_call/textencoder.rs +++ b/crates/perry-hir/src/lower/expr_call/textencoder.rs @@ -2,8 +2,8 @@ //! //! Extracted from `expr_call/mod.rs` as a mechanical move. +use crate::types::Type; use anyhow::Result; -use perry_types::Type; use swc_ecma_ast as ast; use crate::ir::*; diff --git a/crates/perry-hir/src/lower/expr_call/url_date_instance.rs b/crates/perry-hir/src/lower/expr_call/url_date_instance.rs index 764169107d..840c752f9c 100644 --- a/crates/perry-hir/src/lower/expr_call/url_date_instance.rs +++ b/crates/perry-hir/src/lower/expr_call/url_date_instance.rs @@ -2,8 +2,8 @@ //! //! Extracted from `expr_call/mod.rs` as a mechanical move. +use crate::types::Type; use anyhow::Result; -use perry_types::Type; use swc_ecma_ast as ast; use super::static_receiver::static_receiver_class; diff --git a/crates/perry-hir/src/lower/expr_function.rs b/crates/perry-hir/src/lower/expr_function.rs index 842ba9dfc7..6ab5b466f7 100644 --- a/crates/perry-hir/src/lower/expr_function.rs +++ b/crates/perry-hir/src/lower/expr_function.rs @@ -15,8 +15,8 @@ //! recursion through `super::lower_expr`, all `LoweringContext` //! mutation goes through public methods + `pub(crate)` fields. +use crate::types::{LocalId, Type}; use anyhow::Result; -use perry_types::{LocalId, Type}; use swc_ecma_ast as ast; use crate::analysis::{ @@ -40,7 +40,7 @@ use super::{lower_expr, LoweringContext}; /// installed (unit tests / `check`). pub(crate) fn capture_function_source( ctx: &mut LoweringContext, - func_id: perry_types::FuncId, + func_id: crate::types::FuncId, span: &swc_common::Span, is_async: bool, ) { @@ -1520,7 +1520,7 @@ fn compute_closure_captures( /// registration overwrites them in program order. pub(crate) fn insert_class_capture_refresh_after_assignments( stmts: &mut Vec, - regs: &[(Stmt, std::collections::HashSet)], + regs: &[(Stmt, std::collections::HashSet)], ) { let mut i = 0; while i < stmts.len() { diff --git a/crates/perry-hir/src/lower/expr_member.rs b/crates/perry-hir/src/lower/expr_member.rs index 593ac4a376..99fb3395cb 100644 --- a/crates/perry-hir/src/lower/expr_member.rs +++ b/crates/perry-hir/src/lower/expr_member.rs @@ -9,8 +9,8 @@ //! (regular object vs class static vs enum vs builtin namespace) then //! emit the right HIR variant. +use crate::types::Type; use anyhow::Result; -use perry_types::Type; use swc_ecma_ast as ast; use crate::ir::Expr; @@ -2034,8 +2034,8 @@ fn lower_member_inner(ctx: &mut LoweringContext, member: &ast::MemberExpr) -> Re if let ast::Expr::Ident(ident) = member.obj.as_ref() { let recv_ty = ctx.lookup_local_type(ident.sym.as_ref()); let is_array = match recv_ty { - Some(perry_types::Type::Array(_)) | Some(perry_types::Type::Tuple(_)) => true, - Some(perry_types::Type::Named(n)) if n == "TemplateStringsArray" => true, + Some(crate::types::Type::Array(_)) | Some(crate::types::Type::Tuple(_)) => true, + Some(crate::types::Type::Named(n)) if n == "TemplateStringsArray" => true, _ => false, }; if is_array { diff --git a/crates/perry-hir/src/lower/expr_member/member_tail.rs b/crates/perry-hir/src/lower/expr_member/member_tail.rs index ef004c340e..8627d7caa5 100644 --- a/crates/perry-hir/src/lower/expr_member/member_tail.rs +++ b/crates/perry-hir/src/lower/expr_member/member_tail.rs @@ -5,8 +5,8 @@ //! Split out of `expr_member.rs` (pure code move). Runs after the //! early-return checks in `lower_member_inner`. +use crate::types::Type; use anyhow::Result; -use perry_types::Type; use swc_common::Spanned; use swc_ecma_ast as ast; diff --git a/crates/perry-hir/src/lower/expr_misc.rs b/crates/perry-hir/src/lower/expr_misc.rs index ccd9bcbeab..4d00df0d23 100644 --- a/crates/perry-hir/src/lower/expr_misc.rs +++ b/crates/perry-hir/src/lower/expr_misc.rs @@ -166,11 +166,11 @@ pub(super) fn lower_update(ctx: &mut LoweringContext, update: &ast::UpdateExpr) callee: Box::new(Expr::ExternFuncRef { name: "js_global_update".to_string(), param_types: vec![ - perry_types::Type::Any, - perry_types::Type::Any, - perry_types::Type::Any, + crate::types::Type::Any, + crate::types::Type::Any, + crate::types::Type::Any, ], - return_type: perry_types::Type::Any, + return_type: crate::types::Type::Any, }), args: vec![ Expr::String(name), @@ -201,8 +201,8 @@ pub(super) fn lower_update(ctx: &mut LoweringContext, update: &ast::UpdateExpr) Expr::Call { callee: Box::new(Expr::ExternFuncRef { name: "js_to_numeric".to_string(), - param_types: vec![perry_types::Type::Any], - return_type: perry_types::Type::Any, + param_types: vec![crate::types::Type::Any], + return_type: crate::types::Type::Any, }), args: vec![Expr::LocalGet(id)], type_args: vec![], diff --git a/crates/perry-hir/src/lower/expr_new.rs b/crates/perry-hir/src/lower/expr_new.rs index cff17ad7fe..05f1189a7b 100644 --- a/crates/perry-hir/src/lower/expr_new.rs +++ b/crates/perry-hir/src/lower/expr_new.rs @@ -9,8 +9,8 @@ //! `Expr::TypedArrayNew`, etc.), (c) the dynamic //! `new (someFn)(args)` form via `Expr::NewDynamic`. +use crate::types::LocalId; use anyhow::Result; -use perry_types::LocalId; use swc_ecma_ast as ast; use crate::ir::Expr; diff --git a/crates/perry-hir/src/lower/expr_new/helpers.rs b/crates/perry-hir/src/lower/expr_new/helpers.rs index e4f3900eb5..a6d160d3a6 100644 --- a/crates/perry-hir/src/lower/expr_new/helpers.rs +++ b/crates/perry-hir/src/lower/expr_new/helpers.rs @@ -2,8 +2,8 @@ //! `expr_new.rs` so the trunk stays under the file-size budget. Pure code move //! — no behavior change. +use crate::types::Type; use anyhow::{anyhow, Result}; -use perry_types::Type; use swc_ecma_ast as ast; use crate::ir::Expr; diff --git a/crates/perry-hir/src/lower/expr_new/member.rs b/crates/perry-hir/src/lower/expr_new/member.rs index eb2fdb722c..1916e84706 100644 --- a/crates/perry-hir/src/lower/expr_new/member.rs +++ b/crates/perry-hir/src/lower/expr_new/member.rs @@ -5,8 +5,8 @@ use super::*; +use crate::types::Type; use anyhow::Result; -use perry_types::Type; use swc_ecma_ast as ast; use crate::ir::Expr; diff --git a/crates/perry-hir/src/lower/expr_new/non_ident.rs b/crates/perry-hir/src/lower/expr_new/non_ident.rs index c238babd40..f3e9550efe 100644 --- a/crates/perry-hir/src/lower/expr_new/non_ident.rs +++ b/crates/perry-hir/src/lower/expr_new/non_ident.rs @@ -4,8 +4,8 @@ use super::*; +use crate::types::LocalId; use anyhow::Result; -use perry_types::LocalId; use swc_ecma_ast as ast; use crate::ir::Expr; diff --git a/crates/perry-hir/src/lower/expr_object.rs b/crates/perry-hir/src/lower/expr_object.rs index 81d6316892..d51ef51f19 100644 --- a/crates/perry-hir/src/lower/expr_object.rs +++ b/crates/perry-hir/src/lower/expr_object.rs @@ -13,8 +13,8 @@ //! Pattern matches `expr_misc.rs` and `expr_function.rs`: free //! `pub(super) fn` helpers, recursion through `super::lower_expr`. +use crate::types::{LocalId, Type}; use anyhow::Result; -use perry_types::{LocalId, Type}; use swc_ecma_ast as ast; use crate::analysis::{ diff --git a/crates/perry-hir/src/lower/for_head.rs b/crates/perry-hir/src/lower/for_head.rs index cc61da859d..7c726df395 100644 --- a/crates/perry-hir/src/lower/for_head.rs +++ b/crates/perry-hir/src/lower/for_head.rs @@ -7,8 +7,8 @@ //! the for-of / for-in desugars in `stmt_loops.rs` and //! `lower_decl/body_stmt.rs`. +use crate::types::{LocalId, Type}; use anyhow::{anyhow, Result}; -use perry_types::{LocalId, Type}; use swc_ecma_ast as ast; use super::*; diff --git a/crates/perry-hir/src/lower/locals.rs b/crates/perry-hir/src/lower/locals.rs index 7e3a150d67..a55e100ed4 100644 --- a/crates/perry-hir/src/lower/locals.rs +++ b/crates/perry-hir/src/lower/locals.rs @@ -25,7 +25,7 @@ use std::ops::{Deref, DerefMut}; -use perry_types::{LocalId, Type}; +use crate::types::{LocalId, Type}; use std::collections::{HashMap, HashSet}; /// Ordered stack of scope-local bindings with a name→positions index. diff --git a/crates/perry-hir/src/lower/lower_expr/arm_ident.rs b/crates/perry-hir/src/lower/lower_expr/arm_ident.rs index 4a783cc9a2..cb427ff9c7 100644 --- a/crates/perry-hir/src/lower/lower_expr/arm_ident.rs +++ b/crates/perry-hir/src/lower/lower_expr/arm_ident.rs @@ -2,8 +2,8 @@ //! Pure code move — no behavior change. use super::*; +use crate::types::Type; use anyhow::Result; -use perry_types::Type; use swc_ecma_ast as ast; pub(crate) fn lower_ident_expr(ctx: &mut LoweringContext, ident: &ast::Ident) -> Result { diff --git a/crates/perry-hir/src/lower/lower_expr/arm_unary.rs b/crates/perry-hir/src/lower/lower_expr/arm_unary.rs index fe3e158271..d0af98105a 100644 --- a/crates/perry-hir/src/lower/lower_expr/arm_unary.rs +++ b/crates/perry-hir/src/lower/lower_expr/arm_unary.rs @@ -2,8 +2,8 @@ //! Pure code move — no behavior change. use super::*; +use crate::types::Type; use anyhow::{anyhow, Result}; -use perry_types::Type; use swc_ecma_ast as ast; pub(crate) fn lower_unary_expr(ctx: &mut LoweringContext, unary: &ast::UnaryExpr) -> Result { diff --git a/crates/perry-hir/src/lower/lower_expr/helpers.rs b/crates/perry-hir/src/lower/lower_expr/helpers.rs index 44fb58a51b..dd4cf75bbf 100644 --- a/crates/perry-hir/src/lower/lower_expr/helpers.rs +++ b/crates/perry-hir/src/lower/lower_expr/helpers.rs @@ -6,8 +6,8 @@ use super::*; // Pull in the parent `lower` module's full (re-exported) surface so moved // helpers resolve names like `LoweringContext`, `expr_member`, // `is_builtin_function`, etc. exactly as they did in the trunk. +use crate::types::{LocalId, Type}; use anyhow::Result; -use perry_types::{LocalId, Type}; use swc_ecma_ast as ast; use crate::lower_types::extract_ts_type_with_ctx; diff --git a/crates/perry-hir/src/lower/lower_expr/reactive_text.rs b/crates/perry-hir/src/lower/lower_expr/reactive_text.rs index 721b26a615..d6b2597643 100644 --- a/crates/perry-hir/src/lower/lower_expr/reactive_text.rs +++ b/crates/perry-hir/src/lower/lower_expr/reactive_text.rs @@ -2,8 +2,8 @@ //! desugar helper. Extracted from the trunk `lower_expr.rs`. Pure code move. use super::*; +use crate::types::{LocalId, Type}; use anyhow::{anyhow, Result}; -use perry_types::{LocalId, Type}; use swc_ecma_ast as ast; /// If `call` matches `Text(\`...${state.value}...\`)` with at least one State diff --git a/crates/perry-hir/src/lower/lower_module_fn.rs b/crates/perry-hir/src/lower/lower_module_fn.rs index 9ce327eb77..4abef467f4 100644 --- a/crates/perry-hir/src/lower/lower_module_fn.rs +++ b/crates/perry-hir/src/lower/lower_module_fn.rs @@ -7,8 +7,8 @@ //! reach them via `crate::lower::lower_module*` (or the `lib.rs` //! re-exports — `pub use lower::{lower_module, ...}`). +use crate::types::Type; use anyhow::Result; -use perry_types::Type; use std::collections::HashSet; use swc_ecma_ast as ast; diff --git a/crates/perry-hir/src/lower/lowering_context.rs b/crates/perry-hir/src/lower/lowering_context.rs index 1d6e4c31d3..fdb645a9d2 100644 --- a/crates/perry-hir/src/lower/lowering_context.rs +++ b/crates/perry-hir/src/lower/lowering_context.rs @@ -6,7 +6,7 @@ //! field visibility stays `pub(crate)`; downstream code keeps reaching //! the struct via `crate::lower::LoweringContext`. -use perry_types::{FuncId, GlobalId, LocalId, Type, TypeParam}; +use crate::types::{FuncId, GlobalId, LocalId, Type, TypeParam}; use std::collections::{HashMap, HashSet}; use crate::ir::*; @@ -178,7 +178,7 @@ pub struct LoweringContext { /// lowers to `Array` instead of `Array`. /// Without this, codegen sees only `Named` and can't extract the /// shape, so the specialized parse path never fires. - pub(crate) interface_object_types: std::collections::HashMap, + pub(crate) interface_object_types: std::collections::HashMap, /// Imported functions: local_name -> original_name (the exported name in the source module) pub(crate) imported_functions: Vec<(String, String)>, /// Built-in named imports: local_name -> (module_name, exported_name). @@ -648,7 +648,7 @@ pub struct LoweringContext { /// `FuncId` of the synthesized top-level generator function that /// takes `this` as its first parameter. Consumed by `for...of` to /// dispatch through the iterator protocol via a direct FuncRef call. - pub(crate) iterator_func_for_class: std::collections::HashMap, + pub(crate) iterator_func_for_class: std::collections::HashMap, pub(crate) proxy_locals: HashSet, /// #3144: local name -> builtin prototype method name, for bindings like /// `const m = [].map` / `const s = "".slice`. Lets the `.call`/`.apply` diff --git a/crates/perry-hir/src/lower/misc.rs b/crates/perry-hir/src/lower/misc.rs index b1fc37813b..92e6d34ebc 100644 --- a/crates/perry-hir/src/lower/misc.rs +++ b/crates/perry-hir/src/lower/misc.rs @@ -4,7 +4,7 @@ //! visibility and are re-exported from `lower/mod.rs` so the existing //! `expr_*` submodules and the rest of the crate keep compiling unchanged. -use perry_types::Type; +use crate::types::Type; use swc_ecma_ast as ast; use super::*; diff --git a/crates/perry-hir/src/lower/module_decl.rs b/crates/perry-hir/src/lower/module_decl.rs index 4099c1d090..9be4224374 100644 --- a/crates/perry-hir/src/lower/module_decl.rs +++ b/crates/perry-hir/src/lower/module_decl.rs @@ -4,8 +4,8 @@ //! visibility and are re-exported from `lower/mod.rs` so the existing //! `expr_*` submodules and the rest of the crate keep compiling unchanged. +use crate::types::{LocalId, Type}; use anyhow::Result; -use perry_types::{LocalId, Type}; use swc_ecma_ast as ast; use super::*; diff --git a/crates/perry-hir/src/lower/module_decl/namespace.rs b/crates/perry-hir/src/lower/module_decl/namespace.rs index 6812d35420..964fa663b0 100644 --- a/crates/perry-hir/src/lower/module_decl/namespace.rs +++ b/crates/perry-hir/src/lower/module_decl/namespace.rs @@ -1,8 +1,8 @@ //! TypeScript namespace → synthetic-class lowering — extracted from //! `lower/module_decl.rs` (pure mechanical split, no logic changes). +use crate::types::Type; use anyhow::Result; -use perry_types::Type; use swc_ecma_ast as ast; use super::*; diff --git a/crates/perry-hir/src/lower/shared_mutable_capture.rs b/crates/perry-hir/src/lower/shared_mutable_capture.rs index dbc69a1e4a..2ab4410948 100644 --- a/crates/perry-hir/src/lower/shared_mutable_capture.rs +++ b/crates/perry-hir/src/lower/shared_mutable_capture.rs @@ -22,7 +22,7 @@ use std::collections::{HashMap, HashSet}; -use perry_types::{LocalId, Type}; +use crate::types::{LocalId, Type}; use crate::ir::*; use crate::walker::{walk_expr_children, walk_expr_children_mut}; diff --git a/crates/perry-hir/src/lower/stmt.rs b/crates/perry-hir/src/lower/stmt.rs index 7bd7ab876b..de2f8fe3bf 100644 --- a/crates/perry-hir/src/lower/stmt.rs +++ b/crates/perry-hir/src/lower/stmt.rs @@ -4,8 +4,8 @@ //! visibility and are re-exported from `lower/mod.rs` so the existing //! `expr_*` submodules and the rest of the crate keep compiling unchanged. +use crate::types::{LocalId, Type}; use anyhow::{anyhow, Result}; -use perry_types::{LocalId, Type}; use swc_ecma_ast as ast; use super::*; diff --git a/crates/perry-hir/src/lower/stmt_loops.rs b/crates/perry-hir/src/lower/stmt_loops.rs index 45876cb858..1c586f8f87 100644 --- a/crates/perry-hir/src/lower/stmt_loops.rs +++ b/crates/perry-hir/src/lower/stmt_loops.rs @@ -10,8 +10,8 @@ //! The match arms inside `lower_stmt` collapse to one-line delegations //! to `lower_stmt_for_of` / `lower_stmt_for_in`. +use crate::types::{LocalId, Type}; use anyhow::{anyhow, Result}; -use perry_types::{LocalId, Type}; use swc_ecma_ast as ast; use super::*; @@ -856,7 +856,7 @@ pub(crate) fn lower_stmt_for_of( // a synthesized top-level generator function taking `this` // as its first parameter; the for-of here dispatches by // calling that function with the lowered receiver. - let iter_from_class: Option = + let iter_from_class: Option = if let ast::Expr::New(new_expr) = &*for_of_stmt.right { if let ast::Expr::Ident(ident) = new_expr.callee.as_ref() { let class_name = ident.sym.to_string(); diff --git a/crates/perry-hir/src/lower/tests.rs b/crates/perry-hir/src/lower/tests.rs index 372f60fe80..1c91f89147 100644 --- a/crates/perry-hir/src/lower/tests.rs +++ b/crates/perry-hir/src/lower/tests.rs @@ -9,7 +9,7 @@ use super::*; use crate::ir::EnumValue; -use perry_types::{Type, TypeParam}; +use crate::types::{Type, TypeParam}; fn make_ctx() -> LoweringContext { LoweringContext::new("test.ts") diff --git a/crates/perry-hir/src/lower/type_widening.rs b/crates/perry-hir/src/lower/type_widening.rs index 9b65268acb..3a0ecaf167 100644 --- a/crates/perry-hir/src/lower/type_widening.rs +++ b/crates/perry-hir/src/lower/type_widening.rs @@ -17,7 +17,7 @@ use crate::analysis::{infer_expr_type, HirTypeEnv}; use crate::ir::*; -use perry_types::{LocalId, Type}; +use crate::types::{LocalId, Type}; use std::collections::HashSet; fn type_is_certainly_object_like(ty: &Type) -> bool { diff --git a/crates/perry-hir/src/lower/typed_parse.rs b/crates/perry-hir/src/lower/typed_parse.rs index 5f0b6494cb..286c1c6ae5 100644 --- a/crates/perry-hir/src/lower/typed_parse.rs +++ b/crates/perry-hir/src/lower/typed_parse.rs @@ -8,7 +8,7 @@ //! Visibility note: bumped from `pub(super)` to `pub(crate)` so the //! mod.rs named re-export can propagate the symbols across the crate. -use perry_types::Type; +use crate::types::Type; use super::*; diff --git a/crates/perry-hir/src/lower/widget_decl/reactive_animate.rs b/crates/perry-hir/src/lower/widget_decl/reactive_animate.rs index ce22e2ace7..54eddc09df 100644 --- a/crates/perry-hir/src/lower/widget_decl/reactive_animate.rs +++ b/crates/perry-hir/src/lower/widget_decl/reactive_animate.rs @@ -4,8 +4,8 @@ //! visibility (re-exported from `widget_decl.rs`) so the //! `pub(crate) use widget_decl::*` in `lower/mod.rs` still resolves it. +use crate::types::{LocalId, Type}; use anyhow::{anyhow, Result}; -use perry_types::{LocalId, Type}; use swc_ecma_ast as ast; use super::super::*; diff --git a/crates/perry-hir/src/lower_decl/block.rs b/crates/perry-hir/src/lower_decl/block.rs index 2c0e325d79..c8bf0e8ae2 100644 --- a/crates/perry-hir/src/lower_decl/block.rs +++ b/crates/perry-hir/src/lower_decl/block.rs @@ -1,5 +1,5 @@ +use crate::types::{LocalId, Type}; use anyhow::{bail, Result}; -use perry_types::{LocalId, Type}; use swc_ecma_ast as ast; use crate::analysis::*; @@ -1256,7 +1256,7 @@ pub fn lower_fn_body_block_stmt( // refresh-before-EVERY-return placement. { let mut re_regs: Vec = Vec::new(); - let mut re_reg_capsets: Vec<(Stmt, std::collections::HashSet)> = + let mut re_reg_capsets: Vec<(Stmt, std::collections::HashSet)> = Vec::new(); for stmt in &block.stmts { if let ast::Stmt::Decl(ast::Decl::Class(class_decl)) = stmt { @@ -1279,7 +1279,7 @@ pub fn lower_fn_body_block_stmt( // they ALREADY carry appends; restrict this pass to // non-member code by walking the lowered body only // (member bodies live in pending_classes, not here). - let cap_args: Vec<(perry_types::LocalId, perry_types::LocalId)> = + let cap_args: Vec<(crate::types::LocalId, crate::types::LocalId)> = captured.iter().map(|id| (*id, *id)).collect(); for s in body.iter_mut() { super::class_captures::append_new_args_stmt(s, &cname, &cap_args, true); diff --git a/crates/perry-hir/src/lower_decl/body_stmt.rs b/crates/perry-hir/src/lower_decl/body_stmt.rs index ca0d2b72b1..7a88622609 100644 --- a/crates/perry-hir/src/lower_decl/body_stmt.rs +++ b/crates/perry-hir/src/lower_decl/body_stmt.rs @@ -1,5 +1,5 @@ +use crate::types::{LocalId, Type}; use anyhow::{anyhow, Result}; -use perry_types::{LocalId, Type}; use swc_ecma_ast as ast; use crate::analysis::*; @@ -1126,7 +1126,7 @@ pub fn lower_body_stmt(ctx: &mut LoweringContext, stmt: &ast::Stmt) -> Result = + let iter_from_class: Option = if let ast::Expr::New(new_expr) = &*for_of_stmt.right { if let ast::Expr::Ident(ident) = new_expr.callee.as_ref() { let class_name = ident.sym.to_string(); diff --git a/crates/perry-hir/src/lower_decl/class_captures.rs b/crates/perry-hir/src/lower_decl/class_captures.rs index ae9a6860c1..19220ab839 100644 --- a/crates/perry-hir/src/lower_decl/class_captures.rs +++ b/crates/perry-hir/src/lower_decl/class_captures.rs @@ -1,4 +1,4 @@ -use perry_types::{LocalId, Type}; +use crate::types::{LocalId, Type}; use crate::ir::*; use crate::lower::LoweringContext; diff --git a/crates/perry-hir/src/lower_decl/class_computed.rs b/crates/perry-hir/src/lower_decl/class_computed.rs index 3c1b7ee4ae..8d2ab498a0 100644 --- a/crates/perry-hir/src/lower_decl/class_computed.rs +++ b/crates/perry-hir/src/lower_decl/class_computed.rs @@ -2,8 +2,8 @@ //! declared inside a function body. Extracted from `body_stmt.rs` to keep that //! file under the source-size gate. +use crate::types::Type; use anyhow::Result; -use perry_types::Type; use swc_ecma_ast as ast; use crate::ir::*; diff --git a/crates/perry-hir/src/lower_decl/class_decl.rs b/crates/perry-hir/src/lower_decl/class_decl.rs index f31591b675..e8d075ac7e 100644 --- a/crates/perry-hir/src/lower_decl/class_decl.rs +++ b/crates/perry-hir/src/lower_decl/class_decl.rs @@ -1,5 +1,5 @@ +use crate::types::{FuncId, Type}; use anyhow::Result; -use perry_types::{FuncId, Type}; use swc_ecma_ast as ast; use crate::ir::*; diff --git a/crates/perry-hir/src/lower_decl/class_members.rs b/crates/perry-hir/src/lower_decl/class_members.rs index c368afd1c9..769a3e9c0a 100644 --- a/crates/perry-hir/src/lower_decl/class_members.rs +++ b/crates/perry-hir/src/lower_decl/class_members.rs @@ -1,5 +1,5 @@ +use crate::types::{LocalId, Type}; use anyhow::{anyhow, Result}; -use perry_types::{LocalId, Type}; use swc_ecma_ast as ast; use crate::ir::*; diff --git a/crates/perry-hir/src/lower_decl/fn_decl.rs b/crates/perry-hir/src/lower_decl/fn_decl.rs index 605dc2f466..5a131ead13 100644 --- a/crates/perry-hir/src/lower_decl/fn_decl.rs +++ b/crates/perry-hir/src/lower_decl/fn_decl.rs @@ -1,5 +1,5 @@ +use crate::types::{LocalId, Type}; use anyhow::Result; -use perry_types::{LocalId, Type}; use swc_ecma_ast as ast; use crate::ir::*; diff --git a/crates/perry-hir/src/lower_decl/helpers.rs b/crates/perry-hir/src/lower_decl/helpers.rs index 1a5dbab2a0..64040a8f61 100644 --- a/crates/perry-hir/src/lower_decl/helpers.rs +++ b/crates/perry-hir/src/lower_decl/helpers.rs @@ -4,7 +4,7 @@ //! enum declarations, interface declarations, type alias declarations, //! constructors, class methods, getters, setters, and class properties. -use perry_types::{LocalId, Type}; +use crate::types::{LocalId, Type}; use swc_ecma_ast as ast; use crate::ir::*; diff --git a/crates/perry-hir/src/lower_decl/interface_decl.rs b/crates/perry-hir/src/lower_decl/interface_decl.rs index 83c797f9e2..3c6819e627 100644 --- a/crates/perry-hir/src/lower_decl/interface_decl.rs +++ b/crates/perry-hir/src/lower_decl/interface_decl.rs @@ -1,5 +1,5 @@ +use crate::types::Type; use anyhow::Result; -use perry_types::Type; use swc_ecma_ast as ast; use crate::ir::*; @@ -141,12 +141,12 @@ pub fn lower_interface_decl( } // Also materialize an ObjectType so `resolve_typed_parse_ty` can // expand `Named("Item")` → `Object{fields}` for codegen. - let mut obj_props: std::collections::HashMap = + let mut obj_props: std::collections::HashMap = std::collections::HashMap::new(); for p in &properties { obj_props.insert( p.name.clone(), - perry_types::PropertyInfo { + crate::types::PropertyInfo { ty: p.ty.clone(), optional: p.optional, readonly: p.readonly, @@ -156,7 +156,7 @@ pub fn lower_interface_decl( if !obj_props.is_empty() { ctx.interface_object_types.insert( name.clone(), - perry_types::ObjectType { + crate::types::ObjectType { name: Some(name.clone()), properties: obj_props, property_order: Some(source_keys.clone()), diff --git a/crates/perry-hir/src/lower_decl/private_members.rs b/crates/perry-hir/src/lower_decl/private_members.rs index 5e02bdfd9e..c556e08b58 100644 --- a/crates/perry-hir/src/lower_decl/private_members.rs +++ b/crates/perry-hir/src/lower_decl/private_members.rs @@ -1,5 +1,5 @@ +use crate::types::{LocalId, Type}; use anyhow::Result; -use perry_types::{LocalId, Type}; use swc_ecma_ast as ast; use crate::ir::*; diff --git a/crates/perry-hir/src/lower_decl/typeof_narrow.rs b/crates/perry-hir/src/lower_decl/typeof_narrow.rs index e4de9b5abd..ee5e7e5d05 100644 --- a/crates/perry-hir/src/lower_decl/typeof_narrow.rs +++ b/crates/perry-hir/src/lower_decl/typeof_narrow.rs @@ -23,8 +23,8 @@ //! variant in our `Type` enum and naive narrowing would either lose //! precision or incorrectly drop array methods from `object`-typed unions. +use crate::types::Type; use anyhow::Result; -use perry_types::Type; use swc_ecma_ast as ast; use crate::ir::Stmt; diff --git a/crates/perry-hir/src/lower_patterns.rs b/crates/perry-hir/src/lower_patterns.rs index 3d1a01de5c..0055a4fe06 100644 --- a/crates/perry-hir/src/lower_patterns.rs +++ b/crates/perry-hir/src/lower_patterns.rs @@ -6,8 +6,8 @@ use crate::ir::*; use crate::lower::{lower_expr, LoweringContext}; use crate::lower_types::*; +use crate::types::{LocalId, Type}; use anyhow::{anyhow, Result}; -use perry_types::{LocalId, Type}; use swc_common::Spanned; use swc_ecma_ast as ast; diff --git a/crates/perry-hir/src/lower_types.rs b/crates/perry-hir/src/lower_types.rs index ad6eaef1a5..8360c793e1 100644 --- a/crates/perry-hir/src/lower_types.rs +++ b/crates/perry-hir/src/lower_types.rs @@ -3,7 +3,7 @@ //! Contains functions for inferring types from expressions, extracting //! TypeScript type annotations, and parsing function parameter types. -use perry_types::Type; +use crate::types::Type; use swc_ecma_ast as ast; use crate::lower::LoweringContext; @@ -655,7 +655,7 @@ fn infer_type_from_expr_inner(expr: &ast::Expr, ctx: &LoweringContext) -> Type { // Type::Any on anything that makes the shape non-closed: spread, computed // keys, methods/getters/setters, bigint keys. ast::Expr::Object(obj) => { - let mut properties: std::collections::HashMap = + let mut properties: std::collections::HashMap = std::collections::HashMap::new(); let mut property_order: Vec = Vec::new(); let mut open_shape = false; @@ -674,7 +674,7 @@ fn infer_type_from_expr_inner(expr: &ast::Expr, ctx: &LoweringContext) -> Type { } properties.insert( name, - perry_types::PropertyInfo { + crate::types::PropertyInfo { ty, optional: false, readonly: false, @@ -697,7 +697,7 @@ fn infer_type_from_expr_inner(expr: &ast::Expr, ctx: &LoweringContext) -> Type { } properties.insert( key, - perry_types::PropertyInfo { + crate::types::PropertyInfo { ty, optional: false, readonly: false, @@ -714,7 +714,7 @@ fn infer_type_from_expr_inner(expr: &ast::Expr, ctx: &LoweringContext) -> Type { if open_shape { Type::Any } else { - Type::Object(perry_types::ObjectType { + Type::Object(crate::types::ObjectType { name: None, properties, property_order: Some(property_order), @@ -774,7 +774,7 @@ fn infer_type_from_expr_inner(expr: &ast::Expr, ctx: &LoweringContext) -> Type { } else { annotated }; - Type::Function(perry_types::FunctionType { + Type::Function(crate::types::FunctionType { params: arrow .params .iter() diff --git a/crates/perry-hir/src/lower_types/extract.rs b/crates/perry-hir/src/lower_types/extract.rs index b920a282b5..27186b63a6 100644 --- a/crates/perry-hir/src/lower_types/extract.rs +++ b/crates/perry-hir/src/lower_types/extract.rs @@ -4,7 +4,7 @@ //! Named re-exports in `lower_types.rs` keep every existing call path //! (`crate::lower_types::extract_ts_type`, ...) compiling unchanged. -use perry_types::{Type, TypeParam}; +use crate::types::{Type, TypeParam}; use swc_ecma_ast as ast; use crate::ir::*; @@ -207,7 +207,7 @@ pub(crate) fn extract_ts_type_with_ctx( let return_type = extract_ts_type_with_ctx(&fn_ty.type_ann.type_ann, ctx); - Type::Function(perry_types::FunctionType { + Type::Function(crate::types::FunctionType { params, return_type: Box::new(return_type), is_async: false, @@ -295,7 +295,7 @@ pub(crate) fn extract_ts_type_with_ctx( } properties.insert( field_name, - perry_types::PropertyInfo { + crate::types::PropertyInfo { ty: field_type, optional: prop.optional, readonly: prop.readonly, @@ -321,8 +321,8 @@ pub(crate) fn extract_ts_type_with_ctx( .collect(); properties.insert( method_name, - perry_types::PropertyInfo { - ty: Type::Function(perry_types::FunctionType { + crate::types::PropertyInfo { + ty: Type::Function(crate::types::FunctionType { params, return_type: Box::new(return_type), is_async: false, @@ -338,7 +338,7 @@ pub(crate) fn extract_ts_type_with_ctx( // index signature: { [key: string]: T } if let Some(ann) = &idx_sig.type_ann { let val_type = extract_ts_type_with_ctx(&ann.type_ann, ctx); - return Type::Object(perry_types::ObjectType { + return Type::Object(crate::types::ObjectType { name: None, properties, property_order: Some(property_order), @@ -352,7 +352,7 @@ pub(crate) fn extract_ts_type_with_ctx( if properties.is_empty() { Type::Any } else { - Type::Object(perry_types::ObjectType { + Type::Object(crate::types::ObjectType { name: None, properties, property_order: Some(property_order), diff --git a/crates/perry-hir/src/monomorph/inference_lookup.rs b/crates/perry-hir/src/monomorph/inference_lookup.rs index d8f79e1201..bff4a54fa8 100644 --- a/crates/perry-hir/src/monomorph/inference_lookup.rs +++ b/crates/perry-hir/src/monomorph/inference_lookup.rs @@ -8,7 +8,7 @@ pub(crate) struct FuncInfo { // self-describing record + future lookups. #[allow(dead_code)] pub(crate) id: FuncId, - pub(crate) type_params: Vec, + pub(crate) type_params: Vec, pub(crate) params: Vec, pub(crate) return_type: Type, } @@ -20,7 +20,7 @@ pub(crate) struct ClassInfo { // mirrored copy is currently unread. Kept for the self-describing record. #[allow(dead_code)] pub(crate) name: String, - pub(crate) type_params: Vec, + pub(crate) type_params: Vec, pub(crate) constructor_params: Option>, } diff --git a/crates/perry-hir/src/monomorph/mod.rs b/crates/perry-hir/src/monomorph/mod.rs index d6cbcf38ee..9dead6cfad 100644 --- a/crates/perry-hir/src/monomorph/mod.rs +++ b/crates/perry-hir/src/monomorph/mod.rs @@ -14,7 +14,7 @@ //! function identity_string(x: string): string { return x; } use crate::ir::*; -use perry_types::{FuncId, ObjectType, Type}; +use crate::types::{FuncId, ObjectType, Type}; use std::collections::{HashMap, HashSet, VecDeque}; mod constraints; diff --git a/crates/perry-hir/src/monomorph/substitute_type.rs b/crates/perry-hir/src/monomorph/substitute_type.rs index 7a045f3ca4..f478e11c23 100644 --- a/crates/perry-hir/src/monomorph/substitute_type.rs +++ b/crates/perry-hir/src/monomorph/substitute_type.rs @@ -28,7 +28,7 @@ pub fn substitute_type(ty: &Type, substitutions: &HashMap) -> Type .map(|t| substitute_type(t, substitutions)) .collect(), }, - Type::Function(func_type) => Type::Function(perry_types::FunctionType { + Type::Function(func_type) => Type::Function(crate::types::FunctionType { params: func_type .params .iter() diff --git a/crates/perry-hir/src/monomorph/tests.rs b/crates/perry-hir/src/monomorph/tests.rs index af7d09c7ef..7210362d83 100644 --- a/crates/perry-hir/src/monomorph/tests.rs +++ b/crates/perry-hir/src/monomorph/tests.rs @@ -1,5 +1,5 @@ use super::*; -use perry_types::TypeParam; +use crate::types::TypeParam; #[test] fn test_mangle_type() { diff --git a/crates/perry-hir/src/stable_hash/mod.rs b/crates/perry-hir/src/stable_hash/mod.rs index eb26bce45a..cec2468728 100644 --- a/crates/perry-hir/src/stable_hash/mod.rs +++ b/crates/perry-hir/src/stable_hash/mod.rs @@ -46,7 +46,7 @@ mod widgets; mod tests; use crate::ir::Module; -use perry_types::Type; +use crate::types::Type; use primitives::SH; /// Streaming hasher — minimal API so any djb2/fnv/blake variant can plug in. diff --git a/crates/perry-hir/src/stable_hash/tests.rs b/crates/perry-hir/src/stable_hash/tests.rs index 8dffeb611b..0c144e5f78 100644 --- a/crates/perry-hir/src/stable_hash/tests.rs +++ b/crates/perry-hir/src/stable_hash/tests.rs @@ -5,7 +5,7 @@ use super::primitives::SH; use super::*; use crate::ir::*; -use perry_types::{ObjectType, PropertyInfo, Type}; +use crate::types::{ObjectType, PropertyInfo, Type}; use std::collections::{BTreeMap, HashMap}; fn empty_module() -> Module { diff --git a/crates/perry-hir/src/stable_hash/types.rs b/crates/perry-hir/src/stable_hash/types.rs index 25a50667cf..f57358e372 100644 --- a/crates/perry-hir/src/stable_hash/types.rs +++ b/crates/perry-hir/src/stable_hash/types.rs @@ -1,11 +1,11 @@ -//! `SH` impls for the type system (re-exported from `perry-types`). +//! `SH` implementations for HIR type definitions. //! Split out of `stable_hash.rs` (no behavior change). use super::primitives::{tag, SH}; use super::StableHasher; -use perry_types::{FunctionType, ObjectType, PropertyInfo, Type, TypeParam}; +use crate::types::{FunctionType, ObjectType, PropertyInfo, Type, TypeParam}; -// --- Type system (from perry-types) --------------------------------------- +// --- HIR type system ------------------------------------------------------- impl SH for Type { fn hash(&self, hh: &mut H) { diff --git a/crates/perry-types/src/lib.rs b/crates/perry-hir/src/types.rs similarity index 99% rename from crates/perry-types/src/lib.rs rename to crates/perry-hir/src/types.rs index 93ca880117..287a95cb36 100644 --- a/crates/perry-types/src/lib.rs +++ b/crates/perry-hir/src/types.rs @@ -1,4 +1,4 @@ -//! Type system for Perry +//! Type definitions owned by the high-level intermediate representation //! //! Defines the type representations used throughout the compiler, //! from parsing through code generation. diff --git a/crates/perry-hir/tests/c262_parity.rs b/crates/perry-hir/tests/c262_parity.rs index 015f9d84dd..4fb4e4e46a 100644 --- a/crates/perry-hir/tests/c262_parity.rs +++ b/crates/perry-hir/tests/c262_parity.rs @@ -32,7 +32,7 @@ fn top_level_init<'a>(module: &'a perry_hir::Module, name: &str) -> &'a Expr { .unwrap_or_else(|| panic!("top-level binding `{name}` not found")) } -fn top_level_local_id(module: &perry_hir::Module, name: &str) -> perry_types::LocalId { +fn top_level_local_id(module: &perry_hir::Module, name: &str) -> perry_hir::types::LocalId { module .init .iter() diff --git a/crates/perry-hir/tests/cheerio_call_rewrite.rs b/crates/perry-hir/tests/cheerio_call_rewrite.rs index ce80596159..87e14bb47e 100644 --- a/crates/perry-hir/tests/cheerio_call_rewrite.rs +++ b/crates/perry-hir/tests/cheerio_call_rewrite.rs @@ -3,11 +3,11 @@ //! that the runtime can't resolve. use perry_diagnostics::SourceCache; +use perry_hir::types::Type; use perry_hir::{ clear_current_module_source, fix_local_native_instances, lower_module, Expr, Module, Stmt, }; use perry_parser::parse_typescript_with_cache; -use perry_types::Type; fn lower(src: &str) -> perry_hir::Module { let mut cache = SourceCache::new(); diff --git a/crates/perry-hir/tests/native_arena.rs b/crates/perry-hir/tests/native_arena.rs index 319791d92b..d714b3a438 100644 --- a/crates/perry-hir/tests/native_arena.rs +++ b/crates/perry-hir/tests/native_arena.rs @@ -1,7 +1,7 @@ use perry_diagnostics::SourceCache; +use perry_hir::types::Type; use perry_hir::{lower_module, Expr, Function, Module, Stmt}; use perry_parser::parse_typescript_with_cache; -use perry_types::Type; fn lower_src(src: &str) -> Result { let src = src.to_string(); diff --git a/crates/perry-hir/tests/shape_inference.rs b/crates/perry-hir/tests/shape_inference.rs index 77afa1e37f..5160efa779 100644 --- a/crates/perry-hir/tests/shape_inference.rs +++ b/crates/perry-hir/tests/shape_inference.rs @@ -9,9 +9,9 @@ //! downstream codegen to route property access through the direct-GEP path. use perry_diagnostics::SourceCache; +use perry_hir::types::Type; use perry_hir::{lower_module, Module, Stmt}; use perry_parser::parse_typescript_with_cache; -use perry_types::Type; /// Run parsing + lowering on a thread with a larger stack than cargo's default /// 2 MB. The perry HIR lowering passes are deeply recursive — typical compiler diff --git a/crates/perry-transform/Cargo.toml b/crates/perry-transform/Cargo.toml index 3a5a4937a1..c4bd9e5f8c 100644 --- a/crates/perry-transform/Cargo.toml +++ b/crates/perry-transform/Cargo.toml @@ -10,7 +10,6 @@ workspace = true [dependencies] perry-hir.workspace = true -perry-types.workspace = true thiserror.workspace = true anyhow.workspace = true diff --git a/crates/perry-transform/src/async_to_generator.rs b/crates/perry-transform/src/async_to_generator.rs index 9194e250d5..c74bb16e56 100644 --- a/crates/perry-transform/src/async_to_generator.rs +++ b/crates/perry-transform/src/async_to_generator.rs @@ -71,7 +71,7 @@ //! #1021 phase 2. use perry_hir::ir::*; -use perry_types::{LocalId, Type}; +use perry_hir::types::{LocalId, Type}; use std::collections::HashSet; // #5293: the max-LocalId / max-FuncId scans were copy-pasted here; route through @@ -172,7 +172,7 @@ pub fn transform_async_to_generator(module: &mut Module) { collect_async_step_closures(module); if !module.async_step_closures.is_empty() { - let mut next_func_id: perry_types::FuncId = compute_max_func_id(module) + 1; + let mut next_func_id: perry_hir::types::FuncId = compute_max_func_id(module) + 1; // Walk the HIR, rewriting matched async closures in-place. The // walker descends into nested closures so chains like // `async () => { items.map(async x => await f(x)) }` are @@ -279,9 +279,9 @@ pub fn transform_async_to_generator(module: &mut Module) { fn rewrite_async_closures_in_stmts( stmts: &mut Vec, - work: &std::collections::HashSet, + work: &std::collections::HashSet, next_local_id: &mut LocalId, - next_func_id: &mut perry_types::FuncId, + next_func_id: &mut perry_hir::types::FuncId, ) { for s in stmts { rewrite_async_closures_in_stmt(s, work, next_local_id, next_func_id); @@ -290,9 +290,9 @@ fn rewrite_async_closures_in_stmts( fn rewrite_async_closures_in_stmt( stmt: &mut Stmt, - work: &std::collections::HashSet, + work: &std::collections::HashSet, next_local_id: &mut LocalId, - next_func_id: &mut perry_types::FuncId, + next_func_id: &mut perry_hir::types::FuncId, ) { match stmt { Stmt::Let { init: Some(e), .. } => { @@ -370,9 +370,9 @@ fn rewrite_async_closures_in_stmt( fn rewrite_async_closures_in_expr( expr: &mut Expr, - work: &std::collections::HashSet, + work: &std::collections::HashSet, next_local_id: &mut LocalId, - next_func_id: &mut perry_types::FuncId, + next_func_id: &mut perry_hir::types::FuncId, ) { // Match-and-rewrite at the current level. let should_rewrite = if let Expr::Closure { @@ -1544,7 +1544,7 @@ fn rewrite_expr(expr: &mut Expr, had_await: &mut bool) { // Phase 3 (follow-up): `compile_closure` emits the wrapped form when the // closure's func_id is in `module.async_step_closures`. fn collect_async_step_closures(module: &mut Module) { - let mut found: std::collections::HashSet = + let mut found: std::collections::HashSet = std::collections::HashSet::new(); for func in &module.functions { scan_stmts_for_async_closures(&func.body, &mut found); @@ -1597,7 +1597,7 @@ fn collect_async_step_closures(module: &mut Module) { fn scan_stmts_for_async_closures( stmts: &[Stmt], - found: &mut std::collections::HashSet, + found: &mut std::collections::HashSet, ) { for s in stmts { scan_stmt_for_async_closures(s, found); @@ -1606,7 +1606,7 @@ fn scan_stmts_for_async_closures( fn scan_stmt_for_async_closures( stmt: &Stmt, - found: &mut std::collections::HashSet, + found: &mut std::collections::HashSet, ) { match stmt { Stmt::Let { init: Some(e), .. } => scan_expr_for_async_closures(e, found), @@ -1676,7 +1676,7 @@ fn scan_stmt_for_async_closures( fn scan_expr_for_async_closures( expr: &Expr, - found: &mut std::collections::HashSet, + found: &mut std::collections::HashSet, ) { if let Expr::Closure { func_id, @@ -1806,7 +1806,7 @@ mod computed_and_field_async_tests { // The minimal shape the collect scan matches: `async () => { await 1 }` // — `Expr::Closure { is_async, !is_generator }` whose body has an Await. - fn async_closure_with_await(func_id: perry_types::FuncId) -> Expr { + fn async_closure_with_await(func_id: perry_hir::types::FuncId) -> Expr { Expr::Closure { func_id, params: Vec::new(), @@ -1824,7 +1824,7 @@ mod computed_and_field_async_tests { } } - fn empty_fn(id: perry_types::FuncId, body: Vec) -> Function { + fn empty_fn(id: perry_hir::types::FuncId, body: Vec) -> Function { Function { id, name: String::new(), diff --git a/crates/perry-transform/src/deforest/mod.rs b/crates/perry-transform/src/deforest/mod.rs index 8caf26348d..fd33df2b94 100644 --- a/crates/perry-transform/src/deforest/mod.rs +++ b/crates/perry-transform/src/deforest/mod.rs @@ -67,8 +67,8 @@ //! - Consumer's `outer` is modified between `const child = f()` and //! the consume loop in a way that aliases `child`. +use perry_hir::types::{FuncId, LocalId, Type}; use perry_hir::{Expr, Function, Module, Stmt}; -use perry_types::{FuncId, LocalId, Type}; use std::collections::{HashMap, HashSet}; mod call_sites; diff --git a/crates/perry-transform/src/finally_inline.rs b/crates/perry-transform/src/finally_inline.rs index c48a5757ca..307f80ad33 100644 --- a/crates/perry-transform/src/finally_inline.rs +++ b/crates/perry-transform/src/finally_inline.rs @@ -74,8 +74,8 @@ use std::collections::HashMap; +use perry_hir::types::{LocalId, Type}; use perry_hir::{Expr, Module, Stmt}; -use perry_types::{LocalId, Type}; // #5293: the max-LocalId scan was copy-pasted here; route through the canonical // (exhaustive-walker-backed) implementation in `generator::id_scan` instead. diff --git a/crates/perry-transform/src/generator/id_scan.rs b/crates/perry-transform/src/generator/id_scan.rs index aed9c495dd..081d5a1274 100644 --- a/crates/perry-transform/src/generator/id_scan.rs +++ b/crates/perry-transform/src/generator/id_scan.rs @@ -519,7 +519,7 @@ pub fn scan_expr_for_max_func(expr: &Expr, max_id: &mut FuncId) { #[cfg(test)] mod tests { use super::*; - use perry_types::Type; + use perry_hir::types::Type; /// #4851: `Object.assign(p, { a: () => 1, b: () => 2 })` lowers to /// `ObjectAssign { sources: [New { __AnonShape, args: [Closure, ...] }] }`. diff --git a/crates/perry-transform/src/generator/mod.rs b/crates/perry-transform/src/generator/mod.rs index 29f2114ead..df00df9833 100644 --- a/crates/perry-transform/src/generator/mod.rs +++ b/crates/perry-transform/src/generator/mod.rs @@ -9,7 +9,7 @@ //! set __state and `return {value, done: false}`. use perry_hir::ir::*; -use perry_types::{FuncId, LocalId, Type}; +use perry_hir::types::{FuncId, LocalId, Type}; mod break_continue; mod helpers; diff --git a/crates/perry-transform/src/generator/per_iteration.rs b/crates/perry-transform/src/generator/per_iteration.rs index 8608593dc8..393d562fa8 100644 --- a/crates/perry-transform/src/generator/per_iteration.rs +++ b/crates/perry-transform/src/generator/per_iteration.rs @@ -78,9 +78,9 @@ use super::hoist_yields::expr_contains_yield; use crate::unroll::escape_analysis::{ count_local_refs_expr, count_local_refs_stmt, count_local_refs_stmts, }; +use perry_hir::types::{LocalId, Type}; use perry_hir::walker::{walk_expr_children, walk_expr_children_mut}; use perry_hir::{BinaryOp, Expr, Stmt, UpdateOp, WithSetFallback}; -use perry_types::{LocalId, Type}; use std::collections::{HashMap, HashSet}; /// Ids whose `Stmt::Let` the state-machine transform must leave in place so diff --git a/crates/perry-transform/src/inline/analysis.rs b/crates/perry-transform/src/inline/analysis.rs index 04439670e3..96fee7d96f 100644 --- a/crates/perry-transform/src/inline/analysis.rs +++ b/crates/perry-transform/src/inline/analysis.rs @@ -1,6 +1,6 @@ +use perry_hir::types::{FuncId, LocalId}; use perry_hir::walker::walk_expr_children; use perry_hir::{Class, Expr, Function, Module, Stmt}; -use perry_types::{FuncId, LocalId}; use std::collections::{HashMap, HashSet}; use super::*; diff --git a/crates/perry-transform/src/inline/call_inliner.rs b/crates/perry-transform/src/inline/call_inliner.rs index fe3c48337b..827489f341 100644 --- a/crates/perry-transform/src/inline/call_inliner.rs +++ b/crates/perry-transform/src/inline/call_inliner.rs @@ -1,5 +1,5 @@ +use perry_hir::types::{FuncId, LocalId, Type}; use perry_hir::{Expr, Function, Param, Stmt}; -use perry_types::{FuncId, LocalId, Type}; use std::collections::{HashMap, HashSet}; use super::*; diff --git a/crates/perry-transform/src/inline/closure_analysis.rs b/crates/perry-transform/src/inline/closure_analysis.rs index 8517c7007b..4357fbd8f7 100644 --- a/crates/perry-transform/src/inline/closure_analysis.rs +++ b/crates/perry-transform/src/inline/closure_analysis.rs @@ -1,6 +1,6 @@ +use perry_hir::types::LocalId; use perry_hir::walker::walk_expr_children; use perry_hir::{Expr, Function, Stmt}; -use perry_types::LocalId; use super::*; @@ -829,8 +829,8 @@ pub fn find_max_local_id(stmts: &[Stmt]) -> LocalId { #[cfg(test)] mod tests { use super::*; + use perry_hir::types::Type; use perry_hir::Param; - use perry_types::Type; use std::collections::HashSet; fn param(id: LocalId) -> Param { diff --git a/crates/perry-transform/src/inline/exact_receivers.rs b/crates/perry-transform/src/inline/exact_receivers.rs index e279db5b62..58df665219 100644 --- a/crates/perry-transform/src/inline/exact_receivers.rs +++ b/crates/perry-transform/src/inline/exact_receivers.rs @@ -1,6 +1,6 @@ +use perry_hir::types::LocalId; use perry_hir::walker::walk_expr_children; use perry_hir::{Expr, Stmt}; -use perry_types::LocalId; use std::collections::{HashMap, HashSet}; use super::*; diff --git a/crates/perry-transform/src/inline/factory_specialize.rs b/crates/perry-transform/src/inline/factory_specialize.rs index cf8490580a..4eb17a0e16 100644 --- a/crates/perry-transform/src/inline/factory_specialize.rs +++ b/crates/perry-transform/src/inline/factory_specialize.rs @@ -1,6 +1,6 @@ +use perry_hir::types::{FuncId, LocalId}; use perry_hir::walker::walk_expr_children; use perry_hir::{Class, Expr, Module, Stmt}; -use perry_types::{FuncId, LocalId}; use std::collections::{HashMap, HashSet}; use super::*; diff --git a/crates/perry-transform/src/inline/imul.rs b/crates/perry-transform/src/inline/imul.rs index b2f03f7627..79c9150629 100644 --- a/crates/perry-transform/src/inline/imul.rs +++ b/crates/perry-transform/src/inline/imul.rs @@ -1,5 +1,5 @@ +use perry_hir::types::{FuncId, LocalId}; use perry_hir::{BinaryOp, Expr, Function, Stmt}; -use perry_types::{FuncId, LocalId}; use std::collections::HashSet; pub fn detect_math_imul_polyfill(f: &Function) -> bool { diff --git a/crates/perry-transform/src/inline/mod.rs b/crates/perry-transform/src/inline/mod.rs index 92f1937cc0..4534f033ec 100644 --- a/crates/perry-transform/src/inline/mod.rs +++ b/crates/perry-transform/src/inline/mod.rs @@ -52,8 +52,8 @@ pub(crate) use substitute::{ pub(crate) use super_detect::MAX_INLINE_EXPR_RECURSION_DEPTH; pub(crate) use super_detect::{enter_inline_expr_recursion, method_contains_lexical_super}; +use perry_hir::types::{FuncId, LocalId, Type}; use perry_hir::{Class, Expr, Function, Module, Stmt}; -use perry_types::{FuncId, LocalId, Type}; use std::collections::{BTreeMap, HashMap, HashSet}; /// Maximum number of statements for a function to be considered for inlining diff --git a/crates/perry-transform/src/inline/substitute.rs b/crates/perry-transform/src/inline/substitute.rs index e17bcb7908..ac82a2be6a 100644 --- a/crates/perry-transform/src/inline/substitute.rs +++ b/crates/perry-transform/src/inline/substitute.rs @@ -1,6 +1,6 @@ +use perry_hir::types::LocalId; use perry_hir::walker::walk_expr_children_mut; use perry_hir::{Expr, Stmt}; -use perry_types::LocalId; use std::collections::HashMap; pub fn substitute_locals( diff --git a/crates/perry-transform/src/state_desugar.rs b/crates/perry-transform/src/state_desugar.rs index b68e9e7de9..52c652c098 100644 --- a/crates/perry-transform/src/state_desugar.rs +++ b/crates/perry-transform/src/state_desugar.rs @@ -55,9 +55,9 @@ //! HarmonyOS: this pass is gated OFF in `collect_modules.rs` so //! `perry-codegen-arkts`'s harvest stays the source of truth there. +use perry_hir::types::{FuncId, LocalId, Type}; use perry_hir::walker::walk_expr_children_mut; use perry_hir::{Expr, Module, Param, Stmt}; -use perry_types::{FuncId, LocalId, Type}; use std::collections::{HashMap, HashSet}; // #5293: the max-LocalId / max-FuncId scans were copy-pasted here; route through diff --git a/crates/perry-transform/src/unroll/escape_analysis.rs b/crates/perry-transform/src/unroll/escape_analysis.rs index 09d6cc125d..4427e679d0 100644 --- a/crates/perry-transform/src/unroll/escape_analysis.rs +++ b/crates/perry-transform/src/unroll/escape_analysis.rs @@ -5,9 +5,9 @@ //! must keep their original id across unrolled copies rather than being //! renamed per copy by `refresh_local_ids`. See `compute_loop_escaping_ids`. +use perry_hir::types::LocalId; use perry_hir::walker::walk_expr_children; use perry_hir::{Expr, Stmt}; -use perry_types::LocalId; use std::collections::{HashMap, HashSet}; /// #2308: compute the set of loop-body-declared local ids that are diff --git a/crates/perry-transform/src/unroll/mod.rs b/crates/perry-transform/src/unroll/mod.rs index faab87d7e2..2c771e7c59 100644 --- a/crates/perry-transform/src/unroll/mod.rs +++ b/crates/perry-transform/src/unroll/mod.rs @@ -68,9 +68,9 @@ //! kernel-bearing function. Larger trips would inflate code size faster //! than LLVM constant-folding can claw back. +use perry_hir::types::{FuncId, LocalId}; use perry_hir::walker::{walk_expr_children, walk_expr_children_mut}; use perry_hir::{CallArg, CompareOp, Expr, Module, Stmt, UpdateOp}; -use perry_types::{FuncId, LocalId}; use std::collections::HashMap; pub(crate) mod escape_analysis; @@ -974,8 +974,8 @@ fn refresh_in_expr( #[cfg(test)] mod tests { use super::*; + use perry_hir::types::Type; use perry_hir::BinaryOp; - use perry_types::Type; fn ivar(id: LocalId) -> Expr { Expr::LocalGet(id) diff --git a/crates/perry-types/Cargo.toml b/crates/perry-types/Cargo.toml deleted file mode 100644 index 5912e3305f..0000000000 --- a/crates/perry-types/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "perry-types" -version.workspace = true -edition.workspace = true -license.workspace = true -description = "Type system and type inference for Perry" - -[lints] -workspace = true - -[dependencies] -thiserror.workspace = true -anyhow.workspace = true diff --git a/crates/perry/Cargo.toml b/crates/perry/Cargo.toml index 8f21e19776..76f1fe4ae6 100644 --- a/crates/perry/Cargo.toml +++ b/crates/perry/Cargo.toml @@ -15,7 +15,6 @@ path = "src/main.rs" [dependencies] perry-parser.workspace = true swc_ecma_ast.workspace = true -perry-types.workspace = true perry-hir.workspace = true perry-transform.workspace = true perry-codegen.workspace = true diff --git a/crates/perry/src/commands/compile/bootstrap.rs b/crates/perry/src/commands/compile/bootstrap.rs index aa60be49b7..bcc8a927d1 100644 --- a/crates/perry/src/commands/compile/bootstrap.rs +++ b/crates/perry/src/commands/compile/bootstrap.rs @@ -163,12 +163,12 @@ pub(super) fn rerun_collect_with_class_field_types( if ctx.native_modules.len() <= 1 { return Ok(()); } - let mut field_map: HashMap> = HashMap::new(); + let mut field_map: HashMap> = HashMap::new(); let mut accessor_map: HashMap = HashMap::new(); let mut parent_map: HashMap = HashMap::new(); for hir_module in ctx.native_modules.values() { for class in &hir_module.classes { - let fields: Vec<(String, perry_types::Type)> = class + let fields: Vec<(String, perry_hir::types::Type)> = class .fields .iter() .map(|f| (f.name.clone(), f.ty.clone())) diff --git a/crates/perry/src/commands/compile/collect_modules.rs b/crates/perry/src/commands/compile/collect_modules.rs index 88f7032b28..7a8811d037 100644 --- a/crates/perry/src/commands/compile/collect_modules.rs +++ b/crates/perry/src/commands/compile/collect_modules.rs @@ -1860,7 +1860,7 @@ fn collect_module_finish( for prior_module in ctx.native_modules.values() { for class in &prior_module.classes { for f in &class.fields { - if let perry_types::Type::Named(field_class) = &f.ty { + if let perry_hir::types::Type::Named(field_class) = &f.ty { extra_class_fields .entry((class.name.clone(), f.name.clone())) .or_insert_with(|| field_class.clone()); diff --git a/crates/perry/src/commands/compile/object_cache.rs b/crates/perry/src/commands/compile/object_cache.rs index e92d16dc55..72395f51e3 100644 --- a/crates/perry/src/commands/compile/object_cache.rs +++ b/crates/perry/src/commands/compile/object_cache.rs @@ -204,7 +204,7 @@ impl Djb2Hasher { } } -fn stable_type_key(ty: &perry_types::Type) -> String { +fn stable_type_key(ty: &perry_hir::types::Type) -> String { format!("{:016x}", perry_hir::stable_hash::hash_type(ty)) } @@ -662,7 +662,7 @@ fn compute_object_cache_key_with_env( // Imported return types (HashMap — MUST sort). Type can contain nested // HashMaps (ObjectType::properties), so never use Debug output here. { - let mut v: Vec<(&String, &perry_types::Type)> = + let mut v: Vec<(&String, &perry_hir::types::Type)> = opts.imported_func_return_types.iter().collect(); v.sort_by(|a, b| a.0.cmp(b.0)); let s = v @@ -685,7 +685,7 @@ fn compute_object_cache_key_with_env( // Type aliases (HashMap — MUST sort). { - let mut v: Vec<(&String, &perry_types::Type)> = opts.type_aliases.iter().collect(); + let mut v: Vec<(&String, &perry_hir::types::Type)> = opts.type_aliases.iter().collect(); v.sort_by(|a, b| a.0.cmp(b.0)); let s = v .iter() diff --git a/crates/perry/src/commands/compile/object_cache/object_cache_tests.rs b/crates/perry/src/commands/compile/object_cache/object_cache_tests.rs index 24c8ed279d..03aa7c83db 100644 --- a/crates/perry/src/commands/compile/object_cache/object_cache_tests.rs +++ b/crates/perry/src/commands/compile/object_cache/object_cache_tests.rs @@ -292,24 +292,24 @@ fn key_stable_for_order_insensitive_graph_lists() { ); } -fn record_row_type(property_insert_order: &[&str]) -> perry_types::Type { +fn record_row_type(property_insert_order: &[&str]) -> perry_hir::types::Type { let mut properties = std::collections::HashMap::new(); for name in property_insert_order { let ty = match *name { - "name" => perry_types::Type::String, - "id" | "value" => perry_types::Type::Number, + "name" => perry_hir::types::Type::String, + "id" | "value" => perry_hir::types::Type::Number, _ => panic!("unexpected property"), }; properties.insert( (*name).to_string(), - perry_types::PropertyInfo { + perry_hir::types::PropertyInfo { ty, optional: false, readonly: false, }, ); } - perry_types::Type::Object(perry_types::ObjectType { + perry_hir::types::Type::Object(perry_hir::types::ObjectType { name: None, properties, property_order: Some(vec!["id".into(), "name".into(), "value".into()]), @@ -441,7 +441,7 @@ fn key_changes_with_imported_class_codegen_surface() { setter_names: vec![], parent_name: None, field_names: vec!["x".into()], - field_types: vec![perry_types::Type::Number], + field_types: vec![perry_hir::types::Type::Number], static_field_names: vec![], source_class_id: Some(42), }; @@ -481,7 +481,7 @@ fn key_changes_with_imported_class_codegen_surface() { assert_ne!(base_key, key_for(changed)); let mut changed = base; - changed.field_types = vec![perry_types::Type::String]; + changed.field_types = vec![perry_hir::types::Type::String]; assert_ne!(base_key, key_for(changed)); } diff --git a/crates/perry/src/commands/compile/run_pipeline.rs b/crates/perry/src/commands/compile/run_pipeline.rs index 8da57012de..ff839fd55c 100644 --- a/crates/perry/src/commands/compile/run_pipeline.rs +++ b/crates/perry/src/commands/compile/run_pipeline.rs @@ -561,7 +561,7 @@ pub fn run_with_parse_cache( // Collect all non-generic type aliases from all modules. // These are passed to each module's compiler so type_to_abi can resolve // Named("BlockTag") -> Union([...]) for correct ABI types in function signatures. - let mut all_type_aliases: std::collections::BTreeMap = + let mut all_type_aliases: std::collections::BTreeMap = std::collections::BTreeMap::new(); for hir_module in ctx.native_modules.values() { for ta in &hir_module.type_aliases { @@ -705,7 +705,7 @@ pub fn run_with_parse_cache( // from a real `...rest`. effect's `pipe`/`dual` are the load-bearing case. let mut exported_func_synthetic_arguments: BTreeSet<(String, String)> = BTreeSet::new(); // Build a map of all exported functions with their return types from all modules - let mut exported_func_return_types: BTreeMap<(String, String), perry_types::Type> = + let mut exported_func_return_types: BTreeMap<(String, String), perry_hir::types::Type> = BTreeMap::new(); // Set of exported functions that were declared `async` in their source module. // We track this separately because users routinely write `async function f() { ... }` @@ -1277,7 +1277,7 @@ pub fn run_with_parse_cache( // exported_async_funcs is propagated in the same loop so that re-exported async // functions remain marked async at every step in the chain. loop { - let mut new_func_entries: Vec<((String, String), perry_types::Type)> = Vec::new(); + let mut new_func_entries: Vec<((String, String), perry_hir::types::Type)> = Vec::new(); let mut new_async_entries: Vec<(String, String)> = Vec::new(); for (path, hir_module) in &ctx.native_modules { let path_str = path.to_string_lossy().to_string(); @@ -2292,7 +2292,7 @@ pub fn run_with_parse_cache( std::collections::HashSet::new(); let mut imported_param_counts: std::collections::HashMap = std::collections::HashMap::new(); - let mut imported_return_types: std::collections::HashMap = + let mut imported_return_types: std::collections::HashMap = std::collections::HashMap::new(); // Issue #608 — set of imported function names whose source-side // signature has a trailing `...rest` parameter. Built alongside @@ -3662,8 +3662,8 @@ pub fn run_with_parse_cache( && !all_program_type_names.contains(name) && !is_builtin_type_name(name) }; - fn type_has_unresolved bool>(ty: &perry_types::Type, check: &F) -> bool { - use perry_types::Type; + fn type_has_unresolved bool>(ty: &perry_hir::types::Type, check: &F) -> bool { + use perry_hir::types::Type; match ty { Type::Named(name) => check(name), Type::Generic { base, type_args } => { @@ -3866,8 +3866,8 @@ pub fn run_with_parse_cache( let refs: Vec<(String, bool)> = field_types_clone .iter() .filter_map(|ty| match ty { - perry_types::Type::Named(n) => Some(n.clone()), - perry_types::Type::Generic { base, .. } => Some(base.clone()), + perry_hir::types::Type::Named(n) => Some(n.clone()), + perry_hir::types::Type::Generic { base, .. } => Some(base.clone()), _ => None, }) .map(|n| (n, false)) @@ -3958,7 +3958,7 @@ pub fn run_with_parse_cache( } // Type aliases from all modules - let type_alias_map: std::collections::HashMap = + let type_alias_map: std::collections::HashMap = all_type_aliases .iter() .map(|(k, v)| (k.clone(), v.clone())) diff --git a/crates/perry/src/commands/compile/types.rs b/crates/perry/src/commands/compile/types.rs index 9c7985d966..64bb7a9353 100644 --- a/crates/perry/src/commands/compile/types.rs +++ b/crates/perry/src/commands/compile/types.rs @@ -717,7 +717,7 @@ pub struct CompilationContext { /// elsewhere) silently iterates 0 times because the iterable's static /// type is unknown and the `SetValues`/`MapEntries` wrap is skipped at /// `lower_decl.rs:3737-3747`. See ECS demo-simple repro / #412. - pub cross_module_class_field_types: HashMap>, + pub cross_module_class_field_types: HashMap>, /// Cross-module class accessor names collected alongside field types. /// HIR lowering uses this to avoid inferring subclass `this.x = ...` /// constructor writes as data fields when `x` is an inherited accessor diff --git a/crates/perry/src/commands/typecheck.rs b/crates/perry/src/commands/typecheck.rs index 8bd1206468..58f6c794de 100644 --- a/crates/perry/src/commands/typecheck.rs +++ b/crates/perry/src/commands/typecheck.rs @@ -4,7 +4,7 @@ //! over stdin/stdout using the msgpack-based IPC protocol. use anyhow::{anyhow, Result}; -use perry_types::Type; +use perry_hir::types::Type; use std::collections::HashMap; use std::io::{Read, Write}; use std::path::{Path, PathBuf}; diff --git a/docs/po/de.po b/docs/po/de.po index 0a5800c3d6..a8e6b6f437 100644 --- a/docs/po/de.po +++ b/docs/po/de.po @@ -57142,7 +57142,7 @@ msgid "SWC wrapper for TypeScript parsing" msgstr "SWC-Wrapper für TypeScript-Parsing" #: src/contributing/architecture.md:27 -msgid "`perry-types`" +msgid "`perry-hir::types`" msgstr "" #: src/contributing/architecture.md:27 diff --git a/docs/po/es.po b/docs/po/es.po index 742f489fae..1c4193071f 100644 --- a/docs/po/es.po +++ b/docs/po/es.po @@ -57572,7 +57572,7 @@ msgid "SWC wrapper for TypeScript parsing" msgstr "Wrapper de SWC para el análisis de TypeScript" #: src/contributing/architecture.md:27 -msgid "`perry-types`" +msgid "`perry-hir::types`" msgstr "" #: src/contributing/architecture.md:27 diff --git a/docs/po/fr.po b/docs/po/fr.po index cdda663fd5..e8a21a0bec 100644 --- a/docs/po/fr.po +++ b/docs/po/fr.po @@ -57707,7 +57707,7 @@ msgid "SWC wrapper for TypeScript parsing" msgstr "Wrapper SWC pour l'analyse TypeScript" #: src/contributing/architecture.md:27 -msgid "`perry-types`" +msgid "`perry-hir::types`" msgstr "" #: src/contributing/architecture.md:27 diff --git a/docs/po/id.po b/docs/po/id.po index 961e1a2770..e07ebe868f 100644 --- a/docs/po/id.po +++ b/docs/po/id.po @@ -56544,8 +56544,8 @@ msgid "SWC wrapper for TypeScript parsing" msgstr "Wrapper SWC untuk parsing TypeScript" #: src/contributing/architecture.md:27 -msgid "`perry-types`" -msgstr "`perry-types`" +msgid "`perry-hir::types`" +msgstr "`perry-hir::types`" #: src/contributing/architecture.md:27 msgid "Type system definitions" diff --git a/docs/po/it.po b/docs/po/it.po index 5b3b20414d..2e9b5ff475 100644 --- a/docs/po/it.po +++ b/docs/po/it.po @@ -57019,7 +57019,7 @@ msgid "SWC wrapper for TypeScript parsing" msgstr "Wrapper SWC per il parsing TypeScript" #: src/contributing/architecture.md:27 -msgid "`perry-types`" +msgid "`perry-hir::types`" msgstr "" #: src/contributing/architecture.md:27 diff --git a/docs/po/ja.po b/docs/po/ja.po index f0b13be5eb..371e8ac3e8 100644 --- a/docs/po/ja.po +++ b/docs/po/ja.po @@ -54105,7 +54105,7 @@ msgid "SWC wrapper for TypeScript parsing" msgstr "TypeScriptパース用のSWCラッパー" #: src/contributing/architecture.md:27 -msgid "`perry-types`" +msgid "`perry-hir::types`" msgstr "" #: src/contributing/architecture.md:27 diff --git a/docs/po/ko.po b/docs/po/ko.po index e8d8a61468..079f7f380e 100644 --- a/docs/po/ko.po +++ b/docs/po/ko.po @@ -54065,7 +54065,7 @@ msgid "SWC wrapper for TypeScript parsing" msgstr "TypeScript 파싱을 위한 SWC 래퍼" #: src/contributing/architecture.md:27 -msgid "`perry-types`" +msgid "`perry-hir::types`" msgstr "" #: src/contributing/architecture.md:27 diff --git a/docs/po/messages.pot b/docs/po/messages.pot index 61db3242b3..5e1ba90a62 100644 --- a/docs/po/messages.pot +++ b/docs/po/messages.pot @@ -50905,7 +50905,7 @@ msgid "SWC wrapper for TypeScript parsing" msgstr "" #: src/contributing/architecture.md:27 -msgid "`perry-types`" +msgid "`perry-hir::types`" msgstr "" #: src/contributing/architecture.md:27 diff --git a/docs/po/th.po b/docs/po/th.po index c8574af103..7e6b42595e 100644 --- a/docs/po/th.po +++ b/docs/po/th.po @@ -56016,7 +56016,7 @@ msgid "SWC wrapper for TypeScript parsing" msgstr "SWC wrapper สำหรับการ parse TypeScript" #: src/contributing/architecture.md:27 -msgid "`perry-types`" +msgid "`perry-hir::types`" msgstr "" #: src/contributing/architecture.md:27 diff --git a/docs/po/vi.po b/docs/po/vi.po index a2369d5283..9e65129f5d 100644 --- a/docs/po/vi.po +++ b/docs/po/vi.po @@ -56465,7 +56465,7 @@ msgid "SWC wrapper for TypeScript parsing" msgstr "Wrapper SWC để phân tích TypeScript" #: src/contributing/architecture.md:27 -msgid "`perry-types`" +msgid "`perry-hir::types`" msgstr "" #: src/contributing/architecture.md:27 diff --git a/docs/po/zh-CN.po b/docs/po/zh-CN.po index da0100af55..8d2977880f 100644 --- a/docs/po/zh-CN.po +++ b/docs/po/zh-CN.po @@ -53485,8 +53485,8 @@ msgid "SWC wrapper for TypeScript parsing" msgstr "用于 TypeScript 解析的 SWC 封装" #: src/contributing/architecture.md:27 -msgid "`perry-types`" -msgstr "`perry-types`" +msgid "`perry-hir::types`" +msgstr "`perry-hir::types`" #: src/contributing/architecture.md:27 msgid "Type system definitions" diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index b694538924..8489bd9a3a 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -175,5 +175,6 @@ # Contributing - [Architecture](contributing/architecture.md) +- [Crate policy](contributing/crate-policy.md) - [Building from Source](contributing/building.md) - [Releasing Perry](contributing/releasing.md) diff --git a/docs/src/contributing/architecture.md b/docs/src/contributing/architecture.md index 480aa94f4a..bcb589daa1 100644 --- a/docs/src/contributing/architecture.md +++ b/docs/src/contributing/architecture.md @@ -1,6 +1,7 @@ # Architecture -This is a brief overview for contributors. For detailed implementation notes, see the project's `CLAUDE.md`. +This is a brief overview for contributors. The rules for creating, retaining, +or removing workspace crates live in the [crate policy](crate-policy.md). ## Compilation Pipeline @@ -24,19 +25,19 @@ Native Executable |-------|---------| | `perry` | CLI driver, command parsing, compilation orchestration | | `perry-parser` | SWC wrapper for TypeScript parsing | -| `perry-types` | Type system definitions | -| `perry-hir` | HIR data structures (`ir.rs`) and AST→HIR lowering (`lower.rs`) | +| `perry-hir` | HIR types and data structures, plus AST→HIR lowering | | `perry-transform` | IR passes: function inlining, closure conversion, async lowering | -| `perry-codegen-llvm` | LLVM-based native code generation | +| `perry-codegen` | LLVM-based native code generation | | `perry-codegen-wasm` | WebAssembly code generation for `--target web` / `--target wasm` (HIR → WASM bytecode + JS bridge) | | `perry-codegen-js` | Legacy JavaScript code generator (still present for the JS minifier; the JS-emit `--target web` path was consolidated into `perry-codegen-wasm`) | | `perry-codegen-swiftui` | SwiftUI code generation for WidgetKit extensions | | `perry-runtime` | Runtime library: NaN-boxed values, GC, arena allocator, objects, arrays, strings | -| `perry-stdlib` | Node.js API implementations: mysql2, redis, fastify, bcrypt, etc. | -| `perry-ui` | Shared UI types | +| `perry-ffi` | Stable interface used by native binding crates | +| `perry-stdlib` | Runtime-coupled Node.js and Perry standard-library implementations | +| `perry-ext-*` | Independently linked native bindings selected per program | +| `perry-ui` / `perry-ui-model` | Shared UI interface and public model metadata | | `perry-ui-macos` | macOS UI (AppKit) | | `perry-ui-ios` | iOS UI (UIKit) | -| `perry-jsruntime` | JavaScript interop via QuickJS | ## Key Concepts @@ -68,7 +69,7 @@ UI widgets are represented as small integer handles NaN-boxed with `POINTER_TAG` The codegen crate is organized into focused modules: ``` -perry-codegen-llvm/src/ +perry-codegen/src/ codegen.rs # Main entry, module compilation types.rs # Type definitions, context structs util.rs # Helper functions diff --git a/docs/src/contributing/building.md b/docs/src/contributing/building.md index 2b031a32d4..036d78be79 100644 --- a/docs/src/contributing/building.md +++ b/docs/src/contributing/building.md @@ -8,15 +8,20 @@ ## Build ```bash -git clone https://github.com/skelpo/perry.git +git clone https://github.com/PerryTS/perry.git cd perry -# Build all crates (release mode recommended) +# Build the default product and its dependency closure cargo build --release ``` The binary is at `target/release/perry`. +The workspace deliberately defaults to the `perry` CLI. Bindings, platform +adapters, test support, and release-only archives are selected explicitly by +their CI/release jobs. Workspace-wide host commands must use the centralized +platform exclusions described in the [crate policy](crate-policy.md). + ## Build taxonomy (dev / release / dist) Perry has three build profiles, each tuned for a different job (#5422): @@ -75,12 +80,15 @@ the full feature list (`full-cli`, `publish-cli`, `backend-wasm`, …). ## Run Tests ```bash -# All tests (exclude iOS crate on non-iOS host) -cargo test --workspace --exclude perry-ui-ios +# Product unit targets +cargo test -p perry --bins + +# Inspect the nightly CI test scope (all Linux-compatible test crates) +python3 scripts/ci_test_scope.py --full | python3 scripts/ci_test_scope.py [--full] """ @@ -31,20 +31,11 @@ import subprocess import sys -# Excluded from the Linux cargo-test gate (see test.yml): cross-host UI backends -# (objc2 / win32 / NDK / gtk) and the doc fixture crate. -EXCLUDED = { - "perry-ui-macos", - "perry-ui-ios", - "perry-ui-visionos", - "perry-ui-tvos", - "perry-ui-watchos", - "perry-ui-gtk4", - "perry-ui-android", - "perry-ui-windows", - "perry-ui-windows-winui", - "perry-doc-fixture-my-bindings", -} +from workspace_architecture import excluded_members, load_policy + +# One source of truth shared with Clippy and coverage. The test scope adds the +# documentation fixture because the fixture has no product tests of its own. +EXCLUDED = excluded_members(load_policy(), "linux-test") INFRA_PREFIXES = (".github/", "scripts/", "rust-toolchain") diff --git a/scripts/workspace_architecture.py b/scripts/workspace_architecture.py new file mode 100644 index 0000000000..3f2325826f --- /dev/null +++ b/scripts/workspace_architecture.py @@ -0,0 +1,523 @@ +#!/usr/bin/env python3 +"""Audit Perry's Cargo workspace shape and architectural policy. + +The Cargo workspace is the source of truth for packages and dependency edges; +`workspace-architecture.json` records the human decision for every package. +This script joins both views so CI can reject accidental members, unclassified +crates, expanded default builds, missing workspace lints, and new production +dependencies from native bindings into `perry-runtime`. + +Usage: + python3 scripts/workspace_architecture.py --check --print-summary + python3 scripts/workspace_architecture.py --markdown + python3 scripts/workspace_architecture.py --json + python3 scripts/workspace_architecture.py --self-test +""" + +import argparse +import glob +import json +import re +import subprocess +import sys +import unittest +from collections import defaultdict +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +ROOT_MANIFEST = ROOT / "Cargo.toml" +POLICY_PATH = ROOT / "workspace-architecture.json" + +ALLOWED_CATEGORIES = { + "artifact-wrapper", + "binding", + "codegen-adapter", + "compiler-core", + "fixture", + "platform-adapter", + "platform-core", + "product", + "runtime-core", + "test-support", + "tool", +} +ALLOWED_DECISIONS = {"keep", "merge", "externalize", "remove", "review"} +SUPPORTED_SCHEMA_VERSION = 1 + + +def load_metadata(): + raw = subprocess.check_output( + ["cargo", "metadata", "--no-deps", "--format-version", "1"], + cwd=str(ROOT), + ) + return json.loads(raw) + + +def load_policy(): + with POLICY_PATH.open(encoding="utf-8") as handle: + policy = json.load(handle) + validate_policy_schema(policy) + return policy + + +def validate_policy_schema(policy): + version = policy.get("schema_version") + if version != SUPPORTED_SCHEMA_VERSION: + raise ValueError( + "unsupported workspace architecture schema version: {!r}; " + "expected {}".format(version, SUPPORTED_SCHEMA_VERSION) + ) + + +def excluded_members(policy, scope): + """Return the centrally maintained Linux exclusion set for a CI scope.""" + ci = policy.get("ci", {}) + excluded = set(ci.get("linux_host_excluded_members", [])) + if scope == "linux-test": + excluded.update(ci.get("linux_test_extra_excluded_members", [])) + elif scope != "host-compatible": + raise ValueError("unknown package scope: {}".format(scope)) + return excluded + + +def package_scope(metadata, policy, scope): + packages = workspace_packages(metadata) + if scope == "product": + return ["perry"] + return sorted(set(packages) - excluded_members(policy, scope)) + + +def workspace_packages(metadata): + workspace_ids = set(metadata["workspace_members"]) + return { + package["name"]: package + for package in metadata["packages"] + if package["id"] in workspace_ids + } + + +def _workspace_section(text): + match = re.search(r"(?ms)^\[workspace\]\s*(.*?)(?=^\[[^\n]+\]|\Z)", text) + if not match: + raise ValueError("Cargo.toml has no [workspace] section") + return match.group(1) + + +def _quoted_list(section, key): + match = re.search( + r"(?ms)^" + re.escape(key) + r"\s*=\s*\[(.*?)\]", section + ) + if not match: + raise ValueError("[workspace] has no {} list".format(key)) + return re.findall(r'"([^"]+)"', match.group(1)) + + +def declared_workspace_paths(manifest_text): + section = _workspace_section(manifest_text) + declared = set() + for pattern in _quoted_list(section, "members"): + if any(character in pattern for character in "*?["): + matches = glob.glob(str(ROOT / pattern)) + else: + matches = [str(ROOT / pattern)] + for match in matches: + path = Path(match) + crate_dir = path.parent if path.name == "Cargo.toml" else path + declared.add(crate_dir.resolve()) + return declared + + +def declared_default_paths(manifest_text): + section = _workspace_section(manifest_text) + return { + (ROOT / path).resolve() + for path in _quoted_list(section, "default-members") + } + + +def package_path(package): + return Path(package["manifest_path"]).resolve().parent + + +def production_internal_dependencies(package, packages): + names = set(packages) + return { + dep["name"] + for dep in package.get("dependencies", []) + if dep["name"] in names and dep.get("kind") != "dev" + } + + +def dependency_closure(packages, seeds): + graph = { + name: production_internal_dependencies(package, packages) + for name, package in packages.items() + } + reached = set(seeds) + pending = list(seeds) + while pending: + current = pending.pop() + for dependency in graph.get(current, ()): + if dependency not in reached: + reached.add(dependency) + pending.append(dependency) + return reached + + +def rust_metrics(package): + source = package_path(package) / "src" + files = sorted(source.rglob("*.rs")) if source.exists() else [] + lines = 0 + for path in files: + try: + with path.open(encoding="utf-8", errors="ignore") as handle: + lines += sum(1 for _ in handle) + except OSError: + pass + return {"rust_files": len(files), "rust_lines": lines} + + +def has_workspace_lints(package): + text = Path(package["manifest_path"]).read_text(encoding="utf-8") + return bool( + re.search( + r"(?ms)^\[lints\]\s*(.*?)(?=^\[[^\n]+\]|\Z)", text + ) + and re.search( + r"(?m)^\s*workspace\s*=\s*true\s*$", + re.search( + r"(?ms)^\[lints\]\s*(.*?)(?=^\[[^\n]+\]|\Z)", text + ).group(1), + ) + ) + + +def build_inventory(metadata, policy): + packages = workspace_packages(metadata) + default_ids = set(metadata["workspace_default_members"]) + default_names = { + package["name"] + for package in packages.values() + if package["id"] in default_ids + } + reverse = defaultdict(set) + for name, package in packages.items(): + for dependency in production_internal_dependencies(package, packages): + reverse[dependency].add(name) + + rows = [] + decisions = policy.get("crates", {}) + for name, package in sorted(packages.items()): + metrics = rust_metrics(package) + classification = decisions.get(name, {}) + rows.append( + { + "name": name, + "path": str(package_path(package).relative_to(ROOT)), + "category": classification.get("category", "unclassified"), + "decision": classification.get("decision", "unclassified"), + "default_member": name in default_names, + "production_dependencies": sorted( + production_internal_dependencies(package, packages) + ), + "reverse_dependencies": sorted(reverse[name]), + "rust_files": metrics["rust_files"], + "rust_lines": metrics["rust_lines"], + "workspace_lints": has_workspace_lints(package), + } + ) + return rows + + +def audit(metadata, policy, manifest_text): + errors = [] + packages = workspace_packages(metadata) + effective_paths = {package_path(package) for package in packages.values()} + declared_paths = declared_workspace_paths(manifest_text) + + implicit = effective_paths - declared_paths + stale = declared_paths - effective_paths + if implicit: + errors.append( + "implicit workspace members: " + + ", ".join(str(path.relative_to(ROOT)) for path in sorted(implicit)) + ) + if stale: + errors.append( + "declared workspace paths not present in cargo metadata: " + + ", ".join(str(path.relative_to(ROOT)) for path in sorted(stale)) + ) + + policy_crates = set(policy.get("crates", {})) + package_names = set(packages) + missing = package_names - policy_crates + removed = policy_crates - package_names + if missing: + errors.append("unclassified workspace crates: " + ", ".join(sorted(missing))) + if removed: + errors.append("policy entries without workspace crates: " + ", ".join(sorted(removed))) + + for name, classification in sorted(policy.get("crates", {}).items()): + category = classification.get("category") + decision = classification.get("decision") + if category not in ALLOWED_CATEGORIES: + errors.append("{} has invalid category {!r}".format(name, category)) + if decision not in ALLOWED_DECISIONS: + errors.append("{} has invalid decision {!r}".format(name, decision)) + + default_ids = set(metadata["workspace_default_members"]) + actual_defaults = sorted( + package["name"] + for package in packages.values() + if package["id"] in default_ids + ) + expected_defaults = sorted(policy.get("expected_default_members", [])) + if actual_defaults != expected_defaults: + errors.append( + "default members differ: expected {}, got {}".format( + expected_defaults, actual_defaults + ) + ) + + manifest_defaults = declared_default_paths(manifest_text) + metadata_defaults = { + package_path(package) + for package in packages.values() + if package["id"] in default_ids + } + if manifest_defaults != metadata_defaults: + errors.append("Cargo default-members do not match cargo metadata") + + runtime_dependents = sorted( + name + for name, package in packages.items() + if name.startswith("perry-ext-") + and "perry-runtime" in production_internal_dependencies(package, packages) + ) + allowed_runtime_dependents = sorted( + policy.get("allowed_binding_runtime_dependencies", []) + ) + if runtime_dependents != allowed_runtime_dependents: + errors.append( + "production binding -> runtime edges differ: expected {}, got {}".format( + allowed_runtime_dependents, runtime_dependents + ) + ) + + missing_lints = sorted( + name for name, package in packages.items() if not has_workspace_lints(package) + ) + if missing_lints: + errors.append( + "crates missing [lints] workspace = true: " + + ", ".join(missing_lints) + ) + + ci = policy.get("ci", {}) + host_excluded = set(ci.get("linux_host_excluded_members", [])) + test_extra_excluded = set(ci.get("linux_test_extra_excluded_members", [])) + unknown_exclusions = (host_excluded | test_extra_excluded) - package_names + if unknown_exclusions: + errors.append( + "CI exclusions without workspace crates: " + + ", ".join(sorted(unknown_exclusions)) + ) + non_platform_host_exclusions = sorted( + name + for name in host_excluded + if policy.get("crates", {}).get(name, {}).get("category") + != "platform-adapter" + ) + if non_platform_host_exclusions: + errors.append( + "Linux host exclusions must be platform adapters: " + + ", ".join(non_platform_host_exclusions) + ) + + baseline = policy.get("baseline", {}) + cli_closure = sorted(dependency_closure(packages, {"perry"})) + default_closure = sorted(dependency_closure(packages, set(actual_defaults))) + decision_counts = defaultdict(int) + for classification in policy.get("crates", {}).values(): + decision_counts[classification.get("decision")] += 1 + expected_baseline = { + "workspace_members": len(packages), + "default_dependency_closure": default_closure, + "perry_dependency_closure": cli_closure, + "decision_counts": dict(sorted(decision_counts.items())), + } + if baseline != expected_baseline: + errors.append( + "architecture baseline differs; review the structural change and " + "refresh workspace-architecture.json" + ) + + return errors + + +def summary(metadata, policy): + packages = workspace_packages(metadata) + default_ids = set(metadata["workspace_default_members"]) + default_names = { + package["name"] + for package in packages.values() + if package["id"] in default_ids + } + cli_closure = dependency_closure(packages, {"perry"}) + default_closure = dependency_closure(packages, default_names) + decisions = defaultdict(int) + categories = defaultdict(int) + for classification in policy.get("crates", {}).values(): + decisions[classification["decision"]] += 1 + categories[classification["category"]] += 1 + return { + "workspace_members": len(packages), + "default_members": len(default_names), + "default_dependency_closure": len(default_closure), + "perry_dependency_closure": len(cli_closure), + "categories": dict(sorted(categories.items())), + "decisions": dict(sorted(decisions.items())), + } + + +def print_summary(data): + print("Workspace architecture summary") + print(" workspace members: {}".format(data["workspace_members"])) + print(" default members: {}".format(data["default_members"])) + print(" default dependency closure: {}".format(data["default_dependency_closure"])) + print(" perry dependency closure: {}".format(data["perry_dependency_closure"])) + print(" decisions: {}".format( + ", ".join("{}={}".format(k, v) for k, v in data["decisions"].items()) + )) + + +def print_markdown(rows): + print( + "| Crate | Path | Category | Decision | Default | Rust LOC | " + "Internal dependencies | Internal consumers | Workspace lints |" + ) + print("|---|---|---|---|---:|---:|---|---|---:|") + for row in rows: + dependencies = ", ".join( + "`{}`".format(x) for x in row["production_dependencies"] + ) or "—" + consumers = ", ".join( + "`{}`".format(x) for x in row["reverse_dependencies"] + ) or "—" + print( + "| `{}` | `{}` | {} | {} | {} | {} | {} | {} | {} |".format( + row["name"], + row["path"], + row["category"], + row["decision"], + "yes" if row["default_member"] else "no", + row["rust_lines"], + dependencies, + consumers, + "yes" if row["workspace_lints"] else "no", + ) + ) + + +class HelpersTest(unittest.TestCase): + def test_workspace_lists_are_scoped_to_workspace_section(self): + text = ''' +[workspace] +members = ["crates/a", "crates/b"] +default-members = ["crates/a"] + +[workspace.dependencies] +something = "1" +''' + section = _workspace_section(text) + self.assertEqual(_quoted_list(section, "members"), ["crates/a", "crates/b"]) + self.assertEqual(_quoted_list(section, "default-members"), ["crates/a"]) + + def test_dependency_closure_ignores_dev_dependencies(self): + packages = { + "a": {"dependencies": [{"name": "b", "kind": None}]}, + "b": {"dependencies": [{"name": "c", "kind": "dev"}]}, + "c": {"dependencies": []}, + } + self.assertEqual(dependency_closure(packages, {"a"}), {"a", "b"}) + + def test_ci_scopes_share_the_host_exclusion_source(self): + policy = { + "ci": { + "linux_host_excluded_members": ["ui"], + "linux_test_extra_excluded_members": ["fixture"], + } + } + self.assertEqual(excluded_members(policy, "host-compatible"), {"ui"}) + self.assertEqual(excluded_members(policy, "linux-test"), {"ui", "fixture"}) + + def test_unknown_ci_scope_is_rejected(self): + with self.assertRaises(ValueError): + excluded_members({}, "typo") + + def test_policy_schema_version_is_required(self): + with self.assertRaisesRegex(ValueError, "schema version"): + validate_policy_schema({}) + + def test_unknown_policy_schema_version_is_rejected(self): + with self.assertRaisesRegex(ValueError, "schema version"): + validate_policy_schema({"schema_version": 2}) + + def test_supported_policy_schema_version_is_accepted(self): + validate_policy_schema({"schema_version": SUPPORTED_SCHEMA_VERSION}) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--check", action="store_true") + parser.add_argument("--json", action="store_true") + parser.add_argument("--markdown", action="store_true") + parser.add_argument("--print-summary", action="store_true") + parser.add_argument( + "--print-package-scope", + choices=("product", "host-compatible", "linux-test"), + ) + parser.add_argument( + "--print-excluded-scope", + choices=("host-compatible", "linux-test"), + ) + parser.add_argument("--self-test", action="store_true") + args = parser.parse_args() + + if args.self_test: + suite = unittest.defaultTestLoader.loadTestsFromTestCase(HelpersTest) + return 0 if unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful() else 1 + + metadata = load_metadata() + policy = load_policy() + manifest_text = ROOT_MANIFEST.read_text(encoding="utf-8") + if args.print_package_scope: + print("\n".join(package_scope(metadata, policy, args.print_package_scope))) + return 0 + if args.print_excluded_scope: + print("\n".join(sorted(excluded_members(policy, args.print_excluded_scope)))) + return 0 + + rows = build_inventory(metadata, policy) + data = summary(metadata, policy) + + if args.json: + print(json.dumps({"summary": data, "crates": rows}, indent=2, sort_keys=True)) + elif args.markdown: + print_markdown(rows) + elif args.print_summary or not args.check: + print_summary(data) + + if args.check: + errors = audit(metadata, policy, manifest_text) + if errors: + for error in errors: + print("workspace architecture error: {}".format(error), file=sys.stderr) + return 1 + print("Workspace architecture policy: OK") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/workspace-architecture.json b/workspace-architecture.json new file mode 100644 index 0000000000..c42e06af64 --- /dev/null +++ b/workspace-architecture.json @@ -0,0 +1,383 @@ +{ + "schema_version": 1, + "expected_default_members": [ + "perry" + ], + "allowed_binding_runtime_dependencies": [ + "perry-ext-http" + ], + "ci": { + "linux_host_excluded_members": [ + "perry-ui-android", + "perry-ui-gtk4", + "perry-ui-ios", + "perry-ui-macos", + "perry-ui-tvos", + "perry-ui-visionos", + "perry-ui-watchos", + "perry-ui-windows", + "perry-ui-windows-winui" + ], + "linux_test_extra_excluded_members": [ + "perry-doc-fixture-my-bindings" + ] + }, + "baseline": { + "workspace_members": 77, + "default_dependency_closure": [ + "perry", + "perry-api-manifest", + "perry-codegen", + "perry-codegen-arkts", + "perry-codegen-glance", + "perry-codegen-js", + "perry-codegen-swiftui", + "perry-codegen-wasm", + "perry-codegen-wear-tiles", + "perry-diagnostics", + "perry-dispatch", + "perry-hir", + "perry-parser", + "perry-runtime", + "perry-transform", + "perry-ui-model", + "perry-updater" + ], + "perry_dependency_closure": [ + "perry", + "perry-api-manifest", + "perry-codegen", + "perry-codegen-arkts", + "perry-codegen-glance", + "perry-codegen-js", + "perry-codegen-swiftui", + "perry-codegen-wasm", + "perry-codegen-wear-tiles", + "perry-diagnostics", + "perry-dispatch", + "perry-hir", + "perry-parser", + "perry-runtime", + "perry-transform", + "perry-ui-model", + "perry-updater" + ], + "decision_counts": { + "externalize": 29, + "keep": 42, + "merge": 2, + "remove": 1, + "review": 3 + } + }, + "crates": { + "perry": { + "category": "product", + "decision": "keep" + }, + "perry-api-manifest": { + "category": "compiler-core", + "decision": "keep" + }, + "perry-audio-miniaudio": { + "category": "platform-core", + "decision": "keep" + }, + "perry-codegen": { + "category": "compiler-core", + "decision": "keep" + }, + "perry-codegen-arkts": { + "category": "codegen-adapter", + "decision": "keep" + }, + "perry-codegen-glance": { + "category": "codegen-adapter", + "decision": "review" + }, + "perry-codegen-js": { + "category": "codegen-adapter", + "decision": "keep" + }, + "perry-codegen-swiftui": { + "category": "codegen-adapter", + "decision": "review" + }, + "perry-codegen-wasm": { + "category": "codegen-adapter", + "decision": "keep" + }, + "perry-codegen-wear-tiles": { + "category": "codegen-adapter", + "decision": "review" + }, + "perry-container-compose": { + "category": "tool", + "decision": "keep" + }, + "perry-container-e2e": { + "category": "test-support", + "decision": "keep" + }, + "perry-diagnostics": { + "category": "compiler-core", + "decision": "keep" + }, + "perry-dispatch": { + "category": "compiler-core", + "decision": "keep" + }, + "perry-doc-fixture-my-bindings": { + "category": "fixture", + "decision": "keep" + }, + "perry-doc-tests": { + "category": "tool", + "decision": "keep" + }, + "perry-ext-ads": { + "category": "binding", + "decision": "remove" + }, + "perry-ext-argon2": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-axios": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-bcrypt": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-better-sqlite3": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-cheerio": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-commander": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-cron": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-dayjs": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-decimal": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-dotenv": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-ethers": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-events": { + "category": "binding", + "decision": "keep" + }, + "perry-ext-exponential-backoff": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-fastify": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-fetch": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-http": { + "category": "binding", + "decision": "keep" + }, + "perry-ext-http-server": { + "category": "binding", + "decision": "merge" + }, + "perry-ext-ioredis": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-jsonwebtoken": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-lru-cache": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-moment": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-mongodb": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-mysql2": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-nanoid": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-net": { + "category": "binding", + "decision": "keep" + }, + "perry-ext-nodemailer": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-pdf": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-pg": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-ratelimit": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-sharp": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-slugify": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-streams": { + "category": "binding", + "decision": "keep" + }, + "perry-ext-uuid": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-validator": { + "category": "binding", + "decision": "externalize" + }, + "perry-ext-ws": { + "category": "binding", + "decision": "keep" + }, + "perry-ext-zlib": { + "category": "binding", + "decision": "keep" + }, + "perry-ffi": { + "category": "runtime-core", + "decision": "keep" + }, + "perry-hir": { + "category": "compiler-core", + "decision": "keep" + }, + "perry-parser": { + "category": "compiler-core", + "decision": "keep" + }, + "perry-runtime": { + "category": "runtime-core", + "decision": "keep" + }, + "perry-runtime-static": { + "category": "artifact-wrapper", + "decision": "keep" + }, + "perry-stdlib": { + "category": "runtime-core", + "decision": "keep" + }, + "perry-stdlib-static": { + "category": "artifact-wrapper", + "decision": "keep" + }, + "perry-transform": { + "category": "compiler-core", + "decision": "keep" + }, + "perry-ui": { + "category": "platform-core", + "decision": "keep" + }, + "perry-ui-android": { + "category": "platform-adapter", + "decision": "keep" + }, + "perry-ui-geisterhand": { + "category": "test-support", + "decision": "keep" + }, + "perry-ui-gtk4": { + "category": "platform-adapter", + "decision": "keep" + }, + "perry-ui-ios": { + "category": "platform-adapter", + "decision": "keep" + }, + "perry-ui-macos": { + "category": "platform-adapter", + "decision": "keep" + }, + "perry-ui-model": { + "category": "platform-core", + "decision": "keep" + }, + "perry-ui-test": { + "category": "test-support", + "decision": "keep" + }, + "perry-ui-testkit": { + "category": "test-support", + "decision": "keep" + }, + "perry-ui-tvos": { + "category": "platform-adapter", + "decision": "keep" + }, + "perry-ui-visionos": { + "category": "platform-adapter", + "decision": "keep" + }, + "perry-ui-watchos": { + "category": "platform-adapter", + "decision": "keep" + }, + "perry-ui-windows": { + "category": "platform-adapter", + "decision": "keep" + }, + "perry-ui-windows-winui": { + "category": "platform-adapter", + "decision": "merge" + }, + "perry-updater": { + "category": "runtime-core", + "decision": "keep" + }, + "perry-wasm-host": { + "category": "runtime-core", + "decision": "keep" + } + } +}