Datei: NDOEnhancer/Class.cs
Last Commit (9de9fa9)
1 | // |
2 | // Copyright (c) 2002-2016 Mirko Matytschak |
3 | // (www.netdataobjects.de) |
4 | // |
5 | // Author: Mirko Matytschak |
6 | // |
7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated |
8 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation |
9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the |
10 | // Software, and to permit persons to whom the Software is furnished to do so, subject to the following |
11 | // conditions: |
12 | |
13 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions |
14 | // of the Software. |
15 | // |
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED |
17 | // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
18 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF |
19 | // CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
20 | // DEALINGS IN THE SOFTWARE. |
21 | |
22 | |
23 | using System; |
24 | using System.Text.RegularExpressions; |
25 | using System.Xml; |
26 | using System.Collections; |
27 | using System.Reflection; |
28 | using System.IO; |
29 | using System.Diagnostics; |
30 | using System.Data; |
31 | |
32 | using ILCode; |
33 | using NDO; |
34 | |
35 | namespace NDOEnhancer.Patcher |
36 | { |
37 | ····/// <summary> |
38 | ····/// Summary description for Class. |
39 | ····/// </summary> |
40 | ····internal class ClassPatcher |
41 | ····{ |
42 | ········static ClassPatcher() |
43 | ········{ |
44 | ············indTypes = new Hashtable(12); |
45 | ············indTypes.Add("int32", "i4"); |
46 | ············indTypes.Add("bool", "i1"); |
47 | ············indTypes.Add("int8", "i1"); |
48 | ············indTypes.Add("unsigned int8", "u1"); |
49 | ············indTypes.Add("float64", "r8"); |
50 | ············indTypes.Add("float32", "r4"); |
51 | ············indTypes.Add("int16", "i2"); |
52 | ············indTypes.Add("int64", "i8"); |
53 | ············indTypes.Add("char", "u2"); |
54 | ············indTypes.Add("unsigned int16", "u2"); |
55 | ············indTypes.Add("unsigned int32", "u4"); |
56 | ············indTypes.Add("unsigned int64", "i8"); |
57 | ········} |
58 | |
59 | ········public ClassPatcher(····ILClassElement classElement, |
60 | ············NDO.Mapping.NDOMapping mappings, |
61 | ············ClassHashtable externalPersistentBases, |
62 | ············NDOEnhancer.MessageAdapter messages, |
63 | ············IList sortedFields, |
64 | ············IList references, |
65 | ············string oidTypeName) |
66 | ········{ |
67 | ············m_classElement············= classElement; |
68 | ············m_name····················= classElement.getClassFullName(); |
69 | ············m_refName·············· = makeRefName(); |
70 | ············m_nonGenericRefName···· = m_name; |
71 | ············m_references············= references; |
72 | |
73 | ············if (references == null) |
74 | ················throw new ArgumentNullException( "references" ); |
75 | |
76 | ············int p = m_nonGenericRefName.IndexOf('<'); |
77 | ············if (p > -1) |
78 | ················m_nonGenericRefName = m_nonGenericRefName.Substring(0, p); |
79 | |
80 | ············m_persistentBase········= classElement.getBaseFullName(); |
81 | ············this.externalPersistentBases = externalPersistentBases; |
82 | |
83 | ············if (null != externalPersistentBases) |
84 | ············{ |
85 | ················//m_hasPersistentBase····= classElement.hasPersistentBase(temp, typeof(NDOPersistentAttribute)); |
86 | ················m_hasPersistentBase····= (externalPersistentBases.Contains(m_persistentBase)); |
87 | ············} |
88 | |
89 | ············this.m_mappings················= mappings; |
90 | ············this.m_classMapping············= mappings.FindClass(classElement.getMappingName()); |
91 | |
92 | ············if (this.m_classMapping == null) |
93 | ················throw new Exception("Can't find mapping for class " + classElement.getMappingName()); |
94 | |
95 | ············this.messages············= messages; |
96 | ············this.sortedFields = sortedFields; |
97 | ············this.oidTypeName = oidTypeName; |
98 | |
99 | ············for (int i = 0; i < m_references.Count; i++) |
100 | ················((ILReference) m_references[i]).Ordinal = i; |
101 | |
102 | |
103 | ············// sortedFields ist eine flache Ansicht auf die Felder, wie |
104 | ············// sie in der Datenbank sein werden. |
105 | ············// Wir benötigen aber auch die hierarchische Sicht, die die |
106 | ············// Namen der ValueTypes und embedded Objects liefert. |
107 | ············ownFieldsHierarchical = getHierarchicalFieldList(); |
108 | |
109 | ············if (null != externalPersistentBases) |
110 | ············{ |
111 | ················checkPersistentRoot(); |
112 | ················checkNextPersistentBase(); |
113 | ············} |
114 | ········} |
115 | |
116 | ········static private Hashtable indTypes; |
117 | |
118 | ········const string ldarg_0 = "ldarg.0"; |
119 | ········const string ldarg_1 = "ldarg.1"; |
120 | ········private NDOEnhancer.MessageAdapter messages; |
121 | ········private ILClassElement············m_classElement; |
122 | ········private string····················m_name; |
123 | ········private string····················m_refName; |
124 | ········private string····················m_nonGenericRefName; |
125 | ········private string····················m_persistentBase; |
126 | ········private bool····················m_hasPersistentBase; |
127 | ········private NDO.Mapping.NDOMapping····m_mappings; |
128 | ········private string····················oidTypeName; |
129 | ········private NDO.Mapping.Class········m_classMapping; |
130 | |
131 | ········private ArrayList················ownFieldsHierarchical····= new ArrayList(); |
132 | ········private IList····················m_references; |
133 | ········private ArrayList················dirtyDone = new ArrayList(); |
134 | ········private ClassHashtable············externalPersistentBases; |
135 | ········private string····················persistentRoot = null; |
136 | ········private IList····················sortedFields; |
137 | ········private int························mappedFieldCount; |
138 | ········private ClassNode················myClassNode; |
139 | |
140 | |
141 | ········private string makeRefName() |
142 | ········{ |
143 | ············int p = m_name.IndexOf('<'); |
144 | ············if (p == -1) |
145 | ················return m_name; |
146 | ············Ecma335.EcmaGenericParameter genPar = new NDOEnhancer.Ecma335.EcmaGenericParameter(); |
147 | ············genPar.Parse(m_name.Substring(p)); |
148 | ············string newGenPars = "<"; |
149 | ············int count = genPar.Elements.Count; |
150 | ············for (int i = 0; i < count; i++) |
151 | ············{ |
152 | ················string element = genPar.Elements[i]; |
153 | ················newGenPars += "!" + element; |
154 | ················if (i < count - 1) |
155 | ····················newGenPars += ','; |
156 | ············} |
157 | ············return "class " + m_name.Substring(0, p) + newGenPars + '>'; |
158 | ········} |
159 | |
160 | ········private void checkNextPersistentBase() |
161 | ········{ |
162 | ············ClassNode baseClass = getPersistentBaseClassElement(MyClassNode); |
163 | ············if (baseClass == null) |
164 | ················return; |
165 | ············while (!baseClass.IsPersistent) |
166 | ············{ |
167 | ················baseClass = getPersistentBaseClassElement(baseClass); |
168 | ················if (baseClass == null) |
169 | ····················throw new Exception("Internal error #126 in Class.cs"); |
170 | ············} |
171 | ············if (baseClass.AssemblyName != this.m_classElement.getAssemblyName()) |
172 | ················m_persistentBase = "[" + baseClass.AssemblyName + "]" + baseClass.Name; |
173 | ············else |
174 | ················m_persistentBase = baseClass.Name; |
175 | ········} |
176 | |
177 | ········private ArrayList getHierarchicalFieldList() |
178 | ········{ |
179 | ············this.mappedFieldCount = 0;··// count of the flat fields |
180 | ············ArrayList fields = new ArrayList(); |
181 | |
182 | ············if (sortedFields != null) |
183 | ············{ |
184 | ················// Sorted fields is an array of DictionaryEntries |
185 | ················foreach (DictionaryEntry e in sortedFields) |
186 | ················{ |
187 | ····················ILField field = (ILField) e.Value; |
188 | ····················if (field.IsInherited) |
189 | ························continue; |
190 | ····················this.mappedFieldCount++; |
191 | ····················if (field.Parent != null) |
192 | ····················{ |
193 | ························if (!fields.Contains(field.Parent)) |
194 | ····························fields.Add(field.Parent); |
195 | ····················} |
196 | ····················else |
197 | ····················{ |
198 | ························fields.Add(field); |
199 | ····················} |
200 | ················} |
201 | ············} |
202 | ············return fields; |
203 | ········} |
204 | |
205 | |
206 | ········private ClassNode MyClassNode |
207 | ········{ |
208 | ············get |
209 | ············{ |
210 | ················if (myClassNode == null) |
211 | ················{ |
212 | ····················ILClassElement classEl = this.m_classElement; |
213 | ····················string className = classEl.getMappingName(); |
214 | ····················myClassNode = (ClassNode) externalPersistentBases[className]; |
215 | ····················if (myClassNode == null) |
216 | ····················{ |
217 | ························throw new Exception(String.Format("Persistent class {0} must be public.", className)); |
218 | ····················} |
219 | ················} |
220 | ················return myClassNode; |
221 | ············} |
222 | ········} |
223 | |
224 | |
225 | ········private ClassNode getPersistentBaseClassElement(ClassNode parent) |
226 | ········{ |
227 | ············string baseName; |
228 | ············string className = parent.Name; |
229 | ············baseName = parent.BaseName; |
230 | ············if (null == baseName) |
231 | ············{ |
232 | ················if (null == className) |
233 | ····················className = "(null)"; |
234 | ················throw new Exception("Persistent base class name for class " + className + " not found"); |
235 | ············} |
236 | ············return externalPersistentBases[baseName]; |
237 | ········} |
238 | |
239 | |
240 | ········private void checkPersistentRoot() |
241 | ········{ |
242 | ············ClassNode baseClass = MyClassNode; |
243 | ············while (true) |
244 | ············{ |
245 | ················ClassNode newBaseClass = getPersistentBaseClassElement(baseClass); |
246 | ················if (newBaseClass == null) |
247 | ····················break; |
248 | ················baseClass = newBaseClass; |
249 | ············} |
250 | |
251 | ············if (baseClass == MyClassNode) |
252 | ················return; |
253 | ············if (baseClass.AssemblyName != MyClassNode.AssemblyName) |
254 | ················persistentRoot = "[" + baseClass.AssemblyName + "]" + baseClass.Name; |
255 | ············else |
256 | ················persistentRoot = baseClass.Name; |
257 | ········} |
258 | |
259 | |
260 | |
261 | |
262 | |
263 | ········public void |
264 | ············enhance(··) |
265 | ········{ |
266 | ············addInterfaces(m_classElement); |
267 | ············addRelationAttributes(); |
268 | ············addFieldsAndOidAttribute(); |
269 | ············replaceLdfldAndStfld(); |
270 | ············markRelations(); |
271 | ············addFieldAccessors(); |
272 | ············patchConstructor(); |
273 | ············addMethods(); |
274 | ············addMetaClass(); |
275 | ········} |
276 | |
277 | |
278 | ········private void |
279 | ············addInterfaces(ILClassElement parent) |
280 | ········{ |
281 | ············if ( ! m_hasPersistentBase ) |
282 | ············{ |
283 | ················parent.AddImplements( new string[] { "[NDO]NDO.IPersistenceCapable", "[NDO]NDO.IPersistentObject" } ); |
284 | ············} |
285 | ········} |
286 | |
287 | ········public void |
288 | ············addFieldsAndOidAttribute() |
289 | ········{ |
290 | ············ILMethodElement.Iterator methodIter = m_classElement.getMethodIterator(); |
291 | ············ILMethodElement firstMethod = methodIter.getNext(); |
292 | //············m_classElement.insertFieldBefore(".field private static string[] _ndoFieldNames", firstMethod); |
293 | ············ |
294 | ············//if (this.oidTypeName != null)··// Assembly has an OidType |
295 | ············//{ |
296 | ············//····if (MyClassNode.OidTypeName == null····················// Class hasn't an OidType |
297 | ············//········&& this.m_classMapping.Oid.FieldName == null)·· // Class hasn't an oid field |
298 | ············//····{ |
299 | ············//········ILElementIterator it = m_classElement.getAllIterator(false); |
300 | ············//········ILElement firstEl = it.getNext(); |
301 | ············//········string bytes = ILString.CodeBytes(oidTypeName); |
302 | ············//········string line = string.Format($".custom instance void [NDO]NDO.NDOOidTypeAttribute::.ctor(class {Corlib.Name}System.Type) = ( 01 00 {0} 00 00 )", bytes); |
303 | ············//········firstEl.insertBefore(new ILCustomElement(line, m_classElement)); |
304 | ············//····} |
305 | ············//} |
306 | |
307 | ············if (··m_hasPersistentBase ) |
308 | ················return; |
309 | ············ |
310 | ············m_classElement.insertFieldBefore( ".field family class [NDO]NDO.LoadState _ndoLoadState", firstMethod); |
311 | ············m_classElement.insertFieldBefore( ".field family valuetype [NDO]NDO.NDOObjectState _ndoObjectState", firstMethod ); |
312 | ············m_classElement.insertFieldBefore( ".field family class [NDO]NDO.ObjectId _ndoObjectId", firstMethod ); |
313 | ············m_classElement.insertFieldBefore( ".field family notserialized class [NDO]NDO.IStateManager _ndoSm", firstMethod ); |
314 | ············m_classElement.insertFieldBefore( $".field family notserialized valuetype {Corlib.Name}System.Guid _ndoTimeStamp", firstMethod ); |
315 | ········} |
316 | |
317 | |
318 | ········private void addRelationAttributes() |
319 | ········{ |
320 | ············// Relations with generic containers and with multiplicity 1 can omit |
321 | ············// the NDORelation attribute. We insert the attribute here. |
322 | ············ILFieldElement.Iterator it = m_classElement.getFieldIterator(); |
323 | ············ILFieldElement fieldElement; |
324 | ············for (fieldElement = (ILFieldElement)it.getFirst(); fieldElement != null; fieldElement = (ILFieldElement)it.getNext()) |
325 | ············{ |
326 | ················foreach (Patcher.ILReference reference in this.m_references) |
327 | ················{ |
328 | ····················if (reference.CleanName == fieldElement.getName()) |
329 | ····················{ |
330 | ························bool customFound = false; |
331 | ························for (ILElement custElement = fieldElement.getSuccessor(); custElement != null; custElement = custElement.getSuccessor()) |
332 | ························{ |
333 | ····························if (!custElement.getLine(0).StartsWith(".custom")) |
334 | ································break; |
335 | ····························if (custElement.getLine(0).IndexOf("NDORelationAttribute") > -1) |
336 | ····························{ |
337 | ································customFound = true; |
338 | ································break; |
339 | ····························} |
340 | ························} |
341 | ························if (!customFound) |
342 | ························{ |
343 | ····························fieldElement.insertAfter(new ILCustomElement(".custom instance void [NDO]NDO.NDORelationAttribute::.ctor() = ( 01 00 00 00 )", this.m_classElement)); |
344 | ························} |
345 | ························break; |
346 | ····················} |
347 | ················} |
348 | ············} |
349 | ········} |
350 | |
351 | ········private bool |
352 | ············replaceValueTypeAccessorCall(ILStatementElement statementElement, string line) |
353 | ········{ |
354 | ············foreach ( ILField field in ownFieldsHierarchical ) |
355 | ············{ |
356 | ················if (!field.Valid) |
357 | ····················continue; |
358 | ················if (field.IsEmbeddedType) |
359 | ····················continue; |
360 | ················if (field.IsValueType) |
361 | ················{ |
362 | ····················string pureTypeName = field.ILType.Substring(10); |
363 | ····················if (line.StartsWith("call")) |
364 | ····················{ |
365 | ························if (line.IndexOf(pureTypeName + "::set_") > -1) |
366 | ························{ |
367 | ····························// Diese Statements landen in umgekehrter Reihenfolge in der Funktion |
368 | ····························statementElement.insertAfter(new ILStatementElement(callMarkDirty())); |
369 | ····························statementElement.insertAfter(new ILStatementElement(ldarg_0)); |
370 | ····························return true; |
371 | ························} |
372 | ····················} |
373 | ················} |
374 | ············} |
375 | ············return false; |
376 | ········} |
377 | |
378 | |
379 | ········ |
380 | ········private bool |
381 | ············replaceLdfldAndStfldForLine(ILStatementElement statementElement, string line) |
382 | ········{ |
383 | ············// At this point it is clear, that the line starts with ldfld or stfld |
384 | ············bool needsMaxstackAdjustment = false; |
385 | |
386 | ············//Durchsuche alle privaten, persistenten Felder |
387 | ············foreach ( ILField field in ownFieldsHierarchical ) |
388 | ············{ |
389 | ················if (!field.Valid) |
390 | ····················continue; |
391 | |
392 | ················// The line might contain a ldfld to a member of a nested class |
393 | ················// so make sure the line contains a reference to m_refName class |
394 | ················if (line.IndexOf( m_refName + "::" ) == -1) |
395 | ····················return false; |
396 | |
397 | ················int p = line.IndexOf("::"); |
398 | ················string nameInLine = line.Substring(p + 2).Replace("'", string.Empty); |
399 | |
400 | ················if (nameInLine == field.Name.Replace("'", string.Empty)) |
401 | ················{ |
402 | ····················if ( line.StartsWith( "ldfld" ) ) |
403 | ····················{ |
404 | ························NDO.Mapping.Field fieldMapping = this.m_classMapping.FindField(nameInLine); |
405 | ························if (fieldMapping == null) |
406 | ························{ |
407 | ····························messages.WriteLine("Warning: can't determine ordinal for field " + m_name + "." + nameInLine); |
408 | ····························messages.WriteInsertedLine("Fetch Groups don't work with this field.");···························· |
409 | ····························statementElement.insertBefore(new ILStatementElement("dup")); |
410 | ····························statementElement.insertBefore(new ILStatementElement(callLoadData())); |
411 | ····························needsMaxstackAdjustment = true; |
412 | ························} |
413 | ························else |
414 | ························{ |
415 | ····························statementElement.insertBefore(new ILStatementElement("dup"));··// this argument |
416 | ····························statementElement.insertBefore(new ILStatementElement("call······ instance void " + m_refName + "::" + getAccName("ndoget_", field.Name) + "()")); |
417 | ····························// the ldfld[a] statement remains in the code |
418 | ····························needsMaxstackAdjustment = true; |
419 | ························} |
420 | ····················} |
421 | ····················else if (line.StartsWith("stfld")) |
422 | ····················{ |
423 | ························statementElement.setFirstLine("call······ instance void " + m_refName + "::" + getAccName("ndoset_", field.Name) + '(' + field.ILType + ')'); |
424 | ····················} |
425 | ····················return needsMaxstackAdjustment; |
426 | ················} |
427 | |
428 | ············} // foreach ( Field field in ownFieldsHierarchical ) |
429 | ············return false; |
430 | ········} |
431 | ···· |
432 | ········private void |
433 | ············replaceLdfldAndStfld() |
434 | ········{ |
435 | ············ILMethodElement.Iterator methodIter = m_classElement.getMethodIterator(); |
436 | ·················· |
437 | ············for ( ILMethodElement methodElement = methodIter.getNext(); null != methodElement; methodElement = methodIter.getNext() ) |
438 | ············{ |
439 | ················bool adjustMaxStack = false; |
440 | |
441 | ················if ( methodElement.isConstructor() ) |
442 | ····················continue; |
443 | |
444 | ················//string name = methodElement.getLine(methodElement.getLineCount() - 1); |
445 | |
446 | ················ILStatementElement.Iterator statementIter = methodElement.getStatementIterator(true); |
447 | |
448 | ················// We'll change the collection of statements, so we need a new collection |
449 | ················// to iterate through. |
450 | ················IList statements = new ArrayList(); |
451 | ················for ( ILStatementElement statementElement = statementIter.getNext(); null != statementElement; statementElement = statementIter.getNext() ) |
452 | ················{ |
453 | ····················statements.Add(statementElement); |
454 | ················} |
455 | |
456 | ················foreach ( ILStatementElement statementElement in statements ) |
457 | ················{ |
458 | ····················bool result; |
459 | ····················string line = ILElement.stripLabel(statementElement.getLine( 0 )); |
460 | ····················if ( line.StartsWith( "ldfld" ) |
461 | ························||···· line.StartsWith( "stfld" ) ) |
462 | ····················{ |
463 | ························result = replaceLdfldAndStfldForLine(statementElement, line); |
464 | ························adjustMaxStack = adjustMaxStack || result; |
465 | ····················} |
466 | ····················// There is a lack in the logic. If a set-Accessor of a value type |
467 | ····················// is called, we can't determine statically the parent object of the value type. |
468 | ····················// So we aren't able to set the right object to the dirty state. |
469 | ················} |
470 | ················if (adjustMaxStack) |
471 | ················{ |
472 | ····················int newMaxStack = this.getMaxStackVal(methodElement) + 1; |
473 | ····················this.adjustMaxStackVal(methodElement, newMaxStack); |
474 | ····················MakeLongBranches(methodElement); |
475 | ················} |
476 | ············} // ILMethodElement |
477 | ········}········ |
478 | |
479 | ········string loadStateManager() |
480 | ········{ |
481 | ············if (m_hasPersistentBase) |
482 | ················return "ldfld······class [NDO]NDO.IStateManager " + persistentRoot + "::_ndoSm"; |
483 | ············else |
484 | ················return "ldfld······class [NDO]NDO.IStateManager " + m_refName+ "::_ndoSm"; |
485 | ········} |
486 | |
487 | ········string callLoadData() |
488 | ········{ |
489 | ············if (m_hasPersistentBase) |
490 | ················return "call······ instance void " + persistentRoot + "::NDOLoadData()"; |
491 | ············else |
492 | ················return "call······ instance void " + m_refName + "::NDOLoadData()"; |
493 | ········} |
494 | |
495 | ········string callMarkDirty() |
496 | ········{ |
497 | ············if (m_hasPersistentBase) |
498 | ················return "call······ instance void " + persistentRoot + "::NDOMarkDirty()"; |
499 | ············else |
500 | ················return "call······ instance void " + m_refName + "::NDOMarkDirty()"; |
501 | ········} |
502 | |
503 | ········string loadObjectId() |
504 | ········{ |
505 | ············if (m_hasPersistentBase) |
506 | ················return "ldfld······class [NDO]NDO.ObjectId " + persistentRoot + "::_ndoObjectId"; |
507 | ············else |
508 | ················return "ldfld······class [NDO]NDO.ObjectId " + m_refName + "::_ndoObjectId"; |
509 | ········} |
510 | ········string storeObjectId() |
511 | ········{ |
512 | ············if (m_hasPersistentBase) |
513 | ················return "stfld······class [NDO]NDO.ObjectId " + persistentRoot + "::_ndoObjectId"; |
514 | ············else |
515 | ················return "stfld······class [NDO]NDO.ObjectId " + m_refName + "::_ndoObjectId"; |
516 | ········} |
517 | |
518 | ········string loadObjectState() |
519 | ········{ |
520 | ············if (m_hasPersistentBase) |
521 | ················return "ldfld······valuetype [NDO]NDO.NDOObjectState " + persistentRoot + "::_ndoObjectState"; |
522 | ············else |
523 | ················return "ldfld······valuetype [NDO]NDO.NDOObjectState " + m_refName + "::_ndoObjectState"; |
524 | ········} |
525 | ········string storeObjectState() |
526 | ········{ |
527 | ············if (m_hasPersistentBase) |
528 | ················return "stfld······valuetype [NDO]NDO.NDOObjectState " + persistentRoot + "::_ndoObjectState"; |
529 | ············else |
530 | ················return "stfld······valuetype [NDO]NDO.NDOObjectState " + m_refName + "::_ndoObjectState"; |
531 | ········} |
532 | |
533 | ········string loadTimeStamp() |
534 | ········{ |
535 | ············if (m_hasPersistentBase) |
536 | ················return $"ldfld······valuetype {Corlib.Name}System.Guid " + persistentRoot + "::_ndoTimeStamp"; |
537 | ············else |
538 | ················return $"ldfld······valuetype {Corlib.Name}System.Guid " + m_refName + "::_ndoTimeStamp"; |
539 | ········} |
540 | ········string storeTimeStamp() |
541 | ········{ |
542 | ············if (m_hasPersistentBase) |
543 | ················return $"stfld······valuetype {Corlib.Name}System.Guid " + persistentRoot + "::_ndoTimeStamp"; |
544 | ············else |
545 | ················return $"stfld······valuetype {Corlib.Name}System.Guid " + m_refName + "::_ndoTimeStamp"; |
546 | ········} |
547 | |
548 | |
549 | ········void addDirtyStatements(ILMethodElement methodElement, bool markDirty) |
550 | ········{ |
551 | ············if (dirtyDone.Contains(methodElement)) |
552 | ················return; |
553 | ············adjustMaxStackVal(methodElement, 2); |
554 | |
555 | ············ILStatementElement.Iterator statementIter = methodElement.getStatementIterator(); |
556 | ············ILStatementElement beforeElement = statementIter.getNext(); |
557 | ············while(!beforeElement.getLine(0).StartsWith("IL")) |
558 | ················beforeElement = statementIter.getNext(); |
559 | ············ILStatementElement el = new ILStatementElement(); |
560 | ············el.addLine("ldarg.0"); |
561 | ············el.addLine(loadStateManager()); |
562 | ············el.addLine("brfalse.s··NoSm"); |
563 | ············el.addLine("ldarg.0"); |
564 | ············el.addLine(loadStateManager()); |
565 | ············el.addLine("ldarg.0"); |
566 | ············if (markDirty) |
567 | ················el.addLine("callvirt·· instance void [NDO]NDO.IStateManager::MarkDirty(class [NDO]NDO.IPersistenceCapable)"); |
568 | ············else |
569 | ················el.addLine("callvirt·· instance void [NDO]NDO.IStateManager::LoadData(class [NDO]NDO.IPersistenceCapable)"); |
570 | ············el.addLine("NoSm:"); |
571 | ············beforeElement.insertBefore(el); |
572 | ············dirtyDone.Add(methodElement); |
573 | ········} |
574 | |
575 | |
576 | |
577 | |
578 | ········class ReferenceAndElement |
579 | ········{ |
580 | ············public ReferenceAndElement(ILReference r, ILElement e) |
581 | ············{ |
582 | ················this.r = r; |
583 | ················this.e = e; |
584 | ············} |
585 | ············public ILReference r; |
586 | ············public ILElement e; |
587 | ········} |
588 | |
589 | |
590 | |
591 | ········/* |
592 | ················void addAddCalls(IList addEntries, ref int lbl) |
593 | ················{ |
594 | |
595 | ····················foreach (ReferenceAndElement refEl in addEntries) |
596 | ····················{ |
597 | ························int mark = lbl++; |
598 | ························ILElement elToInsert = refEl.e.getPredecessor(); |
599 | ························if (null == elToInsert) |
600 | ····························throw new Exception("Ungültiger IL-Code bei IList.Add (kein Vorgänger)"); |
601 | ························ILElement elParameter = refEl.e.getSuccessor(); |
602 | ························if (null == elParameter) |
603 | ····························throw new Exception("Ungültiger IL-Code bei IList.Add (kein Nachfolger)"); |
604 | |
605 | ························elToInsert.insertBefore(new ILStatementElement(ldarg_0)); |
606 | |
607 | ························elToInsert.insertBefore(new ILStatementElement(loadStateManager())); |
608 | ························elToInsert.insertBefore(new ILStatementElement("brfalse.s··Nosm" + mark.ToString())); |
609 | |
610 | ························elToInsert.insertBefore(new ILStatementElement(ldarg_0)); |
611 | ························elToInsert.insertBefore(new ILStatementElement(loadStateManager())); |
612 | ························elToInsert.insertBefore(new ILStatementElement(ldarg_0)); |
613 | ························elToInsert.insertBefore(new ILStatementElement(@"ldstr······""" + refEl.r.CleanName + @"""")); |
614 | ························elToInsert.insertBefore(new ILStatementElement(stripILx(elParameter.getLine(0)))); |
615 | ························elToInsert.insertBefore(new ILStatementElement(@"callvirt·· instance void [NDO]NDO.IStateManager::AddRelatedObject(class [NDO]NDO.IPersistenceCapable, string, class [NDO]NDO.IPersistenceCapable)")); |
616 | ························elToInsert.insertBefore(new ILStatementElement("Nosm" + mark.ToString() + ":")); |
617 | ····················} |
618 | |
619 | ················} |
620 | ········ |
621 | ················void addRemoveCalls(IList removeEntries, ref int lbl) |
622 | ················{ |
623 | ····················foreach (ReferenceAndElement refEl in removeEntries) |
624 | ····················{ |
625 | ························int mark = lbl++; |
626 | ························ILElement elToInsert = refEl.e.getPredecessor(); |
627 | ························if (null == elToInsert) |
628 | ····························throw new Exception("Ungültiger IL-Code bei IList.Add (kein Vorgänger)"); |
629 | ························ILElement elParameter = refEl.e.getSuccessor(); |
630 | ························if (null == elParameter) |
631 | ····························throw new Exception("Ungültiger IL-Code bei IList.Add (kein Nachfolger)"); |
632 | |
633 | ························elToInsert.insertBefore(new ILStatementElement(ldarg_0)); |
634 | ························elToInsert.insertBefore(new ILStatementElement(loadStateManager())); |
635 | ························elToInsert.insertBefore(new ILStatementElement("brfalse.s··Nosm"+ mark.ToString())); |
636 | |
637 | ························elToInsert.insertBefore(new ILStatementElement(ldarg_0)); |
638 | ························elToInsert.insertBefore(new ILStatementElement(loadStateManager())); |
639 | ························elToInsert.insertBefore(new ILStatementElement(ldarg_0)); |
640 | ························elToInsert.insertBefore(new ILStatementElement(@"ldstr······""" + refEl.r.CleanName + @"""")); |
641 | ························elToInsert.insertBefore(new ILStatementElement(stripILx(elParameter.getLine(0)))); |
642 | ························elToInsert.insertBefore(new ILStatementElement(@"callvirt·· instance void [NDO]NDO.IStateManager::RemoveRelatedObject(class [NDO]NDO.IPersistenceCapable, string, class [NDO]NDO.IPersistenceCapable)")); |
643 | ························elToInsert.insertBefore(new ILStatementElement("Nosm"+ mark.ToString() + ":")); |
644 | ····················} |
645 | ················} |
646 | ········ |
647 | ················void addClearCalls(IList clearEntries, ref int lbl) |
648 | ················{ |
649 | ····················foreach (ReferenceAndElement refEl in clearEntries) |
650 | ····················{ |
651 | ························int mark = lbl++; |
652 | ························ILElement elToInsert = refEl.e.getPredecessor(); |
653 | ························if (null == elToInsert) |
654 | ····························throw new Exception("Ungültiger IL-Code bei IList.Clear (kein Vorgänger)"); |
655 | ························ILElement elParameter = refEl.e; |
656 | |
657 | ························elToInsert.insertBefore(new ILStatementElement(ldarg_0)); |
658 | |
659 | ························elToInsert.insertBefore(new ILStatementElement(loadStateManager())); |
660 | ························elToInsert.insertBefore(new ILStatementElement("brfalse.s··Nosm" + mark.ToString())); |
661 | |
662 | ························elToInsert.insertBefore(new ILStatementElement(ldarg_0)); |
663 | ························elToInsert.insertBefore(new ILStatementElement(loadStateManager())); |
664 | ························elToInsert.insertBefore(new ILStatementElement(ldarg_0)); |
665 | |
666 | ························elToInsert.insertBefore(new ILStatementElement(@"ldstr······""" + refEl.r.CleanName + @"""")); |
667 | ························elToInsert.insertBefore(new ILStatementElement(ldarg_0)); |
668 | ························elToInsert.insertBefore(new ILStatementElement(stripILx(elParameter.getLine(0)))); |
669 | ························elToInsert.insertBefore(new ILStatementElement(@"callvirt·· instance void [NDO]NDO.IStateManager::RemoveRangeRelatedObjects(class [NDO]NDO.IPersistenceCapable, string, class {Corlib.Name}System.Collections.IList)")); |
670 | ························elToInsert.insertBefore(new ILStatementElement("Nosm" + mark.ToString() + ":")); |
671 | ····················} |
672 | ················} |
673 | |
674 | ················void addRemoveAtCalls(IList removeAtEntries, ref int lbl) |
675 | ················{ |
676 | ····················foreach (ReferenceAndElement refEl in removeAtEntries) |
677 | ····················{ |
678 | ························int mark = lbl++; |
679 | ························ILElement elToInsert = refEl.e.getPredecessor(); |
680 | ························if (null == elToInsert) |
681 | ····························throw new Exception("Ungültiger IL-Code bei IList.RemoveAt (kein Vorgänger)"); |
682 | ························ILElement elParameter = refEl.e.getSuccessor(); |
683 | ························if (null == elParameter) |
684 | ····························throw new Exception("Ungültiger IL-Code bei IList.RemoveAt (kein Nachfolger)"); |
685 | ························elToInsert.insertBefore(new ILStatementElement(ldarg_0)); |
686 | |
687 | ························elToInsert.insertBefore(new ILStatementElement(loadStateManager())); |
688 | ························elToInsert.insertBefore(new ILStatementElement("brfalse.s··Nosm" + mark.ToString())); |
689 | |
690 | ························elToInsert.insertBefore(new ILStatementElement(ldarg_0)); |
691 | ························elToInsert.insertBefore(new ILStatementElement(loadStateManager())); |
692 | ························elToInsert.insertBefore(new ILStatementElement(ldarg_0)); |
693 | |
694 | ························elToInsert.insertBefore(new ILStatementElement(@"ldstr······""" + refEl.r.CleanName + @"""")); |
695 | |
696 | ························elToInsert.insertBefore(new ILStatementElement(ldarg_0)); |
697 | ························elToInsert.insertBefore(new ILStatementElement(stripILx(refEl.e.getLine(0)))); |
698 | ························elToInsert.insertBefore(new ILStatementElement(stripILx(elParameter.getLine(0)))); |
699 | ························elToInsert.insertBefore(new ILStatementElement("callvirt·· instance object {Corlib.Name}System.Collections.IList::get_Item(int32)")); |
700 | ························elToInsert.insertBefore(new ILStatementElement("castclass··[NDO]NDO.IPersistenceCapable")); |
701 | ························elToInsert.insertBefore(new ILStatementElement("callvirt·· instance void [NDO]NDO.IStateManager::RemoveRelatedObject(class [NDO]NDO.IPersistenceCapable, string, class [NDO]NDO.IPersistenceCapable)")); |
702 | ························elToInsert.insertBefore(new ILStatementElement("Nosm" + mark.ToString() + ":")); |
703 | ····················} |
704 | ················} |
705 | |
706 | ········ |
707 | ················void addInsertCalls(IList insertEntries, ref int lbl) |
708 | ················{ |
709 | ····················foreach (ReferenceAndElement refEl in insertEntries) |
710 | ····················{ |
711 | ························int mark = lbl++; |
712 | ························ILElement elToInsert = refEl.e.getPredecessor(); |
713 | ························if (null == elToInsert) |
714 | ····························throw new Exception("Ungültiger IL-Code bei IList.Add (kein Vorgänger)"); |
715 | ························ILElement elParameter = refEl.e.getSuccessor(); |
716 | ························if (null == elParameter) |
717 | ····························throw new Exception("Ungültiger IL-Code bei IList.Add (kein Nachfolger 1)"); |
718 | ························elParameter = elParameter.getSuccessor(); |
719 | ························if (null == elParameter) |
720 | ····························throw new Exception("Ungültiger IL-Code bei IList.Add (kein Nachfolger 2)"); |
721 | |
722 | ························elToInsert.insertBefore(new ILStatementElement(ldarg_0)); |
723 | |
724 | ························elToInsert.insertBefore(new ILStatementElement(loadStateManager())); |
725 | ························elToInsert.insertBefore(new ILStatementElement("brfalse.s··Nosm" + mark.ToString())); |
726 | |
727 | ························elToInsert.insertBefore(new ILStatementElement(ldarg_0)); |
728 | ························elToInsert.insertBefore(new ILStatementElement(loadStateManager())); |
729 | ························elToInsert.insertBefore(new ILStatementElement(ldarg_0)); |
730 | |
731 | ························elToInsert.insertBefore(new ILStatementElement(@"ldstr······""" + refEl.r.CleanName + @"""")); |
732 | ························elToInsert.insertBefore(new ILStatementElement(stripILx(elParameter.getLine(0)))); |
733 | |
734 | ························elToInsert.insertBefore(new ILStatementElement("callvirt·· instance void [NDO]NDO.IStateManager::AddRelatedObject(class [NDO]NDO.IPersistenceCapable, string, class [NDO]NDO.IPersistenceCapable)")); |
735 | ························elToInsert.insertBefore(new ILStatementElement("Nosm" + mark.ToString() + ":")); |
736 | |
737 | ····················} |
738 | ················} |
739 | ········*/ |
740 | ········private void |
741 | ············adjustMaxStackVal(ILMethodElement methodElement, int maxStackVal) |
742 | ········{ |
743 | ············ILElement msEl = methodElement.findElement(".maxstack"); |
744 | ············if (null == msEl) |
745 | ················throw new Exception("Method " + m_refName + "." + methodElement.getName() + " doesn't have a .maxstack statement."); |
746 | ············string msline = msEl.getLine(0); |
747 | ············string num = msline.Substring(msline.IndexOf(".maxstack") + 9); |
748 | ············if (int.Parse(num) < maxStackVal) |
749 | ············{ |
750 | ················msEl.remove(); |
751 | ················msEl = new ILStatementElement(); |
752 | ················msEl.addLine(".maxstack " + maxStackVal.ToString()); |
753 | ················methodElement.getStatementIterator().getNext().insertBefore(msEl); |
754 | ············} |
755 | ········} |
756 | |
757 | ········private void |
758 | ············addToMaxStackVal(ILMethodElement methodElement, int diff) |
759 | ········{ |
760 | ············ILElement msEl = methodElement.findElement(".maxstack"); |
761 | ············if (null == msEl) |
762 | ················throw new Exception("Method " + m_refName + "." + methodElement.getName() + " doesn't have a .maxstack statement."); |
763 | ············string msline = msEl.getLine(0); |
764 | ············string num = msline.Substring(msline.IndexOf(".maxstack") + 9); |
765 | ············int newNum = int.Parse(num) + diff; |
766 | ············ILStatementElement newEl = new ILStatementElement(); |
767 | ············msEl.insertBefore(newEl); |
768 | ············msEl.remove(); |
769 | ············newEl.addLine(".maxstack " + newNum.ToString()); |
770 | ········} |
771 | |
772 | ········private int |
773 | ············getMaxStackVal(ILMethodElement methodElement) |
774 | ········{ |
775 | ············ILElement msEl = methodElement.findElement(".maxstack"); |
776 | ············if (null == msEl) |
777 | ················throw new Exception("Method " + m_refName + "." + methodElement.getName() + " doesn't have a .maxstack statement."); |
778 | ············string msline = msEl.getLine(0); |
779 | ············string num = msline.Substring(msline.IndexOf(".maxstack") + 9); |
780 | ············return (int.Parse(num)); |
781 | ········} |
782 | |
783 | |
784 | ········private void addLocalVariable(ILMethodElement methodElement, string name, string ilType) |
785 | ········{ |
786 | ············ILLocalsElement localsElement = methodElement.getLocals(); |
787 | ············if (localsElement == null) |
788 | ············{ |
789 | ················localsElement = new ILLocalsElement(".locals init ([0] " + ilType + " " + name + ")", methodElement); |
790 | ················ILElement maxstackElement = methodElement.findElement(".maxstack"); |
791 | ················if (maxstackElement == null) |
792 | ····················throw new Exception("Method " + m_refName + "." + methodElement.getName() + " doesn't have a .maxstack statement."); |
793 | ················maxstackElement.insertAfter(localsElement); |
794 | ················return; |
795 | ············} |
796 | ············string line = localsElement.getAllLines(); |
797 | ············Regex regex = new Regex(@"\[(\d+)\]"); |
798 | ············MatchCollection matches = regex.Matches(line); |
799 | ············ILLocalsElement newLocalsElement; |
800 | ············int lastBracketPos = line.LastIndexOf(")"); |
801 | ············line = line.Substring(0, lastBracketPos); |
802 | ············if (matches.Count == 0) |
803 | ············{ |
804 | ················line += String.Format(", {0} {1})", ilType, name); |
805 | ············} |
806 | ············else |
807 | ············{ |
808 | ················int lastOrdinal = int.Parse(matches[matches.Count - 1].Groups[1].Value) + 1; |
809 | ················line += String.Format(", [{0}] {1} {2})", lastOrdinal, ilType, name); |
810 | ············} |
811 | ············newLocalsElement = new ILLocalsElement(line, methodElement); |
812 | ············localsElement.insertBefore(newLocalsElement); |
813 | ············localsElement.remove(); |
814 | ········} |
815 | |
816 | ········public void |
817 | ············markRelations() |
818 | ········{ |
819 | ············if (m_references.Count == 0) |
820 | ················return; |
821 | |
822 | ············ILMethodElement.Iterator methodIter = m_classElement.getMethodIterator(); |
823 | ············ListAccessManipulator accessManipulator = new ListAccessManipulator(this.m_classElement.getAssemblyName()); |
824 | ············ |
825 | ············for ( ILMethodElement methodElement = methodIter.getNext(); null != methodElement; methodElement = methodIter.getNext() ) |
826 | ············{ |
827 | ················bool needsContainerStack = false; |
828 | ················bool methodTouched = false; |
829 | ················string mname = methodElement.getName(); |
830 | ················if ( methodElement.isConstructor() ) |
831 | ····················continue; |
832 | |
833 | ················ILStatementElement.Iterator statementIter = methodElement.getStatementIterator(true); |
834 | |
835 | ················ArrayList statements = new ArrayList(100); |
836 | ················ILElement firstElement = null; |
837 | ················ILLocalsElement localsElement = methodElement.getLocals(); |
838 | ················Hashtable listReflectors = new Hashtable(); |
839 | ················string line; |
840 | ················int pos; |
841 | |
842 | ················// Wir kopieren die Statements in eine extra ArrayList, weil die originale |
843 | ················// Liste mit InsertBefore manipuliert wird. |
844 | ················for ( ILStatementElement statementElement = statementIter.getNext(); null != statementElement; statementElement = statementIter.getNext() ) |
845 | ················{ |
846 | ····················statements.Add(statementElement); |
847 | ····················line = statementElement.getLine( 0 ); |
848 | ····················if (firstElement == null && line.StartsWith("IL_")) |
849 | ························firstElement = statementElement; |
850 | ················} |
851 | ················ILElement lineEl = firstElement; |
852 | ················if (firstElement != null) |
853 | ················{ |
854 | ····················lineEl = firstElement.getPredecessor();···················· |
855 | ····················if (lineEl != null && lineEl.getLine(0).StartsWith(".line")) |
856 | ························firstElement = lineEl; |
857 | ················} |
858 | |
859 | ················foreach ( ILStatementElement statementElement in statements ) |
860 | ················{ |
861 | ····················line = statementElement.getLine( 0 ); |
862 | ····················pos··= line.IndexOf( ":" ); |
863 | ····················line = line.Substring( pos + 1 ).Trim(); |
864 | ····················int p = line.IndexOf("::"); |
865 | |
866 | ····················string cleanName = null; |
867 | ····················if (p > -1) |
868 | ························cleanName = line.Substring(p + 2).Replace("'", string.Empty); |
869 | |
870 | ····················if ( line.StartsWith( "ldfld" ) && -1 < line.IndexOf( m_refName + "::" )) |
871 | ····················{ |
872 | ························//Durchsuche alle privaten, persistenten Felder |
873 | ························foreach ( ILReference reference in m_references) |
874 | ························{ |
875 | ····························if (reference.IsInherited) |
876 | ································continue; |
877 | ····························if (reference.CleanName == cleanName && (-1 < line.IndexOf( m_refName + "::"))) |
878 | ····························{ |
879 | ································if (reference.Is1to1) |
880 | ································{ |
881 | ····································statementElement.setFirstLine("call······ instance " + reference.ILType + " " + m_refName + "::" + getAccName("ndoget_", reference.Name) + "()"); |
882 | ································} |
883 | ································else |
884 | ································{ |
885 | ····································if (!listReflectors.Contains(reference.FieldType)) |
886 | ········································listReflectors.Add(reference.FieldType, ListReflectorFactory.CreateListReflector(reference.FieldType)); |
887 | ····································statementElement.insertBefore(new ILStatementElement("dup")); |
888 | ····································IList elements = new ArrayList(); |
889 | ····································elements.Add(new ILStatementElement("ldloc __ndocontainertable")); |
890 | ····································elements.Add(new ILStatementElement(@"ldstr """ + reference.CleanName + @"""")); |
891 | ····································elements.Add(new ILStatementElement($"call······ object [NDO]NDO._NDOContainerStack::RegisterContainer(object,object,class {Corlib.Name}System.Collections.Hashtable,string)")); |
892 | ····································elements.Add(new ILStatementElement("castclass " + new ReflectedType(reference.FieldType, this.m_classElement.getAssemblyName()).QuotedILName)); |
893 | ····································// Achtung: insertAfter benötigt die Statements in umgekehrter Reihenfolge |
894 | ····································for (int i = elements.Count - 1; i >=0; i--) |
895 | ········································statementElement.insertAfter((ILStatementElement)elements[i]); |
896 | ····································needsContainerStack = true; |
897 | ····································break; |
898 | ································} |
899 | ····························} |
900 | ························} |
901 | ····················} |
902 | ····················if ( line.StartsWith( "stfld" ) ) |
903 | ····················{ |
904 | ························//Durchsuche alle Relationen |
905 | ························foreach (ILReference reference in m_references) |
906 | ························{ |
907 | ····························if (reference.IsInherited) |
908 | ································continue; |
909 | ····························if (reference.CleanName == cleanName) |
910 | ····························{ |
911 | ································if ( -1 < line.IndexOf( m_refName + "::")) |
912 | ································{ |
913 | ····································statementElement.setFirstLine("call······ instance void " + m_refName + "::" + getAccName("ndoset_", reference.Name) + "(" + reference.ILType +")"); |
914 | ····································break; |
915 | ································} |
916 | ····························} |
917 | ························} |
918 | ····················} |
919 | ················} |
920 | ················if (needsContainerStack) |
921 | ················{ |
922 | ····················foreach ( ILStatementElement statementElement in statements ) |
923 | ····················{ |
924 | ························line = ILElement.stripLabel( statementElement.getLine( 0 ) ); |
925 | |
926 | ························if ( line.StartsWith( "callvirt" ) || line.StartsWith("call ") ) |
927 | ························{ |
928 | ································if (accessManipulator.Manipulate(listReflectors, statementElement)) |
929 | ····································methodTouched = true; |
930 | ························} |
931 | ····················} |
932 | ················} |
933 | |
934 | ················if (needsContainerStack) |
935 | ················{ |
936 | ····················addLocalVariable(methodElement, "__ndocontainertable", $"class {Corlib.Name}System.Collections.Hashtable"); |
937 | ····················firstElement.insertBefore(new ILStatementElement($"newobj···· instance void {Corlib.Name}System.Collections.Hashtable::.ctor()")); |
938 | ····················firstElement.insertBefore(new ILStatementElement("stloc __ndocontainertable")); |
939 | ····················addToMaxStackVal(methodElement, 3); |
940 | ················} |
941 | |
942 | ················//················if (needsContainerStack || readEntries) |
943 | ················//····················addDirtyStatements(methodElement, false); |
944 | ················if (methodTouched || needsContainerStack) |
945 | ····················MakeLongBranches(methodElement); |
946 | ············} // ILMethodElement |
947 | ········} |
948 | |
949 | |
950 | ········public void MakeLongBranches(ILMethodElement methodElement) |
951 | ········{ |
952 | ············ILStatementElement.Iterator statementIter = methodElement.getStatementIterator(true); |
953 | |
954 | ············for ( ILStatementElement statementElement = statementIter.getNext(); null != statementElement; statementElement = statementIter.getNext() ) |
955 | ············{ |
956 | ················string line = statementElement.getLine(0); |
957 | ················if (line.StartsWith("IL")) |
958 | ················{ |
959 | ····················for (int i = 0; i < AllBranches.Opcodes.Length; i++) |
960 | ····················{ |
961 | ························string s = AllBranches.Opcodes[i]; |
962 | ························if (line.IndexOf(s) > -1) |
963 | ························{ |
964 | ····························statementElement.replaceText(s, AllBranches.LongOpcodes[i]); |
965 | ····························break; |
966 | ························} |
967 | ····················} |
968 | ················} |
969 | ············}················ |
970 | ········} |
971 | |
972 | ········public void |
973 | ········patchConstructor() |
974 | ········{ |
975 | ············ArrayList constructors = new ArrayList(); |
976 | ············ILMethodElement.Iterator methodIter = m_classElement.getMethodIterator(); |
977 | |
978 | ············bool hasDefaultConstructor = false; |
979 | ············for ( ILMethodElement methodElement = methodIter.getNext(); null != methodElement; methodElement = methodIter.getNext() ) |
980 | ············{ |
981 | ················if ( !methodElement.isConstructor() ) |
982 | ····················continue; |
983 | |
984 | ················constructors.Add(methodElement); |
985 | |
986 | ················if (methodElement.getParameterCount() == 0) |
987 | ····················hasDefaultConstructor = true; |
988 | ············} |
989 | |
990 | ············if (!hasDefaultConstructor && constructors.Count > 0) |
991 | ················messages.WriteLine( "Warning: class " + m_refName.Replace( "'", string.Empty ) + " doesn't have a default constructor. NDO will try to resolve other constructors during runtime." ); |
992 | |
993 | ············int maxStack = this.m_hasPersistentBase ? 2 : 2; |
994 | ············ |
995 | ············foreach(ILMethodElement me in constructors) |
996 | ············{ |
997 | ················adjustMaxStackVal(me, maxStack); |
998 | |
999 | ················ILStatementElement statementElement = (ILStatementElement) me.getStatementIterator().getLast(); |
1000 | ················string line = ILElement.stripLabel(statementElement.getLine(0)); |
1001 | ································ |
1002 | ················IList elements = new ArrayList(); |
1003 | |
1004 | ················if (!this.m_hasPersistentBase) |
1005 | ················{ |
1006 | ····················elements.Add(new ILStatementElement("ldarg.0")); |
1007 | ····················elements.Add(new ILStatementElement("ldc.i4.0")); |
1008 | ····················elements.Add(new ILStatementElement("stfld······valuetype [NDO]NDO.NDOObjectState " + m_refName + "::_ndoObjectState")); |
1009 | ····················elements.Add(new ILStatementElement("ldarg.0")); |
1010 | ····················elements.Add(new ILStatementElement("newobj···· instance void [NDO]NDO.LoadState::.ctor()")); |
1011 | ····················elements.Add(new ILStatementElement("stfld······class [NDO]NDO.LoadState " + m_refName + "::_ndoLoadState")); |
1012 | ················} |
1013 | ················if (!(line == "ret") && elements.Count > 0) |
1014 | ····················messages.WriteLine("Can't find return statement of the constructor of class " + m_refName); |
1015 | |
1016 | ················foreach (ILStatementElement el in elements) |
1017 | ····················statementElement.insertBefore(el); |
1018 | ············} |
1019 | |
1020 | |
1021 | ········} |
1022 | |
1023 | ········public void |
1024 | ············addMethods() |
1025 | ········{ |
1026 | ············if ( !m_hasPersistentBase ) |
1027 | ············{ |
1028 | ················//IPersistenceCapable-Implementierung |
1029 | ················addMarkDirty(); |
1030 | ················addLoadData(); |
1031 | ················addObjectId(); |
1032 | ················addTimeStamp(); |
1033 | ················addGetObjectHashCode(); |
1034 | ················addObjectState(); |
1035 | ················addStateManager(); |
1036 | ················addGetNDOHandler(); |
1037 | ············} |
1038 | ············else |
1039 | ············{ |
1040 | ················removeMarkDirty(); |
1041 | ················removeLoadData(); |
1042 | ················removeObjectId(); |
1043 | ················removeTimeStamp(); |
1044 | ················removeObjectState(); |
1045 | ················removeStateManager(); |
1046 | ················removeGetNDOHandler(); |
1047 | ············} |
1048 | ············addRead(); |
1049 | ············addWrite(); |
1050 | ············addRelationAccessors(); |
1051 | ············addLoadStateProperty(); |
1052 | ············addGetLoadState(); |
1053 | ············addSetLoadState(); |
1054 | ········} |
1055 | |
1056 | ········string createNDOException() |
1057 | ········{ |
1058 | ············return "newobj instance void [NDOInterfaces]NDO.NDOException::.ctor(int32, string)"; |
1059 | ········} |
1060 | |
1061 | ········void addGetOrdinal(ILClassElement metaClass) |
1062 | ········{ |
1063 | ············ILMethodElement methodElement = new ILMethodElement(); |
1064 | methodElement. addLine( ". method public hidebysig newslot final virtual instance int32 GetRelationOrdinal( string fieldName) cil managed" ) ; |
1065 | |
1066 | ············methodElement.addStatement(".maxstack··4"); |
1067 | ············addLocalVariable(methodElement, "result", "int32"); |
1068 | ············foreach(ILReference r in m_references) |
1069 | ············{ |
1070 | ················methodElement.addStatement(ldarg_1); |
1071 | ················methodElement.addStatement(@"ldstr······""" + r.CleanName + @""""); |
1072 | ················methodElement.addStatement($"call······ bool {Corlib.Name}System.String::op_Equality(string,string)"); |
1073 | ················methodElement.addStatement("brfalse.s··notthis" + r.Ordinal.ToString()); |
1074 | ················methodElement.addStatement(loadIntConst(r.Ordinal)); |
1075 | ················methodElement.addStatement("stloc.0"); |
1076 | ················methodElement.addStatement("br······ exit"); |
1077 | ················methodElement.addStatement("notthis" + r.Ordinal.ToString() + ":"); |
1078 | ············} |
1079 | ············methodElement.addStatement(loadIntConst(20)); |
1080 | ············methodElement.addStatement(@"ldstr······""GetRelationOrdinal: Can't find field " + m_refName + @"."""); |
1081 | ············methodElement.addStatement(ldarg_1); |
1082 | ············methodElement.addStatement($"call······ string {Corlib.Name}System.String::Concat(string,string)"); |
1083 | ············methodElement.addStatement(createNDOException()); |
1084 | ············methodElement.addStatement("throw"); |
1085 | ············methodElement.addStatement("exit:··ldloc.0"); |
1086 | ············methodElement.addStatement("ret"); |
1087 | |
1088 | ············metaClass.addElement(methodElement); |
1089 | ········} |
1090 | |
1091 | ········void addLoadStateProperty() |
1092 | ········{ |
1093 | ············ILMethodElement methodElement = m_classElement.getMethod( "get_NDOLoadState" ); |
1094 | ············ILPropertyElement propElement = m_classElement.getProperty( "NDOLoadState" ); |
1095 | |
1096 | ············if ( m_hasPersistentBase ) |
1097 | ············{ |
1098 | ················if (methodElement != null) |
1099 | ····················methodElement.remove(); |
1100 | ················if ( propElement != null ) |
1101 | ····················propElement.remove(); |
1102 | ················return; |
1103 | ············} |
1104 | ···· |
1105 | ············if ( methodElement == null ) |
1106 | ············{ |
1107 | ················methodElement = new ILMethodElement(); |
1108 | ················methodElement.addLine( ".method public hidebysig newslot specialname final virtual" ); |
1109 | ················methodElement.addLine( "instance class [NDO]NDO.LoadState get_NDOLoadState() cil managed" ); |
1110 | ················this.m_classElement.addElement( methodElement ); |
1111 | ············} |
1112 | ············else |
1113 | ············{················ |
1114 | ················methodElement.clearElements(); |
1115 | ············} |
1116 | ············methodElement.addStatement(".maxstack··3"); |
1117 | ············methodElement.addStatement(ldarg_0); |
1118 | ············methodElement.addStatement("ldfld······class [NDO]NDO.LoadState " + m_refName + "::_ndoLoadState"); |
1119 | ············methodElement.addStatement("ret"); |
1120 | |
1121 | ············if ( propElement == null ) |
1122 | ············{ |
1123 | ················propElement = new ILPropertyElement(); |
1124 | ················propElement.addLine( ".property instance class [NDO]NDO.LoadState NDOLoadState()" ); |
1125 | ················propElement.addElement( new ILCustomElement( ".custom instance void [System]System.ComponentModel.BrowsableAttribute::.ctor(bool) = ( 01 00 00 00 00 )", propElement ) ); |
1126 | ················propElement.addElement( new ILCustomElement( ".custom instance void [System.Xml]System.Xml.Serialization.XmlIgnoreAttribute::.ctor() = ( 01 00 00 00 )", propElement ) ); |
1127 | ················propElement.addElement( new ILGetElement( ".get instance class [NDO]NDO.LoadState " + m_nonGenericRefName + "::get_NDOLoadState()" ) ); |
1128 | ················this.m_classElement.addElement( propElement ); |
1129 | ············} |
1130 | ········} |
1131 | |
1132 | ········void addGetLoadState() |
1133 | ········{ |
1134 | ············ILMethodElement methodElement = m_classElement.getMethod( "NDOGetLoadState" ); |
1135 | ············ |
1136 | ············if ( m_hasPersistentBase ) |
1137 | ············{ |
1138 | ················if ( methodElement != null ) |
1139 | ····················methodElement.remove(); |
1140 | ················return; |
1141 | ············} |
1142 | |
1143 | ············if ( methodElement == null ) |
1144 | ············{ |
1145 | ················methodElement = new ILMethodElement(); |
1146 | ················methodElement.addLine( ".method public hidebysig newslot virtual" ); |
1147 | ················methodElement.addLine( "instance bool NDOGetLoadState(int32 ordinal) cil managed" ); |
1148 | ················this.m_classElement.addElement( methodElement ); |
1149 | ············} |
1150 | ············else |
1151 | ············{ |
1152 | ················methodElement.clearElements(); |
1153 | ············} |
1154 | ············methodElement.addStatement(".maxstack··3"); |
1155 | |
1156 | ············methodElement.addStatement(ldarg_0); |
1157 | ············methodElement.addStatement("ldfld······class [NDO]NDO.LoadState " + m_refName + "::_ndoLoadState"); |
1158 | ············methodElement.addStatement($"callvirt·· instance class {Corlib.Name}System.Collections.BitArray [NDO]NDO.LoadState::get_RelationLoadState()"); |
1159 | ············methodElement.addStatement(ldarg_1); |
1160 | ············methodElement.addStatement($"callvirt instance bool {Corlib.Name}System.Collections.BitArray::get_Item(int32)"); |
1161 | ············methodElement.addStatement("ret"); |
1162 | ········} |
1163 | |
1164 | ········void addSetLoadState() |
1165 | ········{ |
1166 | ············ILMethodElement methodElement = m_classElement.getMethod( "NDOSetLoadState" ); |
1167 | ············if ( m_hasPersistentBase ) |
1168 | ············{ |
1169 | ················if ( methodElement != null ) |
1170 | ····················methodElement.remove(); |
1171 | ················return; |
1172 | ············} |
1173 | ············if ( methodElement == null ) |
1174 | ············{ |
1175 | ················methodElement = new ILMethodElement(); |
1176 | ················methodElement.addLine( ".method public hidebysig newslot virtual" ); |
1177 | ················methodElement.addLine( "instance void NDOSetLoadState(int32 ordinal, bool isLoaded) cil managed" ); |
1178 | ················this.m_classElement.addElement( methodElement ); |
1179 | ············} |
1180 | ············else |
1181 | ············{ |
1182 | ················methodElement.clearElements(); |
1183 | ············} |
1184 | ············methodElement.addStatement(".maxstack··3"); |
1185 | |
1186 | ············methodElement.addStatement(ldarg_0); |
1187 | ············methodElement.addStatement("ldfld······class [NDO]NDO.LoadState "··+ m_refName + "::_ndoLoadState"); |
1188 | ············methodElement.addStatement($"callvirt·· instance class {Corlib.Name}System.Collections.BitArray [NDO]NDO.LoadState::get_RelationLoadState()"); |
1189 | ············methodElement.addStatement("ldarg.1"); |
1190 | ············methodElement.addStatement("ldarg.2"); |
1191 | ············methodElement.addStatement($"callvirt instance void {Corlib.Name}System.Collections.BitArray::set_Item(int32, bool)"); |
1192 | ············methodElement.addStatement("ret"); |
1193 | ········} |
1194 | |
1195 | |
1196 | |
1197 | |
1198 | ········string getAccName(string prefix, string fieldName) |
1199 | ········{ |
1200 | ············if (fieldName.StartsWith("'")) |
1201 | ················return "'" + prefix + fieldName.Replace("'", string.Empty) + "'"; |
1202 | ············else |
1203 | ················return prefix + fieldName; |
1204 | ········} |
1205 | |
1206 | ········private void |
1207 | ············addRelationAccessors() |
1208 | ········{ |
1209 | ············foreach ( ILReference reference in m_references) |
1210 | ············{ |
1211 | ················if (reference.IsInherited) |
1212 | ····················continue; |
1213 | ················if (reference.Is1to1) |
1214 | ····················add1to1RelationAccessors(reference); |
1215 | ················else |
1216 | ····················add1toNRelationAccessors(reference); |
1217 | ············} |
1218 | ········} |
1219 | |
1220 | ········private string loadIntConst(int val) |
1221 | ········{ |
1222 | ············string valStr = val.ToString(); |
1223 | ············if (val >= 0 && val < 8) |
1224 | ················return "ldc.i4." + valStr; |
1225 | ············else if (val >= -128 && val <= 127) |
1226 | ················return "ldc.i4.s " + valStr; |
1227 | ············else |
1228 | ················return "ldc.i4 " + valStr; |
1229 | ········} |
1230 | |
1231 | ········private void |
1232 | ············add1to1RelationGetAccessor(ILReference reference) |
1233 | ········{ |
1234 | ············// Get-Methode nur für 1:1 |
1235 | ············ILMethodElement method = new ILMethodElement(); |
1236 | ············method.addLine( ".method private hidebysig instance " ); |
1237 | ············method.addLine( reference.ILType + " " + getAccName("ndoget_", reference.Name) + "() cil managed"); |
1238 | #if nix |
1239 | ············method.addStatement(".maxstack··2"); |
1240 | ············method.addStatement(ldarg_0); |
1241 | ············method.addStatement(loadStateManager()); |
1242 | ············method.addStatement("brfalse.s··noSm"); |
1243 | ············method.addStatement(ldarg_0); |
1244 | ············method.addStatement(loadStateManager()); |
1245 | ············method.addStatement(ldarg_0); |
1246 | ············method.addStatement("callvirt·· instance void [NDO]NDO.IStateManager::LoadData(class [NDO]NDO.IPersistenceCapable)"); |
1247 | ············method.addStatement("noSm:"); |
1248 | ············method.addStatement(ldarg_0); |
1249 | ············method.addStatement("ldfld······" + reference.ILType + " " + m_refName + "::" + reference.Name); |
1250 | ············method.addStatement( "ret"); |
1251 | #else |
1252 | ············method.addStatement(".maxstack··5" ); |
1253 | ············method.addStatement(ldarg_0); |
1254 | ············method.addStatement( loadStateManager() ); |
1255 | ············method.addStatement( "brfalse.s··noSm"); |
1256 | ············//············method.addStatement(ldarg_0); |
1257 | ············//············method.addStatement("ldfld······bool[] " + m_refName + "::" + GetRelationStateName()); |
1258 | ············//············method.addStatement(loadIntConst(reference.Ordinal)); |
1259 | ············//············method.addStatement("ldelem.i1"); |
1260 | ············//············method.addStatement("brtrue.s·· noSm"); |
1261 | ············method.addStatement(ldarg_0); |
1262 | ············method.addStatement( loadStateManager() ); |
1263 | ············method.addStatement(ldarg_0); |
1264 | ············method.addStatement(@"ldstr······""" + reference.CleanName + @""""); |
1265 | ············method.addStatement($"callvirt·· instance class {Corlib.Name}System.Collections.IList [NDO]NDO.IStateManager::LoadRelation(class [NDO]NDO.IPersistenceCapable,string)"); |
1266 | ············method.addStatement("pop"); |
1267 | ············//············method.addStatement(ldarg_0); |
1268 | ············//············method.addStatement("ldfld······bool[] " + m_refName + "::" + GetRelationStateName()); |
1269 | ············//············method.addStatement(loadIntConst(reference.Ordinal)); |
1270 | ············//············method.addStatement("ldc.i4.1"); |
1271 | ············//············method.addStatement("stelem.i1"); |
1272 | ············method.addStatement("noSm:"); |
1273 | ············method.addStatement(ldarg_0); |
1274 | ············method.addStatement("ldfld······" + reference.ILType + " " + m_refName + "::" + reference.Name); |
1275 | ············method.addStatement( "ret"); |
1276 | #endif |
1277 | ············m_classElement.getMethodIterator().getLast().insertAfter( method ); |
1278 | ········} |
1279 | |
1280 | ········private void |
1281 | ············add1to1RelationAccessors(ILReference reference) |
1282 | ········{ |
1283 | ············add1to1RelationGetAccessor(reference); |
1284 | |
1285 | ············// Set-Methode |
1286 | ············ILMethodElement method = new ILMethodElement(); |
1287 | ············method.addLine( ".method private hidebysig specialname instance void" ); |
1288 | ············method.addLine( getAccName("ndoset_", reference.Name) + "(" + reference.ILType + " 'value') cil managed"); |
1289 | ············method.addStatement( ".maxstack··4" ); |
1290 | ············method.addStatement( ldarg_0 ); |
1291 | ············method.addStatement( loadStateManager()); |
1292 | ············method.addStatement( "brfalse.s··IL_003c"); |
1293 | |
1294 | ············method.addStatement( ldarg_0); |
1295 | ············method.addStatement( loadStateManager() ); |
1296 | ············method.addStatement( ldarg_0); |
1297 | ············method.addStatement( "callvirt·· instance void [NDO]NDO.IStateManager::LoadData(class [NDO]NDO.IPersistenceCapable)"); |
1298 | |
1299 | ············method.addStatement( ldarg_0 ); |
1300 | ············method.addStatement( "ldfld······" + reference.ILType + " "+ m_refName + "::" + reference.Name); |
1301 | ············method.addStatement( "brfalse.s··IL_0027"); |
1302 | |
1303 | ············method.addStatement( ldarg_0 ); |
1304 | ············method.addStatement( loadStateManager()); |
1305 | ············method.addStatement( ldarg_0 ); |
1306 | ············method.addStatement( @"ldstr······""" + reference.CleanName + @""""); |
1307 | ············method.addStatement( ldarg_0 ); |
1308 | ············method.addStatement( "ldfld······" + reference.ILType + " "+ m_refName + "::" + reference.Name); |
1309 | ············method.addStatement( "callvirt·· instance void [NDO]NDO.IStateManager::RemoveRelatedObject(class [NDO]NDO.IPersistenceCapable,string,class [NDO]NDO.IPersistenceCapable)"); |
1310 | ············method.addStatement( "IL_0027: ldarg.1"); |
1311 | ············method.addStatement( "brfalse.s··IL_003c"); |
1312 | |
1313 | ············method.addStatement( ldarg_0); |
1314 | ············method.addStatement( loadStateManager()); |
1315 | ············method.addStatement( ldarg_0); |
1316 | ············method.addStatement( @"ldstr······""" + reference.CleanName + @""""); |
1317 | ············method.addStatement( ldarg_1); |
1318 | ············method.addStatement( "callvirt·· instance void [NDO]NDO.IStateManager::AddRelatedObject(class [NDO]NDO.IPersistenceCapable,string,class [NDO]NDO.IPersistenceCapable)"); |
1319 | ············method.addStatement( "IL_003c: ldarg.0"); |
1320 | ············method.addStatement( ldarg_1); |
1321 | ············method.addStatement( "stfld······" + reference.ILType + " "+ m_refName + "::" + reference.Name); |
1322 | ············method.addStatement( "ret"); |
1323 | ············m_classElement.getMethodIterator().getLast().insertAfter( method ); |
1324 | ········} |
1325 | |
1326 | |
1327 | ········private void |
1328 | ············add1toNRelationAccessors(ILReference reference) |
1329 | ········{ |
1330 | ············//addRelationGetAccessor(reference); |
1331 | |
1332 | ············// Set-Methode |
1333 | ············ILMethodElement method = new ILMethodElement(); |
1334 | ············method.addLine( ".method private hidebysig specialname instance void" ); |
1335 | ············method.addLine( getAccName("ndoset_", reference.Name) + "(" + reference.ILType + " 'value') cil managed"); |
1336 | ············method.addStatement( ".maxstack··5" ); |
1337 | |
1338 | ············method.addStatement( ldarg_0 ); |
1339 | ············method.addStatement( loadStateManager()); |
1340 | ············method.addStatement( "brfalse.s··NoSm"); |
1341 | |
1342 | ············method.addStatement( ldarg_0); |
1343 | ············method.addStatement( loadStateManager() ); |
1344 | |
1345 | ············method.addStatement( ldarg_0);··// Arg. 1 |
1346 | ············method.addStatement(@"ldstr······""" + reference.CleanName + @""""); |
1347 | |
1348 | ············method.addStatement(ldarg_0); |
1349 | ············method.addStatement( "ldfld······" + reference.ILType + " "+ m_refName + "::" + reference.Name); |
1350 | |
1351 | ············method.addStatement( ldarg_1 ); |
1352 | |
1353 | ············method.addStatement( $"callvirt·· instance void [NDO]NDO.IStateManager::AssignRelation(class [NDO]NDO.IPersistenceCapable, string, class {Corlib.Name}System.Collections.IList, class {Corlib.Name}System.Collections.IList)"); |
1354 | |
1355 | ············method.addStatement( "NoSm:"); |
1356 | ············method.addStatement(ldarg_0); |
1357 | ············method.addStatement( ldarg_1 ); |
1358 | ············method.addStatement( "stfld······" + reference.ILType + " "+ m_refName + "::" + reference.Name); |
1359 | ············method.addStatement( "ret"); |
1360 | |
1361 | ············m_classElement.getMethodIterator().getLast().insertAfter( method ); |
1362 | ········} |
1363 | |
1364 | ········private void addFieldAccessors() |
1365 | ········{ |
1366 | ············foreach (ILField f in this.ownFieldsHierarchical) |
1367 | ············{ |
1368 | ················if (f.IsEmbeddedType) |
1369 | ····················messages.WriteLine("The type of the field " + this.m_refName + "." + f.CleanName + " is not a storable type; it will be treated as embedded type."); |
1370 | ················addFieldAccessorPair(f); |
1371 | ············} |
1372 | ········} |
1373 | |
1374 | ········private void addFieldAccessorPair(ILField field) |
1375 | ········{ |
1376 | ············ILMethodElement method; |
1377 | ············method = new ILMethodElement(); |
1378 | ············method.addLine( ".method private hidebysig instance void" ); |
1379 | ············//············string classStr = field.IsEmbeddedType ? "class " : string.Empty; |
1380 | ············method.addLine( getAccName("ndoset_", field.Name) + "(" + field.ILType + " 'value') cil managed"); |
1381 | ············method.addStatement(".maxstack··2"); |
1382 | ············method.addStatement(ldarg_0); |
1383 | ············method.addStatement(this.loadStateManager()); |
1384 | ············method.addStatement("brfalse.s··NoSm"); |
1385 | ············method.addStatement(ldarg_0); |
1386 | ············method.addStatement(this.loadStateManager()); |
1387 | ············method.addStatement(ldarg_0); |
1388 | ············method.addStatement("callvirt·· instance void [NDO]NDO.IStateManager::MarkDirty(class [NDO]NDO.IPersistenceCapable)"); |
1389 | ············method.addStatement("NoSm:"); |
1390 | ············method.addStatement(ldarg_0); |
1391 | ············method.addStatement(ldarg_1); |
1392 | ············ |
1393 | ············method.addStatement("stfld······" + field.ILType + " " + m_refName + "::" + field.Name); |
1394 | ············method.addStatement("ret"); |
1395 | |
1396 | ············m_classElement.getMethodIterator().getLast().insertAfter( method ); |
1397 | |
1398 | ············NDO.Mapping.Field fieldMapping = this.m_classMapping.FindField(field.CleanName); |
1399 | |
1400 | ············// We can't get Value Types with getter functions, because that would result in a |
1401 | ············// copy of the object. So the original object couldn't be manipulated.············ |
1402 | ············if (!field.IsValueType && fieldMapping != null) |
1403 | ············{ |
1404 | ················method = new ILMethodElement(); |
1405 | ················method.addLine(".method private hidebysig instance void"); |
1406 | ················method.addLine(getAccName("ndoget_", field.Name) + "() cil managed"); |
1407 | ················method.addStatement(".maxstack··3"); |
1408 | ················method.addStatement(ldarg_0); |
1409 | ················method.addStatement(this.loadStateManager()); |
1410 | ················method.addStatement("brfalse.s··NoSm"); |
1411 | ················method.addStatement(ldarg_0); |
1412 | ················method.addStatement(this.loadStateManager()); |
1413 | ················method.addStatement(ldarg_0); |
1414 | ················method.addStatement(this.loadIntConst(fieldMapping.Ordinal)); |
1415 | ················method.addStatement("callvirt·· instance void [NDO]NDO.IStateManager::LoadField(class [NDO]NDO.IPersistenceCapable,int32)"); |
1416 | ················method.addStatement("NoSm: ret"); |
1417 | ················// The original ldfld[a] statement remains in the code. |
1418 | ················// method.addStatement("NoSm:··ldarg.0"); |
1419 | ················// method.addStatement("ldfld······" + field.ILType + " " + m_refName + "::" + field.Name); |
1420 | ················// method.addStatement("ret"); |
1421 | ················m_classElement.getMethodIterator().getLast().insertAfter( method ); |
1422 | ············} |
1423 | ········} |
1424 | |
1425 | ········public void |
1426 | ········removeMarkDirty() |
1427 | ········{ |
1428 | ············ILMethodElement method = m_classElement.getMethod( "NDOMarkDirty" ); |
1429 | |
1430 | ············if ( method != null ) |
1431 | ················method.remove(); |
1432 | ········} |
1433 | |
1434 | ········public void |
1435 | ········addMarkDirty() |
1436 | ········{ |
1437 | ············ILMethodElement method = m_classElement.getMethod( "NDOMarkDirty" ); |
1438 | |
1439 | ············if ( method != null ) |
1440 | ············{ |
1441 | ················method.clearElements(); |
1442 | ············} |
1443 | ············else |
1444 | ············{ |
1445 | ················method = new ILMethodElement(); |
1446 | ················method.addLine( ".method public hidebysig newslot virtual final" ); |
1447 | ················method.addLine( "instance void··NDOMarkDirty() cil managed" ); |
1448 | ················m_classElement.getMethodIterator().getLast().insertAfter( method ); |
1449 | ············} |
1450 | ············method.addStatement( ".maxstack··2" ); |
1451 | ············method.addStatement( ldarg_0 ); |
1452 | ············method.addStatement( loadStateManager()); |
1453 | ············method.addStatement( "dup" ); |
1454 | ············method.addStatement( "brfalse.s··NoSm" ); |
1455 | |
1456 | //············method.addStatement( ldarg_0);··// used dup instead |
1457 | //············method.addStatement( loadStateManager() ); |
1458 | ············method.addStatement( ldarg_0); |
1459 | ············method.addStatement( "callvirt·· instance void [NDO]NDO.IStateManager::MarkDirty(class [NDO]NDO.IPersistenceCapable)"); |
1460 | ············method.addStatement( "NoSm: ret"); |
1461 | ····} |
1462 | |
1463 | ········public void |
1464 | ········removeLoadData() |
1465 | ········{ |
1466 | ············ILMethodElement method = m_classElement.getMethod( "NDOLoadData" ); |
1467 | ············if ( method != null ) |
1468 | ················method.remove(); |
1469 | ········} |
1470 | |
1471 | ········public void |
1472 | ········addLoadData() |
1473 | ········{ |
1474 | ············ILMethodElement method = m_classElement.getMethod( "NDOLoadData" ); |
1475 | ············if ( method != null ) |
1476 | ············{ |
1477 | ················method.clearElements(); |
1478 | ············} |
1479 | ············else |
1480 | ············{ |
1481 | ················method = new ILMethodElement(); |
1482 | ················m_classElement.getMethodIterator().getLast().insertAfter( method ); |
1483 | ················method.addLine( ".method family hidebysig newslot final virtual" ); |
1484 | ················method.addLine( "instance void··NDOLoadData() cil managed" ); |
1485 | ············} |
1486 | ············method.addStatement( ".maxstack··2" ); |
1487 | ············method.addStatement( ldarg_0 ); |
1488 | ············method.addStatement( loadStateManager()); |
1489 | ············method.addStatement( "brfalse.s··NoSm"); |
1490 | |
1491 | ············method.addStatement( ldarg_0); |
1492 | ············method.addStatement( loadStateManager() ); |
1493 | ············method.addStatement( ldarg_0); |
1494 | ············method.addStatement( "callvirt·· instance void [NDO]NDO.IStateManager::LoadData(class [NDO]NDO.IPersistenceCapable)"); |
1495 | ············method.addStatement( "NoSm: ret"); |
1496 | |
1497 | ········} |
1498 | |
1499 | ········public void |
1500 | ········removeObjectId() |
1501 | ········{ |
1502 | ············ILMethodElement method = m_classElement.getMethod( "get_NDOObjectId" ); |
1503 | ············if ( method != null ) |
1504 | ················method.remove(); |
1505 | ············method = m_classElement.getMethod( "set_NDOObjectId" ); |
1506 | ············if ( method != null ) |
1507 | ················method.remove(); |
1508 | ············ILPropertyElement prop = m_classElement.getProperty( "NDOObjectId" ); |
1509 | ············if ( prop != null ) |
1510 | ················prop.remove(); |
1511 | ········} |
1512 | |
1513 | ········public void |
1514 | ········addObjectId() |
1515 | ········{ |
1516 | ············ILMethodElement method = m_classElement.getMethod( "get_NDOObjectId" ); |
1517 | ············if ( method != null ) |
1518 | ············{ |
1519 | ················method.clearElements(); |
1520 | ············} |
1521 | ············else |
1522 | ············{ |
1523 | ················method = new ILMethodElement(); |
1524 | ················method.addLine( ".method public hidebysig newslot specialname final virtual" ); |
1525 | ················method.addLine( "instance class [NDO]NDO.ObjectId get_NDOObjectId() cil managed" ); |
1526 | ················m_classElement.getMethodIterator().getLast().insertAfter( method ); |
1527 | ············} |
1528 | ············method.addStatement( ".maxstack··1" ); |
1529 | ············ |
1530 | ············method.addStatement( "··ldarg.0"); |
1531 | ············method.addStatement(loadObjectId()); |
1532 | ············method.addStatement( "ret"); |
1533 | |
1534 | |
1535 | ············method = m_classElement.getMethod( "set_NDOObjectId" ); |
1536 | ············if ( method != null ) |
1537 | ············{ |
1538 | ················method.clearElements(); |
1539 | ············} |
1540 | ············else |
1541 | ············{ |
1542 | ················method = new ILMethodElement(); |
1543 | ················m_classElement.getMethodIterator().getLast().insertAfter( method ); |
1544 | ················method.addLine( ".method public hidebysig newslot specialname final virtual" ); |
1545 | ················method.addLine( "instance void··set_NDOObjectId(class [NDO]NDO.ObjectId 'value') cil managed" ); |
1546 | ············} |
1547 | ············method.addStatement( ".maxstack··2" ); |
1548 | ············ |
1549 | ············method.addStatement( "··ldarg.0"); |
1550 | ············method.addStatement( "··ldarg.1"); |
1551 | ············method.addStatement(storeObjectId()); |
1552 | ············method.addStatement( "ret"); |
1553 | |
1554 | |
1555 | ············ILPropertyElement prop = m_classElement.getProperty( "NDOObjectId" ); |
1556 | ············if ( prop == null ) |
1557 | ············{ |
1558 | ················prop = new ILPropertyElement( ".property instance class [NDO]NDO.ObjectId NDOObjectId()", m_classElement ); |
1559 | ················prop.addElement( new ILCustomElement( ".custom instance void [System]System.ComponentModel.CategoryAttribute::.ctor(string) = ( 01 00 03 4E 44 4F 00 00 )", prop ) ); |
1560 | ················prop.addElement( new ILCustomElement( ".custom instance void [System.Xml]System.Xml.Serialization.XmlIgnoreAttribute::.ctor() = ( 01 00 00 00 )", prop ) ); |
1561 | ················prop.addElement( new ILSetElement( ".set instance void " + m_nonGenericRefName + "::set_NDOObjectId(class [NDO]NDO.ObjectId)" ) ); |
1562 | ················prop.addElement( new ILGetElement( ".get instance class [NDO]NDO.ObjectId " + m_nonGenericRefName + "::get_NDOObjectId()" ) ); |
1563 | ················m_classElement.getMethodIterator().getLast().insertAfter( prop ); |
1564 | ············} |
1565 | ········} |
1566 | |
1567 | ········public void |
1568 | ········removeTimeStamp() |
1569 | ········{ |
1570 | ············ILMethodElement method = m_classElement.getMethod( "get_NDOTimeStamp" ); |
1571 | ············if ( method != null ) |
1572 | ················method.remove(); |
1573 | ············method = m_classElement.getMethod( "set_NDOTimeStamp" ); |
1574 | ············if ( method != null ) |
1575 | ················method.remove(); |
1576 | ············ILPropertyElement prop = m_classElement.getProperty( "NDOTimeStamp" ); |
1577 | ············if ( prop != null ) |
1578 | ················prop.remove(); |
1579 | ········} |
1580 | |
1581 | ········public void |
1582 | ········addTimeStamp() |
1583 | ········{ |
1584 | ············ILMethodElement method = m_classElement.getMethod( "get_NDOTimeStamp" ); |
1585 | ············if ( method != null ) |
1586 | ············{ |
1587 | ················method.clearElements(); |
1588 | ············} |
1589 | ············else |
1590 | ············{ |
1591 | ················method = new ILMethodElement(); |
1592 | ················method.addLine( ".method public hidebysig newslot specialname final virtual" ); |
1593 | ················method.addLine( $"instance valuetype {Corlib.Name}System.Guid get_NDOTimeStamp() cil managed" ); |
1594 | ················m_classElement.getMethodIterator().getLast().insertAfter( method ); |
1595 | ············} |
1596 | ············method.addStatement( ".maxstack··1" ); |
1597 | ············ |
1598 | ············method.addStatement( "··ldarg.0"); |
1599 | ············method.addStatement(loadTimeStamp()); |
1600 | ············method.addStatement( "ret"); |
1601 | |
1602 | |
1603 | ············method = m_classElement.getMethod( "set_NDOTimeStamp" ); |
1604 | ············if ( method != null ) |
1605 | ············{ |
1606 | ················method.clearElements(); |
1607 | ············} |
1608 | ············else |
1609 | ············{ |
1610 | ················method = new ILMethodElement(); |
1611 | ················method.addLine( ".method public hidebysig newslot specialname final virtual" ); |
1612 | ················method.addLine( $"instance void··set_NDOTimeStamp(valuetype {Corlib.Name}System.Guid 'value') cil managed" ); |
1613 | ················m_classElement.getMethodIterator().getLast().insertAfter( method ); |
1614 | ············} |
1615 | ············method.addStatement( ".maxstack··2" ); |
1616 | ············ |
1617 | ············method.addStatement( "··ldarg.0"); |
1618 | ············method.addStatement( "··ldarg.1"); |
1619 | ············method.addStatement(storeTimeStamp()); |
1620 | ············method.addStatement( "ret"); |
1621 | |
1622 | ············ILPropertyElement prop = m_classElement.getProperty( "NDOTimeStamp" ); |
1623 | ············if ( prop == null ) |
1624 | ············{ |
1625 | ················prop = new ILPropertyElement( $".property instance valuetype {Corlib.Name}System.Guid NDOTimeStamp()", m_classElement ); |
1626 | ················prop.addElement( new ILCustomElement( ".custom instance void [System]System.ComponentModel.BrowsableAttribute::.ctor(bool) = ( 01 00 00 00 00 )", prop ) ); |
1627 | ················prop.addElement( new ILCustomElement( ".custom instance void [System.Xml]System.Xml.Serialization.XmlIgnoreAttribute::.ctor() = ( 01 00 00 00 )", prop ) ); |
1628 | ················prop.addElement( new ILSetElement( ".set instance void " + m_nonGenericRefName + $"::set_NDOTimeStamp(valuetype {Corlib.Name}System.Guid)" ) ); |
1629 | ················prop.addElement( new ILGetElement( $".get instance valuetype {Corlib.Name}System.Guid " + m_nonGenericRefName + "::get_NDOTimeStamp()" ) ); |
1630 | ················m_classElement.getMethodIterator().getLast().insertAfter( prop ); |
1631 | ············} |
1632 | ········} |
1633 | |
1634 | ········public void |
1635 | ········removeObjectState() |
1636 | ········{ |
1637 | ············ILMethodElement method = m_classElement.getMethod( "get_NDOObjectState" ); |
1638 | ············if ( method != null ) |
1639 | ················method.remove(); |
1640 | ············method = m_classElement.getMethod( "set_NDOObjectState" ); |
1641 | ············if ( method != null ) |
1642 | ················method.remove(); |
1643 | ············ILPropertyElement prop = m_classElement.getProperty( "NDOObjectState" ); |
1644 | ············if ( prop != null ) |
1645 | ················prop.remove(); |
1646 | ········} |
1647 | |
1648 | ········public void |
1649 | ········addGetObjectHashCode() |
1650 | ········{ |
1651 | ············ILMethodElement method = new ILMethodElement(); |
1652 | ············if ( m_hasPersistentBase ) |
1653 | ················method.addLine( ".method public hidebysig virtual" ); |
1654 | ············else |
1655 | ················method.addLine( ".method public hidebysig newslot virtual" ); |
1656 | ············method.addLine( "instance int32 NDOGetObjectHashCode() cil managed" ); |
1657 | ············m_classElement.getMethodIterator().getLast().insertAfter( method ); |
1658 | |
1659 | ············method.addStatement(".maxstack··1"); |
1660 | ············method.addStatement(ldarg_0); |
1661 | ············method.addStatement($"call······ instance int32 {Corlib.Name}System.Object::GetHashCode()"); |
1662 | ············method.addStatement("ret");·············· |
1663 | ········} |
1664 | |
1665 | ········public void |
1666 | ········addObjectState() |
1667 | ········{ |
1668 | ············ILMethodElement method = m_classElement.getMethod( "get_NDOObjectState" ); |
1669 | ············if ( method != null ) |
1670 | ············{ |
1671 | ················method.clearElements(); |
1672 | ············} |
1673 | ············else |
1674 | ············{ |
1675 | ················method = new ILMethodElement(); |
1676 | ················method.addLine( ".method public hidebysig newslot specialname final virtual" ); |
1677 | ················method.addLine( "instance valuetype [NDO]NDO.NDOObjectState get_NDOObjectState() cil managed" ); |
1678 | ················m_classElement.getMethodIterator().getLast().insertAfter( method ); |
1679 | ············} |
1680 | ············method.addStatement( ".maxstack··1" ); |
1681 | ············ |
1682 | ············method.addStatement( "··ldarg.0"); |
1683 | ············method.addStatement( this.loadObjectState() ); |
1684 | ············method.addStatement( "ret"); |
1685 | |
1686 | |
1687 | ············method = m_classElement.getMethod( "set_NDOObjectState" ); |
1688 | ············if ( method != null ) |
1689 | ············{ |
1690 | ················method.clearElements(); |
1691 | ············} |
1692 | ············else |
1693 | ············{ |
1694 | ················method = new ILMethodElement(); |
1695 | ················method.addLine( ".method public hidebysig newslot specialname final virtual" ); |
1696 | ················method.addLine( "instance void··set_NDOObjectState(valuetype [NDO]NDO.NDOObjectState 'value') cil managed" ); |
1697 | ················m_classElement.getMethodIterator().getLast().insertAfter( method ); |
1698 | ············} |
1699 | ············method.addStatement( ".maxstack··2" ); |
1700 | ············ |
1701 | ············method.addStatement( "··ldarg.0"); |
1702 | ············method.addStatement( "··ldarg.1"); |
1703 | ············method.addStatement(this.storeObjectState()); |
1704 | ············method.addStatement( "ret"); |
1705 | |
1706 | |
1707 | ············ILPropertyElement prop = m_classElement.getProperty( "NDOObjectState" ); |
1708 | ············if ( prop == null ) |
1709 | ············{ |
1710 | ················prop = new ILPropertyElement( ".property instance valuetype [NDO]NDO.NDOObjectState NDOObjectState()", m_classElement ); |
1711 | ················prop.addElement( new ILCustomElement( ".custom instance void [System]System.ComponentModel.CategoryAttribute::.ctor(string) = ( 01 00 03 4E 44 4F 00 00 )", prop ) ); |
1712 | ················prop.addElement( new ILCustomElement( ".custom instance void [System.Xml]System.Xml.Serialization.XmlIgnoreAttribute::.ctor() = ( 01 00 00 00 )", prop ) ); |
1713 | ················prop.addElement( new ILGetElement( ".get instance valuetype [NDO]NDO.NDOObjectState " + m_nonGenericRefName + "::get_NDOObjectState()" ) ); |
1714 | ················prop.addElement( new ILSetElement( ".set instance void " + m_nonGenericRefName + "::set_NDOObjectState(valuetype [NDO]NDO.NDOObjectState)" ) ); |
1715 | |
1716 | ················m_classElement.getPropertyIterator().getLast().insertAfter( prop ); |
1717 | ············} |
1718 | |
1719 | ········} |
1720 | |
1721 | ········public void |
1722 | ········removeStateManager() |
1723 | ········{ |
1724 | ············ILMethodElement method = m_classElement.getMethod( "get_NDOStateManager" ); |
1725 | ············if ( method != null ) |
1726 | ················method.remove(); |
1727 | ············method = m_classElement.getMethod( "set_NDOStateManager" ); |
1728 | ············if ( method != null ) |
1729 | ················method.remove(); |
1730 | ············ILPropertyElement prop = m_classElement.getProperty( "NDOStateManager" ); |
1731 | ············if ( prop != null ) |
1732 | ················prop.remove(); |
1733 | ········} |
1734 | |
1735 | |
1736 | ········public void |
1737 | ········addStateManager() |
1738 | ········{ |
1739 | ············ILMethodElement method = m_classElement.getMethod( "get_NDOStateManager" ); |
1740 | ············if ( method != null ) |
1741 | ············{ |
1742 | ················method.clearElements(); |
1743 | ············} |
1744 | ············else |
1745 | ············{ |
1746 | ················method = new ILMethodElement(); |
1747 | ················method.addLine( ".method public hidebysig newslot specialname final virtual" ); |
1748 | ················method.addLine( "instance class [NDO]NDO.IStateManager get_NDOStateManager() cil managed" ); |
1749 | ················m_classElement.getMethodIterator().getLast().insertAfter( method ); |
1750 | ············} |
1751 | ············method.addStatement( ".maxstack··1" ); |
1752 | ············ |
1753 | ············method.addStatement( "··ldarg.0"); |
1754 | ············method.addStatement( loadStateManager()); |
1755 | ············method.addStatement( "ret"); |
1756 | |
1757 | |
1758 | ············method = m_classElement.getMethod( "set_NDOStateManager" ); |
1759 | ············if ( method != null ) |
1760 | ············{ |
1761 | ················method.clearElements(); |
1762 | ············} |
1763 | ············else |
1764 | ············{ |
1765 | ················method = new ILMethodElement(); |
1766 | ················method.addLine( ".method public hidebysig newslot specialname final virtual" ); |
1767 | ················method.addLine( "instance void··set_NDOStateManager(class [NDO]NDO.IStateManager 'value') cil managed" ); |
1768 | ················m_classElement.getMethodIterator().getLast().insertAfter( method ); |
1769 | ············} |
1770 | ············method.addStatement( ".maxstack··2" ); |
1771 | ············ |
1772 | ············method.addStatement( "··ldarg.0"); |
1773 | ············method.addStatement( "··ldarg.1"); |
1774 | ············string statement = loadStateManager(); |
1775 | ············method.addStatement( loadStateManager().Replace("ldfld", "stfld")); |
1776 | ············method.addStatement( "ret"); |
1777 | |
1778 | |
1779 | ············ILPropertyElement prop = m_classElement.getProperty( "NDOStateManager" ); |
1780 | ············if ( prop == null ) |
1781 | ············{ |
1782 | ················prop = new ILPropertyElement( ".property instance class [NDO]NDO.IStateManager NDOStateManager()", m_classElement ); |
1783 | ················prop.addElement( new ILCustomElement( ".custom instance void [System]System.ComponentModel.BrowsableAttribute::.ctor(bool) = ( 01 00 00 00 00 )", prop ) ); |
1784 | ················prop.addElement( new ILCustomElement( ".custom instance void [System.Xml]System.Xml.Serialization.XmlIgnoreAttribute::.ctor() = ( 01 00 00 00 )", prop ) ); |
1785 | ················prop.addElement( new ILGetElement( ".get instance class [NDO]NDO.IStateManager " + m_nonGenericRefName + "::get_NDOStateManager()" ) ); |
1786 | ················prop.addElement( new ILSetElement( ".set instance void " + m_nonGenericRefName + "::set_NDOStateManager(class [NDO]NDO.IStateManager)" ) ); |
1787 | |
1788 | ················m_classElement.getPropertyIterator().getLast().insertAfter( prop ); |
1789 | ············} |
1790 | |
1791 | ········} |
1792 | |
1793 | |
1794 | ········private void insertReadForGuidVtPublicField(ILMethodElement method, ILField field, int nr) |
1795 | ········{ |
1796 | ············string vtname = field.Parent.ILType; |
1797 | ············if (vtname.StartsWith("valuetype")) |
1798 | ················vtname = vtname.Substring(10); |
1799 | |
1800 | ············method.addStatement("\r\n//insertReadForGuidVtPublicField\r\n"); |
1801 | |
1802 | |
1803 | ············method.addStatement($"ldsfld···· class {Corlib.Name}System.DBNull {Corlib.Name}System.DBNull::Value"); |
1804 | ············method.addStatement("beq······GuidIsDbNull" + nr.ToString()); |
1805 | |
1806 | ············method.addStatement("ldloc.0"); |
1807 | ············method.addStatement($"isinst···· {Corlib.Name}System.String"); |
1808 | ············method.addStatement("brfalse.s··nostr" + nr.ToString()); |
1809 | |
1810 | ············method.addStatement(ldarg_0); |
1811 | ············method.addStatement("ldflda···· " + field.Parent.ILType + " " + m_refName + "::" + field.Parent.Name ); |
1812 | ············method.addStatement($"ldflda···· valuetype {Corlib.Name}System.Guid " + vtname + "::" + field.Name); |
1813 | ············method.addStatement("ldloc.0"); |
1814 | ············method.addStatement($"castclass··{Corlib.Name}System.String"); |
1815 | ············method.addStatement($"call······ instance void {Corlib.Name}System.Guid::.ctor(string)"); |
1816 | ············method.addStatement("br.s······ guidready" + nr.ToString()); |
1817 | |
1818 | ············method.addStatement("nostr" + nr.ToString() + ":"); |
1819 | ············method.addStatement("ldloc.0"); |
1820 | ············method.addStatement($"isinst···· {Corlib.Name}System.Guid"); |
1821 | ············method.addStatement("brfalse.s··noguid" + nr.ToString()); |
1822 | |
1823 | ············method.addStatement(ldarg_0); |
1824 | ············method.addStatement("ldflda···· " + field.Parent.ILType + " " + m_refName + "::" + field.Parent.Name ); |
1825 | ············method.addStatement("ldloc.0"); |
1826 | ············method.addStatement($"unbox······{Corlib.Name}System.Guid"); |
1827 | ············method.addStatement($"ldobj······{Corlib.Name}System.Guid"); |
1828 | ············method.addStatement($"stfld······valuetype {Corlib.Name}System.Guid " + vtname + "::" + field.Name); |
1829 | ············method.addStatement("br.s······ guidready" + nr.ToString()); |
1830 | |
1831 | ············method.addStatement("noguid" + nr.ToString() + ":"); |
1832 | ············method.addStatement("ldloc.0"); |
1833 | ············method.addStatement("isinst···· unsigned int8[]"); |
1834 | ············method.addStatement("brfalse.s··nobytearr" + nr.ToString()); |
1835 | |
1836 | ············method.addStatement(ldarg_0); |
1837 | ············method.addStatement("ldflda···· " + field.Parent.ILType + " " + m_refName + "::" + field.Parent.Name ); |
1838 | ············method.addStatement($"ldflda···· valuetype {Corlib.Name}System.Guid " + vtname +"::" + field.Name); |
1839 | ············method.addStatement("ldloc.0"); |
1840 | ············method.addStatement("castclass··unsigned int8[]"); |
1841 | ············method.addStatement($"call······ instance void {Corlib.Name}System.Guid::.ctor(unsigned int8[])"); |
1842 | ············method.addStatement("br.s······ guidready" + nr.ToString()); |
1843 | |
1844 | ············method.addStatement("nobytearr" + nr.ToString() + ":"); |
1845 | ············method.addStatement(@"ldstr······""Can't convert Guid field to column type {0}"""); |
1846 | ············method.addStatement("ldloc.0"); |
1847 | ············method.addStatement($"callvirt·· instance class {Corlib.Name}System.Type {Corlib.Name}System.Object::GetType()"); |
1848 | ············method.addStatement($"callvirt·· instance string {Corlib.Name}System.Type::get_FullName()"); |
1849 | ············method.addStatement($"call······ string {Corlib.Name}System.String::Format(string,object)"); |
1850 | ············method.addStatement($"newobj···· instance void {Corlib.Name}System.Exception::.ctor(string)"); |
1851 | ············method.addStatement("throw"); |
1852 | |
1853 | ············method.addStatement("GuidIsDbNull" + nr.ToString() + ":"); |
1854 | ············method.addStatement(ldarg_0); |
1855 | ············method.addStatement("ldflda···· " + field.Parent.ILType + " " + m_refName + "::" + field.Parent.Name ); |
1856 | ············method.addStatement($"ldsfld···· valuetype {Corlib.Name}System.Guid {Corlib.Name}System.Guid::Empty"); |
1857 | ············method.addStatement($"stfld······valuetype {Corlib.Name}System.Guid " + vtname + "::" + field.Name); |
1858 | |
1859 | ············method.addStatement("guidready" + nr.ToString() + ":"); |
1860 | ········} |
1861 | |
1862 | ········private void insertReadForGuidVtProperty(ILMethodElement method, ILField field, int nr) |
1863 | ········{ |
1864 | ············string vtname = field.Parent.ILType; |
1865 | ············if (vtname.StartsWith("valuetype")) |
1866 | ················vtname = vtname.Substring(10); |
1867 | ············method.addStatement("\r\n//insertReadForGuidVtProperty\r\n"); |
1868 | |
1869 | ············method.addStatement($"ldsfld···· class {Corlib.Name}System.DBNull {Corlib.Name}System.DBNull::Value"); |
1870 | ············method.addStatement("beq.s······GuidIsDbNull" + nr.ToString()); |
1871 | |
1872 | ············method.addStatement("ldloc.0"); |
1873 | ············method.addStatement($"isinst···· {Corlib.Name}System.String"); |
1874 | ············method.addStatement("brfalse.s··nostr" + nr.ToString()); |
1875 | |
1876 | ············method.addStatement(ldarg_0); |
1877 | ············method.addStatement("ldflda···· " + field.Parent.ILType + " " + m_refName + "::" + field.Parent.Name ); |
1878 | ············method.addStatement("ldloc.0"); |
1879 | ············method.addStatement($"castclass··{Corlib.Name}System.String"); |
1880 | ············method.addStatement($"newobj···· instance void {Corlib.Name}System.Guid::.ctor(string)"); |
1881 | ············method.addStatement($"call······ instance void " + vtname +"::" + getAccName("set_", field.Name) + $"(valuetype {Corlib.Name}System.Guid)"); |
1882 | ············method.addStatement("br.s······ guidready" + nr.ToString()); |
1883 | |
1884 | ············method.addStatement("nostr" + nr.ToString() + ":"); |
1885 | ············method.addStatement("ldloc.0"); |
1886 | ············method.addStatement($"isinst···· {Corlib.Name}System.Guid"); |
1887 | ············method.addStatement("brfalse.s··noguid" + nr.ToString()); |
1888 | |
1889 | ············method.addStatement(ldarg_0); |
1890 | ············method.addStatement("ldflda···· " + field.Parent.ILType + " " + m_refName + "::" + field.Parent.Name ); |
1891 | ············method.addStatement("ldloc.0"); |
1892 | ············method.addStatement($"unbox······{Corlib.Name}System.Guid"); |
1893 | ············method.addStatement($"ldobj······{Corlib.Name}System.Guid"); |
1894 | ············method.addStatement("call······ instance void " + vtname +"::" + getAccName("set_", field.Name) + $"(valuetype {Corlib.Name}System.Guid)"); |
1895 | ············method.addStatement("br.s······ guidready" + nr.ToString()); |
1896 | |
1897 | ············method.addStatement("noguid" + nr.ToString() + ":"); |
1898 | ············method.addStatement("ldloc.0"); |
1899 | ············method.addStatement("isinst···· unsigned int8[]"); |
1900 | ············method.addStatement("brfalse.s··nobytearr" + nr.ToString()); |
1901 | |
1902 | ············method.addStatement(ldarg_0); |
1903 | ············method.addStatement("ldflda···· " + field.Parent.ILType + " " + m_refName + "::" + field.Parent.Name ); |
1904 | ············method.addStatement("ldloc.0"); |
1905 | ············method.addStatement("castclass··unsigned int8[]"); |
1906 | ············method.addStatement($"newobj···· instance void {Corlib.Name}System.Guid::.ctor(unsigned int8[])"); |
1907 | ············method.addStatement("call······ instance void " + vtname +"::" + getAccName("set_", field.Name) + $"(valuetype {Corlib.Name}System.Guid)"); |
1908 | ············method.addStatement("br.s······ guidready" + nr.ToString()); |
1909 | |
1910 | ············method.addStatement("nobytearr" + nr.ToString() +":"); |
1911 | ············method.addStatement(@"ldstr······""Can't convert Guid field to column type {0}"""); |
1912 | ············method.addStatement("ldloc.0"); |
1913 | ············method.addStatement($"callvirt·· instance class {Corlib.Name}System.Type {Corlib.Name}System.Object::GetType()"); |
1914 | ············method.addStatement($"callvirt·· instance string {Corlib.Name}System.Type::get_FullName()"); |
1915 | ············method.addStatement($"call······ string {Corlib.Name}System.String::Format(string,object)"); |
1916 | ············method.addStatement($"newobj···· instance void {Corlib.Name}System.Exception::.ctor(string)"); |
1917 | ············method.addStatement("throw"); |
1918 | |
1919 | ············method.addStatement("GuidIsDbNull" + nr.ToString() + ":"); |
1920 | ············method.addStatement(ldarg_0); |
1921 | ············method.addStatement("ldflda···· " + field.Parent.ILType + " " + m_refName + "::" + field.Parent.Name ); |
1922 | ············method.addStatement($"ldsfld···· valuetype {Corlib.Name}System.Guid {Corlib.Name}System.Guid::Empty"); |
1923 | ············method.addStatement("call······ instance void " + vtname +"::" + getAccName("set_", field.Name) + $"(valuetype {Corlib.Name}System.Guid)"); |
1924 | |
1925 | ············method.addStatement("guidready" + nr.ToString() +":"); |
1926 | ········} |
1927 | |
1928 | |
1929 | ········private void insertReadForGuidMember(ILMethodElement method, ILField field, int nr) |
1930 | ········{ |
1931 | ············method.addStatement("\n//insertReadForGuidMember\n"); |
1932 | ············// |
1933 | ············method.addStatement($"ldsfld···· class {Corlib.Name}System.DBNull {Corlib.Name}System.DBNull::Value"); |
1934 | ············method.addStatement("beq.s······GuidIsDbNull" + nr.ToString()); |
1935 | ············method.addStatement("ldloc.0"); |
1936 | |
1937 | ············method.addStatement($"isinst···· {Corlib.Name}System.String"); |
1938 | ············method.addStatement("brfalse.s··nostr" + nr.ToString()); |
1939 | |
1940 | ············method.addStatement(ldarg_0); |
1941 | ············method.addStatement($"ldflda···· valuetype {Corlib.Name}System.Guid " + m_refName + "::" + field.Name); |
1942 | ············method.addStatement("ldloc.0"); |
1943 | ············method.addStatement($"castclass··{Corlib.Name}System.String"); |
1944 | ············method.addStatement($"call······ instance void {Corlib.Name}System.Guid::.ctor(string)"); |
1945 | ············method.addStatement("br.s······ guidready" + nr.ToString()); |
1946 | |
1947 | ············method.addStatement("nostr" + nr.ToString() + ":"); |
1948 | ············method.addStatement("ldloc.0"); |
1949 | ············method.addStatement($"isinst···· {Corlib.Name}System.Guid"); |
1950 | ············method.addStatement("brfalse.s··noguid" + nr.ToString()); |
1951 | |
1952 | ············method.addStatement(ldarg_0); |
1953 | ············method.addStatement("ldloc.0"); |
1954 | ············method.addStatement($"unbox······{Corlib.Name}System.Guid"); |
1955 | ············method.addStatement($"ldobj······{Corlib.Name}System.Guid"); |
1956 | ············method.addStatement($"stfld······valuetype {Corlib.Name}System.Guid " + m_refName + "::" + field.Name); |
1957 | ············method.addStatement("br.s······ guidready" + nr.ToString()); |
1958 | ············method.addStatement("noguid" + nr.ToString() + ":"); |
1959 | ············method.addStatement("ldloc.0"); |
1960 | ············method.addStatement("isinst···· unsigned int8[]"); |
1961 | ············method.addStatement("brfalse.s··nobytearr" + nr.ToString()); |
1962 | |
1963 | ············method.addStatement(ldarg_0); |
1964 | ············method.addStatement($"ldflda···· valuetype {Corlib.Name}System.Guid " + m_refName + "::" + field.Name); |
1965 | ············method.addStatement("ldloc.0"); |
1966 | ············method.addStatement("castclass··unsigned int8[]"); |
1967 | ············method.addStatement($"call······ instance void {Corlib.Name}System.Guid::.ctor(unsigned int8[])"); |
1968 | ············method.addStatement("br.s······ guidready" + nr.ToString()); |
1969 | |
1970 | ············method.addStatement("nobytearr" + nr.ToString() + ":"); |
1971 | ············method.addStatement(@"ldstr······""Can't convert Guid field to column type {0}"""); |
1972 | ············method.addStatement("ldloc.0"); |
1973 | ············method.addStatement($"callvirt·· instance class {Corlib.Name}System.Type {Corlib.Name}System.Object::GetType()"); |
1974 | ············method.addStatement($"callvirt·· instance string {Corlib.Name}System.Type::get_FullName()"); |
1975 | ············method.addStatement($"call······ string {Corlib.Name}System.String::Format(string,object)"); |
1976 | ············method.addStatement($"newobj···· instance void {Corlib.Name}System.Exception::.ctor(string)"); |
1977 | ············method.addStatement("throw"); |
1978 | |
1979 | ············method.addStatement("GuidIsDbNull" + nr.ToString() + ":"); |
1980 | ············method.addStatement(ldarg_0); |
1981 | ············method.addStatement($"ldsfld···· valuetype {Corlib.Name}System.Guid {Corlib.Name}System.Guid::Empty"); |
1982 | ············method.addStatement($"stfld······valuetype {Corlib.Name}System.Guid " + m_refName + "::" + field.Name); |
1983 | |
1984 | ············method.addStatement("guidready" + nr.ToString() + ":"); |
1985 | ········} |
1986 | |
1987 | ········private void |
1988 | ············insertReadForGuid(ILMethodElement method, ILField field, int nr, bool parentIsValueType) |
1989 | ········{ |
1990 | ············if (!parentIsValueType) |
1991 | ················insertReadForGuidMember(method, field, nr); |
1992 | ············else if (field.IsProperty) |
1993 | ················insertReadForGuidVtProperty(method, field, nr); |
1994 | ············else |
1995 | ················insertReadForGuidVtPublicField(method, field, nr); |
1996 | ········} |
1997 | |
1998 | ········private void |
1999 | ············insertReadForDateTime(ILMethodElement method, ILField field, int nr, bool parentIsValueType) |
2000 | ········{ |
2001 | ············method.addStatement($"ldsfld···· class {Corlib.Name}System.DBNull {Corlib.Name}System.DBNull::Value"); |
2002 | ············method.addStatement("beq.s······DateTimeIsNull" + nr); |
2003 | ············if (!parentIsValueType)········// Member |
2004 | ············{ |
2005 | ················method.addStatement(ldarg_0); |
2006 | ················method.addStatement("ldloc.0"); |
2007 | ················method.addStatement($"unbox······{Corlib.Name}System.DateTime"); |
2008 | ················method.addStatement($"ldobj······{Corlib.Name}System.DateTime"); |
2009 | ················method.addStatement($"stfld······valuetype {Corlib.Name}System.DateTime " + m_refName + "::" + field.Name); |
2010 | ················method.addStatement("br.s······ DateTimeReady" + nr); |
2011 | ················method.addStatement("DateTimeIsNull" + nr + ":"); |
2012 | ················method.addStatement(ldarg_0); |
2013 | ················method.addStatement($"ldsfld···· valuetype {Corlib.Name}System.DateTime {Corlib.Name}System.DateTime::MinValue"); |
2014 | ················method.addStatement($"stfld······valuetype {Corlib.Name}System.DateTime " + m_refName + "::" + field.Name); |
2015 | ············} |
2016 | ············else if (field.IsProperty)··// Vt with property |
2017 | ············{ |
2018 | ················method.addStatement(ldarg_0); |
2019 | ················method.addStatement("ldflda···· " + field.Parent.ILType + " " + m_refName + "::" + field.Parent.Name); |
2020 | ················method.addStatement("ldloc.0"); |
2021 | ················method.addStatement($"unbox······{Corlib.Name}System.DateTime"); |
2022 | ················method.addStatement($"ldobj······{Corlib.Name}System.DateTime"); |
2023 | ················method.addStatement("call······ instance void " + field.Parent.PureTypeName + "::" + getAccName("set_", field.Name) + $"(valuetype {Corlib.Name}System.DateTime)"); |
2024 | ················method.addStatement("br.s······ DateTimeReady" + nr); |
2025 | ················method.addStatement("DateTimeIsNull" + nr + ":"); |
2026 | ················method.addStatement(ldarg_0); |
2027 | ················method.addStatement("ldflda···· " + field.Parent.ILType + " " + m_refName + "::" + field.Parent.Name); |
2028 | ················method.addStatement($"ldsfld···· valuetype {Corlib.Name}System.DateTime {Corlib.Name}System.DateTime::MinValue"); |
2029 | ················method.addStatement("call······ instance void " + field.Parent.PureTypeName + "::" + getAccName("set_", field.Name) + $"(valuetype {Corlib.Name}System.DateTime)"); |
2030 | ············} |
2031 | ············else························// Vt with public field |
2032 | ············{ |
2033 | ················method.addStatement(ldarg_0); |
2034 | ················method.addStatement("ldflda···· " + field.Parent.ILType + " " + m_refName + "::" + field.Parent.Name); |
2035 | ················method.addStatement("ldloc.0"); |
2036 | ················method.addStatement($"unbox······{Corlib.Name}System.DateTime"); |
2037 | ················method.addStatement($"ldobj······{Corlib.Name}System.DateTime"); |
2038 | ················method.addStatement($"stfld······valuetype {Corlib.Name}System.DateTime " + field.Parent.PureTypeName + "::" + field.Name); |
2039 | ················method.addStatement("br.s······ DateTimeReady" + nr); |
2040 | ················method.addStatement("DateTimeIsNull" + nr + ":"); |
2041 | ················method.addStatement(ldarg_0); |
2042 | ················method.addStatement("ldflda···· " + field.Parent.ILType + " " + m_refName + "::" + field.Parent.Name); |
2043 | ················method.addStatement($"ldsfld···· valuetype {Corlib.Name}System.DateTime {Corlib.Name}System.DateTime::MinValue"); |
2044 | ················method.addStatement($"stfld······valuetype {Corlib.Name}System.DateTime " + field.Parent.PureTypeName + "::" + field.Name); |
2045 | ············} |
2046 | ············method.addStatement("DateTimeReady" + nr + ":"); |
2047 | ········} |
2048 | |
2049 | |
2050 | ········private void |
2051 | ········insertReadForGenericType(ILMethodElement method, ILField field, int nr) |
2052 | ········{ |
2053 | ············method.addStatement($"ldsfld···· class {Corlib.Name}System.DBNull {Corlib.Name}System.DBNull::Value"); |
2054 | ············method.addStatement("ceq"); |
2055 | ············method.addStatement("brtrue.s·· FieldOver" + nr); |
2056 | ············method.addStatement(ldarg_0); |
2057 | ············method.addStatement("ldloc.0"); |
2058 | ············method.addStatement("ldtoken····" + field.ILType); |
2059 | ············method.addStatement($"call······ class {Corlib.Name}System.Type {Corlib.Name}System.Type::GetTypeFromHandle(valuetype {Corlib.Name}System.RuntimeTypeHandle)"); |
2060 | ············method.addStatement($"call······ object [NDO]NDO.GenericFieldConverter::FromString(object,class {Corlib.Name}System.Type)"); |
2061 | ············method.addStatement("unbox.any··" + field.ILType); |
2062 | ············method.addStatement("stfld······"+ field.ILType + " " + m_refName + "::" + field.Name); |
2063 | ········} |
2064 | |
2065 | |
2066 | ········private void |
2067 | ············addReadForGuidNullable(ILMethodElement method, ILField field, int nr) |
2068 | ········{ |
2069 | ············method.addStatement($"isinst···· {Corlib.Name}System.String"); |
2070 | ············method.addStatement("brfalse.s··nostring" + nr); |
2071 | ············method.addStatement("ldloc.0"); |
2072 | ············method.addStatement($"castclass··{Corlib.Name}System.String"); |
2073 | ············method.addStatement($"newobj···· instance void {Corlib.Name}System.Guid::.ctor(string)"); |
2074 | ············method.addStatement("br.s······ guidready" + nr); |
2075 | ············method.addStatement("nostring" + nr + ':'); |
2076 | ············method.addStatement("ldloc.0"); |
2077 | ············method.addStatement($"isinst···· {Corlib.Name}System.Guid"); |
2078 | ············method.addStatement("brfalse.s··noguid" + nr); |
2079 | ············method.addStatement("ldloc.0"); |
2080 | ············method.addStatement($"unbox.any··{Corlib.Name}System.Guid"); |
2081 | ············method.addStatement("br.s······ guidready" + nr); |
2082 | ············method.addStatement("noguid" + nr + ':'); |
2083 | ············method.addStatement("ldstr······\"Can't convert type \""); |
2084 | ············method.addStatement("ldloc.0"); |
2085 | ············method.addStatement($"callvirt·· instance class {Corlib.Name}System.Type {Corlib.Name}System.Object::GetType()"); |
2086 | ············method.addStatement($"callvirt·· instance string {Corlib.Name}System.Type::get_FullName()"); |
2087 | ············method.addStatement("ldstr······\" to field type System.Guid.\""); |
2088 | ············method.addStatement($"call······ string {Corlib.Name}System.String::Concat(string,string,string)"); |
2089 | ············method.addStatement($"newobj···· instance void {Corlib.Name}System.Exception::.ctor(string)"); |
2090 | ············method.addStatement("throw"); |
2091 | ············method.addStatement("guidready" + nr + ':'); |
2092 | ············method.addStatement($"newobj···· instance void valuetype {Corlib.Name}System.Nullable`1<valuetype {Corlib.Name}System.Guid>::.ctor(!0)"); |
2093 | |
2094 | ········} |
2095 | |
2096 | ········private void |
2097 | ············addReadForField(ILMethodElement method, ILField field, int nr) |
2098 | ········{ |
2099 | ············Type t = field.FieldType; |
2100 | ············if (t == null) |
2101 | ················throw new InternalException(1917, "Class.cs: Type for field··" + m_refName + "." + field.CleanName + " is null."); |
2102 | ············string prefix; |
2103 | ············bool parentIsValueType = field.Parent != null && field.Parent.IsValueType; |
2104 | ············if (parentIsValueType) |
2105 | ················prefix = field.Parent.CleanName; |
2106 | ············else |
2107 | ················prefix = string.Empty; |
2108 | ············string fname = prefix + field.CleanName; |
2109 | ············string tname = field.ILType; |
2110 | ············//············Testweise Ausgabe der Feldnamen |
2111 | ············//············method.addStatement("ldarg.2"); |
2112 | ············//············method.addStatement("··ldarg.3"); |
2113 | ············//············method.addStatement("··ldc.i4.s " + nr.ToString()); |
2114 | ············//············method.addStatement("··add"); |
2115 | ············//············method.addStatement("ldelem.ref"); |
2116 | ············//············method.addStatement($"call······ void {Corlib.Name}System.Console::WriteLine(string)"); |
2117 | |
2118 | ············bool isNullable = false; |
2119 | |
2120 | ············Type argType = null; |
2121 | ············string argTypeName = string.Empty; |
2122 | ············if (tname.StartsWith($"valuetype {Corlib.Name}System.Nullable`1<")) |
2123 | ············{ |
2124 | ················isNullable = true; |
2125 | ················argType = t.GetGenericArguments()[0]; |
2126 | ················argTypeName = new ReflectedType(argType, this.m_classElement.getAssemblyName()).QuotedILName; |
2127 | ············} |
2128 | |
2129 | ············method.addStatement("ldarg.1"); |
2130 | ············method.addStatement("ldarg.2"); |
2131 | ············method.addStatement("ldarg.3"); |
2132 | ············if (nr != 0) |
2133 | ············{ |
2134 | ················method.addStatement("ldc.i4.s " + nr.ToString()); |
2135 | ················method.addStatement("add"); |
2136 | ············} |
2137 | |
2138 | ············method.addStatement("dup"); |
2139 | ············method.addStatement("stloc.1"); |
2140 | |
2141 | ············method.addStatement("ldelem.ref"); |
2142 | ············method.addStatement("callvirt·· instance object [System.Data]System.Data.DataRow::get_Item(string)"); |
2143 | ············method.addStatement("dup"); |
2144 | ············method.addStatement("stloc.0"); |
2145 | |
2146 | ············// Special treatment for DateTime and Guid values to map to and from DBNull |
2147 | ············if (tname == $"valuetype {Corlib.Name}System.Guid") |
2148 | ············{ |
2149 | ················insertReadForGuid(method, field, nr, parentIsValueType); |
2150 | ················goto theexit; |
2151 | ············} |
2152 | ············else if (tname == $"valuetype {Corlib.Name}System.DateTime") |
2153 | ············{ |
2154 | ················insertReadForDateTime(method, field, nr, parentIsValueType); |
2155 | ················goto theexit; |
2156 | ············} |
2157 | ············else if (tname.StartsWith("!")) |
2158 | ············{ |
2159 | ················insertReadForGenericType(method, field, nr); |
2160 | ················goto theexit; |
2161 | ············} |
2162 | ············else |
2163 | ············{ |
2164 | ················method.addStatement($"ldsfld···· class {Corlib.Name}System.DBNull {Corlib.Name}System.DBNull::Value"); |
2165 | ················method.addStatement("beq······FieldNull" + nr.ToString()); |
2166 | ············} |
2167 | |
2168 | ············method.addStatement(ldarg_0); |
2169 | ············if (parentIsValueType) |
2170 | ················method.addStatement("ldflda···· " + field.Parent.ILType + " " + m_refName + "::" + field.Parent.Name); |
2171 | ············method.addStatement("ldloc.0"); |
2172 | ············if (tname == "string" || tname == "unsigned int8[]" || tname == $"class {Corlib.Name}System.String" || tname == $"class {Corlib.Name}System.Byte[]") |
2173 | ················method.addStatement("··castclass··" + tname); |
2174 | ············else if (tname.StartsWith("valuetype")) |
2175 | ············{ |
2176 | ················string tname2 = tname.Substring(10); |
2177 | |
2178 | ················if (isNullable) |
2179 | ················{ |
2180 | ····················if (typeof(System.Enum).IsAssignableFrom(argType)) |
2181 | ····················{ |
2182 | ························method.addStatement("unbox.any " + argTypeName); |
2183 | ························method.addStatement($"newobj···· instance void valuetype {Corlib.Name}System.Nullable`1<" + argTypeName + ">::.ctor(!0)"); |
2184 | ····················} |
2185 | ····················else if (argType == typeof(Guid)) |
2186 | ····················{ |
2187 | ························addReadForGuidNullable(method, field, nr); |
2188 | ····················} |
2189 | ····················else |
2190 | ····················{ |
2191 | ························method.addStatement("unbox.any··" + tname); |
2192 | ····················} |
2193 | ················} |
2194 | ················else |
2195 | ················{ |
2196 | ····················method.addStatement("unbox··" + tname2); |
2197 | ····················method.addStatement("ldobj··" + tname2); |
2198 | ················} |
2199 | ············} |
2200 | ············else |
2201 | ············{ |
2202 | ················if (tname == "unsigned int8") |
2203 | ····················method.addStatement($"unbox {Corlib.Name}System.Byte"); |
2204 | ················else |
2205 | ····················method.addStatement("unbox··" + tname); |
2206 | ················string indType = indTypes[tname] as string; |
2207 | ················if (indType == null) |
2208 | ················{ |
2209 | ····················messages.ShowError("Don't know how to handle the type of the field '" + m_refName + '.' + fname + "'. Trying to continue enhancing."); |
2210 | ····················goto theexit; |
2211 | ················} |
2212 | ················else |
2213 | ····················method.addStatement("ldind." + indType); |
2214 | ············} |
2215 | |
2216 | ············if (!parentIsValueType) |
2217 | ············{ |
2218 | ················// nicht fname verwenden, weil evtl. die Anführungsstriche gebraucht werden |
2219 | ················method.addStatement("··stfld······" + tname + " " + m_refName+ "::" + field.Name); |
2220 | ············} |
2221 | ············else |
2222 | ············{ |
2223 | ················string vtname = field.Parent.ILType; |
2224 | ················if (vtname.StartsWith("valuetype")) |
2225 | ····················vtname = vtname.Substring(10); |
2226 | ················if (field.IsProperty) |
2227 | ················{ |
2228 | ····················string accname = this.getAccName("set_", field.Name); |
2229 | ····················method.addStatement("··call······ instance void " + vtname + "::" + accname + "(" + field.ILType + ")"); |
2230 | ····················//····················method.addStatement("··call······ instance void " + vtname + "::" + accname + "(" + field.ILAsmType + ")"); |
2231 | ················} |
2232 | ················else |
2233 | ················{ |
2234 | ····················method.addStatement("··stfld······ " + field.ILType + " " + vtname + "::" + field.Name); |
2235 | ················} |
2236 | ············} |
2237 | ············method.addStatement("br······FieldOver" + nr.ToString()); |
2238 | |
2239 | ············theexit: |
2240 | ················method.addStatement("FieldNull" + nr.ToString() + ":"); |
2241 | ············#if !NDO11 |
2242 | ················if (isNullable) |
2243 | ················{ |
2244 | ····················method.addStatement(ldarg_0); |
2245 | ····················method.addStatement($"ldflda···· valuetype {Corlib.Name}System.Nullable`1<" + argTypeName + "> " + m_refName + "::" + field.Name); |
2246 | ····················method.addStatement($"initobj····valuetype {Corlib.Name}System.Nullable`1<" + argTypeName + ">"); |
2247 | ················} |
2248 | ············#endif |
2249 | ················method.addStatement("FieldOver" + nr.ToString() + ":"); |
2250 | |
2251 | ········} |
2252 | |
2253 | ········// |
2254 | ········// addRead |
2255 | ········// |
2256 | ········public void addRead() |
2257 | ········{ |
2258 | ············ILMethodElement method = m_classElement.getMethod( "NDORead" ); |
2259 | ············if ( method == null ) |
2260 | ············{ |
2261 | ················method = new ILMethodElement(); |
2262 | |
2263 | ················if ( m_hasPersistentBase ) |
2264 | ····················method.addLine( ".method public hidebysig virtual" ); |
2265 | ················else |
2266 | ····················method.addLine( ".method public hidebysig newslot virtual" ); |
2267 | ················method.addLine( "instance void··NDORead(class [System.Data]System.Data.DataRow dr, string[] fields, int32 startind) cil managed" ); |
2268 | ················m_classElement.getMethodIterator().getLast().insertAfter( method ); |
2269 | ············} |
2270 | ············else |
2271 | ············{ |
2272 | ················method.clearElements(); |
2273 | ············} |
2274 | ············method.addStatement(".maxstack··8" ); |
2275 | ············addLocalVariable(method, "theObject", "object"); |
2276 | ············addLocalVariable(method, "i", "int32"); |
2277 | ············addLocalVariable(method, $"ex", $"class {Corlib.Name}System.Exception"); |
2278 | |
2279 | ············method.addStatement("ldc.i4.0"); |
2280 | ············method.addStatement("stloc.1"); |
2281 | |
2282 | ············method.addStatement("ldarg.1"); |
2283 | ············method.addStatement("brtrue·· rownotnull"); |
2284 | ············method.addStatement(@"ldstr······""NDORead: DataRow ist null"""); |
2285 | ············method.addStatement($"newobj···· instance void {Corlib.Name}System.Exception::.ctor(string)"); |
2286 | ············method.addStatement("throw"); |
2287 | ············method.addStatement("rownotnull: "); |
2288 | |
2289 | ············ILStatementElement[] fixupElements = new ILStatementElement[2]; |
2290 | |
2291 | ············method.addStatement("ldarg.3"); |
2292 | ············fixupElements[0] = new ILStatementElement("ldc.i4.s ##fieldcount"); |
2293 | ············method.addElement(fixupElements[0]); |
2294 | ············method.addStatement("add"); |
2295 | ············method.addStatement("ldarg.2"); |
2296 | ············method.addStatement("ldlen"); |
2297 | ············method.addStatement("conv.i4"); |
2298 | ············method.addStatement("ble.s······indexbigger"); |
2299 | ············method.addStatement(@"ldstr······""NDORead: Index {0} is bigger than maximum index of fields array ({1})"""); |
2300 | ············method.addStatement("ldarg.3"); |
2301 | ············fixupElements[1] = new ILStatementElement("ldc.i4.s ##fieldcount"); |
2302 | ············method.addElement(fixupElements[1]); |
2303 | ············method.addStatement("add"); |
2304 | ············method.addStatement($"box········{Corlib.Name}System.Int32"); |
2305 | ············method.addStatement("ldarg.2"); |
2306 | ············method.addStatement("ldlen"); |
2307 | ············method.addStatement("conv.i4"); |
2308 | ············method.addStatement("ldc.i4.1"); |
2309 | ············method.addStatement("sub"); |
2310 | |
2311 | ············method.addStatement($"box········{Corlib.Name}System.Int32"); |
2312 | ············method.addStatement($"call······ string {Corlib.Name}System.String::Format(string, object, object)"); |
2313 | ············method.addStatement($"newobj···· instance void {Corlib.Name}System.Exception::.ctor(string)"); |
2314 | ············method.addStatement("throw"); |
2315 | |
2316 | ············method.addStatement("indexbigger: "); |
2317 | |
2318 | ············method.addStatement(".try {"); |
2319 | ············int nr = 0; |
2320 | |
2321 | ············for(int i = 0; i < this.mappedFieldCount; i++) |
2322 | ············{ |
2323 | ················DictionaryEntry e = (DictionaryEntry) sortedFields[i]; |
2324 | ················ILField field = (ILField) e.Value; |
2325 | ················if (field.Parent != null && field.Parent.IsEmbeddedType) |
2326 | ····················continue; |
2327 | ················addReadForField(method, field, nr); |
2328 | ················nr++; |
2329 | ············} |
2330 | ············fixupElements[0].replaceText("##fieldcount", nr.ToString()); |
2331 | ············nr--; |
2332 | ············fixupElements[1].replaceText("##fieldcount", nr.ToString()); |
2333 | ············nr++; |
2334 | |
2335 | ············method.addStatement("leave.s····aftercatch"); |
2336 | |
2337 | ············method.addStatement("}··// end .try"); |
2338 | ············method.addStatement($"catch {Corlib.Name}System.Exception"); |
2339 | ············method.addStatement("{"); |
2340 | ············method.addStatement("stloc.2"); |
2341 | ············method.addStatement(@"ldstr······""Error while writing to field """); |
2342 | ············method.addStatement("ldarg.2"); |
2343 | ············method.addStatement("ldloc.1"); |
2344 | ············method.addStatement("ldelem.ref"); |
2345 | ············method.addStatement(@"ldstr······""\n"""); |
2346 | ············method.addStatement("ldloc.2"); |
2347 | ············method.addStatement($"callvirt·· instance string {Corlib.Name}System.Exception::get_Message()"); |
2348 | ············method.addStatement($"call······ string {Corlib.Name}System.String::Concat(string,string,string,string)"); |
2349 | ············method.addStatement($"newobj···· instance void {Corlib.Name}System.Exception::.ctor(string)"); |
2350 | ············method.addStatement("throw"); |
2351 | ············method.addStatement("}··// end handler"); |
2352 | |
2353 | ············method.addStatement("aftercatch: "); |
2354 | |
2355 | ············if (m_hasPersistentBase) |
2356 | ············{ |
2357 | ················method.addStatement(ldarg_0); |
2358 | ················method.addStatement(ldarg_1); |
2359 | ················method.addStatement("ldarg.2"); |
2360 | ················method.addStatement("ldarg.3"); |
2361 | ················method.addStatement("ldc.i4.s " + nr.ToString()); |
2362 | ················method.addStatement("add"); |
2363 | ················method.addStatement("call······ instance void " + m_persistentBase + "::NDORead(class [System.Data]System.Data.DataRow dr, string[] fields, int32 startind)"); |
2364 | ············} |
2365 | ············method.addStatement("ret"); |
2366 | ········} |
2367 | |
2368 | ········private void insertWriteForGenericTypes(ILMethodElement method, ILField field, int nr) |
2369 | ········{ |
2370 | ············method.addStatement(ldarg_0); |
2371 | ············method.addStatement("ldfld······" + field.ILType + " " + m_refName + "::" + field.Name); |
2372 | ············method.addStatement("box········" + field.ILType); |
2373 | ············method.addStatement("call······ string [NDO]NDO.GenericFieldConverter::ToString(object)"); |
2374 | ········} |
2375 | |
2376 | ········private void insertWriteForVtField(ILMethodElement method, ILField field, int nr, bool parentIsValueType, string type) |
2377 | ········{ |
2378 | ············string empty = (type == "Guid") ? type + "::Empty" : type + "::MinValue"; |
2379 | ············if (!parentIsValueType) // Member |
2380 | ············{ |
2381 | ················method.addStatement(ldarg_0); |
2382 | ················method.addStatement($"ldfld······valuetype {Corlib.Name}System." + type + " " + m_refName + "::" + field.Name); |
2383 | ················method.addStatement($"ldsfld···· valuetype {Corlib.Name}System." + type + $" {Corlib.Name}System." + empty); |
2384 | ················method.addStatement($"call······ bool {Corlib.Name}System.{type}::op_Inequality(valuetype {Corlib.Name}System.{type}, valuetype {Corlib.Name}System.{type})"); |
2385 | ················method.addStatement("brtrue.s·· VtFieldIsNotEmpty" + nr.ToString()); |
2386 | ················method.addStatement($"ldsfld···· class {Corlib.Name}System.DBNull {Corlib.Name}System.DBNull::Value"); |
2387 | ················method.addStatement("br.s······ VtFieldReady" + nr.ToString()); |
2388 | ················method.addStatement("VtFieldIsNotEmpty" + nr.ToString() + ":"); |
2389 | ················method.addStatement(ldarg_0); |
2390 | ················method.addStatement($"ldfld······valuetype {Corlib.Name}System." + type + " " + m_refName + "::" + field.Name); |
2391 | ················method.addStatement($"box········{Corlib.Name}System." + type + ""); |
2392 | ················method.addStatement("VtFieldReady" + nr.ToString() + ":"); |
2393 | ············} |
2394 | ············else if (field.IsProperty) // ValueType mit Property |
2395 | ············{ |
2396 | ················method.addStatement(ldarg_0); |
2397 | ················method.addStatement("ldflda···· " + field.Parent.ILType + " " + m_refName + "::" + field.Parent.Name);································································································································ |
2398 | ················method.addStatement($"call······ instance valuetype {Corlib.Name}System." + type + " " + field.Parent.PureTypeName + "::" + getAccName("get_", field.Name) + "()"); |
2399 | |
2400 | ················method.addStatement($"ldsfld···· valuetype {Corlib.Name}System." + type + $" {Corlib.Name}System." + empty); |
2401 | ················method.addStatement($"call······ bool {Corlib.Name}System." + type + $"::op_Inequality(valuetype {Corlib.Name}System." + type + $",valuetype {Corlib.Name}System." + type + ")"); |
2402 | ················method.addStatement("brtrue.s·· VtFieldIsNotEmpty" + nr.ToString()); |
2403 | ················method.addStatement($"ldsfld···· class {Corlib.Name}System.DBNull {Corlib.Name}System.DBNull::Value"); |
2404 | ················method.addStatement("br.s······ VtFieldReady" + nr.ToString()); |
2405 | ················method.addStatement("VtFieldIsNotEmpty" + nr.ToString() + ":"); |
2406 | ················method.addStatement(ldarg_0); |
2407 | ················method.addStatement("ldflda···· " + field.Parent.ILType + " " + m_refName + "::" + field.Parent.Name);································································································································ |
2408 | ················method.addStatement($"call······ instance valuetype {Corlib.Name}System." + type + " " + field.Parent.PureTypeName + "::" + getAccName("get_", field.Name) + "()"); |
2409 | ················method.addStatement($"box········{Corlib.Name}System." + type + ""); |
2410 | ················method.addStatement("VtFieldReady" + nr.ToString() + ":"); |
2411 | ············} |
2412 | ············else // Vt. mit public field |
2413 | ············{ |
2414 | ················method.addStatement(ldarg_0); |
2415 | ················method.addStatement("ldflda···· " + field.Parent.ILType + " " + m_refName + "::" + field.Parent.Name);································································································································ |
2416 | ················method.addStatement($"ldfld······valuetype {Corlib.Name}System." + type + " " + field.Parent.PureTypeName + "::" + field.Name); |
2417 | ················method.addStatement($"ldsfld···· valuetype {Corlib.Name}System." + type + $" {Corlib.Name}System." + empty); |
2418 | ················method.addStatement($"call······ bool {Corlib.Name}System." + type + $"::op_Inequality(valuetype {Corlib.Name}System." + type + $", valuetype {Corlib.Name}System." + type + ")"); |
2419 | ················method.addStatement("brtrue.s·· VtFieldIsNotEmpty" + nr.ToString()); |
2420 | ················method.addStatement($"ldsfld···· class {Corlib.Name}System.DBNull {Corlib.Name}System.DBNull::Value"); |
2421 | ················method.addStatement("br.s······ VtFieldReady" + nr.ToString()); |
2422 | ················method.addStatement("VtFieldIsNotEmpty" + nr.ToString() + ":"); |
2423 | ················method.addStatement(ldarg_0); |
2424 | ················method.addStatement("ldflda···· " + field.Parent.ILType + " " + m_refName + "::" + field.Parent.Name);································································································································ |
2425 | ················method.addStatement($"ldfld······valuetype {Corlib.Name}System." + type + " " + field.Parent.PureTypeName + "::" + field.Name); |
2426 | ················method.addStatement($"box········{Corlib.Name}System." + type + "");················ |
2427 | ················method.addStatement("VtFieldReady" + nr.ToString() + ":"); |
2428 | ············} |
2429 | ········} |
2430 | |
2431 | ········private void insertWriteForNullable(ILMethodElement method, ILField field, int nr, bool parentIsValueType) |
2432 | ········{ |
2433 | ············string loadDbNull = $"ldsfld···· class {Corlib.Name}System.DBNull {Corlib.Name}System.DBNull::Value"; |
2434 | ············string callInstance = "call······ instance bool " + field.ILType + "::"; |
2435 | ············Type t = field.FieldType; |
2436 | ············Type argType = t.GetGenericArguments()[0]; |
2437 | ············string argTypeName = new ReflectedType(argType, this.m_classElement.getAssemblyName()).QuotedILName; |
2438 | ············if (!parentIsValueType) // Member |
2439 | ············{ |
2440 | ················method.addStatement(ldarg_0); |
2441 | ················string ldflda = "ldflda···· " + field.ILType + " " + m_refName + "::" + field.Name; |
2442 | ················method.addStatement(ldflda); |
2443 | ················method.addStatement(callInstance + "get_HasValue()"); |
2444 | ················method.addStatement("ldc.i4.0"); |
2445 | ················method.addStatement("ceq"); |
2446 | ················method.addStatement("brtrue.s·· NullabeIsEmpty" + nr); |
2447 | ················method.addStatement(ldarg_0); |
2448 | ················method.addStatement(ldflda); |
2449 | ················method.addStatement("call instance !0 " + field.ILType + "::get_Value()"); |
2450 | ················method.addStatement("box " + argTypeName); |
2451 | ················method.addStatement("br.s······ VtFieldReady" + nr); |
2452 | ············} |
2453 | ············else if (field.IsProperty) // ValueType mit Property |
2454 | ············{ |
2455 | ················ILLocalsElement localsElement = method.getLocals(); |
2456 | ················string nullableName = "__ndonullable" + nr; |
2457 | ················addLocalVariable(method, nullableName, field.ILType); |
2458 | ················method.addStatement(ldarg_0); |
2459 | ················method.addStatement("ldflda···· " + field.Parent.ILType + " " + m_refName + "::" + field.Parent.Name); |
2460 | ················method.addStatement("call······ instance " + field.ILType + " " + field.Parent.PureTypeName + "::" + getAccName("get_", field.Name) + "()"); |
2461 | ················method.addStatement("stloc " + nullableName); |
2462 | ················method.addStatement("ldloca.s " + nullableName); |
2463 | ················method.addStatement(callInstance + "get_HasValue()"); |
2464 | ················method.addStatement("ldc.i4.0"); |
2465 | ················method.addStatement("ceq"); |
2466 | ················method.addStatement("brtrue.s·· NullabeIsEmpty" + nr); |
2467 | ················method.addStatement("ldloca.s " + nullableName); |
2468 | ················method.addStatement("call instance !0 " + field.ILType + "::get_Value()"); |
2469 | ················method.addStatement("box " + argTypeName); |
2470 | ················method.addStatement("br.s······ VtFieldReady" + nr); |
2471 | ············} |
2472 | ············else // Vt. mit public field |
2473 | ············{ |
2474 | ················method.addStatement(ldarg_0); |
2475 | ················method.addStatement("ldflda···· " + field.Parent.ILType + " "··+ m_refName + "::" + field.Parent.Name); |
2476 | ················method.addStatement("ldflda···· " + field.ILType + " " + field.Parent.PureTypeName + "::" + field.Name); |
2477 | ················method.addStatement(callInstance + "get_HasValue()"); |
2478 | ················method.addStatement("ldc.i4.0"); |
2479 | ················method.addStatement("ceq"); |
2480 | ················method.addStatement("brtrue.s·· NullabeIsEmpty" + nr); |
2481 | ················method.addStatement(ldarg_0); |
2482 | ················method.addStatement("ldflda···· " + field.Parent.ILType + " " + m_refName + "::" + field.Parent.Name); |
2483 | ················method.addStatement("ldflda···· " + field.ILType + " " + field.Parent.PureTypeName + "::" + field.Name); |
2484 | ················method.addStatement("call instance !0 " + field.ILType + "::get_Value()"); |
2485 | ················method.addStatement("box " + argTypeName); |
2486 | ················method.addStatement("br.s······ VtFieldReady" + nr); |
2487 | ············} |
2488 | ············method.addStatement("NullabeIsEmpty" + nr + ':'); |
2489 | ············method.addStatement(loadDbNull); |
2490 | ············method.addStatement("VtFieldReady" + nr.ToString() + ":"); |
2491 | ········} |
2492 | |
2493 | ········private void |
2494 | ············addWriteForField(ILMethodElement method, ILField field, int nr) |
2495 | ········{ |
2496 | ············string prefix; |
2497 | ············string tname = field.ILType; |
2498 | |
2499 | ············bool parentIsValueType = field.Parent != null && field.Parent.IsValueType; |
2500 | ············if (parentIsValueType) |
2501 | ················prefix = field.Parent.CleanName; |
2502 | ············else |
2503 | ················prefix = string.Empty; |
2504 | ············string fname = prefix + field.CleanName; |
2505 | |
2506 | ············method.addStatement(ldarg_1); |
2507 | ············method.addStatement("ldarg.2"); |
2508 | ············method.addStatement("ldarg.3"); |
2509 | ············if (nr != 0) |
2510 | ············{ |
2511 | ················method.addStatement("ldc.i4.s " + nr.ToString()); |
2512 | ················method.addStatement("add"); |
2513 | ············} |
2514 | |
2515 | ············method.addStatement("dup"); |
2516 | ············method.addStatement("stloc.0"); |
2517 | |
2518 | ············method.addStatement("ldelem.ref"); |
2519 | |
2520 | ············// Guids and DateTimes have different Write logic, because |
2521 | ············// they map to and from DbNull. |
2522 | ············if (tname == $"valuetype {Corlib.Name}System.Guid") |
2523 | ············{ |
2524 | ················insertWriteForVtField(method, field, nr, parentIsValueType, "Guid"); |
2525 | ············} |
2526 | ············else if (tname == $"valuetype {Corlib.Name}System.DateTime") |
2527 | ············{ |
2528 | ················insertWriteForVtField(method, field, nr, parentIsValueType, "DateTime"); |
2529 | ············} |
2530 | ············else if (tname.StartsWith($"valuetype {Corlib.Name}System.Nullable`1")) |
2531 | ············{ |
2532 | ················insertWriteForNullable(method, field, nr, parentIsValueType); |
2533 | ············} |
2534 | ············else if (tname.StartsWith("!")) |
2535 | ············{ |
2536 | ················insertWriteForGenericTypes(method, field, nr); |
2537 | ············} |
2538 | ············else |
2539 | ············{ |
2540 | ················method.addStatement(ldarg_0); |
2541 | |
2542 | ················if (!parentIsValueType) |
2543 | ················{ |
2544 | ····················// Nicht fname verwenden! |
2545 | ····················method.addStatement("ldfld······" + field.ILType + " " + m_refName + "::" + field.Name); |
2546 | ················} |
2547 | ················else |
2548 | ················{ |
2549 | ····················method.addStatement("ldflda···· " + field.Parent.ILType + " " + m_refName + "::" + field.Parent.Name); |
2550 | ····················string vtname = field.Parent.ILType; |
2551 | ····················if (vtname.StartsWith("valuetype")) |
2552 | ························vtname = vtname.Substring(10); |
2553 | ····················if (field.IsProperty) |
2554 | ····················{ |
2555 | ························string accname = this.getAccName("get_", field.Name); |
2556 | ························method.addStatement("call······ instance " + field.ILType + " " + vtname + "::" + accname + "()"); |
2557 | ····················} |
2558 | ····················else |
2559 | ····················{ |
2560 | ························method.addStatement("··ldfld······ " + field.ILType + " " + vtname + "::" + field.Name); |
2561 | ····················} |
2562 | ················} |
2563 | ················if (!(tname == $"class {Corlib.Name}System.String" || tname == $"class {Corlib.Name}System.Byte[]" || tname == "string" || tname == "unsigned int8[]")) |
2564 | ····················method.addStatement("box··" + tname); |
2565 | ············} |
2566 | ············method.addStatement("callvirt·· instance void [System.Data]System.Data.DataRow::set_Item(string, object)"); |
2567 | ········} |
2568 | |
2569 | |
2570 | ········public void |
2571 | ········addWrite() |
2572 | ········{ |
2573 | ············ILMethodElement method = m_classElement.getMethod( "NDOWrite" ); |
2574 | ············if ( method == null ) |
2575 | ············{ |
2576 | ················method = new ILMethodElement(); |
2577 | |
2578 | ················if ( m_hasPersistentBase ) |
2579 | ····················method.addLine( ".method public hidebysig virtual" ); |
2580 | ················else |
2581 | ····················method.addLine( ".method public hidebysig newslot virtual" ); |
2582 | ················method.addLine( "instance void··NDOWrite(class [System.Data]System.Data.DataRow dr, string[] fields, int32 startind) cil managed" ); |
2583 | ················m_classElement.getMethodIterator().getLast().insertAfter( method ); |
2584 | ············} |
2585 | ············else |
2586 | ············{ |
2587 | ················method.clearElements(); |
2588 | ············} |
2589 | ············method.addStatement( ".maxstack··8" ); |
2590 | |
2591 | ············addLocalVariable(method, "i", "int32"); |
2592 | ············addLocalVariable(method, "ex", $"class {Corlib.Name}System.Exception"); |
2593 | |
2594 | ············method.addStatement("ldc.i4.0"); |
2595 | ············method.addStatement("stloc.0"); |
2596 | |
2597 | ············method.addStatement("ldarg.1"); |
2598 | ············method.addStatement("brtrue.s·· rownotnull"); |
2599 | ············method.addStatement(@"ldstr······""NDOWrite: DataRow ist null"""); |
2600 | ············method.addStatement($"newobj···· instance void {Corlib.Name}System.Exception::.ctor(string)"); |
2601 | ············method.addStatement("throw"); |
2602 | ············method.addStatement("rownotnull: "); |
2603 | |
2604 | ············ILStatementElement[] fixupElements = new ILStatementElement[2]; |
2605 | ············method.addStatement("ldarg.3"); |
2606 | ············fixupElements[0] = new ILStatementElement("ldc.i4.s ##fieldcount"); |
2607 | ············method.addElement(fixupElements[0]); |
2608 | ············method.addStatement("add"); |
2609 | ············method.addStatement("ldarg.2"); |
2610 | ············method.addStatement("ldlen"); |
2611 | ············method.addStatement("conv.i4"); |
2612 | ············method.addStatement("ble.s······indexbigger"); |
2613 | ············method.addStatement(@"ldstr······""NDOWrite: Index {0} is bigger than maximum index of fields array ({1})"""); |
2614 | ············method.addStatement("ldarg.3"); |
2615 | ············fixupElements[1] = new ILStatementElement("ldc.i4.s ##fieldcount"); |
2616 | ············method.addElement(fixupElements[1]); |
2617 | ············method.addStatement("add"); |
2618 | ············method.addStatement($"box········{Corlib.Name}System.Int32"); |
2619 | ············method.addStatement("ldarg.2"); |
2620 | ············method.addStatement("ldlen"); |
2621 | ············method.addStatement("conv.i4"); |
2622 | ············method.addStatement("ldc.i4.1"); |
2623 | ············method.addStatement("sub"); |
2624 | ············method.addStatement($"box········{Corlib.Name}System.Int32"); |
2625 | ············method.addStatement($"call······ string {Corlib.Name}System.String::Format(string, object, object)"); |
2626 | ············method.addStatement($"newobj···· instance void {Corlib.Name}System.Exception::.ctor(string)"); |
2627 | ············method.addStatement("throw"); |
2628 | |
2629 | ············method.addStatement("indexbigger: "); |
2630 | |
2631 | ············method.addStatement(".try {"); |
2632 | |
2633 | |
2634 | ············int nr = 0; |
2635 | ············// SortedFields enthält auch die ererbten Felder |
2636 | ············// Wir brauchen aber nur die eigenen. In ownFieldsHierarchical |
2637 | ············// sind die eigenen, aber unsortiert |
2638 | ············for(int i = 0; i < this.mappedFieldCount; i++) |
2639 | ············{ |
2640 | ················DictionaryEntry e = (DictionaryEntry) sortedFields[i]; |
2641 | ················ILField field = (ILField) e.Value; |
2642 | ················if (field.Parent != null && field.Parent.IsEmbeddedType) |
2643 | ····················continue; |
2644 | ················addWriteForField(method, field, nr); |
2645 | ················nr++; |
2646 | ············} |
2647 | |
2648 | ············fixupElements[0].replaceText("##fieldcount", nr.ToString()); |
2649 | ············nr--; |
2650 | ············fixupElements[1].replaceText("##fieldcount", nr.ToString()); |
2651 | ············nr++; |
2652 | |
2653 | ············method.addStatement("leave.s····aftercatch"); |
2654 | ············method.addStatement("}··// end .try"); |
2655 | ············method.addStatement($"catch {Corlib.Name}System.Exception"); |
2656 | ············method.addStatement("{"); |
2657 | ············method.addStatement("stloc.1"); |
2658 | ············method.addStatement(@"ldstr······""Error while reading from field """); |
2659 | ············method.addStatement("ldarg.2"); |
2660 | ············method.addStatement("ldloc.0"); |
2661 | ············method.addStatement("ldelem.ref"); |
2662 | ············method.addStatement(@"ldstr······""\n"""); |
2663 | ············method.addStatement("ldloc.1"); |
2664 | ············method.addStatement($"callvirt·· instance string {Corlib.Name}System.Exception::get_Message()"); |
2665 | ············method.addStatement($"call······ string {Corlib.Name}System.String::Concat(string,string,string,string)"); |
2666 | ············method.addStatement($"newobj···· instance void {Corlib.Name}System.Exception::.ctor(string)"); |
2667 | ············method.addStatement("throw"); |
2668 | ············method.addStatement("}··// end handler"); |
2669 | |
2670 | ············method.addStatement("aftercatch: "); |
2671 | |
2672 | ············if (m_hasPersistentBase) |
2673 | ············{ |
2674 | ················method.addStatement(ldarg_0); |
2675 | ················method.addStatement(ldarg_1); |
2676 | ················method.addStatement("ldarg.2"); |
2677 | ················method.addStatement("ldarg.3"); |
2678 | ················method.addStatement("ldc.i4.s " + nr.ToString()); |
2679 | ················method.addStatement("add"); |
2680 | ················method.addStatement("call······ instance void " + m_persistentBase + "::NDOWrite(class [System.Data]System.Data.DataRow dr, string[] fields, int32 startind)"); |
2681 | ············} |
2682 | |
2683 | ············method.addStatement("ret"); |
2684 | ········} |
2685 | |
2686 | ········public void removeGetNDOHandler() |
2687 | ········{ |
2688 | ············ILMethodElement method = m_classElement.getMethod( "get_NDOHandler" ); |
2689 | ············if ( method != null ) |
2690 | ················method.remove(); |
2691 | |
2692 | ············ILPropertyElement propEl = m_classElement.getProperty( "NDOHandler" ); |
2693 | ············if ( propEl != null ) |
2694 | ················propEl.remove(); |
2695 | ········} |
2696 | |
2697 | ········public void addGetNDOHandler() |
2698 | ········{ |
2699 | ············ILMethodElement method = m_classElement.getMethod( "get_NDOHandler" ); |
2700 | |
2701 | ············m_classElement.insertFieldBefore(".field family static class [NDO]NDO.IPersistenceHandler _ndoPersistenceHandler", m_classElement.getMethodIterator().getNext()); |
2702 | |
2703 | ············if ( method == null ) |
2704 | ············{ |
2705 | ················method = new ILMethodElement(); |
2706 | ················method.addLine( ".method public hidebysig newslot specialname final virtual instance class [NDO]NDO.IPersistenceHandler get_NDOHandler() cil managed" ); |
2707 | ················m_classElement.addElement( method ); |
2708 | ············} |
2709 | ············else |
2710 | ············{ |
2711 | ················method.clearElements(); |
2712 | ············} |
2713 | ············method.addElement(new ILMaxstackElement(".maxstack··1", method)); |
2714 | ············method.addElement(new ILStatementElement("ldsfld···· class [NDO]NDO.IPersistenceHandler " + m_refName + "::_ndoPersistenceHandler")); |
2715 | ············method.addElement(new ILStatementElement("ret")); |
2716 | |
2717 | ············method = new ILMethodElement(); |
2718 | ············method.addLine(".method public hidebysig static void NDOSetPersistenceHandler(class [NDO]NDO.IPersistenceHandler ph) cil managed"); |
2719 | ············method.addElement(new ILMaxstackElement(".maxstack··1", method)); |
2720 | ············method.addElement(new ILStatementElement(ldarg_0)); |
2721 | ············method.addElement(new ILStatementElement("stsfld···· class [NDO]NDO.IPersistenceHandler " + m_refName + "::_ndoPersistenceHandler")); |
2722 | ············method.addElement(new ILStatementElement("ret")); |
2723 | ············m_classElement.addElement(method); |
2724 | |
2725 | ············ILPropertyElement propEl = m_classElement.getProperty( "NDOHandler" ); |
2726 | ············if ( propEl == null ) |
2727 | ············{ |
2728 | ················propEl = new ILPropertyElement(); |
2729 | ················propEl.addLine( ".property instance class [NDO]NDO.IPersistenceHandler NDOHandler()" ); |
2730 | ················propEl.addElement( new ILCustomElement( ".custom instance void [System]System.ComponentModel.BrowsableAttribute::.ctor(bool) = ( 01 00 00 00 00 )", propEl ) ); |
2731 | ················propEl.addElement( new ILCustomElement( ".custom instance void [System.Xml]System.Xml.Serialization.XmlIgnoreAttribute::.ctor() = ( 01 00 00 00 )", propEl ) ); |
2732 | ················propEl.addElement( new ILGetElement( ".get instance class [NDO]NDO.IPersistenceHandler " + m_nonGenericRefName + "::get_NDOHandler()" ) ); |
2733 | ················m_classElement.addElement( propEl ); |
2734 | ············} |
2735 | ········} |
2736 | |
2737 | |
2738 | |
2739 | ········void addCreateObject(ILClassElement parent) |
2740 | ········{ |
2741 | ············ILMethodElement newMethod = new ILMethodElement(); |
2742 | newMethod. addLine( ". method public hidebysig newslot final virtual instance class [NDO]NDO. IPersistenceCapable CreateObject( ) cil managed") ; |
2743 | ············newMethod.addElement(new ILMaxstackElement(".maxstack··1", newMethod)); |
2744 | ············if (!this.m_classElement.isAbstract()) |
2745 | ················newMethod.addElement(new ILStatementElement("newobj···· instance void " + m_refName + "::.ctor()")); |
2746 | ············else |
2747 | ················newMethod.addElement(new ILStatementElement("ldnull")); |
2748 | ············newMethod.addElement(new ILStatementElement("ret")); |
2749 | ············parent.addElement(newMethod); |
2750 | ········} |
2751 | |
2752 | ········void addMetaClassCtor(ILClassElement parent) |
2753 | ········{ |
2754 | |
2755 | ············ILMethodElement newMethod = new ILMethodElement(); |
2756 | newMethod. addLine( ". method public hidebysig specialname rtspecialname instance void . ctor( ) cil managed") ; |
2757 | newMethod. addElement( new ILMaxstackElement( ". maxstack 1", newMethod) ) ; |
2758 | newMethod. addElement( new ILStatementElement( ldarg_0) ) ; |
2759 | newMethod. addElement( new ILStatementElement( $"call instance void { Corlib. Name} System. Object::. ctor( ) ") ) ; |
2760 | ············newMethod.addElement(new ILStatementElement("ret")); |
2761 | ············parent.addElement(newMethod); |
2762 | ········} |
2763 | |
2764 | |
2765 | ········public void addMetaClass() |
2766 | ········{ |
2767 | ············ILClassElement newClass = new ILClassElement(); |
2768 | newClass. addLine( ". class auto ansi nested private beforefieldinit MetaClass " + this. m_classElement. getGenericArguments( ) ) ; |
2769 | newClass. addLine( $"extends { Corlib. Name} System. Object") ; |
2770 | ············newClass.addLine("implements [NDO]NDO.IMetaClass"); |
2771 | ············m_classElement.addElement(newClass); |
2772 | ············addMetaClassCtor(newClass); |
2773 | ············addCreateObject(newClass); |
2774 | ············addGetOrdinal(newClass); |
2775 | ········} |
2776 | |
2777 | ········private string getGenericRefParameters() |
2778 | ········{ |
2779 | ············int p = m_refName.IndexOf('<'); |
2780 | ············if (p > -1) |
2781 | ············{ |
2782 | ················return m_refName.Substring(p); |
2783 | ············} |
2784 | ············return string.Empty; |
2785 | ········} |
2786 | |
2787 | ····}··// internal class Class |
2788 | |
2789 | |
2790 | ····/// <summary> |
2791 | ····/// Die Klasse repräsentiert ein persistentes Feld |
2792 | ····/// </summary> |
2793 | ····internal class ILField : IComparable |
2794 | ····{ |
2795 | ········protected string········m_name; |
2796 | ········protected string········m_ilType; |
2797 | ········private bool············isValueType; |
2798 | ········private string assemblyName; |
2799 | ········public ArrayList Fields; |
2800 | ········private ILField parent; |
2801 | ········private bool isProperty = false; |
2802 | ········string pureTypeName; |
2803 | ········bool valid = true; |
2804 | ········private bool isEmbeddedType = false; |
2805 | ········private bool isEnum = false; |
2806 | ········private IList embeddedFieldList; |
2807 | ········protected bool isInherited = false; |
2808 | ········string m_ilTypeWithoutPrefix; |
2809 | ········const string classPrefix = "class "; |
2810 | ········const string vtPrefix = "valuetype "; |
2811 | ········protected string declaringType; |
2812 | ········private Type fieldType; |
2813 | |
2814 | ········public ILField( Type type, string iltype, string name, string assemblyName, string declaringType ) |
2815 | ········{ |
2816 | ············Init(type, iltype, name, declaringType, assemblyName); |
2817 | ········} |
2818 | |
2819 | ········public ILField(Type type, string iltype, string name, string assemblyName, IList embeddedFieldList, bool isEnum) |
2820 | ········{ |
2821 | ············this.isEnum = isEnum; |
2822 | ············isEmbeddedType = embeddedFieldList != null; |
2823 | ············this.embeddedFieldList = embeddedFieldList; |
2824 | ············Init(type, iltype, name, null, assemblyName); |
2825 | ········} |
2826 | |
2827 | ········public ILField(Type type, string iltype, string name, string assemblyName, ILField parent, bool isProperty, bool isEnum) |
2828 | ········{ |
2829 | ············this.isProperty = isProperty; |
2830 | ············Init(type, iltype, name, null, assemblyName); |
2831 | ············this.parent = parent; |
2832 | ············this.isEnum = isEnum; |
2833 | ········} |
2834 | |
2835 | ········/// <summary> |
2836 | ········/// Erzeuge die strings m_ilType und pureTypeName |
2837 | ········/// </summary> |
2838 | ········/// <param name="ilTypeName">Typstring, der als Konstruktorparameter kommt</param> |
2839 | ········private void PrepareType(string ilTypeName) |
2840 | ········{ |
2841 | ············ReflectedType rt = new ReflectedType(this.fieldType, this.assemblyName); |
2842 | ············string tname = rt.ILName; |
2843 | ············if (this.isBuiltInType(tname)) |
2844 | ············{ |
2845 | ················pureTypeName = m_ilType = tname; |
2846 | ················return; |
2847 | ············} |
2848 | ············m_ilType = rt.QuotedILName; |
2849 | ············pureTypeName = m_ilType.Substring(m_ilType.IndexOf("]") + 1); |
2850 | ············if (pureTypeName.StartsWith("valuetype")) |
2851 | ················pureTypeName = pureTypeName.Substring(10); |
2852 | |
2853 | ············if (m_ilType.StartsWith(vtPrefix)) |
2854 | ················m_ilTypeWithoutPrefix = m_ilType.Substring(vtPrefix.Length); |
2855 | ············else if (m_ilType.StartsWith(classPrefix)) |
2856 | ················m_ilTypeWithoutPrefix = m_ilType.Substring(classPrefix.Length); |
2857 | ············else |
2858 | ················m_ilTypeWithoutPrefix = m_ilType; |
2859 | ········} |
2860 | ········private void Init( Type type, string iltype, string name, string declaringType, string assemblyName ) |
2861 | ········{ |
2862 | ············this.fieldType = type; |
2863 | ············this.declaringType = declaringType; |
2864 | ············this.assemblyName = assemblyName; |
2865 | |
2866 | ············// We quote all names. It makes no difference in the metadata. |
2867 | ············if (!name.StartsWith("'")) |
2868 | ················m_name = '\'' + name + '\''; |
2869 | ············else |
2870 | ················m_name = name; |
2871 | |
2872 | ············parent = null; |
2873 | ············string quotedName; |
2874 | ············PrepareType(iltype); |
2875 | |
2876 | ············if (isEmbeddedType) |
2877 | ············{ |
2878 | ················Fields = new ArrayList(); |
2879 | ················foreach(FieldNode fieldNode in embeddedFieldList) |
2880 | ················{ |
2881 | ····················quotedName = QuotedName.ConvertTypename(fieldNode.Name); |
2882 | ····················Fields.Add(new ILField(fieldNode.FieldType, ILFromType(fieldNode.DataType), quotedName, assemblyName, this, false, fieldNode.IsEnum)); |
2883 | ················} |
2884 | ············} |
2885 | ············else if (type.IsValueType && !StorableTypes.Contains(type)) |
2886 | ············{ |
2887 | ················ValueTypeNode vtn = ValueTypes.Instance[pureTypeName]; |
2888 | ················if (null != vtn) |
2889 | ················{ |
2890 | ····················isValueType = true; |
2891 | ····················Fields = new ArrayList(); |
2892 | ····················if (vtn.Fields.Count == 0) |
2893 | ························new MessageAdapter().WriteLine("Warning: Mapped value type " + type.FullName + " doesn't have any public member to store."); |
2894 | ····················foreach(FieldNode fn in vtn.Fields) |
2895 | ····················{ |
2896 | ························quotedName = QuotedName.ConvertTypename(fn.Name); |
2897 | ························Fields.Add(new ILField(fn.FieldType, fn.DataType, quotedName, this.assemblyName, this, fn.IsProperty, fn.IsEnum)); |
2898 | ····················} |
2899 | ················} |
2900 | ············} |
2901 | ········} |
2902 | |
2903 | ········public bool IsEmbeddedType |
2904 | ········{ |
2905 | ············get { return isEmbeddedType; } |
2906 | ············set { isEmbeddedType = value; } |
2907 | ········} |
2908 | |
2909 | ········public bool HasNestedFields |
2910 | ········{ |
2911 | ············get { return !IsEnum && (IsEmbeddedType || ( IsValueType && Fields != null && Fields.Count > 0)); } |
2912 | ········} |
2913 | |
2914 | ········public bool IsEnum |
2915 | ········{ |
2916 | ············get { return isEnum; } |
2917 | ········} |
2918 | |
2919 | ········public bool IsProtected |
2920 | ········{ |
2921 | ············get { return declaringType != null; } |
2922 | ········} |
2923 | |
2924 | ········public bool Valid |
2925 | ········{ |
2926 | ············get { return valid; } |
2927 | ············set { valid = value; } |
2928 | ········} |
2929 | |
2930 | ········public Type FieldType |
2931 | ········{ |
2932 | ············get { return fieldType; } |
2933 | ········} |
2934 | |
2935 | ········public string PureTypeName |
2936 | ········{ |
2937 | ············get { return pureTypeName; } |
2938 | ············set { pureTypeName = value; } |
2939 | ········} |
2940 | |
2941 | ········public bool IsProperty |
2942 | ········{ |
2943 | ············get { return isProperty; } |
2944 | ········} |
2945 | |
2946 | ········public string |
2947 | ········CleanName |
2948 | ········{ |
2949 | ············get{ return m_name.Replace("'", string.Empty); } |
2950 | ········} |
2951 | |
2952 | ········public string |
2953 | ········Name |
2954 | ········{ |
2955 | ············get{ return m_name; } |
2956 | ········} |
2957 | |
2958 | ········public ILField Parent |
2959 | ········{ |
2960 | ············get { return parent; } |
2961 | ········} |
2962 | |
2963 | |
2964 | ········public bool IsValueType |
2965 | ········{ |
2966 | ············get { return isValueType; } |
2967 | ········} |
2968 | |
2969 | ········public virtual bool IsInherited |
2970 | ········{ |
2971 | ············get |
2972 | ············{ |
2973 | ················if (this.parent != null) return parent.IsInherited; |
2974 | ················return isInherited; |
2975 | ············} |
2976 | ············set { isInherited = value; } |
2977 | ········} |
2978 | |
2979 | |
2980 | ········public string |
2981 | ········ILType |
2982 | ········{ |
2983 | ············get { return m_ilType; } |
2984 | ········} |
2985 | |
2986 | ········public string |
2987 | ········ILTypeWithoutPrefix |
2988 | ········{ |
2989 | ············get { return m_ilTypeWithoutPrefix; } |
2990 | ········} |
2991 | |
2992 | ········public string |
2993 | ········CsType |
2994 | ········{ |
2995 | ············get { return typeFromIL(m_ilType); } |
2996 | ········} |
2997 | |
2998 | //········public string |
2999 | //········ILAsmType |
3000 | //········{ |
3001 | //············get { return ILFromType(m_ilType); } |
3002 | //········} |
3003 | |
3004 | ········protected bool isBuiltInType(string typeName) |
3005 | ········{ |
3006 | ············typeName = typeName.Trim(); |
3007 | |
3008 | ············if ( typeName == "bool" ) |
3009 | ················return true; |
3010 | ············if ( typeName == "byte" ) |
3011 | ················return true; |
3012 | ············if ( typeName == "sbyte" ) |
3013 | ················return true; |
3014 | ············if ( typeName == "char" ) |
3015 | ················return true; |
3016 | ············if ( typeName == "unsigned char" ) |
3017 | ················return true; |
3018 | ············if ( typeName == "short" || typeName == "int16" ) |
3019 | ················return true; |
3020 | ············if ( typeName == "unsigned int16" ) |
3021 | ················return true; |
3022 | ············if ( typeName == "unsigned int8" ) |
3023 | ················return true; |
3024 | ············if ( typeName == "unsigned int8[]" ) |
3025 | ················return true; |
3026 | ············if ( typeName == "int" || typeName == "int32" ) |
3027 | ················return true; |
3028 | ············if ( typeName == "unsigned int32" ) |
3029 | ················return true; |
3030 | ············if ( typeName == "long" || typeName == "int64" ) |
3031 | ················return true; |
3032 | ············if ( typeName == "unsigned int64" ) |
3033 | ················return true; |
3034 | ············if ( typeName == "float32" || typeName == "float" || typeName == "single" ) |
3035 | ················return true; |
3036 | ············if ( typeName == "float64" || typeName == "double" ) |
3037 | ················return true; |
3038 | ············if ( typeName == "string" ) |
3039 | ················return true; |
3040 | ············else |
3041 | ················return false; |
3042 | ········} |
3043 | |
3044 | ········protected string |
3045 | ········typeFromIL( string typeName ) |
3046 | ········{ |
3047 | ············typeName = typeName.Trim(); |
3048 | ············Regex regex = new Regex("System.Nullable`1<(.*)>"); |
3049 | ············Match match = regex.Match(typeName); |
3050 | ············if (match.Success) |
3051 | ················typeName = match.Groups[1].Value; |
3052 | |
3053 | ············if ( typeName == "bool" ) |
3054 | ················return "System.Boolean"; |
3055 | ············else if ( typeName == "byte" ) |
3056 | ················return "System.Byte"; |
3057 | ············else if ( typeName == "sbyte" ) |
3058 | ················return "System.SByte"; |
3059 | ············else if ( typeName == "char" ) |
3060 | ················return "System.Char"; |
3061 | ············else if ( typeName == "unsigned char" ) |
3062 | ················return "System.UChar"; |
3063 | ············else if ( typeName == "short" || typeName == "int16" ) |
3064 | ················return "System.Int16"; |
3065 | ············else if ( typeName == "unsigned int16" ) |
3066 | ················return "System.UInt16"; |
3067 | ············else if ( typeName == "unsigned int8" ) |
3068 | ················return "System.Byte"; |
3069 | ············else if ( typeName == "unsigned int8[]" ) |
3070 | ················return "System.Byte[]"; |
3071 | ············else if ( typeName == "int" || typeName == "int32" ) |
3072 | ················return "System.Int32"; |
3073 | ············else if ( typeName == "unsigned int32" ) |
3074 | ················return "System.UInt32"; |
3075 | ············else if ( typeName == "long" || typeName == "int64" ) |
3076 | ················return "System.Int64"; |
3077 | ············else if ( typeName == "unsigned int64" ) |
3078 | ················return "System.UInt64"; |
3079 | ············else if ( typeName == "float32" || typeName == "float" || typeName == "single" ) |
3080 | ················return "System.Single"; |
3081 | ············else if ( typeName == "float64" || typeName == "double" ) |
3082 | ················return "System.Double"; |
3083 | ············else if ( typeName == "string" ) |
3084 | ················return "System.String"; |
3085 | ············else |
3086 | ············{ |
3087 | ················string tn = typeName; |
3088 | ················if (tn.StartsWith(vtPrefix)) |
3089 | ····················tn = tn.Substring(10); |
3090 | ················else if (tn.StartsWith(classPrefix)) |
3091 | ····················tn = tn.Substring(6); |
3092 | ················tn = tn.Trim(); |
3093 | ················if (tn.StartsWith($"{Corlib.Name}")) |
3094 | ····················tn = tn.Substring(10).Trim(); |
3095 | ················if (!tn.StartsWith("[")) |
3096 | ····················return tn; |
3097 | ················tn = tn.Substring(1); |
3098 | ················int pos = tn.IndexOf("]"); |
3099 | ················return (tn.Substring(pos + 1) + ", " + tn.Substring(0, pos)); |
3100 | ············} |
3101 | ········} |
3102 | |
3103 | ········private string |
3104 | ········ILFromType( string tName ) |
3105 | ········{ |
3106 | ············bool isArray = false; |
3107 | ············string tempName; |
3108 | ············if (tName.EndsWith("[]")) |
3109 | ············{ |
3110 | ················isArray = true; |
3111 | ················tempName = tName.Substring(0, tName.Length -2); |
3112 | ············} |
3113 | ············else |
3114 | ················tempName = tName; |
3115 | |
3116 | ············string typeName = tempName.Substring(tempName.IndexOf("]") + 1).Trim(); |
3117 | |
3118 | ············if (isArray) |
3119 | ················typeName += "[]"; |
3120 | |
3121 | ············if ( typeName == "System.String" ) |
3122 | ················return "string"; |
3123 | ············else if ( typeName == "System.Int32" ) |
3124 | ················return "int32"; |
3125 | ············else if ( typeName == "System.Boolean" ) |
3126 | ················return "bool"; |
3127 | ············else if ( typeName == "System.Byte") |
3128 | ················return "unsigned int8"; |
3129 | ············else if ( typeName == "System.SByte") |
3130 | ················return "int8"; |
3131 | ············else if ( typeName == "System.Byte[]") |
3132 | ················return "unsigned int8[]"; |
3133 | ············else if ( typeName == "System.SByte" ) |
3134 | ················return "sbyte"; |
3135 | ············else if ( typeName == "System.Char" ) |
3136 | ················return "char"; |
3137 | ············else if ( typeName == "System.UChar" ) |
3138 | ················return "unsigned char"; |
3139 | ············else if ( typeName == "System.Int16" ) |
3140 | ················return "int16"; |
3141 | ············else if ( typeName == "System.UInt16" ) |
3142 | ················return "unsigned int16"; |
3143 | ············else if ( typeName == "System.UInt32" ) |
3144 | ················return "unsigned int32"; |
3145 | ············else if ( typeName == "System.Int64" ) |
3146 | ················return "int64"; |
3147 | ············else if ( typeName == "System.UInt64" ) |
3148 | ················return "unsigned int64"; |
3149 | ············else if ( typeName == "System.Single" ) |
3150 | ················return "float32";·· |
3151 | ············else if ( typeName == "System.Double" ) |
3152 | ················return "float64"; |
3153 | ············else return typeName; |
3154 | ········} |
3155 | |
3156 | ········// Implementation of IComparable |
3157 | ········public int CompareTo(object obj) |
3158 | ········{ |
3159 | ············return this.m_name.CompareTo(((ILField)obj).m_name); |
3160 | ········} |
3161 | |
3162 | ····} |
3163 | |
3164 | ····internal class ILReference : ILField |
3165 | ····{ |
3166 | ········string referencedType; |
3167 | ········RelationInfo relInfo; |
3168 | ········string relationName; |
3169 | ········bool is1to1; |
3170 | ········int ordinal; |
3171 | |
3172 | ········public ILReference (Type fieldType, string refType, string ilType, string fieldName, string assemblyName, RelationInfo ri, string relName, bool isInherited, bool is1to1, string declaringType) |
3173 | ············: base (fieldType, ilType, fieldName, assemblyName, declaringType) |
3174 | ········{ |
3175 | ············this.is1to1 = is1to1; |
3176 | ············this.isInherited = isInherited; |
3177 | ············if (null != refType) |
3178 | ················referencedType = refType; |
3179 | ············else |
3180 | ············{ |
3181 | ················referencedType = CsType; |
3182 | ················if (referencedType.StartsWith("class")) |
3183 | ····················referencedType = referencedType.Substring(6); |
3184 | ················if (referencedType.StartsWith("valuetype")) |
3185 | ····················referencedType = referencedType.Substring(10); |
3186 | ············} |
3187 | |
3188 | ············relInfo = ri; |
3189 | ············if (relName != null) |
3190 | ················relationName = relName; |
3191 | ············else |
3192 | ················relationName = ""; |
3193 | ········} |
3194 | |
3195 | ········public int Ordinal |
3196 | ········{ |
3197 | ············get { return ordinal; } |
3198 | ············set { ordinal = value; } |
3199 | ········} |
3200 | |
3201 | |
3202 | ········public override bool IsInherited |
3203 | ········{ |
3204 | ············get { return isInherited; } |
3205 | ············set { isInherited = value; } |
3206 | ········} |
3207 | |
3208 | ········public RelationInfo ReferenceInfo |
3209 | ········{ |
3210 | ············get { return relInfo; } |
3211 | ········} |
3212 | |
3213 | ········public string RelationName |
3214 | ········{ |
3215 | ············get { return relationName; } |
3216 | ········} |
3217 | |
3218 | ········public bool Is1to1 |
3219 | ········{ |
3220 | ············get { return (is1to1); } |
3221 | ········} |
3222 | |
3223 | ········public string RefTypeShortName |
3224 | ········{ |
3225 | ············get |
3226 | ············{ |
3227 | ················int pos = referencedType.IndexOf("]"); |
3228 | ················// im Fehlerfall ist pos -1, dann wird der ganze String kopiert |
3229 | ················return (referencedType.Substring(pos + 1)).Replace("'", string.Empty); |
3230 | ············} |
3231 | ········} |
3232 | |
3233 | ········public string RefType |
3234 | ········{ |
3235 | ············get |
3236 | ············{ |
3237 | ················return referencedType; |
3238 | ············} |
3239 | ········} |
3240 | ····} |
3241 | |
3242 | |
3243 | |
3244 | } |
3245 |
New Commit (a99de3b)
1 | // |
2 | // Copyright (c) 2002-2016 Mirko Matytschak |
3 | // (www.netdataobjects.de) |
4 | // |
5 | // Author: Mirko Matytschak |
6 | // |
7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated |
8 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation |
9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the |
10 | // Software, and to permit persons to whom the Software is furnished to do so, subject to the following |
11 | // conditions: |
12 | |
13 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions |
14 | // of the Software. |
15 | // |
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED |
17 | // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
18 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF |
19 | // CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
20 | // DEALINGS IN THE SOFTWARE. |
21 | |
22 | |
23 | using System; |
24 | using System.Text.RegularExpressions; |
25 | using System.Xml; |
26 | using System.Collections; |
27 | using System.Reflection; |
28 | using System.IO; |
29 | using System.Diagnostics; |
30 | using System.Data; |
31 | |
32 | using ILCode; |
33 | using NDO; |
34 | |
35 | namespace NDOEnhancer.Patcher |
36 | { |
37 | ····/// <summary> |
38 | ····/// Summary description for Class. |
39 | ····/// </summary> |
40 | ····internal class ClassPatcher |
41 | ····{ |
42 | ········static ClassPatcher() |
43 | ········{ |
44 | ············indTypes = new Hashtable(12); |
45 | ············indTypes.Add("int32", "i4"); |
46 | ············indTypes.Add("bool", "i1"); |
47 | ············indTypes.Add("int8", "i1"); |
48 | ············indTypes.Add("unsigned int8", "u1"); |
49 | ············indTypes.Add("float64", "r8"); |
50 | ············indTypes.Add("float32", "r4"); |
51 | ············indTypes.Add("int16", "i2"); |
52 | ············indTypes.Add("int64", "i8"); |
53 | ············indTypes.Add("char", "u2"); |
54 | ············indTypes.Add("unsigned int16", "u2"); |
55 | ············indTypes.Add("unsigned int32", "u4"); |
56 | ············indTypes.Add("unsigned int64", "i8"); |
57 | ········} |
58 | |
59 | ········public ClassPatcher(····ILClassElement classElement, |
60 | ············NDO.Mapping.NDOMapping mappings, |
61 | ············ClassHashtable externalPersistentBases, |
62 | ············NDOEnhancer.MessageAdapter messages, |
63 | ············IList sortedFields, |
64 | ············IList references, |
65 | ············string oidTypeName) |
66 | ········{ |
67 | ············m_classElement············= classElement; |
68 | ············m_name····················= classElement.getClassFullName(); |
69 | ············m_refName·············· = makeRefName(); |
70 | ············m_nonGenericRefName···· = m_name; |
71 | ············m_references············= references; |
72 | |
73 | ············if (references == null) |
74 | ················throw new ArgumentNullException( "references" ); |
75 | |
76 | ············int p = m_nonGenericRefName.IndexOf('<'); |
77 | ············if (p > -1) |
78 | ················m_nonGenericRefName = m_nonGenericRefName.Substring(0, p); |
79 | |
80 | ············m_persistentBase········= classElement.getBaseFullName(); |
81 | ············this.externalPersistentBases = externalPersistentBases; |
82 | |
83 | ············if (null != externalPersistentBases) |
84 | ············{ |
85 | ················//m_hasPersistentBase····= classElement.hasPersistentBase(temp, typeof(NDOPersistentAttribute)); |
86 | ················m_hasPersistentBase····= (externalPersistentBases.Contains(m_persistentBase)); |
87 | ············} |
88 | |
89 | ············this.m_mappings················= mappings; |
90 | ············this.m_classMapping············= mappings.FindClass(classElement.getMappingName()); |
91 | |
92 | ············if (this.m_classMapping == null) |
93 | ················throw new Exception("Can't find mapping for class " + classElement.getMappingName()); |
94 | |
95 | ············this.messages············= messages; |
96 | ············this.sortedFields = sortedFields; |
97 | ············this.oidTypeName = oidTypeName; |
98 | |
99 | ············for (int i = 0; i < m_references.Count; i++) |
100 | ················((ILReference) m_references[i]).Ordinal = i; |
101 | |
102 | |
103 | ············// sortedFields ist eine flache Ansicht auf die Felder, wie |
104 | ············// sie in der Datenbank sein werden. |
105 | ············// Wir benötigen aber auch die hierarchische Sicht, die die |
106 | ············// Namen der ValueTypes und embedded Objects liefert. |
107 | ············ownFieldsHierarchical = getHierarchicalFieldList(); |
108 | |
109 | ············if (null != externalPersistentBases) |
110 | ············{ |
111 | ················checkPersistentRoot(); |
112 | ················checkNextPersistentBase(); |
113 | ············} |
114 | ········} |
115 | |
116 | ········static private Hashtable indTypes; |
117 | |
118 | ········const string ldarg_0 = "ldarg.0"; |
119 | ········const string ldarg_1 = "ldarg.1"; |
120 | ········private NDOEnhancer.MessageAdapter messages; |
121 | ········private ILClassElement············m_classElement; |
122 | ········private string····················m_name; |
123 | ········private string····················m_refName; |
124 | ········private string····················m_nonGenericRefName; |
125 | ········private string····················m_persistentBase; |
126 | ········private bool····················m_hasPersistentBase; |
127 | ········private NDO.Mapping.NDOMapping····m_mappings; |
128 | ········private string····················oidTypeName; |
129 | ········private NDO.Mapping.Class········m_classMapping; |
130 | |
131 | ········private ArrayList················ownFieldsHierarchical····= new ArrayList(); |
132 | ········private IList····················m_references; |
133 | ········private ArrayList················dirtyDone = new ArrayList(); |
134 | ········private ClassHashtable············externalPersistentBases; |
135 | ········private string····················persistentRoot = null; |
136 | ········private IList····················sortedFields; |
137 | ········private int························mappedFieldCount; |
138 | ········private ClassNode················myClassNode; |
139 | |
140 | |
141 | ········private string makeRefName() |
142 | ········{ |
143 | ············int p = m_name.IndexOf('<'); |
144 | ············if (p == -1) |
145 | ················return m_name; |
146 | ············Ecma335.EcmaGenericParameter genPar = new NDOEnhancer.Ecma335.EcmaGenericParameter(); |
147 | ············genPar.Parse(m_name.Substring(p)); |
148 | ············string newGenPars = "<"; |
149 | ············int count = genPar.Elements.Count; |
150 | ············for (int i = 0; i < count; i++) |
151 | ············{ |
152 | ················string element = genPar.Elements[i]; |
153 | ················newGenPars += "!" + element; |
154 | ················if (i < count - 1) |
155 | ····················newGenPars += ','; |
156 | ············} |
157 | ············return "class " + m_name.Substring(0, p) + newGenPars + '>'; |
158 | ········} |
159 | |
160 | ········private void checkNextPersistentBase() |
161 | ········{ |
162 | ············ClassNode baseClass = getPersistentBaseClassElement(MyClassNode); |
163 | ············if (baseClass == null) |
164 | ················return; |
165 | ············while (!baseClass.IsPersistent) |
166 | ············{ |
167 | ················baseClass = getPersistentBaseClassElement(baseClass); |
168 | ················if (baseClass == null) |
169 | ····················throw new Exception("Internal error #126 in Class.cs"); |
170 | ············} |
171 | ············if (baseClass.AssemblyName != this.m_classElement.getAssemblyName()) |
172 | ················m_persistentBase = "[" + baseClass.AssemblyName + "]" + baseClass.Name; |
173 | ············else |
174 | ················m_persistentBase = baseClass.Name; |
175 | ········} |
176 | |
177 | ········private ArrayList getHierarchicalFieldList() |
178 | ········{ |
179 | ············this.mappedFieldCount = 0;··// count of the flat fields |
180 | ············ArrayList fields = new ArrayList(); |
181 | |
182 | ············if (sortedFields != null) |
183 | ············{ |
184 | ················// Sorted fields is an array of DictionaryEntries |
185 | ················foreach (DictionaryEntry e in sortedFields) |
186 | ················{ |
187 | ····················ILField field = (ILField) e.Value; |
188 | ····················if (field.IsInherited) |
189 | ························continue; |
190 | ····················this.mappedFieldCount++; |
191 | ····················if (field.Parent != null) |
192 | ····················{ |
193 | ························if (!fields.Contains(field.Parent)) |
194 | ····························fields.Add(field.Parent); |
195 | ····················} |
196 | ····················else |
197 | ····················{ |
198 | ························fields.Add |