[mcs] Assignment to value type readonly generated variables needs to check all member...
[mono.git] / mcs / mcs / module.cs
index bcdd786013d11f9cf02e98d302130a2e80b27249..e7e02a0bf14d7f0a1fe29840919fcb06dac0f745 100644 (file)
@@ -36,13 +36,14 @@ namespace Mono.CSharp
                //
                // Compiler generated container for static data
                //
-               sealed class StaticDataContainer : CompilerGeneratedClass
+               sealed class StaticDataContainer : CompilerGeneratedContainer
                {
                        readonly Dictionary<int, Struct> size_types;
-                       new int fields;
+                       int fields;
 
                        public StaticDataContainer (ModuleContainer module)
-                               : base (module, new MemberName ("<PrivateImplementationDetails>" + module.builder.ModuleVersionId.ToString ("B"), Location.Null), Modifiers.STATIC)
+                               : base (module, new MemberName ("<PrivateImplementationDetails>" + module.builder.ModuleVersionId.ToString ("B"), Location.Null),
+                                       Modifiers.STATIC | Modifiers.INTERNAL)
                        {
                                size_types = new Dictionary<int, Struct> ();
                        }
@@ -112,6 +113,7 @@ namespace Mono.CSharp
                readonly Dictionary<TypeSpec, PointerContainer> pointer_types;
                readonly Dictionary<TypeSpec, ReferenceContainer> reference_types;
                readonly Dictionary<TypeSpec, MethodSpec> attrs_cache;
+               readonly Dictionary<TypeSpec, AwaiterDefinition> awaiters;
 
                AssemblyDefinition assembly;
                readonly CompilerContext context;
@@ -126,6 +128,9 @@ namespace Mono.CSharp
                PredefinedTypes predefined_types;
                PredefinedMembers predefined_members;
 
+               public Binary.PredefinedOperator[] OperatorsBinaryEqualityLifted;
+               public Binary.PredefinedOperator[] OperatorsBinaryLifted;
+
                static readonly string[] attribute_targets = new string[] { "assembly", "module" };
 
                public ModuleContainer (CompilerContext context)
@@ -143,6 +148,7 @@ namespace Mono.CSharp
                        pointer_types = new Dictionary<TypeSpec, PointerContainer> ();
                        reference_types = new Dictionary<TypeSpec, ReferenceContainer> ();
                        attrs_cache = new Dictionary<TypeSpec, MethodSpec> ();
+                       awaiters = new Dictionary<TypeSpec, AwaiterDefinition> ();
                }
 
                #region Properties
@@ -180,6 +186,8 @@ namespace Mono.CSharp
                        }
                }
 
