From 2afbc1aa39c37b688ea1e0c47161c2fcdefc05ab Mon Sep 17 00:00:00 2001 From: David Sherret Date: Wed, 28 Aug 2024 21:06:09 -0400 Subject: [PATCH] feat: deprecate import assertions (#25281) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartek Iwańczuk --- cli/emit.rs | 118 ++++++++---------- tests/specs/cache/json_import/main.ts | 2 +- .../run/ts_import_assertions/__test__.jsonc | 2 + .../run/ts_import_assertions/assertion.out | 10 +- .../import_attributes/static_export.out | 6 - .../import_attributes/static_import.out | 6 - .../import_attributes/static_import.ts | 3 +- .../import_attributes/static_reexport.ts | 2 +- 8 files changed, 61 insertions(+), 88 deletions(-) diff --git a/cli/emit.rs b/cli/emit.rs index 6adcfd79b9..b3f4a4477a 100644 --- a/cli/emit.rs +++ b/cli/emit.rs @@ -112,28 +112,26 @@ impl Emitter { let parsed_source_cache = self.parsed_source_cache.clone(); let transpile_and_emit_options = self.transpile_and_emit_options.clone(); - let (should_cache, transpile_result) = - deno_core::unsync::spawn_blocking({ - let specifier = specifier.clone(); - let source = source.clone(); - move || -> Result<_, AnyError> { - EmitParsedSourceHelper::transpile( - &parsed_source_cache, - &specifier, - source.clone(), - media_type, - &transpile_and_emit_options.0, - &transpile_and_emit_options.1, - ) - } - }) - .await - .unwrap()?; + let transpile_result = deno_core::unsync::spawn_blocking({ + let specifier = specifier.clone(); + let source = source.clone(); + move || -> Result<_, AnyError> { + EmitParsedSourceHelper::transpile( + &parsed_source_cache, + &specifier, + source.clone(), + media_type, + &transpile_and_emit_options.0, + &transpile_and_emit_options.1, + ) + } + }) + .await + .unwrap()?; Ok(helper.post_emit_parsed_source( specifier, transpile_result, source_hash, - should_cache, )) } } @@ -150,20 +148,18 @@ impl Emitter { match helper.pre_emit_parsed_source(specifier, source) { PreEmitResult::Cached(emitted_text) => Ok(emitted_text), PreEmitResult::NotCached { source_hash } => { - let (should_cache, transpile_result) = - EmitParsedSourceHelper::transpile( - &self.parsed_source_cache, - specifier, - source.clone(), - media_type, - &self.transpile_and_emit_options.0, - &self.transpile_and_emit_options.1, - )?; + let transpile_result = EmitParsedSourceHelper::transpile( + &self.parsed_source_cache, + specifier, + source.clone(), + media_type, + &self.transpile_and_emit_options.0, + &self.transpile_and_emit_options.1, + )?; Ok(helper.post_emit_parsed_source( specifier, transpile_result, source_hash, - should_cache, )) } } @@ -261,16 +257,13 @@ impl<'a> EmitParsedSourceHelper<'a> { media_type: MediaType, transpile_options: &deno_ast::TranspileOptions, emit_options: &deno_ast::EmitOptions, - ) -> Result<(bool, TranspileResult), AnyError> { + ) -> Result { // nothing else needs the parsed source at this point, so remove from // the cache in order to not transpile owned let parsed_source = parsed_source_cache .remove_or_parse_module(specifier, source, media_type)?; - let should_cache = !has_import_assertion(&parsed_source); - Ok(( - should_cache, - parsed_source.transpile(transpile_options, emit_options)?, - )) + ensure_no_import_assertion(&parsed_source)?; + Ok(parsed_source.transpile(transpile_options, emit_options)?) } pub fn post_emit_parsed_source( @@ -278,8 +271,6 @@ impl<'a> EmitParsedSourceHelper<'a> { specifier: &ModuleSpecifier, transpile_result: TranspileResult, source_hash: u64, - // todo(dsherret): remove after Deno 2.0 - should_cache: bool, ) -> ModuleCodeBytes { let transpiled_source = match transpile_result { TranspileResult::Owned(source) => source, @@ -289,44 +280,47 @@ impl<'a> EmitParsedSourceHelper<'a> { } }; debug_assert!(transpiled_source.source_map.is_none()); - if should_cache { - self.0.emit_cache.set_emit_code( - specifier, - source_hash, - &transpiled_source.source, - ); - } + self.0.emit_cache.set_emit_code( + specifier, + source_hash, + &transpiled_source.source, + ); transpiled_source.source.into_boxed_slice().into() } } -fn has_import_assertion(parsed_source: &deno_ast::ParsedSource) -> bool { +// todo(dsherret): this is a temporary measure until we have swc erroring for this +fn ensure_no_import_assertion( + parsed_source: &deno_ast::ParsedSource, +) -> Result<(), AnyError> { fn has_import_assertion(text: &str) -> bool { // good enough text.contains(" assert ") && !text.contains(" with ") } - fn warn_import_attribute( + fn create_err( parsed_source: &deno_ast::ParsedSource, range: SourceRange, - ) { + ) -> AnyError { let text_info = parsed_source.text_info_lazy(); let loc = text_info.line_and_column_display(range.start); - deno_runtime::import_assertion_callback( - deno_core::ImportAssertionsSupportCustomCallbackArgs { - maybe_specifier: Some(parsed_source.specifier().to_string()), - maybe_line_number: Some(loc.line_number), - column_number: loc.column_number, - maybe_source_line: Some(range.text_fast(text_info).to_string()), - }, - ) + let mut msg = "Import assertions are deprecated. Use `with` keyword, instead of 'assert' keyword.".to_string(); + msg.push_str("\n\n"); + msg.push_str(range.text_fast(text_info)); + msg.push_str("\n\n"); + msg.push_str(&format!( + " at {}:{}:{}\n", + parsed_source.specifier(), + loc.line_number, + loc.column_number, + )); + deno_core::anyhow::anyhow!("{}", msg) } let Some(module) = parsed_source.program_ref().as_module() else { - return false; + return Ok(()); }; - let mut had_import_assertion = false; for item in &module.body { match item { deno_ast::swc::ast::ModuleItem::ModuleDecl(decl) => match decl { @@ -334,24 +328,21 @@ fn has_import_assertion(parsed_source: &deno_ast::ParsedSource) -> bool { if n.with.is_some() && has_import_assertion(n.text_fast(parsed_source.text_info_lazy())) { - had_import_assertion = true; - warn_import_attribute(parsed_source, n.range()); + return Err(create_err(parsed_source, n.range())); } } deno_ast::swc::ast::ModuleDecl::ExportAll(n) => { if n.with.is_some() && has_import_assertion(n.text_fast(parsed_source.text_info_lazy())) { - had_import_assertion = true; - warn_import_attribute(parsed_source, n.range()); + return Err(create_err(parsed_source, n.range())); } } deno_ast::swc::ast::ModuleDecl::ExportNamed(n) => { if n.with.is_some() && has_import_assertion(n.text_fast(parsed_source.text_info_lazy())) { - had_import_assertion = true; - warn_import_attribute(parsed_source, n.range()); + return Err(create_err(parsed_source, n.range())); } } deno_ast::swc::ast::ModuleDecl::ExportDecl(_) @@ -364,5 +355,6 @@ fn has_import_assertion(parsed_source: &deno_ast::ParsedSource) -> bool { deno_ast::swc::ast::ModuleItem::Stmt(_) => {} } } - had_import_assertion + + Ok(()) } diff --git a/tests/specs/cache/json_import/main.ts b/tests/specs/cache/json_import/main.ts index 78273558f1..d7506963b0 100644 --- a/tests/specs/cache/json_import/main.ts +++ b/tests/specs/cache/json_import/main.ts @@ -1,2 +1,2 @@ -import asdf from "./test.json" assert { type: "json" }; +import asdf from "./test.json" with { type: "json" }; console.log(asdf); diff --git a/tests/specs/run/ts_import_assertions/__test__.jsonc b/tests/specs/run/ts_import_assertions/__test__.jsonc index dc5576bd1d..5d8110ae27 100644 --- a/tests/specs/run/ts_import_assertions/__test__.jsonc +++ b/tests/specs/run/ts_import_assertions/__test__.jsonc @@ -3,10 +3,12 @@ "assertion": { "steps": [{ "args": "run assertion.ts", + "exitCode": 1, "output": "assertion.out" }, { // should output the same because the emit won't be cached "args": "run assertion.ts", + "exitCode": 1, "output": "assertion.out" }] }, diff --git a/tests/specs/run/ts_import_assertions/assertion.out b/tests/specs/run/ts_import_assertions/assertion.out index 3cc900d641..3ca7ac8ae5 100644 --- a/tests/specs/run/ts_import_assertions/assertion.out +++ b/tests/specs/run/ts_import_assertions/assertion.out @@ -1,14 +1,6 @@ -⚠️ Import assertions are deprecated. Use `with` keyword, instead of 'assert' keyword. +error: Import assertions are deprecated. Use `with` keyword, instead of 'assert' keyword. import test from "./data.json" assert { type: "json" }; at file:///[WILDLINE]/assertion.ts:1:1 -{ prop: "data" } -⚠️ Import assertions are deprecated. Use `with` keyword, instead of 'assert' keyword. - -console.log((await import("./data.json", { - - at file:///[WILDLINE]/assertion.ts:5:13 - -{ prop: "data" } diff --git a/tests/testdata/import_attributes/static_export.out b/tests/testdata/import_attributes/static_export.out index d7e19c80f4..41af79d7c8 100644 --- a/tests/testdata/import_attributes/static_export.out +++ b/tests/testdata/import_attributes/static_export.out @@ -1,7 +1 @@ -⚠️ Import assertions are deprecated. Use `with` keyword, instead of 'assert' keyword. - -export { default } from "./data.json" assert { type: "json" }; - - at file:///[WILDLINE] - { a: "b", c: { d: 10 } } diff --git a/tests/testdata/import_attributes/static_import.out b/tests/testdata/import_attributes/static_import.out index 85c75d3eba..e57dffa992 100644 --- a/tests/testdata/import_attributes/static_import.out +++ b/tests/testdata/import_attributes/static_import.out @@ -1,8 +1,2 @@ -⚠️ Import assertions are deprecated. Use `with` keyword, instead of 'assert' keyword. - -import data2 from "./data.json" assert { type: "json" }; - - at file:///[WILDLINE] - { a: "b", c: { d: 10 } } { a: "b", c: { d: 10 } } diff --git a/tests/testdata/import_attributes/static_import.ts b/tests/testdata/import_attributes/static_import.ts index 1538a4a2f0..f585b893f3 100644 --- a/tests/testdata/import_attributes/static_import.ts +++ b/tests/testdata/import_attributes/static_import.ts @@ -1,6 +1,5 @@ import data1 from "./data.json" with { type: "json" }; -// deno-lint-ignore no-import-assertions -import data2 from "./data.json" assert { type: "json" }; +import data2 from "./data.json" with { type: "json" }; console.log(data1); console.log(data2); diff --git a/tests/testdata/import_attributes/static_reexport.ts b/tests/testdata/import_attributes/static_reexport.ts index 81af428bed..e6175691c6 100644 --- a/tests/testdata/import_attributes/static_reexport.ts +++ b/tests/testdata/import_attributes/static_reexport.ts @@ -1 +1 @@ -export { default } from "./data.json" assert { type: "json" }; +export { default } from "./data.json" with { type: "json" };