A TypeCollision is used when we have a collision between two types with the same name. Currently this is only possible w/ generic methods that should logically have arity as a portion of their name. For eg: System.EventHandler and System.EventHandler[T] System.Nullable and System.Nullable[T] System.IComparable and System.IComparable[T] The TypeCollision provides an indexer but also is a real type. When used as a real type it is the non-generic form of the type. The indexer allows the user to disambiguate between the generic and non-generic versions. Therefore users must always provide additional information to get the generic version.
Inheritance: TypeTracker
Beispiel #1
0
            internal MemberTracker UpdateTypeEntity(TypeTracker existingTypeEntity, string normalizedTypeName)
            {
                Debug.Assert(normalizedTypeName.IndexOf('.') == -1); // This is the simple name, not the full name
                Debug.Assert(ReflectionUtils.GetNormalizedTypeName(normalizedTypeName) == normalizedTypeName);

                // Look for a non-generic type
                if (_simpleTypeNames.Contains(normalizedTypeName))
                {
                    Type newType = LoadType(_assembly, GetFullChildName(normalizedTypeName));
                    if (newType != null)
                    {
                        existingTypeEntity = TypeGroup.UpdateTypeEntity(existingTypeEntity, TypeTracker.GetTypeTracker(newType));
                    }
                }

                // Look for generic types
                if (_genericTypeNames.ContainsKey(normalizedTypeName))
                {
                    List <string> actualNames = _genericTypeNames[normalizedTypeName];
                    foreach (string actualName in actualNames)
                    {
                        Type newType = LoadType(_assembly, GetFullChildName(actualName));
                        if (newType != null)
                        {
                            existingTypeEntity = TypeGroup.UpdateTypeEntity(existingTypeEntity, TypeTracker.GetTypeTracker(newType));
                        }
                    }
                }

                return(existingTypeEntity);
            }
Beispiel #2
0
        /// <param name="existingTypeEntity">The merged list so far. Could be null</param>
        /// <param name="newType">The new type(s) to add to the merged list</param>
        /// <returns>The merged list.  Could be a TypeTracker or TypeGroup</returns>
        public static TypeTracker UpdateTypeEntity(TypeTracker existingTypeEntity, TypeTracker newType)
        {
            Debug.Assert(newType != null);
            Debug.Assert(existingTypeEntity == null || (existingTypeEntity is NestedTypeTracker) || (existingTypeEntity is TypeGroup));

            if (existingTypeEntity == null)
            {
                return(newType);
            }

            NestedTypeTracker existingType          = existingTypeEntity as NestedTypeTracker;
            TypeGroup         existingTypeCollision = existingTypeEntity as TypeGroup;

            if (existingType != null)
            {
                int existingArity = GetGenericArity(existingType.Type);
                int newArity      = GetGenericArity(newType.Type);

                if (existingArity == newArity)
                {
                    return(newType);
                }

                return(new TypeGroup(existingType.Type, existingArity, newType.Type, newArity));
            }

            return(new TypeGroup(newType.Type, existingTypeCollision));
        }
Beispiel #3
0
        internal void AddTypeName(string typeName, Assembly assem)
        {
            // lock is held when this is called
            Assert.NotNull(typeName, assem);
            Debug.Assert(typeName.IndexOf(Type.Delimiter) == -1); // This is the simple name, not the full name

            if (!_typeNames.ContainsKey(assem))
            {
                _typeNames[assem] = new TypeNames(assem, _fullName);
            }
            _typeNames[assem].AddTypeName(typeName);

            string normalizedTypeName = ReflectionUtils.GetNormalizedTypeName(typeName);

            if (_dict.ContainsKey(normalizedTypeName))
            {
                // A similarly named type, namespace, or module already exists.
                Type newType = LoadType(assem, GetFullChildName(typeName));

                object      existingValue      = _dict[normalizedTypeName];
                TypeTracker existingTypeEntity = existingValue as TypeTracker;
                if (existingTypeEntity == null)
                {
                    // Replace the existing namespace or module with the new type
                    Debug.Assert(existingValue is NamespaceTracker);
                    _dict[normalizedTypeName] = MemberTracker.FromMemberInfo(newType);
                }
                else
                {
                    // Unify the new type with the existing type
                    _dict[normalizedTypeName] = TypeGroup.UpdateTypeEntity(existingTypeEntity, ReflectionCache.GetTypeTracker(newType));
                }
                return;
            }
        }
