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
11 changes: 1 addition & 10 deletions tasks/ast_codegen/src/fmt.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
use std::{
path::PathBuf,
process::{Command, Stdio},
};
use std::process::Command;

use lazy_static::lazy_static;
use proc_macro2::TokenStream;
use regex::{Captures, Regex, Replacer};
use syn::parse_file;

use crate::Result;

static INSERT_MACRO_IDENT: &str = "insert";
static INSERT_MACRO_IDENT_LEN: usize = INSERT_MACRO_IDENT.len();

static ENDL_MACRO_IDENT: &str = "endl";
static ENDL_MACRO_IDENT_LEN: usize = ENDL_MACRO_IDENT.len();

static WHITE_SPACES: &str = " ";

struct InsertReplacer;
Expand Down
18 changes: 13 additions & 5 deletions tasks/ast_codegen/src/generators/ast_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ use std::{borrow::Cow, collections::HashMap};
use convert_case::{Case, Casing};
use itertools::Itertools;
use lazy_static::lazy_static;
use proc_macro2::{TokenStream, TokenTree};
use proc_macro2::TokenStream;
use quote::{format_ident, quote, ToTokens};
use syn::{
parse_quote, punctuated::Punctuated, AngleBracketedGenericArguments, Attribute, Expr, Field,
FnArg, GenericArgument, GenericParam, Ident, ImplItemFn, Lit, Meta, MetaNameValue, PatLit,
PatType, PathArguments, PredicateType, Token, Type, TypePath, Variant, WhereClause,
parse_quote, punctuated::Punctuated, AngleBracketedGenericArguments, Attribute, Expr,
GenericArgument, Ident, Lit, Meta, MetaNameValue, PathArguments, Token, Type, TypePath,
Variant,
};

