/// <summary> /// Creates a delegate with a given signature that could be used to invoke this object from non-dynamic code (w/o code context). /// A stub is created that makes appropriate conversions/boxing and calls the object. /// The stub should be executed within a context of this object's language. /// </summary> /// <returns>The converted delegate.</returns> /// <exception cref="T:Microsoft.Scripting.ArgumentTypeException">The object is either a subclass of Delegate but not the requested type or does not implement IDynamicMetaObjectProvider.</exception> public Delegate GetDelegate(object callableObject, Type delegateType) { ContractUtils.RequiresNotNull(delegateType, nameof(delegateType)); if (callableObject is Delegate result) { if (!delegateType.IsInstanceOfType(result)) { throw ScriptingRuntimeHelpers.SimpleTypeError($"Cannot cast {result.GetType()} to {delegateType}."); } return(result); } if (callableObject is IDynamicMetaObjectProvider dynamicObject) { MethodInfo invoke; if (!typeof(Delegate).IsAssignableFrom(delegateType) || (invoke = delegateType.GetMethod("Invoke")) == null) { throw ScriptingRuntimeHelpers.SimpleTypeError("A specific delegate type is required."); } result = GetOrCreateDelegateForDynamicObject(callableObject, delegateType, invoke); if (result != null) { return(result); } } throw ScriptingRuntimeHelpers.SimpleTypeError("Object is not callable."); }
/// <summary> /// Creates a delegate with a given signature that could be used to invoke this object from non-dynamic code (w/o code context). /// A stub is created that makes appropriate conversions/boxing and calls the object. /// The stub should be executed within a context of this object's language. /// </summary> /// <returns>The delegate or a <c>null</c> reference if the object is not callable.</returns> public static Delegate GetDelegate(LanguageContext context, object callableObject, Type delegateType) { ContractUtils.RequiresNotNull(context, "context"); ContractUtils.RequiresNotNull(delegateType, "delegateType"); Delegate result = callableObject as Delegate; if (result != null) { if (!delegateType.IsAssignableFrom(result.GetType())) { throw ScriptingRuntimeHelpers.SimpleTypeError(String.Format("Cannot cast {0} to {1}.", result.GetType(), delegateType)); } return(result); } IDynamicObject dynamicObject = callableObject as IDynamicObject; if (dynamicObject != null) { MethodInfo invoke; if (!typeof(Delegate).IsAssignableFrom(delegateType) || (invoke = delegateType.GetMethod("Invoke")) == null) { throw ScriptingRuntimeHelpers.SimpleTypeError("A specific delegate type is required."); } ParameterInfo[] parameters = invoke.GetParameters(); DelegateSignatureInfo signatureInfo = new DelegateSignatureInfo( context, invoke.ReturnType, parameters ); DelegateInfo delegateInfo = _dynamicDelegateCache.GetOrCreateValue(signatureInfo, delegate() { // creation code return(signatureInfo.GenerateDelegateStub()); }); result = delegateInfo.CreateDelegate(delegateType, dynamicObject); if (result != null) { return(result); } } throw ScriptingRuntimeHelpers.SimpleTypeError("Object is not callable."); }
public static ArgumentTypeException TypeErrorForIncorrectArgumentCount( string methodName, int minFormalNormalArgumentCount, int maxFormalNormalArgumentCount, int defaultArgumentCount, int providedArgumentCount, bool hasArgList, bool keywordArgumentsProvided) { int formalCount; string formalCountQualifier; string nonKeyword = keywordArgumentsProvided ? "non-keyword " : ""; if (defaultArgumentCount > 0 || hasArgList || minFormalNormalArgumentCount != maxFormalNormalArgumentCount) { if (providedArgumentCount < minFormalNormalArgumentCount || maxFormalNormalArgumentCount == Int32.MaxValue) { formalCountQualifier = "at least"; formalCount = minFormalNormalArgumentCount - defaultArgumentCount; } else { formalCountQualifier = "at most"; formalCount = maxFormalNormalArgumentCount; } } else if (minFormalNormalArgumentCount == 0) { return(ScriptingRuntimeHelpers.SimpleTypeError( $"{methodName}() takes no arguments ({providedArgumentCount} given)")); } else { formalCountQualifier = "exactly"; formalCount = minFormalNormalArgumentCount; } return(new ArgumentTypeException(string.Format( "{0}() takes {1} {2} {3}argument{4} ({5} given)", methodName, // 0 formalCountQualifier, // 1 formalCount, // 2 nonKeyword, // 3 formalCount == 1 ? "" : "s", // 4 providedArgumentCount))); // 5 }