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); }
/// <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)); }
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; } }
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); }
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 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)); }
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; }
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); }
/// <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)); }
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; }
public static MutableString/*!*/ GetName(TypeGroup/*!*/ self) { return MutableString.Create(self.Name, RubyEncoding.UTF8); }
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)); }
public static MutableString/*!*/ GetName(RubyContext/*!*/ context, TypeGroup/*!*/ self) { return MutableString.Create(self.Name, context.GetIdentifierEncoding()); }
public static MutableString/*!*/ GetName(TypeGroup/*!*/ self) { return MutableString.Create(self.Name); }
public static object/*!*/ New(CallSiteStorage<Func<CallSite, object, object, object>>/*!*/ storage, TypeGroup/*!*/ self, [NotNull]params object[] args) { return New("new", storage, self, args); }
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)); }
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); }
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; }
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); }
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)); }
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)); }
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); }
public static MutableString/*!*/ GetName(TypeGroup/*!*/ self) { return MutableString.CreateMutable().Append("TypeGroup of ").Append(self.Name); }
public static RubyMethod/*!*/ GetClrConstructor(RubyContext/*!*/ context, TypeGroup/*!*/ self) { return ClassOps.GetClrConstructor(GetNonGenericClass(context, self)); }
public static RubyClass GetSuperclass(RubyContext/*!*/ context, TypeGroup/*!*/ self) { Type type = GetNonGenericType(self); return type.IsInterface ? null : context.GetClass(type).SuperClass; }
public static object/*!*/ ClrNew(CallSiteStorage<Func<CallSite, object, object, object>>/*!*/ storage, TypeGroup/*!*/ self, params object[]/*!*/ args) { return New("clr_new", storage, self, args); }