Skip to content

Commit

Permalink
feat(ast_codegen, span): process SourceType through ast_codegen. (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
rzvxa committed Aug 6, 2024
1 parent 3f3cb62 commit 125c5fd
Show file tree
Hide file tree
Showing 12 changed files with 130 additions and 63 deletions.
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

0 comments on commit 125c5fd

Please sign in to comment.