Merge pull request #1248 from kumpera/kill_the_interpreter
[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                                 var expl_block = new ExplicitBlock (top_block, loc, loc);
185
186                                 //
187                                 // var converted = System.Convert.ChangeType (obj, System.Convert.GetTypeCode (value));
188                                 //
189                                 var lv_converted = LocalVariable.CreateCompilerGenerated (Compiler.BuiltinTypes.Object, top_block, loc);
190
191                                 var arguments_gettypecode = new Arguments (1);
192                                 arguments_gettypecode.Add (new Argument (top_block.GetParameterReference (1, loc)));
193
194                                 var gettypecode = new Invocation (new MemberAccess (system_convert, "GetTypeCode", loc), arguments_gettypecode);
195
196                                 var arguments_changetype = new Arguments (1);
197                                 arguments_changetype.Add (new Argument (top_block.GetParameterReference (0, loc)));
198                                 arguments_changetype.Add (new Argument (gettypecode));
199
200                                 var changetype = new Invocation (new MemberAccess (system_convert, "ChangeType", loc), arguments_changetype);
201
202                                 expl_block.AddStatement (new StatementExpression (new SimpleAssign (new LocalVariableReference (lv_converted, loc), changetype, loc)));
203
204
205                                 //
206                                 // return converted.Equals (value)
207                                 //
208                                 var equals_arguments = new Arguments (1);
209                                 equals_arguments.Add (new Argument (top_block.GetParameterReference (1, loc)));
210                                 var equals_invocation = new Invocation (new MemberAccess (new LocalVariableReference (lv_converted, loc), "Equals"), equals_arguments);
211                                 expl_block.AddStatement (new Return (equals_invocation, loc));
212
213                                 var catch_block = new ExplicitBlock (top_block, loc, loc);
214                                 catch_block.AddStatement (new Return (new BoolLiteral (Compiler.BuiltinTypes, false, loc), loc));
215                                 top_block.AddStatement (new TryCatch (expl_block, new List<Catch> () {
216                                         new Catch (catch_block, loc)
217                                 }, loc, false));
218
219                                 m.Define ();
220                                 m.PrepareEmit ();
221                                 AddMember (m);
222
223                                 return m;
224                         }
225                 }
226
227                 PatternMatchingHelper pmh;
228
229                 public PatternMatchingHelper CreatePatterMatchingHelper ()
230                 {
231                         if (pmh == null) {
232                                 pmh = new PatternMatchingHelper (this);
233
234                                 pmh.CreateContainer ();
235                                 pmh.DefineContainer ();
236                                 pmh.Define ();
237                                 AddCompilerGeneratedClass (pmh);
238                         }
239
240                         return pmh;
241                 }
242
243                 public CharSet? DefaultCharSet;
244                 public TypeAttributes DefaultCharSetType = TypeAttributes.AnsiClass;
245
246                 readonly Dictionary<int, List<AnonymousTypeClass>> anonymous_types;
247                 readonly Dictionary<ArrayContainer.TypeRankPair, ArrayContainer> array_types;
248                 readonly Dictionary<TypeSpec, PointerContainer> pointer_types;
249                 readonly Dictionary<TypeSpec, ReferenceContainer> reference_types;
250                 readonly Dictionary<TypeSpec, MethodSpec> attrs_cache;
251                 readonly Dictionary<TypeSpec, AwaiterDefinition> awaiters;
252
253                 AssemblyDefinition assembly;
254                 readonly CompilerContext context;
255                 readonly RootNamespace global_ns;
256                 readonly Dictionary<string, RootNamespace> alias_ns;
257
258                 ModuleBuilder builder;
259
260                 bool has_extenstion_method;
261
262                 PredefinedAttributes predefined_attributes;
263                 PredefinedTypes predefined_types;
264                 PredefinedMembers predefined_members;
265
266                 public Binary.PredefinedOperator[] OperatorsBinaryEqualityLifted;
267                 public Binary.PredefinedOperator[] OperatorsBinaryLifted;
268
269                 static readonly string[] attribute_targets = new string[] { "assembly", "module" };
270
271                 public ModuleContainer (CompilerContext context)
272                         : base (null, MemberName.Null, null, 0)
273                 {
274                         this.context = context;
275
276                         caching_flags &= ~(Flags.Obsolete_Undetected | Flags.Excluded_Undetected);
277
278                         containers = new List<TypeContainer> ();
279                         anonymous_types = new Dictionary<int, List<AnonymousTypeClass>> ();
280                         global_ns = new GlobalRootNamespace ();
281                         alias_ns = new Dictionary<string, RootNamespace> ();
282                         array_types = new Dictionary<ArrayContainer.TypeRankPair, ArrayContainer> ();
283                         pointer_types = new Dictionary<TypeSpec, PointerContainer> ();
284                         reference_types = new Dictionary<TypeSpec, ReferenceContainer> ();
285                         attrs_cache = new Dictionary<TypeSpec, MethodSpec> ();
286                         awaiters = new Dictionary<TypeSpec, AwaiterDefinition> ();
287                 }
288
289                 #region Properties
290
291                 internal Dictionary<ArrayContainer.TypeRankPair, ArrayContainer> ArrayTypesCache {
292                         get {
293                                 return array_types;
294                         }
295                 }
296
297                 //
298                 // Cache for parameter-less attributes
299                 //
300                 internal Dictionary<TypeSpec, MethodSpec> AttributeConstructorCache {
301                         get {
302                                 return attrs_cache;
303                         }
304                 }
305
306                 public override AttributeTargets AttributeTargets {
307                         get {
308                                 return AttributeTargets.Assembly;
309                         }
310                 }
311
312                 public ModuleBuilder Builder {
313                         get {
314                                 return builder;
315                         }
316                 }
317
318                 public override CompilerContext Compiler {
319                         get {
320                                 return context;
321                         }
322                 }
323
324                 public int CounterAnonymousTypes { get; set; }
325
326                 public AssemblyDefinition DeclaringAssembly {
327                         get {
328                                 return assembly;
329                         }
330                 }
331
332                 internal DocumentationBuilder DocumentationBuilder {
333                         get; set;
334                 }
335
336                 public override string DocCommentHeader {
337                         get {
338                                 throw new NotSupportedException ();
339                         }
340                 }
341
342                 public Evaluator Evaluator {
343                         get; set;
344                 }
345
346                 public bool HasDefaultCharSet {
347                         get {
348                                 return DefaultCharSet.HasValue;
349                         }
350                 }
351
352                 public bool HasExtensionMethod {
353                         get {
354                                 return has_extenstion_method;
355                         }
356                         set {
357                                 has_extenstion_method = value;
358                         }
359                 }
360
361                 public bool HasTypesFullyDefined {
362                         get; set;
363                 }
364
365                 //
366                 // Returns module global:: namespace
367                 //
368                 public RootNamespace GlobalRootNamespace {
369                     get {
370                         return global_ns;
371                     }
372                 }
373
374                 public override ModuleContainer Module {
375                         get {
376                                 return this;
377                         }
378                 }
379
380                 internal Dictionary<TypeSpec, PointerContainer> PointerTypesCache {
381                         get {
382                                 return pointer_types;
383                         }
384                 }
385
386                 internal PredefinedAttributes PredefinedAttributes {
387                         get {
388                                 return predefined_attributes;
389                         }
390                 }
391
392                 internal PredefinedMembers PredefinedMembers {
393                         get {
394                                 return predefined_members;
395                         }
396                 }
397
398                 internal PredefinedTypes PredefinedTypes {
399                         get {
400                                 return predefined_types;
401                         }
402                 }
403
404                 internal Dictionary<TypeSpec, ReferenceContainer> ReferenceTypesCache {
405                         get {
406                                 return reference_types;
407                         }
408                 }
409
410                 public override string[] ValidAttributeTargets {
411                         get {
412                                 return attribute_targets;
413                         }
414                 }
415
416                 #endregion
417
418                 public override void Accept (StructuralVisitor visitor)
419                 {
420                         visitor.Visit (this);
421                 }
422
423                 public void AddAnonymousType (AnonymousTypeClass type)
424                 {
425                         List<AnonymousTypeClass> existing;
426                         if (!anonymous_types.TryGetValue (type.Parameters.Count, out existing))
427                         if (existing == null) {
428                                 existing = new List<AnonymousTypeClass> ();
429                                 anonymous_types.Add (type.Parameters.Count, existing);
430                         }
431
432                         existing.Add (type);
433                 }
434
435                 public void AddAttribute (Attribute attr, IMemberContext context)
436                 {
437                         attr.AttachTo (this, context);
438
439                         if (attributes == null) {
440                                 attributes = new Attributes (attr);
441                                 return;
442                         }
443
444                         attributes.AddAttribute (attr);
445                 }
446
447                 public override void AddTypeContainer (TypeContainer tc)
448                 {
449                         AddTypeContainerMember (tc);
450                 }
451
452                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
453                 {
454                         if (a.Target == AttributeTargets.Assembly) {
455                                 assembly.ApplyAttributeBuilder (a, ctor, cdata, pa);
456                                 return;
457                         }
458
459                         if (a.Type == pa.DefaultCharset) {
460                                 switch (a.GetCharSetValue ()) {
461                                 case CharSet.Ansi:
462                                 case CharSet.None:
463                                         break;
464                                 case CharSet.Auto:
465                                         DefaultCharSet = CharSet.Auto;
466                                         DefaultCharSetType = TypeAttributes.AutoClass;
467                                         break;
468                                 case CharSet.Unicode:
469                                         DefaultCharSet = CharSet.Unicode;
470                                         DefaultCharSetType = TypeAttributes.UnicodeClass;
471                                         break;
472                                 default:
473                                         Report.Error (1724, a.Location, "Value specified for the argument to `{0}' is not valid",
474                                                 a.GetSignatureForError ());
475                                         break;
476                                 }
477                         } else if (a.Type == pa.CLSCompliant) {
478                                 Attribute cls = DeclaringAssembly.CLSCompliantAttribute;
479                                 if (cls == null) {
480                                         Report.Warning (3012, 1, a.Location,
481                                                 "You must specify the CLSCompliant attribute on the assembly, not the module, to enable CLS compliance checking");
482                                 } else if (DeclaringAssembly.IsCLSCompliant != a.GetBoolean ()) {
483                                         Report.SymbolRelatedToPreviousError (cls.Location, cls.GetSignatureForError ());
484                                         Report.Warning (3017, 1, a.Location,
485                                                 "You cannot specify the CLSCompliant attribute on a module that differs from the CLSCompliant attribute on the assembly");
486                                         return;
487                                 }
488                         }
489
490                         builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
491                 }
492
493                 public override void CloseContainer ()
494                 {
495                         if (anonymous_types != null) {
496                                 foreach (var atypes in anonymous_types)
497                                         foreach (var at in atypes.Value)
498                                                 at.CloseContainer ();
499                         }
500
501                         base.CloseContainer ();
502                 }
503
504                 public TypeBuilder CreateBuilder (string name, TypeAttributes attr, int typeSize)
505                 {
506                         return builder.DefineType (name, attr, null, typeSize);
507                 }
508
509                 //
510                 // Creates alias global namespace
511                 //
512                 public RootNamespace CreateRootNamespace (string alias)
513                 {
514                         if (alias == global_ns.Alias) {
515                                 RootNamespace.Error_GlobalNamespaceRedefined (Report, Location.Null);
516                                 return global_ns;
517                         }
518
519                         RootNamespace rn;
520                         if (!alias_ns.TryGetValue (alias, out rn)) {
521                                 rn = new RootNamespace (alias);
522                                 alias_ns.Add (alias, rn);
523                         }
524
525                         return rn;
526                 }
527
528                 public void Create (AssemblyDefinition assembly, ModuleBuilder moduleBuilder)
529                 {
530                         this.assembly = assembly;
531                         builder = moduleBuilder;
532                 }
533
534                 public override bool Define ()
535                 {
536                         DefineContainer ();
537
538                         ExpandBaseInterfaces ();
539
540                         base.Define ();
541
542                         HasTypesFullyDefined = true;
543
544                         return true;
545                 }
546
547                 public override bool DefineContainer ()
548                 {
549                         DefineNamespace ();
550
551                         return base.DefineContainer ();
552                 }
553
554                 public void EnableRedefinition ()
555                 {
556                         is_defined = false;
557                 }
558
559                 public override void EmitContainer ()
560                 {
561                         if (OptAttributes != null)
562                                 OptAttributes.Emit ();
563
564                         if (Compiler.Settings.Unsafe && !assembly.IsSatelliteAssembly) {
565                                 var pa = PredefinedAttributes.UnverifiableCode;
566                                 if (pa.IsDefined)
567                                         pa.EmitAttribute (builder);
568                         }
569
570                         foreach (var tc in containers) {
571                                 tc.PrepareEmit ();
572                         }
573
574                         base.EmitContainer ();
575
576                         if (Compiler.Report.Errors == 0 && !Compiler.Settings.WriteMetadataOnly)
577                                 VerifyMembers ();
578
579                         if (anonymous_types != null) {
580                                 foreach (var atypes in anonymous_types)
581                                         foreach (var at in atypes.Value)
582                                                 at.EmitContainer ();
583                         }
584                 }
585
586                 internal override void GenerateDocComment (DocumentationBuilder builder)
587                 {
588                         foreach (var tc in containers)
589                                 tc.GenerateDocComment (builder);
590                 }
591
592                 public AnonymousTypeClass GetAnonymousType (IList<AnonymousTypeParameter> parameters)
593                 {
594                         List<AnonymousTypeClass> candidates;
595                         if (!anonymous_types.TryGetValue (parameters.Count, out candidates))
596                                 return null;
597
598                         int i;
599                         foreach (AnonymousTypeClass at in candidates) {
600                                 for (i = 0; i < parameters.Count; ++i) {
601                                         if (!parameters [i].Equals (at.Parameters [i]))
602                                                 break;
603                                 }
604
605                                 if (i == parameters.Count)
606                                         return at;
607                         }
608
609                         return null;
610                 }
611
612                 //
613                 // Return container with awaiter definition. It never returns null
614                 // but all container member can be null for easier error reporting
615                 //
616                 public AwaiterDefinition GetAwaiter (TypeSpec type)
617                 {
618                         AwaiterDefinition awaiter;
619                         if (awaiters.TryGetValue (type, out awaiter))
620                                 return awaiter;
621
622                         awaiter = new AwaiterDefinition ();
623
624                         //
625                         // Predefined: bool IsCompleted { get; } 
626                         //
627                         awaiter.IsCompleted = MemberCache.FindMember (type, MemberFilter.Property ("IsCompleted", Compiler.BuiltinTypes.Bool),
628                                 BindingRestriction.InstanceOnly) as PropertySpec;
629
630                         //
631                         // Predefined: GetResult ()
632                         //
633                         // The method return type is also result type of await expression
634                         //
635                         awaiter.GetResult = MemberCache.FindMember (type, MemberFilter.Method ("GetResult", 0,
636                                 ParametersCompiled.EmptyReadOnlyParameters, null),
637                                 BindingRestriction.InstanceOnly) as MethodSpec;
638
639                         //
640                         // Predefined: INotifyCompletion.OnCompleted (System.Action)
641                         //
642                         var nc = PredefinedTypes.INotifyCompletion;
643                         awaiter.INotifyCompletion = !nc.Define () || type.ImplementsInterface (nc.TypeSpec, false);
644
645                         awaiters.Add (type, awaiter);
646                         return awaiter;
647                 }
648
649                 public override void GetCompletionStartingWith (string prefix, List<string> results)
650                 {
651                         var names = Evaluator.GetVarNames ();
652                         results.AddRange (names.Where (l => l.StartsWith (prefix)));
653                 }
654
655                 public RootNamespace GetRootNamespace (string name)
656                 {
657                         RootNamespace rn;
658                         alias_ns.TryGetValue (name, out rn);
659                         return rn;
660                 }
661
662                 public override string GetSignatureForError ()
663                 {
664                         return "<module>";
665                 }
666
667                 public Binary.PredefinedOperator[] GetPredefinedEnumAritmeticOperators (TypeSpec enumType, bool nullable)
668                 {
669                         TypeSpec underlying;
670                         Binary.Operator mask = 0;
671
672                         if (nullable) {
673                                 underlying = Nullable.NullableInfo.GetEnumUnderlyingType (this, enumType);
674                                 mask = Binary.Operator.NullableMask;
675                         } else {
676                                 underlying = EnumSpec.GetUnderlyingType (enumType);
677                         }
678
679                         var operators = new[] {
680                                 new Binary.PredefinedOperator (enumType, underlying,
681                                         mask | Binary.Operator.AdditionMask | Binary.Operator.SubtractionMask | Binary.Operator.DecomposedMask, enumType),
682                                 new Binary.PredefinedOperator (underlying, enumType,
683                                         mask | Binary.Operator.AdditionMask | Binary.Operator.SubtractionMask | Binary.Operator.DecomposedMask, enumType),
684                                 new Binary.PredefinedOperator (enumType, mask | Binary.Operator.SubtractionMask, underlying)
685                         };
686
687                         return operators;
688                 }
689
690                 public void InitializePredefinedTypes ()
691                 {
692                         predefined_attributes = new PredefinedAttributes (this);
693                         predefined_types = new PredefinedTypes (this);
694                         predefined_members = new PredefinedMembers (this);
695
696                         OperatorsBinaryEqualityLifted = Binary.CreateEqualityLiftedOperatorsTable (this);
697                         OperatorsBinaryLifted = Binary.CreateStandardLiftedOperatorsTable (this);
698                 }
699
700                 public override bool IsClsComplianceRequired ()
701                 {
702                         return DeclaringAssembly.IsCLSCompliant;
703                 }
704
705                 public Attribute ResolveAssemblyAttribute (PredefinedAttribute a_type)
706                 {
707                         Attribute a = OptAttributes.Search ("assembly", a_type);
708                         if (a != null) {
709                                 a.Resolve ();
710                         }
711                         return a;
712                 }
713
714                 public void SetDeclaringAssembly (AssemblyDefinition assembly)
715                 {
716                         // TODO: This setter is quite ugly but I have not found a way around it yet
717                         this.assembly = assembly;
718                 }
719         }
720 }