Beispiel #1
0
 public override MemberGroup GetMember(MemberRequestKind action, Type type, string name)
 {
     if (type == typeof(string))
     {
         var method = typeof(IronTjs.Builtins.String).GetMethod(name);
         if (method != null)
         {
             return(new MemberGroup(MemberTracker.FromMemberInfo(method, typeof(string))));
         }
         var property = typeof(IronTjs.Builtins.String).GetField(name + "Property");
         if (property != null && property.FieldType == typeof(ExtensionPropertyTracker))
         {
             return(new MemberGroup((ExtensionPropertyTracker)property.GetValue(null)));
         }
         return(MemberGroup.EmptyGroup);
     }
     else if (type.IsSubclassOf(typeof(Exception)))
     {
         var property = typeof(IronTjs.Builtins.Exception).GetField(name + "Property");
         if (property != null && property.FieldType == typeof(ExtensionPropertyTracker))
         {
             return(new MemberGroup((ExtensionPropertyTracker)property.GetValue(null)));
         }
     }
     return(base.GetMember(action, type, name));
 }
        public override MemberGroup GetMember(MemberRequestKind actionKind, Type type, string name)
        {
            var res = base.GetMember(actionKind, type, name);

            if (res.Count == 0)
            {
                List <MemberTracker> trackers = new List <MemberTracker>();

                foreach (var method in _extMethodSet.GetExtensionMethods(name))
                {
                    var parameters = method.GetParameters();
                    if (parameters.Length == 0)
                    {
                        continue;
                    }

                    var paramType = parameters[0].ParameterType;

                    if (IsApplicableExtensionMethod(type, paramType))
                    {
                        trackers.Add(MemberTracker.FromMemberInfo(method, paramType));
                    }
                }

                if (trackers.Count > 0)
                {
                    return(new MemberGroup(trackers.ToArray()));
                }
            }
            return(res);
        }
Beispiel #3
0
        /// <summary>
        /// Gets the members that are visible from the provided type of the specified name.
        ///
        /// The default implemetnation first searches the type, then the flattened heirachy of the type, and then
        /// registered extension methods.
        /// </summary>
        public virtual MemberGroup GetMember(MemberRequestKind action, Type type, string name)
        {
            IEnumerable <MemberInfo> foundMembers = type.GetInheritedMembers(name);

            if (!PrivateBinding)
            {
                foundMembers = CompilerHelpers.FilterNonVisibleMembers(type, foundMembers);
            }

            MemberGroup members = new MemberGroup(foundMembers.ToArray());

            // check for generic types w/ arity...
            string          genName  = name + ReflectionUtils.GenericArityDelimiter;
            List <TypeInfo> genTypes = null;

            foreach (TypeInfo t in type.GetDeclaredNestedTypes())
            {
                if (t.IsPublic && t.Name.StartsWith(genName))
                {
                    if (genTypes == null)
                    {
                        genTypes = new List <TypeInfo>();
                    }

                    genTypes.Add(t);
                }
            }

            if (genTypes != null)
            {
                List <MemberTracker> mt = new List <MemberTracker>(members);
                foreach (TypeInfo t in genTypes)
                {
                    mt.Add(MemberTracker.FromMemberInfo(t));
                }
                return(MemberGroup.CreateInternal(mt.ToArray()));
            }

            if (members.Count == 0)
            {
                members = new MemberGroup(
                    type.GetInheritedMembers(name, flattenHierarchy: true).WithBindingFlags(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance).ToArray()
                    );

                if (members.Count == 0)
                {
                    members = GetAllExtensionMembers(type, name);
                }
            }

            return(members);
        }
        public override MemberGroup GetMember(MemberRequestKind actionKind, Type type, string name) {
            var res = base.GetMember(actionKind, type, name);
            if (res.Count == 0) {
                List<MemberTracker> trackers = new List<MemberTracker>();

                foreach (var method in _extMethodSet.GetExtensionMethods(name)) {
                    var parameters = method.GetParameters();
                    if (parameters.Length == 0) {
                        continue;
                    }

                    var paramType = parameters[0].ParameterType;

                    if (IsApplicableExtensionMethod(type, paramType)) {
                        trackers.Add(MemberTracker.FromMemberInfo(method, paramType));
                    }
                }

                if (trackers.Count > 0) {
                    return new MemberGroup(trackers.ToArray());
                }
            }
            return res;
        }