use crate::{
generators::generated_header,
output,
schema::{Inherit, REnum, RStruct, RType},
util::{TypeAnalyzeResult, TypeExt, TypeIdentResult, TypeWrapper},
CodegenCtx, Generator, GeneratorOutput, TypeRef,
Expand All @@ -38,7 +39,7 @@ impl Generator for AstBuilderGenerator {
let header = generated_header!();

GeneratorOutput::Stream((
"ast_builder",
output(crate::AST_CRATE, "ast_builder.rs"),
quote! {
#header
insert!("#![allow(clippy::default_trait_access, clippy::too_many_arguments, clippy::fn_params_excessive_bools)]");
Expand Down Expand Up @@ -318,6 +319,8 @@ fn generate_struct_builder_fn(ty: &RStruct, ctx: &CodegenCtx) -> TokenStream {
}
}

// TODO: remove me
#[allow(dead_code)]
#[derive(Debug)]
struct Param {
is_default: bool,
Expand Down Expand Up @@ -425,6 +428,8 @@ impl<'p> DocComment<'p> {
/// Add a description section made up of multiple lines.
///
/// Each line will be turned into its own paragraph.
// TODO: remove me
#[allow(dead_code)]
pub fn with_description_lines<L, S>(mut self, description: L) -> Self
where
S: Into<Cow<'static, str>>,
Expand Down Expand Up @@ -523,6 +528,9 @@ fn get_doc_comment(attrs: &[Attribute]) -> Option<String> {
_ => None,
})
}

// TODO: remove me
#[allow(dead_code)]
fn get_enum_params(enum_: &REnum, ctx: &CodegenCtx) -> Vec<Param> {
let as_type = enum_.as_type();
let inner_type = match &as_type {
Expand Down
4 changes: 2 additions & 2 deletions tasks/ast_codegen/src/generators/ast_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use quote::quote;
use syn::{parse_quote, Arm, Ident, Type, Variant};

use crate::{
markers::get_visit_markers, schema::RType, util::TypeExt, CodegenCtx, Generator,
markers::get_visit_markers, output, schema::RType, util::TypeExt, CodegenCtx, Generator,
GeneratorOutput, TypeRef,
};

Expand Down Expand Up @@ -163,7 +163,7 @@ impl Generator for AstKindGenerator {
let header = generated_header!();

GeneratorOutput::Stream((
"ast_kind",
output(crate::AST_CRATE, "ast_kind.rs"),
quote! {
#header

Expand Down
8 changes: 3 additions & 5 deletions tasks/ast_codegen/src/generators/impl_get_span.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
use std::collections::HashMap;

use itertools::Itertools;
use lazy_static::lazy_static;
use proc_macro2::TokenStream;
use quote::quote;
use syn::{parse_quote, Attribute, Variant};
use syn::Variant;

use crate::{
output,
schema::{REnum, RStruct, RType},
CodegenCtx, Generator, GeneratorOutput,
};
Expand Down Expand Up @@ -37,7 +35,7 @@ impl Generator for ImplGetSpanGenerator {
let header = generated_header!();

GeneratorOutput::Stream((
"span",
output(crate::AST_CRATE, "span.rs"),
quote! {
#header
insert!("#![allow(clippy::match_same_arms)]");
Expand Down
37 changes: 15 additions & 22 deletions tasks/ast_codegen/src/generators/visit.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,20 @@
use std::{
borrow::Cow,
collections::{HashMap, HashSet},
iter::Cloned,
};
use std::{borrow::Cow, collections::HashMap};

use convert_case::{Case, Casing};
use itertools::Itertools;
use proc_macro2::{TokenStream, TokenTree};
use proc_macro2::TokenStream;
use quote::{format_ident, quote, ToTokens};
use syn::{
parenthesized,
parse::{Parse, ParseStream},
parse2, parse_quote,
punctuated::Punctuated,
spanned::Spanned,
token::Paren,
Arm, Attribute, Expr, Field, GenericArgument, Ident, Meta, MetaNameValue, Path, PathArguments,
Token, Type, Variant,
};
use syn::{parse_quote, Ident};

use crate::{
generators::{ast_kind::BLACK_LIST as KIND_BLACK_LIST, insert},
markers::{
get_scope_attr, get_scope_markers, get_visit_markers, ScopeMarkers, VisitArg, VisitArgs,
VisitMarkers,
get_scope_attr, get_scope_markers, get_visit_markers, ScopeMarkers, VisitArg, VisitMarkers,
},
output,
schema::{Inherit, REnum, RStruct, RType},
util::{StrExt, TokenStreamExt, TypeExt, TypeIdentResult, TypeWrapper},
CodegenCtx, Generator, GeneratorOutput, Result, TypeRef,
util::{StrExt, TokenStreamExt, TypeExt, TypeWrapper},
CodegenCtx, Generator, GeneratorOutput, TypeRef,
};

use super::generated_header;
Expand All @@ -41,7 +28,10 @@ impl Generator for VisitGenerator {
}

fn generate(&mut self, ctx: &CodegenCtx) -> GeneratorOutput {
GeneratorOutput::Stream(("visit", generate_visit::<false>(ctx)))
GeneratorOutput::Stream((
output(crate::AST_CRATE, "visit.rs"),
generate_visit::<false>(ctx),
))
}
}

Expand All @@ -51,7 +41,10 @@ impl Generator for VisitMutGenerator {
}

fn generate(&mut self, ctx: &CodegenCtx) -> GeneratorOutput {
GeneratorOutput::Stream(("visit_mut", generate_visit::<true>(ctx)))
GeneratorOutput::Stream((
output(crate::AST_CRATE, "visit_mut.rs"),
generate_visit::<true>(ctx),
))
}
}

Expand Down
18 changes: 9 additions & 9 deletions tasks/ast_codegen/src/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ use syn::parse_quote;

use super::{CodegenCtx, Cow, Inherit, Itertools, RType, Result};

pub trait Linker<'a> {
fn link(&'a self, linker: impl FnMut(&mut RType, &'a Self) -> Result<bool>) -> Result<&'a ()>;
pub trait Linker: Sized {
fn link(self, linker: impl FnMut(&mut RType, &Self) -> Result<bool>) -> Result<Self>;
}

pub trait Unresolved {
fn unresolved(&self) -> bool;

// TODO: remove me
#[allow(dead_code)]
fn resolved(&self) -> bool {
!self.unresolved()
}
Expand All @@ -27,11 +30,8 @@ impl Unresolved for Vec<Inherit> {
}
}

impl<'a> Linker<'a> for CodegenCtx {
fn link(
&'a self,
mut linker: impl FnMut(&mut RType, &'a Self) -> Result<bool>,
) -> Result<&'a ()> {
impl Linker for CodegenCtx {
fn link(self, mut linker: impl FnMut(&mut RType, &Self) -> Result<bool>) -> Result<Self> {
// we sort by `TypeId` so we always have the same ordering as how it is written in the rust.
let mut unresolved = self
.ident_table
Expand All @@ -45,13 +45,13 @@ impl<'a> Linker<'a> for CodegenCtx {

let val = &mut self.ty_table[next_id].borrow_mut();

if !linker(val, self)? {
if !linker(val, &self)? {
// for now we don't have entangled dependencies so we just add unresolved item back
// to the list so we revisit it again at the end.
unresolved.push_front(next);
}
}
Ok(&())
Ok(self)
}
}

Expand Down
56 changes: 24 additions & 32 deletions tasks/ast_codegen/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// TODO: remove me please!
#![allow(dead_code, unused_imports)]
const AST_CRATE: &str = "crates/oxc_ast";

mod defs;
mod fmt;
mod generators;
Expand All @@ -8,15 +8,7 @@ mod markers;
mod schema;
mod util;

use std::{
borrow::Cow,
cell::RefCell,
collections::HashMap,
fs,
io::{Read, Write},
path::PathBuf,
rc::Rc,
};
use std::{borrow::Cow, cell::RefCell, collections::HashMap, io::Read, path::PathBuf, rc::Rc};

use bpaf::{Bpaf, Parser};
use fmt::{cargo_fmt, pprint};
Expand Down Expand Up @@ -50,15 +42,19 @@ trait Generator {
fn generate(&mut self, ctx: &CodegenCtx) -> GeneratorOutput;
}

type GeneratedStream = (&'static str, TokenStream);
type GeneratedStream = (/* output path */ PathBuf, TokenStream);

// TODO: remove me
#[allow(dead_code)]
#[derive(Debug, Clone)]
enum GeneratorOutput {
None,
Info(String),
Stream(GeneratedStream),
}

// TODO: remove me
#[allow(dead_code)]
impl GeneratorOutput {
pub fn is_none(&self) -> bool {
matches!(self, Self::None)
Expand Down Expand Up @@ -102,9 +98,9 @@ impl GeneratorOutput {
}

struct CodegenCtx {
modules: Vec<Module>,
ty_table: TypeTable,
ident_table: IdentTable,
schema: Vec<Schema>,
}

struct CodegenResult {
Expand All @@ -114,7 +110,7 @@ struct CodegenResult {
}

impl CodegenCtx {
fn new(mods: Vec<Module>) -> Self {
fn new(mods: Vec<Module>) -> Result<Self> {
// worst case len
let len = mods.iter().fold(0, |acc, it| acc + it.items.len());
let defs = mods.iter().flat_map(|it| it.items.iter());
Expand All @@ -129,7 +125,11 @@ impl CodegenCtx {
ident_table.insert(ident, type_id);
}
}
Self { modules: mods, ty_table, ident_table }

let mut me = Self { ty_table, ident_table, schema: Vec::default() }.link(linker)?;
let schema = mods.into_iter().map(Module::build).collect::<Result<Vec<_>>>()?;
_ = std::mem::replace(&mut me.schema, schema);
Ok(me)
}

fn find(&self, key: &TypeName) -> Option<TypeRef> {
Expand Down Expand Up @@ -171,44 +171,32 @@ impl AstCodegen {
.map_ok(Module::analyze)
.collect::<Result<Result<Vec<_>>>>()??;

let ctx = CodegenCtx::new(modules);
ctx.link(linker)?;
let ctx = CodegenCtx::new(modules)?;

let outputs = self
.generators
.into_iter()
.map(|mut gen| (gen.name(), gen.generate(&ctx)))
.collect_vec();

let schema = ctx.modules.into_iter().map(Module::build).collect::<Result<Vec<_>>>()?;
Ok(CodegenResult { schema, outputs })
Ok(CodegenResult { outputs, schema: ctx.schema })
}
}

const AST_ROOT_DIR: &str = "crates/oxc_ast";

fn files() -> impl std::iter::Iterator<Item = String> {
fn path(path: &str) -> String {
format!("{AST_ROOT_DIR}/src/ast/{path}.rs")
format!("{AST_CRATE}/src/ast/{path}.rs")
}

vec![path("literal"), path("js"), path("ts"), path("jsx")].into_iter()
}

fn output_dir() -> std::io::Result<String> {
let dir = format!("{AST_ROOT_DIR}/src/generated");
fs::create_dir_all(&dir)?;
Ok(dir)
}

fn write_generated_streams(
streams: impl IntoIterator<Item = GeneratedStream>,
) -> std::io::Result<()> {
let output_dir = output_dir()?;
for (name, stream) in streams {
for (path, stream) in streams {
let content = pprint(&stream);
let path = format!("{output_dir}/{name}.rs");
write_all_to(content.as_bytes(), path)?;
write_all_to(content.as_bytes(), path.into_os_string().to_str().unwrap())?;
}
Ok(())
}
Expand Down Expand Up @@ -257,3 +245,7 @@ fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {

Ok(())
}

fn output(krate: &str, path: &str) -> PathBuf {
std::path::PathBuf::from_iter(vec![krate, "src", "generated", path])
}
5 changes: 2 additions & 3 deletions tasks/ast_codegen/src/markers.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use proc_macro2::{Delimiter, TokenStream, TokenTree};
use proc_macro2::TokenStream;
use syn::{
ext::IdentExt,
parenthesized,
parse::{Parse, ParseStream},
parse2,
punctuated::Punctuated,
spanned::Spanned,
token::{self, Brace, Bracket, Paren},
Attribute, Expr, Ident, MacroDelimiter, Meta, MetaList, MetaNameValue, Token,
token, Attribute, Expr, Ident, Meta, MetaNameValue, Token,
};

use crate::util::NormalizeError;
Expand Down
Loading