/// <summary> /// 获取动态类型的值 /// </summary> /// <param name="dynamicObject">实例</param> /// <param name="name">名称</param> /// <returns></returns> private object GetValue(DynamicObject dynamicObject, string name) { var binder = new MemberBinder(name); dynamicObject.TryGetMember(binder, out object value); return(value); }
/// <summary> /// Returns a ModelBinder object for the given model path, using cache. /// </summary> /// <param name="modelPath">The model path.</param> /// <returns>The ModelBinder</returns> private MemberBinder <TEntity> GetBinding(string modelPath) { if (this.memberBinders.ContainsKey(modelPath)) { return(this.memberBinders[modelPath]); } var binder = new MemberBinder <TEntity>(modelPath); this.memberBinders[modelPath] = binder; return(binder); }
/// <summary> /// Computes the sorts. /// </summary> public void Sort() { IQueryable <TEntity> sortedQuery = null; if (this.queryParameters.Sorts != null) { bool isMultiple = false; foreach (SortDescriptor sort in this.queryParameters.Sorts) { MemberBinder <TEntity> binder = this.GetBinding(sort.MemberName); sortedQuery = binder.Sort(sortedQuery ?? this.query, sort, isMultiple); isMultiple = true; } } if (sortedQuery != null) { this.query = sortedQuery; } }
private static MemberGroup/*!*/ DocResolver(MemberBinder/*!*/ binder, Type/*!*/ type) { if (_docDescr == null) { _docDescr = new DocumentationDescriptor(); } return new MemberGroup(new CustomAttributeTracker(type, "__doc__", _docDescr)); }
private static MemberGroup/*!*/ AllResolver(MemberBinder/*!*/ binder, Type/*!*/ type) { // static types are like modules and define __all__. if (type.IsAbstract && type.IsSealed) { return new MemberGroup(new ExtensionPropertyTracker("__all__", typeof(InstanceOps).GetMethod("Get__all__").MakeGenericMethod(type), null, null, type)); } return MemberGroup.EmptyGroup; }
/// <summary> /// Provides a mapping of IValueEquality.ValueNotEquals to __ne__ /// </summary> private static MemberGroup/*!*/ InequalityResolver(MemberBinder/*!*/ binder, Type/*!*/ type) { if (typeof(IValueEquality).IsAssignableFrom(type)) { return new MemberGroup(GetEqualityMethods(type, "ValueNotEqualsMethod")); } return MemberGroup.EmptyGroup; }
/// <summary> /// Provides a resolution for __len__ /// </summary> private static MemberGroup/*!*/ LengthResolver(MemberBinder/*!*/ binder, Type/*!*/ type) { if (binder.GetInterfaces(type).Contains(typeof(ICollection))) { return GetInstanceOpsMethod(type, "LengthMethod"); } foreach (Type t in binder.GetInterfaces(type)) { if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(ICollection<>)) { MethodInfo genMeth = typeof(InstanceOps).GetMethod("GenericLengthMethod"); return new MemberGroup( MethodTracker.FromMemberInfo(genMeth.MakeGenericMethod(t.GetGenericArguments()), type) ); } } return MemberGroup.EmptyGroup; }
/// <summary> /// Provides a resolution for __new__. For standard .NET types __new__ resolves to their /// constructor. For Python types they inherit __new__ from their base class. /// /// TODO: Can we just always fallback to object.__new__? If not why not? /// </summary> private static MemberGroup/*!*/ NewResolver(MemberBinder/*!*/ binder, Type/*!*/ type) { if (type.IsSealed && type.IsAbstract) { // static types don't have __new__ return MemberGroup.EmptyGroup; } bool isPythonType = typeof(IPythonObject).IsAssignableFrom(type); // check and see if __new__ has been overridden by the base type. foreach (Type t in binder.GetContributingTypes(type)) { if (!isPythonType && t == typeof(ObjectOps) && type != typeof(object)) { break; } MemberInfo[] news = t.GetMember("__new__"); if (news.Length > 0) { // type has a specific __new__ overload, return that for the constructor return GetExtensionMemberGroup(type, news); } } // type has no Python __new__, just return the .NET constructors if they have // a custom new ConstructorInfo[] ctors = type.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);// CompilerHelpers.GetConstructors(type, binder.DomainManager.Configuration.PrivateBinding, true); ctors = CompilerHelpers.FilterConstructorsToPublicAndProtected(ctors); if (!PythonTypeOps.IsDefaultNew(ctors)) { return new MemberGroup(ctors); } // if no ctor w/ parameters are defined, fall back to object.__new__ which // will ignore all the extra arguments allowing the user to just override // __init__. return MemberGroup.EmptyGroup; }
/// <summary> /// Helper to see if the type explicitly overrides the method. This ignores members /// defined on object. /// </summary> private static bool TypeOverridesMethod(MemberBinder/*!*/ binder, Type/*!*/ type, string/*!*/ methodName) { // check and see if the method has been overridden by the base type. foreach (Type t in binder.GetContributingTypes(type)) { if (!PythonBinder.IsPythonType(type) && t == typeof(ObjectOps) && type != typeof(object)) { break; } MemberInfo[] reduce = t.GetMember(methodName); if (reduce.Length > 0) { // type has a specific overload return true; } } return false; }
/// <summary> /// Provides a resolution for __repr__ /// </summary> private static MemberGroup/*!*/ ReprResolver(MemberBinder/*!*/ binder, Type/*!*/ type) { // __repr__ for normal .NET types is special, if we're a Python type then // we'll use one of the built-in reprs (from object or from the type) if (!PythonBinder.IsPythonType(type) && (!type.IsSealed || !type.IsAbstract)) { // static types don't get __repr__ // check and see if __repr__ has been overridden by the base type. foreach (Type t in binder.GetContributingTypes(type)) { if (t == typeof(ObjectOps) && type != typeof(object)) { break; } if (t.GetMember("__repr__").Length > 0) { // type has a specific __repr__ overload, pick it up normally later return MemberGroup.EmptyGroup; } } // no override, pick up the default fancy .NET __repr__ return binder.GetBaseInstanceMethod(type, "FancyRepr"); } return MemberGroup.EmptyGroup; }
protected override IEnumerable<string/*!*/>/*!*/ GetCandidateNames(MemberBinder/*!*/ binder, OldDynamicAction/*!*/ action, Type/*!*/ type) { yield return _name; }
public override MemberGroup/*!*/ ResolveMember(MemberBinder/*!*/ binder, OldDynamicAction/*!*/ action, Type/*!*/ type, string/*!*/ name) { Assert.NotNull(binder, action, type, name); if (name == _name) { return _resolver(binder, type); } return MemberGroup.EmptyGroup; }
/// <summary> /// Returns a list of possible members which could exist. ResolveMember needs to be called to verify their existance. Duplicate /// names can also be returned. /// </summary> protected abstract IEnumerable<string/*!*/>/*!*/ GetCandidateNames(MemberBinder/*!*/ binder, OldDynamicAction/*!*/ action, Type/*!*/ type);
/// <summary> /// Returns a list of members that exist on the type. The ResolvedMember structure indicates both /// the name and provides the MemberGroup. /// </summary> public IList<ResolvedMember/*!*/>/*!*/ ResolveMembers(MemberBinder/*!*/ binder, OldDynamicAction/*!*/ action, Type/*!*/ type) { Dictionary<string, ResolvedMember> members = new Dictionary<string, ResolvedMember>(); foreach (string name in GetCandidateNames(binder, action, type)) { if (members.ContainsKey(name)) { continue; } MemberGroup member = ResolveMember(binder, action, type, name); if (member.Count > 0) { members[name] = new ResolvedMember(name, member); } } ResolvedMember[] res = new ResolvedMember[members.Count]; members.Values.CopyTo(res, 0); return res; }
/// <summary> /// Looks up an individual member and returns a MemberGroup with the given members. /// </summary> public abstract MemberGroup/*!*/ ResolveMember(MemberBinder/*!*/ binder, OldDynamicAction/*!*/ action, Type/*!*/ type, string/*!*/ name);
private static MemberGroup/*!*/ FormatResolver(MemberBinder/*!*/ binder, Type/*!*/ type) { if (typeof(IFormattable).IsAssignableFrom(type)) { return GetInstanceOpsMethod(type, "Format"); } return MemberGroup.EmptyGroup; }
public override MemberGroup/*!*/ ResolveMember(MemberBinder/*!*/ binder, OldDynamicAction/*!*/ action, Type/*!*/ type, string/*!*/ name) { if (name == ".ctor" || name == ".cctor") return MemberGroup.EmptyGroup; // normal binding MemberGroup res; foreach (Type curType in binder.GetContributingTypes(type)) { res = GetBaseHelperOverloads(type, name, FilterSpecialNames(binder.GetMember(curType, name), name, action)); if (res.Count > 0) { return res; } } if (type.IsInterface) { foreach (Type t in type.GetInterfaces()) { res = FilterSpecialNames(binder.GetMember(t, name), name, action); if (res.Count > 0) { return res; } } } return MemberGroup.EmptyGroup; }
protected override IEnumerable<string/*!*/>/*!*/ GetCandidateNames(MemberBinder/*!*/ binder, OldDynamicAction/*!*/ action, Type/*!*/ type) { foreach (Type curType in binder.GetContributingTypes(type)) { foreach (MemberInfo mi in curType.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)) { if (mi.MemberType == MemberTypes.Method) { MethodInfo meth = (MethodInfo)mi; if (meth.IsSpecialName) { if (meth.IsDefined(typeof(PropertyMethodAttribute), true)) { if (meth.Name.StartsWith("Get") || meth.Name.StartsWith("Set")) { yield return meth.Name.Substring(3); } else { Debug.Assert(meth.Name.StartsWith("Delete")); yield return meth.Name.Substring(6); } } continue; } } yield return mi.Name; } } }
private static MemberGroup/*!*/ SerializationResolver(MemberBinder/*!*/ binder, Type/*!*/ type) { if (type.IsSerializable && !PythonBinder.IsPythonType(type)) { string methodName = "__reduce_ex__"; if (!TypeOverridesMethod(binder, type, methodName)) { return GetInstanceOpsMethod(type, "SerializeReduce"); } } return MemberGroup.EmptyGroup; }
public override MemberGroup/*!*/ ResolveMember(MemberBinder/*!*/ binder, OldDynamicAction/*!*/ action, Type/*!*/ type, string/*!*/ name) { if (type.IsSealed && type.IsAbstract) { // static types don't have PythonOperationKind return MemberGroup.EmptyGroup; } // try mapping __*__ methods to .NET method names PythonOperationKind opMap; EnsureOperatorTable(); if (_pythonOperatorTable.TryGetValue(name, out opMap)) { if (IncludeOperatorMethod(type, opMap)) { OperatorMapping opInfo; if (IsReverseOperator(opMap)) { opInfo = OperatorMapping.GetOperatorMapping(opMap & ~PythonOperationKind.Reversed); } else { opInfo = OperatorMapping.GetOperatorMapping(opMap); } if (opInfo != null) { foreach (Type curType in binder.GetContributingTypes(type)) { if (curType == typeof(BigInteger) && (opInfo.Operator == PythonOperationKind.Mod || opInfo.Operator == PythonOperationKind.RightShift || opInfo.Operator == PythonOperationKind.LeftShift || opInfo.Operator == PythonOperationKind.Compare || opInfo.Operator == PythonOperationKind.Divide)) { // we override these with our own modulus/power PythonOperationKind which are different from BigInteger. continue; } Debug.Assert(opInfo.Name != "Equals"); MemberGroup res = GetBaseHelperOverloads(type, opInfo.Name, binder.GetMember(curType, opInfo.Name)); if (res.Count == 0 && opInfo.AlternateName != null) { res = binder.GetMember(curType, opInfo.AlternateName); if (opInfo.AlternateName == "Equals") { // "Equals" is available as an alternate method name. Because it's also on object and Python // doesn't define it on object we need to filter it out. res = FilterObjectEquality(res); } else { res = GetBaseHelperOverloads(type, opInfo.AlternateName, res); } } if (res.Count > 0) { return FilterForwardReverseMethods(name, res, type, opMap); } } } } } if (name == "__call__") { MemberGroup res = binder.GetMember(type, "Call"); if (res.Count > 0) { return res; } } return MemberGroup.EmptyGroup; }
/// <summary> /// Provides a resolution for IValueEquality.GetValueHashCode to __hash__. /// </summary> private static MemberGroup/*!*/ HashResolver(MemberBinder/*!*/ binder, Type/*!*/ type) { // __repr__ for normal .NET types is special, if we're a Python type then // we'll use one of the built-in reprs (from object or from the type) if (typeof(IValueEquality).IsAssignableFrom(type) && !type.IsInterface) { return new MemberGroup(typeof(IValueEquality).GetMethod("GetValueHashCode")); } // otherwise we'll pick up __hash__ from ObjectOps which will call .NET's .GetHashCode therefore // we don't explicitly search to see if the object overrides GetHashCode here. return MemberGroup.EmptyGroup; }
protected override IEnumerable<string/*!*/>/*!*/ GetCandidateNames(MemberBinder/*!*/ binder, OldDynamicAction/*!*/ action, Type/*!*/ type) { EnsureOperatorTable(); foreach (SymbolId si in _pythonOperatorTable.Keys) { yield return SymbolTable.IdToString(si); } yield return "__call__"; }
/// <summary> /// Provides a resolution for next /// </summary> private static MemberGroup/*!*/ NextResolver(MemberBinder/*!*/ binder, Type/*!*/ type) { if (typeof(IEnumerator).IsAssignableFrom(type)) { return GetInstanceOpsMethod(type, "NextMethod"); } return MemberGroup.EmptyGroup; }
public override MemberGroup/*!*/ ResolveMember(MemberBinder/*!*/ binder, OldDynamicAction/*!*/ action, Type/*!*/ type, string/*!*/ name) { if (binder.DomainManager.Configuration.PrivateBinding) { // in private binding mode Python exposes private members under a mangled name. string header = "_" + type.Name + "__"; if (name.StartsWith(header)) { string memberName = name.Substring(header.Length); MemberGroup res = new MemberGroup(type.GetMember(memberName, _privateFlags)); if (res.Count > 0) { return FilterFieldAndEvent(res); } res = new MemberGroup(type.GetMember(memberName, BindingFlags.FlattenHierarchy | _privateFlags)); if (res.Count > 0) { return FilterFieldAndEvent(res); } } } return MemberGroup.EmptyGroup; }
/// <summary> /// Provides a resolution for __iter__ /// </summary> private static MemberGroup/*!*/ IterResolver(MemberBinder/*!*/ binder, Type/*!*/ type) { // no __iter__ on string, just __getitem__ if (type != typeof(string)) { if (typeof(System.Collections.IEnumerable).IsAssignableFrom(type)) { foreach (Type t in binder.GetContributingTypes(type)) { MemberInfo[] news = t.GetMember("__iter__"); if (news.Length > 0) { // type has a specific __i__ overload, we'll pick it up later return MemberGroup.EmptyGroup; } } // no special __iter__, use the default. return GetInstanceOpsMethod(type, "IterMethod"); } } return MemberGroup.EmptyGroup; }
protected override IEnumerable<string/*!*/>/*!*/ GetCandidateNames(MemberBinder/*!*/ binder, OldDynamicAction/*!*/ action, Type/*!*/ type) { if (!binder.DomainManager.Configuration.PrivateBinding) { yield break; } foreach (MemberInfo mi in type.GetMembers(_privateFlags | BindingFlags.FlattenHierarchy)) { yield return String.Concat("_", mi.DeclaringType.Name, "__", mi.Name); } }
/// <summary> /// Looks for an Equals overload defined on the type and if one is present binds __ne__ to an /// InstanceOps helper. /// </summary> private static MemberGroup/*!*/ FallbackInequalityResolver(MemberBinder/*!*/ binder, Type/*!*/ type) { // if object defines __eq__ then we can call the reverse version if (IncludeOperatorMethod(type, PythonOperationKind.NotEqual)) { foreach (Type curType in binder.GetContributingTypes(type)) { MemberGroup mg = binder.GetMember(curType, "Equals"); foreach (MemberTracker mt in mg) { if (mt.MemberType != TrackerTypes.Method || mt.DeclaringType == typeof(object)) { continue; } MethodTracker method = (MethodTracker)mt; if ((method.Method.Attributes & MethodAttributes.NewSlot) != 0) { continue; } ParameterInfo[] pis = method.Method.GetParameters(); if (pis.Length == 1) { if (pis[0].ParameterType == typeof(object)) { return new MemberGroup(MethodTracker.FromMemberInfo(typeof(InstanceOps).GetMethod("NotEqualsMethod"), curType)); } } } } } return MemberGroup.EmptyGroup; }
public override MemberGroup/*!*/ ResolveMember(MemberBinder/*!*/ binder, OldDynamicAction/*!*/ action, Type/*!*/ type, string/*!*/ name) { foreach (Type t in binder.GetContributingTypes(type)) { MemberGroup res = new MemberGroup(ArrayUtils.FindAll(t.GetMember(name, BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy), ProtectedOnly)); for (int i = 0; i < res.Count; i++) { MethodTracker meth = res[i] as MethodTracker; if (meth == null) { continue; } if (meth.Name == "Finalize" && meth.Method.GetBaseDefinition() == typeof(object).GetMethod("Finalize", BindingFlags.NonPublic | BindingFlags.Instance)) { MemberTracker[] retained = new MemberTracker[res.Count - 1]; if (res.Count == 1) { res = MemberGroup.EmptyGroup; } else { for (int j = 0; j < i; j++) { retained[j] = res[j]; } for (int j = i + 1; j < res.Count; j++) { retained[j - 1] = res[j]; } res = new MemberGroup(retained); } break; } } res = FilterSpecialNames(res, name, action); return GetBaseHelperOverloads(PythonTypeOps.GetFinalSystemType(type), name, res); } return MemberGroup.EmptyGroup; }
private static MemberGroup/*!*/ DirResolver(MemberBinder/*!*/ binder, Type/*!*/ type) { return binder.GetMember(type, "GetMemberNames"); }
protected override IEnumerable<string/*!*/>/*!*/ GetCandidateNames(MemberBinder/*!*/ binder, OldDynamicAction/*!*/ action, Type/*!*/ type) { // these members are visible but only accept derived types. foreach (Type t in binder.GetContributingTypes(type)) { MemberInfo[] mems = ArrayUtils.FindAll(t.GetMembers(BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic), ProtectedOnly); foreach (MemberInfo mi in mems) { yield return mi.Name; } } }
private static MemberGroup/*!*/ ExitResolver(MemberBinder/*!*/ binder, Type/*!*/ type) { if (typeof(IDisposable).IsAssignableFrom(type)) { return GetInstanceOpsMethod(type, "ExitMethod"); } return MemberGroup.EmptyGroup; }
/// <summary> /// Provides a resolution for __str__. /// </summary> private static MemberGroup/*!*/ StringResolver(MemberBinder/*!*/ binder, Type/*!*/ type) { if (type != typeof(double) && type != typeof(float)) { MethodInfo tostr = type.GetMethod("ToString", Type.EmptyTypes); if (tostr != null && tostr.DeclaringType != typeof(object)) { return GetInstanceOpsMethod(type, "ToStringMethod"); } } return MemberGroup.EmptyGroup; }
/// <summary> /// Provides an implementation of __contains__. We can pull contains from: /// ICollection of T which defines Contains directly /// IList which defines Contains directly /// IDictionary which defines Contains directly /// IDictionary of K,V which defines Contains directly /// IEnumerable of K which we have an InstaceOps helper for /// IEnumerable which we have an instance ops helper for /// IEnumerator of K which we have an InstanceOps helper for /// IEnumerator which we have an instance ops helper for /// /// String is ignored here because it defines __contains__ via extension methods already. /// /// The lookup is well ordered and not dependent upon the order of values returned by reflection. /// </summary> private static MemberGroup/*!*/ ContainsResolver(MemberBinder/*!*/ binder, Type/*!*/ type) { if (type == typeof(PythonGenerator)) { // it's enumerable but doesn't have __contains__ return MemberGroup.EmptyGroup; } List<MemberTracker> containsMembers = null; IList<Type> intf = binder.GetInterfaces(type); // if we get a __contains__ for something w/ a generic typed to object don't look for non-generic versions bool hasObjectContains = false; // search for IDictionary<K, V> first because it's ICollection<KVP<K, V>> and we want to call ContainsKey foreach (Type t in intf) { if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IDictionary<,>)) { if (t.GetGenericArguments()[0] == typeof(object)) { hasObjectContains = true; } if (containsMembers == null) { containsMembers = new List<MemberTracker>(); } containsMembers.Add(MethodTracker.FromMemberInfo(t.GetMethod("ContainsKey"))); } } if (containsMembers == null) { // then look for ICollection<T> for generic __contains__ first if we're not an IDictionary<K, V> foreach (Type t in intf) { if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(ICollection<>)) { if (t.GetGenericArguments()[0] == typeof(object)) { hasObjectContains = true; } if (containsMembers == null) { containsMembers = new List<MemberTracker>(); } containsMembers.Add(MethodTracker.FromMemberInfo(t.GetMethod("Contains"))); } } } if (!hasObjectContains) { // look for non-generic contains if we didn't already find an overload which takes // object if (intf.Contains(typeof(IList))) { if (containsMembers == null) { containsMembers = new List<MemberTracker>(); } containsMembers.Add(MethodTracker.FromMemberInfo(typeof(IList).GetMethod("Contains"))); } else if (intf.Contains(typeof(IDictionary))) { if (containsMembers == null) { containsMembers = new List<MemberTracker>(); } containsMembers.Add(MethodTracker.FromMemberInfo(typeof(IDictionary).GetMethod("Contains"))); } else if (containsMembers == null) { // see if we can produce a contains for IEnumerable GetEnumeratorContains(type, intf, ref containsMembers, ref hasObjectContains, typeof(IEnumerable<>), typeof(IEnumerable), String.Empty); if (containsMembers == null) { GetEnumeratorContains(type, intf, ref containsMembers, ref hasObjectContains, typeof(IEnumerator<>), typeof(IEnumerator), "IEnumerator"); } } } if (containsMembers != null) { return new MemberGroup(containsMembers.ToArray()); } return MemberGroup.EmptyGroup; }
/// <summary> /// Creates the filter expression. /// </summary> /// <param name="parameter">The parameter.</param> /// <param name="filterDescriptor">The filter descriptor.</param> /// <returns>The created expression</returns> private Expression CreateFilterExpression(ParameterExpression parameter, FilterDescriptor filterDescriptor) { MemberBinder <TEntity> binder = this.GetBinding(filterDescriptor.MemberName); return(binder.CreateFilterExpression(parameter, filterDescriptor)); }