Beispiel #4
0
        public static RubyModule/*!*/ Of(RubyContext/*!*/ context, TypeGroup/*!*/ self, int genericArity) {
            TypeTracker tracker = self.GetTypeForArity(genericArity);
            if (tracker == null) {
                throw RubyExceptions.CreateArgumentError(String.Format("Type group `{0}' does not contain a type of generic arity {1}", self.Name, genericArity));
            }

            return context.GetModule(tracker.Type);
        }
Beispiel #5
0
 private TypeGroup(Type t1, TypeGroup existingTypes) {
     // TODO: types of different arities might be inherited, but we don't support that yet:
     Debug.Assert(t1.DeclaringType == existingTypes.DeclaringType);
     Debug.Assert(ReflectionUtils.GetNormalizedTypeName(t1) == existingTypes.Name);
     
     _typesByArity = new Dictionary<int, Type>(existingTypes._typesByArity);
     _typesByArity[GetGenericArity(t1)] = t1;
     _name = existingTypes.Name;
 }
Beispiel #6
0
        private TypeGroup(Type t1, TypeGroup existingTypes)
        {
            // TODO: types of different arities might be inherited, but we don't support that yet:
            Debug.Assert(t1.DeclaringType == existingTypes.DeclaringType);
            Debug.Assert(ReflectionUtils.GetNormalizedTypeName(t1) == existingTypes.Name);

            _typesByArity = new Dictionary <int, Type>(existingTypes._typesByArity);
            _typesByArity[GetGenericArity(t1)] = t1;
            _name = existingTypes.Name;
        }
        private void MakeTypeBody(Type type, MemberGroup members)
        {
            TypeTracker typeTracker = (TypeTracker)members[0];

            for (int i = 1; i < members.Count; i++)
            {
                typeTracker = TypeGroup.UpdateTypeEntity(typeTracker, (TypeTracker)members[i]);
            }

            AddToBody(Rule.MakeReturn(Binder, typeTracker.GetValue(Binder, type)));
        }
        private void MakeTypeBody(GetMemberInfo getMemInfo, Type instanceType, MemberGroup members)
        {
            TypeTracker typeTracker = (TypeTracker)members[0];

            for (int i = 1; i < members.Count; i++)
            {
                typeTracker = TypeGroup.UpdateTypeEntity(typeTracker, (TypeTracker)members[i]);
            }

            getMemInfo.Body.FinishCondition(typeTracker.GetValue(getMemInfo.ResolutionFactory, this, instanceType));
        }
Beispiel #9
0
        public static object EachType(RubyContext/*!*/ context, BlockParam/*!*/ block, TypeGroup/*!*/ self) {
            if (block == null) {
                throw RubyExceptions.NoBlockGiven();
            }

            foreach (Type type in self.Types) {
                RubyModule module = context.GetModule(type);
                object result;
                if (block.Yield(module, out result)) {
                    return result;
                }
            }

            return self;
        }
Beispiel #10
0
        public static RubyModule/*!*/ Of(RubyContext/*!*/ context, TypeGroup/*!*/ self, [NotNull]params object[]/*!*/ typeArgs) {
            TypeTracker tracker = self.GetTypeForArity(typeArgs.Length);

            if (tracker == null) {
                throw RubyExceptions.CreateArgumentError(String.Format("Invalid number of type arguments for `{0}'", self.Name));
            }

            Type concreteType;
            if (typeArgs.Length > 0) {
                concreteType = tracker.Type.MakeGenericType(Protocols.ToTypes(context, typeArgs));
            } else {
                concreteType = tracker.Type;
            }

            return context.GetModule(concreteType);
        }
