Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 5 additions & 4 deletions crates/oxc_napi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ doctest = false
crate-type = ["lib", "cdylib"]

[dependencies]
oxc_ast = { workspace = true }
oxc_ast_visit = { workspace = true, features = ["serialize"] }
oxc_diagnostics = { workspace = true }
oxc_syntax = { workspace = true }

napi = { workspace = true }
napi-derive = { workspace = true }
oxc_diagnostics = { workspace = true }

[build-dependencies]
napi-build = { workspace = true }

[package.metadata.cargo-shear]
ignored = ["napi"]
11 changes: 11 additions & 0 deletions crates/oxc_napi/src/comment.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use napi_derive::napi;

#[derive(Debug, Clone)]
#[napi(object)]
pub struct Comment {
#[napi(ts_type = "'Line' | 'Block'")]
pub r#type: String,
pub value: String,
pub start: u32,
pub end: u32,
}
68 changes: 68 additions & 0 deletions crates/oxc_napi/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use napi_derive::napi;

use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};

#[napi(object)]
pub struct OxcError {
pub severity: Severity,
pub message: String,
pub labels: Vec<ErrorLabel>,
pub help_message: Option<String>,
}

impl OxcError {
pub fn new(message: String) -> Self {
Self { severity: Severity::Error, message, labels: vec![], help_message: None }
}
}

impl From<OxcDiagnostic> for OxcError {
fn from(diagnostic: OxcDiagnostic) -> Self {
let labels = diagnostic
.labels
.as_ref()
.map(|labels| labels.iter().map(ErrorLabel::from).collect::<Vec<_>>())
.unwrap_or_default();
Self {
severity: Severity::from(diagnostic.severity),
message: diagnostic.message.to_string(),
labels,
help_message: diagnostic.help.as_ref().map(ToString::to_string),
}
}
}

#[napi(object)]
pub struct ErrorLabel {
pub message: Option<String>,
pub start: u32,
pub end: u32,
}

impl From<&LabeledSpan> for ErrorLabel {
#[expect(clippy::cast_possible_truncation)]
fn from(label: &LabeledSpan) -> Self {
Self {
message: label.label().map(ToString::to_string),
start: label.offset() as u32,
end: (label.offset() + label.len()) as u32,
}
}
}

#[napi(string_enum)]
pub enum Severity {
Error,
Warning,
Advice,
}

impl From<oxc_diagnostics::Severity> for Severity {
fn from(value: oxc_diagnostics::Severity) -> Self {
match value {
oxc_diagnostics::Severity::Error => Self::Error,
oxc_diagnostics::Severity::Warning => Self::Warning,
oxc_diagnostics::Severity::Advice => Self::Advice,
}
}
}
118 changes: 54 additions & 64 deletions crates/oxc_napi/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,68 +1,58 @@
use napi_derive::napi;

use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};

#[napi(object)]
pub struct OxcError {
pub severity: Severity,
pub message: String,
pub labels: Vec<ErrorLabel>,
pub help_message: Option<String>,
}

impl OxcError {
pub fn new(message: String) -> Self {
Self { severity: Severity::Error, message, labels: vec![], help_message: None }
}
}

impl From<OxcDiagnostic> for OxcError {
fn from(diagnostic: OxcDiagnostic) -> Self {
let labels = diagnostic
.labels
.as_ref()
.map(|labels| labels.iter().map(ErrorLabel::from).collect::<Vec<_>>())
.unwrap_or_default();
Self {
severity: Severity::from(diagnostic.severity),
message: diagnostic.message.to_string(),
labels,
help_message: diagnostic.help.as_ref().map(ToString::to_string),
}
}
}

#[napi(object)]
pub struct ErrorLabel {
pub message: Option<String>,
pub start: u32,
pub end: u32,
}

