BOO-999
[boo.git] / src / Boo.Lang / Runtime / CandidateMethod.cs
blob2893a20ba8988a91f980cad944058ebd5cd21fd1
1 #region license
2 // Copyright (c) 2003, 2004, 2005 Rodrigo B. de Oliveira (rbo@acm.org)
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
7 //
8 // * Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright notice,
11 // this list of conditions and the following disclaimer in the documentation
12 // and/or other materials provided with the distribution.
13 // * Neither the name of Rodrigo B. de Oliveira nor the names of its
14 // contributors may be used to endorse or promote products derived from this
15 // software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #endregion
30 using System;
31 using System.Reflection;
33 namespace Boo.Lang.Runtime
35 public class CandidateMethod
37 public const int ExactMatchScore = 7;
38 public const int UpCastScore = 6;
39 public const int WideningPromotion = 5;
40 public const int ImplicitConversionScore = 4;
41 public const int NarrowingPromotion = 3;
42 public const int DowncastScore = 2;
44 public static int CalculateArgumentScore(Type paramType, Type argType)
46 if (null == argType)
48 if (paramType.IsValueType) return -1;
49 return CandidateMethod.ExactMatchScore;
51 else
53 if (paramType == argType) return CandidateMethod.ExactMatchScore;
55 if (paramType.IsAssignableFrom(argType)) return CandidateMethod.UpCastScore;
57 if (argType.IsAssignableFrom(paramType)) return CandidateMethod.DowncastScore;
59 if (IsNumericPromotion(paramType, argType))
61 if (NumericTypes.IsWideningPromotion(paramType, argType)) return WideningPromotion;
62 return CandidateMethod.NarrowingPromotion;
65 MethodInfo conversion = RuntimeServices.FindImplicitConversionOperator(argType, paramType);
66 if (null != conversion) return CandidateMethod.ImplicitConversionScore;
68 return -1;
71 private readonly MethodInfo _method;
72 private readonly int[] _argumentScores;
73 private readonly bool _varArgs;
75 public CandidateMethod(MethodInfo method, int argumentCount, bool varArgs)
77 _method = method;
78 _argumentScores = new int[argumentCount];
79 _varArgs = varArgs;
82 public MethodInfo Method
84 get { return _method; }
87 public int[] ArgumentScores
89 get { return _argumentScores; }
92 public bool VarArgs
94 get { return _varArgs; }
97 public int MinimumArgumentCount
99 get { return _varArgs ? Parameters.Length - 1 : Parameters.Length; }
102 public ParameterInfo[] Parameters
104 get { return _method.GetParameters(); }
107 public Type VarArgsParameterType
109 get { return GetParameterType(Parameters.Length-1).GetElementType(); }
112 public bool DoesNotRequireConversions
114 get { return !Array.Exists(_argumentScores, RequiresConversion); }
117 private static bool RequiresConversion(int score)
119 return score < WideningPromotion;
122 public Type GetParameterType(int i)
124 return Parameters[i].ParameterType;
127 public static bool IsNumericPromotion(Type paramType, Type argType)
129 return RuntimeServices.IsPromotableNumeric(Type.GetTypeCode(paramType))
130 && RuntimeServices.IsPromotableNumeric(Type.GetTypeCode(argType));