Beispiel #11
0
        /// <param name="existingTypeEntity">The merged list so far. Could be null</param>
        /// <param name="newType">The new type(s) to add to the merged list</param>
        /// <returns>The merged list.  Could be a TypeTracker or TypeGroup</returns>
        public static TypeTracker UpdateTypeEntity(
            TypeTracker existingTypeEntity,
            TypeTracker newType)
        {
            Debug.Assert(newType != null);
            Debug.Assert(existingTypeEntity == null || (existingTypeEntity is NestedTypeTracker) || (existingTypeEntity is TypeGroup));

            if (existingTypeEntity == null)
            {
                return(newType);
            }

            NestedTypeTracker existingType          = existingTypeEntity as NestedTypeTracker;
            TypeGroup         existingTypeCollision = existingTypeEntity as TypeGroup;

#if DEBUG
            string existingEntityNormalizedName = (existingType != null) ? ReflectionUtils.GetNormalizedTypeName(existingType.Type)
                                                                         : existingTypeCollision.NormalizedName;
            string newEntityNormalizedName = ReflectionUtils.GetNormalizedTypeName(newType.Type);
            Debug.Assert(existingEntityNormalizedName == newEntityNormalizedName);
#endif

            if (existingType != null)
            {
                if (GetGenericArity(existingType.Type) == GetGenericArity(newType.Type))
                {
                    return(newType);
                }

                return(new TypeGroup(existingType.Type, newType.Type));
            }

            // copy the dictionary and return a new collision
            Dictionary <int, Type> copy = new Dictionary <int, Type>(existingTypeCollision._typesByArity);
            return(new TypeGroup(newType.Type, copy));
        }
Beispiel #12
0
        public static MutableString/*!*/ Inspect(RubyContext/*!*/ context, TypeGroup/*!*/ self) {
            var result = MutableString.CreateMutable(RubyEncoding.ClassName);
            result.Append("#<TypeGroup: ");

            bool isFirst = true;
            foreach (var entry in self.TypesByArity.ToSortedList((x, y) => x.Key - y.Key)) {
                Type type = entry.Value;

                if (!isFirst) {
                    result.Append(", ");
                } else {
                    isFirst = false;
                }

                result.Append(context.GetTypeName(type, true));
            }
            result.Append('>');

            return result;
        }
Beispiel #13
0
 public static MutableString/*!*/ GetName(TypeGroup/*!*/ self) {
     return MutableString.Create(self.Name, RubyEncoding.UTF8);
 }
Beispiel #14
0
        private static object New(string/*!*/ methodName, CallSiteStorage<Func<CallSite, object, object, object>>/*!*/ storage,
            TypeGroup/*!*/ self, params object[]/*!*/ args) {

            var cls = GetNonGenericClass(storage.Context, self);
            var site = storage.GetCallSite(methodName,
                new RubyCallSignature(1, RubyCallFlags.HasImplicitSelf | RubyCallFlags.HasSplattedArgument)
            );

            return site.Target(site, cls, RubyOps.MakeArrayN(args));
        }
Beispiel #15
0
 public static MutableString/*!*/ GetName(RubyContext/*!*/ context, TypeGroup/*!*/ self) {
     return MutableString.Create(self.Name, context.GetIdentifierEncoding());
 }
Beispiel #16
0
 public static MutableString/*!*/ GetName(TypeGroup/*!*/ self) {
     return MutableString.Create(self.Name);
 }
Beispiel #17
0
 public static object/*!*/ New(CallSiteStorage<Func<CallSite, object, object, object>>/*!*/ storage, 
     TypeGroup/*!*/ self, [NotNull]params object[] args) {
     return New("new", storage, self, args);
 }
Beispiel #18
0
        private static object/*!*/ New(string/*!*/ methodName, CallSiteStorage<Func<CallSite, object, object, object, object>>/*!*/ storage, BlockParam block, 
            TypeGroup/*!*/ self, [NotNull]params object[] args) {

            var cls = GetNonGenericClass(storage.Context, self);
            var site = storage.GetCallSite(methodName,
                new RubyCallSignature(1, RubyCallFlags.HasImplicitSelf | RubyCallFlags.HasSplattedArgument | RubyCallFlags.HasBlock)
            );

            return site.Target(site, cls, block != null ? block.Proc : null, RubyOps.MakeArrayN(args));
        }