Beispiel #5
0
            protected override IEnumerable<string/*!*/>/*!*/ GetCandidateNames(MemberBinder/*!*/ binder, MemberRequestKind/*!*/ 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);
                }
            }
Beispiel #6
0
            protected override IEnumerable<string/*!*/>/*!*/ GetCandidateNames(MemberBinder/*!*/ binder, MemberRequestKind/*!*/ action, Type/*!*/ type) {
                EnsureOperatorTable();

                foreach (string si in _pythonOperatorTable.Keys) {
                    yield return si;
                }

                yield return "__call__";
            }
Beispiel #7
0
            public override MemberGroup/*!*/ ResolveMember(MemberBinder/*!*/ binder, MemberRequestKind/*!*/ 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;
            }
Beispiel #8
0
            /// <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, MemberRequestKind/*!*/ 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;
            }
Beispiel #9
0
            public override MemberGroup/*!*/ ResolveMember(MemberBinder/*!*/ binder, MemberRequestKind/*!*/ 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 !CLR2
                                if (curType == typeof(double)) {
                                    if ((opInfo.Operator & PythonOperationKind.Comparison) != 0) {
                                        // we override these with our own comparisons in DoubleOps
                                        continue;
                                    }
                                } else
#endif
                                if (curType == typeof(BigInteger)) {
                                    if (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;
                                    }
#if !CLR2
                                } else if (curType == typeof(Complex) && opInfo.Operator == PythonOperationKind.Divide) {
                                    // we override this with our own division PythonOperationKind which is different from .NET Complex.
                                    continue;
#endif
                                }

                                Debug.Assert(opInfo.Name != "Equals");

                                MemberGroup res = 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);
                                    }

                                    res = FilterAlternateMethods(opInfo, 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;
            }
Beispiel #10
0
        /// <summary>
        /// Gets the statically known member from the type with the specific name.  Searches only the specified type to find the member.
        /// </summary>
        public static MemberGroup/*!*/ GetMember(PythonBinder/*!*/ binder, MemberRequestKind/*!*/ action, Type/*!*/ type, string/*!*/ name) {
            Assert.NotNull(binder, action, type, name);

            PerfTrack.NoteEvent(PerfTrack.Categories.ReflectedTypes, String.Format("LookupMember: {0} {1}", type.Name, name));
            return GetMemberGroup(new LookupBinder(binder), action, type, name);
        }
Beispiel #11
0
        /// <summary>
        /// Gets the members that are visible from the provided type of the specified name.
        /// 
        /// The default implemetnation first searches the type, then the flattened heirachy of the type, and then
        /// registered extension methods.
        /// </summary>
        public virtual MemberGroup GetMember(MemberRequestKind action, Type type, string name) {
            IEnumerable<MemberInfo> foundMembers = type.GetInheritedMembers(name);
            if (!PrivateBinding) {
                foundMembers = CompilerHelpers.FilterNonVisibleMembers(type, foundMembers);
            }

            MemberGroup members = new MemberGroup(foundMembers.ToArray());

            // check for generic types w/ arity...
            string genName = name + ReflectionUtils.GenericArityDelimiter;
            List<TypeInfo> genTypes = null;
            foreach (TypeInfo t in type.GetDeclaredNestedTypes()) {
                if (t.IsPublic && t.Name.StartsWith(genName)) {
                    if (genTypes == null) {
                        genTypes = new List<TypeInfo>();
                    }

                    genTypes.Add(t);
                }
            }

            if (genTypes != null) {
                List<MemberTracker> mt = new List<MemberTracker>(members);
                foreach (TypeInfo t in genTypes) {
                    mt.Add(MemberTracker.FromMemberInfo(t));
                }
                return MemberGroup.CreateInternal(mt.ToArray());
            }

            if (members.Count == 0) {
                members = new MemberGroup(
                    type.GetInheritedMembers(name, flattenHierarchy: true).WithBindingFlags(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance).ToArray()
                );

                if (members.Count == 0) {
                    members = GetAllExtensionMembers(type, name);
                }
            }

            return members;
        }
Beispiel #12
0
            protected override IEnumerable<string/*!*/>/*!*/ GetCandidateNames(MemberBinder/*!*/ binder, MemberRequestKind/*!*/ 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;
                    }
                }
            }
