Move parts of delegate to shared partition (dotnet/coreclr#23552)
authorMarek Safar <marek.safar@gmail.com>
Thu, 4 Apr 2019 16:05:08 +0000 (18:05 +0200)
committerJan Kotas <jkotas@microsoft.com>
Thu, 4 Apr 2019 16:05:08 +0000 (09:05 -0700)
Commit migrated from https://github.com/dotnet/coreclr/commit/991817d90827b206ab25e74e7a5bd326a7e86ad4

src/coreclr/src/System.Private.CoreLib/System.Private.CoreLib.csproj
src/coreclr/src/System.Private.CoreLib/src/System/Delegate.CoreCLR.cs [moved from src/coreclr/src/System.Private.CoreLib/src/System/Delegate.cs with 82% similarity]
src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
src/libraries/System.Private.CoreLib/src/System/Delegate.cs [new file with mode: 0644]

index 3a8c2e7..defcc7a 100644 (file)
     <Compile Include="$(BclSourcesRoot)\System\Collections\ObjectModel\ReadOnlyDictionary.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Currency.cs" />
     <Compile Include="$(BclSourcesRoot)\System\DefaultBinder.CanConvert.cs" />
-    <Compile Include="$(BclSourcesRoot)\System\Delegate.cs" />
+    <Compile Include="$(BclSourcesRoot)\System\Delegate.CoreCLR.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Diagnostics\Debugger.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Diagnostics\EditAndContinueHelper.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\NativeRuntimeEventSource.cs" Condition="'$(FeaturePerfTracing)' == 'true'"/>
@@ -12,7 +12,7 @@ namespace System
 {
     [ClassInterface(ClassInterfaceType.None)]
     [ComVisible(true)]
-    public abstract class Delegate : ICloneable, ISerializable
+    public abstract partial class Delegate : ICloneable, ISerializable
     {
         // _target is the object we will invoke on
         internal object _target;
@@ -84,22 +84,6 @@ namespace System
                              DelegateBindingFlags.CaselessMatching);
         }
 
-        // Protect the default constructor so you can't build a delegate
-        private Delegate()
-        {
-        }
-
-        public object DynamicInvoke(params object[] args)
-        {
-            // Theoretically we should set up a LookForMyCaller stack mark here and pass that along.
-            // But to maintain backward compatibility we can't switch to calling an 
-            // internal overload of DynamicInvokeImpl that takes a stack mark.
-            // Fortunately the stack walker skips all the reflection invocation frames including this one.
-            // So this method will never be returned by the stack walker as the caller.
-            // See SystemDomain::CallersMethodCallbackWithStackMark in AppDomain.cpp.
-            return DynamicInvokeImpl(args);
-        }
-
         protected virtual object DynamicInvokeImpl(object[] args)
         {
             RuntimeMethodHandleInternal method = new RuntimeMethodHandleInternal(GetInvokeMethod());
@@ -177,42 +161,6 @@ namespace System
                 return GetType().GetHashCode();
         }
 
-        public static Delegate Combine(Delegate a, Delegate b)
-        {
-            if ((object)a == null) // cast to object for a more efficient test
-                return b;
-
-            return a.CombineImpl(b);
-        }
-
-        public static Delegate Combine(params Delegate[] delegates)
-        {
-            if (delegates == null || delegates.Length == 0)
-                return null;
-
-            Delegate d = delegates[0];
-            for (int i = 1; i < delegates.Length; i++)
-                d = Combine(d, delegates[i]);
-
-            return d;
-        }
-
-        public virtual Delegate[] GetInvocationList()
-        {
-            Delegate[] d = new Delegate[1];
-            d[0] = this;
-            return d;
-        }
-
-        // This routine will return the method
-        public MethodInfo Method
-        {
-            get
-            {
-                return GetMethodImpl();
-            }
-        }
-
         protected virtual MethodInfo GetMethodImpl()
         {
             if ((_methodBase == null) || !(_methodBase is MethodInfo))
@@ -276,63 +224,6 @@ namespace System
             }
         }
 
