/// <summary> Creates a new TypeCollision using this types generic list w/ the specified /// non-generic type as the TypeCollision's ReflectedType.</summary> internal TypeCollision CloneWithNewBase(Type newBase) { Debug.Assert(!newBase.ContainsGenericParameters); TypeCollision res = new TypeCollision(newBase); res.types.AddRange(types); if (type.ContainsGenericParameters) { // if we have a collision between two non-generic // types new newer type simply wins. res.types.Add((ReflectedType)Ops.GetDynamicTypeFromType(type)); } return res; }
internal DynamicType SaveType(Type type) { string name = GetCoreTypeName(type); object existingType; // if there's no collisions we just save the type if (!__dict__.TryGetValue(SymbolTable.StringToId(name), out existingType)) { DynamicType ret; __dict__[SymbolTable.StringToId(name)] = ret = Ops.GetDynamicTypeFromType(type); return ret; } // two types w/ the same name. Good examples are: // System.Nullable and System.Nullable<T> // System.IComparable vs System.IComparable<T> // In this case we need to allow the user to disambiguate the two. // // Or we could have a recompile & reload cycle (or a really bad // collision). In those cases the new type wins. TypeCollision tc = existingType as TypeCollision; if (tc != null) { // we've collided before... if (!type.ContainsGenericParameters) { // we're replacing the existing non generic type // or moving some random generic type from the "base" // reflected type into the list of generics. __dict__[SymbolTable.StringToId(name)] = tc = tc.CloneWithNewBase(type); } else { // we're a generic type. we just need to add // ourselves to the list or replace an existing type // of the same arity. tc.UpdateType(type); } } else { // first time collision on this name, provide // the type collision to disambiguate. The non-generic // is exposed by default, and the generic gets added // to the list to disambiguate. ReflectedType rt = existingType as ReflectedType; Debug.Assert(rt != null); if (rt.type.ContainsGenericParameters) { // existing type has generics, append it. tc = new TypeCollision(type); __dict__[SymbolTable.StringToId(name)] = tc; tc.UpdateType(rt.type); } else if (type.ContainsGenericParameters) { // new type has generics, append it. tc = new TypeCollision(rt.type); __dict__[SymbolTable.StringToId(name)] = tc; tc.UpdateType(type); } else { // neither type has generics, replace the old // non-generic type w/ the new non-generic type. __dict__[SymbolTable.StringToId(name)] = Ops.GetDynamicTypeFromType(type); } } return tc; }