Beispiel #13
0
            public override MemberGroup/*!*/ ResolveMember(MemberBinder/*!*/ binder, MemberRequestKind/*!*/ action, Type/*!*/ type, string/*!*/ name) {
                Assert.NotNull(binder, action, type, name);

                bool equality;
                switch (name) {
                    case "__eq__": equality = true; break;
                    case "__ne__": equality = false; break;
                    default:
                        return MemberGroup.EmptyGroup;
                }

                if (typeof(IStructuralEquatable).IsAssignableFrom(type)) {
                    return new MemberGroup(
                        GetEqualityMethods(type, equality ? "StructuralEqualityMethod" : "StructuralInequalityMethod")
                    );
#if CLR2
                } else if (typeof(IValueEquality).IsAssignableFrom(type)) {
                    return new MemberGroup(
                        GetEqualityMethods(type, equality ? "ValueEqualsMethod" : "ValueNotEqualsMethod")
                    );
#endif
                }

                return MemberGroup.EmptyGroup;
            }
Beispiel #14
0
            public override MemberGroup/*!*/ ResolveMember(MemberBinder/*!*/ binder, MemberRequestKind/*!*/ action, Type/*!*/ type, string/*!*/ name) {
                Assert.NotNull(binder, action, type, name);

                if (name == _name) {
                    return _resolver(binder, type);
                }

                return MemberGroup.EmptyGroup;
            }
Beispiel #15
0
            public override MemberGroup/*!*/ ResolveMember(MemberBinder/*!*/ binder, MemberRequestKind/*!*/ 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 = 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;
            }
Beispiel #16
0
        private static MemberGroup/*!*/ FilterSpecialNames(MemberGroup/*!*/ group, string/*!*/ name, MemberRequestKind/*!*/ action) {
            Assert.NotNull(group, name, action);

            bool filter = true;
            if (action == MemberRequestKind.Invoke ||
                action == MemberRequestKind.Convert ||
                action == MemberRequestKind.Operation) {
                filter = false;
            }

            if (!IsPythonRecognizedOperator(name)) {
                filter = false;
            }

            List<MemberTracker> mts = null;
            for (int i = 0; i < group.Count; i++) {
                MemberTracker mt = group[i];
                bool skip = false;

                if (mt.MemberType == TrackerTypes.Method) {
                    MethodTracker meth = (MethodTracker)mt;
                    if (meth.Method.IsSpecialName && mt.Name != "op_Implicit" && mt.Name != "op_Explicit") {
                        if (!IsPropertyWithParameters(meth)) {
                            skip = true;
                        }
                    }

                    if (meth.Method.IsDefined(typeof(ClassMethodAttribute), true)) {
                        return new MemberGroup(new ClassMethodTracker(group));
                    }
                } else if (mt.MemberType == TrackerTypes.Property) {
                    PropertyTracker pt = (PropertyTracker)mt;
                    if (name == pt.Name && pt.GetIndexParameters().Length > 0 && IsPropertyDefaultMember(pt)) {
                        // exposed via __*item__, not the property name
                        skip = true;
                    }
                } else if (mt.MemberType == TrackerTypes.Field) {
                    FieldInfo fi = ((FieldTracker)mt).Field;

                    if (fi.IsDefined(typeof(SlotFieldAttribute), false)) {
                        if (mts == null) {
                            mts = MakeListWithPreviousMembers(group, mts, i);

                            mt = new CustomAttributeTracker(mt.DeclaringType, mt.Name, (PythonTypeSlot)fi.GetValue(null));
                        }
                    }
                }

                if (skip && filter) {
                    if (mts == null) {
                        // add any ones we skipped...
                        mts = MakeListWithPreviousMembers(group, mts, i);
                    }
                } else if (mts != null) {
                    mts.Add(mt);
                }
            }
            if (mts != null) {
                if (mts.Count == 0) {
                    return MemberGroup.EmptyGroup;
                }
                return new MemberGroup(mts.ToArray());
            }
            return group;
        }
Beispiel #17
0
 /// <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, MemberRequestKind/*!*/ action, Type/*!*/ type);
