mirror of
https://github.com/denoland/deno.git
synced 2024-11-24 15:19:26 -05:00
feat(cli): add support for jsxImportSourceTypes (#23419)
Co-authored-by: David Sherret <dsherret@gmail.com>
This commit is contained in:
parent
8c3f8ba136
commit
6cdf81db7c
19 changed files with 196 additions and 14 deletions
16
Cargo.lock
generated
16
Cargo.lock
generated
|
@ -1166,9 +1166,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_ast"
|
name = "deno_ast"
|
||||||
version = "0.38.0"
|
version = "0.38.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fffefe28ebd657419ab0f7fbf4ab9cd4ae38d55c2a0e4fe1661c76d7fa2b81ba"
|
checksum = "7e2417aad5382d10d035e46d35f2f5fbbb93a922816408245ee585e7ca775194"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64",
|
||||||
|
@ -1272,9 +1272,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_config"
|
name = "deno_config"
|
||||||
version = "0.16.2"
|
version = "0.16.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f28ad258b58ade470cd745191eacee35562db3c967ffb26b4aa6f0f88f0882dd"
|
checksum = "971658ccd8dbd7de18f44d2270a6881a78a88f123584fc6497189ee5d20aa307"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"glob",
|
"glob",
|
||||||
|
@ -1405,9 +1405,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_emit"
|
name = "deno_emit"
|
||||||
version = "0.40.1"
|
version = "0.40.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "14b9cd09751a6493567d773c2a610f86d41b2f76ecfaf9eff23d3400970f8d30"
|
checksum = "efe4e71f7c2b0ddef4a4927a193ce47824488f29c90166700605b3fe560fecb7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64",
|
||||||
|
@ -1477,9 +1477,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_graph"
|
name = "deno_graph"
|
||||||
version = "0.74.0"
|
version = "0.74.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "02f5fa7d6a74edd749de34216fa52aad7af6b4e47b321cc7e91e38b9a7a2bb48"
|
checksum = "d828c95097ea836267c058ac912b5bd9e5c95cec11f57a32b25ac9e4bbe698fc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
|
|
@ -43,7 +43,7 @@ license = "MIT"
|
||||||
repository = "https://github.com/denoland/deno"
|
repository = "https://github.com/denoland/deno"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
deno_ast = { version = "=0.38.0", features = ["transpiling"] }
|
deno_ast = { version = "=0.38.1", features = ["transpiling"] }
|
||||||
deno_core = { version = "0.278.0" }
|
deno_core = { version = "0.278.0" }
|
||||||
|
|
||||||
deno_bench_util = { version = "0.142.0", path = "./bench_util" }
|
deno_bench_util = { version = "0.142.0", path = "./bench_util" }
|
||||||
|
|
|
@ -65,11 +65,11 @@ winres.workspace = true
|
||||||
[dependencies]
|
[dependencies]
|
||||||
deno_ast = { workspace = true, features = ["bundler", "cjs", "codegen", "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 = { workspace = true }
|
deno_cache_dir = { workspace = true }
|
||||||
deno_config = "=0.16.2"
|
deno_config = "=0.16.3"
|
||||||
deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] }
|
deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] }
|
||||||
deno_doc = { version = "=0.128.1", features = ["html", "syntect"] }
|
deno_doc = { version = "=0.128.1", features = ["html", "syntect"] }
|
||||||
deno_emit = "=0.40.1"
|
deno_emit = "=0.40.2"
|
||||||
deno_graph = { version = "=0.74.0", features = ["tokio_executor"] }
|
deno_graph = { version = "=0.74.2", features = ["tokio_executor"] }
|
||||||
deno_lint = { version = "=0.58.4", features = ["docs"] }
|
deno_lint = { version = "=0.58.4", features = ["docs"] }
|
||||||
deno_lockfile.workspace = true
|
deno_lockfile.workspace = true
|
||||||
deno_npm = "=0.18.0"
|
deno_npm = "=0.18.0"
|
||||||
|
|
|
@ -196,6 +196,7 @@ pub fn ts_config_to_transpile_and_emit_options(
|
||||||
inline_sources: options.inline_sources,
|
inline_sources: options.inline_sources,
|
||||||
keep_comments: false,
|
keep_comments: false,
|
||||||
source_map,
|
source_map,
|
||||||
|
source_map_file: None,
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1071,8 +1071,14 @@ impl LspTsConfig {
|
||||||
let import_map = import_map?;
|
let import_map = import_map?;
|
||||||
let referrer = &config_file?.specifier;
|
let referrer = &config_file?.specifier;
|
||||||
let compiler_options = ts_config.inner.0.as_object_mut()?;
|
let compiler_options = ts_config.inner.0.as_object_mut()?;
|
||||||
let jsx_import_source =
|
let jsx_import_source = compiler_options
|
||||||
compiler_options.get("jsxImportSource")?.as_str()?;
|
.get("jsxImportSourceTypes")
|
||||||
|
.and_then(|v| v.as_str())
|
||||||
|
.or_else(|| {
|
||||||
|
compiler_options
|
||||||
|
.get("jsxImportSource")
|
||||||
|
.and_then(|v| v.as_str())
|
||||||
|
})?;
|
||||||
let jsx_import_source =
|
let jsx_import_source =
|
||||||
import_map.resolve(jsx_import_source, referrer).ok()?;
|
import_map.resolve(jsx_import_source, referrer).ok()?;
|
||||||
compiler_options
|
compiler_options
|
||||||
|
|
|
@ -447,6 +447,7 @@ pub struct CliGraphResolver {
|
||||||
sloppy_imports_resolver: Option<SloppyImportsResolver>,
|
sloppy_imports_resolver: Option<SloppyImportsResolver>,
|
||||||
mapped_specifier_resolver: MappedSpecifierResolver,
|
mapped_specifier_resolver: MappedSpecifierResolver,
|
||||||
maybe_default_jsx_import_source: Option<String>,
|
maybe_default_jsx_import_source: Option<String>,
|
||||||
|
maybe_default_jsx_import_source_types: Option<String>,
|
||||||
maybe_jsx_import_source_module: Option<String>,
|
maybe_jsx_import_source_module: Option<String>,
|
||||||
maybe_vendor_specifier: Option<ModuleSpecifier>,
|
maybe_vendor_specifier: Option<ModuleSpecifier>,
|
||||||
node_resolver: Option<Arc<CliNodeResolver>>,
|
node_resolver: Option<Arc<CliNodeResolver>>,
|
||||||
|
@ -488,6 +489,10 @@ impl CliGraphResolver {
|
||||||
.maybe_jsx_import_source_config
|
.maybe_jsx_import_source_config
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|c| c.default_specifier.clone()),
|
.and_then(|c| c.default_specifier.clone()),
|
||||||
|
maybe_default_jsx_import_source_types: options
|
||||||
|
.maybe_jsx_import_source_config
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|c| c.default_types_specifier.clone()),
|
||||||
maybe_jsx_import_source_module: options
|
maybe_jsx_import_source_module: options
|
||||||
.maybe_jsx_import_source_config
|
.maybe_jsx_import_source_config
|
||||||
.map(|c| c.module),
|
.map(|c| c.module),
|
||||||
|
@ -554,6 +559,10 @@ impl Resolver for CliGraphResolver {
|
||||||
self.maybe_default_jsx_import_source.clone()
|
self.maybe_default_jsx_import_source.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn default_jsx_import_source_types(&self) -> Option<String> {
|
||||||
|
self.maybe_default_jsx_import_source_types.clone()
|
||||||
|
}
|
||||||
|
|
||||||
fn jsx_import_source_module(&self) -> &str {
|
fn jsx_import_source_module(&self) -> &str {
|
||||||
self
|
self
|
||||||
.maybe_jsx_import_source_module
|
.maybe_jsx_import_source_module
|
||||||
|
|
|
@ -76,6 +76,12 @@
|
||||||
"default": "react",
|
"default": "react",
|
||||||
"markdownDescription": "Specify module specifier used to import the JSX factory functions when using jsx: `react-jsx*`.\n\nSee more: https://www.typescriptlang.org/tsconfig/#jsxImportSource"
|
"markdownDescription": "Specify module specifier used to import the JSX factory functions when using jsx: `react-jsx*`.\n\nSee more: https://www.typescriptlang.org/tsconfig/#jsxImportSource"
|
||||||
},
|
},
|
||||||
|
"jsxImportSourceTypes": {
|
||||||
|
"description": "Specify module specifier used to import the types for the JSX factory functions when using jsx: 'react-jsx*'. This is the logical equivalent of prefixing an import to the jsxImportSource with `// @deno-types=\"...\"`.",
|
||||||
|
"type": "string",
|
||||||
|
"default": "@types/react",
|
||||||
|
"markdownDescription": "Specify module specifier used to import the types for the JSX factory functions when using jsx: `react-jsx*`. This is the logical equivalent of prefixing an import to the jsxImportSource with `// @deno-types=\"...\"`."
|
||||||
|
},
|
||||||
"jsxPrecompileSkipElements": {
|
"jsxPrecompileSkipElements": {
|
||||||
"description": "Specify list of elements that should be exempt from being precompiled when the jsx 'precompile' transform is used.",
|
"description": "Specify list of elements that should be exempt from being precompiled when the jsx 'precompile' transform is used.",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
|
|
|
@ -637,6 +637,7 @@ impl ReplSession {
|
||||||
},
|
},
|
||||||
&deno_ast::EmitOptions {
|
&deno_ast::EmitOptions {
|
||||||
source_map: deno_ast::SourceMapOption::None,
|
source_map: deno_ast::SourceMapOption::None,
|
||||||
|
source_map_file: None,
|
||||||
inline_sources: false,
|
inline_sources: false,
|
||||||
keep_comments: false,
|
keep_comments: false,
|
||||||
},
|
},
|
||||||
|
|
2
cli/tools/vendor/build.rs
vendored
2
cli/tools/vendor/build.rs
vendored
|
@ -1205,6 +1205,7 @@ mod test {
|
||||||
builder.add_entry_point("/mod.tsx");
|
builder.add_entry_point("/mod.tsx");
|
||||||
builder.set_jsx_import_source_config(JsxImportSourceConfig {
|
builder.set_jsx_import_source_config(JsxImportSourceConfig {
|
||||||
default_specifier: Some("preact".to_string()),
|
default_specifier: Some("preact".to_string()),
|
||||||
|
default_types_specifier: None,
|
||||||
module: "jsx-runtime".to_string(),
|
module: "jsx-runtime".to_string(),
|
||||||
base_url: builder.resolve_to_url("/deno.json"),
|
base_url: builder.resolve_to_url("/deno.json"),
|
||||||
});
|
});
|
||||||
|
@ -1254,6 +1255,7 @@ mod test {
|
||||||
builder.add_entry_point("/mod.ts");
|
builder.add_entry_point("/mod.ts");
|
||||||
builder.set_jsx_import_source_config(JsxImportSourceConfig {
|
builder.set_jsx_import_source_config(JsxImportSourceConfig {
|
||||||
default_specifier: Some("preact".to_string()),
|
default_specifier: Some("preact".to_string()),
|
||||||
|
default_types_specifier: None,
|
||||||
module: "jsx-runtime".to_string(),
|
module: "jsx-runtime".to_string(),
|
||||||
base_url: builder.resolve_to_url("/deno.json"),
|
base_url: builder.resolve_to_url("/deno.json"),
|
||||||
});
|
});
|
||||||
|
|
|
@ -10525,6 +10525,10 @@ export function B() {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let diagnostics = client.read_diagnostics();
|
||||||
|
println!("{:?}", diagnostics);
|
||||||
|
|
||||||
client.shutdown();
|
client.shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10584,6 +10588,74 @@ fn lsp_jsx_import_source_config_file_automatic_cache() {
|
||||||
client.shutdown();
|
client.shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn lsp_jsx_import_source_types_pragma() {
|
||||||
|
let context = TestContextBuilder::new()
|
||||||
|
.use_http_server()
|
||||||
|
.use_temp_cwd()
|
||||||
|
.build();
|
||||||
|
let mut client = context.new_lsp_command().build();
|
||||||
|
client.initialize_default();
|
||||||
|
client.did_open(json!({
|
||||||
|
"textDocument": {
|
||||||
|
"uri": "file:///a/file.tsx",
|
||||||
|
"languageId": "typescriptreact",
|
||||||
|
"version": 1,
|
||||||
|
"text":
|
||||||
|
"/** @jsxImportSource http://localhost:4545/jsx */
|
||||||
|
/** @jsxImportSourceTypes http://localhost:4545/jsx-types */
|
||||||
|
/** @jsxRuntime automatic */
|
||||||
|
|
||||||
|
function A() {
|
||||||
|
return <a>Hello</a>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function B() {
|
||||||
|
return <A></A>;
|
||||||
|
}
|
||||||
|
",
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
client.write_request(
|
||||||
|
"workspace/executeCommand",
|
||||||
|
json!({
|
||||||
|
"command": "deno.cache",
|
||||||
|
"arguments": [
|
||||||
|
[],
|
||||||
|
"file:///a/file.tsx",
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
let diagnostics = client.read_diagnostics();
|
||||||
|
assert_eq!(diagnostics.all().len(), 0);
|
||||||
|
|
||||||
|
let res = client.write_request(
|
||||||
|
"textDocument/hover",
|
||||||
|
json!({
|
||||||
|
"textDocument": {
|
||||||
|
"uri": "file:///a/file.tsx"
|
||||||
|
},
|
||||||
|
"position": { "line": 0, "character": 25 }
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
res,
|
||||||
|
json!({
|
||||||
|
"contents": {
|
||||||
|
"kind": "markdown",
|
||||||
|
"value": "**Resolved Dependency**\n\n**Code**: http​://localhost:4545/jsx/jsx-runtime\n\n**Types**: http​://localhost:4545/jsx-types/jsx-runtime\n",
|
||||||
|
},
|
||||||
|
"range": {
|
||||||
|
"start": { "line": 0, "character": 21 },
|
||||||
|
"end": { "line": 0, "character": 46 }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
client.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, PartialEq)]
|
#[derive(Debug, Clone, Deserialize, PartialEq)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
struct TestData {
|
struct TestData {
|
||||||
|
|
4
tests/specs/check/jsx_import_source_types/__test__.jsonc
Normal file
4
tests/specs/check/jsx_import_source_types/__test__.jsonc
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"args": "check --all main.tsx",
|
||||||
|
"output": "main.out"
|
||||||
|
}
|
3
tests/specs/check/jsx_import_source_types/main.out
Normal file
3
tests/specs/check/jsx_import_source_types/main.out
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
Download http://localhost:4545/jsx-types/jsx-runtime
|
||||||
|
Download http://localhost:4545/jsx-types/jsx-runtime.d.ts
|
||||||
|
Check file:///[WILDLINE]/main.tsx
|
11
tests/specs/check/jsx_import_source_types/main.tsx
Normal file
11
tests/specs/check/jsx_import_source_types/main.tsx
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
/** @jsxImportSource http://localhost:4545/jsx */
|
||||||
|
/** @jsxImportSourceTypes http://localhost:4545/jsx-types */
|
||||||
|
/** @jsxRuntime automatic */
|
||||||
|
|
||||||
|
function A() {
|
||||||
|
return <a>Hello</a>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function B() {
|
||||||
|
return <A></A>;
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"args": "check --all main.tsx",
|
||||||
|
"output": "main.out"
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"jsxImportSource": "http://localhost:4545/jsx",
|
||||||
|
"jsxImportSourceTypes": "http://localhost:4545/jsx-types"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"version": "3",
|
||||||
|
"remote": {
|
||||||
|
"http://localhost:4545/jsx-types/jsx-runtime": "a9bf78bd825e7db35e1932615ea3a8bee5302a9fe7802f58d52859505ac9cf4a"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
Download http://localhost:4545/jsx-types/jsx-runtime
|
||||||
|
Download http://localhost:4545/jsx-types/jsx-runtime.d.ts
|
||||||
|
Check file:///[WILDLINE]/main.tsx
|
|
@ -0,0 +1,7 @@
|
||||||
|
function A() {
|
||||||
|
return <a>Hello</a>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function B() {
|
||||||
|
return <A></A>;
|
||||||
|
}
|
|
@ -801,6 +801,46 @@ async fn main_server(
|
||||||
);
|
);
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
(_, "/jsx-types/jsx-runtime") | (_, "/jsx-types/jsx-dev-runtime") => {
|
||||||
|
let mut res = Response::new(string_body(
|
||||||
|
r#"
|
||||||
|
/// <reference types="./jsx-runtime.d.ts" />
|
||||||
|
"#,
|
||||||
|
));
|
||||||
|
res.headers_mut().insert(
|
||||||
|
"Content-type",
|
||||||
|
HeaderValue::from_static("application/javascript"),
|
||||||
|
);
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
(_, "/jsx-types/jsx-runtime.d.ts") => {
|
||||||
|
let mut res = Response::new(string_body(
|
||||||
|
r#"export function jsx(
|
||||||
|
_type: "a" | "b",
|
||||||
|
_props: any,
|
||||||
|
_key: any,
|
||||||
|
_source: any,
|
||||||
|
_self: any,
|
||||||
|
): any;
|
||||||
|
export const jsxs: typeof jsx;
|
||||||
|
export const jsxDEV: typeof jsx;
|
||||||
|
export const Fragment: unique symbol;
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
namespace JSX {
|
||||||
|
interface IntrinsicElements {
|
||||||
|
[tagName: string]: Record<string, any>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
));
|
||||||
|
res.headers_mut().insert(
|
||||||
|
"Content-type",
|
||||||
|
HeaderValue::from_static("application/typescript"),
|
||||||
|
);
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
(_, "/dynamic") => {
|
(_, "/dynamic") => {
|
||||||
let mut res = Response::new(string_body(
|
let mut res = Response::new(string_body(
|
||||||
&serde_json::to_string_pretty(&std::time::SystemTime::now()).unwrap(),
|
&serde_json::to_string_pretty(&std::time::SystemTime::now()).unwrap(),
|
||||||
|
|
Loading…
Reference in a new issue