Author: sudha
Date: 2005-05-09 03:01:39 -0400 (Mon, 09 May 2005)
New Revision: 44244
Modified:
trunk/mcs/class/Microsoft.VisualBasic/Microsoft.VisualBasic.CompilerServices/ChangeLog
trunk/mcs/class/Microsoft.VisualBasic/Microsoft.VisualBasic.CompilerServices/ObjectType.cs
trunk/mcs/class/Microsoft.VisualBasic/Microsoft.VisualBasic.CompilerServices/VBBinder.cs
Log:
Support for optional arguments in LateBinding
Modified:
trunk/mcs/class/Microsoft.VisualBasic/Microsoft.VisualBasic.CompilerServices/ChangeLog
===================================================================
---
trunk/mcs/class/Microsoft.VisualBasic/Microsoft.VisualBasic.CompilerServices/ChangeLog
2005-05-09 06:48:21 UTC (rev 44243)
+++
trunk/mcs/class/Microsoft.VisualBasic/Microsoft.VisualBasic.CompilerServices/ChangeLog
2005-05-09 07:01:39 UTC (rev 44244)
@@ -1,3 +1,6 @@
+2005-05-09 Satya Sudha K <[EMAIL PROTECTED]>
+ * VBBinder.cs : Support for optional arguments in LateBinding
+
2005-05-05 Satya Sudha K <[EMAIL PROTECTED]>
* FlowControl.cs : Fixed checks in the methods 'ForNextCheck*'
Modified:
trunk/mcs/class/Microsoft.VisualBasic/Microsoft.VisualBasic.CompilerServices/ObjectType.cs
===================================================================
---
trunk/mcs/class/Microsoft.VisualBasic/Microsoft.VisualBasic.CompilerServices/ObjectType.cs
2005-05-09 06:48:21 UTC (rev 44243)
+++
trunk/mcs/class/Microsoft.VisualBasic/Microsoft.VisualBasic.CompilerServices/ObjectType.cs
2005-05-09 07:01:39 UTC (rev 44244)
@@ -1535,7 +1535,6 @@
return false;
}
if (! ToType.IsValueType) {
- Console.WriteLine ("Sudha--> {0} {1}" ,
FromType, ToType);
return ToType.IsAssignableFrom(FromType);
}
return false;
Modified:
trunk/mcs/class/Microsoft.VisualBasic/Microsoft.VisualBasic.CompilerServices/VBBinder.cs
===================================================================
---
trunk/mcs/class/Microsoft.VisualBasic/Microsoft.VisualBasic.CompilerServices/VBBinder.cs
2005-05-09 06:48:21 UTC (rev 44243)
+++
trunk/mcs/class/Microsoft.VisualBasic/Microsoft.VisualBasic.CompilerServices/VBBinder.cs
2005-05-09 07:01:39 UTC (rev 44244)
@@ -112,6 +112,7 @@
*/
ArrayList candidates = new ArrayList ();
+ // Get the list of all suitable methods
for (int index = 0; index < match.Length; index ++) {
if (IsApplicable (match [index], args))
candidates.Add (match [index]);
@@ -122,7 +123,6 @@
for (int index = 0; index < tempMatchList.Length; index
++)
filteredMatchList [index] = (MethodBase)
tempMatchList [index];
-
ConversionType bestMatch = ConversionType.None;
int numWideningConversions = 0, numNarrowingConversions
= 0;
ArrayList narrowingConv = new ArrayList ();
@@ -176,37 +176,23 @@
ParameterInfo[] pars = mbase.GetParameters ();
if (pars.Length == 0)
return mbase;
- int numFixedParams = pars.Length;
- if (UsesParamArray (mbase))
- numFixedParams --;
+ int numFixedParams = CountStandardParams (pars);
- for(int y = 0; y < numFixedParams; y++)
- {
- if (args [y] == null) {
- count ++;
- continue;
- }
- if((args [y] = ObjectType.CTypeHelper (args[y],
pars[y].ParameterType)) != null)
- count++;
- else
- break;
- }
-
-
- if (UsesParamArray (mbase)) {
+ if (UsesParamArray (pars)) {
int index = 0;
- Type paramArrayType = pars [pars.GetUpperBound
(0)].ParameterType;
- Array paramArgs = Array.CreateInstance
(paramArrayType.GetElementType (), args.Length - numFixedParams);
+ int paramArrayIndex = pars.GetUpperBound (0);
+ Type paramArrayType = pars
[paramArrayIndex].ParameterType;
+ Array paramArgs = Array.CreateInstance
(paramArrayType.GetElementType (), args.Length - paramArrayIndex);
bool isArgArray = false;
- if (numFixedParams + 1 == args.Length) {
- if (args
[numFixedParams].GetType().IsArray) {
+ if (pars.GetUpperBound (0) + 1 == args.Length) {
+ if (args [pars.GetUpperBound
(0)].GetType().IsArray) {
isArgArray = true;
count ++;
}
}
if (!isArgArray) {
- for (int y = numFixedParams; y <
args.Length; y ++) {
+ for (int y = paramArrayIndex; y <
args.Length; y ++) {
Type dest_type = paramArrayType;
if (!args [y].GetType
().IsArray) {
dest_type =
paramArrayType.GetElementType ();
@@ -214,27 +200,52 @@
if((args [y] =
ObjectType.CTypeHelper (args[y], dest_type)) != null) {
paramArgs.SetValue
(args [y], index);
} else
- break;
- count++;
+ return null;
index ++;
}
object[] newArgs = new object
[pars.Length];
- Array.Copy (args, newArgs,
numFixedParams);
+ Array.Copy (args, newArgs,
paramArrayIndex);
newArgs [newArgs.GetUpperBound (0)] =
paramArgs;
args = newArgs;
}
}
- if (count != arguments.Length)
- return null;
+ object[] newArguments = new object [pars.Length];
+ args.CopyTo (newArguments, 0);
+ int numExpectedArgs = pars.Length;
+ if (UsesParamArray (pars))
+ numExpectedArgs --;
+ for(int y = 0; y < numExpectedArgs; y++)
+ {
+ if (y < args.Length && (args [y] is Missing ||
args[y] == null))
+ newArguments [y] = pars
[y].DefaultValue;
+ else if (y >= args.Length)
+ newArguments [y] = pars
[y].DefaultValue;
+ else
+ newArguments [y] = args [y];
+ }
+ for(int y = 0; y < numExpectedArgs; y++) {
+ if (newArguments [y] == null)
+ return null;
+
+ if((newArguments [y] = ObjectType.CTypeHelper
(newArguments[y], pars[y].ParameterType)) == null)
+ return null;
+ }
+
+ ((BinderState) state).args = newArguments;
+
if (byRefFlags == null || pars.Length == 0) {
return mbase;
}
- for (int index = 0; index < pars.Length; index ++) {
- ParameterInfo p = pars [index];
+ int paramIndex = 0;
+ for (int index = 0; index < byRefFlags.Length; index
++) {
+ paramIndex = index;
+ if (index >= pars.Length)
+ paramIndex = pars.GetUpperBound (0);
+ ParameterInfo p = pars [paramIndex];
if (p.ParameterType.IsByRef) {
if (byRefFlags [index] != false)
byRefFlags [index] = true;
@@ -255,11 +266,11 @@
ParameterInfo[] candidateParams =
candidate.GetParameters ();
int numParams = Math.Min (bestMatchParams.Length,
candidateParams.Length);
int paramArrayIndex1 = -1, paramArrayIndex2 = -1;
- if (UsesParamArray (bestMatch)) {
+ if (UsesParamArray (bestMatchParams)) {
paramArrayIndex1 = (bestMatchParams.Length > 0)
? (bestMatchParams.Length - 1) : -1;
}
- if (UsesParamArray (candidate)) {
+ if (UsesParamArray (candidateParams)) {
paramArrayIndex2 = (candidateParams.Length > 0)
? (candidateParams.Length - 1) : -1;
}
@@ -319,9 +330,8 @@
return isBetter;
}
- internal static bool UsesParamArray (MethodBase mb) {
- ParameterInfo[] pars = mb.GetParameters ();
- if (pars.Length == 0)
+ internal static bool UsesParamArray (ParameterInfo [] pars) {
+ if (pars == null || pars.Length == 0)
return false;
ParameterInfo lastParam = pars [pars.GetUpperBound (0)];
object[] attrs = lastParam.GetCustomAttributes (typeof
(System.ParamArrayAttribute), false);
@@ -330,11 +340,32 @@
return true;
}
+ /*
+ Gets the number of parameters that are neither optional not
ParamArray
+ */
+ internal static int CountStandardParams (ParameterInfo [] pars)
{
+ if (pars.Length == 0)
+ return 0;
+ int count = pars.Length;
+ for (int index = 0; index < pars.Length; index ++) {
+ ParameterInfo param = pars [index];
+ if (param.IsOptional)
+ return index;
+ if (index + 1 == pars.Length) {
+ object[] attrs =
param.GetCustomAttributes (typeof (System.ParamArrayAttribute), false);
+ if (attrs != null && attrs.Length > 0)
+ return index;
+ }
+ }
+ return count;
+ }
+
private ConversionType GetConversionType (ParameterInfo[]
parameters, object[] args) {
int numParams = parameters.Length;
int numArgs = args.Length;
int paramArrayIndex = -1;
- int minParams = parameters.Length;
+ int numFixedParams = CountStandardParams (parameters);
+
if (numParams == 0) {
if (numArgs == 0)
return ConversionType.Exact;
@@ -342,70 +373,63 @@
return ConversionType.None;
}
- ParameterInfo lastParam = parameters
[parameters.GetUpperBound (0)];
- object[] attrs = lastParam.GetCustomAttributes (typeof
(System.ParamArrayAttribute), false);
- bool usesParamArray = false;
- if (attrs != null && attrs.Length > 0) {
- usesParamArray = true;
- paramArrayIndex = parameters.GetUpperBound (0)
- 1;
- minParams --;
- }
- if (minParams == 0 && numArgs == 0)
+ bool usesParamArray = UsesParamArray (parameters);
+ if (numFixedParams == 0 && numArgs == 0)
return ConversionType.Exact;
- if (numArgs < minParams)
+
+ if (numArgs < numFixedParams)
return ConversionType.None;
- if (! usesParamArray && numArgs != numParams) {
- return ConversionType.None;
- }
ConversionType ctype = ConversionType.None;
- for (int index = 0; index < minParams; index ++) {
+ bool isLastParam = false;
+ int paramIndex = 0;
+ for (int index = 0; index < numArgs; index ++) {
+ if (index < numFixedParams)
+ paramIndex = index;
+ else if (usesParamArray) {
+ paramIndex = parameters.GetUpperBound
(0);
+ isLastParam = true;
+ }
+
ConversionType currentCType =
ConversionType.None;
Type type1 = null;
if (args [index] != null)
type1 = args [index].GetType ();
- Type type2 = parameters [index].ParameterType;
+ Type type2 = parameters
[paramIndex].ParameterType;
if (type2.IsByRef)
type2 = type2.GetElementType ();
- if (type1 == type2) {
- currentCType = ConversionType.Exact;
- if (ctype < currentCType) {
- ctype = ConversionType.Exact;
- }
- } else if (ObjectType.IsWideningConversion
(type1, type2)) {
- currentCType = ConversionType.Widening;
- if (ctype < currentCType)
- ctype = ConversionType.Widening;
- } else
- ctype = ConversionType.Narrowing;
- }
-
- if (usesParamArray) {
- Type paramArrayType = lastParam.ParameterType;
- if (paramArrayType.IsByRef)
- paramArrayType =
paramArrayType.GetElementType ();
-
- for (int index = minParams; index < numArgs;
index ++) {
- ConversionType currentCType =
ConversionType.None;
- Type argType = args [index].GetType ();
- if (argType.IsArray) {
- if (argType.GetElementType ()
== paramArrayType.GetElementType ())
+ if (usesParamArray && isLastParam) {
+ if (type1.IsArray) {
+ if (type1.GetElementType () ==
type2.GetElementType ())
currentCType =
ConversionType.Exact;
- else if
(ObjectType.IsWideningConversion (argType, paramArrayType))
+ else if
(ObjectType.IsWideningConversion (type1, type2))
currentCType =
ConversionType.Widening;
else
currentCType =
ConversionType.Narrowing;
} else {
- Type elementType =
paramArrayType.GetElementType ();
- if (argType == elementType)
+ Type elementType =
type2.GetElementType ();
+ if (type1 == elementType)
currentCType =
ConversionType.Exact;
- else if
(ObjectType.IsWideningConversion (argType, elementType))
+ else if
(ObjectType.IsWideningConversion (type1, elementType))
currentCType =
ConversionType.Widening;
else
currentCType =
ConversionType.Narrowing;
}
if (currentCType ==
ConversionType.Narrowing || ctype < currentCType)
ctype = currentCType;
+
+ } else {
+ if (type1 == type2) {
+ currentCType =
ConversionType.Exact;
+ if (ctype < currentCType) {
+ ctype =
ConversionType.Exact;
+ }
+ } else if
(ObjectType.IsWideningConversion (type1, type2)) {
+ currentCType =
ConversionType.Widening;
+ if (ctype < currentCType)
+ ctype =
ConversionType.Widening;
+ } else
+ ctype =
ConversionType.Narrowing;
}
}
@@ -549,8 +573,14 @@
if (mbase == null) {
throw new MissingMemberException ("No
member '" + name + "' defined for type '" + objType + "' which takes the given
set of arguments");
}
+
+ object [] newArgs = args;
+ if (objState != null)
+ newArgs = ((BinderState) objState).args;
+
MethodInfo mi = (MethodInfo) mbase;
- retVal = mi.Invoke (target, args);
+ retVal = mi.Invoke (target, newArgs);
+ Array.Copy (newArgs, args, args.Length);
}
if (objState != null &&
((BinderState)objState).byRefFlags != null) {
@@ -560,55 +590,65 @@
return retVal;
}
+ /*
+ Determines whether a given method can be invoked with a given
set of arguments
+ */
private bool IsApplicable (MethodBase mb, object [] args) {
ParameterInfo [] parameters = mb.GetParameters ();
- int numFixedParams = parameters.Length;
+ int numFixedParams = CountStandardParams (parameters);
+ int numParams = parameters.Length;
int argCount = 0;
if (args != null)
argCount = args.Length;
- if (numFixedParams == 0)
- return (argCount == 0);
+ if (numParams == numFixedParams) // No
ParamArray or Optional params
+ if (argCount != numParams)
+ return false;
+
+ if (argCount < numFixedParams)
+ return false;
- ParameterInfo lastParam = parameters
[parameters.GetUpperBound (0)];
- bool usesParamArray = UsesParamArray (mb);
- if (usesParamArray)
- numFixedParams --;
- else if (numFixedParams != argCount)
+ bool usesParamArray = UsesParamArray (parameters);
+ if (!usesParamArray && (argCount > numParams))
return false;
- if (argCount < numFixedParams)
- return false;
- if (argCount == 0 && numFixedParams == 0)
- return true;
-
- for (int index = 0; index < numFixedParams; index ++) {
+ int paramIndex = 0;
+ bool isLastParam = false;
+ for (int index = 0; index < argCount; index ++) {
Type argType = null;
+ Type paramType = null;
+ isLastParam = false;
+ if (index < numFixedParams)
+ paramIndex = index;
+ else if (usesParamArray) {
+ paramIndex = numParams - 1;
+ isLastParam = true;
+ }
+
+ paramType = parameters
[paramIndex].ParameterType;
if (args [index] != null) {
argType = args [index].GetType ();
- Type paramType = parameters
[index].ParameterType;
- if (paramType.IsByRef)
- paramType =
paramType.GetElementType ();
- if
(!ObjectType.ImplicitConversionExists (argType, paramType))
- return false;
- }
- }
-
- if (usesParamArray) {
- Type paramArrayType = lastParam.ParameterType;
-
- for (int index = numFixedParams; index <
argCount; index ++) {
- Type argType = args [index].GetType ();
- if (!argType.IsArray) {
- Type elementType =
paramArrayType.GetElementType ();
- if
(!ObjectType.ImplicitConversionExists (argType, elementType))
- return false;
+ if (usesParamArray && isLastParam) {
+ // ParamArray parameter of type
'T'. We can either have an
+ // argument which is an array
of type T, or 'n' number of
+ // arguments that are
of/convertible to type 'T'
+ if (!argType.IsArray) {
+ Type elementType =
paramType.GetElementType ();
+ if
(!ObjectType.ImplicitConversionExists (argType, elementType))
+ return false;
+ } else {
+ Type elementType =
paramType.GetElementType ();
+ argType =
argType.GetElementType ();
+ if
(!elementType.IsAssignableFrom (argType))
+ return false;
+ }
} else {
- Type elementType =
paramArrayType.GetElementType ();
- argType =
argType.GetElementType ();
- if
(!elementType.IsAssignableFrom (argType))
+ if (paramType.IsByRef)
+ paramType =
paramType.GetElementType ();
+ if
(!ObjectType.ImplicitConversionExists (argType, paramType))
return false;
}
+
}
}
return true;
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches