Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify dependency tracking #3460

Merged
merged 3 commits into from
Jan 22, 2025
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
10 changes: 6 additions & 4 deletions crates/libs/bindgen/src/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ impl Signature {
.fold(0, |sum, param| sum + std::cmp::max(4, param.size()))
}

pub fn dependencies(&self, dependencies: &mut TypeMap) {
self.types().for_each(|ty| ty.dependencies(dependencies));
}

pub fn types(&self) -> impl Iterator<Item = &Type> + '_ {
std::iter::once(&self.return_type)
.chain(self.params.iter().map(|param| &param.ty))
Expand All @@ -44,3 +40,9 @@ impl Signature {
false
}
}

impl Dependencies for Signature {
fn combine(&self, dependencies: &mut TypeMap) {
self.types().for_each(|ty| ty.combine(dependencies));
}
}
25 changes: 25 additions & 0 deletions crates/libs/bindgen/src/tables/method_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@ impl MethodDef {
self.str(3)
}

pub fn import_name(&self) -> Option<&'static str> {
self.impl_map().and_then(|map| {
let import_name = map.import_name();
if self.name() != import_name {
Some(import_name)
} else {
None
}
})
}

pub fn params(&self) -> RowIterator<MethodParam> {
self.list(5)
}
Expand All @@ -29,6 +40,20 @@ impl MethodDef {
self.impl_map().map_or("", |map| map.scope().name())
}

pub fn calling_convention(&self) -> &'static str {
self.impl_map().map_or("", |map| {
let flags = map.flags();

if flags.contains(PInvokeAttributes::CallConvPlatformapi) {
"system"
} else if flags.contains(PInvokeAttributes::CallConvCdecl) {
"cdecl"
} else {
""
}
})
}

#[track_caller]
pub fn signature(&self, namespace: &str, generics: &[Type]) -> Signature {
let mut blob = self.blob(4);
Expand Down
12 changes: 11 additions & 1 deletion crates/libs/bindgen/src/type_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@ use super::*;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct TypeMap(HashMap<TypeName, HashSet<Type>>);

pub trait Dependencies {
fn combine(&self, dependencies: &mut TypeMap);

fn dependencies(&self) -> TypeMap {
let mut dependencies = TypeMap::new();
self.combine(&mut dependencies);
dependencies
}
}

impl std::ops::Deref for TypeMap {
type Target = HashMap<TypeName, HashSet<Type>>;

Expand All @@ -27,7 +37,7 @@ impl TypeMap {
let mut item_dependencies = Self::new();

for ty in types {
ty.dependencies(&mut item_dependencies);
ty.combine(&mut item_dependencies);
}

if item_dependencies.excluded(filter) {
Expand Down
23 changes: 10 additions & 13 deletions crates/libs/bindgen/src/types/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ impl Class {
return (Cfg::default(), quote! {});
}

let mut dependencies = TypeMap::new();
self.dependencies(&mut dependencies);
let cfg = Cfg::new(self.def, &dependencies);
let cfg = Cfg::new(self.def, &self.dependencies());
let tokens = cfg.write(writer, false);
(cfg, tokens)
}
Expand Down Expand Up @@ -92,10 +90,7 @@ impl Class {
let interface_type = interface.write_name(writer);

let cfg = if writer.config.package {
let mut dependencies = TypeMap::new();
interface.dependencies(&mut dependencies);

class_cfg.difference(interface.def, &dependencies).write(writer, false)
class_cfg.difference(interface.def, &interface.dependencies()).write(writer, false)
} else {
quote! {}
};
Expand Down Expand Up @@ -252,12 +247,6 @@ impl Class {
)
}

pub fn dependencies(&self, dependencies: &mut TypeMap) {
for interface in self.required_interfaces() {
Type::Interface(interface).dependencies(dependencies);
}
}

fn bases(&self) -> Vec<Self> {
let mut bases = Vec::new();
let mut def = self.def;
Expand Down Expand Up @@ -356,3 +345,11 @@ impl Class {
})
}
}

impl Dependencies for Class {
fn combine(&self, dependencies: &mut TypeMap) {
for interface in self.required_interfaces() {
Type::Interface(interface).combine(dependencies);
}
}
}
13 changes: 5 additions & 8 deletions crates/libs/bindgen/src/types/cpp_const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,7 @@ impl CppConst {
return quote! {};
}

let mut dependencies = TypeMap::new();
self.dependencies(&mut dependencies);
Cfg::new(self.field, &dependencies).write(writer, false)
Cfg::new(self.field, &self.dependencies()).write(writer, false)
}

