Skip to content

Commit 91b35e8

Browse files
committed
Add Data::merge for merging signature data
1 parent dc51fd5 commit 91b35e8

File tree

3 files changed

+109
-2
lines changed

3 files changed

+109
-2
lines changed

rust/signature.rs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,43 @@ impl Data {
2828
.map(Into::into)
2929
}
3030

31+
pub fn merge(entries: &[Data]) -> Data {
32+
let mut merged_data = Data::default();
33+
merged_data
34+
.types
35+
.extend(entries.iter().flat_map(|e| &e.types).cloned());
36+
// Now sort and remove types with the same guid.
37+
merged_data
38+
.types
39+
.sort_unstable_by(|a, b| a.guid.cmp(&b.guid));
40+
merged_data.types.dedup_by_key(|ty| ty.guid);
41+
merged_data
42+
.functions
43+
.extend(entries.iter().flat_map(|e| &e.functions).cloned());
44+
// Now sort and remove functions with the same symbol and guid.
45+
merged_data
46+
.functions
47+
.sort_unstable_by(|a, b| a.symbol.name.cmp(&b.symbol.name));
48+
merged_data.functions.dedup_by(|a, b| {
49+
if a.guid == b.guid {
50+
// Keep `a`s constraints.
51+
b.constraints
52+
.adjacent
53+
.extend(a.constraints.adjacent.clone());
54+
b.constraints
55+
.call_sites
56+
.extend(a.constraints.call_sites.clone());
57+
b.constraints
58+
.caller_sites
59+
.extend(a.constraints.caller_sites.clone());
60+
true
61+
} else {
62+
false
63+
}
64+
});
65+
merged_data
66+
}
67+
3168
pub fn to_bytes(&self) -> Vec<u8> {
3269
let mut builder = FlatBufferBuilder::new();
3370
let fb_data = self.create(&mut builder);
@@ -65,3 +102,73 @@ impl From<fb::Data<'_>> for Data {
65102
}
66103
}
67104
}
105+
106+
#[cfg(test)]
107+
mod tests {
108+
use super::*;
109+
use crate::r#type::guid::TypeGUID;
110+
use crate::r#type::ComputedType;
111+
use crate::signature::function::{Function, FunctionGUID};
112+
use crate::symbol::class::SymbolClass;
113+
use crate::symbol::Symbol;
114+
use uuid::{uuid, Uuid};
115+
116+
const FUNC1_GUID: Uuid = uuid!("6b50fa09-c8c5-4e88-b317-5a96c01c52ee");
117+
const FUNC2_GUID: Uuid = uuid!("e0565a4e-d730-4073-916c-fa6cb8ad2407");
118+
const FUNC3_GUID: Uuid = uuid!("5a7eb124-b786-4aa8-af2f-ccffbb600d21");
119+
120+
const TYPE1_GUID: Uuid = uuid!("7aee6520-0443-4a91-910e-da068571fa7a");
121+
const TYPE2_GUID: Uuid = uuid!("9e8a58f0-757d-4fa6-8c41-a4da023c5a32");
122+
const TYPE3_GUID: Uuid = uuid!("f81a46df-ad7b-4d7b-a4a7-23ed22ab01ec");
123+
124+
// Used with `test_merge` test.
125+
fn create_sample_function<T: Into<FunctionGUID>>(name: &str, guid: T) -> Function {
126+
Function {
127+
symbol: Symbol {
128+
name: name.to_string(),
129+
modifiers: Default::default(),
130+
class: SymbolClass::Function,
131+
},
132+
guid: guid.into(),
133+
constraints: Default::default(),
134+
ty: rand::random(),
135+
entry: None,
136+
}
137+
}
138+
139+
// Used with `test_merge` test.
140+
fn create_sample_computed_type<T: Into<TypeGUID>>(guid: T) -> ComputedType {
141+
let mut comp_ty = ComputedType::new(rand::random());
142+
comp_ty.guid = guid.into(); // Adjust the guid for testing.
143+
comp_ty
144+
}
145+
146+
#[test]
147+
fn test_merge() {
148+
let first_data = Data::new(
149+
vec![
150+
create_sample_function("func1", FUNC1_GUID),
151+
create_sample_function("func2", FUNC2_GUID),
152+
],
153+
vec![
154+
create_sample_computed_type(TYPE1_GUID),
155+
create_sample_computed_type(TYPE2_GUID),
156+
],
157+
);
158+
159+
let second_data = Data::new(
160+
vec![
161+
create_sample_function("func2", FUNC2_GUID),
162+
create_sample_function("func3", FUNC3_GUID),
163+
],
164+
vec![
165+
create_sample_computed_type(TYPE1_GUID),
166+
create_sample_computed_type(TYPE3_GUID),
167+
],
168+
);
169+
170+
let merged_data = Data::merge(&[first_data, second_data]);
171+
assert_eq!(merged_data.functions.len(), 3, "{:#?}", merged_data.functions);
172+
assert_eq!(merged_data.types.len(), 3, "{:#?}", merged_data.types);
173+
}
174+
}

rust/signature/function.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub mod constraints;
1212

1313
pub const NAMESPACE_FUNCTION: Uuid = uuid!("0192a179-61ac-7cef-88ed-012296e9492f");
1414

15-
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
15+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
1616
pub struct FunctionGUID {
1717
pub guid: Uuid,
1818
}

rust/type/guid.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use uuid::{uuid, Uuid};
77

88
pub const NAMESPACE_TYPEBIN: Uuid = uuid!("01929b90-72e6-73e6-9da1-2b6462e407a6");
99

10-
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
10+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
1111
pub struct TypeGUID {
1212
guid: Uuid,
1313
}

0 commit comments

Comments
 (0)