Implemented PipeSecurity. GetAccessControl, SetAccessControl, and ACL-containing...
[mono.git] / mcs / mcs / method.cs
index f40efb93aa04fdb2cd645fca95c652457f0c2753..8c96171696e8442fb5c800b8b729527b7edff5a2 100644 (file)
@@ -19,6 +19,7 @@ using System.Security.Permissions;
 using System.Text;
 using System.Linq;
 using Mono.CompilerServices.SymbolWriter;
+using System.Runtime.CompilerServices;
 
 #if NET_2_1
 using XmlElement = System.Object;
@@ -495,6 +496,20 @@ namespace Mono.CSharp {
                                missing.AddRange (m);
                        }
 
+                       if (Arity > 0) {
+                               foreach (var tp in GenericDefinition.TypeParameters) {
+                                       var m = tp.GetMissingDependencies ();
+
+                                       if (m == null)
+                                               continue;
+
+                                       if (missing == null)
+                                               missing = new List<TypeSpec> ();
+
+                                       missing.AddRange (m);
+                               }
+                       }
+
                        return missing;                 
                }
 
@@ -533,10 +548,13 @@ namespace Mono.CSharp {
                        }
 
                        if (a.Type == pa.MethodImpl) {
-                               is_external_implementation = a.IsInternalCall ();
-                       }
+                               if ((ModFlags & Modifiers.ASYNC) != 0 && (a.GetMethodImplOptions () & MethodImplOptions.Synchronized) != 0) {
+                                       Report.Error (4015, a.Location, "`{0}': Async methods cannot use `MethodImplOptions.Synchronized'",
+                                               GetSignatureForError ());
+                               }
 
