Libraryless. Click here for Pure Java version (16206L/105K).
1 | sclass RealmCopy { |
2 | O dest = mc(); // destination realm |
3 | new IdentityHashMap seen; |
4 | new HashMap<Class> classMap; |
5 | new HashMap<Class, L<Field>> fieldsForClass; |
6 | //IF1<S, Class> classFinder = toIF1(_defaultClassFinder()); |
7 | bool fullCopy; // descend into objects even when they have the same type |
8 | bool nonTransientOnly; // skip transient fields? |
9 | bool handleEnclosingInstancesProperly; // if false, set enclosing instance to null initially |
10 | |
11 | VStack.Computable copyComputation(O o) { |
12 | ret new CopyObject(o); |
13 | } |
14 | |
15 | O copy(O o) { |
16 | ret evalInVStack(copyComputation(o)); |
17 | } |
18 | |
19 | noeq record CopyObject(O o) extends VStackComputableWithStep { |
20 | void step(VStack stack) { |
21 | // null and simple types |
22 | |
23 | if (o == null || o instanceof String || o instanceof Number) { |
24 | ifdef RealmCopy_debug |
25 | print("Simple object: " + o); |
26 | endifdef |
27 | ret with stack.ret(o); |
28 | } |
29 | |
30 | // seen object |
31 | |
32 | O oo = seen.get(o); |
33 | if (oo != null) stack.ret(oo); |
34 | |
35 | dispatchByType(stack, o); |
36 | } |
37 | } |
38 | |
39 | void dispatchByType(VStack stack, O o) { |
40 | if (o cast O[]) |
41 | ret with stack.replace(new CopyObjectArray(o)); |
42 | |
43 | if (o cast Cl) |
44 | if (!overrideCollectionOrMapCopy(o)) |
45 | ret with stack.replace(new CopyCollection(o)); |
46 | |
47 | if (o cast Map) |
48 | if (!overrideCollectionOrMapCopy(o)) |
49 | ret with stack.replace(new CopyMap(o)); |
50 | |
51 | ret with stack.replace(new CopyObjectFieldByField(o)); |
52 | } |
53 | |
54 | noeq record CopyObjectArray(O[] o) extends VStackComputableWithStep { |
55 | O[] out; |
56 | int i; |
57 | |
58 | void step(VStack stack) { |
59 | if (step == 0) { |
60 | out = newObjectArrayOfSameType(o); |
61 | seen.put(o, out); |
62 | ++step; |
63 | } |
64 | |
65 | if (stack.hasSubResult()) |
66 | out[i++] = stack.subResult(); |
67 | |
68 | if (i >= o.length) |
69 | ret with stack.ret(out); |
70 | |
71 | stack.call(new CopyObject(o[i])); |
72 | } |
73 | } |
74 | |
75 | noeq record CopyCollection(Cl o) extends VStackComputableWithStep { |
76 | Cl out; |
77 | Iterator it; |
78 | |
79 | void step(VStack stack) { |
80 | if (step == 0) { |
81 | out = similarEmptyCollection(o); |
82 | seen.put(o, out); |
83 | it = iterator(o); |
84 | ++step; |
85 | } |
86 | |
87 | if (stack.hasSubResult()) |
88 | out.add(stack.subResult()); |
89 | |
90 | if (!it.hasNext()) |
91 | ret with stack.ret(out); |
92 | |
93 | stack.call(new CopyObject(it.next())); |
94 | } |
95 | } |
96 | |
97 | noeq record CopyMap(Map o) extends VStackComputableWithStep { |
98 | Map out; |
99 | Iterator<Map.Entry> it; |
100 | Map.Entry entry; |
101 | O copiedKey; |
102 | |
103 | void step(VStack stack) { |
104 | if (step == 0) { |
105 | out = similarEmptyMap(o); |
106 | seen.put(o, out); |
107 | it = iterator(o.entrySet()); |
108 | ++step; |
109 | } |
110 | |
111 | if (stack.hasSubResult()) { |
112 | if (step == 1) { |
113 | // got the copied key |
114 | copiedKey = stack.subResult(); |
115 | // now copy the value |
116 | stack.call(new CopyObject(entry.getValue())); |
117 | ret with ++step; |
118 | } else { |
119 | // got the copied value - can put into map |
120 | out.put(copiedKey, stack.subResult()); |
121 | step = 1; |
122 | } |
123 | } |
124 | |
125 | if (!it.hasNext()) |
126 | ret with stack.ret(out); |
127 | |
128 | entry = it.next(); |
129 | stack.call(new CopyObject(entry.getKey())); |
130 | } |
131 | } |
132 | |
133 | noeq record CopyObjectFieldByField(O o) extends VStackComputableWithStep { |
134 | S className; |
135 | Class c, destClass; |
136 | O out; |
137 | O enclosing; |
138 | L<Field> fields; |
139 | Iterator<Field> itField; |
140 | Field field; |
141 | Field[] enclosingFields; |
142 | |
143 | void step(VStack stack) { |
144 | if (step == 0) { |
145 | c = o.getClass(); |
146 | |
147 | destClass = classMap.get(c); |
148 | if (destClass == null) { |
149 | destClass = findDestClass(c); |
150 | classMap.put(c, destClass); |
151 | } |
152 | |
153 | if (destClass == c && !fullCopy) |
154 | ret with stack.ret(o); // short cut unless deep copying |
155 | |
156 | // take care of enclosing instance |
157 | |
158 | enclosingFields = thisDollarOneFields(c); |
159 | if (handleEnclosingInstancesProperly |
160 | && nempty(enclosingFields)) |
161 | stack.push(new CopyObject(fieldGet(first(enclosingFields), o))); |
162 | |
163 | ret with step = 1; |
164 | } else if (step == 1) { |
165 | // create new object |
166 | |
167 | try { |
168 | if (stack.hasSubResult()) |
169 | out = unlisted_gen(destClass, stack.subResult()); |
170 | else if (nempty(enclosingFields)) |
171 | out = unlisted_gen(destClass, (O) null); |
172 | else |
173 | out = unlisted_gen(destClass); |
174 | } on fail { |
175 | printVars_str(+c, +destClass, +enclosingFields); |
176 | } |
177 | seen.put(o, out); |
178 | |
179 | fields = getOrCreate(fieldsForClass, c, () -> |
180 | nonTransientOnly |
181 | ? nonStaticNonTransientFieldObjects(o) |
182 | : nonStaticFieldObjects(o)); |
183 | itField = iterator(fields); |
184 | |
185 | ret with ++step; |
186 | } |
187 | |
188 | if (stack.hasSubResult()) { |
189 | ifdef RealmCopy_debug |
190 | printFunctionCall setOpt(out, field.getName(), stack.subResult()); |
191 | endifdef |
192 | setOpt(out, field.getName(), stack.subResult()); |
193 | } |
194 | |
195 | if (!itField.hasNext()) |
196 | ret with stack.ret(out); |
197 | |
198 | field = itField.next(); |
199 | stack.push(new CopyObject(fieldGet(field, o)); |
200 | } |
201 | } |
202 | |
203 | Class findDestClass(Class c) { |
204 | Class destClass = null; |
205 | S className = c.getName(); |
206 | className = loadableUtilsClassNameToMain(className); |
207 | if (!isAnonymousClassName(className)) |
208 | destClass = getClass_vmName_withLoadableUtils(dest, className); |
209 | ret or(destClass, c); |
210 | } |
211 | |
212 | // set to true if you want to copy a map or collection field-by-field |
213 | swappable bool overrideCollectionOrMapCopy(O o) { false; } |
214 | } |
Began life as a copy of #1002777
download show line numbers debug dex old transpilations
Travelled to 4 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, vouqrxazstgt
No comments. add comment
Snippet ID: | #1030885 |
Snippet name: | RealmCopy - successor of quickExport |
Eternal ID of this version: | #1030885/32 |
Text MD5: | 91fe90d3e2dfef86fbddfbfeb04ea547 |
Transpilation MD5: | 61099b57bd3d8361b89b6913ca601a8c |
Author: | stefan |
Category: | eleu / nl |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2021-06-23 23:58:50 |
Source code size: | 5955 bytes / 214 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 259 / 563 |
Version history: | 31 change(s) |
Referenced in: | [show references] |