Beispiel #19
0
 public static RubyClass/*!*/ GetNonGenericClass(RubyContext/*!*/ context, TypeGroup/*!*/ typeGroup) {
     Type type = GetNonGenericType(typeGroup);
     if (type.IsInterface) {
         throw RubyExceptions.CreateTypeError("cannot instantiate an interface");
     }
     return context.GetClass(type);
 }
Beispiel #20
0
        private static Type/*!*/ GetNonGenericType(TypeGroup/*!*/ self) {
            TypeTracker type = self.GetTypeForArity(0);
            if (type == null) {
                throw RubyExceptions.CreateTypeError("type group doesn't include non-generic type");
            }

            return type.Type;
        }
Beispiel #21
0
 public static object New(CallSiteStorage<Func<CallSite, object, object, object, object>>/*!*/ storage, BlockParam block, 
     TypeGroup/*!*/ self, params object[]/*!*/ args) {
     return New("new", storage, block, self, args);
 }
Beispiel #22
0
        private MetaObject MakeGetMemberTarget(GetMemberInfo getMemInfo, MetaObject target)
        {
            Type         type         = target.LimitType.IsCOMObject ? target.Expression.Type : target.LimitType;
            Restrictions restrictions = target.Restrictions;
            Expression   self         = target.Expression;

            target = target.Restrict(target.LimitType);

            // needed for GetMember call until DynamicAction goes away
            OldDynamicAction act = OldGetMemberAction.Make(
                this,
                getMemInfo.Name
                );

            // Specially recognized types: TypeTracker, NamespaceTracker, and StrongBox.
            // TODO: TypeTracker and NamespaceTracker should technically be IDO's.
            MemberGroup members = MemberGroup.EmptyGroup;

            if (typeof(TypeTracker).IsAssignableFrom(type))
            {
                restrictions = restrictions.Merge(
                    Restrictions.GetInstanceRestriction(target.Expression, target.Value)
                    );

                TypeGroup tg = target.Value as TypeGroup;
                Type      nonGen;
                if (tg == null || tg.TryGetNonGenericType(out nonGen))
                {
                    members = GetMember(act, ((TypeTracker)target.Value).Type, getMemInfo.Name);
                    if (members.Count > 0)
                    {
                        // we have a member that's on the type associated w/ the tracker, return that...
                        type = ((TypeTracker)target.Value).Type;
                        self = null;
                    }
                }
            }

            if (members.Count == 0)
            {
                // Get the members
                members = GetMember(act, type, getMemInfo.Name);
            }

            if (members.Count == 0)
            {
                if (typeof(TypeTracker).IsAssignableFrom(type))
                {
                    // ensure we don't have a non-generic type, and if we do report an error now.  This matches
                    // the rule version of the default binder but should probably be removed long term
                    Type x = ((TypeTracker)target.Value).Type;
                }
                else if (type.IsInterface)
                {
                    // all interfaces have object members
                    type    = typeof(object);
                    members = GetMember(act, type, getMemInfo.Name);
                }
            }

            Expression propSelf = self;

            // if lookup failed try the strong-box type if available.
            if (members.Count == 0 && typeof(IStrongBox).IsAssignableFrom(type))
            {
                // properties/fields need the direct value, methods hold onto the strong box.
                propSelf = Ast.Field(AstUtils.Convert(self, type), type.GetField("Value"));

                type = type.GetGenericArguments()[0];

                members = GetMember(
                    act,
                    type,
                    getMemInfo.Name
                    );
            }

            MakeBodyHelper(getMemInfo, self, propSelf, type, members);

            getMemInfo.Body.Restrictions = restrictions;
            return(getMemInfo.Body.GetMetaObject(target));
        }
