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]]
|
||||
name = "deno_ast"
|
||||
version = "0.38.0"
|
||||
version = "0.38.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fffefe28ebd657419ab0f7fbf4ab9cd4ae38d55c2a0e4fe1661c76d7fa2b81ba"
|
||||
checksum = "7e2417aad5382d10d035e46d35f2f5fbbb93a922816408245ee585e7ca775194"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64",
|
||||
|
@ -1272,9 +1272,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_config"
|
||||
version = "0.16.2"
|
||||
version = "0.16.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f28ad258b58ade470cd745191eacee35562db3c967ffb26b4aa6f0f88f0882dd"
|
||||
checksum = "971658ccd8dbd7de18f44d2270a6881a78a88f123584fc6497189ee5d20aa307"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"glob",
|
||||
|
@ -1405,9 +1405,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_emit"
|
||||
version = "0.40.1"
|
||||
version = "0.40.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14b9cd09751a6493567d773c2a610f86d41b2f76ecfaf9eff23d3400970f8d30"
|
||||
checksum = "efe4e71f7c2b0ddef4a4927a193ce47824488f29c90166700605b3fe560fecb7"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64",
|
||||
|
@ -1477,9 +1477,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_graph"
|
||||
version = "0.74.0"
|
||||
version = "0.74.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02f5fa7d6a74edd749de34216fa52aad7af6b4e47b321cc7e91e38b9a7a2bb48"
|
||||
checksum = "d828c95097ea836267c058ac912b5bd9e5c95cec11f57a32b25ac9e4bbe698fc"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
|
|
|
@ -43,7 +43,7 @@ license = "MIT"
|
|||
repository = "https://github.com/denoland/deno"
|
||||
|
||||
[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_bench_util = { version = "0.142.0", path = "./bench_util" }
|
||||
|
|
|
@ -65,11 +65,11 @@ winres.workspace = true
|
|||
[dependencies]
|
||||
deno_ast = { workspace = true, features = ["bundler", "cjs", "codegen", "proposal", "react", "sourcemap", "transforms", "typescript", "view", "visit"] }
|
||||
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_doc = { version = "=0.128.1", features = ["html", "syntect"] }
|
||||
deno_emit = "=0.40.1"
|
||||
deno_graph = { version = "=0.74.0", features = ["tokio_executor"] }
|
||||
deno_emit = "=0.40.2"
|
||||
deno_graph = { version = "=0.74.2", features = ["tokio_executor"] }
|
||||
deno_lint = { version = "=0.58.4", features = ["docs"] }
|
||||
deno_lockfile.workspace = true
|
||||
deno_npm = "=0.18.0"
|
||||
|
|
|
@ -196,6 +196,7 @@ pub fn ts_config_to_transpile_and_emit_options(
|
|||
inline_sources: options.inline_sources,
|
||||
keep_comments: false,
|
||||
source_map,
|
||||
source_map_file: None,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
|
|
@ -1071,8 +1071,14 @@ impl LspTsConfig {
|
|||
let import_map = import_map?;
|
||||
let referrer = &config_file?.specifier;
|
||||
let compiler_options = ts_config.inner.0.as_object_mut()?;
|
||||
let jsx_import_source =
|
||||
compiler_options.get("jsxImportSource")?.as_str()?;
|
||||
let jsx_import_source = compiler_options
|
||||
.get("jsxImportSourceTypes")
|
||||
.and_then(|v| v.as_str())
|
||||
.or_else(|| {
|
||||
compiler_options
|
||||
.get("jsxImportSource")
|
||||
.and_then(|v| v.as_str())
|
||||
})?;
|
||||
let jsx_import_source =
|
||||
import_map.resolve(jsx_import_source, referrer).ok()?;
|
||||
compiler_options
|
||||
|
|
|
@ -447,6 +447,7 @@ pub struct CliGraphResolver {
|
|||
sloppy_imports_resolver: Option<SloppyImportsResolver>,
|
||||
mapped_specifier_resolver: MappedSpecifierResolver,
|
||||
maybe_default_jsx_import_source: Option<String>,
|
||||
maybe_default_jsx_import_source_types: Option<String>,
|
||||
maybe_jsx_import_source_module: Option<String>,
|
||||
maybe_vendor_specifier: Option<ModuleSpecifier>,
|
||||
node_resolver: Option<Arc<CliNodeResolver>>,
|
||||
|
@ -488,6 +489,10 @@ impl CliGraphResolver {
|
|||
.maybe_jsx_import_source_config
|
||||
.as_ref()
|
||||
.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_config
|
||||
.map(|c| c.module),
|
||||
|
@ -554,6 +559,10 @@ impl Resolver for CliGraphResolver {
|
|||
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 {
|
||||
self
|
||||
.maybe_jsx_import_source_module
|
||||
|
|
|
@ -76,6 +76,12 @@
|
|||
"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"
|
||||
},
|
||||
"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": {
|
||||
"description": "Specify list of elements that should be exempt from being precompiled when the jsx 'precompile' transform is used.",
|
||||
"type": "array",
|
||||
|
|
|
@ -637,6 +637,7 @@ impl ReplSession {
|
|||
},
|
||||
&deno_ast::EmitOptions {
|
||||
source_map: deno_ast::SourceMapOption::None,
|
||||
source_map_file: None,
|
||||
inline_sources: 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.set_jsx_import_source_config(JsxImportSourceConfig {
|
||||
default_specifier: Some("preact".to_string()),
|
||||
default_types_specifier: None,
|
||||
module: "jsx-runtime".to_string(),
|
||||
base_url: builder.resolve_to_url("/deno.json"),
|
||||
});
|
||||
|
@ -1254,6 +1255,7 @@ mod test {
|
|||
builder.add_entry_point("/mod.ts");
|
||||
builder.set_jsx_import_source_config(JsxImportSourceConfig {
|
||||
default_specifier: Some("preact".to_string()),
|
||||
default_types_specifier: None,
|
||||
module: "jsx-runtime".to_string(),
|
||||
base_url: builder.resolve_to_url("/deno.json"),
|
||||
});
|
||||
|
|
|
@ -10525,6 +10525,10 @@ export function B() {
|
|||
}
|
||||
})
|
||||
);
|
||||
|
||||
let diagnostics = client.read_diagnostics();
|
||||
println!("{:?}", diagnostics);
|
||||
|
||||
client.shutdown();
|
||||
}
|
||||
|
||||
|
@ -10584,6 +10588,74 @@ fn lsp_jsx_import_source_config_file_automatic_cache() {
|
|||
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)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
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)
|
||||
}
|
||||
(_, "/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") => {
|
||||
let mut res = Response::new(string_body(
|
||||
&serde_json::to_string_pretty(&std::time::SystemTime::now()).unwrap(),
|
||||
|
|
Loading…
Reference in a new issue