ToReferenceContext() private method

private ToReferenceContext ( ConstructorInfo constructor ) : ConstructorInfo
constructor System.Reflection.ConstructorInfo
return System.Reflection.ConstructorInfo
 private static int SelectBest(TypeReferences typeRefs, MemberInfo[] match, int matches, IReflect[] argIRs, ParameterInfo[][] fparams, object[][] aparams, int candidates, int parameters)
 {
     if (candidates == 0)
     {
         return -1;
     }
     if (candidates == 1)
     {
         for (int m = 0; m < matches; m++)
         {
             if (fparams[m] != null)
             {
                 return m;
             }
         }
     }
     bool[] flagArray = new bool[matches];
     int[] numArray = new int[matches];
     for (int i = 0; i < matches; i++)
     {
         ParameterInfo[] infoArray = fparams[i];
         if (infoArray != null)
         {
             int length = infoArray.Length;
             int num4 = (argIRs == null) ? aparams[i].Length : argIRs.Length;
             if ((num4 > length) && ((length == 0) || !Microsoft.JScript.CustomAttribute.IsDefined(infoArray[length - 1], typeof(ParamArrayAttribute), false)))
             {
                 fparams[i] = null;
                 candidates--;
             }
             else
             {
                 for (int n = parameters; n < length; n++)
                 {
                     ParameterInfo target = infoArray[n];
                     if ((n == (length - 1)) && Microsoft.JScript.CustomAttribute.IsDefined(target, typeof(ParamArrayAttribute), false))
                     {
                         break;
                     }
                     if (TypeReferences.GetDefaultParameterValue(target) is DBNull)
                     {
                         numArray[i] = 50;
                     }
                 }
             }
         }
     }
     for (int j = 0; candidates > 1; j++)
     {
         int num7 = 0;
         int num8 = 0x7fffffff;
         bool flag = false;
         for (int num9 = 0; num9 < matches; num9++)
         {
             int num10 = 0;
             ParameterInfo[] infoArray2 = fparams[num9];
             if (infoArray2 != null)
             {
                 IReflect missing = typeRefs.Missing;
                 if (argIRs == null)
                 {
                     if (aparams[num9].Length > j)
                     {
                         object obj3 = aparams[num9][j];
                         if (obj3 == null)
                         {
                             obj3 = DBNull.Value;
                         }
                         missing = typeRefs.ToReferenceContext(obj3.GetType());
                     }
                 }
                 else if (j < parameters)
                 {
                     missing = argIRs[j];
                 }
                 int num11 = infoArray2.Length;
                 if ((num11 - 1) > j)
                 {
                     num7++;
                 }
                 IReflect formal = typeRefs.Missing;
                 if ((((num11 > 0) && (j >= (num11 - 1))) && (Microsoft.JScript.CustomAttribute.IsDefined(infoArray2[num11 - 1], typeof(ParamArrayAttribute), false) && !(missing is TypedArray))) && ((missing != typeRefs.ArrayObject) && (!(missing is Type) || !((Type) missing).IsArray)))
                 {
                     ParameterInfo info2 = infoArray2[num11 - 1];
                     if (info2 is ParameterDeclaration)
                     {
                         formal = ((TypedArray) ((ParameterDeclaration) info2).ParameterIReflect).elementType;
                     }
                     else
                     {
                         formal = info2.ParameterType.GetElementType();
                     }
                     if (j == (num11 - 1))
                     {
                         numArray[num9]++;
                     }
                 }
                 else if (j < num11)
                 {
                     ParameterInfo parameter = infoArray2[j];
                     formal = (parameter is ParameterDeclaration) ? ((ParameterDeclaration) parameter).ParameterIReflect : parameter.ParameterType;
                     if ((missing == typeRefs.Missing) && !(TypeReferences.GetDefaultParameterValue(parameter) is DBNull))
                     {
                         missing = formal;
                         num10 = 1;
                     }
                 }
                 int num12 = (TypeDistance(typeRefs, formal, missing) + numArray[num9]) + num10;
                 if (num12 == num8)
                 {
                     if ((j == (num11 - 1)) && flagArray[num9])
                     {
                         candidates--;
                         fparams[num9] = null;
                     }
                     flag = flag && flagArray[num9];
                 }
                 else if (num12 > num8)
                 {
                     if ((flag && (j < num11)) && FormalParamTypeIsObject(fparams[num9][j]))
                     {
                         num8 = num12;
                     }
                     else if (((j <= (num11 - 1)) || (missing != typeRefs.Missing)) || !Microsoft.JScript.CustomAttribute.IsDefined(infoArray2[num11 - 1], typeof(ParamArrayAttribute), false))
                     {
                         flagArray[num9] = true;
                     }
                 }
                 else
                 {
                     if ((candidates == 1) && !flagArray[num9])
                     {
                         return num9;
                     }
                     flag = flagArray[num9];
                     for (int num13 = 0; num13 < num9; num13++)
                     {
                         if ((fparams[num13] != null) && !flagArray[num13])
                         {
                             bool flag2 = fparams[num13].Length <= j;
                             if ((!flag2 || (parameters > j)) && ((flag2 || !flag) || !FormalParamTypeIsObject(fparams[num13][j])))
                             {
                                 flagArray[num13] = true;
                             }
                         }
                     }
                     num8 = num12;
                 }
             }
         }
         if ((j >= (parameters - 1)) && (num7 < 1))
         {
             break;
         }
     }
     int index = -1;
     for (int k = 0; (k < matches) && (candidates > 0); k++)
     {
         ParameterInfo[] suppars = fparams[k];
         if (suppars != null)
         {
             if (flagArray[k])
             {
                 candidates--;
                 fparams[k] = null;
             }
             else if (index == -1)
             {
                 index = k;
             }
             else if (Class.ParametersMatch(suppars, fparams[index]))
             {
                 MemberInfo info4 = match[index];
                 JSWrappedMethod method = match[index] as JSWrappedMethod;
                 if (method != null)
                 {
                     info4 = method.method;
                 }
                 if (((info4 is JSFieldMethod) || (info4 is JSConstructor)) || (info4 is JSProperty))
                 {
                     candidates--;
                     fparams[k] = null;
                 }
                 else
                 {
                     Type declaringType = match[index].DeclaringType;
                     Type c = match[k].DeclaringType;
                     if (declaringType != c)
                     {
                         if (c.IsAssignableFrom(declaringType))
                         {
                             candidates--;
                             fparams[k] = null;
                         }
                         else if (declaringType.IsAssignableFrom(c))
                         {
                             fparams[index] = null;
                             index = k;
                             candidates--;
                         }
                     }
                 }
             }
         }
     }
     if (candidates != 1)
     {
         throw new AmbiguousMatchException();
     }
     return index;
 }
Exemplo n.º 2
0
 internal static Type ToType(TypeReferences typeRefs, IReflect ir){
   if (ir is Type)
     return (Type)ir;
   if (ir is ClassScope)
     return ((ClassScope)ir).GetTypeBuilderOrEnumBuilder();
   if (ir is TypedArray){
     return typeRefs.ToReferenceContext(((TypedArray)ir).ToType());
   }
   if (ir is ScriptFunction)
     return typeRefs.ScriptFunction;
   return typeRefs.ToReferenceContext(ir.GetType());
 }
Exemplo n.º 3
0
 private static int SelectBest(TypeReferences typeRefs, MemberInfo[] match, int matches, IReflect[] argIRs, ParameterInfo[][] fparams, Object[][] aparams, int candidates, int parameters){ 
   Debug.Assert(matches > 1);
   if (candidates == 0) return -1;
   if (candidates == 1)
     for (int i = 0; i < matches; i++)
       if (fparams[i] != null) return i;
   bool[] eliminated = new bool[matches];
   //Set up penalties to discourage selection of methods that have more formal parameters than there are actual parameters
   int[] penalty = new int[matches];
   for (int i = 0; i < matches; i++){
     ParameterInfo[] fpars = fparams[i];
     if (fpars != null){
       int m = fpars.Length;
       int actuals =  (argIRs == null ? aparams[i].Length : argIRs.Length);
       if (actuals > m && (m == 0 || !CustomAttribute.IsDefined(fpars[m-1], typeof(ParamArrayAttribute), false))){
         fparams[i] = null;
         candidates--;
         Debug.Assert(candidates >= 0);
         continue;
       }
       for (int j = parameters; j < m; j++){
         ParameterInfo fpar = fpars[j];
         if (j == m-1 && CustomAttribute.IsDefined(fpar, typeof(ParamArrayAttribute), false))
           break;
         Object dv = TypeReferences.GetDefaultParameterValue(fpar);
         if (dv is System.DBNull){
           //No default value, set up a penalty
           penalty[i] = 50;
         }
       }
     }
   }
   for (int p = 0; candidates > 1; p++){
     int candidatesWithFormalParametersStillToBeConsidered = 0;
     //Eliminate any candidate that is worse match than any other candidate for this (possibly missing) actual parameter
     int minval = Int32.MaxValue;
     bool objectCanWin = false;
     for (int i = 0; i < matches; i++){
       int penaltyForUsingDefaultValue = 0;
       ParameterInfo[] fpars = fparams[i];
       if (fpars != null){ //match[i] is a candidate
         IReflect aIR = typeRefs.Missing;
         if (argIRs == null){
           if (aparams[i].Length > p){
             Object apar = aparams[i][p];
             if (apar == null) apar = DBNull.Value;
             aIR = typeRefs.ToReferenceContext(apar.GetType());
           }
         }else if (p < parameters)
           aIR = argIRs[p];
         int m = fpars.Length;
         if (m-1 > p) 
           candidatesWithFormalParametersStillToBeConsidered++;
         IReflect fIR = typeRefs.Missing;
         if (m > 0 && p >= m-1 && CustomAttribute.IsDefined(fpars[m-1], typeof(ParamArrayAttribute), false) && 
         !(aIR is TypedArray || aIR == typeRefs.ArrayObject || (aIR is Type && ((Type)aIR).IsArray))){
           ParameterInfo fpar = fpars[m-1];
           if (fpar is ParameterDeclaration){
             fIR = ((ParameterDeclaration)fpar).ParameterIReflect;
             fIR = ((TypedArray)fIR).elementType;
           }else
             fIR = fpar.ParameterType.GetElementType();
           if (p == m-1) penalty[i]++;
         }else if (p < m){
           ParameterInfo fpar = fpars[p];
           fIR = fpar is ParameterDeclaration ? ((ParameterDeclaration)fpar).ParameterIReflect : fpar.ParameterType;
           if (aIR == typeRefs.Missing){
             //No actual parameter was supplied, if the formal parameter has default value, make the match perfect
             Object dv = TypeReferences.GetDefaultParameterValue(fpar);
             if (!(dv is System.DBNull)) {
               aIR = fIR;
               penaltyForUsingDefaultValue = 1;
             }
           }
         }
         int distance = TypeDistance(typeRefs, fIR, aIR) + penalty[i] + penaltyForUsingDefaultValue;
         if (distance == minval){
           if (p == m-1 && eliminated[i]){
             candidates--;
             fparams[i] = null;
           }
           objectCanWin = objectCanWin && eliminated[i];
           continue;
         }
         if (distance > minval){
           if (objectCanWin && p < m && JSBinder.FormalParamTypeIsObject(fparams[i][p])){
              minval = distance; //Make sure that a future, better match than Object can win.
              continue;
           }
           if (p > m-1 && aIR == typeRefs.Missing && CustomAttribute.IsDefined(fpars[m-1], typeof(ParamArrayAttribute), false)) continue;
           eliminated[i] = true;
           continue;
         }
         //If we get here, we have a match that is strictly better than all previous matches.
         //If there are no other remaining candidates, we're done.
         if (candidates == 1 && !eliminated[i])
           return i;
         //Eliminate those other candidates from consideration.
         objectCanWin = eliminated[i];
         for (int j = 0; j < i; j++)
           if (fparams[j] != null && !eliminated[j]){
             bool noFormalForCurrParam = fparams[j].Length <= p;
             if (noFormalForCurrParam && parameters <= p)
               //Do not eliminate an overload if it does not have a formal for the current position
               //and the call does not have an actual parameter for the current position either.
               continue;
             if (noFormalForCurrParam || !objectCanWin || !JSBinder.FormalParamTypeIsObject(fparams[j][p]))
               eliminated[j] = true;
           }
         minval = distance;
       }
     }
     if (p >= parameters-1 && candidatesWithFormalParametersStillToBeConsidered < 1)
       //Looked at all actual parameters as well as all formal parameters, no further progress can be made
       break;
   }
   int best = -1;
   for (int j = 0; j < matches && candidates > 0; j++){
     ParameterInfo[] fpars = fparams[j];
     if (fpars != null){
       if (eliminated[j]){
         candidates--; fparams[j] = null; continue;
       }
       int pc = fpars.Length;
       if (best == -1){ //Choose the first remaining candidate as "best"
         best = j; continue;
       }
       if (Class.ParametersMatch(fpars, fparams[best])){
         MemberInfo bstm = match[best];
         JSWrappedMethod jswm = match[best] as JSWrappedMethod;
         if (jswm != null) bstm = jswm.method;
         if (bstm is JSFieldMethod || bstm is JSConstructor || bstm is JSProperty){
           //The first match is always the most derived, go with it
           candidates--; fparams[j] = null; continue;
         }
         Type bestMemT = match[best].DeclaringType;
         Type memT = match[j].DeclaringType;
         if (bestMemT != memT){
           if (memT.IsAssignableFrom(bestMemT)){
             candidates--; fparams[j] = null; continue;
           }else if (bestMemT.IsAssignableFrom(memT)){
             fparams[best] = null; best = j; candidates--; continue;
           }
         }
       }  
     }
   }
   if (candidates != 1)
     throw new AmbiguousMatchException();
   return best;
 }