From 20da029666b6dd37d01eab8c276ece399306a700 Mon Sep 17 00:00:00 2001 From: jerel Date: Fri, 1 Sep 2023 13:05:14 -0500 Subject: [PATCH] Change the Dart borrowing approach to avoid name conflicts --- dart_example/test/main_test.dart | 1 + membrane/src/generators/imports.rs | 14 +++++++ membrane/src/lib.rs | 65 +++++++++++++++++------------- 3 files changed, 51 insertions(+), 29 deletions(-) diff --git a/dart_example/test/main_test.dart b/dart_example/test/main_test.dart index 010df4c..e8a0851 100644 --- a/dart_example/test/main_test.dart +++ b/dart_example/test/main_test.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:io'; import 'dart:typed_data'; +import 'package:dart_example/common.dart' show Arg, VecWrapper; import 'package:logging/logging.dart'; import 'package:test/test.dart'; import 'package:dart_example/accounts.dart'; diff --git a/membrane/src/generators/imports.rs b/membrane/src/generators/imports.rs index e6e3705..5a24a68 100644 --- a/membrane/src/generators/imports.rs +++ b/membrane/src/generators/imports.rs @@ -1,4 +1,5 @@ use serde_reflection::{ContainerFormat, Format, Named, VariantFormat}; +use std::fs::{read_to_string, write}; use std::process::exit; use tracing::error; @@ -95,3 +96,16 @@ fn extract_name(format: &Format) -> Option> { fn filter_named(item: &Named) -> Option> { extract_name(&item.value) } + +pub(crate) fn inject_imports( + path: std::path::PathBuf, + filter: impl FnMut(&str) -> Option>, +) -> Result<(), std::io::Error> { + let dart_file = read_to_string(&path)? + .lines() + .filter_map(filter) + .flatten() + .collect::>(); + + write(path, dart_file.join("\n")) +} diff --git a/membrane/src/lib.rs b/membrane/src/lib.rs index 7a89809..776cda9 100644 --- a/membrane/src/lib.rs +++ b/membrane/src/lib.rs @@ -89,7 +89,7 @@ mod generators; use generators::{ exceptions, functions::{Builder, Writable}, - loaders, + imports, loaders, }; use membrane_types::heck::{ToSnakeCase, ToUpperCamelCase}; use serde_reflection::{ @@ -97,7 +97,7 @@ use serde_reflection::{ }; use std::{ collections::{BTreeMap, BTreeSet, HashMap}, - fs::{read_to_string, remove_file}, + fs::remove_file, io::Write, os::raw::c_char, path::{Path, PathBuf}, @@ -909,6 +909,8 @@ export './membrane_loader_ffi.dart' if (dart.library.html) './membrane_loader_we // // Generated by `membrane` export './src/{ns}_ffi.dart' if (dart.library.html) './src/{ns}_web.dart'; + +export './src/{ns}/{ns}.dart' hide TraitHelpers; "#, ns = &namespace, ); @@ -927,12 +929,8 @@ export './src/{ns}_ffi.dart' if (dart.library.html) './src/{ns}_web.dart'; .join(namespace.to_string() + "_ffi.dart"); if self.namespaced_fn_registry.get(namespace).is_none() { - let head = format!( - "export './{ns}/{ns}.dart' hide TraitHelpers;", - ns = &namespace - ); let mut buffer = std::fs::File::create(path).expect("class could not be written at path"); - buffer.write_all(head.as_bytes()).unwrap(); + buffer.write_all("".as_bytes()).unwrap(); return self; } @@ -960,8 +958,6 @@ import './bincode/bincode.dart'; import './ffi_bindings.dart' show MembraneMsgKind, MembraneResponse, MembraneResponseKind; import './{ns}/{ns}.dart'; -export './{ns}/{ns}.dart' hide TraitHelpers; - final _bindings = loader.bindings; final _loggingDisabled = bool.fromEnvironment('MEMBRANE_DISABLE_LOGS'); @@ -1017,12 +1013,8 @@ class {class_name}Api {{ // perhaps this namespace has only enums in it and no functions if self.namespaced_fn_registry.get(namespace).is_none() { - let head = format!( - "export './{ns}/{ns}.dart' hide TraitHelpers;", - ns = &namespace - ); let mut buffer = std::fs::File::create(path).expect("class could not be written at path"); - buffer.write_all(head.as_bytes()).unwrap(); + buffer.write_all("".as_bytes()).unwrap(); return self; } @@ -1040,7 +1032,6 @@ class {class_name}Api {{ import 'package:meta/meta.dart'; import './membrane_exceptions.dart'; import './{ns}/{ns}.dart'; -export './{ns}/{ns}.dart' hide TraitHelpers; @immutable class {class_name}ApiError implements Exception {{ @@ -1144,14 +1135,11 @@ class {class_name}Api {{ // and this is the borrowed path non_owned_types.extend(borrowed_types.iter().map(|ty| format!("{}::{}", from_namespace, ty))); - let file_name = format!("{ns}.dart", ns = namespace); - let namespace_path = self.destination.join("lib/src").join(namespace); - let barrel_file_path = namespace_path.join(file_name); + let src_path = self.destination.join("lib/src"); + let namespace_path = src_path.join(namespace); - let barrel_file = read_to_string(&barrel_file_path) - .unwrap() - .lines() - .filter_map(|line| { + imports::inject_imports(namespace_path.join(format!("{ns}.dart", ns = namespace)), + |line| { // because CamelCasing the snake_cased `part 'central_usa.dart'` won't match the // acronym borrow `CentralUSA` we instead convert the borrows to snake_case to do the match if borrowed_types.iter().map(|t| t.to_snake_case()).collect::>().contains( @@ -1169,11 +1157,34 @@ class {class_name}Api {{ types = borrowed_types.join(",") ), ]) - } else if line.starts_with("export '../serde") { + } else { + Some(vec![line.to_string()]) + } + }).unwrap(); + + imports::inject_imports(src_path.join(format!("{ns}_ffi.dart", ns = namespace)), + |line| { + if line.starts_with(&format!("import './{ns}/{ns}.dart'", ns = namespace)) { + Some(vec![ + line.to_string(), + format!( + "import './{ns}/{ns}.dart' show {types};", + ns = from_namespace, + types = borrowed_types.join(",") + ), + ]) + } else { + Some(vec![line.to_string()]) + } + }).unwrap(); + + imports::inject_imports(src_path.join(format!("{ns}_web.dart", ns = namespace)), + |line| { + if line.starts_with(&format!("import './{ns}/{ns}.dart'", ns = namespace)) { Some(vec![ line.to_string(), format!( - "export '../{ns}/{ns}.dart' show {types};", + "import './{ns}/{ns}.dart' show {types};", ns = from_namespace, types = borrowed_types.join(",") ), @@ -1181,16 +1192,12 @@ class {class_name}Api {{ } else { Some(vec![line.to_string()]) } - }) - .flatten() - .collect::>(); + }).unwrap(); borrowed_types.iter().for_each(|borrowed_type| { let filename = format!("{}.dart", borrowed_type.to_snake_case()); let _ = remove_file(namespace_path.join(filename)); }); - - std::fs::write(barrel_file_path, barrel_file.join("\n")).unwrap(); }); });