/// <summary> /// Gets the effective Value of this ScriptValue instance /// </summary> /// <param name="arguments">indexer/method/constructor arguments</param> /// <returns>an object that represents the value of this ScriptValue</returns> public virtual object GetValue(ScriptValue[] arguments) { if (!Getable) { throw new ScriptException("Get is not supported for this member"); } if (creator != null) { bool ok; object retVal = creator.InvokeExecutor(Value, arguments, bypassCompatibilityOnLazyInvokation, out ok); if (ok) { return retVal; } } if (ValueType == ValueType.Literal) { return Value; } object tmpValue = Value; if (ValueType == ValueType.PropertyOrField) { if (arguments == null || arguments.Length == 0) { var invokationHelper = tmpValue as InvokationHelper; if (invokationHelper != null) { bool ok; object retVal = invokationHelper.Invoke(null, out ok); if (ok) { return retVal; } } FunctionLiteral fx = tmpValue as FunctionLiteral; if (fx != null && fx.AutoInvokeEnabled) { return ((FunctionLiteral) tmpValue).Invoke(null); } return tmpValue; } if (tmpValue == null) { throw new ScriptException("Indexer Failed for NULL - Value"); } if (tmpValue is Type) { throw new ScriptException("Indexer call for Types not supported"); } object[] parameters = (from t in arguments select t.GetValue(null)).ToArray(); if (!(tmpValue is Array)) { object[] args; Type targetType = tmpValue.GetType(); if (ExplicitType != null) { if (!ExplicitType.IsAssignableFrom(targetType)) { throw new ScriptException("Provided Type is not implemented by the target-object"); } targetType = ExplicitType; } PropertyInfo pi = MethodHelper.GetCapableIndexer(targetType, parameters, out args); if (pi == null) { throw new ScriptException("No capable Indexer found for the provided arguments"); } if (creator != null) { creator.SetPreferredExecutor(new LazyIndexer(pi,parameters.Length != args.Length)); } return pi.GetValue(tmpValue, args); } Array arr = (Array)tmpValue; return arr.GetValue(parameters.Cast<int>().ToArray()); } if (ValueType == ValueType.Method) { SequenceValue ta = (SequenceValue) arguments[0]; SequenceValue a = (SequenceValue) arguments[1]; ScriptValue et = arguments[2]; Type explicitType = null; object[] parameters = (from t in a.Sequence select t.GetValue(null)).ToArray(); Type[] typeParameters = Type.EmptyTypes; if (ta != null) { typeParameters = (from t in ta.Sequence select (Type) t.GetValue(null)).ToArray(); } if (et != null) { explicitType = et.GetValue(null) as Type; } Type type; if (tmpValue == null) { ValueType = ValueType.PropertyOrField; } if (Name == null) { try { if (tmpValue is Delegate) { Delegate dlg = (Delegate) tmpValue; return dlg.DynamicInvoke(parameters); } if (tmpValue is InvokationHelper) { InvokationHelper ih = (InvokationHelper) tmpValue; bool ok; var retVal = ih.Invoke(parameters, out ok); if (ok) { return retVal; } throw new ScriptException($"Failed to call method {Name}. Possible Arguments-mismatch."); } if (tmpValue is FunctionLiteral) { FunctionLiteral fl = (FunctionLiteral) tmpValue; return fl.Invoke(parameters); } } finally { ValueType = ValueType.Method; } } if (tmpValue == null) { throw new Exception("Method call failed for NULL - Value"); } object target = tmpValue; bool isStatic = false; if (tmpValue is Type) { type = (Type)tmpValue; target = null; isStatic = true; } else if (tmpValue is ObjectLiteral) { type = tmpValue.GetType(); ObjectLiteral ol = tmpValue as ObjectLiteral; FunctionLiteral fl = ol[Name] as FunctionLiteral; if (fl != null) { return fl.Invoke(parameters); } } else { type = explicitType??tmpValue.GetType(); } object[] args; #if UseDelegates MethodInvoker method = MethodHelper.GetCapableMethod(type, typeParameters, Name, Value is Type, parameters, out args); #else bool tmpStatic = isStatic; MethodInfo method = MethodHelper.GetCapableMethod(type, typeParameters, Name, ref isStatic, parameters, out args); if (!tmpStatic && isStatic) { args[0] = target; target = null; } #endif if (method == null) { throw new ScriptException(string.Format("No capable Method found for {0}", Name)); } var writeBacks = MethodHelper.GetWritebacks(method, args, a.Sequence); if (creator != null) { creator.SetPreferredExecutor(new LazyMethod(method, tmpStatic, !tmpStatic && isStatic, args.Length != a.Sequence.Length)); } #if UseDelegates if (target != null) { target = target.WrapIfValueType(); } return method(target, args); if (target != null) { /*object[] newArgs = new object[args.Length + 1]; newArgs[0] = target; Array.Copy(args, 0, newArgs, 1, args.Length);*/ args[0] = target; if (!(target is System.ValueType)) { return method.FastDynamicInvoke(args); } return method.DynamicInvoke(args); #else try { return method.Invoke(target, args); } finally { foreach (var wb in writeBacks) { wb.Target.SetValue(args[wb.Index]); } } #endif #if UseDelegates } return method.FastDynamicInvoke(args); #endif } if (ValueType == ValueType.Constructor) { if (tmpValue == null || !(tmpValue is Type)) { throw new ScriptException("Require Type in order to create a new instance"); } ScriptValue[] ta = null; if (arguments[0] != null) { ta = ((SequenceValue)arguments[0]).Sequence; } ScriptValue[] a = ((SequenceValue) arguments[1]).Sequence; object[] parameters = (from t in a select t.GetValue(null)).ToArray(); Type[] typeParameters = ta == null ? Type.EmptyTypes : (from t in ta select (Type) t.GetValue(null)).ToArray(); Type type = (Type)tmpValue; if (typeParameters.Length != 0) { //throw new ScriptException(string.Format("Unexpected usage of generic Type {0}", ((Type)Value).FullName)); type = type.MakeGenericType(typeParameters); } object[] args; ConstructorInfo constructor = MethodHelper.GetCapableConstructor(type, parameters, out args); if (constructor == null) { throw new ScriptException(string.Format("No appropriate Constructor was found for {0}", ((Type)tmpValue).FullName)); } if (creator != null) { creator.SetPreferredExecutor(new LazyConstructor(constructor, args.Length != a.Length)); } return constructor.Invoke(args); } throw new ScriptException("Unexpected Value-Type"); }
public bool CanGetValue(ScriptValue[] arguments) { if (!Getable) { throw new ScriptException("Get is not supported for this member"); } if (creator != null) { bool ok = creator.CanInvokeExecutor(Value,arguments,bypassCompatibilityOnLazyInvokation); //object retVal = creator.InvokeExecutor(Value, arguments, bypassCompatibilityOnLazyInvokation, out ok); if (ok) { return true; } } if (ValueType == ValueType.Literal) { return false; } object tmpValue = Value; if (ValueType == ValueType.PropertyOrField) { if (arguments == null || arguments.Length == 0) { return true; } if (tmpValue == null) { return false; } if (tmpValue is Type) { return false; } object[] parameters = (from t in arguments select t.GetValue(null)).ToArray(); if (!(tmpValue is Array)) { object[] args; PropertyInfo pi = MethodHelper.GetCapableIndexer(ExplicitType??tmpValue.GetType(), parameters, out args); return pi != null; } Array arr = (Array)tmpValue; int[] indices = parameters.Cast<int>().ToArray(); bool retVal = true; for (int i = 0; i < indices.Length; i++) { retVal &= arr.GetLength(i) > indices[i]; } return retVal; } if (ValueType == ValueType.Method) { SequenceValue ta = (SequenceValue)arguments[0]; SequenceValue a = (SequenceValue)arguments[1]; ScriptValue et = arguments[2]; object[] parameters = (from t in a.Sequence select t.GetValue(null)).ToArray(); Type[] typeParameters = Type.EmptyTypes; if (ta != null) { typeParameters = (from t in ta.Sequence select (Type)t.GetValue(null)).ToArray(); } Type type; if (tmpValue == null) { ValueType = ValueType.PropertyOrField; } if (Name == null) { try { if (tmpValue is Delegate) { return true; } if (tmpValue is InvokationHelper) { return true; } if (tmpValue is FunctionLiteral) { return true; } } finally { ValueType = ValueType.Method; } } if (tmpValue == null) { return false; } object target = tmpValue; bool isStatic = false; if (tmpValue is Type) { type = (Type)tmpValue; target = null; isStatic = true; } else if (tmpValue is ObjectLiteral) { type = tmpValue.GetType(); ObjectLiteral ol = tmpValue as ObjectLiteral; FunctionLiteral fl = ol[Name] as FunctionLiteral; if (fl != null) { return true; } } else { type = et?.GetValue(null) as Type ?? tmpValue.GetType(); } object[] args; #if UseDelegates MethodInvoker method = MethodHelper.GetCapableMethod(type, typeParameters, Name, Value is Type, parameters, out args); #else bool tmpStatic = isStatic; MethodInfo method = MethodHelper.GetCapableMethod(type, typeParameters, Name, ref isStatic, parameters, out args); if (!tmpStatic && isStatic) { args[0] = target; target = null; } #endif if (method == null) { return false; } return true; } if (ValueType == ValueType.Constructor) { if (tmpValue == null || !(tmpValue is Type)) { throw new ScriptException("Require Type in order to create a new instance"); } ScriptValue[] ta = null; if (arguments[0] != null) { ta = ((SequenceValue)arguments[0]).Sequence; } ScriptValue[] a = ((SequenceValue)arguments[1]).Sequence; object[] parameters = (from t in a select t.GetValue(null)).ToArray(); Type[] typeParameters = ta == null ? Type.EmptyTypes : (from t in ta select (Type)t.GetValue(null)).ToArray(); Type type = (Type)tmpValue; if (typeParameters.Length != 0) { //throw new ScriptException(string.Format("Unexpected usage of generic Type {0}", ((Type)Value).FullName)); type = type.MakeGenericType(typeParameters); } object[] args; ConstructorInfo constructor = MethodHelper.GetCapableConstructor(type, parameters, out args); if (constructor == null) { return false; } return true; } throw new ScriptException("Unexpected Value-Type"); }