/// <summary> /// Provides default binding for performing a call on the specified meta objects. /// </summary> /// <param name="signature">The signature describing the call</param> /// <param name="target">The meta object to be called.</param> /// <param name="args"> /// Additional meta objects are the parameters for the call as specified by the CallSignature in the CallAction. /// </param> /// <param name="resolverFactory">Overload resolver factory.</param> /// <param name="errorSuggestion">The result should the object be uncallable.</param> /// <returns>A MetaObject representing the call or the error.</returns> public DynamicMetaObject Call(CallSignature signature, DynamicMetaObject errorSuggestion, OverloadResolverFactory resolverFactory,ClrMethod method, DynamicMetaObject target, params DynamicMetaObject[] args) { ContractUtils.RequiresNotNullItems(args, "args"); ContractUtils.RequiresNotNull(resolverFactory, "resolverFactory"); TargetInfo targetInfo = GetTargetInfo(method, target, args); if (targetInfo != null) { // we're calling a well-known MethodBase DynamicMetaObject res = MakeMetaMethodCall(signature, resolverFactory, targetInfo); if (res.Expression.Type.IsValueType) { if (res.Expression.Type == Types.Void) res = new DynamicMetaObject( Expression.Block(Types.Object[0], res.Expression, Expression.Constant(null)), res.Restrictions ); else res = new DynamicMetaObject( Expression.Convert(res.Expression, typeof(object)), res.Restrictions ); } return res; } else { // we can't call this object return errorSuggestion ?? MakeCannotCallRule(target, target.GetLimitType()); } }
// instance method call: public PythonOverloadResolver(PythonBinder binder, DynamicMetaObject instance, IList<DynamicMetaObject> args, CallSignature signature, Expression codeContext) : base(binder, instance, args, signature) { Assert.NotNull(codeContext); _context = codeContext; }
public DynamicMetaObject Create(CallSignature signature, DynamicMetaObject target, DynamicMetaObject[] args, Expression contextExpression) { Type t = GetTargetType(target.Value); if (t != null) { if (typeof(Delegate).IsAssignableFrom(t) && args.Length == 1) { // PythonOps.GetDelegate(CodeContext context, object callable, Type t); return new DynamicMetaObject( Ast.Call( typeof(PythonOps).GetMethod("GetDelegate"), contextExpression, AstUtils.Convert(args[0].Expression, typeof(object)), Expression.Constant(t) ), target.Restrictions.Merge(BindingRestrictions.GetInstanceRestriction(target.Expression, target.Value)) ); } return CallMethod( new PythonOverloadResolver( this, args, signature, contextExpression ), CompilerHelpers.GetConstructors(t, PrivateBinding), target.Restrictions.Merge(BindingRestrictions.GetInstanceRestriction(target.Expression, target.Value)) ); } return null; }
public DynamicMetaObject Create(CallSignature signature, DynamicMetaObject target, DynamicMetaObject[] args, Expression contextExpression) { Type t = GetTargetType(target.Value); if (t != null) { if (typeof(Delegate).IsAssignableFrom(t) && args.Length == 1) { MethodInfo dc = GetDelegateCtor(t); // BinderOps.CreateDelegate<T>(CodeContext context, object callable); return new DynamicMetaObject( Ast.Call(null, dc, contextExpression, args[0].Expression), target.Restrictions.Merge(BindingRestrictions.GetInstanceRestriction(target.Expression, target.Value)) ); } return CallMethod( new PythonOverloadResolver( this, args, signature, contextExpression ), CompilerHelpers.GetConstructors(t, PrivateBinding), BindingRestrictions.Empty ); } return null; }
public DefaultOverloadResolver(ActionBinder binder, IList<DynamicMetaObject> args, CallSignature signature, CallTypes callType) : base(binder) { ContractUtils.RequiresNotNullItems(args, "args"); Debug.Assert((callType == CallTypes.ImplicitInstance ? 1 : 0) + signature.ArgumentCount == args.Count); _args = args; _signature = signature; _callType = callType; }
/// <summary> /// Provides default binding for performing a call on the specified meta objects. /// </summary> /// <param name="signature">The signature describing the call</param> /// <param name="target">The meta object to be called.</param> /// <param name="args"> /// Additional meta objects are the parameters for the call as specified by the CallSignature in the CallAction. /// </param> /// <param name="resolverFactory">Overload resolver factory.</param> /// <returns>A MetaObject representing the call or the error.</returns> public DynamicMetaObject Call(CallSignature signature, OverloadResolverFactory resolverFactory, DynamicMetaObject target, params DynamicMetaObject[] args) { ContractUtils.RequiresNotNullItems(args, "args"); ContractUtils.RequiresNotNull(resolverFactory, "resolverFactory"); TargetInfo targetInfo = GetTargetInfo(signature, target, args); if (targetInfo != null) { // we're calling a well-known MethodBase return MakeMetaMethodCall(signature, resolverFactory, targetInfo); } else { // we can't call this object return MakeCannotCallRule(target, target.GetLimitType()); } }
/// <summary> /// Provides default binding for performing a call on the specified meta objects. /// </summary> /// <param name="signature">The signature describing the call</param> /// <param name="target">The meta object to be called.</param> /// <param name="args"> /// Additional meta objects are the parameters for the call as specified by the CallSignature in the CallAction. /// </param> /// <param name="parameterBinder">ParameterBinder used to map arguments to parameters.</param> /// <returns>A MetaObject representing the call or the error.</returns> public DynamicMetaObject Call(CallSignature signature, ParameterBinder parameterBinder, DynamicMetaObject target, params DynamicMetaObject[] args) { ContractUtils.RequiresNotNullItems(args, "args"); ContractUtils.RequiresNotNull(parameterBinder, "parameterBinder"); TargetInfo targetInfo = GetTargetInfo(signature, target, args); if (targetInfo != null) { // we're calling a well-known MethodBase return MakeMetaMethodCall(signature, parameterBinder, targetInfo); } else { // we can't call this object return MakeCannotCallRule(target, target.LimitType); } }
public static Expression/*!*/ Invoke(BinderState/*!*/ binder, Type/*!*/ resultType, CallSignature signature, params Expression/*!*/[]/*!*/ args) { PythonInvokeBinder invoke = new PythonInvokeBinder(binder, signature); switch(args.Length) { case 0: return Ast.Dynamic(invoke, resultType, AstUtils.CodeContext()); case 1: return Ast.Dynamic(invoke, resultType, AstUtils.CodeContext(), args[0]); case 2: return Ast.Dynamic(invoke, resultType, AstUtils.CodeContext(), args[0], args[1]); case 3: return Ast.Dynamic(invoke, resultType, AstUtils.CodeContext(), args[0], args[1], args[2]); default: return Ast.Dynamic( invoke, resultType, new ReadOnlyCollection<Expression>(ArrayUtils.Insert(AstUtils.CodeContext(), args)) ); } }
private DynamicMetaObject MakeMetaMethodCall(CallSignature signature, OverloadResolverFactory resolverFactory, TargetInfo targetInfo) { BindingRestrictions restrictions = BindingRestrictions.Combine(targetInfo.Arguments).Merge(targetInfo.Restrictions); if (targetInfo.Instance != null) { restrictions = targetInfo.Instance.Restrictions.Merge(restrictions); } DynamicMetaObject[] args; CallTypes callType; if (targetInfo.Instance != null) { args = ArrayUtils.Insert(targetInfo.Instance, targetInfo.Arguments); callType = CallTypes.ImplicitInstance; } else { args = targetInfo.Arguments; callType = CallTypes.None; } return CallMethod(resolverFactory.CreateOverloadResolver(args, signature, callType), targetInfo.Targets, restrictions); }
public MetaObject Create(CallSignature signature, ParameterBinderWithCodeContext parameterBinder, MetaObject target, MetaObject[] args) { Type t = GetTargetType(target.Value); if (t != null) { if (typeof(Delegate).IsAssignableFrom(t) && args.Length == 1) { MethodInfo dc = GetDelegateCtor(t); // BinderOps.CreateDelegate<T>(CodeContext context, object callable); return new MetaObject( Ast.Call(null, dc, parameterBinder.ContextExpression, args[0].Expression), target.Restrictions.Merge(Restrictions.GetInstanceRestriction(target.Expression, target.Value)) ); } return CallMethod(parameterBinder, CompilerHelpers.GetConstructors(t, PrivateBinding), args, signature); } return null; }
/// <summary> /// Provides default binding for performing a call on the specified meta objects. /// </summary> /// <param name="signature">The signature describing the call</param> /// <param name="target">The meta object to be called.</param> /// <param name="args"> /// Additional meta objects are the parameters for the call as specified by the CallSignature in the CallAction. /// </param> /// <param name="resolverFactory">Overload resolver factory.</param> /// <returns>A MetaObject representing the call or the error.</returns> public DynamicMetaObject Call(CallSignature signature, OverloadResolverFactory resolverFactory, DynamicMetaObject target, params DynamicMetaObject[] args) { ContractUtils.RequiresNotNullItems(args, "args"); ContractUtils.RequiresNotNull(resolverFactory, "resolverFactory"); TargetInfo targetInfo = GetTargetInfo(target, args); if (targetInfo != null) { // we're calling a well-known MethodBase DynamicMetaObject res = MakeMetaMethodCall(signature, resolverFactory, targetInfo); if (res.Expression.Type.IsValueType) { res = new DynamicMetaObject( AstUtils.Convert(res.Expression, typeof(object)), res.Restrictions ); } return res; } else { // we can't call this object return MakeCannotCallRule(target, target.GetLimitType()); } }
private DynamicMetaObject MakeMetaMethodCall(CallSignature signature, ParameterBinder parameterBinder, TargetInfo targetInfo) { BindingRestrictions restrictions = BindingRestrictions.Combine(targetInfo.Arguments).Merge(targetInfo.Restrictions); if (targetInfo.Instance != null) { restrictions = targetInfo.Instance.Restrictions.Merge(restrictions); } if (targetInfo.Instance != null) { return CallInstanceMethod( parameterBinder, targetInfo.Targets, targetInfo.Instance, targetInfo.Arguments, signature, restrictions ); } return CallMethod( parameterBinder, targetInfo.Targets, targetInfo.Arguments, signature, restrictions); }
public override DefaultOverloadResolver CreateOverloadResolver(IList <DynamicMetaObject> args, CallSignature signature, CallTypes callType) { if (signature.ArgumentCount < args.Count && callType != CallTypes.ImplicitInstance) //FIX: when CallTypes != ImplicitInstance, remove the first arg (self) { //The self arg is added in `DefaultBinder.GetTargetInfo` args = new List <DynamicMetaObject>(args.Skip(1)); } return(new TjsOverloadResolver(_binder, args, signature, callType)); }
public static Expression/*!*/ Invoke(Expression codeContext, PythonContext/*!*/ binder, Type/*!*/ resultType, CallSignature signature, params Expression/*!*/[]/*!*/ args) { return Ast.Dynamic( binder.Invoke( signature ), resultType, ArrayUtils.Insert(codeContext, args) ); }
private static Expression GetArgumentExpression(CallSignature signature, ArgumentType kind, ref int unusedCount, DynamicMetaObject/*!*/[]/*!*/ args) { int index = signature.IndexOf(kind); if (index != -1) { unusedCount--; return args[index].Expression; } return AstUtils.Constant(null); }
/// <summary> /// Attempts to bind to an operator Call method. /// </summary> private TargetInfo TryGetOperatorTargets(DynamicMetaObject self, DynamicMetaObject[] args, object target, CallSignature signature) { MethodBase[] targets; Type targetType = CompilerHelpers.GetType(target); MemberGroup callMembers = GetMember(OldCallAction.Make(this, signature), targetType, "Call"); List<MethodBase> callTargets = new List<MethodBase>(); foreach (MemberTracker mi in callMembers) { if (mi.MemberType == TrackerTypes.Method) { MethodInfo method = ((MethodTracker)mi).Method; if (method.IsSpecialName) { callTargets.Add(method); } } } Expression instance = null; if (callTargets.Count > 0) { targets = callTargets.ToArray(); instance = Ast.Convert(self.Expression, CompilerHelpers.GetType(target)); return new TargetInfo(null, ArrayUtils.Insert(self, args), targets); } return null; }
public override LangElement Call(Span span, LangElement nameExpr, CallSignature signature, TypeRef typeRef) => CountLE(base.Call(span, nameExpr, signature, typeRef));
private Expression/*!*/ MakeCheckSelf(DynamicMetaObjectBinder/*!*/ binder, CallSignature signature, DynamicMetaObject/*!*/[]/*!*/ args) { ArgumentType firstArgKind = signature.GetArgumentKind(0); Expression res; if (firstArgKind == ArgumentType.Simple || firstArgKind == ArgumentType.Instance) { res = CheckSelf(binder, AstUtils.Convert(Expression, typeof(Method)), args[0].Expression); } else if (firstArgKind != ArgumentType.List) { res = CheckSelf(binder, AstUtils.Convert(Expression, typeof(Method)), AstUtils.Constant(null)); } else { // list, check arg[0] and then return original list. If not a list, // or we have no items, then check against null & throw. res = CheckSelf( binder, AstUtils.Convert(Expression, typeof(Method)), Ast.Condition( Ast.AndAlso( Ast.TypeIs(args[0].Expression, typeof(IList<object>)), Ast.NotEqual( Ast.Property( Ast.Convert(args[0].Expression, typeof(ICollection)), typeof(ICollection).GetProperty("Count") ), AstUtils.Constant(0) ) ), Ast.Call( Ast.Convert(args[0].Expression, typeof(IList<object>)), typeof(IList<object>).GetMethod("get_Item"), AstUtils.Constant(0) ), AstUtils.Constant(null) ) ); } return res; }
public MSAst.Expression/*!*/ Invoke(Type/*!*/ resultType, CallSignature signature, params MSAst.Expression/*!*/[]/*!*/ args) { PythonInvokeBinder invoke = BinderState.Invoke(signature); switch (args.Length) { case 0: return Globals.Dynamic(invoke, resultType, LocalContext); case 1: return Globals.Dynamic(invoke, resultType, LocalContext, args[0]); case 2: return Globals.Dynamic(invoke, resultType, LocalContext, args[0], args[1]); case 3: return Globals.Dynamic(invoke, resultType, LocalContext, args[0], args[1], args[2]); default: return Globals.Dynamic( invoke, resultType, ArrayUtils.Insert(LocalContext, args) ); } }
// method call: public PythonOverloadResolver(PythonBinder binder, IList <DynamicMetaObject> args, CallSignature signature, Expression codeContext) : this(binder, args, signature, CallTypes.None, codeContext) { }
// method call: public PythonOverloadResolver(PythonBinder binder, IList <DynamicMetaObject> args, CallSignature signature, CallTypes callType, Expression codeContext) : base(binder, args, signature, callType) { Assert.NotNull(codeContext); _context = codeContext; }
public override LangElement Attribute(Span span, TypeRef classref, CallSignature signature = default(CallSignature)) => CountLE(base.Attribute(span, classref, signature));
public override DefaultOverloadResolver CreateOverloadResolver(IList <DynamicMetaObject> args, CallSignature signature, CallTypes callType) { return(new PythonOverloadResolver(_binder, args, signature, callType, _codeContext)); }
public override LangElement Call(Span span, TranslatedQualifiedName name, CallSignature signature, LangElement memberOfOpt) => CountLE(base.Call(span, name, signature, memberOfOpt));
public override LangElement Call(Span span, Name name, Span nameSpan, CallSignature signature, TypeRef typeRef) => CountLE(base.Call(span, name, nameSpan, signature, typeRef));
public override LangElement Call(Span span, LangElement nameExpr, CallSignature signature, LangElement memberOfOpt) => CountLE(base.Call(span, nameExpr, signature, memberOfOpt));
/// <summary> /// Makes test for param arrays and param dictionary parameters. /// </summary> private static BindingRestrictions MakeSplatTests(CallTypes callType, CallSignature signature, bool testTypes, IList<DynamicMetaObject> args) { BindingRestrictions res = BindingRestrictions.Empty; if (signature.HasListArgument()) { res = MakeParamsArrayTest(callType, signature, testTypes, args); } if (signature.HasDictionaryArgument()) { res = res.Merge(MakeParamsDictionaryTest(args, testTypes)); } return res; }
internal static DynamicMetaObject TranslateArguments(DynamicMetaObjectBinder call, Expression codeContext, DynamicMetaObject function, DynamicMetaObject /*!*/[] args, bool hasSelf, string name) { if (hasSelf) { args = ArrayUtils.RemoveFirst(args); } CallSignature sig = BindingHelpers.GetCallSignature(call); if (sig.HasDictionaryArgument()) { int index = sig.IndexOf(ArgumentType.Dictionary); DynamicMetaObject dict = args[index]; if (!(dict.Value is IDictionary) && dict.Value != null) { // The DefaultBinder only handles types that implement IDictionary. Here we have an // arbitrary user-defined mapping type. We'll convert it into a PythonDictionary // and then have an embedded dynamic site pass that dictionary through to the default // binder. DynamicMetaObject[] dynamicArgs = ArrayUtils.Insert(function, args); dynamicArgs[index + 1] = new DynamicMetaObject( Expression.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.UserMappingToPythonDictionary)), codeContext, args[index].Expression, AstUtils.Constant(name) ), BindingRestrictionsHelpers.GetRuntimeTypeRestriction(dict.Expression, dict.GetLimitType()), PythonOps.UserMappingToPythonDictionary(PythonContext.GetPythonContext(call).SharedContext, dict.Value, name) ); if (call is IPythonSite) { dynamicArgs = ArrayUtils.Insert( new DynamicMetaObject(codeContext, BindingRestrictions.Empty), dynamicArgs ); } return(new DynamicMetaObject( DynamicExpression.Dynamic( call, typeof(object), DynamicUtils.GetExpressions(dynamicArgs) ), BindingRestrictions.Combine(dynamicArgs).Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(dict.Expression, dict.GetLimitType())) )); } } if (sig.HasListArgument()) { int index = sig.IndexOf(ArgumentType.List); DynamicMetaObject str = args[index]; // TODO: ANything w/ __iter__ that's not an IList<object> if (!(str.Value is IList <object>) && str.Value is IEnumerable) { // The DefaultBinder only handles types that implement IList<object>. Here we have a // string. We'll convert it into a tuple // and then have an embedded dynamic site pass that tuple through to the default // binder. DynamicMetaObject[] dynamicArgs = ArrayUtils.Insert(function, args); dynamicArgs[index + 1] = new DynamicMetaObject( Expression.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.MakeTupleFromSequence)), Expression.Convert(args[index].Expression, typeof(object)) ), BindingRestrictions.Empty ); if (call is IPythonSite) { dynamicArgs = ArrayUtils.Insert( new DynamicMetaObject(codeContext, BindingRestrictions.Empty), dynamicArgs ); } return(new DynamicMetaObject( DynamicExpression.Dynamic( call, typeof(object), DynamicUtils.GetExpressions(dynamicArgs) ), function.Restrictions.Merge( BindingRestrictions.Combine(args).Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(str.Expression, str.GetLimitType())) ) )); } } return(null); }
public ArgumentValues(CallSignature signature, DynamicMetaObject/*!*/ self, DynamicMetaObject/*!*/[]/*!*/ args) { Self = self; Signature = signature; Arguments = args; }
public PythonInvokeBinder(PythonContext /*!*/ context, CallSignature signature) { _context = context; _signature = signature; }
// TODO: Rename Call to Invoke, obsolete Call // TODO: Invoke overloads should also take CallInfo objects to simplify use for languages which don't need CallSignature features. /// <summary> /// Provides default binding for performing a call on the specified meta objects. /// </summary> /// <param name="signature">The signature describing the call</param> /// <param name="target">The meta object to be called.</param> /// <param name="args"> /// Additional meta objects are the parameters for the call as specified by the CallSignature in the CallAction. /// </param> /// <returns>A MetaObject representing the call or the error.</returns> public DynamicMetaObject Call(CallSignature signature, DynamicMetaObject target, params DynamicMetaObject[] args) { return Call(signature, new DefaultOverloadResolverFactory(this), target, args); }
public LightThrowBinder(PythonContext /*!*/ context, CallSignature signature) : base(context, signature) { }
public abstract DefaultOverloadResolver CreateOverloadResolver(IList<DynamicMetaObject> args, CallSignature signature, CallTypes callType);
private DynamicMetaObject /*!*/ MakeSelfCall(DynamicMetaObjectBinder /*!*/ call, Expression /*!*/ codeContext, DynamicMetaObject /*!*/[] /*!*/ args) { BindingRestrictions selfRestrict = Restrictions.Merge( BindingRestrictionsHelpers.GetRuntimeTypeRestriction( Expression, LimitType ) ).Merge( BindingRestrictions.GetExpressionRestriction( Value.MakeBoundFunctionTest( AstUtils.Convert(Expression, typeof(BuiltinFunction)) ) ) ); Expression instance = Ast.Call( typeof(PythonOps).GetMethod("GetBuiltinFunctionSelf"), AstUtils.Convert( Expression, typeof(BuiltinFunction) ) ); DynamicMetaObject self = GetInstance(instance, CompilerHelpers.GetType(Value.BindingSelf)); return(Value.MakeBuiltinFunctionCall( call, codeContext, this, ArrayUtils.Insert(self, args), true, // has self selfRestrict, (newArgs) => { CallSignature signature = BindingHelpers.GetCallSignature(call); DynamicMetaObject res; PythonContext state = PythonContext.GetPythonContext(call); BindingTarget target; PythonOverloadResolver resolver; if (Value.IsReversedOperator) { resolver = new PythonOverloadResolver( state.Binder, newArgs, GetReversedSignature(signature), codeContext ); } else { resolver = new PythonOverloadResolver( state.Binder, self, args, signature, codeContext ); } res = state.Binder.CallMethod( resolver, Value.Targets, self.Restrictions, Value.Name, NarrowingLevel.None, Value.IsBinaryOperator ? PythonNarrowing.BinaryOperator : NarrowingLevel.All, out target ); return BindingHelpers.CheckLightThrow(call, res, target); } )); }
/// <summary> /// Creates statistic for ambient function. /// </summary> public FunctionStatistic(SymbolAtom namespaceName, SymbolAtom name, CallSignature callSignature, StringTable stringTable) : this(GetFullName(namespaceName, name), callSignature, stringTable) { }
internal static CallSignature GetReversedSignature(CallSignature signature) { return(new CallSignature(ArrayUtils.Append(signature.GetArgumentInfos(), new Argument(ArgumentType.Simple)))); }
private readonly CallSignature _signature; // the call signature for the call public LateBoundInitBinder(PythonType type, CallSignature signature) { _newType = type; _signature = signature; }
internal DynamicMetaObject /*!*/ InvokeFallback(DynamicMetaObject /*!*/ target, DynamicMetaObject /*!*/[] /*!*/ args, CallSignature sig, DynamicMetaObject errorSuggestion) { return (PythonProtocol.Call(this, target, args) ?? Context.Binder.Create(sig, target, args, AstUtils.Constant(_context.SharedContext)) ?? Context.Binder.Call(sig, errorSuggestion, new PythonOverloadResolverFactory(Context.Binder, AstUtils.Constant(_context.SharedContext)), target, args)); }
private static Expression NoInitCheckNoArgs(CallSignature signature, DynamicMetaObject self, DynamicMetaObject[] args) { int unusedCount = args.Length; Expression dictExpr = GetArgumentExpression(signature, ArgumentType.Dictionary, ref unusedCount, args); Expression listExpr = GetArgumentExpression(signature, ArgumentType.List, ref unusedCount, args); if (signature.IsSimple || unusedCount > 0) { if (args.Length > 0) { return Ast.Call( typeof(PythonOps).GetMethod("OldClassMakeCallError"), self.Expression ); } return AstUtils.Constant(null); } return Ast.Call( typeof(PythonOps).GetMethod("OldClassCheckCallError"), self.Expression, dictExpr, listExpr ); }
public static Expression /*!*/ Invoke(Expression codeContext, PythonContext /*!*/ binder, Type /*!*/ resultType, CallSignature signature, params Expression /*!*/[] /*!*/ args) { return(DynamicExpression.Dynamic( binder.Invoke( signature ), resultType, ArrayUtils.Insert(codeContext, args) )); }
public TjsOverloadResolver(TjsBinder binder, IList <DynamicMetaObject> args, CallSignature signature, CallTypes callType) : base(binder, args, signature, callType) { }
/// <summary> /// Creating a Python type involves calling __new__ and __init__. We resolve them /// and generate calls to either the builtin funcions directly or embed sites which /// call the slots at runtime. /// </summary> private DynamicMetaObject /*!*/ MakePythonTypeCall(DynamicMetaObjectBinder /*!*/ call, Expression /*!*/ codeContext, DynamicMetaObject /*!*/[] /*!*/ args) { ValidationInfo valInfo = MakeVersionCheck(); DynamicMetaObject self = new RestrictedMetaObject( AstUtils.Convert(Expression, LimitType), BindingRestrictionsHelpers.GetRuntimeTypeRestriction(Expression, LimitType), Value ); CallSignature sig = BindingHelpers.GetCallSignature(call); ArgumentValues ai = new ArgumentValues(sig, self, args); NewAdapter newAdapter; InitAdapter initAdapter; if (TooManyArgsForDefaultNew(call, args)) { return(MakeIncorrectArgumentsForCallError(call, ai, valInfo)); } else if (Value.UnderlyingSystemType.IsGenericTypeDefinition) { return(MakeGenericTypeDefinitionError(call, ai, valInfo)); } else if (Value.HasAbstractMethods(PythonContext.GetPythonContext(call).SharedContext)) { return(MakeAbstractInstantiationError(call, ai, valInfo)); } DynamicMetaObject translated = BuiltinFunction.TranslateArguments(call, codeContext, self, args, false, Value.Name); if (translated != null) { return(translated); } GetAdapters(ai, call, codeContext, out newAdapter, out initAdapter); PythonContext state = PythonContext.GetPythonContext(call); // get the expression for calling __new__ DynamicMetaObject createExpr = newAdapter.GetExpression(state.Binder); if (createExpr.Expression.Type == typeof(void)) { return(BindingHelpers.AddDynamicTestAndDefer( call, createExpr, args, valInfo )); } Expression res; BindingRestrictions additionalRestrictions = BindingRestrictions.Empty; if (!Value.IsSystemType && (!(newAdapter is DefaultNewAdapter) || HasFinalizer(call))) { // we need to dynamically check the return value to see if it's a subtype of // the type that we are calling. If it is then we need to call __init__/__del__ // for the actual returned type. res = DynamicExpression.Dynamic( Value.GetLateBoundInitBinder(sig), typeof(object), ArrayUtils.Insert( codeContext, Expression.Convert(createExpr.Expression, typeof(object)), DynamicUtils.GetExpressions(args) ) ); additionalRestrictions = createExpr.Restrictions; } else { // just call the __init__ method, built-in types currently have // no wacky return values which don't return the derived type. // then get the statement for calling __init__ ParameterExpression allocatedInst = Ast.Variable(createExpr.GetLimitType(), "newInst"); Expression tmpRead = allocatedInst; DynamicMetaObject initCall = initAdapter.MakeInitCall( state.Binder, new RestrictedMetaObject( AstUtils.Convert(allocatedInst, Value.UnderlyingSystemType), createExpr.Restrictions ) ); List <Expression> body = new List <Expression>(); Debug.Assert(!HasFinalizer(call)); // add the call to init if we need to if (initCall.Expression != tmpRead) { // init can fail but if __new__ returns a different type // no exception is raised. DynamicMetaObject initStmt = initCall; if (body.Count == 0) { body.Add( Ast.Assign(allocatedInst, createExpr.Expression) ); } if (!Value.UnderlyingSystemType.IsAssignableFrom(createExpr.Expression.Type)) { // return type of object, we need to check the return type before calling __init__. body.Add( AstUtils.IfThen( Ast.TypeIs(allocatedInst, Value.UnderlyingSystemType), initStmt.Expression ) ); } else { // just call the __init__ method, no type check necessary (TODO: need null check?) body.Add(initStmt.Expression); } } // and build the target from everything we have if (body.Count == 0) { res = createExpr.Expression; } else { body.Add(allocatedInst); res = Ast.Block(body); } res = Ast.Block(new ParameterExpression[] { allocatedInst }, res); additionalRestrictions = initCall.Restrictions; } return(BindingHelpers.AddDynamicTestAndDefer( call, new DynamicMetaObject( res, self.Restrictions.Merge(additionalRestrictions) ), ArrayUtils.Insert(this, args), valInfo )); }
private static BindingRestrictions MakeSplatTests(CallTypes callType, CallSignature signature, IList<DynamicMetaObject> args) { return MakeSplatTests(callType, signature, false, args); }
public ArgumentValues(CallSignature signature, DynamicMetaObject /*!*/ self, DynamicMetaObject /*!*/[] /*!*/ args) { Self = self; Signature = signature; Arguments = args; }
/// <summary> /// Pulls out the right argument to build the splat test. MakeParamsTest makes the actual test. /// </summary> private static BindingRestrictions MakeParamsArrayTest(CallTypes callType, CallSignature signature, bool testTypes, IList<DynamicMetaObject> args) { int listIndex = signature.IndexOf(ArgumentType.List); Debug.Assert(listIndex != -1); if (callType == CallTypes.ImplicitInstance) { listIndex++; } return MakeParamsTest(args[listIndex], testTypes); }
/// <summary> /// Creates statistic for a user-defined function or to a member function. /// </summary> public FunctionStatistic(List <SymbolAtom> fullName, CallSignature callSignature, StringTable stringTable) : this(GetFullNameAsString(fullName, callSignature, stringTable)) { }
public override DefaultOverloadResolver CreateOverloadResolver(IList<DynamicMetaObject> args, CallSignature signature, CallTypes callType) { return new DefaultOverloadResolver(_binder, args, signature, callType); }
/// <inheritdoc /> public override string ToDebugString() { return($"{CallSignature.ToDebugString()} => {Body?.ToDebugString()}"); }
private DynamicMetaObject InvokeWorker(DynamicMetaObjectBinder/*!*/ callAction, DynamicMetaObject/*!*/[] args) { PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Method Invoke " + args.Length); PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "Method"); CallSignature signature = BindingHelpers.GetCallSignature(callAction); DynamicMetaObject self = Restrict(typeof(Method)); BindingRestrictions restrictions = self.Restrictions; DynamicMetaObject func = GetMetaFunction(self); DynamicMetaObject call; if (Value.im_self == null) { // restrict to null self (Method is immutable so this is an invariant test) restrictions = restrictions.Merge( BindingRestrictions.GetExpressionRestriction( Ast.Equal( GetSelfExpression(self), AstUtils.Constant(null) ) ) ); if (args.Length == 0) { // this is an error, we pass null which will throw the normal error call = new DynamicMetaObject( Ast.Call( typeof(PythonOps).GetMethod("MethodCheckSelf"), PythonContext.GetCodeContext(callAction), self.Expression, AstUtils.Constant(null) ), restrictions ); } else { // this may or may not be an error call = new DynamicMetaObject( Ast.Block( MakeCheckSelf(callAction, signature, args), Ast.Dynamic( PythonContext.GetPythonContext(callAction).Invoke( BindingHelpers.GetCallSignature(callAction) ), typeof(object), ArrayUtils.Insert(PythonContext.GetCodeContext(callAction), DynamicUtils.GetExpressions(ArrayUtils.Insert(func, args))) ) ), BindingRestrictions.Empty ); /*call = func.Invoke(callAction, ArrayUtils.Insert(func, args)); call = new MetaObject( Ast.Comma( Ast.Call( typeof(PythonOps).GetMethod("MethodCheckSelf"), self.Expression, args[0].Expression ), call.Expression ), call.Restrictions );*/ } } else { // restrict to non-null self (Method is immutable so this is an invariant test) restrictions = restrictions.Merge( BindingRestrictions.GetExpressionRestriction( Ast.NotEqual( GetSelfExpression(self), AstUtils.Constant(null) ) ) ); DynamicMetaObject im_self = GetMetaSelf(self); DynamicMetaObject[] newArgs = ArrayUtils.Insert(func, im_self, args); CallSignature newSig = new CallSignature(ArrayUtils.Insert(new Argument(ArgumentType.Simple), signature.GetArgumentInfos())); call = new DynamicMetaObject( Ast.Dynamic( PythonContext.GetPythonContext(callAction).Invoke( newSig ), typeof(object), ArrayUtils.Insert(PythonContext.GetCodeContext(callAction), DynamicUtils.GetExpressions(newArgs)) ), BindingRestrictions.Empty ); /* call = func.Invoke( new CallBinder( PythonContext.GetBinderState(callAction), newSig ), newArgs );*/ } if (call.HasValue) { return new DynamicMetaObject( call.Expression, restrictions.Merge(call.Restrictions), call.Value ); } else { return new DynamicMetaObject( call.Expression, restrictions.Merge(call.Restrictions) ); } }
/// <summary> /// Creates ambient function. /// </summary> public static FunctionLikeExpression CreateAmbient(SymbolAtom name, CallSignature signature, InvokeAmbient fun, [NotNull] FunctionStatistic statistics) { Contract.Requires(name.IsValid); return(new FunctionLikeExpression(name, signature, fun, default(LineInfo), statistics)); }
/// <summary> /// Provides default binding for performing a call on the specified meta objects. /// </summary> /// <param name="signature">The signature describing the call</param> /// <param name="target">The meta object to be called.</param> /// <param name="args"> /// Additional meta objects are the parameters for the call as specified by the CallSignature in the CallAction. /// </param> /// <param name="resolverFactory">Overload resolver factory.</param> /// <returns>A MetaObject representing the call or the error.</returns> public DynamicMetaObject Call(CallSignature signature, OverloadResolverFactory resolverFactory, DynamicMetaObject target, params DynamicMetaObject[] args) { return Call(signature, null, resolverFactory, target, args); }
/// <summary> /// Creates a callable expression for the ambient function. /// </summary> /// <param name="name">Name of the function if applicable</param> /// <param name="callSignature">Signature of the lambda.</param> /// <param name="ambient">Delegate to serve as lambda's body.</param> /// <param name="location">Location of delegates definition.</param> /// <param name="statistic">Function invocation statistics.</param> private FunctionLikeExpression(SymbolAtom name, [NotNull] CallSignature callSignature, InvokeAmbient ambient, LineInfo location, [NotNull] FunctionStatistic statistic) : this(name, callSignature : callSignature, body : null, captures : 0, locals : callSignature.Parameters.Count, fun : ambient, location : location, statistic : statistic) { Contract.Requires(callSignature != null); Contract.Requires(ambient != null); }
internal static CallSignature GetReversedSignature(CallSignature signature) { return new CallSignature(ArrayUtils.Append(signature.GetArgumentInfos(), new Argument(ArgumentType.Simple))); }
private DynamicMetaObject InvokeWorker(DynamicMetaObjectBinder /*!*/ callAction, DynamicMetaObject /*!*/[] args) { PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Method Invoke " + args.Length); PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "Method"); CallSignature signature = BindingHelpers.GetCallSignature(callAction); DynamicMetaObject self = Restrict(typeof(Method)); BindingRestrictions restrictions = self.Restrictions; DynamicMetaObject func = GetMetaFunction(self); DynamicMetaObject call; if (Value.im_self == null) { // restrict to null self (Method is immutable so this is an invariant test) restrictions = restrictions.Merge( BindingRestrictions.GetExpressionRestriction( Ast.Equal( GetSelfExpression(self), AstUtils.Constant(null) ) ) ); if (args.Length == 0) { // this is an error, we pass null which will throw the normal error call = new DynamicMetaObject( Ast.Call( typeof(PythonOps).GetMethod("MethodCheckSelf"), PythonContext.GetCodeContext(callAction), self.Expression, AstUtils.Constant(null) ), restrictions ); } else { // this may or may not be an error call = new DynamicMetaObject( Ast.Block( MakeCheckSelf(callAction, signature, args), DynamicExpression.Dynamic( PythonContext.GetPythonContext(callAction).Invoke( BindingHelpers.GetCallSignature(callAction) ).GetLightExceptionBinder(callAction.SupportsLightThrow()), typeof(object), ArrayUtils.Insert(PythonContext.GetCodeContext(callAction), DynamicUtils.GetExpressions(ArrayUtils.Insert(func, args))) ) ), BindingRestrictions.Empty ); /*call = func.Invoke(callAction, ArrayUtils.Insert(func, args)); * call = new MetaObject( * Ast.Comma( * Ast.Call( * typeof(PythonOps).GetMethod("MethodCheckSelf"), * self.Expression, * args[0].Expression * ), * call.Expression * ), * call.Restrictions * );*/ } } else { // restrict to non-null self (Method is immutable so this is an invariant test) restrictions = restrictions.Merge( BindingRestrictions.GetExpressionRestriction( Ast.NotEqual( GetSelfExpression(self), AstUtils.Constant(null) ) ) ); DynamicMetaObject im_self = GetMetaSelf(self); DynamicMetaObject[] newArgs = ArrayUtils.Insert(func, im_self, args); CallSignature newSig = new CallSignature(ArrayUtils.Insert(new Argument(ArgumentType.Simple), signature.GetArgumentInfos())); call = new DynamicMetaObject( DynamicExpression.Dynamic( PythonContext.GetPythonContext(callAction).Invoke( newSig ).GetLightExceptionBinder(callAction.SupportsLightThrow()), typeof(object), ArrayUtils.Insert(PythonContext.GetCodeContext(callAction), DynamicUtils.GetExpressions(newArgs)) ), BindingRestrictions.Empty ); /* * call = func.Invoke( * new CallBinder( * PythonContext.GetBinderState(callAction), * newSig * ), * newArgs * );*/ } if (call.HasValue) { return(new DynamicMetaObject( call.Expression, restrictions.Merge(call.Restrictions), call.Value )); } else { return(new DynamicMetaObject( call.Expression, restrictions.Merge(call.Restrictions) )); } }
/// <summary> /// Gets a TargetInfo object for performing a call on this object. /// /// If this object is a delegate we bind to the Invoke method. /// If this object is a MemberGroup or MethodGroup we bind to the methods in the member group. /// If this object is a BoundMemberTracker we bind to the methods with the bound instance. /// If the underlying type has defined an operator Call method we'll bind to that method. /// </summary> private TargetInfo GetTargetInfo(CallSignature signature, DynamicMetaObject target, DynamicMetaObject[] args) { Debug.Assert(target.HasValue); object objTarget = target.Value; return TryGetDelegateTargets(target, args, objTarget as Delegate) ?? TryGetMemberGroupTargets(target, args, objTarget as MemberGroup) ?? TryGetMethodGroupTargets(target, args, objTarget as MethodGroup) ?? TryGetBoundMemberTargets(target, args, objTarget as BoundMemberTracker) ?? TryGetOperatorTargets(target, args, target, signature); }
public static CallInfo GetCallInfoForCallSignature(CallSignature signature) { return(new CallInfo(signature.ArgumentCount, signature.GetArgumentNames())); }
/// <summary> /// Provides default binding for performing a call on the specified meta objects. /// </summary> /// <param name="signature">The signature describing the call</param> /// <param name="target">The object to be called</param> /// <param name="args"> /// Additional meta objects are the parameters for the call as specified by the CallSignature in the CallAction. /// </param> /// <returns>A MetaObject representing the call or the error.</returns> public DynamicMetaObject Call(CallSignature signature, DynamicMetaObject target, params DynamicMetaObject[] args) { return Call(signature, new ParameterBinder(this), target, args); }
public abstract DefaultOverloadResolver CreateOverloadResolver(IList <DynamicMetaObject> args, CallSignature signature, CallTypes callType);
public override DefaultOverloadResolver CreateOverloadResolver(IList <DynamicMetaObject> args, CallSignature signature, CallTypes callType) { return(new DefaultOverloadResolver( _context.DefaultBinderState.Binder, args, signature, callType)); }
public TjsInvokeBinder(TjsContext context, CallSignature signature) : base(Binders.GetCallInfoForCallSignature(signature)) { _context = context; Signature = signature; }