Skip to content

Commit

Permalink
Merge pull request #2037 from fzyzcjy/feat/12157
Browse files Browse the repository at this point in the history
Refactor HIR (high-level intermediate representation) ; Add `stop_on_error` configuration
  • Loading branch information
fzyzcjy authored Jun 6, 2024
2 parents 96edf24 + 0b14d07 commit 03c3f78
Show file tree
Hide file tree
Showing 244 changed files with 7,309 additions and 10,203 deletions.
4 changes: 4 additions & 0 deletions frb_codegen/src/binary/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ pub(crate) struct GenerateCommandArgsPrimary {
#[arg(long, hide = true)]
pub local: bool,

/// If having error when, for example, parsing a function, directly stop instead of continue and skip it
#[arg(long)]
pub stop_on_error: bool,

/// A list of data to be dumped. If specified without a value, defaults to all.
#[arg(long, value_enum, num_args = 0.., default_missing_values = ["config", "ir"])]
pub dump: Option<Vec<ConfigDumpContent>>,
Expand Down
31 changes: 11 additions & 20 deletions frb_codegen/src/binary/commands_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ fn compute_codegen_config_from_naive_command_args(
local: Some(args.local),
default_external_library_loader_web_prefix: args.default_external_library_loader_web_prefix,
dart_type_rename: None, // complex type, not supported on command line yet
stop_on_error: Some(args.stop_on_error),
dump: args.dump,
dump_all: Some(args.dump_all),
})
Expand All @@ -79,7 +80,6 @@ mod tests {
use crate::binary::test_utils::set_cwd_test_fixture;
use clap::Parser;
use itertools::concat;
use lib_flutter_rust_bridge_codegen::codegen::Config;
use lib_flutter_rust_bridge_codegen::utils::logs::configure_opinionated_test_logging;
use lib_flutter_rust_bridge_codegen::{codegen, if_then_some};
use serial_test::serial;
Expand All @@ -92,7 +92,7 @@ mod tests {
configure_opinionated_test_logging();
set_cwd_test_fixture("binary/commands_parser/flutter_rust_bridge_yaml")?;

let config = run_command_line::<Config, anyhow::Error>(vec!["", "generate"])?;
let config = run_command_line(vec!["", "generate"])?;
assert_eq!(config.rust_input, "crate::hello".to_string());
assert!(!config.dart3.unwrap());

Expand All @@ -105,7 +105,7 @@ mod tests {
configure_opinionated_test_logging();
set_cwd_test_fixture("binary/commands_parser/pubspec_yaml")?;

let config = run_command_line::<Config, anyhow::Error>(vec!["", "generate"])?;
let config = run_command_line(vec!["", "generate"])?;
assert_eq!(config.rust_input, "crate::hello".to_string());
assert!(!config.dart3.unwrap());

Expand All @@ -119,7 +119,7 @@ mod tests {
configure_opinionated_test_logging();
set_cwd_test_fixture("binary/commands_parser/faulty_pubspec_yaml")?;

let result = run_command_line::<Config, anyhow::Error>(vec!["", "generate"]);
let result = run_command_line(vec!["", "generate"]);
assert!(result.is_err());
assert!(result
.unwrap_err()
Expand All @@ -137,12 +137,7 @@ mod tests {
configure_opinionated_test_logging();
set_cwd_test_fixture("binary/commands_parser/config_file")?;

let config = run_command_line::<Config, anyhow::Error>(vec![
"",
"generate",
"--config-file",
"hello.yaml",
])?;
let config = run_command_line(vec!["", "generate", "--config-file", "hello.yaml"])?;
assert_eq!(config.rust_input, "crate::hello".to_string());
assert!(!config.dart3.unwrap());

Expand All @@ -154,7 +149,7 @@ mod tests {
fn test_compute_codegen_config_mode_config_file_faulty_file() -> anyhow::Result<()> {
configure_opinionated_test_logging();
set_cwd_test_fixture("binary/commands_parser/flutter_rust_bridge_yaml")?;
let result = run_command_line::<(), anyhow::Error>(vec![
let result = run_command_line(vec![
"",
"generate",
"--config-file",
Expand Down Expand Up @@ -187,22 +182,18 @@ mod tests {
"--c-output",
"hello.h",
];
let config = run_command_line::<(), anyhow::Error>(common_args.clone())
.expect("failed to parse cli args");
let config = run_command_line(common_args.clone()).expect("failed to parse cli args");
assert_eq!(config.dart3, Some(true));
assert_eq!(config.rust_input, "crate::hello".to_string());
assert_eq!(
run_command_line::<Config, anyhow::Error>(concat([
common_args.clone(),
vec!["--no-dart3"]
]))
.expect("failed to parse cli args")
.dart3,
run_command_line(concat([common_args.clone(), vec!["--no-dart3"]]))
.expect("failed to parse cli args")
.dart3,
Some(false)
);
}

fn run_command_line<T, E>(args: Vec<&'static str>) -> anyhow::Result<codegen::Config> {
fn run_command_line(args: Vec<&'static str>) -> anyhow::Result<codegen::Config> {
let cli = Cli::parse_from(args);
let args = if_then_some!(let Commands::Generate(args) = cli.command, args).unwrap();
compute_codegen_config(args.primary)
Expand Down
1 change: 1 addition & 0 deletions frb_codegen/src/library/codegen/config/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub struct Config {
pub local: Option<bool>,
pub default_external_library_loader_web_prefix: Option<String>,
pub dart_type_rename: Option<HashMap<String, String>>,
pub stop_on_error: Option<bool>,
pub dump: Option<Vec<ConfigDumpContent>>,
pub dump_all: Option<bool>,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ impl InternalConfig {
let default_stream_sink_codec = generate_default_stream_sink_codec(full_dep);
let default_rust_opaque_codec = generate_default_rust_opaque_codec(full_dep);
let enable_local_dependency = config.local.unwrap_or_default();
let stop_on_error = config.stop_on_error.unwrap_or_default();

let controller = controller_parser::parse(meta_config, &rust_crate_dir, &rust_output_path)?;

Expand Down Expand Up @@ -106,6 +107,7 @@ impl InternalConfig {
force_codec_mode_pack: compute_force_codec_mode_pack(full_dep),
default_stream_sink_codec,
default_rust_opaque_codec,
stop_on_error,
},
},
generator,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::codegen::ir::mir::func::{
};
use crate::if_then_some;
use crate::library::codegen::generator::api_dart::spec_generator::base::*;
use crate::utils::basic_code::DartBasicHeaderCode;
use crate::utils::namespace::NamespacedName;
use convert_case::{Case, Casing};
use itertools::Itertools;
Expand All @@ -20,15 +21,31 @@ pub(crate) enum GenerateApiMethodMode {
Combined,
}

pub(crate) struct GeneratedApiMethods {
pub(crate) num_methods: usize,
pub(crate) code: String,
pub(crate) header: DartBasicHeaderCode,
}

struct GeneratedApiMethod {
code: String,
header: DartBasicHeaderCode,
}

pub(crate) fn generate_api_methods(
generalized_class_name: &NamespacedName,
context: ApiDartGeneratorContext,
mode: GenerateApiMethodMode,
) -> Vec<String> {
get_methods_of_enum_or_struct(generalized_class_name, &context.mir_pack.funcs)
) -> GeneratedApiMethods {
let methods = get_methods_of_enum_or_struct(generalized_class_name, &context.mir_pack.funcs)
.iter()
.filter_map(|func| generate_api_method(func, context, mode))
.collect_vec()
.collect_vec();
GeneratedApiMethods {
num_methods: methods.len(),
code: methods.iter().map(|x| x.code.clone()).join("\n"),
header: (methods.iter().map(|x| x.header.clone())).fold(Default::default(), |a, b| a + b),
}
}

// TODO move
Expand Down Expand Up @@ -64,7 +81,7 @@ fn generate_api_method(
func: &MirFunc,
context: ApiDartGeneratorContext,
mode: GenerateApiMethodMode,
) -> Option<String> {
) -> Option<GeneratedApiMethod> {
let api_dart_func = api_dart::spec_generator::function::generate(func, context).unwrap();

let method_info =
Expand Down Expand Up @@ -100,7 +117,12 @@ fn generate_api_method(
generate_maybe_implementation(func, context, method_info, &params, mode);
let maybe_implementation = (maybe_implementation.map(|x| format!("=>{x}"))).unwrap_or_default();

Some(format!("{comments}{signature}{maybe_implementation};\n\n"))
let code = format!("{comments}{signature}{maybe_implementation};\n\n");

Some(GeneratedApiMethod {
code,
header: api_dart_func.header,
})
}

fn compute_skip_names(method_info: &MirFuncOwnerInfoMethod) -> Vec<&'static str> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,16 @@ impl<'a> ApiDartGeneratorClassTrait for EnumRefApiDartGenerator<'a> {
fn generate_class(&self) -> Option<ApiDartGeneratedClass> {
let src = self.mir.get(self.context.mir_pack);

let methods_str =
generate_api_methods(&src.name, self.context, GenerateApiMethodMode::Combined)
.join("\n");
let methods =
generate_api_methods(&src.name, self.context, GenerateApiMethodMode::Combined);
let extra_body =
generate_class_extra_body(self.mir_type(), &self.context.mir_pack.dart_code_of_type);

let body = methods_str + &extra_body;
let body = methods.code + &extra_body;

match src.mode {
MirEnumMode::Simple => self.generate_mode_simple(src, &body),
MirEnumMode::Complex => self.generate_mode_complex(src, &body),
MirEnumMode::Simple => self.generate_mode_simple(src, &body, methods.header),
MirEnumMode::Complex => self.generate_mode_complex(src, &body, methods.header),
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::codegen::ir::mir::ty::enumeration::{MirEnum, MirVariant, MirVariantKi
use crate::codegen::ir::mir::ty::structure::MirStruct;
use crate::library::codegen::generator::api_dart::spec_generator::base::*;
use crate::library::codegen::generator::api_dart::spec_generator::info::ApiDartGeneratorInfoTrait;
use crate::utils::basic_code::DartBasicHeaderCode;
use itertools::Itertools;

const BACKTRACE_IDENT: &str = "backtrace";
Expand All @@ -19,6 +20,7 @@ impl<'a> EnumRefApiDartGenerator<'a> {
&self,
src: &MirEnum,
extra_body: &str,
header: DartBasicHeaderCode,
) -> Option<ApiDartGeneratedClass> {
let variants = src
.variants()
Expand Down Expand Up @@ -49,7 +51,7 @@ impl<'a> EnumRefApiDartGenerator<'a> {
}}",
),
needs_freezed: true,
header: Default::default(),
header,
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::codegen::generator::api_dart::spec_generator::class::ApiDartGenerated
use crate::codegen::generator::api_dart::spec_generator::misc::generate_dart_comments;
use crate::codegen::ir::mir::ty::enumeration::{MirEnum, MirVariant};
use crate::library::codegen::generator::api_dart::spec_generator::base::*;
use crate::utils::basic_code::DartBasicHeaderCode;
use crate::utils::dart_keywords::make_string_keyword_safe;
use itertools::Itertools;

Expand All @@ -10,6 +11,7 @@ impl<'a> EnumRefApiDartGenerator<'a> {
&self,
src: &MirEnum,
extra_body: &str,
header: DartBasicHeaderCode,
) -> Option<ApiDartGeneratedClass> {
let comments = generate_dart_comments(&src.comments);

Expand All @@ -33,7 +35,7 @@ impl<'a> EnumRefApiDartGenerator<'a> {
}}",
),
needs_freezed: false,
header: Default::default(),
header,
})
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::codegen::generator::api_dart::spec_generator::class::method::{
generate_api_methods, GenerateApiMethodMode,
generate_api_methods, GenerateApiMethodMode, GeneratedApiMethods,
};
use crate::codegen::generator::api_dart::spec_generator::class::misc::generate_class_extra_body;
use crate::codegen::generator::api_dart::spec_generator::class::ty::ApiDartGeneratorClassTrait;
Expand All @@ -18,6 +18,7 @@ impl<'a> ApiDartGeneratorClassTrait for RustOpaqueApiDartGenerator<'a> {
dart_api_type,
methods,
} = self.compute_info(GenerateApiMethodMode::SeparatedDecl);
let methods_str = &methods.code;

let rust_api_type = self.mir.rust_api_type();

Expand All @@ -31,7 +32,7 @@ impl<'a> ApiDartGeneratorClassTrait for RustOpaqueApiDartGenerator<'a> {
"
// Rust type: {rust_api_type}
abstract class {dart_api_type} {{
{methods}
{methods_str}
void dispose();
Expand All @@ -42,7 +43,7 @@ impl<'a> ApiDartGeneratorClassTrait for RustOpaqueApiDartGenerator<'a> {
"
),
needs_freezed: false,
header: Default::default(),
header: methods.header,
})
}

Expand All @@ -51,6 +52,7 @@ impl<'a> ApiDartGeneratorClassTrait for RustOpaqueApiDartGenerator<'a> {
dart_api_type,
methods,
} = self.compute_info(GenerateApiMethodMode::SeparatedImpl);
let methods_str = &methods.code;

let dart_api_type_impl = format!("{dart_api_type}Impl");

Expand All @@ -74,7 +76,7 @@ impl<'a> ApiDartGeneratorClassTrait for RustOpaqueApiDartGenerator<'a> {
rustArcDecrementStrongCountPtr: {dart_api_instance}.rust_arc_decrement_strong_count_{dart_api_type}Ptr,
);
{methods}
{methods_str}
}}"
))
}
Expand All @@ -91,8 +93,7 @@ impl RustOpaqueApiDartGenerator<'_> {
),
self.context,
mode,
)
.join("\n");
);

Info {
dart_api_type,
Expand All @@ -103,7 +104,7 @@ impl RustOpaqueApiDartGenerator<'_> {

struct Info {
dart_api_type: String,
methods: String,
methods: GeneratedApiMethods,
}

fn compute_api_method_query_name(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl<'a> ApiDartGeneratorClassTrait for StructRefApiDartGenerator<'a> {
)
},
needs_freezed: src.using_freezed(),
header: Default::default(),
header: methods.header,
})
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::codegen::generator::api_dart::spec_generator::class::field::{
generate_field_default, generate_field_required_modifier,
};
use crate::codegen::generator::api_dart::spec_generator::class::method::GeneratedApiMethods;
use crate::codegen::generator::api_dart::spec_generator::misc::generate_dart_maybe_implements_exception;
use crate::codegen::ir::mir::ty::structure::MirStruct;
use crate::library::codegen::generator::api_dart::spec_generator::base::*;
Expand All @@ -14,21 +15,21 @@ impl<'a> StructRefApiDartGenerator<'a> {
src: &MirStruct,
comments: &str,
metadata: &str,
methods: &[String],
methods: &GeneratedApiMethods,
constructor_postfix: &str,
extra_body: &str,
class_name: &str,
) -> String {
let private_constructor = if !methods.is_empty() {
let private_constructor = if methods.num_methods > 0 {
format!("const {}._();", self.mir.ident.0.name)
} else {
"".to_owned()
};

let constructor_params =
self.generate_mode_freezed_constructor_params(src, !methods.is_empty());
self.generate_mode_freezed_constructor_params(src, methods.num_methods > 0);
let implements_exception = generate_dart_maybe_implements_exception(self.mir.is_exception);
let methods_str = methods.join("\n");
let methods_str = &methods.code;

format!(
"{comments}{metadata}class {class_name} with _${class_name} {implements_exception} {{
Expand Down
Loading

0 comments on commit 03c3f78

Please sign in to comment.