-                       if (a.Type == pa.DllImport) {
+                               is_external_implementation = a.IsInternalCall ();
+                       } else if (a.Type == pa.DllImport) {
                                const Modifiers extern_static = Modifiers.EXTERN | Modifiers.STATIC;
                                if ((ModFlags & extern_static) != extern_static) {
                                        Report.Error (601, a.Location, "The DllImport attribute must be specified on a method marked `static' and `extern'");
@@ -633,7 +651,7 @@ namespace Mono.CSharp {
                        if ((ModFlags & Modifiers.PARTIAL) != 0) {
                                for (int i = 0; i < parameters.Count; ++i) {
                                        IParameterData p = parameters.FixedParameters [i];
-                                       if (p.ModFlags == Parameter.Modifier.OUT) {
+                                       if ((p.ModFlags & Parameter.Modifier.OUT) != 0) {
                                                Report.Error (752, Location, "`{0}': A partial method parameters cannot use `out' modifier",
                                                        GetSignatureForError ());
                                        }
@@ -888,7 +906,7 @@ namespace Mono.CSharp {
 
                        var ac = parameters.Types [0] as ArrayContainer;
                        return ac != null && ac.Rank == 1 && ac.Element.BuiltinType == BuiltinTypeSpec.Type.String &&
-                                       (parameters[0].ModFlags & ~Parameter.Modifier.PARAMS) == Parameter.Modifier.NONE;
+                                       (parameters[0].ModFlags & Parameter.Modifier.RefOutMask) == 0;
                }
 
                public override FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
@@ -936,7 +954,7 @@ namespace Mono.CSharp {
                                }
 
                                for (int i = 0; i < parameters.Count; ++i) {
-                                       if (parameters.FixedParameters [i].ModFlags == Parameter.Modifier.OUT) {
+                                       if ((parameters.FixedParameters [i].ModFlags & Parameter.Modifier.OUT) != 0) {
                                                Report.Error (685, Location, "Conditional method `{0}' cannot have an out parameter", GetSignatureForError ());
                                                return;
                                        }
@@ -1192,9 +1210,12 @@ namespace Mono.CSharp {
                                                Report.Error (1983, Location, "The return type of an async method must be void, Task, or Task<T>");
                                        }
 
-                                       AsyncInitializer.Create (this, block, parameters, Parent.PartialContainer, ReturnType, Location);
+                                       block = (ToplevelBlock) block.ConvertToAsyncTask (this, Parent.PartialContainer, parameters, ReturnType, Location);
                                        ModFlags |= Modifiers.DEBUGGER_HIDDEN;
                                }
+
+                               if (Compiler.Settings.WriteMetadataOnly)
+                                       block = null;
                        }
 
                        if ((ModFlags & Modifiers.STATIC) == 0)
@@ -1283,10 +1304,18 @@ namespace Mono.CSharp {
                                        }
                                }
 
-                               base.Emit ();
-                               
+                               if (block != null && block.StateMachine != null) {
+                                       var psm = block.StateMachine is IteratorStorey ?
+                                               Module.PredefinedAttributes.IteratorStateMachine :
+                                               Module.PredefinedAttributes.AsyncStateMachine;
+                                       
+                                       psm.EmitAttribute (MethodBuilder, block.StateMachine);
+                               }
+
                                if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
                                        Module.PredefinedAttributes.Extension.EmitAttribute (MethodBuilder);
+
+                               base.Emit ();
                        } catch {
                                Console.WriteLine ("Internal compiler error at {0}: exception caught while emitting {1}",
                                                   Location, MethodBuilder);
@@ -1414,8 +1443,7 @@ namespace Mono.CSharp {
                                base_ctor = ConstructorLookup (ec, type, ref argument_list, loc);
                        }
        
-                       // TODO MemberCache: Does it work for inflated types ?
-                       if (base_ctor == caller_builder.Spec){
+                       if (base_ctor != null && base_ctor.MemberDefinition == caller_builder.Spec.MemberDefinition) {
                                ec.Report.Error (516, loc, "Constructor `{0}' cannot call itself",
                                        caller_builder.GetSignatureForError ());
                        }
@@ -1600,10 +1628,15 @@ namespace Mono.CSharp {
                        
                        Parent.MemberCache.AddMember (spec);
                        
-                       // It's here only to report an error
-                       if (block != null && block.IsIterator) {
-                               member_type = Compiler.BuiltinTypes.Void;
-                               Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
+                       if (block != null) {
+                               // It's here only to report an error
+                               if (block.IsIterator) {
+                                       member_type = Compiler.BuiltinTypes.Void;
+                                       Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
+                               }
+
+                               if (Compiler.Settings.WriteMetadataOnly)
+                                       block = null;
                        }
 
                        return true;
@@ -1639,14 +1672,14 @@ namespace Mono.CSharp {
                        BlockContext bc = new BlockContext (this, block, Compiler.BuiltinTypes.Void);
                        bc.Set (ResolveContext.Options.ConstructorScope);
 
-                       //
-                       // If we use a "this (...)" constructor initializer, then
-                       // do not emit field initializers, they are initialized in the other constructor
-                       //
-                       if (!(Initializer is ConstructorThisInitializer))
-                               Parent.PartialContainer.ResolveFieldInitializers (bc);
-
                        if (block != null) {
+                               //
+                               // If we use a "this (...)" constructor initializer, then
+                               // do not emit field initializers, they are initialized in the other constructor
+                               //
+                               if (!(Initializer is ConstructorThisInitializer))
+                                       Parent.PartialContainer.ResolveFieldInitializers (bc);
+
                                if (!IsStatic) {
                                        if (Initializer == null) {
                                                if (Parent.PartialContainer.Kind == MemberKind.Struct) {
@@ -1699,6 +1732,11 @@ namespace Mono.CSharp {
                        return null;
                }
 
+               public override string GetCallerMemberName ()
+               {
+                       return IsStatic ? TypeConstructorName : ConstructorName;
+               }
+
                public override string GetSignatureForDocumentation ()
                {
                        return Parent.GetSignatureForDocumentation () + ".#ctor" + parameters.GetSignatureForDocumentation ();
@@ -1942,7 +1980,7 @@ namespace Mono.CSharp {
                                                //
                                                if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public) {
                                                        implementing = null;
-                                               } else if (optional && (container.Interfaces == null || Array.IndexOf (container.Interfaces, implementing.DeclaringType) < 0)) {
+                                               } else if (optional && (container.Interfaces == null || !container.Definition.Interfaces.Contains (implementing.DeclaringType))) {
                                                        //
                                                        // We are not implementing interface when base class already implemented it
                                                        //
@@ -2128,6 +2166,16 @@ namespace Mono.CSharp {
                        return true;
                }
 
+               public override bool Define ()
+               {
+                       base.Define ();
+
+                       if (Compiler.Settings.WriteMetadataOnly)
+                               block = null;
+
+                       return true;
+               }
+
                public override void Emit()
                {
                        var base_type = Parent.PartialContainer.BaseType;
@@ -2236,11 +2284,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               public bool IsExcluded ()
-               {
-                       return false;
-               }
-
                public MemberName MethodName {
                        get {
                                return MemberName;
@@ -2347,6 +2390,11 @@ namespace Mono.CSharp {
                        return false;
                }
 
+               public override string GetCallerMemberName ()
+               {
+                       return base.GetCallerMemberName ().Substring (prefix.Length);
+               }
+
                public override string GetSignatureForDocumentation ()
                {
                        // should not be called
@@ -2491,13 +2539,18 @@ namespace Mono.CSharp {
                        if (!base.Define ())
                                return false;
 
-                       if (block != null && block.IsIterator) {
-                               //
-                               // Current method is turned into automatically generated
-                               // wrapper which creates an instance of iterator
-                               //
-                               Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
-                               ModFlags |= Modifiers.DEBUGGER_HIDDEN;
+                       if (block != null) {
+                               if (block.IsIterator) {
+                                       //
+                                       // Current method is turned into automatically generated
+                                       // wrapper which creates an instance of iterator
+                                       //
+                                       Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
+                                       ModFlags |= Modifiers.DEBUGGER_HIDDEN;
+                               }
+
+                               if (Compiler.Settings.WriteMetadataOnly)
+                                       block = null;
                        }
 
                        // imlicit and explicit operator of same types are not allowed