public override MetaObject /*!*/ Bind(MetaObject /*!*/ context, MetaObject /*!*/[] /*!*/ args) { var mo = new MetaObjectBuilder(); SetRule(mo, new CallArguments(context, args, Signature)); return(mo.CreateMetaObject(this, context, args)); }
public override DynamicMetaObject /*!*/ FallbackInvoke(DynamicMetaObject /*!*/ target, DynamicMetaObject /*!*/[] /*!*/ args, DynamicMetaObject errorSuggestion) { // Used in combination with GetMember to compose InvokeMember operation. // Gets here only if the target is not a callable meta-object. var metaBuilder = new MetaObjectBuilder(this, target, args); var callArgs = new CallArguments(_context, target, args, CallInfo); metaBuilder.AddTypeRestriction(target.GetLimitType(), target.Expression); RubyOverloadResolver.NormalizeArguments(metaBuilder, callArgs, 0, 0); if (!metaBuilder.Error) { // no arguments => just return the target: metaBuilder.Result = target.Expression; } else { // any arguments found (expected none): metaBuilder.SetMetaResult(errorSuggestion, false); } return(metaBuilder.CreateMetaObject(this)); }
public override DynamicMetaObject /*!*/ FallbackGetMember(DynamicMetaObject /*!*/ target, DynamicMetaObject errorSuggestion) { #if !SILVERLIGHT DynamicMetaObject result; if (Microsoft.Scripting.ComInterop.ComBinder.TryBindGetMember(this, target, out result)) { return(result); } #endif var metaBuilder = new MetaObjectBuilder(target); var callArgs = new CallArguments(_context, target, DynamicMetaObject.EmptyMetaObjects, _CallInfo); // See InvokeMember binder for explanation. bool tryAlternateBinding = _unmangled != null && errorSuggestion == null; if (!RubyCallAction.BuildAccess(metaBuilder, _originalName ?? Name, callArgs, errorSuggestion == null && !tryAlternateBinding, true)) { Debug.Assert(errorSuggestion != null || tryAlternateBinding); if (tryAlternateBinding) { metaBuilder.SetMetaResult(target.BindGetMember(_unmangled), true); } else { // method wasn't found so we didn't do any operation with arguments that would require restrictions converted to conditions: metaBuilder.SetMetaResult(errorSuggestion, false); } } return(metaBuilder.CreateMetaObject(this)); }
public override DynamicMetaObject /*!*/ FallbackGetMember(DynamicMetaObject /*!*/ target, DynamicMetaObject errorSuggestion) { if (_unmangled != null) { // TODO: errorSuggestion? return(_unmangled.Bind(target, DynamicMetaObject.EmptyMetaObjects)); } #if !SILVERLIGHT DynamicMetaObject result; if (Microsoft.Scripting.ComInterop.ComBinder.TryBindGetMember(this, target, out result)) { return(result); } #endif var metaBuilder = new MetaObjectBuilder(target); var callArgs = new CallArguments(_context, target, DynamicMetaObject.EmptyMetaObjects, _CallInfo); if (!RubyCallAction.BuildAccess(metaBuilder, _originalName ?? Name, callArgs, errorSuggestion == null, true)) { Debug.Assert(errorSuggestion != null); metaBuilder.SetMetaResult(errorSuggestion, false); } return(metaBuilder.CreateMetaObject(this)); }
public override MetaObject /*!*/ Bind(MetaObject /*!*/ context, MetaObject /*!*/[] /*!*/ args) { var mo = new MetaObjectBuilder(); Bind(mo, _methodName, new CallArguments(context, args, _signature)); return(mo.CreateMetaObject(this, context, args)); }
internal static DynamicMetaObject FallbackInvokeMember(IInteropBinder /*!*/ binder, string /*!*/ methodName, CallInfo /*!*/ callInfo, DynamicMetaObject /*!*/ target, DynamicMetaObject /*!*/[] /*!*/ args, DynamicMetaObject errorSuggestion, InvokeMember alternateBinder) { var metaBuilder = new MetaObjectBuilder(binder, target, args); var callArgs = new CallArguments(binder.Context, target, args, callInfo); // // If we are called with no errorSuggestion we attempt to bind the alternate name since the current binding failed // (unless we successfully bind to a COM object method or Ruby/CLR method defined on the target meta-object). // If we already have an errorSuggestion we use it as it represents a valid binding and no alternate name lookups are thus necessary. // // For example, DynamicObject InvokeMember calls our FallbackInvokeMember 4 times: // // 1) binder.fallback(..., errorSuggestion: null) // -> DynamicObject.BindInvokeMember(altBinder) // 2) altBinder.fallback(..., errorSuggestion: null) // -> [[ error ]] // // 3) altBinder.fallback(..., errorSuggestion: [[ // TryInvokeMember(altName, out result) // ? result // : TryGetMember(altName, out result) // ? altBinder.FallbackInvoke(result) // : [[ error ]] // ]]) // -> errorSuggestion // // 4) binder.fallback(..., errorSuggestion: [[ // TryInvokeMember(name, out result) // ? result // : TryGetMember(name, out result) // ? binder.FallbackInvoke(result) // TryInvokeMember(altName, out result) // ? result // : TryGetMember(altName, out result) // ? altBinder.FallbackInvoke(result) // : [[ error ]] // // ]]) // -> errorSuggestion // bool tryAlternateBinding = alternateBinder != null && errorSuggestion == null; if (!RubyCallAction.BuildCall(metaBuilder, methodName, callArgs, errorSuggestion == null && !tryAlternateBinding, true)) { Debug.Assert(errorSuggestion != null || tryAlternateBinding); if (tryAlternateBinding) { metaBuilder.SetMetaResult(target.BindInvokeMember(alternateBinder, args), true); } else { // method wasn't found so we didn't do any operation with arguments that would require restrictions converted to conditions: metaBuilder.SetMetaResult(errorSuggestion, false); } } return(metaBuilder.CreateMetaObject((DynamicMetaObjectBinder)binder)); }
public override DynamicMetaObject/*!*/ Bind(DynamicMetaObject/*!*/ scopeOrContextOrTarget, DynamicMetaObject/*!*/[]/*!*/ args) { var callArgs = new CallArguments(_context, scopeOrContextOrTarget, args, Signature); var metaBuilder = new MetaObjectBuilder(this, args); if (IsForeignMetaObject(callArgs.MetaTarget)) { return InteropBind(metaBuilder, callArgs); } Build(metaBuilder, callArgs, true); return metaBuilder.CreateMetaObject(this); }
public override DynamicMetaObject/*!*/ Bind(DynamicMetaObject/*!*/ context, DynamicMetaObject/*!*/[]/*!*/ args) { var callArgs = new CallArguments(context, args, Signature); // TODO: COM interop if (IsForeignMetaObject(callArgs.MetaTarget)) { return InteropBind(callArgs); } var metaBuilder = new MetaObjectBuilder(); Build(metaBuilder, callArgs); return metaBuilder.CreateMetaObject(this); }
public static DynamicMetaObject/*!*/ Bind(RubyContext/*!*/ context, InvokeBinder/*!*/ binder, RubyMetaObject/*!*/ target, DynamicMetaObject/*!*/[]/*!*/ args, Action<MetaObjectBuilder, CallArguments>/*!*/ buildInvoke) { RubyCallSignature callSignature; if (RubyCallSignature.TryCreate(binder.CallInfo, out callSignature)) { return binder.FallbackInvoke(target, args); } var metaBuilder = new MetaObjectBuilder(); buildInvoke(metaBuilder, new CallArguments(target.CreateMetaContext(), target, args, callSignature)); return metaBuilder.CreateMetaObject(binder); }
private DynamicMetaObject InteropBind(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args) { // TODO: argument count limit depends on the binder! // TODO: pass block as the last (before RHS arg?) parameter/ignore block if args not accepting block: var normalizedArgs = RubyOverloadResolver.NormalizeArguments(metaBuilder, args, 0, Int32.MaxValue); if (!metaBuilder.Error) { MethodInfo postConverter; var interopBinder = GetInteropBinder(args.RubyContext, normalizedArgs, out postConverter); if (interopBinder != null) { Type resultType; var result = interopBinder.Bind(args.MetaTarget, ArrayUtils.MakeArray(normalizedArgs)); metaBuilder.SetMetaResult(result, args); if (postConverter != null) { // TODO: do better? var paramType = postConverter.GetParameters()[0].ParameterType; metaBuilder.Result = Ast.Call(null, postConverter, AstUtils.Convert(metaBuilder.Result, paramType)); resultType = postConverter.ReturnType; } else { resultType = interopBinder.ReturnType; } return(metaBuilder.CreateMetaObject(interopBinder, resultType)); } else { // interop protocol not supported for this binder -> ignore IDO and treat it as a CLR object: return(null); } } return(metaBuilder.CreateMetaObject(this)); }
public static MetaObject TryBind(RubyContext /*!*/ context, GetMemberBinder /*!*/ binder, MetaObject /*!*/ target) { Assert.NotNull(context, target); var metaBuilder = new MetaObjectBuilder(); var contextExpression = Ast.Constant(context); metaBuilder.AddTargetTypeTest(target.Value, target.Expression, context, contextExpression); RubyMemberInfo method = context.ResolveMethod(target.Value, binder.Name, true).InvalidateSitesOnOverride(); if (method != null && RubyModule.IsMethodVisible(method, false)) { // we need to create a bound member: metaBuilder.Result = Ast.Constant(new RubyMethod(target.Value, method, binder.Name)); } else { // TODO: // We need to throw an exception if we don't find method_missing so that our version update optimization works: // This limits interop with other languages. // // class B CLR type with method 'foo' // class C < B Ruby class // x = C.new // // 1. x.GET("foo") from Ruby // No method found or CLR method found -> fallback to Python // Python might see its method foo or might just fallback to .NET, // in any case it will add rule [1] with restriction on type of C w/o Ruby version check. // 2. B.define_method("foo") // This doesn't update C due to the optimization (there is no overridden method foo in C). // 3. x.GET("foo") from Ruby // This will not invoke the binder since the rule [1] is still valid. // object symbol = SymbolTable.StringToId(binder.Name); RubyCallAction.BindToMethodMissing(metaBuilder, binder.Name, new CallArguments( new MetaObject(contextExpression, Restrictions.Empty, context), new[] { target, new MetaObject(Ast.Constant(symbol), Restrictions.Empty, symbol) }, RubyCallSignature.Simple(1) ), method != null ); } // TODO: we should return null if we fail, we need to throw exception for now: return(metaBuilder.CreateMetaObject(binder, MetaObject.EmptyMetaObjects)); }
internal static DynamicMetaObject FallbackInvokeMember(IInteropBinder /*!*/ binder, string /*!*/ methodName, CallInfo /*!*/ callInfo, DynamicMetaObject /*!*/ target, DynamicMetaObject /*!*/[] /*!*/ args, DynamicMetaObject errorSuggestion) { var metaBuilder = new MetaObjectBuilder(binder, target, args); var callArgs = new CallArguments(binder.Context, target, args, callInfo); if (!RubyCallAction.BuildCall(metaBuilder, methodName, callArgs, errorSuggestion == null, true)) { Debug.Assert(errorSuggestion != null); // method wasn't found so we didn't do any operation with arguments that would require restrictions converted to conditions: metaBuilder.SetMetaResult(errorSuggestion, false); } return(metaBuilder.CreateMetaObject((DynamicMetaObjectBinder)binder)); }
public static DynamicMetaObject /*!*/ Bind(DynamicMetaObject /*!*/ context, GetIndexBinder /*!*/ binder, DynamicMetaObject /*!*/ target, DynamicMetaObject /*!*/[] /*!*/ indexes, Func <DynamicMetaObject, DynamicMetaObject[], DynamicMetaObject> /*!*/ fallback) { Debug.Assert(fallback != null); var callArgs = new CallArguments(context, target, indexes, RubyCallSignature.Interop(indexes.Length)); var metaBuilder = new MetaObjectBuilder(target, indexes); if (!RubyCallAction.BuildCall(metaBuilder, "[]", callArgs, false, false)) { metaBuilder.SetMetaResult(fallback(target, indexes), false); } return(metaBuilder.CreateMetaObject(binder)); }
public static DynamicMetaObject /*!*/ Bind(DynamicMetaObject /*!*/ context, SetMemberBinder /*!*/ binder, DynamicMetaObject /*!*/ target, DynamicMetaObject /*!*/ value, Func <DynamicMetaObject, DynamicMetaObject, DynamicMetaObject> /*!*/ fallback) { Debug.Assert(fallback != null); var args = new[] { value }; var callArgs = new CallArguments(context, target, args, RubyCallSignature.Interop(1)); var metaBuilder = new MetaObjectBuilder(target, args); if (!RubyCallAction.BuildCall(metaBuilder, binder.Name + "=", callArgs, false, false)) { metaBuilder.SetMetaResult(fallback(target, value), false); } return(metaBuilder.CreateMetaObject(binder)); }
public static DynamicMetaObject /*!*/ Bind(DynamicMetaObject /*!*/ context, GetMemberBinder /*!*/ binder, DynamicMetaObject /*!*/ target, Func <DynamicMetaObject, DynamicMetaObject> /*!*/ fallback) { Debug.Assert(fallback != null); var callArgs = new CallArguments(context, target, DynamicMetaObject.EmptyMetaObjects, RubyCallSignature.Interop(0)); var metaBuilder = new MetaObjectBuilder(target); if (!RubyCallAction.BuildAccess(metaBuilder, binder.Name, callArgs, false, false)) { // TODO: error suggestion? metaBuilder.SetMetaResult(fallback(target), false); } return(metaBuilder.CreateMetaObject(binder)); }
public static DynamicMetaObject /*!*/ Bind(DynamicMetaObject /*!*/ context, string /*!*/ methodName, CallInfo /*!*/ callInfo, DynamicMetaObjectBinder /*!*/ binder, DynamicMetaObject /*!*/ target, DynamicMetaObject /*!*/[] /*!*/ args, Func <DynamicMetaObject, DynamicMetaObject[], DynamicMetaObject> /*!*/ fallback) { Debug.Assert(fallback != null); var callArgs = new CallArguments(context, target, args, RubyCallSignature.Interop(callInfo.ArgumentCount)); var metaBuilder = new MetaObjectBuilder(target, args); if (!RubyCallAction.BuildCall(metaBuilder, methodName, callArgs, false, false)) { // TODO: error suggestion? metaBuilder.SetMetaResult(fallback(target, args), false); } return(metaBuilder.CreateMetaObject(binder)); }
public static DynamicMetaObject /*!*/ Bind(InvokeBinder /*!*/ binder, RubyMetaObject /*!*/ target, DynamicMetaObject /*!*/[] /*!*/ args, Action <MetaObjectBuilder, CallArguments> /*!*/ buildInvoke) { RubyCallSignature callSignature; if (RubyCallSignature.TryCreate(binder.CallInfo, out callSignature)) { return(binder.FallbackInvoke(target, args)); } var callArgs = new CallArguments(target.CreateMetaContext(), target, args, callSignature); var metaBuilder = new MetaObjectBuilder(target, args); buildInvoke(metaBuilder, callArgs); return(metaBuilder.CreateMetaObject(binder)); }
public override MetaObject/*!*/ BindInvoke(InvokeBinder/*!*/ action, MetaObject/*!*/[]/*!*/ args) { RubyCallSignature callSignature; if (RubyCallSignature.TryCreate(action.Arguments, out callSignature)) { return action.FallbackInvoke(this, args); } var context = new MetaObject( Methods.GetContextFromProc.OpCall(AstUtils.Convert(Expression, typeof(Proc))), Restrictions.Empty, RubyOps.GetContextFromProc((Proc)Value) ); var metaBuilder = new MetaObjectBuilder(); Proc.SetCallActionRule(metaBuilder, new CallArguments(context, this, args, callSignature), true); return metaBuilder.CreateMetaObject(action, args); }
public override DynamicMetaObject /*!*/ Bind(DynamicMetaObject /*!*/ scopeOrContextOrTargetOrArgArray, DynamicMetaObject /*!*/[] /*!*/ args) { PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Ruby: " + GetType().Name + Signature.ToString() + ": Bind"); var callArgs = new CallArguments(_context, scopeOrContextOrTargetOrArgArray, args, Signature); var metaBuilder = new MetaObjectBuilder(this, args); DynamicMetaObject interopBinding; if (IsForeignMetaObject(callArgs.MetaTarget) && (interopBinding = InteropBind(metaBuilder, callArgs)) != null) { return(interopBinding); } Build(metaBuilder, callArgs, true); return(metaBuilder.CreateMetaObject(this)); }
public static DynamicMetaObject TryBind(RubyContext/*!*/ context, CreateInstanceBinder/*!*/ binder, DynamicMetaObject/*!*/ target, DynamicMetaObject/*!*/[]/*!*/ args) { Assert.NotNull(context, binder, target, args); var metaBuilder = new MetaObjectBuilder(); RubyCallAction.Bind(metaBuilder, "new", new CallArguments( new DynamicMetaObject(AstUtils.Constant(context), BindingRestrictions.Empty, context), target, args, RubyCallSignature.Simple(args.Length) ) ); // TODO: we should return null if we fail, we need to throw exception due to version update optimization: return metaBuilder.CreateMetaObject(binder, DynamicMetaObject.EmptyMetaObjects); }
public static DynamicMetaObject TryBind(RubyContext/*!*/ context, InvokeMemberBinder/*!*/ binder, DynamicMetaObject/*!*/ target, DynamicMetaObject/*!*/[]/*!*/ args) { Assert.NotNull(context, target); var metaBuilder = new MetaObjectBuilder(); RubyCallAction.Bind(metaBuilder, binder.Name, new CallArguments( new DynamicMetaObject(AstUtils.Constant(context), BindingRestrictions.Empty, context), target, args, RubyCallSignature.Simple(binder.CallInfo.ArgumentCount) ) ); // TODO: we should return null if we fail, we need to throw exception for now: return metaBuilder.CreateMetaObject(binder, DynamicMetaObject.EmptyMetaObjects); }
public static MetaObject TryBind(RubyContext /*!*/ context, CreateInstanceBinder /*!*/ binder, MetaObject /*!*/ target, MetaObject /*!*/[] /*!*/ args) { Assert.NotNull(context, binder, target, args); var metaBuilder = new MetaObjectBuilder(); RubyCallAction.Bind(metaBuilder, "new", new CallArguments( new MetaObject(Ast.Constant(context), Restrictions.Empty, context), target, args, RubyCallSignature.Simple(args.Length) ) ); // TODO: we should return null if we fail, we need to throw exception due to version update optimization: return(metaBuilder.CreateMetaObject(binder, MetaObject.EmptyMetaObjects)); }
public static MetaObject TryBind(RubyContext /*!*/ context, InvokeMemberBinder /*!*/ binder, MetaObject /*!*/ target, MetaObject /*!*/[] /*!*/ args) { Assert.NotNull(context, target); var metaBuilder = new MetaObjectBuilder(); RubyCallAction.Bind(metaBuilder, binder.Name, new CallArguments( new MetaObject(Ast.Constant(context), Restrictions.Empty, context), target, args, RubyCallSignature.Simple(binder.Arguments.Count) ) ); // TODO: we should return null if we fail, we need to throw exception for now: return(metaBuilder.CreateMetaObject(binder, MetaObject.EmptyMetaObjects)); }
public override DynamicMetaObject/*!*/ BindInvoke(InvokeBinder/*!*/ action, DynamicMetaObject/*!*/[]/*!*/ args) { RubyCallSignature callSignature; if (RubyCallSignature.TryCreate(action.Arguments, out callSignature)) { return action.FallbackInvoke(this, args); } var self = (RubyMethod)Value; var context = new DynamicMetaObject( Methods.GetContextFromMethod.OpCall(AstUtils.Convert(Expression, typeof(RubyMethod))), BindingRestrictions.Empty, RubyOps.GetContextFromMethod(self) ); var metaBuilder = new MetaObjectBuilder(); Method.SetRuleForCall(metaBuilder, new CallArguments(context, this, args, callSignature)); return metaBuilder.CreateMetaObject(action, args); }
public override DynamicMetaObject /*!*/ FallbackConvert(DynamicMetaObject /*!*/ target, DynamicMetaObject errorSuggestion) { #if !SILVERLIGHT DynamicMetaObject result; if (Microsoft.Scripting.ComInterop.ComBinder.TryConvert(this, target, out result)) { return(result); } #endif var metaBuilder = new MetaObjectBuilder(this, target, DynamicMetaObject.EmptyMetaObjects); if (!GenericConversionAction.BuildConversion(metaBuilder, target, Ast.Constant(_context), Type, errorSuggestion == null)) { Debug.Assert(errorSuggestion != null); // no conversion applicable so we didn't do any operation with arguments that would require restrictions converted to conditions: metaBuilder.SetMetaResult(errorSuggestion, false); } return(metaBuilder.CreateMetaObject(this)); }
public static DynamicMetaObject /*!*/ Bind(DynamicMetaObject /*!*/ context, SetIndexBinder /*!*/ binder, DynamicMetaObject /*!*/ target, DynamicMetaObject /*!*/[] /*!*/ indexes, DynamicMetaObject /*!*/ value, Func <DynamicMetaObject, DynamicMetaObject[], DynamicMetaObject, DynamicMetaObject> /*!*/ fallback) { Debug.Assert(fallback != null); var args = ArrayUtils.Append(indexes, value); var callArgs = new CallArguments(context, target, args, new RubyCallSignature(indexes.Length, RubyCallFlags.IsInteropCall | RubyCallFlags.HasRhsArgument) ); var metaBuilder = new MetaObjectBuilder(target, args); if (!RubyCallAction.BuildCall(metaBuilder, "[]=", callArgs, false, false)) { metaBuilder.SetMetaResult(fallback(target, indexes, value), false); } return(metaBuilder.CreateMetaObject(binder)); }
public static DynamicMetaObject/*!*/ Bind(DynamicMetaObject/*!*/ context, GetMemberBinder/*!*/ binder, DynamicMetaObject/*!*/ target, Func<DynamicMetaObject, DynamicMetaObject>/*!*/ fallback) { Debug.Assert(fallback != null); var callArgs = new CallArguments(context, target, DynamicMetaObject.EmptyMetaObjects, RubyCallSignature.Interop(0)); var metaBuilder = new MetaObjectBuilder(target); if (!RubyCallAction.BuildAccess(metaBuilder, binder.Name, callArgs, false, false)) { metaBuilder.SetMetaResult(fallback(target), false); } return metaBuilder.CreateMetaObject(binder); }
public static DynamicMetaObject/*!*/ Bind(DynamicMetaObject/*!*/ context, string/*!*/ methodName, CallInfo/*!*/ callInfo, DynamicMetaObjectBinder/*!*/ binder, DynamicMetaObject/*!*/ target, DynamicMetaObject/*!*/[]/*!*/ args, Func<DynamicMetaObject, DynamicMetaObject[], DynamicMetaObject>/*!*/ fallback) { Debug.Assert(fallback != null); var callArgs = new CallArguments(context, target, args, RubyCallSignature.Interop(callInfo.ArgumentCount)); var metaBuilder = new MetaObjectBuilder(target, args); if (!RubyCallAction.BuildCall(metaBuilder, methodName, callArgs, false, false)) { metaBuilder.SetMetaResult(fallback(target, args), false); } return metaBuilder.CreateMetaObject(binder); }
internal static DynamicMetaObject FallbackInvokeMember(IInteropBinder/*!*/ binder, string/*!*/ methodName, CallInfo/*!*/ callInfo, DynamicMetaObject/*!*/ target, DynamicMetaObject/*!*/[]/*!*/ args, DynamicMetaObject errorSuggestion) { var metaBuilder = new MetaObjectBuilder(binder, target, args); var callArgs = new CallArguments(binder.Context, target, args, callInfo); if (!RubyCallAction.BuildCall(metaBuilder, methodName, callArgs, errorSuggestion == null, true)) { Debug.Assert(errorSuggestion != null); // method wasn't found so we didn't do any operation with arguments that would require restrictions converted to conditions: metaBuilder.SetMetaResult(errorSuggestion, false); } return metaBuilder.CreateMetaObject((DynamicMetaObjectBinder)binder); }
protected override DynamicMetaObject/*!*/ InteropBind(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args) { metaBuilder.SetError(Ast.New( typeof(NotSupportedException).GetConstructor(new[] { typeof(string) }), Ast.Constant("Super call not supported on foreign meta-objects") )); return metaBuilder.CreateMetaObject(this); }
public override DynamicMetaObject/*!*/ FallbackConvert(DynamicMetaObject/*!*/ target, DynamicMetaObject errorSuggestion) { #if !SILVERLIGHT DynamicMetaObject result; if (Microsoft.Scripting.ComInterop.ComBinder.TryConvert(this, target, out result)) { return result; } #endif var metaBuilder = new MetaObjectBuilder(this, target, DynamicMetaObject.EmptyMetaObjects); if (!GenericConversionAction.BuildConversion(metaBuilder, target, Ast.Constant(_context), Type, errorSuggestion == null)) { Debug.Assert(errorSuggestion != null); // no conversion applicable so we didn't do any operation with arguments that would require restrictions converted to conditions: metaBuilder.SetMetaResult(errorSuggestion, false); } return metaBuilder.CreateMetaObject(this); }
protected override DynamicMetaObject/*!*/ InteropBind(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args) { // TODO: pass block as the last parameter (before RHS arg?): var normalizedArgs = RubyMethodGroupBase.NormalizeArguments(metaBuilder, args, SelfCallConvention.NoSelf, false, false); var callInfo = new CallInfo(normalizedArgs.Length); var interopBinder = GetInteropBinder(args.RubyContext, callInfo); var result = interopBinder.Bind(args.MetaTarget, normalizedArgs); metaBuilder.SetMetaResult(result, args); return metaBuilder.CreateMetaObject(interopBinder); }
// TODO: convert binder internal static DynamicMetaObject TryBindCovertToDelegate(RubyMetaObject /*!*/ target, ConvertBinder /*!*/ binder, MethodInfo /*!*/ delegateFactory) { var metaBuilder = new MetaObjectBuilder(target); return(TryBuildConversionToDelegate(metaBuilder, target, binder.Type, delegateFactory) ? metaBuilder.CreateMetaObject(binder) : null); }
public static DynamicMetaObject TryBind(RubyContext/*!*/ context, GetMemberBinder/*!*/ binder, DynamicMetaObject/*!*/ target) { Assert.NotNull(context, target); var metaBuilder = new MetaObjectBuilder(); var contextExpression = AstUtils.Constant(context); RubyClass targetClass = context.GetImmediateClassOf(target.Value); MethodResolutionResult method; RubyMemberInfo methodMissing = null; using (targetClass.Context.ClassHierarchyLocker()) { metaBuilder.AddTargetTypeTest(target.Value, targetClass, target.Expression, context, contextExpression); method = targetClass.ResolveMethodForSiteNoLock(binder.Name, RubyClass.IgnoreVisibility); if (method.Found) { methodMissing = targetClass.ResolveMethodForSiteNoLock(Symbols.MethodMissing, RubyClass.IgnoreVisibility).Info; } } if (method.Found) { // we need to create a bound member: metaBuilder.Result = AstUtils.Constant(new RubyMethod(target.Value, method.Info, binder.Name)); } else { // TODO: // We need to throw an exception if we don't find method_missing so that our version update optimization works: // This limits interop with other languages. // // class B CLR type with method 'foo' // class C < B Ruby class // x = C.new // // 1. x.GET("foo") from Ruby // No method found or CLR method found -> fallback to Python // Python might see its method foo or might just fallback to .NET, // in any case it will add rule [1] with restriction on type of C w/o Ruby version check. // 2. B.define_method("foo") // This doesn't update C due to the optimization (there is no overridden method foo in C). // 3. x.GET("foo") from Ruby // This will not invoke the binder since the rule [1] is still valid. // object symbol = SymbolTable.StringToId(binder.Name); RubyCallAction.BindToMethodMissing(metaBuilder, new CallArguments( new DynamicMetaObject(contextExpression, BindingRestrictions.Empty, context), new[] { target, new DynamicMetaObject(AstUtils.Constant(symbol), BindingRestrictions.Empty, symbol) }, RubyCallSignature.Simple(1) ), binder.Name, methodMissing, method.IncompatibleVisibility, false ); } // TODO: we should return null if we fail, we need to throw exception for now: return metaBuilder.CreateMetaObject(binder, DynamicMetaObject.EmptyMetaObjects); }
public override DynamicMetaObject/*!*/ FallbackInvokeMember(DynamicMetaObject/*!*/ target, DynamicMetaObject/*!*/[]/*!*/ args, DynamicMetaObject errorSuggestion) { var metaBuilder = new MetaObjectBuilder(); var callArgs = new CallArguments(_context, target, args, CallInfo); if (!RubyCallAction.Build(metaBuilder, Name, callArgs, errorSuggestion == null)) { Debug.Assert(errorSuggestion != null); // method wasn't found so we didn't do any operation with arguments that would require restrictions converted to conditions: metaBuilder.SetMetaResult(errorSuggestion, false); } return metaBuilder.CreateMetaObject(this); }
public static DynamicMetaObject/*!*/ Bind(DynamicMetaObject/*!*/ context, GetIndexBinder/*!*/ binder, DynamicMetaObject/*!*/ target, DynamicMetaObject/*!*/[]/*!*/ indexes, Func<DynamicMetaObject, DynamicMetaObject[], DynamicMetaObject>/*!*/ fallback) { Debug.Assert(fallback != null); var callArgs = new CallArguments(context, target, indexes, RubyCallSignature.Interop(indexes.Length)); var metaBuilder = new MetaObjectBuilder(target, indexes); if (!RubyCallAction.BuildCall(metaBuilder, "[]", callArgs, false, false)) { metaBuilder.SetMetaResult(fallback(target, indexes), false); } return metaBuilder.CreateMetaObject(binder); }
// TODO: convert binder internal static DynamicMetaObject TryBindCovertToDelegate(RubyMetaObject/*!*/ metaTarget, ConvertBinder/*!*/ binder, MethodInfo/*!*/ delegateFactory) { var metaBuilder = new MetaObjectBuilder(); return TryBuildConversionToDelegate(metaBuilder, metaTarget, binder.Type, delegateFactory) ? metaBuilder.CreateMetaObject(binder) : null; }
public static DynamicMetaObject/*!*/ Bind(DynamicMetaObject/*!*/ context, GetMemberBinder/*!*/ binder, DynamicMetaObject/*!*/ target, Func<DynamicMetaObject, DynamicMetaObject>/*!*/ fallback) { Debug.Assert(fallback != null); var metaBuilder = new MetaObjectBuilder(); var callArgs = new CallArguments(context, target, DynamicMetaObject.EmptyMetaObjects, RubyCallSignature.Simple(0)); RubyMemberInfo methodMissing; var method = RubyCallAction.Resolve(metaBuilder, binder.Name, callArgs, out methodMissing); if (method.Found) { // create a bound member: metaBuilder.Result = AstUtils.Constant(new RubyMethod(target.Value, method.Info, binder.Name)); } else { // TODO: support methodMissing // we need to create a wrapper over methodMissing that has curried the method name and calls to methodMissing method: return fallback(target); } return metaBuilder.CreateMetaObject(binder); }
public static DynamicMetaObject/*!*/ Bind(DynamicMetaObject/*!*/ context, SetMemberBinder/*!*/ binder, DynamicMetaObject/*!*/ target, DynamicMetaObject/*!*/ value, Func<DynamicMetaObject, DynamicMetaObject, DynamicMetaObject>/*!*/ fallback) { Debug.Assert(fallback != null); var args = new[] { value }; var callArgs = new CallArguments(context, target, args, RubyCallSignature.Interop(1)); var metaBuilder = new MetaObjectBuilder(target, args); if (!RubyCallAction.BuildCall(metaBuilder, binder.Name + "=", callArgs, false, false)) { metaBuilder.SetMetaResult(fallback(target, value), false); } return metaBuilder.CreateMetaObject(binder); }
private DynamicMetaObject/*!*/ InteropBind(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args) { // TODO: argument count limit depends on the binder! // TODO: pass block as the last (before RHS arg?) parameter/ignore block if args not accepting block: var normalizedArgs = RubyOverloadResolver.NormalizeArguments(metaBuilder, args, 0, Int32.MaxValue); if (!metaBuilder.Error) { MethodInfo postConverter; var interopBinder = GetInteropBinder(args.RubyContext, normalizedArgs, out postConverter); if (interopBinder != null) { Type resultType; var result = interopBinder.Bind(args.MetaTarget, ArrayUtils.MakeArray(normalizedArgs)); metaBuilder.SetMetaResult(result, args); if (postConverter != null) { // TODO: do better? var paramType = postConverter.GetParameters()[0].ParameterType; metaBuilder.Result = Ast.Call(null, postConverter, AstUtils.Convert(metaBuilder.Result, paramType)); resultType = postConverter.ReturnType; } else { resultType = ((IInteropBinder)interopBinder).ResultType; } return metaBuilder.CreateMetaObject(interopBinder, resultType); } else { metaBuilder.SetError(Ast.New( typeof(NotSupportedException).GetConstructor(new[] { typeof(string) }), Ast.Constant(String.Format("{0} not supported on foreign meta-objects", this)) )); } } return metaBuilder.CreateMetaObject(this); }
public override DynamicMetaObject/*!*/ FallbackInvoke(DynamicMetaObject/*!*/ target, DynamicMetaObject/*!*/[]/*!*/ args, DynamicMetaObject errorSuggestion) { // Used in combination with GetMember to compose InvokeMember operation. // Gets here only if the target is not a callable meta-object. var metaBuilder = new MetaObjectBuilder(this, target, args); var callArgs = new CallArguments(_context, target, args, CallInfo); metaBuilder.AddTypeRestriction(target.GetLimitType(), target.Expression); var normalizedArgs = RubyOverloadResolver.NormalizeArguments(metaBuilder, callArgs, 0, 0); if (!metaBuilder.Error) { // no arguments => just return the target: metaBuilder.Result = target.Expression; } else { // any arguments found (expected none): metaBuilder.SetMetaResult(errorSuggestion, false); } return metaBuilder.CreateMetaObject(this); }
public static MetaObject TryBind(RubyContext/*!*/ context, GetMemberBinder/*!*/ binder, MetaObject/*!*/ target) { Assert.NotNull(context, target); var metaBuilder = new MetaObjectBuilder(); var contextExpression = Ast.Constant(context); metaBuilder.AddTargetTypeTest(target.Value, target.Expression, context, contextExpression); RubyMemberInfo method = context.ResolveMethod(target.Value, binder.Name, true).InvalidateSitesOnOverride(); if (method != null && RubyModule.IsMethodVisible(method, false)) { // we need to create a bound member: metaBuilder.Result = Ast.Constant(new RubyMethod(target.Value, method, binder.Name)); } else { // TODO: // We need to throw an exception if we don't find method_missing so that our version update optimization works: // This limits interop with other languages. // // class B CLR type with method 'foo' // class C < B Ruby class // x = C.new // // 1. x.GET("foo") from Ruby // No method found or CLR method found -> fallback to Python // Python might see its method foo or might just fallback to .NET, // in any case it will add rule [1] with restriction on type of C w/o Ruby version check. // 2. B.define_method("foo") // This doesn't update C due to the optimization (there is no overridden method foo in C). // 3. x.GET("foo") from Ruby // This will not invoke the binder since the rule [1] is still valid. // object symbol = SymbolTable.StringToId(binder.Name); RubyCallAction.BindToMethodMissing(metaBuilder, binder.Name, new CallArguments( new MetaObject(contextExpression, Restrictions.Empty, context), new[] { target, new MetaObject(Ast.Constant(symbol), Restrictions.Empty, symbol) }, RubyCallSignature.Simple(1) ), method != null ); } // TODO: we should return null if we fail, we need to throw exception for now: return metaBuilder.CreateMetaObject(binder, MetaObject.EmptyMetaObjects); }
public override DynamicMetaObject/*!*/ FallbackGetMember(DynamicMetaObject/*!*/ target, DynamicMetaObject errorSuggestion) { if (_unmangled != null) { // TODO: errorSuggestion? return _unmangled.Bind(target, DynamicMetaObject.EmptyMetaObjects); } #if !SILVERLIGHT DynamicMetaObject result; if (Microsoft.Scripting.ComInterop.ComBinder.TryBindGetMember(this, target, out result)) { return result; } #endif var metaBuilder = new MetaObjectBuilder(target); var callArgs = new CallArguments(_context, target, DynamicMetaObject.EmptyMetaObjects, _CallInfo); if (!RubyCallAction.BuildAccess(metaBuilder, _originalName ?? Name, callArgs, errorSuggestion == null, true)) { Debug.Assert(errorSuggestion != null); metaBuilder.SetMetaResult(errorSuggestion, false); } return metaBuilder.CreateMetaObject(this); }
public static DynamicMetaObject/*!*/ Bind(DynamicMetaObject/*!*/ context, SetIndexBinder/*!*/ binder, DynamicMetaObject/*!*/ target, DynamicMetaObject/*!*/[]/*!*/ indexes, DynamicMetaObject/*!*/ value, Func<DynamicMetaObject, DynamicMetaObject[], DynamicMetaObject, DynamicMetaObject>/*!*/ fallback) { Debug.Assert(fallback != null); var args = ArrayUtils.Append(indexes, value); var callArgs = new CallArguments(context, target, args, new RubyCallSignature(indexes.Length, RubyCallFlags.IsInteropCall | RubyCallFlags.HasRhsArgument) ); var metaBuilder = new MetaObjectBuilder(target, args); if (!RubyCallAction.BuildCall(metaBuilder, "[]=", callArgs, false, false)) { metaBuilder.SetMetaResult(fallback(target, indexes, value), false); } return metaBuilder.CreateMetaObject(binder); }