From fa87ec07731d772ed4d2b03ba375a322601fc30b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2026 02:40:54 +0000 Subject: [PATCH 1/4] chore(deps): update oxc --- Cargo.lock | 135 +++++++++++++++++++++++++++-------------------------- Cargo.toml | 20 ++++---- 2 files changed, 80 insertions(+), 75 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c070e7895..441ba32b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -107,11 +107,11 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.4" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" dependencies = [ - "generic-array", + "hybrid-array", ] [[package]] @@ -227,6 +227,12 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + [[package]] name = "const-str" version = "0.3.2" @@ -273,9 +279,9 @@ checksum = "417bef24afe1460300965a25ff4a24b8b45ad011948302ec221e8a0a81eb2c79" [[package]] name = "cpufeatures" -version = "0.2.17" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" dependencies = [ "libc", ] @@ -316,12 +322,11 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crypto-common" -version = "0.1.7" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" dependencies = [ - "generic-array", - "typenum", + "hybrid-array", ] [[package]] @@ -402,11 +407,12 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.7" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +checksum = "4850db49bf08e663084f7fb5c87d202ef91a3907271aff24a94eb97ff039153c" dependencies = [ "block-buffer", + "const-oid", "crypto-common", ] @@ -646,16 +652,6 @@ dependencies = [ "slab", ] -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - [[package]] name = "getrandom" version = "0.2.17" @@ -727,6 +723,15 @@ dependencies = [ "foldhash", ] +[[package]] +name = "hybrid-array" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a79f2aff40c18ab8615ddc5caa9eb5b96314aef18fe5823090f204ad988e813" +dependencies = [ + "typenum", +] + [[package]] name = "icu_collections" version = "2.1.1" @@ -1178,9 +1183,9 @@ dependencies = [ [[package]] name = "oxc-miette" -version = "2.7.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a7ba54c704edefead1f44e9ef09c43e5cfae666bdc33516b066011f0e6ebf7" +checksum = "4356a61f2ed4c9b3610245215fbf48970eb277126919f87db9d0efa93a74245c" dependencies = [ "cfg-if", "owo-colors", @@ -1193,9 +1198,9 @@ dependencies = [ [[package]] name = "oxc-miette-derive" -version = "2.7.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4faecb54d0971f948fbc1918df69b26007e6f279a204793669542e1e8b75eb3" +checksum = "b237422b014f8f8fff75bb9379e697d13f8d57551a22c88bebb39f073c1bf696" dependencies = [ "proc-macro2", "quote", @@ -1204,9 +1209,9 @@ dependencies = [ [[package]] name = "oxc_allocator" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff805b88789451a080b3c4d49fa0ebcd02dc6c0e370ed7a37ef954fbaf79915f" +checksum = "5e6fc6ce99f6a28fd477c6df500bbc9bf1c39db166952e15bea218459cc0db0c" dependencies = [ "allocator-api2", "hashbrown 0.16.1", @@ -1275,9 +1280,9 @@ dependencies = [ [[package]] name = "oxc_ast" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "addc03b644cd9f26996bb32883f5cf4f4e46a51d20f5fbdbf675c14b29d38e95" +checksum = "49fa0813bf9fcff5a4e48fc186ee15a0d276b30b0b575389a34a530864567819" dependencies = [ "bitflags", "oxc_allocator", @@ -1292,9 +1297,9 @@ dependencies = [ [[package]] name = "oxc_ast_macros" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5950f9746248c26af04811e6db0523d354080637995be1dcc1c6bd3fca893bb2" +checksum = "3a2b2a2e09ff0dd4790a5ceb4a93349e0ea769d4d98d778946de48decb763b18" dependencies = [ "phf 0.13.1", "proc-macro2", @@ -1304,9 +1309,9 @@ dependencies = [ [[package]] name = "oxc_ast_visit" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31da485219d7ca6810872ce84fbcc7d11d8492145012603ead79beaf1476dc92" +checksum = "ef6d2304cb25dbbd028440591bf289ef16e3df98517930e79dcc304be64b3045" dependencies = [ "oxc_allocator", "oxc_ast", @@ -1316,9 +1321,9 @@ dependencies = [ [[package]] name = "oxc_codegen" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e8af47790edfd7cc2d35ff47b70a1746c73388cc498c7f470a9cdc35f89375c" +checksum = "ce92b24319ee9fbfa14a5cc488a5ba91bb04bac070c4bad0ba18c772060d19c0" dependencies = [ "bitflags", "cow-utils", @@ -1337,9 +1342,9 @@ dependencies = [ [[package]] name = "oxc_compat" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3103453f49b58f20dfb5d0d7be109c44975b436ad056fdb046db03e971ee9f64" +checksum = "bd5a3de8c67c960a20bc0177d54498d1a96275c38eb78a0975b4ffdc5a1fb13a" dependencies = [ "cow-utils", "oxc-browserslist", @@ -1350,18 +1355,18 @@ dependencies = [ [[package]] name = "oxc_data_structures" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "623bffc9732a0d39f248a2e7655d6d1704201790e5a8777aa188a678f1746fe8" +checksum = "c8e8f59bed9522098da177d894dc8635fb3eae218ff97d9c695900cb11fd10a2" dependencies = [ "ropey", ] [[package]] name = "oxc_diagnostics" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c612203fb402e998169c3e152a9fc8e736faafea0f13287c92144d4b8bc7b55" +checksum = "e0476859d4319f2b063f7c4a3120ee5b7e3e48032865ca501f8545ff44badcff" dependencies = [ "cow-utils", "oxc-miette", @@ -1370,9 +1375,9 @@ dependencies = [ [[package]] name = "oxc_ecmascript" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04c62e45b93f4257f5ca6d00f441e669ad52d98d36332394abe9f5527cf461d6" +checksum = "1bcf46e5b1a6f8ea3797e887a9db4c79ed15894ca8685eb628da462d4c4e913f" dependencies = [ "cow-utils", "num-bigint", @@ -1386,9 +1391,9 @@ dependencies = [ [[package]] name = "oxc_estree" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8794e3fbcd834e8ae4246dbd3121f9ee82c6ae60bc92615a276d42b6b62a2341" +checksum = "2251e6b61eab7b96f0e9d140b68b0f0d8a851c7d260725433e18b1babdcb9430" dependencies = [ "dragonbox_ecma", "itoa", @@ -1407,9 +1412,9 @@ dependencies = [ [[package]] name = "oxc_napi" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "323831584e222ef4b2a3ce1b9c1dd54f43703342472ddcb815929896faca279a" +checksum = "ff9776efeaa305817485c69e219bd952ec9b1012ff2cc582e271f3cfd4b10b06" dependencies = [ "napi", "napi-build", @@ -1423,9 +1428,9 @@ dependencies = [ [[package]] name = "oxc_parser" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "041125897019b72d23e6549d95985fe379354cf004e69cb811803109375fa91b" +checksum = "439d2580047b77faf6e60d358b48e5292e0e026b9cfc158d46ddd0175244bb26" dependencies = [ "bitflags", "cow-utils", @@ -1446,9 +1451,9 @@ dependencies = [ [[package]] name = "oxc_regular_expression" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "405e9515c3ae4c7227b3596219ec256dd883cb403db3a0d1c10146f82a894c93" +checksum = "0fb5669d3298a92d440afec516943745794cb4cf977911728cd73e3438db87b9" dependencies = [ "bitflags", "oxc_allocator", @@ -1489,9 +1494,9 @@ dependencies = [ [[package]] name = "oxc_semantic" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebb0597a0132e69aaecb010753b7450ffaf46cf45a389a7babe0e5e5825a911c" +checksum = "487e9ef54375b23b159eef73746a02b505c3ae70b9c302610680d3c68a3bb62c" dependencies = [ "itertools 0.14.0", "memchr", @@ -1522,9 +1527,9 @@ dependencies = [ [[package]] name = "oxc_span" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "894327633e5dcaef8baf34815d68100297f9776e20371502458ea3c42b8a710b" +checksum = "b1d452f6a664627bdd0f1f1586f9258f81cd7edc5c83e9ef50019f701ef1722d" dependencies = [ "compact_str", "oxc-miette", @@ -1537,9 +1542,9 @@ dependencies = [ [[package]] name = "oxc_str" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50e0b900b4f66db7d5b46a454532464861f675d03e16994040484d2c04151490" +checksum = "5c7a27c4371f69387f3d6f8fa56f70e4c6fa6aedc399285de6ec02bb9fd148d7" dependencies = [ "compact_str", "hashbrown 0.16.1", @@ -1550,9 +1555,9 @@ dependencies = [ [[package]] name = "oxc_syntax" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a5edd0173b4667e5a1775b5d37e06a78c796fab18ee095739186831f2c54400" +checksum = "0d60d91023aafc256ab99c3dbf6181473e495695029c0152d2093e87df18ffe2" dependencies = [ "bitflags", "cow-utils", @@ -1570,9 +1575,9 @@ dependencies = [ [[package]] name = "oxc_transformer" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a216c0a1291fcb42f6be51ce32d928921cf2a6e232e43e6339c8e48d0e4048f" +checksum = "226d77c70778860c4b4888e4aa52f1b4799bfc67093aa5070f367848ff8df09b" dependencies = [ "base64", "compact_str", @@ -1599,9 +1604,9 @@ dependencies = [ [[package]] name = "oxc_traverse" -version = "0.122.0" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e1d4f7d8539ccc032bf20a837b075a301a7846c6ded266a7a1889f0cfcae038" +checksum = "c31aba1910999e2f9a1cc9c47a490caaed828bb119351abe20a2a7851d554963" dependencies = [ "itoa", "oxc_allocator", @@ -2141,9 +2146,9 @@ dependencies = [ [[package]] name = "sha1" -version = "0.10.6" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +checksum = "aacc4cc499359472b4abe1bf11d0b12e688af9a805fa5e3016f9a386dc2d0214" dependencies = [ "cfg-if", "cpufeatures", diff --git a/Cargo.toml b/Cargo.toml index fab56acfa..79462d38c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -87,17 +87,17 @@ multiple_crate_versions = "allow" [workspace.dependencies] # External oxc crates from crates.io -oxc_allocator = "0.122" -oxc_ast = "0.122" -oxc_ast_visit = "0.122" -oxc_diagnostics = "0.122" -oxc_napi = "0.122" -oxc_parser = "0.122" -oxc_semantic = "0.122" -oxc_span = "0.122" +oxc_allocator = "0.123" +oxc_ast = "0.123" +oxc_ast_visit = "0.123" +oxc_diagnostics = "0.123" +oxc_napi = "0.123" +oxc_parser = "0.123" +oxc_semantic = "0.123" +oxc_span = "0.123" oxc_sourcemap = "6.0.1" -oxc_transformer = "0.122" -oxc_codegen = "0.122" +oxc_transformer = "0.123" +oxc_codegen = "0.123" # Internal oxc_angular_compiler = { path = "crates/oxc_angular_compiler" } From 752a5a00d93acd68823f5fe40c9a6ee11b2a21a4 Mon Sep 17 00:00:00 2001 From: "anthropic-code-agent[bot]" <242468646+Claude@users.noreply.github.com> Date: Tue, 31 Mar 2026 02:56:36 +0000 Subject: [PATCH 2/4] fix: update code for oxc 0.123 API changes (Atom -> Ident) Agent-Logs-Url: https://github.com/voidzero-dev/oxc-angular-compiler/sessions/e30e0210-0bc0-4fde-89cf-53e615179571 Co-authored-by: Brooooooklyn <3468483+Brooooooklyn@users.noreply.github.com> --- .../angular_conformance/src/extractor/util.rs | 6 +- .../src/subsystems/html_whitespace.rs | 2 +- .../src/ast/expression.rs | 34 +-- crates/oxc_angular_compiler/src/ast/html.rs | 46 ++-- crates/oxc_angular_compiler/src/ast/r3.rs | 108 ++++----- .../src/class_debug_info/compiler.rs | 20 +- .../src/class_debug_info/metadata.rs | 10 +- .../src/class_metadata/builders.rs | 16 +- .../src/class_metadata/compiler.rs | 20 +- .../src/class_metadata/metadata.rs | 6 +- .../src/component/decorator.rs | 70 +++--- .../src/component/definition.rs | 188 ++++++++-------- .../src/component/dependency.rs | 58 ++--- .../src/component/import_elision.rs | 24 +- .../src/component/metadata.rs | 72 +++--- .../src/component/namespace_registry.rs | 66 +++--- .../src/component/transform.rs | 96 ++++---- .../src/directive/compiler.rs | 200 ++++++++--------- .../src/directive/decorator.rs | 40 ++-- .../src/directive/definition.rs | 44 ++-- .../src/directive/metadata.rs | 112 ++++----- .../src/directive/property_decorators.rs | 64 +++--- .../src/directive/query.rs | 72 +++--- crates/oxc_angular_compiler/src/dts.rs | 4 +- .../src/factory/compiler.rs | 42 ++-- .../src/factory/metadata.rs | 8 +- .../src/hmr/dependencies.rs | 62 ++--- .../src/hmr/initializer.rs | 28 +-- .../oxc_angular_compiler/src/i18n/parser.rs | 8 +- .../src/injectable/compiler.rs | 78 +++---- .../src/injectable/decorator.rs | 18 +- .../src/injectable/definition.rs | 22 +- .../src/injectable/metadata.rs | 8 +- .../src/injector/compiler.rs | 32 +-- .../src/injector/metadata.rs | 8 +- .../oxc_angular_compiler/src/ir/expression.rs | 34 +-- crates/oxc_angular_compiler/src/ir/ops.rs | 180 +++++++-------- crates/oxc_angular_compiler/src/linker/mod.rs | 4 +- .../src/ng_module/compiler.rs | 60 ++--- .../src/ng_module/decorator.rs | 42 ++-- .../src/ng_module/definition.rs | 26 +-- crates/oxc_angular_compiler/src/output/ast.rs | 60 ++--- .../src/output/emitter.rs | 128 +++++------ .../src/output/oxc_converter.rs | 16 +- .../src/parser/expression/lexer.rs | 34 +-- .../src/parser/expression/mod.rs | 2 +- .../src/parser/expression/parser.rs | 52 ++--- .../src/parser/html/parser.rs | 60 ++--- .../src/parser/html/whitespace.rs | 6 +- .../oxc_angular_compiler/src/pipe/compiler.rs | 36 +-- .../src/pipe/decorator.rs | 30 +-- .../src/pipe/definition.rs | 26 +-- .../oxc_angular_compiler/src/pipe/metadata.rs | 22 +- .../src/pipeline/compilation.rs | 64 +++--- .../src/pipeline/constant_pool.rs | 36 +-- .../src/pipeline/conversion.rs | 8 +- .../oxc_angular_compiler/src/pipeline/emit.rs | 60 ++--- .../src/pipeline/ingest.rs | 116 +++++----- .../phases/attach_source_locations.rs | 4 +- .../pipeline/phases/binding_specialization.rs | 10 +- .../src/pipeline/phases/const_collection.rs | 22 +- .../src/pipeline/phases/convert_animations.rs | 6 +- .../pipeline/phases/convert_i18n_bindings.rs | 4 +- .../pipeline/phases/create_i18n_contexts.rs | 4 +- .../src/pipeline/phases/expand_safe_reads.rs | 2 +- .../pipeline/phases/extract_i18n_messages.rs | 14 +- .../phases/generate_local_let_references.rs | 4 +- .../phases/generate_projection_def.rs | 8 +- .../src/pipeline/phases/generate_variables.rs | 22 +- .../phases/host_style_property_parsing.rs | 20 +- .../src/pipeline/phases/i18n_closure.rs | 40 ++-- .../pipeline/phases/i18n_const_collection.rs | 50 ++--- .../pipeline/phases/i18n_text_extraction.rs | 8 +- .../src/pipeline/phases/local_refs.rs | 4 +- .../src/pipeline/phases/naming.rs | 112 ++++----- .../pipeline/phases/parse_extracted_styles.rs | 18 +- .../src/pipeline/phases/pipe_creation.rs | 2 +- .../phases/pure_literal_structures.rs | 10 +- .../phases/regular_expression_optimization.rs | 20 +- .../phases/reify/angular_expression.rs | 14 +- .../pipeline/phases/reify/ir_expression.rs | 20 +- .../src/pipeline/phases/reify/mod.rs | 20 +- .../phases/reify/statements/bindings.rs | 66 +++--- .../phases/reify/statements/control_flow.rs | 42 ++-- .../pipeline/phases/reify/statements/defer.rs | 6 +- .../phases/reify/statements/elements.rs | 30 +-- .../pipeline/phases/reify/statements/misc.rs | 48 ++-- .../src/pipeline/phases/reify/utils.rs | 14 +- .../phases/remove_illegal_let_references.rs | 6 +- .../resolve_i18n_element_placeholders.rs | 16 +- .../resolve_i18n_expression_placeholders.rs | 6 +- .../src/pipeline/phases/resolve_names.rs | 8 +- .../src/pipeline/phases/resolve_sanitizers.rs | 18 +- .../src/pipeline/phases/save_restore_view.rs | 12 +- .../phases/strip_nonrequired_parentheses.rs | 2 +- .../pipeline/phases/temporary_variables.rs | 8 +- .../pipeline/phases/track_fn_optimization.rs | 12 +- .../src/pipeline/phases/track_variables.rs | 32 +-- .../src/pipeline/selector.rs | 4 +- .../src/transform/control_flow.rs | 38 ++-- .../src/transform/html_to_r3.rs | 212 +++++++++--------- .../tests/expression_parser_test.rs | 6 +- .../tests/integration_test.rs | 6 +- .../tests/nextcontext_listener.rs | 4 +- .../tests/nextcontext_repro.rs | 6 +- .../tests/playground_repro.rs | 4 +- .../tests/variable_naming_test.rs | 4 +- napi/angular-compiler/src/lib.rs | 30 +-- 108 files changed, 1936 insertions(+), 1936 deletions(-) diff --git a/crates/angular_conformance/src/extractor/util.rs b/crates/angular_conformance/src/extractor/util.rs index 2f493b290..358a5b19c 100644 --- a/crates/angular_conformance/src/extractor/util.rs +++ b/crates/angular_conformance/src/extractor/util.rs @@ -54,7 +54,7 @@ impl SpecExtractor { let parts: Vec<&str> = lit .quasis .iter() - .filter_map(|q| q.value.cooked.as_ref().map(oxc_span::Atom::as_str)) + .filter_map(|q| q.value.cooked.as_ref().map(oxc_span::Str::as_str)) .collect(); Some(parts.join("")) } @@ -138,10 +138,10 @@ impl SpecExtractor { Some(serde_json::Value::String(lit.value.to_string())) } Expression::NumericLiteral(lit) => { - serde_json::Number::from_f64(lit.value).map(serde_json::Value::Number) + serde_json::Number::from_f64(lit.value.into()).map(serde_json::Value::Number) } Expression::NullLiteral(_) => Some(serde_json::Value::Null), - Expression::BooleanLiteral(lit) => Some(serde_json::Value::Bool(lit.value)), + Expression::BooleanLiteral(lit) => Some(serde_json::Value::Bool(lit.value.into())), Expression::ArrayExpression(arr) => { let mut values = Vec::new(); for element in &arr.elements { diff --git a/crates/angular_conformance/src/subsystems/html_whitespace.rs b/crates/angular_conformance/src/subsystems/html_whitespace.rs index 1f18f4fde..8e7447bec 100644 --- a/crates/angular_conformance/src/subsystems/html_whitespace.rs +++ b/crates/angular_conformance/src/subsystems/html_whitespace.rs @@ -384,7 +384,7 @@ impl WhitespaceRemovingHumanizer { for token in tokens { match token.token_type { InterpolatedTokenType::Text => { - let text = token.parts.first().map_or("", oxc_span::Atom::as_str); + let text = token.parts.first().map_or("", oxc_span::Ident::as_str); let processed = process_whitespace(text); result.push(vec![processed]); } diff --git a/crates/oxc_angular_compiler/src/ast/expression.rs b/crates/oxc_angular_compiler/src/ast/expression.rs index 593efc470..e75bd26eb 100644 --- a/crates/oxc_angular_compiler/src/ast/expression.rs +++ b/crates/oxc_angular_compiler/src/ast/expression.rs @@ -11,7 +11,7 @@ //! - No bitwise operators use oxc_allocator::{Allocator, Box, Vec}; -use oxc_span::{Atom, Span}; +use oxc_span::{Ident, Span}; /// A span within the expression source. #[derive(Debug, Clone, Copy)] @@ -594,7 +594,7 @@ pub struct PropertyRead<'a> { /// The receiver expression. pub receiver: AngularExpression<'a>, /// The property name. - pub name: Atom<'a>, + pub name: Ident<'a>, } /// A safe property read expression: `receiver?.property`. @@ -609,7 +609,7 @@ pub struct SafePropertyRead<'a> { /// The receiver expression. pub receiver: AngularExpression<'a>, /// The property name. - pub name: Atom<'a>, + pub name: Ident<'a>, } /// A keyed read expression: `receiver[key]`. @@ -659,7 +659,7 @@ pub struct BindingPipe<'a> { /// The expression being piped. pub exp: AngularExpression<'a>, /// The pipe name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// The pipe arguments. pub args: Vec<'a, AngularExpression<'a>>, /// The type of pipe reference. @@ -670,7 +670,7 @@ pub struct BindingPipe<'a> { #[derive(Debug, Clone)] pub enum LiteralValue<'a> { /// A string literal. - String(Atom<'a>), + String(Ident<'a>), /// A number literal. Number(f64), /// A boolean literal. @@ -718,7 +718,7 @@ pub struct SpreadElement<'a> { #[derive(Debug)] pub struct ArrowFunctionParameter<'a> { /// The parameter name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// The span of this parameter. pub span: ParseSpan, /// The absolute source span. @@ -751,7 +751,7 @@ pub enum LiteralMapKey<'a> { #[derive(Debug)] pub struct LiteralMapPropertyKey<'a> { /// The key string. - pub key: Atom<'a>, + pub key: Ident<'a>, /// Whether the key is quoted. pub quoted: bool, /// Whether this is a shorthand initialization. @@ -788,7 +788,7 @@ pub struct Interpolation<'a> { /// The absolute source span. pub source_span: AbsoluteSourceSpan, /// The static string parts. - pub strings: Vec<'a, Atom<'a>>, + pub strings: Vec<'a, Ident<'a>>, /// The dynamic expression parts. pub expressions: Vec<'a, AngularExpression<'a>>, } @@ -1062,7 +1062,7 @@ pub struct TemplateLiteralElement<'a> { /// The absolute source span. pub source_span: AbsoluteSourceSpan, /// The text content. - pub text: Atom<'a>, + pub text: Ident<'a>, } /// A parenthesized expression. @@ -1084,9 +1084,9 @@ pub struct RegularExpressionLiteral<'a> { /// The absolute source span. pub source_span: AbsoluteSourceSpan, /// The regex pattern. - pub body: Atom<'a>, + pub body: Ident<'a>, /// The regex flags. - pub flags: Option>, + pub flags: Option>, } // ============================================================================ @@ -1128,7 +1128,7 @@ pub struct ExpressionBinding<'a> { #[derive(Debug, Clone)] pub struct TemplateBindingIdentifier<'a> { /// The source text. - pub source: Atom<'a>, + pub source: Ident<'a>, /// The span. pub span: AbsoluteSourceSpan, } @@ -1139,9 +1139,9 @@ pub struct ASTWithSource<'a> { /// The AST. pub ast: AngularExpression<'a>, /// The original source. - pub source: Option>, + pub source: Option>, /// The source location. - pub location: Atom<'a>, + pub location: Ident<'a>, /// The absolute offset in the template. pub absolute_offset: u32, // Note: Errors are collected separately in the parser/transformer context @@ -1210,7 +1210,7 @@ pub enum BindingType { #[derive(Debug)] pub struct ParsedProperty<'a> { /// The property name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// The binding expression. pub expression: ASTWithSource<'a>, /// The type of property binding. @@ -1247,11 +1247,11 @@ impl<'a> ParsedProperty<'a> { #[derive(Debug)] pub struct ParsedEvent<'a> { /// The event name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// The event target or animation phase. /// For regular events: "window", "document", "body", or None. /// For legacy animation events: the animation phase. - pub target_or_phase: Option>, + pub target_or_phase: Option>, /// The type of event binding. pub event_type: ParsedEventType, /// The handler expression. diff --git a/crates/oxc_angular_compiler/src/ast/html.rs b/crates/oxc_angular_compiler/src/ast/html.rs index 41a5e3f6f..751e52038 100644 --- a/crates/oxc_angular_compiler/src/ast/html.rs +++ b/crates/oxc_angular_compiler/src/ast/html.rs @@ -4,7 +4,7 @@ //! ported from Angular's `ml_parser/ast.ts`. use oxc_allocator::{Box, Vec}; -use oxc_span::{Atom, Span}; +use oxc_span::{Ident, Span}; use super::expression::AngularExpression; @@ -31,7 +31,7 @@ pub struct InterpolatedToken<'a> { /// The token type. pub token_type: InterpolatedTokenType, /// The token parts (structure depends on token type). - pub parts: Vec<'a, Atom<'a>>, + pub parts: Vec<'a, Ident<'a>>, /// The source span. pub span: Span, } @@ -83,7 +83,7 @@ impl<'a> HtmlNode<'a> { #[derive(Debug)] pub struct HtmlText<'a> { /// The decoded text value (entities resolved, interpolations joined). - pub value: Atom<'a>, + pub value: Ident<'a>, /// The source span (after stripping leading trivia). pub span: Span, /// The full start offset before stripping leading trivia (for source maps). @@ -100,13 +100,13 @@ pub struct HtmlElement<'a> { /// The element tag name. /// For regular elements: the tag name (e.g., "div", ":svg:rect"). /// For selectorless components: the component name (e.g., "MyComp"). - pub name: Atom<'a>, + pub name: Ident<'a>, /// For selectorless components: the namespace prefix (e.g., "svg" in ``). /// None for regular elements or selectorless components without namespace. - pub component_prefix: Option>, + pub component_prefix: Option>, /// For selectorless components: the HTML tag name (e.g., "rect" in ``). /// None for regular elements or selectorless components without tag name. - pub component_tag_name: Option>, + pub component_tag_name: Option>, /// The element attributes. pub attrs: Vec<'a, HtmlAttribute<'a>>, /// Selectorless directives (e.g., @Dir, @Dir(attr="value")). @@ -133,12 +133,12 @@ pub struct HtmlElement<'a> { #[derive(Debug)] pub struct HtmlComponent<'a> { /// The component class name (e.g., "MyComp"). - pub component_name: Atom<'a>, + pub component_name: Ident<'a>, /// The HTML tag name (e.g., "button" in ``). /// None for component-only syntax like ``. - pub tag_name: Option>, + pub tag_name: Option>, /// The full qualified name (e.g., "MyComp:svg:rect"). - pub full_name: Atom<'a>, + pub full_name: Ident<'a>, /// The element attributes. pub attrs: Vec<'a, HtmlAttribute<'a>>, /// Selectorless directives (e.g., @Dir). @@ -159,7 +159,7 @@ pub struct HtmlComponent<'a> { #[derive(Debug)] pub struct HtmlDirective<'a> { /// The directive name (without the @ prefix). - pub name: Atom<'a>, + pub name: Ident<'a>, /// The directive attributes (inside parentheses, if any). pub attrs: Vec<'a, HtmlAttribute<'a>>, /// The source span for the entire directive. @@ -176,9 +176,9 @@ pub struct HtmlDirective<'a> { #[derive(Debug)] pub struct HtmlAttribute<'a> { /// The attribute name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// The decoded attribute value (entities resolved, interpolations joined). - pub value: Atom<'a>, + pub value: Ident<'a>, /// The source span. pub span: Span, /// The name span. @@ -194,7 +194,7 @@ pub struct HtmlAttribute<'a> { #[derive(Debug)] pub struct HtmlComment<'a> { /// The comment value. - pub value: Atom<'a>, + pub value: Ident<'a>, /// The source span. pub span: Span, } @@ -203,9 +203,9 @@ pub struct HtmlComment<'a> { #[derive(Debug)] pub struct HtmlExpansion<'a> { /// The switch value. - pub switch_value: Atom<'a>, + pub switch_value: Ident<'a>, /// The expansion type (e.g., "plural", "select"). - pub expansion_type: Atom<'a>, + pub expansion_type: Ident<'a>, /// The expansion cases. pub cases: Vec<'a, HtmlExpansionCase<'a>>, /// The source span. @@ -222,7 +222,7 @@ pub struct HtmlExpansion<'a> { #[derive(Debug)] pub struct HtmlExpansionCase<'a> { /// The case value (e.g., "one", "other"). - pub value: Atom<'a>, + pub value: Ident<'a>, /// The expansion nodes. pub expansion: Vec<'a, HtmlNode<'a>>, /// The source span. @@ -268,7 +268,7 @@ pub struct HtmlBlock<'a> { /// The block type. pub block_type: BlockType, /// The block name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// The block parameters. pub parameters: Vec<'a, HtmlBlockParameter<'a>>, /// The child nodes. @@ -291,7 +291,7 @@ pub struct HtmlBlock<'a> { #[derive(Debug)] pub struct HtmlBlockParameter<'a> { /// The raw expression text (e.g., "minimum 500ms", "track item.id"). - pub expression: Atom<'a>, + pub expression: Ident<'a>, /// The source span. pub span: Span, } @@ -300,7 +300,7 @@ pub struct HtmlBlockParameter<'a> { #[derive(Debug)] pub struct HtmlLetDeclaration<'a> { /// The variable name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// The value expression. pub value: AngularExpression<'a>, /// The source span. @@ -506,7 +506,7 @@ mod tests { // Create a simple tree: root element with two child elements let child1 = HtmlElement { - name: Atom::from("span"), + name: Ident::from("span"), component_prefix: None, component_tag_name: None, attrs: Vec::new_in(&allocator), @@ -520,7 +520,7 @@ mod tests { }; let child2 = HtmlElement { - name: Atom::from("p"), + name: Ident::from("p"), component_prefix: None, component_tag_name: None, attrs: Vec::new_in(&allocator), @@ -538,7 +538,7 @@ mod tests { children.push(HtmlNode::Element(Box::new_in(child2, &allocator))); let root = HtmlElement { - name: Atom::from("div"), + name: Ident::from("div"), component_prefix: None, component_tag_name: None, attrs: Vec::new_in(&allocator), @@ -565,7 +565,7 @@ mod tests { let allocator = Allocator::default(); let text = HtmlText { - value: Atom::from("Hello"), + value: Ident::from("Hello"), span: Span::default(), full_start: None, tokens: Vec::new_in(&allocator), diff --git a/crates/oxc_angular_compiler/src/ast/r3.rs b/crates/oxc_angular_compiler/src/ast/r3.rs index e6a311286..772fbbad8 100644 --- a/crates/oxc_angular_compiler/src/ast/r3.rs +++ b/crates/oxc_angular_compiler/src/ast/r3.rs @@ -6,7 +6,7 @@ //! Ported from Angular's `render3/r3_ast.ts`. use oxc_allocator::{Allocator, Box, HashMap, Vec}; -use oxc_span::{Atom, Span}; +use oxc_span::{Ident, Span}; use crate::ast::expression::{ASTWithSource, AngularExpression, BindingType, ParsedEventType}; use crate::i18n::serializer::format_i18n_placeholder_name; @@ -43,18 +43,18 @@ pub struct I18nMessage<'a> { /// Message AST nodes. pub nodes: Vec<'a, I18nNode<'a>>, /// The meaning of the message (for disambiguation). - pub meaning: Atom<'a>, + pub meaning: Ident<'a>, /// Description of the message for translators. - pub description: Atom<'a>, + pub description: Ident<'a>, /// Custom ID specified by the developer. - pub custom_id: Atom<'a>, + pub custom_id: Ident<'a>, /// The computed message ID. - pub id: Atom<'a>, + pub id: Ident<'a>, /// Legacy IDs for backwards compatibility. - pub legacy_ids: Vec<'a, Atom<'a>>, + pub legacy_ids: Vec<'a, Ident<'a>>, /// The serialized message string for goog.getMsg and $localize. /// Contains the message text with placeholder markers like "{$interpolation}". - pub message_string: Atom<'a>, + pub message_string: Ident<'a>, } /// i18n AST node. @@ -80,7 +80,7 @@ pub enum I18nNode<'a> { #[derive(Debug)] pub struct I18nText<'a> { /// The text value. - pub value: Atom<'a>, + pub value: Ident<'a>, /// Source span. pub source_span: Span, } @@ -98,28 +98,28 @@ pub struct I18nContainer<'a> { #[derive(Debug)] pub struct I18nIcu<'a> { /// The expression being evaluated. - pub expression: Atom<'a>, + pub expression: Ident<'a>, /// ICU type string (plural, select, selectordinal, or custom). - pub icu_type: Atom<'a>, + pub icu_type: Ident<'a>, /// Case branches. - pub cases: HashMap<'a, Atom<'a>, I18nNode<'a>>, + pub cases: HashMap<'a, Ident<'a>, I18nNode<'a>>, /// Source span. pub source_span: Span, /// Expression placeholder name (for message serialization). - pub expression_placeholder: Option>, + pub expression_placeholder: Option>, } /// HTML tag placeholder. #[derive(Debug)] pub struct I18nTagPlaceholder<'a> { /// Tag name. - pub tag: Atom<'a>, + pub tag: Ident<'a>, /// Tag attributes. - pub attrs: HashMap<'a, Atom<'a>, Atom<'a>>, + pub attrs: HashMap<'a, Ident<'a>, Ident<'a>>, /// Start tag placeholder name. - pub start_name: Atom<'a>, + pub start_name: Ident<'a>, /// Close tag placeholder name. - pub close_name: Atom<'a>, + pub close_name: Ident<'a>, /// Child nodes. pub children: Vec<'a, I18nNode<'a>>, /// Whether this is a void element. @@ -136,9 +136,9 @@ pub struct I18nTagPlaceholder<'a> { #[derive(Debug)] pub struct I18nPlaceholder<'a> { /// The expression value. - pub value: Atom<'a>, + pub value: Ident<'a>, /// Placeholder name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Source span. pub source_span: Span, } @@ -149,7 +149,7 @@ pub struct I18nIcuPlaceholder<'a> { /// The ICU expression. pub value: Box<'a, I18nIcu<'a>>, /// Placeholder name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Source span. pub source_span: Span, } @@ -158,13 +158,13 @@ pub struct I18nIcuPlaceholder<'a> { #[derive(Debug)] pub struct I18nBlockPlaceholder<'a> { /// Block name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Block parameters. - pub parameters: Vec<'a, Atom<'a>>, + pub parameters: Vec<'a, Ident<'a>>, /// Start block placeholder name. - pub start_name: Atom<'a>, + pub start_name: Ident<'a>, /// End block placeholder name. - pub close_name: Atom<'a>, + pub close_name: Ident<'a>, /// Child nodes. pub children: Vec<'a, I18nNode<'a>>, /// Source span (overall). @@ -559,7 +559,7 @@ impl<'a> R3Node<'a> { #[derive(Debug, Clone)] pub struct R3Comment<'a> { /// The comment text. - pub value: Atom<'a>, + pub value: Ident<'a>, /// Source span. pub source_span: Span, } @@ -568,7 +568,7 @@ pub struct R3Comment<'a> { #[derive(Debug)] pub struct R3Text<'a> { /// The text content. - pub value: Atom<'a>, + pub value: Ident<'a>, /// Source span. pub source_span: Span, } @@ -592,9 +592,9 @@ pub struct R3BoundText<'a> { #[derive(Debug)] pub struct R3TextAttribute<'a> { /// Attribute name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Attribute value. - pub value: Atom<'a>, + pub value: Ident<'a>, /// Source span. pub source_span: Span, /// Key span (the attribute name). @@ -647,7 +647,7 @@ impl Default for SecurityContext { #[derive(Debug)] pub struct R3BoundAttribute<'a> { /// Attribute name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Binding type (Property, Attribute, Class, Style, etc.). pub binding_type: BindingType, /// Security context for sanitization. @@ -655,7 +655,7 @@ pub struct R3BoundAttribute<'a> { /// The binding expression. pub value: AngularExpression<'a>, /// Unit for style bindings (e.g., "px"). - pub unit: Option>, + pub unit: Option>, /// Source span. pub source_span: Span, /// Key span. @@ -670,15 +670,15 @@ pub struct R3BoundAttribute<'a> { #[derive(Debug)] pub struct R3BoundEvent<'a> { /// Event name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Event type. pub event_type: ParsedEventType, /// Handler expression. pub handler: AngularExpression<'a>, /// Target element (for `window:` or `document:` events). - pub target: Option>, + pub target: Option>, /// Animation phase. - pub phase: Option>, + pub phase: Option>, /// Source span. pub source_span: Span, /// Handler span. @@ -695,7 +695,7 @@ pub struct R3BoundEvent<'a> { #[derive(Debug)] pub struct R3Element<'a> { /// Element tag name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Static attributes. pub attributes: Vec<'a, R3TextAttribute<'a>>, /// Bound input properties. @@ -726,7 +726,7 @@ pub struct R3Element<'a> { #[derive(Debug)] pub struct R3Template<'a> { /// Tag name (None for structural directives on `ng-template`). - pub tag_name: Option>, + pub tag_name: Option>, /// Static attributes. pub attributes: Vec<'a, R3TextAttribute<'a>>, /// Bound inputs. @@ -768,7 +768,7 @@ pub enum R3TemplateAttr<'a> { #[derive(Debug)] pub struct R3Content<'a> { /// The selector for content projection. - pub selector: Atom<'a>, + pub selector: Ident<'a>, /// Static attributes. pub attributes: Vec<'a, R3TextAttribute<'a>>, /// Child nodes (usually empty). @@ -789,9 +789,9 @@ pub struct R3Content<'a> { #[derive(Debug)] pub struct R3Variable<'a> { /// Variable name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Variable value (for `let x = value`). - pub value: Atom<'a>, + pub value: Ident<'a>, /// Source span. pub source_span: Span, /// Key span. @@ -804,9 +804,9 @@ pub struct R3Variable<'a> { #[derive(Debug)] pub struct R3Reference<'a> { /// Reference name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Reference value (directive name or empty). - pub value: Atom<'a>, + pub value: Ident<'a>, /// Source span. pub source_span: Span, /// Key span. @@ -1068,7 +1068,7 @@ pub struct R3ImmediateDeferredTrigger { #[derive(Debug)] pub struct R3HoverDeferredTrigger<'a> { /// Reference to the element to hover. - pub reference: Option>, + pub reference: Option>, /// Source span. pub source_span: Span, /// Name span. @@ -1102,7 +1102,7 @@ pub struct R3TimerDeferredTrigger { #[derive(Debug)] pub struct R3InteractionDeferredTrigger<'a> { /// Reference to the element to interact with. - pub reference: Option>, + pub reference: Option>, /// Source span. pub source_span: Span, /// Name span. @@ -1119,7 +1119,7 @@ pub struct R3InteractionDeferredTrigger<'a> { #[derive(Debug)] pub struct R3ViewportDeferredTrigger<'a> { /// Reference to the element to observe. - pub reference: Option>, + pub reference: Option>, /// Viewport options (margin, etc.). pub options: Option>, /// Source span. @@ -1265,7 +1265,7 @@ pub struct R3DeferredBlockError<'a> { #[derive(Debug)] pub struct R3UnknownBlock<'a> { /// Block name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Source span. pub source_span: Span, /// Name span. @@ -1276,7 +1276,7 @@ pub struct R3UnknownBlock<'a> { #[derive(Debug)] pub struct R3LetDeclaration<'a> { /// Variable name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Value expression. pub value: AngularExpression<'a>, /// Source span. @@ -1291,11 +1291,11 @@ pub struct R3LetDeclaration<'a> { #[derive(Debug)] pub struct R3Component<'a> { /// Component class name. - pub component_name: Atom<'a>, + pub component_name: Ident<'a>, /// Tag name in template. - pub tag_name: Option>, + pub tag_name: Option>, /// Full component name. - pub full_name: Atom<'a>, + pub full_name: Ident<'a>, /// Static attributes. pub attributes: Vec<'a, R3TextAttribute<'a>>, /// Bound inputs. @@ -1324,7 +1324,7 @@ pub struct R3Component<'a> { #[derive(Debug)] pub struct R3Directive<'a> { /// Directive class name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Static attributes. pub attributes: Vec<'a, R3TextAttribute<'a>>, /// Bound inputs. @@ -1349,7 +1349,7 @@ pub struct R3Directive<'a> { #[derive(Debug)] pub struct R3HostElement<'a> { /// Possible tag names for the host element. Must have at least one. - pub tag_names: Vec<'a, Atom<'a>>, + pub tag_names: Vec<'a, Ident<'a>>, /// Attribute and property bindings. pub bindings: Vec<'a, R3BoundAttribute<'a>>, /// Event listeners. @@ -1362,9 +1362,9 @@ pub struct R3HostElement<'a> { #[derive(Debug)] pub struct R3Icu<'a> { /// Variable expressions (ordered: must preserve insertion order like JS objects). - pub vars: Vec<'a, (Atom<'a>, R3BoundText<'a>)>, + pub vars: Vec<'a, (Ident<'a>, R3BoundText<'a>)>, /// Placeholder expressions (ordered: must preserve insertion order like JS objects). - pub placeholders: Vec<'a, (Atom<'a>, R3IcuPlaceholder<'a>)>, + pub placeholders: Vec<'a, (Ident<'a>, R3IcuPlaceholder<'a>)>, /// Source span. pub source_span: Span, /// i18n metadata. @@ -1599,11 +1599,11 @@ pub struct R3ParseResult<'a> { /// Uses std::vec::Vec since ParseError contains Drop types (Arc, String). pub errors: std::vec::Vec, /// Extracted styles. - pub styles: Vec<'a, Atom<'a>>, + pub styles: Vec<'a, Ident<'a>>, /// Extracted style URLs. - pub style_urls: Vec<'a, Atom<'a>>, + pub style_urls: Vec<'a, Ident<'a>>, /// Content projection selectors. - pub ng_content_selectors: Vec<'a, Atom<'a>>, + pub ng_content_selectors: Vec<'a, Ident<'a>>, /// Comment nodes (if collected). pub comment_nodes: Option>>, } diff --git a/crates/oxc_angular_compiler/src/class_debug_info/compiler.rs b/crates/oxc_angular_compiler/src/class_debug_info/compiler.rs index 947701555..df4c34e91 100644 --- a/crates/oxc_angular_compiler/src/class_debug_info/compiler.rs +++ b/crates/oxc_angular_compiler/src/class_debug_info/compiler.rs @@ -6,7 +6,7 @@ //! - `setClassDebugInfo(type, { className, filePath?, lineNumber?, forbidOrphanRendering? })` use oxc_allocator::{Allocator, Box, Vec}; -use oxc_span::Atom; +use oxc_span::Ident; use super::metadata::R3ClassDebugInfo; use crate::output::ast::{ @@ -54,7 +54,7 @@ fn internal_compile_class_debug_info<'a>( // className entries.push(LiteralMapEntry { - key: Atom::from("className"), + key: Ident::from("className"), value: literal_string_atom(allocator, debug_info.class_name.clone()), quoted: false, }); @@ -64,13 +64,13 @@ fn internal_compile_class_debug_info<'a>( // will typically ignore lineNumber as well) if let Some(file_path) = &debug_info.file_path { entries.push(LiteralMapEntry { - key: Atom::from("filePath"), + key: Ident::from("filePath"), value: literal_string_atom(allocator, file_path.clone()), quoted: false, }); entries.push(LiteralMapEntry { - key: Atom::from("lineNumber"), + key: Ident::from("lineNumber"), value: literal_number(allocator, debug_info.line_number), quoted: false, }); @@ -79,7 +79,7 @@ fn internal_compile_class_debug_info<'a>( // Include forbidOrphanRendering only if it's true (to reduce generated code) if debug_info.forbid_orphan_rendering { entries.push(LiteralMapEntry { - key: Atom::from("forbidOrphanRendering"), + key: Ident::from("forbidOrphanRendering"), value: literal_bool(allocator, true), quoted: false, }); @@ -114,7 +114,7 @@ fn dev_only_guarded_expression<'a>( expr: OutputExpression<'a>, ) -> OutputExpression<'a> { let guard_var = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("ngDevMode"), source_span: None }, + ReadVarExpr { name: Ident::from("ngDevMode"), source_span: None }, allocator, )); @@ -167,12 +167,12 @@ fn import_expr<'a>(allocator: &'a Allocator, identifier: &'static str) -> Output ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(identifier), + name: Ident::from(identifier), optional: false, source_span: None, }, @@ -183,13 +183,13 @@ fn import_expr<'a>(allocator: &'a Allocator, identifier: &'static str) -> Output /// Creates a string literal from a static str. fn literal_string<'a>(allocator: &'a Allocator, value: &'static str) -> OutputExpression<'a> { OutputExpression::Literal(Box::new_in( - LiteralExpr { value: LiteralValue::String(Atom::from(value)), source_span: None }, + LiteralExpr { value: LiteralValue::String(Ident::from(value)), source_span: None }, allocator, )) } /// Creates a string literal from an Atom. -fn literal_string_atom<'a>(allocator: &'a Allocator, value: Atom<'a>) -> OutputExpression<'a> { +fn literal_string_atom<'a>(allocator: &'a Allocator, value: Ident<'a>) -> OutputExpression<'a> { OutputExpression::Literal(Box::new_in( LiteralExpr { value: LiteralValue::String(value), source_span: None }, allocator, diff --git a/crates/oxc_angular_compiler/src/class_debug_info/metadata.rs b/crates/oxc_angular_compiler/src/class_debug_info/metadata.rs index b86d5cb07..f6c61003c 100644 --- a/crates/oxc_angular_compiler/src/class_debug_info/metadata.rs +++ b/crates/oxc_angular_compiler/src/class_debug_info/metadata.rs @@ -2,7 +2,7 @@ //! //! Ported from Angular's `render3/r3_class_debug_info_compiler.ts`. -use oxc_span::Atom; +use oxc_span::Ident; use crate::output::ast::OutputExpression; @@ -16,7 +16,7 @@ pub struct R3ClassDebugInfo<'a> { pub r#type: OutputExpression<'a>, /// The original class name as it appears in its definition. - pub class_name: Atom<'a>, + pub class_name: Ident<'a>, /// The relative path of the file in which the class is defined. /// @@ -24,7 +24,7 @@ pub struct R3ClassDebugInfo<'a> { /// absolute file paths are never shown. If the relative path cannot /// be computed, this should be `None`, and downstream consumers will /// typically ignore the `line_number` field as well. - pub file_path: Option>, + pub file_path: Option>, /// The line number in which this class is defined (1-indexed). pub line_number: u32, @@ -40,12 +40,12 @@ impl<'a> R3ClassDebugInfo<'a> { /// /// File path and line number default to `None`/`0`, and /// `forbid_orphan_rendering` defaults to `false`. - pub fn new(r#type: OutputExpression<'a>, class_name: Atom<'a>) -> Self { + pub fn new(r#type: OutputExpression<'a>, class_name: Ident<'a>) -> Self { Self { r#type, class_name, file_path: None, line_number: 0, forbid_orphan_rendering: false } } /// Sets the file path for this debug info. - pub fn with_file_path(mut self, file_path: Atom<'a>) -> Self { + pub fn with_file_path(mut self, file_path: Ident<'a>) -> Self { self.file_path = Some(file_path); self } diff --git a/crates/oxc_angular_compiler/src/class_metadata/builders.rs b/crates/oxc_angular_compiler/src/class_metadata/builders.rs index c0e34a0ef..2b8566e21 100644 --- a/crates/oxc_angular_compiler/src/class_metadata/builders.rs +++ b/crates/oxc_angular_compiler/src/class_metadata/builders.rs @@ -8,7 +8,7 @@ use oxc_ast::ast::{ Class, ClassElement, Decorator, Expression, FormalParameter, MethodDefinitionKind, PropertyKey, TSType, TSTypeName, }; -use oxc_span::Atom; +use oxc_span::Ident; use crate::component::{ImportMap, NamespaceRegistry, R3DependencyMetadata}; use crate::output::ast::{ @@ -65,7 +65,7 @@ pub fn build_decorator_metadata_array<'a>( // Add "type" entry map_entries.push(LiteralMapEntry { - key: Atom::from("type"), + key: Ident::from("type"), value: type_expr, quoted: false, }); @@ -84,7 +84,7 @@ pub fn build_decorator_metadata_array<'a>( if !args.is_empty() { map_entries.push(LiteralMapEntry { - key: Atom::from("args"), + key: Ident::from("args"), value: OutputExpression::LiteralArray(Box::new_in( LiteralArrayExpr { entries: args, source_span: None }, allocator, @@ -155,7 +155,7 @@ pub fn build_ctor_params_metadata<'a>( }); map_entries.push(LiteralMapEntry { - key: Atom::from("type"), + key: Ident::from("type"), value: type_expr, quoted: false, }); @@ -165,7 +165,7 @@ pub fn build_ctor_params_metadata<'a>( if !param_decorators.is_empty() { let decorators_array = build_decorator_metadata_array(allocator, ¶m_decorators); map_entries.push(LiteralMapEntry { - key: Atom::from("decorators"), + key: Ident::from("decorators"), value: decorators_array, quoted: false, }); @@ -366,7 +366,7 @@ fn build_param_type_expression<'a>( /// /// Returns the simple type name from the annotation, if present. /// Used to get the type name for namespace-prefixed references in metadata. -fn extract_param_type_name<'a>(param: &FormalParameter<'a>) -> Option> { +fn extract_param_type_name<'a>(param: &FormalParameter<'a>) -> Option> { let type_annotation = param.type_annotation.as_ref()?; match &type_annotation.type_annotation { TSType::TSTypeReference(type_ref) => match &type_ref.type_name { @@ -444,10 +444,10 @@ fn get_decorator_name<'a>(decorator: &Decorator<'a>) -> Option<&'a str> { } /// Get property key name as an Atom. -fn get_property_key_name<'a>(key: &PropertyKey<'a>) -> Option> { +fn get_property_key_name<'a>(key: &PropertyKey<'a>) -> Option> { match key { PropertyKey::StaticIdentifier(id) => Some(id.name.into()), - PropertyKey::StringLiteral(lit) => Some(lit.value), + PropertyKey::StringLiteral(lit) => Some(lit.value.into()), _ => None, } } diff --git a/crates/oxc_angular_compiler/src/class_metadata/compiler.rs b/crates/oxc_angular_compiler/src/class_metadata/compiler.rs index da66f16d5..f0e679424 100644 --- a/crates/oxc_angular_compiler/src/class_metadata/compiler.rs +++ b/crates/oxc_angular_compiler/src/class_metadata/compiler.rs @@ -7,7 +7,7 @@ //! - `setClassMetadataAsync(type, resolver, callback)` for deferred dependencies use oxc_allocator::{Allocator, Box, Vec}; -use oxc_span::Atom; +use oxc_span::Ident; use super::metadata::{R3ClassMetadata, R3DeferPerComponentDependency}; use crate::output::ast::{ @@ -77,7 +77,7 @@ pub fn compile_opaque_async_class_metadata<'a>( allocator: &'a Allocator, metadata: &R3ClassMetadata<'a>, defer_resolver: OutputExpression<'a>, - deferred_dependency_names: &[Atom<'a>], + deferred_dependency_names: &[Ident<'a>], ) -> OutputExpression<'a> { let mut params = Vec::new_in(allocator); for name in deferred_dependency_names { @@ -106,16 +106,16 @@ pub fn compile_component_metadata_async_resolver<'a>( for dep in dependencies { // Create: (m) => m.CmpA (or m.default for default imports) let mut inner_params = Vec::new_in(allocator); - inner_params.push(FnParam { name: Atom::from("m") }); + inner_params.push(FnParam { name: Ident::from("m") }); let prop_name = - if dep.is_default_import { Atom::from("default") } else { dep.symbol_name.clone() }; + if dep.is_default_import { Ident::from("default") } else { dep.symbol_name.clone() }; let inner_body = OutputExpression::ReadProp(Box::new_in( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("m"), source_span: None }, + ReadVarExpr { name: Ident::from("m"), source_span: None }, allocator, )), allocator, @@ -149,7 +149,7 @@ pub fn compile_component_metadata_async_resolver<'a>( let then_prop = OutputExpression::ReadProp(Box::new_in( ReadPropExpr { receiver: Box::new_in(dynamic_import, allocator), - name: Atom::from("then"), + name: Ident::from("then"), optional: false, source_span: None, }, @@ -296,7 +296,7 @@ fn guarded_expression<'a>( expr: OutputExpression<'a>, ) -> OutputExpression<'a> { let guard_var = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from(guard), source_span: None }, + ReadVarExpr { name: Ident::from(guard), source_span: None }, allocator, )); @@ -349,12 +349,12 @@ fn import_expr<'a>(allocator: &'a Allocator, identifier: &'static str) -> Output ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(identifier), + name: Ident::from(identifier), optional: false, source_span: None, }, @@ -373,7 +373,7 @@ fn literal_null<'a>(allocator: &'a Allocator) -> OutputExpression<'a> { /// Creates a string literal. fn literal_string<'a>(allocator: &'a Allocator, value: &'static str) -> OutputExpression<'a> { OutputExpression::Literal(Box::new_in( - LiteralExpr { value: LiteralValue::String(Atom::from(value)), source_span: None }, + LiteralExpr { value: LiteralValue::String(Ident::from(value)), source_span: None }, allocator, )) } diff --git a/crates/oxc_angular_compiler/src/class_metadata/metadata.rs b/crates/oxc_angular_compiler/src/class_metadata/metadata.rs index 6ae215b87..46535ea0f 100644 --- a/crates/oxc_angular_compiler/src/class_metadata/metadata.rs +++ b/crates/oxc_angular_compiler/src/class_metadata/metadata.rs @@ -3,7 +3,7 @@ //! Ported from Angular's `render3/r3_class_metadata_compiler.ts` and `view/api.ts`. use crate::output::ast::OutputExpression; -use oxc_span::Atom; +use oxc_span::Ident; /// Metadata of a class which captures the original Angular decorators. /// @@ -35,10 +35,10 @@ pub struct R3ClassMetadata<'a> { #[derive(Debug)] pub struct R3DeferPerComponentDependency<'a> { /// The symbol name of the dependency. - pub symbol_name: Atom<'a>, + pub symbol_name: Ident<'a>, /// The import path for the dependency. - pub import_path: Atom<'a>, + pub import_path: Ident<'a>, /// Whether this is a default import. pub is_default_import: bool, diff --git a/crates/oxc_angular_compiler/src/component/decorator.rs b/crates/oxc_angular_compiler/src/component/decorator.rs index 9287f0fd4..7ff6a2bdc 100644 --- a/crates/oxc_angular_compiler/src/component/decorator.rs +++ b/crates/oxc_angular_compiler/src/component/decorator.rs @@ -8,7 +8,7 @@ use oxc_ast::ast::{ Argument, ArrayExpressionElement, Class, ClassElement, Decorator, Expression, MethodDefinitionKind, ObjectPropertyKind, PropertyKey, }; -use oxc_span::{Atom, Span}; +use oxc_span::{Ident, Span}; use super::dependency::R3DependencyMetadata; use super::metadata::{ @@ -52,7 +52,7 @@ pub fn extract_component_metadata<'a>( import_map: &ImportMap<'a>, ) -> Option> { // Get the class name - let class_name: Atom<'a> = class.id.as_ref()?.name.clone().into(); + let class_name: Ident<'a> = class.id.as_ref()?.name.clone().into(); let class_span = class.span; // Find the @Component decorator @@ -138,7 +138,7 @@ pub fn extract_component_metadata<'a>( for part in export_as.as_str().split(',') { let trimmed = part.trim(); if !trimmed.is_empty() { - metadata.export_as.push(Atom::from(allocator.alloc_str(trimmed))); + metadata.export_as.push(Ident::from(allocator.alloc_str(trimmed))); } } } @@ -196,7 +196,7 @@ pub fn extract_component_metadata<'a>( // Add @HostBinding properties // Wrap with brackets: "class.active" -> "[class.active]" for (host_prop, class_prop) in host_bindings { - let wrapped_key = Atom::from(allocator.alloc_str(&format!("[{}]", host_prop.as_str()))); + let wrapped_key = Ident::from(allocator.alloc_str(&format!("[{}]", host_prop.as_str()))); host.properties.push((wrapped_key, class_prop)); } @@ -206,15 +206,15 @@ pub fn extract_component_metadata<'a>( for (event_name, method_name, args) in host_listeners { // Wrap event name: "click" -> "(click)" let wrapped_key = - Atom::from(allocator.alloc_str(&format!("({})", event_name.as_str()))); + Ident::from(allocator.alloc_str(&format!("({})", event_name.as_str()))); // Build method expression with args: "handleClick" + ["$event"] -> "handleClick($event)" let method_expr = if args.is_empty() { - Atom::from(allocator.alloc_str(&format!("{}()", method_name.as_str()))) + Ident::from(allocator.alloc_str(&format!("{}()", method_name.as_str()))) } else { let args_str: String = args.iter().map(|a| a.as_str()).collect::>().join(","); - Atom::from(allocator.alloc_str(&format!("{}({})", method_name.as_str(), args_str))) + Ident::from(allocator.alloc_str(&format!("{}({})", method_name.as_str(), args_str))) }; host.listeners.push((wrapped_key, method_expr)); @@ -291,7 +291,7 @@ fn populate_declarations_from_imports<'a>( allocator, import_name.clone(), // Use a placeholder selector - the actual selector isn't used for dependencies array - Atom::from("*"), + Ident::from("*"), false, // is_component - unknown at this point ); @@ -334,23 +334,23 @@ fn is_component_call(callee: &Expression<'_>) -> bool { } /// Get the name of a property key as a string. -fn get_property_key_name<'a>(key: &PropertyKey<'a>) -> Option> { +fn get_property_key_name<'a>(key: &PropertyKey<'a>) -> Option> { match key { PropertyKey::StaticIdentifier(id) => Some(id.name.clone().into()), - PropertyKey::StringLiteral(lit) => Some(lit.value.clone()), + PropertyKey::StringLiteral(lit) => Some(lit.value.clone().into()), _ => None, } } /// Extract a string value from an expression. -fn extract_string_value<'a>(expr: &Expression<'a>) -> Option> { +fn extract_string_value<'a>(expr: &Expression<'a>) -> Option> { match expr { - Expression::StringLiteral(lit) => Some(lit.value.clone()), + Expression::StringLiteral(lit) => Some(lit.value.clone().into()), Expression::TemplateLiteral(tpl) if tpl.expressions.is_empty() => { // Simple template literal with no expressions: `template string` // Use cooked value to properly interpret escape sequences (\n -> newline) // Angular evaluates template literals, so we need cooked, not raw - tpl.quasis.first().and_then(|q| q.value.cooked.clone()) + tpl.quasis.first().and_then(|q| q.value.cooked.clone().map(Into::into)) } _ => None, } @@ -359,7 +359,7 @@ fn extract_string_value<'a>(expr: &Expression<'a>) -> Option> { /// Extract a boolean value from an expression. fn extract_boolean_value(expr: &Expression<'_>) -> Option { match expr { - Expression::BooleanLiteral(lit) => Some(lit.value), + Expression::BooleanLiteral(lit) => Some(lit.value.into()), _ => None, } } @@ -367,7 +367,7 @@ fn extract_boolean_value(expr: &Expression<'_>) -> Option { fn extract_string_array<'a>( allocator: &'a Allocator, expr: &Expression<'a>, -) -> Option>> { +) -> Option>> { let Expression::ArrayExpression(arr) = expr else { return None; }; @@ -375,13 +375,13 @@ fn extract_string_array<'a>( let mut result = Vec::new_in(allocator); for element in &arr.elements { if let ArrayExpressionElement::StringLiteral(lit) = element { - result.push(lit.value.clone()); + result.push(lit.value.clone().into()); } else if let ArrayExpressionElement::TemplateLiteral(tpl) = element { if tpl.expressions.is_empty() { // Use cooked value to properly interpret escape sequences if let Some(quasi) = tpl.quasis.first() { if let Some(cooked) = &quasi.value.cooked { - result.push(cooked.clone()); + result.push(cooked.clone().into()); } } } @@ -395,7 +395,7 @@ fn extract_string_array<'a>( fn extract_identifier_array<'a>( allocator: &'a Allocator, expr: &Expression<'a>, -) -> Vec<'a, Atom<'a>> { +) -> Vec<'a, Ident<'a>> { let mut result = Vec::new_in(allocator); let Expression::ArrayExpression(arr) = expr else { @@ -562,7 +562,7 @@ fn extract_single_host_directive<'a>( match element { // Simple identifier: TooltipDirective ArrayExpressionElement::Identifier(id) => { - let name: Atom<'a> = id.name.clone().into(); + let name: Ident<'a> = id.name.clone().into(); let mut meta = HostDirectiveMetadata::new(allocator, name.clone()); // Look up the source module from the import map if let Some(import_info) = import_map.get(&name) { @@ -573,7 +573,7 @@ fn extract_single_host_directive<'a>( // Object expression: { directive: ColorDirective, inputs: [...], outputs: [...] } ArrayExpressionElement::ObjectExpression(obj) => { - let mut directive_name: Option> = None; + let mut directive_name: Option> = None; let mut inputs = Vec::new_in(allocator); let mut outputs = Vec::new_in(allocator); let mut is_forward_reference = false; @@ -643,7 +643,7 @@ fn extract_single_host_directive<'a>( /// Extract a directive reference from an expression. /// /// Returns the directive class name and whether it's a forward reference. -fn extract_directive_reference<'a>(expr: &Expression<'a>) -> (Option>, bool) { +fn extract_directive_reference<'a>(expr: &Expression<'a>) -> (Option>, bool) { match expr { // Simple identifier: ColorDirective Expression::Identifier(id) => (Some(id.name.clone().into()), false), @@ -672,7 +672,7 @@ fn is_forward_ref_call(callee: &Expression<'_>) -> bool { /// Extract the directive name from a forwardRef argument. /// /// Handles: `forwardRef(() => MyDirective)` -fn extract_forward_ref_directive_name<'a>(arg: Option<&Argument<'a>>) -> Option> { +fn extract_forward_ref_directive_name<'a>(arg: Option<&Argument<'a>>) -> Option> { let arg = arg?; match arg { // forwardRef(() => MyDirective) @@ -712,7 +712,7 @@ fn extract_forward_ref_directive_name<'a>(arg: Option<&Argument<'a>>) -> Option< fn extract_io_mappings<'a>( allocator: &'a Allocator, expr: &Expression<'a>, -) -> Vec<'a, (Atom<'a>, Atom<'a>)> { +) -> Vec<'a, (Ident<'a>, Ident<'a>)> { let mut result = Vec::new_in(allocator); let Expression::ArrayExpression(arr) = expr else { @@ -737,7 +737,7 @@ fn extract_io_mappings<'a>( fn parse_mapping_element<'a>( allocator: &'a Allocator, element: &ArrayExpressionElement<'a>, -) -> Option<(Atom<'a>, Atom<'a>)> { +) -> Option<(Ident<'a>, Ident<'a>)> { match element { // Simple string: "color" - same public and internal name ArrayExpressionElement::StringLiteral(lit) => { @@ -748,12 +748,12 @@ fn parse_mapping_element<'a>( let internal_name = value[..colon_pos].trim(); let public_name = value[colon_pos + 1..].trim(); Some(( - Atom::from(allocator.alloc_str(public_name)), - Atom::from(allocator.alloc_str(internal_name)), + Ident::from(allocator.alloc_str(public_name)), + Ident::from(allocator.alloc_str(internal_name)), )) } else { // Same name for both - Some((lit.value.clone(), lit.value.clone())) + Some((lit.value.clone().into(), lit.value.clone().into())) } } @@ -762,11 +762,11 @@ fn parse_mapping_element<'a>( let elements = &arr.elements; if elements.len() >= 2 { let internal = match elements.first() { - Some(ArrayExpressionElement::StringLiteral(lit)) => Some(lit.value.clone()), + Some(ArrayExpressionElement::StringLiteral(lit)) => Some(lit.value.clone().into()), _ => None, }; let public = match elements.get(1) { - Some(ArrayExpressionElement::StringLiteral(lit)) => Some(lit.value.clone()), + Some(ArrayExpressionElement::StringLiteral(lit)) => Some(lit.value.clone().into()), _ => None, }; if let (Some(internal_name), Some(public_name)) = (internal, public) { @@ -898,8 +898,8 @@ fn extract_param_dependency<'a>( let mut skip_self = false; let mut self_ = false; let mut host = false; - let mut inject_token: Option> = None; - let mut attribute_name: Option> = None; + let mut inject_token: Option> = None; + let mut attribute_name: Option> = None; for decorator in ¶m.decorators { if let Some(name) = get_decorator_name(&decorator.expression) { @@ -920,7 +920,7 @@ fn extract_param_dependency<'a>( // @Attribute('attrName') - extract the attribute name if let Expression::CallExpression(call) = &decorator.expression { if let Some(Argument::StringLiteral(s)) = call.arguments.first() { - attribute_name = Some(s.value.clone()); + attribute_name = Some(s.value.clone().into()); } } } @@ -965,7 +965,7 @@ fn extract_param_dependency<'a>( } /// Get the name of a decorator from its expression. -fn get_decorator_name<'a>(expr: &'a Expression<'a>) -> Option> { +fn get_decorator_name<'a>(expr: &'a Expression<'a>) -> Option> { match expr { // @Optional Expression::Identifier(id) => Some(id.name.clone().into()), @@ -982,7 +982,7 @@ fn get_decorator_name<'a>(expr: &'a Expression<'a>) -> Option> { } /// Extract the injection token from an @Inject decorator argument. -fn extract_inject_token<'a>(arg: &'a Argument<'a>) -> Option> { +fn extract_inject_token<'a>(arg: &'a Argument<'a>) -> Option> { match arg { Argument::Identifier(id) => Some(id.name.clone().into()), _ => { @@ -997,7 +997,7 @@ fn extract_inject_token<'a>(arg: &'a Argument<'a>) -> Option> { } /// Extract the injection token from a parameter's type annotation. -fn extract_param_token<'a>(param: &'a oxc_ast::ast::FormalParameter<'a>) -> Option> { +fn extract_param_token<'a>(param: &'a oxc_ast::ast::FormalParameter<'a>) -> Option> { // Get the type annotation (directly on FormalParameter) let type_annotation = param.type_annotation.as_ref()?; let ts_type = &type_annotation.type_annotation; diff --git a/crates/oxc_angular_compiler/src/component/definition.rs b/crates/oxc_angular_compiler/src/component/definition.rs index 8d02a5add..8a6418e93 100644 --- a/crates/oxc_angular_compiler/src/component/definition.rs +++ b/crates/oxc_angular_compiler/src/component/definition.rs @@ -13,7 +13,7 @@ //! - Inject dependencies use oxc_allocator::{Allocator, Box, FromIn, Vec as OxcVec}; -use oxc_span::Atom; +use oxc_span::Ident; use crate::r3::Identifiers; @@ -129,7 +129,7 @@ fn generate_cmp_definition<'a>( // 1. type: ComponentClass entries.push(LiteralMapEntry { - key: Atom::from("type"), + key: Ident::from("type"), value: OutputExpression::ReadVar(Box::new_in( ReadVarExpr { name: metadata.class_name.clone(), source_span: None }, allocator, @@ -142,10 +142,10 @@ fn generate_cmp_definition<'a>( // See: packages/compiler-cli/src/ngtsc/annotations/directive/src/shared.ts:264-290 // and packages/compiler/src/schema/dom_element_schema_registry.ts:463 let selector_value = - metadata.selector.as_ref().map_or_else(|| Atom::from("ng-component"), |s| s.clone()); + metadata.selector.as_ref().map_or_else(|| Ident::from("ng-component"), |s| s.clone()); let selector_entries = parse_selector_to_array(allocator, &selector_value); entries.push(LiteralMapEntry { - key: Atom::from("selectors"), + key: Ident::from("selectors"), value: selector_entries, quoted: false, }); @@ -156,7 +156,7 @@ fn generate_cmp_definition<'a>( // Per Angular compiler.ts lines 57-63 (baseDirectiveFields) if let Some(content_queries) = content_queries_fn { entries.push(LiteralMapEntry { - key: Atom::from("contentQueries"), + key: Ident::from("contentQueries"), value: content_queries, quoted: false, }); @@ -168,7 +168,7 @@ fn generate_cmp_definition<'a>( // Per Angular compiler.ts lines 65-70 (baseDirectiveFields) if let Some(view_query) = view_query_fn { entries.push(LiteralMapEntry { - key: Atom::from("viewQuery"), + key: Ident::from("viewQuery"), value: view_query, quoted: false, }); @@ -182,7 +182,7 @@ fn generate_cmp_definition<'a>( // 5. hostAttrs: [...] - static host attributes if let Some(host_attrs) = host_result.host_attrs { entries.push(LiteralMapEntry { - key: Atom::from("hostAttrs"), + key: Ident::from("hostAttrs"), value: host_attrs, quoted: false, }); @@ -191,7 +191,7 @@ fn generate_cmp_definition<'a>( // 6. hostVars: number - only if > 0 if let Some(host_vars) = host_result.host_vars { entries.push(LiteralMapEntry { - key: Atom::from("hostVars"), + key: Ident::from("hostVars"), value: OutputExpression::Literal(Box::new_in( LiteralExpr { value: LiteralValue::Number(host_vars as f64), @@ -206,7 +206,7 @@ fn generate_cmp_definition<'a>( // 7. hostBindings: function(rf, ctx) { ... } (if any) if let Some(host_fn) = host_result.host_binding_fn { entries.push(LiteralMapEntry { - key: Atom::from("hostBindings"), + key: Ident::from("hostBindings"), value: OutputExpression::Function(Box::new_in(host_fn, allocator)), quoted: false, }); @@ -218,7 +218,7 @@ fn generate_cmp_definition<'a>( if !metadata.inputs.is_empty() { if let Some(inputs_expr) = create_inputs_literal(allocator, &metadata.inputs) { entries.push(LiteralMapEntry { - key: Atom::from("inputs"), + key: Ident::from("inputs"), value: inputs_expr, quoted: false, }); @@ -230,7 +230,7 @@ fn generate_cmp_definition<'a>( if !metadata.outputs.is_empty() { if let Some(outputs_expr) = create_outputs_literal(allocator, &metadata.outputs) { entries.push(LiteralMapEntry { - key: Atom::from("outputs"), + key: Ident::from("outputs"), value: outputs_expr, quoted: false, }); @@ -248,7 +248,7 @@ fn generate_cmp_definition<'a>( ))); } entries.push(LiteralMapEntry { - key: Atom::from("exportAs"), + key: Ident::from("exportAs"), value: OutputExpression::LiteralArray(Box::new_in( LiteralArrayExpr { entries: export_items, source_span: None }, allocator, @@ -261,7 +261,7 @@ fn generate_cmp_definition<'a>( // Per Angular compiler.ts lines 96-98 (baseDirectiveFields) if !metadata.standalone { entries.push(LiteralMapEntry { - key: Atom::from("standalone"), + key: Ident::from("standalone"), value: OutputExpression::Literal(Box::new_in( LiteralExpr { value: LiteralValue::Boolean(false), source_span: None }, allocator, @@ -274,7 +274,7 @@ fn generate_cmp_definition<'a>( // Per Angular compiler.ts lines 99-101 (baseDirectiveFields) if metadata.is_signal { entries.push(LiteralMapEntry { - key: Atom::from("signals"), + key: Ident::from("signals"), value: OutputExpression::Literal(Box::new_in( LiteralExpr { value: LiteralValue::Boolean(true), source_span: None }, allocator, @@ -291,7 +291,7 @@ fn generate_cmp_definition<'a>( // See: packages/compiler/src/render3/view/compiler.ts:119-161 if let Some(features) = generate_features_array(allocator, metadata, namespace_registry) { entries.push(LiteralMapEntry { - key: Atom::from("features"), + key: Ident::from("features"), value: features, quoted: false, }); @@ -307,14 +307,14 @@ fn generate_cmp_definition<'a>( // The attrs_ref is pre-pooled BEFORE template compilation to ensure correct constant ordering. // TypeScript Angular adds attrs to the pool BEFORE template ingestion/compilation. if let Some(attrs) = attrs_ref { - entries.push(LiteralMapEntry { key: Atom::from("attrs"), value: attrs, quoted: false }); + entries.push(LiteralMapEntry { key: Ident::from("attrs"), value: attrs, quoted: false }); } // 15. ngContentSelectors: [...] - content projection selectors // Per Angular compiler.ts lines 254-256 if let Some(content_selectors) = job.content_selectors.take() { entries.push(LiteralMapEntry { - key: Atom::from("ngContentSelectors"), + key: Ident::from("ngContentSelectors"), value: content_selectors, quoted: false, }); @@ -324,7 +324,7 @@ fn generate_cmp_definition<'a>( // Per Angular compiler.ts line 258 let decls = job.root.decl_count.unwrap_or(0); entries.push(LiteralMapEntry { - key: Atom::from("decls"), + key: Ident::from("decls"), value: OutputExpression::Literal(Box::new_in( LiteralExpr { value: LiteralValue::Number(decls as f64), source_span: None }, allocator, @@ -336,7 +336,7 @@ fn generate_cmp_definition<'a>( // Per Angular compiler.ts line 259 let vars = job.root.vars.unwrap_or(0); entries.push(LiteralMapEntry { - key: Atom::from("vars"), + key: Ident::from("vars"), value: OutputExpression::Literal(Box::new_in( LiteralExpr { value: LiteralValue::Number(vars as f64), source_span: None }, allocator, @@ -395,7 +395,7 @@ fn generate_cmp_definition<'a>( }; entries.push(LiteralMapEntry { - key: Atom::from("consts"), + key: Ident::from("consts"), value: consts_value, quoted: false, }); @@ -404,7 +404,7 @@ fn generate_cmp_definition<'a>( // 19. template: function(rf, ctx) { ... } // Per Angular compiler.ts line 270 entries.push(LiteralMapEntry { - key: Atom::from("template"), + key: Ident::from("template"), value: OutputExpression::Function(Box::new_in(template_fn, allocator)), quoted: false, }); @@ -415,7 +415,7 @@ fn generate_cmp_definition<'a>( generate_dependencies_expression(allocator, metadata, namespace_registry) { entries.push(LiteralMapEntry { - key: Atom::from("dependencies"), + key: Ident::from("dependencies"), value: dependencies, quoted: false, }); @@ -449,7 +449,7 @@ fn generate_cmp_definition<'a>( if style.trim().is_empty() { continue; } - let style_value = Atom::from_in(style.as_str(), allocator); + let style_value = Ident::from_in(style.as_str(), allocator); style_entries.push(OutputExpression::Literal(Box::new_in( LiteralExpr { value: LiteralValue::String(style_value), source_span: None }, @@ -460,7 +460,7 @@ fn generate_cmp_definition<'a>( if !style_entries.is_empty() { has_styles = true; entries.push(LiteralMapEntry { - key: Atom::from("styles"), + key: Ident::from("styles"), value: OutputExpression::LiteralArray(Box::new_in( LiteralArrayExpr { entries: style_entries, source_span: None }, allocator, @@ -486,7 +486,7 @@ fn generate_cmp_definition<'a>( ViewEncapsulation::ShadowDom => 3, }; entries.push(LiteralMapEntry { - key: Atom::from("encapsulation"), + key: Ident::from("encapsulation"), value: OutputExpression::Literal(Box::new_in( LiteralExpr { value: LiteralValue::Number(encapsulation_value as f64), @@ -505,14 +505,14 @@ fn generate_cmp_definition<'a>( let mut data_entries: OxcVec<'a, LiteralMapEntry<'a>> = OxcVec::with_capacity_in(1, allocator); data_entries.push(LiteralMapEntry { - key: Atom::from("animation"), + key: Ident::from("animation"), // Use the full animations expression directly value: animations.clone_in(allocator), quoted: false, }); entries.push(LiteralMapEntry { - key: Atom::from("data"), + key: Ident::from("data"), value: OutputExpression::LiteralMap(Box::new_in( LiteralMapExpr { entries: data_entries, source_span: None }, allocator, @@ -535,7 +535,7 @@ fn generate_cmp_definition<'a>( // ReadPropExpr { receiver: ReadVarExpr("ChangeDetectionStrategy"), name: "OnPush" } let change_detection_strategy_expr = OutputExpression::ReadVar(Box::new_in( ReadVarExpr { - name: Atom::from(Identifiers::CHANGE_DETECTION_STRATEGY), + name: Ident::from(Identifiers::CHANGE_DETECTION_STRATEGY), source_span: None, }, allocator, @@ -543,14 +543,14 @@ fn generate_cmp_definition<'a>( let strategy_value_expr = OutputExpression::ReadProp(Box::new_in( ReadPropExpr { receiver: Box::new_in(change_detection_strategy_expr, allocator), - name: Atom::from(strategy_name), + name: Ident::from(strategy_name), optional: false, source_span: None, }, allocator, )); entries.push(LiteralMapEntry { - key: Atom::from("changeDetection"), + key: Ident::from("changeDetection"), value: strategy_value_expr, quoted: false, }); @@ -633,11 +633,11 @@ fn generate_constructor_factory<'a>( ) -> OutputExpression<'a> { // Function name: ComponentClass_Factory let fn_name_string = format!("{}_Factory", metadata.class_name); - let fn_name = Atom::from_in(fn_name_string.as_str(), allocator); + let fn_name = Ident::from_in(fn_name_string.as_str(), allocator); // Parameter: __ngFactoryType__ (type override for inheritance/testing) let mut params: OxcVec<'a, FnParam<'a>> = OxcVec::new_in(allocator); - params.push(FnParam { name: Atom::from("__ngFactoryType__") }); + params.push(FnParam { name: Ident::from("__ngFactoryType__") }); // Body: return new (__ngFactoryType__ || ComponentClass)(deps...); let mut statements: OxcVec<'a, OutputStatement<'a>> = OxcVec::new_in(allocator); @@ -648,7 +648,7 @@ fn generate_constructor_factory<'a>( operator: crate::output::ast::BinaryOperator::Or, lhs: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("__ngFactoryType__"), source_span: None }, + ReadVarExpr { name: Ident::from("__ngFactoryType__"), source_span: None }, allocator, )), allocator, @@ -720,15 +720,15 @@ fn generate_inherited_factory<'a>( StmtModifier, }; - let factory_type_param = Atom::from("__ngFactoryType__"); + let factory_type_param = Ident::from("__ngFactoryType__"); // Create base factory variable name: ɵComponentClass_BaseFactory let base_factory_var_name = - Atom::from_in(format!("ɵ{}_BaseFactory", metadata.class_name).as_str(), allocator); + Ident::from_in(format!("ɵ{}_BaseFactory", metadata.class_name).as_str(), allocator); // Function name: ComponentClass_Factory let fn_name_string = format!("{}_Factory", metadata.class_name); - let fn_name = Atom::from_in(fn_name_string.as_str(), allocator); + let fn_name = Ident::from_in(fn_name_string.as_str(), allocator); // Create ɵɵgetInheritedFactory(ComponentClass) call let get_inherited_factory_call = { @@ -736,12 +736,12 @@ fn generate_inherited_factory<'a>( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(Identifiers::GET_INHERITED_FACTORY), + name: Ident::from(Identifiers::GET_INHERITED_FACTORY), optional: false, source_span: None, }, @@ -913,12 +913,12 @@ fn create_define_component_call<'a>( crate::output::ast::ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(Identifiers::DEFINE_COMPONENT), + name: Ident::from(Identifiers::DEFINE_COMPONENT), optional: false, source_span: None, }, @@ -953,7 +953,7 @@ fn create_define_component_call<'a>( /// Ported from Angular's `parseSelectorToR3Selector` in `core.ts`. fn parse_selector_to_array<'a>( allocator: &'a Allocator, - selector: &Atom<'a>, + selector: &Ident<'a>, ) -> OutputExpression<'a> { let r3_selectors = parse_selector_to_r3_selector(selector.as_str()); @@ -1194,7 +1194,7 @@ fn create_host_directives_arg<'a>( // directive: DirectiveClass (or i1.DirectiveClass for imports) entries.push(LiteralMapEntry { - key: Atom::from("directive"), + key: Ident::from("directive"), value: directive_ref, quoted: false, }); @@ -1204,7 +1204,7 @@ fn create_host_directives_arg<'a>( let inputs_array = create_host_directive_mappings_array(allocator, &directive.inputs); entries.push(LiteralMapEntry { - key: Atom::from("inputs"), + key: Ident::from("inputs"), value: inputs_array, quoted: false, }); @@ -1215,7 +1215,7 @@ fn create_host_directives_arg<'a>( let outputs_array = create_host_directive_mappings_array(allocator, &directive.outputs); entries.push(LiteralMapEntry { - key: Atom::from("outputs"), + key: Ident::from("outputs"), value: outputs_array, quoted: false, }); @@ -1305,12 +1305,12 @@ fn create_angular_fn_ref<'a>( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(fn_name), + name: Ident::from(fn_name), optional: false, source_span: None, }, @@ -1471,7 +1471,7 @@ fn compile_declaration_list<'a>( OutputExpression::ReadProp(Box::new_in( ReadPropExpr { receiver: Box::new_in(list, allocator), - name: Atom::from("map"), + name: Ident::from("map"), optional: false, source_span: None, }, @@ -1568,7 +1568,7 @@ pub fn const_value_to_expression<'a>( crate::output::ast::ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, @@ -1593,8 +1593,8 @@ mod tests { fn create_test_metadata<'a>(allocator: &'a Allocator) -> ComponentMetadata<'a> { let mut metadata = - ComponentMetadata::new(allocator, Atom::from("TestComponent"), Span::empty(0), true); - metadata.selector = Some(Atom::from("app-test")); + ComponentMetadata::new(allocator, Ident::from("TestComponent"), Span::empty(0), true); + metadata.selector = Some(Ident::from("app-test")); metadata } @@ -1617,7 +1617,7 @@ mod tests { #[test] fn test_parse_element_selector() { let allocator = Allocator::default(); - let result = parse_selector_to_array(&allocator, &Atom::from("app-root")); + let result = parse_selector_to_array(&allocator, &Ident::from("app-root")); let emitter = JsEmitter::new(); let js = emitter.emit_expression(&result); @@ -1628,7 +1628,7 @@ mod tests { #[test] fn test_parse_attribute_selector() { let allocator = Allocator::default(); - let result = parse_selector_to_array(&allocator, &Atom::from("[type=button]")); + let result = parse_selector_to_array(&allocator, &Ident::from("[type=button]")); let emitter = JsEmitter::new(); let js = emitter.emit_expression(&result); @@ -1649,7 +1649,7 @@ mod tests { let allocator = Allocator::default(); let mut metadata = ComponentMetadata::new( &allocator, - Atom::from("EmptyOutletComponent"), + Ident::from("EmptyOutletComponent"), Span::empty(0), true, ); @@ -1657,7 +1657,7 @@ mod tests { metadata.selector = None; let selector_value = - metadata.selector.as_ref().map_or_else(|| Atom::from("ng-component"), |s| s.clone()); + metadata.selector.as_ref().map_or_else(|| Ident::from("ng-component"), |s| s.clone()); let result = parse_selector_to_array(&allocator, &selector_value); let emitter = JsEmitter::new(); @@ -1671,11 +1671,11 @@ mod tests { fn test_explicit_selector_overrides_default() { let allocator = Allocator::default(); let mut metadata = - ComponentMetadata::new(&allocator, Atom::from("TestComponent"), Span::empty(0), true); - metadata.selector = Some(Atom::from("app-test")); + ComponentMetadata::new(&allocator, Ident::from("TestComponent"), Span::empty(0), true); + metadata.selector = Some(Ident::from("app-test")); let selector_value = - metadata.selector.as_ref().map_or_else(|| Atom::from("ng-component"), |s| s.clone()); + metadata.selector.as_ref().map_or_else(|| Ident::from("ng-component"), |s| s.clone()); let result = parse_selector_to_array(&allocator, &selector_value); let emitter = JsEmitter::new(); @@ -1709,7 +1709,7 @@ mod tests { OxcVec::with_capacity_in(names.len(), allocator); for name in names { entries.push(OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from(*name), source_span: None }, + ReadVarExpr { name: Ident::from(*name), source_span: None }, allocator, ))); } @@ -1817,8 +1817,8 @@ mod tests { let allocator = Allocator::default(); let mut metadata = create_test_metadata(&allocator); let mut namespace_registry = NamespaceRegistry::new(&allocator); - metadata.external_styles.push(Atom::from("./styles.css")); - metadata.external_styles.push(Atom::from("./theme.css")); + metadata.external_styles.push(Ident::from("./styles.css")); + metadata.external_styles.push(Ident::from("./theme.css")); let result = generate_features_array(&allocator, &metadata, &mut namespace_registry).unwrap(); @@ -1837,7 +1837,7 @@ mod tests { let mut metadata = create_test_metadata(&allocator); let mut namespace_registry = NamespaceRegistry::new(&allocator); - let directive = HostDirectiveMetadata::new(&allocator, Atom::from("MyDirective")); + let directive = HostDirectiveMetadata::new(&allocator, Ident::from("MyDirective")); metadata.host_directives.push(directive); let result = @@ -1856,9 +1856,9 @@ mod tests { let mut metadata = create_test_metadata(&allocator); let mut namespace_registry = NamespaceRegistry::new(&allocator); - let mut directive = HostDirectiveMetadata::new(&allocator, Atom::from("MyDirective")); - directive.inputs.push((Atom::from("publicInput"), Atom::from("internalInput"))); - directive.outputs.push((Atom::from("publicOutput"), Atom::from("internalOutput"))); + let mut directive = HostDirectiveMetadata::new(&allocator, Ident::from("MyDirective")); + directive.inputs.push((Ident::from("publicInput"), Ident::from("internalInput"))); + directive.outputs.push((Ident::from("publicOutput"), Ident::from("internalOutput"))); metadata.host_directives.push(directive); let result = @@ -1881,7 +1881,7 @@ mod tests { let mut metadata = create_test_metadata(&allocator); let mut namespace_registry = NamespaceRegistry::new(&allocator); - let mut directive = HostDirectiveMetadata::new(&allocator, Atom::from("ForwardRefDir")); + let mut directive = HostDirectiveMetadata::new(&allocator, Ident::from("ForwardRefDir")); directive.is_forward_reference = true; metadata.host_directives.push(directive); @@ -1904,8 +1904,8 @@ mod tests { let mut namespace_registry = NamespaceRegistry::new(&allocator); // Create directive with source_module (imported from another module) - let directive = HostDirectiveMetadata::new(&allocator, Atom::from("ExternalDirective")) - .with_source_module(Atom::from("@angular/external")); + let directive = HostDirectiveMetadata::new(&allocator, Ident::from("ExternalDirective")) + .with_source_module(Ident::from("@angular/external")); metadata.host_directives.push(directive); let result = @@ -1932,13 +1932,13 @@ mod tests { let mut namespace_registry = NamespaceRegistry::new(&allocator); // Local directive (no source_module) - let local_directive = HostDirectiveMetadata::new(&allocator, Atom::from("LocalDirective")); + let local_directive = HostDirectiveMetadata::new(&allocator, Ident::from("LocalDirective")); metadata.host_directives.push(local_directive); // Imported directive (with source_module) let imported_directive = - HostDirectiveMetadata::new(&allocator, Atom::from("ImportedDirective")) - .with_source_module(Atom::from("@angular/library")); + HostDirectiveMetadata::new(&allocator, Ident::from("ImportedDirective")) + .with_source_module(Ident::from("@angular/library")); metadata.host_directives.push(imported_directive); let result = @@ -2007,16 +2007,16 @@ mod tests { // Add directives using the TemplateDependency from metadata module let dir = crate::component::metadata::TemplateDependency::directive( &allocator, - Atom::from("MyDirective"), - Atom::from("[myDir]"), + Ident::from("MyDirective"), + Ident::from("[myDir]"), false, ); metadata.declarations.push(dir); let pipe = crate::component::metadata::TemplateDependency::pipe( &allocator, - Atom::from("MyPipe"), - Atom::from("myPipe"), + Ident::from("MyPipe"), + Ident::from("myPipe"), ); metadata.declarations.push(pipe); @@ -2043,8 +2043,8 @@ mod tests { let dir = crate::component::metadata::TemplateDependency::directive( &allocator, - Atom::from("ForwardDir"), - Atom::from("[fwd]"), + Ident::from("ForwardDir"), + Ident::from("[fwd]"), false, ); metadata.declarations.push(dir); @@ -2072,8 +2072,8 @@ mod tests { let dir = crate::component::metadata::TemplateDependency::directive( &allocator, - Atom::from("JitDir"), - Atom::from("[jit]"), + Ident::from("JitDir"), + Ident::from("[jit]"), false, ); metadata.declarations.push(dir); @@ -2122,7 +2122,7 @@ mod tests { metadata.declaration_list_emit_mode = DeclarationListEmitMode::RuntimeResolved; // Test with a variable reference as raw_imports metadata.raw_imports = Some(OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("IMPORTS"), source_span: None }, + ReadVarExpr { name: Ident::from("IMPORTS"), source_span: None }, &allocator, ))); @@ -2151,15 +2151,15 @@ mod tests { // Test with an array literal as raw_imports (like imports: [A, B, C]) let mut entries: OxcVec<'_, OutputExpression<'_>> = OxcVec::with_capacity_in(3, &allocator); entries.push(OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("A"), source_span: None }, + ReadVarExpr { name: Ident::from("A"), source_span: None }, &allocator, ))); entries.push(OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("B"), source_span: None }, + ReadVarExpr { name: Ident::from("B"), source_span: None }, &allocator, ))); entries.push(OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("C"), source_span: None }, + ReadVarExpr { name: Ident::from("C"), source_span: None }, &allocator, ))); metadata.raw_imports = Some(OutputExpression::LiteralArray(Box::new_in( @@ -2187,11 +2187,11 @@ mod tests { // Add an imported directive with source_module let dir = crate::component::metadata::TemplateDependency::directive( &allocator, - Atom::from("RouterOutlet"), - Atom::from("router-outlet"), + Ident::from("RouterOutlet"), + Ident::from("router-outlet"), false, ) - .with_source_module(Atom::from("@angular/router")); + .with_source_module(Ident::from("@angular/router")); metadata.declarations.push(dir); metadata.declaration_list_emit_mode = DeclarationListEmitMode::Direct; @@ -2207,7 +2207,7 @@ mod tests { assert!(js.contains("i1.RouterOutlet")); // Verify namespace was registered - assert!(namespace_registry.has_module(&Atom::from("@angular/router"))); + assert!(namespace_registry.has_module(&Ident::from("@angular/router"))); } #[test] @@ -2219,8 +2219,8 @@ mod tests { // Add a local directive (no source_module) let local_dir = crate::component::metadata::TemplateDependency::directive( &allocator, - Atom::from("LocalDirective"), - Atom::from("[local]"), + Ident::from("LocalDirective"), + Ident::from("[local]"), false, ); metadata.declarations.push(local_dir); @@ -2228,11 +2228,11 @@ mod tests { // Add an imported directive let imported_dir = crate::component::metadata::TemplateDependency::directive( &allocator, - Atom::from("CommonModule"), - Atom::from("[common]"), + Ident::from("CommonModule"), + Ident::from("[common]"), false, ) - .with_source_module(Atom::from("@angular/common")); + .with_source_module(Ident::from("@angular/common")); metadata.declarations.push(imported_dir); metadata.declaration_list_emit_mode = DeclarationListEmitMode::Direct; @@ -2258,10 +2258,10 @@ mod tests { metadata.providers = Some(create_test_providers_array(&allocator, &["ServiceA"])); metadata.uses_inheritance = true; metadata.lifecycle = LifecycleMetadata { uses_on_changes: true }; - metadata.external_styles.push(Atom::from("./styles.css")); + metadata.external_styles.push(Ident::from("./styles.css")); // Add host directive - let directive = HostDirectiveMetadata::new(&allocator, Atom::from("HostDir")); + let directive = HostDirectiveMetadata::new(&allocator, Ident::from("HostDir")); metadata.host_directives.push(directive); let result = @@ -2305,7 +2305,7 @@ mod tests { let mut metadata = create_test_metadata(&allocator); // Create an animations expression (identifier reference) metadata.animations = Some(OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("myAnimations"), source_span: None }, + ReadVarExpr { name: Ident::from("myAnimations"), source_span: None }, &allocator, ))); diff --git a/crates/oxc_angular_compiler/src/component/dependency.rs b/crates/oxc_angular_compiler/src/component/dependency.rs index e615f203c..42abcb803 100644 --- a/crates/oxc_angular_compiler/src/component/dependency.rs +++ b/crates/oxc_angular_compiler/src/component/dependency.rs @@ -9,7 +9,7 @@ //! Ported from: `packages/compiler/src/render3/r3_factory.ts` use oxc_allocator::{Allocator, Box, Vec as OxcVec}; -use oxc_span::Atom; +use oxc_span::Ident; use super::namespace_registry::NamespaceRegistry; use crate::output::ast::{ @@ -29,12 +29,12 @@ use crate::r3::Identifiers; pub struct R3DependencyMetadata<'a> { /// The injection token name (service class name, InjectionToken, etc.). /// `None` represents an invalid/unresolved dependency. - pub token: Option>, + pub token: Option>, /// The source module of the token (e.g., "@angular/core", "@angular/router"). /// Used to generate proper namespace aliases for imported dependencies. /// `None` for local dependencies or when the source is unknown. - pub token_source_module: Option>, + pub token_source_module: Option>, /// Whether the token has an existing named import in the source file. /// If true, the token can be used with a bare name instead of namespace prefix. @@ -47,7 +47,7 @@ pub struct R3DependencyMetadata<'a> { /// For `@Attribute()` dependencies, the attribute name. /// `None` for regular dependencies. - pub attribute_name: Option>, + pub attribute_name: Option>, /// Whether `@Host()` decorator is present. pub host: bool, @@ -64,7 +64,7 @@ pub struct R3DependencyMetadata<'a> { impl<'a> R3DependencyMetadata<'a> { /// Create a new dependency metadata with default flags. - pub fn new(token: Atom<'a>) -> Self { + pub fn new(token: Ident<'a>) -> Self { Self { token: Some(token), token_source_module: None, @@ -116,7 +116,7 @@ impl<'a> R3DependencyMetadata<'a> { } /// Create an `@Attribute()` dependency. - pub fn attribute(attribute_name: Atom<'a>) -> Self { + pub fn attribute(attribute_name: Ident<'a>) -> Self { Self { token: Some(attribute_name.clone()), token_source_module: None, @@ -136,7 +136,7 @@ impl<'a> R3DependencyMetadata<'a> { } /// Set the source module for the token. - pub fn with_token_source_module(mut self, source_module: Atom<'a>) -> Self { + pub fn with_token_source_module(mut self, source_module: Ident<'a>) -> Self { self.token_source_module = Some(source_module); self } @@ -322,7 +322,7 @@ fn compile_inject_dependency<'a>( fn create_token_expression<'a>( allocator: &'a Allocator, dep: &R3DependencyMetadata<'a>, - token_name: &Atom<'a>, + token_name: &Ident<'a>, namespace_registry: &mut NamespaceRegistry<'a>, ) -> OutputExpression<'a> { if let Some(ref source_module) = dep.token_source_module { @@ -391,7 +391,7 @@ fn create_invalid_factory_dep_call<'a>( /// Create an `i0.ɵɵinjectAttribute(attrName)` call. fn create_inject_attribute_call<'a>( allocator: &'a Allocator, - attr_name: Atom<'a>, + attr_name: Ident<'a>, ) -> OutputExpression<'a> { let fn_expr = create_angular_fn_ref(allocator, Identifiers::INJECT_ATTRIBUTE); @@ -460,12 +460,12 @@ fn create_angular_fn_ref<'a>( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(fn_name), + name: Ident::from(fn_name), optional: false, source_span: None, }, @@ -494,7 +494,7 @@ mod tests { #[test] fn test_simple_dependency() { let allocator = Allocator::default(); - let dep = R3DependencyMetadata::new(Atom::from("MyService")); + let dep = R3DependencyMetadata::new(Ident::from("MyService")); let mut registry = NamespaceRegistry::new(&allocator); let result = @@ -511,7 +511,7 @@ mod tests { #[test] fn test_optional_dependency() { let allocator = Allocator::default(); - let dep = R3DependencyMetadata::new(Atom::from("MyService")).with_optional(); + let dep = R3DependencyMetadata::new(Ident::from("MyService")).with_optional(); let mut registry = NamespaceRegistry::new(&allocator); let result = @@ -528,7 +528,7 @@ mod tests { #[test] fn test_host_dependency() { let allocator = Allocator::default(); - let dep = R3DependencyMetadata::new(Atom::from("HostService")).with_host(); + let dep = R3DependencyMetadata::new(Ident::from("HostService")).with_host(); let mut registry = NamespaceRegistry::new(&allocator); let result = @@ -545,7 +545,7 @@ mod tests { #[test] fn test_combined_flags() { let allocator = Allocator::default(); - let dep = R3DependencyMetadata::new(Atom::from("Service")).with_optional().with_host(); + let dep = R3DependencyMetadata::new(Ident::from("Service")).with_optional().with_host(); let mut registry = NamespaceRegistry::new(&allocator); let result = @@ -561,7 +561,7 @@ mod tests { #[test] fn test_injectable_uses_inject() { let allocator = Allocator::default(); - let dep = R3DependencyMetadata::new(Atom::from("Service")); + let dep = R3DependencyMetadata::new(Ident::from("Service")); let mut registry = NamespaceRegistry::new(&allocator); let result = compile_inject_dependency( @@ -598,7 +598,7 @@ mod tests { #[test] fn test_attribute_dependency() { let allocator = Allocator::default(); - let dep = R3DependencyMetadata::attribute(Atom::from("title")); + let dep = R3DependencyMetadata::attribute(Ident::from("title")); let mut registry = NamespaceRegistry::new(&allocator); let result = @@ -614,8 +614,8 @@ mod tests { #[test] fn test_imported_dependency_with_namespace() { let allocator = Allocator::default(); - let dep = R3DependencyMetadata::new(Atom::from("AuthService")) - .with_token_source_module(Atom::from("@app/auth")); + let dep = R3DependencyMetadata::new(Ident::from("AuthService")) + .with_token_source_module(Ident::from("@app/auth")); let mut registry = NamespaceRegistry::new(&allocator); let result = @@ -632,10 +632,10 @@ mod tests { #[test] fn test_multiple_imported_dependencies_same_module() { let allocator = Allocator::default(); - let dep1 = R3DependencyMetadata::new(Atom::from("AuthService")) - .with_token_source_module(Atom::from("@app/auth")); - let dep2 = R3DependencyMetadata::new(Atom::from("UserService")) - .with_token_source_module(Atom::from("@app/auth")); + let dep1 = R3DependencyMetadata::new(Ident::from("AuthService")) + .with_token_source_module(Ident::from("@app/auth")); + let dep2 = R3DependencyMetadata::new(Ident::from("UserService")) + .with_token_source_module(Ident::from("@app/auth")); let deps = vec![dep1, dep2]; let mut registry = NamespaceRegistry::new(&allocator); @@ -654,10 +654,10 @@ mod tests { #[test] fn test_multiple_imported_dependencies_different_modules() { let allocator = Allocator::default(); - let dep1 = R3DependencyMetadata::new(Atom::from("AuthService")) - .with_token_source_module(Atom::from("@app/auth")); - let dep2 = R3DependencyMetadata::new(Atom::from("HttpService")) - .with_token_source_module(Atom::from("@app/http")); + let dep1 = R3DependencyMetadata::new(Ident::from("AuthService")) + .with_token_source_module(Ident::from("@app/auth")); + let dep2 = R3DependencyMetadata::new(Ident::from("HttpService")) + .with_token_source_module(Ident::from("@app/http")); let deps = vec![dep1, dep2]; let mut registry = NamespaceRegistry::new(&allocator); @@ -676,8 +676,8 @@ mod tests { #[test] fn test_angular_core_dependency() { let allocator = Allocator::default(); - let dep = R3DependencyMetadata::new(Atom::from("ChangeDetectorRef")) - .with_token_source_module(Atom::from("@angular/core")); + let dep = R3DependencyMetadata::new(Ident::from("ChangeDetectorRef")) + .with_token_source_module(Ident::from("@angular/core")); let mut registry = NamespaceRegistry::new(&allocator); let result = diff --git a/crates/oxc_angular_compiler/src/component/import_elision.rs b/crates/oxc_angular_compiler/src/component/import_elision.rs index 459df1d9a..ef9c99f0c 100644 --- a/crates/oxc_angular_compiler/src/component/import_elision.rs +++ b/crates/oxc_angular_compiler/src/component/import_elision.rs @@ -41,7 +41,7 @@ use oxc_ast::ast::{ Program, Statement, TSType, }; use oxc_semantic::{Semantic, SemanticBuilder, SymbolFlags}; -use oxc_span::Atom; +use oxc_span::Ident; use rustc_hash::FxHashSet; use crate::optimizer::Edit; @@ -55,7 +55,7 @@ const PARAM_DECORATORS: &[&str] = &["Inject", "Optional", "Self", "SkipSelf", "H /// Analyzer for determining which imports are type-only and can be elided. pub struct ImportElisionAnalyzer<'a> { /// Set of import specifier local names that should be removed (type-only). - type_only_specifiers: FxHashSet>, + type_only_specifiers: FxHashSet>, } impl<'a> ImportElisionAnalyzer<'a> { @@ -98,7 +98,7 @@ impl<'a> ImportElisionAnalyzer<'a> { continue; } - let name: Atom<'a> = spec.local.name.clone().into(); + let name: Ident<'a> = spec.local.name.clone().into(); // Check if this import has only type references if Self::is_type_only_import(&spec.local, semantic) { @@ -110,7 +110,7 @@ impl<'a> ImportElisionAnalyzer<'a> { } } ImportDeclarationSpecifier::ImportDefaultSpecifier(spec) => { - let name: Atom<'a> = spec.local.name.clone().into(); + let name: Ident<'a> = spec.local.name.clone().into(); if Self::is_type_only_import(&spec.local, semantic) { type_only_specifiers.insert(name.clone()); @@ -145,7 +145,7 @@ impl<'a> ImportElisionAnalyzer<'a> { /// Computed property keys like `[fromEmail]` in type literals reference runtime values, /// even when they appear in type contexts. TypeScript considers these as value references /// and preserves their imports. - fn collect_computed_property_key_idents(program: &'a Program<'a>) -> FxHashSet> { + fn collect_computed_property_key_idents(program: &'a Program<'a>) -> FxHashSet> { let mut result = FxHashSet::default(); for stmt in &program.body { @@ -158,7 +158,7 @@ impl<'a> ImportElisionAnalyzer<'a> { /// Walk a statement collecting computed property key identifiers from type annotations. fn collect_computed_keys_from_statement( stmt: &'a Statement<'a>, - result: &mut FxHashSet>, + result: &mut FxHashSet>, ) { match stmt { Statement::ClassDeclaration(class) => { @@ -185,7 +185,7 @@ impl<'a> ImportElisionAnalyzer<'a> { /// Walk class members collecting computed property key identifiers from type annotations. fn collect_computed_keys_from_class( class: &'a oxc_ast::ast::Class<'a>, - result: &mut FxHashSet>, + result: &mut FxHashSet>, ) { for element in &class.body.body { if let ClassElement::PropertyDefinition(prop) = element { @@ -200,7 +200,7 @@ impl<'a> ImportElisionAnalyzer<'a> { /// Recursively walk a TypeScript type collecting computed property key identifiers. fn collect_computed_keys_from_ts_type( ts_type: &'a TSType<'a>, - result: &mut FxHashSet>, + result: &mut FxHashSet>, ) { match ts_type { TSType::TSTypeLiteral(type_lit) => { @@ -256,7 +256,7 @@ impl<'a> ImportElisionAnalyzer<'a> { /// Collect identifier names from an expression (for computed property keys). fn collect_idents_from_expr( expr: &'a oxc_ast::ast::PropertyKey<'a>, - result: &mut FxHashSet>, + result: &mut FxHashSet>, ) { match expr { oxc_ast::ast::PropertyKey::StaticIdentifier(_) => { @@ -272,7 +272,7 @@ impl<'a> ImportElisionAnalyzer<'a> { } /// Collect identifier names from an expression. - fn collect_idents_from_expression(expr: &'a Expression<'a>, result: &mut FxHashSet>) { + fn collect_idents_from_expression(expr: &'a Expression<'a>, result: &mut FxHashSet>) { match expr { Expression::Identifier(id) => { result.insert(id.name.clone().into()); @@ -641,11 +641,11 @@ impl<'a> ImportElisionAnalyzer<'a> { /// Check if a specifier name should be elided (removed). pub fn should_elide(&self, name: &str) -> bool { - self.type_only_specifiers.contains(name) + self.type_only_specifiers.contains(&Ident::from(name)) } /// Get the set of type-only specifier names. - pub fn type_only_specifiers(&self) -> &FxHashSet> { + pub fn type_only_specifiers(&self) -> &FxHashSet> { &self.type_only_specifiers } diff --git a/crates/oxc_angular_compiler/src/component/metadata.rs b/crates/oxc_angular_compiler/src/component/metadata.rs index 62f6f84ed..75f06db53 100644 --- a/crates/oxc_angular_compiler/src/component/metadata.rs +++ b/crates/oxc_angular_compiler/src/component/metadata.rs @@ -3,7 +3,7 @@ //! This module defines the metadata extracted from `@Component` decorators. use oxc_allocator::Vec; -use oxc_span::{Atom, Span}; +use oxc_span::{Ident, Span}; use super::dependency::R3DependencyMetadata; use crate::directive::R3InputMetadata; @@ -117,25 +117,25 @@ pub enum ChangeDetectionStrategy { #[derive(Debug)] pub struct ComponentMetadata<'a> { /// The name of the component class. - pub class_name: Atom<'a>, + pub class_name: Ident<'a>, /// The span of the class declaration. pub class_span: Span, /// The CSS selector for this component. - pub selector: Option>, + pub selector: Option>, /// Inline template string. - pub template: Option>, + pub template: Option>, /// URL to an external template file. - pub template_url: Option>, + pub template_url: Option>, /// Inline styles array. - pub styles: Vec<'a, Atom<'a>>, + pub styles: Vec<'a, Ident<'a>>, /// URLs to external stylesheet files. - pub style_urls: Vec<'a, Atom<'a>>, + pub style_urls: Vec<'a, Ident<'a>>, /// Whether this is a standalone component. pub standalone: bool, @@ -150,13 +150,13 @@ pub struct ComponentMetadata<'a> { pub host: Option>, /// Component imports (for standalone components). - pub imports: Vec<'a, Atom<'a>>, + pub imports: Vec<'a, Ident<'a>>, /// Exported names for template references. /// /// In Angular, `exportAs` can be a comma-separated string (e.g., "foo, bar"), /// which is split into an array and emitted as `exportAs: ["foo", "bar"]`. - pub export_as: Vec<'a, Atom<'a>>, + pub export_as: Vec<'a, Ident<'a>>, /// Whether to preserve whitespace in templates. pub preserve_whitespaces: bool, @@ -185,7 +185,7 @@ pub struct ComponentMetadata<'a> { /// Extracted from class property decorators like: /// - `@Output() valueChange = new EventEmitter();` /// - `@Output('changed') valueChange = new EventEmitter();` - pub outputs: Vec<'a, (Atom<'a>, Atom<'a>)>, + pub outputs: Vec<'a, (Ident<'a>, Ident<'a>)>, // ========================================================================= // Feature-related fields @@ -226,7 +226,7 @@ pub struct ComponentMetadata<'a> { /// External stylesheet URLs that were resolved and need to be loaded. /// /// Corresponds to resolved `styleUrls`. Used to generate `ɵɵExternalStylesFeature`. - pub external_styles: Vec<'a, Atom<'a>>, + pub external_styles: Vec<'a, Ident<'a>>, // ========================================================================= // Template Dependency Fields @@ -269,7 +269,7 @@ pub struct ComponentMetadata<'a> { /// Corresponds to the `schemas` property in `@Component`. /// Common values are `CUSTOM_ELEMENTS_SCHEMA` and `NO_ERRORS_SCHEMA`. /// These are stored as identifier names. - pub schemas: Vec<'a, Atom<'a>>, + pub schemas: Vec<'a, Ident<'a>>, /// Whether this component uses signal-based inputs. /// @@ -287,20 +287,20 @@ pub struct ComponentMetadata<'a> { #[derive(Debug)] pub struct HostDirectiveMetadata<'a> { /// The directive class name. - pub directive: Atom<'a>, + pub directive: Ident<'a>, /// The source module of the directive (e.g., "@angular/common", "./my-directive"). /// Used to generate proper namespace aliases for imported host directives. /// `None` for local directives defined in the same file. - pub source_module: Option>, + pub source_module: Option>, /// Input mappings: (publicName, internalName) pairs. /// Empty if no inputs are exposed. - pub inputs: Vec<'a, (Atom<'a>, Atom<'a>)>, + pub inputs: Vec<'a, (Ident<'a>, Ident<'a>)>, /// Output mappings: (publicName, internalName) pairs. /// Empty if no outputs are exposed. - pub outputs: Vec<'a, (Atom<'a>, Atom<'a>)>, + pub outputs: Vec<'a, (Ident<'a>, Ident<'a>)>, /// Whether this is a forward reference (requires wrapping in a function). pub is_forward_reference: bool, @@ -308,7 +308,7 @@ pub struct HostDirectiveMetadata<'a> { impl<'a> HostDirectiveMetadata<'a> { /// Create a new HostDirectiveMetadata. - pub fn new(allocator: &'a oxc_allocator::Allocator, directive: Atom<'a>) -> Self { + pub fn new(allocator: &'a oxc_allocator::Allocator, directive: Ident<'a>) -> Self { Self { directive, source_module: None, @@ -324,7 +324,7 @@ impl<'a> HostDirectiveMetadata<'a> { } /// Set the source module for this host directive. - pub fn with_source_module(mut self, source_module: Atom<'a>) -> Self { + pub fn with_source_module(mut self, source_module: Ident<'a>) -> Self { self.source_module = Some(source_module); self } @@ -394,30 +394,30 @@ pub struct TemplateDependency<'a> { pub kind: TemplateDependencyKind, /// The type expression (class name or import reference). - pub type_name: Atom<'a>, + pub type_name: Ident<'a>, /// The source module of the dependency (e.g., "@angular/common", "./my-directive"). /// Used to generate proper namespace aliases for imported dependencies. /// `None` for local dependencies defined in the same file. - pub source_module: Option>, + pub source_module: Option>, /// For directives: the CSS selector. - pub selector: Option>, + pub selector: Option>, /// For directives: input property names. - pub inputs: Vec<'a, Atom<'a>>, + pub inputs: Vec<'a, Ident<'a>>, /// For directives: output property names. - pub outputs: Vec<'a, Atom<'a>>, + pub outputs: Vec<'a, Ident<'a>>, /// For directives: export names (exportAs). - pub export_as: Vec<'a, Atom<'a>>, + pub export_as: Vec<'a, Ident<'a>>, /// For directives: whether this is a component. pub is_component: bool, /// For pipes: the pipe name used in templates. - pub pipe_name: Option>, + pub pipe_name: Option>, /// Whether this is a forward reference. pub is_forward_reference: bool, @@ -427,8 +427,8 @@ impl<'a> TemplateDependency<'a> { /// Create a new directive dependency. pub fn directive( allocator: &'a oxc_allocator::Allocator, - type_name: Atom<'a>, - selector: Atom<'a>, + type_name: Ident<'a>, + selector: Ident<'a>, is_component: bool, ) -> Self { Self { @@ -448,8 +448,8 @@ impl<'a> TemplateDependency<'a> { /// Create a new pipe dependency. pub fn pipe( allocator: &'a oxc_allocator::Allocator, - type_name: Atom<'a>, - pipe_name: Atom<'a>, + type_name: Ident<'a>, + pipe_name: Ident<'a>, ) -> Self { Self { kind: TemplateDependencyKind::Pipe, @@ -472,7 +472,7 @@ impl<'a> TemplateDependency<'a> { } /// Set the source module for this dependency. - pub fn with_source_module(mut self, source_module: Atom<'a>) -> Self { + pub fn with_source_module(mut self, source_module: Ident<'a>) -> Self { self.source_module = Some(source_module); self } @@ -484,21 +484,21 @@ impl<'a> TemplateDependency<'a> { #[derive(Debug)] pub struct HostMetadata<'a> { /// Host property bindings: `{ '[class.active]': 'isActive' }` - pub properties: Vec<'a, (Atom<'a>, Atom<'a>)>, + pub properties: Vec<'a, (Ident<'a>, Ident<'a>)>, /// Host attribute bindings: `{ 'role': 'button' }` - pub attributes: Vec<'a, (Atom<'a>, Atom<'a>)>, + pub attributes: Vec<'a, (Ident<'a>, Ident<'a>)>, /// Host event listeners: `{ '(click)': 'onClick()' }` - pub listeners: Vec<'a, (Atom<'a>, Atom<'a>)>, + pub listeners: Vec<'a, (Ident<'a>, Ident<'a>)>, /// Special attribute for static class binding: `{ 'class': 'foo bar' }` /// Captured separately to generate class instructions during compilation. - pub class_attr: Option>, + pub class_attr: Option>, /// Special attribute for static style binding: `{ 'style': 'color: red' }` /// Captured separately to generate style instructions during compilation. - pub style_attr: Option>, + pub style_attr: Option>, } impl<'a> HostMetadata<'a> { @@ -524,7 +524,7 @@ impl<'a> ComponentMetadata<'a> { /// - `true` when the Angular version is unknown (assume latest) pub fn new( allocator: &'a oxc_allocator::Allocator, - class_name: Atom<'a>, + class_name: Ident<'a>, class_span: Span, implicit_standalone: bool, ) -> Self { diff --git a/crates/oxc_angular_compiler/src/component/namespace_registry.rs b/crates/oxc_angular_compiler/src/component/namespace_registry.rs index 9adc851b6..4d7eaec55 100644 --- a/crates/oxc_angular_compiler/src/component/namespace_registry.rs +++ b/crates/oxc_angular_compiler/src/component/namespace_registry.rs @@ -1,5 +1,5 @@ use oxc_allocator::{Allocator, FromIn}; -use oxc_span::Atom; +use oxc_span::Ident; use rustc_hash::FxHashMap; /// Registry for assigning namespace aliases to imported modules. @@ -9,7 +9,7 @@ use rustc_hash::FxHashMap; /// - i1, i2, i3... are assigned to other modules in order of first reference pub struct NamespaceRegistry<'a> { /// Map of module_path -> namespace alias - modules: FxHashMap, Atom<'a>>, + modules: FxHashMap, Ident<'a>>, /// Counter for next alias index (starts at 1, since i0 is reserved for @angular/core) next_index: usize, /// The allocator for creating atoms @@ -27,18 +27,18 @@ impl<'a> NamespaceRegistry<'a> { allocator, }; // Pre-register @angular/core as i0 - registry.modules.insert(Atom::from("@angular/core"), Atom::from("i0")); + registry.modules.insert(Ident::from("@angular/core"), Ident::from("i0")); registry } /// Get the namespace alias for a module, assigning one if not yet assigned. - pub fn get_or_assign(&mut self, module_path: &Atom<'a>) -> Atom<'a> { + pub fn get_or_assign(&mut self, module_path: &Ident<'a>) -> Ident<'a> { if let Some(alias) = self.modules.get(module_path) { return alias.clone(); } // Assign new alias - let alias = Atom::from_in(format!("i{}", self.next_index).as_str(), self.allocator); + let alias = Ident::from_in(format!("i{}", self.next_index).as_str(), self.allocator); self.next_index += 1; self.modules.insert(module_path.clone(), alias.clone()); alias @@ -46,14 +46,14 @@ impl<'a> NamespaceRegistry<'a> { /// Get all registered modules and their aliases. /// Returns in a deterministic order (sorted by alias). - pub fn get_all_modules(&self) -> Vec<(&Atom<'a>, &Atom<'a>)> { + pub fn get_all_modules(&self) -> Vec<(&Ident<'a>, &Ident<'a>)> { let mut entries: Vec<_> = self.modules.iter().collect(); entries.sort_by_key(|(_, alias)| alias.as_str()); entries } /// Check if a module has been registered. - pub fn has_module(&self, module_path: &Atom<'a>) -> bool { + pub fn has_module(&self, module_path: &Ident<'a>) -> bool { self.modules.contains_key(module_path) } @@ -112,7 +112,7 @@ mod tests { let allocator = Allocator::default(); let mut registry = NamespaceRegistry::new(&allocator); - let core_alias = registry.get_or_assign(&Atom::from("@angular/core")); + let core_alias = registry.get_or_assign(&Ident::from("@angular/core")); assert_eq!(core_alias.as_str(), "i0"); } @@ -121,9 +121,9 @@ mod tests { let allocator = Allocator::default(); let mut registry = NamespaceRegistry::new(&allocator); - let forms_alias = registry.get_or_assign(&Atom::from("@angular/forms")); - let router_alias = registry.get_or_assign(&Atom::from("@angular/router")); - let http_alias = registry.get_or_assign(&Atom::from("@angular/common/http")); + let forms_alias = registry.get_or_assign(&Ident::from("@angular/forms")); + let router_alias = registry.get_or_assign(&Ident::from("@angular/router")); + let http_alias = registry.get_or_assign(&Ident::from("@angular/common/http")); assert_eq!(forms_alias.as_str(), "i1"); assert_eq!(router_alias.as_str(), "i2"); @@ -135,8 +135,8 @@ mod tests { let allocator = Allocator::default(); let mut registry = NamespaceRegistry::new(&allocator); - let first = registry.get_or_assign(&Atom::from("@angular/forms")); - let second = registry.get_or_assign(&Atom::from("@angular/forms")); + let first = registry.get_or_assign(&Ident::from("@angular/forms")); + let second = registry.get_or_assign(&Ident::from("@angular/forms")); assert_eq!(first.as_str(), second.as_str()); assert_eq!(first.as_str(), "i1"); @@ -148,14 +148,14 @@ mod tests { let mut registry = NamespaceRegistry::new(&allocator); // @angular/core is pre-registered - assert!(registry.has_module(&Atom::from("@angular/core"))); + assert!(registry.has_module(&Ident::from("@angular/core"))); // Not yet registered - assert!(!registry.has_module(&Atom::from("@angular/forms"))); + assert!(!registry.has_module(&Ident::from("@angular/forms"))); // Register it - registry.get_or_assign(&Atom::from("@angular/forms")); - assert!(registry.has_module(&Atom::from("@angular/forms"))); + registry.get_or_assign(&Ident::from("@angular/forms")); + assert!(registry.has_module(&Ident::from("@angular/forms"))); } #[test] @@ -163,8 +163,8 @@ mod tests { let allocator = Allocator::default(); let mut registry = NamespaceRegistry::new(&allocator); - registry.get_or_assign(&Atom::from("@angular/router")); - registry.get_or_assign(&Atom::from("@angular/forms")); + registry.get_or_assign(&Ident::from("@angular/router")); + registry.get_or_assign(&Ident::from("@angular/forms")); let all_modules = registry.get_all_modules(); @@ -184,15 +184,15 @@ mod tests { let mut registry = NamespaceRegistry::new(&allocator); // Register other modules first - registry.get_or_assign(&Atom::from("@angular/forms")); - registry.get_or_assign(&Atom::from("@angular/router")); + registry.get_or_assign(&Ident::from("@angular/forms")); + registry.get_or_assign(&Ident::from("@angular/router")); // @angular/core should still be i0 - let core_alias = registry.get_or_assign(&Atom::from("@angular/core")); + let core_alias = registry.get_or_assign(&Ident::from("@angular/core")); assert_eq!(core_alias.as_str(), "i0"); // Next module should be i3 - let http_alias = registry.get_or_assign(&Atom::from("@angular/common/http")); + let http_alias = registry.get_or_assign(&Ident::from("@angular/common/http")); assert_eq!(http_alias.as_str(), "i3"); } @@ -201,8 +201,8 @@ mod tests { let allocator = Allocator::default(); let mut registry = NamespaceRegistry::new(&allocator); - registry.get_or_assign(&Atom::from("@angular/router")); - registry.get_or_assign(&Atom::from("@bitwarden/common/auth/abstractions/auth.service")); + registry.get_or_assign(&Ident::from("@angular/router")); + registry.get_or_assign(&Ident::from("@bitwarden/common/auth/abstractions/auth.service")); let imports = registry.generate_import_statements(); @@ -232,23 +232,23 @@ import * as i2 from '@bitwarden/common/auth/abstractions/auth.service'; let mut registry2 = NamespaceRegistry::new(&allocator); // Registry 1 has @angular/router as i1 - registry1.get_or_assign(&Atom::from("@angular/router")); + registry1.get_or_assign(&Ident::from("@angular/router")); // Registry 2 has @angular/forms as i1, @angular/common as i2 - registry2.get_or_assign(&Atom::from("@angular/forms")); - registry2.get_or_assign(&Atom::from("@angular/common")); + registry2.get_or_assign(&Ident::from("@angular/forms")); + registry2.get_or_assign(&Ident::from("@angular/common")); // Merge registry2 into registry1 registry1.merge_from(®istry2); // registry1 should now have all modules - assert!(registry1.has_module(&Atom::from("@angular/core"))); - assert!(registry1.has_module(&Atom::from("@angular/router"))); - assert!(registry1.has_module(&Atom::from("@angular/forms"))); - assert!(registry1.has_module(&Atom::from("@angular/common"))); + assert!(registry1.has_module(&Ident::from("@angular/core"))); + assert!(registry1.has_module(&Ident::from("@angular/router"))); + assert!(registry1.has_module(&Ident::from("@angular/forms"))); + assert!(registry1.has_module(&Ident::from("@angular/common"))); // New module should get next available index - let http_alias = registry1.get_or_assign(&Atom::from("@angular/common/http")); + let http_alias = registry1.get_or_assign(&Ident::from("@angular/common/http")); assert_eq!(http_alias.as_str(), "i3"); } } diff --git a/crates/oxc_angular_compiler/src/component/transform.rs b/crates/oxc_angular_compiler/src/component/transform.rs index 07b1197d3..f665010ea 100644 --- a/crates/oxc_angular_compiler/src/component/transform.rs +++ b/crates/oxc_angular_compiler/src/component/transform.rs @@ -14,7 +14,7 @@ use oxc_ast::ast::{ }; use oxc_diagnostics::OxcDiagnostic; use oxc_parser::Parser; -use oxc_span::{Atom, GetSpan, SourceType, Span}; +use oxc_span::{Ident, GetSpan, SourceType, Span}; use rustc_hash::FxHashMap; use crate::optimizer::{Edit, apply_edits, apply_edits_with_sourcemap}; @@ -404,7 +404,7 @@ pub struct CompiledComponent<'a> { #[derive(Debug, Clone)] pub struct ImportInfo<'a> { /// The source module path (e.g., "@angular/core", "./services"). - pub source_module: Atom<'a>, + pub source_module: Ident<'a>, /// Whether this is a named import that can be reused with bare name. /// True for: `import { AuthService } from "module"` /// False for: `import * as core from "module"` (namespace imports) @@ -419,7 +419,7 @@ pub struct ImportInfo<'a> { /// /// Used to look up where a constructor dependency token was imported from /// and whether it can be reused with a bare name or requires namespace prefix. -pub type ImportMap<'a> = FxHashMap, ImportInfo<'a>>; +pub type ImportMap<'a> = FxHashMap, ImportInfo<'a>>; /// Build an import map from the program's import declarations. /// @@ -476,7 +476,7 @@ pub fn build_import_map<'a>( // or aliased: `import { AuthService as Auth } from "module"` // We use the local name as the key // Named imports CAN be reused with bare name - let local_name: Atom<'a> = spec.local.name.clone().into(); + let local_name: Ident<'a> = spec.local.name.clone().into(); // Type-only if the declaration is `import type { ... }` or the specifier // is `import { type X }` (inline type specifier) @@ -486,8 +486,8 @@ pub fn build_import_map<'a>( // Check if we have a resolved path for this identifier let source_module = resolved_imports .and_then(|m| m.get(local_name.as_str())) - .map(|resolved| Atom::from(allocator.alloc_str(resolved))) - .unwrap_or_else(|| default_source_module.clone()); + .map(|resolved| Ident::from(allocator.alloc_str(resolved))) + .unwrap_or_else(|| default_source_module.clone().into()); import_map.insert( local_name, @@ -497,13 +497,13 @@ pub fn build_import_map<'a>( ImportDeclarationSpecifier::ImportDefaultSpecifier(spec) => { // Default import: `import DefaultService from "module"` // Default imports CAN be reused with bare name - let local_name: Atom<'a> = spec.local.name.clone().into(); + let local_name: Ident<'a> = spec.local.name.clone().into(); // Check if we have a resolved path for this identifier let source_module = resolved_imports .and_then(|m| m.get(local_name.as_str())) - .map(|resolved| Atom::from(allocator.alloc_str(resolved))) - .unwrap_or_else(|| default_source_module.clone()); + .map(|resolved| Ident::from(allocator.alloc_str(resolved))) + .unwrap_or_else(|| default_source_module.clone().into()); import_map.insert( local_name, @@ -517,13 +517,13 @@ pub fn build_import_map<'a>( ImportDeclarationSpecifier::ImportNamespaceSpecifier(spec) => { // Namespace import: `import * as core from "module"` // Namespace imports CANNOT be reused with bare name for individual symbols - let local_name: Atom<'a> = spec.local.name.clone().into(); + let local_name: Ident<'a> = spec.local.name.clone().into(); // Check if we have a resolved path for this identifier let source_module = resolved_imports .and_then(|m| m.get(local_name.as_str())) - .map(|resolved| Atom::from(allocator.alloc_str(resolved))) - .unwrap_or_else(|| default_source_module.clone()); + .map(|resolved| Ident::from(allocator.alloc_str(resolved))) + .unwrap_or_else(|| default_source_module.clone().into()); import_map.insert( local_name, @@ -1740,7 +1740,7 @@ pub fn transform_angular_file( let type_expr = crate::output::ast::OutputExpression::ReadVar( oxc_allocator::Box::new_in( ReadVarExpr { - name: Atom::from(class_name.as_str()), + name: Ident::from(class_name.as_str()), source_span: None, }, allocator, @@ -2389,7 +2389,7 @@ fn compile_component_full<'a>( // Stage 3-5: Ingest and compile // Build ingest options from metadata and transform options - let component_name_atom = Atom::from_in(metadata.class_name.as_str(), allocator); + let component_name_atom = Ident::from_in(metadata.class_name.as_str(), allocator); // OXC is a single-file compiler, equivalent to Angular's local compilation mode. // In local compilation mode, Angular ALWAYS sets hasDirectiveDependencies=true, @@ -2413,9 +2413,9 @@ fn compile_component_full<'a>( // Build relative paths for debug locations let relative_template_path = - if enable_debug_locations { Some(Atom::from_in(file_path, allocator)) } else { None }; + if enable_debug_locations { Some(Ident::from_in(file_path, allocator)) } else { None }; - let relative_context_file_path = Some(Atom::from_in(file_path, allocator)); + let relative_context_file_path = Some(Ident::from_in(file_path, allocator)); let ingest_options = IngestOptions { mode, @@ -2566,11 +2566,11 @@ fn compile_component_full<'a>( let mut hmr_meta = HmrMetadata::new( component_type, metadata.class_name.clone(), - Atom::from_in(file_path, allocator), + Ident::from_in(file_path, allocator), ); // Add the @angular/core namespace dependency (i0) - hmr_meta.add_namespace_dependency(Atom::from("@angular/core"), Atom::from("i0")); + hmr_meta.add_namespace_dependency(Ident::from("@angular/core"), Ident::from("i0")); // Generate the HMR initializer expression let hmr_expr = compile_hmr_initializer(allocator, &hmr_meta); @@ -2607,7 +2607,7 @@ fn compile_component_full<'a>( // Build the debug info with the actual class declaration line number let debug_info = R3ClassDebugInfo::new(component_type, metadata.class_name.clone()) - .with_file_path(Atom::from_in(file_path, allocator)) + .with_file_path(Ident::from_in(file_path, allocator)) .with_line_number(class_line_number); // Compile to IIFE-wrapped expression @@ -2677,7 +2677,7 @@ fn resolve_styles<'a>( if let Some(style_contents) = resources.styles.get(style_url.as_str()) { // Add all resolved style contents to the metadata styles for style in style_contents { - metadata.styles.push(Atom::from_in(style.as_str(), allocator)); + metadata.styles.push(Ident::from_in(style.as_str(), allocator)); } } } @@ -2751,7 +2751,7 @@ pub fn compile_component_template<'a>( // Stage 3-5: Ingest and compile use oxc_allocator::FromIn; - let component_name_atom = Atom::from_in(component_name, allocator); + let component_name_atom = Ident::from_in(component_name, allocator); let mut job = ingest_component(allocator, component_name_atom, r3_result.nodes); let compiled = compile_template(&mut job); @@ -2872,7 +2872,7 @@ pub fn compile_template_to_js_with_options<'a>( }; // Stage 3-5: Ingest and compile - let component_name_atom = Atom::from_in(component_name, allocator); + let component_name_atom = Ident::from_in(component_name, allocator); let mut job = ingest_component_with_options( allocator, component_name_atom, @@ -3045,7 +3045,7 @@ pub fn compile_template_for_hmr<'a>( }; // Stage 3-5: Ingest and compile - let component_name_atom = Atom::from_in(component_name, allocator); + let component_name_atom = Ident::from_in(component_name, allocator); let mut job = ingest_component_with_options( allocator, component_name_atom, @@ -3203,7 +3203,7 @@ fn compile_component_host_bindings<'a>( // Get component name and selector let component_name = metadata.class_name.clone(); - let component_selector = metadata.selector.clone().unwrap_or_else(|| Atom::from("")); + let component_selector = metadata.selector.clone().unwrap_or_else(|| Ident::from("")); // Convert HostMetadata to HostBindingInput let input = convert_host_metadata_to_input(allocator, host, component_name, component_selector); @@ -3227,8 +3227,8 @@ fn compile_component_host_bindings<'a>( fn convert_host_metadata_to_input<'a>( allocator: &'a Allocator, host: &HostMetadata<'a>, - component_name: Atom<'a>, - component_selector: Atom<'a>, + component_name: Ident<'a>, + component_selector: Ident<'a>, ) -> HostBindingInput<'a> { use oxc_allocator::FromIn; @@ -3255,11 +3255,11 @@ fn convert_host_metadata_to_input<'a>( let parse_result = binding_parser.parse_binding(value_str, empty_span); properties.push(R3BoundAttribute { - name: Atom::from_in(final_name, allocator), + name: Ident::from_in(final_name, allocator), binding_type, security_context: SecurityContext::None, value: parse_result.ast, - unit: unit.map(|u| Atom::from_in(u, allocator)), + unit: unit.map(|u| Ident::from_in(u, allocator)), source_span: empty_span, key_span: empty_span, value_span: Some(empty_span), @@ -3287,10 +3287,10 @@ fn convert_host_metadata_to_input<'a>( let parse_result = binding_parser.parse_event(value_str, empty_span); events.push(R3BoundEvent { - name: Atom::from_in(final_event_name, allocator), + name: Ident::from_in(final_event_name, allocator), event_type: ParsedEventType::Regular, handler: parse_result.ast, - target: target.map(|t| Atom::from_in(t, allocator)), + target: target.map(|t| Ident::from_in(t, allocator)), phase: None, source_span: empty_span, handler_span: empty_span, @@ -3300,7 +3300,7 @@ fn convert_host_metadata_to_input<'a>( // Convert static attributes: "role" -> OutputExpression::Literal // This matches TypeScript which uses `o.literal(value)` for host attributes - let mut attributes: FxHashMap, crate::output::ast::OutputExpression<'a>> = + let mut attributes: FxHashMap, crate::output::ast::OutputExpression<'a>> = FxHashMap::default(); for (key, value) in host.attributes.iter() { @@ -3326,7 +3326,7 @@ fn convert_host_metadata_to_input<'a>( }, allocator, )); - attributes.insert(Atom::from("style"), expr); + attributes.insert(Ident::from("style"), expr); } if let Some(ref class_attr) = host.class_attr { @@ -3337,7 +3337,7 @@ fn convert_host_metadata_to_input<'a>( }, allocator, )); - attributes.insert(Atom::from("class"), expr); + attributes.insert(Ident::from("class"), expr); } HostBindingInput { component_name, component_selector, properties, attributes, events } @@ -3401,30 +3401,30 @@ fn convert_host_metadata_input_to_host_metadata<'a>( ) -> HostMetadata<'a> { use oxc_allocator::FromIn; - let mut properties: OxcVec<'a, (Atom<'a>, Atom<'a>)> = OxcVec::new_in(allocator); + let mut properties: OxcVec<'a, (Ident<'a>, Ident<'a>)> = OxcVec::new_in(allocator); for (k, v) in &input.properties { properties - .push((Atom::from_in(k.as_str(), allocator), Atom::from_in(v.as_str(), allocator))); + .push((Ident::from_in(k.as_str(), allocator), Ident::from_in(v.as_str(), allocator))); } - let mut attributes: OxcVec<'a, (Atom<'a>, Atom<'a>)> = OxcVec::new_in(allocator); + let mut attributes: OxcVec<'a, (Ident<'a>, Ident<'a>)> = OxcVec::new_in(allocator); for (k, v) in &input.attributes { attributes - .push((Atom::from_in(k.as_str(), allocator), Atom::from_in(v.as_str(), allocator))); + .push((Ident::from_in(k.as_str(), allocator), Ident::from_in(v.as_str(), allocator))); } - let mut listeners: OxcVec<'a, (Atom<'a>, Atom<'a>)> = OxcVec::new_in(allocator); + let mut listeners: OxcVec<'a, (Ident<'a>, Ident<'a>)> = OxcVec::new_in(allocator); for (k, v) in &input.listeners { listeners - .push((Atom::from_in(k.as_str(), allocator), Atom::from_in(v.as_str(), allocator))); + .push((Ident::from_in(k.as_str(), allocator), Ident::from_in(v.as_str(), allocator))); } HostMetadata { properties, attributes, listeners, - class_attr: input.class_attr.as_ref().map(|s| Atom::from_in(s.as_str(), allocator)), - style_attr: input.style_attr.as_ref().map(|s| Atom::from_in(s.as_str(), allocator)), + class_attr: input.class_attr.as_ref().map(|s| Ident::from_in(s.as_str(), allocator)), + style_attr: input.style_attr.as_ref().map(|s| Ident::from_in(s.as_str(), allocator)), } } @@ -3460,7 +3460,7 @@ fn pool_selector_attrs<'a>( for attr in selector_attrs { attr_entries.push(OutputExpression::Literal(oxc_allocator::Box::new_in( LiteralExpr { - value: LiteralValue::String(Atom::from_in(attr.as_str(), allocator)), + value: LiteralValue::String(Ident::from_in(attr.as_str(), allocator)), source_span: None, }, allocator, @@ -3507,9 +3507,9 @@ fn compile_host_bindings_from_input<'a>( let host = convert_host_metadata_input_to_host_metadata(allocator, host_input); // Get component name and selector as atoms - let component_name_atom = Atom::from_in(component_name, allocator); + let component_name_atom = Ident::from_in(component_name, allocator); let component_selector = - selector.map(|s| Atom::from_in(s, allocator)).unwrap_or_else(|| Atom::from("")); + selector.map(|s| Ident::from_in(s, allocator)).unwrap_or_else(|| Ident::from("")); // Convert to HostBindingInput and compile let input = @@ -3672,7 +3672,7 @@ pub fn compile_template_for_linker<'a>( angular_version: None, }; - let component_name_atom = Atom::from_in(component_name, allocator); + let component_name_atom = Ident::from_in(component_name, allocator); let mut job = ingest_component_with_options( allocator, component_name_atom, @@ -5023,7 +5023,7 @@ export class AppModule {} build_import_map(&allocator, &parser_ret.program.body, None); assert_eq!( import_map_without_resolved - .get(&Atom::from("AriaDisableDirective")) + .get(&Ident::from("AriaDisableDirective")) .map(|i| i.source_module.as_str()), Some("../a11y") ); @@ -5041,7 +5041,7 @@ export class AppModule {} // AriaDisableDirective should have the resolved path assert_eq!( import_map_with_resolved - .get(&Atom::from("AriaDisableDirective")) + .get(&Ident::from("AriaDisableDirective")) .map(|i| i.source_module.as_str()), Some("../a11y/aria-disable.directive"), "AriaDisableDirective should use resolved path" @@ -5050,7 +5050,7 @@ export class AppModule {} // OtherDirective should still use the original import path (not in resolved_imports) assert_eq!( import_map_with_resolved - .get(&Atom::from("OtherDirective")) + .get(&Ident::from("OtherDirective")) .map(|i| i.source_module.as_str()), Some("./other"), "OtherDirective should use original import path" diff --git a/crates/oxc_angular_compiler/src/directive/compiler.rs b/crates/oxc_angular_compiler/src/directive/compiler.rs index 2fffd2ac3..c88b5ed8e 100644 --- a/crates/oxc_angular_compiler/src/directive/compiler.rs +++ b/crates/oxc_angular_compiler/src/directive/compiler.rs @@ -15,7 +15,7 @@ //! ``` use oxc_allocator::{Allocator, Box, Vec}; -use oxc_span::{Atom, Span}; +use oxc_span::{Ident, Span}; use rustc_hash::FxHashMap; use super::metadata::{ @@ -108,7 +108,7 @@ fn build_base_directive_fields<'a>( // type: MyDirective entries.push(LiteralMapEntry { - key: Atom::from("type"), + key: Ident::from("type"), value: metadata.r#type.clone_in(allocator), quoted: false, }); @@ -117,7 +117,7 @@ fn build_base_directive_fields<'a>( if let Some(selector) = &metadata.selector { if let Some(selectors_expr) = parse_selector_to_r3_selector(allocator, selector) { entries.push(LiteralMapEntry { - key: Atom::from("selectors"), + key: Ident::from("selectors"), value: selectors_expr, quoted: false, }); @@ -135,7 +135,7 @@ fn build_base_directive_fields<'a>( None, ); entries.push(LiteralMapEntry { - key: Atom::from("contentQueries"), + key: Ident::from("contentQueries"), value: content_queries_fn, quoted: false, }); @@ -152,7 +152,7 @@ fn build_base_directive_fields<'a>( None, ); entries.push(LiteralMapEntry { - key: Atom::from("viewQuery"), + key: Ident::from("viewQuery"), value: view_queries_fn, quoted: false, }); @@ -175,7 +175,7 @@ fn build_base_directive_fields<'a>( // as they are dynamic bindings handled by hostBindings function if let Some(host_attrs) = result.host_attrs { entries.push(LiteralMapEntry { - key: Atom::from("hostAttrs"), + key: Ident::from("hostAttrs"), value: host_attrs, quoted: false, }); @@ -184,7 +184,7 @@ fn build_base_directive_fields<'a>( // hostVars: number - only if > 0 if let Some(host_vars) = result.host_vars { entries.push(LiteralMapEntry { - key: Atom::from("hostVars"), + key: Ident::from("hostVars"), value: OutputExpression::Literal(Box::new_in( LiteralExpr { value: LiteralValue::Number(host_vars as f64), @@ -199,7 +199,7 @@ fn build_base_directive_fields<'a>( // hostBindings: function(rf, ctx) { ... } if let Some(host_fn) = result.host_binding_fn { entries.push(LiteralMapEntry { - key: Atom::from("hostBindings"), + key: Ident::from("hostBindings"), value: OutputExpression::Function(Box::new_in(host_fn, allocator)), quoted: false, }); @@ -214,7 +214,7 @@ fn build_base_directive_fields<'a>( if !metadata.inputs.is_empty() { if let Some(inputs_expr) = create_inputs_literal(allocator, &metadata.inputs) { entries.push(LiteralMapEntry { - key: Atom::from("inputs"), + key: Ident::from("inputs"), value: inputs_expr, quoted: false, }); @@ -225,7 +225,7 @@ fn build_base_directive_fields<'a>( if !metadata.outputs.is_empty() { if let Some(outputs_expr) = create_outputs_literal(allocator, &metadata.outputs) { entries.push(LiteralMapEntry { - key: Atom::from("outputs"), + key: Ident::from("outputs"), value: outputs_expr, quoted: false, }); @@ -242,7 +242,7 @@ fn build_base_directive_fields<'a>( ))); } entries.push(LiteralMapEntry { - key: Atom::from("exportAs"), + key: Ident::from("exportAs"), value: OutputExpression::LiteralArray(Box::new_in( LiteralArrayExpr { entries: export_items, source_span: None }, allocator, @@ -254,7 +254,7 @@ fn build_base_directive_fields<'a>( // standalone: false (only if not standalone, since true is default) if !metadata.is_standalone { entries.push(LiteralMapEntry { - key: Atom::from("standalone"), + key: Ident::from("standalone"), value: OutputExpression::Literal(Box::new_in( LiteralExpr { value: LiteralValue::Boolean(false), source_span: None }, allocator, @@ -266,7 +266,7 @@ fn build_base_directive_fields<'a>( // signals: true (only if signal-based) if metadata.is_signal { entries.push(LiteralMapEntry { - key: Atom::from("signals"), + key: Ident::from("signals"), value: OutputExpression::Literal(Box::new_in( LiteralExpr { value: LiteralValue::Boolean(true), source_span: None }, allocator, @@ -316,7 +316,7 @@ fn add_features<'a>( if !features.is_empty() { definition_map.push(LiteralMapEntry { - key: Atom::from("features"), + key: Ident::from("features"), value: OutputExpression::LiteralArray(Box::new_in( LiteralArrayExpr { entries: features, source_span: None }, allocator, @@ -336,12 +336,12 @@ fn create_define_directive_call<'a>( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(Identifiers::DEFINE_DIRECTIVE), + name: Ident::from(Identifiers::DEFINE_DIRECTIVE), optional: false, source_span: None, }, @@ -382,7 +382,7 @@ fn create_define_directive_call<'a>( /// Ported from Angular's `parseSelectorToR3Selector` in `core.ts`. fn parse_selector_to_r3_selector<'a>( allocator: &'a Allocator, - selector: &Atom<'a>, + selector: &Ident<'a>, ) -> Option> { let selector_str = selector.as_str(); if selector_str.is_empty() { @@ -532,7 +532,7 @@ pub fn create_inputs_literal<'a>( /// Creates the outputs literal map. pub fn create_outputs_literal<'a>( allocator: &'a Allocator, - outputs: &[(Atom<'a>, Atom<'a>)], + outputs: &[(Ident<'a>, Ident<'a>)], ) -> Option> { if outputs.is_empty() { return None; @@ -586,7 +586,7 @@ fn compile_directive_host_bindings<'a>( // Get directive name and selector let directive_name = metadata.name.clone(); - let directive_selector = metadata.selector.clone().unwrap_or_else(|| Atom::from("")); + let directive_selector = metadata.selector.clone().unwrap_or_else(|| Ident::from("")); // Convert R3HostMetadata to HostBindingInput let input = @@ -606,17 +606,17 @@ fn compile_directive_host_bindings<'a>( /// Convert R3HostMetadata to HostBindingInput. /// /// R3HostMetadata has: -/// - `attributes`: Vec<(Atom, OutputExpression)> - already compiled expressions -/// - `properties`: Vec<(Atom, Atom)> - unparsed property binding strings -/// - `listeners`: Vec<(Atom, Atom)> - unparsed event handler strings +/// - `attributes`: Vec<(Ident, OutputExpression)> - already compiled expressions +/// - `properties`: Vec<(Ident, Ident)> - unparsed property binding strings +/// - `listeners`: Vec<(Ident, Ident)> - unparsed event handler strings /// /// This function parses the property and listener strings and passes through /// the already-compiled attribute expressions. fn convert_r3_host_metadata_to_input<'a>( allocator: &'a Allocator, host: &R3HostMetadata<'a>, - directive_name: Atom<'a>, - directive_selector: Atom<'a>, + directive_name: Ident<'a>, + directive_selector: Ident<'a>, ) -> HostBindingInput<'a> { use oxc_allocator::FromIn; @@ -643,11 +643,11 @@ fn convert_r3_host_metadata_to_input<'a>( let parse_result = binding_parser.parse_binding(value_str, empty_span); properties.push(R3BoundAttribute { - name: Atom::from_in(final_name, allocator), + name: Ident::from_in(final_name, allocator), binding_type, security_context: SecurityContext::None, value: parse_result.ast, - unit: unit.map(|u| Atom::from_in(u, allocator)), + unit: unit.map(|u| Ident::from_in(u, allocator)), source_span: empty_span, key_span: empty_span, value_span: Some(empty_span), @@ -675,10 +675,10 @@ fn convert_r3_host_metadata_to_input<'a>( let parse_result = binding_parser.parse_event(value_str, empty_span); events.push(R3BoundEvent { - name: Atom::from_in(final_event_name, allocator), + name: Ident::from_in(final_event_name, allocator), event_type: ParsedEventType::Regular, handler: parse_result.ast, - target: target.map(|t| Atom::from_in(t, allocator)), + target: target.map(|t| Ident::from_in(t, allocator)), phase: None, source_span: empty_span, handler_span: empty_span, @@ -688,7 +688,7 @@ fn convert_r3_host_metadata_to_input<'a>( // Copy attributes directly - they are already OutputExpressions // Handle special style_attr and class_attr if present - let mut attributes: FxHashMap, OutputExpression<'a>> = FxHashMap::default(); + let mut attributes: FxHashMap, OutputExpression<'a>> = FxHashMap::default(); for (key, value) in host.attributes.iter() { // Use clone_in to deep clone the OutputExpression with the allocator @@ -701,7 +701,7 @@ fn convert_r3_host_metadata_to_input<'a>( LiteralExpr { value: LiteralValue::String(style_attr.clone()), source_span: None }, allocator, )); - attributes.insert(Atom::from("style"), expr); + attributes.insert(Ident::from("style"), expr); } if let Some(ref class_attr) = host.class_attr { @@ -709,7 +709,7 @@ fn convert_r3_host_metadata_to_input<'a>( LiteralExpr { value: LiteralValue::String(class_attr.clone()), source_span: None }, allocator, )); - attributes.insert(Atom::from("class"), expr); + attributes.insert(Ident::from("class"), expr); } HostBindingInput { @@ -771,12 +771,12 @@ fn create_feature_call<'a>( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(feature_name), + name: Ident::from(feature_name), optional: false, source_span: None, }, @@ -804,12 +804,12 @@ fn create_feature_ref<'a>( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(feature_name), + name: Ident::from(feature_name), optional: false, source_span: None, }, @@ -858,12 +858,12 @@ fn create_host_directives_feature_arg<'a>( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(Identifiers::FORWARD_REF), + name: Ident::from(Identifiers::FORWARD_REF), optional: false, source_span: None, }, @@ -885,7 +885,7 @@ fn create_host_directives_feature_arg<'a>( }; entries.push(LiteralMapEntry { - key: Atom::from("directive"), + key: Ident::from("directive"), value: directive_expr, quoted: false, }); @@ -894,7 +894,7 @@ fn create_host_directives_feature_arg<'a>( if !hd.inputs.is_empty() { let inputs_array = create_host_directive_mappings_array(allocator, &hd.inputs); entries.push(LiteralMapEntry { - key: Atom::from("inputs"), + key: Ident::from("inputs"), value: inputs_array, quoted: false, }); @@ -904,7 +904,7 @@ fn create_host_directives_feature_arg<'a>( if !hd.outputs.is_empty() { let outputs_array = create_host_directive_mappings_array(allocator, &hd.outputs); entries.push(LiteralMapEntry { - key: Atom::from("outputs"), + key: Ident::from("outputs"), value: outputs_array, quoted: false, }); @@ -930,7 +930,7 @@ fn create_host_directives_feature_arg<'a>( /// `createHostDirectivesMappingArray` in `view/compiler.ts`. pub(crate) fn create_host_directive_mappings_array<'a>( allocator: &'a Allocator, - mappings: &[(Atom<'a>, Atom<'a>)], + mappings: &[(Ident<'a>, Ident<'a>)], ) -> OutputExpression<'a> { let mut entries = Vec::with_capacity_in(mappings.len() * 2, allocator); @@ -961,16 +961,16 @@ mod tests { fn test_compile_simple_directive() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("MyDirective"), source_span: None }, + ReadVarExpr { name: Ident::from("MyDirective"), source_span: None }, &allocator, )); let metadata = R3DirectiveMetadata { - name: Atom::from("MyDirective"), + name: Ident::from("MyDirective"), r#type: type_expr, type_argument_count: 0, deps: None, - selector: Some(Atom::from("[myDir]")), + selector: Some(Ident::from("[myDir]")), queries: Vec::new_in(&allocator), view_queries: Vec::new_in(&allocator), host: R3HostMetadata::new(&allocator), @@ -999,22 +999,22 @@ mod tests { fn test_compile_directive_with_inputs_outputs() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("TestDirective"), source_span: None }, + ReadVarExpr { name: Ident::from("TestDirective"), source_span: None }, &allocator, )); let mut inputs = Vec::new_in(&allocator); - inputs.push(R3InputMetadata::simple(Atom::from("myInput"))); + inputs.push(R3InputMetadata::simple(Ident::from("myInput"))); let mut outputs = Vec::new_in(&allocator); - outputs.push((Atom::from("myOutput"), Atom::from("myOutput"))); + outputs.push((Ident::from("myOutput"), Ident::from("myOutput"))); let metadata = R3DirectiveMetadata { - name: Atom::from("TestDirective"), + name: Ident::from("TestDirective"), r#type: type_expr, type_argument_count: 0, deps: None, - selector: Some(Atom::from("[test]")), + selector: Some(Ident::from("[test]")), queries: Vec::new_in(&allocator), view_queries: Vec::new_in(&allocator), host: R3HostMetadata::new(&allocator), @@ -1044,7 +1044,7 @@ mod tests { // Test: Simple input (same name, no transform) -> just string let allocator = Allocator::default(); let mut inputs = Vec::new_in(&allocator); - inputs.push(R3InputMetadata::simple(Atom::from("value"))); + inputs.push(R3InputMetadata::simple(Ident::from("value"))); let result = create_inputs_literal(&allocator, &inputs); let emitter = JsEmitter::new(); @@ -1062,8 +1062,8 @@ mod tests { let allocator = Allocator::default(); let mut inputs = Vec::new_in(&allocator); inputs.push(R3InputMetadata { - class_property_name: Atom::from("count"), - binding_property_name: Atom::from("itemCount"), + class_property_name: Ident::from("count"), + binding_property_name: Ident::from("itemCount"), required: false, is_signal: false, transform_function: None, @@ -1088,12 +1088,12 @@ mod tests { let allocator = Allocator::default(); let mut inputs = Vec::new_in(&allocator); let transform_fn = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("booleanAttribute"), source_span: None }, + ReadVarExpr { name: Ident::from("booleanAttribute"), source_span: None }, &allocator, )); inputs.push(R3InputMetadata { - class_property_name: Atom::from("disabled"), - binding_property_name: Atom::from("disabled"), + class_property_name: Ident::from("disabled"), + binding_property_name: Ident::from("disabled"), required: false, is_signal: false, transform_function: Some(transform_fn), @@ -1117,8 +1117,8 @@ mod tests { let allocator = Allocator::default(); let mut inputs = Vec::new_in(&allocator); inputs.push(R3InputMetadata { - class_property_name: Atom::from("border"), - binding_property_name: Atom::from("border"), + class_property_name: Ident::from("border"), + binding_property_name: Ident::from("border"), required: false, is_signal: true, transform_function: None, @@ -1149,8 +1149,8 @@ mod tests { let allocator = Allocator::default(); let mut inputs = Vec::new_in(&allocator); inputs.push(R3InputMetadata { - class_property_name: Atom::from("borderWidth"), - binding_property_name: Atom::from("border"), + class_property_name: Ident::from("borderWidth"), + binding_property_name: Ident::from("border"), required: false, is_signal: true, transform_function: None, @@ -1175,12 +1175,12 @@ mod tests { let allocator = Allocator::default(); let mut inputs = Vec::new_in(&allocator); let transform_fn = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("toNumber"), source_span: None }, + ReadVarExpr { name: Ident::from("toNumber"), source_span: None }, &allocator, )); inputs.push(R3InputMetadata { - class_property_name: Atom::from("count"), - binding_property_name: Atom::from("count"), + class_property_name: Ident::from("count"), + binding_property_name: Ident::from("count"), required: false, is_signal: true, transform_function: Some(transform_fn), @@ -1205,12 +1205,12 @@ mod tests { let mut inputs = Vec::new_in(&allocator); // Simple input (flags = 0, uses string format) - inputs.push(R3InputMetadata::simple(Atom::from("simple"))); + inputs.push(R3InputMetadata::simple(Ident::from("simple"))); // Signal input (flags = 1) inputs.push(R3InputMetadata { - class_property_name: Atom::from("signalInput"), - binding_property_name: Atom::from("signalInput"), + class_property_name: Ident::from("signalInput"), + binding_property_name: Ident::from("signalInput"), required: false, is_signal: true, transform_function: None, @@ -1218,12 +1218,12 @@ mod tests { // Transform input (flags = 2) let transform_fn = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("booleanAttribute"), source_span: None }, + ReadVarExpr { name: Ident::from("booleanAttribute"), source_span: None }, &allocator, )); inputs.push(R3InputMetadata { - class_property_name: Atom::from("boolInput"), - binding_property_name: Atom::from("boolInput"), + class_property_name: Ident::from("boolInput"), + binding_property_name: Ident::from("boolInput"), required: false, is_signal: false, transform_function: Some(transform_fn), @@ -1258,16 +1258,16 @@ mod tests { fn test_compile_directive_with_features() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("FeatureDirective"), source_span: None }, + ReadVarExpr { name: Ident::from("FeatureDirective"), source_span: None }, &allocator, )); let metadata = R3DirectiveMetadata { - name: Atom::from("FeatureDirective"), + name: Ident::from("FeatureDirective"), r#type: type_expr, type_argument_count: 0, deps: None, - selector: Some(Atom::from("[feature]")), + selector: Some(Ident::from("[feature]")), queries: Vec::new_in(&allocator), view_queries: Vec::new_in(&allocator), host: R3HostMetadata::new(&allocator), @@ -1296,20 +1296,20 @@ mod tests { fn test_compile_directive_with_export_as() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("ExportDirective"), source_span: None }, + ReadVarExpr { name: Ident::from("ExportDirective"), source_span: None }, &allocator, )); let mut export_as = Vec::new_in(&allocator); - export_as.push(Atom::from("myExport")); - export_as.push(Atom::from("otherExport")); + export_as.push(Ident::from("myExport")); + export_as.push(Ident::from("otherExport")); let metadata = R3DirectiveMetadata { - name: Atom::from("ExportDirective"), + name: Ident::from("ExportDirective"), r#type: type_expr, type_argument_count: 0, deps: None, - selector: Some(Atom::from("[export]")), + selector: Some(Ident::from("[export]")), queries: Vec::new_in(&allocator), view_queries: Vec::new_in(&allocator), host: R3HostMetadata::new(&allocator), @@ -1340,16 +1340,16 @@ mod tests { // This was a bug where the selector was being kept as a single string ["ng-template[body]"] let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("BodyTemplateDirective"), source_span: None }, + ReadVarExpr { name: Ident::from("BodyTemplateDirective"), source_span: None }, &allocator, )); let metadata = R3DirectiveMetadata { - name: Atom::from("BodyTemplateDirective"), + name: Ident::from("BodyTemplateDirective"), r#type: type_expr, type_argument_count: 0, deps: None, - selector: Some(Atom::from("ng-template[body]")), + selector: Some(Ident::from("ng-template[body]")), queries: Vec::new_in(&allocator), view_queries: Vec::new_in(&allocator), host: R3HostMetadata::new(&allocator), @@ -1395,16 +1395,16 @@ mod tests { // (8 = CLASS flag) let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("PrimaryButtonDirective"), source_span: None }, + ReadVarExpr { name: Ident::from("PrimaryButtonDirective"), source_span: None }, &allocator, )); let metadata = R3DirectiveMetadata { - name: Atom::from("PrimaryButtonDirective"), + name: Ident::from("PrimaryButtonDirective"), r#type: type_expr, type_argument_count: 0, deps: None, - selector: Some(Atom::from("button.primary")), + selector: Some(Ident::from("button.primary")), queries: Vec::new_in(&allocator), view_queries: Vec::new_in(&allocator), host: R3HostMetadata::new(&allocator), @@ -1440,17 +1440,17 @@ mod tests { // ["publicName", "internalName"], NOT objects {publicName: "internalName"} let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("TooltipTrigger"), source_span: None }, + ReadVarExpr { name: Ident::from("TooltipTrigger"), source_span: None }, &allocator, )); let directive_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("BrnTooltipTrigger"), source_span: None }, + ReadVarExpr { name: Ident::from("BrnTooltipTrigger"), source_span: None }, &allocator, )); let mut host_directive_inputs = Vec::new_in(&allocator); - host_directive_inputs.push((Atom::from("uTooltip"), Atom::from("brnTooltipTrigger"))); + host_directive_inputs.push((Ident::from("uTooltip"), Ident::from("brnTooltipTrigger"))); let mut host_directives = Vec::new_in(&allocator); host_directives.push(R3HostDirectiveMetadata { @@ -1461,11 +1461,11 @@ mod tests { }); let metadata = R3DirectiveMetadata { - name: Atom::from("TooltipTrigger"), + name: Ident::from("TooltipTrigger"), r#type: type_expr, type_argument_count: 0, deps: None, - selector: Some(Atom::from("[uTooltip]")), + selector: Some(Ident::from("[uTooltip]")), queries: Vec::new_in(&allocator), view_queries: Vec::new_in(&allocator), host: R3HostMetadata::new(&allocator), @@ -1505,17 +1505,17 @@ mod tests { // Issue #67: output mappings must also be flat arrays let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("MyDirective"), source_span: None }, + ReadVarExpr { name: Ident::from("MyDirective"), source_span: None }, &allocator, )); let directive_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("ClickTracker"), source_span: None }, + ReadVarExpr { name: Ident::from("ClickTracker"), source_span: None }, &allocator, )); let mut host_directive_outputs = Vec::new_in(&allocator); - host_directive_outputs.push((Atom::from("clicked"), Atom::from("trackClick"))); + host_directive_outputs.push((Ident::from("clicked"), Ident::from("trackClick"))); let mut host_directives = Vec::new_in(&allocator); host_directives.push(R3HostDirectiveMetadata { @@ -1526,11 +1526,11 @@ mod tests { }); let metadata = R3DirectiveMetadata { - name: Atom::from("MyDirective"), + name: Ident::from("MyDirective"), r#type: type_expr, type_argument_count: 0, deps: None, - selector: Some(Atom::from("[myDir]")), + selector: Some(Ident::from("[myDir]")), queries: Vec::new_in(&allocator), view_queries: Vec::new_in(&allocator), host: R3HostMetadata::new(&allocator), @@ -1563,8 +1563,8 @@ mod tests { fn test_create_inputs_literal_quotes_dotted_key() { let allocator = Allocator::default(); let inputs = vec![R3InputMetadata { - class_property_name: Atom::from("fxFlexAlign.xs"), - binding_property_name: Atom::from("fxFlexAlign.xs"), + class_property_name: Ident::from("fxFlexAlign.xs"), + binding_property_name: Ident::from("fxFlexAlign.xs"), required: false, is_signal: false, transform_function: None, @@ -1582,8 +1582,8 @@ mod tests { fn test_create_inputs_literal_quotes_hyphenated_key() { let allocator = Allocator::default(); let inputs = vec![R3InputMetadata { - class_property_name: Atom::from("fxFlexAlign.lt-sm"), - binding_property_name: Atom::from("fxFlexAlign.lt-sm"), + class_property_name: Ident::from("fxFlexAlign.lt-sm"), + binding_property_name: Ident::from("fxFlexAlign.lt-sm"), required: false, is_signal: false, transform_function: None, @@ -1601,8 +1601,8 @@ mod tests { fn test_create_inputs_literal_no_quotes_for_simple_identifier() { let allocator = Allocator::default(); let inputs = vec![R3InputMetadata { - class_property_name: Atom::from("fxFlexAlign"), - binding_property_name: Atom::from("fxFlexAlign"), + class_property_name: Ident::from("fxFlexAlign"), + binding_property_name: Ident::from("fxFlexAlign"), required: false, is_signal: false, transform_function: None, @@ -1625,7 +1625,7 @@ mod tests { #[test] fn test_create_outputs_literal_quotes_dotted_key() { let allocator = Allocator::default(); - let outputs = vec![(Atom::from("activate.xs"), Atom::from("activateXs"))]; + let outputs = vec![(Ident::from("activate.xs"), Ident::from("activateXs"))]; let expr = create_outputs_literal(&allocator, &outputs).unwrap(); let emitter = JsEmitter::new(); let output = emitter.emit_expression(&expr); @@ -1638,7 +1638,7 @@ mod tests { #[test] fn test_create_outputs_literal_no_quotes_for_simple_identifier() { let allocator = Allocator::default(); - let outputs = vec![(Atom::from("activate"), Atom::from("activate"))]; + let outputs = vec![(Ident::from("activate"), Ident::from("activate"))]; let expr = create_outputs_literal(&allocator, &outputs).unwrap(); let emitter = JsEmitter::new(); let output = emitter.emit_expression(&expr); diff --git a/crates/oxc_angular_compiler/src/directive/decorator.rs b/crates/oxc_angular_compiler/src/directive/decorator.rs index de018f214..a580e16ab 100644 --- a/crates/oxc_angular_compiler/src/directive/decorator.rs +++ b/crates/oxc_angular_compiler/src/directive/decorator.rs @@ -8,7 +8,7 @@ use oxc_ast::ast::{ Argument, ArrayExpressionElement, Class, ClassElement, Decorator, Expression, MethodDefinitionKind, ObjectPropertyKind, PropertyKey, }; -use oxc_span::{Atom, Span}; +use oxc_span::{Ident, Span}; use super::metadata::{ R3DirectiveMetadata, R3DirectiveMetadataBuilder, R3HostDirectiveMetadata, R3HostMetadata, @@ -79,7 +79,7 @@ pub fn extract_directive_metadata<'a>( implicit_standalone: bool, ) -> Option> { // Get the class name - let class_name: Atom<'a> = class.id.as_ref()?.name.clone().into(); + let class_name: Ident<'a> = class.id.as_ref()?.name.clone().into(); // Find the @Directive decorator let directive_decorator = find_directive_decorator(&class.decorators)?; @@ -136,7 +136,7 @@ pub fn extract_directive_metadata<'a>( let trimmed = part.trim(); if !trimmed.is_empty() { builder = builder - .add_export_as(Atom::from(allocator.alloc_str(trimmed))); + .add_export_as(Ident::from(allocator.alloc_str(trimmed))); } } } @@ -297,7 +297,7 @@ fn extract_param_dependency<'a>( let mut self_ = false; let mut host = false; let mut inject_token: Option> = None; - let mut attribute_name: Option> = None; + let mut attribute_name: Option> = None; for decorator in ¶m.decorators { if let Some(name) = get_decorator_name_from_expr(&decorator.expression) { @@ -318,7 +318,7 @@ fn extract_param_dependency<'a>( // @Attribute('attrName') - extract the attribute name if let Expression::CallExpression(call) = &decorator.expression { if let Some(Argument::StringLiteral(s)) = call.arguments.first() { - attribute_name = Some(s.value.clone()); + attribute_name = Some(s.value.clone().into()); } } } @@ -354,7 +354,7 @@ fn extract_param_dependency<'a>( } /// Get the name of a decorator from its expression. -fn get_decorator_name_from_expr<'a>(expr: &'a Expression<'a>) -> Option> { +fn get_decorator_name_from_expr<'a>(expr: &'a Expression<'a>) -> Option> { match expr { // @Optional Expression::Identifier(id) => Some(id.name.clone().into()), @@ -433,21 +433,21 @@ fn has_ng_on_changes_method(class: &Class<'_>) -> bool { } /// Get the name of a property key as a string. -fn get_property_key_name<'a>(key: &PropertyKey<'a>) -> Option> { +fn get_property_key_name<'a>(key: &PropertyKey<'a>) -> Option> { match key { PropertyKey::StaticIdentifier(id) => Some(id.name.clone().into()), - PropertyKey::StringLiteral(lit) => Some(lit.value.clone()), + PropertyKey::StringLiteral(lit) => Some(lit.value.clone().into()), _ => None, } } /// Extract a string value from an expression. -fn extract_string_value<'a>(expr: &Expression<'a>) -> Option> { +fn extract_string_value<'a>(expr: &Expression<'a>) -> Option> { match expr { - Expression::StringLiteral(lit) => Some(lit.value.clone()), + Expression::StringLiteral(lit) => Some(lit.value.clone().into()), Expression::TemplateLiteral(tpl) if tpl.expressions.is_empty() => { // Simple template literal with no expressions - tpl.quasis.first().and_then(|q| q.value.cooked.clone()) + tpl.quasis.first().and_then(|q| q.value.cooked.clone().map(Into::into)) } _ => None, } @@ -456,7 +456,7 @@ fn extract_string_value<'a>(expr: &Expression<'a>) -> Option> { /// Extract a boolean value from an expression. fn extract_boolean_value(expr: &Expression<'_>) -> Option { match expr { - Expression::BooleanLiteral(lit) => Some(lit.value), + Expression::BooleanLiteral(lit) => Some(lit.value.into()), _ => None, } } @@ -651,7 +651,7 @@ fn is_forward_ref_call(callee: &Expression<'_>) -> bool { /// Extract the directive name from a forwardRef argument. /// /// Handles: `forwardRef(() => MyDirective)` -fn extract_forward_ref_directive_name<'a>(arg: Option<&Argument<'a>>) -> Option> { +fn extract_forward_ref_directive_name<'a>(arg: Option<&Argument<'a>>) -> Option> { let arg = arg?; match arg { Argument::ArrowFunctionExpression(arrow) => { @@ -682,7 +682,7 @@ fn extract_forward_ref_directive_name<'a>(arg: Option<&Argument<'a>>) -> Option< fn extract_io_mappings<'a>( allocator: &'a Allocator, expr: &Expression<'a>, -) -> Vec<'a, (Atom<'a>, Atom<'a>)> { +) -> Vec<'a, (Ident<'a>, Ident<'a>)> { let mut result = Vec::new_in(allocator); let Expression::ArrayExpression(arr) = expr else { @@ -707,7 +707,7 @@ fn extract_io_mappings<'a>( fn parse_mapping_element<'a>( allocator: &'a Allocator, element: &ArrayExpressionElement<'a>, -) -> Option<(Atom<'a>, Atom<'a>)> { +) -> Option<(Ident<'a>, Ident<'a>)> { match element { // Simple string: "color" - same public and internal name ArrayExpressionElement::StringLiteral(lit) => { @@ -718,12 +718,12 @@ fn parse_mapping_element<'a>( let internal_name = value[..colon_pos].trim(); let public_name = value[colon_pos + 1..].trim(); Some(( - Atom::from(allocator.alloc_str(public_name)), - Atom::from(allocator.alloc_str(internal_name)), + Ident::from(allocator.alloc_str(public_name)), + Ident::from(allocator.alloc_str(internal_name)), )) } else { // Same name for both - Some((lit.value.clone(), lit.value.clone())) + Some((lit.value.clone().into(), lit.value.clone().into())) } } @@ -732,11 +732,11 @@ fn parse_mapping_element<'a>( let elements = &arr.elements; if elements.len() >= 2 { let internal = match elements.first() { - Some(ArrayExpressionElement::StringLiteral(lit)) => Some(lit.value.clone()), + Some(ArrayExpressionElement::StringLiteral(lit)) => Some(lit.value.clone().into()), _ => None, }; let public = match elements.get(1) { - Some(ArrayExpressionElement::StringLiteral(lit)) => Some(lit.value.clone()), + Some(ArrayExpressionElement::StringLiteral(lit)) => Some(lit.value.clone().into()), _ => None, }; if let (Some(internal_name), Some(public_name)) = (internal, public) { diff --git a/crates/oxc_angular_compiler/src/directive/definition.rs b/crates/oxc_angular_compiler/src/directive/definition.rs index 0478a7018..ba5d03e11 100644 --- a/crates/oxc_angular_compiler/src/directive/definition.rs +++ b/crates/oxc_angular_compiler/src/directive/definition.rs @@ -193,20 +193,20 @@ mod tests { use crate::output::ast::ReadVarExpr; use crate::output::emitter::JsEmitter; use oxc_allocator::Box; - use oxc_span::Atom; + use oxc_span::Ident; fn create_test_metadata<'a>(allocator: &'a Allocator) -> R3DirectiveMetadata<'a> { let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("TestDirective"), source_span: None }, + ReadVarExpr { name: Ident::from("TestDirective"), source_span: None }, allocator, )); R3DirectiveMetadata { - name: Atom::from("TestDirective"), + name: Ident::from("TestDirective"), r#type: type_expr, type_argument_count: 0, deps: None, - selector: Some(Atom::from("[testDir]")), + selector: Some(Ident::from("[testDir]")), queries: Vec::new_in(allocator), view_queries: Vec::new_in(allocator), host: R3HostMetadata::new(allocator), @@ -270,16 +270,16 @@ mod tests { // an inherited factory pattern let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("ChildDirective"), source_span: None }, + ReadVarExpr { name: Ident::from("ChildDirective"), source_span: None }, &allocator, )); let metadata = R3DirectiveMetadata { - name: Atom::from("ChildDirective"), + name: Ident::from("ChildDirective"), r#type: type_expr, type_argument_count: 0, deps: None, // No explicit constructor deps - selector: Some(Atom::from("[childDir]")), + selector: Some(Ident::from("[childDir]")), queries: Vec::new_in(&allocator), view_queries: Vec::new_in(&allocator), host: R3HostMetadata::new(&allocator), @@ -309,16 +309,16 @@ mod tests { fn test_generate_fac_definition_with_empty_deps() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("TestDirective"), source_span: None }, + ReadVarExpr { name: Ident::from("TestDirective"), source_span: None }, &allocator, )); let metadata = R3DirectiveMetadata { - name: Atom::from("TestDirective"), + name: Ident::from("TestDirective"), r#type: type_expr, type_argument_count: 0, deps: Some(Vec::new_in(&allocator)), // Empty deps - has constructor but no params - selector: Some(Atom::from("[testDir]")), + selector: Some(Ident::from("[testDir]")), queries: Vec::new_in(&allocator), view_queries: Vec::new_in(&allocator), host: R3HostMetadata::new(&allocator), @@ -350,12 +350,12 @@ mod tests { fn test_generate_fac_definition_with_deps() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("TestDirective"), source_span: None }, + ReadVarExpr { name: Ident::from("TestDirective"), source_span: None }, &allocator, )); let dep_token = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("SomeService"), source_span: None }, + ReadVarExpr { name: Ident::from("SomeService"), source_span: None }, &allocator, )); @@ -363,11 +363,11 @@ mod tests { deps.push(crate::factory::R3DependencyMetadata::simple(dep_token)); let metadata = R3DirectiveMetadata { - name: Atom::from("TestDirective"), + name: Ident::from("TestDirective"), r#type: type_expr, type_argument_count: 0, deps: Some(deps), - selector: Some(Atom::from("[testDir]")), + selector: Some(Ident::from("[testDir]")), queries: Vec::new_in(&allocator), view_queries: Vec::new_in(&allocator), host: R3HostMetadata::new(&allocator), @@ -418,20 +418,20 @@ mod tests { // Create first directive with host bindings let type_expr1 = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("Dir1"), source_span: None }, + ReadVarExpr { name: Ident::from("Dir1"), source_span: None }, &allocator, )); let mut host1 = R3HostMetadata::new(&allocator); // Add a property binding which will use the constant pool - host1.properties.push((Atom::from("[attr.role]"), Atom::from("'button'"))); + host1.properties.push((Ident::from("[attr.role]"), Ident::from("'button'"))); let metadata1 = R3DirectiveMetadata { - name: Atom::from("Dir1"), + name: Ident::from("Dir1"), r#type: type_expr1, type_argument_count: 0, deps: None, - selector: Some(Atom::from("[dir1]")), + selector: Some(Ident::from("[dir1]")), queries: Vec::new_in(&allocator), view_queries: Vec::new_in(&allocator), host: host1, @@ -456,19 +456,19 @@ mod tests { // Create second directive with host bindings using the returned pool index let type_expr2 = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("Dir2"), source_span: None }, + ReadVarExpr { name: Ident::from("Dir2"), source_span: None }, &allocator, )); let mut host2 = R3HostMetadata::new(&allocator); - host2.properties.push((Atom::from("[attr.id]"), Atom::from("'test'"))); + host2.properties.push((Ident::from("[attr.id]"), Ident::from("'test'"))); let metadata2 = R3DirectiveMetadata { - name: Atom::from("Dir2"), + name: Ident::from("Dir2"), r#type: type_expr2, type_argument_count: 0, deps: None, - selector: Some(Atom::from("[dir2]")), + selector: Some(Ident::from("[dir2]")), queries: Vec::new_in(&allocator), view_queries: Vec::new_in(&allocator), host: host2, diff --git a/crates/oxc_angular_compiler/src/directive/metadata.rs b/crates/oxc_angular_compiler/src/directive/metadata.rs index 440dc7450..fbc051154 100644 --- a/crates/oxc_angular_compiler/src/directive/metadata.rs +++ b/crates/oxc_angular_compiler/src/directive/metadata.rs @@ -4,7 +4,7 @@ use oxc_allocator::{Allocator, Vec}; use oxc_ast::ast::Class; -use oxc_span::Atom; +use oxc_span::Ident; use crate::factory::R3DependencyMetadata; use crate::output::ast::OutputExpression; @@ -15,10 +15,10 @@ use crate::output::ast::OutputExpression; #[derive(Debug)] pub struct R3InputMetadata<'a> { /// The property name on the class. - pub class_property_name: Atom<'a>, + pub class_property_name: Ident<'a>, /// The binding property name (can differ from class property name). - pub binding_property_name: Atom<'a>, + pub binding_property_name: Ident<'a>, /// Whether this input is required. pub required: bool, @@ -33,7 +33,7 @@ pub struct R3InputMetadata<'a> { impl<'a> R3InputMetadata<'a> { /// Create a simple input with matching class and binding names. - pub fn simple(name: Atom<'a>) -> Self { + pub fn simple(name: Ident<'a>) -> Self { Self { class_property_name: name.clone(), binding_property_name: name, @@ -44,7 +44,7 @@ impl<'a> R3InputMetadata<'a> { } /// Create a required input. - pub fn required(name: Atom<'a>) -> Self { + pub fn required(name: Ident<'a>) -> Self { Self { class_property_name: name.clone(), binding_property_name: name, @@ -55,7 +55,7 @@ impl<'a> R3InputMetadata<'a> { } /// Create a signal-based input. - pub fn signal(name: Atom<'a>) -> Self { + pub fn signal(name: Ident<'a>) -> Self { Self { class_property_name: name.clone(), binding_property_name: name, @@ -72,7 +72,7 @@ impl<'a> R3InputMetadata<'a> { #[derive(Debug)] pub struct R3QueryMetadata<'a> { /// Name of the property on the class to update with query results. - pub property_name: Atom<'a>, + pub property_name: Ident<'a>, /// Whether to read only the first matching result. pub first: bool, @@ -103,12 +103,12 @@ pub enum QueryPredicate<'a> { Type(OutputExpression<'a>), /// String selectors. - Selectors(Vec<'a, Atom<'a>>), + Selectors(Vec<'a, Ident<'a>>), } impl<'a> R3QueryMetadata<'a> { /// Create a new query metadata with defaults. - pub fn new(allocator: &'a Allocator, property_name: Atom<'a>) -> Self { + pub fn new(allocator: &'a Allocator, property_name: Ident<'a>) -> Self { Self { property_name, first: false, @@ -128,19 +128,19 @@ impl<'a> R3QueryMetadata<'a> { #[derive(Debug)] pub struct R3HostMetadata<'a> { /// A mapping of attribute binding keys to expressions. - pub attributes: Vec<'a, (Atom<'a>, OutputExpression<'a>)>, + pub attributes: Vec<'a, (Ident<'a>, OutputExpression<'a>)>, /// A mapping of event binding keys to unparsed expressions. - pub listeners: Vec<'a, (Atom<'a>, Atom<'a>)>, + pub listeners: Vec<'a, (Ident<'a>, Ident<'a>)>, /// A mapping of property binding keys to unparsed expressions. - pub properties: Vec<'a, (Atom<'a>, Atom<'a>)>, + pub properties: Vec<'a, (Ident<'a>, Ident<'a>)>, /// Special style attribute value. - pub style_attr: Option>, + pub style_attr: Option>, /// Special class attribute value. - pub class_attr: Option>, + pub class_attr: Option>, } impl<'a> R3HostMetadata<'a> { @@ -178,11 +178,11 @@ pub struct R3HostDirectiveMetadata<'a> { /// Inputs from the host directive that will be exposed on the host. /// Key: public name, Value: internal name - pub inputs: Vec<'a, (Atom<'a>, Atom<'a>)>, + pub inputs: Vec<'a, (Ident<'a>, Ident<'a>)>, /// Outputs from the host directive that will be exposed on the host. /// Key: public name, Value: internal name - pub outputs: Vec<'a, (Atom<'a>, Atom<'a>)>, + pub outputs: Vec<'a, (Ident<'a>, Ident<'a>)>, } /// Metadata needed to compile a directive. @@ -191,7 +191,7 @@ pub struct R3HostDirectiveMetadata<'a> { #[derive(Debug)] pub struct R3DirectiveMetadata<'a> { /// Name of the directive type. - pub name: Atom<'a>, + pub name: Ident<'a>, /// An expression representing a reference to the directive itself. pub r#type: OutputExpression<'a>, @@ -203,7 +203,7 @@ pub struct R3DirectiveMetadata<'a> { pub deps: Option>>, /// Unparsed selector of the directive, or None if there was no selector. - pub selector: Option>, + pub selector: Option>, /// Content queries made by the directive. pub queries: Vec<'a, R3QueryMetadata<'a>>, @@ -221,13 +221,13 @@ pub struct R3DirectiveMetadata<'a> { pub inputs: Vec<'a, R3InputMetadata<'a>>, /// Outputs of the directive (class property name -> binding property name). - pub outputs: Vec<'a, (Atom<'a>, Atom<'a>)>, + pub outputs: Vec<'a, (Ident<'a>, Ident<'a>)>, /// Whether or not the directive inherits from another class. pub uses_inheritance: bool, /// Export names for template references. - pub export_as: Vec<'a, Atom<'a>>, + pub export_as: Vec<'a, Ident<'a>>, /// The list of providers defined in the directive. pub providers: Option>, @@ -254,19 +254,19 @@ impl<'a> R3DirectiveMetadata<'a> { /// Builder for R3DirectiveMetadata. pub struct R3DirectiveMetadataBuilder<'a> { - name: Option>, + name: Option>, r#type: Option>, type_argument_count: u32, deps: Option>>, - selector: Option>, + selector: Option>, queries: Vec<'a, R3QueryMetadata<'a>>, view_queries: Vec<'a, R3QueryMetadata<'a>>, host: R3HostMetadata<'a>, uses_on_changes: bool, inputs: Vec<'a, R3InputMetadata<'a>>, - outputs: Vec<'a, (Atom<'a>, Atom<'a>)>, + outputs: Vec<'a, (Ident<'a>, Ident<'a>)>, uses_inheritance: bool, - export_as: Vec<'a, Atom<'a>>, + export_as: Vec<'a, Ident<'a>>, providers: Option>, is_standalone: bool, is_signal: bool, @@ -298,7 +298,7 @@ impl<'a> R3DirectiveMetadataBuilder<'a> { } /// Set the directive name. - pub fn name(mut self, name: Atom<'a>) -> Self { + pub fn name(mut self, name: Ident<'a>) -> Self { self.name = Some(name); self } @@ -322,7 +322,7 @@ impl<'a> R3DirectiveMetadataBuilder<'a> { } /// Set the selector. - pub fn selector(mut self, selector: Atom<'a>) -> Self { + pub fn selector(mut self, selector: Ident<'a>) -> Self { self.selector = Some(selector); self } @@ -358,7 +358,7 @@ impl<'a> R3DirectiveMetadataBuilder<'a> { } /// Add an output. - pub fn add_output(mut self, class_name: Atom<'a>, binding_name: Atom<'a>) -> Self { + pub fn add_output(mut self, class_name: Ident<'a>, binding_name: Ident<'a>) -> Self { self.outputs.push((class_name, binding_name)); self } @@ -370,7 +370,7 @@ impl<'a> R3DirectiveMetadataBuilder<'a> { } /// Add an export name. - pub fn add_export_as(mut self, export_name: Atom<'a>) -> Self { + pub fn add_export_as(mut self, export_name: Ident<'a>) -> Self { self.export_as.push(export_name); self } @@ -440,7 +440,7 @@ impl<'a> R3DirectiveMetadataBuilder<'a> { let host_bindings = super::property_decorators::extract_host_bindings(allocator, class); for (host_prop, class_prop) in host_bindings { // Add to host.properties with wrapped key - let wrapped_key = Atom::from(allocator.alloc_str(&format!("[{}]", host_prop.as_str()))); + let wrapped_key = Ident::from(allocator.alloc_str(&format!("[{}]", host_prop.as_str()))); self.host.properties.push((wrapped_key, class_prop)); } @@ -451,15 +451,15 @@ impl<'a> R3DirectiveMetadataBuilder<'a> { for (event_name, method_name, args) in host_listeners { // Wrap event name: "click" -> "(click)" let wrapped_key = - Atom::from(allocator.alloc_str(&format!("({})", event_name.as_str()))); + Ident::from(allocator.alloc_str(&format!("({})", event_name.as_str()))); // Build method expression with args: "handleClick" + ["$event"] -> "handleClick($event)" let method_expr = if args.is_empty() { - Atom::from(allocator.alloc_str(&format!("{}()", method_name.as_str()))) + Ident::from(allocator.alloc_str(&format!("{}()", method_name.as_str()))) } else { let args_str: String = args.iter().map(|a| a.as_str()).collect::>().join(","); - Atom::from(allocator.alloc_str(&format!("{}({})", method_name.as_str(), args_str))) + Ident::from(allocator.alloc_str(&format!("{}({})", method_name.as_str(), args_str))) }; // Add to host.listeners @@ -542,9 +542,9 @@ mod tests { fn test_builder_basic() { let allocator = Allocator::default(); let builder = R3DirectiveMetadataBuilder::new(&allocator) - .name(Atom::from("TestDirective")) - .r#type(OutputAstBuilder::variable(&allocator, Atom::from("TestDirective"))) - .selector(Atom::from("[test]")); + .name(Ident::from("TestDirective")) + .r#type(OutputAstBuilder::variable(&allocator, Ident::from("TestDirective"))) + .selector(Ident::from("[test]")); let metadata = builder.build(); assert!(metadata.is_some()); @@ -559,7 +559,7 @@ mod tests { fn test_builder_missing_name_returns_none() { let allocator = Allocator::default(); let builder = R3DirectiveMetadataBuilder::new(&allocator) - .r#type(OutputAstBuilder::variable(&allocator, Atom::from("TestDirective"))); + .r#type(OutputAstBuilder::variable(&allocator, Ident::from("TestDirective"))); let metadata = builder.build(); assert!(metadata.is_none()); @@ -568,7 +568,7 @@ mod tests { #[test] fn test_builder_missing_type_returns_none() { let allocator = Allocator::default(); - let builder = R3DirectiveMetadataBuilder::new(&allocator).name(Atom::from("TestDirective")); + let builder = R3DirectiveMetadataBuilder::new(&allocator).name(Ident::from("TestDirective")); let metadata = builder.build(); assert!(metadata.is_none()); @@ -593,8 +593,8 @@ mod tests { assert!(class.is_some()); let builder = R3DirectiveMetadataBuilder::new(&allocator) - .name(Atom::from("TestDirective")) - .r#type(OutputAstBuilder::variable(&allocator, Atom::from("TestDirective"))) + .name(Ident::from("TestDirective")) + .r#type(OutputAstBuilder::variable(&allocator, Ident::from("TestDirective"))) .extract_from_class(&allocator, class.unwrap()); let metadata = builder.build(); @@ -631,8 +631,8 @@ mod tests { assert!(class.is_some()); let builder = R3DirectiveMetadataBuilder::new(&allocator) - .name(Atom::from("TestDirective")) - .r#type(OutputAstBuilder::variable(&allocator, Atom::from("TestDirective"))) + .name(Ident::from("TestDirective")) + .r#type(OutputAstBuilder::variable(&allocator, Ident::from("TestDirective"))) .extract_from_class(&allocator, class.unwrap()); let metadata = builder.build(); @@ -664,8 +664,8 @@ mod tests { assert!(class.is_some()); let builder = R3DirectiveMetadataBuilder::new(&allocator) - .name(Atom::from("TestComponent")) - .r#type(OutputAstBuilder::variable(&allocator, Atom::from("TestComponent"))) + .name(Ident::from("TestComponent")) + .r#type(OutputAstBuilder::variable(&allocator, Ident::from("TestComponent"))) .extract_from_class(&allocator, class.unwrap()); let metadata = builder.build(); @@ -697,8 +697,8 @@ mod tests { assert!(class.is_some()); let builder = R3DirectiveMetadataBuilder::new(&allocator) - .name(Atom::from("TestComponent")) - .r#type(OutputAstBuilder::variable(&allocator, Atom::from("TestComponent"))) + .name(Ident::from("TestComponent")) + .r#type(OutputAstBuilder::variable(&allocator, Ident::from("TestComponent"))) .extract_from_class(&allocator, class.unwrap()); let metadata = builder.build(); @@ -730,8 +730,8 @@ mod tests { assert!(class.is_some()); let builder = R3DirectiveMetadataBuilder::new(&allocator) - .name(Atom::from("TestDirective")) - .r#type(OutputAstBuilder::variable(&allocator, Atom::from("TestDirective"))) + .name(Ident::from("TestDirective")) + .r#type(OutputAstBuilder::variable(&allocator, Ident::from("TestDirective"))) .extract_from_class(&allocator, class.unwrap()); let metadata = builder.build(); @@ -765,8 +765,8 @@ mod tests { assert!(class.is_some()); let builder = R3DirectiveMetadataBuilder::new(&allocator) - .name(Atom::from("TestDirective")) - .r#type(OutputAstBuilder::variable(&allocator, Atom::from("TestDirective"))) + .name(Ident::from("TestDirective")) + .r#type(OutputAstBuilder::variable(&allocator, Ident::from("TestDirective"))) .extract_from_class(&allocator, class.unwrap()); let metadata = builder.build(); @@ -803,8 +803,8 @@ mod tests { assert!(class.is_some()); let builder = R3DirectiveMetadataBuilder::new(&allocator) - .name(Atom::from("TestComponent")) - .r#type(OutputAstBuilder::variable(&allocator, Atom::from("TestComponent"))) + .name(Ident::from("TestComponent")) + .r#type(OutputAstBuilder::variable(&allocator, Ident::from("TestComponent"))) .extract_from_class(&allocator, class.unwrap()); let metadata = builder.build(); @@ -833,8 +833,8 @@ mod tests { assert!(class.is_some()); let builder = R3DirectiveMetadataBuilder::new(&allocator) - .name(Atom::from("EmptyDirective")) - .r#type(OutputAstBuilder::variable(&allocator, Atom::from("EmptyDirective"))) + .name(Ident::from("EmptyDirective")) + .r#type(OutputAstBuilder::variable(&allocator, Ident::from("EmptyDirective"))) .extract_from_class(&allocator, class.unwrap()); let metadata = builder.build(); @@ -865,9 +865,9 @@ mod tests { // Pre-add an input before extract_from_class let builder = R3DirectiveMetadataBuilder::new(&allocator) - .name(Atom::from("TestDirective")) - .r#type(OutputAstBuilder::variable(&allocator, Atom::from("TestDirective"))) - .add_input(R3InputMetadata::simple(Atom::from("existingInput"))) + .name(Ident::from("TestDirective")) + .r#type(OutputAstBuilder::variable(&allocator, Ident::from("TestDirective"))) + .add_input(R3InputMetadata::simple(Ident::from("existingInput"))) .extract_from_class(&allocator, class.unwrap()); let metadata = builder.build(); diff --git a/crates/oxc_angular_compiler/src/directive/property_decorators.rs b/crates/oxc_angular_compiler/src/directive/property_decorators.rs index 11c200512..cf8c0d61e 100644 --- a/crates/oxc_angular_compiler/src/directive/property_decorators.rs +++ b/crates/oxc_angular_compiler/src/directive/property_decorators.rs @@ -16,7 +16,7 @@ use oxc_ast::ast::{ Argument, ArrayExpressionElement, Class, ClassElement, Decorator, Expression, MethodDefinitionKind, ObjectPropertyKind, PropertyKey, }; -use oxc_span::Atom; +use oxc_span::Ident; use super::metadata::{QueryPredicate, R3InputMetadata, R3QueryMetadata}; use crate::output::ast::OutputExpression; @@ -50,10 +50,10 @@ fn find_decorator_by_name<'a>( /// Get the property key name as an Atom. /// /// Handles both identifier keys and string literal keys. -fn get_property_key_name<'a>(key: &PropertyKey<'a>) -> Option> { +fn get_property_key_name<'a>(key: &PropertyKey<'a>) -> Option> { match key { PropertyKey::StaticIdentifier(id) => Some(id.name.clone().into()), - PropertyKey::StringLiteral(lit) => Some(lit.value.clone()), + PropertyKey::StringLiteral(lit) => Some(lit.value.clone().into()), _ => None, } } @@ -61,11 +61,11 @@ fn get_property_key_name<'a>(key: &PropertyKey<'a>) -> Option> { /// Extract a string value from an expression. /// /// Handles string literals and simple template literals (no expressions). -fn extract_string_value<'a>(expr: &Expression<'a>) -> Option> { +fn extract_string_value<'a>(expr: &Expression<'a>) -> Option> { match expr { - Expression::StringLiteral(lit) => Some(lit.value.clone()), + Expression::StringLiteral(lit) => Some(lit.value.clone().into()), Expression::TemplateLiteral(tpl) if tpl.expressions.is_empty() => { - tpl.quasis.first().and_then(|q| q.value.cooked.clone()) + tpl.quasis.first().and_then(|q| q.value.cooked.clone().map(Into::into)) } _ => None, } @@ -74,7 +74,7 @@ fn extract_string_value<'a>(expr: &Expression<'a>) -> Option> { /// Extract a boolean value from an expression. fn extract_boolean_value(expr: &Expression<'_>) -> Option { match expr { - Expression::BooleanLiteral(lit) => Some(lit.value), + Expression::BooleanLiteral(lit) => Some(lit.value.into()), _ => None, } } @@ -128,7 +128,7 @@ fn try_unwrap_forward_ref<'a>(expr: &'a Expression<'a>) -> Option<&'a Expression /// Parsed @Input decorator configuration. struct InputConfig<'a> { /// Alias name for the input binding (different from property name). - alias: Option>, + alias: Option>, /// Whether this input is required. required: bool, /// Transform function for the input value. @@ -162,7 +162,7 @@ fn parse_input_config<'a>( match first_arg { // @Input('alias') Argument::StringLiteral(lit) => { - InputConfig { alias: Some(lit.value.clone()), ..Default::default() } + InputConfig { alias: Some(lit.value.clone().into()), ..Default::default() } } // @Input({ alias: 'name', required: true, transform: fn }) @@ -205,7 +205,7 @@ struct ModelMapping<'a> { input: R3InputMetadata<'a>, /// The output metadata (class property name, binding property name). /// Output binding name is always `inputName + "Change"`. - output: (Atom<'a>, Atom<'a>), + output: (Ident<'a>, Ident<'a>), } /// Try to detect and parse a signal-based model from a property initializer. @@ -224,7 +224,7 @@ struct ModelMapping<'a> { fn try_parse_signal_model<'a>( allocator: &'a Allocator, value: &Expression<'a>, - property_name: Atom<'a>, + property_name: Ident<'a>, ) -> Option> { // Check if the value is a call expression let call_expr = match value { @@ -247,7 +247,7 @@ fn try_parse_signal_model<'a>( } else if member.property.name == "model" { // Handle namespaced calls like `core.model()` if let Expression::Identifier(_) = &member.object { - let output_binding = Atom::from( + let output_binding = Ident::from( allocator.alloc_str(&format!("{}Change", property_name.as_str())), ); return Some(ModelMapping { @@ -274,7 +274,7 @@ fn try_parse_signal_model<'a>( // For model.required(): first arg is options let options_arg_index = if is_required { 0 } else { 1 }; - let mut alias: Option> = None; + let mut alias: Option> = None; if let Some(options_arg) = call_expr.arguments.get(options_arg_index) { if let Argument::ObjectExpression(obj) = options_arg { @@ -295,7 +295,7 @@ fn try_parse_signal_model<'a>( let binding_property_name = alias.unwrap_or_else(|| property_name.clone()); // Output binding name is always `bindingPropertyName + "Change"` let output_binding_name = - Atom::from(allocator.alloc_str(&format!("{}Change", binding_property_name.as_str()))); + Ident::from(allocator.alloc_str(&format!("{}Change", binding_property_name.as_str()))); Some(ModelMapping { input: R3InputMetadata { @@ -324,8 +324,8 @@ fn try_parse_signal_model<'a>( /// Based on Angular's `output_function.ts` in the compiler-cli. fn try_parse_signal_output<'a>( value: &Expression<'a>, - property_name: Atom<'a>, -) -> Option<(Atom<'a>, Atom<'a>)> { + property_name: Ident<'a>, +) -> Option<(Ident<'a>, Ident<'a>)> { // Check if the value is a call expression let call_expr = match value { Expression::CallExpression(call) => call, @@ -353,7 +353,7 @@ fn try_parse_signal_output<'a>( // Parse options from the first argument (options are the first arg for output()) // Options can contain an alias - let mut alias: Option> = None; + let mut alias: Option> = None; if let Some(first_arg) = call_expr.arguments.first() { if let Argument::ObjectExpression(obj) = first_arg { @@ -393,7 +393,7 @@ fn try_parse_signal_output<'a>( fn try_parse_signal_input<'a>( _allocator: &'a Allocator, value: &Expression<'a>, - property_name: Atom<'a>, + property_name: Ident<'a>, ) -> Option> { // Check if the value is a call expression let call_expr = match value { @@ -437,7 +437,7 @@ fn try_parse_signal_input<'a>( // For input.required(): first arg is options let options_arg_index = if is_required { 0 } else { 1 }; - let mut alias: Option> = None; + let mut alias: Option> = None; if let Some(options_arg) = call_expr.arguments.get(options_arg_index) { if let Argument::ObjectExpression(obj) = options_arg { @@ -589,7 +589,7 @@ pub fn extract_input_metadata<'a>( /// Parsed @Output decorator configuration. struct OutputConfig<'a> { /// Alias name for the output binding (different from property name). - alias: Option>, + alias: Option>, } impl<'a> Default for OutputConfig<'a> { @@ -614,7 +614,7 @@ fn parse_output_config<'a>(decorator: &'a Decorator<'a>) -> OutputConfig<'a> { match first_arg { // @Output('alias') - Argument::StringLiteral(lit) => OutputConfig { alias: Some(lit.value.clone()) }, + Argument::StringLiteral(lit) => OutputConfig { alias: Some(lit.value.clone().into()) }, _ => OutputConfig::default(), } } @@ -635,7 +635,7 @@ fn parse_output_config<'a>(decorator: &'a Decorator<'a>) -> OutputConfig<'a> { pub fn extract_output_metadata<'a>( allocator: &'a Allocator, class: &'a Class<'a>, -) -> Vec<'a, (Atom<'a>, Atom<'a>)> { +) -> Vec<'a, (Ident<'a>, Ident<'a>)> { let mut outputs = Vec::new_in(allocator); for element in &class.body.body { @@ -770,7 +770,7 @@ fn parse_query_config<'a>( // @ViewChild('refName') - string selector Argument::StringLiteral(lit) => { let mut selectors = Vec::new_in(allocator); - selectors.push(lit.value.clone()); + selectors.push(lit.value.clone().into()); config.predicate = Some(QueryPredicate::Selectors(selectors)); } @@ -865,7 +865,7 @@ impl SignalQueryType { fn try_parse_signal_query<'a>( allocator: &'a Allocator, value: &'a Expression<'a>, - property_name: Atom<'a>, + property_name: Ident<'a>, ) -> Option<(SignalQueryType, R3QueryMetadata<'a>)> { // Check if the value is a call expression let call_expr = match value { @@ -933,7 +933,7 @@ fn try_parse_signal_query<'a>( // String selector: viewChild('myRef') Argument::StringLiteral(lit) => { let mut selectors = oxc_allocator::Vec::new_in(allocator); - selectors.push(lit.value.clone()); + selectors.push(lit.value.clone().into()); QueryPredicate::Selectors(selectors) } // Type predicate: viewChild(TemplateRef) or viewChild(forwardRef(() => MyClass)) @@ -1285,7 +1285,7 @@ pub fn extract_content_queries<'a>( pub fn extract_host_bindings<'a>( allocator: &'a Allocator, class: &'a Class<'a>, -) -> Vec<'a, (Atom<'a>, Atom<'a>)> { +) -> Vec<'a, (Ident<'a>, Ident<'a>)> { let mut bindings = Vec::new_in(allocator); for element in &class.body.body { @@ -1323,7 +1323,7 @@ pub fn extract_host_bindings<'a>( /// Extract the binding name from a @HostBinding decorator. /// /// Returns the string argument if present, None otherwise. -fn extract_host_binding_name<'a>(decorator: &'a Decorator<'a>) -> Option> { +fn extract_host_binding_name<'a>(decorator: &'a Decorator<'a>) -> Option> { let Expression::CallExpression(call) = &decorator.expression else { return None; }; @@ -1331,7 +1331,7 @@ fn extract_host_binding_name<'a>(decorator: &'a Decorator<'a>) -> Option Some(lit.value.clone()), + Argument::StringLiteral(lit) => Some(lit.value.clone().into()), _ => { let expr = first_arg.to_expression(); extract_string_value(expr) @@ -1357,7 +1357,7 @@ fn extract_host_binding_name<'a>(decorator: &'a Decorator<'a>) -> Option( allocator: &'a Allocator, class: &'a Class<'a>, -) -> Vec<'a, (Atom<'a>, Atom<'a>, Vec<'a, Atom<'a>>)> { +) -> Vec<'a, (Ident<'a>, Ident<'a>, Vec<'a, Ident<'a>>)> { let mut listeners = Vec::new_in(allocator); for element in &class.body.body { @@ -1398,7 +1398,7 @@ pub fn extract_host_listeners<'a>( fn parse_host_listener_config<'a>( allocator: &'a Allocator, decorator: &'a Decorator<'a>, -) -> (Option>, Vec<'a, Atom<'a>>) { +) -> (Option>, Vec<'a, Ident<'a>>) { let mut args = Vec::new_in(allocator); let Expression::CallExpression(call) = &decorator.expression else { @@ -1407,7 +1407,7 @@ fn parse_host_listener_config<'a>( // First argument: event name let event_name = call.arguments.first().and_then(|arg| match arg { - Argument::StringLiteral(lit) => Some(lit.value.clone()), + Argument::StringLiteral(lit) => Some(lit.value.clone().into()), _ => { let expr = arg.to_expression(); extract_string_value(expr) @@ -1420,7 +1420,7 @@ fn parse_host_listener_config<'a>( for elem in &arr.elements { match elem { ArrayExpressionElement::StringLiteral(lit) => { - args.push(lit.value.clone()); + args.push(lit.value.clone().into()); } ArrayExpressionElement::Elision(_) => {} _ => { diff --git a/crates/oxc_angular_compiler/src/directive/query.rs b/crates/oxc_angular_compiler/src/directive/query.rs index afa7f9c75..3930f63a4 100644 --- a/crates/oxc_angular_compiler/src/directive/query.rs +++ b/crates/oxc_angular_compiler/src/directive/query.rs @@ -6,7 +6,7 @@ //! in directive definitions. use oxc_allocator::{Allocator, Box, FromIn, Vec}; -use oxc_span::Atom; +use oxc_span::Ident; use super::metadata::{QueryPredicate, R3QueryMetadata}; use crate::output::ast::{ @@ -107,12 +107,12 @@ fn import_expr<'a>(allocator: &'a Allocator, identifier: &'static str) -> Output ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(identifier), + name: Ident::from(identifier), optional: false, source_span: None, }, @@ -123,7 +123,7 @@ fn import_expr<'a>(allocator: &'a Allocator, identifier: &'static str) -> Output /// Create a variable reference. fn variable<'a>(allocator: &'a Allocator, name: &'static str) -> OutputExpression<'a> { OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from(name), source_span: None }, + ReadVarExpr { name: Ident::from(name), source_span: None }, allocator, )) } @@ -137,7 +137,7 @@ fn literal_number<'a>(allocator: &'a Allocator, value: u32) -> OutputExpression< } /// Create ctx.propertyName. -fn context_prop<'a>(allocator: &'a Allocator, property_name: &Atom<'a>) -> OutputExpression<'a> { +fn context_prop<'a>(allocator: &'a Allocator, property_name: &Ident<'a>) -> OutputExpression<'a> { OutputExpression::ReadProp(Box::new_in( ReadPropExpr { receiver: Box::new_in(variable(allocator, CONTEXT_NAME), allocator), @@ -234,7 +234,7 @@ fn get_query_predicate<'a>( if !trimmed.is_empty() { entries.push(OutputExpression::Literal(Box::new_in( LiteralExpr { - value: LiteralValue::String(Atom::from(trimmed)), + value: LiteralValue::String(Ident::from(trimmed)), source_span: None, }, allocator, @@ -413,7 +413,7 @@ impl TempAllocator { // Angular always reuses the same _t variable - see temporaryAllocator in util.ts self.allocated = true; OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from(TEMPORARY_NAME), source_span: None }, + ReadVarExpr { name: Ident::from(TEMPORARY_NAME), source_span: None }, allocator, )) } @@ -519,7 +519,7 @@ pub fn create_view_queries_function<'a>( OutputExpression::ReadProp(Box::new_in( ReadPropExpr { receiver: Box::new_in(temp.clone_in(allocator), allocator), - name: Atom::from("first"), + name: Ident::from("first"), optional: false, source_span: None, }, @@ -562,7 +562,7 @@ pub fn create_view_queries_function<'a>( if temp_allocator.needs_declaration() { final_update_statements.push(OutputStatement::DeclareVar(Box::new_in( DeclareVarStmt { - name: Atom::from(TEMPORARY_NAME), + name: Ident::from(TEMPORARY_NAME), value: None, modifiers: StmtModifier::NONE, leading_comment: None, @@ -592,13 +592,13 @@ pub fn create_view_queries_function<'a>( // Build function parameters let mut params = Vec::new_in(allocator); - params.push(FnParam { name: Atom::from(RENDER_FLAGS) }); - params.push(FnParam { name: Atom::from(CONTEXT_NAME) }); + params.push(FnParam { name: Ident::from(RENDER_FLAGS) }); + params.push(FnParam { name: Ident::from(CONTEXT_NAME) }); // Create function name let fn_name = name.map(|n| { let formatted = format!("{n}_Query"); - Atom::from_in(formatted.as_str(), allocator) + Ident::from_in(formatted.as_str(), allocator) }); OutputExpression::Function(Box::new_in( @@ -704,7 +704,7 @@ pub fn create_content_queries_function<'a>( OutputExpression::ReadProp(Box::new_in( ReadPropExpr { receiver: Box::new_in(temp.clone_in(allocator), allocator), - name: Atom::from("first"), + name: Ident::from("first"), optional: false, source_span: None, }, @@ -745,7 +745,7 @@ pub fn create_content_queries_function<'a>( if temp_allocator.needs_declaration() { final_update_statements.push(OutputStatement::DeclareVar(Box::new_in( DeclareVarStmt { - name: Atom::from(TEMPORARY_NAME), + name: Ident::from(TEMPORARY_NAME), value: None, modifiers: StmtModifier::NONE, leading_comment: None, @@ -774,14 +774,14 @@ pub fn create_content_queries_function<'a>( // Build function parameters (rf, ctx, dirIndex) let mut params = Vec::new_in(allocator); - params.push(FnParam { name: Atom::from(RENDER_FLAGS) }); - params.push(FnParam { name: Atom::from(CONTEXT_NAME) }); - params.push(FnParam { name: Atom::from("dirIndex") }); + params.push(FnParam { name: Ident::from(RENDER_FLAGS) }); + params.push(FnParam { name: Ident::from(CONTEXT_NAME) }); + params.push(FnParam { name: Ident::from("dirIndex") }); // Create function name let fn_name = name.map(|n| { let formatted = format!("{n}_ContentQueries"); - Atom::from_in(formatted.as_str(), allocator) + Ident::from_in(formatted.as_str(), allocator) }); OutputExpression::Function(Box::new_in( @@ -846,10 +846,10 @@ mod tests { // Create a signal query with a type predicate (e.g., SomeComponent) let query = R3QueryMetadata { - property_name: Atom::from("myQuery"), + property_name: Ident::from("myQuery"), first: true, predicate: QueryPredicate::Type(OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("SomeComponent"), source_span: None }, + ReadVarExpr { name: Ident::from("SomeComponent"), source_span: None }, &allocator, ))), descendants: true, @@ -888,10 +888,10 @@ mod tests { // Create a signal content query with a type predicate let query = R3QueryMetadata { - property_name: Atom::from("myContent"), + property_name: Ident::from("myContent"), first: true, predicate: QueryPredicate::Type(OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("ContentComponent"), source_span: None }, + ReadVarExpr { name: Ident::from("ContentComponent"), source_span: None }, &allocator, ))), descendants: true, @@ -929,10 +929,10 @@ mod tests { // Create two signal queries let query1 = R3QueryMetadata { - property_name: Atom::from("query1"), + property_name: Ident::from("query1"), first: true, predicate: QueryPredicate::Type(OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("Component1"), source_span: None }, + ReadVarExpr { name: Ident::from("Component1"), source_span: None }, &allocator, ))), descendants: true, @@ -943,10 +943,10 @@ mod tests { }; let query2 = R3QueryMetadata { - property_name: Atom::from("query2"), + property_name: Ident::from("query2"), first: true, predicate: QueryPredicate::Type(OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("Component2"), source_span: None }, + ReadVarExpr { name: Ident::from("Component2"), source_span: None }, &allocator, ))), descendants: true, @@ -988,10 +988,10 @@ mod tests { let allocator = Allocator::default(); let query1 = R3QueryMetadata { - property_name: Atom::from("myChild"), + property_name: Ident::from("myChild"), first: true, predicate: QueryPredicate::Type(OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("ChildComponent"), source_span: None }, + ReadVarExpr { name: Ident::from("ChildComponent"), source_span: None }, &allocator, ))), descendants: true, @@ -1002,10 +1002,10 @@ mod tests { }; let query2 = R3QueryMetadata { - property_name: Atom::from("myOther"), + property_name: Ident::from("myOther"), first: false, predicate: QueryPredicate::Type(OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("OtherComponent"), source_span: None }, + ReadVarExpr { name: Ident::from("OtherComponent"), source_span: None }, &allocator, ))), descendants: true, @@ -1054,10 +1054,10 @@ mod tests { let allocator = Allocator::default(); let query1 = R3QueryMetadata { - property_name: Atom::from("items"), + property_name: Ident::from("items"), first: false, predicate: QueryPredicate::Type(OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("ItemComponent"), source_span: None }, + ReadVarExpr { name: Ident::from("ItemComponent"), source_span: None }, &allocator, ))), descendants: true, @@ -1068,10 +1068,10 @@ mod tests { }; let query2 = R3QueryMetadata { - property_name: Atom::from("headers"), + property_name: Ident::from("headers"), first: true, predicate: QueryPredicate::Type(OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("HeaderComponent"), source_span: None }, + ReadVarExpr { name: Ident::from("HeaderComponent"), source_span: None }, &allocator, ))), descendants: false, @@ -1118,10 +1118,10 @@ mod tests { // Create a signal query with a string selector let mut selectors = Vec::new_in(&allocator); - selectors.push(Atom::from("myRef")); + selectors.push(Ident::from("myRef")); let query = R3QueryMetadata { - property_name: Atom::from("refQuery"), + property_name: Ident::from("refQuery"), first: true, predicate: QueryPredicate::Selectors(selectors), descendants: true, diff --git a/crates/oxc_angular_compiler/src/dts.rs b/crates/oxc_angular_compiler/src/dts.rs index 1201ce729..6a8efac19 100644 --- a/crates/oxc_angular_compiler/src/dts.rs +++ b/crates/oxc_angular_compiler/src/dts.rs @@ -578,7 +578,7 @@ fn generate_input_map_type(inputs: &[R3InputMetadata]) -> String { /// Generate the output map type. /// /// Produces: `{ "clicked": "clicked"; "valueChanged": "onChange"; }` -fn generate_output_map_type(outputs: &[(oxc_span::Atom, oxc_span::Atom)]) -> String { +fn generate_output_map_type(outputs: &[(oxc_span::Ident, oxc_span::Ident)]) -> String { if outputs.is_empty() { return "{}".to_string(); } @@ -762,7 +762,7 @@ mod tests { #[test] fn test_generate_output_map_type_empty() { - let outputs: Vec<(oxc_span::Atom, oxc_span::Atom)> = vec![]; + let outputs: Vec<(oxc_span::Ident, oxc_span::Ident)> = vec![]; assert_eq!(generate_output_map_type(&outputs), "{}"); } } diff --git a/crates/oxc_angular_compiler/src/factory/compiler.rs b/crates/oxc_angular_compiler/src/factory/compiler.rs index 331697854..59acce762 100644 --- a/crates/oxc_angular_compiler/src/factory/compiler.rs +++ b/crates/oxc_angular_compiler/src/factory/compiler.rs @@ -33,7 +33,7 @@ //! ``` use oxc_allocator::{Allocator, Box, FromIn, Vec}; -use oxc_span::Atom; +use oxc_span::Ident; use super::metadata::{ FactoryTarget, R3DependencyMetadata, R3FactoryDelegateType, R3FactoryDeps, R3FactoryMetadata, @@ -104,7 +104,7 @@ pub fn compile_factory_function<'a>( factory_name: &'a str, ) -> FactoryCompileResult<'a> { let base = meta.base(); - let factory_type_param = Atom::from("__ngFactoryType__"); + let factory_type_param = Ident::from("__ngFactoryType__"); // The type to instantiate via constructor invocation. If there is no delegated factory, // meaning this type is always created by constructor invocation, then this is the @@ -261,7 +261,7 @@ pub fn compile_factory_function<'a>( let factory_fn = OutputExpression::Function(Box::new_in( FunctionExpr { - name: Some(Atom::from(factory_name)), + name: Some(Ident::from(factory_name)), params, statements: body, source_span: None, @@ -290,11 +290,11 @@ pub fn compile_factory_function<'a>( fn make_conditional_factory<'a>( allocator: &'a Allocator, body: &mut Vec<'a, OutputStatement<'a>>, - factory_type_param: &Atom<'a>, + factory_type_param: &Ident<'a>, ctor_expr: Option>, non_ctor_expr: OutputExpression<'a>, ) -> OutputExpression<'a> { - let conditional_factory_var = Atom::from("__ngConditionalFactory__"); + let conditional_factory_var = Ident::from("__ngConditionalFactory__"); // let __ngConditionalFactory__ = null; body.push(OutputStatement::DeclareVar(Box::new_in( @@ -415,8 +415,8 @@ fn compile_inherited_factory<'a>( ) -> FactoryCompileResult<'a> { // Create base factory variable name: ɵMyClass_BaseFactory let base_factory_var_name = - Atom::from_in(format!("ɵ{}_BaseFactory", base.name).as_str(), allocator); - let factory_type_param = Atom::from("__ngFactoryType__"); + Ident::from_in(format!("ɵ{}_BaseFactory", base.name).as_str(), allocator); + let factory_type_param = Ident::from("__ngFactoryType__"); // Create ɵɵgetInheritedFactory(MyClass) call let get_inherited_factory_call = { @@ -424,12 +424,12 @@ fn compile_inherited_factory<'a>( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(Identifiers::GET_INHERITED_FACTORY), + name: Ident::from(Identifiers::GET_INHERITED_FACTORY), optional: false, source_span: None, }, @@ -530,7 +530,7 @@ fn compile_inherited_factory<'a>( let inner_fn = OutputExpression::Function(Box::new_in( FunctionExpr { - name: Some(Atom::from(factory_name)), + name: Some(Ident::from(factory_name)), params: inner_params, statements: inner_body, source_span: None, @@ -670,12 +670,12 @@ fn create_import_call<'a>( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(name), + name: Ident::from(name), optional: false, source_span: None, }, @@ -722,12 +722,12 @@ mod tests { fn test_compile_simple_factory() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("TestClass"), source_span: None }, + ReadVarExpr { name: Ident::from("TestClass"), source_span: None }, &allocator, )); let meta = R3FactoryMetadata::Constructor(R3ConstructorFactoryMetadata { - name: Atom::from("TestClass"), + name: Ident::from("TestClass"), type_expr: type_expr.clone_in(&allocator), type_decl: type_expr, type_argument_count: 0, @@ -747,12 +747,12 @@ mod tests { fn test_compile_factory_with_deps() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("MyPipe"), source_span: None }, + ReadVarExpr { name: Ident::from("MyPipe"), source_span: None }, &allocator, )); let dep_token = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("SomeService"), source_span: None }, + ReadVarExpr { name: Ident::from("SomeService"), source_span: None }, &allocator, )); @@ -760,7 +760,7 @@ mod tests { deps.push(R3DependencyMetadata::simple(dep_token)); let meta = R3FactoryMetadata::Constructor(R3ConstructorFactoryMetadata { - name: Atom::from("MyPipe"), + name: Ident::from("MyPipe"), type_expr: type_expr.clone_in(&allocator), type_decl: type_expr, type_argument_count: 0, @@ -780,12 +780,12 @@ mod tests { fn test_compile_invalid_deps_factory() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("BrokenClass"), source_span: None }, + ReadVarExpr { name: Ident::from("BrokenClass"), source_span: None }, &allocator, )); let meta = R3FactoryMetadata::Constructor(R3ConstructorFactoryMetadata { - name: Atom::from("BrokenClass"), + name: Ident::from("BrokenClass"), type_expr: type_expr.clone_in(&allocator), type_decl: type_expr, type_argument_count: 0, @@ -804,13 +804,13 @@ mod tests { fn test_compile_inherited_factory() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("ChildClass"), source_span: None }, + ReadVarExpr { name: Ident::from("ChildClass"), source_span: None }, &allocator, )); // R3FactoryDeps::None indicates no constructor, use inherited factory let meta = R3FactoryMetadata::Constructor(R3ConstructorFactoryMetadata { - name: Atom::from("ChildClass"), + name: Ident::from("ChildClass"), type_expr: type_expr.clone_in(&allocator), type_decl: type_expr, type_argument_count: 0, diff --git a/crates/oxc_angular_compiler/src/factory/metadata.rs b/crates/oxc_angular_compiler/src/factory/metadata.rs index 1238e2a1f..daecd815e 100644 --- a/crates/oxc_angular_compiler/src/factory/metadata.rs +++ b/crates/oxc_angular_compiler/src/factory/metadata.rs @@ -3,7 +3,7 @@ //! Ported from Angular's `render3/r3_factory.ts`. use oxc_allocator::Vec; -use oxc_span::Atom; +use oxc_span::Ident; use crate::output::ast::OutputExpression; @@ -98,7 +98,7 @@ pub enum R3FactoryDeps<'a> { #[derive(Debug)] pub struct R3ConstructorFactoryMetadata<'a> { /// String name of the type being generated (used to name the factory function). - pub name: Atom<'a>, + pub name: Ident<'a>, /// An expression representing the interface type being constructed. pub type_expr: OutputExpression<'a>, @@ -186,7 +186,7 @@ mod tests { fn test_dependency_metadata() { let allocator = Allocator::default(); let token = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("TestService"), source_span: None }, + ReadVarExpr { name: Ident::from("TestService"), source_span: None }, &allocator, )); @@ -202,7 +202,7 @@ mod tests { fn test_optional_dependency() { let allocator = Allocator::default(); let token = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("OptionalService"), source_span: None }, + ReadVarExpr { name: Ident::from("OptionalService"), source_span: None }, &allocator, )); diff --git a/crates/oxc_angular_compiler/src/hmr/dependencies.rs b/crates/oxc_angular_compiler/src/hmr/dependencies.rs index 9dd6280e8..6b297257f 100644 --- a/crates/oxc_angular_compiler/src/hmr/dependencies.rs +++ b/crates/oxc_angular_compiler/src/hmr/dependencies.rs @@ -9,7 +9,7 @@ use std::collections::HashSet; use oxc_allocator::Box; -use oxc_span::Atom; +use oxc_span::Ident; use crate::output::ast::{ ExternalExpr, OutputExpression, OutputStatement, ReadVarExpr, RecursiveOutputAstVisitor, @@ -29,16 +29,16 @@ use crate::output::ast::{ #[derive(Debug, Clone)] pub struct HmrNamespaceDependency<'a> { /// Module name of the import (e.g., `@angular/core`). - pub module_name: Atom<'a>, + pub module_name: Ident<'a>, /// Name under which to refer to the namespace inside HMR-related code. /// Must be a valid JS identifier (e.g., `i0`). - pub assigned_name: Atom<'a>, + pub assigned_name: Ident<'a>, } impl<'a> HmrNamespaceDependency<'a> { /// Create a new namespace dependency. - pub fn new(module_name: Atom<'a>, assigned_name: Atom<'a>) -> Self { + pub fn new(module_name: Ident<'a>, assigned_name: Ident<'a>) -> Self { Self { module_name, assigned_name } } } @@ -57,7 +57,7 @@ impl<'a> HmrNamespaceDependency<'a> { #[derive(Debug)] pub struct HmrLocalDependency<'a> { /// Name of the local symbol. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Runtime representation of the local (the expression to pass as argument). pub runtime_representation: OutputExpression<'a>, @@ -65,7 +65,7 @@ pub struct HmrLocalDependency<'a> { impl<'a> HmrLocalDependency<'a> { /// Create a new local dependency. - pub fn new(name: Atom<'a>, runtime_representation: OutputExpression<'a>) -> Self { + pub fn new(name: Ident<'a>, runtime_representation: OutputExpression<'a>) -> Self { Self { name, runtime_representation } } } @@ -83,10 +83,10 @@ pub struct HmrMetadata<'a> { pub component_type: OutputExpression<'a>, /// Name of the component class. - pub class_name: Atom<'a>, + pub class_name: Ident<'a>, /// File path of the component class. - pub file_path: Atom<'a>, + pub file_path: Ident<'a>, /// Namespace dependencies (e.g., `import * as i0 from '@angular/core'`). /// @@ -105,8 +105,8 @@ impl<'a> HmrMetadata<'a> { /// Create new HMR metadata. pub fn new( component_type: OutputExpression<'a>, - class_name: Atom<'a>, - file_path: Atom<'a>, + class_name: Ident<'a>, + file_path: Ident<'a>, ) -> Self { Self { component_type, @@ -118,14 +118,14 @@ impl<'a> HmrMetadata<'a> { } /// Add a namespace dependency. - pub fn add_namespace_dependency(&mut self, module_name: Atom<'a>, assigned_name: Atom<'a>) { + pub fn add_namespace_dependency(&mut self, module_name: Ident<'a>, assigned_name: Ident<'a>) { self.namespace_dependencies.push(HmrNamespaceDependency::new(module_name, assigned_name)); } /// Add a local dependency. pub fn add_local_dependency( &mut self, - name: Atom<'a>, + name: Ident<'a>, runtime_representation: OutputExpression<'a>, ) { self.local_dependencies.push(HmrLocalDependency::new(name, runtime_representation)); @@ -243,7 +243,7 @@ pub struct ExtractedHmrDependencies<'a> { #[derive(Debug)] pub struct LocalDependency<'a> { /// Name of the local symbol. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Runtime representation (the expression to pass as argument). pub runtime_representation: OutputExpression<'a>, @@ -310,8 +310,8 @@ pub fn extract_compiled_dependencies<'a>( .get_namespace_dependencies() .into_iter() .map(|(module_name, assigned_name)| HmrNamespaceDependency { - module_name: Atom::from(allocator.alloc_str(module_name)), - assigned_name: Atom::from(allocator.alloc_str(&assigned_name)), + module_name: Ident::from(allocator.alloc_str(module_name)), + assigned_name: Ident::from(allocator.alloc_str(&assigned_name)), }) .collect(); @@ -322,10 +322,10 @@ pub fn extract_compiled_dependencies<'a>( .map(|name| { // Create variable reference as runtime representation let runtime_representation = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from(allocator.alloc_str(name)), source_span: None }, + ReadVarExpr { name: Ident::from(allocator.alloc_str(name)), source_span: None }, allocator, )); - LocalDependency { name: Atom::from(allocator.alloc_str(name)), runtime_representation } + LocalDependency { name: Ident::from(allocator.alloc_str(name)), runtime_representation } }) .collect(); @@ -498,7 +498,7 @@ mod tests { // Create a variable read expression let var_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("myVar"), source_span: None }, + ReadVarExpr { name: Ident::from("myVar"), source_span: None }, &allocator, )); @@ -516,8 +516,8 @@ mod tests { let external_expr = OutputExpression::External(Box::new_in( ExternalExpr { value: ExternalReference { - module_name: Some(Atom::from("@angular/core")), - name: Some(Atom::from("Component")), + module_name: Some(Ident::from("@angular/core")), + name: Some(Ident::from("Component")), }, source_span: None, }, @@ -540,8 +540,8 @@ mod tests { let expr1 = OutputExpression::External(Box::new_in( ExternalExpr { value: ExternalReference { - module_name: Some(Atom::from("@angular/core")), - name: Some(Atom::from("Component")), + module_name: Some(Ident::from("@angular/core")), + name: Some(Ident::from("Component")), }, source_span: None, }, @@ -551,8 +551,8 @@ mod tests { let expr2 = OutputExpression::External(Box::new_in( ExternalExpr { value: ExternalReference { - module_name: Some(Atom::from("@angular/core")), - name: Some(Atom::from("Injectable")), + module_name: Some(Ident::from("@angular/core")), + name: Some(Ident::from("Injectable")), }, source_span: None, }, @@ -575,8 +575,8 @@ mod tests { let expr1 = OutputExpression::External(Box::new_in( ExternalExpr { value: ExternalReference { - module_name: Some(Atom::from("@angular/core")), - name: Some(Atom::from("Component")), + module_name: Some(Ident::from("@angular/core")), + name: Some(Ident::from("Component")), }, source_span: None, }, @@ -586,8 +586,8 @@ mod tests { let expr2 = OutputExpression::External(Box::new_in( ExternalExpr { value: ExternalReference { - module_name: Some(Atom::from("./my-dep")), - name: Some(Atom::from("MyDep")), + module_name: Some(Ident::from("./my-dep")), + name: Some(Ident::from("MyDep")), }, source_span: None, }, @@ -612,7 +612,7 @@ mod tests { // Add some variable reads for name in ["MyService", "localVar", "AppComponent", "helperFn"] { let expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from(name), source_span: None }, + ReadVarExpr { name: Ident::from(name), source_span: None }, &allocator, )); collector.visit_expression(&expr); @@ -643,8 +643,8 @@ mod tests { let def_expr = OutputExpression::External(Box::new_in( ExternalExpr { value: ExternalReference { - module_name: Some(Atom::from("@angular/core")), - name: Some(Atom::from("ɵɵdefineComponent")), + module_name: Some(Ident::from("@angular/core")), + name: Some(Ident::from("ɵɵdefineComponent")), }, source_span: None, }, diff --git a/crates/oxc_angular_compiler/src/hmr/initializer.rs b/crates/oxc_angular_compiler/src/hmr/initializer.rs index 5142645de..b90d9b6d5 100644 --- a/crates/oxc_angular_compiler/src/hmr/initializer.rs +++ b/crates/oxc_angular_compiler/src/hmr/initializer.rs @@ -6,7 +6,7 @@ //! Ported from Angular's `packages/compiler/src/render3/r3_hmr_compiler.ts`. use oxc_allocator::{Allocator, Box, Vec}; -use oxc_span::Atom; +use oxc_span::Ident; use super::dependencies::HmrMetadata; use crate::output::ast::{ @@ -75,7 +75,7 @@ pub fn compile_hmr_initializer<'a>( // (m) => m.default && ɵɵreplaceMetadata(...) let replace_callback = OutputExpression::ArrowFunction(Box::new_in( ArrowFunctionExpr { - params: Vec::from_iter_in([FnParam { name: Atom::from(module_name) }], allocator), + params: Vec::from_iter_in([FnParam { name: Ident::from(module_name) }], allocator), body: ArrowFunctionBody::Expression(Box::new_in( binary_op(allocator, BinaryOperator::And, default_read, replace_call), allocator, @@ -104,7 +104,7 @@ pub fn compile_hmr_initializer<'a>( let dynamic_import = OutputExpression::DynamicImport(Box::new_in( DynamicImportExpr { url: DynamicImportUrl::Expression(Box::new_in(url, allocator)), - url_comment: Some(Atom::from("@vite-ignore")), + url_comment: Some(Ident::from("@vite-ignore")), source_span: None, }, allocator, @@ -116,8 +116,8 @@ pub fn compile_hmr_initializer<'a>( // function Cmp_HmrLoad(t) { import(...).then(...); } let import_callback = OutputStatement::DeclareFunction(Box::new_in( DeclareFunctionStmt { - name: Atom::from(allocator.alloc_str(&import_callback_name)), - params: Vec::from_iter_in([FnParam { name: Atom::from(timestamp_name) }], allocator), + name: Ident::from(allocator.alloc_str(&import_callback_name)), + params: Vec::from_iter_in([FnParam { name: Ident::from(timestamp_name) }], allocator), statements: Vec::from_iter_in([expr_stmt(allocator, import_then_call)], allocator), modifiers: StmtModifier::FINAL, source_span: None, @@ -128,7 +128,7 @@ pub fn compile_hmr_initializer<'a>( // (d) => d.id === id && Cmp_HmrLoad(d.timestamp) let update_callback = OutputExpression::ArrowFunction(Box::new_in( ArrowFunctionExpr { - params: Vec::from_iter_in([FnParam { name: Atom::from(data_name) }], allocator), + params: Vec::from_iter_in([FnParam { name: Ident::from(data_name) }], allocator), body: ArrowFunctionBody::Expression(Box::new_in( binary_op( allocator, @@ -178,7 +178,7 @@ pub fn compile_hmr_initializer<'a>( // Handles the angular:invalidate event sent when HMR fails let invalidate_callback = OutputExpression::ArrowFunction(Box::new_in( ArrowFunctionExpr { - params: Vec::from_iter_in([FnParam { name: Atom::from(data_name) }], allocator), + params: Vec::from_iter_in([FnParam { name: Ident::from(data_name) }], allocator), body: ArrowFunctionBody::Expression(Box::new_in( binary_op( allocator, @@ -290,7 +290,7 @@ pub fn compile_hmr_initializer<'a>( #[derive(Debug)] pub struct HmrDefinition<'a> { /// Name of the field (e.g., "ɵcmp", "ɵfac"). - pub name: Atom<'a>, + pub name: Ident<'a>, /// Initializer expression. pub initializer: Option>, /// Additional statements after the field assignment. @@ -318,7 +318,7 @@ pub fn compile_hmr_update_callback<'a>( // Build function parameters: [className, ɵɵnamespaces, ...locals] let mut params: Vec<'a, FnParam<'a>> = Vec::new_in(allocator); params.push(FnParam { name: meta.class_name.clone() }); - params.push(FnParam { name: Atom::from(namespaces_param) }); + params.push(FnParam { name: Ident::from(namespaces_param) }); for local in &meta.local_dependencies { params.push(FnParam { name: local.name.clone() }); } @@ -372,7 +372,7 @@ pub fn compile_hmr_update_callback<'a>( let fn_name = format!("{}_UpdateMetadata", meta.class_name); OutputStatement::DeclareFunction(Box::new_in( DeclareFunctionStmt { - name: Atom::from(allocator.alloc_str(&fn_name)), + name: Ident::from(allocator.alloc_str(&fn_name)), params, statements: body, modifiers: StmtModifier::FINAL, @@ -389,7 +389,7 @@ pub fn compile_hmr_update_callback<'a>( /// Create a read variable expression. fn read_var<'a>(allocator: &'a Allocator, name: &str) -> OutputExpression<'a> { OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from(allocator.alloc_str(name)), source_span: None }, + ReadVarExpr { name: Ident::from(allocator.alloc_str(name)), source_span: None }, allocator, )) } @@ -403,7 +403,7 @@ fn read_prop<'a>( OutputExpression::ReadProp(Box::new_in( ReadPropExpr { receiver: Box::new_in(receiver, allocator), - name: Atom::from(allocator.alloc_str(name)), + name: Ident::from(allocator.alloc_str(name)), optional: false, source_span: None, }, @@ -433,7 +433,7 @@ fn invoke_fn<'a>( fn literal_str<'a>(allocator: &'a Allocator, value: &str) -> OutputExpression<'a> { OutputExpression::Literal(Box::new_in( LiteralExpr { - value: LiteralValue::String(Atom::from(allocator.alloc_str(value))), + value: LiteralValue::String(Ident::from(allocator.alloc_str(value))), source_span: None, }, allocator, @@ -487,7 +487,7 @@ fn var_decl<'a>( let modifiers = if is_final { StmtModifier::FINAL } else { StmtModifier::NONE }; OutputStatement::DeclareVar(Box::new_in( DeclareVarStmt { - name: Atom::from(allocator.alloc_str(name)), + name: Ident::from(allocator.alloc_str(name)), value: Some(value), modifiers, source_span: None, diff --git a/crates/oxc_angular_compiler/src/i18n/parser.rs b/crates/oxc_angular_compiler/src/i18n/parser.rs index 67bd3d334..af1a742fb 100644 --- a/crates/oxc_angular_compiler/src/i18n/parser.rs +++ b/crates/oxc_angular_compiler/src/i18n/parser.rs @@ -834,7 +834,7 @@ mod tests { use crate::ast::html::HtmlText; use crate::util::ParseSourceFile; use oxc_allocator::{Allocator, Box, Vec as AllocVec}; - use oxc_span::Atom; + use oxc_span::Ident; use std::sync::Arc; #[test] @@ -858,7 +858,7 @@ mod tests { let factory = create_i18n_message_factory(false, false); let text = HtmlText { - value: Atom::from("Hello {{name}}!"), + value: Ident::from("Hello {{name}}!"), span: Span::default(), full_start: None, tokens: AllocVec::new_in(&allocator), @@ -889,7 +889,7 @@ mod tests { let factory = create_i18n_message_factory(false, false); let text = HtmlText { - value: Atom::from("Hello World"), + value: Ident::from("Hello World"), span: Span::default(), full_start: None, tokens: AllocVec::new_in(&allocator), @@ -910,7 +910,7 @@ mod tests { let factory = create_i18n_message_factory(false, false); let text = HtmlText { - value: Atom::from("{{greeting}} {{name}}!"), + value: Ident::from("{{greeting}} {{name}}!"), span: Span::default(), full_start: None, tokens: AllocVec::new_in(&allocator), diff --git a/crates/oxc_angular_compiler/src/injectable/compiler.rs b/crates/oxc_angular_compiler/src/injectable/compiler.rs index 259d3fb0f..2b8c9c20d 100644 --- a/crates/oxc_angular_compiler/src/injectable/compiler.rs +++ b/crates/oxc_angular_compiler/src/injectable/compiler.rs @@ -12,7 +12,7 @@ //! ``` use oxc_allocator::{Allocator, Box, Vec}; -use oxc_span::Atom; +use oxc_span::Ident; use super::metadata::{InjectableProvider, ProvidedIn, R3InjectableMetadata}; use crate::factory::{ @@ -205,12 +205,12 @@ fn create_inject_call<'a>( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(Identifiers::RESOLVE_FORWARD_REF), + name: Ident::from(Identifiers::RESOLVE_FORWARD_REF), optional: false, source_span: None, }, @@ -239,12 +239,12 @@ fn create_inject_call<'a>( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(Identifiers::INJECT), + name: Ident::from(Identifiers::INJECT), optional: false, source_span: None, }, @@ -274,7 +274,7 @@ fn create_factory_delegation<'a>( OutputExpression::ReadProp(Box::new_in( ReadPropExpr { receiver: Box::new_in(type_expr.clone_in(allocator), allocator), - name: Atom::from("ɵfac"), + name: Ident::from("ɵfac"), optional: false, source_span: None, }, @@ -287,7 +287,7 @@ fn create_forward_ref_factory<'a>( allocator: &'a Allocator, type_expr: &OutputExpression<'a>, ) -> OutputExpression<'a> { - let param_name = Atom::from("t"); + let param_name = Ident::from("t"); let mut params = Vec::new_in(allocator); params.push(FnParam { name: param_name.clone() }); @@ -296,12 +296,12 @@ fn create_forward_ref_factory<'a>( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(Identifiers::RESOLVE_FORWARD_REF), + name: Ident::from(Identifiers::RESOLVE_FORWARD_REF), optional: false, source_span: None, }, @@ -326,7 +326,7 @@ fn create_forward_ref_factory<'a>( let fac_access = OutputExpression::ReadProp(Box::new_in( ReadPropExpr { receiver: Box::new_in(resolved_type, allocator), - name: Atom::from("ɵfac"), + name: Ident::from("ɵfac"), optional: false, source_span: None, }, @@ -405,14 +405,14 @@ fn build_definition_map<'a>( // token: MyService entries.push(LiteralMapEntry { - key: Atom::from("token"), + key: Ident::from("token"), value: metadata.r#type.clone_in(allocator), quoted: false, }); // factory: entries.push(LiteralMapEntry { - key: Atom::from("factory"), + key: Ident::from("factory"), value: factory_expr, quoted: false, }); @@ -421,10 +421,10 @@ fn build_definition_map<'a>( match &metadata.provided_in { ProvidedIn::Root => { entries.push(LiteralMapEntry { - key: Atom::from("providedIn"), + key: Ident::from("providedIn"), value: OutputExpression::Literal(Box::new_in( LiteralExpr { - value: LiteralValue::String(Atom::from("root")), + value: LiteralValue::String(Ident::from("root")), source_span: None, }, allocator, @@ -434,10 +434,10 @@ fn build_definition_map<'a>( } ProvidedIn::Platform => { entries.push(LiteralMapEntry { - key: Atom::from("providedIn"), + key: Ident::from("providedIn"), value: OutputExpression::Literal(Box::new_in( LiteralExpr { - value: LiteralValue::String(Atom::from("platform")), + value: LiteralValue::String(Ident::from("platform")), source_span: None, }, allocator, @@ -447,10 +447,10 @@ fn build_definition_map<'a>( } ProvidedIn::Any => { entries.push(LiteralMapEntry { - key: Atom::from("providedIn"), + key: Ident::from("providedIn"), value: OutputExpression::Literal(Box::new_in( LiteralExpr { - value: LiteralValue::String(Atom::from("any")), + value: LiteralValue::String(Ident::from("any")), source_span: None, }, allocator, @@ -460,7 +460,7 @@ fn build_definition_map<'a>( } ProvidedIn::Module(module_expr) => { entries.push(LiteralMapEntry { - key: Atom::from("providedIn"), + key: Ident::from("providedIn"), value: module_expr.clone_in(allocator), quoted: false, }); @@ -483,12 +483,12 @@ fn create_define_injectable_call<'a>( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(Identifiers::DEFINE_INJECTABLE), + name: Ident::from(Identifiers::DEFINE_INJECTABLE), optional: false, source_span: None, }, @@ -527,12 +527,12 @@ mod tests { fn test_compile_simple_injectable() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("MyService"), source_span: None }, + ReadVarExpr { name: Ident::from("MyService"), source_span: None }, &allocator, )); let metadata = R3InjectableMetadataBuilder::new() - .name(Atom::from("MyService")) + .name(Ident::from("MyService")) .r#type(type_expr) .provided_in_root() .build() @@ -552,19 +552,19 @@ mod tests { fn test_compile_injectable_with_use_value() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("CONFIG_TOKEN"), source_span: None }, + ReadVarExpr { name: Ident::from("CONFIG_TOKEN"), source_span: None }, &allocator, )); let value_expr = OutputExpression::Literal(Box::new_in( LiteralExpr { - value: LiteralValue::String(Atom::from("config_value")), + value: LiteralValue::String(Ident::from("config_value")), source_span: None, }, &allocator, )); let metadata = R3InjectableMetadataBuilder::new() - .name(Atom::from("CONFIG_TOKEN")) + .name(Ident::from("CONFIG_TOKEN")) .r#type(type_expr) .use_value(value_expr) .provided_in_root() @@ -584,16 +584,16 @@ mod tests { fn test_compile_injectable_with_use_existing() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("AliasService"), source_span: None }, + ReadVarExpr { name: Ident::from("AliasService"), source_span: None }, &allocator, )); let existing_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("RealService"), source_span: None }, + ReadVarExpr { name: Ident::from("RealService"), source_span: None }, &allocator, )); let metadata = R3InjectableMetadataBuilder::new() - .name(Atom::from("AliasService")) + .name(Ident::from("AliasService")) .r#type(type_expr) .use_existing(existing_expr, false) .provided_in_root() @@ -612,12 +612,12 @@ mod tests { fn test_compile_injectable_no_provided_in() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("LocalService"), source_span: None }, + ReadVarExpr { name: Ident::from("LocalService"), source_span: None }, &allocator, )); let metadata = R3InjectableMetadataBuilder::new() - .name(Atom::from("LocalService")) + .name(Ident::from("LocalService")) .r#type(type_expr) .build() .unwrap(); @@ -648,11 +648,11 @@ mod tests { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("CipherService"), source_span: None }, + ReadVarExpr { name: Ident::from("CipherService"), source_span: None }, &allocator, )); let factory_fn = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("cipherServiceFactory"), source_span: None }, + ReadVarExpr { name: Ident::from("cipherServiceFactory"), source_span: None }, &allocator, )); @@ -660,7 +660,7 @@ mod tests { let mut deps = Vec::new_in(&allocator); deps.push(R3DependencyMetadata { token: Some(OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("LogService"), source_span: None }, + ReadVarExpr { name: Ident::from("LogService"), source_span: None }, &allocator, ))), attribute_name_type: None, @@ -671,7 +671,7 @@ mod tests { }); let metadata = R3InjectableMetadataBuilder::new() - .name(Atom::from("CipherService")) + .name(Ident::from("CipherService")) .r#type(type_expr) .use_factory(factory_fn, Some(deps)) .provided_in_root() @@ -705,11 +705,11 @@ mod tests { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("BaseService"), source_span: None }, + ReadVarExpr { name: Ident::from("BaseService"), source_span: None }, &allocator, )); let class_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("ConcreteService"), source_span: None }, + ReadVarExpr { name: Ident::from("ConcreteService"), source_span: None }, &allocator, )); @@ -717,7 +717,7 @@ mod tests { let mut deps = Vec::new_in(&allocator); deps.push(R3DependencyMetadata { token: Some(OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("DepService"), source_span: None }, + ReadVarExpr { name: Ident::from("DepService"), source_span: None }, &allocator, ))), attribute_name_type: None, @@ -728,7 +728,7 @@ mod tests { }); let metadata = R3InjectableMetadataBuilder::new() - .name(Atom::from("BaseService")) + .name(Ident::from("BaseService")) .r#type(type_expr) .use_class(class_expr, false, Some(deps)) .provided_in_root() diff --git a/crates/oxc_angular_compiler/src/injectable/decorator.rs b/crates/oxc_angular_compiler/src/injectable/decorator.rs index 654602383..4f478c17d 100644 --- a/crates/oxc_angular_compiler/src/injectable/decorator.rs +++ b/crates/oxc_angular_compiler/src/injectable/decorator.rs @@ -8,7 +8,7 @@ use oxc_ast::ast::{ Argument, ArrayExpressionElement, Class, ClassElement, Decorator, Expression, MethodDefinitionKind, ObjectPropertyKind, PropertyKey, }; -use oxc_span::{Atom, Span}; +use oxc_span::{Ident, Span}; use crate::factory::R3DependencyMetadata; use crate::output::ast::{OutputExpression, ReadVarExpr}; @@ -18,7 +18,7 @@ use crate::output::oxc_converter::convert_oxc_expression; #[derive(Debug)] pub struct InjectableMetadata<'a> { /// The name of the injectable class. - pub class_name: Atom<'a>, + pub class_name: Ident<'a>, /// Span of the class declaration. pub class_span: Span, /// Where this injectable is provided. @@ -218,7 +218,7 @@ pub fn extract_injectable_metadata<'a>( allocator: &'a Allocator, class: &'a Class<'a>, ) -> Option> { - let class_name: Atom<'a> = class.id.as_ref()?.name.clone().into(); + let class_name: Ident<'a> = class.id.as_ref()?.name.clone().into(); let class_span = class.span; // Find the @Injectable decorator @@ -291,10 +291,10 @@ fn is_injectable_decorator(decorator: &Decorator<'_>) -> bool { } } -fn get_property_key_name<'a>(key: &'a PropertyKey<'a>) -> Option> { +fn get_property_key_name<'a>(key: &'a PropertyKey<'a>) -> Option> { match key { PropertyKey::StaticIdentifier(id) => Some(id.name.clone().into()), - PropertyKey::StringLiteral(s) => Some(s.value.clone()), + PropertyKey::StringLiteral(s) => Some(s.value.clone().into()), _ => None, } } @@ -543,7 +543,7 @@ fn extract_param_dependency<'a>( let mut self_ = false; let mut host = false; let mut inject_token: Option> = None; - let mut attribute_name: Option> = None; + let mut attribute_name: Option> = None; for decorator in ¶m.decorators { if let Some(name) = get_decorator_name(&decorator.expression) { @@ -564,7 +564,7 @@ fn extract_param_dependency<'a>( // @Attribute('attrName') - extract the attribute name if let Expression::CallExpression(call) = &decorator.expression { if let Some(Argument::StringLiteral(s)) = call.arguments.first() { - attribute_name = Some(s.value.clone()); + attribute_name = Some(s.value.clone().into()); } } } @@ -600,7 +600,7 @@ fn extract_param_dependency<'a>( } /// Get the name of a decorator from its expression. -fn get_decorator_name<'a>(expr: &'a Expression<'a>) -> Option> { +fn get_decorator_name<'a>(expr: &'a Expression<'a>) -> Option> { match expr { // @Optional Expression::Identifier(id) => Some(id.name.clone().into()), @@ -628,7 +628,7 @@ fn extract_param_token<'a>( // Handle TSTypeReference: SomeClass, SomeModule, etc. if let oxc_ast::ast::TSType::TSTypeReference(type_ref) = ts_type { // Get the type name - let type_name: Atom<'a> = match &type_ref.type_name { + let type_name: Ident<'a> = match &type_ref.type_name { oxc_ast::ast::TSTypeName::IdentifierReference(id) => id.name.clone().into(), oxc_ast::ast::TSTypeName::QualifiedName(_) | oxc_ast::ast::TSTypeName::ThisExpression(_) => { diff --git a/crates/oxc_angular_compiler/src/injectable/definition.rs b/crates/oxc_angular_compiler/src/injectable/definition.rs index be5036450..2805bac60 100644 --- a/crates/oxc_angular_compiler/src/injectable/definition.rs +++ b/crates/oxc_angular_compiler/src/injectable/definition.rs @@ -205,18 +205,18 @@ mod tests { use crate::output::ast::ReadVarExpr; use crate::output::emitter::JsEmitter; use oxc_allocator::Box; - use oxc_span::Atom; + use oxc_span::Ident; #[test] fn test_generate_simple_injectable_definition() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("MyService"), source_span: None }, + ReadVarExpr { name: Ident::from("MyService"), source_span: None }, &allocator, )); let metadata = R3InjectableMetadataBuilder::new() - .name(Atom::from("MyService")) + .name(Ident::from("MyService")) .r#type(type_expr) .provided_in_root() .build() @@ -243,12 +243,12 @@ mod tests { fn test_generate_injectable_definition_no_provided_in() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("LocalService"), source_span: None }, + ReadVarExpr { name: Ident::from("LocalService"), source_span: None }, &allocator, )); let metadata = R3InjectableMetadataBuilder::new() - .name(Atom::from("LocalService")) + .name(Ident::from("LocalService")) .r#type(type_expr) .build() .unwrap(); @@ -268,12 +268,12 @@ mod tests { fn test_generate_injectable_definition_with_platform() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("PlatformService"), source_span: None }, + ReadVarExpr { name: Ident::from("PlatformService"), source_span: None }, &allocator, )); let metadata = R3InjectableMetadataBuilder::new() - .name(Atom::from("PlatformService")) + .name(Ident::from("PlatformService")) .r#type(type_expr) .provided_in_platform() .build() @@ -291,12 +291,12 @@ mod tests { fn test_generate_injectable_definition_with_any() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("AnyService"), source_span: None }, + ReadVarExpr { name: Ident::from("AnyService"), source_span: None }, &allocator, )); let metadata = R3InjectableMetadataBuilder::new() - .name(Atom::from("AnyService")) + .name(Ident::from("AnyService")) .r#type(type_expr) .provided_in_any() .build() @@ -317,12 +317,12 @@ mod tests { // This test verifies the definition is correctly structured for tree-shaking. let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("TreeShakableService"), source_span: None }, + ReadVarExpr { name: Ident::from("TreeShakableService"), source_span: None }, &allocator, )); let metadata = R3InjectableMetadataBuilder::new() - .name(Atom::from("TreeShakableService")) + .name(Ident::from("TreeShakableService")) .r#type(type_expr) .provided_in_root() .build() diff --git a/crates/oxc_angular_compiler/src/injectable/metadata.rs b/crates/oxc_angular_compiler/src/injectable/metadata.rs index e0eb81c1e..79936adff 100644 --- a/crates/oxc_angular_compiler/src/injectable/metadata.rs +++ b/crates/oxc_angular_compiler/src/injectable/metadata.rs @@ -3,7 +3,7 @@ //! Ported from Angular's `injectable_compiler_2.ts`. use oxc_allocator::Vec; -use oxc_span::Atom; +use oxc_span::Ident; use crate::factory::R3DependencyMetadata; use crate::output::ast::OutputExpression; @@ -74,7 +74,7 @@ pub enum ProvidedIn<'a> { #[derive(Debug)] pub struct R3InjectableMetadata<'a> { /// Name of the injectable type. - pub name: Atom<'a>, + pub name: Ident<'a>, /// An expression representing a reference to the injectable class. pub r#type: OutputExpression<'a>, @@ -103,7 +103,7 @@ impl<'a> R3InjectableMetadata<'a> { /// Builder for R3InjectableMetadata. pub struct R3InjectableMetadataBuilder<'a> { - name: Option>, + name: Option>, r#type: Option>, type_argument_count: u32, provided_in: ProvidedIn<'a>, @@ -125,7 +125,7 @@ impl<'a> R3InjectableMetadataBuilder<'a> { } /// Set the injectable name. - pub fn name(mut self, name: Atom<'a>) -> Self { + pub fn name(mut self, name: Ident<'a>) -> Self { self.name = Some(name); self } diff --git a/crates/oxc_angular_compiler/src/injector/compiler.rs b/crates/oxc_angular_compiler/src/injector/compiler.rs index 85bc6e7d1..1fdfaae6b 100644 --- a/crates/oxc_angular_compiler/src/injector/compiler.rs +++ b/crates/oxc_angular_compiler/src/injector/compiler.rs @@ -11,7 +11,7 @@ //! ``` use oxc_allocator::{Allocator, Box, Vec}; -use oxc_span::Atom; +use oxc_span::Ident; use super::metadata::R3InjectorMetadata; use crate::output::ast::{ @@ -64,7 +64,7 @@ fn build_definition_map<'a>( // providers: [...] (only if present) if let Some(providers) = &metadata.providers { entries.push(LiteralMapEntry { - key: Atom::from("providers"), + key: Ident::from("providers"), value: providers.clone_in(allocator), quoted: false, }); @@ -87,7 +87,7 @@ fn build_definition_map<'a>( }; entries.push(LiteralMapEntry { - key: Atom::from("imports"), + key: Ident::from("imports"), value: imports_value, quoted: false, }); @@ -106,12 +106,12 @@ fn create_define_injector_call<'a>( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(Identifiers::DEFINE_INJECTOR), + name: Ident::from(Identifiers::DEFINE_INJECTOR), optional: false, source_span: None, }, @@ -150,12 +150,12 @@ mod tests { fn test_compile_simple_injector() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("MyModule"), source_span: None }, + ReadVarExpr { name: Ident::from("MyModule"), source_span: None }, &allocator, )); let metadata = R3InjectorMetadataBuilder::new(&allocator) - .name(Atom::from("MyModule")) + .name(Ident::from("MyModule")) .r#type(type_expr) .build() .unwrap(); @@ -172,17 +172,17 @@ mod tests { fn test_compile_injector_with_providers() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("ProviderModule"), source_span: None }, + ReadVarExpr { name: Ident::from("ProviderModule"), source_span: None }, &allocator, )); let providers_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("PROVIDERS"), source_span: None }, + ReadVarExpr { name: Ident::from("PROVIDERS"), source_span: None }, &allocator, )); let metadata = R3InjectorMetadataBuilder::new(&allocator) - .name(Atom::from("ProviderModule")) + .name(Ident::from("ProviderModule")) .r#type(type_expr) .providers(providers_expr) .build() @@ -201,21 +201,21 @@ mod tests { fn test_compile_injector_with_imports() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("ImportModule"), source_span: None }, + ReadVarExpr { name: Ident::from("ImportModule"), source_span: None }, &allocator, )); let import1 = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("CommonModule"), source_span: None }, + ReadVarExpr { name: Ident::from("CommonModule"), source_span: None }, &allocator, )); let import2 = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("FormsModule"), source_span: None }, + ReadVarExpr { name: Ident::from("FormsModule"), source_span: None }, &allocator, )); let metadata = R3InjectorMetadataBuilder::new(&allocator) - .name(Atom::from("ImportModule")) + .name(Ident::from("ImportModule")) .r#type(type_expr) .add_import(import1) .add_import(import2) @@ -236,12 +236,12 @@ mod tests { fn test_compile_injector_empty_statements() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("EmptyModule"), source_span: None }, + ReadVarExpr { name: Ident::from("EmptyModule"), source_span: None }, &allocator, )); let metadata = R3InjectorMetadataBuilder::new(&allocator) - .name(Atom::from("EmptyModule")) + .name(Ident::from("EmptyModule")) .r#type(type_expr) .build() .unwrap(); diff --git a/crates/oxc_angular_compiler/src/injector/metadata.rs b/crates/oxc_angular_compiler/src/injector/metadata.rs index 461252eda..66926f318 100644 --- a/crates/oxc_angular_compiler/src/injector/metadata.rs +++ b/crates/oxc_angular_compiler/src/injector/metadata.rs @@ -3,7 +3,7 @@ //! Ported from Angular's `render3/r3_injector_compiler.ts`. use oxc_allocator::Vec; -use oxc_span::Atom; +use oxc_span::Ident; use crate::output::ast::OutputExpression; @@ -14,7 +14,7 @@ use crate::output::ast::OutputExpression; #[derive(Debug)] pub struct R3InjectorMetadata<'a> { /// Name of the injector type. - pub name: Atom<'a>, + pub name: Ident<'a>, /// An expression representing a reference to the injector class. pub r#type: OutputExpression<'a>, @@ -46,7 +46,7 @@ impl<'a> R3InjectorMetadata<'a> { /// Builder for R3InjectorMetadata. pub struct R3InjectorMetadataBuilder<'a> { - name: Option>, + name: Option>, r#type: Option>, providers: Option>, imports: Vec<'a, OutputExpression<'a>>, @@ -66,7 +66,7 @@ impl<'a> R3InjectorMetadataBuilder<'a> { } /// Set the injector name. - pub fn name(mut self, name: Atom<'a>) -> Self { + pub fn name(mut self, name: Ident<'a>) -> Self { self.name = Some(name); self } diff --git a/crates/oxc_angular_compiler/src/ir/expression.rs b/crates/oxc_angular_compiler/src/ir/expression.rs index b7a6bc106..6f9f06ff9 100644 --- a/crates/oxc_angular_compiler/src/ir/expression.rs +++ b/crates/oxc_angular_compiler/src/ir/expression.rs @@ -6,7 +6,7 @@ //! Ported from Angular's `template/pipeline/ir/src/expression.ts`. use oxc_allocator::{Box, Vec}; -use oxc_span::{Atom, Span}; +use oxc_span::{Ident, Span}; use super::enums::ExpressionKind; use super::ops::{SlotId, XrefId}; @@ -793,7 +793,7 @@ pub struct IrParenthesizedExpr<'a> { #[derive(Debug)] pub struct LexicalReadExpr<'a> { /// Variable name to read. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Source span. pub source_span: Option, } @@ -884,7 +884,7 @@ pub struct ReadVariableExpr<'a> { /// Variable XrefId. pub xref: XrefId, /// Resolved variable name. - pub name: Option>, + pub name: Option>, /// Source span. pub source_span: Option, } @@ -899,7 +899,7 @@ pub struct ResolvedPropertyReadExpr<'a> { /// The resolved receiver expression (e.g., ReadVariable for a loop variable). pub receiver: Box<'a, IrExpression<'a>>, /// Property name to read. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Source span. pub source_span: Option, } @@ -961,7 +961,7 @@ pub struct ResolvedSafePropertyReadExpr<'a> { /// The resolved receiver expression (e.g., ReadVariable for a loop variable). pub receiver: Box<'a, IrExpression<'a>>, /// Property name to read. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Source span. pub source_span: Option, } @@ -985,7 +985,7 @@ pub struct ResolvedTemplateLiteralExpr<'a> { #[derive(Debug, Clone)] pub struct IrTemplateLiteralElement<'a> { /// The text content. - pub text: Atom<'a>, + pub text: Ident<'a>, /// Source span. pub source_span: Option, } @@ -1007,7 +1007,7 @@ pub struct DerivedLiteralArrayExpr<'a> { #[derive(Debug)] pub struct DerivedLiteralMapExpr<'a> { /// Map keys (string keys from the original literal map). - pub keys: Vec<'a, Atom<'a>>, + pub keys: Vec<'a, Ident<'a>>, /// Map values - can be Ast (constants) or PureFunctionParameter (refs). pub values: Vec<'a, IrExpression<'a>>, /// Whether each key is quoted. @@ -1031,7 +1031,7 @@ pub struct IrLiteralArrayExpr<'a> { #[derive(Debug)] pub struct IrLiteralMapExpr<'a> { /// Map keys (string keys from the original literal map). - pub keys: Vec<'a, Atom<'a>>, + pub keys: Vec<'a, Ident<'a>>, /// Map values as IR expressions. pub values: Vec<'a, IrExpression<'a>>, /// Whether each key is quoted. @@ -1072,7 +1072,7 @@ pub struct PipeBindingExpr<'a> { /// Target slot. pub target_slot: SlotHandle, /// Pipe name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Pipe arguments. pub args: Vec<'a, IrExpression<'a>>, /// Variable offset. @@ -1089,7 +1089,7 @@ pub struct PipeBindingVariadicExpr<'a> { /// Target slot. pub target_slot: SlotHandle, /// Pipe name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Arguments as an array expression. pub args: Box<'a, IrExpression<'a>>, /// Number of arguments. @@ -1106,7 +1106,7 @@ pub struct SafePropertyReadExpr<'a> { /// Receiver expression. pub receiver: Box<'a, IrExpression<'a>>, /// Property name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Source span. pub source_span: Option, } @@ -1159,7 +1159,7 @@ pub struct AssignTemporaryExpr<'a> { /// Temporary variable XrefId. pub xref: XrefId, /// Resolved variable name. - pub name: Option>, + pub name: Option>, /// Source span. pub source_span: Option, } @@ -1170,7 +1170,7 @@ pub struct ReadTemporaryExpr<'a> { /// Temporary variable XrefId. pub xref: XrefId, /// Resolved variable name. - pub name: Option>, + pub name: Option>, /// Source span. pub source_span: Option, } @@ -1197,7 +1197,7 @@ pub struct ConditionalCaseExpr<'a> { /// Target slot. pub target_slot: SlotHandle, /// Alias variable name. - pub alias: Option>, + pub alias: Option>, /// Source span. pub source_span: Option, } @@ -1261,13 +1261,13 @@ pub struct StoreLetExpr<'a> { #[derive(Debug)] pub struct Interpolation<'a> { /// Static string parts. - pub strings: Vec<'a, Atom<'a>>, + pub strings: Vec<'a, Ident<'a>>, /// Dynamic expression parts. pub expressions: Vec<'a, IrExpression<'a>>, /// I18n placeholder names for each expression. /// Used by convert_i18n_bindings phase to create I18nExpression ops. /// Empty if not in an i18n context. - pub i18n_placeholders: Vec<'a, Atom<'a>>, + pub i18n_placeholders: Vec<'a, Ident<'a>>, /// Source span. pub source_span: Option, } @@ -1279,7 +1279,7 @@ impl<'a> Interpolation<'a> { } /// Returns the constant string value if this is a pure interpolation. - pub fn const_value(&self) -> Option<&Atom<'a>> { + pub fn const_value(&self) -> Option<&Ident<'a>> { if self.is_const_string() && self.strings.len() == 1 { Some(&self.strings[0]) } else { diff --git a/crates/oxc_angular_compiler/src/ir/ops.rs b/crates/oxc_angular_compiler/src/ir/ops.rs index a672cb6e5..7cd5017f8 100644 --- a/crates/oxc_angular_compiler/src/ir/ops.rs +++ b/crates/oxc_angular_compiler/src/ir/ops.rs @@ -10,7 +10,7 @@ use std::ptr::NonNull; use oxc_allocator::{Box, Vec}; -use oxc_span::{Atom, Span}; +use oxc_span::{Ident, Span}; use super::enums::{ AnimationBindingKind, AnimationKind, BindingKind, DeferOpModifierKind, DeferTriggerKind, @@ -58,20 +58,20 @@ pub enum I18nSlotHandle { #[derive(Debug, Clone, PartialEq, Eq)] pub struct I18nPlaceholder<'a> { /// The placeholder name for the opening tag (e.g., "START_TAG_DIV"). - pub start_name: Atom<'a>, + pub start_name: Ident<'a>, /// The placeholder name for the closing tag (e.g., "CLOSE_TAG_DIV"). /// `None` for self-closing/void elements. - pub close_name: Option>, + pub close_name: Option>, } impl<'a> I18nPlaceholder<'a> { /// Creates a new I18nPlaceholder. - pub fn new(start_name: Atom<'a>, close_name: Option>) -> Self { + pub fn new(start_name: Ident<'a>, close_name: Option>) -> Self { Self { start_name, close_name } } /// Creates a placeholder for a self-closing/void element. - pub fn self_closing(start_name: Atom<'a>) -> Self { + pub fn self_closing(start_name: Ident<'a>) -> Self { Self { start_name, close_name: None } } } @@ -658,13 +658,13 @@ pub struct ElementStartOp<'a> { /// Cross-reference ID. pub xref: XrefId, /// Element tag name. - pub tag: Atom<'a>, + pub tag: Ident<'a>, /// Assigned slot. pub slot: Option, /// Namespace. pub namespace: Namespace, /// Attribute namespace (e.g., "xlink" for SVG). - pub attribute_namespace: Option>, + pub attribute_namespace: Option>, /// Local references attached to this element. pub local_refs: Vec<'a, LocalRef<'a>>, /// Index into the consts array for local refs. @@ -686,13 +686,13 @@ pub struct ElementOp<'a> { /// Cross-reference ID. pub xref: XrefId, /// Element tag name. - pub tag: Atom<'a>, + pub tag: Ident<'a>, /// Assigned slot. pub slot: Option, /// Namespace. pub namespace: Namespace, /// Attribute namespace. - pub attribute_namespace: Option>, + pub attribute_namespace: Option>, /// Local references. pub local_refs: Vec<'a, LocalRef<'a>>, /// Index into the consts array for local refs. @@ -728,15 +728,15 @@ pub struct TemplateOp<'a> { pub slot: Option, /// HTML tag name for this template element. /// Used for content projection matching (e.g., `` vs `
`). - pub tag: Option>, + pub tag: Option>, /// Namespace. pub namespace: Namespace, /// Template kind. pub template_kind: TemplateKind, /// Function name suffix. - pub fn_name_suffix: Option>, + pub fn_name_suffix: Option>, /// Block of the template. - pub block: Option>, + pub block: Option>, /// Decl count for structural directive compatibility. pub decl_count: Option, /// The number of binding variable slots used by this template. @@ -847,9 +847,9 @@ pub struct ConditionalOp<'a> { /// Template kind. pub template_kind: TemplateKind, /// Function name suffix. - pub fn_name_suffix: Atom<'a>, + pub fn_name_suffix: Ident<'a>, /// HTML tag name (for content projection). - pub tag: Option>, + pub tag: Option>, /// The number of declaration slots used by this conditional. /// Set by allocate_slots phase. pub decls: Option, @@ -888,9 +888,9 @@ pub struct ConditionalBranchCreateOp<'a> { /// Template kind. pub template_kind: TemplateKind, /// Function name suffix. - pub fn_name_suffix: Atom<'a>, + pub fn_name_suffix: Ident<'a>, /// HTML tag name (for content projection). - pub tag: Option>, + pub tag: Option>, /// The number of declaration slots used by this branch. /// Set by allocate_slots phase. pub decls: Option, @@ -931,11 +931,11 @@ pub struct TextOp<'a> { /// Assigned slot. pub slot: Option, /// Static text value. - pub initial_value: Atom<'a>, + pub initial_value: Ident<'a>, /// I18n placeholder. - pub i18n_placeholder: Option>, + pub i18n_placeholder: Option>, /// ICU placeholder (for text inside ICU expressions). - pub icu_placeholder: Option>, + pub icu_placeholder: Option>, } /// Declare an event listener. @@ -948,25 +948,25 @@ pub struct ListenerOp<'a> { /// Slot to target. pub target_slot: SlotId, /// Tag name of the element on which this listener is placed. Null for host bindings. - pub tag: Option>, + pub tag: Option>, /// Whether this listener is from a host binding. pub host_listener: bool, /// Event name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Handler expression (the expression to execute on event). pub handler_expression: Option>>, /// Handler operations (legacy, for complex handlers). pub handler_ops: Vec<'a, UpdateOp<'a>>, /// Function name. - pub handler_fn_name: Option>, + pub handler_fn_name: Option>, /// Consume functions. - pub consume_fn_name: Option>, + pub consume_fn_name: Option>, /// Whether this is an animation listener. pub is_animation_listener: bool, /// Animation phase. pub animation_phase: Option, /// Event target (window, document, body). - pub event_target: Option>, + pub event_target: Option>, /// Whether this listener uses $event. pub consumes_dollar_event: bool, } @@ -981,7 +981,7 @@ pub struct PipeOp<'a> { /// Assigned slot. pub slot: Option, /// Pipe name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Number of arguments. pub num_args: u32, } @@ -1033,7 +1033,7 @@ pub struct DeferOp<'a> { /// Corresponds to `ownResolverFn` in Angular TS. pub own_resolver_fn: Option>, /// SSR unique ID. - pub ssr_unique_id: Option>, + pub ssr_unique_id: Option>, /// Defer block flags (e.g., HasHydrateTriggers = 1). /// Corresponds to `flags` in Angular TS's DeferOp. pub flags: Option, @@ -1060,7 +1060,7 @@ pub struct DeferOnOp<'a> { /// -1 means starting from placeholder, 0 means same view as defer owner. pub target_slot_view_steps: Option, /// Target name for local ref targeting. - pub target_name: Option>, + pub target_name: Option>, /// Timer delay. pub delay: Option, /// Viewport options (for viewport trigger). @@ -1101,18 +1101,18 @@ pub struct I18nMessageOp<'a> { pub i18n_block: Option, /// Message placeholder for ICU sub-messages. /// Only set for ICU placeholder messages (extracted from parent). - pub message_placeholder: Option>, + pub message_placeholder: Option>, /// Message ID. - pub message_id: Option>, + pub message_id: Option>, /// Custom message ID. - pub custom_id: Option>, + pub custom_id: Option>, /// Message meaning. - pub meaning: Option>, + pub meaning: Option>, /// Message description. - pub description: Option>, + pub description: Option>, /// The serialized message string for goog.getMsg and $localize. /// Contains the message text with placeholder markers like "{$interpolation}". - pub message_string: Option>, + pub message_string: Option>, /// Whether message needs postprocessing (has params with multiple values). pub needs_postprocessing: bool, /// Sub-messages. @@ -1156,7 +1156,7 @@ pub struct ProjectionOp<'a> { /// I18n placeholder data (start_name and close_name for ng-content). pub i18n_placeholder: Option>, /// Selector attribute. - pub selector: Option>, + pub selector: Option>, /// Fallback template. pub fallback: Option, /// I18n placeholder data for fallback view. @@ -1181,7 +1181,7 @@ pub struct RepeaterCreateOp<'a> { /// Track function. pub track: Box<'a, IrExpression<'a>>, /// Track function name. - pub track_fn_name: Option>, + pub track_fn_name: Option>, /// Some kinds of expressions (e.g. safe reads or nullish coalescing) require additional ops /// in order to work. This list keeps track of those ops, if they're necessary. /// Set by track_fn_optimization phase when the track expression cannot be optimized. @@ -1206,12 +1206,12 @@ pub struct RepeaterCreateOp<'a> { /// Var names for template. pub var_names: RepeaterVarNames<'a>, /// HTML tag name (for content projection). - pub tag: Option>, + pub tag: Option>, /// Const index for attributes (for content projection). /// Set by const_collection phase. pub attributes: Option, /// HTML tag name for empty view (for content projection). - pub empty_tag: Option>, + pub empty_tag: Option>, /// Const index for empty view attributes (for content projection). /// Set by const_collection phase. pub empty_attributes: Option, @@ -1225,20 +1225,20 @@ pub struct RepeaterCreateOp<'a> { #[derive(Debug)] pub struct RepeaterVarNames<'a> { /// Alias for the item ($implicit). - pub item: Option>, + pub item: Option>, /// Alias for $count. - pub count: Option>, + pub count: Option>, /// Aliases for $index (can be multiple, e.g. `let i = $index, j = $index`). /// Angular stores these in a `Set`. - pub index: Vec<'a, Atom<'a>>, + pub index: Vec<'a, Ident<'a>>, /// Alias for $first. - pub first: Option>, + pub first: Option>, /// Alias for $last. - pub last: Option>, + pub last: Option>, /// Alias for $even. - pub even: Option>, + pub even: Option>, /// Alias for $odd. - pub odd: Option>, + pub odd: Option>, } /// Initialize a @let slot. @@ -1251,7 +1251,7 @@ pub struct DeclareLetOp<'a> { /// Assigned slot. pub slot: Option, /// Variable name. - pub name: Atom<'a>, + pub name: Ident<'a>, } /// Start an i18n block. @@ -1325,7 +1325,7 @@ pub struct IcuStartOp<'a> { /// Message instance ID for metadata lookup. pub message: Option, /// ICU placeholder. - pub icu_placeholder: Option>, + pub icu_placeholder: Option>, } /// End an ICU expression. @@ -1352,20 +1352,20 @@ pub struct I18nContextOp<'a> { /// Maps placeholder names to lists of param values. pub params: oxc_allocator::HashMap< 'a, - Atom<'a>, + Ident<'a>, oxc_allocator::Vec<'a, super::i18n_params::I18nParamValue>, >, /// Post-processing params map for ICU expressions. /// These are processed after the main params during message generation. pub postprocessing_params: oxc_allocator::HashMap< 'a, - Atom<'a>, + Ident<'a>, oxc_allocator::Vec<'a, super::i18n_params::I18nParamValue>, >, /// ICU placeholder literals map. /// Maps ICU placeholder names to their formatted string values. /// These are string literals like "Hello ${�0�}!" generated from IcuPlaceholderOp. - pub icu_placeholder_literals: oxc_allocator::HashMap<'a, Atom<'a>, Atom<'a>>, + pub icu_placeholder_literals: oxc_allocator::HashMap<'a, Ident<'a>, Ident<'a>>, /// Message instance ID reference (for metadata lookup). /// /// Stores the i18n message's instance_id (not an XrefId) to look up metadata @@ -1395,7 +1395,7 @@ pub struct I18nAttributesOp<'a> { #[derive(Debug)] pub struct I18nAttributeConfig<'a> { /// Attribute name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// I18n message. pub message: XrefId, } @@ -1410,7 +1410,7 @@ pub struct VariableOp<'a> { /// Variable kind. pub kind: SemanticVariableKind, /// Variable name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Initializer expression. pub initializer: Box<'a, IrExpression<'a>>, /// Variable flags. @@ -1434,9 +1434,9 @@ pub struct ExtractedAttributeOp<'a> { /// Binding kind. pub binding_kind: BindingKind, /// Namespace. - pub namespace: Option>, + pub namespace: Option>, /// Attribute name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Attribute value. pub value: Option>>, /// Security context. @@ -1453,7 +1453,7 @@ pub struct ExtractedAttributeOp<'a> { /// i18n context. pub i18n_context: Option, /// Trusted value function for security-sensitive constant attributes. - pub trusted_value_fn: Option>, + pub trusted_value_fn: Option>, } /// Source location for debugging. @@ -1464,7 +1464,7 @@ pub struct SourceLocationOp<'a> { /// Target element. pub target: XrefId, /// Template URL. - pub template_url: Atom<'a>, + pub template_url: Ident<'a>, /// Line number. pub line: u32, /// Column number. @@ -1507,7 +1507,7 @@ pub struct InterpolateTextOp<'a> { /// Interpolation expression. pub interpolation: Box<'a, IrExpression<'a>>, /// I18n placeholder. - pub i18n_placeholder: Option>, + pub i18n_placeholder: Option>, } /// Bind to an element property. @@ -1518,7 +1518,7 @@ pub struct PropertyOp<'a> { /// Target element. pub target: XrefId, /// Property name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Expression. pub expression: Box<'a, IrExpression<'a>>, /// Whether this is a host binding. @@ -1526,7 +1526,7 @@ pub struct PropertyOp<'a> { /// Security context. pub security_context: SecurityContext, /// Sanitizer function. - pub sanitizer: Option>, + pub sanitizer: Option>, /// Whether property should be updated structurally. pub is_structural: bool, /// I18n context. @@ -1547,11 +1547,11 @@ pub struct StylePropOp<'a> { /// Target element. pub target: XrefId, /// Style name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Expression. pub expression: Box<'a, IrExpression<'a>>, /// Unit suffix. - pub unit: Option>, + pub unit: Option>, } /// Bind to a class property. @@ -1562,7 +1562,7 @@ pub struct ClassPropOp<'a> { /// Target element. pub target: XrefId, /// Class name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Expression. pub expression: Box<'a, IrExpression<'a>>, } @@ -1608,15 +1608,15 @@ pub struct AttributeOp<'a> { /// Target element. pub target: XrefId, /// Attribute name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Expression. pub expression: Box<'a, IrExpression<'a>>, /// Namespace. - pub namespace: Option>, + pub namespace: Option>, /// Security context. pub security_context: SecurityContext, /// Sanitizer function. - pub sanitizer: Option>, + pub sanitizer: Option>, /// I18n context. pub i18n_context: Option, /// I18n message instance ID. @@ -1645,7 +1645,7 @@ pub struct DomPropertyOp<'a> { /// Target element. pub target: XrefId, /// Property name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Expression. pub expression: Box<'a, IrExpression<'a>>, /// Whether this is a host binding. @@ -1653,7 +1653,7 @@ pub struct DomPropertyOp<'a> { /// Security context. pub security_context: SecurityContext, /// Sanitizer function. - pub sanitizer: Option>, + pub sanitizer: Option>, /// Binding kind (for animation handling). pub binding_kind: BindingKind, } @@ -1679,13 +1679,13 @@ pub struct TwoWayPropertyOp<'a> { /// Target element. pub target: XrefId, /// Property name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Expression. pub expression: Box<'a, IrExpression<'a>>, /// Security context. pub security_context: SecurityContext, /// Sanitizer function. - pub sanitizer: Option>, + pub sanitizer: Option>, } /// Two-way listener (CREATE op). @@ -1698,13 +1698,13 @@ pub struct TwoWayListenerOp<'a> { /// Target slot. pub target_slot: SlotId, /// Tag name of the element on which this listener is placed. - pub tag: Option>, + pub tag: Option>, /// Event name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Handler operations. pub handler_ops: Vec<'a, UpdateOp<'a>>, /// Function name. - pub handler_fn_name: Option>, + pub handler_fn_name: Option>, } /// Store @let value. @@ -1717,7 +1717,7 @@ pub struct StoreLetOp<'a> { /// Target slot. pub target_slot: SlotId, /// Name that the user set when declaring the `@let`. - pub declared_name: Atom<'a>, + pub declared_name: Ident<'a>, /// Value expression. pub value: Box<'a, IrExpression<'a>>, } @@ -1766,10 +1766,10 @@ pub struct I18nExpressionOp<'a> { /// Expression usage. pub usage: I18nExpressionFor, /// Attribute name (for attribute bindings). - pub name: Atom<'a>, + pub name: Ident<'a>, /// I18n placeholder name associated with this expression. /// This can be None if the expression is part of an ICU placeholder. - pub i18n_placeholder: Option>, + pub i18n_placeholder: Option>, /// Reference to ICU placeholder op if this expression is part of an ICU. pub icu_placeholder: Option, } @@ -1798,10 +1798,10 @@ pub struct IcuPlaceholderOp<'a> { /// Cross-reference ID. pub xref: XrefId, /// Placeholder name in the ICU expression. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Static string segments to be combined with expression placeholders. /// Works like interpolation: strings.len() == expression_placeholders.len() + 1 - pub strings: oxc_allocator::Vec<'a, Atom<'a>>, + pub strings: oxc_allocator::Vec<'a, Ident<'a>>, /// Expression placeholders collected from I18nExpression ops. /// These are combined with strings to form the full placeholder value. pub expression_placeholders: oxc_allocator::Vec<'a, super::i18n_params::I18nParamValue>, @@ -1817,11 +1817,11 @@ pub struct BindingOp<'a> { /// Binding kind. pub kind: BindingKind, /// Binding name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Expression. pub expression: Box<'a, IrExpression<'a>>, /// Unit suffix. - pub unit: Option>, + pub unit: Option>, /// Security context. pub security_context: SecurityContext, /// I18n message instance ID. @@ -1851,13 +1851,13 @@ pub struct AnimationOp<'a> { /// Target element. pub target: XrefId, /// Animation name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Animation kind (enter or leave). pub animation_kind: AnimationKind, /// Handler operations (contains the expression as a return statement). pub handler_ops: Vec<'a, UpdateOp<'a>>, /// Function name for the handler. - pub handler_fn_name: Option>, + pub handler_fn_name: Option>, /// I18n message instance ID. /// /// Stores the i18n message's instance_id for dedup, not an XrefId. @@ -1865,7 +1865,7 @@ pub struct AnimationOp<'a> { /// Security context. pub security_context: SecurityContext, /// Sanitizer function. - pub sanitizer: Option>, + pub sanitizer: Option>, } /// Animation string binding (CREATE op). @@ -1876,7 +1876,7 @@ pub struct AnimationStringOp<'a> { /// Target element. pub target: XrefId, /// Animation name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Animation kind (enter or leave). pub animation_kind: AnimationKind, /// Expression. @@ -1891,7 +1891,7 @@ pub struct AnimationBindingOp<'a> { /// Target element. pub target: XrefId, /// Animation name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Expression. pub expression: Box<'a, IrExpression<'a>>, /// Binding kind. @@ -1908,15 +1908,15 @@ pub struct AnimationListenerOp<'a> { /// Target slot. pub target_slot: SlotId, /// Tag name of the element on which this listener is placed. Null for host bindings. - pub tag: Option>, + pub tag: Option>, /// Whether this listener is from a host binding. pub host_listener: bool, /// Event name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Handler operations. pub handler_ops: Vec<'a, UpdateOp<'a>>, /// Function name. - pub handler_fn_name: Option>, + pub handler_fn_name: Option>, /// Animation phase. pub phase: AnimationKind, /// Whether this listener uses $event. @@ -1933,7 +1933,7 @@ pub struct UpdateVariableOp<'a> { /// Variable kind. pub kind: SemanticVariableKind, /// Variable name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Initializer expression. pub initializer: Box<'a, IrExpression<'a>>, /// Variable flags. @@ -1955,7 +1955,7 @@ pub struct ControlOp<'a> { /// Target element. pub target: XrefId, /// Property name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Expression. pub expression: Box<'a, IrExpression<'a>>, /// Security context. @@ -1984,7 +1984,7 @@ pub struct StatementOp<'a> { #[derive(Debug)] pub struct LocalRef<'a> { /// Reference name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Target directive/component. - pub target: Atom<'a>, + pub target: Ident<'a>, } diff --git a/crates/oxc_angular_compiler/src/linker/mod.rs b/crates/oxc_angular_compiler/src/linker/mod.rs index 47cddb3c9..3c63ff805 100644 --- a/crates/oxc_angular_compiler/src/linker/mod.rs +++ b/crates/oxc_angular_compiler/src/linker/mod.rs @@ -611,7 +611,7 @@ fn get_bool_property(obj: &ObjectExpression<'_>, name: &str) -> Option { && matches!(&prop.key, PropertyKey::StaticIdentifier(ident) if ident.name == name) && let Expression::BooleanLiteral(lit) = &prop.value { - return Some(lit.value); + return Some(lit.value.into()); } } None @@ -1252,7 +1252,7 @@ fn convert_inputs_to_definition_format(inputs_obj: &ObjectExpression<'_>, source match &p.value { // Simple string: propertyName: "publicName" → keep as is Expression::StringLiteral(lit) => { - entries.push(format!("{quoted_key}: \"{}\"", lit.value)); + entries.push(format!("{quoted_key}: \"{}\"", lit.value.as_str())); } // Array: check if it's declaration format [publicName, classPropertyName] // and convert to definition format [InputFlags, publicName, classPropertyName] diff --git a/crates/oxc_angular_compiler/src/ng_module/compiler.rs b/crates/oxc_angular_compiler/src/ng_module/compiler.rs index 84ceb1896..eef56a507 100644 --- a/crates/oxc_angular_compiler/src/ng_module/compiler.rs +++ b/crates/oxc_angular_compiler/src/ng_module/compiler.rs @@ -14,7 +14,7 @@ //! ``` use oxc_allocator::{Allocator, Box, Vec}; -use oxc_span::Atom; +use oxc_span::Ident; use super::metadata::{R3NgModuleMetadata, R3Reference}; use crate::output::ast::{ @@ -82,7 +82,7 @@ fn build_definition_map<'a>( // type: ModuleClass entries.push(LiteralMapEntry { - key: Atom::from("type"), + key: Ident::from("type"), value: metadata.r#type.value.clone_in(allocator), quoted: false, }); @@ -92,7 +92,7 @@ fn build_definition_map<'a>( let bootstrap_array = create_reference_array(allocator, &metadata.bootstrap, metadata.contains_forward_decls); entries.push(LiteralMapEntry { - key: Atom::from("bootstrap"), + key: Ident::from("bootstrap"), value: bootstrap_array, quoted: false, }); @@ -108,7 +108,7 @@ fn build_definition_map<'a>( metadata.contains_forward_decls, ); entries.push(LiteralMapEntry { - key: Atom::from("declarations"), + key: Ident::from("declarations"), value: declarations_array, quoted: false, }); @@ -122,7 +122,7 @@ fn build_definition_map<'a>( metadata.contains_forward_decls, ); entries.push(LiteralMapEntry { - key: Atom::from("imports"), + key: Ident::from("imports"), value: imports_array, quoted: false, }); @@ -136,7 +136,7 @@ fn build_definition_map<'a>( metadata.contains_forward_decls, ); entries.push(LiteralMapEntry { - key: Atom::from("exports"), + key: Ident::from("exports"), value: exports_array, quoted: false, }); @@ -148,7 +148,7 @@ fn build_definition_map<'a>( let schemas_array = create_reference_array(allocator, &metadata.schemas, metadata.contains_forward_decls); entries.push(LiteralMapEntry { - key: Atom::from("schemas"), + key: Ident::from("schemas"), value: schemas_array, quoted: false, }); @@ -157,7 +157,7 @@ fn build_definition_map<'a>( // id: 'unique-module-id' if let Some(id) = &metadata.id { entries.push(LiteralMapEntry { - key: Atom::from("id"), + key: Ident::from("id"), value: id.clone_in(allocator), quoted: false, }); @@ -211,12 +211,12 @@ fn create_define_ng_module_call<'a>( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(Identifiers::DEFINE_NG_MODULE), + name: Ident::from(Identifiers::DEFINE_NG_MODULE), optional: false, source_span: None, }, @@ -277,7 +277,7 @@ fn create_set_scope_side_effect<'a>( metadata.contains_forward_decls, ); scope_entries.push(LiteralMapEntry { - key: Atom::from("declarations"), + key: Ident::from("declarations"), value: decls, quoted: false, }); @@ -287,7 +287,7 @@ fn create_set_scope_side_effect<'a>( let imports = create_reference_array(allocator, &metadata.imports, metadata.contains_forward_decls); scope_entries.push(LiteralMapEntry { - key: Atom::from("imports"), + key: Ident::from("imports"), value: imports, quoted: false, }); @@ -297,7 +297,7 @@ fn create_set_scope_side_effect<'a>( let exports = create_reference_array(allocator, &metadata.exports, metadata.contains_forward_decls); scope_entries.push(LiteralMapEntry { - key: Atom::from("exports"), + key: Ident::from("exports"), value: exports, quoted: false, }); @@ -313,12 +313,12 @@ fn create_set_scope_side_effect<'a>( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(Identifiers::SET_NG_MODULE_SCOPE), + name: Ident::from(Identifiers::SET_NG_MODULE_SCOPE), optional: false, source_span: None, }, @@ -342,7 +342,7 @@ fn create_set_scope_side_effect<'a>( // Create: (typeof ngJitMode === "undefined" || ngJitMode) let typeof_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("typeof ngJitMode"), source_span: None }, + ReadVarExpr { name: Ident::from("typeof ngJitMode"), source_span: None }, allocator, )); @@ -353,7 +353,7 @@ fn create_set_scope_side_effect<'a>( rhs: Box::new_in( OutputExpression::Literal(Box::new_in( LiteralExpr { - value: LiteralValue::String(Atom::from("undefined")), + value: LiteralValue::String(Ident::from("undefined")), source_span: None, }, allocator, @@ -366,7 +366,7 @@ fn create_set_scope_side_effect<'a>( )); let ng_jit_mode = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("ngJitMode"), source_span: None }, + ReadVarExpr { name: Ident::from("ngJitMode"), source_span: None }, allocator, )); @@ -431,12 +431,12 @@ fn create_register_ng_module_type<'a>( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(Identifiers::REGISTER_NG_MODULE_TYPE), + name: Ident::from(Identifiers::REGISTER_NG_MODULE_TYPE), optional: false, source_span: None, }, @@ -474,7 +474,7 @@ mod tests { fn test_compile_simple_ng_module() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("AppModule"), source_span: None }, + ReadVarExpr { name: Ident::from("AppModule"), source_span: None }, &allocator, )); @@ -496,11 +496,11 @@ mod tests { fn test_compile_ng_module_with_declarations() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("MyModule"), source_span: None }, + ReadVarExpr { name: Ident::from("MyModule"), source_span: None }, &allocator, )); let component_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("MyComponent"), source_span: None }, + ReadVarExpr { name: Ident::from("MyComponent"), source_span: None }, &allocator, )); @@ -524,15 +524,15 @@ mod tests { fn test_compile_ng_module_with_imports_exports() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("SharedModule"), source_span: None }, + ReadVarExpr { name: Ident::from("SharedModule"), source_span: None }, &allocator, )); let import_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("CommonModule"), source_span: None }, + ReadVarExpr { name: Ident::from("CommonModule"), source_span: None }, &allocator, )); let export_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("SharedComponent"), source_span: None }, + ReadVarExpr { name: Ident::from("SharedComponent"), source_span: None }, &allocator, )); @@ -558,11 +558,11 @@ mod tests { fn test_compile_ng_module_with_side_effect_scope() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("JitModule"), source_span: None }, + ReadVarExpr { name: Ident::from("JitModule"), source_span: None }, &allocator, )); let decl_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("JitComponent"), source_span: None }, + ReadVarExpr { name: Ident::from("JitComponent"), source_span: None }, &allocator, )); @@ -583,11 +583,11 @@ mod tests { fn test_compile_ng_module_with_forward_decls() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("ForwardModule"), source_span: None }, + ReadVarExpr { name: Ident::from("ForwardModule"), source_span: None }, &allocator, )); let decl_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("ForwardComponent"), source_span: None }, + ReadVarExpr { name: Ident::from("ForwardComponent"), source_span: None }, &allocator, )); diff --git a/crates/oxc_angular_compiler/src/ng_module/decorator.rs b/crates/oxc_angular_compiler/src/ng_module/decorator.rs index 0672b7513..63e0fa564 100644 --- a/crates/oxc_angular_compiler/src/ng_module/decorator.rs +++ b/crates/oxc_angular_compiler/src/ng_module/decorator.rs @@ -8,7 +8,7 @@ use oxc_ast::ast::{ Argument, ArrayExpressionElement, Class, ClassElement, Decorator, Expression, MethodDefinitionKind, ObjectPropertyKind, PropertyKey, }; -use oxc_span::{Atom, Span}; +use oxc_span::{Ident, Span}; use crate::factory::R3DependencyMetadata; use crate::output::ast::{OutputExpression, ReadVarExpr}; @@ -21,16 +21,16 @@ use crate::output::oxc_converter::convert_oxc_expression; #[derive(Debug)] pub struct NgModuleMetadata<'a> { /// The name of the NgModule class. - pub class_name: Atom<'a>, + pub class_name: Ident<'a>, /// Span of the class declaration. pub class_span: Span, /// Declared components, directives, and pipes as class names. - pub declarations: Vec<'a, Atom<'a>>, + pub declarations: Vec<'a, Ident<'a>>, /// Imported modules as class names (for ɵmod scope resolution). - pub imports: Vec<'a, Atom<'a>>, + pub imports: Vec<'a, Ident<'a>>, /// Raw imports array expression (for ɵinj provider resolution). /// This preserves call expressions like `StoreModule.forRoot(...)` and spread elements @@ -38,19 +38,19 @@ pub struct NgModuleMetadata<'a> { pub raw_imports_expr: Option>, /// Exported declarations and modules as class names. - pub exports: Vec<'a, Atom<'a>>, + pub exports: Vec<'a, Ident<'a>>, /// Providers expression as OutputExpression. pub providers: Option>, /// Bootstrap components as class names. - pub bootstrap: Vec<'a, Atom<'a>>, + pub bootstrap: Vec<'a, Ident<'a>>, /// Schema identifiers (e.g., "CUSTOM_ELEMENTS_SCHEMA"). - pub schemas: Vec<'a, Atom<'a>>, + pub schemas: Vec<'a, Ident<'a>>, /// Module ID for registration. - pub id: Option>, + pub id: Option>, /// Whether any declarations/imports/exports contain forward references. pub contains_forward_decls: bool, @@ -63,7 +63,7 @@ pub struct NgModuleMetadata<'a> { impl<'a> NgModuleMetadata<'a> { /// Create a new NgModuleMetadata with defaults. - pub fn new(allocator: &'a Allocator, class_name: Atom<'a>, class_span: Span) -> Self { + pub fn new(allocator: &'a Allocator, class_name: Ident<'a>, class_span: Span) -> Self { Self { class_name, class_span, @@ -182,7 +182,7 @@ pub fn extract_ng_module_metadata<'a>( class: &'a Class<'a>, ) -> Option> { // Get the class name - let class_name: Atom<'a> = class.id.as_ref()?.name.clone().into(); + let class_name: Ident<'a> = class.id.as_ref()?.name.clone().into(); let class_span = class.span; // Find the @NgModule decorator @@ -305,20 +305,20 @@ fn is_ng_module_call(callee: &Expression<'_>) -> bool { } /// Get the name of a property key as a string. -fn get_property_key_name<'a>(key: &PropertyKey<'a>) -> Option> { +fn get_property_key_name<'a>(key: &PropertyKey<'a>) -> Option> { match key { PropertyKey::StaticIdentifier(id) => Some(id.name.clone().into()), - PropertyKey::StringLiteral(lit) => Some(lit.value.clone()), + PropertyKey::StringLiteral(lit) => Some(lit.value.clone().into()), _ => None, } } /// Extract a string value from an expression. -fn extract_string_value<'a>(expr: &Expression<'a>) -> Option> { +fn extract_string_value<'a>(expr: &Expression<'a>) -> Option> { match expr { - Expression::StringLiteral(lit) => Some(lit.value.clone()), + Expression::StringLiteral(lit) => Some(lit.value.clone().into()), Expression::TemplateLiteral(tpl) if tpl.expressions.is_empty() => { - tpl.quasis.first().and_then(|q| q.value.cooked.clone()) + tpl.quasis.first().and_then(|q| q.value.cooked.clone().map(Into::into)) } _ => None, } @@ -329,7 +329,7 @@ fn extract_string_value<'a>(expr: &Expression<'a>) -> Option> { fn extract_reference_array<'a>( allocator: &'a Allocator, expr: &Expression<'a>, -) -> (Vec<'a, Atom<'a>>, bool) { +) -> (Vec<'a, Ident<'a>>, bool) { let mut result = Vec::new_in(allocator); let mut has_forward_refs = false; @@ -377,7 +377,7 @@ fn extract_reference_array<'a>( fn extract_identifier_array<'a>( allocator: &'a Allocator, expr: &Expression<'a>, -) -> Vec<'a, Atom<'a>> { +) -> Vec<'a, Ident<'a>> { let mut result = Vec::new_in(allocator); let Expression::ArrayExpression(arr) = expr else { @@ -444,7 +444,7 @@ fn extract_param_dependency<'a>( let mut skip_self = false; let mut self_ = false; let mut host = false; - let mut attribute_name: Option> = None; + let mut attribute_name: Option> = None; for decorator in ¶m.decorators { if let Some(name) = get_decorator_name(&decorator.expression) { @@ -457,7 +457,7 @@ fn extract_param_dependency<'a>( // @Attribute('attrName') - extract the attribute name if let Expression::CallExpression(call) = &decorator.expression { if let Some(Argument::StringLiteral(s)) = call.arguments.first() { - attribute_name = Some(s.value.clone()); + attribute_name = Some(s.value.clone().into()); } } } @@ -491,7 +491,7 @@ fn extract_param_dependency<'a>( } /// Get the name of a decorator from its expression. -fn get_decorator_name<'a>(expr: &'a Expression<'a>) -> Option> { +fn get_decorator_name<'a>(expr: &'a Expression<'a>) -> Option> { match expr { // @Optional Expression::Identifier(id) => Some(id.name.clone().into()), @@ -519,7 +519,7 @@ fn extract_param_token<'a>( // Handle TSTypeReference: SomeClass, SomeModule, etc. if let oxc_ast::ast::TSType::TSTypeReference(type_ref) = ts_type { // Get the type name - let type_name: Atom<'a> = match &type_ref.type_name { + let type_name: Ident<'a> = match &type_ref.type_name { oxc_ast::ast::TSTypeName::IdentifierReference(id) => id.name.clone().into(), oxc_ast::ast::TSTypeName::QualifiedName(_) | oxc_ast::ast::TSTypeName::ThisExpression(_) => { diff --git a/crates/oxc_angular_compiler/src/ng_module/definition.rs b/crates/oxc_angular_compiler/src/ng_module/definition.rs index 7f98c5e55..2cdc5aaaf 100644 --- a/crates/oxc_angular_compiler/src/ng_module/definition.rs +++ b/crates/oxc_angular_compiler/src/ng_module/definition.rs @@ -335,13 +335,13 @@ mod tests { use crate::ng_module::metadata::{R3NgModuleMetadataBuilder, R3Reference, R3SelectorScopeMode}; use crate::output::ast::ReadVarExpr; use oxc_allocator::Box; - use oxc_span::Atom; + use oxc_span::Ident; #[test] fn test_generate_simple_ng_module_definition() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("AppModule"), source_span: None }, + ReadVarExpr { name: Ident::from("AppModule"), source_span: None }, &allocator, )); @@ -368,11 +368,11 @@ mod tests { fn test_generate_ng_module_with_declarations() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("MyModule"), source_span: None }, + ReadVarExpr { name: Ident::from("MyModule"), source_span: None }, &allocator, )); let component_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("MyComponent"), source_span: None }, + ReadVarExpr { name: Ident::from("MyComponent"), source_span: None }, &allocator, )); @@ -397,15 +397,15 @@ mod tests { fn test_generate_ng_module_with_imports_exports() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("SharedModule"), source_span: None }, + ReadVarExpr { name: Ident::from("SharedModule"), source_span: None }, &allocator, )); let import_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("CommonModule"), source_span: None }, + ReadVarExpr { name: Ident::from("CommonModule"), source_span: None }, &allocator, )); let export_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("SharedComponent"), source_span: None }, + ReadVarExpr { name: Ident::from("SharedComponent"), source_span: None }, &allocator, )); @@ -433,11 +433,11 @@ mod tests { fn test_generate_ng_module_with_bootstrap() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("RootModule"), source_span: None }, + ReadVarExpr { name: Ident::from("RootModule"), source_span: None }, &allocator, )); let bootstrap_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("AppComponent"), source_span: None }, + ReadVarExpr { name: Ident::from("AppComponent"), source_span: None }, &allocator, )); @@ -461,11 +461,11 @@ mod tests { fn test_generate_ng_module_with_side_effect_scope() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("JitModule"), source_span: None }, + ReadVarExpr { name: Ident::from("JitModule"), source_span: None }, &allocator, )); let decl_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("JitComponent"), source_span: None }, + ReadVarExpr { name: Ident::from("JitComponent"), source_span: None }, &allocator, )); @@ -487,7 +487,7 @@ mod tests { fn test_emit_ng_module_definition() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("TestModule"), source_span: None }, + ReadVarExpr { name: Ident::from("TestModule"), source_span: None }, &allocator, )); @@ -618,7 +618,7 @@ mod tests { // This enables tree-shaking via the @__PURE__ annotation. let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("TreeShakableModule"), source_span: None }, + ReadVarExpr { name: Ident::from("TreeShakableModule"), source_span: None }, &allocator, )); diff --git a/crates/oxc_angular_compiler/src/output/ast.rs b/crates/oxc_angular_compiler/src/output/ast.rs index 5395e54a0..1ac69d59e 100644 --- a/crates/oxc_angular_compiler/src/output/ast.rs +++ b/crates/oxc_angular_compiler/src/output/ast.rs @@ -6,7 +6,7 @@ //! Ported from Angular's `output/output_ast.ts`. use oxc_allocator::{Box, Vec}; -use oxc_span::{Atom, Span}; +use oxc_span::{Ident, Span}; use crate::ir::expression::IrExpression; @@ -293,7 +293,7 @@ pub struct MapType<'a> { #[derive(Debug)] pub struct TransplantedType<'a> { /// String representation of the external type. - pub type_repr: Atom<'a>, + pub type_repr: Ident<'a>, /// Type modifiers. pub modifiers: TypeModifier, } @@ -483,7 +483,7 @@ pub enum LiteralValue<'a> { /// Number literal. Number(f64), /// String literal. - String(Atom<'a>), + String(Ident<'a>), } /// Array literal expression. @@ -499,7 +499,7 @@ pub struct LiteralArrayExpr<'a> { #[derive(Debug)] pub struct LiteralMapEntry<'a> { /// Property key. - pub key: Atom<'a>, + pub key: Ident<'a>, /// Property value. pub value: OutputExpression<'a>, /// Whether the key is quoted. @@ -519,9 +519,9 @@ pub struct LiteralMapExpr<'a> { #[derive(Debug)] pub struct RegularExpressionLiteralExpr<'a> { /// Regex body. - pub body: Atom<'a>, + pub body: Ident<'a>, /// Regex flags. - pub flags: Option>, + pub flags: Option>, /// Source span. pub source_span: Option, } @@ -530,9 +530,9 @@ pub struct RegularExpressionLiteralExpr<'a> { #[derive(Debug)] pub struct TemplateLiteralElement<'a> { /// Cooked text. - pub text: Atom<'a>, + pub text: Ident<'a>, /// Raw text. - pub raw_text: Atom<'a>, + pub raw_text: Ident<'a>, /// Source span. pub source_span: Option, } @@ -563,7 +563,7 @@ pub struct TaggedTemplateLiteralExpr<'a> { #[derive(Debug)] pub struct ReadVarExpr<'a> { /// Variable name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Source span. pub source_span: Option, } @@ -574,7 +574,7 @@ pub struct ReadPropExpr<'a> { /// Receiver expression. pub receiver: Box<'a, OutputExpression<'a>>, /// Property name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Whether this is an optional chain access (`?.`). pub optional: bool, /// Source span. @@ -682,14 +682,14 @@ pub struct CommaExpr<'a> { #[derive(Debug)] pub struct FnParam<'a> { /// Parameter name. - pub name: Atom<'a>, + pub name: Ident<'a>, } /// Function expression. #[derive(Debug)] pub struct FunctionExpr<'a> { /// Function name (optional). - pub name: Option>, + pub name: Option>, /// Parameters. pub params: Vec<'a, FnParam<'a>>, /// Function body. @@ -750,7 +750,7 @@ pub struct DynamicImportExpr<'a> { /// URL to import. pub url: DynamicImportUrl<'a>, /// URL comment for bundlers. - pub url_comment: Option>, + pub url_comment: Option>, /// Source span. pub source_span: Option, } @@ -759,7 +759,7 @@ pub struct DynamicImportExpr<'a> { #[derive(Debug)] pub enum DynamicImportUrl<'a> { /// Static string URL. - String(Atom<'a>), + String(Ident<'a>), /// Dynamic expression URL. Expression(Box<'a, OutputExpression<'a>>), } @@ -768,9 +768,9 @@ pub enum DynamicImportUrl<'a> { #[derive(Debug)] pub struct ExternalReference<'a> { /// Module name. - pub module_name: Option>, + pub module_name: Option>, /// Export name. - pub name: Option>, + pub name: Option>, } /// External expression (reference to external module). @@ -786,15 +786,15 @@ pub struct ExternalExpr<'a> { #[derive(Debug)] pub struct LocalizedStringExpr<'a> { /// Message description. - pub description: Option>, + pub description: Option>, /// Message meaning. - pub meaning: Option>, + pub meaning: Option>, /// Custom message ID. - pub custom_id: Option>, + pub custom_id: Option>, /// Message parts. - pub message_parts: Vec<'a, Atom<'a>>, + pub message_parts: Vec<'a, Ident<'a>>, /// Placeholder names. - pub placeholder_names: Vec<'a, Atom<'a>>, + pub placeholder_names: Vec<'a, Ident<'a>>, /// Interpolated expressions. pub expressions: Vec<'a, OutputExpression<'a>>, /// Source span. @@ -805,7 +805,7 @@ pub struct LocalizedStringExpr<'a> { #[derive(Debug)] pub struct WrappedNodeExpr<'a> { /// Node identifier/reference. - pub node_id: Atom<'a>, + pub node_id: Ident<'a>, /// Source span. pub source_span: Option, } @@ -856,7 +856,7 @@ pub enum OutputStatement<'a> { #[derive(Debug)] pub struct DeclareVarStmt<'a> { /// Variable name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Initial value. pub value: Option>, /// Statement modifiers. @@ -873,18 +873,18 @@ pub enum LeadingComment<'a> { /// JSDoc comment. JSDoc(JsDocComment<'a>), /// Single-line comment. - SingleLine(Atom<'a>), + SingleLine(Ident<'a>), /// Multi-line comment. - MultiLine(Atom<'a>), + MultiLine(Ident<'a>), } /// JSDoc comment for Closure Compiler compatibility. #[derive(Debug, Clone)] pub struct JsDocComment<'a> { /// Description tag (@desc). - pub description: Option>, + pub description: Option>, /// Meaning tag (@meaning). - pub meaning: Option>, + pub meaning: Option>, /// Suppress warnings (@suppress {msgDescriptions}). pub suppress_msg_descriptions: bool, } @@ -893,7 +893,7 @@ pub struct JsDocComment<'a> { #[derive(Debug)] pub struct DeclareFunctionStmt<'a> { /// Function name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Parameters. pub params: Vec<'a, FnParam<'a>>, /// Function body. @@ -1588,7 +1588,7 @@ impl OutputAstBuilder { /// Create a string literal. pub fn string<'a>( allocator: &'a oxc_allocator::Allocator, - value: Atom<'a>, + value: Ident<'a>, ) -> OutputExpression<'a> { OutputExpression::Literal(Box::new_in( LiteralExpr { value: LiteralValue::String(value), source_span: None }, @@ -1599,7 +1599,7 @@ impl OutputAstBuilder { /// Create a variable read. pub fn variable<'a>( allocator: &'a oxc_allocator::Allocator, - name: Atom<'a>, + name: Ident<'a>, ) -> OutputExpression<'a> { OutputExpression::ReadVar(Box::new_in(ReadVarExpr { name, source_span: None }, allocator)) } diff --git a/crates/oxc_angular_compiler/src/output/emitter.rs b/crates/oxc_angular_compiler/src/output/emitter.rs index 9eb735d4e..350b2ec4b 100644 --- a/crates/oxc_angular_compiler/src/output/emitter.rs +++ b/crates/oxc_angular_compiler/src/output/emitter.rs @@ -16,7 +16,7 @@ use std::sync::Arc; use oxc_diagnostics::OxcDiagnostic; -use oxc_span::{Atom, Span}; +use oxc_span::{Ident, Span}; use super::ast::{ ArrowFunctionBody, BinaryOperator, DeclareVarStmt, DynamicImportUrl, FnParam, LeadingComment, @@ -1276,7 +1276,7 @@ fn push_unicode_escape(buf: &mut String, code: u32) { } /// Escape an identifier for use as a property key. -fn escape_identifier(input: &Atom<'_>, escape_dollar: bool, always_quote: bool) -> String { +fn escape_identifier(input: &Ident<'_>, escape_dollar: bool, always_quote: bool) -> String { // Check if the identifier is a valid JavaScript identifier fn is_legal_identifier(s: &str) -> bool { let mut chars = s.chars(); @@ -1393,7 +1393,7 @@ mod tests { use super::*; use crate::output::ast::{LiteralExpr, LiteralValue, ReadVarExpr}; use oxc_allocator::{Allocator, Box}; - use oxc_span::Atom; + use oxc_span::Ident; #[test] fn test_emit_literal_null() { @@ -1478,7 +1478,7 @@ mod tests { let emitter = JsEmitter::new(); let alloc = Allocator::default(); let expr = OutputExpression::Literal(Box::new_in( - LiteralExpr { value: LiteralValue::String(Atom::from("hello")), source_span: None }, + LiteralExpr { value: LiteralValue::String(Ident::from("hello")), source_span: None }, &alloc, )); // Uses double quotes to match Angular's output style @@ -1490,7 +1490,7 @@ mod tests { let emitter = JsEmitter::new(); let alloc = Allocator::default(); let expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("myVar"), source_span: None }, + ReadVarExpr { name: Ident::from("myVar"), source_span: None }, &alloc, )); assert_eq!(emitter.emit_expression(&expr), "myVar"); @@ -1764,18 +1764,18 @@ mod tests { #[test] fn test_emit_jsdoc_comment() { use super::super::ast::{DeclareVarStmt, JsDocComment, LeadingComment, StmtModifier}; - use oxc_span::Atom; + use oxc_span::Ident; let emitter = JsEmitter::new(); // Create a statement with a JSDoc comment let stmt = DeclareVarStmt { - name: Atom::from("MSG_HELLO"), + name: Ident::from("MSG_HELLO"), value: None, modifiers: StmtModifier::FINAL, leading_comment: Some(LeadingComment::JSDoc(JsDocComment { - description: Some(Atom::from("Hello world")), - meaning: Some(Atom::from("greeting")), + description: Some(Ident::from("Hello world")), + meaning: Some(Ident::from("greeting")), suppress_msg_descriptions: false, })), source_span: None, @@ -1792,13 +1792,13 @@ mod tests { #[test] fn test_emit_jsdoc_with_suppress() { use super::super::ast::{DeclareVarStmt, JsDocComment, LeadingComment, StmtModifier}; - use oxc_span::Atom; + use oxc_span::Ident; let emitter = JsEmitter::new(); // Create a statement with @suppress let stmt = DeclareVarStmt { - name: Atom::from("MSG_HELLO"), + name: Ident::from("MSG_HELLO"), value: None, modifiers: StmtModifier::FINAL, leading_comment: Some(LeadingComment::JSDoc(JsDocComment { @@ -1820,15 +1820,15 @@ mod tests { #[test] fn test_emit_single_line_comment() { use super::super::ast::{DeclareVarStmt, LeadingComment, StmtModifier}; - use oxc_span::Atom; + use oxc_span::Ident; let emitter = JsEmitter::new(); let stmt = DeclareVarStmt { - name: Atom::from("x"), + name: Ident::from("x"), value: None, modifiers: StmtModifier::NONE, - leading_comment: Some(LeadingComment::SingleLine(Atom::from("test comment"))), + leading_comment: Some(LeadingComment::SingleLine(Ident::from("test comment"))), source_span: None, }; @@ -1843,15 +1843,15 @@ mod tests { #[test] fn test_emit_multi_line_comment() { use super::super::ast::{DeclareVarStmt, LeadingComment, StmtModifier}; - use oxc_span::Atom; + use oxc_span::Ident; let emitter = JsEmitter::new(); let stmt = DeclareVarStmt { - name: Atom::from("x"), + name: Ident::from("x"), value: None, modifiers: StmtModifier::NONE, - leading_comment: Some(LeadingComment::MultiLine(Atom::from("multi\nline"))), + leading_comment: Some(LeadingComment::MultiLine(Ident::from("multi\nline"))), source_span: None, }; @@ -1867,16 +1867,16 @@ mod tests { #[test] fn test_emit_multi_line_comment_with_asterisk() { use super::super::ast::{DeclareVarStmt, LeadingComment, StmtModifier}; - use oxc_span::Atom; + use oxc_span::Ident; let emitter = JsEmitter::new(); // Test license-style comment with asterisks let stmt = DeclareVarStmt { - name: Atom::from("x"), + name: Ident::from("x"), value: None, modifiers: StmtModifier::NONE, - leading_comment: Some(LeadingComment::MultiLine(Atom::from( + leading_comment: Some(LeadingComment::MultiLine(Ident::from( "\n* @license\n* Copyright Google LLC\n", ))), source_span: None, @@ -1896,14 +1896,14 @@ mod tests { fn test_emit_conditional_expression() { use super::super::ast::{ConditionalExpr, LiteralExpr, LiteralValue, ReadVarExpr}; use oxc_allocator::{Allocator, Box}; - use oxc_span::Atom; + use oxc_span::Ident; let emitter = JsEmitter::new(); let alloc = Allocator::default(); // Build: (condition? true: false) let condition = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("condition"), source_span: None }, + ReadVarExpr { name: Ident::from("condition"), source_span: None }, &alloc, )); let true_case = OutputExpression::Literal(Box::new_in( @@ -1936,7 +1936,7 @@ mod tests { BinaryOperatorExpr, ConditionalExpr, LiteralExpr, LiteralValue, ReadVarExpr, }; use oxc_allocator::{Allocator, Box}; - use oxc_span::Atom; + use oxc_span::Ident; let emitter = JsEmitter::new(); let alloc = Allocator::default(); @@ -1948,7 +1948,7 @@ mod tests { operator: super::super::ast::BinaryOperator::Identical, lhs: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("tmp"), source_span: None }, + ReadVarExpr { name: Ident::from("tmp"), source_span: None }, &alloc, )), &alloc, @@ -1956,7 +1956,7 @@ mod tests { rhs: Box::new_in( OutputExpression::Literal(Box::new_in( LiteralExpr { - value: LiteralValue::String(Atom::from("year")), + value: LiteralValue::String(Ident::from("year")), source_span: None, }, &alloc, @@ -1996,7 +1996,7 @@ mod tests { operator: super::super::ast::BinaryOperator::Identical, lhs: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("tmp"), source_span: None }, + ReadVarExpr { name: Ident::from("tmp"), source_span: None }, &alloc, )), &alloc, @@ -2004,7 +2004,7 @@ mod tests { rhs: Box::new_in( OutputExpression::Literal(Box::new_in( LiteralExpr { - value: LiteralValue::String(Atom::from("month")), + value: LiteralValue::String(Ident::from("month")), source_span: None, }, &alloc, @@ -2046,7 +2046,7 @@ mod tests { // Build: [...arr, 1, 2] let arr_var = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("arr"), source_span: None }, + ReadVarExpr { name: Ident::from("arr"), source_span: None }, &alloc, )); let spread_expr = OutputExpression::SpreadElement(Box::new_in( @@ -2085,11 +2085,11 @@ mod tests { // Build: [...a, ...b] let a_var = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("a"), source_span: None }, + ReadVarExpr { name: Ident::from("a"), source_span: None }, &alloc, )); let b_var = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("b"), source_span: None }, + ReadVarExpr { name: Ident::from("b"), source_span: None }, &alloc, )); let spread_a = OutputExpression::SpreadElement(Box::new_in( @@ -2122,22 +2122,22 @@ mod tests { fn test_emit_nullish_coalescing_with_logical_and_on_left() { use super::super::ast::BinaryOperatorExpr; use oxc_allocator::{Allocator, Box}; - use oxc_span::Atom; + use oxc_span::Ident; let emitter = JsEmitter::new(); let alloc = Allocator::default(); // Build: (a && b) ?? c let a = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("a"), source_span: None }, + ReadVarExpr { name: Ident::from("a"), source_span: None }, &alloc, )); let b = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("b"), source_span: None }, + ReadVarExpr { name: Ident::from("b"), source_span: None }, &alloc, )); let c = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("c"), source_span: None }, + ReadVarExpr { name: Ident::from("c"), source_span: None }, &alloc, )); @@ -2172,22 +2172,22 @@ mod tests { fn test_emit_nullish_coalescing_with_logical_or_on_right() { use super::super::ast::BinaryOperatorExpr; use oxc_allocator::{Allocator, Box}; - use oxc_span::Atom; + use oxc_span::Ident; let emitter = JsEmitter::new(); let alloc = Allocator::default(); // Build: a ?? (b || c) let a = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("a"), source_span: None }, + ReadVarExpr { name: Ident::from("a"), source_span: None }, &alloc, )); let b = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("b"), source_span: None }, + ReadVarExpr { name: Ident::from("b"), source_span: None }, &alloc, )); let c = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("c"), source_span: None }, + ReadVarExpr { name: Ident::from("c"), source_span: None }, &alloc, )); @@ -2222,22 +2222,22 @@ mod tests { fn test_emit_logical_and_with_nullish_coalescing_on_left() { use super::super::ast::BinaryOperatorExpr; use oxc_allocator::{Allocator, Box}; - use oxc_span::Atom; + use oxc_span::Ident; let emitter = JsEmitter::new(); let alloc = Allocator::default(); // Build: (a ?? b) && c let a = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("a"), source_span: None }, + ReadVarExpr { name: Ident::from("a"), source_span: None }, &alloc, )); let b = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("b"), source_span: None }, + ReadVarExpr { name: Ident::from("b"), source_span: None }, &alloc, )); let c = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("c"), source_span: None }, + ReadVarExpr { name: Ident::from("c"), source_span: None }, &alloc, )); @@ -2272,26 +2272,26 @@ mod tests { fn test_emit_nullish_coalescing_with_conditional_on_left() { use super::super::ast::{BinaryOperatorExpr, ConditionalExpr}; use oxc_allocator::{Allocator, Box}; - use oxc_span::Atom; + use oxc_span::Ident; let emitter = JsEmitter::new(); let alloc = Allocator::default(); // Build: (a ? b : c) ?? d let a = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("a"), source_span: None }, + ReadVarExpr { name: Ident::from("a"), source_span: None }, &alloc, )); let b = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("b"), source_span: None }, + ReadVarExpr { name: Ident::from("b"), source_span: None }, &alloc, )); let c = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("c"), source_span: None }, + ReadVarExpr { name: Ident::from("c"), source_span: None }, &alloc, )); let d = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("d"), source_span: None }, + ReadVarExpr { name: Ident::from("d"), source_span: None }, &alloc, )); @@ -2337,7 +2337,7 @@ mod tests { // Build: (x) =>(x + 1) let x_var = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("x"), source_span: None }, + ReadVarExpr { name: Ident::from("x"), source_span: None }, &alloc, )); let one = OutputExpression::Literal(Box::new_in( @@ -2355,7 +2355,7 @@ mod tests { )); let mut params = oxc_allocator::Vec::new_in(&alloc); - params.push(FnParam { name: Atom::from("x") }); + params.push(FnParam { name: Ident::from("x") }); let expr = OutputExpression::ArrowFunction(Box::new_in( ArrowFunctionExpr { @@ -2382,11 +2382,11 @@ mod tests { // Build: (x, y) =>(x + y) let x_var = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("x"), source_span: None }, + ReadVarExpr { name: Ident::from("x"), source_span: None }, &alloc, )); let y_var = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("y"), source_span: None }, + ReadVarExpr { name: Ident::from("y"), source_span: None }, &alloc, )); let body = OutputExpression::BinaryOperator(Box::new_in( @@ -2400,8 +2400,8 @@ mod tests { )); let mut params = oxc_allocator::Vec::new_in(&alloc); - params.push(FnParam { name: Atom::from("x") }); - params.push(FnParam { name: Atom::from("y") }); + params.push(FnParam { name: Ident::from("x") }); + params.push(FnParam { name: Ident::from("y") }); let expr = OutputExpression::ArrowFunction(Box::new_in( ArrowFunctionExpr { @@ -2455,7 +2455,7 @@ mod tests { // Simple $localize with a single message part and no expressions let mut message_parts = oxc_allocator::Vec::new_in(&alloc); - message_parts.push(Atom::from("Hello")); + message_parts.push(Ident::from("Hello")); let placeholder_names = oxc_allocator::Vec::new_in(&alloc); let expressions = oxc_allocator::Vec::new_in(&alloc); @@ -2487,15 +2487,15 @@ mod tests { // $localize with interpolation: "Hello {$name}!" let mut message_parts = oxc_allocator::Vec::new_in(&alloc); - message_parts.push(Atom::from("Hello ")); - message_parts.push(Atom::from("!")); + message_parts.push(Ident::from("Hello ")); + message_parts.push(Ident::from("!")); let mut placeholder_names = oxc_allocator::Vec::new_in(&alloc); - placeholder_names.push(Atom::from("name")); + placeholder_names.push(Ident::from("name")); let mut expressions = oxc_allocator::Vec::new_in(&alloc); expressions.push(OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("name"), source_span: None }, + ReadVarExpr { name: Ident::from("name"), source_span: None }, &alloc, ))); @@ -2596,14 +2596,14 @@ mod tests { fn test_emit_empty_declare_function_body() { use super::super::ast::{DeclareFunctionStmt, StmtModifier}; use oxc_allocator::{Allocator, Box}; - use oxc_span::Atom; + use oxc_span::Ident; let emitter = JsEmitter::new(); let alloc = Allocator::default(); let stmt = OutputStatement::DeclareFunction(Box::new_in( DeclareFunctionStmt { - name: Atom::from("foo"), + name: Ident::from("foo"), params: oxc_allocator::Vec::new_in(&alloc), statements: oxc_allocator::Vec::new_in(&alloc), modifiers: StmtModifier::NONE, @@ -2634,7 +2634,7 @@ mod tests { super::super::ast::InvokeFunctionExpr { fn_expr: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("signal"), source_span: None }, + ReadVarExpr { name: Ident::from("signal"), source_span: None }, &alloc, )), &alloc, @@ -2656,7 +2656,7 @@ mod tests { let mut entries = oxc_allocator::Vec::new_in(&alloc); entries.push(LiteralMapEntry { - key: Atom::from("showMenu"), + key: Ident::from("showMenu"), value: signal_call, quoted: false, }); @@ -2699,7 +2699,7 @@ mod tests { super::super::ast::InvokeFunctionExpr { fn_expr: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("signal"), source_span: None }, + ReadVarExpr { name: Ident::from("signal"), source_span: None }, &alloc, )), &alloc, @@ -2721,7 +2721,7 @@ mod tests { let mut entries = oxc_allocator::Vec::new_in(&alloc); entries.push(LiteralMapEntry { - key: Atom::from("showMenu"), + key: Ident::from("showMenu"), value: signal_call, quoted: false, }); diff --git a/crates/oxc_angular_compiler/src/output/oxc_converter.rs b/crates/oxc_angular_compiler/src/output/oxc_converter.rs index 649d73d2f..6eb2b9527 100644 --- a/crates/oxc_angular_compiler/src/output/oxc_converter.rs +++ b/crates/oxc_angular_compiler/src/output/oxc_converter.rs @@ -16,7 +16,7 @@ use oxc_ast::ast::{ Argument, ArrayExpressionElement, BindingPattern, Expression, ObjectPropertyKind, PropertyKey, UnaryOperator as OxcUnaryOperator, }; -use oxc_span::Atom; +use oxc_span::Ident; use super::ast::{ ArrowFunctionBody, ArrowFunctionExpr, BinaryOperator, BinaryOperatorExpr, CommaExpr, @@ -49,7 +49,7 @@ pub fn convert_oxc_expression<'a>( match expr { // Literals Expression::BooleanLiteral(lit) => Some(OutputExpression::Literal(Box::new_in( - LiteralExpr { value: LiteralValue::Boolean(lit.value), source_span: None }, + LiteralExpr { value: LiteralValue::Boolean(lit.value.into()), source_span: None }, allocator, ))), @@ -59,12 +59,12 @@ pub fn convert_oxc_expression<'a>( ))), Expression::NumericLiteral(lit) => Some(OutputExpression::Literal(Box::new_in( - LiteralExpr { value: LiteralValue::Number(lit.value), source_span: None }, + LiteralExpr { value: LiteralValue::Number(lit.value.into()), source_span: None }, allocator, ))), Expression::StringLiteral(lit) => Some(OutputExpression::Literal(Box::new_in( - LiteralExpr { value: LiteralValue::String(lit.value.clone()), source_span: None }, + LiteralExpr { value: LiteralValue::String(lit.value.clone().into()), source_span: None }, allocator, ))), @@ -203,7 +203,7 @@ pub fn convert_oxc_expression<'a>( // This expression Expression::ThisExpression(_) => Some(OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("this"), source_span: None }, + ReadVarExpr { name: Ident::from("this"), source_span: None }, allocator, ))), @@ -288,9 +288,9 @@ fn convert_object_expression<'a>( // Get the property key let (key, quoted) = match &p.key { PropertyKey::StaticIdentifier(id) => (id.name.clone().into(), false), - PropertyKey::StringLiteral(lit) => (lit.value.clone(), true), + PropertyKey::StringLiteral(lit) => (lit.value.clone().into(), true), PropertyKey::NumericLiteral(lit) => { - (Atom::from(allocator.alloc_str(&lit.value.to_string())), true) + (Ident::from(allocator.alloc_str(&lit.value.to_string())), true) } PropertyKey::PrivateIdentifier(_) => return None, // Private fields not supported _ => { @@ -532,7 +532,7 @@ fn convert_template_literal<'a>( .map_or_else(|| quasi.value.raw.clone(), |cooked| cooked.clone()); let raw_text = quasi.value.raw.clone(); - elements.push(TemplateLiteralElement { text, raw_text, source_span: None }); + elements.push(TemplateLiteralElement { text: text.into(), raw_text: raw_text.into(), source_span: None }); } // Convert expressions diff --git a/crates/oxc_angular_compiler/src/parser/expression/lexer.rs b/crates/oxc_angular_compiler/src/parser/expression/lexer.rs index 8e24a0298..58a3ce233 100644 --- a/crates/oxc_angular_compiler/src/parser/expression/lexer.rs +++ b/crates/oxc_angular_compiler/src/parser/expression/lexer.rs @@ -5,7 +5,7 @@ //! Ported from Angular's `expression_parser/lexer.ts`. use oxc_allocator::{Allocator, FromIn}; -use oxc_span::Atom; +use oxc_span::Ident; use crate::util::chars; @@ -72,7 +72,7 @@ pub struct Token<'a> { /// The numeric value (for Number tokens). pub num_value: f64, /// The string value (for String/Identifier tokens). - pub str_value: Atom<'a>, + pub str_value: Ident<'a>, /// The string token kind (for String/Template tokens). pub str_kind: StringTokenKind, } @@ -84,7 +84,7 @@ impl<'a> Token<'a> { index: u32, end: u32, num_value: f64, - str_value: Atom<'a>, + str_value: Ident<'a>, str_kind: StringTokenKind, ) -> Self { Self { token_type, index, end, num_value, str_value, str_kind } @@ -97,7 +97,7 @@ impl<'a> Token<'a> { index, end, code as u32 as f64, - Atom::from_in(String::from(code), allocator), + Ident::from_in(String::from(code), allocator), StringTokenKind::Plain, ) } @@ -109,7 +109,7 @@ impl<'a> Token<'a> { index, end, 0.0, - Atom::from_in(text, allocator), + Ident::from_in(text, allocator), StringTokenKind::Plain, ) } @@ -121,7 +121,7 @@ impl<'a> Token<'a> { index, end, 0.0, - Atom::from_in(text, allocator), + Ident::from_in(text, allocator), StringTokenKind::Plain, ) } @@ -133,7 +133,7 @@ impl<'a> Token<'a> { index, end, 0.0, - Atom::from_in(text, allocator), + Ident::from_in(text, allocator), StringTokenKind::Plain, ) } @@ -145,7 +145,7 @@ impl<'a> Token<'a> { index, end, 0.0, - Atom::from_in(text, allocator), + Ident::from_in(text, allocator), StringTokenKind::Plain, ) } @@ -157,7 +157,7 @@ impl<'a> Token<'a> { index, end, 0.0, - Atom::from_in(text, allocator), + Ident::from_in(text, allocator), StringTokenKind::Plain, ) } @@ -169,7 +169,7 @@ impl<'a> Token<'a> { index, end, value, - Atom::from_in("", allocator), + Ident::from_in("", allocator), StringTokenKind::Plain, ) } @@ -181,7 +181,7 @@ impl<'a> Token<'a> { index, end, 0.0, - Atom::from_in(message, allocator), + Ident::from_in(message, allocator), StringTokenKind::Plain, ) } @@ -198,7 +198,7 @@ impl<'a> Token<'a> { index, end, 0.0, - Atom::from_in(text, allocator), + Ident::from_in(text, allocator), StringTokenKind::TemplateLiteralEnd, ) } @@ -210,7 +210,7 @@ impl<'a> Token<'a> { index, end, 0.0, - Atom::from_in(text, allocator), + Ident::from_in(text, allocator), StringTokenKind::TemplateLiteralPart, ) } @@ -222,7 +222,7 @@ impl<'a> Token<'a> { index, end, 0.0, - Atom::from_in(text, allocator), + Ident::from_in(text, allocator), StringTokenKind::TemplateLiteralPart, ) } @@ -234,7 +234,7 @@ impl<'a> Token<'a> { index, end, 0.0, - Atom::from_in(text, allocator), + Ident::from_in(text, allocator), StringTokenKind::TemplateLiteralEnd, ) } @@ -246,7 +246,7 @@ impl<'a> Token<'a> { index, end, 0.0, - Atom::from_in(text, allocator), + Ident::from_in(text, allocator), StringTokenKind::Plain, ) } @@ -258,7 +258,7 @@ impl<'a> Token<'a> { index, end, 0.0, - Atom::from_in(text, allocator), + Ident::from_in(text, allocator), StringTokenKind::Plain, ) } diff --git a/crates/oxc_angular_compiler/src/parser/expression/mod.rs b/crates/oxc_angular_compiler/src/parser/expression/mod.rs index 1cb19d9d4..3aa5f8f84 100644 --- a/crates/oxc_angular_compiler/src/parser/expression/mod.rs +++ b/crates/oxc_angular_compiler/src/parser/expression/mod.rs @@ -223,7 +223,7 @@ impl<'a> BindingParser<'a> { ) -> TemplateBindingParseResult<'a> { let parser = Parser::with_offset(self.allocator, template_value, value_span.start); let key_identifier = TemplateBindingIdentifier { - source: oxc_span::Atom::from(template_key), + source: oxc_span::Ident::from(template_key), span: AbsoluteSourceSpan::new(key_span.start, key_span.end), }; parser.parse_template_bindings(key_identifier) diff --git a/crates/oxc_angular_compiler/src/parser/expression/parser.rs b/crates/oxc_angular_compiler/src/parser/expression/parser.rs index 4fc6fbb6a..f605e88b2 100644 --- a/crates/oxc_angular_compiler/src/parser/expression/parser.rs +++ b/crates/oxc_angular_compiler/src/parser/expression/parser.rs @@ -5,7 +5,7 @@ //! Ported from Angular's `expression_parser/parser.ts`. use oxc_allocator::{Allocator, Box, FromIn, Vec}; -use oxc_span::Atom; +use oxc_span::Ident; use crate::ast::expression::{ ASTWithSource, AbsoluteSourceSpan, AngularExpression, ArrowFunction, ArrowFunctionParameter, @@ -314,7 +314,7 @@ impl<'a> Parser<'a> { let source_span = span.to_absolute(absolute_offset); let value = match input { - Some(s) => LiteralValue::String(Atom::from_in(s, self.allocator)), + Some(s) => LiteralValue::String(Ident::from_in(s, self.allocator)), None => LiteralValue::Null, }; @@ -323,8 +323,8 @@ impl<'a> Parser<'a> { ASTWithSource { ast, - source: input.map(|s| Atom::from_in(s, self.allocator)), - location: Atom::from_in(location, self.allocator), + source: input.map(|s| Ident::from_in(s, self.allocator)), + location: Ident::from_in(location, self.allocator), absolute_offset, } } @@ -512,8 +512,8 @@ impl<'a> Parser<'a> { } else { Some(ASTWithSource { ast: value, - source: Some(Atom::from_in(value_source, self.allocator)), - location: Atom::from_in("", self.allocator), + source: Some(Ident::from_in(value_source, self.allocator)), + location: Ident::from_in("", self.allocator), absolute_offset: self.absolute_offset + start, }) }; @@ -597,7 +597,7 @@ impl<'a> Parser<'a> { end: u32, ) -> TemplateBindingIdentifier<'a> { TemplateBindingIdentifier { - source: Atom::from_in(source, self.allocator), + source: Ident::from_in(source, self.allocator), span: AbsoluteSourceSpan::new(start, end), } } @@ -747,8 +747,8 @@ impl<'a> Parser<'a> { let value_source = &self.source[expr_start as usize..value_end as usize]; let ast_with_source = ASTWithSource { ast: value, - source: Some(Atom::from_in(value_source, self.allocator)), - location: Atom::from_in("", self.allocator), + source: Some(Ident::from_in(value_source, self.allocator)), + location: Ident::from_in("", self.allocator), absolute_offset: self.absolute_offset + expr_start, }; @@ -996,7 +996,7 @@ impl<'a> Parser<'a> { { // Add text before the interpolation let text = &self.source[current_pos..abs_start]; - strings.push(Atom::from_in(text, self.allocator)); + strings.push(Ident::from_in(text, self.allocator)); let expr_text = &self.source[expr_start..expr_start + end_idx]; @@ -1016,13 +1016,13 @@ impl<'a> Parser<'a> { // Treat the {{ and everything after as literal text // by adding all remaining text to strings and exiting let text = &self.source[current_pos..]; - strings.push(Atom::from_in(text, self.allocator)); + strings.push(Ident::from_in(text, self.allocator)); break; } } else { // No more interpolations - add remaining text and exit let text = &self.source[current_pos..]; - strings.push(Atom::from_in(text, self.allocator)); + strings.push(Ident::from_in(text, self.allocator)); break; } } @@ -1031,7 +1031,7 @@ impl<'a> Parser<'a> { // all input including the last "}}"), we still need to add the trailing string. // This ensures strings.len() == expressions.len() + 1 for proper interleaving. if !expressions.is_empty() && strings.len() == expressions.len() { - strings.push(Atom::from_in("", self.allocator)); + strings.push(Ident::from_in("", self.allocator)); } if expressions.is_empty() { @@ -1861,7 +1861,7 @@ impl<'a> Parser<'a> { let span = ParseSpan::new(start, end); let source_span = span.to_absolute(self.absolute_offset); let name_span = source_span; - let empty_name = Atom::from_in("", self.allocator); + let empty_name = Ident::from_in("", self.allocator); if safe { let read = SafePropertyRead { span, @@ -1990,7 +1990,7 @@ impl<'a> Parser<'a> { let span = ParseSpan::new(start, end); let source_span = span.to_absolute(self.absolute_offset); let name_span = source_span; // Empty name span at end - let empty_name = Atom::from_in("", self.allocator); + let empty_name = Ident::from_in("", self.allocator); if safe { let read = @@ -2160,7 +2160,7 @@ impl<'a> Parser<'a> { &mut self, receiver: AngularExpression<'a>, start: u32, - name: Atom<'a>, + name: Ident<'a>, name_start: u32, name_end: u32, safe: bool, @@ -2889,7 +2889,7 @@ impl<'a> Parser<'a> { )); self.advance(); let key = LiteralMapKey::Property(LiteralMapPropertyKey { - key: Atom::from_in("", self.allocator), + key: Ident::from_in("", self.allocator), quoted: false, is_shorthand_initialized: false, }); @@ -2944,7 +2944,7 @@ impl<'a> Parser<'a> { self.error("Missing expected identifier, keyword, or string"); let key = LiteralMapKey::Property(LiteralMapPropertyKey { - key: Atom::from_in("", self.allocator), + key: Ident::from_in("", self.allocator), quoted: false, is_shorthand_initialized: false, }); @@ -3014,13 +3014,13 @@ impl<'a> Parser<'a> { // The fullSpanEnd tracks whitespace after the pipe character let full_span_end = self.peek().map(|t| t.index).unwrap_or(self.source.len() as u32); - (Atom::from_in("", self.allocator), full_span_end, Some(full_span_end)) + (Ident::from_in("", self.allocator), full_span_end, Some(full_span_end)) } } else { // End of input - create empty pipe name self.error("Unexpected end of input, expected identifier or keyword"); let end_pos = self.source.len() as u32; - (Atom::from_in("", self.allocator), end_pos, Some(end_pos)) + (Ident::from_in("", self.allocator), end_pos, Some(end_pos)) }; // Parse pipe arguments @@ -3251,7 +3251,7 @@ mod tests { let allocator = Allocator::default(); let parser = Parser::new(&allocator, "condition"); let key = TemplateBindingIdentifier { - source: Atom::from("ngIf"), + source: Ident::from("ngIf"), span: AbsoluteSourceSpan::new(0, 4), }; let result = parser.parse_template_bindings(key); @@ -3275,7 +3275,7 @@ mod tests { let allocator = Allocator::default(); let parser = Parser::new(&allocator, "let item of items"); let key = TemplateBindingIdentifier { - source: Atom::from("ngFor"), + source: Ident::from("ngFor"), span: AbsoluteSourceSpan::new(0, 5), }; let result = parser.parse_template_bindings(key); @@ -3317,7 +3317,7 @@ mod tests { let allocator = Allocator::default(); let parser = Parser::new(&allocator, "let item of items; let i = index"); let key = TemplateBindingIdentifier { - source: Atom::from("ngFor"), + source: Ident::from("ngFor"), span: AbsoluteSourceSpan::new(0, 5), }; let result = parser.parse_template_bindings(key); @@ -3367,7 +3367,7 @@ mod tests { let allocator = Allocator::default(); let parser = Parser::new(&allocator, "let item of items; trackBy: trackByFn"); let key = TemplateBindingIdentifier { - source: Atom::from("ngFor"), + source: Ident::from("ngFor"), span: AbsoluteSourceSpan::new(0, 5), }; let result = parser.parse_template_bindings(key); @@ -3391,7 +3391,7 @@ mod tests { let allocator = Allocator::default(); let parser = Parser::new(&allocator, "obs$ | async as result"); let key = TemplateBindingIdentifier { - source: Atom::from("ngIf"), + source: Ident::from("ngIf"), span: AbsoluteSourceSpan::new(0, 4), }; let result = parser.parse_template_bindings(key); @@ -3437,7 +3437,7 @@ mod tests { let allocator = Allocator::default(); let parser = Parser::new(&allocator, "let item of items; index as i"); let key = TemplateBindingIdentifier { - source: Atom::from("ngFor"), + source: Ident::from("ngFor"), span: AbsoluteSourceSpan::new(0, 5), }; let result = parser.parse_template_bindings(key); diff --git a/crates/oxc_angular_compiler/src/parser/html/parser.rs b/crates/oxc_angular_compiler/src/parser/html/parser.rs index df1fb36f7..3fa2845c9 100644 --- a/crates/oxc_angular_compiler/src/parser/html/parser.rs +++ b/crates/oxc_angular_compiler/src/parser/html/parser.rs @@ -7,7 +7,7 @@ use std::sync::Arc; use oxc_allocator::{Allocator, Box, FromIn, Vec}; -use oxc_span::{Atom, Span}; +use oxc_span::{Ident, Span}; use crate::ast::html::{ BlockType, HtmlAttribute, HtmlBlock, HtmlBlockParameter, HtmlComment, HtmlDirective, @@ -202,7 +202,7 @@ impl<'a> HtmlParser<'a> { &mut self.blocks[idx], HtmlBlock { block_type: BlockType::If, - name: Atom::from(""), + name: Ident::from(""), parameters: Vec::new_in(self.allocator), children: Vec::new_in(self.allocator), span: Span::new(0, 0), @@ -223,7 +223,7 @@ impl<'a> HtmlParser<'a> { let element = std::mem::replace( &mut self.elements[idx], HtmlElement { - name: Atom::from(""), + name: Ident::from(""), component_prefix: None, component_tag_name: None, attrs: Vec::new_in(self.allocator), @@ -299,7 +299,7 @@ impl<'a> HtmlParser<'a> { &mut self.blocks[idx], HtmlBlock { block_type: BlockType::If, - name: Atom::from(""), + name: Ident::from(""), parameters: Vec::new_in(self.allocator), children: Vec::new_in(self.allocator), span: Span::new(0, 0), @@ -352,7 +352,7 @@ impl<'a> HtmlParser<'a> { let element = std::mem::replace( &mut self.elements[idx], HtmlElement { - name: Atom::from(""), + name: Ident::from(""), component_prefix: None, component_tag_name: None, attrs: Vec::new_in(self.allocator), @@ -374,7 +374,7 @@ impl<'a> HtmlParser<'a> { &mut self.blocks[idx], HtmlBlock { block_type: BlockType::If, - name: Atom::from(""), + name: Ident::from(""), parameters: Vec::new_in(self.allocator), children: Vec::new_in(self.allocator), span: Span::new(0, 0), @@ -395,7 +395,7 @@ impl<'a> HtmlParser<'a> { let mut element = std::mem::replace( &mut self.elements[match_elem_idx], HtmlElement { - name: Atom::from(""), + name: Ident::from(""), component_prefix: None, component_tag_name: None, attrs: Vec::new_in(self.allocator), @@ -626,9 +626,9 @@ impl<'a> HtmlParser<'a> { let is_void = is_void_element(&tag_name); let element = HtmlElement { - name: Atom::from_in(tag_name.clone(), self.allocator), - component_prefix: component_prefix.map(|p| Atom::from_in(p, self.allocator)), - component_tag_name: component_tag_name.map(|t| Atom::from_in(t, self.allocator)), + name: Ident::from_in(tag_name.clone(), self.allocator), + component_prefix: component_prefix.map(|p| Ident::from_in(p, self.allocator)), + component_tag_name: component_tag_name.map(|t| Ident::from_in(t, self.allocator)), attrs, directives, children: Vec::new_in(self.allocator), @@ -881,7 +881,7 @@ impl<'a> HtmlParser<'a> { for (token_type, parts, tok_span) in tokens { let mut arena_parts = Vec::new_in(self.allocator); for part in parts { - arena_parts.push(Atom::from_in(part, self.allocator)); + arena_parts.push(Ident::from_in(part, self.allocator)); } arena_tokens.push(InterpolatedToken { token_type, @@ -893,8 +893,8 @@ impl<'a> HtmlParser<'a> { }); let attr = HtmlAttribute { - name: Atom::from_in(name, self.allocator), - value: Atom::from_in(value, self.allocator), + name: Ident::from_in(name, self.allocator), + value: Ident::from_in(value, self.allocator), span, name_span, value_span, @@ -1064,14 +1064,14 @@ impl<'a> HtmlParser<'a> { for (token_type, parts, span) in tokens { let mut arena_parts = Vec::new_in(self.allocator); for part in parts { - arena_parts.push(Atom::from_in(part, self.allocator)); + arena_parts.push(Ident::from_in(part, self.allocator)); } arena_tokens.push(InterpolatedToken { token_type, parts: arena_parts, span }); } let span = self.make_span(start, end); let text_node = HtmlText { - value: Atom::from_in(text, self.allocator), + value: Ident::from_in(text, self.allocator), span, full_start, tokens: arena_tokens, @@ -1107,7 +1107,7 @@ impl<'a> HtmlParser<'a> { // Create element with no end span (incomplete) // Note: is_self_closing is false because this is an incomplete tag, not explicitly self-closing let element = HtmlElement { - name: Atom::from_in(tag_name.clone(), self.allocator), + name: Ident::from_in(tag_name.clone(), self.allocator), component_prefix: None, component_tag_name: None, attrs: Vec::new_in(self.allocator), @@ -1155,7 +1155,7 @@ impl<'a> HtmlParser<'a> { }; let span = self.make_span(start, end); - let comment = HtmlComment { value: Atom::from_in(value, self.allocator), span }; + let comment = HtmlComment { value: Ident::from_in(value, self.allocator), span }; Some(HtmlNode::Comment(Box::new_in(comment, self.allocator))) } @@ -1195,11 +1195,11 @@ impl<'a> HtmlParser<'a> { // CDATA content becomes a text node with a single text token let mut tokens = Vec::new_in(self.allocator); let mut parts = Vec::new_in(self.allocator); - parts.push(Atom::from_in(value.clone(), self.allocator)); + parts.push(Ident::from_in(value.clone(), self.allocator)); tokens.push(InterpolatedToken { token_type: InterpolatedTokenType::Text, parts, span }); // CDATA tokens don't have leading trivia stripped let text = HtmlText { - value: Atom::from_in(value, self.allocator), + value: Ident::from_in(value, self.allocator), span, full_start: None, tokens, @@ -1263,7 +1263,7 @@ impl<'a> HtmlParser<'a> { let parse_result = expr_parser.parse_binding(value_str, value_span); let let_decl = HtmlLetDeclaration { - name: Atom::from_in(name, self.allocator), + name: Ident::from_in(name, self.allocator), value: parse_result.ast, span, name_span, @@ -1338,8 +1338,8 @@ impl<'a> HtmlParser<'a> { let span = self.make_span(start, end); let expansion = HtmlExpansion { - switch_value: Atom::from_in(switch_value, self.allocator), - expansion_type: Atom::from_in(expansion_type, self.allocator), + switch_value: Ident::from_in(switch_value, self.allocator), + expansion_type: Ident::from_in(expansion_type, self.allocator), cases, span, switch_value_span, @@ -1419,7 +1419,7 @@ impl<'a> HtmlParser<'a> { let element = std::mem::replace( &mut self.elements[idx], HtmlElement { - name: Atom::from(""), + name: Ident::from(""), component_prefix: None, component_tag_name: None, attrs: Vec::new_in(self.allocator), @@ -1439,7 +1439,7 @@ impl<'a> HtmlParser<'a> { &mut self.blocks[idx], HtmlBlock { block_type: BlockType::If, - name: Atom::from(""), + name: Ident::from(""), parameters: Vec::new_in(self.allocator), children: Vec::new_in(self.allocator), span: Span::new(0, 0), @@ -1482,7 +1482,7 @@ impl<'a> HtmlParser<'a> { let expansion_span = self.make_span(exp_start, exp_end); Some(HtmlExpansionCase { - value: Atom::from_in(value, self.allocator), + value: Ident::from_in(value, self.allocator), expansion, span, value_span, @@ -1532,7 +1532,7 @@ impl<'a> HtmlParser<'a> { let param_end = param_token.end; let param_span = self.make_span(param_start, param_end); parameters.push(HtmlBlockParameter { - expression: Atom::from_in(¶m_text, self.allocator), + expression: Ident::from_in(¶m_text, self.allocator), span: param_span, }); } else { @@ -1554,7 +1554,7 @@ impl<'a> HtmlParser<'a> { let block = HtmlBlock { block_type, - name: Atom::from_in(name, self.allocator), + name: Ident::from_in(name, self.allocator), parameters, children: Vec::new_in(self.allocator), span, @@ -1661,8 +1661,8 @@ impl<'a> HtmlParser<'a> { let attr_name_span = self.make_span(attr_name_start, attr_name_end); attrs.push(HtmlAttribute { - name: Atom::from_in(attr_name, self.allocator), - value: Atom::from_in(attr_value, self.allocator), + name: Ident::from_in(attr_name, self.allocator), + value: Ident::from_in(attr_value, self.allocator), span: attr_span, name_span: attr_name_span, value_span, @@ -1687,7 +1687,7 @@ impl<'a> HtmlParser<'a> { let span = self.make_span(directive_start, directive_end); Some(HtmlDirective { - name: Atom::from_in(name, self.allocator), + name: Ident::from_in(name, self.allocator), attrs, span, name_span, diff --git a/crates/oxc_angular_compiler/src/parser/html/whitespace.rs b/crates/oxc_angular_compiler/src/parser/html/whitespace.rs index 43621a50b..c9978b686 100644 --- a/crates/oxc_angular_compiler/src/parser/html/whitespace.rs +++ b/crates/oxc_angular_compiler/src/parser/html/whitespace.rs @@ -10,7 +10,7 @@ //! Ported from Angular's `ml_parser/html_whitespaces.ts`. use oxc_allocator::{Allocator, Box, FromIn, Vec}; -use oxc_span::Atom; +use oxc_span::Ident; use crate::ast::html::{ HtmlAttribute, HtmlBlock, HtmlBlockParameter, HtmlComment, HtmlComponent, HtmlDirective, @@ -473,7 +473,7 @@ impl<'a> WhitespaceVisitor<'a> { // Process tokens let tokens = self.process_tokens(&text.tokens, context); - let value_atom = Atom::from_in(value.as_str(), self.allocator); + let value_atom = Ident::from_in(value.as_str(), self.allocator); Some(HtmlNode::Text(Box::new_in( HtmlText { value: value_atom, @@ -514,7 +514,7 @@ impl<'a> WhitespaceVisitor<'a> { } let mut parts = Vec::with_capacity_in(1, self.allocator); - parts.push(Atom::from_in(processed.as_str(), self.allocator)); + parts.push(Ident::from_in(processed.as_str(), self.allocator)); result.push(InterpolatedToken { token_type: token.token_type, diff --git a/crates/oxc_angular_compiler/src/pipe/compiler.rs b/crates/oxc_angular_compiler/src/pipe/compiler.rs index 82b545740..e0fc34ba3 100644 --- a/crates/oxc_angular_compiler/src/pipe/compiler.rs +++ b/crates/oxc_angular_compiler/src/pipe/compiler.rs @@ -3,7 +3,7 @@ //! Ported from Angular's `render3/r3_pipe_compiler.ts`. use oxc_allocator::{Allocator, Box, Vec}; -use oxc_span::Atom; +use oxc_span::Ident; use super::metadata::R3PipeMetadata; use crate::output::ast::{ @@ -65,7 +65,7 @@ fn build_definition_map<'a>( // name: literal(metadata.pipeName ?? metadata.name) let pipe_name = metadata.pipe_name.clone().unwrap_or_else(|| metadata.name.clone()); entries.push(LiteralMapEntry { - key: Atom::from("name"), + key: Ident::from("name"), value: OutputExpression::Literal(Box::new_in( LiteralExpr { value: LiteralValue::String(pipe_name), source_span: None }, allocator, @@ -75,14 +75,14 @@ fn build_definition_map<'a>( // type: metadata.type.value entries.push(LiteralMapEntry { - key: Atom::from("type"), + key: Ident::from("type"), value: metadata.r#type.clone_in(allocator), quoted: false, }); // pure: literal(metadata.pure) entries.push(LiteralMapEntry { - key: Atom::from("pure"), + key: Ident::from("pure"), value: OutputExpression::Literal(Box::new_in( LiteralExpr { value: LiteralValue::Boolean(metadata.pure), source_span: None }, allocator, @@ -93,7 +93,7 @@ fn build_definition_map<'a>( // standalone: only included if false (Angular's runtime defaults standalone to true) if !metadata.is_standalone { entries.push(LiteralMapEntry { - key: Atom::from("standalone"), + key: Ident::from("standalone"), value: OutputExpression::Literal(Box::new_in( LiteralExpr { value: LiteralValue::Boolean(false), source_span: None }, allocator, @@ -115,12 +115,12 @@ fn create_define_pipe_call<'a>( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(Identifiers::DEFINE_PIPE), + name: Ident::from(Identifiers::DEFINE_PIPE), optional: false, source_span: None, }, @@ -157,15 +157,15 @@ mod tests { #[test] fn test_compile_pure_pipe() { let allocator = Allocator::default(); - let name = Atom::from("TestPipe"); + let name = Ident::from("TestPipe"); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("TestPipe"), source_span: None }, + ReadVarExpr { name: Ident::from("TestPipe"), source_span: None }, &allocator, )); let metadata = R3PipeMetadata { name: name.clone(), - pipe_name: Some(Atom::from("test")), + pipe_name: Some(Ident::from("test")), r#type: type_expr, type_argument_count: 0, deps: None, @@ -187,9 +187,9 @@ mod tests { #[test] fn test_compile_impure_pipe() { let allocator = Allocator::default(); - let name = Atom::from("ImpurePipe"); + let name = Ident::from("ImpurePipe"); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("ImpurePipe"), source_span: None }, + ReadVarExpr { name: Ident::from("ImpurePipe"), source_span: None }, &allocator, )); @@ -214,16 +214,16 @@ mod tests { #[test] fn test_compile_standalone_pipe() { let allocator = Allocator::default(); - let name = Atom::from("StandalonePipe"); + let name = Ident::from("StandalonePipe"); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("StandalonePipe"), source_span: None }, + ReadVarExpr { name: Ident::from("StandalonePipe"), source_span: None }, &allocator, )); // Standalone = true means DON'T include standalone in output (it's the default) let metadata = R3PipeMetadata { name: name.clone(), - pipe_name: Some(Atom::from("standalone")), + pipe_name: Some(Ident::from("standalone")), r#type: type_expr, type_argument_count: 0, deps: None, @@ -242,16 +242,16 @@ mod tests { #[test] fn test_compile_non_standalone_pipe() { let allocator = Allocator::default(); - let name = Atom::from("NonStandalonePipe"); + let name = Ident::from("NonStandalonePipe"); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("NonStandalonePipe"), source_span: None }, + ReadVarExpr { name: Ident::from("NonStandalonePipe"), source_span: None }, &allocator, )); // Non-standalone pipes should include standalone: false let metadata = R3PipeMetadata { name: name.clone(), - pipe_name: Some(Atom::from("legacy")), + pipe_name: Some(Ident::from("legacy")), r#type: type_expr, type_argument_count: 0, deps: None, diff --git a/crates/oxc_angular_compiler/src/pipe/decorator.rs b/crates/oxc_angular_compiler/src/pipe/decorator.rs index 769970cb5..43340a70f 100644 --- a/crates/oxc_angular_compiler/src/pipe/decorator.rs +++ b/crates/oxc_angular_compiler/src/pipe/decorator.rs @@ -8,7 +8,7 @@ use oxc_ast::ast::{ Argument, Class, ClassElement, Decorator, Expression, MethodDefinitionKind, ObjectPropertyKind, PropertyKey, }; -use oxc_span::{Atom, Span}; +use oxc_span::{Ident, Span}; use super::metadata::R3PipeMetadata; use crate::factory::R3DependencyMetadata; @@ -21,13 +21,13 @@ use crate::output::ast::{OutputExpression, ReadVarExpr}; #[derive(Debug)] pub struct PipeMetadata<'a> { /// The name of the pipe class. - pub class_name: Atom<'a>, + pub class_name: Ident<'a>, /// Span of the class declaration. pub class_span: Span, /// The pipe name used in templates (from `@Pipe({name: '...'})`). - pub pipe_name: Option>, + pub pipe_name: Option>, /// Whether the pipe is pure (default: true). /// Pure pipes only transform when inputs change. @@ -46,7 +46,7 @@ impl<'a> PipeMetadata<'a> { /// Create a new PipeMetadata with defaults. pub fn new( _allocator: &'a Allocator, - class_name: Atom<'a>, + class_name: Ident<'a>, class_span: Span, implicit_standalone: bool, ) -> Self { @@ -109,7 +109,7 @@ pub fn extract_pipe_metadata<'a>( implicit_standalone: bool, ) -> Option> { // Get the class name - let class_name: Atom<'a> = class.id.as_ref()?.name.clone().into(); + let class_name: Ident<'a> = class.id.as_ref()?.name.clone().into(); let class_span = class.span; // Find the @Pipe decorator @@ -200,20 +200,20 @@ fn is_pipe_call(callee: &Expression<'_>) -> bool { } /// Get the name of a property key as a string. -fn get_property_key_name<'a>(key: &PropertyKey<'a>) -> Option> { +fn get_property_key_name<'a>(key: &PropertyKey<'a>) -> Option> { match key { PropertyKey::StaticIdentifier(id) => Some(id.name.clone().into()), - PropertyKey::StringLiteral(lit) => Some(lit.value.clone()), + PropertyKey::StringLiteral(lit) => Some(lit.value.clone().into()), _ => None, } } /// Extract a string value from an expression. -fn extract_string_value<'a>(expr: &Expression<'a>) -> Option> { +fn extract_string_value<'a>(expr: &Expression<'a>) -> Option> { match expr { - Expression::StringLiteral(lit) => Some(lit.value.clone()), + Expression::StringLiteral(lit) => Some(lit.value.clone().into()), Expression::TemplateLiteral(tpl) if tpl.expressions.is_empty() => { - tpl.quasis.first().and_then(|q| q.value.cooked.clone()) + tpl.quasis.first().and_then(|q| q.value.cooked.clone().map(Into::into)) } _ => None, } @@ -222,7 +222,7 @@ fn extract_string_value<'a>(expr: &Expression<'a>) -> Option> { /// Extract a boolean value from an expression. fn extract_boolean_value(expr: &Expression<'_>) -> Option { match expr { - Expression::BooleanLiteral(lit) => Some(lit.value), + Expression::BooleanLiteral(lit) => Some(lit.value.into()), _ => None, } } @@ -267,7 +267,7 @@ fn extract_param_dependency<'a>( let mut skip_self = false; let mut self_ = false; let mut host = false; - let mut attribute_name: Option> = None; + let mut attribute_name: Option> = None; for decorator in ¶m.decorators { if let Some(name) = get_decorator_name(&decorator.expression) { @@ -280,7 +280,7 @@ fn extract_param_dependency<'a>( // @Attribute('attrName') - extract the attribute name if let Expression::CallExpression(call) = &decorator.expression { if let Some(Argument::StringLiteral(s)) = call.arguments.first() { - attribute_name = Some(s.value.clone()); + attribute_name = Some(s.value.clone().into()); } } } @@ -314,7 +314,7 @@ fn extract_param_dependency<'a>( } /// Get the name of a decorator from its expression. -fn get_decorator_name<'a>(expr: &'a Expression<'a>) -> Option> { +fn get_decorator_name<'a>(expr: &'a Expression<'a>) -> Option> { match expr { // @Optional Expression::Identifier(id) => Some(id.name.clone().into()), @@ -342,7 +342,7 @@ fn extract_param_token<'a>( // Handle TSTypeReference: SomeClass, SomeModule, etc. if let oxc_ast::ast::TSType::TSTypeReference(type_ref) = ts_type { // Get the type name - let type_name: Atom<'a> = match &type_ref.type_name { + let type_name: Ident<'a> = match &type_ref.type_name { oxc_ast::ast::TSTypeName::IdentifierReference(id) => id.name.clone().into(), oxc_ast::ast::TSTypeName::QualifiedName(_) | oxc_ast::ast::TSTypeName::ThisExpression(_) => { diff --git a/crates/oxc_angular_compiler/src/pipe/definition.rs b/crates/oxc_angular_compiler/src/pipe/definition.rs index bd7474398..dbf18d984 100644 --- a/crates/oxc_angular_compiler/src/pipe/definition.rs +++ b/crates/oxc_angular_compiler/src/pipe/definition.rs @@ -209,18 +209,18 @@ mod tests { use crate::output::emitter::JsEmitter; use crate::pipe::metadata::R3PipeMetadataBuilder; use oxc_allocator::Box; - use oxc_span::Atom; + use oxc_span::Ident; #[test] fn test_generate_pure_pipe_definition() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("MyPipe"), source_span: None }, + ReadVarExpr { name: Ident::from("MyPipe"), source_span: None }, &allocator, )); - let metadata = R3PipeMetadataBuilder::new(Atom::from("MyPipe"), type_expr) - .pipe_name(Atom::from("myPipe")) + let metadata = R3PipeMetadataBuilder::new(Ident::from("MyPipe"), type_expr) + .pipe_name(Ident::from("myPipe")) .pure(true) .is_standalone(true) .build(); @@ -248,12 +248,12 @@ mod tests { fn test_generate_impure_pipe_definition() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("ImpurePipe"), source_span: None }, + ReadVarExpr { name: Ident::from("ImpurePipe"), source_span: None }, &allocator, )); - let metadata = R3PipeMetadataBuilder::new(Atom::from("ImpurePipe"), type_expr) - .pipe_name(Atom::from("impure")) + let metadata = R3PipeMetadataBuilder::new(Ident::from("ImpurePipe"), type_expr) + .pipe_name(Ident::from("impure")) .pure(false) .is_standalone(true) .build(); @@ -272,12 +272,12 @@ mod tests { fn test_generate_non_standalone_pipe_definition() { let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("LegacyPipe"), source_span: None }, + ReadVarExpr { name: Ident::from("LegacyPipe"), source_span: None }, &allocator, )); - let metadata = R3PipeMetadataBuilder::new(Atom::from("LegacyPipe"), type_expr) - .pipe_name(Atom::from("legacy")) + let metadata = R3PipeMetadataBuilder::new(Ident::from("LegacyPipe"), type_expr) + .pipe_name(Ident::from("legacy")) .pure(true) .is_standalone(false) .build(); @@ -298,12 +298,12 @@ mod tests { // This enables tree-shaking via the @__PURE__ annotation. let allocator = Allocator::default(); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("TreeShakablePipe"), source_span: None }, + ReadVarExpr { name: Ident::from("TreeShakablePipe"), source_span: None }, &allocator, )); - let metadata = R3PipeMetadataBuilder::new(Atom::from("TreeShakablePipe"), type_expr) - .pipe_name(Atom::from("treeshakable")) + let metadata = R3PipeMetadataBuilder::new(Ident::from("TreeShakablePipe"), type_expr) + .pipe_name(Ident::from("treeshakable")) .pure(true) .is_standalone(true) .build(); diff --git a/crates/oxc_angular_compiler/src/pipe/metadata.rs b/crates/oxc_angular_compiler/src/pipe/metadata.rs index c36d0b2fb..641997b61 100644 --- a/crates/oxc_angular_compiler/src/pipe/metadata.rs +++ b/crates/oxc_angular_compiler/src/pipe/metadata.rs @@ -3,7 +3,7 @@ //! Ported from Angular's `render3/r3_pipe_compiler.ts`. use oxc_allocator::{Box, Vec}; -use oxc_span::Atom; +use oxc_span::Ident; use crate::output::ast::OutputExpression; @@ -13,11 +13,11 @@ use crate::output::ast::OutputExpression; #[derive(Debug)] pub struct R3PipeMetadata<'a> { /// The TypeScript class name of the pipe. - pub name: Atom<'a>, + pub name: Ident<'a>, /// The actual pipe name used in templates (from `@Pipe({name: '...'})`). /// If None, the class name is used. - pub pipe_name: Option>, + pub pipe_name: Option>, /// Reference to the pipe class itself. pub r#type: OutputExpression<'a>, @@ -91,8 +91,8 @@ impl<'a> R3DependencyMetadata<'a> { /// Builder for creating pipe metadata. pub struct R3PipeMetadataBuilder<'a> { - name: Atom<'a>, - pipe_name: Option>, + name: Ident<'a>, + pipe_name: Option>, r#type: OutputExpression<'a>, type_argument_count: u32, deps: Option>>, @@ -102,7 +102,7 @@ pub struct R3PipeMetadataBuilder<'a> { impl<'a> R3PipeMetadataBuilder<'a> { /// Creates a new builder with required fields. - pub fn new(name: Atom<'a>, r#type: OutputExpression<'a>) -> Self { + pub fn new(name: Ident<'a>, r#type: OutputExpression<'a>) -> Self { Self { name, pipe_name: None, @@ -115,7 +115,7 @@ impl<'a> R3PipeMetadataBuilder<'a> { } /// Sets the pipe name (as used in templates). - pub fn pipe_name(mut self, name: Atom<'a>) -> Self { + pub fn pipe_name(mut self, name: Ident<'a>) -> Self { self.pipe_name = Some(name); self } @@ -167,14 +167,14 @@ mod tests { #[test] fn test_pipe_metadata_builder() { let allocator = Allocator::default(); - let name = Atom::from("TestPipe"); + let name = Ident::from("TestPipe"); let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("TestPipe"), source_span: None }, + ReadVarExpr { name: Ident::from("TestPipe"), source_span: None }, &allocator, )); let metadata = R3PipeMetadataBuilder::new(name.clone(), type_expr) - .pipe_name(Atom::from("test")) + .pipe_name(Ident::from("test")) .pure(true) .is_standalone(true) .build(); @@ -191,7 +191,7 @@ mod tests { let token = Box::new_in( OutputExpression::Literal(Box::new_in( LiteralExpr { - value: LiteralValue::String(Atom::from("MyService")), + value: LiteralValue::String(Ident::from("MyService")), source_span: None, }, &allocator, diff --git a/crates/oxc_angular_compiler/src/pipeline/compilation.rs b/crates/oxc_angular_compiler/src/pipeline/compilation.rs index 99b3e3354..ae8113bbe 100644 --- a/crates/oxc_angular_compiler/src/pipeline/compilation.rs +++ b/crates/oxc_angular_compiler/src/pipeline/compilation.rs @@ -9,7 +9,7 @@ use indexmap::IndexMap; use oxc_allocator::{Allocator, Box, Vec}; use oxc_diagnostics::OxcDiagnostic; -use oxc_span::{Atom, Span}; +use oxc_span::{Ident, Span}; use rustc_hash::{FxBuildHasher, FxHashMap}; use crate::AngularVersion; @@ -86,18 +86,18 @@ pub enum DeferMetadata<'a> { #[derive(Debug)] pub struct I18nMessageMetadata<'a> { /// Message ID (computed). - pub message_id: Option>, + pub message_id: Option>, /// Custom ID supplied by the author. - pub custom_id: Option>, + pub custom_id: Option>, /// Message meaning for disambiguation. - pub meaning: Option>, + pub meaning: Option>, /// Message description for translators. - pub description: Option>, + pub description: Option>, /// Legacy message IDs. - pub legacy_ids: Vec<'a, Atom<'a>>, + pub legacy_ids: Vec<'a, Ident<'a>>, /// The serialized message string for goog.getMsg and $localize. /// Contains the message text with placeholder markers like "{$interpolation}". - pub message_string: Option>, + pub message_string: Option>, } /// A complete compilation job for a single component template. @@ -108,7 +108,7 @@ pub struct ComponentCompilationJob<'a> { /// The allocator for this compilation. pub allocator: &'a Allocator, /// Name of the component being compiled. - pub component_name: Atom<'a>, + pub component_name: Ident<'a>, /// Constant pool for deduplication. pub pool: ConstantPool<'a>, /// Expression store for managing expressions by reference. @@ -156,7 +156,7 @@ pub struct ComponentCompilationJob<'a> { /// /// Used to generate unique, file-based variable names for i18n translations. /// The path is sanitized to create a valid identifier suffix. - pub relative_context_file_path: Option>, + pub relative_context_file_path: Option>, /// Relocation entries. pub relocation_entries: Vec<'a, RelocationEntry>, /// Whether to attach debug source locations. @@ -165,7 +165,7 @@ pub struct ComponentCompilationJob<'a> { pub enable_debug_locations: bool, /// Relative path to the template file for source location debugging. /// Required when `enable_debug_locations` is true. - pub relative_template_path: Option>, + pub relative_template_path: Option>, /// Template source text for computing line/column from byte offsets. /// Required when `enable_debug_locations` is true. pub template_source: Option<&'a str>, @@ -196,7 +196,7 @@ pub struct ComponentCompilationJob<'a> { impl<'a> ComponentCompilationJob<'a> { /// Creates a new compilation job. - pub fn new(allocator: &'a Allocator, component_name: Atom<'a>) -> Self { + pub fn new(allocator: &'a Allocator, component_name: Ident<'a>) -> Self { Self::with_pool_starting_index(allocator, component_name, 0) } @@ -210,7 +210,7 @@ impl<'a> ComponentCompilationJob<'a> { /// be created with `pool_starting_index: 3` to start with _c3. pub fn with_pool_starting_index( allocator: &'a Allocator, - component_name: Atom<'a>, + component_name: Ident<'a>, pool_starting_index: u32, ) -> Self { let root_xref = XrefId::new(0); @@ -408,7 +408,7 @@ pub struct ViewCompilationUnit<'a> { /// Number of variable slots needed. pub vars: Option, /// Generated function name. - pub fn_name: Option>, + pub fn_name: Option>, /// Declaration count for template compatibility. pub decl_count: Option, /// First child element/template xref. @@ -464,10 +464,10 @@ pub const CTX_REF: &str = "CTX_REF_MARKER"; #[derive(Debug)] pub struct ContextVariable<'a> { /// Variable name (the user-defined identifier). - pub name: Atom<'a>, + pub name: Ident<'a>, /// Variable value (the context property name, e.g., "$implicit"). /// If this equals `CTX_REF`, the variable represents the entire context object. - pub value: Atom<'a>, + pub value: Ident<'a>, /// Cross-reference to the variable's origin. pub xref: XrefId, } @@ -481,7 +481,7 @@ pub struct ContextVariable<'a> { #[derive(Debug)] pub struct AliasVariable<'a> { /// The user-visible identifier for this alias. - pub identifier: Atom<'a>, + pub identifier: Ident<'a>, /// The expression that computes this alias's value. /// This expression is cloned and inlined at every usage site. pub expression: crate::ir::expression::IrExpression<'a>, @@ -491,7 +491,7 @@ pub struct AliasVariable<'a> { #[derive(Debug)] pub enum ConstValue<'a> { /// A string constant. - String(Atom<'a>), + String(Ident<'a>), /// An array of constants (attribute arrays). Array(Vec<'a, ConstValue<'a>>), /// A number constant. @@ -535,9 +535,9 @@ impl<'a> ConstValue<'a> { #[derive(Debug)] pub struct ExternalRef<'a> { /// Module name (e.g., "@angular/core"). - pub module_name: Atom<'a>, + pub module_name: Ident<'a>, /// Export name. - pub name: Atom<'a>, + pub name: Ident<'a>, } /// A relocation entry for defer blocks. @@ -566,7 +566,7 @@ pub struct CompilationResult<'a> { /// A compiled template function. pub struct TemplateFn<'a> { /// Function name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Number of creation slots. pub creation_slots: u32, /// Number of variable slots. @@ -599,9 +599,9 @@ pub struct HostBindingCompilationJob<'a> { /// The allocator for this compilation. pub allocator: &'a Allocator, /// Name of the component/directive being compiled. - pub component_name: Atom<'a>, + pub component_name: Ident<'a>, /// The CSS selector for the component/directive. - pub component_selector: Atom<'a>, + pub component_selector: Ident<'a>, /// Constant pool for deduplication. pub pool: ConstantPool<'a>, /// Expression store for managing expressions by reference. @@ -615,7 +615,7 @@ pub struct HostBindingCompilationJob<'a> { /// Template compilation mode (always DomOnly for host bindings). pub mode: TemplateCompilationMode, /// Function name suffix. - pub fn_suffix: Atom<'a>, + pub fn_suffix: Ident<'a>, /// Diagnostics collected during compilation. pub diagnostics: std::vec::Vec, /// Angular version for version-gated instruction emission. @@ -626,8 +626,8 @@ impl<'a> HostBindingCompilationJob<'a> { /// Creates a new host binding compilation job. pub fn new( allocator: &'a Allocator, - component_name: Atom<'a>, - component_selector: Atom<'a>, + component_name: Ident<'a>, + component_selector: Ident<'a>, ) -> Self { Self::with_pool_starting_index(allocator, component_name, component_selector, 0) } @@ -646,8 +646,8 @@ impl<'a> HostBindingCompilationJob<'a> { /// compilation share the same ConstantPool instance. pub fn with_pool_starting_index( allocator: &'a Allocator, - component_name: Atom<'a>, - component_selector: Atom<'a>, + component_name: Ident<'a>, + component_selector: Ident<'a>, pool_starting_index: u32, ) -> Self { let root_xref = XrefId::new(0); @@ -663,7 +663,7 @@ impl<'a> HostBindingCompilationJob<'a> { next_xref_id: 1, // 0 is reserved for root compatibility_mode: CompatibilityMode::TemplateDefinitionBuilder, mode: TemplateCompilationMode::DomOnly, // Host bindings always use DomOnly - fn_suffix: Atom::from("HostBindings"), + fn_suffix: Ident::from("HostBindings"), diagnostics: std::vec::Vec::new(), angular_version: None, } @@ -731,7 +731,7 @@ pub struct HostBindingCompilationUnit<'a> { /// Number of variable slots needed. pub vars: Option, /// Generated function name. - pub fn_name: Option>, + pub fn_name: Option>, } impl<'a> HostBindingCompilationUnit<'a> { @@ -760,14 +760,14 @@ pub enum FnStatement<'a> { /// A runtime instruction call. Instruction(Instruction<'a>), /// A variable declaration. - VarDecl(Atom<'a>), + VarDecl(Ident<'a>), } /// A runtime instruction call. #[derive(Debug)] pub struct Instruction<'a> { /// Instruction name (e.g., "ɵɵelement"). - pub name: Atom<'a>, + pub name: Ident<'a>, /// Arguments to the instruction. pub args: Vec<'a, InstructionArg<'a>>, } @@ -782,5 +782,5 @@ pub enum InstructionArg<'a> { /// A slot reference. Slot(u32), /// An expression string. - Expression(Atom<'a>), + Expression(Ident<'a>), } diff --git a/crates/oxc_angular_compiler/src/pipeline/constant_pool.rs b/crates/oxc_angular_compiler/src/pipeline/constant_pool.rs index c6cb2ed2b..a44b43e36 100644 --- a/crates/oxc_angular_compiler/src/pipeline/constant_pool.rs +++ b/crates/oxc_angular_compiler/src/pipeline/constant_pool.rs @@ -6,7 +6,7 @@ //! Ported from Angular's `constant_pool.ts`. use oxc_allocator::{Allocator, Box, Vec}; -use oxc_span::Atom; +use oxc_span::Ident; use rustc_hash::FxHashMap; use crate::ir::expression::IrExpression; @@ -108,7 +108,7 @@ impl<'a> ConstantPool<'a> { let index = self.values.len() as u32; let name = self.generate_name("_c"); - let atom = Atom::from(self.allocator.alloc_str(value)); + let atom = Ident::from(self.allocator.alloc_str(value)); self.values.push(PooledConstant { name: name.clone(), @@ -168,10 +168,10 @@ impl<'a> ConstantPool<'a> { } /// Generates a unique name for a pooled constant. - fn generate_name(&mut self, prefix: &str) -> Atom<'a> { + fn generate_name(&mut self, prefix: &str) -> Ident<'a> { let name = format!("{}{}", prefix, self.next_name_index); self.next_name_index += 1; - Atom::from(self.allocator.alloc_str(&name)) + Ident::from(self.allocator.alloc_str(&name)) } /// Gets the constant at the given index. @@ -193,8 +193,8 @@ impl<'a> ConstantPool<'a> { let index = self.values.len() as u32; let name = self.generate_name("_c"); - let body_atom = Atom::from(self.allocator.alloc_str(body)); - let flags_atom = flags.map(|f| Atom::from(self.allocator.alloc_str(f))); + let body_atom = Ident::from(self.allocator.alloc_str(body)); + let flags_atom = flags.map(|f| Ident::from(self.allocator.alloc_str(f))); self.values.push(PooledConstant { name: name.clone(), @@ -230,7 +230,7 @@ impl<'a> ConstantPool<'a> { num_args: u32, body_key: &str, body_expr: IrExpression<'a>, - ) -> (u32, Atom<'a>) { + ) -> (u32, Ident<'a>) { // Create a key for deduplication based on arg count and body let key = format!("pf:{}:{}", num_args, body_key); @@ -247,7 +247,7 @@ impl<'a> ConstantPool<'a> { // Generate parameter names: a0, a1, a2, ... let mut params = Vec::with_capacity_in(num_args as usize, self.allocator); for i in 0..num_args { - params.push(Atom::from(self.allocator.alloc_str(&format!("a{}", i)))); + params.push(Ident::from(self.allocator.alloc_str(&format!("a{}", i)))); } // Store the actual body expression @@ -404,7 +404,7 @@ impl<'a> ConstantPool<'a> { /// * `base` - The base name to make unique /// * `always_include_suffix` - If `true`, always append a numeric suffix. /// If `false`, only append suffix if the name has been used before. - pub fn unique_name(&mut self, base: &str, always_include_suffix: bool) -> Atom<'a> { + pub fn unique_name(&mut self, base: &str, always_include_suffix: bool) -> Ident<'a> { // Get the per-base-name count for deduplication within this component let count = self.claimed_names.get(base).copied().unwrap_or(0); @@ -424,7 +424,7 @@ impl<'a> ConstantPool<'a> { // Increment the per-base-name counter self.claimed_names.insert(base.to_string(), count + 1); - Atom::from(self.allocator.alloc_str(&name)) + Ident::from(self.allocator.alloc_str(&name)) } /// Gets or creates a constant literal and returns a reference expression. @@ -513,7 +513,7 @@ pub struct PooledValue { #[derive(Debug)] pub struct PooledConstant<'a> { /// Generated variable name. - pub name: Atom<'a>, + pub name: Ident<'a>, /// Value reference. pub value: PooledValue, /// The constant's kind and value. @@ -524,7 +524,7 @@ pub struct PooledConstant<'a> { #[derive(Debug)] pub enum PooledConstantKind<'a> { /// A string literal. - String(Atom<'a>), + String(Ident<'a>), /// A number literal. Number(f64), /// A boolean literal. @@ -534,7 +534,7 @@ pub enum PooledConstantKind<'a> { /// A placeholder for an array (content not yet known). ArrayPlaceholder, /// An object literal. - Object(Vec<'a, (Atom<'a>, PooledConstantKind<'a>)>), + Object(Vec<'a, (Ident<'a>, PooledConstantKind<'a>)>), /// An external reference. External(ExternalReference<'a>), /// A pure function wrapper. @@ -550,18 +550,18 @@ pub enum PooledConstantKind<'a> { #[derive(Debug)] pub struct RegexConstant<'a> { /// The regex pattern body. - pub body: Atom<'a>, + pub body: Ident<'a>, /// The regex flags. - pub flags: Option>, + pub flags: Option>, } /// An external reference (import). #[derive(Debug)] pub struct ExternalReference<'a> { /// Module to import from. - pub module: Atom<'a>, + pub module: Ident<'a>, /// Name to import. - pub name: Atom<'a>, + pub name: Ident<'a>, } /// A pure function definition. @@ -574,7 +574,7 @@ pub struct ExternalReference<'a> { #[derive(Debug)] pub struct PureFunctionDef<'a> { /// Parameter names (a0, a1, a2, ...). - pub params: Vec<'a, Atom<'a>>, + pub params: Vec<'a, Ident<'a>>, /// Body expression - the actual IR expression to emit. /// /// This expression may contain `PureFunctionParameterExpr` nodes that diff --git a/crates/oxc_angular_compiler/src/pipeline/conversion.rs b/crates/oxc_angular_compiler/src/pipeline/conversion.rs index 917573944..f8f66175c 100644 --- a/crates/oxc_angular_compiler/src/pipeline/conversion.rs +++ b/crates/oxc_angular_compiler/src/pipeline/conversion.rs @@ -7,7 +7,7 @@ //! and `template/pipeline/src/conversion.ts`. use oxc_allocator::{Allocator, Box, Vec}; -use oxc_span::{Atom, Span}; +use oxc_span::{Ident, Span}; use crate::ast::expression::{ AbsoluteSourceSpan, AngularExpression, BinaryOperator as AstBinaryOperator, LiteralMapKey, @@ -199,10 +199,10 @@ pub fn convert_unary_operator(op: AstUnaryOperator) -> OutputUnaryOperator { /// - `${` to prevent interpolation syntax /// - Backslashes to preserve escape sequences /// - Carriage returns and line feeds to their escape sequences -fn cooked_to_raw_text<'a>(allocator: &'a Allocator, cooked: &str) -> Atom<'a> { +fn cooked_to_raw_text<'a>(allocator: &'a Allocator, cooked: &str) -> Ident<'a> { // Fast path: if no escaping needed, return as-is if !cooked.contains(['`', '$', '\\', '\r', '\n']) { - return Atom::from(allocator.alloc_str(cooked)); + return Ident::from(allocator.alloc_str(cooked)); } // Escape special characters @@ -225,7 +225,7 @@ fn cooked_to_raw_text<'a>(allocator: &'a Allocator, cooked: &str) -> Atom<'a> { _ => raw.push(c), } } - Atom::from(allocator.alloc_str(&raw)) + Ident::from(allocator.alloc_str(&raw)) } // ============================================================================ diff --git a/crates/oxc_angular_compiler/src/pipeline/emit.rs b/crates/oxc_angular_compiler/src/pipeline/emit.rs index 0a15550be..cf1f22b7c 100644 --- a/crates/oxc_angular_compiler/src/pipeline/emit.rs +++ b/crates/oxc_angular_compiler/src/pipeline/emit.rs @@ -15,7 +15,7 @@ use crate::output::ast::{ }; use crate::r3::{Identifiers, get_interpolate_instruction, get_pipe_bind_instruction}; use oxc_allocator::Box; -use oxc_span::Atom; +use oxc_span::Ident; use crate::ir::ops::XrefId; @@ -138,8 +138,8 @@ fn emit_view<'a>(allocator: &'a Allocator, view: &ViewCompilationUnit<'a>) -> Fu // - rf: Render flags (1 = create, 2 = update) // - ctx: Component context (this) let mut params: OxcVec<'a, FnParam<'a>> = OxcVec::new_in(allocator); - params.push(FnParam { name: Atom::from("rf") }); - params.push(FnParam { name: Atom::from("ctx") }); + params.push(FnParam { name: Ident::from("rf") }); + params.push(FnParam { name: Ident::from("ctx") }); FunctionExpr { name: fn_name, params, statements: body, source_span: None } } @@ -186,7 +186,7 @@ fn maybe_generate_rf_block<'a>( operator: BinaryOperator::BitwiseAnd, lhs: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("rf"), source_span: None }, + ReadVarExpr { name: Ident::from("rf"), source_span: None }, allocator, )), allocator, @@ -250,8 +250,8 @@ pub fn emit_host_binding_function<'a>( // Create function parameters: (rf, ctx) let mut params: OxcVec<'a, FnParam<'a>> = OxcVec::new_in(allocator); - params.push(FnParam { name: Atom::from("rf") }); - params.push(FnParam { name: Atom::from("ctx") }); + params.push(FnParam { name: Ident::from("rf") }); + params.push(FnParam { name: Ident::from("ctx") }); Some(FunctionExpr { name: unit.fn_name.clone(), params, statements: body, source_span: None }) } @@ -369,7 +369,7 @@ pub fn emit_additional_pool_constants<'a>( fn convert_pure_function_body<'a>( allocator: &'a Allocator, expr: &IrExpression<'a>, - params: &[Atom<'a>], + params: &[Ident<'a>], ) -> OutputExpression<'a> { use crate::ir::expression::*; use crate::output::ast::*; @@ -381,7 +381,7 @@ fn convert_pure_function_body<'a>( params[pfp.index as usize].clone() } else { // Fallback if index out of range - Atom::from(allocator.alloc_str(&format!("a{}", pfp.index))) + Ident::from(allocator.alloc_str(&format!("a{}", pfp.index))) }; OutputExpression::ReadVar(Box::new_in( ReadVarExpr { name: param_name, source_span: None }, @@ -394,7 +394,7 @@ fn convert_pure_function_body<'a>( if lexical.name.as_str() == "ctx" { // Direct reference to context parameter - emit as just `ctx` OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("ctx"), source_span: None }, + ReadVarExpr { name: Ident::from("ctx"), source_span: None }, allocator, )) } else { @@ -403,7 +403,7 @@ fn convert_pure_function_body<'a>( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("ctx"), source_span: None }, + ReadVarExpr { name: Ident::from("ctx"), source_span: None }, allocator, )), allocator, @@ -419,13 +419,13 @@ fn convert_pure_function_body<'a>( // Context reference becomes ctx IrExpression::Context(_) => OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("ctx"), source_span: None }, + ReadVarExpr { name: Ident::from("ctx"), source_span: None }, allocator, )), // TrackContext reference becomes this (for track functions) IrExpression::TrackContext(_) => OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("this"), source_span: None }, + ReadVarExpr { name: Ident::from("this"), source_span: None }, allocator, )), @@ -434,7 +434,7 @@ fn convert_pure_function_body<'a>( let var_name = var .name .clone() - .unwrap_or_else(|| Atom::from(allocator.alloc_str(&format!("_v{}", var.xref.0)))); + .unwrap_or_else(|| Ident::from(allocator.alloc_str(&format!("_v{}", var.xref.0)))); OutputExpression::ReadVar(Box::new_in( ReadVarExpr { name: var_name, source_span: None }, allocator, @@ -443,7 +443,7 @@ fn convert_pure_function_body<'a>( // Read temporary variable IrExpression::ReadTemporary(tmp) => { - let var_name = tmp.name.clone().unwrap_or_else(|| Atom::from("_tmp")); + let var_name = tmp.name.clone().unwrap_or_else(|| Ident::from("_tmp")); OutputExpression::ReadVar(Box::new_in( ReadVarExpr { name: var_name, source_span: None }, allocator, @@ -452,7 +452,7 @@ fn convert_pure_function_body<'a>( // Assign temporary variable: _tmp = expr IrExpression::AssignTemporary(assign) => { - let var_name = assign.name.clone().unwrap_or_else(|| Atom::from("_tmp")); + let var_name = assign.name.clone().unwrap_or_else(|| Ident::from("_tmp")); let value = convert_pure_function_body(allocator, &assign.expr, params); OutputExpression::BinaryOperator(Box::new_in( BinaryOperatorExpr { @@ -533,8 +533,8 @@ fn convert_pure_function_body<'a>( OutputExpression::External(Box::new_in( ExternalExpr { value: ExternalReference { - module_name: Some(Atom::from("@angular/core")), - name: Some(Atom::from(allocator.alloc_str(instruction))), + module_name: Some(Ident::from("@angular/core")), + name: Some(Ident::from(allocator.alloc_str(instruction))), }, source_span: None, }, @@ -600,8 +600,8 @@ fn convert_pure_function_body<'a>( OutputExpression::External(Box::new_in( ExternalExpr { value: ExternalReference { - module_name: Some(Atom::from("@angular/core")), - name: Some(Atom::from(fn_name)), + module_name: Some(Ident::from("@angular/core")), + name: Some(Ident::from(fn_name)), }, source_span: None, }, @@ -643,8 +643,8 @@ fn convert_pure_function_body<'a>( OutputExpression::External(Box::new_in( ExternalExpr { value: ExternalReference { - module_name: Some(Atom::from("@angular/core")), - name: Some(Atom::from(Identifiers::PIPE_BIND_V)), + module_name: Some(Ident::from("@angular/core")), + name: Some(Ident::from(Identifiers::PIPE_BIND_V)), }, source_span: None, }, @@ -1005,8 +1005,8 @@ fn convert_pure_function_body<'a>( OutputExpression::External(Box::new_in( ExternalExpr { value: ExternalReference { - module_name: Some(Atom::from("@angular/core")), - name: Some(Atom::from(Identifiers::TWO_WAY_BINDING_SET)), + module_name: Some(Ident::from("@angular/core")), + name: Some(Ident::from(Identifiers::TWO_WAY_BINDING_SET)), }, source_span: None, }, @@ -1038,8 +1038,8 @@ fn convert_pure_function_body<'a>( OutputExpression::External(Box::new_in( ExternalExpr { value: ExternalReference { - module_name: Some(Atom::from("@angular/core")), - name: Some(Atom::from(Identifiers::READ_CONTEXT_LET)), + module_name: Some(Ident::from("@angular/core")), + name: Some(Ident::from(Identifiers::READ_CONTEXT_LET)), }, source_span: None, }, @@ -1066,8 +1066,8 @@ fn convert_pure_function_body<'a>( OutputExpression::External(Box::new_in( ExternalExpr { value: ExternalReference { - module_name: Some(Atom::from("@angular/core")), - name: Some(Atom::from(Identifiers::STORE_LET)), + module_name: Some(Ident::from("@angular/core")), + name: Some(Ident::from(Identifiers::STORE_LET)), }, source_span: None, }, @@ -1315,7 +1315,7 @@ fn convert_pure_function_body<'a>( fn convert_ast_for_pure_function_body<'a>( allocator: &'a Allocator, ast: &crate::ast::expression::AngularExpression<'a>, - params: &[Atom<'a>], + params: &[Ident<'a>], ) -> OutputExpression<'a> { use crate::ast::expression::{AngularExpression, LiteralMapKey}; use crate::output::ast::{LiteralArrayExpr, LiteralMapEntry, LiteralMapExpr}; @@ -1378,7 +1378,7 @@ fn convert_ast_for_pure_function_body<'a>( receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( crate::output::ast::ReadVarExpr { - name: Atom::from("ctx"), + name: Ident::from("ctx"), source_span: None, }, allocator, @@ -1629,7 +1629,7 @@ mod tests { #[test] fn test_empty_template() { let allocator = Allocator::default(); - let mut job = ComponentCompilationJob::new(&allocator, Atom::from("TestComponent")); + let mut job = ComponentCompilationJob::new(&allocator, Ident::from("TestComponent")); let result = compile_template(&mut job); diff --git a/crates/oxc_angular_compiler/src/pipeline/ingest.rs b/crates/oxc_angular_compiler/src/pipeline/ingest.rs index 2c956eeae..00723b51d 100644 --- a/crates/oxc_angular_compiler/src/pipeline/ingest.rs +++ b/crates/oxc_angular_compiler/src/pipeline/ingest.rs @@ -16,7 +16,7 @@ use oxc_allocator::{Allocator, Box, Vec}; use oxc_diagnostics::OxcDiagnostic; -use oxc_span::Atom; +use oxc_span::Ident; use super::compilation::{ CTX_REF, ComponentCompilationJob, DeferBlockDepsEmitMode, DeferMetadata, @@ -67,7 +67,7 @@ pub struct IngestOptions<'a> { /// Relative path to the context file for i18n suffix generation. /// /// Used to generate unique, file-based variable names for i18n translations. - pub relative_context_file_path: Option>, + pub relative_context_file_path: Option>, /// Whether to use external message IDs in i18n variable names. /// @@ -83,7 +83,7 @@ pub struct IngestOptions<'a> { pub defer_block_deps_emit_mode: DeferBlockDepsEmitMode, /// Relative path to the template file for source location debugging. - pub relative_template_path: Option>, + pub relative_template_path: Option>, /// Whether to enable debug source locations. /// @@ -635,7 +635,7 @@ fn convert_interpolation_to_ir<'a>( fn convert_interpolation_to_ir_with_i18n_placeholders<'a>( job: &mut ComponentCompilationJob<'a>, expr: AngularExpression<'a>, - i18n_placeholders: Vec<'a, Atom<'a>>, + i18n_placeholders: Vec<'a, Ident<'a>>, ) -> Box<'a, IrExpression<'a>> { let allocator = job.allocator; @@ -678,7 +678,7 @@ fn convert_interpolation_to_ir_with_i18n_placeholders<'a>( /// `ingest_component_with_options` directly. pub fn ingest_component<'a>( allocator: &'a Allocator, - component_name: Atom<'a>, + component_name: Ident<'a>, template: Vec<'a, R3Node<'a>>, ) -> ComponentCompilationJob<'a> { ingest_component_with_options(allocator, component_name, template, IngestOptions::default()) @@ -703,7 +703,7 @@ pub fn ingest_component<'a>( /// A `ComponentCompilationJob` ready for transformation phases. pub fn ingest_component_with_options<'a>( allocator: &'a Allocator, - component_name: Atom<'a>, + component_name: Ident<'a>, template: Vec<'a, R3Node<'a>>, options: IngestOptions<'a>, ) -> ComponentCompilationJob<'a> { @@ -814,7 +814,7 @@ fn ingest_text<'a>( job: &mut ComponentCompilationJob<'a>, view_xref: XrefId, text: R3Text<'a>, - icu_placeholder: Option>, + icu_placeholder: Option>, ) { let xref = job.allocate_xref_id(); @@ -840,7 +840,7 @@ fn ingest_bound_text<'a>( job: &mut ComponentCompilationJob<'a>, view_xref: XrefId, bound_text: R3BoundText<'a>, - icu_placeholder: Option>, + icu_placeholder: Option>, ) { let allocator = job.allocator; let xref = job.allocate_xref_id(); @@ -850,7 +850,7 @@ fn ingest_bound_text<'a>( base: CreateOpBase { source_span: Some(bound_text.source_span), ..Default::default() }, xref, slot: None, - initial_value: Atom::from(""), + initial_value: Ident::from(""), i18n_placeholder: None, icu_placeholder, }); @@ -861,7 +861,7 @@ fn ingest_bound_text<'a>( // Extract i18n placeholders from the bound text's i18n metadata // Ported from Angular's ingestBoundText (ingest.ts lines 485-495) - let i18n_placeholders: Vec<'_, Atom<'_>> = match &bound_text.i18n { + let i18n_placeholders: Vec<'_, Ident<'_>> = match &bound_text.i18n { Some(I18nMeta::Node(I18nNode::Container(container))) => { let mut placeholders = Vec::new_in(allocator); for child in container.children.iter() { @@ -947,7 +947,7 @@ fn ingest_icu<'a>(job: &mut ComponentCompilationJob<'a>, view_xref: XrefId, icu: } // Process vars (bound text expressions) - // In Rust, vars is typed as HashMap so no runtime check needed + // In Rust, vars is typed as HashMap so no runtime check needed for (placeholder_name, bound_text) in icu.vars { ingest_bound_text(job, view_xref, bound_text, Some(placeholder_name)); } @@ -1033,8 +1033,8 @@ fn ingest_element<'a>( let namespace = namespace_for_key(namespace_key); // Allocate the stripped element name in the arena - let tag: Atom<'a> = if namespace_key.is_some() { - Atom::from(allocator.alloc_str(element_name)) + let tag: Ident<'a> = if namespace_key.is_some() { + Ident::from(allocator.alloc_str(element_name)) } else { element.name.clone() }; @@ -1373,8 +1373,8 @@ fn ingest_static_attributes_with_i18n<'a>( // Split namespace from attribute name (e.g., `:xmlns:xlink` → namespace="xmlns", name="xlink") let (ns, local_name) = split_ns_name(name.as_str()); - let namespace = ns.map(|n| Atom::from(n)); - let local_name = Atom::from(local_name); + let namespace = ns.map(|n| Ident::from(n)); + let local_name = Ident::from(local_name); let extracted = ExtractedAttributeOp { base: CreateOpBase::default(), @@ -1415,8 +1415,8 @@ fn ingest_single_static_attribute<'a>( job: &mut ComponentCompilationJob<'a>, view_xref: XrefId, element_xref: XrefId, - name: Atom<'a>, - value: Atom<'a>, + name: Ident<'a>, + value: Ident<'a>, is_structural_template_attribute: bool, ) { use crate::output::ast::{LiteralExpr, LiteralValue, OutputExpression}; @@ -1453,8 +1453,8 @@ fn ingest_single_static_attribute<'a>( // For regular (non-structural) attributes, create ExtractedAttributeOp directly // Split namespace from attribute name (e.g., `:xmlns:xlink` → namespace="xmlns", name="xlink") let (ns, local_name) = split_ns_name(name.as_str()); - let namespace = ns.map(|n| Atom::from(n)); - let local_name = Atom::from(local_name); + let namespace = ns.map(|n| Ident::from(n)); + let local_name = Ident::from(local_name); let extracted = ExtractedAttributeOp { base: CreateOpBase::default(), @@ -1481,7 +1481,7 @@ fn ingest_bindings_owned<'a>( job: &mut ComponentCompilationJob<'a>, view_xref: XrefId, element_xref: XrefId, - tag: Option>, + tag: Option>, inputs: Vec<'a, R3BoundAttribute<'a>>, outputs: Vec<'a, R3BoundEvent<'a>>, ) { @@ -1620,7 +1620,7 @@ fn ingest_listener_owned<'a>( job: &mut ComponentCompilationJob<'a>, view_xref: XrefId, element_xref: XrefId, - tag: Option>, + tag: Option>, output: R3BoundEvent<'a>, ) { let allocator = job.allocator; @@ -1677,7 +1677,7 @@ fn ingest_listener_owned<'a>( // Create $event reference let event_ref = IrExpression::LexicalRead(Box::new_in( - LexicalReadExpr { name: Atom::from("$event"), source_span: None }, + LexicalReadExpr { name: Ident::from("$event"), source_span: None }, allocator, )); @@ -1816,7 +1816,7 @@ fn ingest_listener_owned<'a>( /// Checks if a template is an explicit `` (as opposed to a structural directive). /// Ported from Angular's `isPlainTemplate` in `ingest.ts`. -fn is_plain_template(tag_name: &Option) -> bool { +fn is_plain_template(tag_name: &Option) -> bool { tag_name.as_ref().map_or(false, |tag| tag.as_str() == NG_TEMPLATE_TAG_NAME) } @@ -1961,12 +1961,12 @@ fn ingest_template<'a>( // `tagName` for HTML. The sanitizeIdentifier function later replaces non-word chars with `_`. let fn_name_suffix = tag_name_without_namespace.map(|stripped_tag| { let suffix = prefix_with_namespace(stripped_tag, namespace); - Atom::from(allocator.alloc_str(&suffix)) + Ident::from(allocator.alloc_str(&suffix)) }); // Build the tag atom from the stripped tag name (without namespace prefix). // TypeScript passes `tagNameWithoutNamespace` to createTemplateOp (line 367). - let tag = tag_name_without_namespace.map(|s| Atom::from(allocator.alloc_str(s))); + let tag = tag_name_without_namespace.map(|s| Ident::from(allocator.alloc_str(s))); // Convert references to local refs - needed for template op creation let local_refs = ingest_references_owned(allocator, references); @@ -2177,7 +2177,7 @@ fn ingest_template<'a>( // NOTE: This happens AFTER children are ingested, matching Angular's order. for variable in variables { let context_value = if variable.value.is_empty() { - Atom::from("$implicit") + Ident::from("$implicit") } else { variable.value.clone() }; @@ -2354,7 +2354,7 @@ fn ingest_if_block<'a>( if let Some(view) = job.view_mut(branch_view_xref) { view.context_variables.push(ContextVariable { name: alias.name.clone(), - value: Atom::from(CTX_REF), + value: Ident::from(CTX_REF), xref: branch_view_xref, }); } @@ -2383,7 +2383,7 @@ fn ingest_if_block<'a>( // fn_name_suffix is hardcoded to "Conditional" without namespace prefix // This matches Angular's ingestIfBlock which passes 'Conditional' directly - let fn_name_suffix = Atom::from("Conditional"); + let fn_name_suffix = Ident::from("Conditional"); // Create the appropriate CREATE op // Namespace is always HTML for control flow blocks, matching Angular's hardcoded ir.Namespace.HTML @@ -2500,13 +2500,13 @@ fn ingest_for_block<'a>( // Create unique names for $index and $count that are suffixed with the view xref // to disambiguate nested @for loops. This matches Angular's TemplateDefinitionBuilder pattern. - let index_name: Atom<'a> = { + let index_name: Ident<'a> = { let s = allocator.alloc_str(&format!("ɵ$index_{}", body_xref.0)); - Atom::from(s) + Ident::from(s) }; - let count_name: Atom<'a> = { + let count_name: Ident<'a> = { let s = allocator.alloc_str(&format!("ɵ$count_{}", body_xref.0)); - Atom::from(s) + Ident::from(s) }; // Collect context variables and aliases for the body view @@ -2516,7 +2516,7 @@ fn ingest_for_block<'a>( // Add the item variable (maps to $implicit in the context) context_variables.push(ContextVariable { name: for_block.item.name.clone(), - value: Atom::from("$implicit"), + value: Ident::from("$implicit"), xref: body_xref, }); @@ -2556,7 +2556,7 @@ fn ingest_for_block<'a>( // This is the implicit $index variable (name and value are both $index) // Add both $index and the unique indexed name to context context_variables.push(ContextVariable { - name: Atom::from("$index"), + name: Ident::from("$index"), value: var.value.clone(), xref: body_xref, }); @@ -2570,7 +2570,7 @@ fn ingest_for_block<'a>( // This is the implicit $count variable (name and value are both $count) // Add both $count and the unique counted name to context context_variables.push(ContextVariable { - name: Atom::from("$count"), + name: Ident::from("$count"), value: var.value.clone(), xref: body_xref, }); @@ -2720,8 +2720,8 @@ fn ingest_for_block<'a>( fn get_computed_for_loop_variable_expression<'a>( allocator: &'a Allocator, value: &str, - index_name: &Atom<'a>, - count_name: &Atom<'a>, + index_name: &Ident<'a>, + count_name: &Ident<'a>, diagnostics: &mut std::vec::Vec, ) -> Result, ()> { match value { @@ -2797,7 +2797,7 @@ fn get_computed_for_loop_variable_expression<'a>( } /// Helper: create a LexicalRead expression -fn create_lexical_read<'a>(allocator: &'a Allocator, name: &Atom<'a>) -> IrExpression<'a> { +fn create_lexical_read<'a>(allocator: &'a Allocator, name: &Ident<'a>) -> IrExpression<'a> { IrExpression::LexicalRead(Box::new_in( LexicalReadExpr { name: name.clone(), source_span: None }, allocator, @@ -2822,7 +2822,7 @@ fn create_number_literal<'a>(allocator: &'a Allocator, value: f64) -> IrExpressi } /// Helper: create a string literal as an AST expression wrapped in IR -fn create_string_literal_atom<'a>(allocator: &'a Allocator, value: Atom<'a>) -> IrExpression<'a> { +fn create_string_literal_atom<'a>(allocator: &'a Allocator, value: Ident<'a>) -> IrExpression<'a> { use crate::ast::expression::{AbsoluteSourceSpan, LiteralPrimitive, LiteralValue, ParseSpan}; IrExpression::Ast(Box::new_in( @@ -2967,7 +2967,7 @@ fn ingest_switch_block<'a>( // fn_name_suffix is hardcoded to "Case" without namespace prefix // This matches Angular's ingestSwitchBlock which passes 'Case' directly - let fn_name_suffix = Atom::from("Case"); + let fn_name_suffix = Ident::from("Case"); // Create the appropriate CREATE op // Namespace is always HTML for control flow blocks, matching Angular's hardcoded ir.Namespace.HTML @@ -3099,7 +3099,7 @@ fn ingest_defer_view<'a>( // This TemplateOp will be reified to a `ɵɵdomTemplate()` call. // IMPORTANT: In Angular, TemplateOp.xref IS the embedded view's xref (secondaryView.xref). // We use the same pattern here so that defer_resolve_targets can find elements by view xref. - let fn_name_suffix = Some(Atom::from(job.allocator.alloc_str(&format!("Defer{suffix}")))); + let fn_name_suffix = Some(Ident::from(job.allocator.alloc_str(&format!("Defer{suffix}")))); // Convert i18n metadata to placeholder, matching Angular's ingestDeferView which passes // i18nMeta through to createTemplateOp. This enables propagate_i18n_blocks to wrap the @@ -3573,14 +3573,14 @@ fn ingest_references_owned<'a>( /// It mirrors Angular TypeScript's `HostBindingInput` interface in `ingest.ts`. pub struct HostBindingInput<'a> { /// Name of the component/directive. - pub component_name: Atom<'a>, + pub component_name: Ident<'a>, /// CSS selector of the component/directive. - pub component_selector: Atom<'a>, + pub component_selector: Ident<'a>, /// Host property bindings (`[prop]="expr"`). pub properties: Vec<'a, R3BoundAttribute<'a>>, /// Static host attributes (`attr="value"`). /// Uses OutputExpression to match TypeScript's `{[key: string]: o.Expression}`. - pub attributes: FxHashMap, crate::output::ast::OutputExpression<'a>>, + pub attributes: FxHashMap, crate::output::ast::OutputExpression<'a>>, /// Host event bindings (`(event)="handler"`). pub events: Vec<'a, R3BoundEvent<'a>>, } @@ -3996,7 +3996,7 @@ fn ingest_host_dom_property<'a>( let (binding_kind, name) = if property.name.starts_with("attr.") { // Handle `attr.` prefix let stripped = &property.name[5..]; - (BindingKind::Attribute, Atom::from(allocator.alloc_str(stripped))) + (BindingKind::Attribute, Ident::from(allocator.alloc_str(stripped))) } else { let kind = match property.binding_type { BindingType::Property => BindingKind::Property, @@ -4096,7 +4096,7 @@ fn extract_element_from_selector(selector: &str) -> Option { /// Uses OutputExpression directly to match TypeScript's `o.Expression` parameter. fn ingest_host_attribute<'a>( job: &mut HostBindingCompilationJob<'a>, - name: Atom<'a>, + name: Ident<'a>, value: crate::output::ast::OutputExpression<'a>, ) { use crate::ir::expression::IrExpression; @@ -4298,7 +4298,7 @@ fn ingest_control_flow_insertion_point<'a, 'b>( parent_xref: XrefId, xref: XrefId, children: &'b [R3Node<'a>], -) -> Option> { +) -> Option> { // Find the single root element or template let mut root: Option> = None; @@ -4484,12 +4484,12 @@ impl<'a, 'b> RootNodeRef<'a, 'b> { } } - fn tag_name(&self) -> Atom<'a> { + fn tag_name(&self) -> Ident<'a> { match self { RootNodeRef::Element(elem) => elem.name.clone(), RootNodeRef::Template(tmpl) => { // Template should have a tag_name since we checked for it - tmpl.tag_name.clone().unwrap_or_else(|| Atom::from("")) + tmpl.tag_name.clone().unwrap_or_else(|| Ident::from("")) } } } @@ -4514,12 +4514,12 @@ mod tests { let unexpected_i18n = I18nMeta::Message(I18nMessage { instance_id: 0, nodes: Vec::new_in(&allocator), - meaning: Atom::from(""), - description: Atom::from(""), - custom_id: Atom::from(""), - id: Atom::from(""), + meaning: Ident::from(""), + description: Ident::from(""), + custom_id: Ident::from(""), + id: Ident::from(""), legacy_ids: Vec::new_in(&allocator), - message_string: Atom::from(""), + message_string: Ident::from(""), }); let result = convert_i18n_meta_to_placeholder( @@ -4559,8 +4559,8 @@ mod tests { fn get_computed_for_loop_variable_expression_returns_err_for_unknown_var() { let allocator = Allocator::default(); let mut diagnostics = std::vec::Vec::new(); - let index_name = Atom::from("ɵ$index_0"); - let count_name = Atom::from("ɵ$count_0"); + let index_name = Ident::from("ɵ$index_0"); + let count_name = Ident::from("ɵ$count_0"); let result = get_computed_for_loop_variable_expression( &allocator, @@ -4583,8 +4583,8 @@ mod tests { #[test] fn get_computed_for_loop_variable_expression_returns_ok_for_known_vars() { let allocator = Allocator::default(); - let index_name = Atom::from("ɵ$index_0"); - let count_name = Atom::from("ɵ$count_0"); + let index_name = Ident::from("ɵ$index_0"); + let count_name = Ident::from("ɵ$count_0"); for var in &["$index", "$count", "$first", "$last", "$even", "$odd"] { let mut diagnostics = std::vec::Vec::new(); diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/attach_source_locations.rs b/crates/oxc_angular_compiler/src/pipeline/phases/attach_source_locations.rs index 555bca355..56127dc77 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/attach_source_locations.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/attach_source_locations.rs @@ -7,7 +7,7 @@ //! //! Ported from Angular's `template/pipeline/src/phases/attach_source_locations.ts`. -use oxc_span::Atom; +use oxc_span::Ident; use crate::ir::ops::{CreateOp, CreateOpBase, SourceLocationOp, XrefId}; use crate::pipeline::compilation::ComponentCompilationJob; @@ -110,7 +110,7 @@ pub fn attach_source_locations(job: &mut ComponentCompilationJob<'_>) { let source_op = CreateOp::SourceLocation(SourceLocationOp { base: CreateOpBase::default(), target: loc.target, - template_url: Atom::from(template_path.as_str()), + template_url: Ident::from(template_path.as_str()), line: loc.line, column: loc.column, }); diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/binding_specialization.rs b/crates/oxc_angular_compiler/src/pipeline/phases/binding_specialization.rs index d686b2d62..4528d1353 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/binding_specialization.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/binding_specialization.rs @@ -21,7 +21,7 @@ //! Ported from Angular's `template/pipeline/src/phases/binding_specialization.ts`. use oxc_allocator::Box; -use oxc_span::Atom; +use oxc_span::Ident; use rustc_hash::FxHashMap; use crate::ast::expression::{AbsoluteSourceSpan, AngularExpression, EmptyExpr, ParseSpan}; @@ -237,8 +237,8 @@ fn specialize_in_view<'a>( &mut binding.expression, create_placeholder_expression(allocator), ); - let ns_atom = namespace.map(|ns| Atom::from(ns)); - let local_atom = Atom::from(local_name); + let ns_atom = namespace.map(|ns| Ident::from(ns)); + let local_atom = Ident::from(local_name); let new_op = UpdateOp::Attribute(AttributeOp { base: UpdateOpBase { source_span, ..Default::default() }, target, @@ -473,8 +473,8 @@ pub fn specialize_bindings_for_host(job: &mut HostBindingCompilationJob<'_>) { &mut binding.expression, create_placeholder_expression(allocator), ); - let ns_atom = namespace.map(|ns| Atom::from(ns)); - let local_atom = Atom::from(local_name); + let ns_atom = namespace.map(|ns| Ident::from(ns)); + let local_atom = Ident::from(local_name); let new_op = UpdateOp::Attribute(AttributeOp { base: UpdateOpBase { source_span, ..Default::default() }, target, diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/const_collection.rs b/crates/oxc_angular_compiler/src/pipeline/phases/const_collection.rs index 2ec5d59e7..7a1aabab0 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/const_collection.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/const_collection.rs @@ -10,7 +10,7 @@ use oxc_allocator::Vec as OxcVec; use oxc_diagnostics::OxcDiagnostic; -use oxc_span::Atom; +use oxc_span::Ident; use rustc_hash::FxHashMap; use oxc_allocator::Box; @@ -31,10 +31,10 @@ use crate::pipeline::selector::{parse_selector_to_r3_selector, r3_selector_to_ou #[derive(Debug, Clone)] enum AttributeValue<'a> { /// A string literal value. - String(Atom<'a>), + String(Ident<'a>), /// An i18n variable reference (stores just the variable name for efficient comparison). /// This will be serialized as a ReadVar expression in the const array. - I18nVar(Atom<'a>), + I18nVar(Ident<'a>), } /// Marker values for attribute arrays (matches Angular's AttributeMarker enum). @@ -71,19 +71,19 @@ struct ElementAttributes<'a> { known: std::collections::HashMap>, /// Static attributes (namespace, name, value). /// Value can be a string literal or an expression (for i18n variable references). - attributes: std::vec::Vec<(Option>, Atom<'a>, Option>)>, + attributes: std::vec::Vec<(Option>, Ident<'a>, Option>)>, /// Class names. - classes: std::vec::Vec>, + classes: std::vec::Vec>, /// Style properties. - styles: std::vec::Vec<(Atom<'a>, Option>)>, + styles: std::vec::Vec<(Ident<'a>, Option>)>, /// Property bindings (just names for the const array). - bindings: std::vec::Vec>, + bindings: std::vec::Vec>, /// Template bindings. - template: std::vec::Vec>, + template: std::vec::Vec>, /// i18n attributes. - i18n: std::vec::Vec>, + i18n: std::vec::Vec>, /// The ngProjectAs selector value (if present). - project_as: Option>, + project_as: Option>, } impl<'a> ElementAttributes<'a> { @@ -296,7 +296,7 @@ impl<'a> ElementAttributes<'a> { } // Fall back to truthy expression check (for boolean attributes) - if attr.truthy_expression { Some(AttributeValue::String(Atom::from(""))) } else { None } + if attr.truthy_expression { Some(AttributeValue::String(Ident::from(""))) } else { None } } fn is_empty(&self) -> bool { diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/convert_animations.rs b/crates/oxc_angular_compiler/src/pipeline/phases/convert_animations.rs index fa0121b60..a89942192 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/convert_animations.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/convert_animations.rs @@ -38,7 +38,7 @@ fn get_animation_kind(name: &str) -> AnimationKind { /// Info needed to create Animation CreateOps. struct AnimationInfo<'a> { target: XrefId, - name: oxc_span::Atom<'a>, + name: oxc_span::Ident<'a>, animation_kind: AnimationKind, handler_ops: OxcVec<'a, UpdateOp<'a>>, source_span: Option, @@ -47,7 +47,7 @@ struct AnimationInfo<'a> { /// Info needed to create AnimationString CreateOps. struct AnimationStringInfo<'a> { target: XrefId, - name: oxc_span::Atom<'a>, + name: oxc_span::Ident<'a>, animation_kind: AnimationKind, expression: Box<'a, IrExpression<'a>>, source_span: Option, @@ -167,7 +167,7 @@ pub fn convert_animations(job: &mut ComponentCompilationJob<'_>) { // Third pass: insert Animation CreateOps into create list after their target elements if !animations_to_create.is_empty() || !strings_to_create.is_empty() { - let mut missing_targets: Vec> = Vec::new(); + let mut missing_targets: Vec> = Vec::new(); if let Some(view) = job.view_mut(view_xref) { // Process Animation ops (Value kind) diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/convert_i18n_bindings.rs b/crates/oxc_angular_compiler/src/pipeline/phases/convert_i18n_bindings.rs index 79a5321ff..8c9e2c3b7 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/convert_i18n_bindings.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/convert_i18n_bindings.rs @@ -69,7 +69,7 @@ struct ConversionInfo<'a> { op_ptr: NonNull>, target: XrefId, i18n_context: XrefId, - name: oxc_span::Atom<'a>, + name: oxc_span::Ident<'a>, source_span: Option, /// The expression (if it's an interpolation, we extract sub-expressions). expression: Option>, @@ -78,7 +78,7 @@ struct ConversionInfo<'a> { /// Information extracted from an Interpolation expression. struct InterpolationInfo<'a> { expressions: Vec>, - i18n_placeholders: Vec>, + i18n_placeholders: Vec>, } /// Processes update ops for a single view, converting i18n bindings. diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/create_i18n_contexts.rs b/crates/oxc_angular_compiler/src/pipeline/phases/create_i18n_contexts.rs index 432c24e5f..8f7232b6c 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/create_i18n_contexts.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/create_i18n_contexts.rs @@ -11,7 +11,7 @@ //! //! Ported from Angular's `template/pipeline/src/phases/create_i18n_contexts.ts`. -use oxc_span::Atom; +use oxc_span::Ident; use rustc_hash::FxHashMap; use crate::ir::enums::I18nContextKind; @@ -39,7 +39,7 @@ pub fn create_i18n_contexts(job: &mut ComponentCompilationJob<'_>) { is_create_op: bool, // true for ExtractedAttribute, false for update ops // Additional fields to uniquely identify the attribute target: XrefId, // Element xref this attribute belongs to - name: Atom<'a>, // Attribute name + name: Ident<'a>, // Attribute name } let mut attr_ops_needing_context: Vec> = Vec::new(); diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/expand_safe_reads.rs b/crates/oxc_angular_compiler/src/pipeline/phases/expand_safe_reads.rs index 0d57a08d9..4c4c6833f 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/expand_safe_reads.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/expand_safe_reads.rs @@ -287,7 +287,7 @@ where /// Data extracted from an access expression for processing. enum AccessInfo<'a> { /// Property read: `.name` - PropertyRead { name: oxc_span::Atom<'a>, source_span: Option }, + PropertyRead { name: oxc_span::Ident<'a>, source_span: Option }, /// Keyed read: `[key]` KeyedRead { key: IrExpression<'a>, source_span: Option }, /// Function call: `(args)` diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/extract_i18n_messages.rs b/crates/oxc_angular_compiler/src/pipeline/phases/extract_i18n_messages.rs index b72c6e90a..1d2df483d 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/extract_i18n_messages.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/extract_i18n_messages.rs @@ -7,7 +7,7 @@ use std::ptr::NonNull; -use oxc_span::Atom; +use oxc_span::Ident; use rustc_hash::FxHashMap; use crate::ir::enums::{I18nContextKind, I18nParamValueFlags}; @@ -57,7 +57,7 @@ pub fn extract_i18n_messages(job: &mut ComponentCompilationJob<'_>) { let mut i18n_blocks: FxHashMap, Option)> = FxHashMap::default(); // xref -> (root, context) let mut i18n_contexts: FxHashMap)> = FxHashMap::default(); // xref -> (kind, i18n_block) - let mut context_params: FxHashMap, Vec)>> = + let mut context_params: FxHashMap, Vec)>> = FxHashMap::default(); // Create an i18n message for each context. @@ -154,7 +154,7 @@ pub fn extract_i18n_messages(job: &mut ComponentCompilationJob<'_>) { // Third pass: handle ICU sub-messages // Collect ICU info first to avoid borrow issues - let mut icu_sub_message_associations: Vec<(XrefId, XrefId, Option>)> = Vec::new(); + let mut icu_sub_message_associations: Vec<(XrefId, XrefId, Option>)> = Vec::new(); for view_xref in &view_xrefs { let view = if view_xref.0 == 0 { Some(&job.root) } else { job.view(*view_xref) }; @@ -241,7 +241,7 @@ pub fn extract_i18n_messages(job: &mut ComponentCompilationJob<'_>) { XrefId, // view_xref NonNull>, // op_ptr XrefId, // icu_context_xref - Atom<'_>, // placeholder name + Ident<'_>, // placeholder name String, // formatted value )> = Vec::new(); @@ -286,7 +286,7 @@ pub fn extract_i18n_messages(job: &mut ComponentCompilationJob<'_>) { for (view_xref, op_ptr, context_xref, name, formatted) in icu_placeholders_to_process { // Find the I18nContext and add the icu_placeholder_literal // Allocate the formatted string in the arena - let formatted_atom = Atom::from(allocator.alloc_str(&formatted)); + let formatted_atom = Ident::from(allocator.alloc_str(&formatted)); for vx in &view_xrefs_for_icu { let view = if vx.0 == 0 { Some(&mut job.root) } else { job.view_mut(*vx) }; @@ -352,7 +352,7 @@ pub fn extract_i18n_messages(job: &mut ComponentCompilationJob<'_>) { /// Formats a list of params into (placeholder, formatted_value) pairs. /// Returns the formatted params and whether postprocessing is needed. pub fn format_params( - params: &[(Atom<'_>, Vec)], + params: &[(Ident<'_>, Vec)], ) -> (std::vec::Vec<(String, String)>, bool) { let mut formatted = std::vec::Vec::new(); let mut needs_postprocessing = false; @@ -398,7 +398,7 @@ pub fn format_param_values(values: &[I18nParamValue]) -> Option { /// /// Ported from Angular's `formatIcuPlaceholder` function. pub fn format_icu_placeholder( - strings: &[Atom<'_>], + strings: &[Ident<'_>], expression_placeholders: &[I18nParamValue], ) -> String { let mut result = String::new(); diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/generate_local_let_references.rs b/crates/oxc_angular_compiler/src/pipeline/phases/generate_local_let_references.rs index fcd9a2bf3..332e235db 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/generate_local_let_references.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/generate_local_let_references.rs @@ -42,7 +42,7 @@ pub fn generate_local_let_references(job: &mut ComponentCompilationJob<'_>) { None => continue, }; - let mut names: FxHashMap> = FxHashMap::default(); + let mut names: FxHashMap> = FxHashMap::default(); for op in view.create.iter() { if let CreateOp::DeclareLet(let_decl) = op { names.insert(let_decl.xref, let_decl.name.clone()); @@ -85,7 +85,7 @@ pub fn generate_local_let_references(job: &mut ComponentCompilationJob<'_>) { let declared_name = let_names .get(&store_let.target) .cloned() - .unwrap_or_else(|| oxc_span::Atom::from("")); + .unwrap_or_else(|| oxc_span::Ident::from("")); // Create a new Variable op with StoreLetExpr as the initializer let store_let_expr = IrExpression::StoreLet(Box::new_in( diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/generate_projection_def.rs b/crates/oxc_angular_compiler/src/pipeline/phases/generate_projection_def.rs index e969c3d96..d0b657483 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/generate_projection_def.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/generate_projection_def.rs @@ -9,7 +9,7 @@ //! Ported from Angular's `template/pipeline/src/phases/generate_projection_def.ts`. use oxc_allocator::{Box as OxcBox, Vec as OxcVec}; -use oxc_span::Atom; +use oxc_span::Ident; use std::ptr::NonNull; use crate::ir::ops::{CreateOp, CreateOpBase, ProjectionDefOp, XrefId}; @@ -72,7 +72,7 @@ pub fn generate_projection_defs(job: &mut ComponentCompilationJob<'_>) { // Phase 2: Assign projection slot indexes and collect selectors let allocator = job.allocator; - let mut selectors: Vec> = Vec::new(); + let mut selectors: Vec> = Vec::new(); for (slot_index, ptr) in projection_ptrs.iter().enumerate() { // SAFETY: ptr is valid from our cursor traversal @@ -82,7 +82,7 @@ pub fn generate_projection_defs(job: &mut ComponentCompilationJob<'_>) { proj.projection_slot_index = slot_index as u32; // Collect selector (use "*" for wildcard if None) - let selector = proj.selector.clone().unwrap_or_else(|| Atom::from("*")); + let selector = proj.selector.clone().unwrap_or_else(|| Ident::from("*")); selectors.push(selector); } } @@ -112,7 +112,7 @@ pub fn generate_projection_defs(job: &mut ComponentCompilationJob<'_>) { if selector.as_str() == "*" { // Wildcard stays as string literal "*" def_elements.push(OutputExpression::Literal(OxcBox::new_in( - LiteralExpr { value: LiteralValue::String(Atom::from("*")), source_span: None }, + LiteralExpr { value: LiteralValue::String(Ident::from("*")), source_span: None }, allocator, ))); } else { diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/generate_variables.rs b/crates/oxc_angular_compiler/src/pipeline/phases/generate_variables.rs index 2cf8583d6..1435446d1 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/generate_variables.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/generate_variables.rs @@ -17,7 +17,7 @@ //! Ported from Angular's `template/pipeline/src/phases/generate_variables.ts`. use oxc_allocator::Box; -use oxc_span::Atom; +use oxc_span::Ident; use crate::ir::enums::{SemanticVariableKind, VariableFlags}; use crate::ir::expression::{ @@ -31,7 +31,7 @@ use crate::pipeline::compilation::ComponentCompilationJob; #[derive(Debug, Clone)] struct LocalRefInfo<'a> { /// Name of the local reference (e.g., "myDiv" from #myDiv). - name: Atom<'a>, + name: Ident<'a>, /// XrefId of the element this reference points to. target_id: XrefId, /// Slot of the target element. @@ -49,7 +49,7 @@ struct LetDeclarationInfo<'a> { /// Slot of the @let declaration. target_slot: Option, /// Variable name. - variable_name: Atom<'a>, + variable_name: Ident<'a>, } /// Lexical scope of a view, including a reference to its parent view's scope. @@ -59,9 +59,9 @@ struct Scope<'a, 'b> { /// XrefId of the view this scope belongs to. view: XrefId, /// Context variables (name, value) from the view. - context_variables: Vec<(Atom<'a>, Atom<'a>)>, + context_variables: Vec<(Ident<'a>, Ident<'a>)>, /// Alias variables (name, expression) from the view. - alias_variables: Vec<(Atom<'a>, IrExpression<'a>)>, + alias_variables: Vec<(Ident<'a>, IrExpression<'a>)>, /// Local references collected from elements within the view. references: Vec>, /// @let declarations collected from the view. @@ -554,7 +554,7 @@ fn clone_update_op<'a>(allocator: &'a oxc_allocator::Allocator, op: &UpdateOp<'a base: Default::default(), xref: XrefId(0), kind: SemanticVariableKind::Identifier, - name: Atom::from(""), + name: Ident::from(""), initializer: Box::new_in( IrExpression::NextContext(Box::new_in( NextContextExpr { steps: 0, source_span: None }, @@ -674,7 +674,7 @@ fn create_next_context_variable<'a>( base: Default::default(), xref, kind: SemanticVariableKind::Context, - name: Atom::from(""), // Empty = naming phase will assign it + name: Ident::from(""), // Empty = naming phase will assign it initializer: Box::new_in(initializer, allocator), flags: VariableFlags::NONE, view: Some(context_view), @@ -694,8 +694,8 @@ fn create_context_read_variable<'a>( allocator: &'a oxc_allocator::Allocator, xref: XrefId, view_xref: XrefId, - name: Atom<'a>, - context_value: Atom<'a>, + name: Ident<'a>, + context_value: Ident<'a>, ) -> UpdateOp<'a> { use crate::pipeline::compilation::CTX_REF; @@ -740,7 +740,7 @@ fn create_alias_variable<'a>( allocator: &'a oxc_allocator::Allocator, xref: XrefId, view_xref: XrefId, - name: Atom<'a>, + name: Ident<'a>, expression: IrExpression<'a>, ) -> UpdateOp<'a> { UpdateOp::Variable(UpdateVariableOp { @@ -795,7 +795,7 @@ fn create_reference_variable<'a>( fn create_context_let_reference_variable<'a>( allocator: &'a oxc_allocator::Allocator, xref: XrefId, - name: Atom<'a>, + name: Ident<'a>, target_id: XrefId, target_slot: Option, ) -> UpdateOp<'a> { diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/host_style_property_parsing.rs b/crates/oxc_angular_compiler/src/pipeline/phases/host_style_property_parsing.rs index 40e50ad0b..823e88848 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/host_style_property_parsing.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/host_style_property_parsing.rs @@ -64,21 +64,21 @@ pub fn parse_host_style_properties(job: &mut ComponentCompilationJob<'_>) { // Parse property and unit suffix let (property, unit) = parse_property(&hyphenated); - binding.name = oxc_span::Atom::from(allocator.alloc_str(&property)); - binding.unit = unit.map(|u| oxc_span::Atom::from(allocator.alloc_str(&u))); + binding.name = oxc_span::Ident::from(allocator.alloc_str(&property)); + binding.unit = unit.map(|u| oxc_span::Ident::from(allocator.alloc_str(&u))); } else if name.starts_with(STYLE_BANG) { binding.kind = BindingKind::StyleProperty; - binding.name = oxc_span::Atom::from("style"); + binding.name = oxc_span::Ident::from("style"); } else if name.starts_with(CLASS_DOT) { binding.kind = BindingKind::ClassName; let class_name = &name[CLASS_DOT.len()..]; let (property, _) = parse_property(class_name); - binding.name = oxc_span::Atom::from(allocator.alloc_str(&property)); + binding.name = oxc_span::Ident::from(allocator.alloc_str(&property)); } else if name.starts_with(CLASS_BANG) { binding.kind = BindingKind::ClassName; let class_name = &name[CLASS_BANG.len()..]; let (property, _) = parse_property(class_name); - binding.name = oxc_span::Atom::from(allocator.alloc_str(&property)); + binding.name = oxc_span::Ident::from(allocator.alloc_str(&property)); } } } @@ -163,21 +163,21 @@ pub fn parse_host_style_properties_for_host(job: &mut HostBindingCompilationJob< // Parse property and unit suffix let (property, unit) = parse_property(&hyphenated); - binding.name = oxc_span::Atom::from(allocator.alloc_str(&property)); - binding.unit = unit.map(|u| oxc_span::Atom::from(allocator.alloc_str(&u))); + binding.name = oxc_span::Ident::from(allocator.alloc_str(&property)); + binding.unit = unit.map(|u| oxc_span::Ident::from(allocator.alloc_str(&u))); } else if name.starts_with(STYLE_BANG) { binding.kind = BindingKind::StyleProperty; - binding.name = oxc_span::Atom::from("style"); + binding.name = oxc_span::Ident::from("style"); } else if name.starts_with(CLASS_DOT) { binding.kind = BindingKind::ClassName; let class_name = &name[CLASS_DOT.len()..]; let (property, _) = parse_property(class_name); - binding.name = oxc_span::Atom::from(allocator.alloc_str(&property)); + binding.name = oxc_span::Ident::from(allocator.alloc_str(&property)); } else if name.starts_with(CLASS_BANG) { binding.kind = BindingKind::ClassName; let class_name = &name[CLASS_BANG.len()..]; let (property, _) = parse_property(class_name); - binding.name = oxc_span::Atom::from(allocator.alloc_str(&property)); + binding.name = oxc_span::Ident::from(allocator.alloc_str(&property)); } } } diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/i18n_closure.rs b/crates/oxc_angular_compiler/src/pipeline/phases/i18n_closure.rs index 4e5c126ca..9cc0f90a9 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/i18n_closure.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/i18n_closure.rs @@ -27,7 +27,7 @@ //! `template/pipeline/src/phases/i18n_const_collection.ts`. use oxc_allocator::{Box as AllocBox, Vec as AllocVec}; -use oxc_span::Atom; +use oxc_span::Ident; use crate::i18n::serializer::format_i18n_placeholder_name; use crate::output::ast::{ @@ -59,7 +59,7 @@ pub fn create_closure_mode_guard<'a>( TypeofExpr { expr: AllocBox::new_in( OutputExpression::ReadVar(AllocBox::new_in( - ReadVarExpr { name: Atom::from(NG_I18N_CLOSURE_MODE), source_span: None }, + ReadVarExpr { name: Ident::from(NG_I18N_CLOSURE_MODE), source_span: None }, allocator, )), allocator, @@ -71,7 +71,7 @@ pub fn create_closure_mode_guard<'a>( // "undefined" let undefined_literal = OutputExpression::Literal(AllocBox::new_in( - LiteralExpr { value: LiteralValue::String(Atom::from("undefined")), source_span: None }, + LiteralExpr { value: LiteralValue::String(Ident::from("undefined")), source_span: None }, allocator, )); @@ -88,7 +88,7 @@ pub fn create_closure_mode_guard<'a>( // ngI18nClosureMode let closure_mode_var = OutputExpression::ReadVar(AllocBox::new_in( - ReadVarExpr { name: Atom::from(NG_I18N_CLOSURE_MODE), source_span: None }, + ReadVarExpr { name: Ident::from(NG_I18N_CLOSURE_MODE), source_span: None }, allocator, )); @@ -107,14 +107,14 @@ pub fn create_closure_mode_guard<'a>( /// I18n message metadata for JSDoc comments. pub struct I18nMessageMeta<'a> { /// Message description for translators. - pub description: Option>, + pub description: Option>, /// Message meaning for disambiguation. - pub meaning: Option>, + pub meaning: Option>, } impl<'a> I18nMessageMeta<'a> { /// Creates a new I18n message metadata. - pub fn new(description: Option>, meaning: Option>) -> Self { + pub fn new(description: Option>, meaning: Option>) -> Self { Self { description, meaning } } } @@ -135,14 +135,14 @@ pub fn create_i18n_jsdoc<'a>( allocator: &'a oxc_allocator::Allocator, meta: &I18nMessageMeta<'a>, ) -> LeadingComment<'a> { - // Convert Option to Option with arena allocation + // Convert Option to Option with arena allocation let desc = meta.description.as_ref().map(|d| { let s = allocator.alloc_str(d.as_str()); - Atom::from(s) + Ident::from(s) }); let meaning = meta.meaning.as_ref().map(|m| { let s = allocator.alloc_str(m.as_str()); - Atom::from(s) + Ident::from(s) }); // Suppress msgDescriptions warning if no description is provided @@ -168,8 +168,8 @@ pub fn create_i18n_jsdoc<'a>( /// ``` pub fn create_goog_get_msg_statements<'a>( allocator: &'a oxc_allocator::Allocator, - i18n_var_name: &Atom<'a>, - closure_var_name: &Atom<'a>, + i18n_var_name: &Ident<'a>, + closure_var_name: &Ident<'a>, message_string: &str, params: &[(String, String)], meta: Option<&I18nMessageMeta<'a>>, @@ -182,7 +182,7 @@ pub fn create_goog_get_msg_statements<'a>( // First arg: message string with {$placeholder} format let message_str = allocator.alloc_str(message_string); goog_args.push(OutputExpression::Literal(AllocBox::new_in( - LiteralExpr { value: LiteralValue::String(Atom::from(message_str)), source_span: None }, + LiteralExpr { value: LiteralValue::String(Ident::from(message_str)), source_span: None }, allocator, ))); @@ -195,10 +195,10 @@ pub fn create_goog_get_msg_statements<'a>( let key_str = allocator.alloc_str(&formatted_name); let value_str = allocator.alloc_str(value); entries.push(LiteralMapEntry { - key: Atom::from(key_str), + key: Ident::from(key_str), value: OutputExpression::Literal(AllocBox::new_in( LiteralExpr { - value: LiteralValue::String(Atom::from(value_str)), + value: LiteralValue::String(Ident::from(value_str)), source_span: None, }, allocator, @@ -214,13 +214,13 @@ pub fn create_goog_get_msg_statements<'a>( // goog.getMsg reference let goog_var = OutputExpression::ReadVar(AllocBox::new_in( - ReadVarExpr { name: Atom::from("goog"), source_span: None }, + ReadVarExpr { name: Ident::from("goog"), source_span: None }, allocator, )); let goog_get_msg = OutputExpression::ReadProp(AllocBox::new_in( ReadPropExpr { receiver: AllocBox::new_in(goog_var, allocator), - name: Atom::from("getMsg"), + name: Ident::from("getMsg"), optional: false, source_span: None, }, @@ -288,7 +288,7 @@ pub fn create_goog_get_msg_statements<'a>( /// ``` pub fn create_localize_statements<'a>( allocator: &'a oxc_allocator::Allocator, - i18n_var_name: &Atom<'a>, + i18n_var_name: &Ident<'a>, localized_expr: OutputExpression<'a>, ) -> AllocVec<'a, OutputStatement<'a>> { let mut statements = AllocVec::new_in(allocator); @@ -333,8 +333,8 @@ pub fn create_localize_statements<'a>( /// ``` pub fn create_translation_declaration<'a>( allocator: &'a oxc_allocator::Allocator, - i18n_var_name: Atom<'a>, - closure_var_name: Atom<'a>, + i18n_var_name: Ident<'a>, + closure_var_name: Ident<'a>, message_for_closure: &str, params: &[(String, String)], localized_expr: OutputExpression<'a>, diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/i18n_const_collection.rs b/crates/oxc_angular_compiler/src/pipeline/phases/i18n_const_collection.rs index 1a8f950d2..492a384c9 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/i18n_const_collection.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/i18n_const_collection.rs @@ -8,7 +8,7 @@ use std::ptr::NonNull; use oxc_allocator::Vec as ArenaVec; -use oxc_span::Atom; +use oxc_span::Ident; use rustc_hash::FxHashMap; use crate::i18n::serializer::format_i18n_placeholder_name; @@ -132,7 +132,7 @@ pub fn collect_i18n_consts(job: &mut ComponentCompilationJob<'_>) { // Map: i18n_block xref -> const index let mut message_const_indices: FxHashMap = FxHashMap::default(); // Map: i18n_context xref -> i18n variable name (for attribute bindings) - let mut i18n_var_names_by_context: FxHashMap> = FxHashMap::default(); + let mut i18n_var_names_by_context: FxHashMap> = FxHashMap::default(); // Counter for unique variable names let mut i18n_var_counter: usize = 0; @@ -184,7 +184,7 @@ pub fn collect_i18n_consts(job: &mut ComponentCompilationJob<'_>) { // Add to consts array with statements as initializers and record the index. let var_name_str = allocator.alloc_str(&main_var_name); let main_var = OutputExpression::ReadVar(oxc_allocator::Box::new_in( - ReadVarExpr { name: Atom::from(var_name_str), source_span: None }, + ReadVarExpr { name: Ident::from(var_name_str), source_span: None }, allocator, )); let const_index = @@ -195,7 +195,7 @@ pub fn collect_i18n_consts(job: &mut ComponentCompilationJob<'_>) { // Add statements to consts_initializers and save the variable name. job.consts_initializers.extend(statements); let var_name_str = allocator.alloc_str(&main_var_name); - let var_name_atom = Atom::from(var_name_str); + let var_name_atom = Ident::from(var_name_str); i18n_var_names_by_context.insert(ctx_xref, var_name_atom.clone()); // This i18n message may correspond to an individual extracted attribute. If so, @@ -320,7 +320,7 @@ pub fn collect_i18n_consts(job: &mut ComponentCompilationJob<'_>) { let name_str = allocator.alloc_str(&expr.name); let name_literal = OutputExpression::Literal(oxc_allocator::Box::new_in( crate::output::ast::LiteralExpr { - value: LiteralValue::String(Atom::from(name_str)), + value: LiteralValue::String(Ident::from(name_str)), source_span: None, }, allocator, @@ -508,11 +508,11 @@ fn collect_message<'a>( let meta = if msg_info.description.is_some() || msg_info.meaning.is_some() { let desc = msg_info.description.as_ref().map(|d| { let s = allocator.alloc_str(d); - Atom::from(s) + Ident::from(s) }); let meaning = msg_info.meaning.as_ref().map(|m| { let s = allocator.alloc_str(m); - Atom::from(s) + Ident::from(s) }); Some(I18nMessageMeta::new(desc, meaning)) } else { @@ -542,8 +542,8 @@ fn collect_message<'a>( }; // Generate dual-mode translation declaration - let i18n_var_atom = Atom::from(allocator.alloc_str(&i18n_var_name)); - let closure_var_atom = Atom::from(allocator.alloc_str(&closure_var_name)); + let i18n_var_atom = Ident::from(allocator.alloc_str(&i18n_var_name)); + let closure_var_atom = Ident::from(allocator.alloc_str(&closure_var_name)); let statements = create_translation_declaration( allocator, @@ -593,11 +593,11 @@ fn generate_message_from_params(params: &[(String, String)]) -> String { /// Format params from an I18nContext into (placeholder, value) pairs. fn format_context_params( - params: &oxc_allocator::HashMap<'_, Atom<'_>, ArenaVec<'_, I18nParamValue>>, + params: &oxc_allocator::HashMap<'_, Ident<'_>, ArenaVec<'_, I18nParamValue>>, ) -> Vec<(String, String)> { use crate::pipeline::phases::extract_i18n_messages::format_params; - let params_vec: Vec<(Atom<'_>, Vec)> = + let params_vec: Vec<(Ident<'_>, Vec)> = params.iter().map(|(k, v)| (k.clone(), v.iter().copied().collect())).collect(); let (formatted, _needs_postprocessing) = format_params(¶ms_vec); @@ -640,14 +640,14 @@ fn create_localize_expression<'a>( let first_text = text_parts.first().map(|s| s.as_str()).unwrap_or(""); let head_cooked = serialize_i18n_head(first_text, &meaning, &description, &custom_id); let head_str = allocator.alloc_str(&head_cooked); - message_parts.push(Atom::from(head_str)); + message_parts.push(Ident::from(head_str)); // Subsequent parts: ":PLACEHOLDER_NAME:text" for (i, placeholder) in placeholder_order.iter().enumerate() { // Format placeholder name (UPPERCASE for $localize) let formatted_name = format_i18n_placeholder_name(placeholder, false); let name_str = allocator.alloc_str(&formatted_name); - placeholder_names.push(Atom::from(name_str)); + placeholder_names.push(Ident::from(name_str)); // Get the value for this placeholder // The params_map is keyed by the original placeholder name, but the message_string @@ -657,7 +657,7 @@ fn create_localize_expression<'a>( let value_str = allocator.alloc_str(&value); let literal_expr = OutputExpression::Literal(oxc_allocator::Box::new_in( crate::output::ast::LiteralExpr { - value: LiteralValue::String(Atom::from(value_str)), + value: LiteralValue::String(Ident::from(value_str)), source_span: None, }, allocator, @@ -668,21 +668,21 @@ fn create_localize_expression<'a>( let text_part = text_parts.get(i + 1).map(|s| s.as_str()).unwrap_or(""); let part_cooked = serialize_i18n_template_part(&formatted_name, text_part); let part_str = allocator.alloc_str(&part_cooked); - message_parts.push(Atom::from(part_str)); + message_parts.push(Ident::from(part_str)); } // Store metadata for potential future use (JSDoc generation in emitter) let desc_atom = description.map(|d| { let s = allocator.alloc_str(&d); - Atom::from(s) + Ident::from(s) }); let meaning_atom = meaning.map(|m| { let s = allocator.alloc_str(&m); - Atom::from(s) + Ident::from(s) }); let custom_id_atom = custom_id.map(|c| { let s = allocator.alloc_str(&c); - Atom::from(s) + Ident::from(s) }); OutputExpression::LocalizedString(oxc_allocator::Box::new_in( @@ -829,12 +829,12 @@ fn wrap_with_postprocess<'a>( crate::output::ast::ReadPropExpr { receiver: oxc_allocator::Box::new_in( OutputExpression::ReadVar(oxc_allocator::Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(Identifiers::I18N_POSTPROCESS), + name: Ident::from(Identifiers::I18N_POSTPROCESS), optional: false, source_span: None, }, @@ -858,13 +858,13 @@ fn wrap_with_postprocess<'a>( for var_name in var_names { let var_str = allocator.alloc_str(var_name); var_refs.push(OutputExpression::ReadVar(oxc_allocator::Box::new_in( - ReadVarExpr { name: Atom::from(var_str), source_span: None }, + ReadVarExpr { name: Ident::from(var_str), source_span: None }, allocator, ))); } entries.push(LiteralMapEntry { - key: Atom::from(key_str), + key: Ident::from(key_str), value: OutputExpression::LiteralArray(oxc_allocator::Box::new_in( LiteralArrayExpr { entries: var_refs, source_span: None }, allocator, @@ -898,7 +898,7 @@ mod tests { use crate::output::ast::{LiteralExpr, OutputExpression, ReadVarExpr}; use crate::output::emitter::JsEmitter; use oxc_allocator::Allocator; - use oxc_span::Atom; + use oxc_span::Ident; #[test] fn test_wrap_with_postprocess_uses_namespace_prefix() { @@ -913,7 +913,7 @@ mod tests { // Create a simple input expression (simulating a $localize result) let input_expr = OutputExpression::Literal(oxc_allocator::Box::new_in( LiteralExpr { - value: LiteralValue::String(Atom::from("test message")), + value: LiteralValue::String(Ident::from("test message")), source_span: None, }, &allocator, @@ -941,7 +941,7 @@ mod tests { let allocator = Allocator::default(); let input_expr = OutputExpression::ReadVar(oxc_allocator::Box::new_in( - ReadVarExpr { name: Atom::from("i18n_0"), source_span: None }, + ReadVarExpr { name: Ident::from("i18n_0"), source_span: None }, &allocator, )); diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/i18n_text_extraction.rs b/crates/oxc_angular_compiler/src/pipeline/phases/i18n_text_extraction.rs index bcb8e201e..a10fbfd02 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/i18n_text_extraction.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/i18n_text_extraction.rs @@ -9,7 +9,7 @@ use std::ptr::NonNull; -use oxc_span::Atom; +use oxc_span::Ident; use rustc_hash::FxHashMap; use crate::ir::enums::{I18nExpressionFor, I18nParamResolutionTime}; @@ -50,7 +50,7 @@ fn convert_i18n_text_in_view(job: &mut ComponentCompilationJob<'_>, view_xref: X // Track text ops to be replaced with IcuPlaceholder ops // (text_op_ptr, text_xref, icu_placeholder_name, initial_value) - let mut text_ops_to_replace_with_icu: Vec<(NonNull>, XrefId, Atom<'_>, Atom<'_>)> = + let mut text_ops_to_replace_with_icu: Vec<(NonNull>, XrefId, Ident<'_>, Ident<'_>)> = Vec::new(); // Track text ops to be removed (those without ICU placeholder) @@ -260,7 +260,7 @@ fn convert_i18n_text_in_view(job: &mut ComponentCompilationJob<'_>, view_xref: X expression: oxc_allocator::Box::new_in(expr.clone_in(allocator), allocator), resolution_time, usage: I18nExpressionFor::I18nText, - name: oxc_span::Atom::from(""), + name: oxc_span::Ident::from(""), i18n_placeholder, icu_placeholder: info.icu_placeholder_xref, })); @@ -305,7 +305,7 @@ fn convert_i18n_text_in_view(job: &mut ComponentCompilationJob<'_>, view_xref: X ), resolution_time, usage: I18nExpressionFor::I18nText, - name: oxc_span::Atom::from(""), + name: oxc_span::Ident::from(""), i18n_placeholder: None, icu_placeholder: info.icu_placeholder_xref, })); diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/local_refs.rs b/crates/oxc_angular_compiler/src/pipeline/phases/local_refs.rs index 39c6b975d..6d6b6fb38 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/local_refs.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/local_refs.rs @@ -26,7 +26,7 @@ use crate::pipeline::compilation::{ComponentCompilationJob, ConstValue}; /// Info about an op that needs local refs serialized. struct LocalRefInfo<'a> { op_kind: LocalRefOpKind, - refs: std::vec::Vec<(oxc_span::Atom<'a>, oxc_span::Atom<'a>)>, + refs: std::vec::Vec<(oxc_span::Ident<'a>, oxc_span::Ident<'a>)>, } #[derive(Clone, Copy)] @@ -171,7 +171,7 @@ pub fn lift_local_refs(job: &mut ComponentCompilationJob<'_>) { /// not extracted to a top-level const declaration. fn serialize_local_refs_to_const_value<'a>( allocator: &'a oxc_allocator::Allocator, - refs: &[(oxc_span::Atom<'a>, oxc_span::Atom<'a>)], + refs: &[(oxc_span::Ident<'a>, oxc_span::Ident<'a>)], ) -> ConstValue<'a> { let mut entries = OxcVec::with_capacity_in(refs.len() * 2, allocator); diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/naming.rs b/crates/oxc_angular_compiler/src/pipeline/phases/naming.rs index 4a0992147..0ff521273 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/naming.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/naming.rs @@ -11,7 +11,7 @@ //! //! Ported from Angular's `template/pipeline/src/phases/naming.ts`. -use oxc_span::Atom; +use oxc_span::Ident; use rustc_hash::FxHashMap; use crate::ir::enums::{BindingKind, SemanticVariableKind}; @@ -65,7 +65,7 @@ enum SemanticVariableKey<'a> { /// SavedView variable for a specific view. SavedView { view: XrefId }, /// Alias variable with a specific identifier. - Alias { identifier: Atom<'a> }, + Alias { identifier: Ident<'a> }, /// Reference variable (template ref like #defaultContent). /// Multiple child views accessing the same template ref share this key. /// Identified by the target element and offset. @@ -86,7 +86,7 @@ enum SemanticVariableKey<'a> { /// The view whose context is being read (the parent view with context variables). view: XrefId, /// The identifier name for the variable (e.g., "breadcrumb"). - identifier: Atom<'a>, + identifier: Ident<'a>, }, } @@ -104,7 +104,7 @@ enum SemanticVariableKey<'a> { /// We detect references by checking if the initializer is an `IrExpression::Reference`. fn make_semantic_key<'a>( kind: SemanticVariableKind, - name: &Atom<'a>, + name: &Ident<'a>, view: Option, initializer: &IrExpression<'a>, ) -> Option> { @@ -257,13 +257,13 @@ pub fn name_functions_and_variables(job: &mut ComponentCompilationJob<'_>) { let sanitized_base = sanitize_identifier(component_name); // Map from xref to generated variable name - let mut var_names: FxHashMap> = FxHashMap::default(); + let mut var_names: FxHashMap> = FxHashMap::default(); // Map from semantic key to generated variable name. // This enables name reuse for variables with the same semantic identity, // matching TypeScript's behavior where multiple Variable ops can share // the same SemanticVariable object. - let mut semantic_var_names: FxHashMap, Atom<'_>> = FxHashMap::default(); + let mut semantic_var_names: FxHashMap, Ident<'_>> = FxHashMap::default(); // Recursively name views starting from root // TypeScript: addNamesToView(job.root, job.componentName, state, compatibility) @@ -302,8 +302,8 @@ fn add_names_to_root_view<'a>( base_name: &str, allocator: &'a oxc_allocator::Allocator, state: &mut NamingState, - var_names: &mut FxHashMap>, - semantic_var_names: &mut FxHashMap, Atom<'a>>, + var_names: &mut FxHashMap>, + semantic_var_names: &mut FxHashMap, Ident<'a>>, ) { // Name the root view // TypeScript: unit.fnName = unit.job.pool.uniqueName(sanitizeIdentifier(`${baseName}_${unit.job.fnSuffix}`), false) @@ -335,8 +335,8 @@ fn add_names_to_child_view<'a>( base_name: &str, allocator: &'a oxc_allocator::Allocator, state: &mut NamingState, - var_names: &mut FxHashMap>, - semantic_var_names: &mut FxHashMap, Atom<'a>>, + var_names: &mut FxHashMap>, + semantic_var_names: &mut FxHashMap, Ident<'a>>, ) { // Name this view // TypeScript: unit.fnName = unit.job.pool.uniqueName(sanitizeIdentifier(`${baseName}_${unit.job.fnSuffix}`), false) @@ -386,10 +386,10 @@ fn process_view_ops_depth_first<'a>( view_xref: Option, // None for root view base_name: &str, allocator: &'a oxc_allocator::Allocator, - fn_name: Option<&Atom<'a>>, + fn_name: Option<&Ident<'a>>, state: &mut NamingState, - var_names: &mut FxHashMap>, - semantic_var_names: &mut FxHashMap, Atom<'a>>, + var_names: &mut FxHashMap>, + semantic_var_names: &mut FxHashMap, Ident<'a>>, ) { // Phase 0: Process function ops FIRST (matches TypeScript ops() generator order) // Arrow functions have their own ops lists that contain Variable ops prepended @@ -550,10 +550,10 @@ fn process_create_ops_with_child_recursion<'a>( view_xref: Option, allocator: &'a oxc_allocator::Allocator, base_name: &str, - fn_name: Option<&Atom<'a>>, + fn_name: Option<&Ident<'a>>, state: &mut NamingState, - var_names: &mut FxHashMap>, - semantic_var_names: &mut FxHashMap, Atom<'a>>, + var_names: &mut FxHashMap>, + semantic_var_names: &mut FxHashMap, Ident<'a>>, child_views: &[ChildViewInfo], ) { // Group child views by their create op index for efficient lookup @@ -679,8 +679,8 @@ fn name_create_variable_op<'a>( var_op: &mut crate::ir::ops::VariableOp<'a>, allocator: &'a oxc_allocator::Allocator, state: &mut NamingState, - var_names: &mut FxHashMap>, - semantic_var_names: &mut FxHashMap, Atom<'a>>, + var_names: &mut FxHashMap>, + semantic_var_names: &mut FxHashMap, Ident<'a>>, ) { // Check if we need to assign a name let needs_naming = @@ -726,8 +726,8 @@ fn name_variable_op<'a>( var_op: &mut crate::ir::ops::UpdateVariableOp<'a>, allocator: &'a oxc_allocator::Allocator, state: &mut NamingState, - var_names: &mut FxHashMap>, - semantic_var_names: &mut FxHashMap, Atom<'a>>, + var_names: &mut FxHashMap>, + semantic_var_names: &mut FxHashMap, Ident<'a>>, ) { // Check if we need to assign a name let needs_naming = @@ -770,10 +770,10 @@ fn process_single_create_op_ref<'a>( op: &mut CreateOp<'a>, allocator: &'a oxc_allocator::Allocator, base_name: &str, - fn_name: Option<&Atom<'a>>, + fn_name: Option<&Ident<'a>>, state: &mut NamingState, - var_names: &mut FxHashMap>, - semantic_var_names: &mut FxHashMap, Atom<'a>>, + var_names: &mut FxHashMap>, + semantic_var_names: &mut FxHashMap, Ident<'a>>, ) { match op { CreateOp::Listener(listener) => { @@ -805,7 +805,7 @@ fn process_single_create_op_ref<'a>( .unwrap_or("start"); let new_name = format!("@{}.{}", listener.name.as_str(), phase_str); let name_str = allocator.alloc_str(&new_name); - listener.name = Atom::from(name_str); + listener.name = Ident::from(name_str); // Note: no trailing underscore - the @ in event_name will become _ after sanitize (new_name, "animation") } else { @@ -825,7 +825,7 @@ fn process_single_create_op_ref<'a>( let sanitized = sanitize_identifier(&handler_name); let name_str = allocator.alloc_str(&sanitized); - listener.handler_fn_name = Some(Atom::from(name_str)); + listener.handler_fn_name = Some(Ident::from(name_str)); } // Process handler ops inline for handler_op in listener.handler_ops.iter_mut() { @@ -844,7 +844,7 @@ fn process_single_create_op_ref<'a>( let handler_name = format!("{fn_name_str}_{tag}_{event_name}_{slot}_listener"); let sanitized = sanitize_identifier(&handler_name); let name_str = allocator.alloc_str(&sanitized); - listener.handler_fn_name = Some(Atom::from(name_str)); + listener.handler_fn_name = Some(Ident::from(name_str)); } // Process handler ops inline for handler_op in listener.handler_ops.iter_mut() { @@ -872,7 +872,7 @@ fn process_single_create_op_ref<'a>( let sanitized = sanitize_identifier(&handler_name); let name_str = allocator.alloc_str(&sanitized); - listener.handler_fn_name = Some(Atom::from(name_str)); + listener.handler_fn_name = Some(Ident::from(name_str)); } // Process handler ops inline for handler_op in listener.handler_ops.iter_mut() { @@ -892,7 +892,7 @@ fn process_single_create_op_ref<'a>( let handler_name = format!("{fn_name_str}_{animation_kind}_cb"); let sanitized = sanitize_identifier(&handler_name); let name_str = allocator.alloc_str(&sanitized); - animation.handler_fn_name = Some(Atom::from(name_str)); + animation.handler_fn_name = Some(Ident::from(name_str)); } // Process handler ops inline for handler_op in animation.handler_ops.iter_mut() { @@ -942,7 +942,7 @@ fn process_function_ops_in_view<'a>( view_xref: Option, allocator: &'a oxc_allocator::Allocator, state: &mut NamingState, - var_names: &mut FxHashMap>, + var_names: &mut FxHashMap>, ) { let functions = match view_xref { None => &job.root.functions, @@ -967,7 +967,7 @@ fn process_function_ops_in_view<'a>( // Each arrow function gets its own semantic variable map to prevent // deduplication with other scopes (listeners, update, other arrow functions). - let mut arrow_fn_semantic_var_names: FxHashMap, Atom<'a>> = + let mut arrow_fn_semantic_var_names: FxHashMap, Ident<'a>> = FxHashMap::default(); // Process Variable ops in this arrow function @@ -991,8 +991,8 @@ fn process_update_ops_in_view<'a>( view_xref: Option, allocator: &'a oxc_allocator::Allocator, state: &mut NamingState, - var_names: &mut FxHashMap>, - semantic_var_names: &mut FxHashMap, Atom<'a>>, + var_names: &mut FxHashMap>, + semantic_var_names: &mut FxHashMap, Ident<'a>>, ) { let update_ops = match view_xref { None => &mut job.root.update, @@ -1014,25 +1014,25 @@ fn process_update_ops_in_view<'a>( if prop.binding_kind == BindingKind::LegacyAnimation && !prop.name.starts_with('@') { let prefixed = format!("@{}", prop.name.as_str()); - prop.name = Atom::from(allocator.alloc_str(&prefixed)); + prop.name = Ident::from(allocator.alloc_str(&prefixed)); } } UpdateOp::DomProperty(prop) => { if prop.binding_kind == BindingKind::LegacyAnimation && !prop.name.starts_with('@') { let prefixed = format!("@{}", prop.name.as_str()); - prop.name = Atom::from(allocator.alloc_str(&prefixed)); + prop.name = Ident::from(allocator.alloc_str(&prefixed)); } } UpdateOp::StyleProp(style) => { if !style.name.starts_with("--") { let hyphenated = hyphenate(style.name.as_str()); - style.name = Atom::from(allocator.alloc_str(&hyphenated)); + style.name = Ident::from(allocator.alloc_str(&hyphenated)); } if style.name.contains("!important") { let stripped = style.name.as_str().replace("!important", ""); let stripped = stripped.trim_end(); - style.name = Atom::from(allocator.alloc_str(stripped)); + style.name = Ident::from(allocator.alloc_str(stripped)); } } UpdateOp::Variable(var_op) => { @@ -1053,9 +1053,9 @@ fn process_update_ops_in_view<'a>( fn get_variable_name<'a>( allocator: &'a oxc_allocator::Allocator, kind: SemanticVariableKind, - identifier: Option<&Atom<'a>>, + identifier: Option<&Ident<'a>>, state: &mut NamingState, -) -> Atom<'a> { +) -> Ident<'a> { let name = match kind { SemanticVariableKind::Context => { // Context uses post-increment (starts at 0) @@ -1088,14 +1088,14 @@ fn get_variable_name<'a>( }; let name_str = allocator.alloc_str(&name); - Atom::from(name_str) + Ident::from(name_str) } /// Propagates variable names to ReadVariableExpr expressions in a view. fn propagate_variable_names_in_view<'a>( create_ops: &mut crate::ir::list::CreateOpList<'a>, update_ops: &mut crate::ir::list::UpdateOpList<'a>, - var_names: &FxHashMap>, + var_names: &FxHashMap>, ) { // Process create operations for op in create_ops.iter_mut() { @@ -1123,7 +1123,7 @@ fn propagate_variable_names_in_view<'a>( /// Propagates a variable name to a ReadVariableExpr expression. fn propagate_name_to_expression<'a>( expr: &mut IrExpression<'a>, - var_names: &FxHashMap>, + var_names: &FxHashMap>, ) { if let IrExpression::ReadVariable(read_var) = expr { // Only set name if it's currently None @@ -1148,7 +1148,7 @@ pub fn name_functions_and_variables_for_host(job: &mut HostBindingCompilationJob // Generate the function name for the host binding function let fn_name = format!("{}_{}", component_name, job.fn_suffix); - job.root.fn_name = Some(oxc_span::Atom::from(allocator.alloc_str(&fn_name))); + job.root.fn_name = Some(oxc_span::Ident::from(allocator.alloc_str(&fn_name))); // Name listener handlers in create ops // Host listeners need names like: ComponentName_click_HostBindingHandler @@ -1162,7 +1162,7 @@ pub fn name_functions_and_variables_for_host(job: &mut HostBindingCompilationJob let handler_name = format!("{sanitized_base}_{event_name}_HostBindingHandler"); let sanitized = sanitize_identifier(&handler_name); let name_str = allocator.alloc_str(&sanitized); - listener.handler_fn_name = Some(Atom::from(name_str)); + listener.handler_fn_name = Some(Ident::from(name_str)); } } CreateOp::AnimationListener(listener) => { @@ -1172,7 +1172,7 @@ pub fn name_functions_and_variables_for_host(job: &mut HostBindingCompilationJob format!("{sanitized_base}_{animation_kind}_HostBindingHandler"); let sanitized = sanitize_identifier(&handler_name); let name_str = allocator.alloc_str(&sanitized); - listener.handler_fn_name = Some(Atom::from(name_str)); + listener.handler_fn_name = Some(Ident::from(name_str)); } } _ => {} @@ -1187,7 +1187,7 @@ mod tests { use crate::ir::expression::{IrExpression, NextContextExpr}; use crate::ir::ops::{UpdateVariableOp, XrefId}; use oxc_allocator::{Allocator, Box as AllocBox}; - use oxc_span::Atom; + use oxc_span::Ident; /// Helper: create an `UpdateVariableOp` representing a NextContext-based /// context variable for the given `view_xref`. The variable starts with @@ -1201,7 +1201,7 @@ mod tests { base: Default::default(), xref, kind: SemanticVariableKind::Context, - name: Atom::from(""), + name: Ident::from(""), initializer: AllocBox::new_in( IrExpression::NextContext(AllocBox::new_in( NextContextExpr { steps: 1, source_span: None }, @@ -1225,8 +1225,8 @@ mod tests { fn test_shared_semantic_map_deduplicates_context_variables() { let allocator = Allocator::default(); let mut state = NamingState { index: 0 }; - let mut var_names: FxHashMap> = FxHashMap::default(); - let mut semantic_var_names: FxHashMap, Atom<'_>> = + let mut var_names: FxHashMap> = FxHashMap::default(); + let mut semantic_var_names: FxHashMap, Ident<'_>> = FxHashMap::default(); let parent_view = XrefId(100); @@ -1280,12 +1280,12 @@ mod tests { fn test_arrow_function_gets_independent_context_variable_name() { let allocator = Allocator::default(); let mut state = NamingState { index: 0 }; - let mut var_names: FxHashMap> = FxHashMap::default(); + let mut var_names: FxHashMap> = FxHashMap::default(); let parent_view = XrefId(100); // --- Simulate the update scope naming a Context variable --- - let mut update_semantic: FxHashMap, Atom<'_>> = + let mut update_semantic: FxHashMap, Ident<'_>> = FxHashMap::default(); let mut update_ctx_var = make_context_var_op(&allocator, XrefId(1), parent_view); name_variable_op( @@ -1303,7 +1303,7 @@ mod tests { assert_eq!(state.index, 1); // --- Simulate an arrow function with its OWN semantic map (the fix) --- - let mut arrow_fn_semantic: FxHashMap, Atom<'_>> = + let mut arrow_fn_semantic: FxHashMap, Ident<'_>> = FxHashMap::default(); let mut arrow_ctx_var = make_context_var_op(&allocator, XrefId(2), parent_view); name_variable_op( @@ -1335,12 +1335,12 @@ mod tests { fn test_multiple_arrow_functions_get_independent_names() { let allocator = Allocator::default(); let mut state = NamingState { index: 0 }; - let mut var_names: FxHashMap> = FxHashMap::default(); + let mut var_names: FxHashMap> = FxHashMap::default(); let parent_view = XrefId(100); // Arrow function 1: own semantic map. - let mut arrow1_semantic: FxHashMap, Atom<'_>> = + let mut arrow1_semantic: FxHashMap, Ident<'_>> = FxHashMap::default(); let mut arrow1_ctx = make_context_var_op(&allocator, XrefId(1), parent_view); name_variable_op( @@ -1353,7 +1353,7 @@ mod tests { assert_eq!(arrow1_ctx.name.as_str(), "ctx_r0"); // Arrow function 2: own semantic map. - let mut arrow2_semantic: FxHashMap, Atom<'_>> = + let mut arrow2_semantic: FxHashMap, Ident<'_>> = FxHashMap::default(); let mut arrow2_ctx = make_context_var_op(&allocator, XrefId(2), parent_view); name_variable_op( @@ -1383,10 +1383,10 @@ mod tests { fn test_shared_map_causes_incorrect_deduplication_for_arrow_functions() { let allocator = Allocator::default(); let mut state = NamingState { index: 0 }; - let mut var_names: FxHashMap> = FxHashMap::default(); + let mut var_names: FxHashMap> = FxHashMap::default(); // Use a SINGLE shared semantic map (simulating the buggy behavior). - let mut shared_semantic: FxHashMap, Atom<'_>> = + let mut shared_semantic: FxHashMap, Ident<'_>> = FxHashMap::default(); let parent_view = XrefId(100); diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/parse_extracted_styles.rs b/crates/oxc_angular_compiler/src/pipeline/phases/parse_extracted_styles.rs index 97200b911..56df651b6 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/parse_extracted_styles.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/parse_extracted_styles.rs @@ -6,7 +6,7 @@ //! Ported from Angular's `template/pipeline/src/phases/parse_extracted_styles.ts`. use oxc_allocator::Box; -use oxc_span::Atom; +use oxc_span::Ident; use rustc_hash::FxHashSet; use crate::ast::expression::{ @@ -65,7 +65,7 @@ pub fn parse_extracted_styles(job: &mut ComponentCompilationJob<'_>) { // We collect first because we need to insert new ops and remove old ones for view_xref in &view_xrefs { // Collect ops to process - let ops_to_process: std::vec::Vec<(XrefId, Atom<'_>, String)> = { + let ops_to_process: std::vec::Vec<(XrefId, Ident<'_>, String)> = { let Some(view) = job.view(*view_xref) else { continue; }; @@ -113,7 +113,7 @@ pub fn parse_extracted_styles(job: &mut ComponentCompilationJob<'_>) { LiteralPrimitive { span: ParseSpan::new(0, 0), source_span: AbsoluteSourceSpan::new(0, 0), - value: LiteralValue::String(Atom::from( + value: LiteralValue::String(Ident::from( allocator.alloc_str(&prop_value), )), }, @@ -129,7 +129,7 @@ pub fn parse_extracted_styles(job: &mut ComponentCompilationJob<'_>) { target, binding_kind: BindingKind::StyleProperty, namespace: None, - name: Atom::from(allocator.alloc_str(&prop_name)), + name: Ident::from(allocator.alloc_str(&prop_name)), value: Some(value_expr), security_context: SecurityContext::Style, truthy_expression: false, @@ -159,7 +159,7 @@ pub fn parse_extracted_styles(job: &mut ComponentCompilationJob<'_>) { target, binding_kind: BindingKind::ClassName, namespace: None, - name: Atom::from(allocator.alloc_str(&class_name)), + name: Ident::from(allocator.alloc_str(&class_name)), value: None, security_context: SecurityContext::None, truthy_expression: false, @@ -351,7 +351,7 @@ pub fn parse_extracted_styles_for_host(job: &mut HostBindingCompilationJob<'_>) let allocator = job.allocator; // Collect style/class attributes to parse - let ops_to_process: std::vec::Vec<(XrefId, Atom<'_>, String)> = job + let ops_to_process: std::vec::Vec<(XrefId, Ident<'_>, String)> = job .root .create .iter() @@ -386,7 +386,7 @@ pub fn parse_extracted_styles_for_host(job: &mut HostBindingCompilationJob<'_>) LiteralPrimitive { span: ParseSpan::new(0, 0), source_span: AbsoluteSourceSpan::new(0, 0), - value: LiteralValue::String(Atom::from( + value: LiteralValue::String(Ident::from( allocator.alloc_str(&prop_value), )), }, @@ -402,7 +402,7 @@ pub fn parse_extracted_styles_for_host(job: &mut HostBindingCompilationJob<'_>) target, binding_kind: BindingKind::StyleProperty, namespace: None, - name: Atom::from(allocator.alloc_str(&prop_name)), + name: Ident::from(allocator.alloc_str(&prop_name)), value: Some(value_expr), security_context: SecurityContext::Style, truthy_expression: false, @@ -429,7 +429,7 @@ pub fn parse_extracted_styles_for_host(job: &mut HostBindingCompilationJob<'_>) target, binding_kind: BindingKind::ClassName, namespace: None, - name: Atom::from(allocator.alloc_str(&class_name)), + name: Ident::from(allocator.alloc_str(&class_name)), value: None, security_context: SecurityContext::None, truthy_expression: false, diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/pipe_creation.rs b/crates/oxc_angular_compiler/src/pipeline/phases/pipe_creation.rs index 428d89ca3..1707442a1 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/pipe_creation.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/pipe_creation.rs @@ -212,7 +212,7 @@ struct PipeInfo<'a> { /// This is preserved from the expression to match Angular's behavior. target_slot: SlotHandle, /// Pipe name. - name: oxc_span::Atom<'a>, + name: oxc_span::Ident<'a>, /// Number of arguments (including the input expression). num_args: u32, /// Target element xref (for compatibility mode insertion ordering). diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/pure_literal_structures.rs b/crates/oxc_angular_compiler/src/pipeline/phases/pure_literal_structures.rs index a9eead152..476de4c13 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/pure_literal_structures.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/pure_literal_structures.rs @@ -292,21 +292,21 @@ fn create_pure_function_for_ir_array<'a>( /// Create a PureFunctionExpr for a literal map with IR expression values. fn create_pure_function_for_ir_map<'a>( - keys: &oxc_allocator::Vec<'a, oxc_span::Atom<'a>>, + keys: &oxc_allocator::Vec<'a, oxc_span::Ident<'a>>, values: &oxc_allocator::Vec<'a, IrExpression<'a>>, quoted: &oxc_allocator::Vec<'a, bool>, allocator: &'a oxc_allocator::Allocator, expressions: &ExpressionStore<'a>, ) -> Option> { let mut args: AllocVec<'a, IrExpression<'a>> = AllocVec::new_in(allocator); - let mut body_keys: AllocVec<'a, oxc_span::Atom<'a>> = AllocVec::new_in(allocator); + let mut body_keys: AllocVec<'a, oxc_span::Ident<'a>> = AllocVec::new_in(allocator); let mut body_values: AllocVec<'a, IrExpression<'a>> = AllocVec::new_in(allocator); let mut body_quoted: AllocVec<'a, bool> = AllocVec::new_in(allocator); let mut param_index: u32 = 0; for (i, value) in values.iter().enumerate() { // Get key and quoted from the arrays - let key = keys.get(i).cloned().unwrap_or_else(|| oxc_span::Atom::from("")); + let key = keys.get(i).cloned().unwrap_or_else(|| oxc_span::Ident::from("")); let is_quoted = quoted.get(i).copied().unwrap_or(false); body_keys.push(key); body_quoted.push(is_quoted); @@ -399,7 +399,7 @@ fn create_pure_function_for_map<'a>( allocator: &'a oxc_allocator::Allocator, ) -> Option> { let mut args: AllocVec<'a, IrExpression<'a>> = AllocVec::new_in(allocator); - let mut body_keys: AllocVec<'a, oxc_span::Atom<'a>> = AllocVec::new_in(allocator); + let mut body_keys: AllocVec<'a, oxc_span::Ident<'a>> = AllocVec::new_in(allocator); let mut body_values: AllocVec<'a, IrExpression<'a>> = AllocVec::new_in(allocator); let mut body_quoted: AllocVec<'a, bool> = AllocVec::new_in(allocator); let mut param_index: u32 = 0; @@ -417,7 +417,7 @@ fn create_pure_function_for_map<'a>( None // Skip spread keys } }) - .unwrap_or_else(|| (oxc_span::Atom::from(""), false)); + .unwrap_or_else(|| (oxc_span::Ident::from(""), false)); body_keys.push(key); body_quoted.push(quoted); diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/regular_expression_optimization.rs b/crates/oxc_angular_compiler/src/pipeline/phases/regular_expression_optimization.rs index 9913a22e2..cb7e6f79f 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/regular_expression_optimization.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/regular_expression_optimization.rs @@ -7,7 +7,7 @@ //! Ported from Angular's `template/pipeline/src/phases/regular_expression_optimization.ts`. use oxc_allocator::Box; -use oxc_span::Atom; +use oxc_span::Ident; use crate::ast::expression::AngularExpression; use crate::ir::expression::IrExpression; @@ -32,7 +32,7 @@ pub fn optimize_regular_expressions(job: &mut ComponentCompilationJob<'_>) { // First pass: Pool regexes and collect their names for replacement // We need to collect regex info and pool them first, then do the replacement - let mut regex_replacements: Vec<(String, Option, Atom<'_>)> = Vec::new(); + let mut regex_replacements: Vec<(String, Option, Ident<'_>)> = Vec::new(); // Collect and pool all non-global regexes from root view using split borrow { @@ -86,7 +86,7 @@ pub fn optimize_regular_expressions(job: &mut ComponentCompilationJob<'_>) { } /// Check if regex flags contain the global flag. -fn is_global_regex(flags: Option<&oxc_span::Atom<'_>>) -> bool { +fn is_global_regex(flags: Option<&oxc_span::Ident<'_>>) -> bool { flags.map_or(false, |f| f.contains('g')) } @@ -99,7 +99,7 @@ fn make_regex_key(body: &str, flags: Option<&str>) -> String { fn collect_and_pool_regexes_from_create_op<'a>( op: &CreateOp<'a>, pool: &mut crate::pipeline::constant_pool::ConstantPool<'a>, - replacements: &mut Vec<(String, Option, Atom<'a>)>, + replacements: &mut Vec<(String, Option, Ident<'a>)>, ) { match op { CreateOp::Variable(var) => { @@ -133,7 +133,7 @@ fn collect_and_pool_regexes_from_create_op<'a>( fn collect_and_pool_regexes_from_update_op<'a>( op: &UpdateOp<'a>, pool: &mut crate::pipeline::constant_pool::ConstantPool<'a>, - replacements: &mut Vec<(String, Option, Atom<'a>)>, + replacements: &mut Vec<(String, Option, Ident<'a>)>, ) { match op { UpdateOp::Property(prop) => { @@ -162,7 +162,7 @@ fn collect_and_pool_regexes_from_update_op<'a>( fn collect_and_pool_from_expr<'a>( expr: &IrExpression<'a>, pool: &mut crate::pipeline::constant_pool::ConstantPool<'a>, - replacements: &mut Vec<(String, Option, Atom<'a>)>, + replacements: &mut Vec<(String, Option, Ident<'a>)>, ) { if let IrExpression::Ast(ast_expr) = expr { if let AngularExpression::RegularExpressionLiteral(regex) = ast_expr.as_ref() { @@ -191,7 +191,7 @@ fn collect_and_pool_from_expr<'a>( fn transform_regexes_in_create_op<'a>( op: &mut CreateOp<'a>, allocator: &'a oxc_allocator::Allocator, - replacements: &[(String, Option, Atom<'a>)], + replacements: &[(String, Option, Ident<'a>)], ) { match op { CreateOp::Variable(var) => { @@ -225,7 +225,7 @@ fn transform_regexes_in_create_op<'a>( fn transform_regexes_in_update_op<'a>( op: &mut UpdateOp<'a>, allocator: &'a oxc_allocator::Allocator, - replacements: &[(String, Option, Atom<'a>)], + replacements: &[(String, Option, Ident<'a>)], ) { match op { UpdateOp::Property(prop) => { @@ -254,7 +254,7 @@ fn transform_regexes_in_update_op<'a>( fn transform_expr<'a>( expr: &mut IrExpression<'a>, allocator: &'a oxc_allocator::Allocator, - replacements: &[(String, Option, Atom<'a>)], + replacements: &[(String, Option, Ident<'a>)], ) { if let IrExpression::Ast(ast_expr) = expr { if let AngularExpression::RegularExpressionLiteral(regex) = ast_expr.as_ref() { @@ -285,7 +285,7 @@ fn transform_expr<'a>( /// Host version - only processes the root unit (no embedded views). pub fn optimize_regular_expressions_for_host(job: &mut HostBindingCompilationJob<'_>) { let allocator = job.allocator; - let mut regex_replacements: Vec<(String, Option, Atom<'_>)> = Vec::new(); + let mut regex_replacements: Vec<(String, Option, Ident<'_>)> = Vec::new(); // First pass: Pool regexes from root unit { diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/reify/angular_expression.rs b/crates/oxc_angular_compiler/src/pipeline/phases/reify/angular_expression.rs index 22c776241..269588e90 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/reify/angular_expression.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/reify/angular_expression.rs @@ -3,7 +3,7 @@ use std::cell::RefCell; use oxc_allocator::{Box, Vec as OxcVec}; -use oxc_span::Atom; +use oxc_span::Ident; use crate::ast::expression::AngularExpression; use crate::ir::ops::XrefId; @@ -29,13 +29,13 @@ impl<'a> SafeConversionContext<'a> { } /// Allocates a new temporary variable name. - fn allocate_temp_name(&self) -> Atom<'a> { + fn allocate_temp_name(&self) -> Ident<'a> { let mut count = self.temp_count.borrow_mut(); // Use op_index 0 since angular_expression conversion happens during reify // The actual op_index will be adjusted by temporary_variables phase if needed let name = format!("tmp_0_{}", *count); *count += 1; - Atom::from(self.allocator.alloc_str(&name)) + Ident::from(self.allocator.alloc_str(&name)) } } @@ -130,7 +130,7 @@ fn convert_angular_expression_with_ctx<'a>( // Implicit receiver becomes ctx OutputExpression::ReadVar(Box::new_in( ReadVarExpr { - name: Atom::from("ctx"), + name: Ident::from("ctx"), source_span: Some(ir.source_span.to_span()), }, allocator, @@ -141,7 +141,7 @@ fn convert_angular_expression_with_ctx<'a>( // This receiver becomes ctx OutputExpression::ReadVar(Box::new_in( ReadVarExpr { - name: Atom::from("ctx"), + name: Ident::from("ctx"), source_span: Some(tr.source_span.to_span()), }, allocator, @@ -155,7 +155,7 @@ fn convert_angular_expression_with_ctx<'a>( if matches!(&prop.receiver, AngularExpression::ImplicitReceiver(_)) { return OutputExpression::ReadVar(Box::new_in( ReadVarExpr { - name: Atom::from("$event"), + name: Ident::from("$event"), source_span: Some(prop.source_span.to_span()), }, allocator, @@ -733,7 +733,7 @@ fn convert_angular_expression_with_ctx<'a>( } else { OutputExpression::Literal(Box::new_in( LiteralExpr { - value: LiteralValue::String(Atom::from("")), + value: LiteralValue::String(Ident::from("")), source_span: Some(interp.source_span.to_span()), }, allocator, diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/reify/ir_expression.rs b/crates/oxc_angular_compiler/src/pipeline/phases/reify/ir_expression.rs index 1e98084c7..3ff0e6160 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/reify/ir_expression.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/reify/ir_expression.rs @@ -1,7 +1,7 @@ //! IR expression to Output AST conversion. use oxc_allocator::{Box, Vec as OxcVec}; -use oxc_span::Atom; +use oxc_span::Ident; use crate::ast::expression::AngularExpression; use crate::ir::expression::{IrExpression, TwoWayBindingSetExpr}; @@ -39,7 +39,7 @@ pub fn convert_ir_expression<'a>( // Fallback to a debuggable name using xref (should not happen after naming phase) let fallback = format!("_unnamed_{}", var.xref.0); let fallback_str = allocator.alloc_str(&fallback); - Atom::from(fallback_str) + Ident::from(fallback_str) } }; OutputExpression::ReadVar(Box::new_in( @@ -52,7 +52,7 @@ pub fn convert_ir_expression<'a>( // Reference to the component context // This becomes `ctx` in the generated code OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("ctx"), source_span: ctx.source_span }, + ReadVarExpr { name: Ident::from("ctx"), source_span: ctx.source_span }, allocator, )) } @@ -73,7 +73,7 @@ pub fn convert_ir_expression<'a>( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("ctx"), source_span: None }, + ReadVarExpr { name: Ident::from("ctx"), source_span: None }, allocator, )), allocator, @@ -150,7 +150,7 @@ pub fn convert_ir_expression<'a>( crate::ir::expression::RestoreViewTarget::Static(_) => { // Fallback: use _r if not resolved (shouldn't happen in correct flow) args.push(OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("_r"), source_span: None }, + ReadVarExpr { name: Ident::from("_r"), source_span: None }, allocator, ))); } @@ -315,14 +315,14 @@ pub fn convert_ir_expression<'a>( IrExpression::TrackContext(_) => { // Reference to `this` for track functions OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("this"), source_span: None }, + ReadVarExpr { name: Ident::from("this"), source_span: None }, allocator, )) } IrExpression::ReadTemporary(tmp) => { // Read a temporary variable - let var_name = tmp.name.clone().unwrap_or_else(|| Atom::from("_tmp")); + let var_name = tmp.name.clone().unwrap_or_else(|| Ident::from("_tmp")); OutputExpression::ReadVar(Box::new_in( ReadVarExpr { name: var_name, source_span: None }, allocator, @@ -331,7 +331,7 @@ pub fn convert_ir_expression<'a>( IrExpression::AssignTemporary(assign) => { // Assign to a temporary variable: _tmp = expr - let var_name = assign.name.clone().unwrap_or_else(|| Atom::from("_tmp")); + let var_name = assign.name.clone().unwrap_or_else(|| Ident::from("_tmp")); let value = convert_ir_expression(allocator, &assign.expr, expressions, root_xref); OutputExpression::BinaryOperator(Box::new_in( BinaryOperatorExpr { @@ -820,7 +820,7 @@ pub fn convert_ir_expression<'a>( IrExpression::LiteralMap(map) => { let mut entries = OxcVec::with_capacity_in(map.values.len(), allocator); for (i, value) in map.values.iter().enumerate() { - let key = map.keys.get(i).cloned().unwrap_or_else(|| Atom::from("")); + let key = map.keys.get(i).cloned().unwrap_or_else(|| Ident::from("")); let quoted = map.quoted.get(i).copied().unwrap_or(false); let converted_value = convert_ir_expression(allocator, value, expressions, root_xref); @@ -846,7 +846,7 @@ pub fn convert_ir_expression<'a>( IrExpression::DerivedLiteralMap(map) => { let mut entries = OxcVec::with_capacity_in(map.values.len(), allocator); for (i, value) in map.values.iter().enumerate() { - let key = map.keys.get(i).cloned().unwrap_or_else(|| Atom::from("")); + let key = map.keys.get(i).cloned().unwrap_or_else(|| Ident::from("")); let quoted = map.quoted.get(i).copied().unwrap_or(false); let converted_value = convert_ir_expression(allocator, value, expressions, root_xref); diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/reify/mod.rs b/crates/oxc_angular_compiler/src/pipeline/phases/reify/mod.rs index 7cb143a9e..15551c736 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/reify/mod.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/reify/mod.rs @@ -15,7 +15,7 @@ mod utils; use oxc_allocator::{Box, Vec as OxcVec}; use oxc_diagnostics::OxcDiagnostic; -use oxc_span::Atom; +use oxc_span::Ident; use rustc_hash::FxHashMap; use crate::ast::expression::AngularExpression; @@ -103,7 +103,7 @@ fn convert_output_expr_ir_nodes<'a>( /// Context for reifying operations, holding information needed across views. struct ReifyContext<'a> { /// Map from view xref to its function name (set by naming phase). - view_fn_names: FxHashMap>, + view_fn_names: FxHashMap>, /// Map from view xref to its declaration count. view_decls: FxHashMap, /// Map from view xref to its variable count. @@ -1398,7 +1398,7 @@ fn reify_track_by<'a>( expressions: &ExpressionStore<'a>, root_xref: XrefId, track: &IrExpression<'a>, - track_fn_name: Option<&Atom<'a>>, + track_fn_name: Option<&Ident<'a>>, uses_component_instance: bool, track_by_ops: &mut Option>>, diagnostics: &mut Vec, @@ -1411,7 +1411,7 @@ fn reify_track_by<'a>( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, @@ -1428,14 +1428,14 @@ fn reify_track_by<'a>( // Allocate the parts into the arena first let receiver_name_str = allocator.alloc_str(&fn_name[..dot_pos]); let prop_name_str = allocator.alloc_str(&fn_name[dot_pos + 1..]); - let receiver_name = Atom::from(receiver_name_str); - let prop_name = Atom::from(prop_name_str); + let receiver_name = Ident::from(receiver_name_str); + let prop_name = Ident::from(prop_name_str); // Check if receiver ends with "()" indicating a function call if receiver_name.ends_with("()") { // componentInstance().fn pattern let call_name = - Atom::from(allocator.alloc_str(&receiver_name[..receiver_name.len() - 2])); + Ident::from(allocator.alloc_str(&receiver_name[..receiver_name.len() - 2])); return OutputExpression::ReadProp(Box::new_in( ReadPropExpr { receiver: Box::new_in( @@ -1447,7 +1447,7 @@ fn reify_track_by<'a>( receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( ReadVarExpr { - name: Atom::from("i0"), + name: Ident::from("i0"), source_span: None, }, allocator, @@ -1503,8 +1503,8 @@ fn reify_track_by<'a>( // Create the track function with params ($index, $item) let mut params = OxcVec::with_capacity_in(2, allocator); - params.push(FnParam { name: Atom::from("$index") }); - params.push(FnParam { name: Atom::from("$item") }); + params.push(FnParam { name: Ident::from("$index") }); + params.push(FnParam { name: Ident::from("$item") }); let fn_expr = if let Some(track_ops) = track_by_ops { // Complex case: track_by_ops is present (set by track_fn_optimization phase). diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/reify/statements/bindings.rs b/crates/oxc_angular_compiler/src/pipeline/phases/reify/statements/bindings.rs index dfbe89c41..e6f63c56b 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/reify/statements/bindings.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/reify/statements/bindings.rs @@ -1,7 +1,7 @@ //! Property, style, class, and attribute binding statement generation. use oxc_allocator::{Box, Vec as OxcVec}; -use oxc_span::Atom; +use oxc_span::Ident; use crate::output::ast::{ LiteralExpr, LiteralValue, OutputExpression, OutputStatement, ReadPropExpr, ReadVarExpr, @@ -28,14 +28,14 @@ pub fn is_aria_attribute(name: &str) -> bool { /// DOM properties that need to be remapped on the compiler side. /// Note: this mapping has to be kept in sync with the equally named mapping in the Angular runtime. /// See: Angular's `template/pipeline/src/phases/reify.ts` -fn remap_dom_property<'a>(name: &Atom<'a>) -> Atom<'a> { +fn remap_dom_property<'a>(name: &Ident<'a>) -> Ident<'a> { match name.as_str() { - "class" => Atom::from("className"), - "for" => Atom::from("htmlFor"), - "formaction" => Atom::from("formAction"), - "innerHtml" => Atom::from("innerHTML"), - "readonly" => Atom::from("readOnly"), - "tabindex" => Atom::from("tabIndex"), + "class" => Ident::from("className"), + "for" => Ident::from("htmlFor"), + "formaction" => Ident::from("formAction"), + "innerHtml" => Ident::from("innerHTML"), + "readonly" => Ident::from("readOnly"), + "tabindex" => Ident::from("tabIndex"), _ => name.clone(), } } @@ -46,14 +46,14 @@ fn remap_dom_property<'a>(name: &Atom<'a>) -> Atom<'a> { /// This creates an expression like `i0.ɵɵsanitizeHtml`. fn create_sanitizer_expr<'a>( allocator: &'a oxc_allocator::Allocator, - sanitizer: &Atom<'a>, + sanitizer: &Ident<'a>, ) -> OutputExpression<'a> { // Create: i0.ɵɵsanitize* expression OutputExpression::ReadProp(Box::new_in( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, @@ -69,9 +69,9 @@ fn create_sanitizer_expr<'a>( /// Creates an ɵɵproperty() call statement with expression value. pub fn create_property_stmt_with_expr<'a>( allocator: &'a oxc_allocator::Allocator, - name: &Atom<'a>, + name: &Ident<'a>, value: OutputExpression<'a>, - sanitizer: Option<&Atom<'a>>, + sanitizer: Option<&Ident<'a>>, ) -> OutputStatement<'a> { let mut args = OxcVec::new_in(allocator); args.push(OutputExpression::Literal(Box::new_in( @@ -91,7 +91,7 @@ pub fn create_property_stmt_with_expr<'a>( /// that sets the ARIA attribute rather than a DOM property. pub fn create_aria_property_stmt<'a>( allocator: &'a oxc_allocator::Allocator, - name: &Atom<'a>, + name: &Ident<'a>, value: OutputExpression<'a>, ) -> OutputStatement<'a> { let mut args = OxcVec::new_in(allocator); @@ -106,7 +106,7 @@ pub fn create_aria_property_stmt<'a>( /// Creates a generic binding statement with expression value. pub fn create_binding_stmt_with_expr<'a>( allocator: &'a oxc_allocator::Allocator, - name: &Atom<'a>, + name: &Ident<'a>, value: OutputExpression<'a>, ) -> OutputStatement<'a> { let mut args = OxcVec::new_in(allocator); @@ -122,9 +122,9 @@ pub fn create_binding_stmt_with_expr<'a>( /// Creates an ɵɵstyleProp() call statement with expression. pub fn create_style_prop_stmt_with_expr<'a>( allocator: &'a oxc_allocator::Allocator, - name: &Atom<'a>, + name: &Ident<'a>, value: OutputExpression<'a>, - unit: Option<&Atom<'a>>, + unit: Option<&Ident<'a>>, ) -> OutputStatement<'a> { let mut args = OxcVec::new_in(allocator); args.push(OutputExpression::Literal(Box::new_in( @@ -145,7 +145,7 @@ pub fn create_style_prop_stmt_with_expr<'a>( /// Creates an ɵɵclassProp() call statement with expression. pub fn create_class_prop_stmt_with_expr<'a>( allocator: &'a oxc_allocator::Allocator, - name: &Atom<'a>, + name: &Ident<'a>, value: OutputExpression<'a>, ) -> OutputStatement<'a> { let mut args = OxcVec::new_in(allocator); @@ -163,10 +163,10 @@ pub fn create_class_prop_stmt_with_expr<'a>( /// If sanitizer is None but namespace is Some, emits null for sanitizer. pub fn create_attribute_stmt_with_expr<'a>( allocator: &'a oxc_allocator::Allocator, - name: &Atom<'a>, + name: &Ident<'a>, value: OutputExpression<'a>, - sanitizer: Option<&Atom<'a>>, - namespace: Option<&Atom<'a>>, + sanitizer: Option<&Ident<'a>>, + namespace: Option<&Ident<'a>>, ) -> OutputStatement<'a> { let mut args = OxcVec::new_in(allocator); args.push(OutputExpression::Literal(Box::new_in( @@ -198,9 +198,9 @@ pub fn create_attribute_stmt_with_expr<'a>( /// Creates an ɵɵtwoWayProperty() call statement. pub fn create_two_way_property_stmt<'a>( allocator: &'a oxc_allocator::Allocator, - name: &Atom<'a>, + name: &Ident<'a>, value: OutputExpression<'a>, - sanitizer: Option<&Atom<'a>>, + sanitizer: Option<&Ident<'a>>, ) -> OutputStatement<'a> { let mut args = OxcVec::new_in(allocator); args.push(OutputExpression::Literal(Box::new_in( @@ -221,9 +221,9 @@ pub fn create_two_way_property_stmt<'a>( /// The property name is remapped if necessary (e.g., `for` -> `htmlFor`). pub fn create_dom_property_stmt<'a>( allocator: &'a oxc_allocator::Allocator, - name: &Atom<'a>, + name: &Ident<'a>, value: OutputExpression<'a>, - sanitizer: Option<&Atom<'a>>, + sanitizer: Option<&Ident<'a>>, ) -> OutputStatement<'a> { let remapped_name = remap_dom_property(name); let mut args = OxcVec::new_in(allocator); @@ -284,10 +284,10 @@ pub fn create_text_interpolate_stmt_with_args<'a>( /// Arguments: name, [s0, v0, s1, v1, ..., sN], [sanitizer] pub fn create_property_interpolate_stmt<'a>( allocator: &'a oxc_allocator::Allocator, - name: &Atom<'a>, + name: &Ident<'a>, interp_args: OxcVec<'a, OutputExpression<'a>>, expr_count: usize, - sanitizer: Option<&Atom<'a>>, + sanitizer: Option<&Ident<'a>>, ) -> OutputStatement<'a> { // Save length before consuming interp_args — the simple case check must use // the interpolation args count, not the final args count (which includes name @@ -327,11 +327,11 @@ pub fn create_property_interpolate_stmt<'a>( /// Arguments: name, [s0, v0, s1, v1, ..., sN], [sanitizer], [namespace] pub fn create_attribute_interpolate_stmt<'a>( allocator: &'a oxc_allocator::Allocator, - name: &Atom<'a>, + name: &Ident<'a>, interp_args: OxcVec<'a, OutputExpression<'a>>, expr_count: usize, - sanitizer: Option<&Atom<'a>>, - namespace: Option<&Atom<'a>>, + sanitizer: Option<&Ident<'a>>, + namespace: Option<&Ident<'a>>, ) -> OutputStatement<'a> { // Save length before consuming — same reason as create_property_interpolate_stmt. let interp_args_len = interp_args.len(); @@ -376,9 +376,9 @@ pub fn create_attribute_interpolate_stmt<'a>( /// For Angular 19, host/DomOnly property bindings use `ɵɵhostProperty` instead of `ɵɵdomProperty`. pub fn create_host_property_stmt<'a>( allocator: &'a oxc_allocator::Allocator, - name: &Atom<'a>, + name: &Ident<'a>, value: OutputExpression<'a>, - sanitizer: Option<&Atom<'a>>, + sanitizer: Option<&Ident<'a>>, ) -> OutputStatement<'a> { let remapped_name = remap_dom_property(name); let mut args = OxcVec::new_in(allocator); @@ -402,10 +402,10 @@ pub fn create_host_property_stmt<'a>( /// Signature: `ɵɵstylePropInterpolateN(prop, s0, v0, ..., [unit])` pub fn create_style_prop_interpolate_stmt<'a>( allocator: &'a oxc_allocator::Allocator, - name: &Atom<'a>, + name: &Ident<'a>, interp_args: OxcVec<'a, OutputExpression<'a>>, expr_count: usize, - unit: Option<&Atom<'a>>, + unit: Option<&Ident<'a>>, ) -> OutputStatement<'a> { let mut args = OxcVec::new_in(allocator); // First arg: style property name diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/reify/statements/control_flow.rs b/crates/oxc_angular_compiler/src/pipeline/phases/reify/statements/control_flow.rs index 1ae1ea7ac..d3a6d1a09 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/reify/statements/control_flow.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/reify/statements/control_flow.rs @@ -1,7 +1,7 @@ //! Control flow and variable statement generation. use oxc_allocator::{Box, Vec as OxcVec}; -use oxc_span::Atom; +use oxc_span::Ident; use crate::output::ast::{ DeclareVarStmt, LiteralExpr, LiteralValue, OutputExpression, OutputStatement, ReadPropExpr, @@ -27,10 +27,10 @@ use super::super::utils::create_instruction_call_stmt; pub fn create_conditional_create_stmt<'a>( allocator: &'a oxc_allocator::Allocator, slot: u32, - fn_name: Option>, + fn_name: Option>, decls: Option, vars: Option, - tag: Option<&Atom<'a>>, + tag: Option<&Ident<'a>>, attributes: Option, local_refs_index: Option, ) -> OutputStatement<'a> { @@ -52,7 +52,7 @@ pub fn create_conditional_create_stmt<'a>( // Fallback placeholder let placeholder_str = allocator.alloc_str(&format!("_c{slot}")); args.push(OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from(placeholder_str), source_span: None }, + ReadVarExpr { name: Ident::from(placeholder_str), source_span: None }, allocator, ))); } @@ -109,12 +109,12 @@ pub fn create_conditional_create_stmt<'a>( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(Identifiers::TEMPLATE_REF_EXTRACTOR), + name: Ident::from(Identifiers::TEMPLATE_REF_EXTRACTOR), optional: false, source_span: None, }, @@ -168,10 +168,10 @@ pub fn create_conditional_update_stmt<'a>( pub fn create_conditional_branch_create_stmt<'a>( allocator: &'a oxc_allocator::Allocator, slot: u32, - fn_name: Option>, + fn_name: Option>, decls: Option, vars: Option, - tag: Option<&Atom<'a>>, + tag: Option<&Ident<'a>>, attributes: Option, local_refs_index: Option, ) -> OutputStatement<'a> { @@ -193,7 +193,7 @@ pub fn create_conditional_branch_create_stmt<'a>( // Fallback placeholder let placeholder_str = allocator.alloc_str(&format!("_c{slot}")); args.push(OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from(placeholder_str), source_span: None }, + ReadVarExpr { name: Ident::from(placeholder_str), source_span: None }, allocator, ))); } @@ -250,12 +250,12 @@ pub fn create_conditional_branch_create_stmt<'a>( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(Identifiers::TEMPLATE_REF_EXTRACTOR), + name: Ident::from(Identifiers::TEMPLATE_REF_EXTRACTOR), optional: false, source_span: None, }, @@ -324,17 +324,17 @@ pub fn create_repeater_stmt<'a>( pub fn create_repeater_create_stmt_with_track_expr<'a>( allocator: &'a oxc_allocator::Allocator, slot: u32, - fn_name: Option>, + fn_name: Option>, body_decl_count: Option, body_var_count: Option, - tag: Option<&Atom<'a>>, + tag: Option<&Ident<'a>>, attributes: Option, track_fn_expr: OutputExpression<'a>, uses_component_instance: bool, - empty_fn_name: Option>, + empty_fn_name: Option>, empty_decls: Option, empty_vars: Option, - empty_tag: Option<&Atom<'a>>, + empty_tag: Option<&Ident<'a>>, empty_attributes: Option, ) -> OutputStatement<'a> { let mut args = OxcVec::new_in(allocator); @@ -355,7 +355,7 @@ pub fn create_repeater_create_stmt_with_track_expr<'a>( // Fallback placeholder let placeholder_str = allocator.alloc_str(&format!("_r{slot}")); args.push(OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from(placeholder_str), source_span: None }, + ReadVarExpr { name: Ident::from(placeholder_str), source_span: None }, allocator, ))); } @@ -476,7 +476,7 @@ pub fn create_repeater_create_stmt_with_track_expr<'a>( /// All Variable ops use `const` (StmtModifier::Final), matching Angular's reify.ts. pub fn create_variable_decl_stmt_with_value<'a>( allocator: &'a oxc_allocator::Allocator, - name: &Atom<'a>, + name: &Ident<'a>, value: OutputExpression<'a>, ) -> OutputStatement<'a> { OutputStatement::DeclareVar(Box::new_in( @@ -524,7 +524,7 @@ mod tests { let stmt = create_conditional_create_stmt( &allocator, 0, - Some(Atom::from("TestComponent_Conditional_0_Template")), + Some(Ident::from("TestComponent_Conditional_0_Template")), Some(1), Some(0), None, @@ -553,7 +553,7 @@ mod tests { let stmt = create_conditional_create_stmt( &allocator, 0, - Some(Atom::from("TestComponent_Conditional_0_Template")), + Some(Ident::from("TestComponent_Conditional_0_Template")), Some(1), Some(0), None, @@ -575,7 +575,7 @@ mod tests { let stmt = create_conditional_branch_create_stmt( &allocator, 1, - Some(Atom::from("TestComponent_Conditional_1_Template")), + Some(Ident::from("TestComponent_Conditional_1_Template")), Some(1), Some(0), None, @@ -602,7 +602,7 @@ mod tests { let stmt = create_conditional_branch_create_stmt( &allocator, 1, - Some(Atom::from("TestComponent_Conditional_1_Template")), + Some(Ident::from("TestComponent_Conditional_1_Template")), Some(1), Some(0), None, diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/reify/statements/defer.rs b/crates/oxc_angular_compiler/src/pipeline/phases/reify/statements/defer.rs index 298973d90..87a7985c8 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/reify/statements/defer.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/reify/statements/defer.rs @@ -1,7 +1,7 @@ //! @defer block statement generation. use oxc_allocator::{Box, Vec as OxcVec}; -use oxc_span::Atom; +use oxc_span::Ident; use crate::ir::enums::{DeferOpModifierKind, DeferTriggerKind}; use crate::output::ast::{ @@ -141,12 +141,12 @@ pub fn create_defer_stmt<'a>( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(Identifiers::DEFER_ENABLE_TIMER_SCHEDULING), + name: Ident::from(Identifiers::DEFER_ENABLE_TIMER_SCHEDULING), optional: false, source_span: None, }, diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/reify/statements/elements.rs b/crates/oxc_angular_compiler/src/pipeline/phases/reify/statements/elements.rs index 7bf8331ee..09d5636cf 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/reify/statements/elements.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/reify/statements/elements.rs @@ -1,7 +1,7 @@ //! Element, container, template, and text statement generation. use oxc_allocator::{Box, Vec as OxcVec}; -use oxc_span::Atom; +use oxc_span::Ident; use crate::output::ast::{ LiteralExpr, LiteralValue, OutputExpression, OutputStatement, ReadPropExpr, ReadVarExpr, @@ -16,7 +16,7 @@ use super::super::utils::create_instruction_call_stmt; /// If localRefIndex is present, constIndex must also be present (even if null). pub fn create_element_args<'a>( allocator: &'a oxc_allocator::Allocator, - tag: &Atom<'a>, + tag: &Ident<'a>, slot: u32, attributes: Option, local_refs_index: Option, @@ -64,7 +64,7 @@ pub fn create_element_args<'a>( /// Creates an ɵɵelementStart() call statement. pub fn create_element_start_stmt<'a>( allocator: &'a oxc_allocator::Allocator, - tag: &Atom<'a>, + tag: &Ident<'a>, slot: u32, attributes: Option, local_refs_index: Option, @@ -76,7 +76,7 @@ pub fn create_element_start_stmt<'a>( /// Creates an ɵɵelement() call statement. pub fn create_element_stmt<'a>( allocator: &'a oxc_allocator::Allocator, - tag: &Atom<'a>, + tag: &Ident<'a>, slot: u32, attributes: Option, local_refs_index: Option, @@ -100,7 +100,7 @@ pub fn create_element_end_stmt<'a>(allocator: &'a oxc_allocator::Allocator) -> O /// This is an optimized version that skips directive matching at runtime. pub fn create_dom_element_start_stmt<'a>( allocator: &'a oxc_allocator::Allocator, - tag: &Atom<'a>, + tag: &Ident<'a>, slot: u32, attributes: Option, local_refs_index: Option, @@ -115,7 +115,7 @@ pub fn create_dom_element_start_stmt<'a>( /// This is an optimized version that skips directive matching at runtime. pub fn create_dom_element_stmt<'a>( allocator: &'a oxc_allocator::Allocator, - tag: &Atom<'a>, + tag: &Ident<'a>, slot: u32, attributes: Option, local_refs_index: Option, @@ -175,10 +175,10 @@ pub fn create_text_stmt<'a>( pub fn create_template_stmt<'a>( allocator: &'a oxc_allocator::Allocator, slot: u32, - fn_name: Option>, + fn_name: Option>, decls: Option, vars: Option, - tag: Option<&Atom<'a>>, + tag: Option<&Ident<'a>>, attributes: Option, local_refs_index: Option, ) -> OutputStatement<'a> { @@ -202,10 +202,10 @@ pub fn create_template_stmt<'a>( fn create_template_args<'a>( allocator: &'a oxc_allocator::Allocator, slot: u32, - fn_name: Option>, + fn_name: Option>, decls: Option, vars: Option, - tag: Option<&Atom<'a>>, + tag: Option<&Ident<'a>>, attributes: Option, local_refs_index: Option, ) -> OxcVec<'a, OutputExpression<'a>> { @@ -225,7 +225,7 @@ fn create_template_args<'a>( ))); } else { let placeholder_str = allocator.alloc_str(&format!("_r{slot}")); - let placeholder = Atom::from(placeholder_str); + let placeholder = Ident::from(placeholder_str); args.push(OutputExpression::ReadVar(Box::new_in( ReadVarExpr { name: placeholder, source_span: None }, allocator, @@ -283,12 +283,12 @@ fn create_template_args<'a>( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(Identifiers::TEMPLATE_REF_EXTRACTOR), + name: Ident::from(Identifiers::TEMPLATE_REF_EXTRACTOR), optional: false, source_span: None, }, @@ -326,10 +326,10 @@ fn create_template_args<'a>( pub fn create_dom_template_stmt<'a>( allocator: &'a oxc_allocator::Allocator, slot: u32, - fn_name: Option>, + fn_name: Option>, decls: Option, vars: Option, - tag: Option<&Atom<'a>>, + tag: Option<&Ident<'a>>, attributes: Option, local_refs_index: Option, ) -> OutputStatement<'a> { diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/reify/statements/misc.rs b/crates/oxc_angular_compiler/src/pipeline/phases/reify/statements/misc.rs index 97a665de8..3ec096d44 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/reify/statements/misc.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/reify/statements/misc.rs @@ -1,7 +1,7 @@ //! Miscellaneous statement generation (listener, animation, pipe, projection, etc.). use oxc_allocator::{Box, Vec as OxcVec}; -use oxc_span::Atom; +use oxc_span::Ident; use crate::ir::enums::AnimationKind; use crate::output::ast::{ @@ -55,11 +55,11 @@ impl GlobalEventTarget { /// The `consumes_dollar_event` parameter controls whether the `$event` parameter is included. pub fn create_listener_stmt_with_handler<'a>( allocator: &'a oxc_allocator::Allocator, - name: &Atom<'a>, + name: &Ident<'a>, handler_stmts: OxcVec<'a, OutputStatement<'a>>, event_target: Option, use_capture: bool, - handler_fn_name: Option<&Atom<'a>>, + handler_fn_name: Option<&Ident<'a>>, consumes_dollar_event: bool, ) -> OutputStatement<'a> { let mut args = OxcVec::new_in(allocator); @@ -72,7 +72,7 @@ pub fn create_listener_stmt_with_handler<'a>( // Handler function: function name($event) { ... } or function name() { ... } let mut params = OxcVec::new_in(allocator); if consumes_dollar_event { - params.push(FnParam { name: Atom::from("$event") }); + params.push(FnParam { name: Ident::from("$event") }); } let handler_fn = OutputExpression::Function(Box::new_in( @@ -94,14 +94,14 @@ pub fn create_listener_stmt_with_handler<'a>( receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( crate::output::ast::ReadVarExpr { - name: Atom::from("i0"), + name: Ident::from("i0"), source_span: None, }, allocator, )), allocator, ), - name: Atom::from(target.resolver_instruction()), + name: Ident::from(target.resolver_instruction()), optional: false, source_span: None, }, @@ -135,10 +135,10 @@ pub fn create_listener_stmt_with_handler<'a>( /// The `consumes_dollar_event` parameter controls whether the `$event` parameter is included. pub fn create_dom_listener_stmt_with_handler<'a>( allocator: &'a oxc_allocator::Allocator, - name: &Atom<'a>, + name: &Ident<'a>, handler_stmts: OxcVec<'a, OutputStatement<'a>>, event_target: Option, - handler_fn_name: Option<&Atom<'a>>, + handler_fn_name: Option<&Ident<'a>>, consumes_dollar_event: bool, ) -> OutputStatement<'a> { let mut args = OxcVec::new_in(allocator); @@ -151,7 +151,7 @@ pub fn create_dom_listener_stmt_with_handler<'a>( // Handler function: function name($event) { ... } or function name() { ... } let mut params = OxcVec::new_in(allocator); if consumes_dollar_event { - params.push(FnParam { name: Atom::from("$event") }); + params.push(FnParam { name: Ident::from("$event") }); } let handler_fn = OutputExpression::Function(Box::new_in( @@ -173,14 +173,14 @@ pub fn create_dom_listener_stmt_with_handler<'a>( receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( crate::output::ast::ReadVarExpr { - name: Atom::from("i0"), + name: Ident::from("i0"), source_span: None, }, allocator, )), allocator, ), - name: Atom::from(target.resolver_instruction()), + name: Ident::from(target.resolver_instruction()), optional: false, source_span: None, }, @@ -196,9 +196,9 @@ pub fn create_dom_listener_stmt_with_handler<'a>( /// The `handler_fn_name` parameter sets the name of the handler function expression. pub fn create_two_way_listener_stmt<'a>( allocator: &'a oxc_allocator::Allocator, - name: &Atom<'a>, + name: &Ident<'a>, handler_stmts: OxcVec<'a, OutputStatement<'a>>, - handler_fn_name: Option<&Atom<'a>>, + handler_fn_name: Option<&Ident<'a>>, ) -> OutputStatement<'a> { let mut args = OxcVec::new_in(allocator); // Event name (typically "{property}Change") @@ -210,7 +210,7 @@ pub fn create_two_way_listener_stmt<'a>( // Handler function: function name($event) { ... } // Two-way listeners always consume $event since they need the new value let mut params = OxcVec::new_in(allocator); - params.push(FnParam { name: Atom::from("$event") }); + params.push(FnParam { name: Ident::from("$event") }); let handler_fn = OutputExpression::Function(Box::new_in( FunctionExpr { @@ -236,10 +236,10 @@ pub fn create_two_way_listener_stmt<'a>( /// The `consumes_dollar_event` parameter controls whether the `$event` parameter is included. pub fn create_animation_listener_stmt<'a>( allocator: &'a oxc_allocator::Allocator, - name: &Atom<'a>, + name: &Ident<'a>, phase: crate::ir::enums::AnimationKind, handler_stmts: OxcVec<'a, OutputStatement<'a>>, - handler_fn_name: Option<&Atom<'a>>, + handler_fn_name: Option<&Ident<'a>>, consumes_dollar_event: bool, ) -> OutputStatement<'a> { let mut args = OxcVec::new_in(allocator); @@ -252,14 +252,14 @@ pub fn create_animation_listener_stmt<'a>( }; let full_name = allocator.alloc_str(&format!("@{}.{}", name.as_str(), phase_str)); args.push(OutputExpression::Literal(Box::new_in( - LiteralExpr { value: LiteralValue::String(Atom::from(full_name)), source_span: None }, + LiteralExpr { value: LiteralValue::String(Ident::from(full_name)), source_span: None }, allocator, ))); // Handler function: function name($event) { ... } or function name() { ... } let mut params = OxcVec::new_in(allocator); if consumes_dollar_event { - params.push(FnParam { name: Atom::from("$event") }); + params.push(FnParam { name: Ident::from("$event") }); } let handler_fn = OutputExpression::Function(Box::new_in( @@ -300,7 +300,7 @@ pub fn create_animation_string_stmt<'a>( /// It emits `syntheticHostProperty(name, value)`. pub fn create_animation_stmt<'a>( allocator: &'a oxc_allocator::Allocator, - name: &Atom<'a>, + name: &Ident<'a>, value: OutputExpression<'a>, ) -> OutputStatement<'a> { let mut args = OxcVec::new_in(allocator); @@ -308,7 +308,7 @@ pub fn create_animation_stmt<'a>( // Animation name with @ prefix let full_name = allocator.alloc_str(&format!("@{}", name.as_str())); args.push(OutputExpression::Literal(Box::new_in( - LiteralExpr { value: LiteralValue::String(Atom::from(full_name)), source_span: None }, + LiteralExpr { value: LiteralValue::String(Ident::from(full_name)), source_span: None }, allocator, ))); args.push(value); @@ -334,7 +334,7 @@ pub fn create_animation_op_stmt<'a>( allocator: &'a oxc_allocator::Allocator, animation_kind: AnimationKind, handler_stmts: OxcVec<'a, OutputStatement<'a>>, - handler_fn_name: Option<&Atom<'a>>, + handler_fn_name: Option<&Ident<'a>>, ) -> OutputStatement<'a> { let mut args = OxcVec::new_in(allocator); @@ -363,7 +363,7 @@ pub fn create_animation_op_stmt<'a>( /// Creates an animation binding call statement. pub fn create_animation_binding_stmt<'a>( allocator: &'a oxc_allocator::Allocator, - name: &Atom<'a>, + name: &Ident<'a>, value: OutputExpression<'a>, ) -> OutputStatement<'a> { let mut args = OxcVec::new_in(allocator); @@ -387,7 +387,7 @@ pub fn create_animation_binding_stmt<'a>( pub fn create_control_stmt<'a>( allocator: &'a oxc_allocator::Allocator, value: OutputExpression<'a>, - name: &Atom<'a>, + name: &Ident<'a>, ) -> OutputStatement<'a> { let mut args = OxcVec::new_in(allocator); args.push(value); @@ -438,7 +438,7 @@ pub fn create_enable_bindings_stmt<'a>( pub fn create_pipe_stmt<'a>( allocator: &'a oxc_allocator::Allocator, slot: u32, - name: &Atom<'a>, + name: &Ident<'a>, ) -> OutputStatement<'a> { let mut args = OxcVec::new_in(allocator); args.push(OutputExpression::Literal(Box::new_in( diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/reify/utils.rs b/crates/oxc_angular_compiler/src/pipeline/phases/reify/utils.rs index a9e958e80..f32bd20fc 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/reify/utils.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/reify/utils.rs @@ -1,7 +1,7 @@ //! Shared utilities for the reify phase. use oxc_allocator::{Box, Vec as OxcVec}; -use oxc_span::Atom; +use oxc_span::Ident; use crate::output::ast::{ ExpressionStatement, InvokeFunctionExpr, OutputExpression, OutputStatement, ReadPropExpr, @@ -10,9 +10,9 @@ use crate::output::ast::{ /// Strips a prefix from a binding name if present. /// For example: "class.active" -> "active", "style.color" -> "color", "attr.aria-label" -> "aria-label" -pub fn strip_prefix<'a>(name: &Atom<'a>, prefix: &str) -> Atom<'a> { +pub fn strip_prefix<'a>(name: &Ident<'a>, prefix: &str) -> Ident<'a> { if name.as_str().starts_with(prefix) { - Atom::from(&name.as_str()[prefix.len()..]) + Ident::from(&name.as_str()[prefix.len()..]) } else { name.clone() } @@ -29,12 +29,12 @@ pub fn create_instruction_call_stmt<'a>( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(instruction), + name: Ident::from(instruction), optional: false, source_span: None, }, @@ -68,12 +68,12 @@ pub fn create_instruction_call_expr<'a>( ReadPropExpr { receiver: Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("i0"), source_span: None }, + ReadVarExpr { name: Ident::from("i0"), source_span: None }, allocator, )), allocator, ), - name: Atom::from(instruction), + name: Ident::from(instruction), optional: false, source_span: None, }, diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/remove_illegal_let_references.rs b/crates/oxc_angular_compiler/src/pipeline/phases/remove_illegal_let_references.rs index db2167f6d..0b34acb38 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/remove_illegal_let_references.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/remove_illegal_let_references.rs @@ -18,7 +18,7 @@ //! Ported from Angular's `template/pipeline/src/phases/remove_illegal_let_references.ts`. use oxc_allocator::Box; -use oxc_span::Atom; +use oxc_span::Ident; use crate::ast::expression::{ AbsoluteSourceSpan, AngularExpression, LiteralPrimitive, LiteralValue, ParseSpan, @@ -41,7 +41,7 @@ pub fn remove_illegal_let_references(job: &mut ComponentCompilationJob<'_>) { for view_xref in view_xrefs { // First pass: collect let variable names from Variable ops - let let_names: Vec> = { + let let_names: Vec> = { let view = match job.view(view_xref) { Some(v) => v, None => continue, @@ -77,7 +77,7 @@ pub fn remove_illegal_let_references(job: &mut ComponentCompilationJob<'_>) { // A let name is "declared" AFTER we finish transforming its Variable op. // This matches Angular which walks backward from the declaration op itself, // replacing self-references (e.g. `@let x = x + 1`) with `undefined`. - let mut declared_names: Vec> = Vec::new(); + let mut declared_names: Vec> = Vec::new(); for op in view.update.iter_mut() { // Check if this op declares a let variable — extract the name before diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/resolve_i18n_element_placeholders.rs b/crates/oxc_angular_compiler/src/pipeline/phases/resolve_i18n_element_placeholders.rs index 1543556ad..73bf72e58 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/resolve_i18n_element_placeholders.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/resolve_i18n_element_placeholders.rs @@ -4,7 +4,7 @@ //! //! Ported from Angular's `template/pipeline/src/phases/resolve_i18n_element_placeholders.ts`. -use oxc_span::Atom; +use oxc_span::Ident; use rustc_hash::FxHashMap; use crate::ir::enums::{I18nParamValueFlags, TemplateKind}; @@ -564,7 +564,7 @@ enum OpInfo<'a> { ElementStart { slot: Option, /// The start placeholder name (e.g., "START_TAG_DIV"). - start_name: Atom<'a>, + start_name: Ident<'a>, context_xref: XrefId, sub_template_index: Option, pending_structural: Option, @@ -574,7 +574,7 @@ enum OpInfo<'a> { ElementEnd { slot: Option, /// The close placeholder name (e.g., "CLOSE_TAG_DIV"). - close_name: Atom<'a>, + close_name: Ident<'a>, context_xref: XrefId, sub_template_index: Option, pending_structural: Option, @@ -583,7 +583,7 @@ enum OpInfo<'a> { view_xref: XrefId, slot: u32, /// The start placeholder name (e.g., "START_BLOCK_IF"). - start_name: Atom<'a>, + start_name: Ident<'a>, context_xref: XrefId, sub_template_index: Option, pending_structural: Option, @@ -594,7 +594,7 @@ enum OpInfo<'a> { view_xref: XrefId, slot: u32, /// The close placeholder name (e.g., "CLOSE_BLOCK_IF"). - close_name: Atom<'a>, + close_name: Ident<'a>, context_xref: XrefId, pending_structural: Option, }, @@ -608,7 +608,7 @@ fn add_param_to_context<'a>( value: I18nParamValue, allocator: &'a oxc_allocator::Allocator, ) { - let placeholder_atom = Atom::from(placeholder); + let placeholder_atom = Ident::from(placeholder); // Try root view first for op in job.root.create.iter_mut() { @@ -638,8 +638,8 @@ fn add_param_to_context<'a>( /// Add a value to a params map, creating the list if needed. fn add_to_params_map<'a>( - params: &mut oxc_allocator::HashMap<'a, Atom<'a>, oxc_allocator::Vec<'a, I18nParamValue>>, - placeholder: Atom<'a>, + params: &mut oxc_allocator::HashMap<'a, Ident<'a>, oxc_allocator::Vec<'a, I18nParamValue>>, + placeholder: Ident<'a>, value: I18nParamValue, allocator: &'a oxc_allocator::Allocator, ) { diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/resolve_i18n_expression_placeholders.rs b/crates/oxc_angular_compiler/src/pipeline/phases/resolve_i18n_expression_placeholders.rs index 524bf007e..9c7c5f37b 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/resolve_i18n_expression_placeholders.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/resolve_i18n_expression_placeholders.rs @@ -4,7 +4,7 @@ //! //! Ported from Angular's `template/pipeline/src/phases/resolve_i18n_expression_placeholders.ts`. -use oxc_span::Atom; +use oxc_span::Ident; use rustc_hash::FxHashMap; use crate::ir::enums::{I18nExpressionFor, I18nParamResolutionTime, I18nParamValueFlags}; @@ -50,7 +50,7 @@ pub fn resolve_i18n_expression_placeholders(job: &mut ComponentCompilationJob<'_ // (context_xref, placeholder_name, value, resolution_time, icu_placeholder_xref) struct ExprUpdate<'a> { context_xref: XrefId, - placeholder: Option>, + placeholder: Option>, value: I18nParamValue, resolution_time: I18nParamResolutionTime, icu_placeholder: Option, @@ -115,7 +115,7 @@ pub fn resolve_i18n_expression_placeholders(job: &mut ComponentCompilationJob<'_ }; // Add to params map - let placeholder_atom = Atom::from(placeholder.as_str()); + let placeholder_atom = Ident::from(placeholder.as_str()); if let Some(values) = params.get_mut(&placeholder_atom) { values.push(update.value); } else { diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/resolve_names.rs b/crates/oxc_angular_compiler/src/pipeline/phases/resolve_names.rs index d86be92c6..b3f4be299 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/resolve_names.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/resolve_names.rs @@ -11,7 +11,7 @@ use oxc_allocator::Box; use oxc_diagnostics::OxcDiagnostic; -use oxc_span::Atom; +use oxc_span::Ident; use rustc_hash::FxHashMap; use crate::ast::expression::AngularExpression; @@ -81,13 +81,13 @@ pub fn resolve_names(job: &mut ComponentCompilationJob<'_>) { /// take precedence over other variables with the same name. #[derive(Default, Clone)] struct ScopeMaps<'a> { - scope: FxHashMap, XrefId>, - local_definitions: FxHashMap, XrefId>, + scope: FxHashMap, XrefId>, + local_definitions: FxHashMap, XrefId>, } impl<'a> ScopeMaps<'a> { /// Look up a name, checking local definitions first (they take precedence). - fn get(&self, name: &Atom<'a>) -> Option<&XrefId> { + fn get(&self, name: &Ident<'a>) -> Option<&XrefId> { self.local_definitions.get(name).or_else(|| self.scope.get(name)) } } diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/resolve_sanitizers.rs b/crates/oxc_angular_compiler/src/pipeline/phases/resolve_sanitizers.rs index aa11fc202..93cde79fa 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/resolve_sanitizers.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/resolve_sanitizers.rs @@ -6,7 +6,7 @@ //! //! Ported from Angular's `template/pipeline/src/phases/resolve_sanitizers.ts`. -use oxc_span::Atom; +use oxc_span::Ident; use crate::ast::r3::SecurityContext; use crate::ir::ops::{CreateOp, UpdateOp}; @@ -62,7 +62,7 @@ pub fn resolve_sanitizers(job: &mut ComponentCompilationJob<'_>) { for op in view.create.iter_mut() { if let CreateOp::ExtractedAttribute(attr) = op { if let Some(fn_name) = get_trusted_value_fn(attr.security_context) { - attr.trusted_value_fn = Some(Atom::from(fn_name)); + attr.trusted_value_fn = Some(Ident::from(fn_name)); } } } @@ -72,17 +72,17 @@ pub fn resolve_sanitizers(job: &mut ComponentCompilationJob<'_>) { match op { UpdateOp::Property(prop) => { if let Some(fn_name) = get_sanitizer_fn(prop.security_context) { - prop.sanitizer = Some(Atom::from(fn_name)); + prop.sanitizer = Some(Ident::from(fn_name)); } } UpdateOp::Attribute(attr) => { if let Some(fn_name) = get_sanitizer_fn(attr.security_context) { - attr.sanitizer = Some(Atom::from(fn_name)); + attr.sanitizer = Some(Ident::from(fn_name)); } } UpdateOp::DomProperty(dom_prop) => { if let Some(fn_name) = get_sanitizer_fn(dom_prop.security_context) { - dom_prop.sanitizer = Some(Atom::from(fn_name)); + dom_prop.sanitizer = Some(Ident::from(fn_name)); } } _ => {} @@ -100,7 +100,7 @@ pub fn resolve_sanitizers_for_host(job: &mut HostBindingCompilationJob<'_>) { for op in job.root.create.iter_mut() { if let CreateOp::ExtractedAttribute(attr) = op { if let Some(fn_name) = get_trusted_value_fn(attr.security_context) { - attr.trusted_value_fn = Some(Atom::from(fn_name)); + attr.trusted_value_fn = Some(Ident::from(fn_name)); } } } @@ -110,17 +110,17 @@ pub fn resolve_sanitizers_for_host(job: &mut HostBindingCompilationJob<'_>) { match op { UpdateOp::Property(prop) => { if let Some(fn_name) = get_sanitizer_fn(prop.security_context) { - prop.sanitizer = Some(Atom::from(fn_name)); + prop.sanitizer = Some(Ident::from(fn_name)); } } UpdateOp::Attribute(attr) => { if let Some(fn_name) = get_sanitizer_fn(attr.security_context) { - attr.sanitizer = Some(Atom::from(fn_name)); + attr.sanitizer = Some(Ident::from(fn_name)); } } UpdateOp::DomProperty(dom_prop) => { if let Some(fn_name) = get_sanitizer_fn(dom_prop.security_context) { - dom_prop.sanitizer = Some(Atom::from(fn_name)); + dom_prop.sanitizer = Some(Ident::from(fn_name)); } } _ => {} diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/save_restore_view.rs b/crates/oxc_angular_compiler/src/pipeline/phases/save_restore_view.rs index e2e1970f2..c977706d4 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/save_restore_view.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/save_restore_view.rs @@ -14,7 +14,7 @@ //! Ported from Angular's `template/pipeline/src/phases/save_restore_view.ts`. use oxc_allocator::{Box, Vec as OxcVec}; -use oxc_span::Atom; +use oxc_span::Ident; use crate::ir::enums::{ExpressionKind, SemanticVariableKind, VariableFlags}; use crate::ir::expression::{ @@ -181,7 +181,7 @@ fn process_arrow_functions_in_view( // Per Angular (save_restore_view.ts lines 77-93): // The target is o.variable(expr.currentViewName) where currentViewName is 'view' let view_var_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("view"), source_span: None }, + ReadVarExpr { name: Ident::from("view"), source_span: None }, allocator, )); @@ -189,7 +189,7 @@ fn process_arrow_functions_in_view( base: UpdateOpBase::default(), xref: var_xref, kind: SemanticVariableKind::Context, - name: Atom::from(""), // Empty = naming phase will assign it + name: Ident::from(""), // Empty = naming phase will assign it initializer: Box::new_in( IrExpression::RestoreView(Box::new_in( RestoreViewExpr { @@ -395,7 +395,7 @@ fn add_restore_view_ops_only<'a>( base: UpdateOpBase::default(), xref: var_xref, kind: SemanticVariableKind::Context, - name: oxc_span::Atom::from(""), // Empty = naming phase will assign it + name: oxc_span::Ident::from(""), // Empty = naming phase will assign it initializer: Box::new_in( IrExpression::RestoreView(Box::new_in( RestoreViewExpr { view: RestoreViewTarget::Static(view_xref), source_span: None }, @@ -435,7 +435,7 @@ fn add_restore_view_to_listener<'a>( base: UpdateOpBase::default(), xref: var_xref, kind: SemanticVariableKind::Context, - name: oxc_span::Atom::from(""), // Empty = naming phase will assign it + name: oxc_span::Ident::from(""), // Empty = naming phase will assign it initializer: Box::new_in( IrExpression::RestoreView(Box::new_in( RestoreViewExpr { view: RestoreViewTarget::Static(view_xref), source_span: None }, @@ -511,7 +511,7 @@ fn create_saved_view_variable<'a>( base: Default::default(), xref, kind: SemanticVariableKind::SavedView, - name: oxc_span::Atom::from(""), // Empty = naming phase will assign it + name: oxc_span::Ident::from(""), // Empty = naming phase will assign it initializer: Box::new_in( IrExpression::GetCurrentView(Box::new_in( GetCurrentViewExpr { source_span: None }, diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/strip_nonrequired_parentheses.rs b/crates/oxc_angular_compiler/src/pipeline/phases/strip_nonrequired_parentheses.rs index 579285860..1c5f718a3 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/strip_nonrequired_parentheses.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/strip_nonrequired_parentheses.rs @@ -98,7 +98,7 @@ fn visit_expressions_for_required_parens( check_ir_expression_for_required_parens(&r.track, required); } CreateOp::I18nMessage(_) => { - // I18nMessage params are now formatted strings (Atom), not expressions + // I18nMessage params are now formatted strings (Ident), not expressions // No expressions to check here } CreateOp::I18nContext(_) => { diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/temporary_variables.rs b/crates/oxc_angular_compiler/src/pipeline/phases/temporary_variables.rs index 6c2bced42..d91730886 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/temporary_variables.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/temporary_variables.rs @@ -34,7 +34,7 @@ use std::cell::RefCell; use oxc_allocator::Allocator; -use oxc_span::Atom; +use oxc_span::Ident; use rustc_hash::{FxHashMap, FxHashSet}; use crate::ir::expression::{ @@ -388,7 +388,7 @@ fn generate_temporaries_for_update<'a>( fn create_declare_var_statement<'a>(allocator: &'a Allocator, name: &str) -> OutputStatement<'a> { OutputStatement::DeclareVar(oxc_allocator::Box::new_in( DeclareVarStmt { - name: Atom::from(allocator.alloc_str(name)), + name: Ident::from(allocator.alloc_str(name)), value: None, modifiers: StmtModifier::NONE, // Use `var` since there's no initializer leading_comment: None, @@ -416,12 +416,12 @@ fn assign_temp_names<'a>( match expr { IrExpression::AssignTemporary(assign) => { let name = tracker.borrow_mut().assign(assign.xref); - assign.name = Some(Atom::from(allocator.alloc_str(&name))); + assign.name = Some(Ident::from(allocator.alloc_str(&name))); } IrExpression::ReadTemporary(read) => { let name = tracker.borrow_mut().read(read.xref); if let Some(n) = name { - read.name = Some(Atom::from(allocator.alloc_str(&n))); + read.name = Some(Ident::from(allocator.alloc_str(&n))); } } // Recursively process nested expressions diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/track_fn_optimization.rs b/crates/oxc_angular_compiler/src/pipeline/phases/track_fn_optimization.rs index 4e0aacd5f..e508dec4d 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/track_fn_optimization.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/track_fn_optimization.rs @@ -9,7 +9,7 @@ //! //! Ported from Angular's `template/pipeline/src/phases/track_fn_optimization.ts`. -use oxc_span::Atom; +use oxc_span::Ident; use crate::ir::expression::{ IrExpression, TrackContextExpr, VisitorContextFlag, transform_expressions_in_expression, @@ -62,7 +62,7 @@ fn optimize_track_expression<'a>( // Check for simple $index or $item tracking if let Some(opt_fn) = check_simple_track_variable(&rep.track, expressions) { // Set the optimized track function name - rep.track_fn_name = Some(Atom::from(opt_fn)); + rep.track_fn_name = Some(Ident::from(opt_fn)); return; } @@ -77,13 +77,13 @@ fn optimize_track_expression<'a>( // Emit as ctx.methodName let fn_name = format!("ctx.{}", method_name); let name_str = allocator.alloc_str(&fn_name); - rep.track_fn_name = Some(Atom::from(name_str)); + rep.track_fn_name = Some(Ident::from(name_str)); } else { // Need to use componentInstance() to access the method // Create the full function reference string let fn_name = format!("{}().{}", Identifiers::COMPONENT_INSTANCE, method_name); let name_str = allocator.alloc_str(&fn_name); - rep.track_fn_name = Some(Atom::from(name_str)); + rep.track_fn_name = Some(Ident::from(name_str)); } return; } @@ -317,14 +317,14 @@ mod tests { let prop_read = IrExpression::ResolvedPropertyRead(oxc_allocator::Box::new_in( ResolvedPropertyReadExpr { receiver: oxc_allocator::Box::new_in(ctx, alloc), - name: Atom::from(method_name), + name: Ident::from(method_name), source_span: None, }, alloc, )); let index_arg = IrExpression::OutputExpr(oxc_allocator::Box::new_in( OutputExpression::ReadVar(oxc_allocator::Box::new_in( - ReadVarExpr { name: Atom::from("$index"), source_span: None }, + ReadVarExpr { name: Ident::from("$index"), source_span: None }, alloc, )), alloc, diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/track_variables.rs b/crates/oxc_angular_compiler/src/pipeline/phases/track_variables.rs index faf970110..1030fcaf2 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/track_variables.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/track_variables.rs @@ -7,7 +7,7 @@ //! Ported from Angular's `template/pipeline/src/phases/track_variables.ts`. use oxc_allocator::Box; -use oxc_span::Atom; +use oxc_span::Ident; use crate::ast::expression::AngularExpression; use crate::ir::expression::{ @@ -36,10 +36,10 @@ pub fn generate_track_variables(job: &mut ComponentCompilationJob<'_>) { for op in view.create.iter_mut() { if let CreateOp::RepeaterCreate(rep) = op { // Get $index names and $implicit name for this repeater - let index_names: Vec> = { - let mut names: Vec> = rep.var_names.index.iter().cloned().collect(); + let index_names: Vec> = { + let mut names: Vec> = rep.var_names.index.iter().cloned().collect(); // Also include '$index' itself - names.push(Atom::from("$index")); + names.push(Ident::from("$index")); names }; let implicit_name = rep.var_names.item.clone(); @@ -63,12 +63,12 @@ pub fn generate_track_variables(job: &mut ComponentCompilationJob<'_>) { fn transform_track_expression<'a>( allocator: &'a oxc_allocator::Allocator, expr: &mut Box<'a, IrExpression<'a>>, - index_names: &[Atom<'a>], - implicit_name: Option<&Atom<'a>>, + index_names: &[Ident<'a>], + implicit_name: Option<&Ident<'a>>, expressions: &crate::pipeline::expression_store::ExpressionStore<'a>, ) { - let index_names_clone: Vec> = index_names.to_vec(); - let implicit_name_clone: Option> = implicit_name.cloned(); + let index_names_clone: Vec> = index_names.to_vec(); + let implicit_name_clone: Option> = implicit_name.cloned(); transform_expressions_in_expression( expr, @@ -80,7 +80,7 @@ fn transform_track_expression<'a>( // Replace with o.variable('$index') *inner_expr = IrExpression::OutputExpr(Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("$index"), source_span: None }, + ReadVarExpr { name: Ident::from("$index"), source_span: None }, allocator, )), allocator, @@ -94,7 +94,7 @@ fn transform_track_expression<'a>( // Replace with o.variable('$item') *inner_expr = IrExpression::OutputExpr(Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("$item"), source_span: None }, + ReadVarExpr { name: Ident::from("$item"), source_span: None }, allocator, )), allocator, @@ -107,7 +107,7 @@ fn transform_track_expression<'a>( if lexical.name.as_str() == "$implicit" { *inner_expr = IrExpression::OutputExpr(Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("$item"), source_span: None }, + ReadVarExpr { name: Ident::from("$item"), source_span: None }, allocator, )), allocator, @@ -157,8 +157,8 @@ fn transform_track_expression<'a>( fn transform_angular_expression_for_track<'a>( allocator: &'a oxc_allocator::Allocator, expr: &AngularExpression<'a>, - index_names: &[Atom<'a>], - implicit_name: Option<&Atom<'a>>, + index_names: &[Ident<'a>], + implicit_name: Option<&Ident<'a>>, ) -> Option> { match expr { // Direct read of loop variable: `item` or `$index` @@ -171,7 +171,7 @@ fn transform_angular_expression_for_track<'a>( if index_names.iter().any(|n| *n == *name) { return Some(IrExpression::OutputExpr(Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("$index"), source_span: None }, + ReadVarExpr { name: Ident::from("$index"), source_span: None }, allocator, )), allocator, @@ -183,7 +183,7 @@ fn transform_angular_expression_for_track<'a>( if *name == *item_name { return Some(IrExpression::OutputExpr(Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("$item"), source_span: None }, + ReadVarExpr { name: Ident::from("$item"), source_span: None }, allocator, )), allocator, @@ -195,7 +195,7 @@ fn transform_angular_expression_for_track<'a>( if name.as_str() == "$implicit" { return Some(IrExpression::OutputExpr(Box::new_in( OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from("$item"), source_span: None }, + ReadVarExpr { name: Ident::from("$item"), source_span: None }, allocator, )), allocator, diff --git a/crates/oxc_angular_compiler/src/pipeline/selector.rs b/crates/oxc_angular_compiler/src/pipeline/selector.rs index 4d6a827e6..7b753653f 100644 --- a/crates/oxc_angular_compiler/src/pipeline/selector.rs +++ b/crates/oxc_angular_compiler/src/pipeline/selector.rs @@ -7,7 +7,7 @@ //! `core.ts` parseSelectorToR3Selector function. use oxc_allocator::{Allocator, Vec as OxcVec}; -use oxc_span::Atom; +use oxc_span::Ident; use crate::output::ast::{LiteralExpr, LiteralValue, OutputExpression}; @@ -441,7 +441,7 @@ pub fn r3_selector_to_output_expr<'a>( R3SelectorElement::String(s) => { result.push(OutputExpression::Literal(oxc_allocator::Box::new_in( LiteralExpr { - value: LiteralValue::String(Atom::from(allocator.alloc_str(s))), + value: LiteralValue::String(Ident::from(allocator.alloc_str(s))), source_span: None, }, allocator, diff --git a/crates/oxc_angular_compiler/src/transform/control_flow.rs b/crates/oxc_angular_compiler/src/transform/control_flow.rs index d9efa0c84..11b934890 100644 --- a/crates/oxc_angular_compiler/src/transform/control_flow.rs +++ b/crates/oxc_angular_compiler/src/transform/control_flow.rs @@ -8,7 +8,7 @@ //! Ported from Angular's `render3/r3_control_flow.ts`. use oxc_allocator::{Allocator, Vec}; -use oxc_span::{Atom, Span}; +use oxc_span::{Ident, Span}; use crate::ast::expression::{ASTWithSource, AngularExpression}; use crate::ast::html::HtmlBlockParameter; @@ -261,8 +261,8 @@ pub fn parse_conditional_params<'a>( ); let name_alloc = allocator.alloc_str(name_str); expression_alias = Some(R3Variable { - name: Atom::from(name_alloc), - value: Atom::from(name_alloc), // value same as name for alias + name: Ident::from(name_alloc), + value: Ident::from(name_alloc), // value same as name for alias source_span: name_span, key_span: name_span, value_span: None, // No value span for expression alias @@ -374,14 +374,14 @@ pub fn parse_for_loop_parameters<'a>( // Create item variable - use the allocator to intern the string // Calculate a span that only covers the item name (not "of items.foo.bar") - let item_name_atom = Atom::from(allocator.alloc_str(&item_name_owned)); + let item_name_atom = Ident::from(allocator.alloc_str(&item_name_owned)); let item_name_span = Span::new( expression_param.span.start, expression_param.span.start + item_name_str.len() as u32, ); let item = R3Variable { name: item_name_atom, - value: Atom::from("$implicit"), + value: Ident::from("$implicit"), source_span: item_name_span, key_span: item_name_span, value_span: None, @@ -579,8 +579,8 @@ fn parse_let_parameter<'a>( let name_alloc = allocator.alloc_str(name); let value_alloc = allocator.alloc_str(variable_name); context_variables.push(R3Variable { - name: Atom::from(name_alloc), - value: Atom::from(value_alloc), + name: Ident::from(name_alloc), + value: Ident::from(value_alloc), source_span, key_span, value_span: Some(value_span), @@ -605,8 +605,8 @@ fn create_default_context_variables<'a>( for &var_name in ALLOWED_FOR_LOOP_LET_VARIABLES { vars.push(R3Variable { - name: Atom::from(var_name), - value: Atom::from(var_name), + name: Ident::from(var_name), + value: Ident::from(var_name), source_span: empty_span, key_span: empty_span, value_span: None, @@ -620,8 +620,8 @@ fn create_default_context_variables<'a>( fn create_empty_variable<'a>(_allocator: &'a Allocator, span: Span) -> R3Variable<'a> { // Note: allocator reserved for future use (e.g., allocating default expression). R3Variable { - name: Atom::from(""), - value: Atom::from("$implicit"), + name: Ident::from(""), + value: Ident::from("$implicit"), source_span: span, key_span: span, value_span: None, @@ -641,7 +641,7 @@ fn create_empty_ast_with_source<'a>(allocator: &'a Allocator, span: Span) -> AST allocator, )), source: None, - location: Atom::from(""), + location: Ident::from(""), absolute_offset: span.start, } } @@ -663,8 +663,8 @@ fn parse_expression_to_ast_with_source<'a>( ASTWithSource { ast: result.ast, - source: Some(Atom::from(expr_str)), - location: Atom::from(""), + source: Some(Ident::from(expr_str)), + location: Ident::from(""), absolute_offset: span.start + expression_start_offset, } } @@ -1384,7 +1384,7 @@ fn parse_single_on_trigger<'a>( return; } } - let reference = params.map(|s| Atom::from(s.trim())); + let reference = params.map(|s| Ident::from(s.trim())); triggers.hover = Some(R3HoverDeferredTrigger { reference, source_span, @@ -1416,7 +1416,7 @@ fn parse_single_on_trigger<'a>( return; } } - let reference = params.map(|s| Atom::from(s.trim())); + let reference = params.map(|s| Ident::from(s.trim())); triggers.interaction = Some(R3InteractionDeferredTrigger { reference, source_span, @@ -1471,7 +1471,7 @@ fn parse_single_on_trigger<'a>( (result.reference, result.options) } else { // Simple reference name - (Some(Atom::from(trimmed)), None) + (Some(Ident::from(trimmed)), None) } } else { (None, None) @@ -1504,7 +1504,7 @@ fn parse_single_on_trigger<'a>( /// Result type for viewport trigger extraction. struct ViewportTriggerResult<'a> { - reference: Option>, + reference: Option>, options: Option>, errors: std::vec::Vec, } @@ -1535,7 +1535,7 @@ fn extract_viewport_trigger_and_options<'a>( let mut errors = std::vec::Vec::new(); if let AngularExpression::LiteralMap(map) = expr { - let mut trigger_ref: Option> = None; + let mut trigger_ref: Option> = None; let mut trigger_idx: Option = None; // First pass: find the trigger key, check for "root" key, and extract trigger value diff --git a/crates/oxc_angular_compiler/src/transform/html_to_r3.rs b/crates/oxc_angular_compiler/src/transform/html_to_r3.rs index d066bc136..8d03c96cf 100644 --- a/crates/oxc_angular_compiler/src/transform/html_to_r3.rs +++ b/crates/oxc_angular_compiler/src/transform/html_to_r3.rs @@ -6,7 +6,7 @@ //! Ported from Angular's `render3/r3_template_transform.ts`. use oxc_allocator::{Allocator, Box, FromIn, HashMap, Vec}; -use oxc_span::{Atom, Span}; +use oxc_span::{Ident, Span}; use rustc_hash::{FxHashMap, FxHashSet}; use crate::ast::expression::{ @@ -81,9 +81,9 @@ enum BindingPrefix { #[derive(Debug, Clone)] struct TemplateAttrInfo<'a> { /// The attribute name (e.g., `*ngFor`). - name: Atom<'a>, + name: Ident<'a>, /// The attribute value (e.g., `let item of items`). - value: Atom<'a>, + value: Ident<'a>, /// The full span of the attribute. span: Span, /// The span of the attribute name. @@ -102,8 +102,8 @@ pub struct TransformOptions { /// Inserts or updates a var entry in an ordered Vec, preserving first-insertion order. /// This matches JS object semantics where reassigning an existing key keeps its position. fn ordered_insert_var<'a>( - vec: &mut Vec<'a, (Atom<'a>, R3BoundText<'a>)>, - key: Atom<'a>, + vec: &mut Vec<'a, (Ident<'a>, R3BoundText<'a>)>, + key: Ident<'a>, value: R3BoundText<'a>, ) { if let Some(existing) = vec.iter_mut().find(|(k, _)| *k == key) { @@ -116,8 +116,8 @@ fn ordered_insert_var<'a>( /// Inserts or updates a placeholder entry in an ordered Vec, preserving first-insertion order. /// This matches JS object semantics where reassigning an existing key keeps its position. fn ordered_insert_placeholder<'a>( - vec: &mut Vec<'a, (Atom<'a>, R3IcuPlaceholder<'a>)>, - key: Atom<'a>, + vec: &mut Vec<'a, (Ident<'a>, R3IcuPlaceholder<'a>)>, + key: Ident<'a>, value: R3IcuPlaceholder<'a>, ) { if let Some(existing) = vec.iter_mut().find(|(k, _)| *k == key) { @@ -137,9 +137,9 @@ pub struct HtmlToR3Transform<'a> { /// Parse errors. /// Uses std::vec::Vec since ParseError contains Drop types (Arc, String). errors: std::vec::Vec, - styles: Vec<'a, Atom<'a>>, - style_urls: Vec<'a, Atom<'a>>, - ng_content_selectors: Vec<'a, Atom<'a>>, + styles: Vec<'a, Ident<'a>>, + style_urls: Vec<'a, Ident<'a>>, + ng_content_selectors: Vec<'a, Ident<'a>>, comment_nodes: Option>>, processed_nodes: FxHashSet, namespace_stack: std::vec::Vec, @@ -285,7 +285,7 @@ impl<'a> HtmlToR3Transform<'a> { }; // Reconstruct the @let text with semicolon let reconstructed = format!("@let {} = {};", decl.name.as_str(), value_text); - let text_value = Atom::from_in(reconstructed.as_str(), self.allocator); + let text_value = Ident::from_in(reconstructed.as_str(), self.allocator); let r3_text = R3Text { value: text_value, source_span: decl.span }; return Some(R3Node::Text(Box::new_in(r3_text, self.allocator))); } @@ -584,11 +584,11 @@ impl<'a> HtmlToR3Transform<'a> { (None, Some(tag)) => Some(*tag), (Some(prefix), None) => { // Has prefix but no tag name - use "ng-component" as default - Some(Atom::from_in(&format!(":{prefix}:ng-component"), self.allocator)) + Some(Ident::from_in(&format!(":{prefix}:ng-component"), self.allocator)) } (Some(prefix), Some(tag)) => { // Both prefix and tag name: ":prefix:tag_name" - Some(Atom::from_in(&format!(":{prefix}:{tag}"), self.allocator)) + Some(Ident::from_in(&format!(":{prefix}:{tag}"), self.allocator)) } }; @@ -596,11 +596,11 @@ impl<'a> HtmlToR3Transform<'a> { let full_name = match &tag_name { Some(tag) if tag.starts_with(':') => { // Namespace format: "MyComp:svg:rect" (tag_name already has :prefix:) - Atom::from_in(&format!("{}{}", element.name, tag), self.allocator) + Ident::from_in(&format!("{}{}", element.name, tag), self.allocator) } Some(tag) => { // Simple format: "MyComp:div" - Atom::from_in(&format!("{}:{}", element.name, tag), self.allocator) + Ident::from_in(&format!("{}:{}", element.name, tag), self.allocator) } None => element.name, }; @@ -703,7 +703,7 @@ impl<'a> HtmlToR3Transform<'a> { // Transform selectorless directives from HTML AST // For components, tag_name may be None (e.g., ``), in which case we use empty string // which matches TypeScript's behavior where elementName can be null. - let element_name = component.tag_name.as_ref().map_or("", oxc_span::Atom::as_str); + let element_name = component.tag_name.as_ref().map_or("", oxc_span::Ident::as_str); let directives = self.transform_directives(&component.directives, element_name); // Validate selectorless references @@ -789,7 +789,7 @@ impl<'a> HtmlToR3Transform<'a> { } } - fn qualify_element_name(&self, name: Atom<'a>, namespace: ElementNamespace) -> Atom<'a> { + fn qualify_element_name(&self, name: Ident<'a>, namespace: ElementNamespace) -> Ident<'a> { if namespace == ElementNamespace::Html { return name; } @@ -803,7 +803,7 @@ impl<'a> HtmlToR3Transform<'a> { && Self::namespace_from_prefix(prefix).is_some() { let qualified = format!(":{prefix}:{local}"); - return Atom::from_in(&qualified, self.allocator); + return Ident::from_in(&qualified, self.allocator); } let ns = match namespace { @@ -812,7 +812,7 @@ impl<'a> HtmlToR3Transform<'a> { ElementNamespace::Html => return name, }; let qualified = format!(":{ns}:{name_str}"); - Atom::from_in(&qualified, self.allocator) + Ident::from_in(&qualified, self.allocator) } /// Transforms HTML directives to R3 directives. @@ -899,8 +899,8 @@ impl<'a> HtmlToR3Transform<'a> { } else { seen_reference_names.insert(ref_name); references.push(R3Reference { - name: Atom::from_in(ref_name, self.allocator), - value: Atom::from_in("", self.allocator), + name: Ident::from_in(ref_name, self.allocator), + value: Ident::from_in("", self.allocator), source_span: attr.span, key_span: attr.name_span, value_span: None, @@ -942,7 +942,7 @@ impl<'a> HtmlToR3Transform<'a> { self.binding_parser.parse_binding(attr_value, value_span); inputs.push(R3BoundAttribute { - name: Atom::from_in(prop_name, self.allocator), + name: Ident::from_in(prop_name, self.allocator), binding_type, value: parse_result.ast, unit: None, @@ -960,7 +960,7 @@ impl<'a> HtmlToR3Transform<'a> { self.binding_parser.parse_event(attr_value, value_span); outputs.push(R3BoundEvent { - name: Atom::from_in(rest, self.allocator), + name: Ident::from_in(rest, self.allocator), handler: parse_result.ast, target: None, event_type: ParsedEventType::Regular, @@ -977,7 +977,7 @@ impl<'a> HtmlToR3Transform<'a> { self.binding_parser.parse_binding(attr_value, value_span); inputs.push(R3BoundAttribute { - name: Atom::from_in(rest, self.allocator), + name: Ident::from_in(rest, self.allocator), binding_type: BindingType::TwoWay, value: parse_result.ast, unit: None, @@ -990,7 +990,7 @@ impl<'a> HtmlToR3Transform<'a> { // Two-way binding also creates an output event let event_name = - Atom::from_in(&format!("{rest}Change"), self.allocator); + Ident::from_in(&format!("{rest}Change"), self.allocator); let event_parse_result = self.binding_parser.parse_event(attr_value, value_span); @@ -1016,7 +1016,7 @@ impl<'a> HtmlToR3Transform<'a> { self.binding_parser.parse_binding(value_str, value_span); inputs.push(R3BoundAttribute { - name: Atom::from_in(rest, self.allocator), + name: Ident::from_in(rest, self.allocator), binding_type: BindingType::LegacyAnimation, value: parse_result.ast, unit: None, @@ -1043,7 +1043,7 @@ impl<'a> HtmlToR3Transform<'a> { let parse_result = self.binding_parser.parse_binding(value_str, value_span); inputs.push(R3BoundAttribute { - name: Atom::from_in(prop_name, self.allocator), + name: Ident::from_in(prop_name, self.allocator), binding_type: BindingType::TwoWay, value: parse_result.ast, unit: None, @@ -1055,7 +1055,7 @@ impl<'a> HtmlToR3Transform<'a> { }); // Two-way binding also creates an output event - let event_name = Atom::from_in(&format!("{prop_name}Change"), self.allocator); + let event_name = Ident::from_in(&format!("{prop_name}Change"), self.allocator); let event_value_str = self.allocator.alloc_str(attr_value); let event_parse_result = self.binding_parser.parse_event(event_value_str, value_span); @@ -1114,7 +1114,7 @@ impl<'a> HtmlToR3Transform<'a> { let parse_result = self.binding_parser.parse_binding(value_str, value_span); inputs.push(R3BoundAttribute { - name: Atom::from_in(prop_name, self.allocator), + name: Ident::from_in(prop_name, self.allocator), binding_type: BindingType::Property, value: parse_result.ast, unit: None, @@ -1139,7 +1139,7 @@ impl<'a> HtmlToR3Transform<'a> { let parse_result = self.binding_parser.parse_event(value_str, value_span); outputs.push(R3BoundEvent { - name: Atom::from_in(event_name, self.allocator), + name: Ident::from_in(event_name, self.allocator), handler: parse_result.ast, target: None, event_type: ParsedEventType::Regular, @@ -1244,8 +1244,8 @@ impl<'a> HtmlToR3Transform<'a> { let icu_type_upper = expansion.expansion_type.as_str().to_uppercase(); let base_name = format!("VAR_{icu_type_upper}"); let expression_placeholder = - Atom::from_in(&self.generate_unique_icu_placeholder(&base_name), self.allocator); - let icu_placeholder_name = Atom::from_in("ICU", self.allocator); + Ident::from_in(&self.generate_unique_icu_placeholder(&base_name), self.allocator); + let icu_placeholder_name = Ident::from_in("ICU", self.allocator); // Create the I18nIcu for the i18n metadata // The cases are empty here since they're parsed separately into R3Icu.placeholders @@ -1270,15 +1270,15 @@ impl<'a> HtmlToR3Transform<'a> { // Serialize the message string for goog.getMsg and $localize let message_string_str = serialize_i18n_nodes(&nodes); - let message_string = Atom::from_in(&*message_string_str, self.allocator); + let message_string = Ident::from_in(&*message_string_str, self.allocator); let i18n_message = I18nMessage { instance_id: self.allocate_i18n_message_instance_id(), nodes, - meaning: Atom::from(""), - description: Atom::from(""), - custom_id: Atom::from(""), - id: Atom::from(""), + meaning: Ident::from(""), + description: Ident::from(""), + custom_id: Ident::from(""), + id: Ident::from(""), legacy_ids: Vec::new_in(self.allocator), message_string, }; @@ -1325,8 +1325,8 @@ impl<'a> HtmlToR3Transform<'a> { fn extract_placeholders_from_nodes( &mut self, nodes: &[HtmlNode<'a>], - placeholders: &mut Vec<'a, (Atom<'a>, R3IcuPlaceholder<'a>)>, - vars: &mut Vec<'a, (Atom<'a>, R3BoundText<'a>)>, + placeholders: &mut Vec<'a, (Ident<'a>, R3IcuPlaceholder<'a>)>, + vars: &mut Vec<'a, (Ident<'a>, R3BoundText<'a>)>, ) { for node in nodes { match node { @@ -1357,7 +1357,7 @@ impl<'a> HtmlToR3Transform<'a> { let icu_type_upper = nested_expansion.expansion_type.as_str().to_uppercase(); let base_name = format!("VAR_{icu_type_upper}"); let unique_name = self.generate_unique_icu_placeholder(&base_name); - let var_placeholder_name = Atom::from_in(&unique_name, self.allocator); + let var_placeholder_name = Ident::from_in(&unique_name, self.allocator); // Recursively extract from nested expansion cases FIRST. // This ensures placeholders and further nested ICU vars are processed @@ -1401,7 +1401,7 @@ impl<'a> HtmlToR3Transform<'a> { &mut self, text: &str, base_span: Span, - placeholders: &mut Vec<'a, (Atom<'a>, R3IcuPlaceholder<'a>)>, + placeholders: &mut Vec<'a, (Ident<'a>, R3IcuPlaceholder<'a>)>, ) { // Use default Angular interpolation markers let start_marker = "{{"; @@ -1433,7 +1433,7 @@ impl<'a> HtmlToR3Transform<'a> { let value_str = self.allocator.alloc_str(expr_content); let parse_result = self.binding_parser.parse_binding(value_str, interp_span); - let placeholder_key = Atom::from_in(interpolation, self.allocator); + let placeholder_key = Ident::from_in(interpolation, self.allocator); let bound_text = R3BoundText { value: parse_result.ast, source_span: interp_span, @@ -1516,7 +1516,7 @@ impl<'a> HtmlToR3Transform<'a> { // Static text - use value with ngsp replaced let value_atom = if has_ngsp { let value_no_ngsp = value_str.replace(NGSP_UNICODE, " "); - Atom::from_in(&value_no_ngsp, self.allocator) + Ident::from_in(&value_no_ngsp, self.allocator) } else { text.value }; @@ -1561,7 +1561,7 @@ impl<'a> HtmlToR3Transform<'a> { // Add start text node nodes.push(R3Node::Text(Box::new_in( R3Text { - value: Atom::from(self.allocator.alloc_str(start_text)), + value: Ident::from(self.allocator.alloc_str(start_text)), source_span: block.start_span, }, self.allocator, @@ -1585,7 +1585,7 @@ impl<'a> HtmlToR3Transform<'a> { nodes.push(R3Node::Text(Box::new_in( R3Text { - value: Atom::from(self.allocator.alloc_str(end_text)), + value: Ident::from(self.allocator.alloc_str(end_text)), source_span: end_span, }, self.allocator, @@ -1634,7 +1634,7 @@ impl<'a> HtmlToR3Transform<'a> { // Add start text node nodes.push(R3Node::Text(Box::new_in( R3Text { - value: Atom::from(self.allocator.alloc_str(start_text)), + value: Ident::from(self.allocator.alloc_str(start_text)), source_span: block.start_span, }, self.allocator, @@ -1659,7 +1659,7 @@ impl<'a> HtmlToR3Transform<'a> { nodes.push(R3Node::Text(Box::new_in( R3Text { - value: Atom::from(self.allocator.alloc_str(end_text)), + value: Ident::from(self.allocator.alloc_str(end_text)), source_span: end_span, }, self.allocator, @@ -1932,7 +1932,7 @@ impl<'a> HtmlToR3Transform<'a> { fn create_block_placeholder( &mut self, block_name: &str, - parameters: &[Atom<'a>], + parameters: &[Ident<'a>], source_span: Span, start_source_span: Span, end_source_span: Option, @@ -1949,15 +1949,15 @@ impl<'a> HtmlToR3Transform<'a> { self.block_placeholder_counter += 1; let start_name = if count == 0 { - Atom::from_in(format!("START_BLOCK_{block_upper}").as_str(), self.allocator) + Ident::from_in(format!("START_BLOCK_{block_upper}").as_str(), self.allocator) } else { - Atom::from_in(format!("START_BLOCK_{block_upper}_{count}").as_str(), self.allocator) + Ident::from_in(format!("START_BLOCK_{block_upper}_{count}").as_str(), self.allocator) }; let close_name = if count == 0 { - Atom::from_in(format!("CLOSE_BLOCK_{block_upper}").as_str(), self.allocator) + Ident::from_in(format!("CLOSE_BLOCK_{block_upper}").as_str(), self.allocator) } else { - Atom::from_in(format!("CLOSE_BLOCK_{block_upper}_{count}").as_str(), self.allocator) + Ident::from_in(format!("CLOSE_BLOCK_{block_upper}_{count}").as_str(), self.allocator) }; // Convert parameters to Atom vec @@ -1967,7 +1967,7 @@ impl<'a> HtmlToR3Transform<'a> { } let placeholder = I18nBlockPlaceholder { - name: Atom::from_in(block_name, self.allocator), + name: Ident::from_in(block_name, self.allocator), parameters: params, start_name, close_name, @@ -3177,7 +3177,7 @@ impl<'a> HtmlToR3Transform<'a> { ) -> R3BoundAttribute<'a> { let value_span = attr.value_span.unwrap_or(attr.span); let value = self.parse_binding_expression(&attr.value, value_span); - let name_atom = Atom::from(self.allocator.alloc_str(property_name)); + let name_atom = Ident::from(self.allocator.alloc_str(property_name)); // Look up security context based on element and property let security_context = get_security_context(element_name, property_name); @@ -3187,7 +3187,7 @@ impl<'a> HtmlToR3Transform<'a> { binding_type, security_context, value, - unit: unit.map(|u| Atom::from(self.allocator.alloc_str(u))), + unit: unit.map(|u| Ident::from(self.allocator.alloc_str(u))), source_span: attr.span, key_span: attr.name_span, value_span: attr.value_span, @@ -3196,7 +3196,7 @@ impl<'a> HtmlToR3Transform<'a> { } /// Parses a binding expression from an attribute value. - fn parse_binding_expression(&mut self, value: &Atom<'a>, span: Span) -> AngularExpression<'a> { + fn parse_binding_expression(&mut self, value: &Ident<'a>, span: Span) -> AngularExpression<'a> { let value_str = value.as_str(); if value_str.is_empty() { return self.create_empty_expression(span); @@ -3232,7 +3232,7 @@ impl<'a> HtmlToR3Transform<'a> { self.errors.push(error); } - let name_atom = Atom::from(self.allocator.alloc_str(property_name)); + let name_atom = Ident::from(self.allocator.alloc_str(property_name)); R3BoundAttribute { name: name_atom, @@ -3269,12 +3269,12 @@ impl<'a> HtmlToR3Transform<'a> { let (event_name, target) = if let Some(colon_pos) = name.find(':') { let target = &name[..colon_pos]; let event = &name[colon_pos + 1..]; - (event, Some(Atom::from(self.allocator.alloc_str(target)))) + (event, Some(Ident::from(self.allocator.alloc_str(target)))) } else { (name, None) }; - let name_atom = Atom::from(self.allocator.alloc_str(event_name)); + let name_atom = Ident::from(self.allocator.alloc_str(event_name)); R3BoundEvent { name: name_atom, @@ -3292,7 +3292,7 @@ impl<'a> HtmlToR3Transform<'a> { fn create_bound_event(&mut self, name: &str, attr: &HtmlAttribute<'a>) -> R3BoundEvent<'a> { let handler_span = self.calculate_event_handler_span(attr); let handler = self.parse_event_expression(&attr.value, handler_span); - let name_atom = Atom::from(self.allocator.alloc_str(name)); + let name_atom = Ident::from(self.allocator.alloc_str(name)); R3BoundEvent { name: name_atom, @@ -3330,13 +3330,13 @@ impl<'a> HtmlToR3Transform<'a> { let phase_str = &name[dot_pos + 1..]; // Phase is lowercased per TypeScript: matches[1].toLowerCase() let phase_lower = phase_str.to_lowercase(); - (event_name, Some(Atom::from(self.allocator.alloc_str(&phase_lower)))) + (event_name, Some(Ident::from(self.allocator.alloc_str(&phase_lower)))) } else { (name, None) }; // Use only the event name (trigger name), not including the phase - let name_atom = Atom::from(self.allocator.alloc_str(event_name)); + let name_atom = Ident::from(self.allocator.alloc_str(event_name)); R3BoundEvent { name: name_atom, @@ -3355,7 +3355,7 @@ impl<'a> HtmlToR3Transform<'a> { /// The `$event` is added separately in the ingest phase. fn create_two_way_event(&mut self, name: &str, attr: &HtmlAttribute<'a>) -> R3BoundEvent<'a> { let handler_span = self.calculate_event_handler_span(attr); - let name_atom = Atom::from(self.allocator.alloc_str(name)); + let name_atom = Ident::from(self.allocator.alloc_str(name)); // For two-way binding, the handler is just the target expression (e.g., `name`) // NOT the full assignment `name = $event`. @@ -3375,7 +3375,7 @@ impl<'a> HtmlToR3Transform<'a> { } /// Parses an event handler expression. - fn parse_event_expression(&mut self, value: &Atom<'a>, span: Span) -> AngularExpression<'a> { + fn parse_event_expression(&mut self, value: &Ident<'a>, span: Span) -> AngularExpression<'a> { let value_str = value.as_str(); if value_str.is_empty() { return self.create_empty_expression(span); @@ -3425,7 +3425,7 @@ impl<'a> HtmlToR3Transform<'a> { } // Still create the variable even if invalid (for error recovery) - let name_atom = Atom::from(self.allocator.alloc_str(name)); + let name_atom = Ident::from(self.allocator.alloc_str(name)); Some(R3Variable { name: name_atom, value: attr.value, @@ -3456,7 +3456,7 @@ impl<'a> HtmlToR3Transform<'a> { } // Still create the reference even if invalid (for error recovery) - let name_atom = Atom::from(self.allocator.alloc_str(name)); + let name_atom = Ident::from(self.allocator.alloc_str(name)); Some(R3Reference { name: name_atom, value: attr.value, @@ -3499,7 +3499,7 @@ impl<'a> HtmlToR3Transform<'a> { template_attr.name.strip_prefix('*').unwrap_or(&template_attr.name); // Allocate the directive name in the arena for long-lived reference let directive_name = self.allocator.alloc_str(directive_name); - let directive_name_atom = Atom::from(directive_name); + let directive_name_atom = Ident::from(directive_name); // Get the value span (if present) let value_span = template_attr.value_span.unwrap_or(template_attr.span); @@ -3580,7 +3580,7 @@ impl<'a> HtmlToR3Transform<'a> { ); attributes.push(R3TextAttribute { name: directive_name_atom, - value: Atom::from(""), + value: Ident::from(""), source_span: directive_source_span, key_span: Some(directive_source_span), value_span: None, @@ -3641,7 +3641,7 @@ impl<'a> HtmlToR3Transform<'a> { // Use the full binding name (e.g., "ngForOf", not "of") let full_name = expr.key.source.as_str(); - let binding_name_atom = Atom::from(self.allocator.alloc_str(full_name)); + let binding_name_atom = Ident::from(self.allocator.alloc_str(full_name)); let source_span = Span::new(expr.source_span.start, expr.source_span.end); // Parse the expression value from source @@ -3687,7 +3687,7 @@ impl<'a> HtmlToR3Transform<'a> { Span::new(template_attr.name_span.start + 1, template_attr.name_span.end); attributes.push(R3TextAttribute { name: directive_name_atom, - value: Atom::from(""), + value: Ident::from(""), source_span: directive_source_span, key_span: Some(directive_source_span), value_span: None, @@ -3765,7 +3765,7 @@ impl<'a> HtmlToR3Transform<'a> { let directive_name: &str = template_attr.name.strip_prefix('*').unwrap_or(&template_attr.name); let directive_name = self.allocator.alloc_str(directive_name); - let directive_name_atom = Atom::from(directive_name); + let directive_name_atom = Ident::from(directive_name); let value_span = template_attr.value_span.unwrap_or(template_attr.span); let key_span = Span::new(template_attr.name_span.start + 1, template_attr.name_span.end); @@ -3829,7 +3829,7 @@ impl<'a> HtmlToR3Transform<'a> { Span::new(template_attr.name_span.start + 1, template_attr.name_span.end); attributes.push(R3TextAttribute { name: directive_name_atom, - value: Atom::from(""), + value: Ident::from(""), source_span: directive_source_span, key_span: Some(directive_source_span), value_span: None, @@ -3884,7 +3884,7 @@ impl<'a> HtmlToR3Transform<'a> { } let full_name = expr.key.source.as_str(); - let binding_name_atom = Atom::from(self.allocator.alloc_str(full_name)); + let binding_name_atom = Ident::from(self.allocator.alloc_str(full_name)); let source_span = Span::new(expr.source_span.start, expr.source_span.end); let expr_value = if let Some(v) = &expr.value { @@ -3927,7 +3927,7 @@ impl<'a> HtmlToR3Transform<'a> { Span::new(template_attr.name_span.start + 1, template_attr.name_span.end); attributes.push(R3TextAttribute { name: directive_name_atom, - value: Atom::from(""), + value: Ident::from(""), source_span: directive_source_span, key_span: Some(directive_source_span), value_span: None, @@ -4016,12 +4016,12 @@ impl<'a> HtmlToR3Transform<'a> { /// Gets the tag name from a wrapped R3Node for template wrapping. /// Returns the element name for R3Element, "ng-content" for Content, None for R3Template. /// Reference: r3_template_transform.ts lines 1018-1026 - fn get_wrapped_tag_name(&self, node: &R3Node<'a>) -> Option> { + fn get_wrapped_tag_name(&self, node: &R3Node<'a>) -> Option> { match node { R3Node::Element(elem) => Some(elem.name), R3Node::Template(_) => None, // Content has a readonly name = 'ng-content' in TypeScript - R3Node::Content(_) => Some(Atom::from("ng-content")), + R3Node::Content(_) => Some(Ident::from("ng-content")), _ => None, } } @@ -4078,16 +4078,16 @@ impl<'a> HtmlToR3Transform<'a> { let mut placeholder_attrs = HashMap::new_in(self.allocator); for (k, v) in attrs { placeholder_attrs.insert( - Atom::from(self.allocator.alloc_str(&k)), - Atom::from(self.allocator.alloc_str(&v)), + Ident::from(self.allocator.alloc_str(&k)), + Ident::from(self.allocator.alloc_str(&v)), ); } I18nMeta::Node(I18nNode::TagPlaceholder(I18nTagPlaceholder { - tag: Atom::from(self.allocator.alloc_str(tag_name)), + tag: Ident::from(self.allocator.alloc_str(tag_name)), attrs: placeholder_attrs, - start_name: Atom::from(self.allocator.alloc_str(&start_name)), - close_name: Atom::from(self.allocator.alloc_str(&close_name)), + start_name: Ident::from(self.allocator.alloc_str(&start_name)), + close_name: Ident::from(self.allocator.alloc_str(&close_name)), children: Vec::new_in(self.allocator), is_void, source_span: element.span, @@ -4131,16 +4131,16 @@ impl<'a> HtmlToR3Transform<'a> { let mut placeholder_attrs = HashMap::new_in(self.allocator); for (k, v) in attrs { placeholder_attrs.insert( - Atom::from(self.allocator.alloc_str(&k)), - Atom::from(self.allocator.alloc_str(&v)), + Ident::from(self.allocator.alloc_str(&k)), + Ident::from(self.allocator.alloc_str(&v)), ); } I18nMeta::Node(I18nNode::TagPlaceholder(I18nTagPlaceholder { - tag: Atom::from(self.allocator.alloc_str(tag_name)), + tag: Ident::from(self.allocator.alloc_str(tag_name)), attrs: placeholder_attrs, - start_name: Atom::from(self.allocator.alloc_str(&start_name)), - close_name: Atom::from(self.allocator.alloc_str(&close_name)), + start_name: Ident::from(self.allocator.alloc_str(&start_name)), + close_name: Ident::from(self.allocator.alloc_str(&close_name)), children: Vec::new_in(self.allocator), is_void, source_span: component.span, @@ -4201,7 +4201,7 @@ impl<'a> HtmlToR3Transform<'a> { ) -> R3Variable<'a> { let name = var.key.source; // When value is None, Angular uses "$implicit" as the default binding - let value = var.value.as_ref().map_or(Atom::from("$implicit"), |v| v.source); + let value = var.value.as_ref().map_or(Ident::from("$implicit"), |v| v.source); let value_span = var.value.as_ref().map(|v| Span::new(v.span.start, v.span.end)); R3Variable { @@ -4252,7 +4252,7 @@ impl<'a> HtmlToR3Transform<'a> { if start > 0 { let text_before = &text[current_pos..abs_start]; if !text_before.is_empty() { - let text_atom = Atom::from_in(text_before, self.allocator); + let text_atom = Ident::from_in(text_before, self.allocator); children.push(I18nNode::Text(I18nText { value: text_atom, source_span: span })); } } @@ -4266,8 +4266,8 @@ impl<'a> HtmlToR3Transform<'a> { // Generate placeholder name using the i18n placeholder registry let placeholder_name = self.i18n_placeholder_registry.get_placeholder_name("INTERPOLATION", expr); - let name_atom = Atom::from_in(&placeholder_name, self.allocator); - let value_atom = Atom::from_in(expr, self.allocator); + let name_atom = Ident::from_in(&placeholder_name, self.allocator); + let value_atom = Ident::from_in(expr, self.allocator); children.push(I18nNode::Placeholder(I18nPlaceholder { value: value_atom, @@ -4287,7 +4287,7 @@ impl<'a> HtmlToR3Transform<'a> { if current_pos < text.len() { let remaining = &text[current_pos..]; if !remaining.is_empty() { - let text_atom = Atom::from_in(remaining, self.allocator); + let text_atom = Ident::from_in(remaining, self.allocator); children.push(I18nNode::Text(I18nText { value: text_atom, source_span: span })); } } @@ -4350,7 +4350,7 @@ impl<'a> HtmlToR3Transform<'a> { if token.parts.len() >= 3 { // Before adding an expression, commit the current string buffer // (even if empty, we need a string before each expression) - strings.push(Atom::from_in(current_string.as_str(), self.allocator)); + strings.push(Ident::from_in(current_string.as_str(), self.allocator)); current_string.clear(); let start_marker = &token.parts[0]; @@ -4394,7 +4394,7 @@ impl<'a> HtmlToR3Transform<'a> { } // Commit the trailing string (after the last expression) - strings.push(Atom::from_in(current_string.as_str(), self.allocator)); + strings.push(Ident::from_in(current_string.as_str(), self.allocator)); // Create the Interpolation expression let span = ParseSpan::new(0, text.span.end - text.span.start); @@ -4442,7 +4442,7 @@ impl<'a> HtmlToR3Transform<'a> { if token.parts.len() >= 3 { // Before adding an expression, commit the current string buffer // (even if empty, we need a string before each expression) - strings.push(Atom::from_in(current_string.as_str(), self.allocator)); + strings.push(Ident::from_in(current_string.as_str(), self.allocator)); current_string.clear(); let start_marker = &token.parts[0]; @@ -4483,7 +4483,7 @@ impl<'a> HtmlToR3Transform<'a> { } // Commit the trailing string (after the last expression) - strings.push(Atom::from_in(current_string.as_str(), self.allocator)); + strings.push(Ident::from_in(current_string.as_str(), self.allocator)); // Create the Interpolation expression let span = ParseSpan::new(0, value_span.size()); @@ -4545,14 +4545,14 @@ impl<'a> HtmlToR3Transform<'a> { (BindingType::Property, name, None, security_context) }; - let name_atom = Atom::from(self.allocator.alloc_str(final_name)); + let name_atom = Ident::from(self.allocator.alloc_str(final_name)); Some(R3BoundAttribute { name: name_atom, binding_type, security_context, value: expr, - unit: unit.map(|u| Atom::from(self.allocator.alloc_str(u))), + unit: unit.map(|u| Ident::from(self.allocator.alloc_str(u))), source_span: attr.span, key_span: attr.name_span, value_span: attr.value_span, @@ -4630,7 +4630,7 @@ impl<'a> HtmlToR3Transform<'a> { } /// Gets text content from an element. - fn get_text_content(&self, element: &HtmlElement<'a>) -> Option> { + fn get_text_content(&self, element: &HtmlElement<'a>) -> Option> { if element.children.len() == 1 && let HtmlNode::Text(text) = &element.children[0] { @@ -4642,7 +4642,7 @@ impl<'a> HtmlToR3Transform<'a> { /// Gets the stylesheet href from a link element. /// Only returns resolvable URLs per Angular's `isStyleUrlResolvable`. /// Reference: style_url_resolver.ts lines 12-18 - fn get_stylesheet_href(&self, element: &HtmlElement<'a>) -> Option> { + fn get_stylesheet_href(&self, element: &HtmlElement<'a>) -> Option> { let mut is_stylesheet = false; let mut href = None; @@ -4671,13 +4671,13 @@ impl<'a> HtmlToR3Transform<'a> { } /// Gets the ng-content selector. - fn get_ng_content_selector(&self, element: &HtmlElement<'a>) -> Atom<'a> { + fn get_ng_content_selector(&self, element: &HtmlElement<'a>) -> Ident<'a> { for attr in &element.attrs { if attr.name.as_str() == "select" && !attr.value.is_empty() { return attr.value; } } - Atom::from("*") + Ident::from("*") } /// Checks if an element is a void element. @@ -4777,12 +4777,12 @@ fn parse_i18n_meta_with_message<'a>( I18nMeta::Message(I18nMessage { instance_id, nodes: Vec::new_in(allocator), - meaning: Atom::from_in(meaning, allocator), - description: Atom::from_in(description, allocator), - custom_id: Atom::from_in(custom_id, allocator), - id: Atom::from(""), + meaning: Ident::from_in(meaning, allocator), + description: Ident::from_in(description, allocator), + custom_id: Ident::from_in(custom_id, allocator), + id: Ident::from(""), legacy_ids: Vec::new_in(allocator), - message_string: Atom::from_in(message_string, allocator), + message_string: Ident::from_in(message_string, allocator), }) } diff --git a/crates/oxc_angular_compiler/tests/expression_parser_test.rs b/crates/oxc_angular_compiler/tests/expression_parser_test.rs index 334342882..98da0b78c 100644 --- a/crates/oxc_angular_compiler/tests/expression_parser_test.rs +++ b/crates/oxc_angular_compiler/tests/expression_parser_test.rs @@ -1089,7 +1089,7 @@ mod parse_template_bindings { /// Helper to extract key source from ASTWithSource if present. fn get_value_source<'a>(value: &'a Option>) -> Option<&'a str> { - value.as_ref().and_then(|v| v.source.as_ref().map(oxc_span::Atom::as_str)) + value.as_ref().and_then(|v| v.source.as_ref().map(oxc_span::Ident::as_str)) } /// Humanize bindings into (key, value, is_variable) tuples. @@ -1128,7 +1128,7 @@ mod parse_template_bindings { let allocator = Box::leak(Box::new(Allocator::default())); let parser = Parser::new(allocator, value); let template_key = TemplateBindingIdentifier { - source: oxc_span::Atom::from(key), + source: oxc_span::Ident::from(key), span: oxc_angular_compiler::ast::expression::AbsoluteSourceSpan::new( 0, key.len() as u32, @@ -1288,7 +1288,7 @@ mod parse_interpolation { fn get_strings<'a>(result: &'a ParseResult<'a>) -> Vec<&'a str> { match &result.ast { AngularExpression::Interpolation(interp) => { - interp.strings.iter().map(oxc_span::Atom::as_str).collect() + interp.strings.iter().map(oxc_span::Ident::as_str).collect() } _ => vec![], } diff --git a/crates/oxc_angular_compiler/tests/integration_test.rs b/crates/oxc_angular_compiler/tests/integration_test.rs index fa6d8cc33..79960280c 100644 --- a/crates/oxc_angular_compiler/tests/integration_test.rs +++ b/crates/oxc_angular_compiler/tests/integration_test.rs @@ -13,7 +13,7 @@ use oxc_angular_compiler::{ transform::html_to_r3::{HtmlToR3Transform, TransformOptions}, transform_angular_file, }; -use oxc_span::Atom; +use oxc_span::Ident; /// Compiles an Angular template to JavaScript. fn compile_template_to_js(template: &str, component_name: &str) -> String { @@ -55,12 +55,12 @@ fn compile_template_to_js_with_version( let options = IngestOptions { angular_version: Some(version), ..Default::default() }; ingest_component_with_options( &allocator, - Atom::from(component_name), + Ident::from(component_name), r3_result.nodes, options, ) } else { - ingest_component(&allocator, Atom::from(component_name), r3_result.nodes) + ingest_component(&allocator, Ident::from(component_name), r3_result.nodes) }; // Stage 4-5: Transform and emit diff --git a/crates/oxc_angular_compiler/tests/nextcontext_listener.rs b/crates/oxc_angular_compiler/tests/nextcontext_listener.rs index ae9eaf182..65aad4d76 100644 --- a/crates/oxc_angular_compiler/tests/nextcontext_listener.rs +++ b/crates/oxc_angular_compiler/tests/nextcontext_listener.rs @@ -7,7 +7,7 @@ use oxc_angular_compiler::{ pipeline::{emit::compile_template, ingest::ingest_component}, transform::html_to_r3::{HtmlToR3Transform, TransformOptions}, }; -use oxc_span::Atom; +use oxc_span::Ident; fn compile_template_to_js(template: &str, component_name: &str) -> String { let allocator = Allocator::default(); @@ -18,7 +18,7 @@ fn compile_template_to_js(template: &str, component_name: &str) -> String { let transformer = HtmlToR3Transform::new(&allocator, template, TransformOptions::default()); let r3_result = transformer.transform(&nodes); assert!(r3_result.errors.is_empty(), "Transform errors: {:?}", r3_result.errors); - let mut job = ingest_component(&allocator, Atom::from(component_name), r3_result.nodes); + let mut job = ingest_component(&allocator, Ident::from(component_name), r3_result.nodes); let result = compile_template(&mut job); let emitter = JsEmitter::new(); let mut output = String::new(); diff --git a/crates/oxc_angular_compiler/tests/nextcontext_repro.rs b/crates/oxc_angular_compiler/tests/nextcontext_repro.rs index d4bec1b33..d12e226f8 100644 --- a/crates/oxc_angular_compiler/tests/nextcontext_repro.rs +++ b/crates/oxc_angular_compiler/tests/nextcontext_repro.rs @@ -9,7 +9,7 @@ use oxc_angular_compiler::{ }, transform::html_to_r3::{HtmlToR3Transform, TransformOptions}, }; -use oxc_span::Atom; +use oxc_span::Ident; fn compile_template_to_js(template: &str, component_name: &str) -> String { let allocator = Allocator::default(); @@ -20,7 +20,7 @@ fn compile_template_to_js(template: &str, component_name: &str) -> String { let transformer = HtmlToR3Transform::new(&allocator, template, TransformOptions::default()); let r3_result = transformer.transform(&nodes); assert!(r3_result.errors.is_empty(), "Transform errors: {:?}", r3_result.errors); - let mut job = ingest_component(&allocator, Atom::from(component_name), r3_result.nodes); + let mut job = ingest_component(&allocator, Ident::from(component_name), r3_result.nodes); let result = compile_template(&mut job); let emitter = JsEmitter::new(); let mut output = String::new(); @@ -341,7 +341,7 @@ fn test_for_loop_alias_ingest() { let transformer = HtmlToR3Transform::new(&allocator, template, TransformOptions::default()); let r3_result = transformer.transform(&nodes); - let job = ingest_component(&allocator, Atom::from("TestComponent"), r3_result.nodes); + let job = ingest_component(&allocator, Ident::from("TestComponent"), r3_result.nodes); // Check that the body view has the expected context variables and aliases assert!(!job.views.is_empty(), "Should have at least one embedded view"); diff --git a/crates/oxc_angular_compiler/tests/playground_repro.rs b/crates/oxc_angular_compiler/tests/playground_repro.rs index 86b4473d3..6a4533cd0 100644 --- a/crates/oxc_angular_compiler/tests/playground_repro.rs +++ b/crates/oxc_angular_compiler/tests/playground_repro.rs @@ -7,7 +7,7 @@ use oxc_angular_compiler::{ pipeline::{emit::compile_template, ingest::ingest_component}, transform::html_to_r3::{HtmlToR3Transform, TransformOptions}, }; -use oxc_span::Atom; +use oxc_span::Ident; fn compile_template_to_js(template: &str, component_name: &str) -> String { let allocator = Allocator::default(); @@ -19,7 +19,7 @@ fn compile_template_to_js(template: &str, component_name: &str) -> String { let transformer = HtmlToR3Transform::new(&allocator, template, TransformOptions::default()); let r3_result = transformer.transform(&nodes); assert!(r3_result.errors.is_empty(), "Transform errors: {:?}", r3_result.errors); - let mut job = ingest_component(&allocator, Atom::from(component_name), r3_result.nodes); + let mut job = ingest_component(&allocator, Ident::from(component_name), r3_result.nodes); let result = compile_template(&mut job); let emitter = JsEmitter::new(); let mut output = String::new(); diff --git a/crates/oxc_angular_compiler/tests/variable_naming_test.rs b/crates/oxc_angular_compiler/tests/variable_naming_test.rs index 1a060f72a..f3929ea55 100644 --- a/crates/oxc_angular_compiler/tests/variable_naming_test.rs +++ b/crates/oxc_angular_compiler/tests/variable_naming_test.rs @@ -43,7 +43,7 @@ use oxc_angular_compiler::{ pipeline::{emit::compile_template, ingest::ingest_component}, transform::html_to_r3::{HtmlToR3Transform, TransformOptions}, }; -use oxc_span::Atom; +use oxc_span::Ident; use std::collections::HashSet; fn compile_template_to_js(template: &str, component_name: &str) -> String { @@ -55,7 +55,7 @@ fn compile_template_to_js(template: &str, component_name: &str) -> String { let transformer = HtmlToR3Transform::new(&allocator, template, TransformOptions::default()); let r3_result = transformer.transform(&nodes); assert!(r3_result.errors.is_empty(), "Transform errors: {:?}", r3_result.errors); - let mut job = ingest_component(&allocator, Atom::from(component_name), r3_result.nodes); + let mut job = ingest_component(&allocator, Ident::from(component_name), r3_result.nodes); let result = compile_template(&mut job); let emitter = JsEmitter::new(); let mut output = String::new(); diff --git a/napi/angular-compiler/src/lib.rs b/napi/angular-compiler/src/lib.rs index 827e41ae9..7efc41667 100644 --- a/napi/angular-compiler/src/lib.rs +++ b/napi/angular-compiler/src/lib.rs @@ -1266,7 +1266,7 @@ pub fn compile_pipe_sync( use oxc_angular_compiler::{R3PipeMetadataBuilder, compile_pipe, extract_pipe_metadata}; use oxc_ast::ast::{Declaration, ExportDefaultDeclarationKind, Statement}; use oxc_parser::Parser; - use oxc_span::{Atom, SourceType}; + use oxc_span::{Ident, SourceType}; let allocator = Allocator::default(); let source_type = SourceType::from_path(&file_path).unwrap_or_default(); @@ -1316,7 +1316,7 @@ pub fn compile_pipe_sync( .is_standalone(metadata.standalone); if let Some(name) = &metadata.pipe_name { - builder = builder.pipe_name(Atom::from(name.as_str())); + builder = builder.pipe_name(Ident::from(name.as_str())); } let r3_metadata = builder.build(); @@ -1715,7 +1715,7 @@ pub fn extract_component_metadata_sync( metadata .export_as .iter() - .map(oxc_span::Atom::as_str) + .map(oxc_span::Ident::as_str) .collect::>() .join(","), ) @@ -1804,25 +1804,25 @@ pub fn compile_injector_sync(input: InjectorCompileInput) -> InjectorNapiCompile use oxc_angular_compiler::output::ast::{OutputExpression, ReadVarExpr}; use oxc_angular_compiler::output::emitter::JsEmitter; use oxc_angular_compiler::{R3InjectorMetadataBuilder, compile_injector}; - use oxc_span::Atom; + use oxc_span::Ident; let allocator = Allocator::default(); // Create type expression for the injector class let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from(input.name.as_str()), source_span: None }, + ReadVarExpr { name: Ident::from(input.name.as_str()), source_span: None }, &allocator, )); // Build the metadata let mut builder = R3InjectorMetadataBuilder::new(&allocator) - .name(Atom::from(input.name.as_str())) + .name(Ident::from(input.name.as_str())) .r#type(type_expr); // Add providers if present (as a variable reference) if let Some(providers_str) = &input.providers { let providers_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from(providers_str.as_str()), source_span: None }, + ReadVarExpr { name: Ident::from(providers_str.as_str()), source_span: None }, &allocator, )); builder = builder.providers(providers_expr); @@ -1832,7 +1832,7 @@ pub fn compile_injector_sync(input: InjectorCompileInput) -> InjectorNapiCompile if let Some(imports) = &input.imports { for import_name in imports { let import_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from(import_name.as_str()), source_span: None }, + ReadVarExpr { name: Ident::from(import_name.as_str()), source_span: None }, &allocator, )); builder = builder.add_import(import_expr); @@ -1905,7 +1905,7 @@ pub fn compile_class_metadata_sync( use oxc_angular_compiler::output::emitter::JsEmitter; use oxc_ast::ast::{Class, Declaration, ExportDefaultDeclarationKind, Statement}; use oxc_parser::Parser; - use oxc_span::{Atom, SourceType}; + use oxc_span::{Ident, SourceType}; let allocator = Allocator::default(); let source_type = SourceType::from_path(&file_path).unwrap_or_default(); @@ -1959,7 +1959,7 @@ pub fn compile_class_metadata_sync( // Build the class type expression let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from(class_name.as_str()), source_span: None }, + ReadVarExpr { name: Ident::from(class_name.as_str()), source_span: None }, &allocator, )); @@ -2144,7 +2144,7 @@ fn compile_factory_impl(input: FactoryCompileInput) -> FactoryNapiCompileResult }; use oxc_angular_compiler::output::ast::{OutputExpression, ReadVarExpr}; use oxc_angular_compiler::output::emitter::JsEmitter; - use oxc_span::Atom; + use oxc_span::Ident; let allocator = Allocator::default(); @@ -2167,7 +2167,7 @@ fn compile_factory_impl(input: FactoryCompileInput) -> FactoryNapiCompileResult // Create type expression for the class let type_expr = OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from(input.name.as_str()), source_span: None }, + ReadVarExpr { name: Ident::from(input.name.as_str()), source_span: None }, &allocator, )); @@ -2183,7 +2183,7 @@ fn compile_factory_impl(input: FactoryCompileInput) -> FactoryNapiCompileResult // Use ReadVarExpr for token since WrappedNodeExpr cannot be emitted let token = dep.token.as_ref().map(|t| { OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from(t.as_str()), source_span: None }, + ReadVarExpr { name: Ident::from(t.as_str()), source_span: None }, &allocator, )) }); @@ -2191,7 +2191,7 @@ fn compile_factory_impl(input: FactoryCompileInput) -> FactoryNapiCompileResult // Use ReadVarExpr for attribute name type let attribute_name_type = dep.attribute_name_type.as_ref().map(|a| { OutputExpression::ReadVar(Box::new_in( - ReadVarExpr { name: Atom::from(a.as_str()), source_span: None }, + ReadVarExpr { name: Ident::from(a.as_str()), source_span: None }, &allocator, )) }); @@ -2221,7 +2221,7 @@ fn compile_factory_impl(input: FactoryCompileInput) -> FactoryNapiCompileResult // Build factory metadata let factory_name = format!("{}_Factory", input.name); let metadata = R3FactoryMetadata::Constructor(R3ConstructorFactoryMetadata { - name: Atom::from(input.name.as_str()), + name: Ident::from(input.name.as_str()), type_expr: type_expr.clone_in(&allocator), type_decl: type_expr, type_argument_count: 0, From 1a5daaf5f58a91ddb99599977efd373c5b97064a Mon Sep 17 00:00:00 2001 From: "anthropic-code-agent[bot]" <242468646+Claude@users.noreply.github.com> Date: Tue, 31 Mar 2026 03:30:39 +0000 Subject: [PATCH 3/4] fix: resolve type mismatch errors with --all-features Fix HashMap/HashSet lookups where Ident keys require proper type conversions Agent-Logs-Url: https://github.com/voidzero-dev/oxc-angular-compiler/sessions/a7e20639-8c1f-41cd-9213-7290a72152ec Co-authored-by: Brooooooklyn <3468483+Brooooooklyn@users.noreply.github.com> --- crates/oxc_angular_compiler/src/component/import_elision.rs | 2 +- crates/oxc_angular_compiler/src/component/transform.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/oxc_angular_compiler/src/component/import_elision.rs b/crates/oxc_angular_compiler/src/component/import_elision.rs index ef9c99f0c..fcafb803f 100644 --- a/crates/oxc_angular_compiler/src/component/import_elision.rs +++ b/crates/oxc_angular_compiler/src/component/import_elision.rs @@ -704,7 +704,7 @@ impl<'a> ImportElisionAnalyzer<'a> { let local_name = &spec.local.name; // Skip if already marked as type-only by semantic analysis - if analyzer.type_only_specifiers.contains(local_name.as_str()) { + if analyzer.type_only_specifiers.contains(local_name) { continue; } diff --git a/crates/oxc_angular_compiler/src/component/transform.rs b/crates/oxc_angular_compiler/src/component/transform.rs index f665010ea..165f701d1 100644 --- a/crates/oxc_angular_compiler/src/component/transform.rs +++ b/crates/oxc_angular_compiler/src/component/transform.rs @@ -1586,7 +1586,7 @@ pub fn transform_angular_file( // a TypeScript type checker we cannot otherwise distinguish interfaces from classes. #[cfg(feature = "cross_file_elision")] for (name, is_type_only) in &cross_file_type_only { - if let Some(info) = import_map.get_mut(name.as_str()) { + if let Some(info) = import_map.get_mut(&Ident::from(name.as_str())) { if *is_type_only { info.is_type_only = true; } @@ -5174,7 +5174,7 @@ export class ButtonComponent {} &allocator, component_path.to_str().unwrap(), component_source, - &options, + Some(&options), None, ); From 911abed74cf70ecca18bfd534c0475f37b236fa3 Mon Sep 17 00:00:00 2001 From: "anthropic-code-agent[bot]" <242468646+Claude@users.noreply.github.com> Date: Tue, 31 Mar 2026 03:46:31 +0000 Subject: [PATCH 4/4] chore: run cargo fmt to fix formatting issues Agent-Logs-Url: https://github.com/voidzero-dev/oxc-angular-compiler/sessions/bd85e1c3-dac8-400f-905a-65ef81ad4ae1 Co-authored-by: Brooooooklyn <3468483+Brooooooklyn@users.noreply.github.com> --- .../oxc_angular_compiler/src/component/decorator.rs | 11 ++++++++--- .../oxc_angular_compiler/src/component/transform.rs | 2 +- .../oxc_angular_compiler/src/directive/decorator.rs | 8 ++++++-- crates/oxc_angular_compiler/src/directive/metadata.rs | 6 ++++-- .../oxc_angular_compiler/src/output/oxc_converter.rs | 11 +++++++++-- .../src/pipeline/phases/create_i18n_contexts.rs | 2 +- .../src/pipeline/phases/extract_i18n_messages.rs | 2 +- .../src/pipeline/phases/generate_projection_def.rs | 5 ++++- .../src/pipeline/phases/i18n_text_extraction.rs | 8 ++++++-- .../src/pipeline/phases/naming.rs | 3 ++- 10 files changed, 42 insertions(+), 16 deletions(-) diff --git a/crates/oxc_angular_compiler/src/component/decorator.rs b/crates/oxc_angular_compiler/src/component/decorator.rs index 7ff6a2bdc..deca15ac6 100644 --- a/crates/oxc_angular_compiler/src/component/decorator.rs +++ b/crates/oxc_angular_compiler/src/component/decorator.rs @@ -196,7 +196,8 @@ pub fn extract_component_metadata<'a>( // Add @HostBinding properties // Wrap with brackets: "class.active" -> "[class.active]" for (host_prop, class_prop) in host_bindings { - let wrapped_key = Ident::from(allocator.alloc_str(&format!("[{}]", host_prop.as_str()))); + let wrapped_key = + Ident::from(allocator.alloc_str(&format!("[{}]", host_prop.as_str()))); host.properties.push((wrapped_key, class_prop)); } @@ -762,11 +763,15 @@ fn parse_mapping_element<'a>( let elements = &arr.elements; if elements.len() >= 2 { let internal = match elements.first() { - Some(ArrayExpressionElement::StringLiteral(lit)) => Some(lit.value.clone().into()), + Some(ArrayExpressionElement::StringLiteral(lit)) => { + Some(lit.value.clone().into()) + } _ => None, }; let public = match elements.get(1) { - Some(ArrayExpressionElement::StringLiteral(lit)) => Some(lit.value.clone().into()), + Some(ArrayExpressionElement::StringLiteral(lit)) => { + Some(lit.value.clone().into()) + } _ => None, }; if let (Some(internal_name), Some(public_name)) = (internal, public) { diff --git a/crates/oxc_angular_compiler/src/component/transform.rs b/crates/oxc_angular_compiler/src/component/transform.rs index 165f701d1..767a4428c 100644 --- a/crates/oxc_angular_compiler/src/component/transform.rs +++ b/crates/oxc_angular_compiler/src/component/transform.rs @@ -14,7 +14,7 @@ use oxc_ast::ast::{ }; use oxc_diagnostics::OxcDiagnostic; use oxc_parser::Parser; -use oxc_span::{Ident, GetSpan, SourceType, Span}; +use oxc_span::{GetSpan, Ident, SourceType, Span}; use rustc_hash::FxHashMap; use crate::optimizer::{Edit, apply_edits, apply_edits_with_sourcemap}; diff --git a/crates/oxc_angular_compiler/src/directive/decorator.rs b/crates/oxc_angular_compiler/src/directive/decorator.rs index a580e16ab..834194333 100644 --- a/crates/oxc_angular_compiler/src/directive/decorator.rs +++ b/crates/oxc_angular_compiler/src/directive/decorator.rs @@ -732,11 +732,15 @@ fn parse_mapping_element<'a>( let elements = &arr.elements; if elements.len() >= 2 { let internal = match elements.first() { - Some(ArrayExpressionElement::StringLiteral(lit)) => Some(lit.value.clone().into()), + Some(ArrayExpressionElement::StringLiteral(lit)) => { + Some(lit.value.clone().into()) + } _ => None, }; let public = match elements.get(1) { - Some(ArrayExpressionElement::StringLiteral(lit)) => Some(lit.value.clone().into()), + Some(ArrayExpressionElement::StringLiteral(lit)) => { + Some(lit.value.clone().into()) + } _ => None, }; if let (Some(internal_name), Some(public_name)) = (internal, public) { diff --git a/crates/oxc_angular_compiler/src/directive/metadata.rs b/crates/oxc_angular_compiler/src/directive/metadata.rs index fbc051154..aba78a5c7 100644 --- a/crates/oxc_angular_compiler/src/directive/metadata.rs +++ b/crates/oxc_angular_compiler/src/directive/metadata.rs @@ -440,7 +440,8 @@ impl<'a> R3DirectiveMetadataBuilder<'a> { let host_bindings = super::property_decorators::extract_host_bindings(allocator, class); for (host_prop, class_prop) in host_bindings { // Add to host.properties with wrapped key - let wrapped_key = Ident::from(allocator.alloc_str(&format!("[{}]", host_prop.as_str()))); + let wrapped_key = + Ident::from(allocator.alloc_str(&format!("[{}]", host_prop.as_str()))); self.host.properties.push((wrapped_key, class_prop)); } @@ -568,7 +569,8 @@ mod tests { #[test] fn test_builder_missing_type_returns_none() { let allocator = Allocator::default(); - let builder = R3DirectiveMetadataBuilder::new(&allocator).name(Ident::from("TestDirective")); + let builder = + R3DirectiveMetadataBuilder::new(&allocator).name(Ident::from("TestDirective")); let metadata = builder.build(); assert!(metadata.is_none()); diff --git a/crates/oxc_angular_compiler/src/output/oxc_converter.rs b/crates/oxc_angular_compiler/src/output/oxc_converter.rs index 6eb2b9527..cc6fd85af 100644 --- a/crates/oxc_angular_compiler/src/output/oxc_converter.rs +++ b/crates/oxc_angular_compiler/src/output/oxc_converter.rs @@ -64,7 +64,10 @@ pub fn convert_oxc_expression<'a>( ))), Expression::StringLiteral(lit) => Some(OutputExpression::Literal(Box::new_in( - LiteralExpr { value: LiteralValue::String(lit.value.clone().into()), source_span: None }, + LiteralExpr { + value: LiteralValue::String(lit.value.clone().into()), + source_span: None, + }, allocator, ))), @@ -532,7 +535,11 @@ fn convert_template_literal<'a>( .map_or_else(|| quasi.value.raw.clone(), |cooked| cooked.clone()); let raw_text = quasi.value.raw.clone(); - elements.push(TemplateLiteralElement { text: text.into(), raw_text: raw_text.into(), source_span: None }); + elements.push(TemplateLiteralElement { + text: text.into(), + raw_text: raw_text.into(), + source_span: None, + }); } // Convert expressions diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/create_i18n_contexts.rs b/crates/oxc_angular_compiler/src/pipeline/phases/create_i18n_contexts.rs index 8f7232b6c..442ea3823 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/create_i18n_contexts.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/create_i18n_contexts.rs @@ -38,7 +38,7 @@ pub fn create_i18n_contexts(job: &mut ComponentCompilationJob<'_>) { message_instance_id: u32, is_create_op: bool, // true for ExtractedAttribute, false for update ops // Additional fields to uniquely identify the attribute - target: XrefId, // Element xref this attribute belongs to + target: XrefId, // Element xref this attribute belongs to name: Ident<'a>, // Attribute name } let mut attr_ops_needing_context: Vec> = Vec::new(); diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/extract_i18n_messages.rs b/crates/oxc_angular_compiler/src/pipeline/phases/extract_i18n_messages.rs index 1d2df483d..8c1717c00 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/extract_i18n_messages.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/extract_i18n_messages.rs @@ -241,7 +241,7 @@ pub fn extract_i18n_messages(job: &mut ComponentCompilationJob<'_>) { XrefId, // view_xref NonNull>, // op_ptr XrefId, // icu_context_xref - Ident<'_>, // placeholder name + Ident<'_>, // placeholder name String, // formatted value )> = Vec::new(); diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/generate_projection_def.rs b/crates/oxc_angular_compiler/src/pipeline/phases/generate_projection_def.rs index d0b657483..b6717d1bc 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/generate_projection_def.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/generate_projection_def.rs @@ -112,7 +112,10 @@ pub fn generate_projection_defs(job: &mut ComponentCompilationJob<'_>) { if selector.as_str() == "*" { // Wildcard stays as string literal "*" def_elements.push(OutputExpression::Literal(OxcBox::new_in( - LiteralExpr { value: LiteralValue::String(Ident::from("*")), source_span: None }, + LiteralExpr { + value: LiteralValue::String(Ident::from("*")), + source_span: None, + }, allocator, ))); } else { diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/i18n_text_extraction.rs b/crates/oxc_angular_compiler/src/pipeline/phases/i18n_text_extraction.rs index a10fbfd02..20ea582a8 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/i18n_text_extraction.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/i18n_text_extraction.rs @@ -50,8 +50,12 @@ fn convert_i18n_text_in_view(job: &mut ComponentCompilationJob<'_>, view_xref: X // Track text ops to be replaced with IcuPlaceholder ops // (text_op_ptr, text_xref, icu_placeholder_name, initial_value) - let mut text_ops_to_replace_with_icu: Vec<(NonNull>, XrefId, Ident<'_>, Ident<'_>)> = - Vec::new(); + let mut text_ops_to_replace_with_icu: Vec<( + NonNull>, + XrefId, + Ident<'_>, + Ident<'_>, + )> = Vec::new(); // Track text ops to be removed (those without ICU placeholder) let mut text_nodes_to_remove: Vec>> = Vec::new(); diff --git a/crates/oxc_angular_compiler/src/pipeline/phases/naming.rs b/crates/oxc_angular_compiler/src/pipeline/phases/naming.rs index 0ff521273..d6db424cf 100644 --- a/crates/oxc_angular_compiler/src/pipeline/phases/naming.rs +++ b/crates/oxc_angular_compiler/src/pipeline/phases/naming.rs @@ -263,7 +263,8 @@ pub fn name_functions_and_variables(job: &mut ComponentCompilationJob<'_>) { // This enables name reuse for variables with the same semantic identity, // matching TypeScript's behavior where multiple Variable ops can share // the same SemanticVariable object. - let mut semantic_var_names: FxHashMap, Ident<'_>> = FxHashMap::default(); + let mut semantic_var_names: FxHashMap, Ident<'_>> = + FxHashMap::default(); // Recursively name views starting from root // TypeScript: addNamesToView(job.root, job.componentName, state, compatibility)