/// <inheritdoc /> protected override object ExecuteToken(ScriptContext context) { object host = hosttoken.Execute(context); PropertyInfo[] indexer = host.GetType().GetProperties().Where(p => p.GetIndexParameters().Length == parameters.Length).ToArray(); if (indexer.Length == 0) { if (parameters.Length == 1) { if (host is Array array) { return(array.GetValue(Converter.Convert <int>(parameters[0].Execute(context)))); } if (host is IEnumerable enumerable) { return(enumerable.Cast <object>().Skip(Converter.Convert <int>(parameters[0].Execute(context))).First()); } } throw new ScriptRuntimeException($"No indexer methods found on {host}", this); } object[] parametervalues = parameters.Select(p => p.Execute(context)).ToArray(); Tuple <MethodInfo, int>[] evaluated = indexer.Select(i => MethodOperations.GetMethodMatchValue(i.GetMethod, parametervalues)).Where(e => e.Item2 >= 0).ToArray(); if (evaluated.Length == 0) { throw new ScriptRuntimeException($"No index getter found on '{host.GetType().Name}' which matched the specified parameters '{string.Join(", ", parametervalues)}'", this); } MethodInfo method = evaluated.OrderBy(m => m.Item2).Select(m => m.Item1).First(); return(MethodOperations.CallMethod(this, host, method, parametervalues, context)); }
/// <inheritdoc /> protected override object AssignToken(IScriptToken token, ScriptContext context) { object host = hosttoken.Execute(context); if (parameters.Length == 1) { if (host is Array array) { object value = token.Execute(context); array.SetValue(value, Converter.Convert <int>(parameters[0].Execute(context))); return(value); } } PropertyInfo[] indexer = host.GetType().GetProperties().Where(p => p.GetIndexParameters().Length == parameters.Length).ToArray(); object[] parametervalues = parameters.Select(p => p.Execute(context)).Concat(new[] { token.Execute(context) }).ToArray(); Tuple <MethodInfo, int>[] evaluated = indexer.Select(i => MethodOperations.GetMethodMatchValue(i.SetMethod, parametervalues)).Where(e => e.Item2 >= 0).OrderBy(m => m.Item2).ToArray(); if (evaluated.Length == 0) { throw new ScriptRuntimeException($"No index setter found on '{host.GetType().Name}' which matched the specified parameters '{string.Join(", ", parametervalues)}'", this); } return(MethodOperations.CallMethod(this, host, evaluated[0].Item1, parametervalues, context)); }
/// <inheritdoc /> public object Create(IScriptToken[] parameters, ScriptContext context) { ConstructorInfo[] constructors = type.GetConstructors().Where(c => MethodOperations.MatchesParameterCount(c, parameters)).ToArray(); if (constructors.Length == 0) { throw new ScriptRuntimeException($"No matching constructors available for '{type.Name}({string.Join<IScriptToken>(",", parameters)})'", null); } object[] parametervalues = parameters.Select(p => p.Execute(context)).ToArray(); Tuple <ConstructorInfo, int>[] evaluated = constructors.Select(c => MethodOperations.GetMethodMatchValue(c, parametervalues)).Where(e => e.Item2 >= 0).ToArray(); if (evaluated.Length == 0) { throw new ScriptRuntimeException($"No matching constructor found for '{type.Name}({string.Join(", ", parametervalues)})'", null); } return(MethodOperations.CallConstructor(evaluated[0].Item1, parameters, context)); }
/// <inheritdoc /> protected override object ExecuteToken(ScriptContext context) { object host = hosttoken.Execute(context); if (host == null) { throw new ScriptRuntimeException($"'{hosttoken}' results in null", this); } if (host is IExternalMethod externmethod && MethodName.ToLower() == "invoke") { try { return(externmethod.Invoke(context.Arguments, Parameters.Select(a => a.Execute(context)).ToArray())); } catch (Exception e) { throw new ScriptRuntimeException($"Error calling external method '{externmethod}'", this, e); } } MethodInfo[] methods = host.GetType().GetMethods().Where(m => m.Name.ToLower() == methodname && MethodOperations.MatchesParameterCount(m, parameters)).ToArray(); object[] parametervalues = parameters.Select(p => p.Execute(context)).ToArray(); List <ReferenceParameter> references = new List <ReferenceParameter>(); for (int i = 0; i < parameters.Length; ++i) { if (!(parameters[i] is Reference r)) { continue; } references.Add(new ReferenceParameter(i, r)); } Tuple <MethodInfo, int>[] evaluation = methods.Select(m => MethodOperations.GetMethodMatchValue(m, parametervalues)).Where(e => e.Item2 >= 0).OrderBy(m => m.Item2).ToArray(); if (evaluation.Length > 0) { return(MethodOperations.CallMethod(this, host, evaluation[0].Item1, parametervalues, context, references)); } if (extensions != null) { Type extensionbase = host.GetType(); while (extensionbase != null) { Type lookuptype = extensionbase; if (lookuptype.IsGenericType) { lookuptype = lookuptype.GetGenericTypeDefinition(); } methods = extensions.GetExtensions(lookuptype).Where(m => m.Name.ToLower() == methodname && MethodOperations.MatchesParameterCount(m, parameters, true)).ToArray(); evaluation = methods.Select(m => MethodOperations.GetMethodMatchValue(m, parametervalues, true)).OrderBy(m => m.Item2).ToArray(); if (evaluation.Length > 0) { MethodInfo method = evaluation[0].Item1; if (method.IsGenericMethodDefinition) { method = method.MakeGenericMethod(extensionbase.GetGenericArguments()); } return(MethodOperations.CallMethod(this, host, method, parametervalues, context, references, true)); } if (extensionbase == typeof(object)) { break; } extensionbase = extensionbase.BaseType; } foreach (Type interfacetype in host.GetType().GetInterfaces().OrderBy(i => i.IsGenericType ? 0 : 1)) { Type lookuptype = interfacetype; if (lookuptype.IsGenericType) { lookuptype = lookuptype.GetGenericTypeDefinition(); } methods = extensions.GetExtensions(lookuptype).Where(m => m.Name.ToLower() == methodname && MethodOperations.MatchesParameterCount(m, parameters, true)).ToArray(); evaluation = methods.Select(m => MethodOperations.GetMethodMatchValue(m, parametervalues, true)).OrderBy(m => m.Item2).ToArray(); if (evaluation.Length > 0) { MethodInfo method = evaluation[0].Item1; if (method.IsGenericMethodDefinition) { method = method.MakeGenericMethod(interfacetype.GetGenericArguments()); } return(MethodOperations.CallMethod(this, host, method, parametervalues, context, references, true)); } } } throw new ScriptRuntimeException($"Method '{methodname}' matching the parameters '({string.Join(",", parametervalues)})' not found on type {host.GetType().Name}", this); }