From ad48b765b60bfdd1e4d116a12df6a18fca087c19 Mon Sep 17 00:00:00 2001 From: Bert Belder Date: Mon, 12 Oct 2020 08:09:23 +0200 Subject: [PATCH] Create Rust crate for extracting import specifiers from source code --- service/import_scanner/.gitignore | 2 + service/import_scanner/.rustfmt.toml | 4 + service/import_scanner/Cargo.lock | 815 +++++++++++++++++++++++++++ service/import_scanner/Cargo.toml | 30 + service/import_scanner/src/lib.rs | 251 +++++++++ 5 files changed, 1102 insertions(+) create mode 100644 service/import_scanner/.gitignore create mode 100644 service/import_scanner/.rustfmt.toml create mode 100644 service/import_scanner/Cargo.lock create mode 100644 service/import_scanner/Cargo.toml create mode 100644 service/import_scanner/src/lib.rs diff --git a/service/import_scanner/.gitignore b/service/import_scanner/.gitignore new file mode 100644 index 0000000..2e0ed6d --- /dev/null +++ b/service/import_scanner/.gitignore @@ -0,0 +1,2 @@ +/.vscode +/target diff --git a/service/import_scanner/.rustfmt.toml b/service/import_scanner/.rustfmt.toml new file mode 100644 index 0000000..8b888c2 --- /dev/null +++ b/service/import_scanner/.rustfmt.toml @@ -0,0 +1,4 @@ +# Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. +max_width = 80 +tab_spaces = 2 +edition = "2018" \ No newline at end of file diff --git a/service/import_scanner/Cargo.lock b/service/import_scanner/Cargo.lock new file mode 100644 index 0000000..7b9d954 --- /dev/null +++ b/service/import_scanner/Cargo.lock @@ -0,0 +1,815 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[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 = "aho-corasick" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86" +dependencies = [ + "memchr", +] + +[[package]] +name = "ast_node" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6ee2941db3551563d29eaf5214cd3d7b2f322e0c0e3954f5ae020f860bae8c" +dependencies = [ + "darling", + "pmutil", + "proc-macro2", + "quote", + "swc_macros_common", + "syn", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "bumpalo" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" + +[[package]] +name = "byteorder" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "console_error_panic_hook" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "darling" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "enum_kind" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e57153e35187d51f08471d5840459ff29093473e7bedd004a1414985aab92f3" +dependencies = [ + "pmutil", + "proc-macro2", + "swc_macros_common", + "syn", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "from_variant" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "039885ad6579a86b94ad8df696cce8c530da496bf7b07b12fec8d6c4cd654bb9" +dependencies = [ + "pmutil", + "proc-macro2", + "swc_macros_common", + "syn", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "getrandom" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "hashbrown" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "import_scanner" +version = "0.1.0" +dependencies = [ + "serde", + "serde_derive", + "serde_json", + "swc_common", + "swc_ecmascript", + "wasm-bindgen", + "wasm-bindgen-test", +] + +[[package]] +name = "indexmap" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "is-macro" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04807f3dc9e3ea39af3f8469a5297267faf94859637afb836b33f47d9b2650ee" +dependencies = [ + "Inflector", + "pmutil", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "itoa" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" + +[[package]] +name = "js-sys" +version = "0.3.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca059e81d9486668f12d455a4ea6daa600bd408134cd17e3d3fb5a32d1f016f8" +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.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2448f6066e80e3bfc792e9c98bf705b4b0fc6e8ef5b43e5889aff0eaa9c58743" + +[[package]] +name = "log" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" + +[[package]] +name = "new_debug_unreachable" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-integer" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad" + +[[package]] +name = "owning_ref" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ff55baddef9e4ad00f88b6c743a2a8062d4c6ade126c2a528644b8e444d52ce" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "phf_generator" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pmutil" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3894e5d549cccbe44afecf72922f277f603cd4bb0219c8342631ef18fffbe004" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20" + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "proc-macro2" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom", + "libc", + "rand_chacha", + "rand_core", + "rand_hc", + "rand_pcg", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core", +] + +[[package]] +name = "regex" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f45b719a674bf4b828ff318906d6c133264c793eff7a41e30074a45b5099e2" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", + "thread_local", +] + +[[package]] +name = "regex-syntax" +version = "0.6.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17be88d9eaa858870aa5e48cc406c206e4600e983fc4f06bbe5750d93d09761" + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "scoped-tls" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" + +[[package]] +name = "serde" +version = "1.0.116" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.116" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a230ea9107ca2220eea9d46de97eddcb04cd00e92d13dda78e478dd33fa82bd4" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "siphasher" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa8f3741c7372e75519bd9346068370c9cdaabcc1f9599cbcf2a2719352286b7" + +[[package]] +name = "smallvec" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "string_cache" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2940c75beb4e3bf3a494cef919a747a2cb81e52571e212bfbd185074add7208a" +dependencies = [ + "lazy_static", + "new_debug_unreachable", + "phf_shared", + "precomputed-hash", + "serde", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f24c8e5e19d22a726626f1a5e16fe15b132dcf21d10177fa5a45ce7962996b97" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", +] + +[[package]] +name = "string_enum" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fdb6536756cfd35ee18b9a9972ab2a699d405cc57e0ad0532022960f30d581" +dependencies = [ + "pmutil", + "proc-macro2", + "quote", + "swc_macros_common", + "syn", +] + +[[package]] +name = "strsim" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" + +[[package]] +name = "swc_atoms" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34d36e046dd23a5b5f7f9d4fd1f9ca0eb07dfd67c87521ecd358dc26c4ad1f42" +dependencies = [ + "string_cache", + "string_cache_codegen", +] + +[[package]] +name = "swc_common" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f47e6a3f5701ea126cf5022e931be682dd87ab1bcbb53de3d49689c4c3a1692" +dependencies = [ + "ast_node", + "cfg-if", + "either", + "from_variant", + "fxhash", + "log", + "once_cell", + "owning_ref", + "scoped-tls", + "serde", + "swc_visit", + "unicode-width", +] + +[[package]] +name = "swc_ecma_ast" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35c4031fc0fbdf091100e504e00fc8e9cb4c7e85396d8f22813ef3c3bf1d735c" +dependencies = [ + "enum_kind", + "is-macro", + "num-bigint", + "serde", + "string_enum", + "swc_atoms", + "swc_common", +] + +[[package]] +name = "swc_ecma_parser" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf2847e59f92d8e682bd3e0dabc9e9ab2d3d4148218ddabf508b483174982f37" +dependencies = [ + "either", + "enum_kind", + "fxhash", + "log", + "num-bigint", + "serde", + "smallvec", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_parser_macros", + "swc_ecma_visit", + "unicode-xid", +] + +[[package]] +name = "swc_ecma_parser_macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8798810e2c79b884cf238bcb72b4bd12375121ee91724f1ceeb54b6e38a138e7" +dependencies = [ + "pmutil", + "proc-macro2", + "quote", + "swc_macros_common", + "syn", +] + +[[package]] +name = "swc_ecma_visit" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04a3c00c0a4ed846261e653fb4ae734bffd9a29795042f7d414a1e6f01b9c812" +dependencies = [ + "num-bigint", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_visit", +] + +[[package]] +name = "swc_ecmascript" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5866615c98d2252eb75d6986af0701570a0ca86ce3e6769c1e951f33c7eb7d10" +dependencies = [ + "swc_ecma_ast", + "swc_ecma_parser", + "swc_ecma_visit", +] + +[[package]] +name = "swc_macros_common" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18a9f27d290938370597d363df9a77ba4be8e2bc99f32f69eb5245cdeed3c512" +dependencies = [ + "pmutil", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "swc_visit" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b95ece564c6d6bf980140cedd960697226098800f2de07dad6a140c2dbdcc742" +dependencies = [ + "either", + "swc_visit_macros", +] + +[[package]] +name = "swc_visit_macros" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59a75265aea70df7a405e2aafb104c976017fe9a54e7b770017d0583873a3cff" +dependencies = [ + "Inflector", + "pmutil", + "proc-macro2", + "quote", + "swc_macros_common", + "syn", +] + +[[package]] +name = "syn" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e03e57e4fcbfe7749842d53e24ccb9aa12b7252dbe5e91d2acad31834c8b8fdd" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "thread_local" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "unicode-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" + +[[package]] +name = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasm-bindgen" +version = "0.2.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ac64ead5ea5f05873d7c12b545865ca2b8d28adfc50a49b84770a3a97265d42" +dependencies = [ + "cfg-if", + "serde", + "serde_json", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f22b422e2a757c35a73774860af8e112bff612ce6cb604224e8e47641a9e4f68" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7866cab0aa01de1edf8b5d7936938a7e397ee50ce24119aef3e1eaa3b6171da" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b13312a745c08c469f0b292dd2fcd6411dba5f7160f593da6ef69b64e407038" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d649a3145108d7d3fbcde896a468d1bd636791823c9921135218ad89be08307" + +[[package]] +name = "wasm-bindgen-test" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34d1cdc8b98a557f24733d50a1199c4b0635e465eecba9c45b214544da197f64" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "scoped-tls", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test-macro", +] + +[[package]] +name = "wasm-bindgen-test-macro" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8fb9c67be7439ee8ab1b7db502a49c05e51e2835b66796c705134d9b8e1a585" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "web-sys" +version = "0.3.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bf6ef87ad7ae8008e15a355ce696bed26012b7caa21605188cfd8214ab51e2d" +dependencies = [ + "js-sys", + "wasm-bindgen", +] diff --git a/service/import_scanner/Cargo.toml b/service/import_scanner/Cargo.toml new file mode 100644 index 0000000..8406a0e --- /dev/null +++ b/service/import_scanner/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "import_scanner" +version = "0.1.0" +authors = ["Bert Belder "] +edition = "2018" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +swc_common = "0.10.3" +swc_ecmascript = { version = "0.9.3", default-features = false, features = [ + "parser", + "visit" +] } +serde = { version = "1.0.116", features = ["derive"] } +serde_derive = "1.0.116" +serde_json = { version = "1.0.58", features = ["preserve_order"] } +wasm-bindgen = { version = "0.2.68", features = ["serde-serialize"] } + +[dev-dependencies] +wasm-bindgen-test = "0.3.18" + +[package.metadata.wasm-pack.profile.release] +wasm-opt = ["-Oz", "--enable-mutable-globals"] + +[profile.release] +lto = "fat" +opt-level = "z" +panic = "abort" diff --git a/service/import_scanner/src/lib.rs b/service/import_scanner/src/lib.rs new file mode 100644 index 0000000..922c5fe --- /dev/null +++ b/service/import_scanner/src/lib.rs @@ -0,0 +1,251 @@ +use swc_common::{sync::Lrc, FileName, Loc, SourceMap, Span, DUMMY_SP}; +use swc_ecmascript::{ + ast, + parser::{lexer::Lexer, EsConfig, PResult, Parser, StringInput, Syntax}, + visit::{Node, Visit, VisitWith}, +}; + +use serde::Serialize; +use wasm_bindgen::prelude::*; + +#[serde(rename_all = "camelCase")] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)] +pub enum ImportKind { + Import, + Export, +} + +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] +pub struct ImportDescriptor { + pub specifier: String, + pub kind: ImportKind, + pub col: usize, + pub line: usize, +} + +#[wasm_bindgen] +pub fn get_imports(source: &[u8]) -> Box<[u8]> { + let source = String::from_utf8_lossy(source).into(); + let imports = get_imports_impl(source).ok(); + let json = serde_json::to_vec(&imports).unwrap(); + json.into_boxed_slice() +} + +#[inline(always)] +fn get_imports_impl(source: String) -> PResult> { + let source_map = Lrc::::default(); + let source_file = source_map.new_source_file(FileName::Anon, source); + let lexer = Lexer::>::new( + Syntax::Es(EsConfig { + jsx: true, // TODO: off? + num_sep: true, + class_private_props: true, + class_private_methods: true, + class_props: true, + fn_bind: true, + decorators: true, // TODO: off? + decorators_before_export: true, // TODO: off? + export_default_from: true, + export_namespace_from: true, + dynamic_import: true, + nullish_coalescing: true, + optional_chaining: true, + import_meta: true, + top_level_await: true, + import_assertions: true, + }), + Default::default(), + (&*source_file).into(), + None, + ); + let mut parser = Parser::new_from(lexer); + let module = parser.parse_module()?; + let mut visitor = ImportVisitor { + source_map: &source_map, + imports: vec![], + }; + module.visit_with(&ast::Invalid { span: DUMMY_SP }, &mut visitor); + Ok(visitor.imports) +} + +struct ImportVisitor<'a> { + pub imports: Vec, + source_map: &'a SourceMap, +} + +impl<'a> ImportVisitor<'a> { + #[inline(always)] + fn get_location(&self, span: Span) -> (usize, usize) { + let Loc { line, col, .. } = self.source_map.lookup_char_pos(span.lo); + // Swc does not export any public module to convert a CharPos to a number. + let col: usize = unsafe { std::mem::transmute(col) }; + (line, col) + } +} + +impl<'a> Visit for ImportVisitor<'a> { + #[inline(always)] + fn visit_import_decl(&mut self, node: &ast::ImportDecl, _parent: &dyn Node) { + let specifier = node.src.value.to_string(); + let (line, col) = self.get_location(node.span); + self.imports.push(ImportDescriptor { + specifier, + kind: ImportKind::Import, + line, + col, + }); + } + + #[inline(always)] + fn visit_named_export( + &mut self, + node: &ast::NamedExport, + _parent: &dyn Node, + ) { + if let Some(src) = &node.src { + let specifier = src.value.to_string(); + let (line, col) = self.get_location(node.span); + self.imports.push(ImportDescriptor { + specifier, + kind: ImportKind::Export, + col, + line, + }); + } + } + + #[inline(always)] + fn visit_export_all(&mut self, node: &ast::ExportAll, _parent: &dyn Node) { + let specifier = node.src.value.to_string(); + let (line, col) = self.get_location(node.span); + self.imports.push(ImportDescriptor { + specifier, + kind: ImportKind::Export, + line, + col, + }); + } + + #[inline(always)] + fn visit_stmts(&mut self, _imports: &[ast::Stmt], _parent: &dyn Node) {} +} + +#[cfg(test)] +mod tests { + use super::*; + use wasm_bindgen_test::*; + + wasm_bindgen_test_configure!(run_in_browser); + + #[test] + #[wasm_bindgen_test] + fn test_ok() { + let source = br#" +import something from "../module_with_default_export.js"; +import { something_else } from "ordinary_module"; +import * as everything from "some_other_module.js"; + +import "same_line_1"; import "same_line_2"; + +import ""; // Empty specifier. + +await everything(); + +import "after_top_level_await"; + +export * from "complete re-exported module"; +export { that } from "partially re-exported module"; + +import "repeated_import"; +import "repeated_import"; + +/* padding */ import _ from "at column 14"; +"#; + let imports_json = serde_json::json!([ + { + "specifier": "../module_with_default_export.js", + "kind": "import", + "col": 0, + "line": 2 + }, + { + "specifier": "ordinary_module", + "kind": "import", + "col": 0, + "line": 3 + }, + { + "specifier": "some_other_module.js", + "kind": "import", + "col": 0, + "line": 4 + }, + { + "specifier": "same_line_1", + "kind": "import", + "col": 0, + "line": 6 + }, + { + "specifier": "same_line_2", + "kind": "import", + "col": 22, + "line": 6 + }, + { + "specifier": "", + "kind": "import", + "col": 0, + "line": 8 + }, + { + "specifier": "after_top_level_await", + "kind": "import", + "col": 0, + "line": 12 + }, + { + "specifier": "complete re-exported module", + "kind": "export", + "col": 0, + "line": 14 + }, + { + "specifier": "partially re-exported module", + "kind": "export", + "col": 0, + "line": 15 + }, + { + "specifier": "repeated_import", + "kind": "import", + "col": 0, + "line": 17 + }, + { + "specifier": "repeated_import", + "kind": "import", + "col": 0, + "line": 18 + }, + { + "specifier": "at column 14", + "kind": "import", + "col": 14, + "line": 20 + } + ]); + let actual = get_imports(source); + let expected = serde_json::to_vec(&imports_json) + .unwrap() + .into_boxed_slice(); + assert_eq!(actual, expected); + } + + #[test] + #[wasm_bindgen_test] + fn test_err() { + let r = get_imports(b"{;"); + assert_eq!(r, b"null"[..].into()); + } +}