Skip to content

Commit 8474717

Browse files
committed
test backup
1 parent e2d42bf commit 8474717

File tree

8 files changed

+218
-111
lines changed

8 files changed

+218
-111
lines changed

Cargo.lock

Lines changed: 98 additions & 103 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/inferrer/optimizer.rs

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,34 @@ impl Optimizer {
5858
// when TypeArenaWithDSU is dropped
5959
}
6060
}
61+
// drop(ufarena);
62+
63+
// let sets = schema.arena.find_disjoint_sets(|a, b| {
64+
// if let (Some(a), Some(b)) = (a.as_union(), b.as_union()) {
65+
// self.to_merge_same_unions && (a.types == b.types)
66+
// } else {
67+
// // TODO: merge same array?
68+
// false
69+
// }
70+
// });
71+
// for (leader, mut set) in sets.into_iter() {
72+
// if ufarena.get(leader).map(|r#type| {
73+
// self.to_merge_same_unions && r#type.is_union()
74+
// }) == Some(true)
75+
// {
76+
// set.insert(leader); // leader in disjoint set is now a follower
77+
78+
// let compact_set = set
79+
// .iter()
80+
// .cloned()
81+
// .filter(|&r#type| ufarena.contains(r#type))
82+
// .collect::<Vec<ArenaIndex>>();
83+
// // unioned is now the new leader
84+
// let _leader = union(&mut ufarena, compact_set);
85+
// // References to non-representative AreneIndex will be replaced automatically
86+
// // when TypeArenaWithDSU is dropped
87+
// }
88+
// }
6189
// Although unioner always keeps the first map slot intact, there is no guarantee that
6290
// root would always be the first map in types to be unioned. So update it if necessary.
6391
schema.root = ufarena.find_representative(schema.root).unwrap();
@@ -120,6 +148,7 @@ pub struct TypeArenaWithDSU<'a> {
120148

