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 |