Beispiel #23
0
        private DynamicMetaObject MakeGetMemberTarget(GetMemberInfo getMemInfo, DynamicMetaObject target)
        {
            Type targetType = target.GetLimitType();
            BindingRestrictions restrictions = target.Restrictions;
            DynamicMetaObject   self         = target;

            target = target.Restrict(target.GetLimitType());

            // Specially recognized types: TypeTracker, NamespaceTracker, and StrongBox.
            // TODO: TypeTracker and NamespaceTracker should technically be IDO's.
            MemberGroup members = MemberGroup.EmptyGroup;

            if (typeof(TypeTracker).IsAssignableFrom(targetType))
            {
                restrictions = restrictions.Merge(
                    BindingRestrictions.GetInstanceRestriction(target.Expression, target.Value)
                    );

                TypeGroup tg = target.Value as TypeGroup;
                if (tg == null || tg.TryGetNonGenericType(out Type _))
                {
                    members = GetMember(MemberRequestKind.Get, ((TypeTracker)target.Value).Type, getMemInfo.Name);
                    if (members.Count > 0)
                    {
                        // we have a member that's on the type associated w/ the tracker, return that...
                        targetType = ((TypeTracker)target.Value).Type;
                        self       = null;
                    }
                }
            }

            if (members.Count == 0)
            {
                // Get the members
                members = GetMember(MemberRequestKind.Get, targetType, getMemInfo.Name);
            }

            if (members.Count == 0)
            {
                if (typeof(TypeTracker).IsAssignableFrom(targetType))
                {
                    // Throws an exception if we don't have a non-generic type, and if we do report an error now.  This matches
                    // the rule version of the default binder but should probably be removed long term.
                    EnsureTrackerRepresentsNonGenericType((TypeTracker)target.Value);
                }
                else if (targetType.IsInterface)
                {
                    // all interfaces have object members
                    targetType = typeof(object);
                    members    = GetMember(MemberRequestKind.Get, targetType, getMemInfo.Name);
                }
            }

            DynamicMetaObject propSelf = self;

            // if lookup failed try the strong-box type if available.
            if (members.Count == 0 && typeof(IStrongBox).IsAssignableFrom(targetType) && propSelf != null)
            {
                // properties/fields need the direct value, methods hold onto the strong box.
                propSelf = new DynamicMetaObject(
                    Expression.Field(AstUtils.Convert(propSelf.Expression, targetType), targetType.GetInheritedFields("Value").First()),
                    propSelf.Restrictions,
                    ((IStrongBox)propSelf.Value).Value
                    );

                targetType = targetType.GetGenericArguments()[0];

                members = GetMember(
                    MemberRequestKind.Get,
                    targetType,
                    getMemInfo.Name
                    );
            }

            MakeBodyHelper(getMemInfo, self, propSelf, targetType, members);

            getMemInfo.Body.Restrictions = restrictions;
            return(getMemInfo.Body.GetMetaObject(target));
        }
Beispiel #24
0
 public static object/*!*/ ClrNew(CallSiteStorage<Func<CallSite, object, object, object, object>>/*!*/ storage, BlockParam block,
     TypeGroup/*!*/ self, [NotNull]params object[] args) {
     return New("clr_new", storage, block, self, args);
 }
Beispiel #25
0
 public static MutableString/*!*/ GetName(TypeGroup/*!*/ self) {
     return MutableString.CreateMutable().Append("TypeGroup of ").Append(self.Name);
 }
Beispiel #26
0
 public static RubyMethod/*!*/ GetClrConstructor(RubyContext/*!*/ context, TypeGroup/*!*/ self) {
     return ClassOps.GetClrConstructor(GetNonGenericClass(context, self));
 }
Beispiel #27
0
 public static RubyClass GetSuperclass(RubyContext/*!*/ context, TypeGroup/*!*/ self) {
     Type type = GetNonGenericType(self);
     return type.IsInterface ? null : context.GetClass(type).SuperClass;
 }
Beispiel #28
0
 public static object/*!*/ ClrNew(CallSiteStorage<Func<CallSite, object, object, object>>/*!*/ storage,
     TypeGroup/*!*/ self, params object[]/*!*/ args) {
     return New("clr_new", storage, self, args);
 }