/// <summary>If this is a method, this attempts to find the correct overload /// by using the set of arguments given in the method call.</summary> /// <param name="arguments">The set of arguments given in the method call.</param> /// <returns>The MethodInfo if found; null otherwise.</returns> public MethodInfo GetOverload(CompiledFragment[] arguments) { Type fragType = OfType(); if (Types.IsDynamic(fragType)) { CompiledClass cc = Method.Script.GetClass(fragType); return((cc == null)?null:cc.FindMethodOverload(Name, arguments)); } else if (Name == "gettype" && (arguments == null || arguments.Length == 0)) { return(fragType.GetMethod("GetType", new Type[0])); } else { if (!Method.Script.AllowUse(fragType)) { Error("Unable to call methods on type " + fragType.Name + " as it is restricted."); } Type[] paramTypes = Types.GetTypes(arguments); MethodInfo result = Types.GetOverload(fragType.GetMethods(), Name, paramTypes, true); if (IsStatic && result != null && !result.IsStatic) { // Special case! This is where we're calling e.g. ToString on a straight type, for example int.ToString(); // Another example is actually the call below! We're getting a type, then calling a method on the type - not a static method of it. // The method is not static yet we're 'expecting' one. // So, look for the same method on System.Type and return that instead. return(Types.GetOverload(typeof(System.Type).GetMethods(), Name, paramTypes, true)); } return(result); } }
/// <summary>If this is a method, this attempts to find the correct overload /// by using the set of arguments given in the method call.</summary> /// <param name="arguments">The set of arguments given in the method call.</param> /// <returns>The MethodInfo if found; null otherwise.</returns> public MethodInfo GetOverload(Type[] paramTypes) { // Get the parent type: Type fragType = OfType(); if (Methods != null) { // Extension methods. int count = 0; if (paramTypes != null) { count = paramTypes.Length; } // Get types: Type[] argTypes = new Type[count + 1]; if (paramTypes != null) { Array.Copy(paramTypes, 0, argTypes, 1, count); } // Get the overload: return(Types.GetOverload(Methods, argTypes)); } if (Types.IsDynamic(fragType)) { CompiledClass cc = Method.Script.GetClass(fragType); return((cc == null)?null:cc.FindMethodOverload(Name, paramTypes)); } else if (Name == "gettype" && (paramTypes == null || paramTypes.Length == 0)) { return(fragType.GetMethod("GetType", new Type[0])); } if (!Method.Script.AllowUse(fragType)) { Error("Unable to call methods on type " + fragType.Name + " as it is restricted."); } MethodInfo result = Types.GetOverload(fragType.GetMethods(), Name, paramTypes, true); if (IsStatic && result != null && !result.IsStatic) { // Special case! This is where we're calling e.g. ToString on a straight type, for example int.ToString(); // Another example is actually the call below! We're getting a type, then calling a method on the type - not a static method of it. // The method is not static yet we're 'expecting' one. // So, look for the same method on System.Type and return that instead. return(Types.GetOverload(typeof(System.Type).GetMethods(), Name, paramTypes, true)); } return(result); }
public override Type OutputType(out CompiledFragment v) { v = this; Type type = OfType(); // Map to functionality: CompiledClass Class = null; bool isDynamic = Types.IsDynamic(type); // (Constant) binding flags: BindingFlags flags = BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static; if (Name == "length" && type.IsGenericType && !isDynamic) { // Does length actually exist as a field/ property? Field = type.GetField(Name, flags); if (Field == null) { Property = type.GetProperty(Name, flags); if (Property == null) { // Assume we meant count instead: Name = "Count"; } } } if (isDynamic) { Class = Method.Script.GetClass(type); } else if (!Method.Script.AllowUse(type)) { Error("Unable to access properties of type " + type + " as it has not been made accessible."); } if (isDynamic) { Field = Class.GetField(Name); } else { Field = type.GetField(Name, flags); } if (Field != null) { if (IsStatic && !Field.IsStatic) { Error("Property " + Name + " is not static. You must use an object reference to access it."); } return(Field.FieldType); } if (isDynamic) { Property = Class.GetProperty(Name); } else { Property = type.GetProperty(Name, flags); } if (Property != null) { if (IsStatic) { MethodInfo staticTest = Property.GetGetMethod(); if (staticTest == null) { staticTest = Property.GetSetMethod(); } if (!staticTest.IsStatic) { Error("Property " + Name + " is not static. You must use an object reference to access it."); } } return(Property.PropertyType); } if (isDynamic) { MethodReturnType = Class.MethodReturnType(Name); } else { MethodReturnType = Types.MethodReturnType(type, Name); } if (MethodReturnType != null) { if (Types.IsVoid(MethodReturnType)) { MethodReturnType = typeof(Void); } return(DynamicMethodCompiler.TypeFor(MethodReturnType)); } if (Of.GetType() == typeof(ThisOperation)) { // This was the first property - it can potentially be a static type name too. Type staticType = Method.Script.GetType(Name); if (staticType != null) { // It's a static type! Generate a new type operation to replace this one and return the type. v = new TypeOperation(Method, staticType); return(v.OutputType(out v)); } } if (Name == "this") { // This is handled here as it allows variables called "This". Use case: PowerUI. v = new ThisOperation(Method); return(v.OutputType(out v)); } // Does it support indexing? If so, Do Parent["property"] instead. MethodOperation mOp = null; if (Input0 != null) { // This is a set. Input0 is the object we're setting. Type setType = Input0.OutputType(out Input0); // Get the set method: MethodInfo mInfo; if (isDynamic) { mInfo = Class.FindMethodOverload("set_Item", new Type[] { typeof(string), setType }); } else { // Grab all the methods of the type: MethodInfo[] allMethods = type.GetMethods(); mInfo = Types.GetOverload(allMethods, "set_Item", new Type[] { typeof(string), setType }); } if (mInfo == null) { // Try finding the extension method: mInfo = FindExtensionMethod(type, "set"); if (mInfo == null) { // It doesn't exist! // Error("Property '"+ToString()+"' is not a property or extension of "+type.ToString()+"."); // Create as a global: Field = Method.Script.MainClass.DefineField(Name, true, setType); return(setType); } // Extension property or method. // -> We only know which based on MethodOperation later calling GetOverload. // Or OutputSet/ OutputIL being called. return(mInfo.ReturnType); } // It exists - create the method operation now. mOp = new MethodOperation(Method, mInfo, new CompiledFragment(Name), Input0); v = mOp; mOp.CalledOn = Of; return(setType); } else { // Get. // Get the get method: MethodInfo mInfo; if (isDynamic) { mInfo = Class.FindMethodOverload("get_Item", new Type[] { typeof(string) }); } else { // Grab all the methods of the type: MethodInfo[] allMethods = type.GetMethods(); mInfo = Types.GetOverload(allMethods, "get_Item", new Type[] { typeof(string) }); } if (mInfo == null) { // Try finding the extension method: mInfo = FindExtensionMethod(type, "get"); if (mInfo == null) { // It doesn't exist! // Error("Property '"+ToString()+"' is not a property or extension of "+type.ToString()+"."); // Create as a global: Field = Method.Script.MainClass.DefineField(Name, true, typeof(object)); return(typeof(object)); } // Extension property or method. // -> We only know which based on MethodOperation later calling GetOverload. // Or OutputSet/ OutputIL being called. return(mInfo.ReturnType); } // It exists - create the method operation now: mOp = new MethodOperation(Method, mInfo, new CompiledFragment(Name)); v = mOp; mOp.CalledOn = Of; return(mInfo.ReturnType); } }