pub fn write(&self, writer: &Writer) -> TokenStream {
Expand Down Expand Up @@ -137,12 +135,11 @@ impl CppConst {
panic!()
}
}
}

pub fn dependencies(&self, dependencies: &mut TypeMap) {
self.field
.ty(None)
.to_const_type()
.dependencies(dependencies);
impl Dependencies for CppConst {
fn combine(&self, dependencies: &mut TypeMap) {
self.field.ty(None).to_const_type().combine(dependencies);
}
}

Expand Down
10 changes: 5 additions & 5 deletions crates/libs/bindgen/src/types/cpp_delegate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,7 @@ impl CppDelegate {
return quote! {};
}

let mut dependencies = TypeMap::new();
self.dependencies(&mut dependencies);
Cfg::new(self.def, &dependencies).write(writer, false)
Cfg::new(self.def, &self.dependencies()).write(writer, false)
}

pub fn write(&self, writer: &Writer) -> TokenStream {
Expand All @@ -65,11 +63,13 @@ impl CppDelegate {
pub type #name = Option<unsafe extern "system" fn(#params) #return_sig>;
}
}
}

pub fn dependencies(&self, dependencies: &mut TypeMap) {
impl Dependencies for CppDelegate {
fn combine(&self, dependencies: &mut TypeMap) {
self.method()
.signature(self.def.namespace(), &[])
.dependencies(dependencies);
.combine(dependencies);
}
}

Expand Down
22 changes: 12 additions & 10 deletions crates/libs/bindgen/src/types/cpp_enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,22 +124,24 @@ impl CppEnum {
}
}

pub fn dependencies(&self, dependencies: &mut TypeMap) {
pub fn size(&self) -> usize {
self.def.underlying_type().size()
}

pub fn align(&self) -> usize {
self.def.underlying_type().align()
}
}

impl Dependencies for CppEnum {
fn combine(&self, dependencies: &mut TypeMap) {
if let Some(attribute) = self.def.find_attribute("AlsoUsableForAttribute") {
if let Some((_, Value::Str(type_name))) = attribute.args().first() {
self.def
.reader()
.unwrap_full_name(self.def.namespace(), type_name)
.dependencies(dependencies);
.combine(dependencies);
}
}
}

pub fn size(&self) -> usize {
self.def.underlying_type().size()
}

pub fn align(&self) -> usize {
self.def.underlying_type().align()
}
}
37 changes: 8 additions & 29 deletions crates/libs/bindgen/src/types/cpp_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,10 @@ impl CppFn {
}

pub fn write_link(&self, writer: &Writer, underlying_types: bool) -> TokenStream {
let name = self.method.name();
let library = self.method.module_name().to_lowercase();
let impl_map = self.method.impl_map().unwrap();
let mut symbol = Some(impl_map.import_name());

if symbol == Some(name) {
symbol = None;
}

let symbol = self.method.import_name();
let name = to_ident(self.method.name());
let impl_flags = impl_map.flags();

let abi = if impl_flags.contains(PInvokeAttributes::CallConvPlatformapi) {
"system"
} else if impl_flags.contains(PInvokeAttributes::CallConvCdecl) {
"cdecl"
} else {
panic!()
};

let abi = self.method.calling_convention();
let signature = self.method.signature(self.namespace, &[]);

let params = signature.params.iter().map(|param| {
Expand Down Expand Up @@ -81,19 +65,12 @@ impl CppFn {
return quote! {};
}

let mut dependencies = TypeMap::new();
self.dependencies(&mut dependencies);
Cfg::new(self.method, &dependencies).write(writer, false)
Cfg::new(self.method, &self.dependencies()).write(writer, false)
}

pub fn write(&self, writer: &Writer) -> TokenStream {
let name = to_ident(self.method.name());
let signature = self.method.signature(self.namespace, &[]);
let mut dependencies = TypeMap::new();

if writer.config.package {
self.dependencies(&mut dependencies);
}

let link = self.write_link(writer, false);
let arches = write_arches(self.method);
Expand Down Expand Up @@ -271,11 +248,13 @@ impl CppFn {
_ => quote! {},
}
}
}

pub fn dependencies(&self, dependencies: &mut TypeMap) {
impl Dependencies for CppFn {
fn combine(&self, dependencies: &mut TypeMap) {
self.method
.signature(self.namespace, &[])
.dependencies(dependencies);
.combine(dependencies);

let dependency = match self.method.name() {
"GetWindowLongPtrA" => Some("GetWindowLongA"),
Expand All @@ -289,7 +268,7 @@ impl CppFn {
self.method
.reader()
.unwrap_full_name(self.namespace, dependency)
.dependencies(dependencies);
.combine(dependencies);
}
}
}
Expand Down
48 changes: 23 additions & 25 deletions crates/libs/bindgen/src/types/cpp_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,7 @@ impl CppInterface {
return (Cfg::default(), quote! {});
}

let mut dependencies = TypeMap::new();
self.dependencies(&mut dependencies);
let cfg = Cfg::new(self.def, &dependencies);
let cfg = Cfg::new(self.def, &self.dependencies());
let tokens = cfg.write(writer, false);
(cfg, tokens)
}
Expand Down Expand Up @@ -223,21 +221,20 @@ impl CppInterface {
let impl_name: TokenStream = format!("{}_Impl", self.def.name()).into();

let cfg = if writer.config.package {
fn collect(interface: &CppInterface, dependencies: &mut TypeMap, writer: &Writer) {
fn combine(interface: &CppInterface, dependencies: &mut TypeMap, writer: &Writer) {
for method in interface.get_methods(writer).iter() {
if let CppMethodOrName::Method(method) = method {
dependencies.combine(&method.dependencies);
}
}
}

let mut dependencies = TypeMap::new();
self.dependencies(&mut dependencies);
let mut dependencies = self.dependencies();
combine(self, &mut dependencies, writer);

collect(self, &mut dependencies, writer);
base_interfaces.iter().for_each(|interface| {
if let Type::CppInterface(ty) = interface {
collect(ty, &mut dependencies, writer);
combine(ty, &mut dependencies, writer);
}
});

Expand Down Expand Up @@ -417,23 +414,6 @@ impl CppInterface {
quote! { #namespace #name }
}

#[track_caller]
pub fn dependencies(&self, dependencies: &mut TypeMap) {
let base_interfaces = self.base_interfaces();

for interface in &base_interfaces {
interface.dependencies(dependencies);
}

for method in self.def.methods() {
for ty in method.signature(self.def.namespace(), &[]).types() {
if ty.is_core() {
ty.dependencies(dependencies);
}
}
}
}

pub fn base_interfaces(&self) -> Vec<Type> {
let mut bases = vec![];
let mut def = self.def;
Expand All @@ -460,3 +440,21 @@ impl CppInterface {
bases
}
}

impl Dependencies for CppInterface {
fn combine(&self, dependencies: &mut TypeMap) {
let base_interfaces = self.base_interfaces();

for interface in &base_interfaces {
interface.combine(dependencies);
}

for method in self.def.methods() {
for ty in method.signature(self.def.namespace(), &[]).types() {
if ty.is_core() {
ty.combine(dependencies);
}
}
}
}
}
5 changes: 1 addition & 4 deletions crates/libs/bindgen/src/types/cpp_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,16 +78,13 @@ impl ParamHint {
impl CppMethod {
pub fn new(def: MethodDef, namespace: &'static str) -> Self {
let signature = def.signature(namespace, &[]);

let dependencies = signature.dependencies();
let mut param_hints = vec![ParamHint::None; signature.params.len()];

for (position, param) in signature.params.iter().enumerate() {
param_hints[position] = param.into();
}

let mut dependencies = TypeMap::new();
signature.dependencies(&mut dependencies);

for position in 0..signature.params.len() {
// Point len params back to the corresponding ptr params.
match param_hints[position] {
Expand Down
Loading