From c7babb32c147f864ce49fa0765970079d2a286de Mon Sep 17 00:00:00 2001 From: Iban Eguia Moraza Date: Thu, 30 Mar 2023 16:58:08 +0200 Subject: [PATCH 1/9] Initial version of a JS -> Rust conversion trait. --- Cargo.lock | 226 ++++++++++++----- .../{conversions.rs => conversions/mod.rs} | 54 +++- .../src/value/{ => conversions}/serde_json.rs | 0 .../src/value/conversions/try_from_js.rs | 237 ++++++++++++++++++ boa_engine/src/value/mod.rs | 19 +- boa_examples/Cargo.toml | 2 - boa_examples/src/bin/derive.rs | 48 ++++ boa_icu_provider/Cargo.toml | 2 +- boa_macros/Cargo.toml | 5 +- boa_macros/src/lib.rs | 152 ++++++++++- boa_macros/tests/derive/from_js_with.rs | 20 ++ boa_macros/tests/derive/simple_struct.rs | 8 + boa_macros/tests/{utf16.rs => tests.rs} | 7 + 13 files changed, 687 insertions(+), 93 deletions(-) rename boa_engine/src/value/{conversions.rs => conversions/mod.rs} (64%) rename boa_engine/src/value/{ => conversions}/serde_json.rs (100%) create mode 100644 boa_engine/src/value/conversions/try_from_js.rs create mode 100644 boa_examples/src/bin/derive.rs create mode 100644 boa_macros/tests/derive/from_js_with.rs create mode 100644 boa_macros/tests/derive/simple_struct.rs rename boa_macros/tests/{utf16.rs => tests.rs} (68%) diff --git a/Cargo.lock b/Cargo.lock index aba2e8a35a2..dd675509434 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -160,22 +160,22 @@ dependencies = [ [[package]] name = "async-io" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c374dda1ed3e7d8f0d9ba58715f924862c63eae6849c92d3a18e7fbde9e2794" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" dependencies = [ "async-lock", "autocfg", + "cfg-if 1.0.0", "concurrent-queue", "futures-lite", - "libc", "log", "parking", "polling", + "rustix", "slab", "socket2", "waker-fn", - "windows-sys 0.42.0", ] [[package]] @@ -219,9 +219,9 @@ dependencies = [ [[package]] name = "async-task" -version = "4.3.0" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524" +checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" [[package]] name = "atomic-polyfill" @@ -291,6 +291,15 @@ version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" +[[package]] +name = "basic-toml" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c0de75129aa8d0cceaf750b89013f0e08804d6ec61416da787b35ad0d7cddf1" +dependencies = [ + "serde", +] + [[package]] name = "bincode" version = "1.3.3" @@ -473,10 +482,12 @@ dependencies = [ name = "boa_macros" version = "0.16.0" dependencies = [ + "boa_engine", "proc-macro2", "quote", "syn 2.0.11", "synstructure 0.13.0", + "trybuild", ] [[package]] @@ -741,7 +752,7 @@ dependencies = [ "anstream", "anstyle", "bitflags 1.3.2", - "clap_lex 0.4.0", + "clap_lex 0.4.1", "strsim 0.10.0", ] @@ -768,9 +779,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f0807fb6f644c83f3e4ec014fec9858c1c8b26a7db8eb5f0bde5817df9c1df7" +checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" [[package]] name = "clipboard-win" @@ -922,9 +933,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181" dependencies = [ "libc", ] @@ -1066,9 +1077,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c00419335c41018365ddf7e4d5f1c12ee3659ddcf3e01974650ba1de73d038" +checksum = "f61f1b6389c3fe1c316bf8a4dccc90a38208354b330925bce1f74a6c4756eb93" dependencies = [ "cc", "cxxbridge-flags", @@ -1078,9 +1089,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb8307ad413a98fff033c8545ecf133e3257747b3bae935e7602aab8aa92d4ca" +checksum = "12cee708e8962df2aeb38f594aae5d827c022b6460ac71a7a3e2c3c2aae5a07b" dependencies = [ "cc", "codespan-reporting", @@ -1093,15 +1104,15 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc52e2eb08915cb12596d29d55f0b5384f00d697a646dbd269b6ecb0fbd9d31" +checksum = "7944172ae7e4068c533afbb984114a56c46e9ccddda550499caa222902c7f7bb" [[package]] name = "cxxbridge-macro" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "631569015d0d8d54e6c241733f944042623ab6df7bc3be7466874b05fcdb1c5f" +checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5" dependencies = [ "proc-macro2", "quote", @@ -1377,13 +1388,13 @@ dependencies = [ [[package]] name = "errno" -version = "0.2.8" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0" dependencies = [ "errno-dragonfly", "libc", - "winapi", + "windows-sys 0.45.0", ] [[package]] @@ -1445,9 +1456,9 @@ dependencies = [ [[package]] name = "fd-lock" -version = "3.0.10" +version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ef1a30ae415c3a691a4f41afddc2dbcd6d70baf338368d85ebc1e8ed92cedb9" +checksum = "9799aefb4a2e4a01cc47610b1dd47c18ab13d991f27bbcaed9296f5a53d5cbad" dependencies = [ "cfg-if 1.0.0", "rustix", @@ -1462,7 +1473,7 @@ checksum = "8a3de6e8d11b22ff9edc6d916f890800597d60f8b2da1caf2955c274638d6412" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall", + "redox_syscall 0.2.16", "windows-sys 0.45.0", ] @@ -1631,9 +1642,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -1853,16 +1864,16 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.53" +version = "0.1.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +checksum = "716f12fbcfac6ffab0a5e9ec51d0a0ff70503742bb2dc7b99396394c9dc323f0" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "winapi", + "windows", ] [[package]] @@ -2380,15 +2391,15 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.7.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30e22bd8629359895450b59ea7a776c850561b96a3b1d31321c1949d9e6c9146" +checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" [[package]] name = "is-terminal" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8687c819457e979cc940d09cb16e42a1bf70aa6b60a549de6d3a62a0ee90c69e" +checksum = "256017f749ab3117e93acb91063009e1f1bb56d03965b14c2c8df4eb02c524d8" dependencies = [ "hermit-abi 0.3.1", "io-lifetimes", @@ -2485,9 +2496,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.1.4" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" +checksum = "cd550e73688e6d578f0ac2119e32b797a327631a42f9433e59d02e139c8df60d" [[package]] name = "litemap" @@ -2925,7 +2936,7 @@ dependencies = [ "cfg-if 1.0.0", "instant", "libc", - "redox_syscall", + "redox_syscall 0.2.16", "smallvec", "winapi", ] @@ -2938,7 +2949,7 @@ checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall", + "redox_syscall 0.2.16", "smallvec", "windows-sys 0.45.0", ] @@ -3240,6 +3251,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "redox_users" version = "0.4.3" @@ -3247,7 +3267,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ "getrandom", - "redox_syscall", + "redox_syscall 0.2.16", "thiserror", ] @@ -3311,9 +3331,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.15" +version = "0.11.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ba30cc2c0cd02af1222ed216ba659cdb2f879dfe3181852fe7c50b1d0005949" +checksum = "27b71749df584b7f4cac2c426c127a7c785a5106cc98f7a8feb044115f0fa254" dependencies = [ "base64", "bytes", @@ -3382,9 +3402,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" +checksum = "d4a36c42d1873f9a77c53bde094f9664d9891bc604a45b4798fd2c389ed12e5b" [[package]] name = "rustc-hash" @@ -3412,9 +3432,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.36.11" +version = "0.37.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db4165c9963ab29e422d6c26fbc1d37f15bace6b2810221f9d925023480fcf0e" +checksum = "0e78cc525325c06b4a7ff02db283472f3c042b7ff0c391f96c6d5ac6f4f91b75" dependencies = [ "bitflags 1.3.2", "errno", @@ -3817,9 +3837,9 @@ dependencies = [ [[package]] name = "spin" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5d6e0250b93c8427a177b849d144a96d5acc57006149479403d7861ab721e34" +checksum = "c0959fd6f767df20b231736396e4f602171e00d95205676286e79d4a4eb67bef" dependencies = [ "lock_api", ] @@ -4031,15 +4051,15 @@ checksum = "8ae9980cab1db3fceee2f6c6f643d5d8de2997c58ee8d25fb0cc8a9e9e7348e5" [[package]] name = "tempfile" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af18f7ae1acd354b992402e9ec5864359d693cd8a79dcbef59f76891701c1e95" +checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" dependencies = [ "cfg-if 1.0.0", "fastrand", - "redox_syscall", + "redox_syscall 0.3.5", "rustix", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] @@ -4230,14 +4250,13 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.26.0" +version = "1.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03201d01c3c27a29c8a5cee5b55a93ddae1ccf6f08f65365c2c918f8c1b76f64" +checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001" dependencies = [ "autocfg", "bytes", "libc", - "memchr", "mio", "num_cpus", "pin-project-lite", @@ -4301,9 +4320,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.19.7" +version = "0.19.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc18466501acd8ac6a3f615dd29a3438f8ca6bb3b19537138b3106e575621274" +checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13" dependencies = [ "indexmap", "serde", @@ -4379,6 +4398,21 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +[[package]] +name = "trybuild" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501dbdbb99861e4ab6b60eb6a7493956a9defb644fd034bc4a5ef27c693c8a3a" +dependencies = [ + "basic-toml", + "glob", + "once_cell", + "serde", + "serde_derive", + "serde_json", + "termcolor", +] + [[package]] name = "typenum" version = "1.16.0" @@ -4931,6 +4965,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.47.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2649ff315bee4c98757f15dac226efe3d81927adbb6e882084bb1ee3e0c330a7" +dependencies = [ + "windows-targets 0.47.0", +] + [[package]] name = "windows-sys" version = "0.33.0" @@ -4950,12 +4993,12 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "windows_aarch64_gnullvm", + "windows_aarch64_gnullvm 0.42.2", "windows_aarch64_msvc 0.42.2", "windows_i686_gnu 0.42.2", "windows_i686_msvc 0.42.2", "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm", + "windows_x86_64_gnullvm 0.42.2", "windows_x86_64_msvc 0.42.2", ] @@ -4965,7 +5008,7 @@ version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows-targets", + "windows-targets 0.42.2", ] [[package]] @@ -4974,21 +5017,42 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ - "windows_aarch64_gnullvm", + "windows_aarch64_gnullvm 0.42.2", "windows_aarch64_msvc 0.42.2", "windows_i686_gnu 0.42.2", "windows_i686_msvc 0.42.2", "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm", + "windows_x86_64_gnullvm 0.42.2", "windows_x86_64_msvc 0.42.2", ] +[[package]] +name = "windows-targets" +version = "0.47.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f8996d3f43b4b2d44327cd71b7b0efd1284ab60e6e9d0e8b630e18555d87d3e" +dependencies = [ + "windows_aarch64_gnullvm 0.47.0", + "windows_aarch64_msvc 0.47.0", + "windows_i686_gnu 0.47.0", + "windows_i686_msvc 0.47.0", + "windows_x86_64_gnu 0.47.0", + "windows_x86_64_gnullvm 0.47.0", + "windows_x86_64_msvc 0.47.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.47.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831d567d53d4f3cb1db332b68e6e2b6260228eb4d99a777d8b2e8ed794027c90" + [[package]] name = "windows_aarch64_msvc" version = "0.33.0" @@ -5001,6 +5065,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +[[package]] +name = "windows_aarch64_msvc" +version = "0.47.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a42d54a417c60ce4f0e31661eed628f0fa5aca73448c093ec4d45fab4c51cdf" + [[package]] name = "windows_i686_gnu" version = "0.33.0" @@ -5013,6 +5083,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +[[package]] +name = "windows_i686_gnu" +version = "0.47.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1925beafdbb22201a53a483db861a5644123157c1c3cee83323a2ed565d71e3" + [[package]] name = "windows_i686_msvc" version = "0.33.0" @@ -5025,6 +5101,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +[[package]] +name = "windows_i686_msvc" +version = "0.47.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8ef8f2f1711b223947d9b69b596cf5a4e452c930fb58b6fc3fdae7d0ec6b31" + [[package]] name = "windows_x86_64_gnu" version = "0.33.0" @@ -5037,12 +5119,24 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +[[package]] +name = "windows_x86_64_gnu" +version = "0.47.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7acaa0c2cf0d2ef99b61c308a0c3dbae430a51b7345dedec470bd8f53f5a3642" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.47.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a0628f71be1d11e17ca4a0e9e15b3a5180f6fbf1c2d55e3ba3f850378052c1" + [[package]] name = "windows_x86_64_msvc" version = "0.33.0" @@ -5055,11 +5149,17 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +[[package]] +name = "windows_x86_64_msvc" +version = "0.47.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d6e62c256dc6d40b8c8707df17df8d774e60e39db723675241e7c15e910bce7" + [[package]] name = "winnow" -version = "0.3.6" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d020b441f92996c80d94ae9166e8501e59c7bb56121189dc9eab3bd8216966" +checksum = "ae8970b36c66498d8ff1d66685dc86b91b29db0c7739899012f63a63814b4b28" dependencies = [ "memchr", ] diff --git a/boa_engine/src/value/conversions.rs b/boa_engine/src/value/conversions/mod.rs similarity index 64% rename from boa_engine/src/value/conversions.rs rename to boa_engine/src/value/conversions/mod.rs index 8a8335cec55..b90c080ef8f 100644 --- a/boa_engine/src/value/conversions.rs +++ b/boa_engine/src/value/conversions/mod.rs @@ -1,5 +1,10 @@ +//! Conversions from JavaScript values into Rust values, and the other way around. + use super::{JsBigInt, JsObject, JsString, JsSymbol, JsValue, Profiler}; +mod serde_json; +pub(super) mod try_from_js; + impl From for JsValue where T: Into, @@ -14,6 +19,8 @@ where impl From for JsValue { #[inline] fn from(value: char) -> Self { + let _timer = Profiler::global().start_event("From", "value"); + Self::new(value.to_string()) } } @@ -21,37 +28,35 @@ impl From for JsValue { impl From for JsValue { #[inline] fn from(value: JsSymbol) -> Self { + let _timer = Profiler::global().start_event("From", "value"); + Self::Symbol(value) } } impl From for JsValue { - #[allow(clippy::float_cmp)] #[inline] fn from(value: f32) -> Self { - // if value as i32 as f64 == value { - // Self::Integer(value as i32) - // } else { + let _timer = Profiler::global().start_event("From", "value"); + Self::Rational(value.into()) - // } } } impl From for JsValue { - #[allow(clippy::float_cmp)] #[inline] fn from(value: f64) -> Self { - // if value as i32 as f64 == value { - // Self::Integer(value as i32) - // } else { + let _timer = Profiler::global().start_event("From", "value"); + Self::Rational(value) - // } } } impl From for JsValue { #[inline] fn from(value: u8) -> Self { + let _timer = Profiler::global().start_event("From", "value"); + Self::Integer(value.into()) } } @@ -59,6 +64,8 @@ impl From for JsValue { impl From for JsValue { #[inline] fn from(value: i8) -> Self { + let _timer = Profiler::global().start_event("From", "value"); + Self::Integer(value.into()) } } @@ -66,6 +73,8 @@ impl From for JsValue { impl From for JsValue { #[inline] fn from(value: u16) -> Self { + let _timer = Profiler::global().start_event("From", "value"); + Self::Integer(value.into()) } } @@ -73,6 +82,8 @@ impl From for JsValue { impl From for JsValue { #[inline] fn from(value: i16) -> Self { + let _timer = Profiler::global().start_event("From", "value"); + Self::Integer(value.into()) } } @@ -80,6 +91,8 @@ impl From for JsValue { impl From for JsValue { #[inline] fn from(value: u32) -> Self { + let _timer = Profiler::global().start_event("From", "value"); + i32::try_from(value).map_or_else(|_| Self::Rational(value.into()), Self::Integer) } } @@ -87,6 +100,8 @@ impl From for JsValue { impl From for JsValue { #[inline] fn from(value: i32) -> Self { + let _timer = Profiler::global().start_event("From", "value"); + Self::Integer(value) } } @@ -94,6 +109,8 @@ impl From for JsValue { impl From for JsValue { #[inline] fn from(value: JsBigInt) -> Self { + let _timer = Profiler::global().start_event("From", "value"); + Self::BigInt(value) } } @@ -101,6 +118,8 @@ impl From for JsValue { impl From for JsValue { #[inline] fn from(value: usize) -> Self { + let _timer = Profiler::global().start_event("From", "value"); + i32::try_from(value).map_or(Self::Rational(value as f64), Self::Integer) } } @@ -108,6 +127,8 @@ impl From for JsValue { impl From for JsValue { #[inline] fn from(value: u64) -> Self { + let _timer = Profiler::global().start_event("From", "value"); + i32::try_from(value).map_or(Self::Rational(value as f64), Self::Integer) } } @@ -115,6 +136,8 @@ impl From for JsValue { impl From for JsValue { #[inline] fn from(value: i64) -> Self { + let _timer = Profiler::global().start_event("From", "value"); + i32::try_from(value).map_or(Self::Rational(value as f64), Self::Integer) } } @@ -122,6 +145,8 @@ impl From for JsValue { impl From for JsValue { #[inline] fn from(value: bool) -> Self { + let _timer = Profiler::global().start_event("From", "value"); + Self::Boolean(value) } } @@ -130,6 +155,7 @@ impl From for JsValue { #[inline] fn from(object: JsObject) -> Self { let _timer = Profiler::global().start_event("From", "value"); + Self::Object(object) } } @@ -137,11 +163,18 @@ impl From for JsValue { impl From<()> for JsValue { #[inline] fn from(_: ()) -> Self { + let _timer = Profiler::global().start_event("From<()>", "value"); + Self::null() } } +/// Converts an `Option` into a `JsValue`. +/// +/// It will convert the `None` variant to `JsValue::undefined()`, and the `Some()` variant into a +/// `JsValue` using the `Into` trait. pub(crate) trait IntoOrUndefined { + /// Converts an `Option` into a `JsValue`. fn into_or_undefined(self) -> JsValue; } @@ -149,6 +182,7 @@ impl IntoOrUndefined for Option where T: Into, { + #[inline] fn into_or_undefined(self) -> JsValue { self.map_or_else(JsValue::undefined, Into::into) } diff --git a/boa_engine/src/value/serde_json.rs b/boa_engine/src/value/conversions/serde_json.rs similarity index 100% rename from boa_engine/src/value/serde_json.rs rename to boa_engine/src/value/conversions/serde_json.rs diff --git a/boa_engine/src/value/conversions/try_from_js.rs b/boa_engine/src/value/conversions/try_from_js.rs new file mode 100644 index 00000000000..bfd44936cbc --- /dev/null +++ b/boa_engine/src/value/conversions/try_from_js.rs @@ -0,0 +1,237 @@ +//! This module contains the [`TryFromJs`] trait, and conversions to basic Rust types. + +use crate::{Context, JsBigInt, JsNativeError, JsResult, JsValue}; +use num_bigint::BigInt; + +/// This trait adds a fallible and efficient conversions from a [`JsValue`] to Rust types. +pub trait TryFromJs: Sized { + /// This function tries to convert a JavaScript value into `Self`. + fn try_from_js(value: &JsValue, context: &mut Context<'_>) -> JsResult; +} + +impl JsValue { + /// This function is the inverse of [`TryFromJs`]. It tries to convert a [`JsValue`] to a given + /// Rust type. + pub fn try_js_into(&self, context: &mut Context<'_>) -> JsResult + where + T: TryFromJs, + { + T::try_from_js(self, context) + } +} + +impl TryFromJs for bool { + fn try_from_js(value: &JsValue, _context: &mut Context<'_>) -> JsResult { + match value { + JsValue::Boolean(b) => Ok(*b), + _ => Err(JsNativeError::typ() + .with_message("cannot convert value to a boolean") + .into()), + } + } +} + +impl TryFromJs for String { + fn try_from_js(value: &JsValue, _context: &mut Context<'_>) -> JsResult { + match value { + JsValue::String(s) => s.to_std_string().map_err(|e| { + JsNativeError::typ() + .with_message(format!("could not convert JsString to Rust string, since it has UTF-16 characters: {e}")) + .into() + }), + _ => Err(JsNativeError::typ() + .with_message("cannot convert value to a String") + .into()), + } + } +} + +impl TryFromJs for Option +where + T: TryFromJs, +{ + fn try_from_js(value: &JsValue, context: &mut Context<'_>) -> JsResult { + match value { + JsValue::Null | JsValue::Undefined => Ok(None), + value => Ok(Some(T::try_from_js(value, context)?)), + } + } +} + +impl TryFromJs for JsBigInt { + fn try_from_js(value: &JsValue, _context: &mut Context<'_>) -> JsResult { + match value { + JsValue::BigInt(b) => Ok(b.clone()), + _ => Err(JsNativeError::typ() + .with_message("cannot convert value to a BigInt") + .into()), + } + } +} + +impl TryFromJs for BigInt { + fn try_from_js(value: &JsValue, _context: &mut Context<'_>) -> JsResult { + match value { + JsValue::BigInt(b) => Ok(b.as_inner().clone()), + _ => Err(JsNativeError::typ() + .with_message("cannot convert value to a BigInt") + .into()), + } + } +} + +impl TryFromJs for JsValue { + fn try_from_js(value: &JsValue, _context: &mut Context<'_>) -> JsResult { + Ok(value.clone()) + } +} + +impl TryFromJs for f64 { + fn try_from_js(value: &JsValue, _context: &mut Context<'_>) -> JsResult { + match value { + JsValue::Integer(i) => Ok((*i).into()), + JsValue::Rational(r) => Ok(*r), + _ => Err(JsNativeError::typ() + .with_message("cannot convert value to a f64") + .into()), + } + } +} + +impl TryFromJs for i8 { + fn try_from_js(value: &JsValue, _context: &mut Context<'_>) -> JsResult { + match value { + JsValue::Integer(i) => (*i).try_into().map_err(|e| { + JsNativeError::typ() + .with_message(format!("cannot convert value to a i8: {e}")) + .into() + }), + _ => Err(JsNativeError::typ() + .with_message("cannot convert value to a i8") + .into()), + } + } +} + +impl TryFromJs for u8 { + fn try_from_js(value: &JsValue, _context: &mut Context<'_>) -> JsResult { + match value { + JsValue::Integer(i) => (*i).try_into().map_err(|e| { + JsNativeError::typ() + .with_message(format!("cannot convert value to a u8: {e}")) + .into() + }), + _ => Err(JsNativeError::typ() + .with_message("cannot convert value to a u8") + .into()), + } + } +} + +impl TryFromJs for i16 { + fn try_from_js(value: &JsValue, _context: &mut Context<'_>) -> JsResult { + match value { + JsValue::Integer(i) => (*i).try_into().map_err(|e| { + JsNativeError::typ() + .with_message(format!("cannot convert value to a i16: {e}")) + .into() + }), + _ => Err(JsNativeError::typ() + .with_message("cannot convert value to a i16") + .into()), + } + } +} + +impl TryFromJs for u16 { + fn try_from_js(value: &JsValue, _context: &mut Context<'_>) -> JsResult { + match value { + JsValue::Integer(i) => (*i).try_into().map_err(|e| { + JsNativeError::typ() + .with_message(format!("cannot convert value to a iu16: {e}")) + .into() + }), + _ => Err(JsNativeError::typ() + .with_message("cannot convert value to a u16") + .into()), + } + } +} + +impl TryFromJs for i32 { + fn try_from_js(value: &JsValue, _context: &mut Context<'_>) -> JsResult { + match value { + JsValue::Integer(i) => Ok(*i), + _ => Err(JsNativeError::typ() + .with_message("cannot convert value to a i32") + .into()), + } + } +} + +impl TryFromJs for u32 { + fn try_from_js(value: &JsValue, _context: &mut Context<'_>) -> JsResult { + match value { + JsValue::Integer(i) => (*i).try_into().map_err(|e| { + JsNativeError::typ() + .with_message(format!("cannot convert value to a u32: {e}")) + .into() + }), + _ => Err(JsNativeError::typ() + .with_message("cannot convert value to a u32") + .into()), + } + } +} + +impl TryFromJs for i64 { + fn try_from_js(value: &JsValue, _context: &mut Context<'_>) -> JsResult { + match value { + JsValue::Integer(i) => Ok((*i).into()), + _ => Err(JsNativeError::typ() + .with_message("cannot convert value to a i64") + .into()), + } + } +} + +impl TryFromJs for u64 { + fn try_from_js(value: &JsValue, _context: &mut Context<'_>) -> JsResult { + match value { + JsValue::Integer(i) => (*i).try_into().map_err(|e| { + JsNativeError::typ() + .with_message(format!("cannot convert value to a u64: {e}")) + .into() + }), + _ => Err(JsNativeError::typ() + .with_message("cannot convert value to a u64") + .into()), + } + } +} + +impl TryFromJs for i128 { + fn try_from_js(value: &JsValue, _context: &mut Context<'_>) -> JsResult { + match value { + JsValue::Integer(i) => Ok((*i).into()), + _ => Err(JsNativeError::typ() + .with_message("cannot convert value to a i128") + .into()), + } + } +} + +impl TryFromJs for u128 { + fn try_from_js(value: &JsValue, _context: &mut Context<'_>) -> JsResult { + match value { + JsValue::Integer(i) => (*i).try_into().map_err(|e| { + JsNativeError::typ() + .with_message(format!("cannot convert value to a u128: {e}")) + .into() + }), + _ => Err(JsNativeError::typ() + .with_message("cannot convert value to a u128") + .into()), + } + } +} diff --git a/boa_engine/src/value/mod.rs b/boa_engine/src/value/mod.rs index 2da1cdfee60..c27dedd30f8 100644 --- a/boa_engine/src/value/mod.rs +++ b/boa_engine/src/value/mod.rs @@ -3,15 +3,13 @@ //! Javascript values, utility methods and conversion between Javascript values and Rust values. mod conversions; +pub(crate) mod display; mod equality; mod hash; mod integer; mod operations; -mod serde_json; mod r#type; -pub(crate) mod display; - #[cfg(test)] mod tests; @@ -39,14 +37,15 @@ use std::{ ops::Sub, }; -pub(crate) use conversions::*; - -pub use display::ValueDisplay; -pub use integer::IntegerOrInfinity; -pub use operations::*; -pub use r#type::Type; +#[doc(inline)] +pub use self::{ + conversions::try_from_js::TryFromJs, display::ValueDisplay, integer::IntegerOrInfinity, + operations::*, r#type::Type, +}; +#[doc(inline)] +pub use boa_macros::TryFromJs; -pub(crate) use self::integer::IntegerOrNan; +pub(crate) use self::{conversions::IntoOrUndefined, integer::IntegerOrNan}; static TWO_E_64: Lazy = Lazy::new(|| { const TWO_E_64: u128 = 2u128.pow(64); diff --git a/boa_examples/Cargo.toml b/boa_examples/Cargo.toml index d754a321fb3..1b98b91630d 100644 --- a/boa_examples/Cargo.toml +++ b/boa_examples/Cargo.toml @@ -9,8 +9,6 @@ license.workspace = true repository.workspace = true rust-version.workspace = true -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] boa_engine = { workspace = true, features = ["console"] } boa_ast.workspace = true diff --git a/boa_examples/src/bin/derive.rs b/boa_examples/src/bin/derive.rs new file mode 100644 index 00000000000..298027dad97 --- /dev/null +++ b/boa_examples/src/bin/derive.rs @@ -0,0 +1,48 @@ +use boa_engine::{value::TryFromJs, Context, JsNativeError, JsResult, JsValue, Source}; + +/// You can easily derive `TryFromJs` for structures with base Rust types. +/// +/// By default, the conversion will only work if the type is directly representable by the Rust +/// type. +#[derive(Debug, TryFromJs)] +#[allow(dead_code)] +struct TestStruct { + inner: bool, + hello: String, + // You can override the conversion of an attribute. + #[boa(from_js_with = "lossy_conversion")] + my_float: i16, +} + +fn main() { + let js_str = r#" + let x = { + inner: false, + hello: "World", + my_float: 2.9, + }; + + x; + "#; + let js = Source::from_bytes(js_str); + + let mut context = Context::default(); + let res = context.eval_script(js).unwrap(); + + let str = TestStruct::try_from_js(&res, &mut context) + .map_err(|e| e.to_string()) + .unwrap(); + + println!("{str:?}"); +} + +/// Converts the value lossly +fn lossy_conversion(value: &JsValue, _context: &mut Context) -> JsResult { + match value { + JsValue::Rational(r) => Ok(r.round() as i16), + JsValue::Integer(i) => Ok(*i as i16), + _ => Err(JsNativeError::typ() + .with_message("cannot convert value to an i16") + .into()), + } +} diff --git a/boa_icu_provider/Cargo.toml b/boa_icu_provider/Cargo.toml index 49c670f181f..be32cb34c49 100644 --- a/boa_icu_provider/Cargo.toml +++ b/boa_icu_provider/Cargo.toml @@ -17,7 +17,7 @@ icu_provider = { version = "1.1.0", features = ["serde", "sync"] } icu_provider_blob = "1.1.0" icu_provider_adapters = { version = "1.1.0", features = ["serde"] } once_cell = {version = "1.17.1", default-features = false, features = ["critical-section"]} -icu_datagen = { version = "1.1.1", optional = true } +icu_datagen = { version = "1.1.2", optional = true } log = { version = "0.4.17", optional = true } simple_logger = { version = "4.1.0", optional = true } diff --git a/boa_macros/Cargo.toml b/boa_macros/Cargo.toml index cd7e4e0ad16..4a9a1fd9729 100644 --- a/boa_macros/Cargo.toml +++ b/boa_macros/Cargo.toml @@ -8,7 +8,6 @@ license.workspace = true repository.workspace = true rust-version.workspace = true - [lib] proc-macro = true @@ -17,3 +16,7 @@ quote = "1.0.26" syn = { version = "2.0.11", features = ["full"] } proc-macro2 = "1.0" synstructure = "0.13" + +[dev-dependencies] +trybuild = "1.0.80" +boa_engine.workspace = true diff --git a/boa_macros/src/lib.rs b/boa_macros/src/lib.rs index 090a98d47bc..b281cee7d5e 100644 --- a/boa_macros/src/lib.rs +++ b/boa_macros/src/lib.rs @@ -57,14 +57,18 @@ clippy::nursery, )] +#[cfg(test)] +use boa_engine as _; +#[cfg(test)] +use trybuild as _; + use proc_macro::TokenStream; -use proc_macro2::Ident; use quote::{quote, ToTokens}; use syn::{ parse::{Parse, ParseStream}, parse_macro_input, punctuated::Punctuated, - Expr, ExprLit, Lit, LitStr, Token, + Data, DeriveInput, Expr, ExprLit, Fields, FieldsNamed, Ident, Lit, LitStr, Token, }; use synstructure::{decl_derive, AddBounds, Structure}; @@ -182,10 +186,14 @@ pub fn static_syms(input: TokenStream) -> TokenStream { /// /// `COMMON_STRINGS_UTF8`, `COMMON_STRINGS_UTF16` and the constants /// defined in [`Sym`] must always be in sync. - // FIXME: use phf when const expressions are allowed. https://github.com/rust-phf/rust-phf/issues/188 + // FIXME: use phf when const expressions are allowed. + // pub(super) static COMMON_STRINGS_UTF16: ::once_cell::sync::Lazy> = ::once_cell::sync::Lazy::new(|| { - let mut set = Set::with_capacity_and_hasher(COMMON_STRINGS_UTF8.len(), ::core::hash::BuildHasherDefault::default()); + let mut set = Set::with_capacity_and_hasher( + COMMON_STRINGS_UTF8.len(), + ::core::hash::BuildHasherDefault::default() + ); #( set.insert(::boa_macros::utf16!(#literals)); )* @@ -216,10 +224,11 @@ pub fn utf16(input: TokenStream) -> TokenStream { decl_derive! { [Trace, attributes(unsafe_ignore_trace)] => - /// Derive the Trace trait. + /// Derive the `Trace` trait. derive_trace } +/// Derives the `Trace` trait. fn derive_trace(mut s: Structure<'_>) -> proc_macro2::TokenStream { s.filter(|bi| { !bi.ast() @@ -299,11 +308,142 @@ fn derive_trace(mut s: Structure<'_>) -> proc_macro2::TokenStream { decl_derive! { [Finalize] => - /// Derive the Finalize trait. + /// Derive the `Finalize` trait. derive_finalize } +/// Derives the `Finalize` trait. #[allow(clippy::needless_pass_by_value)] fn derive_finalize(s: Structure<'_>) -> proc_macro2::TokenStream { s.unbound_impl(quote!(::boa_gc::Finalize), quote!()) } + +/// Derives the `TryFromJs` trait, with the `#[boa()]` attribute. +/// +/// # Panics +/// +/// It will panic if the user tries to derive the `TryFromJs` trait in an `enum` or a tuple struct. +#[proc_macro_derive(TryFromJs, attributes(boa))] +pub fn derive_try_from_js(input: TokenStream) -> TokenStream { + // Parse the input tokens into a syntax tree + let input = parse_macro_input!(input as DeriveInput); + + let Data::Struct(data) = input.data else { + panic!("you can only derive TryFromJs for structs"); + }; + + let Fields::Named(fields) = data.fields else { + panic!("you can only derive TryFromJs for named-field structs") + }; + + let conv = generate_conversion(fields).unwrap_or_else(to_compile_errors); + + let type_name = input.ident; + + // Build the output, possibly using quasi-quotation + let expanded = quote! { + impl boa_engine::value::TryFromJs for #type_name { + fn try_from_js(value: &boa_engine::JsValue, context: &mut boa_engine::Context) + -> boa_engine::JsResult { + match value { + boa_engine::JsValue::Object(o) => {#conv}, + _ => Err(boa_engine::JsError::from( + boa_engine::JsNativeError::typ() + .with_message("cannot convert value to a #type_name") + )), + } + } + } + }; + + // Hand the output tokens back to the compiler + expanded.into() +} + +/// Generates the conversion field by field. +fn generate_conversion(fields: FieldsNamed) -> Result> { + use syn::spanned::Spanned; + + let mut field_list = Vec::with_capacity(fields.named.len()); + let mut final_fields = Vec::with_capacity(fields.named.len()); + + for field in fields.named { + let span = field.span(); + let name = field.ident.ok_or_else(|| { + vec![syn::Error::new( + span, + "you can only derive `TryFromJs` for named-field structs", + )] + })?; + + let name_str = format!("{name}"); + field_list.push(name.clone()); + + let error_str = format!("cannot get property {name_str} of value"); + + let mut from_js_with = None; + if let Some(attr) = field + .attrs + .into_iter() + .find(|attr| attr.path().is_ident("boa")) + { + attr.parse_nested_meta(|meta| { + if meta.path.is_ident("from_js_with") { + let value = meta.value()?; + from_js_with = Some(value.parse::()?); + Ok(()) + } else { + Err(meta.error( + "invalid syntax in the `#[boa()]` attribute. \ + Note that this attribute only accepts the following syntax: \ + `#[boa(from_js_with = \"fully::qualified::path\")]`", + )) + } + }) + .map_err(|err| vec![err])?; + } + + if let Some(method) = from_js_with { + let ident = Ident::new(&method.value(), method.span()); + final_fields.push(quote! { + let #name = #ident(props.get(&#name_str.into()).ok_or_else(|| { + boa_engine::JsError::from( + boa_engine::JsNativeError::typ().with_message(#error_str) + ) + })?.value().ok_or_else(|| { + boa_engine::JsError::from( + boa_engine::JsNativeError::typ().with_message(#error_str) + ) + })?, context)?; + }); + } else { + final_fields.push(quote! { + let #name = props.get(&#name_str.into()).ok_or_else(|| { + boa_engine::JsError::from( + boa_engine::JsNativeError::typ().with_message(#error_str) + ) + })?.value().ok_or_else(|| { + boa_engine::JsError::from( + boa_engine::JsNativeError::typ().with_message(#error_str) + ) + })?.clone().try_js_into(context)?; + }); + } + } + + Ok(quote! { + let o = o.borrow(); + let props = o.properties(); + #(#final_fields)* + Ok(Self { + #(#field_list),* + }) + }) +} + +/// Generates a list of compile errors. +#[allow(clippy::needless_pass_by_value)] +fn to_compile_errors(errors: Vec) -> proc_macro2::TokenStream { + let compile_errors = errors.iter().map(syn::Error::to_compile_error); + quote!(#(#compile_errors)*) +} diff --git a/boa_macros/tests/derive/from_js_with.rs b/boa_macros/tests/derive/from_js_with.rs new file mode 100644 index 00000000000..a40bba62a6a --- /dev/null +++ b/boa_macros/tests/derive/from_js_with.rs @@ -0,0 +1,20 @@ +use boa_engine::{value::TryFromJs, Context, JsNativeError, JsResult, JsValue}; + +#[derive(TryFromJs)] +struct TestStruct { + inner: bool, + #[boa(from_js_with = "lossy_float")] + my_int: i16, +} + +fn main() {} + +fn lossy_float(value: &JsValue, _context: &mut Context) -> JsResult { + match value { + JsValue::Rational(r) => Ok(r.round() as i16), + JsValue::Integer(i) => Ok(*i as i16), + _ => Err(JsNativeError::typ() + .with_message("cannot convert value to an i16") + .into()), + } +} diff --git a/boa_macros/tests/derive/simple_struct.rs b/boa_macros/tests/derive/simple_struct.rs new file mode 100644 index 00000000000..f9ea0c97b23 --- /dev/null +++ b/boa_macros/tests/derive/simple_struct.rs @@ -0,0 +1,8 @@ +use boa_engine::value::TryFromJs; + +#[derive(TryFromJs)] +struct TestStruct { + inner: bool, +} + +fn main() {} diff --git a/boa_macros/tests/utf16.rs b/boa_macros/tests/tests.rs similarity index 68% rename from boa_macros/tests/utf16.rs rename to boa_macros/tests/tests.rs index c3ece6489b1..323d1a256ed 100644 --- a/boa_macros/tests/utf16.rs +++ b/boa_macros/tests/tests.rs @@ -13,3 +13,10 @@ fn utf16() { let manual = "hello!😁😁😁".encode_utf16().collect::>(); assert_eq!(manual, utf16); } + +#[test] +fn try_from_js() { + let t = trybuild::TestCases::new(); + t.pass("tests/derive/simple_struct.rs"); + t.pass("tests/derive/from_js_with.rs"); +} From 7845ba2a49f1a631b22880cd68dec58013673619 Mon Sep 17 00:00:00 2001 From: jedel1043 Date: Thu, 30 Mar 2023 10:29:14 -0600 Subject: [PATCH 2/9] Skip caching targets --- .github/workflows/rust.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 27fe2d8d892..535ade16051 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -24,6 +24,7 @@ jobs: profile: minimal - uses: Swatinem/rust-cache@v2 with: + cache-targets: false key: tarpaulin - name: Run cargo-tarpaulin uses: actions-rs/tarpaulin@v0.1 From c963bcfd773afd840b98d67c53935a76a8b7ca70 Mon Sep 17 00:00:00 2001 From: jedel1043 Date: Thu, 30 Mar 2023 10:45:20 -0600 Subject: [PATCH 3/9] Reenable `target` cache --- .github/workflows/rust.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 535ade16051..27fe2d8d892 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -24,7 +24,6 @@ jobs: profile: minimal - uses: Swatinem/rust-cache@v2 with: - cache-targets: false key: tarpaulin - name: Run cargo-tarpaulin uses: actions-rs/tarpaulin@v0.1 From e2363f3f154384e5d14264d51b657667e8e7bb06 Mon Sep 17 00:00:00 2001 From: jedel1043 Date: Thu, 30 Mar 2023 11:03:43 -0600 Subject: [PATCH 4/9] Workaround tarpaulin error --- boa_cli/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boa_cli/src/main.rs b/boa_cli/src/main.rs index 640216545bc..d6b1064e035 100644 --- a/boa_cli/src/main.rs +++ b/boa_cli/src/main.rs @@ -201,7 +201,7 @@ fn parse_tokens(src: &S, context: &mut Context<'_>) -> Result + ?Sized, { - boa_parser::Parser::new(Source::from_bytes(&src)) + boa_parser::Parser::new(boa_parser::Source::from_bytes(&src)) .parse_script(context.interner_mut()) .map_err(|e| format!("Uncaught SyntaxError: {e}")) } From ae50286979d060c6c8496521c6ba63e1716397ff Mon Sep 17 00:00:00 2001 From: jedel1043 Date: Thu, 30 Mar 2023 11:19:59 -0600 Subject: [PATCH 5/9] Temporarily disable cache --- .github/workflows/rust.yml | 6 +++--- boa_cli/src/main.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 27fe2d8d892..02039e1645c 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -22,9 +22,9 @@ jobs: toolchain: stable override: true profile: minimal - - uses: Swatinem/rust-cache@v2 - with: - key: tarpaulin + # - uses: Swatinem/rust-cache@v2 + # with: + # key: tarpaulin - name: Run cargo-tarpaulin uses: actions-rs/tarpaulin@v0.1 with: diff --git a/boa_cli/src/main.rs b/boa_cli/src/main.rs index d6b1064e035..640216545bc 100644 --- a/boa_cli/src/main.rs +++ b/boa_cli/src/main.rs @@ -201,7 +201,7 @@ fn parse_tokens(src: &S, context: &mut Context<'_>) -> Result + ?Sized, { - boa_parser::Parser::new(boa_parser::Source::from_bytes(&src)) + boa_parser::Parser::new(Source::from_bytes(&src)) .parse_script(context.interner_mut()) .map_err(|e| format!("Uncaught SyntaxError: {e}")) } From 4d2b8249264000c06f4438c0dbfe97f6370a54f8 Mon Sep 17 00:00:00 2001 From: jedel1043 Date: Thu, 30 Mar 2023 12:00:44 -0600 Subject: [PATCH 6/9] Remove dependency to tarpaulin action --- .github/workflows/rust.yml | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 02039e1645c..e8611d21e44 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -22,14 +22,18 @@ jobs: toolchain: stable override: true profile: minimal - # - uses: Swatinem/rust-cache@v2 - # with: - # key: tarpaulin - - name: Run cargo-tarpaulin - uses: actions-rs/tarpaulin@v0.1 + - uses: actions-rs/install@v0.1 with: - version: 0.22.0 - args: --features intl --ignore-tests --engine llvm + crate: cargo-tarpaulin + version: latest + - uses: Swatinem/rust-cache@v2 + with: + key: tarpaulin + - name: Run tarpaulin + uses: actions-rs/cargo@v1 + with: + command: tarpaulin + args: --workspace --features intl --ignore-tests --engine llvm --out Xml - name: Upload to codecov.io uses: codecov/codecov-action@v3 From dd293d7dd947feaed48de0ce9f404cc7d4866812 Mon Sep 17 00:00:00 2001 From: jedel1043 Date: Thu, 30 Mar 2023 12:38:02 -0600 Subject: [PATCH 7/9] Disable macro tests --- Cargo.lock | 26 -------------------------- boa_macros/Cargo.toml | 6 +++--- boa_macros/src/lib.rs | 8 ++++---- boa_macros/tests/tests.rs | 12 ++++++------ 4 files changed, 13 insertions(+), 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dd675509434..7f70f1a995f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -291,15 +291,6 @@ version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" -[[package]] -name = "basic-toml" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c0de75129aa8d0cceaf750b89013f0e08804d6ec61416da787b35ad0d7cddf1" -dependencies = [ - "serde", -] - [[package]] name = "bincode" version = "1.3.3" @@ -482,12 +473,10 @@ dependencies = [ name = "boa_macros" version = "0.16.0" dependencies = [ - "boa_engine", "proc-macro2", "quote", "syn 2.0.11", "synstructure 0.13.0", - "trybuild", ] [[package]] @@ -4398,21 +4387,6 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" -[[package]] -name = "trybuild" -version = "1.0.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501dbdbb99861e4ab6b60eb6a7493956a9defb644fd034bc4a5ef27c693c8a3a" -dependencies = [ - "basic-toml", - "glob", - "once_cell", - "serde", - "serde_derive", - "serde_json", - "termcolor", -] - [[package]] name = "typenum" version = "1.16.0" diff --git a/boa_macros/Cargo.toml b/boa_macros/Cargo.toml index 4a9a1fd9729..313d7b9b450 100644 --- a/boa_macros/Cargo.toml +++ b/boa_macros/Cargo.toml @@ -17,6 +17,6 @@ syn = { version = "2.0.11", features = ["full"] } proc-macro2 = "1.0" synstructure = "0.13" -[dev-dependencies] -trybuild = "1.0.80" -boa_engine.workspace = true +# [dev-dependencies] +# trybuild = "1.0.80" +# boa_engine.workspace = true diff --git a/boa_macros/src/lib.rs b/boa_macros/src/lib.rs index b281cee7d5e..c8a630fff24 100644 --- a/boa_macros/src/lib.rs +++ b/boa_macros/src/lib.rs @@ -57,10 +57,10 @@ clippy::nursery, )] -#[cfg(test)] -use boa_engine as _; -#[cfg(test)] -use trybuild as _; +// #[cfg(test)] +// use boa_engine as _; +// #[cfg(test)] +// use trybuild as _; use proc_macro::TokenStream; use quote::{quote, ToTokens}; diff --git a/boa_macros/tests/tests.rs b/boa_macros/tests/tests.rs index 323d1a256ed..ec92cf338c3 100644 --- a/boa_macros/tests/tests.rs +++ b/boa_macros/tests/tests.rs @@ -14,9 +14,9 @@ fn utf16() { assert_eq!(manual, utf16); } -#[test] -fn try_from_js() { - let t = trybuild::TestCases::new(); - t.pass("tests/derive/simple_struct.rs"); - t.pass("tests/derive/from_js_with.rs"); -} +// #[test] +// fn try_from_js() { +// let t = trybuild::TestCases::new(); +// t.pass("tests/derive/simple_struct.rs"); +// t.pass("tests/derive/from_js_with.rs"); +// } From 32d17fe55bce8d8eabe70f75a2aad6fac1d0750b Mon Sep 17 00:00:00 2001 From: Iban Eguia Moraza Date: Thu, 30 Mar 2023 21:52:08 +0200 Subject: [PATCH 8/9] Added the boa_macros_tests crate --- Cargo.lock | 33 +++++++++++++++++++ Cargo.toml | 11 ++++--- boa_macros/Cargo.toml | 4 --- boa_macros/src/lib.rs | 5 --- boa_macros/tests/tests.rs | 7 ---- boa_macros_tests/Cargo.toml | 16 +++++++++ .../tests/derive/from_js_with.rs | 0 .../tests/derive/simple_struct.rs | 0 boa_macros_tests/tests/tests.rs | 6 ++++ 9 files changed, 61 insertions(+), 21 deletions(-) create mode 100644 boa_macros_tests/Cargo.toml rename {boa_macros => boa_macros_tests}/tests/derive/from_js_with.rs (100%) rename {boa_macros => boa_macros_tests}/tests/derive/simple_struct.rs (100%) create mode 100644 boa_macros_tests/tests/tests.rs diff --git a/Cargo.lock b/Cargo.lock index 7f70f1a995f..fb46210f294 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -291,6 +291,15 @@ version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" +[[package]] +name = "basic-toml" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c0de75129aa8d0cceaf750b89013f0e08804d6ec61416da787b35ad0d7cddf1" +dependencies = [ + "serde", +] + [[package]] name = "bincode" version = "1.3.3" @@ -479,6 +488,15 @@ dependencies = [ "synstructure 0.13.0", ] +[[package]] +name = "boa_macros_tests" +version = "0.16.0" +dependencies = [ + "boa_engine", + "boa_macros", + "trybuild", +] + [[package]] name = "boa_parser" version = "0.16.0" @@ -4387,6 +4405,21 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +[[package]] +name = "trybuild" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501dbdbb99861e4ab6b60eb6a7493956a9defb644fd034bc4a5ef27c693c8a3a" +dependencies = [ + "basic-toml", + "glob", + "once_cell", + "serde", + "serde_derive", + "serde_json", + "termcolor", +] + [[package]] name = "typenum" version = "1.16.0" diff --git a/Cargo.toml b/Cargo.toml index 0af692a1c1e..cad08fa89b6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,18 +1,19 @@ [workspace] members = [ + "boa_ast", "boa_cli", "boa_engine", - "boa_ast", - "boa_parser", + "boa_examples", "boa_gc", + "boa_icu_provider", "boa_interner", + "boa_macros", + "boa_macros_tests", + "boa_parser", "boa_profiler", "boa_tester", "boa_unicode", "boa_wasm", - "boa_examples", - "boa_macros", - "boa_icu_provider", ] [workspace.package] diff --git a/boa_macros/Cargo.toml b/boa_macros/Cargo.toml index 313d7b9b450..5a8aea0f920 100644 --- a/boa_macros/Cargo.toml +++ b/boa_macros/Cargo.toml @@ -16,7 +16,3 @@ quote = "1.0.26" syn = { version = "2.0.11", features = ["full"] } proc-macro2 = "1.0" synstructure = "0.13" - -# [dev-dependencies] -# trybuild = "1.0.80" -# boa_engine.workspace = true diff --git a/boa_macros/src/lib.rs b/boa_macros/src/lib.rs index c8a630fff24..80c2985e05c 100644 --- a/boa_macros/src/lib.rs +++ b/boa_macros/src/lib.rs @@ -57,11 +57,6 @@ clippy::nursery, )] -// #[cfg(test)] -// use boa_engine as _; -// #[cfg(test)] -// use trybuild as _; - use proc_macro::TokenStream; use quote::{quote, ToTokens}; use syn::{ diff --git a/boa_macros/tests/tests.rs b/boa_macros/tests/tests.rs index ec92cf338c3..c3ece6489b1 100644 --- a/boa_macros/tests/tests.rs +++ b/boa_macros/tests/tests.rs @@ -13,10 +13,3 @@ fn utf16() { let manual = "hello!😁😁😁".encode_utf16().collect::>(); assert_eq!(manual, utf16); } - -// #[test] -// fn try_from_js() { -// let t = trybuild::TestCases::new(); -// t.pass("tests/derive/simple_struct.rs"); -// t.pass("tests/derive/from_js_with.rs"); -// } diff --git a/boa_macros_tests/Cargo.toml b/boa_macros_tests/Cargo.toml new file mode 100644 index 00000000000..59105f6f584 --- /dev/null +++ b/boa_macros_tests/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "boa_macros_tests" +description = "Testing crate for boa_macros" +keywords = ["javascript", "ECMASCript", "compiler", "tester"] +publish = false +version.workspace = true +edition.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true +rust-version.workspace = true + +[dev-dependencies] +trybuild = "1.0.80" +boa_macros.workspace = true +boa_engine.workspace = true \ No newline at end of file diff --git a/boa_macros/tests/derive/from_js_with.rs b/boa_macros_tests/tests/derive/from_js_with.rs similarity index 100% rename from boa_macros/tests/derive/from_js_with.rs rename to boa_macros_tests/tests/derive/from_js_with.rs diff --git a/boa_macros/tests/derive/simple_struct.rs b/boa_macros_tests/tests/derive/simple_struct.rs similarity index 100% rename from boa_macros/tests/derive/simple_struct.rs rename to boa_macros_tests/tests/derive/simple_struct.rs diff --git a/boa_macros_tests/tests/tests.rs b/boa_macros_tests/tests/tests.rs new file mode 100644 index 00000000000..16de9065e06 --- /dev/null +++ b/boa_macros_tests/tests/tests.rs @@ -0,0 +1,6 @@ +#[test] +fn try_from_js() { + let t = trybuild::TestCases::new(); + t.pass("tests/derive/simple_struct.rs"); + t.pass("tests/derive/from_js_with.rs"); +} From 5bff2ff08e8b0ee89d7cf9e9e8cbc1bf0e0102ca Mon Sep 17 00:00:00 2001 From: Iban Eguia Moraza Date: Thu, 30 Mar 2023 22:15:12 +0200 Subject: [PATCH 9/9] Added missing newline --- boa_macros_tests/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boa_macros_tests/Cargo.toml b/boa_macros_tests/Cargo.toml index 59105f6f584..faf70997936 100644 --- a/boa_macros_tests/Cargo.toml +++ b/boa_macros_tests/Cargo.toml @@ -13,4 +13,4 @@ rust-version.workspace = true [dev-dependencies] trybuild = "1.0.80" boa_macros.workspace = true -boa_engine.workspace = true \ No newline at end of file +boa_engine.workspace = true