예제 #1
0
        private int BetterCandidate(CandidateMethod c1, CandidateMethod c2)
        {
            int result = Math.Sign(TotalScore(c1) - TotalScore(c2));

            if (result != 0)
            {
                return(result);
            }
            if (c1.VarArgs && !c2.VarArgs)
            {
                return(-1);
            }
            if (c2.VarArgs && !c1.VarArgs)
            {
                return(1);
            }

            int minArgumentCount = Math.Min(c1.MinimumArgumentCount, c2.MinimumArgumentCount);

            for (int i = 0; i < minArgumentCount; ++i)
            {
                result += MoreSpecificType(c1.GetParameterType(i), c2.GetParameterType(i));
            }
            if (result != 0)
            {
                return(result);
            }

            if (c1.VarArgs && c2.VarArgs)
            {
                return(MoreSpecificType(c1.VarArgsParameterType, c2.VarArgsParameterType));
            }
            return(0);
        }
예제 #2
0
        private bool CalculateCandidateScore(CandidateMethod candidateMethod)
        {
            ParameterInfo[] parameters = candidateMethod.Parameters;
            for (int i = 0; i < candidateMethod.MinimumArgumentCount; ++i)
            {
                if (parameters[i].IsOut)
                {
                    return(false);
                }

                if (!CalculateCandidateArgumentScore(candidateMethod, i, parameters[i].ParameterType))
                {
                    return(false);
                }
            }

            if (candidateMethod.VarArgs)
            {
                Type varArgItemType = candidateMethod.VarArgsParameterType;
                for (int i = candidateMethod.MinimumArgumentCount; i < _arguments.Length; ++i)
                {
                    if (!CalculateCandidateArgumentScore(candidateMethod, i, varArgItemType))
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
예제 #3
0
		private static int TotalScore(CandidateMethod c1)
		{
			int total = 0;
			foreach (int score in c1.ArgumentScores)
			{
				total += score;
			}
			return total;
		}
예제 #4
0
        private static int TotalScore(CandidateMethod c1)
        {
            int total = 0;

            foreach (int score in c1.ArgumentScores)
            {
                total += score;
            }
            return(total);
        }
예제 #5
0
        private Dispatcher ProduceExtensionDispatcher()
        {
            CandidateMethod found = ResolveExtensionMethod();

            if (found == null)
            {
                throw new System.MissingMethodException(_type.FullName, _name);
            }
            return(EmitExtensionDispatcher(found));
        }
예제 #6
0
        private Dispatcher FindExtension(IEnumerable <MethodInfo> candidates)
        {
            CandidateMethod found = ResolveExtension(candidates);

            if (null != found)
            {
                return(EmitExtensionDispatcher(found));
            }
            throw MissingField();
        }
예제 #7
0
        private Dispatcher EmitMethodDispatcher(MethodInfo candidate)
        {
            CandidateMethod method = ResolveMethod(GetArgumentTypes(), new MethodInfo[] { candidate });

            if (null == method)
            {
                throw MissingField();
            }

            return(new MethodDispatcherEmitter(_type, method, GetArgumentTypes()).Emit());
        }
예제 #8
0
        public Dispatcher Create()
        {
            Type[]          types = GetArgumentTypes();
            CandidateMethod found = ResolveMethod(types);

            if (null != found)
            {
                return(EmitMethodDispatcher(found, types));
            }
            return(ProduceExtensionDispatcher());
        }
예제 #9
0
        private bool CalculateCandidateArgumentScore(CandidateMethod candidateMethod, int argumentIndex, Type paramType)
        {
            int score = CandidateMethod.CalculateArgumentScore(paramType, _arguments[argumentIndex]);

            if (score < 0)
            {
                return(false);
            }

            candidateMethod.ArgumentScores[argumentIndex] = score;
            return(true);
        }
예제 #10
0
        private int BetterCandidate(CandidateMethod c1, CandidateMethod c2)
        {
            int result = Math.Sign(TotalScore(c1) - TotalScore(c2));

            if (result != 0)
            {
                return(result);
            }

            if (c1.VarArgs)
            {
                return(c2.VarArgs ? 0 : -1);
            }
            return(c2.VarArgs ? 1 : 0);
        }
예제 #11
0
        private List <CandidateMethod> FindApplicableMethods(IEnumerable <MethodInfo> candidates)
        {
            List <CandidateMethod> applicable = new List <CandidateMethod>();

            foreach (MethodInfo method in candidates)
            {
                CandidateMethod candidateMethod = IsApplicableMethod(method);
                if (null == candidateMethod)
                {
                    continue;
                }
                applicable.Add(candidateMethod);
            }
            return(applicable);
        }
예제 #12
0
        private CandidateMethod IsApplicableMethod(MethodInfo method)
        {
            ParameterInfo[] parameters = method.GetParameters();
            bool            varargs    = IsVarArgs(parameters);

            if (!ValidArgumentCount(parameters, varargs))
            {
                return(null);
            }

            CandidateMethod candidateMethod = new CandidateMethod(method, _arguments.Length, varargs);

            if (CalculateCandidateScore(candidateMethod))
            {
                return(candidateMethod);
            }

            return(null);
        }
예제 #13
0
        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 (SetOrGet.Get == gos)
            {
                return(new MethodDispatcherEmitter(_type, found, argumentTypes).Emit());
            }
            return(new SetPropertyEmitter(_type, found, argumentTypes).Emit());
        }
예제 #14
0
 private Dispatcher EmitMethodDispatcher(CandidateMethod found, Type[] argumentTypes)
 {
     return(new MethodDispatcherEmitter(_type, found, argumentTypes).Emit());
 }
예제 #15
0
 public MethodDispatcherEmitter(CandidateMethod found, params  Type[] argumentTypes)
     : this(found.Method.DeclaringType, found, argumentTypes)
 {
 }
예제 #16
0
 public MethodDispatcherEmitter(Type owner, CandidateMethod found, Type[] argumentTypes)
     : base(owner, found.Method.Name + "$" + Builtins.join(argumentTypes, "$"))
 {
     _found = found;
     _argumentTypes = argumentTypes;
 }
예제 #17
0
 private static bool DoesNotRequireConversions(CandidateMethod candidate)
 {
     return candidate.DoesNotRequireConversions;
 }
예제 #18
0
        private CandidateMethod IsApplicableMethod(MethodInfo method)
        {
            ParameterInfo[] parameters = method.GetParameters();
            bool varargs = IsVarArgs(parameters);
            if (!ValidArgumentCount(parameters, varargs)) return null;

            CandidateMethod candidateMethod = new CandidateMethod(method, _arguments.Length, varargs);
            if (CalculateCandidateScore(candidateMethod)) return candidateMethod;

            return null;
        }
예제 #19
0
 public MethodDispatcherEmitter(Type owner, CandidateMethod found, Type[] argumentTypes) : base(owner, found.Method.Name + "$" + Builtins.join(argumentTypes, "$"))
 {
     _found         = found;
     _argumentTypes = argumentTypes;
 }
예제 #20
0
 public ExtensionMethodDispatcherEmitter(CandidateMethod found, Type[] argumentTypes) : base(found, argumentTypes)
 {
 }
예제 #21
0
 private static bool ShouldResolveArgsOf(CandidateMethod method)
 {
     return MetaAttributeOf(method).ResolveArgs;
 }
예제 #22
0
 private Dispatcher EmitMethodDispatcher(CandidateMethod found, Type[] argumentTypes)
 {
     return new MethodDispatcherEmitter(_type, found, argumentTypes).Emit();
 }
예제 #23
0
 private void EmitLoadValue()
 {
     EmitArgArrayElement(0);
     EmitCoercion(_argumentType, _field.FieldType, CandidateMethod.CalculateArgumentScore(_field.FieldType, _argumentType));
 }
예제 #24
0
 public SetPropertyEmitter(Type type, CandidateMethod found, Type[] argumentTypes) : base(type, found, argumentTypes)
 {
 }
예제 #25
0
 private static bool DoesNotRequireConversions(CandidateMethod candidate)
 {
     return(candidate.DoesNotRequireConversions);
 }
예제 #26
0
 public SetPropertyEmitter(Type type, CandidateMethod found, Type[] argumentTypes)
     : base(type, found, argumentTypes)
 {
 }
 public ExtensionMethodDispatcherEmitter(CandidateMethod found, Type[] argumentTypes)
     : base(found, argumentTypes)
 {
 }
예제 #28
0
 private static MetaAttribute MetaAttributeOf(CandidateMethod method)
 {
     return (MetaAttribute) method.Method.GetCustomAttributes(typeof (MetaAttribute), false).Single();
 }
예제 #29
0
        private int BetterCandidate(CandidateMethod c1, CandidateMethod c2)
        {
            int result = Math.Sign(TotalScore(c1) - TotalScore(c2));
            if (result != 0) return result;
            if (c1.VarArgs && !c2.VarArgs) return -1;
            if (c2.VarArgs && !c1.VarArgs) return 1;

            int minArgumentCount = Math.Min(c1.MinimumArgumentCount, c2.MinimumArgumentCount);
            for (int i = 0; i < minArgumentCount; ++i)
            {
                result += MoreSpecificType(c1.GetParameterType(i), c2.GetParameterType(i));
            }
            if (result != 0) return result;

            if (c1.VarArgs && c2.VarArgs)
            {
                return MoreSpecificType(c1.VarArgsParameterType, c2.VarArgsParameterType);
            }
            return 0;
        }
예제 #30
0
 private void InvokeMetaMethod(MethodInvocationExpression node, CandidateMethod method, object[] arguments)
 {
     var replacement = (Node) method.DynamicInvoke(null, arguments);
     ReplaceMetaMethodInvocationSite(node, replacement);
 }
예제 #31
0
        private bool CalculateCandidateArgumentScore(CandidateMethod candidateMethod, int argumentIndex, Type paramType)
        {
            int score = CandidateMethod.CalculateArgumentScore(paramType, _arguments[argumentIndex]);
            if (score < 0) return false;

            candidateMethod.ArgumentScores[argumentIndex] = score;
            return true;
        }
예제 #32
0
 public MethodDispatcherEmitter(CandidateMethod found, params Type[] argumentTypes) : this(found.Method.DeclaringType, found, argumentTypes)
 {
 }
예제 #33
0
        private bool CalculateCandidateScore(CandidateMethod candidateMethod)
        {
            ParameterInfo[] parameters = candidateMethod.Parameters;
            for (int i = 0; i < candidateMethod.MinimumArgumentCount; ++i)
            {
                if (parameters[i].IsOut) return false;

                if (!CalculateCandidateArgumentScore(candidateMethod, i, parameters[i].ParameterType))
                {
                    return false;
                }
            }

            if (candidateMethod.VarArgs)
            {
                Type varArgItemType = candidateMethod.VarArgsParameterType;
                for (int i = candidateMethod.MinimumArgumentCount; i < _arguments.Length; ++i)
                {
                    if (!CalculateCandidateArgumentScore(candidateMethod, i, varArgItemType))
                    {
                        return false;
                    }
                }
            }
            return true;
        }
예제 #34
0
 private Node InvokeMetaMethod(CandidateMethod method, object[] arguments)
 {
     return (Node)method.DynamicInvoke(null, arguments);
 }
예제 #35
0
 protected Dispatcher EmitExtensionDispatcher(CandidateMethod found)
 {
     return(new ExtensionMethodDispatcherEmitter(found, GetArgumentTypes()).Emit());
 }