mirror of
https://github.com/denoland/deno.git
synced 2025-02-01 12:16:11 -05:00
fix: upgrade to deno_ast 0.33 (#22341)
* Uses diagnostics from deno_ast * Real fix for https://github.com/denoland/deno/pull/22310 * Moves `deno lint --json` code here * Upgrades swc Closes #22117 Closes #22109 Closes #21927 Closes #20993
This commit is contained in:
parent
b07a156b1d
commit
e5e2c45998
30 changed files with 326 additions and 1185 deletions
|
@ -56,7 +56,7 @@
|
||||||
"ext/websocket/autobahn/reports"
|
"ext/websocket/autobahn/reports"
|
||||||
],
|
],
|
||||||
"plugins": [
|
"plugins": [
|
||||||
"https://plugins.dprint.dev/typescript-0.88.10.wasm",
|
"https://plugins.dprint.dev/typescript-0.89.0.wasm",
|
||||||
"https://plugins.dprint.dev/json-0.19.1.wasm",
|
"https://plugins.dprint.dev/json-0.19.1.wasm",
|
||||||
"https://plugins.dprint.dev/markdown-0.16.3.wasm",
|
"https://plugins.dprint.dev/markdown-0.16.3.wasm",
|
||||||
"https://plugins.dprint.dev/toml-0.6.0.wasm",
|
"https://plugins.dprint.dev/toml-0.6.0.wasm",
|
||||||
|
|
146
Cargo.lock
generated
146
Cargo.lock
generated
|
@ -92,6 +92,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a"
|
checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
"getrandom",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"version_check",
|
"version_check",
|
||||||
"zerocopy",
|
"zerocopy",
|
||||||
|
@ -1071,14 +1072,17 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_ast"
|
name = "deno_ast"
|
||||||
version = "0.32.1"
|
version = "0.33.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6fa239d4d69bb6c61bd73e0fc23e3688c7e87e1f47f2f37f4cff7a0080017299"
|
checksum = "9fdafff817ae3ad89672d54cd8daebc86dc352065ccc18691605043e6b845d00"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64",
|
||||||
"deno_media_type",
|
"deno_media_type",
|
||||||
|
"deno_terminal",
|
||||||
"dprint-swc-ext",
|
"dprint-swc-ext",
|
||||||
|
"once_cell",
|
||||||
|
"percent-encoding",
|
||||||
"serde",
|
"serde",
|
||||||
"swc_atoms",
|
"swc_atoms",
|
||||||
"swc_bundler",
|
"swc_bundler",
|
||||||
|
@ -1088,7 +1092,6 @@ dependencies = [
|
||||||
"swc_ecma_ast",
|
"swc_ecma_ast",
|
||||||
"swc_ecma_codegen",
|
"swc_ecma_codegen",
|
||||||
"swc_ecma_codegen_macros",
|
"swc_ecma_codegen_macros",
|
||||||
"swc_ecma_dep_graph",
|
|
||||||
"swc_ecma_loader",
|
"swc_ecma_loader",
|
||||||
"swc_ecma_parser",
|
"swc_ecma_parser",
|
||||||
"swc_ecma_transforms_base",
|
"swc_ecma_transforms_base",
|
||||||
|
@ -1106,6 +1109,7 @@ dependencies = [
|
||||||
"swc_visit",
|
"swc_visit",
|
||||||
"swc_visit_macros",
|
"swc_visit_macros",
|
||||||
"text_lines",
|
"text_lines",
|
||||||
|
"unicode-width",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1281,9 +1285,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_doc"
|
name = "deno_doc"
|
||||||
version = "0.100.0"
|
version = "0.103.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d1df9ba70ba4335847c304a9a771da4833e4e0c219758b8b58db36c096061b7b"
|
checksum = "73fe6bd8144456ca3f01b8d1cd1b668b974c84dc94cb642936c0938348b17017"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
@ -1305,9 +1309,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_emit"
|
name = "deno_emit"
|
||||||
version = "0.35.0"
|
version = "0.36.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "870bd633969034668194c6cdf7d6f8aa94296e26db554aba1ea5f074aa966c37"
|
checksum = "3c5002f2c25489fb993132dc0cb0dabd41bae70a8629168db4bd726ee2e296ac"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64",
|
||||||
|
@ -1375,9 +1379,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_graph"
|
name = "deno_graph"
|
||||||
version = "0.64.2"
|
version = "0.65.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a60def166df99195520b3b020974fdf7d3865b7a07eca5284ff0d24235f972da"
|
checksum = "bd7e17cc32255286c37c81a44425b71c4a7e1aadb7bdf65968a31d28415fa1d0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
@ -1485,9 +1489,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_lint"
|
name = "deno_lint"
|
||||||
version = "0.55.2"
|
version = "0.56.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4a23713fe2da1e320e95f6b6d137b00b75554dfe3018ebc89bc7922b0dae37d8"
|
checksum = "0367f164f601211ea2593937d1b73c0f46ab966ab0f7b16d4eb1d7582a7be401"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"deno_ast",
|
"deno_ast",
|
||||||
|
@ -1755,9 +1759,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_terminal"
|
name = "deno_terminal"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b847702ef57565e1417fad2291f65a3c8a5ecf2ba38d64e56f02828e7546d891"
|
checksum = "7e6337d4e7f375f8b986409a76fbeecfa4bd8a1343e63355729ae4befa058eaf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"termcolor",
|
"termcolor",
|
||||||
|
@ -2158,22 +2162,23 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dprint-plugin-typescript"
|
name = "dprint-plugin-typescript"
|
||||||
version = "0.88.10"
|
version = "0.89.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ff4df63bcc9131ef68094ed468bf7b252e5771ed120545ea42983e99e411d467"
|
checksum = "7dedd02b402282e71c309aa3e1e27bc8557517c968effe52783cdeeafdd17cc2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"deno_ast",
|
"deno_ast",
|
||||||
"dprint-core",
|
"dprint-core",
|
||||||
|
"percent-encoding",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dprint-swc-ext"
|
name = "dprint-swc-ext"
|
||||||
version = "0.13.0"
|
version = "0.14.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7b2f24ce6b89a06ae3eb08d5d4f88c05d0aef1fa58e2eba8dd92c97b84210c25"
|
checksum = "ebaedd46a16dd179b260a9fcb56be5780814afcb20f615eedde6acf971c9628e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
|
@ -2383,9 +2388,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "eszip"
|
name = "eszip"
|
||||||
version = "0.60.0"
|
version = "0.62.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a060f8bb81229bd98c26e1c0efc066be2460558ee9187e73e40a89bd2c949f06"
|
checksum = "7a26aa6791e6021e9e3ffc6bc8ab00ff2d0d748c64a75b7333076d973ce32f6b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64",
|
||||||
|
@ -4343,9 +4348,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "percent-encoding"
|
name = "percent-encoding"
|
||||||
version = "2.3.0"
|
version = "2.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
|
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pest"
|
name = "pest"
|
||||||
|
@ -5741,9 +5746,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swc_bundler"
|
name = "swc_bundler"
|
||||||
version = "0.223.20"
|
version = "0.225.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4d7530df85b1a56f6a879ca102dc59718db4bcd6bfff55fb8bb379fbeab6c88c"
|
checksum = "26491762e84ae1d0a2e179fe48066072834777a1b12e8e88a7f07c8f92cc0188"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"crc",
|
"crc",
|
||||||
|
@ -5770,10 +5775,24 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swc_common"
|
name = "swc_cached"
|
||||||
version = "0.33.12"
|
version = "0.3.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9b3ae36feceded27f0178dc9dabb49399830847ffb7f866af01798844de8f973"
|
checksum = "630c761c74ac8021490b78578cc2223aa4a568241e26505c27bf0e4fd4ad8ec2"
|
||||||
|
dependencies = [
|
||||||
|
"ahash",
|
||||||
|
"anyhow",
|
||||||
|
"dashmap",
|
||||||
|
"once_cell",
|
||||||
|
"regex",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "swc_common"
|
||||||
|
version = "0.33.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "095c158fe55b36faeebb4274692643a6d7cdc5b7902e1d5968ddbe52b7de1d1c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ast_node",
|
"ast_node",
|
||||||
"better_scoped_tls",
|
"better_scoped_tls",
|
||||||
|
@ -5797,13 +5816,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swc_config"
|
name = "swc_config"
|
||||||
version = "0.1.9"
|
version = "0.1.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "112884e66b60e614c0f416138b91b8b82b7fea6ed0ecc5e26bad4726c57a6c99"
|
checksum = "ce837c5eae1cb200a310940de989fd9b3d12ed62d7752bc69b39ef8aa775ec04"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"swc_cached",
|
||||||
"swc_config_macro",
|
"swc_config_macro",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -5821,9 +5842,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swc_ecma_ast"
|
name = "swc_ecma_ast"
|
||||||
version = "0.110.17"
|
version = "0.112.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "79401a45da704f4fb2552c5bf86ee2198e8636b121cb81f8036848a300edd53b"
|
checksum = "852a48a24a2533de88298c6b25355bc68fdee31ac21cb4fb8939b7001715353c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.4.1",
|
"bitflags 2.4.1",
|
||||||
"is-macro",
|
"is-macro",
|
||||||
|
@ -5839,9 +5860,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swc_ecma_codegen"
|
name = "swc_ecma_codegen"
|
||||||
version = "0.146.54"
|
version = "0.148.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "99b61ca275e3663238b71c4b5da8e6fb745bde9989ef37d94984dfc81fc6d009"
|
checksum = "d79df3f8c5ed028fce5dc24acb83002c0854f8b9d7e893292aeee394a6b9eaf4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
|
@ -5868,36 +5889,25 @@ dependencies = [
|
||||||
"syn 2.0.48",
|
"syn 2.0.48",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "swc_ecma_dep_graph"
|
|
||||||
version = "0.113.22"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "59fc6ac1a84afe910182dcda33d70a16545e6058529d51afb63bd6be8764370f"
|
|
||||||
dependencies = [
|
|
||||||
"swc_atoms",
|
|
||||||
"swc_common",
|
|
||||||
"swc_ecma_ast",
|
|
||||||
"swc_ecma_visit",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swc_ecma_loader"
|
name = "swc_ecma_loader"
|
||||||
version = "0.45.13"
|
version = "0.45.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c5713ab3429530c10bdf167170ebbde75b046c8003558459e4de5aaec62ce0f1"
|
checksum = "7c16051bce5421992a1b49350735bf4d110f761fd68ae7098af17a64ad639b8d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"pathdiff",
|
"pathdiff",
|
||||||
"serde",
|
"serde",
|
||||||
|
"swc_atoms",
|
||||||
"swc_common",
|
"swc_common",
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swc_ecma_parser"
|
name = "swc_ecma_parser"
|
||||||
version = "0.141.37"
|
version = "0.143.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c4d17401dd95048a6a62b777d533c0999dabdd531ef9d667e22f8ae2a2a0d294"
|
checksum = "90ff55811ed5de14b05e9a2979bae2bce3c807582f559b4325948463265307d9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"either",
|
"either",
|
||||||
"new_debug_unreachable",
|
"new_debug_unreachable",
|
||||||
|
@ -5917,9 +5927,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swc_ecma_transforms_base"
|
name = "swc_ecma_transforms_base"
|
||||||
version = "0.135.11"
|
version = "0.137.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6d4ab26ec124b03e47f54d4daade8e9a9dcd66d3a4ca3cd47045f138d267a60e"
|
checksum = "bfd47dd9ccb73a1f5d8d7eff9518554b752b1733b56503af090e78859abb42dd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"better_scoped_tls",
|
"better_scoped_tls",
|
||||||
"bitflags 2.4.1",
|
"bitflags 2.4.1",
|
||||||
|
@ -5940,9 +5950,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swc_ecma_transforms_classes"
|
name = "swc_ecma_transforms_classes"
|
||||||
version = "0.124.11"
|
version = "0.126.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9fe4376c024fa04394cafb8faecafb4623722b92dbbe46532258cc0a6b569d9c"
|
checksum = "8ecb31417e0d415d7f0ff026f1e7c909427e386b7d0af9a2a78678507e4d9d79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"swc_atoms",
|
"swc_atoms",
|
||||||
"swc_common",
|
"swc_common",
|
||||||
|
@ -5966,9 +5976,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swc_ecma_transforms_optimization"
|
name = "swc_ecma_transforms_optimization"
|
||||||
version = "0.196.17"
|
version = "0.198.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fec185cf4d18e90b7c8b18b0d1f04a5707e6f4c7b57c1bfd5086392cd07b75a9"
|
checksum = "3920268ac8972b494067d0b7c088964b21d08f5d1f58d7151bd1eb7054a137b0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dashmap",
|
"dashmap",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
|
@ -5990,9 +6000,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swc_ecma_transforms_proposal"
|
name = "swc_ecma_transforms_proposal"
|
||||||
version = "0.169.16"
|
version = "0.171.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ed89d6ff74f60de490fb56e1cc505b057905e36c13d405d7d61dd5c9f6ee8fc9"
|
checksum = "448c40c2a2b224cb5101cc6cdee81837c281a34f2a2aa6dd18d6d5cd8d492e60"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"either",
|
"either",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
|
@ -6010,9 +6020,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swc_ecma_transforms_react"
|
name = "swc_ecma_transforms_react"
|
||||||
version = "0.181.18"
|
version = "0.183.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e31a2f879fd21d18080b6c42e633e0ae8c6f3d54b83c1de876767d82b458c999"
|
checksum = "ee2394dc3abceada246feeb709b8c4d23392973f49a24fcc59b2ee21737cb6c8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"dashmap",
|
"dashmap",
|
||||||
|
@ -6034,9 +6044,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swc_ecma_transforms_typescript"
|
name = "swc_ecma_transforms_typescript"
|
||||||
version = "0.186.17"
|
version = "0.188.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3e4263372cc7cd1a3b4570ccf7438f3c1e1575f134fd05cdf074edb322480a5b"
|
checksum = "0cff231437173e041e5a3be9b8c782fd297ffcb53ed16d805f853e4a68315c45"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ryu-js",
|
"ryu-js",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -6051,9 +6061,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swc_ecma_utils"
|
name = "swc_ecma_utils"
|
||||||
version = "0.125.4"
|
version = "0.127.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7cead1083e46b0f072a82938f16d366014468f7510350957765bb4d013496890"
|
checksum = "4cd185161161dfc65ee0d6f3044c901b766c3abb4efcd0b35c9e76c833724896"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
|
@ -6069,9 +6079,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swc_ecma_visit"
|
name = "swc_ecma_visit"
|
||||||
version = "0.96.17"
|
version = "0.98.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a1d0100c383fb08b6f34911ab6f925950416a5d14404c1cd520d59fb8dfbb3bf"
|
checksum = "cdb71511a816c7c84ddc96e6939389be261caf20858486a5e76948551f110e1f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"swc_atoms",
|
"swc_atoms",
|
||||||
|
@ -6094,9 +6104,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swc_fast_graph"
|
name = "swc_fast_graph"
|
||||||
version = "0.21.13"
|
version = "0.21.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8acfc056067a0fbfe26a4763c1eb246e813fdbe6b376415d07915e96e15481b6"
|
checksum = "ffd32eda2dd2c725f8d4448d0013c3b5466118e4ff5c30aff2c04f6750f7238b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"petgraph",
|
"petgraph",
|
||||||
|
@ -6106,9 +6116,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swc_graph_analyzer"
|
name = "swc_graph_analyzer"
|
||||||
version = "0.22.15"
|
version = "0.22.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1c6e0110c0433c27221f03e45419b7e18d1db4d472db309088caa458ac2f304e"
|
checksum = "52ae1172960aa3b0cdbe94a1d5edf3efa9f1199cbd8384f48dedd0c5bdb5d6bd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"auto_impl",
|
"auto_impl",
|
||||||
"petgraph",
|
"petgraph",
|
||||||
|
|
|
@ -41,14 +41,14 @@ license = "MIT"
|
||||||
repository = "https://github.com/denoland/deno"
|
repository = "https://github.com/denoland/deno"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
deno_ast = { version = "0.32.0", features = ["transpiling"] }
|
deno_ast = { version = "0.33.2", features = ["transpiling"] }
|
||||||
deno_core = { version = "0.260.0" }
|
deno_core = { version = "0.260.0" }
|
||||||
|
|
||||||
deno_bench_util = { version = "0.131.0", path = "./bench_util" }
|
deno_bench_util = { version = "0.131.0", path = "./bench_util" }
|
||||||
deno_lockfile = "0.18.0"
|
deno_lockfile = "0.18.0"
|
||||||
deno_media_type = { version = "0.1.1", features = ["module_specifier"] }
|
deno_media_type = { version = "0.1.1", features = ["module_specifier"] }
|
||||||
deno_runtime = { version = "0.145.0", path = "./runtime" }
|
deno_runtime = { version = "0.145.0", path = "./runtime" }
|
||||||
deno_terminal = "0.1.0"
|
deno_terminal = "0.1.1"
|
||||||
napi_sym = { version = "0.67.0", path = "./cli/napi/sym" }
|
napi_sym = { version = "0.67.0", path = "./cli/napi/sym" }
|
||||||
test_util = { path = "./test_util" }
|
test_util = { path = "./test_util" }
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ p224 = { version = "0.13.0", features = ["ecdh"] }
|
||||||
p256 = { version = "0.13.2", features = ["ecdh"] }
|
p256 = { version = "0.13.2", features = ["ecdh"] }
|
||||||
p384 = { version = "0.13.0", features = ["ecdh"] }
|
p384 = { version = "0.13.0", features = ["ecdh"] }
|
||||||
parking_lot = "0.12.0"
|
parking_lot = "0.12.0"
|
||||||
percent-encoding = "=2.3.0"
|
percent-encoding = "2.3.0"
|
||||||
phf = { version = "0.11", features = ["macros"] }
|
phf = { version = "0.11", features = ["macros"] }
|
||||||
pin-project = "1.0.11" # don't pin because they yank crates from cargo
|
pin-project = "1.0.11" # don't pin because they yank crates from cargo
|
||||||
pretty_assertions = "=1.4.0"
|
pretty_assertions = "=1.4.0"
|
||||||
|
|
|
@ -53,21 +53,21 @@ winapi.workspace = true
|
||||||
winres.workspace = true
|
winres.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
deno_ast = { workspace = true, features = ["bundler", "cjs", "codegen", "dep_graph", "module_specifier", "proposal", "react", "sourcemap", "transforms", "typescript", "view", "visit"] }
|
deno_ast = { workspace = true, features = ["bundler", "cjs", "codegen", "proposal", "react", "sourcemap", "transforms", "typescript", "view", "visit"] }
|
||||||
deno_cache_dir = "=0.6.1"
|
deno_cache_dir = "=0.6.1"
|
||||||
deno_config = "=0.9.2"
|
deno_config = "=0.9.2"
|
||||||
deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] }
|
deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] }
|
||||||
deno_doc = { version = "=0.100.0", features = ["html"] }
|
deno_doc = { version = "=0.103.0", features = ["html"] }
|
||||||
deno_emit = "=0.35.0"
|
deno_emit = "=0.36.0"
|
||||||
deno_graph = "=0.64.2"
|
deno_graph = "=0.65.0"
|
||||||
deno_lint = { version = "=0.55.2", features = ["docs"] }
|
deno_lint = { version = "=0.56.0", features = ["docs"] }
|
||||||
deno_lockfile.workspace = true
|
deno_lockfile.workspace = true
|
||||||
deno_npm = "=0.16.0"
|
deno_npm = "=0.16.0"
|
||||||
deno_runtime = { workspace = true, features = ["include_js_files_for_snapshotting"] }
|
deno_runtime = { workspace = true, features = ["include_js_files_for_snapshotting"] }
|
||||||
deno_semver = "=0.5.4"
|
deno_semver = "=0.5.4"
|
||||||
deno_task_shell = "=0.14.3"
|
deno_task_shell = "=0.14.3"
|
||||||
deno_terminal.workspace = true
|
deno_terminal.workspace = true
|
||||||
eszip = "=0.60.0"
|
eszip = "=0.62.0"
|
||||||
napi_sym.workspace = true
|
napi_sym.workspace = true
|
||||||
|
|
||||||
async-trait.workspace = true
|
async-trait.workspace = true
|
||||||
|
@ -89,7 +89,7 @@ dotenvy = "0.15.7"
|
||||||
dprint-plugin-json = "=0.19.1"
|
dprint-plugin-json = "=0.19.1"
|
||||||
dprint-plugin-jupyter = "=0.1.2"
|
dprint-plugin-jupyter = "=0.1.2"
|
||||||
dprint-plugin-markdown = "=0.16.3"
|
dprint-plugin-markdown = "=0.16.3"
|
||||||
dprint-plugin-typescript = "=0.88.10"
|
dprint-plugin-typescript = "=0.89.0"
|
||||||
env_logger = "=0.10.0"
|
env_logger = "=0.10.0"
|
||||||
fancy-regex = "=0.10.0"
|
fancy-regex = "=0.10.0"
|
||||||
# If you disable the default __vendored_zlib_ng feature above, you _must_ be able to link against `-lz`.
|
# If you disable the default __vendored_zlib_ng feature above, you _must_ be able to link against `-lz`.
|
||||||
|
|
2
cli/cache/module_info.rs
vendored
2
cli/cache/module_info.rs
vendored
|
@ -149,7 +149,7 @@ impl<'a> deno_graph::ModuleAnalyzer for ModuleInfoCacheModuleAnalyzer<'a> {
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
source: Arc<str>,
|
source: Arc<str>,
|
||||||
media_type: MediaType,
|
media_type: MediaType,
|
||||||
) -> Result<ModuleInfo, deno_ast::Diagnostic> {
|
) -> Result<ModuleInfo, deno_ast::ParseDiagnostic> {
|
||||||
// attempt to load from the cache
|
// attempt to load from the cache
|
||||||
let source_hash = ModuleInfoCacheSourceHash::from_source(source.as_bytes());
|
let source_hash = ModuleInfoCacheSourceHash::from_source(source.as_bytes());
|
||||||
match self.module_info_cache.get_module_info(
|
match self.module_info_cache.get_module_info(
|
||||||
|
|
6
cli/cache/parsed_source.rs
vendored
6
cli/cache/parsed_source.rs
vendored
|
@ -32,7 +32,7 @@ impl<'a> LazyGraphSourceParser<'a> {
|
||||||
pub fn get_or_parse_source(
|
pub fn get_or_parse_source(
|
||||||
&self,
|
&self,
|
||||||
module_specifier: &ModuleSpecifier,
|
module_specifier: &ModuleSpecifier,
|
||||||
) -> Result<Option<deno_ast::ParsedSource>, deno_ast::Diagnostic> {
|
) -> Result<Option<deno_ast::ParsedSource>, deno_ast::ParseDiagnostic> {
|
||||||
let Some(deno_graph::Module::Js(module)) = self.graph.get(module_specifier)
|
let Some(deno_graph::Module::Js(module)) = self.graph.get(module_specifier)
|
||||||
else {
|
else {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
|
@ -53,7 +53,7 @@ impl ParsedSourceCache {
|
||||||
pub fn get_parsed_source_from_js_module(
|
pub fn get_parsed_source_from_js_module(
|
||||||
&self,
|
&self,
|
||||||
module: &deno_graph::JsModule,
|
module: &deno_graph::JsModule,
|
||||||
) -> Result<ParsedSource, deno_ast::Diagnostic> {
|
) -> Result<ParsedSource, deno_ast::ParseDiagnostic> {
|
||||||
self.get_or_parse_module(
|
self.get_or_parse_module(
|
||||||
&module.specifier,
|
&module.specifier,
|
||||||
module.source.clone(),
|
module.source.clone(),
|
||||||
|
@ -68,7 +68,7 @@ impl ParsedSourceCache {
|
||||||
specifier: &deno_graph::ModuleSpecifier,
|
specifier: &deno_graph::ModuleSpecifier,
|
||||||
source: Arc<str>,
|
source: Arc<str>,
|
||||||
media_type: MediaType,
|
media_type: MediaType,
|
||||||
) -> deno_core::anyhow::Result<ParsedSource, deno_ast::Diagnostic> {
|
) -> deno_core::anyhow::Result<ParsedSource, deno_ast::ParseDiagnostic> {
|
||||||
let parser = self.as_capturing_parser();
|
let parser = self.as_capturing_parser();
|
||||||
// this will conditionally parse because it's using a CapturingModuleParser
|
// this will conditionally parse because it's using a CapturingModuleParser
|
||||||
parser.parse_module(ParseOptions {
|
parser.parse_module(ParseOptions {
|
||||||
|
|
|
@ -1,678 +0,0 @@
|
||||||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
|
||||||
|
|
||||||
use std::borrow::Cow;
|
|
||||||
use std::fmt;
|
|
||||||
use std::fmt::Display;
|
|
||||||
use std::fmt::Write as _;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
use deno_ast::ModuleSpecifier;
|
|
||||||
use deno_ast::SourcePos;
|
|
||||||
use deno_ast::SourceRange;
|
|
||||||
use deno_ast::SourceRanged;
|
|
||||||
use deno_ast::SourceTextInfo;
|
|
||||||
use deno_terminal::colors;
|
|
||||||
use unicode_width::UnicodeWidthStr;
|
|
||||||
|
|
||||||
use crate::cache::LazyGraphSourceParser;
|
|
||||||
|
|
||||||
pub trait SourceTextStore {
|
|
||||||
fn get_source_text<'a>(
|
|
||||||
&'a self,
|
|
||||||
specifier: &ModuleSpecifier,
|
|
||||||
) -> Option<Cow<'a, SourceTextInfo>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct SourceTextParsedSourceStore<'a>(pub LazyGraphSourceParser<'a>);
|
|
||||||
|
|
||||||
impl<'a> SourceTextParsedSourceStore<'a> {
|
|
||||||
pub fn get_source_text_from_store(
|
|
||||||
&self,
|
|
||||||
specifier: &ModuleSpecifier,
|
|
||||||
) -> Option<Cow<'_, SourceTextInfo>> {
|
|
||||||
let parsed_source = self.0.get_or_parse_source(specifier).ok()??;
|
|
||||||
Some(Cow::Owned(parsed_source.text_info().clone()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SourceTextStore for SourceTextParsedSourceStore<'_> {
|
|
||||||
fn get_source_text<'a>(
|
|
||||||
&'a self,
|
|
||||||
specifier: &ModuleSpecifier,
|
|
||||||
) -> Option<Cow<'a, SourceTextInfo>> {
|
|
||||||
match self.get_source_text_from_store(specifier) {
|
|
||||||
Some(text_info) => Some(text_info),
|
|
||||||
None => {
|
|
||||||
// todo(#22117): this is extremely hacky and bad because the file
|
|
||||||
// may have changed by the time we get here. Instead of doing this,
|
|
||||||
// we should store the text info in the diagnostics
|
|
||||||
if specifier.scheme() == "file" {
|
|
||||||
let path = specifier.to_file_path().ok()?;
|
|
||||||
let text = std::fs::read_to_string(path).ok()?;
|
|
||||||
Some(Cow::Owned(SourceTextInfo::new(text.into())))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum DiagnosticLevel {
|
|
||||||
Error,
|
|
||||||
Warning,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
|
||||||
pub struct DiagnosticSourceRange {
|
|
||||||
pub start: DiagnosticSourcePos,
|
|
||||||
pub end: DiagnosticSourcePos,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
|
||||||
pub enum DiagnosticSourcePos {
|
|
||||||
SourcePos(SourcePos),
|
|
||||||
ByteIndex(usize),
|
|
||||||
LineAndCol {
|
|
||||||
// 0-indexed line number
|
|
||||||
line: usize,
|
|
||||||
// 0-indexed column number
|
|
||||||
column: usize,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DiagnosticSourcePos {
|
|
||||||
fn pos(&self, source: &SourceTextInfo) -> SourcePos {
|
|
||||||
match self {
|
|
||||||
DiagnosticSourcePos::SourcePos(pos) => *pos,
|
|
||||||
DiagnosticSourcePos::ByteIndex(index) => source.range().start() + *index,
|
|
||||||
DiagnosticSourcePos::LineAndCol { line, column } => {
|
|
||||||
source.line_start(*line) + *column
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub enum DiagnosticLocation<'a> {
|
|
||||||
/// The diagnostic is relevant to a specific path.
|
|
||||||
Path { path: PathBuf },
|
|
||||||
/// The diagnostic is relevant to an entire module.
|
|
||||||
Module {
|
|
||||||
/// The specifier of the module that contains the diagnostic.
|
|
||||||
specifier: Cow<'a, ModuleSpecifier>,
|
|
||||||
},
|
|
||||||
/// The diagnostic is relevant to a specific position in a module.
|
|
||||||
///
|
|
||||||
/// This variant will get the relevant `SouceTextInfo` from the cache using
|
|
||||||
/// the given specifier, and will then calculate the line and column numbers
|
|
||||||
/// from the given `SourcePos`.
|
|
||||||
ModulePosition {
|
|
||||||
/// The specifier of the module that contains the diagnostic.
|
|
||||||
specifier: Cow<'a, ModuleSpecifier>,
|
|
||||||
/// The source position of the diagnostic.
|
|
||||||
source_pos: DiagnosticSourcePos,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> DiagnosticLocation<'a> {
|
|
||||||
/// Return the line and column number of the diagnostic.
|
|
||||||
///
|
|
||||||
/// The line number is 1-indexed.
|
|
||||||
///
|
|
||||||
/// The column number is 1-indexed. This is the number of UTF-16 code units
|
|
||||||
/// from the start of the line to the diagnostic.
|
|
||||||
/// Why UTF-16 code units? Because that's what VS Code understands, and
|
|
||||||
/// everyone uses VS Code. :)
|
|
||||||
fn position(&self, sources: &dyn SourceTextStore) -> Option<(usize, usize)> {
|
|
||||||
match self {
|
|
||||||
DiagnosticLocation::Path { .. } => None,
|
|
||||||
DiagnosticLocation::Module { .. } => None,
|
|
||||||
DiagnosticLocation::ModulePosition {
|
|
||||||
specifier,
|
|
||||||
source_pos,
|
|
||||||
} => {
|
|
||||||
let source = sources.get_source_text(specifier).expect(
|
|
||||||
"source text should be in the cache if the location is in a file",
|
|
||||||
);
|
|
||||||
let pos = source_pos.pos(&source);
|
|
||||||
let line_index = source.line_index(pos);
|
|
||||||
let line_start_pos = source.line_start(line_index);
|
|
||||||
let content = source.range_text(&SourceRange::new(line_start_pos, pos));
|
|
||||||
let line = line_index + 1;
|
|
||||||
let column = content.encode_utf16().count() + 1;
|
|
||||||
Some((line, column))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct DiagnosticSnippet<'a> {
|
|
||||||
/// The source text for this snippet. The
|
|
||||||
pub source: DiagnosticSnippetSource<'a>,
|
|
||||||
/// The piece of the snippet that should be highlighted.
|
|
||||||
pub highlight: DiagnosticSnippetHighlight<'a>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct DiagnosticSnippetHighlight<'a> {
|
|
||||||
/// The range of the snippet that should be highlighted.
|
|
||||||
pub range: DiagnosticSourceRange,
|
|
||||||
/// The style of the highlight.
|
|
||||||
pub style: DiagnosticSnippetHighlightStyle,
|
|
||||||
/// An optional inline description of the highlight.
|
|
||||||
pub description: Option<Cow<'a, str>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum DiagnosticSnippetHighlightStyle {
|
|
||||||
/// The highlight is an error. This will place red carets under the highlight.
|
|
||||||
Error,
|
|
||||||
#[allow(dead_code)]
|
|
||||||
/// The highlight is a warning. This will place yellow carets under the
|
|
||||||
/// highlight.
|
|
||||||
Warning,
|
|
||||||
#[allow(dead_code)]
|
|
||||||
/// The highlight shows code additions. This will place green + signs under
|
|
||||||
/// the highlight and will highlight the code in green.
|
|
||||||
Addition,
|
|
||||||
/// The highlight shows a hint. This will place blue dashes under the
|
|
||||||
/// highlight.
|
|
||||||
Hint,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DiagnosticSnippetHighlightStyle {
|
|
||||||
fn style_underline(
|
|
||||||
&self,
|
|
||||||
s: impl std::fmt::Display,
|
|
||||||
) -> impl std::fmt::Display {
|
|
||||||
match self {
|
|
||||||
DiagnosticSnippetHighlightStyle::Error => colors::red_bold(s),
|
|
||||||
DiagnosticSnippetHighlightStyle::Warning => colors::yellow_bold(s),
|
|
||||||
DiagnosticSnippetHighlightStyle::Addition => colors::green_bold(s),
|
|
||||||
DiagnosticSnippetHighlightStyle::Hint => colors::intense_blue(s),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn underline_char(&self) -> char {
|
|
||||||
match self {
|
|
||||||
DiagnosticSnippetHighlightStyle::Error => '^',
|
|
||||||
DiagnosticSnippetHighlightStyle::Warning => '^',
|
|
||||||
DiagnosticSnippetHighlightStyle::Addition => '+',
|
|
||||||
DiagnosticSnippetHighlightStyle::Hint => '-',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum DiagnosticSnippetSource<'a> {
|
|
||||||
/// The specifier of the module that should be displayed in this snippet. The
|
|
||||||
/// contents of the file will be retrieved from the `SourceTextStore`.
|
|
||||||
Specifier(Cow<'a, ModuleSpecifier>),
|
|
||||||
#[allow(dead_code)]
|
|
||||||
/// The source text that should be displayed in this snippet.
|
|
||||||
///
|
|
||||||
/// This should be used if the text of the snippet is not available in the
|
|
||||||
/// `SourceTextStore`.
|
|
||||||
SourceTextInfo(Cow<'a, deno_ast::SourceTextInfo>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> DiagnosticSnippetSource<'a> {
|
|
||||||
fn to_source_text_info(
|
|
||||||
&self,
|
|
||||||
sources: &'a dyn SourceTextStore,
|
|
||||||
) -> Cow<'a, SourceTextInfo> {
|
|
||||||
match self {
|
|
||||||
DiagnosticSnippetSource::Specifier(specifier) => {
|
|
||||||
sources.get_source_text(specifier).expect(
|
|
||||||
"source text should be in the cache if snippet source is a specifier",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
DiagnosticSnippetSource::SourceTextInfo(info) => info.clone(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the text of the line with the given number.
|
|
||||||
fn line_text(source: &SourceTextInfo, line_number: usize) -> &str {
|
|
||||||
source.line_text(line_number - 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the text of the line that contains the given position, split at the
|
|
||||||
/// given position.
|
|
||||||
fn line_text_split(
|
|
||||||
source: &SourceTextInfo,
|
|
||||||
pos: DiagnosticSourcePos,
|
|
||||||
) -> (&str, &str) {
|
|
||||||
let pos = pos.pos(source);
|
|
||||||
let line_index = source.line_index(pos);
|
|
||||||
let line_start_pos = source.line_start(line_index);
|
|
||||||
let line_end_pos = source.line_end(line_index);
|
|
||||||
let before = source.range_text(&SourceRange::new(line_start_pos, pos));
|
|
||||||
let after = source.range_text(&SourceRange::new(pos, line_end_pos));
|
|
||||||
(before, after)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the text of the line that contains the given positions, split at the
|
|
||||||
/// given positions.
|
|
||||||
///
|
|
||||||
/// If the positions are on different lines, this will panic.
|
|
||||||
fn line_text_split3(
|
|
||||||
source: &SourceTextInfo,
|
|
||||||
start_pos: DiagnosticSourcePos,
|
|
||||||
end_pos: DiagnosticSourcePos,
|
|
||||||
) -> (&str, &str, &str) {
|
|
||||||
let start_pos = start_pos.pos(source);
|
|
||||||
let end_pos = end_pos.pos(source);
|
|
||||||
let line_index = source.line_index(start_pos);
|
|
||||||
assert_eq!(
|
|
||||||
line_index,
|
|
||||||
source.line_index(end_pos),
|
|
||||||
"start and end must be on the same line"
|
|
||||||
);
|
|
||||||
let line_start_pos = source.line_start(line_index);
|
|
||||||
let line_end_pos = source.line_end(line_index);
|
|
||||||
let before = source.range_text(&SourceRange::new(line_start_pos, start_pos));
|
|
||||||
let between = source.range_text(&SourceRange::new(start_pos, end_pos));
|
|
||||||
let after = source.range_text(&SourceRange::new(end_pos, line_end_pos));
|
|
||||||
(before, between, after)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the line number (1 indexed) of the line that contains the given
|
|
||||||
/// position.
|
|
||||||
fn line_number(source: &SourceTextInfo, pos: DiagnosticSourcePos) -> usize {
|
|
||||||
source.line_index(pos.pos(source)) + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Diagnostic {
|
|
||||||
/// The level of the diagnostic.
|
|
||||||
fn level(&self) -> DiagnosticLevel;
|
|
||||||
|
|
||||||
/// The diagnostic code, like `no-explicit-any` or `ban-untagged-ignore`.
|
|
||||||
fn code(&self) -> impl fmt::Display + '_;
|
|
||||||
|
|
||||||
/// The human-readable diagnostic message.
|
|
||||||
fn message(&self) -> impl fmt::Display + '_;
|
|
||||||
|
|
||||||
/// The location this diagnostic is associated with.
|
|
||||||
fn location(&self) -> DiagnosticLocation;
|
|
||||||
|
|
||||||
/// A snippet showing the source code associated with the diagnostic.
|
|
||||||
fn snippet(&self) -> Option<DiagnosticSnippet<'_>>;
|
|
||||||
|
|
||||||
/// A hint for fixing the diagnostic.
|
|
||||||
fn hint(&self) -> Option<impl fmt::Display + '_>;
|
|
||||||
|
|
||||||
/// A snippet showing how the diagnostic can be fixed.
|
|
||||||
fn snippet_fixed(&self) -> Option<DiagnosticSnippet<'_>>;
|
|
||||||
|
|
||||||
fn info(&self) -> Cow<'_, [Cow<'_, str>]>;
|
|
||||||
|
|
||||||
/// An optional URL to the documentation for the diagnostic.
|
|
||||||
fn docs_url(&self) -> Option<impl fmt::Display + '_>;
|
|
||||||
|
|
||||||
fn display<'a>(
|
|
||||||
&'a self,
|
|
||||||
sources: &'a dyn SourceTextStore,
|
|
||||||
) -> DiagnosticDisplay<'a, Self> {
|
|
||||||
DiagnosticDisplay {
|
|
||||||
diagnostic: self,
|
|
||||||
sources,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct RepeatingCharFmt(char, usize);
|
|
||||||
impl fmt::Display for RepeatingCharFmt {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
for _ in 0..self.1 {
|
|
||||||
f.write_char(self.0)?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// How many spaces a tab should be displayed as. 2 is the default used for
|
|
||||||
/// `deno fmt`, so we'll use that here.
|
|
||||||
const TAB_WIDTH: usize = 2;
|
|
||||||
|
|
||||||
struct ReplaceTab<'a>(&'a str);
|
|
||||||
impl fmt::Display for ReplaceTab<'_> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
let mut written = 0;
|
|
||||||
for (i, c) in self.0.char_indices() {
|
|
||||||
if c == '\t' {
|
|
||||||
self.0[written..i].fmt(f)?;
|
|
||||||
RepeatingCharFmt(' ', TAB_WIDTH).fmt(f)?;
|
|
||||||
written = i + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.0[written..].fmt(f)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The width of the string as displayed, assuming tabs are 2 spaces wide.
|
|
||||||
///
|
|
||||||
/// This display width assumes that zero-width-joined characters are the width
|
|
||||||
/// of their consituent characters. This means that "Person: Red Hair" (which is
|
|
||||||
/// represented as "Person" + "ZWJ" + "Red Hair") will have a width of 4.
|
|
||||||
///
|
|
||||||
/// Whether this is correct is unfortunately dependent on the font / terminal
|
|
||||||
/// being used. Here is a list of what terminals consider the length of
|
|
||||||
/// "Person: Red Hair" to be:
|
|
||||||
///
|
|
||||||
/// | Terminal | Rendered Width |
|
|
||||||
/// | ---------------- | -------------- |
|
|
||||||
/// | Windows Terminal | 5 chars |
|
|
||||||
/// | iTerm (macOS) | 2 chars |
|
|
||||||
/// | Terminal (macOS) | 2 chars |
|
|
||||||
/// | VS Code terminal | 4 chars |
|
|
||||||
/// | GNOME Terminal | 4 chars |
|
|
||||||
///
|
|
||||||
/// If we really wanted to, we could try and detect the terminal being used and
|
|
||||||
/// adjust the width accordingly. However, this is probably not worth the
|
|
||||||
/// effort.
|
|
||||||
fn display_width(str: &str) -> usize {
|
|
||||||
str.width_cjk() + (str.chars().filter(|c| *c == '\t').count() * TAB_WIDTH)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct DiagnosticDisplay<'a, T: Diagnostic + ?Sized> {
|
|
||||||
diagnostic: &'a T,
|
|
||||||
sources: &'a dyn SourceTextStore,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Diagnostic + ?Sized> Display for DiagnosticDisplay<'_, T> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
print_diagnostic(f, self.sources, self.diagnostic)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// error[missing-return-type]: missing explicit return type on public function
|
|
||||||
// at /mnt/artemis/Projects/github.com/denoland/deno/test.ts:1:16
|
|
||||||
// |
|
|
||||||
// 1 | export function test() {
|
|
||||||
// | ^^^^
|
|
||||||
// = hint: add an explicit return type to the function
|
|
||||||
// |
|
|
||||||
// 1 | export function test(): string {
|
|
||||||
// | ^^^^^^^^
|
|
||||||
//
|
|
||||||
// info: all functions that are exported from a module must have an explicit return type to support fast check and documentation generation.
|
|
||||||
// docs: https://jsr.io/d/missing-return-type
|
|
||||||
fn print_diagnostic(
|
|
||||||
io: &mut dyn std::fmt::Write,
|
|
||||||
sources: &dyn SourceTextStore,
|
|
||||||
diagnostic: &(impl Diagnostic + ?Sized),
|
|
||||||
) -> Result<(), std::fmt::Error> {
|
|
||||||
match diagnostic.level() {
|
|
||||||
DiagnosticLevel::Error => {
|
|
||||||
write!(
|
|
||||||
io,
|
|
||||||
"{}",
|
|
||||||
colors::red_bold(format_args!("error[{}]", diagnostic.code()))
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
DiagnosticLevel::Warning => {
|
|
||||||
write!(
|
|
||||||
io,
|
|
||||||
"{}",
|
|
||||||
colors::yellow_bold(format_args!("warning[{}]", diagnostic.code()))
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
writeln!(io, ": {}", colors::bold(diagnostic.message()))?;
|
|
||||||
|
|
||||||
let mut max_line_number_digits = 1;
|
|
||||||
if let Some(snippet) = diagnostic.snippet() {
|
|
||||||
let source = snippet.source.to_source_text_info(sources);
|
|
||||||
let last_line = line_number(&source, snippet.highlight.range.end);
|
|
||||||
max_line_number_digits = max_line_number_digits.max(last_line.ilog10() + 1);
|
|
||||||
}
|
|
||||||
if let Some(snippet) = diagnostic.snippet_fixed() {
|
|
||||||
let source = snippet.source.to_source_text_info(sources);
|
|
||||||
let last_line = line_number(&source, snippet.highlight.range.end);
|
|
||||||
max_line_number_digits = max_line_number_digits.max(last_line.ilog10() + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
let location = diagnostic.location();
|
|
||||||
write!(
|
|
||||||
io,
|
|
||||||
"{}{}",
|
|
||||||
RepeatingCharFmt(' ', max_line_number_digits as usize),
|
|
||||||
colors::intense_blue("-->"),
|
|
||||||
)?;
|
|
||||||
match &location {
|
|
||||||
DiagnosticLocation::Path { path } => {
|
|
||||||
write!(io, " {}", colors::cyan(path.display()))?;
|
|
||||||
}
|
|
||||||
DiagnosticLocation::Module { specifier }
|
|
||||||
| DiagnosticLocation::ModulePosition { specifier, .. } => {
|
|
||||||
if let Ok(path) = specifier.to_file_path() {
|
|
||||||
write!(io, " {}", colors::cyan(path.display()))?;
|
|
||||||
} else {
|
|
||||||
write!(io, " {}", colors::cyan(specifier.as_str()))?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some((line, column)) = location.position(sources) {
|
|
||||||
write!(
|
|
||||||
io,
|
|
||||||
"{}",
|
|
||||||
colors::yellow(format_args!(":{}:{}", line, column))
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
writeln!(io)?;
|
|
||||||
|
|
||||||
if let Some(snippet) = diagnostic.snippet() {
|
|
||||||
print_snippet(io, sources, &snippet, max_line_number_digits)?;
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(hint) = diagnostic.hint() {
|
|
||||||
write!(
|
|
||||||
io,
|
|
||||||
"{} {} ",
|
|
||||||
RepeatingCharFmt(' ', max_line_number_digits as usize),
|
|
||||||
colors::intense_blue("=")
|
|
||||||
)?;
|
|
||||||
writeln!(io, "{}: {}", colors::bold("hint"), hint)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(snippet) = diagnostic.snippet_fixed() {
|
|
||||||
print_snippet(io, sources, &snippet, max_line_number_digits)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
writeln!(io)?;
|
|
||||||
|
|
||||||
let mut needs_final_newline = false;
|
|
||||||
for info in diagnostic.info().iter() {
|
|
||||||
needs_final_newline = true;
|
|
||||||
writeln!(io, " {}: {}", colors::intense_blue("info"), info)?;
|
|
||||||
}
|
|
||||||
if let Some(docs_url) = diagnostic.docs_url() {
|
|
||||||
needs_final_newline = true;
|
|
||||||
writeln!(io, " {}: {}", colors::intense_blue("docs"), docs_url)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if needs_final_newline {
|
|
||||||
writeln!(io)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Prints a snippet to the given writer and returns the line number indent.
|
|
||||||
fn print_snippet(
|
|
||||||
io: &mut dyn std::fmt::Write,
|
|
||||||
sources: &dyn SourceTextStore,
|
|
||||||
snippet: &DiagnosticSnippet<'_>,
|
|
||||||
max_line_number_digits: u32,
|
|
||||||
) -> Result<(), std::fmt::Error> {
|
|
||||||
let DiagnosticSnippet { source, highlight } = snippet;
|
|
||||||
|
|
||||||
fn print_padded(
|
|
||||||
io: &mut dyn std::fmt::Write,
|
|
||||||
text: impl std::fmt::Display,
|
|
||||||
padding: u32,
|
|
||||||
) -> Result<(), std::fmt::Error> {
|
|
||||||
for _ in 0..padding {
|
|
||||||
write!(io, " ")?;
|
|
||||||
}
|
|
||||||
write!(io, "{}", text)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
let source = source.to_source_text_info(sources);
|
|
||||||
|
|
||||||
let start_line_number = line_number(&source, highlight.range.start);
|
|
||||||
let end_line_number = line_number(&source, highlight.range.end);
|
|
||||||
|
|
||||||
print_padded(io, colors::intense_blue(" | "), max_line_number_digits)?;
|
|
||||||
writeln!(io)?;
|
|
||||||
for line_number in start_line_number..=end_line_number {
|
|
||||||
print_padded(
|
|
||||||
io,
|
|
||||||
colors::intense_blue(format_args!("{} | ", line_number)),
|
|
||||||
max_line_number_digits - line_number.ilog10() - 1,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let padding_width;
|
|
||||||
let highlight_width;
|
|
||||||
if line_number == start_line_number && start_line_number == end_line_number
|
|
||||||
{
|
|
||||||
let (before, between, after) =
|
|
||||||
line_text_split3(&source, highlight.range.start, highlight.range.end);
|
|
||||||
write!(io, "{}", ReplaceTab(before))?;
|
|
||||||
match highlight.style {
|
|
||||||
DiagnosticSnippetHighlightStyle::Addition => {
|
|
||||||
write!(io, "{}", colors::green(ReplaceTab(between)))?;
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
write!(io, "{}", ReplaceTab(between))?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
writeln!(io, "{}", ReplaceTab(after))?;
|
|
||||||
padding_width = display_width(before);
|
|
||||||
highlight_width = display_width(between);
|
|
||||||
} else if line_number == start_line_number {
|
|
||||||
let (before, after) = line_text_split(&source, highlight.range.start);
|
|
||||||
write!(io, "{}", ReplaceTab(before))?;
|
|
||||||
match highlight.style {
|
|
||||||
DiagnosticSnippetHighlightStyle::Addition => {
|
|
||||||
write!(io, "{}", colors::green(ReplaceTab(after)))?;
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
write!(io, "{}", ReplaceTab(after))?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
writeln!(io)?;
|
|
||||||
padding_width = display_width(before);
|
|
||||||
highlight_width = display_width(after);
|
|
||||||
} else if line_number == end_line_number {
|
|
||||||
let (before, after) = line_text_split(&source, highlight.range.end);
|
|
||||||
match highlight.style {
|
|
||||||
DiagnosticSnippetHighlightStyle::Addition => {
|
|
||||||
write!(io, "{}", colors::green(ReplaceTab(before)))?;
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
write!(io, "{}", ReplaceTab(before))?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
write!(io, "{}", ReplaceTab(after))?;
|
|
||||||
writeln!(io)?;
|
|
||||||
padding_width = 0;
|
|
||||||
highlight_width = display_width(before);
|
|
||||||
} else {
|
|
||||||
let line = line_text(&source, line_number);
|
|
||||||
writeln!(io, "{}", ReplaceTab(line))?;
|
|
||||||
padding_width = 0;
|
|
||||||
highlight_width = display_width(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
print_padded(io, colors::intense_blue(" | "), max_line_number_digits)?;
|
|
||||||
write!(io, "{}", RepeatingCharFmt(' ', padding_width))?;
|
|
||||||
let underline =
|
|
||||||
RepeatingCharFmt(highlight.style.underline_char(), highlight_width);
|
|
||||||
write!(io, "{}", highlight.style.style_underline(underline))?;
|
|
||||||
|
|
||||||
if line_number == end_line_number {
|
|
||||||
if let Some(description) = &highlight.description {
|
|
||||||
write!(io, " {}", highlight.style.style_underline(description))?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
writeln!(io)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use std::borrow::Cow;
|
|
||||||
|
|
||||||
use deno_ast::ModuleSpecifier;
|
|
||||||
use deno_ast::SourceTextInfo;
|
|
||||||
|
|
||||||
use super::SourceTextStore;
|
|
||||||
|
|
||||||
struct TestSource {
|
|
||||||
specifier: ModuleSpecifier,
|
|
||||||
text_info: SourceTextInfo,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SourceTextStore for TestSource {
|
|
||||||
fn get_source_text<'a>(
|
|
||||||
&'a self,
|
|
||||||
specifier: &ModuleSpecifier,
|
|
||||||
) -> Option<Cow<'a, SourceTextInfo>> {
|
|
||||||
if specifier == &self.specifier {
|
|
||||||
Some(Cow::Borrowed(&self.text_info))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_display_width() {
|
|
||||||
assert_eq!(super::display_width("abc"), 3);
|
|
||||||
assert_eq!(super::display_width("\t"), 2);
|
|
||||||
assert_eq!(super::display_width("\t\t123"), 7);
|
|
||||||
assert_eq!(super::display_width("🎄"), 2);
|
|
||||||
assert_eq!(super::display_width("🎄🎄"), 4);
|
|
||||||
assert_eq!(super::display_width("🧑🦰"), 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_position_in_file_from_text_info_simple() {
|
|
||||||
let specifier: ModuleSpecifier = "file:///dev/test.ts".parse().unwrap();
|
|
||||||
let text_info = SourceTextInfo::new("foo\nbar\nbaz".into());
|
|
||||||
let pos = text_info.line_start(1);
|
|
||||||
let sources = TestSource {
|
|
||||||
specifier: specifier.clone(),
|
|
||||||
text_info,
|
|
||||||
};
|
|
||||||
let location = super::DiagnosticLocation::ModulePosition {
|
|
||||||
specifier: Cow::Borrowed(&specifier),
|
|
||||||
source_pos: super::DiagnosticSourcePos::SourcePos(pos),
|
|
||||||
};
|
|
||||||
let position = location.position(&sources).unwrap();
|
|
||||||
assert_eq!(position, (2, 1))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_position_in_file_from_text_info_emoji() {
|
|
||||||
let specifier: ModuleSpecifier = "file:///dev/test.ts".parse().unwrap();
|
|
||||||
let text_info = SourceTextInfo::new("🧑🦰text".into());
|
|
||||||
let pos = text_info.line_start(0) + 11; // the end of the emoji
|
|
||||||
let sources = TestSource {
|
|
||||||
specifier: specifier.clone(),
|
|
||||||
text_info,
|
|
||||||
};
|
|
||||||
let location = super::DiagnosticLocation::ModulePosition {
|
|
||||||
specifier: Cow::Borrowed(&specifier),
|
|
||||||
source_pos: super::DiagnosticSourcePos::SourcePos(pos),
|
|
||||||
};
|
|
||||||
let position = location.position(&sources).unwrap();
|
|
||||||
assert_eq!(position, (1, 6))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -9,7 +9,7 @@
|
||||||
//! Diagnostics are compile-time type errors, whereas JsErrors are runtime
|
//! Diagnostics are compile-time type errors, whereas JsErrors are runtime
|
||||||
//! exceptions.
|
//! exceptions.
|
||||||
|
|
||||||
use deno_ast::Diagnostic;
|
use deno_ast::ParseDiagnostic;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_graph::source::ResolveError;
|
use deno_graph::source::ResolveError;
|
||||||
use deno_graph::ModuleError;
|
use deno_graph::ModuleError;
|
||||||
|
@ -22,7 +22,7 @@ fn get_import_map_error_class(_: &ImportMapError) -> &'static str {
|
||||||
"URIError"
|
"URIError"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_diagnostic_class(_: &Diagnostic) -> &'static str {
|
fn get_diagnostic_class(_: &ParseDiagnostic) -> &'static str {
|
||||||
"SyntaxError"
|
"SyntaxError"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,10 @@ pub fn get_error_class_name(e: &AnyError) -> &'static str {
|
||||||
e.downcast_ref::<ImportMapError>()
|
e.downcast_ref::<ImportMapError>()
|
||||||
.map(get_import_map_error_class)
|
.map(get_import_map_error_class)
|
||||||
})
|
})
|
||||||
.or_else(|| e.downcast_ref::<Diagnostic>().map(get_diagnostic_class))
|
.or_else(|| {
|
||||||
|
e.downcast_ref::<ParseDiagnostic>()
|
||||||
|
.map(get_diagnostic_class)
|
||||||
|
})
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
e.downcast_ref::<ModuleGraphError>()
|
e.downcast_ref::<ModuleGraphError>()
|
||||||
.map(get_module_graph_error_class)
|
.map(get_module_graph_error_class)
|
||||||
|
|
|
@ -20,6 +20,7 @@ use deno_core::serde::Deserialize;
|
||||||
use deno_core::serde_json;
|
use deno_core::serde_json;
|
||||||
use deno_core::serde_json::json;
|
use deno_core::serde_json::json;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
|
use deno_lint::diagnostic::LintDiagnostic;
|
||||||
use deno_lint::rules::LintRule;
|
use deno_lint::rules::LintRule;
|
||||||
use deno_runtime::deno_node::NodeResolver;
|
use deno_runtime::deno_node::NodeResolver;
|
||||||
use deno_runtime::deno_node::NpmResolver;
|
use deno_runtime::deno_node::NpmResolver;
|
||||||
|
@ -118,15 +119,21 @@ impl Reference {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_lsp_range(range: &deno_lint::diagnostic::Range) -> Range {
|
fn as_lsp_range(diagnostic: &LintDiagnostic) -> Range {
|
||||||
|
let start_lc = diagnostic
|
||||||
|
.text_info
|
||||||
|
.line_and_column_index(diagnostic.range.start);
|
||||||
|
let end_lc = diagnostic
|
||||||
|
.text_info
|
||||||
|
.line_and_column_index(diagnostic.range.end);
|
||||||
Range {
|
Range {
|
||||||
start: Position {
|
start: Position {
|
||||||
line: range.start.line_index as u32,
|
line: start_lc.line_index as u32,
|
||||||
character: range.start.column_index as u32,
|
character: start_lc.column_index as u32,
|
||||||
},
|
},
|
||||||
end: Position {
|
end: Position {
|
||||||
line: range.end.line_index as u32,
|
line: end_lc.line_index as u32,
|
||||||
character: range.end.column_index as u32,
|
character: end_lc.column_index as u32,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,12 +149,12 @@ pub fn get_lint_references(
|
||||||
lint_diagnostics
|
lint_diagnostics
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|d| Reference {
|
.map(|d| Reference {
|
||||||
|
range: as_lsp_range(&d),
|
||||||
category: Category::Lint {
|
category: Category::Lint {
|
||||||
message: d.message,
|
message: d.message,
|
||||||
code: d.code,
|
code: d.code,
|
||||||
hint: d.hint,
|
hint: d.hint,
|
||||||
},
|
},
|
||||||
range: as_lsp_range(&d.range),
|
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
)
|
)
|
||||||
|
@ -1060,36 +1067,6 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_as_lsp_range() {
|
|
||||||
let fixture = deno_lint::diagnostic::Range {
|
|
||||||
start: deno_lint::diagnostic::Position {
|
|
||||||
line_index: 0,
|
|
||||||
column_index: 2,
|
|
||||||
byte_index: 23,
|
|
||||||
},
|
|
||||||
end: deno_lint::diagnostic::Position {
|
|
||||||
line_index: 1,
|
|
||||||
column_index: 0,
|
|
||||||
byte_index: 33,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
let actual = as_lsp_range(&fixture);
|
|
||||||
assert_eq!(
|
|
||||||
actual,
|
|
||||||
lsp::Range {
|
|
||||||
start: lsp::Position {
|
|
||||||
line: 0,
|
|
||||||
character: 2,
|
|
||||||
},
|
|
||||||
end: lsp::Position {
|
|
||||||
line: 1,
|
|
||||||
character: 0,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_try_reverse_map_package_json_exports() {
|
fn test_try_reverse_map_package_json_exports() {
|
||||||
let exports = json!({
|
let exports = json!({
|
||||||
|
|
|
@ -560,7 +560,7 @@ mod tests {
|
||||||
Deno.test(`test template literal name`, () => {});
|
Deno.test(`test template literal name`, () => {});
|
||||||
"#;
|
"#;
|
||||||
let parsed_module = deno_ast::parse_module(deno_ast::ParseParams {
|
let parsed_module = deno_ast::parse_module(deno_ast::ParseParams {
|
||||||
specifier: specifier.to_string(),
|
specifier: specifier.clone(),
|
||||||
text_info: SourceTextInfo::new(source.into()),
|
text_info: SourceTextInfo::new(source.into()),
|
||||||
media_type: MediaType::TypeScript,
|
media_type: MediaType::TypeScript,
|
||||||
capture_tokens: true,
|
capture_tokens: true,
|
||||||
|
|
|
@ -246,7 +246,7 @@ impl AssetOrDocument {
|
||||||
|
|
||||||
pub fn maybe_parsed_source(
|
pub fn maybe_parsed_source(
|
||||||
&self,
|
&self,
|
||||||
) -> Option<Result<deno_ast::ParsedSource, deno_ast::Diagnostic>> {
|
) -> Option<Result<deno_ast::ParsedSource, deno_ast::ParseDiagnostic>> {
|
||||||
self.document().and_then(|d| d.maybe_parsed_source())
|
self.document().and_then(|d| d.maybe_parsed_source())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,7 +283,7 @@ impl DocumentDependencies {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ModuleResult = Result<deno_graph::JsModule, deno_graph::ModuleGraphError>;
|
type ModuleResult = Result<deno_graph::JsModule, deno_graph::ModuleGraphError>;
|
||||||
type ParsedSourceResult = Result<ParsedSource, deno_ast::Diagnostic>;
|
type ParsedSourceResult = Result<ParsedSource, deno_ast::ParseDiagnostic>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct DocumentInner {
|
struct DocumentInner {
|
||||||
|
@ -595,7 +595,7 @@ impl Document {
|
||||||
|
|
||||||
pub fn maybe_parsed_source(
|
pub fn maybe_parsed_source(
|
||||||
&self,
|
&self,
|
||||||
) -> Option<Result<deno_ast::ParsedSource, deno_ast::Diagnostic>> {
|
) -> Option<Result<deno_ast::ParsedSource, deno_ast::ParseDiagnostic>> {
|
||||||
self.0.maybe_parsed_source.clone()
|
self.0.maybe_parsed_source.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1855,7 +1855,7 @@ fn parse_source(
|
||||||
maybe_headers: Option<&HashMap<String, String>>,
|
maybe_headers: Option<&HashMap<String, String>>,
|
||||||
) -> ParsedSourceResult {
|
) -> ParsedSourceResult {
|
||||||
deno_ast::parse_module(deno_ast::ParseParams {
|
deno_ast::parse_module(deno_ast::ParseParams {
|
||||||
specifier: specifier.to_string(),
|
specifier: specifier.clone(),
|
||||||
text_info,
|
text_info,
|
||||||
media_type: MediaType::from_specifier_and_headers(specifier, maybe_headers),
|
media_type: MediaType::from_specifier_and_headers(specifier, maybe_headers),
|
||||||
capture_tokens: true,
|
capture_tokens: true,
|
||||||
|
|
|
@ -644,7 +644,7 @@ pub mod tests {
|
||||||
let specifier = resolve_url("file:///a/example.ts").unwrap();
|
let specifier = resolve_url("file:///a/example.ts").unwrap();
|
||||||
|
|
||||||
let parsed_module = deno_ast::parse_module(deno_ast::ParseParams {
|
let parsed_module = deno_ast::parse_module(deno_ast::ParseParams {
|
||||||
specifier: specifier.to_string(),
|
specifier: specifier.clone(),
|
||||||
text_info: deno_ast::SourceTextInfo::new(source.into()),
|
text_info: deno_ast::SourceTextInfo::new(source.into()),
|
||||||
media_type: deno_ast::MediaType::TypeScript,
|
media_type: deno_ast::MediaType::TypeScript,
|
||||||
capture_tokens: true,
|
capture_tokens: true,
|
||||||
|
|
|
@ -5,7 +5,6 @@ mod auth_tokens;
|
||||||
mod cache;
|
mod cache;
|
||||||
mod cdp;
|
mod cdp;
|
||||||
mod deno_std;
|
mod deno_std;
|
||||||
mod diagnostics;
|
|
||||||
mod emit;
|
mod emit;
|
||||||
mod errors;
|
mod errors;
|
||||||
mod factory;
|
mod factory;
|
||||||
|
|
|
@ -67,7 +67,7 @@ impl CliCjsCodeAnalyzer {
|
||||||
}
|
}
|
||||||
|
|
||||||
let parsed_source = deno_ast::parse_script(deno_ast::ParseParams {
|
let parsed_source = deno_ast::parse_script(deno_ast::ParseParams {
|
||||||
specifier: specifier.to_string(),
|
specifier: specifier.clone(),
|
||||||
text_info: deno_ast::SourceTextInfo::new(source.into()),
|
text_info: deno_ast::SourceTextInfo::new(source.into()),
|
||||||
media_type,
|
media_type,
|
||||||
capture_tokens: true,
|
capture_tokens: true,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
"diagnostics": [
|
"diagnostics": [
|
||||||
{
|
{
|
||||||
|
"filename": "[WILDCARD]$deno$stdin.ts",
|
||||||
"range": {
|
"range": {
|
||||||
"start": {
|
"start": {
|
||||||
"line": 1,
|
"line": 1,
|
||||||
|
@ -13,7 +14,6 @@
|
||||||
"bytePos": 11
|
"bytePos": 11
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"filename": "[WILDCARD]$deno$stdin.ts",
|
|
||||||
"message": "`any` type is not allowed",
|
"message": "`any` type is not allowed",
|
||||||
"code": "no-explicit-any",
|
"code": "no-explicit-any",
|
||||||
"hint": [WILDCARD]
|
"hint": [WILDCARD]
|
||||||
|
|
6
cli/tests/testdata/lint/expected_json.out
vendored
6
cli/tests/testdata/lint/expected_json.out
vendored
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
"diagnostics": [
|
"diagnostics": [
|
||||||
{
|
{
|
||||||
|
"filename": "[WILDCARD]file1.js",
|
||||||
"range": {
|
"range": {
|
||||||
"start": {
|
"start": {
|
||||||
"line": 1,
|
"line": 1,
|
||||||
|
@ -13,12 +14,12 @@
|
||||||
"bytePos": 19
|
"bytePos": 19
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"filename": "[WILDCARD]file1.js",
|
|
||||||
"message": "Ignore directive requires lint rule name(s)",
|
"message": "Ignore directive requires lint rule name(s)",
|
||||||
"code": "ban-untagged-ignore",
|
"code": "ban-untagged-ignore",
|
||||||
"hint": [WILDCARD]
|
"hint": [WILDCARD]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"filename": "[WILDCARD]file1.js",
|
||||||
"range": {
|
"range": {
|
||||||
"start": {
|
"start": {
|
||||||
"line": 2,
|
"line": 2,
|
||||||
|
@ -31,12 +32,12 @@
|
||||||
"bytePos": 36
|
"bytePos": 36
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"filename": "[WILDCARD]file1.js",
|
|
||||||
"message": "Empty block statement",
|
"message": "Empty block statement",
|
||||||
"code": "no-empty",
|
"code": "no-empty",
|
||||||
"hint": [WILDCARD]
|
"hint": [WILDCARD]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"filename": "[WILDCARD]file2.ts",
|
||||||
"range": {
|
"range": {
|
||||||
"start": {
|
"start": {
|
||||||
"line": 3,
|
"line": 3,
|
||||||
|
@ -49,7 +50,6 @@
|
||||||
"bytePos": 59
|
"bytePos": 59
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"filename": "[WILDCARD]file2.ts",
|
|
||||||
"message": "Empty block statement",
|
"message": "Empty block statement",
|
||||||
"code": "no-empty",
|
"code": "no-empty",
|
||||||
"hint": [WILDCARD]
|
"hint": [WILDCARD]
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
"diagnostics": [
|
"diagnostics": [
|
||||||
{
|
{
|
||||||
|
"filename": "[WILDCARD]a.ts",
|
||||||
"range": {
|
"range": {
|
||||||
"start": {
|
"start": {
|
||||||
"line": 1,
|
"line": 1,
|
||||||
|
@ -13,12 +14,12 @@
|
||||||
"bytePos": 12
|
"bytePos": 12
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"filename": "[WILDCARD]a.ts",
|
|
||||||
"message": "TODO should be tagged with (@username) or (#issue)",
|
"message": "TODO should be tagged with (@username) or (#issue)",
|
||||||
"code": "ban-untagged-todo",
|
"code": "ban-untagged-todo",
|
||||||
"hint": "Add a user tag or issue reference to the TODO comment, e.g. TODO(@djones), TODO(djones), TODO(#123)"
|
"hint": "Add a user tag or issue reference to the TODO comment, e.g. TODO(@djones), TODO(djones), TODO(#123)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"filename": "[WILDCARD]a.ts",
|
||||||
"range": {
|
"range": {
|
||||||
"start": {
|
"start": {
|
||||||
"line": 2,
|
"line": 2,
|
||||||
|
@ -31,7 +32,6 @@
|
||||||
"bytePos": 25
|
"bytePos": 25
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"filename": "[WILDCARD]a.ts",
|
|
||||||
"message": "`add` is never used",
|
"message": "`add` is never used",
|
||||||
"code": "no-unused-vars",
|
"code": "no-unused-vars",
|
||||||
"hint": "If this is intentional, prefix it with an underscore like `_add`"
|
"hint": "If this is intentional, prefix it with an underscore like `_add`"
|
||||||
|
|
137
cli/tools/doc.rs
137
cli/tools/doc.rs
|
@ -4,24 +4,14 @@ use crate::args::DocFlags;
|
||||||
use crate::args::DocHtmlFlag;
|
use crate::args::DocHtmlFlag;
|
||||||
use crate::args::DocSourceFileFlag;
|
use crate::args::DocSourceFileFlag;
|
||||||
use crate::args::Flags;
|
use crate::args::Flags;
|
||||||
use crate::cache::LazyGraphSourceParser;
|
|
||||||
use crate::colors;
|
use crate::colors;
|
||||||
use crate::diagnostics::Diagnostic;
|
|
||||||
use crate::diagnostics::DiagnosticLevel;
|
|
||||||
use crate::diagnostics::DiagnosticLocation;
|
|
||||||
use crate::diagnostics::DiagnosticSnippet;
|
|
||||||
use crate::diagnostics::DiagnosticSnippetHighlight;
|
|
||||||
use crate::diagnostics::DiagnosticSnippetHighlightStyle;
|
|
||||||
use crate::diagnostics::DiagnosticSnippetSource;
|
|
||||||
use crate::diagnostics::DiagnosticSourcePos;
|
|
||||||
use crate::diagnostics::DiagnosticSourceRange;
|
|
||||||
use crate::diagnostics::SourceTextParsedSourceStore;
|
|
||||||
use crate::display::write_json_to_stdout;
|
use crate::display::write_json_to_stdout;
|
||||||
use crate::display::write_to_stdout_ignore_sigpipe;
|
use crate::display::write_to_stdout_ignore_sigpipe;
|
||||||
use crate::factory::CliFactory;
|
use crate::factory::CliFactory;
|
||||||
use crate::graph_util::graph_lock_or_exit;
|
use crate::graph_util::graph_lock_or_exit;
|
||||||
use crate::tsc::get_types_declaration_file_text;
|
use crate::tsc::get_types_declaration_file_text;
|
||||||
use crate::util::fs::collect_specifiers;
|
use crate::util::fs::collect_specifiers;
|
||||||
|
use deno_ast::diagnostics::Diagnostic;
|
||||||
use deno_config::glob::FilePatterns;
|
use deno_config::glob::FilePatterns;
|
||||||
use deno_config::glob::PathOrPatternSet;
|
use deno_config::glob::PathOrPatternSet;
|
||||||
use deno_core::anyhow::bail;
|
use deno_core::anyhow::bail;
|
||||||
|
@ -34,10 +24,7 @@ use deno_graph::ModuleAnalyzer;
|
||||||
use deno_graph::ModuleParser;
|
use deno_graph::ModuleParser;
|
||||||
use deno_graph::ModuleSpecifier;
|
use deno_graph::ModuleSpecifier;
|
||||||
use doc::DocDiagnostic;
|
use doc::DocDiagnostic;
|
||||||
use doc::DocDiagnosticKind;
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use lsp_types::Url;
|
|
||||||
use std::borrow::Cow;
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
@ -143,10 +130,7 @@ pub async fn doc(flags: Flags, doc_flags: DocFlags) -> Result<(), AnyError> {
|
||||||
|
|
||||||
if doc_flags.lint {
|
if doc_flags.lint {
|
||||||
let diagnostics = doc_parser.take_diagnostics();
|
let diagnostics = doc_parser.take_diagnostics();
|
||||||
check_diagnostics(
|
check_diagnostics(&diagnostics)?;
|
||||||
LazyGraphSourceParser::new(parsed_source_cache, &graph),
|
|
||||||
&diagnostics,
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
doc_nodes_by_url
|
doc_nodes_by_url
|
||||||
|
@ -252,6 +236,7 @@ async fn generate_docs_directory(
|
||||||
hide_module_doc_title: false,
|
hide_module_doc_title: false,
|
||||||
href_resolver: Rc::new(DocResolver { deno_ns }),
|
href_resolver: Rc::new(DocResolver { deno_ns }),
|
||||||
sidebar_flatten_namespaces: false,
|
sidebar_flatten_namespaces: false,
|
||||||
|
usage_composer: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let files = deno_doc::html::generate(options, doc_nodes_by_url)
|
let files = deno_doc::html::generate(options, doc_nodes_by_url)
|
||||||
|
@ -308,118 +293,7 @@ fn print_docs_to_stdout(
|
||||||
write_to_stdout_ignore_sigpipe(details.as_bytes()).map_err(AnyError::from)
|
write_to_stdout_ignore_sigpipe(details.as_bytes()).map_err(AnyError::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Diagnostic for DocDiagnostic {
|
fn check_diagnostics(diagnostics: &[DocDiagnostic]) -> Result<(), AnyError> {
|
||||||
fn level(&self) -> DiagnosticLevel {
|
|
||||||
DiagnosticLevel::Error
|
|
||||||
}
|
|
||||||
|
|
||||||
fn code(&self) -> impl std::fmt::Display + '_ {
|
|
||||||
match self.kind {
|
|
||||||
DocDiagnosticKind::MissingJsDoc => "missing-jsdoc",
|
|
||||||
DocDiagnosticKind::MissingExplicitType => "missing-explicit-type",
|
|
||||||
DocDiagnosticKind::MissingReturnType => "missing-return-type",
|
|
||||||
DocDiagnosticKind::PrivateTypeRef { .. } => "private-type-ref",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn message(&self) -> impl std::fmt::Display + '_ {
|
|
||||||
match &self.kind {
|
|
||||||
DocDiagnosticKind::MissingJsDoc => {
|
|
||||||
Cow::Borrowed("exported symbol is missing JSDoc documentation")
|
|
||||||
}
|
|
||||||
DocDiagnosticKind::MissingExplicitType => {
|
|
||||||
Cow::Borrowed("exported symbol is missing an explicit type annotation")
|
|
||||||
}
|
|
||||||
DocDiagnosticKind::MissingReturnType => Cow::Borrowed(
|
|
||||||
"exported function is missing an explicit return type annotation",
|
|
||||||
),
|
|
||||||
DocDiagnosticKind::PrivateTypeRef {
|
|
||||||
reference, name, ..
|
|
||||||
} => Cow::Owned(format!(
|
|
||||||
"public type '{name}' references private type '{reference}'",
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn location(&self) -> DiagnosticLocation {
|
|
||||||
let specifier = Url::parse(&self.location.filename).unwrap();
|
|
||||||
DiagnosticLocation::ModulePosition {
|
|
||||||
specifier: Cow::Owned(specifier),
|
|
||||||
source_pos: DiagnosticSourcePos::ByteIndex(self.location.byte_index),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn snippet(&self) -> Option<DiagnosticSnippet<'_>> {
|
|
||||||
let specifier = Url::parse(&self.location.filename).unwrap();
|
|
||||||
Some(DiagnosticSnippet {
|
|
||||||
source: DiagnosticSnippetSource::Specifier(Cow::Owned(specifier)),
|
|
||||||
highlight: DiagnosticSnippetHighlight {
|
|
||||||
style: DiagnosticSnippetHighlightStyle::Error,
|
|
||||||
range: DiagnosticSourceRange {
|
|
||||||
start: DiagnosticSourcePos::ByteIndex(self.location.byte_index),
|
|
||||||
end: DiagnosticSourcePos::ByteIndex(self.location.byte_index + 1),
|
|
||||||
},
|
|
||||||
description: None,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn hint(&self) -> Option<impl std::fmt::Display + '_> {
|
|
||||||
match &self.kind {
|
|
||||||
DocDiagnosticKind::PrivateTypeRef { .. } => {
|
|
||||||
Some("make the referenced type public or remove the reference")
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn snippet_fixed(&self) -> Option<DiagnosticSnippet<'_>> {
|
|
||||||
match &self.kind {
|
|
||||||
DocDiagnosticKind::PrivateTypeRef {
|
|
||||||
reference_location, ..
|
|
||||||
} => {
|
|
||||||
let specifier = Url::parse(&reference_location.filename).unwrap();
|
|
||||||
Some(DiagnosticSnippet {
|
|
||||||
source: DiagnosticSnippetSource::Specifier(Cow::Owned(specifier)),
|
|
||||||
highlight: DiagnosticSnippetHighlight {
|
|
||||||
style: DiagnosticSnippetHighlightStyle::Hint,
|
|
||||||
range: DiagnosticSourceRange {
|
|
||||||
start: DiagnosticSourcePos::ByteIndex(
|
|
||||||
reference_location.byte_index,
|
|
||||||
),
|
|
||||||
end: DiagnosticSourcePos::ByteIndex(
|
|
||||||
reference_location.byte_index + 1,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
description: Some(Cow::Borrowed("this is the referenced type")),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn info(&self) -> std::borrow::Cow<'_, [std::borrow::Cow<'_, str>]> {
|
|
||||||
match &self.kind {
|
|
||||||
DocDiagnosticKind::MissingJsDoc => Cow::Borrowed(&[]),
|
|
||||||
DocDiagnosticKind::MissingExplicitType => Cow::Borrowed(&[]),
|
|
||||||
DocDiagnosticKind::MissingReturnType => Cow::Borrowed(&[]),
|
|
||||||
DocDiagnosticKind::PrivateTypeRef { .. } => {
|
|
||||||
Cow::Borrowed(&[Cow::Borrowed(
|
|
||||||
"to ensure documentation is complete all types that are exposed in the public API must be public",
|
|
||||||
)])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn docs_url(&self) -> Option<impl std::fmt::Display + '_> {
|
|
||||||
None::<&str>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check_diagnostics(
|
|
||||||
source_parser: LazyGraphSourceParser,
|
|
||||||
diagnostics: &[DocDiagnostic],
|
|
||||||
) -> Result<(), AnyError> {
|
|
||||||
if diagnostics.is_empty() {
|
if diagnostics.is_empty() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -441,8 +315,7 @@ fn check_diagnostics(
|
||||||
for (_, diagnostics_by_col) in diagnostics_by_lc {
|
for (_, diagnostics_by_col) in diagnostics_by_lc {
|
||||||
for (_, diagnostics) in diagnostics_by_col {
|
for (_, diagnostics) in diagnostics_by_col {
|
||||||
for diagnostic in diagnostics {
|
for diagnostic in diagnostics {
|
||||||
let sources = SourceTextParsedSourceStore(source_parser);
|
log::error!("{}", diagnostic.display());
|
||||||
log::error!("{}", diagnostic.display(&sources));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,33 +8,22 @@ use crate::args::LintOptions;
|
||||||
use crate::args::LintReporterKind;
|
use crate::args::LintReporterKind;
|
||||||
use crate::args::LintRulesConfig;
|
use crate::args::LintRulesConfig;
|
||||||
use crate::colors;
|
use crate::colors;
|
||||||
use crate::diagnostics::Diagnostic;
|
|
||||||
use crate::diagnostics::DiagnosticLevel;
|
|
||||||
use crate::diagnostics::DiagnosticLocation;
|
|
||||||
use crate::diagnostics::DiagnosticSnippet;
|
|
||||||
use crate::diagnostics::DiagnosticSnippetHighlight;
|
|
||||||
use crate::diagnostics::DiagnosticSnippetHighlightStyle;
|
|
||||||
use crate::diagnostics::DiagnosticSnippetSource;
|
|
||||||
use crate::diagnostics::DiagnosticSourcePos;
|
|
||||||
use crate::diagnostics::DiagnosticSourceRange;
|
|
||||||
use crate::diagnostics::SourceTextStore;
|
|
||||||
use crate::factory::CliFactory;
|
use crate::factory::CliFactory;
|
||||||
use crate::tools::fmt::run_parallelized;
|
use crate::tools::fmt::run_parallelized;
|
||||||
use crate::util::file_watcher;
|
use crate::util::file_watcher;
|
||||||
use crate::util::fs::canonicalize_path;
|
use crate::util::fs::canonicalize_path;
|
||||||
|
use crate::util::fs::specifier_from_file_path;
|
||||||
use crate::util::fs::FileCollector;
|
use crate::util::fs::FileCollector;
|
||||||
use crate::util::path::is_script_ext;
|
use crate::util::path::is_script_ext;
|
||||||
use crate::util::sync::AtomicFlag;
|
use crate::util::sync::AtomicFlag;
|
||||||
|
use deno_ast::diagnostics::Diagnostic;
|
||||||
use deno_ast::MediaType;
|
use deno_ast::MediaType;
|
||||||
use deno_ast::ModuleSpecifier;
|
|
||||||
use deno_ast::ParsedSource;
|
use deno_ast::ParsedSource;
|
||||||
use deno_ast::SourceTextInfo;
|
|
||||||
use deno_config::glob::FilePatterns;
|
use deno_config::glob::FilePatterns;
|
||||||
use deno_core::anyhow::bail;
|
use deno_core::anyhow::bail;
|
||||||
use deno_core::error::generic_error;
|
use deno_core::error::generic_error;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::serde_json;
|
use deno_core::serde_json;
|
||||||
use deno_core::url;
|
|
||||||
use deno_lint::diagnostic::LintDiagnostic;
|
use deno_lint::diagnostic::LintDiagnostic;
|
||||||
use deno_lint::linter::LintFileOptions;
|
use deno_lint::linter::LintFileOptions;
|
||||||
use deno_lint::linter::Linter;
|
use deno_lint::linter::Linter;
|
||||||
|
@ -44,7 +33,6 @@ use deno_lint::rules::LintRule;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use log::info;
|
use log::info;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::borrow::Cow;
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::stdin;
|
use std::io::stdin;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
@ -124,9 +112,12 @@ pub async fn lint(flags: Flags, lint_flags: LintFlags) -> Result<(), AnyError> {
|
||||||
let reporter_lock = Arc::new(Mutex::new(create_reporter(reporter_kind)));
|
let reporter_lock = Arc::new(Mutex::new(create_reporter(reporter_kind)));
|
||||||
let lint_rules = get_config_rules_err_empty(lint_options.rules)?;
|
let lint_rules = get_config_rules_err_empty(lint_options.rules)?;
|
||||||
let file_path = cli_options.initial_cwd().join(STDIN_FILE_NAME);
|
let file_path = cli_options.initial_cwd().join(STDIN_FILE_NAME);
|
||||||
let file_path = file_path.to_string_lossy();
|
|
||||||
let r = lint_stdin(&file_path, lint_rules);
|
let r = lint_stdin(&file_path, lint_rules);
|
||||||
let success = handle_lint_result(&file_path, r, reporter_lock.clone());
|
let success = handle_lint_result(
|
||||||
|
&file_path.to_string_lossy(),
|
||||||
|
r,
|
||||||
|
reporter_lock.clone(),
|
||||||
|
);
|
||||||
reporter_lock.lock().unwrap().close(1);
|
reporter_lock.lock().unwrap().close(1);
|
||||||
success
|
success
|
||||||
} else {
|
} else {
|
||||||
|
@ -278,13 +269,13 @@ fn lint_file(
|
||||||
source_code: String,
|
source_code: String,
|
||||||
lint_rules: Vec<&'static dyn LintRule>,
|
lint_rules: Vec<&'static dyn LintRule>,
|
||||||
) -> Result<(Vec<LintDiagnostic>, ParsedSource), AnyError> {
|
) -> Result<(Vec<LintDiagnostic>, ParsedSource), AnyError> {
|
||||||
let filename = file_path.to_string_lossy().to_string();
|
let specifier = specifier_from_file_path(file_path)?;
|
||||||
let media_type = MediaType::from_path(file_path);
|
let media_type = MediaType::from_specifier(&specifier);
|
||||||
|
|
||||||
let linter = create_linter(lint_rules);
|
let linter = create_linter(lint_rules);
|
||||||
|
|
||||||
let (source, file_diagnostics) = linter.lint_file(LintFileOptions {
|
let (source, file_diagnostics) = linter.lint_file(LintFileOptions {
|
||||||
filename,
|
specifier,
|
||||||
media_type,
|
media_type,
|
||||||
source_code: source_code.clone(),
|
source_code: source_code.clone(),
|
||||||
})?;
|
})?;
|
||||||
|
@ -296,7 +287,7 @@ fn lint_file(
|
||||||
/// Treats input as TypeScript.
|
/// Treats input as TypeScript.
|
||||||
/// Compatible with `--json` flag.
|
/// Compatible with `--json` flag.
|
||||||
fn lint_stdin(
|
fn lint_stdin(
|
||||||
file_path: &str,
|
file_path: &Path,
|
||||||
lint_rules: Vec<&'static dyn LintRule>,
|
lint_rules: Vec<&'static dyn LintRule>,
|
||||||
) -> Result<(Vec<LintDiagnostic>, ParsedSource), AnyError> {
|
) -> Result<(Vec<LintDiagnostic>, ParsedSource), AnyError> {
|
||||||
let mut source_code = String::new();
|
let mut source_code = String::new();
|
||||||
|
@ -307,7 +298,7 @@ fn lint_stdin(
|
||||||
let linter = create_linter(lint_rules);
|
let linter = create_linter(lint_rules);
|
||||||
|
|
||||||
let (source, file_diagnostics) = linter.lint_file(LintFileOptions {
|
let (source, file_diagnostics) = linter.lint_file(LintFileOptions {
|
||||||
filename: file_path.to_string(),
|
specifier: specifier_from_file_path(file_path)?,
|
||||||
source_code: source_code.clone(),
|
source_code: source_code.clone(),
|
||||||
media_type: MediaType::TypeScript,
|
media_type: MediaType::TypeScript,
|
||||||
})?;
|
})?;
|
||||||
|
@ -324,7 +315,10 @@ fn handle_lint_result(
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok((mut file_diagnostics, source)) => {
|
Ok((mut file_diagnostics, source)) => {
|
||||||
sort_diagnostics(&mut file_diagnostics);
|
file_diagnostics.sort_by(|a, b| match a.specifier.cmp(&b.specifier) {
|
||||||
|
std::cmp::Ordering::Equal => a.range.start.cmp(&b.range.start),
|
||||||
|
file_order => file_order,
|
||||||
|
});
|
||||||
for d in file_diagnostics.iter() {
|
for d in file_diagnostics.iter() {
|
||||||
reporter.visit_diagnostic(d, &source);
|
reporter.visit_diagnostic(d, &source);
|
||||||
}
|
}
|
||||||
|
@ -359,77 +353,11 @@ impl PrettyLintReporter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Diagnostic for LintDiagnostic {
|
|
||||||
fn level(&self) -> DiagnosticLevel {
|
|
||||||
DiagnosticLevel::Error
|
|
||||||
}
|
|
||||||
|
|
||||||
fn code(&self) -> impl std::fmt::Display + '_ {
|
|
||||||
&self.code
|
|
||||||
}
|
|
||||||
|
|
||||||
fn message(&self) -> impl std::fmt::Display + '_ {
|
|
||||||
&self.message
|
|
||||||
}
|
|
||||||
|
|
||||||
fn location(&self) -> DiagnosticLocation {
|
|
||||||
let specifier = url::Url::from_file_path(&self.filename).unwrap();
|
|
||||||
DiagnosticLocation::ModulePosition {
|
|
||||||
specifier: Cow::Owned(specifier),
|
|
||||||
source_pos: DiagnosticSourcePos::ByteIndex(self.range.start.byte_index),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn snippet(&self) -> Option<DiagnosticSnippet<'_>> {
|
|
||||||
let specifier = url::Url::from_file_path(&self.filename).unwrap();
|
|
||||||
let range = DiagnosticSourceRange {
|
|
||||||
start: DiagnosticSourcePos::ByteIndex(self.range.start.byte_index),
|
|
||||||
end: DiagnosticSourcePos::ByteIndex(self.range.end.byte_index),
|
|
||||||
};
|
|
||||||
Some(DiagnosticSnippet {
|
|
||||||
source: DiagnosticSnippetSource::Specifier(Cow::Owned(specifier)),
|
|
||||||
highlight: DiagnosticSnippetHighlight {
|
|
||||||
range,
|
|
||||||
style: DiagnosticSnippetHighlightStyle::Error,
|
|
||||||
description: None,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn hint(&self) -> Option<impl std::fmt::Display + '_> {
|
|
||||||
self.hint.as_ref().map(|h| h as &dyn std::fmt::Display)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn snippet_fixed(&self) -> Option<DiagnosticSnippet<'_>> {
|
|
||||||
None // todo
|
|
||||||
}
|
|
||||||
|
|
||||||
fn info(&self) -> Cow<'_, [std::borrow::Cow<'_, str>]> {
|
|
||||||
Cow::Borrowed(&[])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn docs_url(&self) -> Option<impl std::fmt::Display + '_> {
|
|
||||||
Some(format!("https://lint.deno.land/#{}", &self.code))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct OneSource<'a>(&'a ParsedSource);
|
|
||||||
|
|
||||||
impl SourceTextStore for OneSource<'_> {
|
|
||||||
fn get_source_text<'a>(
|
|
||||||
&'a self,
|
|
||||||
_specifier: &ModuleSpecifier,
|
|
||||||
) -> Option<Cow<'a, SourceTextInfo>> {
|
|
||||||
Some(Cow::Borrowed(self.0.text_info()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LintReporter for PrettyLintReporter {
|
impl LintReporter for PrettyLintReporter {
|
||||||
fn visit_diagnostic(&mut self, d: &LintDiagnostic, source: &ParsedSource) {
|
fn visit_diagnostic(&mut self, d: &LintDiagnostic, _source: &ParsedSource) {
|
||||||
self.lint_count += 1;
|
self.lint_count += 1;
|
||||||
|
|
||||||
let sources = OneSource(source);
|
eprintln!("{}", d.display());
|
||||||
eprintln!("{}", d.display(&sources));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_error(&mut self, file_path: &str, err: &AnyError) {
|
fn visit_error(&mut self, file_path: &str, err: &AnyError) {
|
||||||
|
@ -466,11 +394,12 @@ impl LintReporter for CompactLintReporter {
|
||||||
fn visit_diagnostic(&mut self, d: &LintDiagnostic, _source: &ParsedSource) {
|
fn visit_diagnostic(&mut self, d: &LintDiagnostic, _source: &ParsedSource) {
|
||||||
self.lint_count += 1;
|
self.lint_count += 1;
|
||||||
|
|
||||||
|
let line_and_column = d.text_info.line_and_column_display(d.range.start);
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"{}: line {}, col {} - {} ({})",
|
"{}: line {}, col {} - {} ({})",
|
||||||
d.filename,
|
d.specifier,
|
||||||
d.range.start.line_index + 1,
|
line_and_column.line_number,
|
||||||
d.range.start.column_index + 1,
|
line_and_column.column_number,
|
||||||
d.message,
|
d.message,
|
||||||
d.code
|
d.code
|
||||||
)
|
)
|
||||||
|
@ -496,9 +425,47 @@ impl LintReporter for CompactLintReporter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WARNING: Ensure doesn't change because it's used in the JSON output
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct JsonDiagnosticLintPosition {
|
||||||
|
/// The 1-indexed line number.
|
||||||
|
pub line: usize,
|
||||||
|
/// The 0-indexed column index.
|
||||||
|
pub col: usize,
|
||||||
|
pub byte_pos: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl JsonDiagnosticLintPosition {
|
||||||
|
pub fn new(byte_index: usize, loc: deno_ast::LineAndColumnIndex) -> Self {
|
||||||
|
JsonDiagnosticLintPosition {
|
||||||
|
line: loc.line_index + 1,
|
||||||
|
col: loc.column_index,
|
||||||
|
byte_pos: byte_index,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WARNING: Ensure doesn't change because it's used in the JSON output
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
|
||||||
|
struct JsonLintDiagnosticRange {
|
||||||
|
pub start: JsonDiagnosticLintPosition,
|
||||||
|
pub end: JsonDiagnosticLintPosition,
|
||||||
|
}
|
||||||
|
|
||||||
|
// WARNING: Ensure doesn't change because it's used in the JSON output
|
||||||
|
#[derive(Clone, Serialize)]
|
||||||
|
struct JsonLintDiagnostic {
|
||||||
|
pub filename: String,
|
||||||
|
pub range: JsonLintDiagnosticRange,
|
||||||
|
pub message: String,
|
||||||
|
pub code: String,
|
||||||
|
pub hint: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct JsonLintReporter {
|
struct JsonLintReporter {
|
||||||
diagnostics: Vec<LintDiagnostic>,
|
diagnostics: Vec<JsonLintDiagnostic>,
|
||||||
errors: Vec<LintError>,
|
errors: Vec<LintError>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -513,7 +480,22 @@ impl JsonLintReporter {
|
||||||
|
|
||||||
impl LintReporter for JsonLintReporter {
|
impl LintReporter for JsonLintReporter {
|
||||||
fn visit_diagnostic(&mut self, d: &LintDiagnostic, _source: &ParsedSource) {
|
fn visit_diagnostic(&mut self, d: &LintDiagnostic, _source: &ParsedSource) {
|
||||||
self.diagnostics.push(d.clone());
|
self.diagnostics.push(JsonLintDiagnostic {
|
||||||
|
filename: d.specifier.to_string(),
|
||||||
|
range: JsonLintDiagnosticRange {
|
||||||
|
start: JsonDiagnosticLintPosition::new(
|
||||||
|
d.range.start.as_byte_index(d.text_info.range().start),
|
||||||
|
d.text_info.line_and_column_index(d.range.start),
|
||||||
|
),
|
||||||
|
end: JsonDiagnosticLintPosition::new(
|
||||||
|
d.range.end.as_byte_index(d.text_info.range().start),
|
||||||
|
d.text_info.line_and_column_index(d.range.end),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
message: d.message.clone(),
|
||||||
|
code: d.code.clone(),
|
||||||
|
hint: d.hint.clone(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_error(&mut self, file_path: &str, err: &AnyError) {
|
fn visit_error(&mut self, file_path: &str, err: &AnyError) {
|
||||||
|
@ -530,19 +512,16 @@ impl LintReporter for JsonLintReporter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sort_diagnostics(diagnostics: &mut [LintDiagnostic]) {
|
fn sort_diagnostics(diagnostics: &mut [JsonLintDiagnostic]) {
|
||||||
// Sort so that we guarantee a deterministic output which is useful for tests
|
// Sort so that we guarantee a deterministic output which is useful for tests
|
||||||
diagnostics.sort_by(|a, b| {
|
diagnostics.sort_by(|a, b| {
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
let file_order = a.filename.cmp(&b.filename);
|
let file_order = a.filename.cmp(&b.filename);
|
||||||
match file_order {
|
match file_order {
|
||||||
Ordering::Equal => {
|
Ordering::Equal => {
|
||||||
let line_order =
|
let line_order = a.range.start.line.cmp(&b.range.start.line);
|
||||||
a.range.start.line_index.cmp(&b.range.start.line_index);
|
|
||||||
match line_order {
|
match line_order {
|
||||||
Ordering::Equal => {
|
Ordering::Equal => a.range.start.col.cmp(&b.range.start.col),
|
||||||
a.range.start.column_index.cmp(&b.range.start.column_index)
|
|
||||||
}
|
|
||||||
_ => line_order,
|
_ => line_order,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +1,25 @@
|
||||||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::fmt::Display;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
|
use deno_ast::diagnostics::Diagnostic;
|
||||||
|
use deno_ast::diagnostics::DiagnosticLevel;
|
||||||
|
use deno_ast::diagnostics::DiagnosticLocation;
|
||||||
|
use deno_ast::diagnostics::DiagnosticSnippet;
|
||||||
|
use deno_ast::diagnostics::DiagnosticSnippetHighlight;
|
||||||
|
use deno_ast::diagnostics::DiagnosticSnippetHighlightStyle;
|
||||||
|
use deno_ast::diagnostics::DiagnosticSourcePos;
|
||||||
|
use deno_ast::diagnostics::DiagnosticSourceRange;
|
||||||
use deno_ast::swc::common::util::take::Take;
|
use deno_ast::swc::common::util::take::Take;
|
||||||
|
use deno_ast::SourceTextInfo;
|
||||||
use deno_core::anyhow::anyhow;
|
use deno_core::anyhow::anyhow;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_graph::FastCheckDiagnostic;
|
use deno_graph::FastCheckDiagnostic;
|
||||||
use lsp_types::Url;
|
use lsp_types::Url;
|
||||||
|
|
||||||
use crate::cache::LazyGraphSourceParser;
|
|
||||||
use crate::diagnostics::Diagnostic;
|
|
||||||
use crate::diagnostics::DiagnosticLevel;
|
|
||||||
use crate::diagnostics::DiagnosticLocation;
|
|
||||||
use crate::diagnostics::DiagnosticSnippet;
|
|
||||||
use crate::diagnostics::DiagnosticSnippetHighlight;
|
|
||||||
use crate::diagnostics::DiagnosticSnippetHighlightStyle;
|
|
||||||
use crate::diagnostics::DiagnosticSnippetSource;
|
|
||||||
use crate::diagnostics::DiagnosticSourcePos;
|
|
||||||
use crate::diagnostics::DiagnosticSourceRange;
|
|
||||||
use crate::diagnostics::SourceTextParsedSourceStore;
|
|
||||||
use crate::util::import_map::ImportMapUnfurlDiagnostic;
|
use crate::util::import_map::ImportMapUnfurlDiagnostic;
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
|
@ -31,16 +28,12 @@ pub struct PublishDiagnosticsCollector {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PublishDiagnosticsCollector {
|
impl PublishDiagnosticsCollector {
|
||||||
pub fn print_and_error(
|
pub fn print_and_error(&self) -> Result<(), AnyError> {
|
||||||
&self,
|
|
||||||
sources: LazyGraphSourceParser,
|
|
||||||
) -> Result<(), AnyError> {
|
|
||||||
let mut errors = 0;
|
let mut errors = 0;
|
||||||
let mut has_zap_errors = false;
|
let mut has_zap_errors = false;
|
||||||
let diagnostics = self.diagnostics.lock().unwrap().take();
|
let diagnostics = self.diagnostics.lock().unwrap().take();
|
||||||
let sources = SourceTextParsedSourceStore(sources);
|
|
||||||
for diagnostic in diagnostics {
|
for diagnostic in diagnostics {
|
||||||
eprint!("{}", diagnostic.display(&sources));
|
eprint!("{}", diagnostic.display());
|
||||||
if matches!(diagnostic.level(), DiagnosticLevel::Error) {
|
if matches!(diagnostic.level(), DiagnosticLevel::Error) {
|
||||||
errors += 1;
|
errors += 1;
|
||||||
}
|
}
|
||||||
|
@ -90,6 +83,7 @@ pub enum PublishDiagnostic {
|
||||||
InvalidExternalImport {
|
InvalidExternalImport {
|
||||||
kind: String,
|
kind: String,
|
||||||
imported: Url,
|
imported: Url,
|
||||||
|
text_info: SourceTextInfo,
|
||||||
referrer: deno_graph::Range,
|
referrer: deno_graph::Range,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -110,22 +104,22 @@ impl Diagnostic for PublishDiagnostic {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn code(&self) -> impl Display + '_ {
|
fn code(&self) -> Cow<'_, str> {
|
||||||
use PublishDiagnostic::*;
|
use PublishDiagnostic::*;
|
||||||
match &self {
|
match &self {
|
||||||
FastCheck(diagnostic) => diagnostic.code(),
|
FastCheck(diagnostic) => diagnostic.code(),
|
||||||
ImportMapUnfurl(diagnostic) => diagnostic.code(),
|
ImportMapUnfurl(diagnostic) => Cow::Borrowed(diagnostic.code()),
|
||||||
InvalidPath { .. } => "invalid-path",
|
InvalidPath { .. } => Cow::Borrowed("invalid-path"),
|
||||||
DuplicatePath { .. } => "case-insensitive-duplicate-path",
|
DuplicatePath { .. } => Cow::Borrowed("case-insensitive-duplicate-path"),
|
||||||
UnsupportedFileType { .. } => "unsupported-file-type",
|
UnsupportedFileType { .. } => Cow::Borrowed("unsupported-file-type"),
|
||||||
InvalidExternalImport { .. } => "invalid-external-import",
|
InvalidExternalImport { .. } => Cow::Borrowed("invalid-external-import"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn message(&self) -> impl Display + '_ {
|
fn message(&self) -> Cow<'_, str> {
|
||||||
use PublishDiagnostic::*;
|
use PublishDiagnostic::*;
|
||||||
match &self {
|
match &self {
|
||||||
FastCheck(diagnostic) => Cow::Owned(diagnostic.to_string()) ,
|
FastCheck(diagnostic) => diagnostic.message(),
|
||||||
ImportMapUnfurl(diagnostic) => Cow::Borrowed(diagnostic.message()),
|
ImportMapUnfurl(diagnostic) => Cow::Borrowed(diagnostic.message()),
|
||||||
InvalidPath { message, .. } => Cow::Borrowed(message.as_str()),
|
InvalidPath { message, .. } => Cow::Borrowed(message.as_str()),
|
||||||
DuplicatePath { .. } => {
|
DuplicatePath { .. } => {
|
||||||
|
@ -141,21 +135,15 @@ impl Diagnostic for PublishDiagnostic {
|
||||||
fn location(&self) -> DiagnosticLocation {
|
fn location(&self) -> DiagnosticLocation {
|
||||||
use PublishDiagnostic::*;
|
use PublishDiagnostic::*;
|
||||||
match &self {
|
match &self {
|
||||||
FastCheck(diagnostic) => match diagnostic.range() {
|
FastCheck(diagnostic) => diagnostic.location(),
|
||||||
Some(range) => DiagnosticLocation::ModulePosition {
|
|
||||||
specifier: Cow::Borrowed(diagnostic.specifier()),
|
|
||||||
source_pos: DiagnosticSourcePos::SourcePos(range.range.start),
|
|
||||||
},
|
|
||||||
None => DiagnosticLocation::Module {
|
|
||||||
specifier: Cow::Borrowed(diagnostic.specifier()),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ImportMapUnfurl(diagnostic) => match diagnostic {
|
ImportMapUnfurl(diagnostic) => match diagnostic {
|
||||||
ImportMapUnfurlDiagnostic::UnanalyzableDynamicImport {
|
ImportMapUnfurlDiagnostic::UnanalyzableDynamicImport {
|
||||||
specifier,
|
specifier,
|
||||||
|
text_info,
|
||||||
range,
|
range,
|
||||||
} => DiagnosticLocation::ModulePosition {
|
} => DiagnosticLocation::ModulePosition {
|
||||||
specifier: Cow::Borrowed(specifier),
|
specifier: Cow::Borrowed(specifier),
|
||||||
|
text_info: Cow::Borrowed(text_info),
|
||||||
source_pos: DiagnosticSourcePos::SourcePos(range.start),
|
source_pos: DiagnosticSourcePos::SourcePos(range.start),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -168,41 +156,31 @@ impl Diagnostic for PublishDiagnostic {
|
||||||
UnsupportedFileType { specifier, .. } => DiagnosticLocation::Module {
|
UnsupportedFileType { specifier, .. } => DiagnosticLocation::Module {
|
||||||
specifier: Cow::Borrowed(specifier),
|
specifier: Cow::Borrowed(specifier),
|
||||||
},
|
},
|
||||||
InvalidExternalImport { referrer, .. } => {
|
InvalidExternalImport {
|
||||||
DiagnosticLocation::ModulePosition {
|
referrer,
|
||||||
|
text_info,
|
||||||
|
..
|
||||||
|
} => DiagnosticLocation::ModulePosition {
|
||||||
specifier: Cow::Borrowed(&referrer.specifier),
|
specifier: Cow::Borrowed(&referrer.specifier),
|
||||||
|
text_info: Cow::Borrowed(text_info),
|
||||||
source_pos: DiagnosticSourcePos::LineAndCol {
|
source_pos: DiagnosticSourcePos::LineAndCol {
|
||||||
line: referrer.start.line,
|
line: referrer.start.line,
|
||||||
column: referrer.start.character,
|
column: referrer.start.character,
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn snippet(&self) -> Option<DiagnosticSnippet<'_>> {
|
fn snippet(&self) -> Option<DiagnosticSnippet<'_>> {
|
||||||
match &self {
|
match &self {
|
||||||
PublishDiagnostic::FastCheck(diagnostic) => {
|
PublishDiagnostic::FastCheck(diagnostic) => diagnostic.snippet(),
|
||||||
diagnostic.range().map(|range| DiagnosticSnippet {
|
|
||||||
source: DiagnosticSnippetSource::Specifier(Cow::Borrowed(
|
|
||||||
diagnostic.specifier(),
|
|
||||||
)),
|
|
||||||
highlight: DiagnosticSnippetHighlight {
|
|
||||||
style: DiagnosticSnippetHighlightStyle::Error,
|
|
||||||
range: DiagnosticSourceRange {
|
|
||||||
start: DiagnosticSourcePos::SourcePos(range.range.start),
|
|
||||||
end: DiagnosticSourcePos::SourcePos(range.range.end),
|
|
||||||
},
|
|
||||||
description: diagnostic.range_description().map(Cow::Borrowed),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
PublishDiagnostic::ImportMapUnfurl(diagnostic) => match diagnostic {
|
PublishDiagnostic::ImportMapUnfurl(diagnostic) => match diagnostic {
|
||||||
ImportMapUnfurlDiagnostic::UnanalyzableDynamicImport {
|
ImportMapUnfurlDiagnostic::UnanalyzableDynamicImport {
|
||||||
specifier,
|
text_info,
|
||||||
range,
|
range,
|
||||||
|
..
|
||||||
} => Some(DiagnosticSnippet {
|
} => Some(DiagnosticSnippet {
|
||||||
source: DiagnosticSnippetSource::Specifier(Cow::Borrowed(specifier)),
|
source: Cow::Borrowed(text_info),
|
||||||
highlight: DiagnosticSnippetHighlight {
|
highlight: DiagnosticSnippetHighlight {
|
||||||
style: DiagnosticSnippetHighlightStyle::Warning,
|
style: DiagnosticSnippetHighlightStyle::Warning,
|
||||||
range: DiagnosticSourceRange {
|
range: DiagnosticSourceRange {
|
||||||
|
@ -216,11 +194,12 @@ impl Diagnostic for PublishDiagnostic {
|
||||||
PublishDiagnostic::InvalidPath { .. } => None,
|
PublishDiagnostic::InvalidPath { .. } => None,
|
||||||
PublishDiagnostic::DuplicatePath { .. } => None,
|
PublishDiagnostic::DuplicatePath { .. } => None,
|
||||||
PublishDiagnostic::UnsupportedFileType { .. } => None,
|
PublishDiagnostic::UnsupportedFileType { .. } => None,
|
||||||
PublishDiagnostic::InvalidExternalImport { referrer, .. } => {
|
PublishDiagnostic::InvalidExternalImport {
|
||||||
Some(DiagnosticSnippet {
|
referrer,
|
||||||
source: DiagnosticSnippetSource::Specifier(Cow::Borrowed(
|
text_info,
|
||||||
&referrer.specifier,
|
..
|
||||||
)),
|
} => Some(DiagnosticSnippet {
|
||||||
|
source: Cow::Borrowed(text_info),
|
||||||
highlight: DiagnosticSnippetHighlight {
|
highlight: DiagnosticSnippetHighlight {
|
||||||
style: DiagnosticSnippetHighlightStyle::Error,
|
style: DiagnosticSnippetHighlightStyle::Error,
|
||||||
range: DiagnosticSourceRange {
|
range: DiagnosticSourceRange {
|
||||||
|
@ -235,25 +214,24 @@ impl Diagnostic for PublishDiagnostic {
|
||||||
},
|
},
|
||||||
description: Some("the specifier".into()),
|
description: Some("the specifier".into()),
|
||||||
},
|
},
|
||||||
})
|
}),
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hint(&self) -> Option<impl Display + '_> {
|
fn hint(&self) -> Option<Cow<'_, str>> {
|
||||||
match &self {
|
match &self {
|
||||||
PublishDiagnostic::FastCheck(diagnostic) => Some(diagnostic.fix_hint()),
|
PublishDiagnostic::FastCheck(diagnostic) => diagnostic.hint(),
|
||||||
PublishDiagnostic::ImportMapUnfurl(_) => None,
|
PublishDiagnostic::ImportMapUnfurl(_) => None,
|
||||||
PublishDiagnostic::InvalidPath { .. } => Some(
|
PublishDiagnostic::InvalidPath { .. } => Some(
|
||||||
"rename or remove the file, or add it to 'publish.exclude' in the config file",
|
Cow::Borrowed("rename or remove the file, or add it to 'publish.exclude' in the config file"),
|
||||||
),
|
),
|
||||||
PublishDiagnostic::DuplicatePath { .. } => Some(
|
PublishDiagnostic::DuplicatePath { .. } => Some(
|
||||||
"rename or remove the file",
|
Cow::Borrowed("rename or remove the file"),
|
||||||
),
|
),
|
||||||
PublishDiagnostic::UnsupportedFileType { .. } => Some(
|
PublishDiagnostic::UnsupportedFileType { .. } => Some(
|
||||||
"remove the file, or add it to 'publish.exclude' in the config file",
|
Cow::Borrowed("remove the file, or add it to 'publish.exclude' in the config file"),
|
||||||
),
|
),
|
||||||
PublishDiagnostic::InvalidExternalImport { .. } => Some("replace this import with one from jsr or npm, or vendor the dependency into your package")
|
PublishDiagnostic::InvalidExternalImport { .. } => Some(Cow::Borrowed("replace this import with one from jsr or npm, or vendor the dependency into your package"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,12 +242,7 @@ impl Diagnostic for PublishDiagnostic {
|
||||||
fn info(&self) -> Cow<'_, [Cow<'_, str>]> {
|
fn info(&self) -> Cow<'_, [Cow<'_, str>]> {
|
||||||
match &self {
|
match &self {
|
||||||
PublishDiagnostic::FastCheck(diagnostic) => {
|
PublishDiagnostic::FastCheck(diagnostic) => {
|
||||||
let infos = diagnostic
|
diagnostic.info()
|
||||||
.additional_info()
|
|
||||||
.iter()
|
|
||||||
.map(|s| Cow::Borrowed(*s))
|
|
||||||
.collect();
|
|
||||||
Cow::Owned(infos)
|
|
||||||
}
|
}
|
||||||
PublishDiagnostic::ImportMapUnfurl(diagnostic) => match diagnostic {
|
PublishDiagnostic::ImportMapUnfurl(diagnostic) => match diagnostic {
|
||||||
ImportMapUnfurlDiagnostic::UnanalyzableDynamicImport { .. } => Cow::Borrowed(&[
|
ImportMapUnfurlDiagnostic::UnanalyzableDynamicImport { .. } => Cow::Borrowed(&[
|
||||||
|
@ -296,25 +269,23 @@ impl Diagnostic for PublishDiagnostic {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn docs_url(&self) -> Option<impl Display + '_> {
|
fn docs_url(&self) -> Option<Cow<'_, str>> {
|
||||||
match &self {
|
match &self {
|
||||||
PublishDiagnostic::FastCheck(diagnostic) => {
|
PublishDiagnostic::FastCheck(diagnostic) => diagnostic.docs_url(),
|
||||||
Some(format!("https://jsr.io/go/{}", diagnostic.code()))
|
|
||||||
}
|
|
||||||
PublishDiagnostic::ImportMapUnfurl(diagnostic) => match diagnostic {
|
PublishDiagnostic::ImportMapUnfurl(diagnostic) => match diagnostic {
|
||||||
ImportMapUnfurlDiagnostic::UnanalyzableDynamicImport { .. } => None,
|
ImportMapUnfurlDiagnostic::UnanalyzableDynamicImport { .. } => None,
|
||||||
},
|
},
|
||||||
PublishDiagnostic::InvalidPath { .. } => {
|
PublishDiagnostic::InvalidPath { .. } => {
|
||||||
Some("https://jsr.io/go/invalid-path".to_owned())
|
Some(Cow::Borrowed("https://jsr.io/go/invalid-path"))
|
||||||
}
|
|
||||||
PublishDiagnostic::DuplicatePath { .. } => {
|
|
||||||
Some("https://jsr.io/go/case-insensitive-duplicate-path".to_owned())
|
|
||||||
}
|
}
|
||||||
|
PublishDiagnostic::DuplicatePath { .. } => Some(Cow::Borrowed(
|
||||||
|
"https://jsr.io/go/case-insensitive-duplicate-path",
|
||||||
|
)),
|
||||||
PublishDiagnostic::UnsupportedFileType { .. } => {
|
PublishDiagnostic::UnsupportedFileType { .. } => {
|
||||||
Some("https://jsr.io/go/unsupported-file-type".to_owned())
|
Some(Cow::Borrowed("https://jsr.io/go/unsupported-file-type"))
|
||||||
}
|
}
|
||||||
PublishDiagnostic::InvalidExternalImport { .. } => {
|
PublishDiagnostic::InvalidExternalImport { .. } => {
|
||||||
Some("https://jsr.io/go/invalid-external-import".to_owned())
|
Some(Cow::Borrowed("https://jsr.io/go/invalid-external-import"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use deno_ast::ModuleSpecifier;
|
use deno_ast::ModuleSpecifier;
|
||||||
|
use deno_ast::SourceTextInfo;
|
||||||
use deno_config::ConfigFile;
|
use deno_config::ConfigFile;
|
||||||
use deno_config::WorkspaceConfig;
|
use deno_config::WorkspaceConfig;
|
||||||
use deno_core::anyhow::bail;
|
use deno_core::anyhow::bail;
|
||||||
|
@ -76,7 +78,9 @@ pub fn collect_invalid_external_imports(
|
||||||
let mut skip_specifiers: HashSet<Url> = HashSet::new();
|
let mut skip_specifiers: HashSet<Url> = HashSet::new();
|
||||||
|
|
||||||
let mut collect_if_invalid =
|
let mut collect_if_invalid =
|
||||||
|skip_specifiers: &mut HashSet<Url>, resolution: &ResolutionResolved| {
|
|skip_specifiers: &mut HashSet<Url>,
|
||||||
|
text: &Arc<str>,
|
||||||
|
resolution: &ResolutionResolved| {
|
||||||
if visited.insert(resolution.specifier.clone()) {
|
if visited.insert(resolution.specifier.clone()) {
|
||||||
match resolution.specifier.scheme() {
|
match resolution.specifier.scheme() {
|
||||||
"file" | "data" | "node" => {}
|
"file" | "data" | "node" => {}
|
||||||
|
@ -88,6 +92,7 @@ pub fn collect_invalid_external_imports(
|
||||||
diagnostics_collector.push(
|
diagnostics_collector.push(
|
||||||
PublishDiagnostic::InvalidExternalImport {
|
PublishDiagnostic::InvalidExternalImport {
|
||||||
kind: format!("non-JSR '{}'", resolution.specifier.scheme()),
|
kind: format!("non-JSR '{}'", resolution.specifier.scheme()),
|
||||||
|
text_info: SourceTextInfo::new(text.clone()),
|
||||||
imported: resolution.specifier.clone(),
|
imported: resolution.specifier.clone(),
|
||||||
referrer: resolution.range.clone(),
|
referrer: resolution.range.clone(),
|
||||||
},
|
},
|
||||||
|
@ -98,6 +103,7 @@ pub fn collect_invalid_external_imports(
|
||||||
diagnostics_collector.push(
|
diagnostics_collector.push(
|
||||||
PublishDiagnostic::InvalidExternalImport {
|
PublishDiagnostic::InvalidExternalImport {
|
||||||
kind: format!("'{}'", resolution.specifier.scheme()),
|
kind: format!("'{}'", resolution.specifier.scheme()),
|
||||||
|
text_info: SourceTextInfo::new(text.clone()),
|
||||||
imported: resolution.specifier.clone(),
|
imported: resolution.specifier.clone(),
|
||||||
referrer: resolution.range.clone(),
|
referrer: resolution.range.clone(),
|
||||||
},
|
},
|
||||||
|
@ -128,10 +134,10 @@ pub fn collect_invalid_external_imports(
|
||||||
|
|
||||||
for (_, dep) in &module.dependencies {
|
for (_, dep) in &module.dependencies {
|
||||||
if let Some(resolved) = dep.maybe_code.ok() {
|
if let Some(resolved) = dep.maybe_code.ok() {
|
||||||
collect_if_invalid(&mut skip_specifiers, resolved);
|
collect_if_invalid(&mut skip_specifiers, &module.source, resolved);
|
||||||
}
|
}
|
||||||
if let Some(resolved) = dep.maybe_type.ok() {
|
if let Some(resolved) = dep.maybe_type.ok() {
|
||||||
collect_if_invalid(&mut skip_specifiers, resolved);
|
collect_if_invalid(&mut skip_specifiers, &module.source, resolved);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,7 +150,7 @@ pub fn collect_fast_check_type_graph_diagnostics(
|
||||||
packages: &[MemberRoots],
|
packages: &[MemberRoots],
|
||||||
diagnostics_collector: &PublishDiagnosticsCollector,
|
diagnostics_collector: &PublishDiagnosticsCollector,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let mut seen_diagnostics = HashSet::new();
|
let mut had_diagnostic = false;
|
||||||
let mut seen_modules = HashSet::with_capacity(graph.specifiers_count());
|
let mut seen_modules = HashSet::with_capacity(graph.specifiers_count());
|
||||||
for package in packages {
|
for package in packages {
|
||||||
let mut pending = VecDeque::new();
|
let mut pending = VecDeque::new();
|
||||||
|
@ -161,12 +167,9 @@ pub fn collect_fast_check_type_graph_diagnostics(
|
||||||
let Some(es_module) = module.js() else {
|
let Some(es_module) = module.js() else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
if let Some(diagnostic) = es_module.fast_check_diagnostic() {
|
if let Some(diagnostics) = es_module.fast_check_diagnostics() {
|
||||||
for diagnostic in diagnostic.flatten_multiple() {
|
for diagnostic in diagnostics {
|
||||||
if !seen_diagnostics.insert(diagnostic.message_with_range_for_test())
|
had_diagnostic = true;
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
diagnostics_collector
|
diagnostics_collector
|
||||||
.push(PublishDiagnostic::FastCheck(diagnostic.clone()));
|
.push(PublishDiagnostic::FastCheck(diagnostic.clone()));
|
||||||
if matches!(
|
if matches!(
|
||||||
|
@ -197,5 +200,5 @@ pub fn collect_fast_check_type_graph_diagnostics(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
!seen_diagnostics.is_empty()
|
had_diagnostic
|
||||||
}
|
}
|
||||||
|
|
|
@ -643,7 +643,6 @@ async fn publish_package(
|
||||||
|
|
||||||
struct PreparePackagesData {
|
struct PreparePackagesData {
|
||||||
publish_order_graph: PublishOrderGraph,
|
publish_order_graph: PublishOrderGraph,
|
||||||
graph: Arc<deno_graph::ModuleGraph>,
|
|
||||||
package_by_name: HashMap<String, Rc<PreparedPublishPackage>>,
|
package_by_name: HashMap<String, Rc<PreparedPublishPackage>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -678,7 +677,7 @@ async fn prepare_packages_for_publishing(
|
||||||
let package = prepare_publish(
|
let package = prepare_publish(
|
||||||
&deno_json,
|
&deno_json,
|
||||||
source_cache.clone(),
|
source_cache.clone(),
|
||||||
graph.clone(),
|
graph,
|
||||||
import_map,
|
import_map,
|
||||||
diagnostics_collector,
|
diagnostics_collector,
|
||||||
)
|
)
|
||||||
|
@ -689,7 +688,6 @@ async fn prepare_packages_for_publishing(
|
||||||
let package_by_name = HashMap::from([(package_name, package)]);
|
let package_by_name = HashMap::from([(package_name, package)]);
|
||||||
return Ok(PreparePackagesData {
|
return Ok(PreparePackagesData {
|
||||||
publish_order_graph,
|
publish_order_graph,
|
||||||
graph,
|
|
||||||
package_by_name,
|
package_by_name,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -743,7 +741,6 @@ async fn prepare_packages_for_publishing(
|
||||||
}
|
}
|
||||||
Ok(PreparePackagesData {
|
Ok(PreparePackagesData {
|
||||||
publish_order_graph,
|
publish_order_graph,
|
||||||
graph,
|
|
||||||
package_by_name,
|
package_by_name,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -849,11 +846,7 @@ pub async fn publish(
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let source_parser = LazyGraphSourceParser::new(
|
diagnostics_collector.print_and_error()?;
|
||||||
cli_factory.parsed_source_cache(),
|
|
||||||
&prepared_data.graph,
|
|
||||||
);
|
|
||||||
diagnostics_collector.print_and_error(source_parser)?;
|
|
||||||
|
|
||||||
if prepared_data.package_by_name.is_empty() {
|
if prepared_data.package_by_name.is_empty() {
|
||||||
bail!("No packages to publish");
|
bail!("No packages to publish");
|
||||||
|
|
|
@ -206,7 +206,7 @@ fn resolve_content_maybe_unfurling(
|
||||||
|
|
||||||
let text = String::from_utf8(data)?;
|
let text = String::from_utf8(data)?;
|
||||||
deno_ast::parse_module(deno_ast::ParseParams {
|
deno_ast::parse_module(deno_ast::ParseParams {
|
||||||
specifier: specifier.to_string(),
|
specifier: specifier.clone(),
|
||||||
text_info: deno_ast::SourceTextInfo::from_string(text),
|
text_info: deno_ast::SourceTextInfo::from_string(text),
|
||||||
media_type,
|
media_type,
|
||||||
capture_tokens: false,
|
capture_tokens: false,
|
||||||
|
|
|
@ -16,14 +16,15 @@ use crate::tools::test::worker_has_tests;
|
||||||
use crate::tools::test::TestEvent;
|
use crate::tools::test::TestEvent;
|
||||||
use crate::tools::test::TestEventSender;
|
use crate::tools::test::TestEventSender;
|
||||||
|
|
||||||
|
use deno_ast::diagnostics::Diagnostic;
|
||||||
use deno_ast::swc::ast as swc_ast;
|
use deno_ast::swc::ast as swc_ast;
|
||||||
use deno_ast::swc::common::comments::CommentKind;
|
use deno_ast::swc::common::comments::CommentKind;
|
||||||
use deno_ast::swc::visit::noop_visit_type;
|
use deno_ast::swc::visit::noop_visit_type;
|
||||||
use deno_ast::swc::visit::Visit;
|
use deno_ast::swc::visit::Visit;
|
||||||
use deno_ast::swc::visit::VisitWith;
|
use deno_ast::swc::visit::VisitWith;
|
||||||
use deno_ast::DiagnosticsError;
|
|
||||||
use deno_ast::ImportsNotUsedAsValues;
|
use deno_ast::ImportsNotUsedAsValues;
|
||||||
use deno_ast::ModuleSpecifier;
|
use deno_ast::ModuleSpecifier;
|
||||||
|
use deno_ast::ParseDiagnosticsError;
|
||||||
use deno_ast::ParsedSource;
|
use deno_ast::ParsedSource;
|
||||||
use deno_ast::SourcePos;
|
use deno_ast::SourcePos;
|
||||||
use deno_ast::SourceRangedForSpanned;
|
use deno_ast::SourceRangedForSpanned;
|
||||||
|
@ -324,7 +325,7 @@ impl ReplSession {
|
||||||
&mut self,
|
&mut self,
|
||||||
line: &str,
|
line: &str,
|
||||||
) -> EvaluationOutput {
|
) -> EvaluationOutput {
|
||||||
fn format_diagnostic(diagnostic: &deno_ast::Diagnostic) -> String {
|
fn format_diagnostic(diagnostic: &deno_ast::ParseDiagnostic) -> String {
|
||||||
let display_position = diagnostic.display_position();
|
let display_position = diagnostic.display_position();
|
||||||
format!(
|
format!(
|
||||||
"{}: {} at {}:{}",
|
"{}: {} at {}:{}",
|
||||||
|
@ -377,11 +378,11 @@ impl ReplSession {
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
// handle a parsing diagnostic
|
// handle a parsing diagnostic
|
||||||
match err.downcast_ref::<deno_ast::Diagnostic>() {
|
match err.downcast_ref::<deno_ast::ParseDiagnostic>() {
|
||||||
Some(diagnostic) => {
|
Some(diagnostic) => {
|
||||||
Ok(EvaluationOutput::Error(format_diagnostic(diagnostic)))
|
Ok(EvaluationOutput::Error(format_diagnostic(diagnostic)))
|
||||||
}
|
}
|
||||||
None => match err.downcast_ref::<DiagnosticsError>() {
|
None => match err.downcast_ref::<ParseDiagnosticsError>() {
|
||||||
Some(diagnostics) => Ok(EvaluationOutput::Error(
|
Some(diagnostics) => Ok(EvaluationOutput::Error(
|
||||||
diagnostics
|
diagnostics
|
||||||
.0
|
.0
|
||||||
|
@ -786,13 +787,13 @@ fn parse_source_as(
|
||||||
media_type: deno_ast::MediaType,
|
media_type: deno_ast::MediaType,
|
||||||
) -> Result<deno_ast::ParsedSource, AnyError> {
|
) -> Result<deno_ast::ParsedSource, AnyError> {
|
||||||
let specifier = if media_type == deno_ast::MediaType::Tsx {
|
let specifier = if media_type == deno_ast::MediaType::Tsx {
|
||||||
"repl.tsx"
|
ModuleSpecifier::parse("file:///repl.tsx").unwrap()
|
||||||
} else {
|
} else {
|
||||||
"repl.ts"
|
ModuleSpecifier::parse("file:///repl.ts").unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
let parsed = deno_ast::parse_module(deno_ast::ParseParams {
|
let parsed = deno_ast::parse_module(deno_ast::ParseParams {
|
||||||
specifier: specifier.to_string(),
|
specifier,
|
||||||
text_info: deno_ast::SourceTextInfo::from_string(source),
|
text_info: deno_ast::SourceTextInfo::from_string(source),
|
||||||
media_type,
|
media_type,
|
||||||
capture_tokens: true,
|
capture_tokens: true,
|
||||||
|
|
|
@ -752,7 +752,7 @@ fn extract_files_from_source_comments(
|
||||||
media_type: MediaType,
|
media_type: MediaType,
|
||||||
) -> Result<Vec<File>, AnyError> {
|
) -> Result<Vec<File>, AnyError> {
|
||||||
let parsed_source = deno_ast::parse_module(deno_ast::ParseParams {
|
let parsed_source = deno_ast::parse_module(deno_ast::ParseParams {
|
||||||
specifier: specifier.to_string(),
|
specifier: specifier.clone(),
|
||||||
text_info: deno_ast::SourceTextInfo::new(source),
|
text_info: deno_ast::SourceTextInfo::new(source),
|
||||||
media_type,
|
media_type,
|
||||||
capture_tokens: false,
|
capture_tokens: false,
|
||||||
|
|
|
@ -141,7 +141,7 @@ impl PrettyTestReporter {
|
||||||
.child_results_buffer
|
.child_results_buffer
|
||||||
.entry(description.parent_id)
|
.entry(description.parent_id)
|
||||||
.or_default()
|
.or_default()
|
||||||
.remove(&description.id);
|
.shift_remove(&description.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_output_end(&mut self) {
|
fn write_output_end(&mut self) {
|
||||||
|
|
3
cli/tools/vendor/analyze.rs
vendored
3
cli/tools/vendor/analyze.rs
vendored
|
@ -61,6 +61,7 @@ fn export_specifier_has_default(s: &ExportSpecifier) -> bool {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use deno_ast::MediaType;
|
use deno_ast::MediaType;
|
||||||
|
use deno_ast::ModuleSpecifier;
|
||||||
use deno_ast::ParseParams;
|
use deno_ast::ParseParams;
|
||||||
use deno_ast::ParsedSource;
|
use deno_ast::ParsedSource;
|
||||||
use deno_ast::SourceTextInfo;
|
use deno_ast::SourceTextInfo;
|
||||||
|
@ -101,7 +102,7 @@ mod test {
|
||||||
|
|
||||||
fn parse_module(text: &str) -> ParsedSource {
|
fn parse_module(text: &str) -> ParsedSource {
|
||||||
deno_ast::parse_module(ParseParams {
|
deno_ast::parse_module(ParseParams {
|
||||||
specifier: "file:///mod.ts".to_string(),
|
specifier: ModuleSpecifier::parse("file:///mod.ts").unwrap(),
|
||||||
capture_tokens: false,
|
capture_tokens: false,
|
||||||
maybe_syntax: None,
|
maybe_syntax: None,
|
||||||
media_type: MediaType::TypeScript,
|
media_type: MediaType::TypeScript,
|
||||||
|
|
|
@ -361,8 +361,7 @@ pub fn collect_specifiers(
|
||||||
if path.is_dir() {
|
if path.is_dir() {
|
||||||
result.push(PathOrPattern::Path(path));
|
result.push(PathOrPattern::Path(path));
|
||||||
} else if !files.exclude.matches_path(&path) {
|
} else if !files.exclude.matches_path(&path) {
|
||||||
let url = ModuleSpecifier::from_file_path(&path)
|
let url = specifier_from_file_path(&path)?;
|
||||||
.map_err(|_| anyhow!("Invalid file path '{}'", path.display()))?;
|
|
||||||
prepared.push(url);
|
prepared.push(url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -385,7 +384,7 @@ pub fn collect_specifiers(
|
||||||
.collect_file_patterns(files)?;
|
.collect_file_patterns(files)?;
|
||||||
let mut collected_files_as_urls = collected_files
|
let mut collected_files_as_urls = collected_files
|
||||||
.iter()
|
.iter()
|
||||||
.map(|f| ModuleSpecifier::from_file_path(f).unwrap())
|
.map(|f| specifier_from_file_path(f).unwrap())
|
||||||
.collect::<Vec<ModuleSpecifier>>();
|
.collect::<Vec<ModuleSpecifier>>();
|
||||||
|
|
||||||
collected_files_as_urls.sort();
|
collected_files_as_urls.sort();
|
||||||
|
@ -703,6 +702,13 @@ impl LaxSingleProcessFsFlag {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn specifier_from_file_path(
|
||||||
|
path: &Path,
|
||||||
|
) -> Result<ModuleSpecifier, AnyError> {
|
||||||
|
ModuleSpecifier::from_file_path(path)
|
||||||
|
.map_err(|_| anyhow!("Invalid file path '{}'", path.display()))
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -4,6 +4,7 @@ use std::collections::HashSet;
|
||||||
|
|
||||||
use deno_ast::ParsedSource;
|
use deno_ast::ParsedSource;
|
||||||
use deno_ast::SourceRange;
|
use deno_ast::SourceRange;
|
||||||
|
use deno_ast::SourceTextInfo;
|
||||||
use deno_core::serde_json;
|
use deno_core::serde_json;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
use deno_graph::DefaultModuleAnalyzer;
|
use deno_graph::DefaultModuleAnalyzer;
|
||||||
|
@ -72,6 +73,7 @@ fn values_to_set<'a>(
|
||||||
pub enum ImportMapUnfurlDiagnostic {
|
pub enum ImportMapUnfurlDiagnostic {
|
||||||
UnanalyzableDynamicImport {
|
UnanalyzableDynamicImport {
|
||||||
specifier: ModuleSpecifier,
|
specifier: ModuleSpecifier,
|
||||||
|
text_info: SourceTextInfo,
|
||||||
range: SourceRange,
|
range: SourceRange,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -150,6 +152,7 @@ impl<'a> ImportMapUnfurler<'a> {
|
||||||
ImportMapUnfurlDiagnostic::UnanalyzableDynamicImport {
|
ImportMapUnfurlDiagnostic::UnanalyzableDynamicImport {
|
||||||
specifier: url.to_owned(),
|
specifier: url.to_owned(),
|
||||||
range: SourceRange::new(start_pos, end_pos),
|
range: SourceRange::new(start_pos, end_pos),
|
||||||
|
text_info: parsed_source.text_info().clone(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -295,7 +298,7 @@ mod tests {
|
||||||
fn parse_ast(specifier: &Url, source_code: &str) -> ParsedSource {
|
fn parse_ast(specifier: &Url, source_code: &str) -> ParsedSource {
|
||||||
let media_type = MediaType::from_specifier(specifier);
|
let media_type = MediaType::from_specifier(specifier);
|
||||||
deno_ast::parse_module(deno_ast::ParseParams {
|
deno_ast::parse_module(deno_ast::ParseParams {
|
||||||
specifier: specifier.to_string(),
|
specifier: specifier.clone(),
|
||||||
media_type,
|
media_type,
|
||||||
capture_tokens: false,
|
capture_tokens: false,
|
||||||
maybe_syntax: None,
|
maybe_syntax: None,
|
||||||
|
|
|
@ -84,7 +84,7 @@ pub fn maybe_transpile_source(
|
||||||
let code = source.load()?;
|
let code = source.load()?;
|
||||||
|
|
||||||
let parsed = deno_ast::parse_module(ParseParams {
|
let parsed = deno_ast::parse_module(ParseParams {
|
||||||
specifier: source.specifier.to_string(),
|
specifier: deno_core::url::Url::parse(source.specifier).unwrap(),
|
||||||
text_info: SourceTextInfo::from_string(code.as_str().to_owned()),
|
text_info: SourceTextInfo::from_string(code.as_str().to_owned()),
|
||||||
media_type,
|
media_type,
|
||||||
capture_tokens: false,
|
capture_tokens: false,
|
||||||
|
|
Loading…
Add table
Reference in a new issue