121149
impl<'a> TypeArenaWithDSU<'a> {
122150
fn from_type_arena(arena: &'a mut TypeArena) -> Self {
151+
dbg!(arena.len());
123152
let imap: Bimap<usize, ArenaIndex> =
124153
Bimap::from_hash_map(arena.iter().map(|(index, _)| index).enumerate().collect());
125154

@@ -189,7 +218,7 @@ impl<'a> TypeArenaWithDSU<'a> {
189218
for r#type in dangling_types.into_iter() {
190219
// TODO: Should these all removed during unioning?
191220
println!("removed dangling: {:?}", r#type);
192-
assert!(self.arena.remove(r#type).is_none());
221+
// debug_assert!(self.arena.remove(r#type).is_none());
193222
}
194223
}
195224

@@ -237,21 +266,29 @@ impl<'a> ITypeArena for TypeArenaWithDSU<'a> {
237266
// Note: It is not removed from DSU. So just ignore non-existing types when iterating DSU.
238267
// As get/get_mut wraps DSU internally, unioner won't get panicked.
239268
DerefMut::deref_mut(self).remove(i)
269+
// DerefMut::deref_mut(self).get(i).cloned()
240270
}
241271

242272
/// Remove the type denoted by the index i and union i into j in the DSU
243273
fn remove_in_favor_of(&mut self, i: ArenaIndex, j: ArenaIndex) -> Option<Type> {
274+
dbg!(i,j, self.imap.len(), self.arena.len());
275+
244276
self.dsu.union(
245277
*self.imap.get_rev(&i).unwrap(),
246278
*self.imap.get_rev(&j).unwrap(),
247279
);
248-
DerefMut::deref_mut(self).remove(i)
280+
// DerefMut::deref_mut(self).remove(i)
281+
DerefMut::deref_mut(self).get(i).cloned()
249282
}
250283

251284
#[inline(always)]
252285
fn insert(&mut self, value: Type) -> ArenaIndex {
253286
// Note: The DSU is not updated.
254-
DerefMut::deref_mut(self).insert(value)
287+
debug_assert_eq!(self.dsu.len(), self.imap.len());
288+
let i = self.dsu.alloc();
289+
let arni = DerefMut::deref_mut(self).insert(value);
290+
self.imap.insert(i, arni);
291+
arni
255292
}
256293

257294
#[inline(always)]

src/inferrer/unioner.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,11 @@ impl<'a, T: ITypeArena> UnionerClosure<'a, T> {
4444
// TODO: keep first_array?
4545

4646
// Expand any nested unions. Due to borrow issues, collecting is inevitable
47-
let types: Vec<ArenaIndex> = types
47+
let mut types: Vec<ArenaIndex> = types.into_iter().collect();
48+
let mut changed = true;
49+
while changed {
50+
changed = false;
51+
types = types
4852
.into_iter()
4953
.flat_map(|r#type| {
5054
// dbg!(r#type);
@@ -54,10 +58,12 @@ impl<'a, T: ITypeArena> UnionerClosure<'a, T> {
5458
.expect("The type should be present in the arena during unioning")
5559
{
5660
Type::Union(_) => {
61+
changed = true;
5762
let Union { name_hints, types } = if let Some(first_union) = first_union {
58-
self.arena
63+
dbg!(r#type, first_union);
64+
dbg!(self.arena
5965
.remove_in_favor_of(r#type, first_union)
60-
.unwrap()
66+
.unwrap())
6167
.into_union()
6268
.unwrap() // remove & expand the union
6369
} else {
@@ -75,6 +81,7 @@ impl<'a, T: ITypeArena> UnionerClosure<'a, T> {
7581
.collect::<HashSet<_>>()
7682
.into_iter()
7783
.collect();
84+
}
7885
for r#type in types {
7986
// dbg!(r#type, self.arena.get(r#type));
8087
match *self.arena.get(r#type).unwrap() {
@@ -111,6 +118,7 @@ impl<'a, T: ITypeArena> UnionerClosure<'a, T> {
111118
arrays.push(inner);
112119
}
113120
Type::Union(_) => unreachable!(), // union should have been expanded above
121+
Type::Undetermined => unreachable!(),
114122
_ => {
115123
// O.W. it is a primitive type. Then just add it to the union as is.
116124
// Note: SPECIAL CASE:
@@ -162,6 +170,7 @@ impl<'a, T: ITypeArena> UnionerClosure<'a, T> {
162170
// TODO: should slot be removed from arena here?
163171
unioned.insert(self.arena.get_index_of_primitive(Type::Any)); // Any
164172
} else {
173+
dbg!(map_count);
165174
let slot = first_map.unwrap();
166175
*self.arena.get_mut(slot).unwrap() = Type::Map(Map {
167176
name_hints: map_name_hints,

src/main.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,26 @@
1+
use serde_json::Value;
2+
3+
use json2pyi::inferrer::*;
4+
use json2pyi::target::{
5+
Indentation, PythonClass, PythonKind, PythonTypedDict, Quote, TargetGenerator,
6+
};
7+
18
fn main() {
2-
println!("Hello, world!");
9+
let data = include_str!("../tests/data/issue8.json");
10+
let v: Value = serde_json::from_str(data).unwrap();
11+
12+
let mut schema = infer_from_json(&v, None);
13+
dbg!("BUMP1");
14+
Optimizer {
15+
to_merge_similar_datatypes: true,
16+
to_merge_same_unions: true,
17+
}
18+
.optimize(&mut schema);
19+
dbg!("BUMP2");
20+
let _output = PythonClass {
21+
kind: PythonKind::Dataclass,
22+
to_generate_type_alias_for_union: false,
23+
indentation: Indentation::Space(4),
24+
}
25+
.generate(&schema);
326
}

src/schema/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ pub enum Type {
3737
UUID,
3838
Null,
3939
Missing,
40-
#[default]
4140
Any,
41+
#[default]
42+
Undetermined,
4243
}
4344

4445
pub struct TopdownIter<'a> {

src/target/python_class.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ impl<'i, 'c> Display for Contexted<&'i Type, Context<'c>> {
283283
Type::Null => write!(f, "None"),
284284
Type::Missing => write!(f, "Missing"),
285285
Type::Any => write!(f, "Any"),
286+
Type::Undetermined => unreachable!()
286287
}
287288
}
288289
}

src/target/python_inline.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ impl<'c> Display for Contexted<ArenaIndex, Context<'c>> {
272272
Type::Null => write!(f, "None"),
273273
Type::Missing => write!(f, "Missing"),
274274
Type::Any => write!(f, "Any"),
275+
Type::Undetermined => unreachable!()
275276
}
276277
}
277278
}

src/tests.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,43 @@ fn test_tree_recursion() {
7070
}
7171
.generate(&schema);
7272
}
73+
74+
#[test]
75+
fn test_issue8_1() {
76+
let data = include_str!("../tests/data/issue8.json");
77+
let v: Value = serde_json::from_str(data).unwrap();
78+
79+
let mut schema = infer_from_json(&v, None);
80+
dbg!("BUMP1");
81+
Optimizer {
82+
to_merge_similar_datatypes: true,
83+
to_merge_same_unions: true,
84+
}
85+
.optimize(&mut schema);
86+
dbg!("BUMP2");
87+
let _output = PythonClass {
88+
kind: PythonKind::Dataclass,
89+
to_generate_type_alias_for_union: false,
90+
indentation: Indentation::Space(4),
91+
}
92+
.generate(&schema);
93+
}
94+
95+
#[test]
96+
fn test_issue8_2() {
97+
let data = include_str!("../tests/data/issue8-2.json");
98+
let v: Value = serde_json::from_str(data).unwrap();
99+
100+
let mut schema = infer_from_json(&v, None);
101+
Optimizer {
102+
to_merge_similar_datatypes: true,
103+
to_merge_same_unions: true,
104+
}
105+
.optimize(&mut schema);
106+
let _output = PythonClass {
107+
kind: PythonKind::Dataclass,
108+
to_generate_type_alias_for_union: false,
109+
indentation: Indentation::Space(4),
110+
}
111+
.generate(&schema);
112+
}

0 commit comments

Comments
 (0)