private static MethodInfo[] GetCallableMethods(MemberGroup members) { MethodInfo[] methods = new MethodInfo[members.Count]; for (int i = 0; i < members.Count; i++) { methods[i] = CompilerHelpers.GetCallableMethod(((MethodTracker)members[i]).Method); } return(methods); }
private void MakeMethodBaseRule(MethodBase[] targets) { Type[] argTypes; // will not include implicit instance argument (if any) SymbolId[] argNames; // will include ArgumentKind.Dictionary keyword names GetArgumentNamesAndTypes(out argNames, out argTypes); Type[] bindingArgs = argTypes; // will include instance argument (if any) CallTypes callType = CallTypes.None; if (_instance != null) { bindingArgs = ArrayUtils.Insert(InstanceType, argTypes); callType = CallTypes.ImplicitInstance; } if (_reversedOperator && bindingArgs.Length >= 2) { // we swap the arguments before binding, and swap back before calling. ArrayUtils.SwapLastTwo(bindingArgs); if (argNames.Length >= 2) { ArrayUtils.SwapLastTwo(argNames); } } // attempt to bind to an individual method MethodBinder binder = MethodBinder.MakeBinder(Binder, GetTargetName(targets), targets, argNames, NarrowingLevel.None, _maxLevel); BindingTarget bt = binder.MakeBindingTarget(callType, bindingArgs); if (bt.Success) { // if we succeed make the target for the rule MethodBase target = bt.Method; MethodInfo targetMethod = target as MethodInfo; if (targetMethod != null) { target = CompilerHelpers.GetCallableMethod(targetMethod, Binder.PrivateBinding); } Expression[] exprargs = FinishTestForCandidate(bt.ArgumentTests, argTypes); _rule.Target = _rule.MakeReturn( Binder, bt.MakeExpression(_rule, exprargs)); } else { // make an error rule MakeInvalidParametersRule(bt); } }
private MethodInfo ResolveGetter() { MethodInfo getter = GetGetMethod(true); if (getter == null) { return(null); } // Allow access to protected getters TODO: this should go, it supports IronPython semantics. if (!getter.IsPublic && !(getter.IsFamily || getter.IsFamilyOrAssembly)) { if (!ScriptDomainManager.Options.PrivateBinding) { getter = null; } } return(CompilerHelpers.GetCallableMethod(getter)); }
private void MakePropertyRule(SetOrDeleteMemberInfo memInfo, DynamicMetaObject instance, DynamicMetaObject target, Type targetType, MemberGroup properties, DynamicMetaObject errorSuggestion) { PropertyTracker info = (PropertyTracker)properties[0]; MethodInfo setter = info.GetSetMethod(true); // Allow access to protected getters TODO: this should go, it supports IronPython semantics. if (setter != null && !setter.IsPublic && !setter.IsProtected()) { if (!PrivateBinding) { setter = null; } } if (setter != null) { setter = CompilerHelpers.GetCallableMethod(setter, PrivateBinding); if (info.IsStatic != (instance == null)) { memInfo.Body.FinishCondition( errorSuggestion ?? MakeError( MakeStaticPropertyInstanceAccessError( info, true, instance, target ), typeof(object) ) ); } else if (info.IsStatic && info.DeclaringType != targetType) { memInfo.Body.FinishCondition( errorSuggestion ?? MakeError( MakeStaticAssignFromDerivedTypeError(targetType, instance, info, target, memInfo.ResolutionFactory), typeof(object) ) ); } else if (setter.ContainsGenericParameters) { memInfo.Body.FinishCondition( MakeGenericPropertyExpression(memInfo) ); } else if (setter.IsPublic && !setter.DeclaringType.IsValueType) { if (instance == null) { memInfo.Body.FinishCondition( Ast.Block( AstUtils.SimpleCallHelper( setter, ConvertExpression( target.Expression, setter.GetParameters()[0].ParameterType, ConversionResultKind.ExplicitCast, memInfo.ResolutionFactory ) ), Ast.Constant(null) ) ); } else { memInfo.Body.FinishCondition( MakeReturnValue( MakeCallExpression(memInfo.ResolutionFactory, setter, instance, target), target ) ); } } else { // TODO: Should be able to do better w/ value types. memInfo.Body.FinishCondition( MakeReturnValue( Ast.Call( AstUtils.Constant(((ReflectedPropertyTracker)info).Property), // TODO: Private binding on extension properties typeof(PropertyInfo).GetMethod("SetValue", new Type[] { typeof(object), typeof(object), typeof(object[]) }), instance == null ? AstUtils.Constant(null) : AstUtils.Convert(instance.Expression, typeof(object)), AstUtils.Convert( ConvertExpression( target.Expression, setter.GetParameters()[0].ParameterType, ConversionResultKind.ExplicitCast, memInfo.ResolutionFactory ), typeof(object) ), Ast.NewArrayInit(typeof(object)) ), target ) ); } } else { memInfo.Body.FinishCondition( errorSuggestion ?? MakeError( MakeMissingMemberErrorForAssignReadOnlyProperty(targetType, instance, memInfo.Name), typeof(object) ) ); } }
private void MakePropertyRule(Type targetType, MemberGroup properties) { PropertyTracker info = (PropertyTracker)properties[0]; MethodInfo setter = info.GetSetMethod(true); // Allow access to protected getters TODO: this should go, it supports IronPython semantics. if (setter != null && !setter.IsPublic && !(setter.IsFamily || setter.IsFamilyOrAssembly)) { if (!ScriptDomainManager.Options.PrivateBinding) { setter = null; } } if (setter != null) { setter = CompilerHelpers.GetCallableMethod(setter); if (info.IsStatic != _isStatic) { // TODO: Too python specific AddToBody(Binder.MakeReadOnlyMemberError(Rule, targetType, StringName)); } else if (setter.ContainsGenericParameters) { AddToBody(Rule.MakeError(MakeGenericPropertyExpression())); } else if (setter.IsPublic && !setter.DeclaringType.IsValueType) { if (_isStatic) { AddToBody( Rule.MakeReturn( Binder, Ast.SimpleCallHelper( setter, Binder.ConvertExpression( Rule.Parameters[1], setter.GetParameters()[0].ParameterType ) ) ) ); } else { AddToBody(Rule.MakeReturn(Binder, MakeReturnValue(Binder.MakeCallExpression(setter, Rule.Parameters)))); } } else { // TODO: Should be able to do better w/ value types. AddToBody( Rule.MakeReturn( Binder, MakeReturnValue( Ast.Call( Ast.RuntimeConstant(((ReflectedPropertyTracker)info).Property), // TODO: Private binding on extension properties typeof(PropertyInfo).GetMethod("SetValue", new Type[] { typeof(object), typeof(object), typeof(object[]) }), Ast.ConvertHelper(Instance, typeof(object)), Ast.ConvertHelper(Rule.Parameters[1], typeof(object)), Ast.NewArray(typeof(object[])) ) ) ) ); } } else { AddToBody(Binder.MakeMissingMemberError(Rule, targetType, StringName)); } }
private void MakePropertyRule(Type targetType, MemberGroup properties) { PropertyTracker info = (PropertyTracker)properties[0]; MethodInfo setter = info.GetSetMethod(true); // Allow access to protected getters TODO: this should go, it supports IronPython semantics. if (setter != null && !setter.IsPublic && !(setter.IsFamily || setter.IsFamilyOrAssembly)) { if (!PrivateBinding) { setter = null; } } if (setter != null) { setter = CompilerHelpers.GetCallableMethod(setter, Binder.PrivateBinding); if (info.IsStatic != _isStatic) { AddToBody(Binder.MakeStaticPropertyInstanceAccessError(info, true, Rule.Parameters).MakeErrorForRule(Rule, Binder)); } else if (info.IsStatic && info.DeclaringType != targetType) { AddToBody(Binder.MakeStaticAssignFromDerivedTypeError(targetType, info, Rule.Parameters[1], Rule.Context).MakeErrorForRule(Rule, Binder)); } else if (setter.ContainsGenericParameters) { AddToBody(Rule.MakeError(MakeGenericPropertyExpression())); } else if (setter.IsPublic && !setter.DeclaringType.IsValueType) { if (_isStatic) { AddToBody( Rule.MakeReturn( Binder, AstUtils.SimpleCallHelper( setter, Binder.ConvertExpression( Rule.Parameters[1], setter.GetParameters()[0].ParameterType, ConversionResultKind.ExplicitCast, Rule.Context ) ) ) ); } else { AddToBody(Rule.MakeReturn(Binder, MakeReturnValue(Binder.MakeCallExpression(Rule.Context, setter, Rule.Parameters)))); } } else { // TODO: Should be able to do better w/ value types. AddToBody( Rule.MakeReturn( Binder, MakeReturnValue( Ast.Call( Ast.Constant(((ReflectedPropertyTracker)info).Property), // TODO: Private binding on extension properties typeof(PropertyInfo).GetMethod("SetValue", new Type[] { typeof(object), typeof(object), typeof(object[]) }), AstUtils.Convert(Instance, typeof(object)), AstUtils.Convert(Rule.Parameters[1], typeof(object)), Ast.NewArrayInit(typeof(object)) ) ) ) ); } } else { AddToBody(Binder.MakeMissingMemberError(targetType, StringName).MakeErrorForRule(Rule, Binder)); } }
private void MakeMethodBaseRule(MethodBase[] targets) { Type[] testTypes, argTypes; SymbolId[] argNames; //If an instance is explicitly passed in as an argument, ignore it. //Calls that need an instance will pick it up from the bound objects //passed in or the rule. CallType can differentiate between the type //of call during method binding. int instanceIndex = Action.Signature.IndexOf(ArgumentKind.Instance); if (instanceIndex > -1) { _args = ArrayUtils.RemoveAt(_args, instanceIndex + 1); } GetArgumentNamesAndTypes(out argNames, out argTypes); Type[] bindingArgs = argTypes; CallType callType = CallType.None; if (_instance != null) { bindingArgs = ArrayUtils.Insert(_instance.Type, argTypes); callType = CallType.ImplicitInstance; } if (_reversedOperator && bindingArgs.Length >= 2) { // we swap the arguments before binding, and swap back before calling. ArrayUtils.SwapLastTwo(bindingArgs); if (argNames.Length >= 2) { ArrayUtils.SwapLastTwo(argNames); } } // attempt to bind to an individual method MethodBinder binder = MethodBinder.MakeBinder(Binder, GetTargetName(targets), targets, GetBinderType(targets), argNames); MethodCandidate cand = binder.MakeBindingTarget(callType, bindingArgs, out testTypes); if (cand != null) { // if we succeed make the target for the rule MethodBase target = cand.Target.Method; MethodInfo targetMethod = target as MethodInfo; if (targetMethod != null) { target = CompilerHelpers.GetCallableMethod(targetMethod); } if (!MakeActionOnCallRule(target)) { Expression[] exprargs = FinishTestForCandidate(testTypes, argTypes); _rule.SetTarget(_rule.MakeReturn( Binder, cand.Target.MakeExpression(Binder, _rule, exprargs, testTypes))); } } else { // make an error rule MakeInvalidParametersRule(binder, callType, targets); } }
internal Expression MakeExpression(ParameterBinder parameterBinder, IList <Expression> parameters) { bool[] usageMarkers; Expression[] spilledArgs; Expression[] args = GetArgumentExpressions(parameterBinder, parameters, out usageMarkers, out spilledArgs); MethodBase mb = Method; MethodInfo mi = mb as MethodInfo; Expression ret, call; if (!mb.IsPublic || (mb.DeclaringType != null && !mb.DeclaringType.IsVisible)) { if (mi != null) { mi = CompilerHelpers.GetCallableMethod(mi, _binder._binder.PrivateBinding); if (mi != null) { mb = mi; } } } ConstructorInfo ci = mb as ConstructorInfo; Debug.Assert(mi != null || ci != null); if (mb.IsPublic && (mb.DeclaringType == null || mb.DeclaringType.IsVisible)) { // public method if (mi != null) { Expression instance = mi.IsStatic ? null : _instanceBuilder.ToExpression(parameterBinder, parameters, usageMarkers); call = AstUtils.SimpleCallHelper(instance, mi, args); } else { call = AstUtils.SimpleNewHelper(ci, args); } } else { // Private binding, invoke via reflection if (mi != null) { Expression instance = mi.IsStatic ? Ast.Constant(null) : _instanceBuilder.ToExpression(parameterBinder, parameters, usageMarkers); Debug.Assert(instance != null, "Can't skip instance expression"); call = Ast.Call( typeof(BinderOps).GetMethod("InvokeMethod"), Ast.Constant(mi), AstUtils.Convert(instance, typeof(object)), AstUtils.NewArrayHelper(typeof(object), args) ); } else { call = Ast.Call( typeof(BinderOps).GetMethod("InvokeConstructor"), Ast.Constant(ci), AstUtils.NewArrayHelper(typeof(object), args) ); } } if (spilledArgs != null) { call = Expression.Block(spilledArgs.AddLast(call)); } ret = _returnBuilder.ToExpression(parameterBinder, _argBuilders, parameters, call); List <Expression> updates = null; for (int i = 0; i < _argBuilders.Count; i++) { Expression next = _argBuilders[i].UpdateFromReturn(parameterBinder, parameters); if (next != null) { if (updates == null) { updates = new List <Expression>(); } updates.Add(next); } } if (updates != null) { if (ret.Type != typeof(void)) { ParameterExpression temp = Ast.Variable(ret.Type, "$ret"); updates.Insert(0, Ast.Assign(temp, ret)); updates.Add(temp); ret = Ast.Block(new [] { temp }, updates.ToArray()); } else { updates.Insert(0, ret); ret = Ast.Convert( Ast.Block(updates.ToArray()), typeof(void) ); } } if (parameterBinder.Temps != null) { ret = Ast.Block(parameterBinder.Temps, ret); } return(ret); }