+               public int CounterAnonymousTypes { get; set; }
+
                public AssemblyDefinition DeclaringAssembly {
                        get {
                                return assembly;
@@ -303,7 +311,7 @@ namespace Mono.CSharp
 
                public override void AddTypeContainer (TypeContainer tc)
                {
-                       containers.Add (tc);
+                       AddTypeContainerMember (tc);
                }
 
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
@@ -392,6 +400,8 @@ namespace Mono.CSharp
                {
                        DefineContainer ();
 
+                       ExpandBaseInterfaces ();
+
                        base.Define ();
 
                        HasTypesFullyDefined = true;
@@ -406,24 +416,30 @@ namespace Mono.CSharp
                        return base.DefineContainer ();
                }
 
+               public void EnableRedefinition ()
+               {
+                       is_defined = false;
+               }
+
                public override void EmitContainer ()
                {
                        if (OptAttributes != null)
                                OptAttributes.Emit ();
 
-                       if (Compiler.Settings.Unsafe) {
+                       if (Compiler.Settings.Unsafe && !assembly.IsSatelliteAssembly) {
                                var pa = PredefinedAttributes.UnverifiableCode;
                                if (pa.IsDefined)
                                        pa.EmitAttribute (builder);
                        }
 
                        foreach (var tc in containers) {
-                               tc.DefineConstants ();
+                               tc.PrepareEmit ();
                        }
 
                        base.EmitContainer ();
 
-                       VerifyMembers ();
+                       if (Compiler.Report.Errors == 0 && !Compiler.Settings.WriteMetadataOnly)
+                               VerifyMembers ();
 
                        if (anonymous_types != null) {
                                foreach (var atypes in anonymous_types)
@@ -458,6 +474,43 @@ namespace Mono.CSharp
                        return null;
                }
 
+               //
+               // Return container with awaiter definition. It never returns null
+               // but all container member can be null for easier error reporting
+               //
+               public AwaiterDefinition GetAwaiter (TypeSpec type)
+               {
+                       AwaiterDefinition awaiter;
+                       if (awaiters.TryGetValue (type, out awaiter))
+                               return awaiter;
+
+                       awaiter = new AwaiterDefinition ();
+
+                       //
+                       // Predefined: bool IsCompleted { get; } 
+                       //
+                       awaiter.IsCompleted = MemberCache.FindMember (type, MemberFilter.Property ("IsCompleted", Compiler.BuiltinTypes.Bool),
+                               BindingRestriction.InstanceOnly) as PropertySpec;
+
+                       //
+                       // Predefined: GetResult ()
+                       //
+                       // The method return type is also result type of await expression
+                       //
+                       awaiter.GetResult = MemberCache.FindMember (type, MemberFilter.Method ("GetResult", 0,
+                               ParametersCompiled.EmptyReadOnlyParameters, null),
+                               BindingRestriction.InstanceOnly) as MethodSpec;
+
+                       //
+                       // Predefined: INotifyCompletion.OnCompleted (System.Action)
+                       //
+                       var nc = PredefinedTypes.INotifyCompletion;
+                       awaiter.INotifyCompletion = !nc.Define () || type.ImplementsInterface (nc.TypeSpec, false);
+
+                       awaiters.Add (type, awaiter);
+                       return awaiter;
+               }
+
                public override void GetCompletionStartingWith (string prefix, List<string> results)
                {
                        var names = Evaluator.GetVarNames ();
@@ -476,11 +529,37 @@ namespace Mono.CSharp
                        return "<module>";
                }
 
+               public Binary.PredefinedOperator[] GetPredefinedEnumAritmeticOperators (TypeSpec enumType, bool nullable)
+               {
+                       TypeSpec underlying;
+                       Binary.Operator mask = 0;
+
+                       if (nullable) {
+                               underlying = Nullable.NullableInfo.GetEnumUnderlyingType (this, enumType);
+                               mask = Binary.Operator.NullableMask;
+                       } else {
+                               underlying = EnumSpec.GetUnderlyingType (enumType);
+                       }
+
+                       var operators = new[] {
+                               new Binary.PredefinedOperator (enumType, underlying,
+                                       mask | Binary.Operator.AdditionMask | Binary.Operator.SubtractionMask | Binary.Operator.DecomposedMask, enumType),
+                               new Binary.PredefinedOperator (underlying, enumType,
+                                       mask | Binary.Operator.AdditionMask | Binary.Operator.SubtractionMask | Binary.Operator.DecomposedMask, enumType),
+                               new Binary.PredefinedOperator (enumType, mask | Binary.Operator.SubtractionMask, underlying)
+                       };
+
+                       return operators;
+               }
+
                public void InitializePredefinedTypes ()
                {
                        predefined_attributes = new PredefinedAttributes (this);
                        predefined_types = new PredefinedTypes (this);
                        predefined_members = new PredefinedMembers (this);
+
+                       OperatorsBinaryEqualityLifted = Binary.CreateEqualityLiftedOperatorsTable (this);
+                       OperatorsBinaryLifted = Binary.CreateStandardLiftedOperatorsTable (this);
                }
 
                public override bool IsClsComplianceRequired ()