}
}
-#if NET_2_0
+ internal class GenericInstanceKey {
+ Type gtd;
+ internal Type[] args;
+
+ internal GenericInstanceKey (Type gtd, Type[] args)
+ {
+ this.gtd = gtd;
+ this.args = args;
+ }
+
+ static bool IsBoundedVector (Type type) {
+ ArrayType at = type as ArrayType;
+ if (at != null)
+ return at.GetEffectiveRank () == 1;
+ return type.ToString ().EndsWith ("[*]", StringComparison.Ordinal); /*Super uggly hack, SR doesn't allow one to query for it */
+ }
+
+ static bool TypeEquals (Type a, Type b) {
+ if (a == b)
+ return true;
+
+ if (a.HasElementType) {
+ if (!b.HasElementType)
+ return false;
+ if (!TypeEquals (a.GetElementType (), b.GetElementType ()))
+ return false;
+ if (a.IsArray) {
+ if (!b.IsArray)
+ return false;
+ int rank = a.GetArrayRank ();
+ if (rank != b.GetArrayRank ())
+ return false;
+ if (rank == 1 && IsBoundedVector (a) != IsBoundedVector (b))
+ return false;
+ } else if (a.IsByRef) {
+ if (!b.IsByRef)
+ return false;
+ } else if (a.IsPointer) {
+ if (!b.IsPointer)
+ return false;
+ }
+ return true;
+ }
+
+ if (a.IsGenericType) {
+ if (!b.IsGenericType)
+ return false;
+ if (a.IsGenericParameter)
+ return a == b;
+ if (a.IsGenericParameter) //previous test should have caught it
+ return false;
+
+ if (a.IsGenericTypeDefinition) {
+ if (!b.IsGenericTypeDefinition)
+ return false;
+ } else {
+ if (b.IsGenericTypeDefinition)
+ return false;
+ if (!TypeEquals (a.GetGenericTypeDefinition (), b.GetGenericTypeDefinition ()))
+ return false;
+
+ Type[] argsA = a.GetGenericArguments ();
+ Type[] argsB = b.GetGenericArguments ();
+ for (int i = 0; i < argsA.Length; ++i) {
+ if (!TypeEquals (argsA [i], argsB [i]))
+ return false;
+ }
+ }
+ }
+
+ /*
+ Now only non-generic, non compound types are left. To properly deal with user
+ types we would have to call UnderlyingSystemType, but we let them have their
+ own instantiation as this is MS behavior and mcs (pre C# 4.0, at least) doesn't
+ depend on proper UT canonicalization.
+ */
+ return a == b;
+ }
+
+ public override bool Equals (object obj)
+ {
+ GenericInstanceKey other = obj as GenericInstanceKey;
+ if (other == null)
+ return false;
+ if (gtd != other.gtd)
+ return false;
+ for (int i = 0; i < args.Length; ++i) {
+ Type a = args [i];
+ Type b = other.args [i];
+ /*
+ We must cannonicalize as much as we can. Using equals means that some resulting types
+ won't have the exact same types as the argument ones.
+ For example, flyweight types used array, pointer and byref will should this behavior.
+ MCS seens to be resilient to this problem so hopefully this won't show up.
+ */
+ if (a != b && !a.Equals (b))
+ return false;
+ }
+ return true;
+ }
+
+ public override int GetHashCode ()
+ {
+ int hash = gtd.GetHashCode ();
+ for (int i = 0; i < args.Length; ++i)
+ hash ^= args [i].GetHashCode ();
+ return hash;
+ }
+ }
+
+
[ComVisible (true)]
[ComDefaultInterface (typeof (_AssemblyBuilder))]
-#endif
[ClassInterface (ClassInterfaceType.None)]
public sealed class AssemblyBuilder : Assembly, _AssemblyBuilder {
#pragma warning disable 169, 414
NativeResourceType native_resource;
readonly bool is_compiler_context;
string versioninfo_culture;
+ Hashtable generic_instances = new Hashtable ();
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void basic_init (AssemblyBuilder ab);
// remove Mono specific flag to allow enum check to pass
access &= ~COMPILER_ACCESS;
-#if NET_2_0
+#if MOONLIGHT
+ // only "Run" is supported by Silverlight
+ // however SMCS requires more than this but runs outside the CoreCLR sandbox
+ if (SecurityManager.SecurityEnabled && (access != AssemblyBuilderAccess.Run))
+ throw new ArgumentException ("access");
+#endif
+
if (!Enum.IsDefined (typeof (AssemblyBuilderAccess), access))
throw new ArgumentException (string.Format (CultureInfo.InvariantCulture,
"Argument value {0} is not valid.", (int) access),
"access");
-#endif
#if NET_4_0
if ((access & AssemblyBuilderAccess.RunAndCollect) == AssemblyBuilderAccess.RunAndCollect)
}
}
-#if NET_1_1
/* This is to keep signature compatibility with MS.NET */
public override string ImageRuntimeVersion {
get {
return base.ImageRuntimeVersion;
}
}
-#endif
-#if NET_2_0
[MonoTODO]
public override bool ReflectionOnly {
get { return base.ReflectionOnly; }
}
-#endif
public void AddResourceFile (string name, string fileName)
{
resources [p].data = blob;
}
-#if NET_2_0
internal void AddTypeForwarder (Type t) {
if (t == null)
throw new ArgumentNullException ("t");
+ if (t.IsNested)
+ throw new ArgumentException ();
if (type_forwarders == null) {
type_forwarders = new Type [1] { t };
type_forwarders = arr;
}
}
-#endif
public ModuleBuilder DefineDynamicModule (string name)
{
}
}
-#if NET_2_0 || BOOTSTRAP_NET_2_0
ModuleBuilder manifest_module;
//
manifest_module = DefineDynamicModule ("Default Dynamic Module");
return manifest_module;
}
-#endif
-#if NET_2_0 || BOOTSTRAP_NET_2_0
[MonoLimitation ("No support for PE32+ assemblies for AMD64 and IA64")]
public
-#else
- internal
-#endif
void Save (string assemblyFileName, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
{
this.peKind = portableExecutableKind;
flags |= ((uint) data [pos + 2]) << 16;
flags |= ((uint) data [pos + 3]) << 24;
-#if NET_2_0
// ignore PublicKey flag if assembly is not strongnamed
if (sn == null)
flags &= ~(uint) AssemblyNameFlags.PublicKey;
-#endif
}
}
}
}
-#if NET_2_0
[ComVisible (true)]
-#endif
public void SetCustomAttribute ( ConstructorInfo con, byte[] binaryAttribute) {
if (con == null)
throw new ArgumentNullException ("con");
return an;
}
+ /*Warning, @typeArguments must be a mscorlib internal array. So make a copy before passing it in*/
+ internal Type MakeGenericType (Type gtd, Type[] typeArguments)
+ {
+ if (!IsCompilerContext)
+ return new MonoGenericClass (gtd, typeArguments);
+
+ GenericInstanceKey key = new GenericInstanceKey (gtd, typeArguments);
+ MonoGenericClass res = (MonoGenericClass)generic_instances [key];
+ if (res == null) {
+ res = new MonoGenericClass (gtd, typeArguments);
+ generic_instances [key] = res;
+ }
+ return res;
+ }
+
void _AssemblyBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
{
throw new NotImplementedException ();
{
throw new NotImplementedException ();
}
+
+#if NET_4_0
+ public override Type GetType (string name, bool throwOnError, bool ignoreCase)
+ {
+ if (name == null)
+ throw new ArgumentNullException (name);
+ if (name.Length == 0)
+ throw new ArgumentException ("name", "Name cannot be empty");
+
+ var res = InternalGetType (null, name, throwOnError, ignoreCase);
+ if (res is TypeBuilder) {
+ if (throwOnError)
+ throw new TypeLoadException (string.Format ("Could not load type '{0}' from assembly '{1}'", name, this.name));
+ return null;
+ }
+ return res;
+ }
+
+ public override Module GetModule (String name)
+ {
+ if (name == null)
+ throw new ArgumentNullException ("name");
+ if (name.Length == 0)
+ throw new ArgumentException ("Name can't be empty");
+
+ if (modules == null)
+ return null;
+
+ foreach (Module module in modules) {
+ if (module.ScopeName == name)
+ return module;
+ }
+
+ return null;
+ }
+
+ public override Module[] GetModules (bool getResourceModules)
+ {
+ Module[] modules = GetModulesInternal ();
+
+ if (!getResourceModules) {
+ ArrayList result = new ArrayList (modules.Length);
+ foreach (Module m in modules)
+ if (!m.IsResource ())
+ result.Add (m);
+ return (Module[])result.ToArray (typeof (Module));
+ }
+ return modules;
+ }
+#endif
}
}