Skip to content

Commit

Permalink
Separate generated definitions from implementations (not tested) #298
Browse files Browse the repository at this point in the history
  • Loading branch information
fzyzcjy committed Jan 11, 2022
1 parent 2918ac2 commit c9a2262
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 55 deletions.
5 changes: 5 additions & 0 deletions frb_codegen/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ pub struct RawOpts {
/// Path of output generated Dart code
#[structopt(short, long)]
pub dart_output: String,
/// If provided, generated Dart declaration code to this separate file
#[structopt(short, long)]
pub dart_decl_output: Option<String>,

/// Path of output generated C header
#[structopt(short, long)]
Expand Down Expand Up @@ -49,6 +52,7 @@ pub struct RawOpts {
pub struct Opts {
pub rust_input_path: String,
pub dart_output_path: String,
pub dart_decl_output_path: Option<String>,
pub c_output_path: String,
pub rust_crate_dir: String,
pub rust_output_path: String,
Expand Down Expand Up @@ -82,6 +86,7 @@ pub fn parse(raw: RawOpts) -> Opts {
Opts {
rust_input_path,
dart_output_path: canon_path(&raw.dart_output),
dart_decl_output_path: raw.dart_decl_output.as_ref().map(canon_path),
c_output_path,
rust_crate_dir,
rust_output_path,
Expand Down
72 changes: 34 additions & 38 deletions frb_codegen/src/generator_dart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,12 @@ use crate::api_types::ApiType::*;
use crate::api_types::*;
use crate::others::*;

pub struct Output {
pub header: String,
pub api_class: String,
pub other: String,
}

pub fn generate(
api_file: &ApiFile,
dart_api_class_name: &str,
dart_api_impl_class_name: &str,
dart_wire_class_name: &str,
) -> Output {
) -> (DartBasicCode, DartBasicCode) {
let distinct_types = api_file.distinct_types(true, true);
let distinct_input_types = api_file.distinct_types(true, false);
let distinct_output_types = api_file.distinct_types(false, true);
Expand Down Expand Up @@ -54,45 +48,41 @@ pub fn generate(
.any(|ty| matches!(ty, EnumRef(e) if e.is_struct));
let freezed_header = if needs_freezed {
"import 'package:freezed_annotation/freezed_annotation.dart';
// import 'package:flutter/foundation.dart';
part 'bridge_generated.freezed.dart';"
} else {
""
};

let header = format!(
let common_header = format!(
"{}
// ignore_for_file: non_constant_identifier_names, unused_element, duplicate_ignore, directives_ordering, curly_braces_in_flow_control_structures, unnecessary_lambdas, slash_for_doc_comments, prefer_const_literals_to_create_immutables, implicit_dynamic_list_literal
import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter_rust_bridge/flutter_rust_bridge.dart';",
CODE_HEADER,
import 'dart:typed_data';",
CODE_HEADER
);

let api_class = format!(
let decl_header = format!(
"{}
abstract class {} extends FlutterRustBridgeBase<{}> {{
factory {}(ffi.DynamicLibrary dylib) => {}.raw({}(dylib));
{}",
common_header, freezed_header,
);

{}.raw({} inner) : super(inner);
let impl_header = format!(
"{}
import 'package:flutter_rust_bridge/flutter_rust_bridge.dart';",
common_header
);

let decl_body = format!(
"abstract class {} {{
{}
}}
{}
// ------------------------- Implementation Details -------------------------
",
freezed_header,
dart_api_class_name,
dart_wire_class_name,
dart_api_class_name,
dart_api_impl_class_name,
dart_wire_class_name,
dart_api_class_name,
dart_wire_class_name,
dart_func_signatures_and_implementations
.iter()
.map(|(sig, _, comm)| format!("{}{}", comm, sig))
Expand All @@ -101,11 +91,10 @@ pub fn generate(
dart_structs.join("\n\n"),
);

let other = format!(
"/// Implementations for {}. Prefer using {} if possible; but this class allows more
/// flexible customizations (such as subclassing to create an initializer, a logger, or
/// a timer).
class {} extends {} {{
let impl_body = format!(
"class {} extends FlutterRustBridgeBase<{}> implements {} {{
factory {}(ffi.DynamicLibrary dylib) => {}.raw({}(dylib));
{}.raw({} inner) : super.raw(inner);
{}
Expand All @@ -120,11 +109,13 @@ pub fn generate(
// Section: wire2api
{}
",
dart_api_class_name,
dart_api_class_name,
dart_api_impl_class_name,
dart_wire_class_name,
dart_api_class_name,
dart_api_impl_class_name,
dart_api_impl_class_name,
dart_wire_class_name,
dart_api_impl_class_name,
dart_wire_class_name,
dart_func_signatures_and_implementations
.iter()
Expand All @@ -136,11 +127,16 @@ pub fn generate(
dart_wire2api_funcs.join("\n\n"),
);

Output {
header,
api_class,
other,
}
(
DartBasicCode {
header: decl_header,
body: decl_body,
},
DartBasicCode {
header: impl_header,
body: impl_body,
},
)
}

fn generate_api_func(func: &ApiFunc) -> (String, String, String) {
Expand Down
36 changes: 21 additions & 15 deletions frb_codegen/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ fn main() {
fs::write(&config.rust_output_path, generated_rust.code).unwrap();

info!("Phase: Generate Dart code");
let generated_dart_api = generator_dart::generate(
let (generated_dart_decl_raw, generated_dart_impl_raw) = generator_dart::generate(
&api_file,
&config.dart_api_class_name(),
&config.dart_api_impl_class_name(),
Expand Down Expand Up @@ -116,27 +116,33 @@ fn main() {

fs::create_dir_all(&dart_output_dir).unwrap();
let generated_dart_wire_code_raw = fs::read_to_string(temp_dart_wire_file).unwrap();
let (generated_dart_wire_import_code, generated_dart_wire_body_code) =
extract_dart_wire_content(&modify_dart_wire_content(
&generated_dart_wire_code_raw,
&config.dart_wire_class_name(),
));
let generated_dart_wire = extract_dart_wire_content(&modify_dart_wire_content(
&generated_dart_wire_code_raw,
&config.dart_wire_class_name(),
));

sanity_check(
&generated_dart_wire_body_code,
&config.dart_wire_class_name(),
);

let generated_dart_code = format!(
"{}\n{}\n{}\n{}\n{}",
generated_dart_api.header,
generated_dart_wire_import_code,
generated_dart_api.api_class,
generated_dart_api.other,
generated_dart_wire_body_code,
);
fs::write(&config.dart_output_path, generated_dart_code).unwrap();
let generated_dart_decl_all = generated_dart_decl_raw;
let generated_dart_impl_all = generated_dart_impl_raw + generated_dart_wire;
if let Some(dart_decl_output_path) = &config.dart_decl_output_path {
fs::write(&dart_decl_output_path, generated_dart_decl_all.to_text()).unwrap();
fs::write(&config.dart_output_path, generated_dart_impl_all.to_text()).unwrap();
} else {
fs::write(
&config.dart_output_path,
(&generated_dart_decl_all + &generated_dart_impl_all).to_text(),
)
.unwrap();
}

commands::format_dart(&config.dart_output_path, config.dart_format_line_length);
if let Some(dart_decl_output_path) = &config.dart_decl_output_path {
commands::format_dart(&dart_decl_output_path, config.dart_format_line_length);
}

info!("Success! Now go and use it :)");
}
30 changes: 28 additions & 2 deletions frb_codegen/src/others.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::fs;
use std::ops::Add;
use std::path::Path;

use anyhow::{anyhow, Result};
Expand Down Expand Up @@ -56,7 +57,29 @@ pub fn modify_dart_wire_content(content_raw: &str, dart_wire_class_name: &str) -
content.to_string()
}

pub fn extract_dart_wire_content(content: &str) -> (String, String) {
pub struct DartBasicCode {
pub header: String,
pub body: String,
}

impl Add for &DartBasicCode {
type Output = DartBasicCode;

fn add(self, rhs: Self) -> Self::Output {
DartBasicCode {
header: format!("{}\n{}", self.header, rhs.header),
body: format!("{}\n{}", self.body, rhs.body),
}
}
}

impl DartBasicCode {
pub fn to_text(&self) -> String {
format!("{}\n{}", self.header, self.body)
}
}

pub fn extract_dart_wire_content(content: &str) -> DartBasicCode {
let (mut imports, mut body) = (Vec::new(), Vec::new());
for line in content.split('\n') {
(if line.starts_with("import ") {
Expand All @@ -66,7 +89,10 @@ pub fn extract_dart_wire_content(content: &str) -> (String, String) {
})
.push(line);
}
(imports.join("\n"), body.join("\n"))
DartBasicCode {
header: imports.join("\n"),
body: body.join("\n"),
}
}

pub fn sanity_check(generated_dart_wire_code: &str, dart_wire_class_name: &str) {
Expand Down

0 comments on commit c9a2262

Please sign in to comment.