private bool TryMakeDefaultUnaryRule(OperatorInfo info) { switch (info.Operator) { case Operators.IsTrue: if (_types[0] == typeof(bool)) { _rule.Target = _rule.MakeReturn(Binder, Param0); return(true); } break; case Operators.Negate: if (TypeUtils.IsArithmetic(_types[0])) { _rule.Target = _rule.MakeReturn(Binder, Ast.Negate(Param0)); return(true); } break; case Operators.Not: if (TypeUtils.IsIntegerOrBool(_types[0])) { _rule.Target = _rule.MakeReturn(Binder, Ast.Not(Param0)); return(true); } break; case Operators.Documentation: object[] attrs = _types[0].GetCustomAttributes(typeof(DocumentationAttribute), true); string documentation = String.Empty; if (attrs.Length > 0) { documentation = ((DocumentationAttribute)attrs[0]).Documentation; } _rule.Target = _rule.MakeReturn(Binder, Ast.Constant(documentation)); return(true); case Operators.MemberNames: if (typeof(IMembersList).IsAssignableFrom(_types[0])) { MakeIMembersListRule(); return(true); } MemberInfo[] members = _types[0].GetMembers(); Dictionary <string, string> mems = new Dictionary <string, string>(); foreach (MemberInfo mi in members) { mems[mi.Name] = mi.Name; } string[] res = new string[mems.Count]; mems.Keys.CopyTo(res, 0); _rule.Target = _rule.MakeReturn(Binder, Ast.Constant(res)); return(true); case Operators.CallSignatures: MakeCallSignatureResult(CompilerHelpers.GetMethodTargets(_args[0])); break; case Operators.IsCallable: // IsCallable() is tightly tied to Call actions. So in general, we need the call-action providers to also // provide IsCallable() status. // This is just a rough fallback. We could also attempt to simulate the default CallBinder logic to see // if there are any applicable calls targets, but that would be complex (the callbinder wants the argument list, // which we don't have here), and still not correct. bool callable = false; if (typeof(Delegate).IsAssignableFrom(_types[0]) || typeof(MethodGroup).IsAssignableFrom(_types[0])) { callable = true; } _rule.Target = _rule.MakeReturn(Context.LanguageContext.Binder, Ast.Constant(callable)); return(true); } return(false); }
public DynamicMetaObject GetCallSignatures(DynamicMetaObject target) { return(MakeCallSignatureResult(CompilerHelpers.GetMethodTargets(target.LimitType), target)); }
private static MetaObject TryMakeDefaultUnaryRule(OperatorInfo info, Expression codeContext, MetaObject[] args) { if (args.Length == 1) { Restrictions restrictions = Restrictions.GetTypeRestriction(args[0].Expression, args[0].LimitType).Merge(Restrictions.Combine(args)); switch (info.Operator) { case Operators.IsTrue: if (args[0].LimitType == typeof(bool)) { return(args[0]); } break; case Operators.Negate: if (TypeUtils.IsArithmetic(args[0].LimitType)) { return(new MetaObject( Ast.Negate(args[0].Expression), restrictions )); } break; case Operators.Not: if (TypeUtils.IsIntegerOrBool(args[0].LimitType)) { return(new MetaObject( Ast.Not(args[0].Expression), restrictions )); } break; case Operators.Documentation: object[] attrs = args[0].LimitType.GetCustomAttributes(typeof(DocumentationAttribute), true); string documentation = String.Empty; if (attrs.Length > 0) { documentation = ((DocumentationAttribute)attrs[0]).Documentation; } return(new MetaObject( Ast.Constant(documentation), restrictions )); case Operators.MemberNames: if (typeof(IMembersList).IsAssignableFrom(args[0].LimitType)) { return(MakeIMembersListRule(codeContext, args[0])); } MemberInfo[] members = args[0].LimitType.GetMembers(); Dictionary <string, string> mems = new Dictionary <string, string>(); foreach (MemberInfo mi in members) { mems[mi.Name] = mi.Name; } string[] res = new string[mems.Count]; mems.Keys.CopyTo(res, 0); return(new MetaObject( Ast.Constant(res), restrictions )); case Operators.CallSignatures: return(MakeCallSignatureResult(CompilerHelpers.GetMethodTargets(args[0].LimitType), args[0])); case Operators.IsCallable: // IsCallable() is tightly tied to Call actions. So in general, we need the call-action providers to also // provide IsCallable() status. // This is just a rough fallback. We could also attempt to simulate the default CallBinder logic to see // if there are any applicable calls targets, but that would be complex (the callbinder wants the argument list, // which we don't have here), and still not correct. bool callable = false; if (typeof(Delegate).IsAssignableFrom(args[0].LimitType) || typeof(MethodGroup).IsAssignableFrom(args[0].LimitType)) { callable = true; } return(new MetaObject( Ast.Constant(callable), restrictions )); } } return(null); }