-
-        public static Delegate Remove(Delegate source, Delegate value)
-        {
-            if (source == null)
-                return null;
-
-            if (value == null)
-                return source;
-
-            if (!InternalEqualTypes(source, value))
-                throw new ArgumentException(SR.Arg_DlgtTypeMis);
-
-            return source.RemoveImpl(value);
-        }
-
-        public static Delegate RemoveAll(Delegate source, Delegate value)
-        {
-            Delegate newDelegate = null;
-
-            do
-            {
-                newDelegate = source;
-                source = Remove(source, value);
-            }
-            while (newDelegate != source);
-
-            return newDelegate;
-        }
-
-        protected virtual Delegate CombineImpl(Delegate d)
-        {
-            throw new MulticastNotSupportedException(SR.Multicast_Combine);
-        }
-
-        protected virtual Delegate RemoveImpl(Delegate d)
-        {
-            return (d.Equals(this)) ? null : this;
-        }
-
-
-        public virtual object Clone()
-        {
-            return MemberwiseClone();
-        }
-
-        // V1 API.
-        public static Delegate CreateDelegate(Type type, object target, string method)
-        {
-            return CreateDelegate(type, target, method, false, true);
-        }
-
-        // V1 API.
-        public static Delegate CreateDelegate(Type type, object target, string method, bool ignoreCase)
-        {
-            return CreateDelegate(type, target, method, ignoreCase, true);
-        }
-
         // V1 API.
         public static Delegate CreateDelegate(Type type, object target, string method, bool ignoreCase, bool throwOnBindFailure)
         {
@@ -372,18 +263,6 @@ namespace System
         }
 
         // V1 API.
-        public static Delegate CreateDelegate(Type type, Type target, string method)
-        {
-            return CreateDelegate(type, target, method, false, true);
-        }
-
-        // V1 API.
-        public static Delegate CreateDelegate(Type type, Type target, string method, bool ignoreCase)
-        {
-            return CreateDelegate(type, target, method, ignoreCase, true);
-        }
-
-        // V1 API.
         public static Delegate CreateDelegate(Type type, Type target, string method, bool ignoreCase, bool throwOnBindFailure)
         {
             if (type == null)
@@ -463,12 +342,6 @@ namespace System
         }
 
         // V2 API.
-        public static Delegate CreateDelegate(Type type, object firstArgument, MethodInfo method)
-        {
-            return CreateDelegate(type, firstArgument, method, true);
-        }
-
-        // V2 API.
         public static Delegate CreateDelegate(Type type, object firstArgument, MethodInfo method, bool throwOnBindFailure)
         {
             // Validate the parameters.
@@ -505,43 +378,6 @@ namespace System
             return d;
         }
 
-        // Force inline as the true/false ternary takes it above ALWAYS_INLINE size even though the asm ends up smaller
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public static bool operator ==(Delegate d1, Delegate d2)
-        {
-            // Test d2 first to allow branch elimination when inlined for null checks (== null)
-            // so it can become a simple test
-            if (d2 is null)
-            {
-                // return true/false not the test result https://github.com/dotnet/coreclr/issues/914
-                return (d1 is null) ? true : false;
-            }
-
-            return ReferenceEquals(d2, d1) ? true : d2.Equals((object)d1);
-        }
-
-        public static bool operator !=(Delegate d1, Delegate d2)
-        {
-            // Test d2 first to allow branch elimination when inlined for not null checks (!= null)
-            // so it can become a simple test
-            if (d2 is null)
-            {
-                // return true/false not the test result https://github.com/dotnet/coreclr/issues/914
-                return (d1 is null) ? false : true;
-            }
-
-            return ReferenceEquals(d2, d1) ? false : !d2.Equals(d1);
-        }
-
-        //
-        // Implementation of ISerializable
-        //
-
-        public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
-        {
-            throw new PlatformNotSupportedException();
-        }
-
         //
         // internal implementation details (FCALLS and utilities)
         //
@@ -614,12 +450,6 @@ namespace System
             return d;
         }
 
