1
0
Fork 0
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:
Luca Casonato 2024-04-30 20:12:35 +02:00 committed by GitHub
parent 8c3f8ba136
commit 6cdf81db7c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 196 additions and 14 deletions

16
Cargo.lock generated
View file

@ -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",

View file

@ -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" }

View file

@ -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"

View file

@ -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,
},
))
}

View file

@ -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

View file

@ -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

View file

@ -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",

View file

@ -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,
},

View file

@ -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"),
});

View file

@ -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&#8203;://localhost:4545/jsx/jsx-runtime\n\n**Types**: http&#8203;://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 {

View file

@ -0,0 +1,4 @@
{
"args": "check --all main.tsx",
"output": "main.out"
}

View 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

View 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>;
}

View file

@ -0,0 +1,4 @@
{
"args": "check --all main.tsx",
"output": "main.out"
}

View file

@ -0,0 +1,7 @@
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "http://localhost:4545/jsx",
"jsxImportSourceTypes": "http://localhost:4545/jsx-types"
}
}

View file

@ -0,0 +1,6 @@
{
"version": "3",
"remote": {
"http://localhost:4545/jsx-types/jsx-runtime": "a9bf78bd825e7db35e1932615ea3a8bee5302a9fe7802f58d52859505ac9cf4a"
}
}

View 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

View file

@ -0,0 +1,7 @@
function A() {
return <a>Hello</a>;
}
export function B() {
return <A></A>;
}

View file

@ -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(),