private Dispatcher EmitMethodDispatcher(CandidateMethod found, Type[] argumentTypes) { #if NO_SYSTEM_REFLECTION_EMIT return found.DynamicInvoke; #else return new Emitters.MethodDispatcherEmitter(_type, found, argumentTypes).Emit(); #endif }
private Dispatcher EmitMethodDispatcher(CandidateMethod found, Type[] argumentTypes) { #if NO_SYSTEM_REFLECTION_EMIT return(found.DynamicInvoke); #else return(new Emitters.MethodDispatcherEmitter(_type, found, argumentTypes).Emit()); #endif }
protected Dispatcher EmitExtensionDispatcher(CandidateMethod found) { #if NO_SYSTEM_REFLECTION_EMIT return((target, args) => found.DynamicInvoke(null, AdjustExtensionArgs(target, args))); #else return(new Emitters.ExtensionMethodDispatcherEmitter(found, GetArgumentTypes()).Emit()); #endif }
public void Execute(string data) { if (string.IsNullOrEmpty(data)) { return; } var parts = new Queue <string>(Regex.Split(data, @"\s+")); List <CandidateMethod> currentOperations = new List <CandidateMethod>(); CandidateMethod lastCandidate = null; int paramNumber = 0; while (parts.Count != 0) { var p = parts.Dequeue(); paramNumber++; foreach (var candidate in currentOperations.ToList()) { try { var parameter = candidate.Method.GetParameters()[paramNumber - 1]; candidate.ParameterValues.Add(Convert.ChangeType(p, parameter.ParameterType, CultureInfo.InvariantCulture)); } catch (Exception) { currentOperations.Remove(candidate); if (currentOperations.Count == 0) { lastCandidate = candidate; } } } if (lastCandidate != null) { lastCandidate.Invoke(); lastCandidate = null; } if (currentOperations.Count == 0) { currentOperations = FindOperations(p); if (currentOperations.Count == 0) { throw new InvalidOperationException("Geometry command : " + p + " is unknown"); } paramNumber = 0; continue; } } var lastOperation = currentOperations.LastOrDefault(); if (lastOperation != null) { lastOperation.Invoke(); } }
private Dispatcher FindExtension(IEnumerable <MethodInfo> candidates) { CandidateMethod found = ResolveExtension(candidates); if (null != found) { return(EmitExtensionDispatcher(found)); } throw MissingField(); }
private Dispatcher ProduceExtensionDispatcher() { CandidateMethod found = ResolveExtensionMethod(); if (found == null) { throw new System.MissingMethodException(_type.FullName, _name); } return(EmitExtensionDispatcher(found)); }
public Dispatcher Create() { Type[] types = GetArgumentTypes(); CandidateMethod found = ResolveMethod(types); if (null != found) { return(EmitMethodDispatcher(found, types)); } return(ProduceExtensionDispatcher()); }
private Dispatcher EmitMethodDispatcher(IEnumerable <MethodInfo> candidates) { CandidateMethod method = ResolveMethod(GetArgumentTypes(), candidates); if (null == method) { throw MissingField(); } #if NO_SYSTEM_REFLECTION_EMIT return(method.DynamicInvoke); #else return(new Emitters.MethodDispatcherEmitter(_type, method, GetArgumentTypes()).Emit()); #endif }
private Dispatcher EmitPropertyDispatcher(PropertyInfo property, SetOrGet gos) { Type[] argumentTypes = GetArgumentTypes(); MethodInfo accessor = Accessor(property, gos); if (null == accessor) { throw MissingField(); } CandidateMethod found = ResolveMethod(argumentTypes, new MethodInfo[] { accessor }); if (null == found) { throw MissingField(); } #if NO_SYSTEM_REFLECTION_EMIT switch (gos) { case SetOrGet.Get: return((target, args) => property.GetValue(target, args)); case SetOrGet.Set: return((target, args) => { var value = args[args.Length - 1]; var remainingArgs = new object[args.Length - 1]; Array.Copy(args, remainingArgs, remainingArgs.Length); property.SetValue(target, RuntimeServices.Coerce(value, property.PropertyType), remainingArgs); return value; }); default: throw new ArgumentException(); } #else if (SetOrGet.Get == gos) { return(new Emitters.MethodDispatcherEmitter(_type, found, argumentTypes).Emit()); } return(new Emitters.SetPropertyEmitter(_type, found, argumentTypes).Emit()); #endif }
public MethodDispatcherEmitter(CandidateMethod found, params Type[] argumentTypes) : this(found.Method.DeclaringType, found, argumentTypes) { }
public ExtensionMethodDispatcherEmitter(CandidateMethod found, Type[] argumentTypes) : base(found, argumentTypes) { }
/// <summary> /// Looks up the MethodInfo in our cache, if it does not exist it is resolved /// </summary> /// <param name="Node">The node to look this up for</param> /// <param name="Method">The name of the method</param> /// <param name="Parameters">The parameters you intend to send to the method</param> /// <returns>The MethodInfo or null if it does not exist</returns> public static MethodInfo GetMethodInfo(Node Node, string Method, params object[] Parameters) { Type nodeType = Node.GetType(); List <Type> Signature = MDStatics.GetSignatureFromParameters(Parameters); StringBuilder SignatureString = new StringBuilder(); Signature.ForEach(type => SignatureString.Append(type.ToString())); String key = $"{nodeType.ToString()}#{Method}#{SignatureString.ToString()}"; if (!MethodInfoCache.ContainsKey(key)) { MethodInfo newInfo = nodeType.GetMethod(Method, MDStatics.BindFlagsAllMembers, null, Signature.ToArray(), null); if (newInfo != null) { MethodInfoCache.Add(key, newInfo); } else { // Couldn't find anything with direct compare so we will search for the method manually and cache it if found MethodInfo[] Methods = nodeType.GetAllMethods(); foreach (MethodInfo CandidateMethod in Methods) { if (CandidateMethod.Name != Method) { continue; } ParameterInfo[] CandidateParams = CandidateMethod.GetParameters(); if (CandidateParams.Count() != Signature.Count) { continue; } List <Type> CandidateSignature = new List <Type>(); CandidateParams.ToList().ForEach(param => CandidateSignature.Add(param.ParameterType)); MDLog.Debug(LOG_CAT, $"Evaluating {CandidateMethod.Name} ({GetParametersAsString(CandidateSignature.ToArray())})"); bool IsCompatible = true; for (int i = 0; i < Signature.Count; ++i) { Type SignatureType = Signature[i]; Type CandidateType = CandidateSignature[i]; bool isNullable = CandidateType.IsNullable(); if ((CandidateType.IsNullable() && (Parameters == null || Parameters[i] == null)) == false && (SignatureType.IsCastableTo(CandidateType) == false)) { MDLog.Debug(LOG_CAT, $"CandidateMethod.Name: {CandidateMethod.Name} SignatureType: {SignatureType.ToString()} does not cast to {CandidateType.ToString()}"); IsCompatible = false; break; } } if (IsCompatible) { MDLog.Debug(LOG_CAT, $"Adding compatible method key {key}"); MethodInfoCache.Add(key, CandidateMethod); } } } } if (MethodInfoCache.ContainsKey(key)) { return(MethodInfoCache[key]); } return(null); }
public SetPropertyEmitter(Type type, CandidateMethod found, Type[] argumentTypes) : base(type, found, argumentTypes) { }
public MethodDispatcherEmitter(Type owner, CandidateMethod found, Type[] argumentTypes) : base(owner, found.Method.Name + "$" + Builtins.join(argumentTypes, "$")) { _found = found; _argumentTypes = argumentTypes; }
private void EmitLoadValue() { EmitArgArrayElement(0); EmitCoercion(_argumentType, _field.FieldType, CandidateMethod.CalculateArgumentScore(_field.FieldType, _argumentType)); }