[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] // TODO: fix public static void SetEvent(EventTracker eventTracker, object value) { if (value is EventTracker et) { if (et != eventTracker) { throw new ArgumentException(String.Format("expected event from {0}.{1}, got event from {2}.{3}", eventTracker.DeclaringType.Name, eventTracker.Name, et.DeclaringType.Name, et.Name)); } return; } BoundMemberTracker bmt = value as BoundMemberTracker; if (bmt == null) { throw new ArgumentTypeException("expected bound event, got " + CompilerHelpers.GetType(value).Name); } if (bmt.BoundTo.MemberType != TrackerTypes.Event) { throw new ArgumentTypeException("expected bound event, got " + bmt.BoundTo.MemberType.ToString()); } if (bmt.BoundTo != eventTracker) { throw new ArgumentException( $"expected event from {eventTracker.DeclaringType.Name}.{eventTracker.Name}, got event from {bmt.BoundTo.DeclaringType.Name}.{bmt.BoundTo.Name}"); } }
public static MethodBase[] GetMethodTargets(object obj) { Type t = CompilerHelpers.GetType(obj); if (typeof(Delegate).IsAssignableFrom(t)) { MethodInfo mi = t.GetMethod("Invoke"); return(new MethodBase[] { mi }); } if (typeof(BoundMemberTracker).IsAssignableFrom(t)) { BoundMemberTracker bmt = obj as BoundMemberTracker; if (bmt.BoundTo.MemberType == TrackerTypes.Method) { } } else if (typeof(MethodGroup).IsAssignableFrom(t)) { } else if (typeof(MemberGroup).IsAssignableFrom(t)) { } else { return(MakeCallSignatureForCallableObject(t)); } return(null); }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] // TODO: fix public static void SetEvent(EventTracker eventTracker, object value) { if (value is EventTracker et) { if (et != eventTracker) { throw Error.UnexpectedEvent(eventTracker.DeclaringType.Name, eventTracker.Name, et.DeclaringType.Name, et.Name); } return; } BoundMemberTracker bmt = value as BoundMemberTracker; if (bmt == null) { throw Error.ExpectedBoundEvent(CompilerHelpers.GetType(value).Name); } if (bmt.BoundTo.MemberType != TrackerTypes.Event) { throw Error.ExpectedBoundEvent(bmt.BoundTo.MemberType.ToString()); } if (bmt.BoundTo != eventTracker) { throw Error.UnexpectedEvent( eventTracker.DeclaringType.Name, eventTracker.Name, bmt.BoundTo.DeclaringType.Name, bmt.BoundTo.Name); } }
public static BoundMemberTracker BoundEventTrackerInPlaceRemove <T>(BoundMemberTracker self, T target) { if (self.BoundTo.MemberType == TrackerTypes.Event) { EventTracker et = (EventTracker)self.BoundTo; MethodInfo remove = et.Event.GetRemoveMethod(ScriptDomainManager.Options.PrivateBinding); remove.Invoke(self.ObjectInstance, new object[] { target }); return(self); } throw new InvalidOperationException(); }
public static object GetItem(BoundMemberTracker self, params object[] keys) { throw new NotImplementedException(); }
public DynamicMetaObject FallbackOperation(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion) { Expression convertedTarget = Expression.Convert(target.Expression, target.LimitType); Expression[] convertedArgs = args.Select(x => Expression.Convert(x.Expression, x.LimitType)).ToArray(); Expression exp = null; var restrictions = target.Restrictions.Merge(GetTypeRestriction(target)); int usedArgs = 0; switch (OperationKind) { // Unary case TjsOperationKind.CharCodeToChar: exp = Expression.Call(Context.Convert(convertedTarget, typeof(char)), "ToString", null); break; case TjsOperationKind.CharToCharCode: exp = Expression.Call(new Func <string, long>(TjsOperationHelper.CharToCharCode).Method, Context.Convert(convertedTarget, typeof(string))); break; case TjsOperationKind.Evaluate: case TjsOperationKind.Invalidate: case TjsOperationKind.IsValid: //MARK: not implemented? if (errorSuggestion == null) { errorSuggestion = new DynamicMetaObject(Expression.Throw(Expression.Constant(new NotImplementedException())), BindingRestrictions.Empty); } break; case TjsOperationKind.TypeOf: if (target.RuntimeType == null) { exp = Expression.Constant("Object"); } else if (target.RuntimeType == typeof(Builtins.Void)) { exp = Expression.Constant("void"); } else if (target.RuntimeType == typeof(string)) { exp = Expression.Constant("String"); } else if (Binders.IsInteger(target.RuntimeType)) { exp = Expression.Constant("Integer"); } else if (Binders.IsFloatingPoint(target.RuntimeType)) { exp = Expression.Constant("Real"); } else { exp = Expression.Constant("Object"); } break; // Unary (Special) case TjsOperationKind.InvokePropertyHandler: if (target.LimitType == typeof(Property)) { if (args.Length == 0) { exp = Expression.Property(convertedTarget, (System.Reflection.PropertyInfo)Utils.GetMember <Property>(x => x.Value)); } else if (args.Length == 1) { exp = Expression.Assign(Expression.Property(convertedTarget, (System.Reflection.PropertyInfo)Utils.GetMember <Property>(x => x.Value)), args[0].Expression); usedArgs = 1; } else { if (errorSuggestion == null) { errorSuggestion = new DynamicMetaObject(Expression.Throw(Expression.Constant(new InvalidOperationException("引数の数が * 演算子に適用できる許容範囲を超えています。"))), BindingRestrictions.Empty); } } } else if (target.LimitType == typeof(BoundMemberTracker)) { var tracker = (BoundMemberTracker)target.Value; if (tracker.Instance == null) { tracker = new BoundMemberTracker(tracker.BoundTo, new DynamicMetaObject(Expression.Constant(tracker.ObjectInstance), BindingRestrictions.Empty, tracker.ObjectInstance)); } var type = tracker.Instance.GetLimitType(); if (args.Length == 0) { var res = tracker.GetValue(new TjsOverloadResolverFactory(Context.Binder), Context.Binder, type); if (res != null) { exp = res.Expression; restrictions = restrictions.Merge(res.Restrictions); } else { if (errorSuggestion == null) { errorSuggestion = new DynamicMetaObject(Expression.Throw(Expression.Constant(new InvalidOperationException("メンバの取得に失敗しました。"))), BindingRestrictions.Empty); } } } else if (args.Length == 1) { var res = tracker.SetValue(new TjsOverloadResolverFactory(Context.Binder), Context.Binder, type, args[0]); if (res != null) { exp = res.Expression; restrictions = restrictions.Merge(res.Restrictions); usedArgs = 1; } else { if (errorSuggestion == null) { errorSuggestion = new DynamicMetaObject(Expression.Throw(Expression.Constant(new InvalidOperationException("メンバの設定に失敗しました。"))), BindingRestrictions.Empty); } } } else { if (errorSuggestion == null) { errorSuggestion = new DynamicMetaObject(Expression.Throw(Expression.Constant(new InvalidOperationException("引数の数が * 演算子に適用できる許容範囲を超えています。"))), BindingRestrictions.Empty); } } } else { if (errorSuggestion == null) { errorSuggestion = new DynamicMetaObject(Expression.Throw(Expression.Constant(new InvalidOperationException("プロパティ以外に対して * 演算子が使用されました。"))), BindingRestrictions.Empty); } } break; // Binary (Arithmetic & Logical) case TjsOperationKind.FloorDivide: exp = Expression.Divide(Context.Convert(convertedTarget, typeof(long)), Context.Convert(convertedArgs[0], typeof(long))); usedArgs = 1; break; case TjsOperationKind.RightShiftLogical: exp = Expression.Convert(Expression.RightShift(Context.Convert(convertedTarget, typeof(ulong)), Context.Convert(convertedArgs[0], typeof(int))), typeof(long)); usedArgs = 1; break; // Binary (Comparison) case TjsOperationKind.DistinctEqual: if (convertedTarget.Type == convertedArgs[0].Type) { exp = Expression.Condition(Expression.Equal(convertedTarget, convertedArgs[0]), Expression.Constant(1L), Expression.Constant(0L)); } else { exp = Expression.Constant(0L); } usedArgs = 1; break; case TjsOperationKind.DistinctNotEqual: if (convertedTarget.Type == convertedArgs[0].Type) { exp = Expression.Condition(Expression.Equal(convertedTarget, convertedArgs[0]), Expression.Constant(0L), Expression.Constant(1L)); } else { exp = Expression.Constant(1L); } usedArgs = 1; break; // Binary (Special) case TjsOperationKind.InstanceOf: exp = Expression.Condition(Expression.Equal(Expression.Constant(convertedTarget.Type.Name), Context.Convert(convertedArgs[0], typeof(string))), Expression.Constant(1L), Expression.Constant(0L) ); usedArgs = 1; break; case TjsOperationKind.InContextOf: if (target.Value is IContextChangeable) { exp = Expression.Call(Expression.Convert(convertedTarget, typeof(IContextChangeable)), "ChangeContext", null, args[0].Expression); } else if (target.LimitType == typeof(BoundMemberTracker)) { exp = Expression.New((System.Reflection.ConstructorInfo)Utils.GetMember(() => new BoundMemberTracker(null, (object)null)), Expression.PropertyOrField(convertedTarget, "BoundTo"), args[0].Expression); } else { if (errorSuggestion == null) { errorSuggestion = new DynamicMetaObject(Expression.Throw(Expression.Constant(new InvalidOperationException("incontextof 演算子は指定されたオブジェクトに適用できません。"))), BindingRestrictions.Empty); } } usedArgs = 1; break; } for (int i = 0; i < usedArgs; i++) { restrictions = restrictions.Merge(args[i].Restrictions).Merge(GetTypeRestriction(args[i])); } if (exp == null) { return(new DynamicMetaObject(errorSuggestion.Expression, errorSuggestion.Restrictions.Merge(restrictions))); } if (exp.Type != typeof(object)) { exp = Expression.Convert(exp, typeof(object)); } return(new DynamicMetaObject(exp, restrictions)); }
public static BoundMemberTracker BoundEventTrackerInPlaceAdd <T>(CodeContext context, BoundMemberTracker self, T target) { if (self.BoundTo.MemberType == TrackerTypes.Event) { EventTracker et = (EventTracker)self.BoundTo; MethodInfo add = et.Event.GetAddMethod(context.LanguageContext.DomainManager.Configuration.PrivateBinding); add.Invoke(self.ObjectInstance, new object[] { target }); return(self); } throw new InvalidOperationException(); }