2 // Copyright (c) 2003, 2004, 2005 Rodrigo B. de Oliveira (rbo@acm.org)
3 // All rights reserved.
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
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.
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.
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
)
48 if (paramType
.IsValueType
) return -1;
49 return CandidateMethod
.ExactMatchScore
;
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
;
71 private readonly MethodInfo _method
;
72 private readonly int[] _argumentScores
;
73 private readonly bool _varArgs
;
75 public CandidateMethod(MethodInfo method
, int argumentCount
, bool varArgs
)
78 _argumentScores
= new int[argumentCount
];
82 public MethodInfo Method
84 get { return _method; }
87 public int[] ArgumentScores
89 get { return _argumentScores; }
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
));