feat(napi): export a pure parse function for benchmark purposes (#571)

This commit is contained in:
Boshen 2023-07-19 12:55:26 +08:00 committed by GitHub
parent e1dec30bc0
commit 3f84a7fc25
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 14 deletions

View file

@ -13,11 +13,22 @@ export interface ParserOptions {
sourceFilename?: string sourceFilename?: string
} }
export interface ParseResult { export interface ParseResult {
program: any program: string
errors: Array<string> errors: Array<string>
} }
/** /**
* Parse without returning anything.
* For benchmark purposes such as measuring the napi communication overhead.
*
* # Panics * # Panics
*
* * File extension is invalid
* * Serde JSON serialization
*/
export function parseWithoutReturn(sourceText: string, options?: ParserOptions | undefined | null): void
/**
* # Panics
*
* * File extension is invalid * * File extension is invalid
* * Serde JSON serialization * * Serde JSON serialization
*/ */

View file

@ -252,7 +252,8 @@ if (!nativeBinding) {
throw new Error(`Failed to load native binding`) throw new Error(`Failed to load native binding`)
} }
const { parseSync, parseAsync } = nativeBinding const { parseWithoutReturn, parseSync, parseAsync } = nativeBinding
module.exports.parseWithoutReturn = parseWithoutReturn
module.exports.parseSync = parseSync module.exports.parseSync = parseSync
module.exports.parseAsync = parseAsync module.exports.parseAsync = parseAsync

View file

@ -6,7 +6,7 @@ use miette::NamedSource;
use napi_derive::napi; use napi_derive::napi;
use oxc_allocator::Allocator; use oxc_allocator::Allocator;
pub use oxc_ast::ast::Program; pub use oxc_ast::ast::Program;
use oxc_parser::Parser; use oxc_parser::{Parser, ParserReturn};
use oxc_span::SourceType; use oxc_span::SourceType;
/// Babel Parser Options /// Babel Parser Options
@ -22,18 +22,15 @@ pub struct ParserOptions {
#[napi(object)] #[napi(object)]
pub struct ParseResult { pub struct ParseResult {
pub program: serde_json::Value, pub program: String,
pub errors: Vec<String>, pub errors: Vec<String>,
} }
/// # Panics fn parse<'a>(
/// * File extension is invalid allocator: &'a Allocator,
/// * Serde JSON serialization source_text: &'a str,
#[allow(clippy::needless_pass_by_value)] options: &ParserOptions,
#[napi] ) -> ParserReturn<'a> {
pub fn parse_sync(source_text: String, options: Option<ParserOptions>) -> ParseResult {
let options = options.unwrap_or_default();
let source_type = options let source_type = options
.source_filename .source_filename
.as_ref() .as_ref()
@ -44,10 +41,36 @@ pub fn parse_sync(source_text: String, options: Option<ParserOptions>) -> ParseR
Some("module") => source_type.with_module(true), Some("module") => source_type.with_module(true),
_ => source_type, _ => source_type,
}; };
Parser::new(allocator, source_text, source_type).parse()
}
/// Parse without returning anything.
/// This is for benchmark purposes such as measuring napi communication overhead.
///
/// # Panics
///
/// * File extension is invalid
/// * Serde JSON serialization
#[allow(clippy::needless_pass_by_value)]
#[napi]
pub fn parse_without_return(source_text: String, options: Option<ParserOptions>) {
let options = options.unwrap_or_default();
let allocator = Allocator::default();
parse(&allocator, &source_text, &options);
}
/// # Panics
///
/// * File extension is invalid
/// * Serde JSON serialization
#[allow(clippy::needless_pass_by_value)]
#[napi]
pub fn parse_sync(source_text: String, options: Option<ParserOptions>) -> ParseResult {
let options = options.unwrap_or_default();
let allocator = Allocator::default(); let allocator = Allocator::default();
let ret = Parser::new(&allocator, &source_text, source_type).parse(); let ret = parse(&allocator, &source_text, &options);
let program = serde_json::to_value(&ret.program).unwrap(); let program = serde_json::to_string(&ret.program).unwrap();
let errors = if ret.errors.is_empty() { let errors = if ret.errors.is_empty() {
vec![] vec![]
@ -60,10 +83,12 @@ pub fn parse_sync(source_text: String, options: Option<ParserOptions>) -> ParseR
.map(|error| format!("{error:?}")) .map(|error| format!("{error:?}"))
.collect() .collect()
}; };
ParseResult { program, errors } ParseResult { program, errors }
} }
/// # Panics /// # Panics
///
/// * Tokio crashes /// * Tokio crashes
#[allow(clippy::needless_pass_by_value)] #[allow(clippy::needless_pass_by_value)]
#[napi] #[napi]