Skip to content

Commit

Permalink
Merge pull request #2049 from fzyzcjy/feat/12183
Browse files Browse the repository at this point in the history
Refactor to extract early_generator between high-level intermediate representation and mid-level intermediate representation
  • Loading branch information
fzyzcjy authored Jun 8, 2024
2 parents 4fc3123 + 40308fd commit 5f2065e
Show file tree
Hide file tree
Showing 19 changed files with 147 additions and 136 deletions.
74 changes: 43 additions & 31 deletions frb_codegen/src/library/codegen/dumper/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,36 +14,56 @@ use strum::IntoEnumIterator;

pub(super) mod internal_config;

pub(crate) struct Dumper<'a>(pub &'a DumperInternalConfig);
#[derive(Clone)]
pub(crate) struct Dumper<'a> {
config: &'a DumperInternalConfig,
content: Option<ConfigDumpContent>,
name_prefix: String,
}

impl Dumper<'_> {
pub(crate) fn dump<T: Serialize>(
&self,
content: ConfigDumpContent,
name: &str,
data: &T,
) -> anyhow::Result<()> {
if !self.is_enabled(content) {
impl<'a> Dumper<'a> {
pub(crate) fn new(config: &'a DumperInternalConfig) -> Self {
Self {
config,
content: None,
name_prefix: "".to_string(),
}
}

pub(crate) fn with_content(&self, content: ConfigDumpContent) -> Self {
Self {
content: Some(content),
..self.clone()
}
}

pub(crate) fn with_add_name_prefix(&self, add_name_prefix: &str) -> Self {
Self {
name_prefix: format!("{}{}", self.name_prefix, add_name_prefix),
..self.clone()
}
}

pub(crate) fn dump<T: Serialize>(&self, name: &str, data: &T) -> anyhow::Result<()> {
if !self.is_enabled() {
return Ok(());
}

self.dump_str(content, name, &serde_json::to_string_pretty(data)?)
self.dump_str(name, &serde_json::to_string_pretty(data)?)
}

pub(crate) fn dump_path_texts(
&self,
content: ConfigDumpContent,
partial_name: &str,
path_texts: &PathTexts,
base_dir: &Path,
) -> anyhow::Result<()> {
if !self.is_enabled(content) {
if !self.is_enabled() {
return Ok(());
}

for path_text in path_texts.0.iter() {
self.dump_str(
content,
&format!(
"{partial_name}/{}",
path_to_string(
Expand All @@ -59,18 +79,16 @@ impl Dumper<'_> {

pub(crate) fn dump_acc(
&self,
content: ConfigDumpContent,
partial_name: &str,
extension: &str,
acc: &Acc<Option<String>>,
) -> anyhow::Result<()> {
if !self.is_enabled(content) {
if !self.is_enabled() {
return Ok(());
}

for target in TargetOrCommon::iter() {
self.dump_str(
content,
&format!("{partial_name}/{target}.{extension}"),
&acc[target].clone().unwrap_or_default(),
)?;
Expand All @@ -79,27 +97,21 @@ impl Dumper<'_> {
Ok(())
}

pub(crate) fn dump_str(
&self,
content: ConfigDumpContent,
name: &str,
str: &str,
) -> anyhow::Result<()> {
if !self.is_enabled(content) {
pub(crate) fn dump_str(&self, partial_name: &str, text: &str) -> anyhow::Result<()> {
if !self.is_enabled() {
return Ok(());
}

let path = self
.0
.dump_directory
.join(content.to_string().to_case(Case::Snake))
.join(name);
let name = format!("{}{}", self.name_prefix, partial_name);
let path = (self.config.dump_directory)
.join(self.content.unwrap().to_string().to_case(Case::Snake))
.join(&name);
debug!("Dumping {name} into {path:?}");

create_dir_all_and_write(path, str)
create_dir_all_and_write(path, text)
}

fn is_enabled(&self, content: ConfigDumpContent) -> bool {
self.0.dump_contents.contains(&content)
fn is_enabled(&self) -> bool {
self.config.dump_contents.contains(&self.content.unwrap())
}
}
10 changes: 5 additions & 5 deletions frb_codegen/src/library/codegen/generator/api_dart/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ pub(crate) fn generate(
dumper: &Dumper,
) -> Result<GeneratorApiDartOutput> {
let spec = spec_generator::generate(mir_pack, config, dumper)?;
dumper.dump(ConfigDumpContent::GeneratorSpec, "api_dart.json", &spec)?;

(dumper.with_content(ConfigDumpContent::GeneratorSpec)).dump("api_dart.json", &spec)?;

let text = text_generator::generate(&spec, config)?;
dumper.dump_path_texts(
ConfigDumpContent::GeneratorText,
(dumper.with_content(ConfigDumpContent::GeneratorText)).dump_path_texts(
"api_dart",
&text.output_texts,
&config.dart_decl_base_output_path,
Expand Down Expand Up @@ -85,13 +85,13 @@ mod tests {
let internal_config = InternalConfig::parse(&config, &MetaConfig { watch: false })?;
let mir_pack = crate::codegen::parser::parse(
&internal_config.parser,
&Dumper(&Default::default()),
&Dumper::new(&Default::default()),
&GeneratorProgressBarPack::new(),
)?;
let actual = generate(
&mir_pack,
&internal_config.generator.api_dart,
&Dumper(&Default::default()),
&Dumper::new(&Default::default()),
)?;

let output_texts = actual.output_texts;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,8 @@ pub(crate) fn generate(
let cache = MirPackComputedCache::compute(mir_pack);
let context = ApiDartGeneratorContext { mir_pack, config };

dumper.dump(
GeneratorInfo,
"api_dart.json",
&generate_dump_info(&cache, context),
)?;
(dumper.with_content(GeneratorInfo))
.dump("api_dart.json", &generate_dump_info(&cache, context))?;

let funcs_with_impl = mir_pack.funcs_with_impl();
let grouped_funcs = (funcs_with_impl.iter()).into_group_map_by(|x| x.name.namespace.clone());
Expand Down
4 changes: 2 additions & 2 deletions frb_codegen/src/library/codegen/generator/wire/c/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ pub(crate) fn generate(
rust_output_texts,
progress_bar_pack,
)?;
dumper.dump(ConfigDumpContent::GeneratorSpec, "wire_c.json", &spec)?;
(dumper.with_content(ConfigDumpContent::GeneratorSpec)).dump("wire_c.json", &spec)?;

let text = text_generator::generate(spec)?;
dumper.dump_str(ConfigDumpContent::GeneratorText, "wire_c/content.h", &text)?;
(dumper.with_content(ConfigDumpContent::GeneratorText)).dump_str("wire_c/content.h", &text)?;

Ok(GeneratorWireCOutput {
output_texts: PathTexts({
Expand Down
5 changes: 2 additions & 3 deletions frb_codegen/src/library/codegen/generator/wire/dart/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,10 @@ pub(crate) fn generate(
dumper,
progress_bar_pack,
)?;
dumper.dump(ConfigDumpContent::GeneratorSpec, "wire_dart.json", &spec)?;
(dumper.with_content(ConfigDumpContent::GeneratorSpec)).dump("wire_dart.json", &spec)?;

let text = text_generator::generate(&spec, context.config)?;
dumper.dump_acc(
ConfigDumpContent::GeneratorText,
(dumper.with_content(ConfigDumpContent::GeneratorText)).dump_acc(
"wire_dart",
"dart",
&text.text.clone().map(|x, _| x.map(|x| x.all_code())),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,8 @@ pub(crate) fn generate(
) -> anyhow::Result<WireDartOutputSpec> {
let cache = MirPackComputedCache::compute(context.mir_pack);

dumper.dump(
GeneratorInfo,
"wire_dart.json",
&generate_dump_info(&cache, context),
)?;
(dumper.with_content(GeneratorInfo))
.dump("wire_dart.json", &generate_dump_info(&cache, context))?;

Ok(WireDartOutputSpec {
misc: misc::generate(
Expand Down
5 changes: 2 additions & 3 deletions frb_codegen/src/library/codegen/generator/wire/rust/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,10 @@ pub(crate) fn generate(
dumper: &Dumper,
) -> anyhow::Result<GeneratorWireRustOutput> {
let spec = spec_generator::generate(context, dumper)?;
dumper.dump(ConfigDumpContent::GeneratorSpec, "wire_rust.json", &spec)?;
(dumper.with_content(ConfigDumpContent::GeneratorSpec)).dump("wire_rust.json", &spec)?;

let text = text_generator::generate(&spec, context.config)?;
dumper.dump_acc(
ConfigDumpContent::GeneratorText,
(dumper.with_content(ConfigDumpContent::GeneratorText)).dump_acc(
"wire_rust",
"rs",
&text.text,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,8 @@ pub(super) fn generate(
) -> anyhow::Result<WireRustOutputSpec> {
let cache = MirPackComputedCache::compute(context.mir_pack);

dumper.dump(
GeneratorInfo,
"wire_rust.json",
&generate_dump_info(&cache, context),
)?;
(dumper.with_content(GeneratorInfo))
.dump("wire_rust.json", &generate_dump_info(&cache, context))?;

let dart2rust = WireRustCodecEntrypoint::generate_all(context, &cache, Decode);
let rust2dart = WireRustCodecEntrypoint::generate_all(context, &cache, Encode);
Expand Down
10 changes: 7 additions & 3 deletions frb_codegen/src/library/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ pub fn generate(config: Config, meta_config: MetaConfig) -> anyhow::Result<()> {
let internal_config = InternalConfig::parse(&config, &meta_config)?;
debug!("internal_config={internal_config:?}");

let dumper = Dumper(&internal_config.dumper);
dumper.dump(ContentConfig, "config.json", &config)?;
let dumper = Dumper::new(&internal_config.dumper);
dumper
.with_content(ContentConfig)
.dump("config.json", &config)?;

controller::run(&internal_config.controller, &|| {
generate_once(&internal_config, &dumper)
Expand All @@ -38,7 +40,9 @@ pub fn generate(config: Config, meta_config: MetaConfig) -> anyhow::Result<()> {
fn generate_once(internal_config: &InternalConfig, dumper: &Dumper) -> anyhow::Result<()> {
let progress_bar_pack = GeneratorProgressBarPack::new();

dumper.dump(ContentConfig, "internal_config.json", &internal_config)?;
dumper
.with_content(ContentConfig)
.dump("internal_config.json", &internal_config)?;

preparer::prepare(&internal_config.preparer)?;

Expand Down
27 changes: 27 additions & 0 deletions frb_codegen/src/library/codegen/parser/early_generator/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
pub(crate) mod trait_impl_enum;

use crate::codegen::dumper::Dumper;
use crate::codegen::ir::hir::flat::pack::HirFlatPack;
use crate::codegen::parser::hir::flat::extra_code_injector::inject_extra_code;
use crate::codegen::parser::hir::internal_config::ParserHirInternalConfig;
use crate::codegen::parser::mir;
use crate::codegen::parser::mir::internal_config::ParserMirInternalConfig;

pub(crate) fn execute(
mut pack: HirFlatPack,
config_mir: &ParserMirInternalConfig,
dumper: &Dumper,
) -> anyhow::Result<HirFlatPack> {
let dumper_tentative_mir = dumper.with_add_name_prefix("tentative_mir/");
let tentative_mir_pack = mir::parse(config_mir, &pack, &dumper_tentative_mir)?;

let extra_code = trait_impl_enum::generate(&pack, &tentative_mir_pack)?;

inject_extra_code(
&mut pack,
&extra_code,
&(config_mir.rust_input_namespace_pack).rust_output_path_namespace,
)?;

Ok(pack)
}
Original file line number Diff line number Diff line change
@@ -1,40 +1,32 @@
use crate::codegen::ir::hir::flat::pack::HirFlatPack;
use crate::codegen::ir::hir::flat::traits::HirFlatTrait;
use crate::codegen::ir::mir::pack::MirPack;
use crate::codegen::ir::mir::trait_impl::MirTraitImpl;
use crate::codegen::ir::mir::ty::MirType;
use crate::codegen::parser::hir::flat::extra_code_injector::inject_extra_code;
use crate::codegen::parser::hir::internal_config::ParserHirInternalConfig;
use crate::codegen::parser::mir::parser::attribute::FrbAttributes;
use crate::codegen::parser::mir::parser::function::real::FUNC_PREFIX_FRB_INTERNAL_NO_IMPL;
use crate::codegen::parser::mir::parser::tentative_parse_trait_impls;
use crate::library::codegen::ir::mir::ty::MirTypeTrait;
use convert_case::{Case, Casing};
use itertools::Itertools;
use strum_macros::Display;

pub(crate) fn transform(
mut pack: HirFlatPack,
config: &ParserHirInternalConfig,
) -> anyhow::Result<HirFlatPack> {
let trait_impls = tentative_parse_trait_impls(&pack)?;

let extra_code = (pack.traits.iter())
pub(crate) fn generate(
pack: &HirFlatPack,
tentative_mir_pack: &MirPack,
) -> anyhow::Result<String> {
Ok((pack.traits.iter())
.filter(|x| {
FrbAttributes::parse(&x.attrs)
.unwrap()
.generate_implementor_enum()
})
.sorted_by_key(|x| x.name.clone())
.map(|x| generate_trait_impl_enum(x, &trait_impls))
.map(|x| generate_trait_impl_enum(x, &tentative_mir_pack.trait_impls))
.collect::<anyhow::Result<Vec<_>>>()?
.into_iter()
.join("");

let namespace = &config.rust_input_namespace_pack.rust_output_path_namespace;

inject_extra_code(&mut pack, &extra_code, namespace)?;

Ok(pack)
.join(""))
}

fn generate_trait_impl_enum(
Expand Down
24 changes: 8 additions & 16 deletions frb_codegen/src/library/codegen/parser/hir/flat/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,43 +7,35 @@ use crate::codegen::dumper::Dumper;
use crate::codegen::ir::hir::flat::pack::HirFlatPack;
use crate::codegen::ir::hir::naive_flat::pack::HirNaiveFlatPack;
use crate::codegen::parser::hir::internal_config::ParserHirInternalConfig;
use crate::codegen::ConfigDumpContent::Hir;

pub(crate) fn parse(
config: &ParserHirInternalConfig,
hir_naive_flat: HirNaiveFlatPack,
dumper: &Dumper,
) -> anyhow::Result<HirFlatPack> {
let pack = parser::pack::parse_pack(config, hir_naive_flat)?;
dump(dumper, "1_parse_pack", &pack)?;
dumper.dump("1_parse_pack", &pack)?;

let pack = transformer::filter_transformer::transform(pack, config)?;
dump(dumper, "2_filter_transformer", &pack)?;
dumper.dump("2_filter_transformer", &pack)?;

let pack = transformer::remove_not_defined_trait_transformer::transform(pack)?;
dump(dumper, "3_remove_not_defined_trait_transformer", &pack)?;
dumper.dump("3_remove_not_defined_trait_transformer", &pack)?;

let pack = transformer::copy_trait_def_to_impl_transformer::transform(pack)?;
dump(dumper, "4_copy_trait_def_to_impl_transformer", &pack)?;
dumper.dump("4_copy_trait_def_to_impl_transformer", &pack)?;

let pack = transformer::function_frb_override_transformer::transform(pack)?;
dump(dumper, "5_function_frb_override_transformer", &pack)?;
dumper.dump("5_function_frb_override_transformer", &pack)?;

let pack = transformer::merge_duplicate_transformer::transform(pack)?;
dump(dumper, "6_merge_duplicate_transformer", &pack)?;
dumper.dump("6_merge_duplicate_transformer", &pack)?;

let pack = transformer::resolve_type_alias_transformer::transform(pack)?;
dump(dumper, "7_resolve_type_alias_transformer", &pack)?;

let pack = transformer::generate_trait_impl_enum_transformer::transform(pack, config)?;
dump(dumper, "8_generate_trait_impl_enum_transformer", &pack)?;
dumper.dump("7_resolve_type_alias_transformer", &pack)?;

let pack = transformer::sort_transformer::transform(pack)?;
dump(dumper, "9_sort_transformer", &pack)?;
dumper.dump("8_sort_transformer", &pack)?;

Ok(pack)
}

fn dump(dumper: &Dumper, name: &str, pack: &HirFlatPack) -> anyhow::Result<()> {
dumper.dump(Hir, &format!("hir_flat/{name}.json"), pack)
}
Loading

0 comments on commit 5f2065e

Please sign in to comment.