protected object AssignIndexer(AssignmentExpression node, object value) { var exp = (IndexExpression)node.Left; var obj = exp.Target.Accept(this); if (obj == null) { ExecutionException.ThrowNullError(exp.Target, node); } var args = exp.Arguments.Map(arg => arg.Accept(this)).AddLast(value); if (exp.Setter is null) { var indexer = exp.Target.Type .FindSetIndexer(args, out ArgumentConversions conversions); if (indexer is null) { ExecutionException.ThrowMissingIndexer(exp.Target.Type, "set", exp.Target, node); } exp.Conversions = conversions; exp.Setter = indexer; // ok to be node.Right.Type instead of indexer.GetParameters().Last().ParameterType var valueBind = conversions[args.Length - 1]; node.Type = (valueBind == null) ? node.Right.Type : valueBind.Type; } exp.Conversions.Invoke(ref args); SafeInvoke(exp, exp.Setter, obj, args); return(value); }
private object Invoke(BinaryExpression node, string opName) { if (opName is null) { ExecutionException.ThrowInvalidOp(node); } var left = node.Left.Accept(this); var right = node.Right.Accept(this); return(Invoke(node, opName, left, right)); }
static void ResolveIndexer(IndexExpression node, object[] args) { System.Reflection.MethodInfo indexer; var type = node.Target.Type; indexer = type .FindGetIndexer(args, out ArgumentConversions conversions); if (indexer is null) { ExecutionException.ThrowMissingIndexer(type, "get", node); } node.Type = indexer.ReturnType; node.Conversions = conversions; node.Getter = indexer; }
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)); }
object IExpressionVisitor <object> .VisitIndex(IndexExpression node) { var obj = node.Target.Accept(this); if (obj is null) { ExecutionException.ThrowNullError(node); } var args = node.Arguments.Map(arg => arg.Accept(this)); if (node.Getter is null) { ResolveIndexer(node, args); } node.Conversions.Invoke(ref args); return(SafeInvoke(node, node.Getter, obj, args)); }
/// <summary> /// Safe compiler invoke for exceptions /// </summary> /// <param name="exp">Invoking expression</param> /// <param name="method">method to Invoke</param> /// <param name="target">method target</param> /// <param name="parmeters">parameters for invoke</param> /// <returns>result of invoke</returns> public static object SafeInvoke(Expression exp, System.Reflection.MethodBase method, object target, object[] parmeters) { try { return(method.Invoke(target, System.Reflection.BindingFlags.Default, null, parmeters, null)); } catch (System.Reflection.TargetInvocationException) { throw ExecutionException.ThrowInvalidOp(exp); } catch (ArgumentException ex) { throw ExecutionException.ThrowInvalidOp(exp, new NameExpression(ex.ParamName, ExpressionType.Identifier)); } catch (System.Reflection.TargetParameterCountException) { throw ExecutionException.ThrowArgumentMisMatch(exp); } }
/// <inheritdoc/> public object VisitConvert(ConvertExpression node) { var value = node.Target.Accept(this); if (node.Type is null) { var type = node.TypeName.ResolveType(TypeContext); if (!TypeUtils.AreReferenceAssignable(type, node.Target.Type)) { if (!node.Target.Type.TryImplicitConvert(type, out System.Reflection.MethodInfo method) && !node.Target.Type.TryExplicitConvert(type, out method)) { ExecutionException.ThrowInvalidCast(type, node); } node.Method = method; } node.Type = type; } return(value); }
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 MethodInfo Resolve(InvocationExpression node, string name, object obj, object[] args) { throw ExecutionException.ThrowMissingMethod(obj.GetType(), name, node); }
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); }
public virtual object VisitArrayLiteral(ArrayListExpression node) { Type type = node.ArrayType != null?node.ArrayType.ResolveType(TypeContext) : TypeProvider.AnyType; node.Type = typeof(Collections.List <>).MakeGenericType(type); node.ElementType = type; var items = node.Expressions; var length = items.Count; object[] args; if (node.Arguments != null) { args = node.Arguments.Map(arg => arg.Accept(this)); if (node.Constructor is null) { var methods = node.Type.GetConstructors(ReflectionUtils.PublicInstance); var ctor = ReflectionUtils.BindToMethod(methods, args, out ArgumentConversions conversions); if (ctor is null) { ExecutionException.ThrowMissingMethod(node.Type, ".ctor", node); } node.Constructor = ctor; node.ArgumentConversions = conversions; } node.ArgumentConversions.Invoke(ref args); } else { args = new object[1] { new Integer(length) }; if (node.Constructor is null) { node.Constructor = node.Type.GetConstructor(ReflectionUtils.PublicInstance, null, new Type[] { TypeProvider.IntType }, null); } } var array = (System.Collections.IList)node.Constructor.Invoke(System.Reflection.BindingFlags.Default, null, args, null); if (length > 0) { var arrayConversions = node.ArrayConversions ?? new ArgumentConversions(items.Count); for (int index = 0; index < length; index++) { Expression expression = items[index]; var value = expression.Accept(this); var conversion = arrayConversions[index]; if (conversion == null && !TypeUtils.AreReferenceAssignable(type, expression.Type) && expression.Type.TryImplicitConvert(type, out System.Reflection.MethodInfo implicitCall)) { conversion = new ParamConversion(index, implicitCall); arrayConversions.Append(index, conversion); } if (conversion != null && conversion.ConversionType == ConversionType.Normal) { value = conversion.Invoke(value); } array.Add(value); } node.ArrayConversions = arrayConversions; } return(array); }