コード例 #1
0
        public static MethodInfo GetMethodOnType(Type type, MethodInfo proxiedMethod)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            Debug.Assert(proxiedMethod.DeclaringType.IsAssignableFrom(type),
                         "proxiedMethod.DeclaringType.IsAssignableFrom(type)");
            using (var locker = @lock.ForReading())
            {
                var methodOnTarget = GetFromCache(proxiedMethod, type);
                if (methodOnTarget != null)
                {
                    return(methodOnTarget);
                }
            }

            using (var locker = @lock.ForReadingUpgradeable())
            {
                var methodOnTarget = GetFromCache(proxiedMethod, type);
                if (methodOnTarget != null)
                {
                    return(methodOnTarget);
                }

                // Upgrade the lock to a write lock.
                using (locker.Upgrade())
                {
                    methodOnTarget = ObtainMethod(proxiedMethod, type);
                    PutToCache(proxiedMethod, type, methodOnTarget);
                }
                return(methodOnTarget);
            }
        }
コード例 #2
0
        public static FieldInfo[] GetAllFields(this Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            if (type.GetTypeInfo().IsClass == false)
            {
                throw new ArgumentException(string.Format("Type {0} is not a class type. This method supports only classes", type));
            }

            var fields      = new List <FieldInfo>();
            var currentType = type;

            while (currentType != typeof(object))
            {
                Debug.Assert(currentType != null);
                var currentFields = currentType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
                fields.AddRange(currentFields);
                currentType = currentType.GetTypeInfo().BaseType;
            }

            return(fields.ToArray());
        }
コード例 #3
0
        protected void AddMapping(Type @interface, ITypeContributor implementer, IDictionary <Type, ITypeContributor> mapping)
        {
            Debug.Assert(implementer != null, "implementer != null");
            Debug.Assert(@interface != null, "@interface != null");
            Debug.Assert(@interface.GetTypeInfo().IsInterface, "@interface.IsInterface");

            if (!mapping.ContainsKey(@interface))
            {
                AddMappingNoCheck(@interface, implementer, mapping);
            }
        }
コード例 #4
0
        private static MethodInfo ObtainMethod(MethodInfo proxiedMethod, Type type)
        {
            Type[] genericArguments = null;
            if (proxiedMethod.IsGenericMethod)
            {
                genericArguments = proxiedMethod.GetGenericArguments();
                proxiedMethod    = proxiedMethod.GetGenericMethodDefinition();
            }
            var        declaringType  = proxiedMethod.DeclaringType;
            MethodInfo methodOnTarget = null;

            if (declaringType.GetTypeInfo().IsInterface)
            {
                var mapping = type.GetTypeInfo().GetRuntimeInterfaceMap(declaringType);
                var index   = Array.IndexOf(mapping.InterfaceMethods, proxiedMethod);
                Debug.Assert(index != -1);
                methodOnTarget = mapping.TargetMethods[index];
            }
            else
            {
                // NOTE: this implementation sucks, feel free to improve it.
                var methods = MethodFinder.GetAllInstanceMethods(type, BindingFlags.Public | BindingFlags.NonPublic);
                foreach (var method in methods)
                {
                    if (MethodSignatureComparer.Instance.Equals(method.GetBaseDefinition(), proxiedMethod))
                    {
                        methodOnTarget = method;
                        break;
                    }
                }
            }
            if (methodOnTarget == null)
            {
                throw new ArgumentException(
                          string.Format("Could not find method overriding {0} on type {1}. This is most likely a bug. Please report it.",
                                        proxiedMethod, type));
            }

            if (genericArguments == null)
            {
                return(methodOnTarget);
            }
            return(methodOnTarget.MakeGenericMethod(genericArguments));
        }
コード例 #5
0
        protected void GenerateConstructor(ClassEmitter emitter, ConstructorInfo baseConstructor,
                                           ProxyConstructorImplementation impl, params FieldReference[] fields)
        {
            if (impl == ProxyConstructorImplementation.SkipConstructor)
            {
                return;
            }

            ArgumentReference[] args;
            ParameterInfo[]     baseConstructorParams = null;

            if (baseConstructor != null)
            {
                baseConstructorParams = baseConstructor.GetParameters();
            }

            if (baseConstructorParams != null && baseConstructorParams.Length != 0)
            {
                args = new ArgumentReference[fields.Length + baseConstructorParams.Length];

                var offset = fields.Length;
                for (var i = offset; i < offset + baseConstructorParams.Length; i++)
                {
                    var paramInfo = baseConstructorParams[i - offset];
                    args[i] = new ArgumentReference(paramInfo.ParameterType, paramInfo.DefaultValue);
                }
            }
            else
            {
                args = new ArgumentReference[fields.Length];
            }

            for (var i = 0; i < fields.Length; i++)
            {
                args[i] = new ArgumentReference(fields[i].Reference.FieldType);
            }

            var constructor = emitter.CreateConstructor(args);

            if (baseConstructorParams != null && baseConstructorParams.Length != 0)
            {
                var last = baseConstructorParams.Last();
                if (last.ParameterType.IsArray && last.IsDefined(typeof(ParamArrayAttribute)))
                {
                    var parameter = constructor.ConstructorBuilder.DefineParameter(args.Length, ParameterAttributes.None, last.Name);
                    var builder   = AttributeUtil.CreateBuilder <ParamArrayAttribute>();
                    parameter.SetCustomAttribute(builder);
                }
            }

            for (var i = 0; i < fields.Length; i++)
            {
                constructor.CodeBuilder.AddStatement(new AssignStatement(fields[i], args[i].ToExpression()));
            }

            // Invoke base constructor

            if (impl == ProxyConstructorImplementation.CallBase)
            {
                if (baseConstructor != null)
                {
                    Debug.Assert(baseConstructorParams != null);

                    var slice = new ArgumentReference[baseConstructorParams.Length];
                    Array.Copy(args, fields.Length, slice, 0, baseConstructorParams.Length);

                    constructor.CodeBuilder.InvokeBaseConstructor(baseConstructor, slice);
                }
                else
                {
                    constructor.CodeBuilder.InvokeBaseConstructor();
                }
            }

            constructor.CodeBuilder.AddStatement(new ReturnStatement());
        }
コード例 #6
0
 public InAssertSetContext(RepositorySharedContext context)
     : base(context)
 {
     Debug.Assert(!this.Context.InAssertSet);
     context.InAssertSet = true;
 }
コード例 #7
0
 public InArrangeArgMatchingContext(RepositorySharedContext context)
     : base(context)
 {
     Debug.Assert(!this.Context.InArrangeArgMatching);
     context.InArrangeArgMatching = true;
 }
コード例 #8
0
 public InArrangeContext(RepositorySharedContext context)
     : base(context)
 {
     Debug.Assert(!this.Context.InArrange);
     context.InArrange = true;
 }
コード例 #9
0
 public override void Dispose()
 {
     Debug.Assert(this.Context.RunClassConstructorCount >= 1);
     this.Context.RunClassConstructorCount--;
     Monitor.Exit(this.Context);
 }