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
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ jobs:
- 'crates/oxc_ast/src/generated/**' # to potentially cause CI error if generated files are edited manually
- 'crates/oxc_syntax/src/number.rs'
- 'crates/oxc_syntax/src/operator.rs'
- 'crates/oxc_span/src/source_type/types.rs'
- 'tasks/ast_codegen/src/**'

- uses: Boshen/setup-rust@main
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

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

17 changes: 17 additions & 0 deletions crates/oxc_ast/src/generated/assert_layouts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use std::mem::{align_of, offset_of, size_of};

use crate::ast::*;
use oxc_span::*;
use oxc_syntax::{number::*, operator::*};

#[cfg(target_pointer_width = "64")]
Expand Down Expand Up @@ -1139,6 +1140,14 @@ const _: () = {
assert!(align_of::<UnaryOperator>() == 1usize);
assert!(size_of::<UpdateOperator>() == 1usize);
assert!(align_of::<UpdateOperator>() == 1usize);
assert!(size_of::<SourceType>() == 4usize);
assert!(align_of::<SourceType>() == 1usize);
assert!(size_of::<Language>() == 1usize);
assert!(align_of::<Language>() == 1usize);
assert!(size_of::<ModuleKind>() == 1usize);
assert!(align_of::<ModuleKind>() == 1usize);
assert!(size_of::<LanguageVariant>() == 1usize);
assert!(align_of::<LanguageVariant>() == 1usize);
};

#[cfg(target_pointer_width = "32")]
Expand Down Expand Up @@ -2274,6 +2283,14 @@ const _: () = {
assert!(align_of::<UnaryOperator>() == 1usize);
assert!(size_of::<UpdateOperator>() == 1usize);
assert!(align_of::<UpdateOperator>() == 1usize);
assert!(size_of::<SourceType>() == 4usize);
assert!(align_of::<SourceType>() == 1usize);
assert!(size_of::<Language>() == 1usize);
assert!(align_of::<Language>() == 1usize);
assert!(size_of::<ModuleKind>() == 1usize);
assert!(align_of::<ModuleKind>() == 1usize);
assert!(size_of::<LanguageVariant>() == 1usize);
assert!(align_of::<LanguageVariant>() == 1usize);
};

#[cfg(not(any(target_pointer_width = "64", target_pointer_width = "32")))]
Expand Down
3 changes: 2 additions & 1 deletion crates/oxc_span/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ workspace = true
doctest = false

[dependencies]
oxc_allocator = { workspace = true }
oxc_allocator = { workspace = true }
oxc_ast_macros = { workspace = true }

miette = { workspace = true }
compact_str = { workspace = true }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,60 +1,11 @@
// Silence erroneous warnings from Rust Analyser for `#[derive(Tsify)]`
#![allow(non_snake_case)]

use std::path::Path;

#[cfg(feature = "serialize")]
use serde::Serialize;
#[cfg(feature = "serialize")]
use tsify::Tsify;

/// Source Type for JavaScript vs TypeScript / Script vs Module / JSX
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
#[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))]
pub struct SourceType {
/// JavaScript or TypeScript, default JavaScript
language: Language,

/// Script or Module, default Module
module_kind: ModuleKind,

/// Support JSX for JavaScript and TypeScript? default without JSX
variant: LanguageVariant,

/// Mark strict mode as always strict
/// See <https://github.com/tc39/test262/blob/main/INTERPRETING.md#strict-mode>
always_strict: bool,
}

/// JavaScript or TypeScript
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
#[cfg_attr(feature = "serialize", serde(rename_all = "lowercase"))]
pub enum Language {
JavaScript,
TypeScript,
#[cfg_attr(feature = "serialize", serde(rename = "typescriptDefinition"))]
TypeScriptDefinition,
}
mod types;

/// Script or Module
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
#[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))]
pub enum ModuleKind {
Script,
Module,
}
use std::path::Path;

/// JSX for JavaScript and TypeScript
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
#[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))]
pub enum LanguageVariant {
Standard,
Jsx,
}
pub use types::*;

#[derive(Debug)]
pub struct UnknownExtension(pub String);
Expand Down
55 changes: 55 additions & 0 deletions crates/oxc_span/src/source_type/types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use oxc_ast_macros::ast;
#[cfg(feature = "serialize")]
use ::{serde::Serialize, tsify::Tsify};

/// Source Type for JavaScript vs TypeScript / Script vs Module / JSX
#[ast]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
#[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))]
pub struct SourceType {
/// JavaScript or TypeScript, default JavaScript
pub(super) language: Language,

/// Script or Module, default Module
pub(super) module_kind: ModuleKind,

/// Support JSX for JavaScript and TypeScript? default without JSX
pub(super) variant: LanguageVariant,

/// Mark strict mode as always strict
/// See <https://github.com/tc39/test262/blob/main/INTERPRETING.md#strict-mode>
pub(super) always_strict: bool,
}

/// JavaScript or TypeScript
#[ast]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
#[cfg_attr(feature = "serialize", serde(rename_all = "lowercase"))]
pub enum Language {
JavaScript = 0,
TypeScript = 1,
#[cfg_attr(feature = "serialize", serde(rename = "typescriptDefinition"))]
TypeScriptDefinition = 2,
}

