mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
feat(napi/transform): add lang option to change source type (#6309)
part of #6274 and #6156 ``` /// Treat the source text as `js`, `jsx`, `ts`, or `tsx`. #[napi(ts_type = "'js' | 'jsx' | 'ts' | 'tsx'")] pub lang: Option<String>, ```
This commit is contained in:
parent
5b5daec392
commit
a0ccc26c12
7 changed files with 57 additions and 30 deletions
|
|
@ -57,6 +57,10 @@ pub struct TransformOptions {
|
|||
#[napi(ts_type = "'script' | 'module' | 'unambiguous' | undefined")]
|
||||
pub source_type: Option<String>,
|
||||
|
||||
/// Treat the source text as `js`, `jsx`, `ts`, or `tsx`.
|
||||
#[napi(ts_type = "'js' | 'jsx' | 'ts' | 'tsx'")]
|
||||
pub lang: Option<String>,
|
||||
|
||||
/// The current working directory. Used to resolve relative paths in other
|
||||
/// options.
|
||||
pub cwd: Option<String>,
|
||||
|
|
|
|||
2
napi/transform/index.d.ts
vendored
2
napi/transform/index.d.ts
vendored
|
|
@ -182,6 +182,8 @@ export declare function transform(filename: string, sourceText: string, options?
|
|||
*/
|
||||
export interface TransformOptions {
|
||||
sourceType?: 'script' | 'module' | 'unambiguous' | undefined
|
||||
/** Treat the source text as `js`, `jsx`, `ts`, or `tsx`. */
|
||||
lang?: 'js' | 'jsx' | 'ts' | 'tsx'
|
||||
/**
|
||||
* The current working directory. Used to resolve relative paths in other
|
||||
* options.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::sync::Arc;
|
||||
use std::{path::Path, sync::Arc};
|
||||
|
||||
use oxc::{
|
||||
diagnostics::{Error, NamedSource, OxcDiagnostic},
|
||||
|
|
@ -6,7 +6,7 @@ use oxc::{
|
|||
};
|
||||
|
||||
pub fn wrap_diagnostics(
|
||||
filename: &str,
|
||||
filename: &Path,
|
||||
source_type: SourceType,
|
||||
source_text: &str,
|
||||
errors: Vec<OxcDiagnostic>,
|
||||
|
|
@ -28,7 +28,8 @@ pub fn wrap_diagnostics(
|
|||
}
|
||||
};
|
||||
|
||||
let ns = NamedSource::new(filename, source_text.to_string()).with_language(lang);
|
||||
let ns = NamedSource::new(filename.to_string_lossy(), source_text.to_string())
|
||||
.with_language(lang);
|
||||
Arc::new(ns)
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
use std::path::Path;
|
||||
|
||||
use napi_derive::napi;
|
||||
|
||||
use oxc::{
|
||||
|
|
@ -22,7 +24,8 @@ pub fn isolated_declaration(
|
|||
source_text: String,
|
||||
options: Option<IsolatedDeclarationsOptions>,
|
||||
) -> IsolatedDeclarationsResult {
|
||||
let source_type = SourceType::from_path(&filename).unwrap_or_default().with_typescript(true);
|
||||
let source_path = Path::new(&filename);
|
||||
let source_type = SourceType::from_path(source_path).unwrap_or_default().with_typescript(true);
|
||||
let allocator = Allocator::default();
|
||||
let options = options.unwrap_or_default();
|
||||
|
||||
|
|
@ -49,7 +52,7 @@ pub fn isolated_declaration(
|
|||
let codegen_ret = codegen.build(&transformed_ret.program);
|
||||
|
||||
let errors = ret.errors.into_iter().chain(transformed_ret.errors).collect();
|
||||
let errors = wrap_diagnostics(&filename, source_type, &source_text, errors);
|
||||
let errors = wrap_diagnostics(source_path, source_type, &source_text, errors);
|
||||
|
||||
IsolatedDeclarationsResult {
|
||||
code: codegen_ret.source_text,
|
||||
|
|
|
|||
|
|
@ -140,22 +140,35 @@ pub fn transform(
|
|||
options: Option<TransformOptions>,
|
||||
) -> TransformResult {
|
||||
let source_path = Path::new(&filename);
|
||||
let source_type = {
|
||||
let mut source_type = SourceType::from_path(source_path).unwrap_or_default();
|
||||
// Force `script` or `module`
|
||||
match options.as_ref().and_then(|options| options.source_type.as_deref()) {
|
||||
Some("script") => source_type = source_type.with_script(true),
|
||||
Some("module") => source_type = source_type.with_module(true),
|
||||
_ => {}
|
||||
|
||||
let source_type = match options.as_ref().and_then(|options| options.lang.as_deref()) {
|
||||
Some("js") => SourceType::mjs(),
|
||||
Some("jsx") => SourceType::jsx(),
|
||||
Some("ts") => SourceType::ts(),
|
||||
Some("tsx") => SourceType::tsx(),
|
||||
Some(lang) => {
|
||||
return TransformResult {
|
||||
errors: vec![format!("Incorrect lang '{lang}'")],
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
None => {
|
||||
let mut source_type = SourceType::from_path(source_path).unwrap_or_default();
|
||||
// Force `script` or `module`
|
||||
match options.as_ref().and_then(|options| options.source_type.as_deref()) {
|
||||
Some("script") => source_type = source_type.with_script(true),
|
||||
Some("module") => source_type = source_type.with_module(true),
|
||||
_ => {}
|
||||
}
|
||||
source_type
|
||||
}
|
||||
source_type
|
||||
};
|
||||
|
||||
let mut compiler = match Compiler::new(options) {
|
||||
Ok(compiler) => compiler,
|
||||
Err(errors) => {
|
||||
return TransformResult {
|
||||
errors: wrap_diagnostics(&filename, source_type, &source_text, errors),
|
||||
errors: wrap_diagnostics(source_path, source_type, &source_text, errors),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
|
@ -167,6 +180,6 @@ pub fn transform(
|
|||
map: compiler.printed_sourcemap,
|
||||
declaration: compiler.declaration,
|
||||
declaration_map: compiler.declaration_map,
|
||||
errors: wrap_diagnostics(&filename, source_type, &source_text, compiler.errors),
|
||||
errors: wrap_diagnostics(source_path, source_type, &source_text, compiler.errors),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ describe('isolated declaration', () => {
|
|||
|
||||
it('matches output', () => {
|
||||
const ret = oxc.isolatedDeclaration('test.ts', code, { sourcemap: true });
|
||||
assert(ret, {
|
||||
assert.deepEqual(ret, {
|
||||
code: '/**\n' +
|
||||
'* jsdoc 1\n' +
|
||||
'*/\n' +
|
||||
|
|
@ -28,12 +28,13 @@ describe('isolated declaration', () => {
|
|||
'\tfoo: string;\n' +
|
||||
'}\n',
|
||||
map: {
|
||||
mappings: ';;;AAIA,OAAO,cAAM,EAAE;;;;CAIb;AACD',
|
||||
mappings: ';;;AAIE,OAAO,cAAM,EAAE;;;;CAIb;AACD',
|
||||
names: [],
|
||||
sources: ['test.ts'],
|
||||
sourcesContent: [code],
|
||||
version: 3,
|
||||
},
|
||||
errors: [],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -7,8 +7,9 @@ describe('transform', () => {
|
|||
|
||||
it('matches output', () => {
|
||||
const ret = oxc.transform('test.ts', code, { sourcemap: true });
|
||||
assert(ret, {
|
||||
assert.deepEqual(ret, {
|
||||
code: 'class A {}\n',
|
||||
errors: [],
|
||||
map: {
|
||||
mappings: 'AAAA,MAAM,EAAK,CAAE',
|
||||
names: [],
|
||||
|
|
@ -18,6 +19,11 @@ describe('transform', () => {
|
|||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('lang', () => {
|
||||
const ret = oxc.transform('test.vue', code, { lang: 'ts' });
|
||||
assert.equal(ret.code, 'class A {}\n');
|
||||
});
|
||||
});
|
||||
|
||||
describe('react refresh plugin', () => {
|
||||
|
|
@ -29,8 +35,9 @@ describe('react refresh plugin', () => {
|
|||
|
||||
it('matches output', () => {
|
||||
const ret = oxc.transform('test.tsx', code, { jsx: { refresh: {} } });
|
||||
assert(ret, {
|
||||
code: 'var _s = $RefreshSig$();\n' +
|
||||
assert.equal(
|
||||
ret.code,
|
||||
'var _s = $RefreshSig$();\n' +
|
||||
'import { useState } from "react";\n' +
|
||||
'import { jsxs as _jsxs } from "react/jsx-runtime";\n' +
|
||||
'export const App = () => {\n' +
|
||||
|
|
@ -45,7 +52,7 @@ describe('react refresh plugin', () => {
|
|||
'_c = App;\n' +
|
||||
'var _c;\n' +
|
||||
'$RefreshReg$(_c, "App");\n',
|
||||
});
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -58,10 +65,8 @@ describe('define plugin', () => {
|
|||
'process.env.NODE_ENV': 'false',
|
||||
},
|
||||
});
|
||||
assert(ret, {
|
||||
// TODO: should be constant folded
|
||||
code: 'if (false === "production") {\n\tfoo;\n}\n',
|
||||
});
|
||||
// TODO: should be constant folded
|
||||
assert.equal(ret.code, 'if (false === "production") {\n\tfoo;\n}\n');
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -70,12 +75,10 @@ describe('inject plugin', () => {
|
|||
|
||||
it('matches output', () => {
|
||||
const ret = oxc.transform('test.tsx', code, {
|
||||
define: {
|
||||
'process.env.NODE_ENV': 'false',
|
||||
inject: {
|
||||
'Object.assign': 'foo',
|
||||
},
|
||||
});
|
||||
assert(ret, {
|
||||
code: 'import $inject_Object_assign from "foo";\nlet _ = $inject_Object_assign;\n',
|
||||
});
|
||||
assert.equal(ret.code, 'import $inject_Object_assign from "foo";\nlet _ = $inject_Object_assign;\n');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue