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(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 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 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( class { Corlib. Name} System. Type t) cil managed" ) ;
2757 newMethod. addElement( new ILMaxstackElement( ". maxstack 8", newMethod) ) ;
2758 newMethod. addElement( new ILStatementElement( ldarg_0 ) ) ;
2759 newMethod. addElement( new ILStatementElement( ldarg_1 ) ) ;
2760 ············newMethod.addElement(new ILStatementElement($"call······ instance void [NDO]NDO.MetaclassBase::.ctor(class {Corlib.Name}System.Type)" ));
2761 ············newMethod.addElement(new ILStatementElement("ret"));
2762 ············parent.addElement(newMethod);
2763 ········}
2764
2765
2766 ········public void addMetaClass()
2767 ········{
2768 ············ILClassElement newClass = new ILClassElement();
2769 newClass. addLine( ". class auto ansi nested private beforefieldinit MetaClass " + this. m_classElement. getGenericArguments( ) ) ;
2770 newClass. addLine( "extends [NDO]NDO. MetaclassBase" ) ;
 
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