/// Script or Module
#[ast]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
#[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))]
pub enum ModuleKind {
Script = 0,
Module = 1,
}

/// JSX for JavaScript and TypeScript
#[ast]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
#[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))]
pub enum LanguageVariant {
Standard = 0,
Jsx = 1,
}
15 changes: 9 additions & 6 deletions tasks/ast_codegen/src/generators/assert_layouts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ impl Generator for AssertLayouts {
endl!();

use crate::ast::*;
use oxc_span::*;
use oxc_syntax::{number::*, operator::*};


Expand Down Expand Up @@ -100,12 +101,14 @@ fn with_offsets_assertion(
) -> TokenStream {
let Some(offsets) = offsets else { return tk };

let assertions = fields.iter().zip(offsets).map(|(field, offset)| {
let field = field.name.as_ref().map(|it| format_ident!("{it}"));
quote! {
assert!(offset_of!(#ty, #field) == #offset);
}
});
let assertions = fields.iter().zip(offsets).filter(|(field, _)| field.vis.is_pub()).map(
|(field, offset)| {
let field = field.name.as_ref().map(|it| format_ident!("{it}"));
quote! {
assert!(offset_of!(#ty, #field) == #offset);
}
},
);
tk.extend(assertions);
tk
}
17 changes: 15 additions & 2 deletions tasks/ast_codegen/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const AST_CRATE: &str = "crates/oxc_ast";
const AST_SYNTAX: &str = "crates/oxc_syntax";
const AST_SPAN: &str = "crates/oxc_span";
#[allow(dead_code)]
const AST_MACROS_CRATE: &str = "crates/oxc_ast_macros";

Expand Down Expand Up @@ -252,8 +253,20 @@ fn files() -> impl std::iter::Iterator<Item = String> {
format!("{AST_SYNTAX}/src/{path}.rs")
}

vec![ast("literal"), ast("js"), ast("ts"), ast("jsx"), syntax("number"), syntax("operator")]
.into_iter()
fn span(path: &str) -> String {
format!("{AST_SPAN}/src/{path}.rs")
}

vec![
ast("literal"),
ast("js"),
ast("ts"),
ast("jsx"),
syntax("number"),
syntax("operator"),
span("source_type/types"),
]
.into_iter()
}

fn write_generated_streams(
Expand Down
1 change: 0 additions & 1 deletion tasks/ast_codegen/src/passes/calc_layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,6 @@ lazy_static! {
Cell<Option<ScopeId>>: { _ => Layout::known(4, 4, 0), },
Cell<Option<SymbolId>>: { _ => Layout::known(4, 4, 0), },
Cell<Option<ReferenceId>>: { _ => Layout::known(4, 4, 0), },
SourceType: { _ => Layout::known(4, 1, 1), },
// Unsupported: this is a `bitflags` generated type, we don't expand macros
ReferenceFlag: { _ => Layout::known(1, 1, 0), },
// Unsupported: this is a `bitflags` generated type, we don't expand macros
Expand Down
2 changes: 1 addition & 1 deletion tasks/ast_codegen/src/rust_ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ pub fn analyze(ast_ref: &AstRef) -> Result<()> {
// AST without visit!
ast_ref.borrow_mut().set_ast(true)?;
}
Some(AstAttr::None) => return Err(String::from("All `enums` and `structs` defined in the source of truth should be marked with an `#[ast]` attribute!")),
Some(AstAttr::None) => return Err(format!("All `enums` and `structs` defined in the source of truth should be marked with an `#[ast]` attribute(missing `#[ast]` on '{:?}')", ast_ref.borrow().ident())),
None => { /* unrelated items like `use`, `type` and `macro` definitions */ }
}

Expand Down
25 changes: 25 additions & 0 deletions tasks/ast_codegen/src/schema/defs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,36 @@ pub struct InheritDef {
pub struct FieldDef {
/// `None` if unnamed
pub name: Option<String>,
pub vis: Visibility,
pub typ: TypeRef,
pub markers: InnerMarkers,
pub docs: Vec<String>,
}

#[derive(Debug, Serialize)]
pub enum Visibility {
None,
Pub,
/// rest of the restricted visibilities
Rest,
}

impl Visibility {
pub fn is_pub(&self) -> bool {
matches!(self, Self::Pub)
}
}

impl From<&syn::Visibility> for Visibility {
fn from(vis: &syn::Visibility) -> Self {
match vis {
syn::Visibility::Public(_) => Self::Pub,
syn::Visibility::Inherited => Self::None,
syn::Visibility::Restricted(_) => Self::Rest,
}
}
}

impl FieldDef {
pub fn ident(&self) -> Option<syn::Ident> {
self.name.as_ref().map(ToIdent::to_ident)
Expand Down
1 change: 1 addition & 0 deletions tasks/ast_codegen/src/schema/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ fn lower_inherit(inherit: &rust::Inherit, ctx: &crate::EarlyCtx) -> InheritDef {
fn lower_field(field: &syn::Field, ctx: &crate::EarlyCtx) -> FieldDef {
FieldDef {
name: field.ident.as_ref().map(ToString::to_string),
vis: Visibility::from(&field.vis),
typ: create_type_ref(&field.ty, ctx),
markers: parse_inner_markers(&field.attrs).unwrap(),
docs: get_docs(&field.attrs),
Expand Down