Beispiel #18
0
        /// <summary>
        /// Primary worker for returning a list of all members in a type.  Can be called with different MemberBinder's to alter the scope
        /// of the search.
        /// </summary>
        private static IList<ResolvedMember/*!*/>/*!*/ GetResolvedMembers(MemberBinder/*!*/ memberBinder, MemberRequestKind/*!*/ action, Type/*!*/ type) {
            List<ResolvedMember> res = new List<ResolvedMember>();

            foreach (MemberResolver resolver in _resolvers) {
                res.AddRange(resolver.ResolveMembers(memberBinder, action, type));
            }

            return res;
        }
Beispiel #19
0
            public override MemberGroup/*!*/ ResolveMember(MemberBinder/*!*/ binder, MemberRequestKind/*!*/ action, Type/*!*/ type, string/*!*/ name) {
                foreach (Type t in binder.GetContributingTypes(type)) {
                    MemberGroup res = new MemberGroup(
                        t.GetMember(name, BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy)
                        .Where(ProtectedOnly)
                        .ToArray());

                    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;
                        }
                    }
                    return FilterSpecialNames(res, name, action);
                }

                return MemberGroup.EmptyGroup;
            }
Beispiel #20
0
 /// <summary>
 /// Looks up an individual member and returns a MemberGroup with the given members.
 /// </summary>
 public abstract MemberGroup/*!*/ ResolveMember(MemberBinder/*!*/ binder, MemberRequestKind/*!*/ action, Type/*!*/ type, string/*!*/ name);
Beispiel #21
0
 protected override IEnumerable<string/*!*/>/*!*/ GetCandidateNames(MemberBinder/*!*/ binder, MemberRequestKind/*!*/ action, Type/*!*/ type) {
     // these members are visible but only accept derived types.
     foreach (Type t in binder.GetContributingTypes(type)) {
         foreach (MemberInfo mi in t.GetMembers(BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic)) {
             if (ProtectedOnly(mi)) {
                 yield return mi.Name;
             }
         }
     }
 }
Beispiel #22
0
            public override MemberGroup/*!*/ ResolveMember(MemberBinder/*!*/ binder, MemberRequestKind/*!*/ action, Type/*!*/ type, string/*!*/ name) {
                Assert.NotNull(binder, action, type, name);

                // Do not map IComparable if this is a primitive builtin type.
                if (_excludePrimitiveTypes) {
                    if (type.IsPrimitive() || type == typeof(BigInteger) ||
                        type == typeof(string) || type == typeof(decimal)) {
                        return MemberGroup.EmptyGroup;
                    }
                }

                string helperName;
                if (_helperMap.TryGetValue(name, out helperName) &&
                    _comparable.IsAssignableFrom(type)) {
                    return new MemberGroup(GetEqualityMethods(type, helperName));
                }

                return MemberGroup.EmptyGroup;
            }
Beispiel #23
0
        /// <summary>
        /// Gets all the statically known members from the specified type.  Searches only the specified type to find the members.
        /// 
        /// The result may include multiple resolution.  It is the callers responsibility to only treat the 1st one by name as existing.
        /// </summary>
        public static IList<ResolvedMember/*!*/>/*!*/ GetMembers(PythonBinder/*!*/ binder, MemberRequestKind/*!*/ action, Type/*!*/ type) {
            Assert.NotNull(binder, action, type);

            return GetResolvedMembers(new LookupBinder(binder), action, type);
        }
Beispiel #24
0
 protected override IEnumerable<string/*!*/>/*!*/ GetCandidateNames(MemberBinder/*!*/ binder, MemberRequestKind/*!*/ action, Type/*!*/ type) {
     return _helperMap.Keys;
 }
Beispiel #25
0
 protected override IEnumerable<string/*!*/>/*!*/ GetCandidateNames(MemberBinder/*!*/ binder, MemberRequestKind/*!*/ action, Type/*!*/ type) {
     yield return "__eq__";
     yield return "__ne__";
 }
Beispiel #26
0
        /// <summary>
        /// Primary worker for getting the member(s) associated with a single name.  Can be called with different MemberBinder's to alter the
        /// scope of the search.
        /// </summary>
        private static MemberGroup/*!*/ GetMemberGroup(MemberBinder/*!*/ memberBinder, MemberRequestKind/*!*/ action, Type/*!*/ type, string/*!*/ name) {
            foreach (MemberResolver resolver in _resolvers) {
                MemberGroup/*!*/ group = resolver.ResolveMember(memberBinder, action, type, name);
                if (group.Count > 0) {
                    return group;
                }
            }

            return MemberGroup.EmptyGroup;
        }