-        // V1 API.
-        public static Delegate CreateDelegate(Type type, MethodInfo method)
-        {
-            return CreateDelegate(type, method, true);
-        }
-
         internal static Delegate CreateDelegateInternal(RuntimeType rtType, RuntimeMethodInfo rtMethod, object firstArgument, DelegateBindingFlags flags)
         {
             Delegate d = InternalAlloc(rtType);
index f2b23c6..69fb556 100644 (file)
     <Compile Include="$(MSBuildThisFileDirectory)System\Decimal.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Decimal.DecCalc.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\DefaultBinder.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)System\Delegate.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\CodeAnalysis\SuppressMessageAttribute.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\ConditionalAttribute.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Contracts\ContractException.cs" />
diff --git a/src/libraries/System.Private.CoreLib/src/System/Delegate.cs b/src/libraries/System.Private.CoreLib/src/System/Delegate.cs
new file mode 100644 (file)
index 0000000..d4db0f2
--- /dev/null
@@ -0,0 +1,126 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.Serialization;
+
+namespace System
+{
+    public abstract partial class Delegate : ICloneable, ISerializable
+    {
+        private Delegate()
+        {
+        }
+
+        public virtual object Clone() => MemberwiseClone();
+
+        public static Delegate Combine(Delegate a, Delegate b)
+        {
+            if (a is null)
+                return b;
+
+            return a.CombineImpl(b);
+        }
+
+        public static Delegate Combine(params Delegate[] delegates)
+        {
+            if (delegates is null || delegates.Length == 0)
+                return null;
+
+            Delegate d = delegates [0];
+            for (int i = 1; i < delegates.Length; i++)
+                d = Combine(d, delegates[i]);
+
+            return d;
+        }
+
+        protected virtual Delegate CombineImpl(Delegate d) => throw new MulticastNotSupportedException(SR.Multicast_Combine);
+
+        // V2 api: Creates open or closed delegates to static or instance methods - relaxed signature checking allowed. 
+        public static Delegate CreateDelegate(Type type, object firstArgument, MethodInfo method) => CreateDelegate(type, firstArgument, method, throwOnBindFailure: true);
+
+        // V1 api: Creates open delegates to static or instance methods - relaxed signature checking allowed.
+        public static Delegate CreateDelegate(Type type, MethodInfo method) => CreateDelegate(type, method, throwOnBindFailure: true);
+
+        // V1 api: Creates closed delegates to instance methods only, relaxed signature checking disallowed.
+        public static Delegate CreateDelegate(Type type, object target, string method) => CreateDelegate(type, target, method, ignoreCase: false, throwOnBindFailure: true);
+        public static Delegate CreateDelegate(Type type, object target, string method, bool ignoreCase) => CreateDelegate(type, target, method, ignoreCase, throwOnBindFailure: true);
+
+        // V1 api: Creates open delegates to static methods only, relaxed signature checking disallowed.
+        public static Delegate CreateDelegate(Type type, Type target, string method) => CreateDelegate(type, target, method, ignoreCase: false, throwOnBindFailure: true);
+        public static Delegate CreateDelegate(Type type, Type target, string method, bool ignoreCase) => CreateDelegate(type, target, method, ignoreCase, throwOnBindFailure: true);
+
+        public object DynamicInvoke(params object[] args)
+        {
+            return DynamicInvokeImpl(args);
+        }
+
+        public virtual Delegate[] GetInvocationList() => new Delegate[] { this };
+
+        public virtual void GetObjectData(SerializationInfo info, StreamingContext context) => throw new PlatformNotSupportedException();
+
+        public MethodInfo Method => GetMethodImpl();
+
+        protected virtual Delegate RemoveImpl(Delegate d) => d.Equals(this) ? null : this;
+
+        public static Delegate Remove(Delegate source, Delegate value)
+        {
+            if (source == null)
+                return null;
+
+            if (value == null)
+                return source;
+
+            if (!InternalEqualTypes(source, value))
+                throw new ArgumentException(SR.Arg_DlgtTypeMis);
+
+            return source.RemoveImpl(value);
+        }
+
+        public static Delegate RemoveAll(Delegate source, Delegate value)
+        {
+            Delegate newDelegate = null;
+
+            do
+            {
+                newDelegate = source;
+                source = Remove(source, value);
+            }
+            while (newDelegate != source);
+
+            return newDelegate;
+        }
+
+        // Force inline as the true/false ternary takes it above ALWAYS_INLINE size even though the asm ends up smaller
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static bool operator ==(Delegate d1, Delegate d2)
+        {
+            // Test d2 first to allow branch elimination when inlined for null checks (== null)
+            // so it can become a simple test
+            if (d2 is null)
+            {
+                // return true/false not the test result https://github.com/dotnet/coreclr/issues/914
+                return (d1 is null) ? true : false;
+            }
+
+            return ReferenceEquals(d2, d1) || d2.Equals((object)d1);
+        }
+
+        // Force inline as the true/false ternary takes it above ALWAYS_INLINE size even though the asm ends up smaller
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static bool operator !=(Delegate d1, Delegate d2)
+        {
+            // Test d2 first to allow branch elimination when inlined for not null checks (!= null)
+            // so it can become a simple test
+            if (d2 is null)
+            {
+                // return true/false not the test result https://github.com/dotnet/coreclr/issues/914
+                return (d1 is null) ? false : true;
+            }
+
+            return ReferenceEquals(d2, d1) ? false : !d2.Equals(d1);
+        }
+    }
+}
\ No newline at end of file