Beispiel #1
0
        protected override Expression VisitMember(MemberExpression node)
        {
            PropertyInfo property = node.Member as PropertyInfo;
            MethodInfo   getter;

            // We handle only properties (that aren't indexers) that have
            // a get
            if (property != null && property.GetIndexParameters().Length == 0 && (getter = property.GetGetMethod(true)) != null)
            {
                // We work only on methods marked as [ExpandableAttribute]
                var attribute = property.GetCustomAttributes(typeof(ExpandableAttribute), false).FirstOrDefault();
                if (attribute != null)
                {
                    string name      = property.Name + ExpandableAttribute.ExpandableSuffix;
                    var    property2 = property.DeclaringType.GetProperty(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, null, Type.EmptyTypes, null);
                    if (property2 == null || property2.GetGetMethod(true) == null)
                    {
                        if (property2 == null)
                        {
                            if (property.DeclaringType.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, null, Type.EmptyTypes, null) != null)
                            {
                                throw new NotSupportedException(string.Format("{0}.{1} isn't static!", property.DeclaringType.FullName, name));
                            }
                            throw new NotSupportedException(string.Format("{0}.{1} not found!", property.DeclaringType.FullName, name));
                        }
                        // property2.GetGetMethod(true) == null
                        throw new NotSupportedException(string.Format("{0}.{1} doesn't have a getter!", property.DeclaringType.FullName, name));
                    }
                    // Instance Parameters have the additional
                    // "parameter" of the declaring type
                    var argumentsPlusReturnTypes = getter.IsStatic ?
                                                   new[] { node.Type } :
                    new[] { property.DeclaringType, node.Type };
                    var funcType   = typeof(Func <>).Assembly.GetType(string.Format("System.Func`{0}", argumentsPlusReturnTypes.Length));
                    var returnType = typeof(Expression <>).MakeGenericType(funcType.MakeGenericType(argumentsPlusReturnTypes));
                    if (property2.PropertyType != returnType)
                    {
                        throw new NotSupportedException(string.Format("{0}.{1} has wrong return type!", property.DeclaringType.FullName, name));
                    }
                    var expression = (LambdaExpression)property2.GetValue(null, null);
                    // Instance Members have the additional "parameter"
                    // of the declaring type
                    var arguments2 = getter.IsStatic ? new Expression[0] : new[] { node.Expression };
                    var replacer   = new SimpleExpressionReplacer(expression.Parameters, arguments2);
                    var body       = replacer.Visit(expression.Body);
                    return(this.Visit(body));
                }
            }
            return(base.VisitMember(node));
        }
Beispiel #2
0
        protected override Expression VisitMethodCall(MethodCallExpression node)
        {
            MethodInfo method = node.Method;
            // We work only on methods marked as [ExpandableAttribute]
            var attribute = method.GetCustomAttributes(typeof(ExpandableAttribute), false).FirstOrDefault();

            if (attribute != null)
            {
                string name    = method.Name + ExpandableAttribute.ExpandableSuffix;
                var    method2 = method.DeclaringType.GetMethod(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
                if (method2 == null)
                {
                    if (method.DeclaringType.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null) != null)
                    {
                        throw new NotSupportedException(string.Format("{0}.{1} isn't static!", method.DeclaringType.FullName, name));
                    }
                    throw new NotSupportedException(string.Format("{0}.{1} not found!", method.DeclaringType.FullName, name));
                }
                // Instance methods have the additional "parameter" of
                // the declaring type
                var argumentsPlusReturnTypes = method.IsStatic ?
                                               node.Arguments.Select(x => x.Type).Concat(new[] { node.Type }).ToArray() :
                                               new[] { method.DeclaringType }.Concat(node.Arguments.Select(x => x.Type)).Concat(new[] { node.Type }).ToArray();
                var funcType   = typeof(Func <>).Assembly.GetType(string.Format("System.Func`{0}", argumentsPlusReturnTypes.Length));
                var returnType = typeof(Expression <>).MakeGenericType(funcType.MakeGenericType(argumentsPlusReturnTypes));
                if (method2.ReturnType != returnType)
                {
                    throw new NotSupportedException(string.Format("{0}.{1} has wrong return type!", method.DeclaringType.FullName, name));
                }
                var expression = (LambdaExpression)method2.Invoke(null, null);
                // Instance methods have the additional "parameter" of
                // the declaring type
                var arguments2 = method.IsStatic ? node.Arguments : new[] { node.Object }.Concat(node.Arguments);
                var replacer = new SimpleExpressionReplacer(expression.Parameters, arguments2);
                var body     = replacer.Visit(expression.Body);
                return(this.Visit(body));
            }
            return(base.VisitMethodCall(node));
        }