impl From<&LabeledSpan> for ErrorLabel {
#[expect(clippy::cast_possible_truncation)]
fn from(label: &LabeledSpan) -> Self {
Self {
message: label.label().map(ToString::to_string),
start: label.offset() as u32,
end: (label.offset() + label.len()) as u32,
mod comment;
mod error;

pub use comment::*;
pub use error::*;

use oxc_ast::{CommentKind, ast::Program};
use oxc_ast_visit::utf8_to_utf16::Utf8ToUtf16;
use oxc_syntax::module_record::ModuleRecord;

/// Convert spans to UTF-16
pub fn convert_utf8_to_utf16(
source_text: &str,
program: &mut Program,
module_record: &mut ModuleRecord,
errors: &mut Vec<OxcError>,
) -> Vec<Comment> {
let span_converter = Utf8ToUtf16::new(source_text);
span_converter.convert_program(program);

// Convert comments
let mut offset_converter = span_converter.converter();
let comments = program
.comments
.iter()
.map(|comment| {
let value = comment.content_span().source_text(source_text).to_string();
let mut span = comment.span;
if let Some(converter) = offset_converter.as_mut() {
converter.convert_span(&mut span);
}
Comment {
r#type: match comment.kind {
CommentKind::Line => String::from("Line"),
CommentKind::Block => String::from("Block"),
},
value,
start: span.start,
end: span.end,
}
})
.collect::<Vec<_>>();

// Convert spans in module record to UTF-16
span_converter.convert_module_record(module_record);

// Convert spans in errors to UTF-16
if let Some(mut converter) = span_converter.converter() {
for error in errors {
for label in &mut error.labels {
converter.convert_offset(&mut label.start);
converter.convert_offset(&mut label.end);
}
}
}
}

#[napi(string_enum)]
pub enum Severity {
Error,
Warning,
Advice,
}

impl From<oxc_diagnostics::Severity> for Severity {
fn from(value: oxc_diagnostics::Severity) -> Self {
match value {
oxc_diagnostics::Severity::Error => Self::Error,
oxc_diagnostics::Severity::Warning => Self::Warning,
oxc_diagnostics::Severity::Advice => Self::Advice,
}
}
comments
}
48 changes: 4 additions & 44 deletions napi/parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,18 @@ use napi_derive::napi;

use oxc::{
allocator::Allocator,
ast::CommentKind,
ast_visit::utf8_to_utf16::Utf8ToUtf16,
parser::{ParseOptions, Parser, ParserReturn},
semantic::SemanticBuilder,
span::SourceType,
};
use oxc_napi::OxcError;
use oxc_napi::{OxcError, convert_utf8_to_utf16};

mod convert;
mod raw_transfer;
mod raw_transfer_types;
mod types;
pub use raw_transfer::{get_buffer_offset, parse_sync_raw, raw_transfer_supported};
pub use types::{Comment, EcmaScriptModule, ParseResult, ParserOptions};
pub use types::{EcmaScriptModule, ParseResult, ParserOptions};

mod generated {
// Note: We intentionally don't import `generated/derive_estree.rs`. It's not needed.
Expand Down Expand Up @@ -100,46 +98,8 @@ fn parse_with_return(filename: &str, source_text: String, options: &ParserOption
errors.extend(semantic_ret.errors.into_iter().map(OxcError::from));
}

// Convert spans to UTF-16
let span_converter = Utf8ToUtf16::new(&source_text);
span_converter.convert_program(&mut program);

// Convert comments
let mut offset_converter = span_converter.converter();
let comments = program
.comments
.iter()
.map(|comment| {
let value = comment.content_span().source_text(&source_text).to_string();
let mut span = comment.span;
if let Some(converter) = offset_converter.as_mut() {
converter.convert_span(&mut span);
}

Comment {
r#type: match comment.kind {
CommentKind::Line => String::from("Line"),
CommentKind::Block => String::from("Block"),
},
value,
start: span.start,
end: span.end,
}
})
.collect::<Vec<_>>();

// Convert spans in module record to UTF-16
span_converter.convert_module_record(&mut module_record);

// Convert spans in errors to UTF-16
if let Some(mut converter) = span_converter.converter() {
for error in &mut errors {
for label in &mut error.labels {
converter.convert_offset(&mut label.start);
converter.convert_offset(&mut label.end);
}
}
}
let comments =
convert_utf8_to_utf16(&source_text, &mut program, &mut module_record, &mut errors);

let program = match ast_type {
AstType::JavaScript => program.to_estree_js_json(),
Expand Down
11 changes: 1 addition & 10 deletions napi/parser/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::mem;

use napi_derive::napi;

use oxc_napi::OxcError;
use oxc_napi::{Comment, OxcError};

#[napi(object)]
#[derive(Default)]
Expand Down Expand Up @@ -70,15 +70,6 @@ impl ParseResult {
}
}

#[napi(object)]
pub struct Comment {
#[napi(ts_type = "'Line' | 'Block'")]
pub r#type: String,
pub value: String,
pub start: u32,
pub end: u32,
}

#[napi(object)]
#[derive(Default)]
pub struct EcmaScriptModule {
Expand Down
17 changes: 2 additions & 15 deletions napi/playground/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ export declare class Oxc {
prettierFormattedText: string
prettierIrText: string
constructor()
getDiagnostics2(): Array<OxcError>
getDiagnostics(): Array<OxcDiagnostic>
getDiagnostics(): Array<OxcError>
getComments(): Array<Comment>
/**
* # Errors
Expand All @@ -23,17 +22,12 @@ export declare class Oxc {
}

export interface Comment {
type: CommentType
type: 'Line' | 'Block'
value: string
start: number
end: number
}

export declare const enum CommentType {
Line = 0,
Block = 1
}

export interface ErrorLabel {
message?: string
start: number
Expand All @@ -60,13 +54,6 @@ export interface OxcControlFlowOptions {
verbose?: boolean
}

export interface OxcDiagnostic {
start: number
end: number
severity: string
message: string
}

export interface OxcError {
severity: Severity
message: string
Expand Down
1 change: 0 additions & 1 deletion napi/playground/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -371,5 +371,4 @@ if (!nativeBinding) {
}

module.exports.Oxc = nativeBinding.Oxc
module.exports.CommentType = nativeBinding.CommentType
module.exports.Severity = nativeBinding.Severity
1 change: 0 additions & 1 deletion napi/playground/playground.wasi-browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,4 @@ const {
},
})
export const Oxc = __napiModule.exports.Oxc
export const CommentType = __napiModule.exports.CommentType
export const Severity = __napiModule.exports.Severity
1 change: 0 additions & 1 deletion napi/playground/playground.wasi.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,4 @@ const { instance: __napiInstance, module: __wasiModule, napiModule: __napiModule
})

module.exports.Oxc = __napiModule.exports.Oxc
module.exports.CommentType = __napiModule.exports.CommentType
module.exports.Severity = __napiModule.exports.Severity
Loading
Loading