public override void SetValue(Bindings bindings, ELContext context, object value) { if (!lvalue) { throw new ELException(LocalMessages.Get("error.value.set.rvalue", GetStructuralId(bindings))); } object @base = prefix.Eval(bindings, context); if (@base == null) { throw new PropertyNotFoundException(LocalMessages.Get("error.property.base.null", prefix)); } object property = GetProperty(bindings, context); if (property == null && strict) { throw new PropertyNotFoundException(LocalMessages.Get("error.property.property.notfound", "null", @base)); } context.PropertyResolved = false; context.ELResolver.SetValue(context, @base, property, value); if (!context.PropertyResolved) { throw new PropertyNotFoundException(LocalMessages.Get("error.property.property.notfound", property, @base)); } }
public override Type GetType(Bindings bindings, ELContext context) { if (!lvalue) { return(null); } object @base = prefix.Eval(bindings, context); if (@base == null) { throw new PropertyNotFoundException(LocalMessages.Get("error.property.base.null", prefix)); } object property = GetProperty(bindings, context); if (property == null && strict) { throw new PropertyNotFoundException(LocalMessages.Get("error.property.property.notfound", "null", @base)); } context.PropertyResolved = false; Type result = context.ELResolver.GetType(context, @base, property); if (!context.PropertyResolved) { throw new PropertyNotFoundException(LocalMessages.Get("error.property.property.notfound", property, @base)); } return(result); }
/// <summary> /// Create a new method expression. /// The expression must be an lvalue expression or literal text. /// The expected return type may be <code>null</code>, meaning "don't care". /// If it is an lvalue expression, the parameter types must not be <code>null</code>. /// If it is literal text, the expected return type must not be <code>void</code>. </summary> /// <param name="store"> used to get the parse tree from. </param> /// <param name="functions"> the function mapper used to bind functions </param> /// <param name="variables"> the variable mapper used to bind variables </param> /// <param name="expr"> the expression string </param> /// <param name="returnType"> the expected return type (may be <code>null</code>) </param> /// <param name="paramTypes"> the expected parameter types (must not be <code>null</code> for lvalues) </param> public TreeMethodExpression(TreeStore store, FunctionMapper functions, VariableMapper variables, ITypeConverter converter, string expr, Type returnType, Type[] paramTypes) : base() { Tree tree = store.Get(expr); this.builder = store.Builder; this.bindings = tree.Bind(functions, variables, converter); this.expr = expr; this.type = returnType; this.types = paramTypes; this.node = tree.Root; this.deferred = tree.Deferred; if (node.LiteralText) { if (returnType == typeof(void)) { throw new ELException(LocalMessages.Get("error.method.literal.void", expr)); } } else if (!node.MethodInvocation) { if (!node.LeftValue) { throw new ELException(LocalMessages.Get("error.method.invalid", expr)); } if (paramTypes == null) { throw new ELException(LocalMessages.Get("error.method.notypes")); } } }
private static bool Gt0(ITypeConverter converter, object o1, object o2) { Type t1 = o1.GetType(); Type t2 = o2.GetType(); if (t1.IsSubclassOf(typeof(decimal)) || t2.IsSubclassOf(typeof(decimal))) { return(converter.Convert <decimal>(o1, typeof(decimal)).CompareTo(converter.Convert <decimal>(o2, typeof(decimal))) > 0); } if (SIMPLE_FLOAT_TYPES.Contains(t1) || SIMPLE_FLOAT_TYPES.Contains(t2)) { return(converter.Convert <double>(o1, typeof(double)) > converter.Convert <double>(o2, typeof(double))); } if (SIMPLE_INTEGER_TYPES.Contains(t1) || SIMPLE_INTEGER_TYPES.Contains(t2)) { return(converter.Convert <long>(o1, typeof(long)) > converter.Convert <long>(o2, typeof(long))); } if (t1 == typeof(string) || t2 == typeof(string)) { return(converter.Convert <string>(o1, typeof(string)).CompareTo(converter.Convert <string>(o2, typeof(string))) > 0); } if (o1 is IComparable) { return(((IComparable)o1).CompareTo(o2) > 0); } if (o2 is IComparable) { return(((IComparable)o2).CompareTo(o1) < 0); } throw new ELException(LocalMessages.Get("error.compare.types", o1.GetType(), o2.GetType())); }
protected internal virtual long?CoerceToLong(object value) { if (value == null || "".Equals(value)) { return(System.Convert.ToInt64(0L)); } if (value is long?) { return((long?)value); } if (value is decimal @decimal) { return(System.Convert.ToInt64(@decimal)); } if (value is int i) { return(System.Convert.ToInt64(i)); } if (value is string s) { try { return(System.Convert.ToInt64(s)); } catch (System.FormatException) { throw new ELException(LocalMessages.Get("error.coerce.value {0} {1}", s, typeof(long))); } } if (value is char?) { return(System.Convert.ToInt64((short)((char?)value).Value)); } throw new ELException(LocalMessages.Get("error.coerce.type {0} {1}", value.GetType(), typeof(long))); }
/// <summary> /// Create a bindings. </summary> /// <param name="fnMapper"> the function mapper to use </param> /// <param name="varMapper"> the variable mapper to use </param> /// <param name="converter"> custom type converter </param> /// <returns> tree bindings </returns> public virtual Bindings Bind(FunctionMapper fnMapper, VariableMapper varMapper, ITypeConverter converter) { MethodInfo[] methods = null; if (functions.Count > 0) { if (fnMapper == null) { throw new ELException(LocalMessages.Get("error.function.nomapper")); } methods = new MethodInfo[functions.Count]; foreach (IFunctionNode node in functions) { string image = node.Name; MethodInfo method = null; int colon = image.IndexOf(':'); if (colon < 0) { method = fnMapper.ResolveFunction("", image); } else { method = fnMapper.ResolveFunction(image.Substring(0, colon), image.Substring(colon + 1)); } if (method == null) { throw new ELException(LocalMessages.Get("{0} error.function.notfound", image)); } //if (node.VarArgs && method.VarArgs) //{ // if (method.ParameterTypes.length > node.ParamCount + 1) // { // throw new ELException(LocalMessages.Get("error.function.params", image)); // } //} //else //{ // if (method.ParameterTypes.length != node.ParamCount) // { // throw new ELException(LocalMessages.Get("error.function.params", image)); // } //} methods[node.Index] = method; } } ValueExpression[] expressions = null; if (identifiers.Count > 0) { expressions = new ValueExpression[identifiers.Count]; foreach (IIdentifierNode node in identifiers) { ValueExpression expression = null; if (varMapper != null) { expression = varMapper.ResolveVariable(node.Name); } expressions[node.Index] = expression; } } return(new Bindings(methods, expressions, converter)); }
protected internal virtual sbyte?CoerceToByte(object value) { if (value == null || "".Equals(value)) { return(System.Convert.ToSByte((sbyte)0)); } if (value is sbyte?) { return((sbyte?)value); } if (value is decimal @decimal) { return(System.Convert.ToSByte(@decimal)); } if (value is string s) { try { return(System.Convert.ToSByte(s)); } catch (System.FormatException) { throw new ELException(LocalMessages.Get("error.coerce.value {0} {1}", s, typeof(Byte))); } } if (value is char?) { return(System.Convert.ToSByte(System.Convert.ToInt16((short)((char?)value).Value))); } throw new ELException(LocalMessages.Get("error.coerce.type {0} {1}", value.GetType(), typeof(Byte))); }
protected internal virtual object CoerceToType(object value, Type type) { if (type == typeof(string)) { return(CoerceToString(value)); } if (type == typeof(long) || type == typeof(long)) { return(CoerceToLong(value)); } if (type == typeof(Double) || type == typeof(double)) { return(CoerceToDouble(value)); } if (type == typeof(Boolean) || type == typeof(bool)) { return(CoerceToBoolean(value)); } if (type == typeof(int) || type == typeof(int)) { return(CoerceToInteger(value)); } if (type == typeof(float) || type == typeof(float)) { return(CoerceToFloat(value)); } if (type == typeof(short) || type == typeof(short)) { return(CoerceToShort(value)); } if (type == typeof(Byte) || type == typeof(sbyte)) { return(CoerceToByte(value)); } if (type == typeof(char) || type == typeof(char)) { return(CoerceToCharacter(value)); } if (type == typeof(decimal)) { return(CoerceToBigDecimal(value)); } if (type == typeof(Int64)) { return(CoerceToBigInteger(value)); } if (type.BaseType == typeof(Enum)) { return(CoerceToEnum <object>(value, type)); } if (value == null || value.GetType() == type || type.IsInstanceOfType(value)) { return(value); } if (value is string) { return(CoerceStringToType((string)value, type)); } throw new ELException(LocalMessages.Get("error.coerce.type {0} {1}", value.GetType(), type)); }
protected internal virtual decimal CoerceToBigDecimal(object value) { if (value == null || "".Equals(value)) { return(0L); } if (value is decimal @decimal) { return(@decimal); } if (value is long l) { return(new decimal(l)); } if (value is string) { try { return(decimal.Parse(value.ToString())); } catch (System.FormatException) { throw new ELException(LocalMessages.Get("error.coerce.value {0} {1}", value, typeof(decimal))); } } if (value is char?) { return(new decimal((short)((char?)value).Value)); } throw new ELException(LocalMessages.Get("error.coerce.type {0} {1}", value.GetType(), typeof(decimal))); }
protected internal virtual Int64 CoerceToBigInteger(object value) { if (value == null || "".Equals(value)) { return(0L); } if (value is long l) { return(l); } if (value is decimal) { return(System.Convert.ToInt64(value)); } if (value is string s) { try { return(long.Parse(s)); } catch (System.FormatException) { throw new ELException(LocalMessages.Get("error.coerce.value {0} {1}", s, typeof(Int64))); } } if (value is char?) { return((short)((char?)value).Value); } throw new ELException(LocalMessages.Get("error.coerce.type {0} {1}", value.GetType(), typeof(Int64))); }
public override object Invoke(Bindings bindings, ELContext context, Type returnType, Type[] paramTypes, object[] paramValues) { object @base = prefix.Eval(bindings, context); if (@base == null) { throw new PropertyNotFoundException(LocalMessages.Get("error.property.base.null", prefix)); } object property = GetProperty(bindings, context); if (property == null && strict) { throw new PropertyNotFoundException(LocalMessages.Get("error.property.method.notfound", "null", @base)); } string name = bindings.Convert <string>(property, typeof(string)); MethodInfo method = FindMethod(name, @base.GetType(), returnType, paramTypes); try { return(method.Invoke(@base, paramValues)); } catch (AccessViolationException) { throw new ELException(LocalMessages.Get("error.property.method.access", name, @base.GetType())); } catch (System.ArgumentException e) { throw new ELException(LocalMessages.Get("error.property.method.invocation", name, @base.GetType()), e); } catch (TargetInvocationException e) { throw new ELException(LocalMessages.Get("error.property.method.invocation", name, @base.GetType()), e.InnerException); } }
public override object Invoke(Bindings bindings, ELContext context, Type returnType, Type[] paramTypes, object[] paramValues) { object @base = property.Prefix.Eval(bindings, context); if (@base == null) { throw new PropertyNotFoundException(LocalMessages.Get("error.property.base.null", property.Prefix)); } object method = property.GetProperty(bindings, context); if (method == null) { throw new PropertyNotFoundException(LocalMessages.Get("error.property.method.notfound", "null", @base)); } string name = bindings.Convert <string>(method, typeof(string)); paramValues = (object[])@params.Eval(bindings, context); context.PropertyResolved = false; object result = context.ELResolver.Invoke(context, @base, name, paramTypes, paramValues); if (!context.PropertyResolved) { throw new MethodNotFoundException(LocalMessages.Get("error.property.method.notfound", name, @base.GetType())); } // if (returnType != null && !returnType.isInstance(result)) { // should we check returnType for method invocations? // throw new MethodNotFoundException(LocalMessages.get("error.property.method.notfound", name, base.getClass())); // } return(result); }
public override void SetValue(Bindings bindings, ELContext context, object value) { ValueExpression expression = bindings.GetVariable(index); if (expression != null) { expression.SetValue(context, value); return; } context.PropertyResolved = false; context.ELResolver.SetValue(context, null, name, value); if (!context.PropertyResolved) { throw new PropertyNotFoundException(LocalMessages.Get("error.identifier.property.notfound", name)); } }
/// <summary> /// Create a new value expression. </summary> /// <param name="store"> used to get the parse tree from. </param> /// <param name="functions"> the function mapper used to bind functions </param> /// <param name="variables"> the variable mapper used to bind variables </param> /// <param name="expr"> the expression string </param> /// <param name="type"> the expected type (may be <code>null</code>) </param> public TreeValueExpression(TreeStore store, FunctionMapper functions, VariableMapper variables, ITypeConverter converter, string expr, Type type) : base() { Tree tree = store.Get(expr); this.builder = store.Builder; this.bindings = tree.Bind(functions, variables, converter); this.expr = expr; this.type = type; this.node = tree.Root; this.deferred = tree.Deferred; if (type == null) { throw new System.NullReferenceException(LocalMessages.Get("error.value.notype")); } }
protected internal virtual bool?CoerceToBoolean(object value) { if (value == null || "".Equals(value)) { return(false); } if (value is bool?) { return((bool?)value); } if (value is string s) { return(System.Convert.ToBoolean(s)); } throw new ELException(LocalMessages.Get("error.coerce.type {0} {1}", value.GetType(), typeof(Boolean))); }
public override bool IsReadOnly(Bindings bindings, ELContext context) { ValueExpression expression = bindings.GetVariable(index); if (expression != null) { return(expression.IsReadOnly(context)); } context.PropertyResolved = false; bool result = context.ELResolver.IsReadOnly(context, null, name); if (!context.PropertyResolved) { throw new PropertyNotFoundException(LocalMessages.Get("error.identifier.property.notfound", name)); } return(result); }
public override object Eval(Bindings bindings, ELContext context) { ValueExpression expression = bindings.GetVariable(index); if (expression != null) { return(expression.GetValue(context)); } context.PropertyResolved = false; object result = context.ELResolver.GetValue(context, null, name); if (!context.PropertyResolved) { throw new PropertyNotFoundException(LocalMessages.Get(string.Format("error.identifier.property.notfound:{0}", name))); } return(result); }
public override object Eval(Bindings bindings, ELContext context) { MethodInfo method = bindings.GetFunction(index); try { return(Invoke(bindings, context, null, method)); } catch (AccessViolationException e) { throw new ELException(LocalMessages.Get("error.function.access", name), e); } catch (TargetInvocationException e) { throw new ELException(LocalMessages.Get("error.function.invocation", name), e.InnerException); } }
protected internal virtual MethodInfo FindMethod(string name, Type clazz, Type returnType, Type[] paramTypes) { MethodInfo method = null; try { method = clazz.GetMethod(name, paramTypes); } catch (MethodNotFoundException) { throw new MethodNotFoundException(LocalMessages.Get("error.property.method.notfound", name, clazz)); } if (returnType != null && !returnType.IsAssignableFrom(method.ReturnType)) { throw new MethodNotFoundException(LocalMessages.Get("error.property.method.notfound", name, clazz)); } return(method); }
public override MethodInfo GetMethodInfo(Bindings bindings, ELContext context, Type returnType, Type[] paramTypes) { object @base = prefix.Eval(bindings, context); if (@base == null) { throw new PropertyNotFoundException(LocalMessages.Get("error.property.base.null", prefix)); } object property = GetProperty(bindings, context); if (property == null && strict) { throw new PropertyNotFoundException(LocalMessages.Get("error.property.method.notfound", "null", @base)); } string name = bindings.Convert <string>(property, typeof(string)); MethodInfo method = FindMethod(name, @base.GetType(), returnType, paramTypes); //return new MethodInfo(method.Name, method.ReturnType, paramTypes); return(method); }
protected internal virtual char?CoerceToCharacter(object value) { if (value == null || "".Equals(value)) { return(System.Convert.ToChar((char)0)); } if (value is char?) { return((char?)value); } if (value is decimal c) { return(System.Convert.ToChar((char)c)); } if (value is string s) { return(System.Convert.ToChar(s[0])); } throw new ELException(LocalMessages.Get("error.coerce.type {0} {1}", value.GetType(), typeof(char))); }
public override object Invoke(Bindings bindings, ELContext context, Type returnType, Type[] paramTypes, object[] @params) { MethodInfo method = GetMethod(bindings, context, returnType, paramTypes); try { return(method.Invoke(null, @params)); } catch (AccessViolationException) { throw new ELException(LocalMessages.Get("error.identifier.method.access", name)); } catch (System.ArgumentException e) { throw new ELException(LocalMessages.Get("error.identifier.method.invocation", name, e)); } catch (TargetInvocationException e) { throw new ELException(LocalMessages.Get("error.identifier.method.invocation", name, e.InnerException)); } }
protected internal virtual MethodInfo GetMethod(Bindings bindings, ELContext context, Type returnType, Type[] paramTypes) { object value = Eval(bindings, context); if (value == null) { throw new MethodNotFoundException(LocalMessages.Get("error.identifier.method.notfound", name)); } if (value is MethodInfo) { MethodInfo method = (MethodInfo)value; if (returnType != null && !returnType.IsAssignableFrom(method.ReturnType)) { throw new MethodNotFoundException(LocalMessages.Get("error.identifier.method.notfound", name)); } if (!Enumerable.SequenceEqual(method.GetParameters().Select(c => c.ParameterType), paramTypes)) { throw new MethodNotFoundException(LocalMessages.Get("error.identifier.method.notfound", name)); } return(method); } throw new MethodNotFoundException(LocalMessages.Get("error.identifier.method.notamethod", name, value.GetType())); }
protected internal virtual T CoerceToEnum <T>(object value, Type type) { if (value == null || "".Equals(value)) { return(default(T)); } if (type.IsInstanceOfType(value)) { return((T)value); } if (value is string) { try { return((T)value); } catch (System.ArgumentException) { throw new ELException(LocalMessages.Get("error.coerce.value {0} {1}", value, type)); } } throw new ELException(LocalMessages.Get("error.coerce.type {0} {1}", value.GetType(), type)); }
/// <summary> /// non-lvalues are always readonly, so throw an exception /// </summary> public sealed override void SetValue(Bindings bindings, ELContext context, object value) { throw new ELException(LocalMessages.Get("error.value.set.rvalue", GetStructuralId(bindings))); }
public sealed override object Invoke(Bindings bindings, ELContext context, Type returnType, Type[] paramTypes, object[] paramValues) { throw new ELException(LocalMessages.Get("error.method.invalid", GetStructuralId(bindings))); }