public static bool TryGetDelegateMethod(Type type, Type[] args, out MethodInfo method, out ArgumentConversions conversions) { conversions = new ArgumentConversions(args.Length); method = type.GetMethod(InvokeMethod, PublicInstance); // only static method can allowed return(method.MatchesArgumentTypes(args, conversions)); }
public static MethodInfo FindSetIndexer(this System.Type type, System.Type[] args, out ArgumentConversions conversions) { conversions = new ArgumentConversions(args.Length); if (type.IsArray) { var m = type.GetMethod("Set", TypeUtils.PublicInstance); //for array no indexer we have to use Set Method if (m.MatchesArgumentTypes(args, conversions)) { return(m); } return(null); } foreach (var item in type.GetDefaultMembers()) { if (item.MemberType == MemberTypes.Property) { var p = (PropertyInfo)item; if (p.CanWrite) { var m = p.GetSetMethod(true); if (m.MatchesArgumentTypes(args, conversions)) { return(m); } } } } return(null); }
static void PrepareLogicalBoolean(int index, Type type, ArgumentConversions conversions) { if (type == TypeProvider.BooleanType) { return; } else if (type.IsPrimitive && type == typeof(bool)) { conversions.Append(index, new ParamConversion(index, TypeProvider.BooleanType.GetMethod(TypeUtils.ImplicitConversionName, TypeUtils.PublicStatic, null, new Type[1] { type }, null))); return; } else if (type.GetInterface(ReflectionUtils.ConvertibleType, false) != null) { if (type.IsValueType) { conversions.Append(index, new BoxConversion(index, type)); } conversions.Append(index, new ParamConversion(index, ReflectionHelpers.ToBoolean)); return; } var methods = type.GetMember(TypeUtils.ImplicitConversionName, System.Reflection.MemberTypes.Method, TypeUtils.PublicStatic); var types = new Type[] { type }; foreach (System.Reflection.MethodInfo method in methods) { if (method.MatchesArgumentTypes(types, conversions) && method.ReturnType == TypeProvider.BooleanType) { return; } } throw new Exception(string.Concat("can't convert from ", type, " to type Boolean")); }
static bool ParamArrayMatchs(Type[] types, int index, Type dest, ArgumentConversions conversions) { var binder = new ArgumentConversions(types.Length - index); // check first parameter type matches for (int i = 0, current = index; current < types.Length; i++, current++) { var src = types[current]; if (src is null) { if (dest.IsValueType && !dest.IsNullableType()) { return(false); } } else if (!TypeUtils.AreReferenceAssignable(dest, src)) { if (src.TryImplicitConvert(dest, out MethodInfo opImplict) == false) { return(false); } if (src.IsValueType && opImplict.GetParameters()[0].ParameterType.IsValueType == false) { binder.Add(new BoxConversion(i, src)); } binder.Add(new ParamConversion(i, opImplict)); } else if (src.IsValueType && dest.IsValueType == false) { conversions.Add(new BoxConversion(i, src)); } } conversions.Add(new ParamArrayConversion(index, dest, binder)); return(true); }
/// <inheritdoc/> Expression IExpressionVisitor <Expression> .VisitBinary(BinaryExpression node) { //todo like rutime compiler var left = node.Left.Accept(this); var right = node.Right.Accept(this); ArgumentConversions conversions = new ArgumentConversions(2); System.Reflection.MethodInfo method; switch (node.NodeType) { case ExpressionType.Plus: method = VisitAddition(left, right, conversions); break; case ExpressionType.AndAnd: case ExpressionType.OrOr: PrepareLogicalBoolean(0, left.Type, conversions); PrepareLogicalBoolean(1, right.Type, conversions); method = node.NodeType == ExpressionType.AndAnd ? ReflectionHelpers.LogicalAnd : ReflectionHelpers.LogicalOr; break; case ExpressionType.StarStar: method = VisitPow(node, left, right, conversions); break; default: method = VisitBinary(left, right, node.MethodName, conversions); break; } node.Conversions = conversions; node.Method = method ?? throw new OperationCanceledException(string.Concat("Invalid Operation ", node.ToString())); node.Type = method.ReturnType; return(node); }
internal static bool TryGetDelegateMethod(object obj, object[] args, out MethodInfo method, out ArgumentConversions conversions) { conversions = new ArgumentConversions(args.Length); method = obj.GetType().GetMethod(InvokeMethod, PublicInstance); // only static method can allowed return(method.MatchesArguments(args, conversions)); }
public static TMethod BindToMethod <TMethod>(TMethod[] methods, Type[] types, out ArgumentConversions bindings) where TMethod : MethodBase { bindings = new ArgumentConversions(types.Length); foreach (var m in methods) { if (m.MatchesArgumentTypes(types, bindings)) { return(m); } } return(null); }
public static TMethod BindToMethod <TMethod>(TMethod[] methods, object[] args, out ArgumentConversions conversions) where TMethod : MethodBase { conversions = new ArgumentConversions(args.Length); foreach (var m in methods) { if (m.MatchesArguments(args, conversions)) { return(m); } } return(null); }
public void EmitArguments(INodeList <Expression> arguments, ArgumentConversions conversions) { if (arguments.Count > 0) { for (int i = 0; i < arguments.Count; i++) { var arg = arguments[i]; var conv = conversions[i]; if (conv != null) { if (conv.ConversionType == ConversionType.Normal) { arg.GenerateCode(this, Expression.AssignOption); EmitConvert(conv); } else if (conv.ConversionType == ConversionType.ParamArray) { var args = new Expression[arguments.Count - i]; arguments.CopyTo(args, conv.Index); EmitConvert((ParamArrayConversion)conv, args); break; } } else { arg.GenerateCode(this, Expression.AssignOption); } } } // remaing Conversions like optional or param array if (arguments.Count < conversions.Count) { for (var i = arguments.Count; i < conversions.Count; i++) { Conversion conv = conversions[i]; if (conv.ConversionType == ConversionType.Normal) { arguments[i].GenerateCode(this, Expression.AssignOption); EmitConvert(conv); } else if (conv.ConversionType == ConversionType.ParamArray) { // remaining arguments var args = new Expression[arguments.Count - i]; arguments.CopyTo(args, conv.Index); EmitConvert((ParamArrayConversion)conv, args); break; } } } }
public static MethodInfo GetOperatorOverload(string name, ArgumentConversions conversions, params Type[] types) { for (int i = 0; i < types.Length; i++) { var members = types[i].GetMember(name, PublicStatic); foreach (MethodInfo m in members) { if (MethodExtensions.MatchesArgumentTypes(m, types, conversions)) { return(m); } } } return(null); }
public static MethodInfo BindToMethod(MemberInfo[] members, Type[] types, out ArgumentConversions bindings) { bindings = new ArgumentConversions(types.Length); foreach (var m in members) { if (m.MemberType == MemberTypes.Method) { if (MethodExtensions.MatchesArgumentTypes((MethodInfo)m, types, bindings)) { return((MethodInfo)m); } } } return(null); }
public static MethodInfo BindToMethod(MemberInfo[] members, object[] args, out ArgumentConversions conversions) { conversions = new ArgumentConversions(args.Length); foreach (var m in members) { if (m.MemberType == MemberTypes.Method) { if (ReflectionExtensions.MatchesArguments((MethodInfo)m, args, conversions)) { return((MethodInfo)m); } } } return(null); }
/// <inheritdoc/> Expression IExpressionVisitor <Expression> .VisitArrayLiteral(ArrayListExpression node) { var type = node.ArrayType != null?node.ArrayType.ResolveType(Context) : TypeProvider.AnyType; node.Type = typeof(Collections.List <>).MakeGenericType(type); node.ElementType = type; if (node.Arguments != null) { var types = node.Arguments.Map(arg => arg.Accept(this).Type); if (node.Constructor == null) { var ctors = node.Type.GetConstructors(ReflectionUtils.PublicInstance); var ctor = ReflectionUtils.BindToMethod(ctors, types, out ArgumentConversions conversions); if (ctor == null) { ExecutionException.ThrowMissingMethod(node.Type, "ctor", node); } node.Constructor = ctor; node.ArgumentConversions = conversions; } } else if (node.Constructor == null) { node.Constructor = node.Type.GetConstructor(ReflectionUtils.PublicInstance, null, new Type[0], null); } var items = node.Expressions; if (items.Count > 0) { var arrayConversions = new ArgumentConversions(items.Count); for (int index = 0; index < items.Count; index++) { var expression = items[index].Accept(this); if (!TypeUtils.AreReferenceAssignable(type, expression.Type) && expression.Type.TryImplicitConvert(type, out System.Reflection.MethodInfo implicitCall)) { if (expression.Type.IsValueType && implicitCall.GetParameters()[0].ParameterType == TypeProvider.ObjectType) { arrayConversions.Append(index, new BoxConversion(index, expression.Type)); } arrayConversions.Append(index, new ParamConversion(index, implicitCall)); } } node.ArrayConversions = arrayConversions; } return(node); }
static object Invoke(BinaryExpression node, string opName, object left, object right) { if (left is null) { ExecutionException.ThrowNullError(node.Left, node); } if (right is null) { ExecutionException.ThrowNullError(node.Right, node); } if (node.Method is null) { var leftType = left.GetType(); var rightType = right.GetType(); var types = new Type[2] { leftType, rightType }; ArgumentConversions conversions = new ArgumentConversions(2); System.Reflection.MethodInfo method; if (leftType.IsPrimitive || rightType.IsPrimitive) { var initial = (ReflectionUtils.FromSystemType(ref types)); method = ReflectionUtils. GetOperatorOverload(opName, conversions, types); conversions.SetInitial(initial); } else { method = ReflectionUtils. GetOperatorOverload(opName, conversions, types); } if (method is null) { ExecutionException.ThrowInvalidOp(node); } node.Method = method; node.Type = method.ReturnType; node.Conversions = conversions; } object[] args = new object[2] { left, right }; node.Conversions.Invoke(ref args); // operator overload invoke return(node.Method.Invoke(null, System.Reflection.BindingFlags.Default, null, args, null)); }
/// <inheritdoc/> Expression IExpressionVisitor <Expression> .VisitUnary(UnaryExpression node) { var operand = node.Operand.Accept(this); if (node.NodeType == ExpressionType.Parenthesized) { node.Type = operand.Type; return(operand); } ArgumentConversions conversions = new ArgumentConversions(2); var method = ReflectionUtils.GetOperatorOverload(node.MethodName, conversions, operand.Type); node.Conversions = conversions; node.Method = method; node.Type = method.ReturnType; return(node); }
private object VisitCompare(BinaryExpression node, string opName) { var left = node.Left.Accept(this); var right = node.Right.Accept(this); if (left is null || right is null) { return(NullCompare(node, left, right)); } if (node.Method is null) { var leftType = left.GetType(); var rightType = right.GetType(); var types = new Type[2] { leftType, rightType }; ArgumentConversions conversions = new ArgumentConversions(2); System.Reflection.MethodInfo method; if (leftType.IsPrimitive || rightType.IsPrimitive) { var initial = ReflectionUtils.FromSystemType(ref types); method = ReflectionUtils. GetOperatorOverload(opName, conversions, types); conversions.SetInitial(initial); } else { method = ReflectionUtils. GetOperatorOverload(opName, conversions, types); } if (method is null) { return(NullCompare(node, left, right)); } node.Method = method; node.Conversions = conversions; node.Type = method.ReturnType; } // null method handled object[] args = new object[2] { left, right }; node.Conversions.Invoke(ref args); return(node.Method.Invoke(null, args)); }
public static MethodInfo FindMethod(this System.Type type, string name, System.Type[] types, BindingFlags bindingAttr, out ArgumentConversions conversions) { conversions = new ArgumentConversions(types.Length); if (type.IsDefined(typeof(RegisterAttribute), false)) { var methods = type.GetMethods(bindingAttr); for (int i = 0; i < methods.Length; i++) { var m = methods[i]; var attrs = (System.Attribute[])m.GetCustomAttributes(typeof(RegisterAttribute), false); if (attrs.Length > 0 && attrs[0].Match(name) && m.MatchesArgumentTypes(types, conversions)) { return(m); } } return(null); } return(FindSystemMethod(type, name, types, bindingAttr, conversions)); }
private object VisitExponentiation(BinaryExpression node) { var left = node.Left.Accept(this); var right = node.Right.Accept(this); if (left is null) { ExecutionException.ThrowNullError(node, node.Left); } if (right is null) { ExecutionException.ThrowNullError(node, node.Right); } object[] args = new object[2] { left, right }; if (node.Method is null) { Type leftType = left.GetType(); Type rightType = right.GetType(); var types = new Type[] { leftType, rightType }; var conversions = new ArgumentConversions(2); if (leftType.IsPrimitive || rightType.IsPrimitive) { conversions.SetInitial(ReflectionUtils.FromSystemType(ref types)); } if (!ReflectionHelpers.MathPow.MatchesArgumentTypes(types, conversions)) { ExecutionException.ThrowArgumentMisMatch(node); } node.Conversions = conversions; node.Method = ReflectionHelpers.MathPow; node.Type = TypeProvider.DoubleType; } node.Conversions.Invoke(ref args); return(node.Method.Invoke(null, args)); }
public static bool MatchesArgumentTypes(this MethodBase method, Type[] types, ArgumentConversions conversions) { var parameters = method.GetParameters(); var length = types.Length; if (parameters.Length < length) { return(false); } int i; for (i = 0; i < parameters.Length; i++) { var param = parameters[i]; var dest = param.ParameterType; if (param.IsDefined(typeof(ParamArrayAttribute), false)) { // parameters is extra example print(string, params string[] args) and print('hello') // in this case 2 and 1 if (parameters.Length > length) { conversions.Add(new ParamArrayConversion(i, dest.GetElementType())); return(true); } //No further check required if matchs return(ParamArrayMatchs(types, i, dest.GetElementType(), conversions)); } // matches current index if (i >= length) { return(conversions.Recycle()); } var src = types[i]; if (src is null) { if (dest.IsValueType && !dest.IsNullableType()) { return(conversions.Recycle()); } } else if (!TypeUtils.AreReferenceAssignable(dest, src)) { if (src.TryImplicitConvert(dest, out MethodInfo m) == false) { return(conversions.Recycle()); } if (src.IsValueType && m.GetParameters()[0].ParameterType.IsValueType == false) { conversions.Add(new BoxConversion(i, src)); } conversions.Add(new ParamConversion(i, m)); } if (src.IsValueType && dest.IsValueType == false) { conversions.Add(new BoxConversion(i, src)); } } if (i == length) { return(true); } return(conversions.Recycle()); }
public object VisitUnary(UnaryExpression node) { var value = node.Operand.Accept(this); if (node.NodeType == ExpressionType.Parenthesized) { node.Type = node.Operand.Type; return(value); } //modified a++; updated new value bool modified = false, updated = true; switch (node.NodeType) { case ExpressionType.PostfixPlusPlus: modified = true; updated = false; break; case ExpressionType.PrefixPlusPlus: modified = true; break; case ExpressionType.PostfixMinusMinus: modified = true; updated = false; break; case ExpressionType.PrefixMinusMinus: modified = true; break; case ExpressionType.Bang: // here value is null it is as not defined if (value is null) { return(Boolean.True); } break; } if (value is null) { ExecutionException.ThrowNullError(node.Operand, node); } // no primitive supported it should be wrapped //resolve call if (node.Method is null) { Type type = node.Operand.Type; ArgumentConversions conversions = new ArgumentConversions(1); System.Reflection.MethodInfo method; if (type.IsPrimitive) { type = TypeProvider.Find(Type.GetTypeCode(type)); method = ReflectionUtils.GetOperatorOverload(node.MethodName, conversions, type); conversions.AddFirst(new ParamConversion(0, ReflectionHelpers.ToAny)); } else { method = ReflectionUtils.GetOperatorOverload(node.MethodName, conversions, type); } if (method is null) { ExecutionException.ThrowInvalidOp(node); } node.Conversions = conversions; node.Method = method; node.Type = method.ReturnType; } object[] args = new object[1] { value }; node.Conversions.Invoke(ref args); object obj = node.Method.Invoke(null, args); if (modified) { if (node.Operand.NodeType == ExpressionType.Literal) { ExecutionException.ThrowNotSupported(node); } var exp = new AssignmentExpression(node.Operand, new LiteralExpression(obj)); exp.Accept(this); } return(updated ? obj : value); }
static System.Reflection.MethodInfo VisitAddition(Expression left, Expression right, ArgumentConversions conversions) { if (left.Type.Name.Equals(TypeProvider.String)) { if (right.Type.Name.Equals(TypeProvider.String)) { return(VisitBinary(left, right, Operators.Addition, conversions)); } if (right.Type.IsValueType) { conversions.Add(new BoxConversion(1, right.Type)); } conversions.Add(new ParamConversion(1, ReflectionHelpers.AnyToString)); right.Type = TypeProvider.StringType; return(VisitBinary(left, right, Operators.Addition, conversions)); } if (right.Type.Name.Equals(TypeProvider.String)) { if (left.Type.Name.Equals(TypeProvider.String)) { return(VisitBinary(left, right, Operators.Addition, conversions)); } if (right.Type.IsValueType) { conversions.Add(new BoxConversion(1, left.Type)); } conversions.Add(new ParamConversion(0, ReflectionHelpers.AnyToString)); left.Type = TypeProvider.StringType; return(VisitBinary(left, right, Operators.Addition, conversions)); } return(VisitBinary(left, right, Operators.Addition, conversions)); }
static System.Reflection.MethodInfo VisitPow(BinaryExpression node, Expression left, Expression right, ArgumentConversions conversions) { var types = new Type[2] { left.Type, right.Type }; System.Reflection.MethodInfo method = ReflectionHelpers.MathPow; if (left.Type.IsPrimitive || right.Type.IsPrimitive) { var initial = ReflectionUtils.FromSystemType(ref types); if (!method.MatchesArgumentTypes(types, conversions)) { ExecutionException.ThrowArgumentMisMatch(node); } conversions.SetInitial(initial); return(method); } if (!method.MatchesArgumentTypes(types, conversions)) { ExecutionException.ThrowArgumentMisMatch(node); } return(method); }
static System.Reflection.MethodInfo VisitBinary(Expression left, Expression right, string opName, ArgumentConversions conversions) { var types = new Type[2] { left.Type, right.Type }; System.Reflection.MethodInfo methodInfo; if (left.Type.IsPrimitive || right.Type.IsPrimitive) { Conversion[] initial = ReflectionUtils.FromSystemType(ref types); methodInfo = ReflectionUtils. GetOperatorOverload(opName, conversions, types); // add initial conversion conversions.SetInitial(initial); } else { methodInfo = ReflectionUtils. GetOperatorOverload(opName, conversions, types); } return(methodInfo); }
public static MethodInfo FindSystemMethod(this System.Type type, string name, System.Type[] types, BindingFlags bindingAttr, ArgumentConversions conversions) { var members = type.GetMember(name, MemberTypes.Method, bindingAttr); // start from last ex: in Console.Write(String) no match at the beginning for (int i = members.Length - 1; i >= 0; i--) { MethodInfo m = (MethodInfo)members[i]; if (m.MatchesArgumentTypes(types, conversions)) { return(m); } } return(null); }