diff --git a/Cargo.lock b/Cargo.lock index aec7f8e..5fa5b59 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,9 +14,9 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.24.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] @@ -82,6 +82,15 @@ dependencies = [ "libc", ] +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + [[package]] name = "anstream" version = "0.6.15" @@ -155,7 +164,7 @@ dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -178,14 +187,14 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" @@ -225,9 +234,9 @@ dependencies = [ [[package]] name = "better_scoped_tls" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "794edcc9b3fb07bb4aecaa11f093fd45663b4feadb782d68303a2268bc2701de" +checksum = "297b153aa5e573b5863108a6ddc9d5c968bd0b20e75cc614ee9821d2f45679c7" dependencies = [ "scoped-tls", ] @@ -283,7 +292,7 @@ dependencies = [ "ahash 0.8.11", "chrono", "either", - "indexmap 2.5.0", + "indexmap 2.6.0", "itertools 0.13.0", "nom", "once_cell", @@ -307,6 +316,9 @@ name = "bumpalo" version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +dependencies = [ + "allocator-api2", +] [[package]] name = "bytecheck" @@ -360,9 +372,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "camino" @@ -398,9 +410,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.19" +version = "1.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d74707dde2ba56f86ae90effb3b43ddd369504387e718014de010cec7959800" +checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945" dependencies = [ "shlex", ] @@ -425,9 +437,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.17" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", "clap_derive", @@ -435,9 +447,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.17" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstream", "anstyle", @@ -447,14 +459,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.13" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -554,6 +566,18 @@ dependencies = [ "typenum", ] +[[package]] +name = "css_dataset" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0ed4c49b3d82ab5e2a0167f0d24d30872cbd8526b54fb060c84295ad7b6d71d" +dependencies = [ + "phf 0.11.2", + "phf_codegen", + "serde", + "serde_json", +] + [[package]] name = "csv" version = "1.3.0" @@ -623,6 +647,18 @@ dependencies = [ "powerfmt", ] +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + +[[package]] +name = "difference" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" + [[package]] name = "digest" version = "0.10.7" @@ -676,7 +712,7 @@ checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -867,6 +903,18 @@ dependencies = [ "farmfe_toolkit_plugin_types", ] +[[package]] +name = "farmfe_plugin_vue_jsx" +version = "0.0.0" +dependencies = [ + "farmfe_core", + "farmfe_macro_plugin", + "farmfe_toolkit", + "farmfe_toolkit_plugin_types", + "serde", + "vue_jsx_visitor", +] + [[package]] name = "farmfe_plugin_yaml" version = "0.0.1" @@ -919,7 +967,7 @@ dependencies = [ "swc_ecma_transforms_base 0.140.3", "swc_ecma_utils 0.130.3", "swc_ecma_visit 0.101.0", - "swc_error_reporters", + "swc_error_reporters 0.18.1", "swc_html_codegen", "swc_html_minifier", "swc_html_parser 0.40.0", @@ -1051,6 +1099,12 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3ea1ec5f8307826a5b71094dd91fc04d4ae75d5709b20ad351c7fb4815c86ec" +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -1068,7 +1122,7 @@ checksum = "32016f1242eb82af5474752d00fd8ebcd9004bd69b462b1c91de833972d08ed4" dependencies = [ "proc-macro2", "swc_macros_common", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -1116,7 +1170,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -1127,14 +1181,14 @@ checksum = "b0e085ded9f1267c32176b40921b9754c474f7dd96f7e808d4a982e48aa1e854" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] name = "gimli" -version = "0.31.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "glob" @@ -1151,8 +1205,8 @@ dependencies = [ "aho-corasick", "bstr", "log", - "regex-automata", - "regex-syntax", + "regex-automata 0.4.8", + "regex-syntax 0.8.5", ] [[package]] @@ -1174,6 +1228,12 @@ dependencies = [ "allocator-api2", ] +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" + [[package]] name = "heck" version = "0.4.1" @@ -1263,12 +1323,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.15.0", "serde", ] @@ -1316,7 +1376,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -1351,9 +1411,9 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" -version = "0.3.70" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" dependencies = [ "wasm-bindgen", ] @@ -1439,9 +1499,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.158" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "libloading" @@ -1489,13 +1549,22 @@ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "markdown" -version = "1.0.0-alpha.20" +version = "1.0.0-alpha.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "911a8325e6fb87b89890cd4529a2ab34c2669c026279e61c26b7140a3d821ccb" +checksum = "a6491e6c702bf7e3b24e769d800746d5f2c06a6c6a2db7992612e0f429029e81" dependencies = [ "unicode-id", ] +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + [[package]] name = "mdxjs" version = "0.2.5" @@ -1547,7 +1616,7 @@ checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -1558,7 +1627,7 @@ checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -1629,6 +1698,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-bigint" version = "0.4.6" @@ -1676,18 +1755,18 @@ dependencies = [ [[package]] name = "object" -version = "0.36.4" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "outref" @@ -1695,6 +1774,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f222829ae9293e33a9f5e9f440c6760a3d450a64affe1846486b140db81c1f4" +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "owo-colors" version = "4.1.0" @@ -1735,9 +1820,9 @@ checksum = "ecba01bf2678719532c5e3059e0b5f0811273d94b397088b82e3bd0a78c78fdd" [[package]] name = "pathdiff" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" +checksum = "d61c5ce1153ab5b689d0c074c4e7fc613e942dfb7dd9eea5ab202d2ad91fe361" [[package]] name = "percent-encoding" @@ -1752,7 +1837,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.5.0", + "indexmap 2.6.0", ] [[package]] @@ -1776,6 +1861,16 @@ dependencies = [ "phf_shared 0.11.2", ] +[[package]] +name = "phf_codegen" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" +dependencies = [ + "phf_generator 0.11.2", + "phf_shared 0.11.2", +] + [[package]] name = "phf_generator" version = "0.10.0" @@ -1820,7 +1915,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -1906,6 +2001,16 @@ dependencies = [ "tracing", ] +[[package]] +name = "pretty_assertions" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" +dependencies = [ + "diff", + "yansi", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -1949,7 +2054,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -1960,9 +2065,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" dependencies = [ "unicode-ident", ] @@ -2069,41 +2174,56 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.4" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ "bitflags 2.6.0", ] [[package]] name = "regex" -version = "1.10.6" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", - "regex-automata", - "regex-syntax", + "regex-automata 0.4.8", + "regex-syntax 0.8.5", ] [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.8.5", ] [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "regress" @@ -2311,7 +2431,7 @@ checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -2320,7 +2440,7 @@ version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ - "indexmap 2.5.0", + "indexmap 2.6.0", "itoa", "memchr", "ryu", @@ -2333,7 +2453,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.5.0", + "indexmap 2.6.0", "itoa", "ryu", "serde", @@ -2362,6 +2482,15 @@ dependencies = [ "digest", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shlex" version = "1.3.0" @@ -2388,9 +2517,9 @@ dependencies = [ [[package]] name = "simdutf8" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] name = "siphasher" @@ -2522,7 +2651,7 @@ checksum = "710e9696ef338691287aeb937ee6ffe60022f579d3c8d2fd9d58973a9a10a466" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -2566,7 +2695,7 @@ dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -2596,6 +2725,19 @@ dependencies = [ "swc_xml", ] +[[package]] +name = "swc_allocator" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76aa0eb65c0f39f9b6d82a7e5192c30f7ac9a78f084a21f270de1d8c600ca388" +dependencies = [ + "bumpalo", + "hashbrown 0.14.5", + "ptr_meta", + "rustc-hash", + "triomphe", +] + [[package]] name = "swc_atoms" version = "0.4.43" @@ -2691,7 +2833,7 @@ dependencies = [ "string_cache", "swc_atoms 0.4.43", "swc_eq_ignore_macros", - "swc_visit", + "swc_visit 0.5.14", "tracing", "unicode-width", "url", @@ -2717,7 +2859,7 @@ dependencies = [ "sourcemap 8.0.1", "swc_atoms 0.6.7", "swc_eq_ignore_macros", - "swc_visit", + "swc_visit 0.5.14", "tracing", "unicode-width", "url", @@ -2746,7 +2888,35 @@ dependencies = [ "sourcemap 8.0.1", "swc_atoms 0.6.7", "swc_eq_ignore_macros", - "swc_visit", + "swc_visit 0.5.14", + "tracing", + "unicode-width", + "url", +] + +[[package]] +name = "swc_common" +version = "0.36.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "457fb92efa9f0c849d6bc4e86561982d464176bc3df96bb22baed5e98309e090" +dependencies = [ + "ast_node", + "better_scoped_tls", + "cfg-if", + "either", + "from_variant", + "new_debug_unreachable", + "num-bigint", + "once_cell", + "parking_lot", + "rustc-hash", + "serde", + "siphasher", + "swc_allocator", + "swc_atoms 0.6.7", + "swc_eq_ignore_macros", + "swc_visit 0.6.2", + "termcolor", "tracing", "unicode-width", "url", @@ -2759,7 +2929,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4740e53eaf68b101203c1df0937d5161a29f3c13bceed0836ddfe245b72dd000" dependencies = [ "anyhow", - "indexmap 2.5.0", + "indexmap 2.6.0", "serde", "serde_json", "sourcemap 9.0.0", @@ -2776,7 +2946,7 @@ dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -2895,7 +3065,7 @@ dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -3011,7 +3181,7 @@ dependencies = [ "swc_atoms 0.6.7", "swc_common 0.33.26", "swc_css_ast 0.140.23", - "swc_visit", + "swc_visit 0.5.14", ] [[package]] @@ -3024,7 +3194,7 @@ dependencies = [ "swc_atoms 0.6.7", "swc_common 0.34.4", "swc_css_ast 0.141.0", - "swc_visit", + "swc_visit 0.5.14", ] [[package]] @@ -3147,7 +3317,7 @@ dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -3187,7 +3357,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d23a9a192078d1d074113d77d8ad811f2a81a4447ae967739824da5d391616bf" dependencies = [ "arrayvec", - "indexmap 2.5.0", + "indexmap 2.6.0", "is-macro 0.3.6", "serde", "serde_derive", @@ -3384,7 +3554,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adde00302d7ddb37f312ee6d07078c7f3c7ede36c0f81c5050bae1d4c3fe501c" dependencies = [ "arrayvec", - "indexmap 2.5.0", + "indexmap 2.6.0", "num-bigint", "num_cpus", "once_cell", @@ -3483,7 +3653,7 @@ checksum = "9cd4847a3356a01bb9a73ccdd1c462dfdaed66d27d7ea6d6785ee1b54c9556ce" dependencies = [ "anyhow", "dashmap", - "indexmap 2.5.0", + "indexmap 2.6.0", "once_cell", "preset_env_base", "rustc-hash", @@ -3551,7 +3721,7 @@ checksum = "660badfe2eed8b6213ec9dcd71aa0786f8fb46ffa012e0313bcba1fe4a9a5c73" dependencies = [ "better_scoped_tls", "bitflags 2.6.0", - "indexmap 2.5.0", + "indexmap 2.6.0", "once_cell", "phf 0.11.2", "rustc-hash", @@ -3574,7 +3744,7 @@ checksum = "d37dc505c92af56d0f77cf6f31a6ccd37ac40cad1e01ff77277e0b1c70e8f8ff" dependencies = [ "better_scoped_tls", "bitflags 2.6.0", - "indexmap 2.5.0", + "indexmap 2.6.0", "once_cell", "phf 0.11.2", "rayon", @@ -3611,7 +3781,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "626198f214d4c09adc98ab14565c19d72b6df9630f7e806ef9b2ef05a5fd17a5" dependencies = [ "arrayvec", - "indexmap 2.5.0", + "indexmap 2.6.0", "is-macro 0.3.6", "num-bigint", "rayon", @@ -3650,7 +3820,7 @@ dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -3662,7 +3832,7 @@ dependencies = [ "Inflector", "anyhow", "bitflags 2.6.0", - "indexmap 2.5.0", + "indexmap 2.6.0", "is-macro 0.3.6", "path-clean", "pathdiff", @@ -3712,7 +3882,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "724a8306e98c1b1f9640fc44c1acc0c971f6daa17651919e06b64f905d4a4564" dependencies = [ "dashmap", - "indexmap 2.5.0", + "indexmap 2.6.0", "once_cell", "petgraph", "rayon", @@ -3758,7 +3928,7 @@ checksum = "446da32cac8299973aaf1d37496562bfd0c1e4f3c3ab5d0af6f07f42e8184102" dependencies = [ "base64 0.21.7", "dashmap", - "indexmap 2.5.0", + "indexmap 2.6.0", "once_cell", "rayon", "serde", @@ -3798,7 +3968,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "146562ac3515c8de0fa9d479c43ae673cf9df9ece814f8b8130686080a7251ac" dependencies = [ - "indexmap 2.5.0", + "indexmap 2.6.0", "rustc-hash", "swc_atoms 0.6.7", "swc_common 0.34.4", @@ -3833,7 +4003,7 @@ version = "0.127.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15d40abfc4f3a7bfdf54d11ac705cc9dd0836c48bf085b359143b4d40b50cb31" dependencies = [ - "indexmap 2.5.0", + "indexmap 2.6.0", "num_cpus", "once_cell", "rustc-hash", @@ -3851,7 +4021,7 @@ version = "0.130.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13e62b199454a576c5fdbd7e1bef8ab88a395427456d8a713d994b7d469833aa" dependencies = [ - "indexmap 2.5.0", + "indexmap 2.6.0", "num_cpus", "once_cell", "rayon", @@ -3875,7 +4045,7 @@ dependencies = [ "swc_atoms 0.4.43", "swc_common 0.30.5", "swc_ecma_ast 0.102.5", - "swc_visit", + "swc_visit 0.5.14", "tracing", ] @@ -3889,7 +4059,7 @@ dependencies = [ "swc_atoms 0.6.7", "swc_common 0.33.26", "swc_ecma_ast 0.112.6", - "swc_visit", + "swc_visit 0.5.14", "tracing", ] @@ -3903,7 +4073,7 @@ dependencies = [ "swc_atoms 0.6.7", "swc_common 0.34.4", "swc_ecma_ast 0.115.1", - "swc_visit", + "swc_visit 0.5.14", "tracing", ] @@ -3915,7 +4085,7 @@ checksum = "63db0adcff29d220c3d151c5b25c0eabe7e32dd936212b84cdaa1392e3130497" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -3931,6 +4101,19 @@ dependencies = [ "swc_common 0.34.4", ] +[[package]] +name = "swc_error_reporters" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e02c81943772dc4fb0a6228360552d353fedc1a368ee6d80a5172ecb376b1796" +dependencies = [ + "anyhow", + "miette 7.2.0", + "once_cell", + "parking_lot", + "swc_common 0.36.3", +] + [[package]] name = "swc_fast_graph" version = "0.18.5" @@ -3949,7 +4132,7 @@ version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c00cf5c1687e9858fb9de1ffa90a3e21369095406e97ace870a389320d105b0a" dependencies = [ - "indexmap 2.5.0", + "indexmap 2.6.0", "petgraph", "rustc-hash", "swc_common 0.34.4", @@ -4018,7 +4201,7 @@ dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -4110,18 +4293,18 @@ dependencies = [ "swc_atoms 0.6.7", "swc_common 0.34.4", "swc_html_ast 0.34.0", - "swc_visit", + "swc_visit 0.5.14", ] [[package]] name = "swc_macros_common" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f486687bfb7b5c560868f69ed2d458b880cebc9babebcb67e49f31b55c5bf847" +checksum = "27e18fbfe83811ffae2bb23727e45829a0d19c6870bced7c0f545cc99ad248dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -4141,7 +4324,7 @@ checksum = "ff9719b6085dd2824fd61938a881937be14b08f95e2d27c64c825a9f65e052ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -4154,6 +4337,16 @@ dependencies = [ "swc_visit_macros", ] +[[package]] +name = "swc_visit" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ceb044142ba2719ef9eb3b6b454fce61ab849eb696c34d190f04651955c613d" +dependencies = [ + "either", + "new_debug_unreachable", +] + [[package]] name = "swc_visit_macros" version = "0.5.13" @@ -4164,7 +4357,7 @@ dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -4215,7 +4408,7 @@ dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -4238,7 +4431,7 @@ dependencies = [ "serde", "swc_atoms 0.4.43", "swc_common 0.30.5", - "swc_visit", + "swc_visit 0.5.14", "swc_xml_ast", ] @@ -4255,9 +4448,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.77" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", @@ -4280,6 +4473,52 @@ dependencies = [ "vec1", ] +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "testing" +version = "0.38.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dda7450d6e429db582ca8a2cf698f3bc63bc04dae8d857936e810180e510c86" +dependencies = [ + "ansi_term", + "cargo_metadata", + "difference", + "once_cell", + "pretty_assertions", + "regex", + "serde", + "serde_json", + "swc_common 0.36.3", + "swc_error_reporters 0.20.0", + "testing_macros", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "testing_macros" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a39660370116afe46d5ff8bcb01b7afe2140dda3137ef5cb1914681e37a4ee06" +dependencies = [ + "anyhow", + "glob", + "once_cell", + "proc-macro2", + "quote", + "regex", + "relative-path", + "syn 2.0.79", +] + [[package]] name = "textwrap" version = "0.16.1" @@ -4293,22 +4532,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -4321,6 +4560,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + [[package]] name = "time" version = "0.3.36" @@ -4393,7 +4642,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -4415,7 +4664,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -4425,13 +4674,43 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", ] [[package]] name = "triomphe" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6631e42e10b40c0690bf92f404ebcfe6e1fdb480391d15f17cc8e96eeed5369" +checksum = "ef8f7726da4807b58ea5c96fdc122f80702030edc33b35aff9190a51148ccc85" dependencies = [ "serde", "stable_deref_trait", @@ -4460,15 +4739,15 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.15" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" [[package]] name = "unicode-id" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1b6def86329695390197b82c1e244a54a131ceb66c996f2088a3876e2ae083f" +checksum = "10103c57044730945224467c09f71a4db0071c123a0648cc3e818913bde6b561" [[package]] name = "unicode-id-start" @@ -4490,24 +4769,24 @@ checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] [[package]] name = "unicode-width" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode-xid" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "unsafe-libyaml" @@ -4538,6 +4817,12 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "vec1" version = "1.12.1" @@ -4577,6 +4862,22 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "vue_jsx_visitor" +version = "0.3.2" +dependencies = [ + "bitflags 2.6.0", + "css_dataset", + "farmfe_core", + "farmfe_toolkit", + "fnv", + "indexmap 2.6.0", + "regex", + "serde", + "serde_json", + "testing", +] + [[package]] name = "walkdir" version = "2.5.0" @@ -4595,9 +4896,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" dependencies = [ "cfg-if", "once_cell", @@ -4606,24 +4907,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4631,22 +4932,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" [[package]] name = "wax" @@ -4811,6 +5112,12 @@ dependencies = [ "xml-rs", ] +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + [[package]] name = "zerocopy" version = "0.7.35" @@ -4829,5 +5136,5 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] diff --git a/rust-plugins/vue-jsx/.gitignore b/rust-plugins/vue-jsx/.gitignore new file mode 100644 index 0000000..50e4f22 --- /dev/null +++ b/rust-plugins/vue-jsx/.gitignore @@ -0,0 +1,197 @@ +# Created by https://www.toptal.com/developers/gitignore/api/node +# Edit at https://www.toptal.com/developers/gitignore?templates=node + +### Node ### +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.test + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# Next.js build output +.next + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# End of https://www.toptal.com/developers/gitignore/api/node + +# Created by https://www.toptal.com/developers/gitignore/api/macos +# Edit at https://www.toptal.com/developers/gitignore?templates=macos + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### macOS Patch ### +# iCloud generated files +*.icloud + +# End of https://www.toptal.com/developers/gitignore/api/macos + +# Created by https://www.toptal.com/developers/gitignore/api/windows +# Edit at https://www.toptal.com/developers/gitignore?templates=windows + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# End of https://www.toptal.com/developers/gitignore/api/windows + +#Added by cargo + +/target +# Cargo.lock + +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/sdks +!.yarn/versions + +*.farm diff --git a/rust-plugins/vue-jsx/Cargo.lock b/rust-plugins/vue-jsx/Cargo.lock new file mode 100644 index 0000000..7fdd132 --- /dev/null +++ b/rust-plugins/vue-jsx/Cargo.lock @@ -0,0 +1,2192 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42cd52102d3df161c77a887b608d7a4897d7cc112886a9537b738a887a03aaff" +dependencies = [ + "cfg-if", + "getrandom", + "once_cell", + "serde", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "ast_node" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab31376d309dd3bfc9cfb3c11c93ce0e0741bbe0354b20e7f8c60b044730b79" +dependencies = [ + "proc-macro2", + "quote", + "swc_macros_common", + "syn 2.0.65", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64-simd" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "781dd20c3aff0bd194fe7d2a977dd92f21c173891f3a03b677359e5fa457e5d5" +dependencies = [ + "simd-abstraction", +] + +[[package]] +name = "better_scoped_tls" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "794edcc9b3fb07bb4aecaa11f093fd45663b4feadb782d68303a2268bc2701de" +dependencies = [ + "scoped-tls", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "browserslist-rs" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdf0ca73de70c3da94e4194e4a01fe732378f55d47cf4c0588caab22a0dbfa14" +dependencies = [ + "ahash 0.8.8", + "chrono", + "either", + "indexmap", + "itertools 0.13.0", + "nom", + "once_cell", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "bstr" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c48f0051a4b4c5e0b6d365cd04af53aeaa209e3cc15ec2cdb69e73cc87fbd0dc" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "bytecheck" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" +dependencies = [ + "bytecheck_derive 0.6.11", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41502630fe304ce54cbb2f8389e017784dee2b0328147779fcbe43b9db06d35d" +dependencies = [ + "bytecheck_derive 0.7.0", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "bytecheck_derive" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eda88c587085bc07dc201ab9df871bd9baa5e07f7754b745e4d7194b43ac1eda" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "windows-targets 0.52.0", +] + +[[package]] +name = "const_format" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "ctor" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.3", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "data-encoding" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" + +[[package]] +name = "debugid" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" +dependencies = [ + "serde", + "uuid", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "enhanced-magic-string" +version = "0.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6082b74cc322c69840d97a7d7cba3ee9ed34fa70536fb51a69824f36742960f5" +dependencies = [ + "base64 0.22.1", + "farmfe_utils", + "parking_lot", + "regex", + "sourcemap", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "farm_plugin_test1" +version = "0.0.0" +dependencies = [ + "farmfe_core", + "farmfe_macro_plugin", + "farmfe_toolkit_plugin_types", +] + +[[package]] +name = "farmfe_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ace47d8f9846d426af3462d631690d5eba8ae778f58ce4b096d410975d9df6f" +dependencies = [ + "blake2", + "bytecheck 0.7.0", + "dashmap", + "downcast-rs", + "enhanced-magic-string", + "farmfe_macro_cache_item", + "farmfe_utils", + "globset", + "heck", + "hex", + "parking_lot", + "petgraph", + "ptr_meta", + "rayon", + "regex", + "relative-path", + "rkyv", + "rkyv_dyn", + "rkyv_typename", + "serde", + "serde_json", + "swc_common", + "swc_css_ast", + "swc_css_prefixer", + "swc_ecma_ast", + "swc_ecma_parser", + "swc_html_ast", + "thiserror", + "wax", +] + +[[package]] +name = "farmfe_macro_cache_item" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61782617a57f8fa265ce3b4111763d703d457fef83c06341d2eed55cbc06297" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "farmfe_macro_plugin" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "055ed906d281675468dc70294716c6af0b6b904f09fdd7b111865cc72b4f4933" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "farmfe_toolkit_plugin_types" +version = "0.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b9933e059e6d28fb4c81e78aabfd1ca9288feb7a9e2c0516b4f08ca8b2d5c80" +dependencies = [ + "farmfe_core", + "lazy_static", + "libloading", +] + +[[package]] +name = "farmfe_utils" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d797c8fb2b5c357bd730dc119169e663f8ae7dfbc606696350c104e39324749d" +dependencies = [ + "base64 0.21.7", + "pathdiff", + "sha2", +] + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "from_variant" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc9cc75639b041067353b9bce2450d6847e547276c6fbe4487d7407980e07db" +dependencies = [ + "proc-macro2", + "swc_macros_common", + "syn 2.0.65", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[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.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "ghost" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0e085ded9f1267c32176b40921b9754c474f7dd96f7e808d4a982e48aa1e854" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "globset" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.8", +] + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hstr" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0f5356d62012374578cd3a5c013d6586de3efbca3b53379fc1edfbb95c9db14" +dependencies = [ + "hashbrown 0.14.3", + "new_debug_unreachable", + "once_cell", + "phf", + "rustc-hash", + "triomphe", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "if_chain" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", + "serde", +] + +[[package]] +name = "inventory" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0eb5160c60ba1e809707918ee329adb99d222888155835c6feedba19f6c3fd4" +dependencies = [ + "ctor", + "ghost", + "inventory-impl", +] + +[[package]] +name = "inventory-impl" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e41b53715c6f0c4be49510bb82dee2c1e51c8586d885abe65396e82ed518548" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "is-macro" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59a85abdc13717906baccb5a1e435556ce0df215f242892f721dff62bf25288f" +dependencies = [ + "Inflector", + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "miette" +version = "5.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59bb584eaeeab6bd0226ccf3509a69d7936d148cf3d036ad350abe35e8c6856e" +dependencies = [ + "miette-derive", + "once_cell", + "thiserror", + "unicode-width", +] + +[[package]] +name = "miette-derive" +version = "5.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "outref" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f222829ae9293e33a9f5e9f440c6760a3d450a64affe1846486b140db81c1f4" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "backtrace", + "cfg-if", + "libc", + "petgraph", + "redox_syscall", + "smallvec", + "thread-id", + "windows-targets 0.48.5", +] + +[[package]] +name = "pathdiff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pori" +version = "0.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a63d338dec139f56dacc692ca63ad35a6be6a797442479b55acd611d79e906" +dependencies = [ + "nom", +] + +[[package]] +name = "preset_env_base" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b30eab18be480c194938e433e269d5298a279f6410f02fbc73f3576a325c110" +dependencies = [ + "ahash 0.8.8", + "anyhow", + "browserslist-rs", + "dashmap", + "from_variant", + "once_cell", + "semver 1.0.21", + "serde", + "st-map", + "tracing", +] + +[[package]] +name = "proc-macro2" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "psm" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" +dependencies = [ + "cc", +] + +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "rayon" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "relative-path" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e898588f33fdd5b9420719948f9f2a32c922a246964576f71ba7f24f80610fbc" + +[[package]] +name = "rend" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" +dependencies = [ + "bytecheck 0.6.11", +] + +[[package]] +name = "rkyv" +version = "0.7.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" +dependencies = [ + "bitvec", + "bytecheck 0.6.11", + "bytes", + "hashbrown 0.12.3", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rkyv_dyn" +version = "0.7.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7087f1bf1fdffcf7391cd0755df81c47f8a87fe863bab93f99d9f6bbf16b40b7" +dependencies = [ + "inventory", + "lazy_static", + "ptr_meta", + "rkyv", + "rkyv_dyn_derive", + "rkyv_typename", +] + +[[package]] +name = "rkyv_dyn_derive" +version = "0.7.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f21d9c9cfb6d952b4baf89f1ffcfaccd56e0f8c81510f5a7b04de2c034bad18" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rkyv_typename" +version = "0.7.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f3b496694520c6001309c86ab52cf126d084778eb8a372b6bed1400f0562b8" +dependencies = [ + "rkyv_typename_derive", +] + +[[package]] +name = "rkyv_typename_derive" +version = "0.7.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05589f3fceeb5ad55f3a68b6ac56274feeb3c1b8215b4734d2562b78134a3551" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" +dependencies = [ + "serde", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "serde" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "serde_json" +version = "1.0.115" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "simd-abstraction" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cadb29c57caadc51ff8346233b5cec1d240b68ce55cf1afc764818791876987" +dependencies = [ + "outref", +] + +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "smallvec" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2593d31f82ead8df961d8bd23a64c2ccf2eb5dd34b0a34bfb4dd54011c72009e" + +[[package]] +name = "smartstring" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29" +dependencies = [ + "autocfg", + "static_assertions", + "version_check", +] + +[[package]] +name = "sourcemap" +version = "8.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "208d40b9e8cad9f93613778ea295ed8f3c2b1824217c6cfc7219d3f6f45b96d4" +dependencies = [ + "base64-simd", + "bitvec", + "data-encoding", + "debugid", + "if_chain", + "rustc-hash", + "rustc_version", + "serde", + "serde_json", + "unicode-id-start", + "url", +] + +[[package]] +name = "st-map" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a8a5c4e5cc839409346495370b2df67489cafd7fa83616d0547a9697a6a89a1" +dependencies = [ + "arrayvec", + "static-map-macro", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "stacker" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce" +dependencies = [ + "cc", + "cfg-if", + "libc", + "psm", + "winapi", +] + +[[package]] +name = "static-map-macro" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf483ea7e0e3a03d1b91687895814425149ad77facd3e2b6839dde26da98454" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "string_enum" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05e383308aebc257e7d7920224fa055c632478d92744eca77f99be8fa1545b90" +dependencies = [ + "proc-macro2", + "quote", + "swc_macros_common", + "syn 2.0.65", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "swc_atoms" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb6567e4e67485b3e7662b486f1565bdae54bd5b9d6b16b2ba1a9babb1e42125" +dependencies = [ + "bytecheck 0.6.11", + "hstr", + "once_cell", + "rkyv", + "rustc-hash", + "serde", +] + +[[package]] +name = "swc_common" +version = "0.34.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9087befec6b63911f9d2f239e4f91c9b21589c169b86ed2d616944d23cf4a243" +dependencies = [ + "ast_node", + "better_scoped_tls", + "bytecheck 0.6.11", + "cfg-if", + "either", + "from_variant", + "new_debug_unreachable", + "num-bigint", + "once_cell", + "parking_lot", + "rkyv", + "rustc-hash", + "serde", + "siphasher", + "sourcemap", + "swc_atoms", + "swc_eq_ignore_macros", + "swc_visit", + "tracing", + "unicode-width", + "url", +] + +[[package]] +name = "swc_css_ast" +version = "0.141.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89a5f28ff625a89de2a269bde3ed3b99be74bb9d3dc78dea6f3b071991b2cbf4" +dependencies = [ + "is-macro", + "rkyv", + "string_enum", + "swc_atoms", + "swc_common", +] + +[[package]] +name = "swc_css_prefixer" +version = "0.155.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc9930655060121c32d829e13fe4fa11294c03e71eb84c22e039703c929dcdf7" +dependencies = [ + "once_cell", + "preset_env_base", + "serde", + "serde_json", + "swc_atoms", + "swc_common", + "swc_css_ast", + "swc_css_utils", + "swc_css_visit", +] + +[[package]] +name = "swc_css_utils" +version = "0.138.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b135df778449825f38d54664bb179c839b3285f9a553ec10dd3cc3eafb751599" +dependencies = [ + "once_cell", + "serde", + "serde_json", + "swc_atoms", + "swc_common", + "swc_css_ast", + "swc_css_visit", +] + +[[package]] +name = "swc_css_visit" +version = "0.140.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c97dceaa18c8ae7f5a4c991e15efc5c333e5880b58ee6d61e42fd1365748ff05" +dependencies = [ + "serde", + "swc_atoms", + "swc_common", + "swc_css_ast", + "swc_visit", +] + +[[package]] +name = "swc_ecma_ast" +version = "0.115.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7be1306930c235435a892104c00c2b5e16231043c085d5a10bd3e7537b15659b" +dependencies = [ + "bitflags 2.5.0", + "bytecheck 0.6.11", + "is-macro", + "num-bigint", + "phf", + "rkyv", + "scoped-tls", + "serde", + "string_enum", + "swc_atoms", + "swc_common", + "unicode-id-start", +] + +[[package]] +name = "swc_ecma_parser" +version = "0.146.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a4e0c2e85f12c63b85c805e923079b04d1fb3e25edd069d638eed5f2098de74" +dependencies = [ + "either", + "new_debug_unreachable", + "num-bigint", + "num-traits", + "phf", + "serde", + "smallvec", + "smartstring", + "stacker", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "tracing", + "typed-arena", +] + +[[package]] +name = "swc_eq_ignore_macros" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "695a1d8b461033d32429b5befbf0ad4d7a2c4d6ba9cd5ba4e0645c615839e8e4" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "swc_html_ast" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b909aca7c9cbd630a461d4a0a1d476ac13704dc515d2a79264c93d3280b02d23" +dependencies = [ + "is-macro", + "rkyv", + "string_enum", + "swc_atoms", + "swc_common", +] + +[[package]] +name = "swc_macros_common" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91745f3561057493d2da768437c427c0e979dff7396507ae02f16c981c4a8466" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "swc_visit" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "043d11fe683dcb934583ead49405c0896a5af5face522e4682c16971ef7871b9" +dependencies = [ + "either", + "swc_visit_macros", +] + +[[package]] +name = "swc_visit_macros" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae9ef18ff8daffa999f729db056d2821cd2f790f3a11e46422d19f46bb193e7" +dependencies = [ + "Inflector", + "proc-macro2", + "quote", + "swc_macros_common", + "syn 2.0.65", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tardar" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900c942f83b6a8b9998cc8f74ad3ffa24b7ff3c4279ea1c1c52d95dced9f3516" +dependencies = [ + "miette", + "vec1", +] + +[[package]] +name = "thiserror" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "thread-id" +version = "4.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0ec81c46e9eb50deaa257be2f148adf052d1fb7701cfd55ccfab2525280b70b" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "triomphe" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3" +dependencies = [ + "serde", + "stable_deref_trait", +] + +[[package]] +name = "typed-arena" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-id-start" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02aebfa694eccbbbffdd92922c7de136b9fe764396d2f10e21bce1681477cfc1" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "uuid" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" + +[[package]] +name = "vec1" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eab68b56840f69efb0fefbe3ab6661499217ffdc58e2eef7c3f6f69835386322" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.65", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" + +[[package]] +name = "wax" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d12a78aa0bab22d2f26ed1a96df7ab58e8a93506a3e20adb47c51a93b4e1357" +dependencies = [ + "const_format", + "itertools 0.11.0", + "miette", + "nom", + "pori", + "regex", + "tardar", + "thiserror", + "walkdir", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] diff --git a/rust-plugins/vue-jsx/Cargo.toml b/rust-plugins/vue-jsx/Cargo.toml new file mode 100644 index 0000000..3f7aa2b --- /dev/null +++ b/rust-plugins/vue-jsx/Cargo.toml @@ -0,0 +1,15 @@ +[package] +edition = "2021" +name = "farmfe_plugin_vue_jsx" +version = "0.0.0" + +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +farmfe_core = { workspace = true } +farmfe_toolkit_plugin_types = { workspace = true } +farmfe_macro_plugin = { workspace = true } +farmfe_toolkit = { workspace = true } +vue_jsx_visitor = { path = "./crates/visitor" } +serde = { version = "1.0.197", features = ["derive"] } diff --git a/rust-plugins/vue-jsx/crates/visitor/Cargo.toml b/rust-plugins/vue-jsx/crates/visitor/Cargo.toml new file mode 100644 index 0000000..495fe69 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "vue_jsx_visitor" +description = "SWC visitor for transforming Vue JSX." +version = "0.3.2" +license = "MIT" +edition = "2021" + +[dependencies] +bitflags = "2.4" +css_dataset = "0.3" +fnv = "1.0" +indexmap = "2.1" +regex = "1.10" +farmfe_core = { workspace = true } +farmfe_toolkit = { workspace = true } +serde = { version = "1.0.210", features = ["derive"] } + +[dev-dependencies] +serde_json = "1.0" +testing = "0.38" diff --git a/rust-plugins/vue-jsx/crates/visitor/src/directive.rs b/rust-plugins/vue-jsx/crates/visitor/src/directive.rs new file mode 100644 index 0000000..8a59c5f --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/src/directive.rs @@ -0,0 +1,345 @@ +use std::{collections::BTreeSet, str::Split}; +use farmfe_core::{swc_common::{errors::HANDLER, DUMMY_SP}, swc_ecma_ast::*}; +use farmfe_toolkit::{ + swc_atoms::JsWord, + swc_ecma_utils::{quote_ident, quote_str}, +}; +pub(crate) fn is_directive(jsx_attr: &JSXAttr) -> bool { + let name = match &jsx_attr.name { + JSXAttrName::Ident(ident) => &ident.sym, + JSXAttrName::JSXNamespacedName(JSXNamespacedName { ns, .. }) => &ns.sym, + }; + matches!(name.as_bytes(), [b'v', b'-' | b'A'..=b'Z', ..]) +} + +pub(crate) struct NormalDirective { + pub(crate) name: JsWord, + pub(crate) argument: Option, + pub(crate) modifiers: Option, + pub(crate) value: Expr, +} + +pub(crate) struct VModelDirective { + pub(crate) argument: Option, + pub(crate) transformed_argument: Option, + pub(crate) modifiers: Option, + pub(crate) value: Expr, +} + +pub(crate) enum Directive { + Normal(NormalDirective), + Text(Expr), + Html(Expr), + VModel(VModelDirective), + Slots(Option>), +} + +pub(crate) fn parse_directive(jsx_attr: &JSXAttr, is_component: bool) -> Directive { + let (name, argument, splitted) = match &jsx_attr.name { + JSXAttrName::Ident(ident) => { + let mut splitted = ident + .sym + .trim_start_matches('v') + .trim_start_matches('-') + .split('_'); + ( + splitted.next().unwrap_or(&*ident.sym).to_ascii_lowercase(), + splitted.next(), + splitted, + ) + } + JSXAttrName::JSXNamespacedName(JSXNamespacedName { ns, name, .. }) => { + let mut splitted = name.sym.split('_'); + ( + ns.sym + .trim_start_matches('v') + .trim_start_matches('-') + .to_ascii_lowercase(), + Some(splitted.next().unwrap_or(&*name.sym)), + splitted, + ) + } + }; + + let mut argument = argument.map(|argument| Expr::Lit(Lit::Str(quote_str!(argument)))); + + match &*name { + "html" => return parse_v_html_directive(jsx_attr), + "text" => return parse_v_text_directive(jsx_attr), + "model" => return parse_v_model_directive(jsx_attr, is_component, argument, splitted), + "slots" => return parse_v_slots_directive(jsx_attr), + _ => {} + } + + let mut modifiers = None; + let value; + + if let Some(JSXAttrValue::JSXExprContainer(JSXExprContainer { + expr: JSXExpr::Expr(expr), + .. + })) = &jsx_attr.value + { + if let Expr::Array(ArrayLit { elems, .. }) = &**expr { + value = match elems.get(0) { + Some(Some(ExprOrSpread { spread: None, expr })) => (**expr).clone(), + _ => Expr::Ident(quote_ident!("").into()), + }; + if let Some(Some(ExprOrSpread { spread: None, expr })) = elems.get(1) { + match &**expr { + Expr::Array(ArrayLit { elems, .. }) => { + modifiers = Some(parse_modifiers(elems)); + } + expr => { + if argument.is_none() { + argument = Some(expr.clone()); + } + if let Some(Some(ExprOrSpread { spread: None, expr })) = elems.get(2) { + if let Expr::Array(ArrayLit { elems, .. }) = &**expr { + modifiers = Some(parse_modifiers(elems)); + } + } + } + } + } else { + modifiers = Some(splitted.map(JsWord::from).collect()); + } + } else { + modifiers = Some(splitted.map(JsWord::from).collect()); + value = (**expr).clone(); + } + } else { + modifiers = Some(splitted.map(JsWord::from).collect()); + value = Expr::Ident(quote_ident!("").into()); + } + + Directive::Normal(NormalDirective { + name: JsWord::from(name), + argument: if modifiers + .as_ref() + .map(|modifiers| !modifiers.is_empty()) + .unwrap_or_default() + { + argument.or_else(|| { + Some(Expr::Unary(UnaryExpr { + span: DUMMY_SP, + op: op!("void"), + arg: Box::new(Expr::Lit(Lit::Num(Number { + span: DUMMY_SP, + value: 0.0, + raw: None, + }))), + })) + }) + } else { + argument + }, + modifiers: modifiers.and_then(|modifiers| transform_modifiers(modifiers, false)), + value, + }) +} + +fn parse_modifiers(exprs: &[Option]) -> BTreeSet { + exprs + .iter() + .filter_map(|expr| match expr { + Some(ExprOrSpread { spread: None, expr }) => match &**expr { + Expr::Lit(Lit::Str(Str { value, .. })) => Some(value.clone()), + _ => None, + }, + _ => None, + }) + .collect() +} + +fn parse_v_text_directive(jsx_attr: &JSXAttr) -> Directive { + let expr = match &jsx_attr.value { + Some(JSXAttrValue::Lit(lit)) => Expr::Lit(lit.clone()), + Some(JSXAttrValue::JSXExprContainer(JSXExprContainer { + expr: JSXExpr::Expr(expr), + .. + })) => { + if let Some(Some(ExprOrSpread { spread: None, expr })) = + expr.as_array().and_then(|array| array.elems.get(0)) + { + (**expr).clone() + } else { + (**expr).clone() + } + } + None => { + HANDLER.with(|handler| { + handler.span_err( + jsx_attr.span, + "You have to use JSX Expression inside your `v-text`.", + ); + }); + Expr::Lit(Lit::Bool(Bool { + span: DUMMY_SP, + value: true, + })) + } + _ => unreachable!(), + }; + + Directive::Text(expr) +} + +fn parse_v_html_directive(jsx_attr: &JSXAttr) -> Directive { + let expr = match &jsx_attr.value { + Some(JSXAttrValue::Lit(lit)) => Expr::Lit(lit.clone()), + Some(JSXAttrValue::JSXExprContainer(JSXExprContainer { + expr: JSXExpr::Expr(expr), + .. + })) => { + if let Some(Some(ExprOrSpread { spread: None, expr })) = + expr.as_array().and_then(|array| array.elems.get(0)) + { + (**expr).clone() + } else { + (**expr).clone() + } + } + None => { + HANDLER.with(|handler| { + handler.span_err( + jsx_attr.span, + "You have to use JSX Expression inside your `v-html`.", + ); + }); + Expr::Lit(Lit::Bool(Bool { + span: DUMMY_SP, + value: true, + })) + } + _ => unreachable!(), + }; + + Directive::Html(expr) +} + +fn parse_v_model_directive( + jsx_attr: &JSXAttr, + is_component: bool, + mut argument: Option, + splitted_attr_name: Split, +) -> Directive { + let attr_value = match &jsx_attr.value { + Some(JSXAttrValue::JSXExprContainer(JSXExprContainer { + expr: JSXExpr::Expr(expr), + .. + })) => (**expr).clone(), + _ => { + HANDLER.with(|handler| { + handler.span_err( + jsx_attr.span, + "You have to use JSX Expression inside your `v-model`.", + ); + }); + Expr::Ident(quote_ident!("").into()) + } + }; + + let mut modifiers = None; + let value; + + if let Expr::Array(ArrayLit { elems, .. }) = attr_value { + value = match elems.get(0) { + Some(Some(ExprOrSpread { spread: None, expr })) => (**expr).clone(), + _ => Expr::Ident(quote_ident!("").into()), + }; + if let Some(Some(ExprOrSpread { spread: None, expr })) = elems.get(1) { + match &**expr { + Expr::Array(ArrayLit { elems, .. }) => { + if is_component && argument.is_none() { + argument = Some(Expr::Lit(Lit::Null(Null { span: DUMMY_SP }))); + } + modifiers = Some(parse_modifiers(elems)); + } + expr => { + if argument.is_none() { + argument = Some(expr.clone()); + } + if let Some(Some(ExprOrSpread { spread: None, expr })) = elems.get(2) { + if let Expr::Array(ArrayLit { elems, .. }) = &**expr { + modifiers = Some(parse_modifiers(elems)); + } + } + } + } + } else { + if is_component && argument.is_none() { + argument = Some(Expr::Lit(Lit::Null(Null { span: DUMMY_SP }))); + } + modifiers = Some(splitted_attr_name.map(JsWord::from).collect()); + } + } else { + modifiers = Some(splitted_attr_name.map(JsWord::from).collect()); + value = attr_value.clone(); + } + + Directive::VModel(VModelDirective { + argument: argument.clone(), + transformed_argument: if !is_component + && modifiers + .as_ref() + .map(|modifiers| !modifiers.is_empty()) + .unwrap_or_default() + { + argument.or_else(|| { + Some(Expr::Unary(UnaryExpr { + span: DUMMY_SP, + op: op!("void"), + arg: Box::new(Expr::Lit(Lit::Num(Number { + span: DUMMY_SP, + value: 0.0, + raw: None, + }))), + })) + }) + } else { + argument + }, + modifiers: modifiers.and_then(|modifiers| transform_modifiers(modifiers, is_component)), + value, + }) +} + +fn transform_modifiers(modifiers: BTreeSet, quote_prop: bool) -> Option { + if modifiers.is_empty() { + None + } else { + Some(Expr::Object(ObjectLit { + span: DUMMY_SP, + props: modifiers + .into_iter() + .map(|modifier| { + PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { + key: if quote_prop { + PropName::Str(quote_str!(modifier)) + } else { + PropName::Ident(quote_ident!(modifier)) + }, + value: Box::new(Expr::Lit(Lit::Bool(Bool { + span: DUMMY_SP, + value: true, + }))), + }))) + }) + .collect(), + })) + } +} + +fn parse_v_slots_directive(jsx_attr: &JSXAttr) -> Directive { + let expr = match &jsx_attr.value { + Some(JSXAttrValue::JSXExprContainer(JSXExprContainer { + expr: JSXExpr::Expr(expr), + .. + })) => match &**expr { + Expr::Ident(..) | Expr::Object(..) => Some(expr.clone()), + _ => None, + }, + _ => None, + }; + Directive::Slots(expr) +} diff --git a/rust-plugins/vue-jsx/crates/visitor/src/lib.rs b/rust-plugins/vue-jsx/crates/visitor/src/lib.rs new file mode 100644 index 0000000..0f0954b --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/src/lib.rs @@ -0,0 +1,1476 @@ +use directive::{is_directive, parse_directive, Directive, NormalDirective}; +use fnv::FnvHashMap; +use indexmap::IndexSet; +pub use options::{Options, Regex}; +use patch_flags::PatchFlags; +use slot_flag::SlotFlag; +use std::{borrow::Cow, collections::BTreeMap, mem}; +use farmfe_core::{ + swc_common::{comments::Comments, errors::HANDLER, Mark, Span, Spanned, SyntaxContext, DUMMY_SP}, + swc_ecma_ast::*, +}; +use farmfe_toolkit::{ + swc_atoms::JsWord, + swc_ecma_utils::{private_ident, quote_ident, quote_str}, + swc_ecma_visit::{VisitMut, VisitMutWith}, +}; + +mod directive; +mod options; +mod patch_flags; +mod resolve_type; +mod slot_flag; +mod util; + +const FRAGMENT: &str = "Fragment"; +const KEEP_ALIVE: &str = "KeepAlive"; + +struct AttrsTransformationResult<'a> { + attrs: Expr, + patch_flags: PatchFlags, + dynamic_props: Option>>, + slots: Option>, +} + +pub struct VueJsxTransformVisitor +where + C: Comments, +{ + options: Options, + vue_imports: BTreeMap<&'static str, Ident>, + transform_on_helper: Option, + + define_component: Option, + interfaces: FnvHashMap<(JsWord, SyntaxContext), TsInterfaceDecl>, + type_aliases: FnvHashMap<(JsWord, SyntaxContext), TsType>, + + unresolved_mark: Mark, + comments: Option, + + pragma: Option, + slot_helper_ident: Option, + injecting_vars: Vec, + slot_counter: usize, + slot_flag_stack: Vec, + + assignment_left: Option, + injecting_consts: Vec, +} + +impl VueJsxTransformVisitor +where + C: Comments, +{ + pub fn new(options: Options, unresolved_mark: Mark, comments: Option) -> Self { + Self { + options, + vue_imports: Default::default(), + transform_on_helper: None, + + define_component: None, + interfaces: Default::default(), + type_aliases: Default::default(), + + unresolved_mark, + comments, + + pragma: None, + slot_helper_ident: None, + injecting_vars: Default::default(), + slot_counter: 1, + slot_flag_stack: Default::default(), + + assignment_left: None, + injecting_consts: Default::default(), + } + } + fn import_from_vue(&mut self, item: &'static str) -> Ident { + self + .vue_imports + .entry(item) + .or_insert_with_key(|name| private_ident!(format!("_{name}"))) + .clone() + } + + fn generate_slot_helper(&mut self) -> Ident { + self + .slot_helper_ident + .get_or_insert_with(|| private_ident!("_isSlot")) + .clone() + } + + fn transform_jsx_element(&mut self, jsx_element: &JSXElement) -> Expr { + if self.options.optimize { + self.slot_flag_stack.push(SlotFlag::Stable); + } + + let is_component = self.is_component(&jsx_element.opening.name); + let mut directives = vec![]; + let AttrsTransformationResult { + attrs, + patch_flags, + dynamic_props, + slots, + } = self.transform_attrs(&jsx_element.opening.attrs, is_component, &mut directives); + let mut vnode_call_args = vec![ + ExprOrSpread { + spread: None, + expr: Box::new(self.transform_tag(&jsx_element.opening.name)), + }, + ExprOrSpread { + spread: None, + expr: Box::new(attrs), + }, + ExprOrSpread { + spread: None, + expr: Box::new(self.transform_children(&jsx_element.children, is_component, slots)), + }, + ]; + if self.options.optimize { + if !patch_flags.is_empty() { + vnode_call_args.push(ExprOrSpread { + spread: None, + expr: Box::new(Expr::Lit(Lit::Num(Number { + span: DUMMY_SP, + value: patch_flags.bits() as f64, + raw: None, + }))), + }); + } + match dynamic_props { + Some(dynamic_props) if !dynamic_props.is_empty() => vnode_call_args.push(ExprOrSpread { + spread: None, + expr: Box::new(Expr::Array(ArrayLit { + span: DUMMY_SP, + elems: dynamic_props + .into_iter() + .map(|prop| { + Some(ExprOrSpread { + spread: None, + expr: Box::new(Expr::Lit(Lit::Str(quote_str!(prop)))), + }) + }) + .collect(), + })), + }), + _ => {} + } + } + + let create_vnode_call = Expr::Call(CallExpr { + span: DUMMY_SP, + callee: Callee::Expr(Box::new(Expr::Ident(self.get_pragma()))), + args: vnode_call_args, + type_args: None, + }); + + if directives.is_empty() { + create_vnode_call + } else { + Expr::Call(CallExpr { + span: DUMMY_SP, + callee: Callee::Expr(Box::new(Expr::Ident( + self.import_from_vue("withDirectives"), + ))), + args: vec![ + ExprOrSpread { + spread: None, + expr: Box::new(create_vnode_call), + }, + ExprOrSpread { + spread: None, + expr: Box::new(Expr::Array(ArrayLit { + span: DUMMY_SP, + elems: directives + .into_iter() + .map(|directive| { + let mut elems = vec![ + Some(ExprOrSpread { + spread: None, + expr: Box::new(self.resolve_directive(&directive.name, jsx_element)), + }), + Some(ExprOrSpread { + spread: None, + expr: Box::new(directive.value), + }), + ]; + if let Some(argument) = directive.argument { + elems.push(Some(ExprOrSpread { + spread: None, + expr: Box::new(argument), + })); + } + if let Some(modifiers) = directive.modifiers { + elems.push(Some(ExprOrSpread { + spread: None, + expr: Box::new(modifiers), + })); + } + Some(ExprOrSpread { + spread: None, + expr: Box::new(Expr::Array(ArrayLit { + span: DUMMY_SP, + elems, + })), + }) + }) + .collect(), + })), + }, + ], + type_args: None, + }) + } + } + + fn transform_jsx_fragment(&mut self, jsx_fragment: &JSXFragment) -> Expr { + if self.options.optimize { + self.slot_flag_stack.push(SlotFlag::Stable); + } + + Expr::Call(CallExpr { + span: DUMMY_SP, + callee: Callee::Expr(Box::new(Expr::Ident(self.get_pragma()))), + args: vec![ + ExprOrSpread { + spread: None, + expr: Box::new(Expr::Ident(self.import_from_vue(FRAGMENT))), + }, + ExprOrSpread { + spread: None, + expr: Box::new(Expr::Lit(Lit::Null(Null { span: DUMMY_SP }))), + }, + ExprOrSpread { + spread: None, + expr: Box::new(self.transform_children(&jsx_fragment.children, false, None)), + }, + ], + type_args: None, + }) + } + + fn transform_tag(&mut self, jsx_element_name: &JSXElementName) -> Expr { + match jsx_element_name { + JSXElementName::Ident(ident) => { + let name = &*ident.sym; + if name.as_bytes()[0].is_ascii_lowercase() + && (css_dataset::tags::STANDARD_HTML_TAGS.contains(name) + || css_dataset::tags::SVG_TAGS.contains(name)) + { + Expr::Lit(Lit::Str(quote_str!(name))) + } else if name == FRAGMENT { + Expr::Ident(self.import_from_vue(FRAGMENT)) + } else if self + .options + .custom_element_patterns + .iter() + .any(|pattern| pattern.is_match(name)) + { + Expr::Lit(Lit::Str(quote_str!(name))) + } else if ident.to_id().1.has_mark(self.unresolved_mark) { + // for components that can't be resolved from current file + Expr::Call(CallExpr { + span: DUMMY_SP, + callee: Callee::Expr(Box::new(Expr::Ident( + self.import_from_vue("resolveComponent"), + ))), + args: vec![ExprOrSpread { + spread: None, + expr: Box::new(Expr::Lit(Lit::Str(quote_str!(name)))), + }], + type_args: None, + }) + } else { + Expr::Ident(ident.clone()) + } + } + JSXElementName::JSXMemberExpr(expr) => Expr::JSXMember(expr.clone()), + JSXElementName::JSXNamespacedName(name) => Expr::JSXNamespacedName(name.clone()), + } + } + + fn transform_attrs<'a>( + &mut self, + attrs: &'a [JSXAttrOrSpread], + is_component: bool, + directives: &mut Vec, + ) -> AttrsTransformationResult<'a> { + let mut slots = None; + + if attrs.is_empty() { + return AttrsTransformationResult { + attrs: Expr::Lit(Lit::Null(Null { span: DUMMY_SP })), + patch_flags: PatchFlags::empty(), + dynamic_props: None, + slots, + }; + } + + let mut dynamic_props = IndexSet::new(); + + // patch flags analysis + let mut has_ref = false; + let mut has_class_binding = false; + let mut has_style_binding = false; + let mut has_hydration_event_binding = false; + let mut has_dynamic_keys = false; + + let (mut props, mut merge_args) = attrs.iter().fold( + ( + Vec::with_capacity(attrs.len()), + Vec::with_capacity(attrs.len()), + ), + |(mut props, mut merge_args), jsx_attr_or_spread| { + match jsx_attr_or_spread { + JSXAttrOrSpread::JSXAttr(jsx_attr) if is_directive(jsx_attr) => { + match parse_directive(jsx_attr, is_component) { + Directive::Normal(directive) => directives.push(directive), + Directive::Html(expr) => { + props.push(PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { + key: PropName::Str(quote_str!("innerHTML")), + value: Box::new(expr), + })))); + dynamic_props.insert("innerHTML".into()); + } + Directive::Text(expr) => { + props.push(PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { + key: PropName::Str(quote_str!("textContent")), + value: Box::new(expr), + })))); + dynamic_props.insert("textContent".into()); + } + Directive::VModel(directive) => { + if is_component { + props.push(PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { + key: match &directive.argument { + Some(Expr::Lit(Lit::Null(..))) | None => { + dynamic_props.insert("modelValue".into()); + PropName::Str(quote_str!("modelValue")) + } + Some(Expr::Lit(Lit::Str(Str { value, .. }))) => { + dynamic_props.insert(Cow::from(value.to_string())); + PropName::Str(quote_str!(&**value)) + } + Some(expr) => PropName::Computed(ComputedPropName { + span: DUMMY_SP, + expr: Box::new(expr.clone()), + }), + }, + value: Box::new(directive.value.clone()), + })))); + if let Some(modifiers) = directive.modifiers { + props.push(PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { + key: match &directive.argument { + Some(Expr::Lit(Lit::Null(..))) | None => { + PropName::Str(quote_str!("modelModifiers")) + } + Some(Expr::Lit(Lit::Str(Str { value, .. }))) => { + PropName::Str(quote_str!(format!("{value}Modifiers"))) + } + Some(expr) => PropName::Computed(ComputedPropName { + span: DUMMY_SP, + expr: Box::new(Expr::Bin(BinExpr { + span: DUMMY_SP, + op: op!(bin, "+"), + left: Box::new(expr.clone()), + right: Box::new(Expr::Lit(Lit::Str(quote_str!("Modifiers")))), + })), + }), + }, + value: Box::new(modifiers), + })))) + } + } else { + directives.push(NormalDirective { + name: JsWord::from("model"), + argument: directive.transformed_argument, + modifiers: directive.modifiers.clone(), + value: directive.value.clone(), + }); + } + + props.push(PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { + key: match directive.argument { + Some(Expr::Lit(Lit::Null(..))) | None => { + dynamic_props.insert("onUpdate:modelValue".into()); + PropName::Str(quote_str!("onUpdate:modelValue")) + } + Some(Expr::Lit(Lit::Str(Str { value, .. }))) => { + let name = format!("onUpdate:{value}"); + let prop_name = PropName::Str(quote_str!(&*name)); + dynamic_props.insert(name.into()); + prop_name + } + Some(expr) => { + has_dynamic_keys = true; + PropName::Computed(ComputedPropName { + span: DUMMY_SP, + expr: Box::new(Expr::Bin(BinExpr { + span: DUMMY_SP, + op: op!(bin, "+"), + left: Box::new(Expr::Lit(Lit::Str(quote_str!("onUpdate")))), + right: Box::new(expr), + })), + }) + } + }, + value: Box::new(Expr::Arrow(ArrowExpr { + span: DUMMY_SP, + params: vec![Pat::Ident(BindingIdent { + id: quote_ident!("$event").into(), + type_ann: None, + })], + body: Box::new(BlockStmtOrExpr::Expr(Box::new(Expr::Assign(AssignExpr { + span: DUMMY_SP, + op: op!("="), + left: AssignTarget::Simple(SimpleAssignTarget::Paren(ParenExpr { + span: DUMMY_SP, + expr: Box::new(directive.value), + })), + right: Box::new(Expr::Ident(quote_ident!("$event").into())), + })))), + is_async: false, + is_generator: false, + type_params: None, + return_type: None, + })), + })))); + } + Directive::Slots(expr) => slots = expr, + } + } + JSXAttrOrSpread::JSXAttr(jsx_attr) => { + let attr_name = match &jsx_attr.name { + JSXAttrName::Ident(ident) => Cow::from(&*ident.sym), + JSXAttrName::JSXNamespacedName(name) => { + Cow::from(format!("{}:{}", name.ns.sym, name.name.sym)) + } + }; + let attr_value = jsx_attr + .value + .as_ref() + .map(|value| match value { + JSXAttrValue::Lit(Lit::Str(str)) => Box::new(Expr::Lit(Lit::Str(quote_str!( + util::transform_text(&str.value) + )))), + JSXAttrValue::Lit(..) => { + unreachable!("JSX attribute value literal must be string") + } + JSXAttrValue::JSXExprContainer(JSXExprContainer { + expr: JSXExpr::Expr(expr), + .. + }) => expr.clone(), + JSXAttrValue::JSXExprContainer(JSXExprContainer { + expr: JSXExpr::JSXEmptyExpr(expr), + .. + }) => Box::new(Expr::JSXEmpty(*expr)), + JSXAttrValue::JSXElement(element) => Box::new(Expr::JSXElement(element.clone())), + JSXAttrValue::JSXFragment(fragment) => { + Box::new(Expr::JSXFragment(fragment.clone())) + } + }) + .unwrap_or_else(|| { + Box::new(Expr::Lit(Lit::Bool(Bool { + span: DUMMY_SP, + value: true, + }))) + }); + + if attr_name == "ref" { + has_ref = true; + } else if !jsx_attr + .value + .as_ref() + .map(util::is_jsx_attr_value_constant) + .unwrap_or_default() + { + if !is_component && util::is_on(&attr_name) + // omit the flag for click handlers becaues hydration gives click + // dedicated fast path. + && !attr_name.eq_ignore_ascii_case("onclick") + // omit v-model handlers + && attr_name != "onUpdate:modelValue" + { + has_hydration_event_binding = true; + } + match &*attr_name { + "class" if !is_component => has_class_binding = true, + "style" if !is_component => has_style_binding = true, + "key" | "on" | "ref" => {} + _ => { + dynamic_props.insert(attr_name.clone()); + } + } + } + + if self.options.transform_on && (attr_name == "on" || attr_name == "nativeOn") { + merge_args.push(Expr::Call(CallExpr { + span: DUMMY_SP, + callee: Callee::Expr(Box::new(Expr::Ident( + self + .transform_on_helper + .get_or_insert_with(|| private_ident!("_transformOn")) + .clone(), + ))), + args: vec![ExprOrSpread { + spread: None, + expr: attr_value, + }], + type_args: None, + })); + } else { + props.push(PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { + key: PropName::Str(quote_str!(attr_name)), + value: attr_value, + })))); + } + } + JSXAttrOrSpread::SpreadElement(spread) => { + has_dynamic_keys = true; + + if !props.is_empty() && self.options.merge_props { + merge_args.push(Expr::Object(ObjectLit { + span: DUMMY_SP, + props: util::dedupe_props(mem::take(&mut props)), + })); + } + + if let Expr::Object(object) = &*spread.expr { + if self.options.merge_props { + merge_args.push(Expr::Object(object.clone())); + } else { + props.extend_from_slice(&object.props); + } + } else if self.options.merge_props { + merge_args.push(*spread.expr.clone()); + } else { + props.push(PropOrSpread::Spread(spread.clone())); + } + } + } + (props, merge_args) + }, + ); + + let expr = if !merge_args.is_empty() { + if !props.is_empty() { + merge_args.push(Expr::Object(ObjectLit { + span: DUMMY_SP, + props: if self.options.merge_props { + util::dedupe_props(mem::take(&mut props)) + } else { + mem::take(&mut props) + }, + })); + } + match merge_args.as_slice() { + [expr] => expr.clone(), + _ => Expr::Call(CallExpr { + span: DUMMY_SP, + callee: Callee::Expr(Box::new(Expr::Ident(self.import_from_vue("mergeProps")))), + args: merge_args + .into_iter() + .map(|expr| ExprOrSpread { + spread: None, + expr: Box::new(expr), + }) + .collect(), + type_args: None, + }), + } + } else if !props.is_empty() { + if let [PropOrSpread::Spread(SpreadElement { expr, .. })] = props.as_slice() { + *expr.clone() + } else { + Expr::Object(ObjectLit { + span: DUMMY_SP, + props: if self.options.merge_props { + util::dedupe_props(props) + } else { + props + }, + }) + } + } else { + Expr::Lit(Lit::Null(Null { span: DUMMY_SP })) + }; + + let mut patch_flags = PatchFlags::empty(); + if has_dynamic_keys { + patch_flags.insert(PatchFlags::FULL_PROPS); + } else { + if has_class_binding { + patch_flags.insert(PatchFlags::CLASS); + } + if has_style_binding { + patch_flags.insert(PatchFlags::STYLE); + } + if !dynamic_props.is_empty() { + patch_flags.insert(PatchFlags::PROPS); + } + if has_hydration_event_binding { + patch_flags.insert(PatchFlags::HYDRATE_EVENTS); + } + } + if (patch_flags.is_empty() || patch_flags == PatchFlags::HYDRATE_EVENTS) + && (has_ref || !directives.is_empty()) + { + patch_flags.insert(PatchFlags::NEED_PATCH); + } + + AttrsTransformationResult { + attrs: expr, + patch_flags, + dynamic_props: Some(dynamic_props), + slots, + } + } + + fn transform_children( + &mut self, + children: &[JSXElementChild], + is_component: bool, + slots: Option>, + ) -> Expr { + let elems = children + .iter() + .filter_map(|child| match child { + JSXElementChild::JSXText(jsx_text) => { + self.transform_jsx_text(jsx_text).map(|expr| ExprOrSpread { + spread: None, + expr: Box::new(expr), + }) + } + JSXElementChild::JSXExprContainer(JSXExprContainer { + expr: JSXExpr::JSXEmptyExpr(..), + .. + }) => None, + JSXElementChild::JSXExprContainer(JSXExprContainer { + expr: JSXExpr::Expr(expr), + .. + }) => { + if self.options.optimize { + match &**expr { + Expr::Ident(ident) if !ident.to_id().1.has_mark(self.unresolved_mark) => { + self.slot_flag_stack.fill(SlotFlag::Dynamic); + } + _ => {} + } + } + Some(ExprOrSpread { + spread: None, + expr: expr.clone(), + }) + } + JSXElementChild::JSXSpreadChild(JSXSpreadChild { expr, .. }) => { + if self.options.optimize { + match &**expr { + Expr::Ident(ident) if !ident.to_id().1.has_mark(self.unresolved_mark) => { + self.slot_flag_stack.fill(SlotFlag::Dynamic); + } + _ => {} + } + } + Some(ExprOrSpread { + spread: Some(DUMMY_SP), + expr: expr.clone(), + }) + } + JSXElementChild::JSXElement(jsx_element) => Some(ExprOrSpread { + spread: None, + expr: Box::new(self.transform_jsx_element(jsx_element)), + }), + JSXElementChild::JSXFragment(jsx_fragment) => Some(ExprOrSpread { + spread: None, + expr: Box::new(self.transform_jsx_fragment(jsx_fragment)), + }), + }) + .map(Some) + .collect::>(); + + let slot_flag = if self.options.optimize { + self.slot_flag_stack.pop().unwrap_or(SlotFlag::Stable) + } else { + SlotFlag::Stable + }; + + match elems.as_slice() { + [] => { + if let Some(slots) = slots { + *slots + } else { + Expr::Lit(Lit::Null(Null { span: DUMMY_SP })) + } + } + [Some(ExprOrSpread { spread: None, expr })] => match &**expr { + expr @ Expr::Ident(..) if is_component => { + let elems = self.build_iife(elems.clone()); + if self.options.enable_object_slots { + Expr::Cond(CondExpr { + span: DUMMY_SP, + test: Box::new(Expr::Call(CallExpr { + span: DUMMY_SP, + callee: Callee::Expr(Box::new(Expr::Ident(self.generate_slot_helper()))), + args: vec![ExprOrSpread { + spread: None, + expr: Box::new(expr.clone()), + }], + type_args: None, + })), + cons: Box::new(expr.clone()), + alt: Box::new(self.wrap_children(elems, slot_flag, slots)), + }) + } else { + self.wrap_children(elems, slot_flag, slots) + } + } + expr @ Expr::Call(..) if expr.span() != DUMMY_SP && is_component => { + // the element was generated and doesn't have location information + if self.options.enable_object_slots { + let slot_ident = self.generate_unique_slot_ident(); + Expr::Cond(CondExpr { + span: DUMMY_SP, + test: Box::new(Expr::Call(CallExpr { + span: DUMMY_SP, + callee: Callee::Expr(Box::new(Expr::Ident(self.generate_slot_helper()))), + args: vec![ExprOrSpread { + spread: None, + expr: Box::new(Expr::Assign(AssignExpr { + span: DUMMY_SP, + op: op!("="), + left: AssignTarget::Simple(SimpleAssignTarget::Paren(ParenExpr { + span: DUMMY_SP, + expr: Box::new(Expr::Ident(slot_ident.clone())), + })), + right: Box::new(expr.clone()), + })), + }], + type_args: None, + })), + cons: Box::new(Expr::Ident(slot_ident.clone())), + alt: { + let elems = self.build_iife(vec![Some(ExprOrSpread { + spread: None, + expr: Box::new(Expr::Ident(slot_ident)), + })]); + Box::new(self.wrap_children(elems, slot_flag, slots)) + }, + }) + } else { + self.wrap_children(elems, slot_flag, slots) + } + } + expr @ Expr::Fn(..) | expr @ Expr::Arrow(..) => Expr::Object(ObjectLit { + span: DUMMY_SP, + props: vec![PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { + key: PropName::Ident(quote_ident!("default")), + value: Box::new(expr.clone()), + })))], + }), + Expr::Object(ObjectLit { props, .. }) => { + let mut props = props.clone(); + if self.options.optimize { + props.push(PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { + key: PropName::Ident(quote_ident!("_")), + value: Box::new(Expr::Lit(Lit::Num(Number { + span: DUMMY_SP, + value: slot_flag as u8 as f64, + raw: None, + }))), + })))); + } + Expr::Object(ObjectLit { + span: DUMMY_SP, + props, + }) + } + _ => { + if is_component { + self.wrap_children(elems, slot_flag, slots) + } else { + Expr::Array(ArrayLit { + span: DUMMY_SP, + elems, + }) + } + } + }, + _ => { + if is_component { + self.wrap_children(elems, slot_flag, slots) + } else { + Expr::Array(ArrayLit { + span: DUMMY_SP, + elems, + }) + } + } + } + } + + fn wrap_children( + &self, + elems: Vec>, + slot_flag: SlotFlag, + slots: Option>, + ) -> Expr { + let mut props = vec![PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { + key: PropName::Ident(quote_ident!("default")), + value: Box::new(Expr::Arrow(ArrowExpr { + span: DUMMY_SP, + params: vec![], + body: Box::new(BlockStmtOrExpr::Expr(Box::new(Expr::Array(ArrayLit { + span: DUMMY_SP, + elems, + })))), + is_async: false, + is_generator: false, + type_params: None, + return_type: None, + })), + })))]; + + if let Some(expr) = slots { + match *expr { + Expr::Object(ObjectLit { + props: slot_props, .. + }) => props.extend_from_slice(&slot_props), + _ => props.push(PropOrSpread::Spread(SpreadElement { + dot3_token: DUMMY_SP, + expr, + })), + } + } + + if self.options.optimize { + props.push(PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { + key: PropName::Ident(quote_ident!("_")), + value: Box::new(Expr::Lit(Lit::Num(Number { + span: DUMMY_SP, + value: slot_flag as u8 as f64, + raw: None, + }))), + })))); + } + + Expr::Object(ObjectLit { + span: DUMMY_SP, + props, + }) + } + + fn generate_unique_slot_ident(&mut self) -> Ident { + let ident = if self.slot_counter == 1 { + private_ident!("_slot") + } else { + private_ident!(format!("_slot{}", self.slot_counter)) + }; + self.injecting_vars.push(VarDeclarator { + span: DUMMY_SP, + name: Pat::Ident(BindingIdent { + id: ident.clone(), + type_ann: None, + }), + init: None, + definite: false, + }); + + self.slot_counter += 1; + ident + } + + fn transform_jsx_text(&mut self, jsx_text: &JSXText) -> Option { + let text = util::transform_text(&jsx_text.value); + if text.is_empty() { + None + } else { + Some(Expr::Call(CallExpr { + span: DUMMY_SP, + callee: Callee::Expr(Box::new(Expr::Ident( + self.import_from_vue("createTextVNode"), + ))), + args: vec![ExprOrSpread { + spread: None, + expr: Box::new(Expr::Lit(Lit::Str(quote_str!(text)))), + }], + type_args: None, + })) + } + } + + fn resolve_directive(&mut self, directive_name: &str, jsx_element: &JSXElement) -> Expr { + match directive_name { + "show" => Expr::Ident(self.import_from_vue("vShow")), + "model" => match &jsx_element.opening.name { + JSXElementName::Ident(ident) if &ident.sym == "select" => { + Expr::Ident(self.import_from_vue("vModelSelect")) + } + JSXElementName::Ident(ident) if &ident.sym == "textarea" => { + Expr::Ident(self.import_from_vue("vModelText")) + } + _ => { + let typ = + jsx_element.opening.attrs.iter().find_map( + |jsx_attr_or_spread| match jsx_attr_or_spread { + JSXAttrOrSpread::JSXAttr(JSXAttr { + name: JSXAttrName::Ident(ident), + value, + .. + }) if &ident.sym == "type" => value.as_ref(), + _ => None, + }, + ); + match typ { + Some(JSXAttrValue::Lit(Lit::Str(str))) if &str.value == "checkbox" => { + Expr::Ident(self.import_from_vue("vModelCheckbox")) + } + Some(JSXAttrValue::Lit(Lit::Str(str))) if &str.value == "radio" => { + Expr::Ident(self.import_from_vue("vModelRadio")) + } + Some(JSXAttrValue::Lit(Lit::Str(..))) | None => { + Expr::Ident(self.import_from_vue("vModelText")) + } + Some(..) => Expr::Ident(self.import_from_vue("vModelDynamic")), + } + } + }, + _ => Expr::Call(CallExpr { + span: DUMMY_SP, + callee: Callee::Expr(Box::new(Expr::Ident( + self.import_from_vue("resolveDirective"), + ))), + args: vec![ExprOrSpread { + spread: None, + expr: Box::new(Expr::Lit(Lit::Str(quote_str!(directive_name)))), + }], + type_args: None, + }), + } + } + + fn is_component(&self, element_name: &JSXElementName) -> bool { + let name = match element_name { + JSXElementName::Ident(Ident { sym, .. }) => sym, + JSXElementName::JSXMemberExpr(JSXMemberExpr { prop, .. }) => &*prop.sym, + JSXElementName::JSXNamespacedName(JSXNamespacedName { name, .. }) => &*name.sym, + }; + let should_transformed_to_slots = !self + .vue_imports + .get(FRAGMENT) + .map(|ident| &*ident.sym == name) + .unwrap_or_default() + && name != KEEP_ALIVE; + + if matches!(element_name, JSXElementName::JSXMemberExpr(..)) { + should_transformed_to_slots + } else { + self + .options + .custom_element_patterns + .iter() + .all(|pattern| !pattern.is_match(name)) + && should_transformed_to_slots + && !(name.as_bytes()[0].is_ascii_lowercase() + && (css_dataset::tags::STANDARD_HTML_TAGS.contains(name) + || css_dataset::tags::SVG_TAGS.contains(name))) + } + } + + fn get_pragma(&mut self) -> Ident { + self + .pragma + .as_ref() + .or(self.options.pragma.as_ref()) + .map(|name| quote_ident!(name.as_str()).into()) + .unwrap_or_else(|| self.import_from_vue("createVNode")) + } + + fn search_jsx_pragma(&mut self, span: Span) { + if let Some(comments) = &self.comments { + comments.with_leading(span.lo, |comments| { + let pragma = comments.iter().find_map(|comment| { + let trimmed = comment.text.trim(); + trimmed + .strip_prefix('*') + .unwrap_or(trimmed) + .trim() + .strip_prefix("@jsx") + .map(str::trim) + }); + if let Some(pragma) = pragma { + self.pragma = Some(pragma.to_string()); + } + }); + } + } + + fn build_iife(&mut self, elems: Vec>) -> Vec> { + let left = self.assignment_left.take(); + if let Some(left) = left { + elems + .into_iter() + .map(|elem| match elem { + Some(ExprOrSpread { spread: None, expr }) => match *expr { + Expr::Ident(ident) if ident.sym == left.sym => { + let name = private_ident!(format!("_{}", ident.sym)); + self.injecting_consts.push(VarDeclarator { + span: DUMMY_SP, + name: Pat::Ident(BindingIdent { + id: name.clone(), + type_ann: None, + }), + init: Some(Box::new(Expr::Call(CallExpr { + span: DUMMY_SP, + callee: Callee::Expr(Box::new(Expr::Fn(FnExpr { + ident: None, + function: Box::new(Function { + params: vec![], + decorators: vec![], + span: DUMMY_SP, + body: Some(BlockStmt { + span: DUMMY_SP, + stmts: vec![Stmt::Return(ReturnStmt { + span: DUMMY_SP, + arg: Some(Box::new(Expr::Ident(ident))), + })], + }), + is_generator: false, + is_async: false, + type_params: None, + return_type: None, + }), + }))), + args: vec![], + type_args: None, + }))), + definite: false, + }); + Some(ExprOrSpread { + spread: None, + expr: Box::new(Expr::Ident(name)), + }) + } + expr => Some(ExprOrSpread { + spread: None, + expr: Box::new(expr), + }), + }, + _ => elem, + }) + .collect() + } else { + elems + } + } + + fn is_define_component_call(&self, CallExpr { callee, .. }: &CallExpr) -> bool { + callee + .as_expr() + .and_then(|expr| expr.as_ident()) + .and_then(|ident| { + self + .define_component + .map(|ctxt| ctxt == ident.span.ctxt && ident.sym == "defineComponent") + }) + .unwrap_or_default() + } +} + +impl VisitMut for VueJsxTransformVisitor +where + C: Comments, +{ + fn visit_mut_module(&mut self, module: &mut Module) { + self.search_jsx_pragma(module.span); + module + .body + .iter() + .for_each(|item| self.search_jsx_pragma(item.span())); + + module.visit_mut_children_with(self); + + if !self.injecting_consts.is_empty() { + module.body.insert( + 0, + ModuleItem::Stmt(Stmt::Decl(Decl::Var(Box::new(VarDecl { + span: DUMMY_SP, + kind: VarDeclKind::Const, + decls: mem::take(&mut self.injecting_consts), + declare: false, + })))), + ); + } + + if !self.injecting_vars.is_empty() { + module.body.insert( + 0, + ModuleItem::Stmt(Stmt::Decl(Decl::Var(Box::new(VarDecl { + span: DUMMY_SP, + kind: VarDeclKind::Let, + decls: mem::take(&mut self.injecting_vars), + declare: false, + })))), + ); + self.slot_counter = 1; + } + + if let Some(slot_helper) = &self.slot_helper_ident { + module.body.insert( + 0, + ModuleItem::Stmt(Stmt::Decl(Decl::Fn(util::build_slot_helper( + slot_helper.clone(), + self.import_from_vue("isVNode"), + )))), + ) + } + + if let Some(helper) = &self.transform_on_helper { + module.body.insert( + 0, + ModuleItem::ModuleDecl(ModuleDecl::Import(ImportDecl { + span: DUMMY_SP, + specifiers: vec![ImportSpecifier::Default(ImportDefaultSpecifier { + span: DUMMY_SP, + local: helper.clone(), + })], + src: Box::new(quote_str!("@vue/babel-helper-vue-transform-on")), + type_only: false, + with: None, + phase: Default::default(), + })), + ) + } + + if !self.vue_imports.is_empty() { + module.body.insert( + 0, + ModuleItem::ModuleDecl(ModuleDecl::Import(ImportDecl { + span: DUMMY_SP, + specifiers: self + .vue_imports + .iter() + .map(|(imported, local)| { + ImportSpecifier::Named(ImportNamedSpecifier { + span: DUMMY_SP, + local: local.clone(), + imported: Some(ModuleExportName::Ident(quote_ident!(*imported).into())), + is_type_only: false, + }) + }) + .collect(), + src: Box::new(quote_str!("vue")), + type_only: false, + with: None, + phase: Default::default(), + })), + ); + } + } + + fn visit_mut_stmts(&mut self, stmts: &mut Vec) { + stmts.visit_mut_children_with(self); + + if !self.injecting_consts.is_empty() { + stmts.insert( + 0, + Stmt::Decl(Decl::Var(Box::new(VarDecl { + span: DUMMY_SP, + kind: VarDeclKind::Const, + decls: mem::take(&mut self.injecting_consts), + declare: false, + }))), + ); + } + + if !self.injecting_vars.is_empty() { + stmts.insert( + 0, + Stmt::Decl(Decl::Var(Box::new(VarDecl { + span: DUMMY_SP, + kind: VarDeclKind::Let, + decls: mem::take(&mut self.injecting_vars), + declare: false, + }))), + ); + self.slot_counter = 1; + } + } + + fn visit_mut_arrow_expr(&mut self, arrow_expr: &mut ArrowExpr) { + arrow_expr.visit_mut_children_with(self); + + if !self.injecting_consts.is_empty() || !self.injecting_vars.is_empty() { + if let BlockStmtOrExpr::Expr(ret) = &*arrow_expr.body { + let mut stmts = Vec::with_capacity(3); + + if !self.injecting_consts.is_empty() { + stmts.push(Stmt::Decl(Decl::Var(Box::new(VarDecl { + span: DUMMY_SP, + kind: VarDeclKind::Const, + decls: mem::take(&mut self.injecting_consts), + declare: false, + })))); + } + + if !self.injecting_vars.is_empty() { + stmts.push(Stmt::Decl(Decl::Var(Box::new(VarDecl { + span: DUMMY_SP, + kind: VarDeclKind::Let, + decls: mem::take(&mut self.injecting_vars), + declare: false, + })))); + self.slot_counter = 1; + } + + stmts.push(Stmt::Return(ReturnStmt { + span: DUMMY_SP, + arg: Some(ret.clone()), + })); + + arrow_expr.body = Box::new(BlockStmtOrExpr::BlockStmt(BlockStmt { + span: DUMMY_SP, + stmts, + })); + } + } + } + + fn visit_mut_expr(&mut self, expr: &mut Expr) { + expr.visit_mut_children_with(self); + + match expr { + Expr::JSXElement(jsx_element) => *expr = self.transform_jsx_element(jsx_element), + Expr::JSXFragment(jsx_fragment) => *expr = self.transform_jsx_fragment(jsx_fragment), + Expr::Assign(AssignExpr { + left: AssignTarget::Simple(simple_assign_target), + .. + }) => { + if let SimpleAssignTarget::Ident(binding_ident) = &*simple_assign_target { + self.assignment_left = Some(binding_ident.id.clone()); + } + } + _ => {} + } + } + + // decouple `v-models` + fn visit_mut_jsx_opening_element(&mut self, jsx_opening_element: &mut JSXOpeningElement) { + jsx_opening_element.visit_mut_children_with(self); + + let Some(index) = + jsx_opening_element + .attrs + .iter() + .enumerate() + .find_map(|(i, jsx_attr_or_spread)| match jsx_attr_or_spread { + JSXAttrOrSpread::JSXAttr(JSXAttr { + name: JSXAttrName::Ident(Ident { sym, .. }), + .. + }) if sym == "v-models" => Some(i), + _ => None, + }) + else { + return; + }; + + let JSXAttrOrSpread::JSXAttr(JSXAttr { value, .. }) = jsx_opening_element.attrs.remove(index) + else { + unreachable!() + }; + + let Some(JSXAttrValue::JSXExprContainer(JSXExprContainer { + expr: JSXExpr::Expr(expr), + .. + })) = value + else { + HANDLER.with(|handler| { + handler.span_err( + value.span(), + "you should pass a Two-dimensional Arrays to v-models", + ) + }); + return; + }; + let Expr::Array(ArrayLit { elems, .. }) = *expr else { + HANDLER.with(|handler| { + handler.span_err( + expr.span(), + "you should pass a Two-dimensional Arrays to v-models", + ) + }); + return; + }; + + jsx_opening_element + .attrs + .splice(index..index, util::decouple_v_models(elems)); + } + + fn visit_mut_import_decl(&mut self, import_decl: &mut ImportDecl) { + import_decl.visit_mut_children_with(self); + + if import_decl.src.value != "vue" { + return; + } + + let ctxt = import_decl.specifiers.iter().find_map(|specifier| { + if let ImportSpecifier::Named(ImportNamedSpecifier { + local, + imported: None, + .. + }) = specifier + { + (local.sym == "defineComponent").then_some(local.span.ctxt) + } else { + None + } + }); + if let Some(ctxt) = ctxt { + self.define_component = Some(ctxt); + } + } + + fn visit_mut_ts_interface_decl(&mut self, ts_interface_decl: &mut TsInterfaceDecl) { + ts_interface_decl.visit_mut_children_with(self); + if self.options.resolve_type { + let key = ( + ts_interface_decl.id.sym.clone(), + ts_interface_decl.id.span.ctxt, + ); + if let Some(interface) = self.interfaces.get_mut(&key) { + interface + .body + .body + .extend_from_slice(&ts_interface_decl.body.body); + } else { + self.interfaces.insert(key, ts_interface_decl.clone()); + } + } + } + + fn visit_mut_ts_type_alias_decl(&mut self, ts_type_alias_decl: &mut TsTypeAliasDecl) { + ts_type_alias_decl.visit_mut_children_with(self); + if self.options.resolve_type { + self.type_aliases.insert( + ( + ts_type_alias_decl.id.sym.clone(), + ts_type_alias_decl.id.span.ctxt, + ), + (*ts_type_alias_decl.type_ann).clone(), + ); + } + } + + fn visit_mut_call_expr(&mut self, call_expr: &mut CallExpr) { + call_expr.visit_mut_children_with(self); + + if !self.options.resolve_type { + return; + } + + if !self.is_define_component_call(call_expr) { + return; + } + + let Some(maybe_setup) = call_expr.args.first() else { + return; + }; + + let props_types = self.extract_props_type(maybe_setup); + let emits_types = self.extract_emits_type(maybe_setup); + if let Some(prop_types) = props_types { + inject_define_component_option(call_expr, "props", prop_types); + } + if let Some(emits_type) = emits_types { + inject_define_component_option(call_expr, "emits", Expr::Array(emits_type)); + } + } + + fn visit_mut_var_declarator(&mut self, var_declarator: &mut VarDeclarator) { + var_declarator.visit_mut_children_with(self); + + if !self.options.resolve_type { + return; + } + let Pat::Ident(name) = &var_declarator.name else { + return; + }; + let Some(Expr::Call(call)) = var_declarator.init.as_deref_mut() else { + return; + }; + if !self.is_define_component_call(call) { + return; + } + + inject_define_component_option( + call, + "name", + Expr::Lit(Lit::Str(quote_str!(name.sym.clone()))), + ); + } +} + +fn inject_define_component_option(call: &mut CallExpr, name: &'static str, value: Expr) { + let options = call.args.get_mut(1); + if options + .as_ref() + .and_then(|options| options.spread) + .is_some() + { + return; + } + + match options.map(|options| &mut *options.expr) { + Some(Expr::Object(object)) => { + if !object.props.iter().any(|prop| { + prop + .as_prop() + .and_then(|prop| prop.as_key_value()) + .and_then(|key_value| key_value.key.as_ident()) + .map(|ident| ident.sym == name) + .unwrap_or_default() + }) { + object + .props + .push(PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { + key: PropName::Ident(quote_ident!(name)), + value: Box::new(value), + })))); + } + } + Some(..) => { + let expr = Expr::Object(ObjectLit { + props: vec![ + PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { + key: PropName::Ident(quote_ident!(name)), + value: Box::new(value), + }))), + PropOrSpread::Spread(SpreadElement { + expr: call.args.remove(1).expr, + dot3_token: DUMMY_SP, + }), + ], + span: DUMMY_SP, + }); + call.args.insert( + 1, + ExprOrSpread { + expr: Box::new(expr), + spread: None, + }, + ); + } + None => { + call.args.push(ExprOrSpread { + expr: Box::new(Expr::Object(ObjectLit { + props: vec![PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { + key: PropName::Ident(quote_ident!(name)), + value: Box::new(value), + })))], + span: DUMMY_SP, + })), + spread: None, + }); + } + } +} diff --git a/rust-plugins/vue-jsx/crates/visitor/src/options.rs b/rust-plugins/vue-jsx/crates/visitor/src/options.rs new file mode 100644 index 0000000..2e8105b --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/src/options.rs @@ -0,0 +1,92 @@ +use serde::{ + de::{Error, Unexpected, Visitor}, + Deserialize, Deserializer, +}; +use std::{fmt, ops::Deref}; + +#[derive(Clone, Debug, Deserialize)] +#[serde(rename_all = "camelCase", default)] +pub struct Options { + pub transform_on: bool, + pub optimize: bool, + pub custom_element_patterns: Vec, + pub merge_props: bool, + pub enable_object_slots: bool, + pub pragma: Option, + pub resolve_type: bool, +} + +impl Default for Options { + fn default() -> Self { + Self { + transform_on: false, + optimize: false, + custom_element_patterns: Default::default(), + merge_props: true, + enable_object_slots: true, + pragma: None, + resolve_type: false, + } + } +} + +#[derive(Clone, Debug)] +pub struct Regex(regex::Regex); + +impl Regex { + pub fn new(re: &str) -> Result { + regex::Regex::new(re).map(Self) + } +} + +impl From for Regex { + fn from(value: regex::Regex) -> Self { + Self(value) + } +} + +impl Deref for Regex { + type Target = regex::Regex; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl<'de> Deserialize<'de> for Regex { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_string(RegexVisitor) + } +} + +/// Serde visitor for parsing string as the [`Regex`] type. +struct RegexVisitor; + +impl<'de> Visitor<'de> for RegexVisitor { + type Value = Regex; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "a string that represents a regex") + } + + fn visit_str(self, v: &str) -> Result + where + E: Error, + { + regex::Regex::new(v) + .map(Regex) + .map_err(|_| E::invalid_value(Unexpected::Str(v), &"a valid regex")) + } + + fn visit_string(self, v: String) -> Result + where + E: Error, + { + regex::Regex::new(&v) + .map(Regex) + .map_err(|_| E::invalid_value(Unexpected::Str(&v), &"a valid regex")) + } +} diff --git a/rust-plugins/vue-jsx/crates/visitor/src/patch_flags.rs b/rust-plugins/vue-jsx/crates/visitor/src/patch_flags.rs new file mode 100644 index 0000000..871b604 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/src/patch_flags.rs @@ -0,0 +1,20 @@ +use bitflags::bitflags; + +bitflags! { + #[derive(PartialEq, Eq)] + pub struct PatchFlags: i16 { + const TEXT = 1; + const CLASS = 1 << 1; + const STYLE = 1 << 2; + const PROPS = 1 << 3; + const FULL_PROPS = 1 << 4; + const HYDRATE_EVENTS = 1 << 5; + const STABLE_FRAGMENT = 1 << 6; + const KEYED_FRAGMENT = 1 << 7; + const UNKEYED_FRAGMENT = 1 << 8; + const NEED_PATCH = 1 << 9; + const DYNAMIC_SLOTS = 1 << 10; + const HOISTED = -1; + const BAIL = -2; + } +} diff --git a/rust-plugins/vue-jsx/crates/visitor/src/resolve_type.rs b/rust-plugins/vue-jsx/crates/visitor/src/resolve_type.rs new file mode 100644 index 0000000..078586c --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/src/resolve_type.rs @@ -0,0 +1,1160 @@ +use crate::VueJsxTransformVisitor; +use indexmap::{IndexMap, IndexSet}; +use std::borrow::Cow; +use farmfe_core::{ + swc_common::{comments::Comments, errors::HANDLER, EqIgnoreSpan, Span, Spanned, DUMMY_SP}, + swc_ecma_ast::*, +}; +use farmfe_toolkit::{ + swc_atoms::{js_word, JsWord}, + swc_ecma_utils::{quote_ident, quote_str}, +}; + +enum RefinedTsTypeElement { + Property(TsPropertySignature), + GetterSignature(TsGetterSignature), + MethodSignature(TsMethodSignature), + CallSignature(TsCallSignatureDecl), +} + +struct PropIr { + types: IndexSet>, + required: bool, +} + +impl VueJsxTransformVisitor +where + C: Comments, +{ + pub(crate) fn extract_props_type(&mut self, setup_fn: &ExprOrSpread) -> Option { + let mut defaults = None; + let Some(first_param_type) = (if let ExprOrSpread { expr, spread: None } = setup_fn { + match &**expr { + Expr::Arrow(arrow) => arrow.params.first().and_then(|param| { + if let Pat::Assign(AssignPat { right, .. }) = param { + defaults = Some(&**right); + } + extract_type_ann_from_pat(param) + }), + Expr::Fn(fn_expr) => fn_expr.function.params.first().and_then(|param| { + if let Pat::Assign(AssignPat { right, .. }) = ¶m.pat { + defaults = Some(&**right); + } + extract_type_ann_from_pat(¶m.pat) + }), + _ => None, + } + } else { + None + }) else { + return None; + }; + + enum Defaults<'n> { + Static(Vec<(Cow<'n, PropName>, Expr)>), + Dynamic(&'n Expr), + } + let defaults = defaults.map(|defaults| { + if let Expr::Object(ObjectLit { props, .. }) = defaults { + if let Some(props) = props + .iter() + .map(|prop| { + if let PropOrSpread::Prop(prop) = prop { + match &**prop { + Prop::Shorthand(ident) => Some(( + Cow::Owned(PropName::Ident(ident.clone().into())), + Expr::Arrow(ArrowExpr { + params: vec![], + body: Box::new(BlockStmtOrExpr::Expr(Box::new(Expr::Ident(ident.clone())))), + is_async: false, + is_generator: false, + span: DUMMY_SP, + type_params: None, + return_type: None, + }), + )), + Prop::KeyValue(KeyValueProp { key, value }) => { + let Some(key) = try_unwrap_lit_prop_name(key) else { + return None; + }; + Some(( + key, + if value.is_lit() { + (**value).clone() + } else { + Expr::Arrow(ArrowExpr { + params: vec![], + body: Box::new(BlockStmtOrExpr::Expr(value.clone())), + is_async: false, + is_generator: false, + span: DUMMY_SP, + type_params: None, + return_type: None, + }) + }, + )) + } + Prop::Getter(GetterProp { + key, + body: Some(body), + .. + }) => { + let Some(key) = try_unwrap_lit_prop_name(key) else { + return None; + }; + Some(( + key, + Expr::Arrow(ArrowExpr { + params: vec![], + body: Box::new(BlockStmtOrExpr::BlockStmt(body.clone())), + is_async: false, + is_generator: false, + span: DUMMY_SP, + type_params: None, + return_type: None, + }), + )) + } + Prop::Method(MethodProp { key, function }) => { + let Some(key) = try_unwrap_lit_prop_name(key) else { + return None; + }; + Some(( + key, + Expr::Fn(FnExpr { + ident: None, + function: function.clone(), + }), + )) + } + _ => None, + } + } else { + None + } + }) + .collect::>>() + { + Defaults::Static(props) + } else { + Defaults::Dynamic(defaults) + } + } else { + Defaults::Dynamic(defaults) + } + }); + + Some(match defaults { + Some(Defaults::Static(props)) => { + Expr::Object(self.build_props_type(first_param_type, Some(props))) + } + Some(Defaults::Dynamic(expr)) => { + let merge_defaults = self.import_from_vue("mergeDefaults"); + Expr::Call(CallExpr { + callee: Callee::Expr(Box::new(Expr::Ident(merge_defaults))), + args: vec![ + ExprOrSpread { + expr: Box::new(Expr::Object(self.build_props_type(first_param_type, None))), + spread: None, + }, + ExprOrSpread { + expr: Box::new(expr.clone()), + spread: None, + }, + ], + span: if let Some(comments) = &self.comments { + let span = Span::dummy_with_cmt(); + comments.add_pure_comment(span.lo); + span + } else { + DUMMY_SP + }, + type_args: None, + }) + } + None => Expr::Object(self.build_props_type(first_param_type, None)), + }) + } + + fn build_props_type( + &self, + TsTypeAnn { type_ann, .. }: &TsTypeAnn, + defaults: Option, Expr)>>, + ) -> ObjectLit { + let mut props = Vec::with_capacity(3); + self.resolve_type_elements(type_ann, &mut props); + + let cap = props.len(); + let irs = props.into_iter().fold( + IndexMap::::with_capacity(cap), + |mut irs, prop| { + match prop { + RefinedTsTypeElement::Property(TsPropertySignature { + key, + computed, + optional, + type_ann, + .. + }) => { + let prop_name = extract_prop_name(*key, computed); + let types = if let Some(type_ann) = type_ann { + self.infer_runtime_type(&type_ann.type_ann) + } else { + let mut types = IndexSet::with_capacity(1); + types.insert(None); + types + }; + if let Some((_, ir)) = irs + .iter_mut() + .find(|(key, _)| prop_name.eq_ignore_span(key)) + { + if optional { + ir.required = false; + } + ir.types.extend(types); + } else { + irs.insert( + prop_name, + PropIr { + types, + required: !optional, + }, + ); + } + } + RefinedTsTypeElement::GetterSignature(TsGetterSignature { + key, + computed, + type_ann, + .. + }) => { + let prop_name = extract_prop_name(*key, computed); + let types = if let Some(type_ann) = type_ann { + self.infer_runtime_type(&type_ann.type_ann) + } else { + let mut types = IndexSet::with_capacity(1); + types.insert(None); + types + }; + if let Some((_, ir)) = irs + .iter_mut() + .find(|(key, _)| prop_name.eq_ignore_span(key)) + { + ir.types.extend(types); + } else { + irs.insert( + prop_name, + PropIr { + types, + required: true, + }, + ); + } + } + RefinedTsTypeElement::MethodSignature(TsMethodSignature { + key, + computed, + optional, + .. + }) => { + let prop_name = extract_prop_name(*key, computed); + let ty = Some(js_word!("Function")); + if let Some((_, ir)) = irs + .iter_mut() + .find(|(key, _)| prop_name.eq_ignore_span(key)) + { + if optional { + ir.required = false; + } + ir.types.insert(ty); + } else { + let mut types = IndexSet::with_capacity(1); + types.insert(ty); + irs.insert( + prop_name, + PropIr { + types, + required: !optional, + }, + ); + } + } + RefinedTsTypeElement::CallSignature(..) => {} + } + irs + }, + ); + + ObjectLit { + props: irs + .into_iter() + .map(|(prop_name, mut ir)| { + let mut props = vec![ + PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { + key: PropName::Ident(quote_ident!("type")), + value: Box::new(if ir.types.len() == 1 { + if let Some(ty) = ir.types.pop().unwrap() { + Expr::Ident(quote_ident!(ty).into()) + } else { + Expr::Lit(Lit::Null(Null { span: DUMMY_SP })) + } + } else { + Expr::Array(ArrayLit { + elems: ir + .types + .into_iter() + .map(|ty| { + Some(ExprOrSpread { + expr: Box::new(if let Some(ty) = ty { + Expr::Ident(quote_ident!(ty).into()) + } else { + Expr::Lit(Lit::Null(Null { span: DUMMY_SP })) + }), + spread: None, + }) + }) + .collect(), + span: DUMMY_SP, + }) + }), + }))), + PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { + key: PropName::Ident(quote_ident!("required")), + value: Box::new(Expr::Lit(Lit::Bool(Bool { + value: ir.required, + span: DUMMY_SP, + }))), + }))), + ]; + if let Some((_, default)) = defaults.iter().flatten().find(|(name, _)| { + name.eq_ignore_span(&prop_name) + || if let ( + PropName::Ident(Ident { sym: a, .. }), + PropName::Str(Str { value: b, .. }), + ) + | ( + PropName::Str(Str { value: a, .. }), + PropName::Ident(Ident { sym: b, .. }), + ) = (&**name, &prop_name) + { + a == b + } else { + false + } + }) { + props.push(PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { + key: PropName::Ident(quote_ident!("default")), + value: Box::new(default.clone()), + })))); + } + PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { + key: prop_name, + value: Box::new(Expr::Object(ObjectLit { + props, + span: DUMMY_SP, + })), + }))) + }) + .collect(), + span: DUMMY_SP, + } + } + + fn resolve_type_elements(&self, ty: &TsType, props: &mut Vec) { + match ty { + TsType::TsTypeLit(TsTypeLit { members, .. }) => { + props.extend(members.iter().filter_map(|member| match member { + TsTypeElement::TsPropertySignature(prop) => { + Some(RefinedTsTypeElement::Property(prop.clone())) + } + TsTypeElement::TsMethodSignature(method) => { + Some(RefinedTsTypeElement::MethodSignature(method.clone())) + } + TsTypeElement::TsGetterSignature(getter) => { + Some(RefinedTsTypeElement::GetterSignature(getter.clone())) + } + TsTypeElement::TsCallSignatureDecl(call) => { + Some(RefinedTsTypeElement::CallSignature(call.clone())) + } + _ => None, + })); + } + TsType::TsUnionOrIntersectionType( + TsUnionOrIntersectionType::TsIntersectionType(TsIntersectionType { types, .. }) + | TsUnionOrIntersectionType::TsUnionType(TsUnionType { types, .. }), + ) => { + types + .iter() + .for_each(|ty| self.resolve_type_elements(ty, props)); + } + TsType::TsTypeRef(TsTypeRef { + type_name: TsEntityName::Ident(ident), + type_params, + span: _, + .. + }) => { + let key = (ident.sym.clone(), ident.span.ctxt); + if let Some(aliased) = self.type_aliases.get(&key) { + self.resolve_type_elements(aliased, props); + } else if let Some(TsInterfaceDecl { + extends, + body: TsInterfaceBody { body, .. }, + .. + }) = self.interfaces.get(&key) + { + props.extend(body.iter().filter_map(|element| match element { + TsTypeElement::TsPropertySignature(prop) => { + Some(RefinedTsTypeElement::Property(prop.clone())) + } + TsTypeElement::TsMethodSignature(method) => { + Some(RefinedTsTypeElement::MethodSignature(method.clone())) + } + TsTypeElement::TsGetterSignature(getter) => { + Some(RefinedTsTypeElement::GetterSignature(getter.clone())) + } + TsTypeElement::TsCallSignatureDecl(call) => { + Some(RefinedTsTypeElement::CallSignature(call.clone())) + } + _ => None, + })); + extends + .iter() + .filter_map(|parent| parent.expr.as_ident()) + .for_each(|ident| { + self.resolve_type_elements( + &TsType::TsTypeRef(TsTypeRef { + type_name: TsEntityName::Ident(ident.clone()), + type_params: None, + span: DUMMY_SP, + }), + props, + ) + }); + } else if ident.span.ctxt.has_mark(self.unresolved_mark) { + match &*ident.sym { + "Partial" => { + if let Some(param) = type_params + .as_deref() + .and_then(|params| params.params.first()) + { + let mut inner_props = vec![]; + self.resolve_type_elements(param, &mut inner_props); + props.extend(inner_props.into_iter().map(|mut prop| { + match &mut prop { + RefinedTsTypeElement::Property(property) => { + property.optional = true; + } + RefinedTsTypeElement::MethodSignature(method) => { + method.optional = true; + } + RefinedTsTypeElement::GetterSignature(..) => {} + RefinedTsTypeElement::CallSignature(..) => {} + } + prop + })); + } + } + "Required" => { + if let Some(param) = type_params + .as_deref() + .and_then(|params| params.params.first()) + { + let mut inner_props = vec![]; + self.resolve_type_elements(param, &mut inner_props); + props.extend(inner_props.into_iter().map(|mut prop| { + match &mut prop { + RefinedTsTypeElement::Property(TsPropertySignature { optional, .. }) + | RefinedTsTypeElement::MethodSignature(TsMethodSignature { + optional, .. + }) => { + *optional = false; + } + RefinedTsTypeElement::GetterSignature(..) + | RefinedTsTypeElement::CallSignature(..) => {} + } + prop + })); + } + } + "Pick" => { + if let Some((object, keys)) = type_params + .as_deref() + .and_then(|params| params.params.first().zip(params.params.get(1))) + { + let keys = self.resolve_string_or_union_strings(keys); + let mut inner_props = vec![]; + self.resolve_type_elements(object, &mut inner_props); + props.extend(inner_props.into_iter().filter(|prop| match prop { + RefinedTsTypeElement::Property(TsPropertySignature { key, .. }) + | RefinedTsTypeElement::MethodSignature(TsMethodSignature { key, .. }) + | RefinedTsTypeElement::GetterSignature(TsGetterSignature { key, .. }) => { + match &**key { + Expr::Ident(ident) => keys.contains(&ident.sym), + Expr::Lit(Lit::Str(str)) => keys.contains(&str.value), + _ => false, + } + } + RefinedTsTypeElement::CallSignature(..) => false, + })); + } + } + "Omit" => { + if let Some((object, keys)) = type_params + .as_deref() + .and_then(|params| params.params.first().zip(params.params.get(1))) + { + let keys = self.resolve_string_or_union_strings(keys); + let mut inner_props = vec![]; + self.resolve_type_elements(object, &mut inner_props); + props.extend(inner_props.into_iter().filter(|prop| match prop { + RefinedTsTypeElement::Property(TsPropertySignature { key, .. }) + | RefinedTsTypeElement::MethodSignature(TsMethodSignature { key, .. }) + | RefinedTsTypeElement::GetterSignature(TsGetterSignature { key, .. }) => { + match &**key { + Expr::Ident(ident) => !keys.contains(&ident.sym), + Expr::Lit(Lit::Str(str)) => !keys.contains(&str.value), + _ => true, + } + } + RefinedTsTypeElement::CallSignature(..) => true, + })); + } + } + _ => { + HANDLER.with(|handler| { + handler.span_err( + ident.span, + "Unresolvable type reference or unsupported built-in utility type.", + ); + }); + } + } + } else { + HANDLER.with(|handler| { + handler.span_err(ident.span, "Types from other modules can't be resolved."); + }); + } + } + TsType::TsIndexedAccessType(TsIndexedAccessType { + obj_type, + index_type, + .. + }) => { + if let Some(ty) = self.resolve_indexed_access(obj_type, index_type) { + self.resolve_type_elements(&ty, props); + } else { + HANDLER.with(|handler| { + handler.span_err(ty.span(), "Unresolvable type."); + }); + } + } + TsType::TsFnOrConstructorType(TsFnOrConstructorType::TsFnType(TsFnType { + params, + type_params, + type_ann, + .. + })) => { + props.push(RefinedTsTypeElement::CallSignature(TsCallSignatureDecl { + params: params.clone(), + type_ann: Some(type_ann.clone()), + type_params: type_params.clone(), + span: DUMMY_SP, + })); + } + TsType::TsParenthesizedType(TsParenthesizedType { type_ann, .. }) + | TsType::TsOptionalType(TsOptionalType { type_ann, .. }) => { + self.resolve_type_elements(type_ann, props); + } + _ => { + HANDLER.with(|handler| { + handler.span_err(ty.span(), "Unresolvable type."); + }) + } + } + } + + fn resolve_string_or_union_strings(&self, ty: &TsType) -> Vec { + match ty { + TsType::TsLitType(TsLitType { + lit: TsLit::Str(key), + .. + }) => vec![key.value.clone()], + TsType::TsUnionOrIntersectionType(TsUnionOrIntersectionType::TsUnionType(TsUnionType { + types, + .. + })) => types + .iter() + .fold(Vec::with_capacity(types.len()), |mut strings, ty| { + if let TsType::TsLitType(TsLitType { + lit: TsLit::Str(str), + .. + }) = &**ty + { + strings.push(str.value.clone()); + } else { + strings.extend_from_slice(&self.resolve_string_or_union_strings(ty)); + } + strings + }), + TsType::TsTypeRef(TsTypeRef { + type_name: TsEntityName::Ident(ident), + .. + }) => { + if let Some(aliased) = self.type_aliases.get(&(ident.sym.clone(), ident.span.ctxt)) { + self.resolve_string_or_union_strings(aliased) + } else if ident.span.ctxt.has_mark(self.unresolved_mark) { + HANDLER.with(|handler| { + handler.span_err( + ty.span(), + "Unresolvable type reference or unsupported built-in utility type.", + ); + }); + vec![] + } else { + HANDLER.with(|handler| { + handler.span_err(ty.span(), "Types from other modules can't be resolved."); + }); + vec![] + } + } + _ => { + HANDLER.with(|handler| handler.span_err(ty.span(), "Unsupported type as index key.")); + vec![] + } + } + } + + fn resolve_indexed_access(&self, obj: &TsType, index: &TsType) -> Option { + match obj { + TsType::TsTypeRef(TsTypeRef { + type_name: TsEntityName::Ident(ident), + type_params, + .. + }) => { + let key = (ident.sym.clone(), ident.span.ctxt); + if let Some(aliased) = self.type_aliases.get(&key) { + self.resolve_indexed_access(aliased, index) + } else if let Some(interface) = self.interfaces.get(&key) { + let mut properties = match index { + TsType::TsKeywordType(TsKeywordType { + kind: TsKeywordTypeKind::TsStringKeyword, + .. + }) => interface + .body + .body + .iter() + .filter_map(|element| match element { + TsTypeElement::TsCallSignatureDecl(..) + | TsTypeElement::TsConstructSignatureDecl(..) + | TsTypeElement::TsSetterSignature(..) => None, + TsTypeElement::TsPropertySignature(TsPropertySignature { + key, type_ann, .. + }) + | TsTypeElement::TsGetterSignature(TsGetterSignature { key, type_ann, .. }) => { + if matches!(&**key, Expr::Ident(..) | Expr::Lit(Lit::Str(..))) { + type_ann.as_ref().map(|type_ann| type_ann.type_ann.clone()) + } else { + None + } + } + TsTypeElement::TsIndexSignature(TsIndexSignature { type_ann, .. }) => { + type_ann.as_ref().map(|type_ann| type_ann.type_ann.clone()) + } + TsTypeElement::TsMethodSignature(..) => { + Some(Box::new(TsType::TsTypeRef(TsTypeRef { + type_name: TsEntityName::Ident(quote_ident!("Function").into()), + type_params: None, + span: DUMMY_SP, + }))) + } + }) + .collect(), + TsType::TsLitType(TsLitType { + lit: TsLit::Str(..), + .. + }) + | TsType::TsUnionOrIntersectionType(TsUnionOrIntersectionType::TsUnionType(..)) + | TsType::TsTypeRef(..) => { + let keys = self.resolve_string_or_union_strings(index); + interface + .body + .body + .iter() + .filter_map(|element| match element { + TsTypeElement::TsPropertySignature(TsPropertySignature { + key, type_ann, .. + }) + | TsTypeElement::TsGetterSignature(TsGetterSignature { key, type_ann, .. }) => { + if let Expr::Ident(Ident { sym: key, .. }) + | Expr::Lit(Lit::Str(Str { value: key, .. })) = &**key + { + if keys.contains(key) { + type_ann.as_ref().map(|type_ann| type_ann.type_ann.clone()) + } else { + None + } + } else { + None + } + } + TsTypeElement::TsMethodSignature(TsMethodSignature { key, .. }) => { + if let Expr::Ident(Ident { sym: key, .. }) + | Expr::Lit(Lit::Str(Str { value: key, .. })) = &**key + { + if keys.contains(key) { + Some(Box::new(TsType::TsTypeRef(TsTypeRef { + type_name: TsEntityName::Ident(quote_ident!("Function").into()), + type_params: None, + span: DUMMY_SP, + }))) + } else { + None + } + } else { + None + } + } + TsTypeElement::TsCallSignatureDecl(..) + | TsTypeElement::TsConstructSignatureDecl(..) + | TsTypeElement::TsSetterSignature(..) + | TsTypeElement::TsIndexSignature(..) => None, + }) + .collect() + } + _ => vec![], + }; + if properties.len() == 1 { + Some((*properties.remove(0)).clone()) + } else { + Some(TsType::TsUnionOrIntersectionType( + TsUnionOrIntersectionType::TsUnionType(TsUnionType { + types: properties, + span: DUMMY_SP, + }), + )) + } + } else if ident.span.ctxt.has_mark(self.unresolved_mark) { + if ident.sym == "Array" { + type_params + .as_ref() + .and_then(|params| params.params.first()) + .map(|ty| (**ty).clone()) + } else { + None + } + } else { + None + } + } + TsType::TsTypeLit(TsTypeLit { members, .. }) => { + let mut properties = match index { + TsType::TsKeywordType(TsKeywordType { + kind: TsKeywordTypeKind::TsStringKeyword, + .. + }) => members + .iter() + .filter_map(|member| match member { + TsTypeElement::TsCallSignatureDecl(..) + | TsTypeElement::TsConstructSignatureDecl(..) + | TsTypeElement::TsSetterSignature(..) => None, + TsTypeElement::TsPropertySignature(TsPropertySignature { key, type_ann, .. }) + | TsTypeElement::TsGetterSignature(TsGetterSignature { key, type_ann, .. }) => { + if matches!(&**key, Expr::Ident(..) | Expr::Lit(Lit::Str(..))) { + type_ann.as_ref().map(|type_ann| type_ann.type_ann.clone()) + } else { + None + } + } + TsTypeElement::TsIndexSignature(TsIndexSignature { type_ann, .. }) => { + type_ann.as_ref().map(|type_ann| type_ann.type_ann.clone()) + } + TsTypeElement::TsMethodSignature(..) => { + Some(Box::new(TsType::TsTypeRef(TsTypeRef { + type_name: TsEntityName::Ident(quote_ident!("Function").into()), + type_params: None, + span: DUMMY_SP, + }))) + } + }) + .collect(), + TsType::TsLitType(TsLitType { + lit: TsLit::Str(..), + .. + }) + | TsType::TsTypeRef(..) + | TsType::TsUnionOrIntersectionType(TsUnionOrIntersectionType::TsUnionType(..)) => { + let keys = self.resolve_string_or_union_strings(index); + members + .iter() + .filter_map(|member| match member { + TsTypeElement::TsPropertySignature(TsPropertySignature { + key, type_ann, .. + }) + | TsTypeElement::TsGetterSignature(TsGetterSignature { key, type_ann, .. }) => { + if let Expr::Ident(Ident { sym: key, .. }) + | Expr::Lit(Lit::Str(Str { value: key, .. })) = &**key + { + if keys.contains(key) { + type_ann.as_ref().map(|type_ann| type_ann.type_ann.clone()) + } else { + None + } + } else { + None + } + } + TsTypeElement::TsMethodSignature(TsMethodSignature { key, .. }) => { + if let Expr::Ident(Ident { sym: key, .. }) + | Expr::Lit(Lit::Str(Str { value: key, .. })) = &**key + { + if keys.contains(key) { + Some(Box::new(TsType::TsTypeRef(TsTypeRef { + type_name: TsEntityName::Ident(quote_ident!("Function").into()), + type_params: None, + span: DUMMY_SP, + }))) + } else { + None + } + } else { + None + } + } + TsTypeElement::TsCallSignatureDecl(..) + | TsTypeElement::TsConstructSignatureDecl(..) + | TsTypeElement::TsSetterSignature(..) + | TsTypeElement::TsIndexSignature(..) => None, + }) + .collect() + } + _ => vec![], + }; + if properties.len() == 1 { + Some(*properties.remove(0)) + } else { + Some(TsType::TsUnionOrIntersectionType( + TsUnionOrIntersectionType::TsUnionType(TsUnionType { + types: properties, + span: DUMMY_SP, + }), + )) + } + } + TsType::TsArrayType(TsArrayType { elem_type, .. }) => { + if matches!( + index, + TsType::TsKeywordType(TsKeywordType { + kind: TsKeywordTypeKind::TsNumberKeyword, + .. + }) | TsType::TsLitType(TsLitType { + lit: TsLit::Number(..), + .. + }) + ) { + Some((**elem_type).clone()) + } else { + None + } + } + TsType::TsTupleType(TsTupleType { elem_types, .. }) => match index { + TsType::TsLitType(TsLitType { + lit: TsLit::Number(num), + .. + }) => elem_types + .get(num.value as usize) + .map(|element| (*element.ty).clone()), + TsType::TsKeywordType(TsKeywordType { + kind: TsKeywordTypeKind::TsNumberKeyword, + .. + }) => Some(TsType::TsUnionOrIntersectionType( + TsUnionOrIntersectionType::TsUnionType(TsUnionType { + types: elem_types + .iter() + .map(|TsTupleElement { ty, .. }| ty.clone()) + .collect(), + span: DUMMY_SP, + }), + )), + _ => None, + }, + _ => None, + } + } + + fn infer_runtime_type(&self, ty: &TsType) -> IndexSet> { + let mut runtime_types = IndexSet::with_capacity(1); + match ty { + TsType::TsKeywordType(keyword) => match keyword.kind { + TsKeywordTypeKind::TsStringKeyword => { + runtime_types.insert(Some(js_word!("String"))); + } + TsKeywordTypeKind::TsNumberKeyword => { + runtime_types.insert(Some(js_word!("Number"))); + } + TsKeywordTypeKind::TsBooleanKeyword => { + runtime_types.insert(Some(js_word!("Boolean"))); + } + TsKeywordTypeKind::TsObjectKeyword => { + runtime_types.insert(Some(js_word!("Object"))); + } + TsKeywordTypeKind::TsNullKeyword => { + runtime_types.insert(None); + } + TsKeywordTypeKind::TsBigIntKeyword => { + runtime_types.insert(Some(js_word!("BigInt"))); + } + TsKeywordTypeKind::TsSymbolKeyword => { + runtime_types.insert(Some(js_word!("Symbol"))); + } + _ => { + runtime_types.insert(None); + } + }, + TsType::TsTypeLit(TsTypeLit { members, .. }) => { + members.iter().for_each(|member| { + if let TsTypeElement::TsCallSignatureDecl(..) + | TsTypeElement::TsConstructSignatureDecl(..) = member + { + runtime_types.insert(Some(js_word!("Function"))); + } else { + runtime_types.insert(Some(js_word!("Object"))); + } + }); + } + TsType::TsFnOrConstructorType(..) => { + runtime_types.insert(Some(js_word!("Function"))); + } + TsType::TsArrayType(..) | TsType::TsTupleType(..) => { + runtime_types.insert(Some(js_word!("Array"))); + } + TsType::TsLitType(TsLitType { lit, .. }) => match lit { + TsLit::Str(..) | TsLit::Tpl(..) => { + runtime_types.insert(Some(js_word!("String"))); + } + TsLit::Bool(..) => { + runtime_types.insert(Some(js_word!("Boolean"))); + } + TsLit::Number(..) | TsLit::BigInt(..) => { + runtime_types.insert(Some(js_word!("Number"))); + } + }, + TsType::TsTypeRef(TsTypeRef { + type_name: TsEntityName::Ident(ident), + type_params, + .. + }) => { + let key = (ident.sym.clone(), ident.span.ctxt); + if let Some(aliased) = self.type_aliases.get(&key) { + runtime_types.extend(self.infer_runtime_type(aliased)); + } else if let Some(TsInterfaceDecl { + body: TsInterfaceBody { body, .. }, + .. + }) = self.interfaces.get(&key) + { + body.iter().for_each(|element| { + if let TsTypeElement::TsCallSignatureDecl(..) + | TsTypeElement::TsConstructSignatureDecl(..) = element + { + runtime_types.insert(Some(js_word!("Function"))); + } else { + runtime_types.insert(Some(js_word!("Object"))); + } + }); + } else { + match &*ident.sym { + "Array" | "Function" | "Object" | "Set" | "Map" | "WeakSet" | "WeakMap" | "Date" + | "Promise" | "Error" | "RegExp" => { + runtime_types.insert(Some(ident.sym.clone())); + } + "Partial" | "Required" | "Readonly" | "Record" | "Pick" | "Omit" | "InstanceType" => { + runtime_types.insert(Some(js_word!("Object"))); + } + "Uppercase" | "Lowercase" | "Capitalize" | "Uncapitalize" => { + runtime_types.insert(Some(js_word!("String"))); + } + "Parameters" | "ConstructorParameters" => { + runtime_types.insert(Some(js_word!("Array"))); + } + "NonNullable" => { + if let Some(ty) = type_params + .as_ref() + .and_then(|type_params| type_params.params.first()) + { + let types = self.infer_runtime_type(ty); + runtime_types.extend(types.into_iter().filter(|ty| ty.is_some())); + } else { + runtime_types.insert(Some(js_word!("Object"))); + } + } + "Exclude" | "OmitThisParameter" => { + if let Some(ty) = type_params + .as_ref() + .and_then(|type_params| type_params.params.first()) + { + runtime_types.extend(self.infer_runtime_type(ty)); + } else { + runtime_types.insert(Some(js_word!("Object"))); + } + } + "Extract" => { + if let Some(ty) = type_params + .as_ref() + .and_then(|type_params| type_params.params.get(1)) + { + runtime_types.extend(self.infer_runtime_type(ty)); + } else { + runtime_types.insert(Some(js_word!("Object"))); + } + } + _ => { + runtime_types.insert(Some(js_word!("Object"))); + } + } + } + } + TsType::TsParenthesizedType(TsParenthesizedType { type_ann, .. }) => { + runtime_types.extend(self.infer_runtime_type(type_ann)); + } + TsType::TsUnionOrIntersectionType( + TsUnionOrIntersectionType::TsUnionType(TsUnionType { types, .. }) + | TsUnionOrIntersectionType::TsIntersectionType(TsIntersectionType { types, .. }), + ) => runtime_types.extend(types.iter().flat_map(|ty| self.infer_runtime_type(ty))), + TsType::TsIndexedAccessType(TsIndexedAccessType { + obj_type, + index_type, + .. + }) => { + if let Some(ty) = self.resolve_indexed_access(obj_type, index_type) { + runtime_types.extend(self.infer_runtime_type(&ty)); + } + } + TsType::TsOptionalType(TsOptionalType { type_ann, .. }) => { + runtime_types.extend(self.infer_runtime_type(type_ann)); + } + _ => { + runtime_types.insert(Some(js_word!("Object"))); + } + }; + runtime_types + } + + pub(crate) fn extract_emits_type(&self, setup_fn: &ExprOrSpread) -> Option { + let Some(TsTypeAnn { + type_ann: second_param_type, + .. + }) = (if let ExprOrSpread { expr, spread: None } = setup_fn { + match &**expr { + Expr::Arrow(arrow) => match arrow.params.get(1) { + Some(Pat::Ident(ident)) => ident.type_ann.as_deref(), + Some(Pat::Array(array)) => array.type_ann.as_deref(), + Some(Pat::Object(object)) => object.type_ann.as_deref(), + _ => return None, + }, + Expr::Fn(fn_expr) => match fn_expr.function.params.get(1).map(|param| ¶m.pat) { + Some(Pat::Ident(ident)) => ident.type_ann.as_deref(), + Some(Pat::Array(array)) => array.type_ann.as_deref(), + Some(Pat::Object(object)) => object.type_ann.as_deref(), + _ => return None, + }, + _ => return None, + } + } else { + return None; + }) + else { + return None; + }; + + match &**second_param_type { + TsType::TsTypeRef(TsTypeRef { + type_name: TsEntityName::Ident(ident), + type_params: Some(type_params), + .. + }) if ident.sym == "SetupContext" => { + if let Some(emits_def) = type_params.params.first() { + let mut emits = Vec::with_capacity(1); + self.resolve_type_elements(emits_def, &mut emits); + Some(ArrayLit { + elems: emits + .into_iter() + .flat_map(|emit| match emit { + RefinedTsTypeElement::MethodSignature(TsMethodSignature { key, .. }) + | RefinedTsTypeElement::Property(TsPropertySignature { key, .. }) => match &*key { + Expr::Ident(ident) => vec![ident.sym.clone()], + Expr::Lit(Lit::Str(str)) => vec![str.value.clone()], + _ => vec![], + }, + RefinedTsTypeElement::CallSignature(TsCallSignatureDecl { params, .. }) => params + .first() + .and_then(|param| match param { + TsFnParam::Ident(ident) => ident.type_ann.as_deref(), + TsFnParam::Array(array) => array.type_ann.as_deref(), + TsFnParam::Rest(rest) => rest.type_ann.as_deref(), + TsFnParam::Object(object) => object.type_ann.as_deref(), + }) + .map(|type_ann| self.resolve_string_or_union_strings(&type_ann.type_ann)) + .unwrap_or_default(), + RefinedTsTypeElement::GetterSignature(..) => vec![], + }) + .map(|name| { + Some(ExprOrSpread { + expr: Box::new(Expr::Lit(Lit::Str(quote_str!(name)))), + spread: None, + }) + }) + .collect(), + span: DUMMY_SP, + }) + } else { + None + } + } + _ => None, + } + } +} + +fn extract_prop_name(expr: Expr, computed: bool) -> PropName { + match expr { + Expr::Ident(ident) => PropName::Ident(ident.into()), + Expr::Lit(Lit::Str(str)) => PropName::Str(str), + Expr::Lit(Lit::Num(num)) => PropName::Num(num), + Expr::Lit(Lit::BigInt(bigint)) => PropName::BigInt(bigint), + _ => { + if computed { + PropName::Computed(ComputedPropName { + expr: Box::new(expr), + span: DUMMY_SP, + }) + } else { + HANDLER.with(|handler| handler.span_err(expr.span(), "Unsupported prop key.")); + PropName::Ident(quote_ident!("")) + } + } + } +} + +fn try_unwrap_lit_prop_name(prop_name: &PropName) -> Option> { + match prop_name { + PropName::Ident(..) | PropName::Str(..) | PropName::Num(..) | PropName::BigInt(..) => { + Some(Cow::Borrowed(prop_name)) + } + PropName::Computed(ComputedPropName { expr, .. }) => match &**expr { + Expr::Ident(ident) => Some(Cow::Owned(PropName::Ident(ident.clone().into()))), + Expr::Lit(Lit::Str(str)) => Some(Cow::Owned(PropName::Str(str.clone()))), + Expr::Lit(Lit::Num(num)) => Some(Cow::Owned(PropName::Num(num.clone()))), + Expr::Lit(Lit::BigInt(bigint)) => Some(Cow::Owned(PropName::BigInt(bigint.clone()))), + _ => None, + }, + } +} + +fn extract_type_ann_from_pat(pat: &Pat) -> Option<&TsTypeAnn> { + match pat { + Pat::Ident(ident) => ident.type_ann.as_deref(), + Pat::Object(object) => object.type_ann.as_deref(), + Pat::Array(array) => array.type_ann.as_deref(), + Pat::Assign(assign) => extract_type_ann_from_pat(&assign.left), + _ => None, + } +} diff --git a/rust-plugins/vue-jsx/crates/visitor/src/slot_flag.rs b/rust-plugins/vue-jsx/crates/visitor/src/slot_flag.rs new file mode 100644 index 0000000..1922078 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/src/slot_flag.rs @@ -0,0 +1,5 @@ +#[derive(Clone, Debug)] +pub enum SlotFlag { + Stable = 1, + Dynamic = 2, +} diff --git a/rust-plugins/vue-jsx/crates/visitor/src/util.rs b/rust-plugins/vue-jsx/crates/visitor/src/util.rs new file mode 100644 index 0000000..7cd3e01 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/src/util.rs @@ -0,0 +1,278 @@ +use farmfe_core::{swc_common::DUMMY_SP, swc_ecma_ast::*}; +use farmfe_toolkit::swc_ecma_utils::{private_ident, quote_ident, quote_str}; + +pub(crate) fn build_slot_helper(helper_name: Ident, is_vnode: Ident) -> FnDecl { + let arg = private_ident!("s"); + + FnDecl { + ident: helper_name, + declare: false, + function: Box::new(Function { + params: vec![Param { + span: DUMMY_SP, + decorators: vec![], + pat: Pat::Ident(BindingIdent { + id: arg.clone(), + type_ann: None, + }), + }], + decorators: vec![], + span: DUMMY_SP, + body: Some(BlockStmt { + span: DUMMY_SP, + stmts: vec![Stmt::Return(ReturnStmt { + span: DUMMY_SP, + arg: Some(Box::new(Expr::Bin(BinExpr { + span: DUMMY_SP, + op: op!("||"), + left: Box::new(Expr::Bin(BinExpr { + span: DUMMY_SP, + op: op!("==="), + left: Box::new(Expr::Unary(UnaryExpr { + span: DUMMY_SP, + op: op!("typeof"), + arg: Box::new(Expr::Ident(arg.clone())), + })), + right: Box::new(Expr::Lit(Lit::Str(quote_str!("function")))), + })), + right: Box::new(Expr::Bin(BinExpr { + span: DUMMY_SP, + op: op!("&&"), + left: Box::new(Expr::Bin(BinExpr { + span: DUMMY_SP, + op: op!("==="), + left: Box::new(Expr::Call(CallExpr { + span: DUMMY_SP, + callee: Callee::Expr(Box::new(Expr::Member(MemberExpr { + span: DUMMY_SP, + obj: Box::new(Expr::Member(MemberExpr { + span: DUMMY_SP, + obj: Box::new(Expr::Object(ObjectLit { + span: DUMMY_SP, + props: vec![], + })), + prop: MemberProp::Ident(quote_ident!("toString")), + })), + prop: MemberProp::Ident(quote_ident!("call")), + }))), + args: vec![ExprOrSpread { + spread: None, + expr: Box::new(Expr::Ident(arg.clone())), + }], + type_args: None, + })), + right: Box::new(Expr::Lit(Lit::Str(quote_str!("[object Object]")))), + })), + right: Box::new(Expr::Unary(UnaryExpr { + span: DUMMY_SP, + op: op!("!"), + arg: Box::new(Expr::Call(CallExpr { + span: DUMMY_SP, + callee: Callee::Expr(Box::new(Expr::Ident(is_vnode))), + args: vec![ExprOrSpread { + spread: None, + expr: Box::new(Expr::Ident(arg)), + }], + type_args: None, + })), + })), + })), + }))), + })], + }), + is_generator: false, + is_async: false, + type_params: None, + return_type: None, + }), + } +} + +pub(crate) fn is_jsx_attr_value_constant(value: &JSXAttrValue) -> bool { + match value { + JSXAttrValue::Lit(..) => true, + JSXAttrValue::JSXExprContainer(JSXExprContainer { + expr: JSXExpr::Expr(expr), + .. + }) => is_constant(expr), + _ => false, + } +} + +fn is_constant(expr: &Expr) -> bool { + match expr { + Expr::Ident(ident) => &ident.sym == "undefined", + Expr::Array(ArrayLit { elems, .. }) => elems.iter().all(|element| match element { + Some(ExprOrSpread { spread: None, expr }) => is_constant(expr), + _ => false, + }), + Expr::Object(ObjectLit { props, .. }) => props.iter().all(|prop| { + if let PropOrSpread::Prop(prop) = prop { + match &**prop { + Prop::KeyValue(KeyValueProp { value, .. }) => is_constant(value), + Prop::Shorthand(ident) => &ident.sym == "undefined", + _ => false, + } + } else { + false + } + }), + Expr::Lit(..) => true, + _ => false, + } +} + +pub(crate) fn is_on(attr_name: &str) -> bool { + match attr_name.as_bytes() { + [b'o', b'n', c, ..] => !c.is_ascii_lowercase(), + _ => false, + } +} + +pub(crate) fn dedupe_props(props: Vec) -> Vec { + let capacity = props.len(); + props.into_iter().fold( + Vec::with_capacity(capacity), + |mut defined, prop_or_spread| { + if let PropOrSpread::Prop(prop) = prop_or_spread { + if let Prop::KeyValue(KeyValueProp { + key: + PropName::Str(Str { + value: ref name, + raw, + span, + }), + value, + }) = *prop + { + match defined.iter_mut().find_map(|item| match item { + PropOrSpread::Prop(prop) => match &mut **prop { + Prop::KeyValue(KeyValueProp { + key: + PropName::Str(Str { + value: defined_name, + .. + }), + value, + .. + }) if defined_name == name => Some(value), + _ => None, + }, + _ => None, + }) { + Some(defined_value) if name == "class" || name == "style" || name.starts_with("on") => { + if let Expr::Array(ArrayLit { elems, .. }) = &mut **defined_value { + elems.push(Some(ExprOrSpread { + spread: None, + expr: value, + })); + } else { + *defined_value = Box::new(Expr::Array(ArrayLit { + span: DUMMY_SP, + elems: vec![ + Some(ExprOrSpread { + spread: None, + expr: defined_value.clone(), + }), + Some(ExprOrSpread { + spread: None, + expr: value, + }), + ], + })); + } + } + Some(..) => {} + None => { + defined.push(PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { + key: PropName::Str(Str { + span, + value: name.clone(), + raw, + }), + value, + })))); + } + } + } else { + defined.push(PropOrSpread::Prop(prop)); + } + } else { + defined.push(prop_or_spread); + } + defined + }, + ) +} + +pub(crate) fn decouple_v_models( + elems: Vec>, +) -> impl Iterator { + elems + .into_iter() + .filter_map(|elem| match elem { + Some(ExprOrSpread { spread: None, expr }) => expr.array(), + _ => None, + }) + .map(|ArrayLit { mut elems, .. }| { + let argument = elems + .get(1) + .and_then(|elem| { + if let Some(ExprOrSpread { spread: None, expr }) = elem { + expr.as_lit() + } else { + None + } + }) + .and_then(|lit| { + if let Lit::Str(Str { value, .. }) = lit { + Some(value.clone()) + } else { + None + } + }); + if argument.is_some() { + elems.remove(1); + } + JSXAttrOrSpread::JSXAttr(JSXAttr { + span: DUMMY_SP, + name: if let Some(argument) = argument { + JSXAttrName::JSXNamespacedName(JSXNamespacedName { + ns: quote_ident!("v-model"), + name: quote_ident!(argument), + }) + } else { + JSXAttrName::Ident(quote_ident!("v-model")) + }, + value: Some(JSXAttrValue::JSXExprContainer(JSXExprContainer { + span: DUMMY_SP, + expr: JSXExpr::Expr(Box::new(Expr::Array(ArrayLit { + span: DUMMY_SP, + elems, + }))), + })), + }) + }) +} + +pub(crate) fn transform_text(text: &str) -> String { + let jsx_text_value = text.replace('\t', " "); + let mut jsx_text_lines = jsx_text_value.lines().enumerate().peekable(); + + let mut lines = vec![]; + while let Some((index, line)) = jsx_text_lines.next() { + let line = if index == 0 { + // first line + line.trim_end() + } else if jsx_text_lines.peek().is_none() { + // last line + line.trim_start() + } else { + line.trim() + }; + if !line.is_empty() { + lines.push(line); + } + } + lines.join(" ") +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture.rs b/rust-plugins/vue-jsx/crates/visitor/tests/fixture.rs new file mode 100644 index 0000000..2217b43 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture.rs @@ -0,0 +1,66 @@ +// use farmfe_core::{ +// swc_common::{chain, Mark}, +// swc_ecma_parser::{EsConfig, TsConfig}, +// }; +// use farmfe_toolkit::{swc_ecma_transforms::{ +// resolver, +// }, swc_ecma_visit::as_folder}; +// use std::{fs, io::ErrorKind, path::PathBuf}; +// // use swc_core::{ +// // common::{chain, Mark}, +// // ecma::{ +// // parser::{EsConfig, Syntax, TsConfig}, +// // transforms::{base::resolver, testing::test_fixture}, +// // visit::as_folder, +// // }, +// // }; +// use vue_jsx_visitor::{Options, VueJsxTransformVisitor}; + +// #[testing::fixture("tests/fixture/**/input.jsx")] +// #[testing::fixture("tests/fixture/**/input.tsx")] +// fn test(input: PathBuf) { +// let config = match fs::read_to_string(input.with_file_name("config.json")) { +// Ok(json) => serde_json::from_str(&json).unwrap(), +// Err(err) if err.kind() == ErrorKind::NotFound => Options { +// optimize: true, +// ..Default::default() +// }, +// Err(err) => panic!("failed to read `config.json`: {err}"), +// }; +// println!("config: {:?}", config); +// let output = input.with_file_name("output.js"); + +// let is_ts = input +// .extension() +// .map(|ext| ext.to_string_lossy()) +// .map(|ext| &*ext == "tsx") +// .unwrap_or_default(); + +// test_fixture( +// if is_ts { +// Syntax::Typescript(TsConfig { +// tsx: true, +// ..Default::default() +// }) +// } else { +// Syntax::Es(EsConfig { +// jsx: true, +// ..Default::default() +// }) +// }, +// &|tester| { +// let unresolved_mark = Mark::new(); +// chain!( +// resolver(unresolved_mark, Mark::new(), is_ts), +// as_folder(VueJsxTransformVisitor::new( +// config.clone(), +// unresolved_mark, +// Some(tester.comments.clone()) +// )) +// ) +// }, +// &input, +// &output, +// Default::default(), +// ) +// } diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-directive-with-argument-and-modifiers/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-directive-with-argument-and-modifiers/input.jsx new file mode 100644 index 0000000..6e5ddb0 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-directive-with-argument-and-modifiers/input.jsx @@ -0,0 +1,9 @@ +<> + + + + + + + + diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-directive-with-argument-and-modifiers/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-directive-with-argument-and-modifiers/output.js new file mode 100644 index 0000000..8d82387 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-directive-with-argument-and-modifiers/output.js @@ -0,0 +1,28 @@ +import { + Fragment as _Fragment, + createVNode as _createVNode, + resolveComponent as _resolveComponent, + resolveDirective as _resolveDirective, + withDirectives as _withDirectives, +} from "vue"; +_createVNode(_Fragment, null, [ + _withDirectives(_createVNode(_resolveComponent("A"), null, null, 512), [[_resolveDirective("xxx"), x]]), + _withDirectives(_createVNode(_resolveComponent("A"), null, null, 512), [[_resolveDirective("xxx"), x]]), + _withDirectives(_createVNode(_resolveComponent("A"), null, null, 512), [[_resolveDirective("xxx"), x, 'y']]), + _withDirectives(_createVNode(_resolveComponent("A"), null, null, 512), [[_resolveDirective("xxx"), x, 'y', { + a: true, + b: true + }]]), + _withDirectives(_createVNode(_resolveComponent("A"), null, null, 512), [[_resolveDirective("xxx"), x, void 0, { + a: true, + b: true + }]]), + _withDirectives(_createVNode(_resolveComponent("A"), null, null, 512), [[_resolveDirective("xxx"), x, y, { + a: true, + b: true + }]]), + _withDirectives(_createVNode(_resolveComponent("A"), null, null, 512), [[_resolveDirective("xxx"), x, y, { + a: true, + b: true + }]]), +]); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-directive/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-directive/input.jsx new file mode 100644 index 0000000..fce8c2b --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-directive/input.jsx @@ -0,0 +1 @@ + diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-directive/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-directive/output.js new file mode 100644 index 0000000..be21e30 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-directive/output.js @@ -0,0 +1,7 @@ +import { + createVNode as _createVNode, + resolveComponent as _resolveComponent, + resolveDirective as _resolveDirective, + withDirectives as _withDirectives, +} from "vue"; +_withDirectives(_createVNode(_resolveComponent("A"), null, null, 512), [[_resolveDirective("cus"), x]]); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-element/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-element/config.json new file mode 100644 index 0000000..3c9123c --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-element/config.json @@ -0,0 +1,3 @@ +{ + "customElementPatterns": ["foo"] +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-element/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-element/input.jsx new file mode 100644 index 0000000..3353782 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-element/input.jsx @@ -0,0 +1 @@ +foo diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-element/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-element/output.js new file mode 100644 index 0000000..19e6e41 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-element/output.js @@ -0,0 +1,2 @@ +import { createTextVNode as _createTextVNode, createVNode as _createVNode } from "vue"; +_createVNode("foo", null, [_createVNode("span", null, [_createTextVNode("foo")])]); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-pragma-in-comment/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-pragma-in-comment/input.jsx new file mode 100644 index 0000000..71fdbac --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-pragma-in-comment/input.jsx @@ -0,0 +1,2 @@ +/* @jsx custom */ +
Hello
diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-pragma-in-comment/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-pragma-in-comment/output.js new file mode 100644 index 0000000..f866ebb --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-pragma-in-comment/output.js @@ -0,0 +1,3 @@ +/* @jsx custom */ +import { createTextVNode as _createTextVNode } from "vue"; +custom("div", { "id": "custom" }, [_createTextVNode("Hello")]); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-pragma-in-options/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-pragma-in-options/config.json new file mode 100644 index 0000000..e71a5ca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-pragma-in-options/config.json @@ -0,0 +1,3 @@ +{ + "pragma": "custom" +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-pragma-in-options/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-pragma-in-options/input.jsx new file mode 100644 index 0000000..eb97d7f --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-pragma-in-options/input.jsx @@ -0,0 +1 @@ +
pragma
diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-pragma-in-options/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-pragma-in-options/output.js new file mode 100644 index 0000000..c603eee --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/custom-pragma-in-options/output.js @@ -0,0 +1,2 @@ +import { createTextVNode as _createTextVNode } from "vue"; +custom("div", null, [_createTextVNode("pragma")]); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/disable-object-slot/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/disable-object-slot/config.json new file mode 100644 index 0000000..f1f2c11 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/disable-object-slot/config.json @@ -0,0 +1,4 @@ +{ + "optimize": true, + "enableObjectSlots": false +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/disable-object-slot/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/disable-object-slot/input.jsx new file mode 100644 index 0000000..dd7bdbb --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/disable-object-slot/input.jsx @@ -0,0 +1 @@ +{slots.default()} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/disable-object-slot/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/disable-object-slot/output.js new file mode 100644 index 0000000..5676d41 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/disable-object-slot/output.js @@ -0,0 +1,5 @@ +import { createVNode as _createVNode, resolveComponent as _resolveComponent } from "vue"; +_createVNode(_resolveComponent("Badge"), null, { + default: () => [slots.default()], + _: 1 +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/empty-string/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/empty-string/input.jsx new file mode 100644 index 0000000..7a1cc4d --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/empty-string/input.jsx @@ -0,0 +1 @@ +

diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/empty-string/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/empty-string/output.js new file mode 100644 index 0000000..3545722 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/empty-string/output.js @@ -0,0 +1,2 @@ +import { createVNode as _createVNode } from "vue"; +_createVNode("h1", { "title": "" }, null); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/fragment-already-imported/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/fragment-already-imported/config.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/fragment-already-imported/config.json @@ -0,0 +1 @@ +{} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/fragment-already-imported/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/fragment-already-imported/input.jsx new file mode 100644 index 0000000..5b19caf --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/fragment-already-imported/input.jsx @@ -0,0 +1,3 @@ +import { Fragment as _Fragment } from 'vue' +const Root1 = () => <>root1 +const Root2 = () => <_Fragment>root2 diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/fragment-already-imported/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/fragment-already-imported/output.js new file mode 100644 index 0000000..97c024e --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/fragment-already-imported/output.js @@ -0,0 +1,4 @@ +import { Fragment as _Fragment, createTextVNode as _createTextVNode, createVNode as _createVNode } from "vue"; +import { Fragment as _Fragment1 } from 'vue'; +const Root1 = () => _createVNode(_Fragment, null, [_createTextVNode("root1")]); +const Root2 = () => _createVNode(_Fragment1, null, [_createTextVNode("root2")]); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/function-expr-slot/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/function-expr-slot/config.json new file mode 100644 index 0000000..c09cd55 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/function-expr-slot/config.json @@ -0,0 +1,4 @@ +{ + "optimize": true, + "enableObjectSlots": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/function-expr-slot/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/function-expr-slot/input.jsx new file mode 100644 index 0000000..d0bd0ec --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/function-expr-slot/input.jsx @@ -0,0 +1 @@ +
{() => "foo"} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/function-expr-slot/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/function-expr-slot/output.js new file mode 100644 index 0000000..9b9c6df --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/function-expr-slot/output.js @@ -0,0 +1,4 @@ +import { createVNode as _createVNode, resolveComponent as _resolveComponent } from "vue"; +_createVNode(_resolveComponent("A"), null, { + default: () => "foo" +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/infer-component-name/disabled/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/infer-component-name/disabled/input.tsx new file mode 100644 index 0000000..3875e2b --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/infer-component-name/disabled/input.tsx @@ -0,0 +1,3 @@ +import { defineComponent } from 'vue' + +const Foo = defineComponent(() => { }) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/infer-component-name/disabled/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/infer-component-name/disabled/output.js new file mode 100644 index 0000000..50d70ac --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/infer-component-name/disabled/output.js @@ -0,0 +1,2 @@ +import { defineComponent } from 'vue'; +const Foo = defineComponent(()=>{}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/infer-component-name/enabled/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/infer-component-name/enabled/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/infer-component-name/enabled/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/infer-component-name/enabled/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/infer-component-name/enabled/input.tsx new file mode 100644 index 0000000..2d1e446 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/infer-component-name/enabled/input.tsx @@ -0,0 +1,9 @@ +import { defineComponent } from 'vue' + +const Component1 = defineComponent(() => { }) + +const Component2 = defineComponent(() => { }, { foo: 'bar' }) + +const Component3 = defineComponent(() => { }, opts) + +const Component4 = defineComponent(() => { }, ...args) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/infer-component-name/enabled/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/infer-component-name/enabled/output.js new file mode 100644 index 0000000..ae42df6 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/infer-component-name/enabled/output.js @@ -0,0 +1,13 @@ +import { defineComponent } from 'vue'; +const Component1 = defineComponent(()=>{}, { + name: "Component1" +}); +const Component2 = defineComponent(()=>{}, { + foo: 'bar', + name: "Component2" +}); +const Component3 = defineComponent(()=>{}, { + name: "Component3", + ...opts +}); +const Component4 = defineComponent(()=>{}, ...args); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/keep-alive-named-import/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/keep-alive-named-import/input.jsx new file mode 100644 index 0000000..8c780b0 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/keep-alive-named-import/input.jsx @@ -0,0 +1,3 @@ +import { KeepAlive } from 'vue'; + +123 diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/keep-alive-named-import/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/keep-alive-named-import/output.js new file mode 100644 index 0000000..47426c4 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/keep-alive-named-import/output.js @@ -0,0 +1,3 @@ +import { createTextVNode as _createTextVNode, createVNode as _createVNode } from "vue"; +import { KeepAlive } from 'vue'; +_createVNode(KeepAlive, null, [_createTextVNode("123")]); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/keep-alive-namespace-import/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/keep-alive-namespace-import/input.jsx new file mode 100644 index 0000000..5768a1d --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/keep-alive-namespace-import/input.jsx @@ -0,0 +1,3 @@ +import * as Vue from 'vue'; + +123 diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/keep-alive-namespace-import/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/keep-alive-namespace-import/output.js new file mode 100644 index 0000000..66c6209 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/keep-alive-namespace-import/output.js @@ -0,0 +1,3 @@ +import { createTextVNode as _createTextVNode, createVNode as _createVNode } from "vue"; +import * as Vue from 'vue'; +_createVNode(Vue.KeepAlive, null, [_createTextVNode("123")]); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/keep-namespace-import/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/keep-namespace-import/input.jsx new file mode 100644 index 0000000..42d0eef --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/keep-namespace-import/input.jsx @@ -0,0 +1,2 @@ +import * as Vue from 'vue'; +
Vue
diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/keep-namespace-import/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/keep-namespace-import/output.js new file mode 100644 index 0000000..2cc7b40 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/keep-namespace-import/output.js @@ -0,0 +1,3 @@ +import { createTextVNode as _createTextVNode, createVNode as _createVNode } from "vue"; +import * as Vue from 'vue'; +_createVNode("div", null, [_createTextVNode("Vue")]); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/merge-class-style-attrs/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/merge-class-style-attrs/input.jsx new file mode 100644 index 0000000..0cbdef3 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/merge-class-style-attrs/input.jsx @@ -0,0 +1 @@ +
diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/merge-class-style-attrs/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/merge-class-style-attrs/output.js new file mode 100644 index 0000000..024fa2d --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/merge-class-style-attrs/output.js @@ -0,0 +1,5 @@ +import { createVNode as _createVNode } from "vue"; +_createVNode("div", { + "class": ["a", b], + "style": ["color: red", s] +}, null, 6); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/merge-props-order/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/merge-props-order/input.jsx new file mode 100644 index 0000000..7e75963 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/merge-props-order/input.jsx @@ -0,0 +1 @@ + diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/merge-props-order/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/merge-props-order/output.js new file mode 100644 index 0000000..4abd84b --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/merge-props-order/output.js @@ -0,0 +1,6 @@ +import { createTextVNode as _createTextVNode, createVNode as _createVNode, mergeProps as _mergeProps } from "vue"; +_createVNode("button", _mergeProps({ + "loading": true +}, x, { + "type": "submit" +}), [_createTextVNode("btn")], 16, ["loading"]); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/model-as-prop-name/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/model-as-prop-name/input.jsx new file mode 100644 index 0000000..fbd2b60 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/model-as-prop-name/input.jsx @@ -0,0 +1 @@ + diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/model-as-prop-name/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/model-as-prop-name/output.js new file mode 100644 index 0000000..c1a8e46 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/model-as-prop-name/output.js @@ -0,0 +1,5 @@ +import { createVNode as _createVNode, resolveComponent as _resolveComponent } from "vue"; +_createVNode(_resolveComponent("C"), { + "model": foo, + "onUpdate:model": $event => foo = $event +}, null, 8, ["model", "onUpdate:model"]); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/multiple-exprs-slot/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/multiple-exprs-slot/config.json new file mode 100644 index 0000000..c09cd55 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/multiple-exprs-slot/config.json @@ -0,0 +1,4 @@ +{ + "optimize": true, + "enableObjectSlots": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/multiple-exprs-slot/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/multiple-exprs-slot/input.jsx new file mode 100644 index 0000000..8757af5 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/multiple-exprs-slot/input.jsx @@ -0,0 +1 @@ +{foo}{bar} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/multiple-exprs-slot/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/multiple-exprs-slot/output.js new file mode 100644 index 0000000..2e94b2c --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/multiple-exprs-slot/output.js @@ -0,0 +1,5 @@ +import { createVNode as _createVNode, resolveComponent as _resolveComponent } from "vue"; +_createVNode(_resolveComponent("A"), null, { + default: () => [foo, bar], + _: 1 +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/nesting-slot-flags/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/nesting-slot-flags/input.jsx new file mode 100644 index 0000000..0f621ec --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/nesting-slot-flags/input.jsx @@ -0,0 +1,16 @@ +let defined; + + + {unknown1} + + {unknown2} + + {unknown3} + {defined} + + + + {unknown4} + {unknown5} + + diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/nesting-slot-flags/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/nesting-slot-flags/output.js new file mode 100644 index 0000000..003fbad --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/nesting-slot-flags/output.js @@ -0,0 +1,28 @@ +import { createVNode as _createVNode, isVNode as _isVNode, resolveComponent as _resolveComponent } from "vue"; +function _isSlot(s) { + return typeof s === "function" || ({}).toString.call(s) === "[object Object]" && !_isVNode(s); +} +let defined; +_createVNode(_resolveComponent("Comp"), null, { + default: () => [ + unknown1, + _createVNode(_resolveComponent("Comp"), null, { + default: () => [unknown2, _createVNode(_resolveComponent("Comp"), null, { + default: () => [unknown3, _createVNode(_resolveComponent("Comp"), null, _isSlot(defined) ? defined : { + default: () => [defined], + _: 2 + })], + _: 2 + })], + _: 2 + }), + _createVNode(_resolveComponent("Comp"), null, { + default: () => [unknown4, _createVNode(_resolveComponent("Comp"), null, _isSlot(unknown5) ? unknown5 : { + default: () => [unknown5], + _: 1 + })], + _: 1 + }), + ], + _: 2 +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/non-literal-expr-slot/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/non-literal-expr-slot/config.json new file mode 100644 index 0000000..c09cd55 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/non-literal-expr-slot/config.json @@ -0,0 +1,4 @@ +{ + "optimize": true, + "enableObjectSlots": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/non-literal-expr-slot/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/non-literal-expr-slot/input.jsx new file mode 100644 index 0000000..76fdd0c --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/non-literal-expr-slot/input.jsx @@ -0,0 +1,2 @@ +const foo = () => 1; +{foo()}; diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/non-literal-expr-slot/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/non-literal-expr-slot/output.js new file mode 100644 index 0000000..bc06c00 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/non-literal-expr-slot/output.js @@ -0,0 +1,10 @@ +import { createVNode as _createVNode, isVNode as _isVNode, resolveComponent as _resolveComponent } from "vue"; +function _isSlot(s) { + return typeof s === "function" || ({}).toString.call(s) === "[object Object]" && !_isVNode(s); +} +let _slot; +const foo = () => 1; +_createVNode(_resolveComponent("A"), null, _isSlot(_slot = foo()) ? _slot : { + default: () => [_slot], + _: 1 +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/override-props-multiple/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/override-props-multiple/config.json new file mode 100644 index 0000000..a881159 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/override-props-multiple/config.json @@ -0,0 +1,3 @@ +{ + "mergeProps": false +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/override-props-multiple/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/override-props-multiple/input.jsx new file mode 100644 index 0000000..a69c6db --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/override-props-multiple/input.jsx @@ -0,0 +1 @@ + diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/override-props-multiple/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/override-props-multiple/output.js new file mode 100644 index 0000000..f05845f --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/override-props-multiple/output.js @@ -0,0 +1,11 @@ +import { createVNode as _createVNode, resolveComponent as _resolveComponent } from "vue"; +_createVNode(_resolveComponent("A"), { + "loading": true, + ...a, + b: 1, + c: { + d: 2 + }, + "class": "x", + "style": x +}, null); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/override-props-single/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/override-props-single/config.json new file mode 100644 index 0000000..a881159 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/override-props-single/config.json @@ -0,0 +1,3 @@ +{ + "mergeProps": false +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/override-props-single/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/override-props-single/input.jsx new file mode 100644 index 0000000..a9a59bb --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/override-props-single/input.jsx @@ -0,0 +1 @@ +
diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/override-props-single/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/override-props-single/output.js new file mode 100644 index 0000000..8b75fcf --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/override-props-single/output.js @@ -0,0 +1,2 @@ +import { createVNode as _createVNode } from "vue"; +_createVNode("div", a, null); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/reassign-variable-as-component/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/reassign-variable-as-component/input.jsx new file mode 100644 index 0000000..63ee067 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/reassign-variable-as-component/input.jsx @@ -0,0 +1,13 @@ +import { defineComponent } from 'vue'; +let a = 1; +const A = defineComponent({ + setup(_, { slots }) { + return () => {slots.default()}; + }, +}); + +const _a2 = 2; + +a = _a2; + +a = {a}; diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/reassign-variable-as-component/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/reassign-variable-as-component/output.js new file mode 100644 index 0000000..3a79cfa --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/reassign-variable-as-component/output.js @@ -0,0 +1,22 @@ +import { createVNode as _createVNode, isVNode as _isVNode } from "vue"; +function _isSlot(s) { + return typeof s === "function" || ({}).toString.call(s) === "[object Object]" && !_isVNode(s); +} +const _a = function () { + return a; +}(); +import { defineComponent } from 'vue'; +let a = 1; +const A = defineComponent({ + setup(_, { + slots + }) { + return () => _createVNode("span", null, [slots.default()]); + } +}); +const _a2 = 2; +a = _a2; +a = _createVNode(A, null, _isSlot(a) ? a : { + default: () => [_a], + _: 2 +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/disabled/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/disabled/input.tsx new file mode 100644 index 0000000..3249882 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/disabled/input.tsx @@ -0,0 +1,3 @@ +import { defineComponent, type SetupContext } from 'vue' + +defineComponent((_, ctx: SetupContext<(e: 'foo' | 'bar') => void>) => {}) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/disabled/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/disabled/output.js new file mode 100644 index 0000000..bcd7c1f --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/disabled/output.js @@ -0,0 +1,2 @@ +import { defineComponent, type SetupContext } from 'vue'; +defineComponent((_, ctx: SetupContext<(e: 'foo' | 'bar') => void>)=>{}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/exported-interface/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/exported-interface/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/exported-interface/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/exported-interface/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/exported-interface/input.tsx new file mode 100644 index 0000000..fd8d5f6 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/exported-interface/input.tsx @@ -0,0 +1,5 @@ +import { defineComponent, type SetupContext } from 'vue' + +export interface Emits { (e: 'foo' | 'bar'): void } + +defineComponent((_, ctx: SetupContext) => {}) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/exported-interface/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/exported-interface/output.js new file mode 100644 index 0000000..d476fdb --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/exported-interface/output.js @@ -0,0 +1,10 @@ +import { defineComponent, type SetupContext } from 'vue'; +export interface Emits { + (e: 'foo' | 'bar') : void; +} +defineComponent((_, ctx: SetupContext)=>{}, { + emits: [ + "foo", + "bar" + ] +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/exported-type-alias/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/exported-type-alias/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/exported-type-alias/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/exported-type-alias/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/exported-type-alias/input.tsx new file mode 100644 index 0000000..1ab35eb --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/exported-type-alias/input.tsx @@ -0,0 +1,5 @@ +import { defineComponent, type SetupContext } from 'vue' + +export type Emits = { (e: 'foo' | 'bar'): void } + +defineComponent((_, ctx: SetupContext) => {}) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/exported-type-alias/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/exported-type-alias/output.js new file mode 100644 index 0000000..1d651db --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/exported-type-alias/output.js @@ -0,0 +1,10 @@ +import { defineComponent, type SetupContext } from 'vue'; +export type Emits = { + (e: 'foo' | 'bar') : void; +}; +defineComponent((_, ctx: SetupContext)=>{}, { + emits: [ + "foo", + "bar" + ] +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/fn-type/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/fn-type/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/fn-type/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/fn-type/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/fn-type/input.tsx new file mode 100644 index 0000000..e022a18 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/fn-type/input.tsx @@ -0,0 +1,7 @@ +import { defineComponent, type SetupContext } from 'vue' + +defineComponent((_, ctx: SetupContext<(e: 'foo' | 'bar') => void>) => {}) + +defineComponent((_, ctx: SetupContext<((e: 'foo' | 'bar') => void) | ((e: 'baz', id: number) => void)>) => {}) + +defineComponent((_, ctx: SetupContext<{(e: 'foo' | 'bar'): void; (e: 'baz', id: number): void;}>) => {}) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/fn-type/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/fn-type/output.js new file mode 100644 index 0000000..475fdc7 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/fn-type/output.js @@ -0,0 +1,24 @@ +import { defineComponent, type SetupContext } from 'vue'; +defineComponent((_, ctx: SetupContext<(e: 'foo' | 'bar') => void>)=>{}, { + emits: [ + "foo", + "bar" + ] +}); +defineComponent((_, ctx: SetupContext<((e: 'foo' | 'bar') => void) | ((e: 'baz', id: number) => void)>)=>{}, { + emits: [ + "foo", + "bar", + "baz" + ] +}); +defineComponent((_, ctx: SetupContext<{ + (e: 'foo' | 'bar') : void; + (e: 'baz', id: number) : void; +}>)=>{}, { + emits: [ + "foo", + "bar", + "baz" + ] +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/interface-with-extends/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/interface-with-extends/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/interface-with-extends/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/interface-with-extends/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/interface-with-extends/input.tsx new file mode 100644 index 0000000..2ea5cb8 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/interface-with-extends/input.tsx @@ -0,0 +1,6 @@ +import { defineComponent, type SetupContext } from 'vue' + +interface Base { (e: 'foo'): void } +interface Emits extends Base { (e: 'bar'): void } + +defineComponent((_, ctx: SetupContext) => {}) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/interface-with-extends/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/interface-with-extends/output.js new file mode 100644 index 0000000..5b958f3 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/interface-with-extends/output.js @@ -0,0 +1,13 @@ +import { defineComponent, type SetupContext } from 'vue'; +interface Base { + (e: 'foo') : void; +} +interface Emits extends Base { + (e: 'bar') : void; +} +defineComponent((_, ctx: SetupContext)=>{}, { + emits: [ + "bar", + "foo" + ] +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/interface/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/interface/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/interface/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/interface/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/interface/input.tsx new file mode 100644 index 0000000..46f34de --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/interface/input.tsx @@ -0,0 +1,5 @@ +import { defineComponent, type SetupContext } from 'vue' + +interface Emits { (e: 'foo' | 'bar'): void } + +defineComponent((_, ctx: SetupContext) => {}) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/interface/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/interface/output.js new file mode 100644 index 0000000..b13e5dc --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/interface/output.js @@ -0,0 +1,10 @@ +import { defineComponent, type SetupContext } from 'vue'; +interface Emits { + (e: 'foo' | 'bar') : void; +} +defineComponent((_, ctx: SetupContext)=>{}, { + emits: [ + "foo", + "bar" + ] +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/property-syntax/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/property-syntax/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/property-syntax/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/property-syntax/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/property-syntax/input.tsx new file mode 100644 index 0000000..5e8019f --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/property-syntax/input.tsx @@ -0,0 +1,5 @@ +import { defineComponent, type SetupContext } from 'vue' + +defineComponent((_, ctx: SetupContext<{ foo: [], bar: [] }>) => {}) + +defineComponent((_, ctx: SetupContext<{ 'foo:bar': [] }>) => {}) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/property-syntax/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/property-syntax/output.js new file mode 100644 index 0000000..da89ed5 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/property-syntax/output.js @@ -0,0 +1,17 @@ +import { defineComponent, type SetupContext } from 'vue'; +defineComponent((_, ctx: SetupContext<{ + foo: []; + bar: []; +}>)=>{}, { + emits: [ + "foo", + "bar" + ] +}); +defineComponent((_, ctx: SetupContext<{ + 'foo:bar': []; +}>)=>{}, { + emits: [ + "foo:bar" + ] +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/referenced-exported-fn-type/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/referenced-exported-fn-type/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/referenced-exported-fn-type/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/referenced-exported-fn-type/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/referenced-exported-fn-type/input.tsx new file mode 100644 index 0000000..b4d2a6e --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/referenced-exported-fn-type/input.tsx @@ -0,0 +1,5 @@ +import { defineComponent, type SetupContext } from 'vue' + +export type Emits = (e: 'foo' | 'bar') => void + +defineComponent((_, ctx: SetupContext) => {}) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/referenced-exported-fn-type/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/referenced-exported-fn-type/output.js new file mode 100644 index 0000000..457a657 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/referenced-exported-fn-type/output.js @@ -0,0 +1,8 @@ +import { defineComponent, type SetupContext } from 'vue'; +export type Emits = (e: 'foo' | 'bar') => void; +defineComponent((_, ctx: SetupContext)=>{}, { + emits: [ + "foo", + "bar" + ] +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/referenced-fn-type/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/referenced-fn-type/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/referenced-fn-type/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/referenced-fn-type/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/referenced-fn-type/input.tsx new file mode 100644 index 0000000..729919b --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/referenced-fn-type/input.tsx @@ -0,0 +1,5 @@ +import { defineComponent, type SetupContext } from 'vue' + +type Emits = (e: 'foo' | 'bar') => void + +defineComponent((_, ctx: SetupContext) => {}) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/referenced-fn-type/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/referenced-fn-type/output.js new file mode 100644 index 0000000..6d9e513 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/referenced-fn-type/output.js @@ -0,0 +1,8 @@ +import { defineComponent, type SetupContext } from 'vue'; +type Emits = (e: 'foo' | 'bar') => void; +defineComponent((_, ctx: SetupContext)=>{}, { + emits: [ + "foo", + "bar" + ] +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/type-alias/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/type-alias/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/type-alias/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/type-alias/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/type-alias/input.tsx new file mode 100644 index 0000000..51bbac6 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/type-alias/input.tsx @@ -0,0 +1,5 @@ +import { defineComponent, type SetupContext } from 'vue' + +type Emits = { (e: 'foo' | 'bar'): void } + +defineComponent((_, ctx: SetupContext) => {}) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/type-alias/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/type-alias/output.js new file mode 100644 index 0000000..3c6849e --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/type-alias/output.js @@ -0,0 +1,10 @@ +import { defineComponent, type SetupContext } from 'vue'; +type Emits = { + (e: 'foo' | 'bar') : void; +}; +defineComponent((_, ctx: SetupContext)=>{}, { + emits: [ + "foo", + "bar" + ] +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/type-references-in-union/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/type-references-in-union/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/type-references-in-union/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/type-references-in-union/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/type-references-in-union/input.tsx new file mode 100644 index 0000000..0303592 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/type-references-in-union/input.tsx @@ -0,0 +1,9 @@ +import { defineComponent, type SetupContext } from 'vue' + +type BaseEmit = "change" +type Emit = "some" | "emit" | BaseEmit + +defineComponent((_, ctx: SetupContext<{ + (e: Emit): void; + (e: "another", val: string): void; +}>) => {}) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/type-references-in-union/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/type-references-in-union/output.js new file mode 100644 index 0000000..315854d --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-emits-types/type-references-in-union/output.js @@ -0,0 +1,14 @@ +import { defineComponent, type SetupContext } from 'vue'; +type BaseEmit = "change"; +type Emit = "some" | "emit" | BaseEmit; +defineComponent((_, ctx: SetupContext<{ + (e: Emit) : void; + (e: "another", val: string) : void; +}>)=>{}, { + emits: [ + "some", + "emit", + "change", + "another" + ] +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/check-define-component/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/check-define-component/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/check-define-component/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/check-define-component/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/check-define-component/input.tsx new file mode 100644 index 0000000..42b75ac --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/check-define-component/input.tsx @@ -0,0 +1,7 @@ +function scope() { + function defineComponent() {} + + defineComponent((props: { msg: string }) => {}) +} + +defineComponent((props: { msg: string }) => {}) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/check-define-component/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/check-define-component/output.js new file mode 100644 index 0000000..2944ced --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/check-define-component/output.js @@ -0,0 +1,9 @@ +function scope() { + function defineComponent1() {} + defineComponent1((props: { + msg: string; + })=>{}); +} +defineComponent((props: { + msg: string; +})=>{}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/disabled/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/disabled/input.tsx new file mode 100644 index 0000000..3888274 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/disabled/input.tsx @@ -0,0 +1,7 @@ +import { defineComponent } from 'vue' + +type Props = { + foo: string +} + +defineComponent((props: Props) => {}) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/disabled/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/disabled/output.js new file mode 100644 index 0000000..3999007 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/disabled/output.js @@ -0,0 +1,5 @@ +import { defineComponent } from 'vue'; +type Props = { + foo: string; +}; +defineComponent((props: Props)=>{}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/function/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/function/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/function/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/function/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/function/input.tsx new file mode 100644 index 0000000..b54da35 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/function/input.tsx @@ -0,0 +1,21 @@ +import { defineComponent } from 'vue' + +defineComponent(({}: { + foo: number, +}) => { }) + +defineComponent(([]: { + foo: number, +}) => { }) + +defineComponent(function (props: { + foo: number, +}) { }) + +defineComponent(function ({}: { + foo: number, +}) { }) + +defineComponent(function ([]: { + foo: number, +}) { }) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/function/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/function/output.js new file mode 100644 index 0000000..8f01b1b --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/function/output.js @@ -0,0 +1,51 @@ +import { defineComponent } from 'vue'; +defineComponent(({}: { + foo: number; +})=>{}, { + props: { + foo: { + type: Number, + required: true + } + } +}); +defineComponent(([]: { + foo: number; +})=>{}, { + props: { + foo: { + type: Number, + required: true + } + } +}); +defineComponent(function(props: { + foo: number; +}) {}, { + props: { + foo: { + type: Number, + required: true + } + } +}); +defineComponent(function({}: { + foo: number; +}) {}, { + props: { + foo: { + type: Number, + required: true + } + } +}); +defineComponent(function([]: { + foo: number; +}) {}, { + props: { + foo: { + type: Number, + required: true + } + } +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-interface-advanced/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-interface-advanced/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-interface-advanced/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-interface-advanced/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-interface-advanced/input.tsx new file mode 100644 index 0000000..030fbf8 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-interface-advanced/input.tsx @@ -0,0 +1,9 @@ +import { defineComponent } from 'vue' + +type K = 'foo' | 'bar' +interface T { foo: string, bar: number } +interface Foo { foo: T[string] } +interface Bar { bar: string } +interface S { foo: Foo, bar: Bar } + +defineComponent((props: S[K]) => { }) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-interface-advanced/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-interface-advanced/output.js new file mode 100644 index 0000000..7906d0a --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-interface-advanced/output.js @@ -0,0 +1,31 @@ +import { defineComponent } from 'vue'; +type K = 'foo' | 'bar'; +interface T { + foo: string; + bar: number; +} +interface Foo { + foo: T[string]; +} +interface Bar { + bar: string; +} +interface S { + foo: Foo; + bar: Bar; +} +defineComponent((props: S[K])=>{}, { + props: { + foo: { + type: [ + String, + Number + ], + required: true + }, + bar: { + type: String, + required: true + } + } +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-interface-literal/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-interface-literal/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-interface-literal/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-interface-literal/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-interface-literal/input.tsx new file mode 100644 index 0000000..5defe97 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-interface-literal/input.tsx @@ -0,0 +1,6 @@ +import { defineComponent } from 'vue' + +interface T { bar: number } +interface S { nested: { foo: T['bar'] }} + +defineComponent((props: S['nested']) => { }) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-interface-literal/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-interface-literal/output.js new file mode 100644 index 0000000..d00023b --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-interface-literal/output.js @@ -0,0 +1,17 @@ +import { defineComponent } from 'vue'; +interface T { + bar: number; +} +interface S { + nested: { + foo: T['bar']; + }; +} +defineComponent((props: S['nested'])=>{}, { + props: { + foo: { + type: Number, + required: true + } + } +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-type-advanced/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-type-advanced/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-type-advanced/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-type-advanced/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-type-advanced/input.tsx new file mode 100644 index 0000000..e5076f0 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-type-advanced/input.tsx @@ -0,0 +1,7 @@ +import { defineComponent } from 'vue' + +type K = 'foo' | 'bar' +type T = { foo: string, bar: number } +type S = { foo: { foo: T[string] }, bar: { bar: string } } + +defineComponent((props: S[K]) => { }) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-type-advanced/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-type-advanced/output.js new file mode 100644 index 0000000..4a8b699 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-type-advanced/output.js @@ -0,0 +1,29 @@ +import { defineComponent } from 'vue'; +type K = 'foo' | 'bar'; +type T = { + foo: string; + bar: number; +}; +type S = { + foo: { + foo: T[string]; + }; + bar: { + bar: string; + }; +}; +defineComponent((props: S[K])=>{}, { + props: { + foo: { + type: [ + String, + Number + ], + required: true + }, + bar: { + type: String, + required: true + } + } +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-type-literal/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-type-literal/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-type-literal/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-type-literal/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-type-literal/input.tsx new file mode 100644 index 0000000..84c54f0 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-type-literal/input.tsx @@ -0,0 +1,6 @@ +import { defineComponent } from 'vue' + +type T = { bar: number } +type S = { nested: { foo: T['bar'] }} + +defineComponent((props: S['nested']) => { }) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-type-literal/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-type-literal/output.js new file mode 100644 index 0000000..6d3b11e --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-type-literal/output.js @@ -0,0 +1,17 @@ +import { defineComponent } from 'vue'; +type T = { + bar: number; +}; +type S = { + nested: { + foo: T['bar']; + }; +}; +defineComponent((props: S['nested'])=>{}, { + props: { + foo: { + type: Number, + required: true + } + } +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-type-number/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-type-number/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-type-number/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-type-number/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-type-number/input.tsx new file mode 100644 index 0000000..7723534 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-type-number/input.tsx @@ -0,0 +1,17 @@ +import { defineComponent } from 'vue' + +type A = (string | number)[] +type AA = Array +type T = [1, 'foo'] +type TT = [foo: 1, bar: 'foo'] +type Optional = [1?] + +defineComponent((props: { + foo: A[number], + bar: AA[number], + tuple: T[number], + tuple0: T[0], + tuple1: T[1], + namedTuple: TT[number], + optional: Optional[0], +}) => { }) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-type-number/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-type-number/output.js new file mode 100644 index 0000000..59cec8d --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/indexed-access-type-number/output.js @@ -0,0 +1,55 @@ +import { defineComponent } from 'vue'; +type A = (string | number)[]; +type AA = Array; +type T = [1, 'foo']; +type TT = [foo: 1, bar: 'foo']; +type Optional = [1?]; +defineComponent((props: { + foo: A[number]; + bar: AA[number]; + tuple: T[number]; + tuple0: T[0]; + tuple1: T[1]; + namedTuple: TT[number]; + optional: Optional[0]; +})=>{}, { + props: { + foo: { + type: [ + String, + Number + ], + required: true + }, + bar: { + type: String, + required: true + }, + tuple: { + type: [ + Number, + String + ], + required: true + }, + tuple0: { + type: Number, + required: true + }, + tuple1: { + type: String, + required: true + }, + namedTuple: { + type: [ + Number, + String + ], + required: true + }, + optional: { + type: Number, + required: true + } + } +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/interface-merging/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/interface-merging/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/interface-merging/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/interface-merging/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/interface-merging/input.tsx new file mode 100644 index 0000000..4ecbc59 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/interface-merging/input.tsx @@ -0,0 +1,13 @@ +import { defineComponent } from 'vue' + +interface Foo { + a: string +} +interface Foo { + b: number +} + +defineComponent((props: { + foo: Foo['a'], + bar: Foo['b'], +}) => { }) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/interface-merging/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/interface-merging/output.js new file mode 100644 index 0000000..6653b13 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/interface-merging/output.js @@ -0,0 +1,22 @@ +import { defineComponent } from 'vue'; +interface Foo { + a: string; +} +interface Foo { + b: number; +} +defineComponent((props: { + foo: Foo['a']; + bar: Foo['b']; +})=>{}, { + props: { + foo: { + type: String, + required: true + }, + bar: { + type: Number, + required: true + } + } +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/intersection-type/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/intersection-type/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/intersection-type/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/intersection-type/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/intersection-type/input.tsx new file mode 100644 index 0000000..14617b3 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/intersection-type/input.tsx @@ -0,0 +1,7 @@ +import { defineComponent } from 'vue' + +type Foo = { foo: number } +type Bar = { bar: string } +type Baz = { bar: string | boolean } + +defineComponent((props: { self: any } & Foo & Bar & Baz) => { }) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/intersection-type/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/intersection-type/output.js new file mode 100644 index 0000000..05627ee --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/intersection-type/output.js @@ -0,0 +1,31 @@ +import { defineComponent } from 'vue'; +type Foo = { + foo: number; +}; +type Bar = { + bar: string; +}; +type Baz = { + bar: string | boolean; +}; +defineComponent((props: { + self: any; +} & Foo & Bar & Baz)=>{}, { + props: { + self: { + type: null, + required: true + }, + foo: { + type: Number, + required: true + }, + bar: { + type: [ + String, + Boolean + ], + required: true + } + } +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/optional/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/optional/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/optional/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/optional/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/optional/input.tsx new file mode 100644 index 0000000..8608b9a --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/optional/input.tsx @@ -0,0 +1,10 @@ +import { defineComponent } from 'vue' + +defineComponent((props: { + foo?: number, // property + bar?(): void, // method + 'baz'?: string, // string literal key + + untyped1?, + untyped2?(), +}) => { }) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/optional/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/optional/output.js new file mode 100644 index 0000000..1ac9003 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/optional/output.js @@ -0,0 +1,31 @@ +import { defineComponent } from 'vue'; +defineComponent((props: { + foo?: number; + bar?(): void; + 'baz'?: string; + untyped1?; + untyped2?(); +})=>{}, { + props: { + foo: { + type: Number, + required: false + }, + bar: { + type: Function, + required: false + }, + 'baz': { + type: String, + required: false + }, + untyped1: { + type: null, + required: false + }, + untyped2: { + type: Function, + required: false + } + } +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/options-object/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/options-object/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/options-object/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/options-object/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/options-object/input.tsx new file mode 100644 index 0000000..032ed83 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/options-object/input.tsx @@ -0,0 +1,16 @@ +import { defineComponent } from 'vue' + +defineComponent((props: { + foo: number, +}) => { }, {}) + +// shouldn't be resolved +defineComponent((props: { + foo: number, +}) => { }, { + props: { + bar: { + type: String, + }, + }, +}) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/options-object/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/options-object/output.js new file mode 100644 index 0000000..0c2e335 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/options-object/output.js @@ -0,0 +1,21 @@ +import { defineComponent } from 'vue'; +defineComponent((props: { + foo: number; +})=>{}, { + props: { + foo: { + type: Number, + required: true + } + } +}); +// shouldn't be resolved +defineComponent((props: { + foo: number; +})=>{}, { + props: { + bar: { + type: String + } + } +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-class/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-class/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-class/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-class/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-class/input.tsx new file mode 100644 index 0000000..1659a68 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-class/input.tsx @@ -0,0 +1,5 @@ +import { defineComponent } from 'vue' + +class Foo {} + +defineComponent((props: { foo: Foo }) => { }) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-class/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-class/output.js new file mode 100644 index 0000000..e0038fc --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-class/output.js @@ -0,0 +1,13 @@ +import { defineComponent } from 'vue'; +class Foo { +} +defineComponent((props: { + foo: Foo; +})=>{}, { + props: { + foo: { + type: Object, + required: true + } + } +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-exported-interface/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-exported-interface/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-exported-interface/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-exported-interface/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-exported-interface/input.tsx new file mode 100644 index 0000000..11dd98a --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-exported-interface/input.tsx @@ -0,0 +1,5 @@ +import { defineComponent } from 'vue' + +export interface Aliased { foo: number } + +defineComponent((props: Aliased) => { }) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-exported-interface/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-exported-interface/output.js new file mode 100644 index 0000000..116b527 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-exported-interface/output.js @@ -0,0 +1,12 @@ +import { defineComponent } from 'vue'; +export interface Aliased { + foo: number; +} +defineComponent((props: Aliased)=>{}, { + props: { + foo: { + type: Number, + required: true + } + } +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-exported-type/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-exported-type/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-exported-type/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-exported-type/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-exported-type/input.tsx new file mode 100644 index 0000000..ec6287c --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-exported-type/input.tsx @@ -0,0 +1,5 @@ +import { defineComponent } from 'vue' + +export type Aliased = { foo: number } + +defineComponent((props: Aliased) => { }) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-exported-type/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-exported-type/output.js new file mode 100644 index 0000000..efa7dd5 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-exported-type/output.js @@ -0,0 +1,12 @@ +import { defineComponent } from 'vue'; +export type Aliased = { + foo: number; +}; +defineComponent((props: Aliased)=>{}, { + props: { + foo: { + type: Number, + required: true + } + } +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-interface-extends/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-interface-extends/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-interface-extends/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-interface-extends/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-interface-extends/input.tsx new file mode 100644 index 0000000..e5ec12b --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-interface-extends/input.tsx @@ -0,0 +1,8 @@ +import { defineComponent } from 'vue' + +export interface A { a(): void } +export interface B extends A { b: boolean } +interface C { c: string } +interface Aliased extends B, C { foo: number } + +defineComponent((props: Aliased) => { }) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-interface-extends/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-interface-extends/output.js new file mode 100644 index 0000000..4d3bf16 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-interface-extends/output.js @@ -0,0 +1,33 @@ +import { defineComponent } from 'vue'; +export interface A { + a(): void; +} +export interface B extends A { + b: boolean; +} +interface C { + c: string; +} +interface Aliased extends B, C { + foo: number; +} +defineComponent((props: Aliased)=>{}, { + props: { + foo: { + type: Number, + required: true + }, + b: { + type: Boolean, + required: true + }, + a: { + type: Function, + required: true + }, + c: { + type: String, + required: true + } + } +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-interface/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-interface/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-interface/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-interface/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-interface/input.tsx new file mode 100644 index 0000000..a95a816 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-interface/input.tsx @@ -0,0 +1,7 @@ +import { defineComponent } from 'vue' + +interface Aliased { foo: number } + +defineComponent((props: Aliased) => { }) + +defineComponent((props: (Aliased)) => { }) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-interface/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-interface/output.js new file mode 100644 index 0000000..b9b8e7f --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-interface/output.js @@ -0,0 +1,20 @@ +import { defineComponent } from 'vue'; +interface Aliased { + foo: number; +} +defineComponent((props: Aliased)=>{}, { + props: { + foo: { + type: Number, + required: true + } + } +}); +defineComponent((props: (Aliased))=>{}, { + props: { + foo: { + type: Number, + required: true + } + } +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-type/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-type/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-type/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-type/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-type/input.tsx new file mode 100644 index 0000000..da9e0c8 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-type/input.tsx @@ -0,0 +1,5 @@ +import { defineComponent } from 'vue' + +type Aliased = { foo: number } + +defineComponent((props: Aliased) => { }) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-type/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-type/output.js new file mode 100644 index 0000000..cd7a921 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/reference-type/output.js @@ -0,0 +1,12 @@ +import { defineComponent } from 'vue'; +type Aliased = { + foo: number; +}; +defineComponent((props: Aliased)=>{}, { + props: { + foo: { + type: Number, + required: true + } + } +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/runtime-types/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/runtime-types/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/runtime-types/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/runtime-types/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/runtime-types/input.tsx new file mode 100644 index 0000000..df342ef --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/runtime-types/input.tsx @@ -0,0 +1,91 @@ +import { defineComponent } from 'vue' + +type FunctionType = { + (): void +} +type ObjectType = { + foo: string +} +type MixedType = { + foo: string + (): void +} + +interface FunctionInterface { + (): void +} +interface ObjectInterface { + foo: string +} +interface MixedInterface { + foo: string + (): void +} + +defineComponent((props: { + a: string + b: number + c: boolean + d: object + e: null + f: bigint + g: symbol + h: any + i: () => void + j: new () => object + k: string[] + l: Array + m: [string, number] + n: 'literal' + o: 123 + p: 123n + q: true + r: FunctionType + s: ObjectType + t: MixedType + u: FunctionInterface + v: ObjectInterface + w: MixedInterface +}) => { }) + +defineComponent((props: { + function: Function, + object: Object, + set: Set, + map: Map, + weakSet: WeakSet, + weakMap: WeakMap, + date: Date, + promise: Promise, + error: Error, + regexp: RegExp, +}) => { }) + +defineComponent((props: { + partial: Partial<{ foo: string }>, + required: Required<{ foo?: string }>, + readonly: Readonly<{ foo: string }>, + record: Record, + pick: Pick<{ foo: string, bar: number }, 'foo'>, + omit: Omit<{ foo: string, bar: number }, 'foo'>, + instance: InstanceType, +}) => { }) + +defineComponent((props: { + uppercase: Uppercase<'foo'>, + lowercase: Lowercase<'FOO'>, + capitalize: Capitalize<'foo'>, + uncapitalize: Uncapitalize<'FOO'>, +}) => { }) + +defineComponent((props: { + parameters: Parameters<() => void>, + constructorParameters: ConstructorParameters, +}) => { }) + +defineComponent((props: { + nonNullable: NonNullable, + exclude: Exclude, + extract: Extract, + omitThisParameter: OmitThisParameter<(this: string) => void>, +}) => { }) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/runtime-types/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/runtime-types/output.js new file mode 100644 index 0000000..ed8d7ab --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/runtime-types/output.js @@ -0,0 +1,323 @@ +import { defineComponent } from 'vue'; +type FunctionType = { + () : void; +}; +type ObjectType = { + foo: string; +}; +type MixedType = { + foo: string; + () : void; +}; +interface FunctionInterface { + () : void; +} +interface ObjectInterface { + foo: string; +} +interface MixedInterface { + foo: string; + () : void; +} +defineComponent((props: { + a: string; + b: number; + c: boolean; + d: object; + e: null; + f: bigint; + g: symbol; + h: any; + i: () => void; + j: new() => object; + k: string[]; + l: Array; + m: [string, number]; + n: 'literal'; + o: 123; + p: 123n; + q: true; + r: FunctionType; + s: ObjectType; + t: MixedType; + u: FunctionInterface; + v: ObjectInterface; + w: MixedInterface; +})=>{}, { + props: { + a: { + type: String, + required: true + }, + b: { + type: Number, + required: true + }, + c: { + type: Boolean, + required: true + }, + d: { + type: Object, + required: true + }, + e: { + type: null, + required: true + }, + f: { + type: BigInt, + required: true + }, + g: { + type: Symbol, + required: true + }, + h: { + type: null, + required: true + }, + i: { + type: Function, + required: true + }, + j: { + type: Function, + required: true + }, + k: { + type: Array, + required: true + }, + l: { + type: Array, + required: true + }, + m: { + type: Array, + required: true + }, + n: { + type: String, + required: true + }, + o: { + type: Number, + required: true + }, + p: { + type: Number, + required: true + }, + q: { + type: Boolean, + required: true + }, + r: { + type: Function, + required: true + }, + s: { + type: Object, + required: true + }, + t: { + type: [ + Object, + Function + ], + required: true + }, + u: { + type: Function, + required: true + }, + v: { + type: Object, + required: true + }, + w: { + type: [ + Object, + Function + ], + required: true + } + } +}); +defineComponent((props: { + function: Function; + object: Object; + set: Set; + map: Map; + weakSet: WeakSet; + weakMap: WeakMap; + date: Date; + promise: Promise; + error: Error; + regexp: RegExp; +})=>{}, { + props: { + function: { + type: Function, + required: true + }, + object: { + type: Object, + required: true + }, + set: { + type: Set, + required: true + }, + map: { + type: Map, + required: true + }, + weakSet: { + type: WeakSet, + required: true + }, + weakMap: { + type: WeakMap, + required: true + }, + date: { + type: Date, + required: true + }, + promise: { + type: Promise, + required: true + }, + error: { + type: Error, + required: true + }, + regexp: { + type: RegExp, + required: true + } + } +}); +defineComponent((props: { + partial: Partial<{ + foo: string; + }>; + required: Required<{ + foo?: string; + }>; + readonly: Readonly<{ + foo: string; + }>; + record: Record; + pick: Pick<{ + foo: string; + bar: number; + }, 'foo'>; + omit: Omit<{ + foo: string; + bar: number; + }, 'foo'>; + instance: InstanceType; +})=>{}, { + props: { + partial: { + type: Object, + required: true + }, + required: { + type: Object, + required: true + }, + readonly: { + type: Object, + required: true + }, + record: { + type: Object, + required: true + }, + pick: { + type: Object, + required: true + }, + omit: { + type: Object, + required: true + }, + instance: { + type: Object, + required: true + } + } +}); +defineComponent((props: { + uppercase: Uppercase<'foo'>; + lowercase: Lowercase<'FOO'>; + capitalize: Capitalize<'foo'>; + uncapitalize: Uncapitalize<'FOO'>; +})=>{}, { + props: { + uppercase: { + type: String, + required: true + }, + lowercase: { + type: String, + required: true + }, + capitalize: { + type: String, + required: true + }, + uncapitalize: { + type: String, + required: true + } + } +}); +defineComponent((props: { + parameters: Parameters<() => void>; + constructorParameters: ConstructorParameters; +})=>{}, { + props: { + parameters: { + type: Array, + required: true + }, + constructorParameters: { + type: Array, + required: true + } + } +}); +defineComponent((props: { + nonNullable: NonNullable; + exclude: Exclude; + extract: Extract; + omitThisParameter: OmitThisParameter<(this: string) => void>; +})=>{}, { + props: { + nonNullable: { + type: String, + required: true + }, + exclude: { + type: [ + String, + Number, + Boolean + ], + required: true + }, + extract: { + type: Boolean, + required: true + }, + omitThisParameter: { + type: Function, + required: true + } + } +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/scope/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/scope/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/scope/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/scope/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/scope/input.tsx new file mode 100644 index 0000000..90b8c45 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/scope/input.tsx @@ -0,0 +1,15 @@ +import { defineComponent } from 'vue' + +type Props = { + foo: string +} + +function scope() { + type Props = { + bar: number + } + + defineComponent((props: Props) => {}) +} + +defineComponent((props: Props) => {}) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/scope/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/scope/output.js new file mode 100644 index 0000000..d885dfa --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/scope/output.js @@ -0,0 +1,25 @@ +import { defineComponent } from 'vue'; +type Props = { + foo: string; +}; +function scope() { + type Props = { + bar: number; + }; + defineComponent((props: Props)=>{}, { + props: { + bar: { + type: Number, + required: true + } + } + }); +} +defineComponent((props: Props)=>{}, { + props: { + foo: { + type: String, + required: true + } + } +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/type-literal/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/type-literal/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/type-literal/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/type-literal/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/type-literal/input.tsx new file mode 100644 index 0000000..cfde591 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/type-literal/input.tsx @@ -0,0 +1,14 @@ +import { defineComponent } from 'vue' + +defineComponent((props: { + foo: number, // property + bar(): void, // method + 'baz': string, // string literal key + get qux(): number, // getter + (e: 'foo'): void, // call signature + (e: 'bar'): void, + + untyped1, + get untyped2(), + untyped3(), +}) => { }) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/type-literal/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/type-literal/output.js new file mode 100644 index 0000000..aeaf609 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/type-literal/output.js @@ -0,0 +1,43 @@ +import { defineComponent } from 'vue'; +defineComponent((props: { + foo: number; + bar(): void; + 'baz': string; + get qux(): number; + (e: 'foo') : void; + (e: 'bar') : void; + untyped1; + get untyped2(); + untyped3(); +})=>{}, { + props: { + foo: { + type: Number, + required: true + }, + bar: { + type: Function, + required: true + }, + 'baz': { + type: String, + required: true + }, + qux: { + type: Number, + required: true + }, + untyped1: { + type: null, + required: true + }, + untyped2: { + type: null, + required: true + }, + untyped3: { + type: Function, + required: true + } + } +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/union-type/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/union-type/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/union-type/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/union-type/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/union-type/input.tsx new file mode 100644 index 0000000..c96de52 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/union-type/input.tsx @@ -0,0 +1,18 @@ +import { defineComponent } from 'vue' + +interface CommonProps { + size?: 'xl' | 'l' | 'm' | 's' | 'xs' +} + +type ConditionalProps = + | { + color: 'normal' | 'primary' | 'secondary' + appearance: 'normal' | 'outline' | 'text' + } + | { + color: number + appearance: 'outline' + note: string + } + +defineComponent((props: CommonProps & ConditionalProps) => { }) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/union-type/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/union-type/output.js new file mode 100644 index 0000000..e12f597 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/union-type/output.js @@ -0,0 +1,35 @@ +import { defineComponent } from 'vue'; +interface CommonProps { + size?: 'xl' | 'l' | 'm' | 's' | 'xs'; +} +type ConditionalProps = { + color: 'normal' | 'primary' | 'secondary'; + appearance: 'normal' | 'outline' | 'text'; +} | { + color: number; + appearance: 'outline'; + note: string; +}; +defineComponent((props: CommonProps & ConditionalProps)=>{}, { + props: { + size: { + type: String, + required: false + }, + color: { + type: [ + String, + Number + ], + required: true + }, + appearance: { + type: String, + required: true + }, + note: { + type: String, + required: true + } + } +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-omit/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-omit/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-omit/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-omit/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-omit/input.tsx new file mode 100644 index 0000000..5531f66 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-omit/input.tsx @@ -0,0 +1,6 @@ +import { defineComponent } from 'vue' + +type T = { foo: number, bar: string, baz: boolean } +type K = 'foo' | 'bar' + +defineComponent((props: Omit) => { }) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-omit/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-omit/output.js new file mode 100644 index 0000000..90b2a43 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-omit/output.js @@ -0,0 +1,15 @@ +import { defineComponent } from 'vue'; +type T = { + foo: number; + bar: string; + baz: boolean; +}; +type K = 'foo' | 'bar'; +defineComponent((props: Omit)=>{}, { + props: { + baz: { + type: Boolean, + required: true + } + } +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-partial/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-partial/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-partial/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-partial/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-partial/input.tsx new file mode 100644 index 0000000..96d28fa --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-partial/input.tsx @@ -0,0 +1,5 @@ +import { defineComponent } from 'vue' + +type T = { foo: number, bar: string } + +defineComponent((props: Partial) => { }) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-partial/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-partial/output.js new file mode 100644 index 0000000..8740bb1 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-partial/output.js @@ -0,0 +1,17 @@ +import { defineComponent } from 'vue'; +type T = { + foo: number; + bar: string; +}; +defineComponent((props: Partial)=>{}, { + props: { + foo: { + type: Number, + required: false + }, + bar: { + type: String, + required: false + } + } +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-pick/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-pick/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-pick/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-pick/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-pick/input.tsx new file mode 100644 index 0000000..308a27d --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-pick/input.tsx @@ -0,0 +1,6 @@ +import { defineComponent } from 'vue' + +type T = { foo: number, bar: string, baz: boolean } +type K = 'foo' | 'bar' + +defineComponent((props: Pick) => { }) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-pick/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-pick/output.js new file mode 100644 index 0000000..750fd8e --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-pick/output.js @@ -0,0 +1,19 @@ +import { defineComponent } from 'vue'; +type T = { + foo: number; + bar: string; + baz: boolean; +}; +type K = 'foo' | 'bar'; +defineComponent((props: Pick)=>{}, { + props: { + foo: { + type: Number, + required: true + }, + bar: { + type: String, + required: true + } + } +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-required/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-required/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-required/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-required/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-required/input.tsx new file mode 100644 index 0000000..40d6ba1 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-required/input.tsx @@ -0,0 +1,5 @@ +import { defineComponent } from 'vue' + +type T = { foo?: number, bar?: string } + +defineComponent((props: Required) => { }) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-required/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-required/output.js new file mode 100644 index 0000000..7529eec --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/utility-type-required/output.js @@ -0,0 +1,17 @@ +import { defineComponent } from 'vue'; +type T = { + foo?: number; + bar?: string; +}; +defineComponent((props: Required)=>{}, { + props: { + foo: { + type: Number, + required: true + }, + bar: { + type: String, + required: true + } + } +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/with-defaults/config.json b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/with-defaults/config.json new file mode 100644 index 0000000..46eaaca --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/with-defaults/config.json @@ -0,0 +1,3 @@ +{ + "resolveType": true +} diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/with-defaults/input.tsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/with-defaults/input.tsx new file mode 100644 index 0000000..e552464 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/with-defaults/input.tsx @@ -0,0 +1,44 @@ +import { defineComponent } from 'vue' +import { defaults } from './foo' + +defineComponent((props: { + foo?: string, + bar?: number, + baz: boolean, + qux?(): number, + quux?(): void, + quuxx?: Promise, + fred?: string, +} = { + foo: 'hi', + qux() { + return 1 + }, + ['quux']() { }, + async quuxx() { + return await Promise.resolve('hi') + }, + get fred() { + return 'fred' + }, + }) => { }) + +defineComponent((props: { + foo?: string, + bar?: number, + baz: boolean, +} = { ...defaults }) => { }) + +defineComponent((props: { + foo?: string, + bar?: number, + baz: boolean, +} = defaults) => { }) + +defineComponent((props: { + foo?: () => 'string', +} = { + ['fo' + 'o']() { + return 'foo' + }, + }) => { }) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/with-defaults/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/with-defaults/output.js new file mode 100644 index 0000000..3f0a4e2 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/resolve-props-types/with-defaults/output.js @@ -0,0 +1,128 @@ +import { mergeDefaults as _mergeDefaults } from "vue"; +import { defineComponent } from 'vue'; +import { defaults } from './foo'; +defineComponent((props: { + foo?: string; + bar?: number; + baz: boolean; + qux?(): number; + quux?(): void; + quuxx?: Promise; + fred?: string; +} = { + foo: 'hi', + qux () { + return 1; + }, + ['quux'] () {}, + async quuxx () { + return await Promise.resolve('hi'); + }, + get fred () { + return 'fred'; + } +})=>{}, { + props: { + foo: { + type: String, + required: false, + default: 'hi' + }, + bar: { + type: Number, + required: false + }, + baz: { + type: Boolean, + required: true + }, + qux: { + type: Function, + required: false, + default: function() { + return 1; + } + }, + quux: { + type: Function, + required: false, + default: function() {} + }, + quuxx: { + type: Promise, + required: false, + default: async function() { + return await Promise.resolve('hi'); + } + }, + fred: { + type: String, + required: false, + default: ()=>{ + return 'fred'; + } + } + } +}); +defineComponent((props: { + foo?: string; + bar?: number; + baz: boolean; +} = { + ...defaults +})=>{}, { + props: /*#__PURE__*/ _mergeDefaults({ + foo: { + type: String, + required: false + }, + bar: { + type: Number, + required: false + }, + baz: { + type: Boolean, + required: true + } + }, { + ...defaults + }) +}); +defineComponent((props: { + foo?: string; + bar?: number; + baz: boolean; +} = defaults)=>{}, { + props: /*#__PURE__*/ _mergeDefaults({ + foo: { + type: String, + required: false + }, + bar: { + type: Number, + required: false + }, + baz: { + type: Boolean, + required: true + } + }, defaults) +}); +defineComponent((props: { + foo?: () => 'string'; +} = { + ['fo' + 'o'] () { + return 'foo'; + } +})=>{}, { + props: /*#__PURE__*/ _mergeDefaults({ + foo: { + type: Function, + required: false + } + }, { + ['fo' + 'o'] () { + return 'foo'; + } + }) +}); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/single-attr/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/single-attr/input.jsx new file mode 100644 index 0000000..e099411 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/single-attr/input.jsx @@ -0,0 +1 @@ +
single
diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/single-attr/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/single-attr/output.js new file mode 100644 index 0000000..5a3c502 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/single-attr/output.js @@ -0,0 +1,2 @@ +import { createTextVNode as _createTextVNode, createVNode as _createVNode } from "vue"; +_createVNode("div", x, [_createTextVNode("single")], 16); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/slot-in-arrow-function-bug/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/slot-in-arrow-function-bug/input.jsx new file mode 100644 index 0000000..01e49e5 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/slot-in-arrow-function-bug/input.jsx @@ -0,0 +1,17 @@ +const Component = (row) => ( + + + {t('text1')} + + + {t('text2')} + + + {t('text3')} + + +) diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/slot-in-arrow-function-bug/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/slot-in-arrow-function-bug/output.js new file mode 100644 index 0000000..7de5531 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/slot-in-arrow-function-bug/output.js @@ -0,0 +1,46 @@ +import { createVNode as _createVNode, isVNode as _isVNode, resolveComponent as _resolveComponent } from "vue"; +function _isSlot(s) { + return typeof s === "function" || ({}).toString.call(s) === "[object Object]" && !_isVNode(s); +} +const Component = (row)=>{ + let _slot, _slot2, _slot3; + return _createVNode(_resolveComponent("NSpace"), null, { + default: ()=>[ + _createVNode(_resolveComponent("NButton"), { + "type": "primary", + "secondary": true, + "onClick": handler1 + }, _isSlot(_slot = t('text1')) ? _slot : { + default: ()=>[ + _slot + ], + _: 1 + }, 8, [ + "secondary", + "onClick" + ]), + _createVNode(_resolveComponent("NButton"), { + "onClick": handler2 + }, _isSlot(_slot2 = t('text2')) ? _slot2 : { + default: ()=>[ + _slot2 + ], + _: 1 + }, 8, [ + "onClick" + ]), + _createVNode(_resolveComponent("NButton"), { + "type": "error", + "onClick": handler3 + }, _isSlot(_slot3 = t('text3')) ? _slot3 : { + default: ()=>[ + _slot3 + ], + _: 1 + }, 8, [ + "onClick" + ]) + ], + _: 1 + }); +}; diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/specifiers-merged-into-single-import-decl/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/specifiers-merged-into-single-import-decl/input.jsx new file mode 100644 index 0000000..491633b --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/specifiers-merged-into-single-import-decl/input.jsx @@ -0,0 +1,4 @@ +import { createVNode, Fragment as _Fragment } from 'vue'; +import { vShow } from 'vue' + +<_Fragment /> diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/specifiers-merged-into-single-import-decl/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/specifiers-merged-into-single-import-decl/output.js new file mode 100644 index 0000000..e66cfd1 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/specifiers-merged-into-single-import-decl/output.js @@ -0,0 +1,4 @@ +import { createVNode as _createVNode } from "vue"; +import { createVNode, Fragment as _Fragment } from 'vue'; +import { vShow } from 'vue'; +_createVNode(_Fragment, null, null); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-html/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-html/input.jsx new file mode 100644 index 0000000..9dfc7c7 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-html/input.jsx @@ -0,0 +1 @@ +

diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-html/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-html/output.js new file mode 100644 index 0000000..a26721f --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-html/output.js @@ -0,0 +1,4 @@ +import { createVNode as _createVNode } from "vue"; +_createVNode("h1", { + "innerHTML": "
foo
" +}, null, 8, ["innerHTML"]); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-value-supports-variable/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-value-supports-variable/input.jsx new file mode 100644 index 0000000..69ddcd3 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-value-supports-variable/input.jsx @@ -0,0 +1,13 @@ +const foo = 'foo'; + +const a = () => 'a'; + +const b = { c: 'c' }; +<> + + + + + + + diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-value-supports-variable/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-value-supports-variable/output.js new file mode 100644 index 0000000..4523fc3 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-value-supports-variable/output.js @@ -0,0 +1,42 @@ +import { Fragment as _Fragment, createVNode as _createVNode, resolveComponent as _resolveComponent } from "vue"; +const foo = 'foo'; +const a = () => 'a'; +const b = { + c: 'c' +}; +_createVNode(_Fragment, null, [ + _createVNode(_resolveComponent("A"), { [foo]: xx, ["onUpdate" + foo]: $event => xx = $event }, null, 16), + _createVNode(_resolveComponent("B"), { + "modelValue": xx, + "modelModifiers": { "a": true }, + "onUpdate:modelValue": $event => xx = $event, + }, null, 8, ["modelValue", "onUpdate:modelValue"]), + _createVNode(_resolveComponent("C"), { + [foo]: xx, + [foo + "Modifiers"]: { + "a": true + }, + ["onUpdate" + foo]: $event => xx = $event, + }, null, 16), + _createVNode(_resolveComponent("D"), { + [foo === 'foo' ? 'a' : 'b']: xx, + [(foo === 'foo' ? 'a' : 'b') + "Modifiers"]: { + "a": true + }, + ["onUpdate" + (foo === 'foo' ? 'a' : 'b')]: $event => xx = $event, + }, null, 16), + _createVNode(_resolveComponent("E"), { + [a()]: xx, + [a() + "Modifiers"]: { + "a": true + }, + ["onUpdate" + a()]: $event => xx = $event + }, null, 16), + _createVNode(_resolveComponent("F"), { + [b.c]: xx, + [b.c + "Modifiers"]: { + "a": true + }, + ["onUpdate" + b.c]: $event => xx = $event + }, null, 16), +]); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-arg-and-modifier/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-arg-and-modifier/input.jsx new file mode 100644 index 0000000..28aa3c8 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-arg-and-modifier/input.jsx @@ -0,0 +1 @@ + diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-arg-and-modifier/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-arg-and-modifier/output.js new file mode 100644 index 0000000..2728559 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-arg-and-modifier/output.js @@ -0,0 +1,11 @@ +import { createVNode as _createVNode, resolveComponent as _resolveComponent } from "vue"; +_createVNode(_resolveComponent("Child"), { + "value": this.foo, + "valueModifiers": { + "double": true + }, + "onUpdate:value": ($event)=>this.foo = $event +}, null, 8, [ + "value", + "onUpdate:value" +]); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-checkbox/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-checkbox/input.jsx new file mode 100644 index 0000000..248df3e --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-checkbox/input.jsx @@ -0,0 +1 @@ + diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-checkbox/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-checkbox/output.js new file mode 100644 index 0000000..a7b29c5 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-checkbox/output.js @@ -0,0 +1,5 @@ +import { createVNode as _createVNode, vModelCheckbox as _vModelCheckbox, withDirectives as _withDirectives } from "vue"; +_withDirectives(_createVNode("input", { + "type": "checkbox", + "onUpdate:modelValue": $event => test = $event +}, null, 8, ["onUpdate:modelValue"]), [[_vModelCheckbox, test]]); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-dynamic-type-input/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-dynamic-type-input/input.jsx new file mode 100644 index 0000000..e672d8a --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-dynamic-type-input/input.jsx @@ -0,0 +1 @@ + diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-dynamic-type-input/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-dynamic-type-input/output.js new file mode 100644 index 0000000..d25b596 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-dynamic-type-input/output.js @@ -0,0 +1,5 @@ +import { createVNode as _createVNode, vModelDynamic as _vModelDynamic, withDirectives as _withDirectives } from "vue"; +_withDirectives(_createVNode("input", { + "type": type, + "onUpdate:modelValue": $event => test = $event +}, null, 8, ["type", "onUpdate:modelValue"]), [[_vModelDynamic, test]]); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-input-lazy-modifier/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-input-lazy-modifier/input.jsx new file mode 100644 index 0000000..be55a2c --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-input-lazy-modifier/input.jsx @@ -0,0 +1 @@ + diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-input-lazy-modifier/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-input-lazy-modifier/output.js new file mode 100644 index 0000000..f10f6f2 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-input-lazy-modifier/output.js @@ -0,0 +1,6 @@ +import { createVNode as _createVNode, vModelText as _vModelText, withDirectives as _withDirectives } from "vue"; +_withDirectives(_createVNode("input", { + "onUpdate:modelValue": $event => test = $event +}, null, 8, ["onUpdate:modelValue"]), [[_vModelText, test, void 0, { + lazy: true +}]]); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-radio/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-radio/input.jsx new file mode 100644 index 0000000..356b722 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-radio/input.jsx @@ -0,0 +1,4 @@ +<> + + + diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-radio/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-radio/output.js new file mode 100644 index 0000000..bc2d4d2 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-radio/output.js @@ -0,0 +1,12 @@ +import { Fragment as _Fragment, createVNode as _createVNode, vModelRadio as _vModelRadio, withDirectives as _withDirectives } from "vue"; +_createVNode(_Fragment, null, [_withDirectives(_createVNode("input", { + "type": "radio", + "value": "1", + "onUpdate:modelValue": $event => test = $event, + "name": "test" +}, null, 8, ["onUpdate:modelValue"]), [[_vModelRadio, test]]), _withDirectives(_createVNode("input", { + "type": "radio", + "value": "2", + "onUpdate:modelValue": $event => test = $event, + "name": "test" +}, null, 8, ["onUpdate:modelValue"]), [[_vModelRadio, test]])]); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-select/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-select/input.jsx new file mode 100644 index 0000000..6f1516c --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-select/input.jsx @@ -0,0 +1,5 @@ + diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-select/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-select/output.js new file mode 100644 index 0000000..ec2d6ac --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-select/output.js @@ -0,0 +1,15 @@ +import { + createTextVNode as _createTextVNode, + createVNode as _createVNode, + vModelSelect as _vModelSelect, + withDirectives as _withDirectives, +} from "vue"; +_withDirectives(_createVNode("select", { + "onUpdate:modelValue": $event => test = $event +}, [_createVNode("option", { + "value": "1" +}, [_createTextVNode("a")]), _createVNode("option", { + "value": 2 +}, [_createTextVNode("b")]), _createVNode("option", { + "value": 3 +}, [_createTextVNode("c")])], 8, ["onUpdate:modelValue"]), [[_vModelSelect, test]]); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-text-input/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-text-input/input.jsx new file mode 100644 index 0000000..2052a0c --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-text-input/input.jsx @@ -0,0 +1 @@ + diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-text-input/output.js b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-text-input/output.js new file mode 100644 index 0000000..ce8e4d4 --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-text-input/output.js @@ -0,0 +1,4 @@ +import { createVNode as _createVNode, vModelText as _vModelText, withDirectives as _withDirectives } from "vue"; +_withDirectives(_createVNode("input", { + "onUpdate:modelValue": $event => test = $event +}, null, 8, ["onUpdate:modelValue"]), [[_vModelText, test]]); diff --git a/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-textarea/input.jsx b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-textarea/input.jsx new file mode 100644 index 0000000..72e35bf --- /dev/null +++ b/rust-plugins/vue-jsx/crates/visitor/tests/fixture/v-model-with-textarea/input.jsx @@ -0,0 +1 @@ +