Unit Tests for SourceSwitch. Counting the number of events traced based on the Trace...
[mono.git] / mcs / mcs / module.cs
1 //
2 // module.cs: keeps a tree representation of the generated code
3 //
4 // Authors: Miguel de Icaza (miguel@gnu.org)
5 //          Marek Safar  (marek.safar@gmail.com)
6 //
7 // Dual licensed under the terms of the MIT X11 or GNU GPL
8 //
9 // Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
10 // Copyright 2003-2008 Novell, Inc.
11 // Copyright 2011 Xamarin Inc
12 //
13
14 using System;
15 using System.Collections.Generic;
16 using System.Runtime.InteropServices;
17 using Mono.CompilerServices.SymbolWriter;
18 using System.Linq;
19
20 #if STATIC
21 using IKVM.Reflection;
22 using IKVM.Reflection.Emit;
23 #else
24 using System.Reflection;
25 using System.Reflection.Emit;
26 #endif
27
28 namespace Mono.CSharp
29 {
30         //
31         // Module (top-level type) container
32         //
33         public sealed class ModuleContainer : TypeContainer
34         {
35 #if STATIC
36                 //
37                 // Compiler generated container for static data
38                 //
39                 sealed class StaticDataContainer : CompilerGeneratedContainer
40                 {
41                         readonly Dictionary<int, Struct> size_types;
42                         int fields;
43
44                         public StaticDataContainer (ModuleContainer module)
45                                 : base (module, new MemberName ("<PrivateImplementationDetails>" + module.builder.ModuleVersionId.ToString ("B"), Location.Null),
46                                         Modifiers.STATIC | Modifiers.INTERNAL)
47                         {
48                                 size_types = new Dictionary<int, Struct> ();
49                         }
50
51                         public override void CloseContainer ()
52                         {
53                                 base.CloseContainer ();
54
55                                 foreach (var entry in size_types) {
56                                         entry.Value.CloseContainer ();
57                                 }
58                         }
59
60                         public FieldSpec DefineInitializedData (byte[] data, Location loc)
61                         {
62                                 Struct size_type;
63                                 if (!size_types.TryGetValue (data.Length, out size_type)) {
64                                         //
65                                         // Build common type for this data length. We cannot use
66                                         // DefineInitializedData because it creates public type,
67                                         // and its name is not unique among modules
68                                         //
69                                         size_type = new Struct (this, new MemberName ("$ArrayType=" + data.Length, loc), Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED, null);
70                                         size_type.CreateContainer ();
71                                         size_type.DefineContainer ();
72
73                                         size_types.Add (data.Length, size_type);
74
75                                         // It has to work even if StructLayoutAttribute does not exist
76                                         size_type.TypeBuilder.__SetLayout (1, data.Length);
77                                 }
78
79                                 var name = "$field-" + fields.ToString ("X");
80                                 ++fields;
81                                 const Modifiers fmod = Modifiers.STATIC | Modifiers.INTERNAL;
82                                 var fbuilder = TypeBuilder.DefineField (name, size_type.CurrentType.GetMetaInfo (), ModifiersExtensions.FieldAttr (fmod) | FieldAttributes.HasFieldRVA);
83                                 fbuilder.__SetDataAndRVA (data);
84
85                                 return new FieldSpec (CurrentType, null, size_type.CurrentType, fbuilder, fmod);
86                         }
87                 }
88
89                 StaticDataContainer static_data;
90
91                 //
92                 // Makes const data field inside internal type container
93                 //
94                 public FieldSpec MakeStaticData (byte[] data, Location loc)
95                 {
96                         if (static_data == null) {
97                                 static_data = new StaticDataContainer (this);
98                                 static_data.CreateContainer ();
99                                 static_data.DefineContainer ();
100
101                                 AddCompilerGeneratedClass (static_data);
102                         }
103
104                         return static_data.DefineInitializedData (data, loc);
105                 }
106 #endif
107
108                 public sealed class PatternMatchingHelper : CompilerGeneratedContainer
109                 {
110                         public PatternMatchingHelper (ModuleContainer module)
111                                 : base (module, new MemberName ("<PatternMatchingHelper>", Location.Null),
112                                         Modifiers.STATIC | Modifiers.INTERNAL | Modifiers.DEBUGGER_HIDDEN)
113                         {
114                         }
115
116                         public Method NumberMatcher { get; private set; }
117
118                         protected override bool DoDefineMembers ()
119                         {
120                                 if (!base.DoDefineMembers ())
121                                         return false;
122
123                                 NumberMatcher = GenerateNumberMatcher ();
124                                 return true;
125                         }
126
127                         Method GenerateNumberMatcher ()
128                         {
129                                 var loc = Location;
130                                 var parameters = ParametersCompiled.CreateFullyResolved (
131                                         new [] {
132                                                 new Parameter (new TypeExpression (Compiler.BuiltinTypes.Object, loc), "obj", 0, null, loc),
133                                                 new Parameter (new TypeExpression (Compiler.BuiltinTypes.Object, loc), "value", 0, null, loc),
134                                                 new Parameter (new TypeExpression (Compiler.BuiltinTypes.Bool, loc), "enumType", 0, null, loc),
135                                         },
136                                         new [] {
137                                                 Compiler.BuiltinTypes.Object,
138                                                 Compiler.BuiltinTypes.Object,
139                                                 Compiler.BuiltinTypes.Bool
140                                         });
141
142                                 var m = new Method (this, new TypeExpression (Compiler.BuiltinTypes.Bool, loc),
143                                         Modifiers.PUBLIC | Modifiers.STATIC | Modifiers.DEBUGGER_HIDDEN, new MemberName ("NumberMatcher", loc),
144                                         parameters, null);
145
146                                 parameters [0].Resolve (m, 0);
147                                 parameters [1].Resolve (m, 1);
148                                 parameters [2].Resolve (m, 2);
149
150                                 ToplevelBlock top_block = new ToplevelBlock (Compiler, parameters, loc);
151                                 m.Block = top_block;
152
153                                 //
154                                 // if (enumType)
155                                 //              return Equals (obj, value);
156                                 //
157                                 var equals_args = new Arguments (2);
158                                 equals_args.Add (new Argument (top_block.GetParameterReference (0, loc)));
159                                 equals_args.Add (new Argument (top_block.GetParameterReference (1, loc)));
160
161                                 var if_type = new If (
162                                                       top_block.GetParameterReference (2, loc),
163                                                       new Return (new Invocation (new SimpleName ("Equals", loc), equals_args), loc),
164                                                       loc);
165
166                                 top_block.AddStatement (if_type);
167
168                                 //
169                                 // if (obj is Enum || obj == null)
170                                 //              return false;
171                                 //
172
173                                 var if_enum = new If (
174                                                       new Binary (Binary.Operator.LogicalOr,
175                                                               new Is (top_block.GetParameterReference (0, loc), new TypeExpression (Compiler.BuiltinTypes.Enum, loc), loc),
176                                                               new Binary (Binary.Operator.Equality, top_block.GetParameterReference (0, loc), new NullLiteral (loc))),
177                                                       new Return (new BoolLiteral (Compiler.BuiltinTypes, false, loc), loc),
178                                                       loc);
179
180                                 top_block.AddStatement (if_enum);
181
182
183                                 var system_convert = new MemberAccess (new QualifiedAliasMember ("global", "System", loc), "Convert", loc);
184
185                                 //
186                                 // var converted = System.Convert.ChangeType (obj, System.Convert.GetTypeCode (value));
187                                 //
188                                 var lv_converted = LocalVariable.CreateCompilerGenerated (Compiler.BuiltinTypes.Object, top_block, loc);
189
190                                 var arguments_gettypecode = new Arguments (1);
191                                 arguments_gettypecode.Add (new Argument (top_block.GetParameterReference (1, loc)));
192
193                                 var gettypecode = new Invocation (new MemberAccess (system_convert, "GetTypeCode", loc), arguments_gettypecode);
194
195                                 var arguments_changetype = new Arguments (1);
196                                 arguments_changetype.Add (new Argument (top_block.GetParameterReference (0, loc)));
197                                 arguments_changetype.Add (new Argument (gettypecode));
198
199                                 var changetype = new Invocation (new MemberAccess (system_convert, "ChangeType", loc), arguments_changetype);
200
201                                 top_block.AddStatement (new StatementExpression (new SimpleAssign (new LocalVariableReference (lv_converted, loc), changetype, loc)));
202
203
204                                 //
205                                 // return converted.Equals (value)
206                                 //
207                                 var equals_arguments = new Arguments (1);
208                                 equals_arguments.Add (new Argument (top_block.GetParameterReference (1, loc)));
209                                 var equals_invocation = new Invocation (new MemberAccess (new LocalVariableReference (lv_converted, loc), "Equals"), equals_arguments);
210                                 top_block.AddStatement (new Return (equals_invocation, loc));
211
212                                 m.Define ();
213                                 m.PrepareEmit ();
214                                 AddMember (m);
215
216                                 return m;
217                         }
218                 }
219
220                 PatternMatchingHelper pmh;
221
222                 public PatternMatchingHelper CreatePatterMatchingHelper ()
223                 {
224                         if (pmh == null) {
225                                 pmh = new PatternMatchingHelper (this);
226
227                                 pmh.CreateContainer ();
228                                 pmh.DefineContainer ();
229                                 pmh.Define ();
230                                 AddCompilerGeneratedClass (pmh);
231                         }
232
233                         return pmh;
234                 }
235
236                 public CharSet? DefaultCharSet;
237                 public TypeAttributes DefaultCharSetType = TypeAttributes.AnsiClass;
238
239                 readonly Dictionary<int, List<AnonymousTypeClass>> anonymous_types;
240                 readonly Dictionary<ArrayContainer.TypeRankPair, ArrayContainer> array_types;
241                 readonly Dictionary<TypeSpec, PointerContainer> pointer_types;
242                 readonly Dictionary<TypeSpec, ReferenceContainer> reference_types;
243                 readonly Dictionary<TypeSpec, MethodSpec> attrs_cache;
244                 readonly Dictionary<TypeSpec, AwaiterDefinition> awaiters;
245
246                 AssemblyDefinition assembly;
247                 readonly CompilerContext context;
248                 readonly RootNamespace global_ns;
249                 readonly Dictionary<string, RootNamespace> alias_ns;
250
251                 ModuleBuilder builder;
252
253                 bool has_extenstion_method;
254
255                 PredefinedAttributes predefined_attributes;
256                 PredefinedTypes predefined_types;
257                 PredefinedMembers predefined_members;
258
259                 public Binary.PredefinedOperator[] OperatorsBinaryEqualityLifted;
260                 public Binary.PredefinedOperator[] OperatorsBinaryLifted;
261
262                 static readonly string[] attribute_targets = new string[] { "assembly", "module" };
263
264                 public ModuleContainer (CompilerContext context)
265                         : base (null, MemberName.Null, null, 0)
266                 {
267                         this.context = context;
268
269                         caching_flags &= ~(Flags.Obsolete_Undetected | Flags.Excluded_Undetected);
270
271                         containers = new List<TypeContainer> ();
272                         anonymous_types = new Dictionary<int, List<AnonymousTypeClass>> ();
273                         global_ns = new GlobalRootNamespace ();
274                         alias_ns = new Dictionary<string, RootNamespace> ();
275                         array_types = new Dictionary<ArrayContainer.TypeRankPair, ArrayContainer> ();
276                         pointer_types = new Dictionary<TypeSpec, PointerContainer> ();
277                         reference_types = new Dictionary<TypeSpec, ReferenceContainer> ();
278                         attrs_cache = new Dictionary<TypeSpec, MethodSpec> ();
279                         awaiters = new Dictionary<TypeSpec, AwaiterDefinition> ();
280                 }
281
282                 #region Properties
283
284                 internal Dictionary<ArrayContainer.TypeRankPair, ArrayContainer> ArrayTypesCache {
285                         get {
286                                 return array_types;
287                         }
288                 }
289
290                 //
291                 // Cache for parameter-less attributes
292                 //
293                 internal Dictionary<TypeSpec, MethodSpec> AttributeConstructorCache {
294                         get {
295                                 return attrs_cache;
296                         }
297                 }
298
299                 public override AttributeTargets AttributeTargets {
300                         get {
301                                 return AttributeTargets.Assembly;
302                         }
303                 }
304
305                 public ModuleBuilder Builder {
306                         get {
307                                 return builder;
308                         }
309                 }
310
311                 public override CompilerContext Compiler {
312                         get {
313                                 return context;
314                         }
315                 }
316
317                 public int CounterAnonymousTypes { get; set; }
318
319                 public AssemblyDefinition DeclaringAssembly {
320                         get {
321                                 return assembly;
322                         }
323                 }
324
325                 internal DocumentationBuilder DocumentationBuilder {
326                         get; set;
327                 }
328
329                 public override string DocCommentHeader {
330                         get {
331                                 throw new NotSupportedException ();
332                         }
333                 }
334
335                 public Evaluator Evaluator {
336                         get; set;
337                 }
338
339                 public bool HasDefaultCharSet {
340                         get {
341                                 return DefaultCharSet.HasValue;
342                         }
343                 }
344
345                 public bool HasExtensionMethod {
346                         get {
347                                 return has_extenstion_method;
348                         }
349                         set {
350                                 has_extenstion_method = value;
351                         }
352                 }
353
354                 public bool HasTypesFullyDefined {
355                         get; set;
356                 }
357
358                 //
359                 // Returns module global:: namespace
360                 //
361                 public RootNamespace GlobalRootNamespace {
362                     get {
363                         return global_ns;
364                     }
365                 }
366
367                 public override ModuleContainer Module {
368                         get {
369                                 return this;
370                         }
371                 }
372
373                 internal Dictionary<TypeSpec, PointerContainer> PointerTypesCache {
374                         get {
375                                 return pointer_types;
376                         }
377                 }
378
379                 internal PredefinedAttributes PredefinedAttributes {
380                         get {
381                                 return predefined_attributes;
382                         }
383                 }
384
385                 internal PredefinedMembers PredefinedMembers {
386                         get {
387                                 return predefined_members;
388                         }
389                 }
390
391                 internal PredefinedTypes PredefinedTypes {
392                         get {
393                                 return predefined_types;
394                         }
395                 }
396
397                 internal Dictionary<TypeSpec, ReferenceContainer> ReferenceTypesCache {
398                         get {
399                                 return reference_types;
400                         }
401                 }
402
403                 public override string[] ValidAttributeTargets {
404                         get {
405                                 return attribute_targets;
406                         }
407                 }
408
409                 #endregion
410
411                 public override void Accept (StructuralVisitor visitor)
412                 {
413                         visitor.Visit (this);
414                 }
415
416                 public void AddAnonymousType (AnonymousTypeClass type)
417                 {
418                         List<AnonymousTypeClass> existing;
419                         if (!anonymous_types.TryGetValue (type.Parameters.Count, out existing))
420                         if (existing == null) {
421                                 existing = new List<AnonymousTypeClass> ();
422                                 anonymous_types.Add (type.Parameters.Count, existing);
423                         }
424
425                         existing.Add (type);
426                 }
427
428                 public void AddAttribute (Attribute attr, IMemberContext context)
429                 {
430                         attr.AttachTo (this, context);
431
432                         if (attributes == null) {
433                                 attributes = new Attributes (attr);
434                                 return;
435                         }
436
437                         attributes.AddAttribute (attr);
438                 }
439
440                 public override void AddTypeContainer (TypeContainer tc)
441                 {
442                         AddTypeContainerMember (tc);
443                 }
444
445                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
446                 {
447                         if (a.Target == AttributeTargets.Assembly) {
448                                 assembly.ApplyAttributeBuilder (a, ctor, cdata, pa);
449                                 return;
450                         }
451
452                         if (a.Type == pa.DefaultCharset) {
453                                 switch (a.GetCharSetValue ()) {
454                                 case CharSet.Ansi:
455                                 case CharSet.None:
456                                         break;
457                                 case CharSet.Auto:
458                                         DefaultCharSet = CharSet.Auto;
459                                         DefaultCharSetType = TypeAttributes.AutoClass;
460                                         break;
461                                 case CharSet.Unicode:
462                                         DefaultCharSet = CharSet.Unicode;
463                                         DefaultCharSetType = TypeAttributes.UnicodeClass;
464                                         break;
465                                 default:
466                                         Report.Error (1724, a.Location, "Value specified for the argument to `{0}' is not valid",
467                                                 a.GetSignatureForError ());
468                                         break;
469                                 }
470                         } else if (a.Type == pa.CLSCompliant) {
471                                 Attribute cls = DeclaringAssembly.CLSCompliantAttribute;
472                                 if (cls == null) {
473                                         Report.Warning (3012, 1, a.Location,
474                                                 "You must specify the CLSCompliant attribute on the assembly, not the module, to enable CLS compliance checking");
475                                 } else if (DeclaringAssembly.IsCLSCompliant != a.GetBoolean ()) {
476                                         Report.SymbolRelatedToPreviousError (cls.Location, cls.GetSignatureForError ());
477                                         Report.Warning (3017, 1, a.Location,
478                                                 "You cannot specify the CLSCompliant attribute on a module that differs from the CLSCompliant attribute on the assembly");
479                                         return;
480                                 }
481                         }
482
483                         builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
484                 }
485
486                 public override void CloseContainer ()
487                 {
488                         if (anonymous_types != null) {
489                                 foreach (var atypes in anonymous_types)
490                                         foreach (var at in atypes.Value)
491                                                 at.CloseContainer ();
492                         }
493
494                         base.CloseContainer ();
495                 }
496
497                 public TypeBuilder CreateBuilder (string name, TypeAttributes attr, int typeSize)
498                 {
499                         return builder.DefineType (name, attr, null, typeSize);
500                 }
501
502                 //
503                 // Creates alias global namespace
504                 //
505                 public RootNamespace CreateRootNamespace (string alias)
506                 {
507                         if (alias == global_ns.Alias) {
508                                 RootNamespace.Error_GlobalNamespaceRedefined (Report, Location.Null);
509                                 return global_ns;
510                         }
511
512                         RootNamespace rn;
513                         if (!alias_ns.TryGetValue (alias, out rn)) {
514                                 rn = new RootNamespace (alias);
515                                 alias_ns.Add (alias, rn);
516                         }
517
518                         return rn;
519                 }
520
521                 public void Create (AssemblyDefinition assembly, ModuleBuilder moduleBuilder)
522                 {
523                         this.assembly = assembly;
524                         builder = moduleBuilder;
525                 }
526
527                 public override bool Define ()
528                 {
529                         DefineContainer ();
530
531                         ExpandBaseInterfaces ();
532
533                         base.Define ();
534
535                         HasTypesFullyDefined = true;
536
537                         return true;
538                 }
539
540                 public override bool DefineContainer ()
541                 {
542                         DefineNamespace ();
543
544                         return base.DefineContainer ();
545                 }
546
547                 public void EnableRedefinition ()
548                 {
549                         is_defined = false;
550                 }
551
552                 public override void EmitContainer ()
553                 {
554                         if (OptAttributes != null)
555                                 OptAttributes.Emit ();
556
557                         if (Compiler.Settings.Unsafe && !assembly.IsSatelliteAssembly) {
558                                 var pa = PredefinedAttributes.UnverifiableCode;
559                                 if (pa.IsDefined)
560                                         pa.EmitAttribute (builder);
561                         }
562
563                         foreach (var tc in containers) {
564                                 tc.PrepareEmit ();
565                         }
566
567                         base.EmitContainer ();
568
569                         if (Compiler.Report.Errors == 0 && !Compiler.Settings.WriteMetadataOnly)
570                                 VerifyMembers ();
571
572                         if (anonymous_types != null) {
573                                 foreach (var atypes in anonymous_types)
574                                         foreach (var at in atypes.Value)
575                                                 at.EmitContainer ();
576                         }
577                 }
578
579                 internal override void GenerateDocComment (DocumentationBuilder builder)
580                 {
581                         foreach (var tc in containers)
582                                 tc.GenerateDocComment (builder);
583                 }
584
585                 public AnonymousTypeClass GetAnonymousType (IList<AnonymousTypeParameter> parameters)
586                 {
587                         List<AnonymousTypeClass> candidates;
588                         if (!anonymous_types.TryGetValue (parameters.Count, out candidates))
589                                 return null;
590
591                         int i;
592                         foreach (AnonymousTypeClass at in candidates) {
593                                 for (i = 0; i < parameters.Count; ++i) {
594                                         if (!parameters [i].Equals (at.Parameters [i]))
595                                                 break;
596                                 }
597
598                                 if (i == parameters.Count)
599                                         return at;
600                         }
601
602                         return null;
603                 }
604
605                 //
606                 // Return container with awaiter definition. It never returns null
607                 // but all container member can be null for easier error reporting
608                 //
609                 public AwaiterDefinition GetAwaiter (TypeSpec type)
610                 {
611                         AwaiterDefinition awaiter;
612                         if (awaiters.TryGetValue (type, out awaiter))
613                                 return awaiter;
614
615                         awaiter = new AwaiterDefinition ();
616
617                         //
618                         // Predefined: bool IsCompleted { get; } 
619                         //
620                         awaiter.IsCompleted = MemberCache.FindMember (type, MemberFilter.Property ("IsCompleted", Compiler.BuiltinTypes.Bool),
621                                 BindingRestriction.InstanceOnly) as PropertySpec;
622
623                         //
624                         // Predefined: GetResult ()
625                         //
626                         // The method return type is also result type of await expression
627                         //
628                         awaiter.GetResult = MemberCache.FindMember (type, MemberFilter.Method ("GetResult", 0,
629                                 ParametersCompiled.EmptyReadOnlyParameters, null),
630                                 BindingRestriction.InstanceOnly) as MethodSpec;
631
632                         //
633                         // Predefined: INotifyCompletion.OnCompleted (System.Action)
634                         //
635                         var nc = PredefinedTypes.INotifyCompletion;
636                         awaiter.INotifyCompletion = !nc.Define () || type.ImplementsInterface (nc.TypeSpec, false);
637
638                         awaiters.Add (type, awaiter);
639                         return awaiter;
640                 }
641
642                 public override void GetCompletionStartingWith (string prefix, List<string> results)
643                 {
644                         var names = Evaluator.GetVarNames ();
645                         results.AddRange (names.Where (l => l.StartsWith (prefix)));
646                 }
647
648                 public RootNamespace GetRootNamespace (string name)
649                 {
650                         RootNamespace rn;
651                         alias_ns.TryGetValue (name, out rn);
652                         return rn;
653                 }
654
655                 public override string GetSignatureForError ()
656                 {
657                         return "<module>";
658                 }
659
660                 public Binary.PredefinedOperator[] GetPredefinedEnumAritmeticOperators (TypeSpec enumType, bool nullable)
661                 {
662                         TypeSpec underlying;
663                         Binary.Operator mask = 0;
664
665                         if (nullable) {
666                                 underlying = Nullable.NullableInfo.GetEnumUnderlyingType (this, enumType);
667                                 mask = Binary.Operator.NullableMask;
668                         } else {
669                                 underlying = EnumSpec.GetUnderlyingType (enumType);
670                         }
671
672                         var operators = new[] {
673                                 new Binary.PredefinedOperator (enumType, underlying,
674                                         mask | Binary.Operator.AdditionMask | Binary.Operator.SubtractionMask | Binary.Operator.DecomposedMask, enumType),
675                                 new Binary.PredefinedOperator (underlying, enumType,
676                                         mask | Binary.Operator.AdditionMask | Binary.Operator.SubtractionMask | Binary.Operator.DecomposedMask, enumType),
677                                 new Binary.PredefinedOperator (enumType, mask | Binary.Operator.SubtractionMask, underlying)
678                         };
679
680                         return operators;
681                 }
682
683                 public void InitializePredefinedTypes ()
684                 {
685                         predefined_attributes = new PredefinedAttributes (this);
686                         predefined_types = new PredefinedTypes (this);
687                         predefined_members = new PredefinedMembers (this);
688
689                         OperatorsBinaryEqualityLifted = Binary.CreateEqualityLiftedOperatorsTable (this);
690                         OperatorsBinaryLifted = Binary.CreateStandardLiftedOperatorsTable (this);
691                 }
692
693                 public override bool IsClsComplianceRequired ()
694                 {
695                         return DeclaringAssembly.IsCLSCompliant;
696                 }
697
698                 public Attribute ResolveAssemblyAttribute (PredefinedAttribute a_type)
699                 {
700                         Attribute a = OptAttributes.Search ("assembly", a_type);
701                         if (a != null) {
702                                 a.Resolve ();
703                         }
704                         return a;
705                 }
706
707                 public void SetDeclaringAssembly (AssemblyDefinition assembly)
708                 {
709                         // TODO: This setter is quite ugly but I have not found a way around it yet
710                         this.assembly = assembly;
711                 }
712         }
713 }