In ilasm/tests:
[mono.git] / mcs / ilasm / codegen / GenericTypeInst.cs
1 //
2 // Mono.ILASM.GenericTypeInst
3 //
4 // Author(s):
5 //  Jackson Harper (Jackson@LatitudeGeo.com)
6 //  Ankit Jain (JAnkit@novell.com)
7 //
8 // (C) 2003 Latitude Geographics Group, All rights reserved
9 // (C) 2005 Novell, Inc (http://www.novell.com)
10 //
11
12
13 using System;
14 using System.Collections;
15
16 namespace Mono.ILASM {
17
18         public class GenericTypeInst : ModifiableType, IGenericTypeRef {
19
20                 private IClassRef class_ref;
21                 private PEAPI.Type ptype;
22                 private PEAPI.GenericTypeInst p_gen_inst;
23                 private bool is_valuetypeinst;
24                 private bool is_resolved;
25                 private GenericArguments gen_args;
26                 private string sig_mod;
27                 private bool is_added; /* Added to PEFile (to TypeSpec table) ? */
28                 private static Hashtable method_table = new Hashtable ();
29
30                 public GenericTypeInst (IClassRef class_ref, GenericArguments gen_args, bool is_valuetypeinst)
31                         : this (class_ref, gen_args, is_valuetypeinst, null, null)
32                 {
33                 }
34
35                 public GenericTypeInst (IClassRef class_ref, GenericArguments gen_args, bool is_valuetypeinst,
36                                 string sig_mod, ArrayList conv_list)
37                 {
38                         if (class_ref is GenericTypeInst)
39                                 throw new ArgumentException (String.Format ("Cannot create nested GenericInst, '{0}' '{1}'", class_ref.FullName, gen_args.ToString ()));
40
41                         this.class_ref = class_ref;
42                         this.gen_args = gen_args;
43                         this.is_valuetypeinst = is_valuetypeinst;
44                         this.sig_mod = sig_mod;
45                         is_added = false;
46                         if (conv_list != null)
47                                 ConversionList = conv_list;
48
49                         is_resolved = false;
50                 }
51
52                 public PEAPI.Type PeapiType {
53                         get { return ptype; }
54                 }
55
56                 public string FullName {
57                         get { return class_ref.FullName + gen_args.ToString () + SigMod; }
58                 }
59
60                 public PEAPI.Class PeapiClass {
61                         get { return (PEAPI.Class) ptype; }
62                 }
63
64                 public override string SigMod {
65                         get { return sig_mod; }
66                         set { sig_mod = value; }
67                 }
68
69                 public IClassRef Clone ()
70                 {
71                         //Clone'd instance shares the class_ref and gen_args,
72                         //as its basically used to create modified types (arrays etc)
73                         return new GenericTypeInst (class_ref, gen_args, is_valuetypeinst, sig_mod, 
74                                         (ArrayList) ConversionList.Clone () );
75                 }
76
77                 public void MakeValueClass ()
78                 {
79                         class_ref.MakeValueClass ();
80                 }
81
82                 public GenericTypeInst GetGenericTypeInst (GenericArguments gen_args)
83                 {
84                         throw new Exception (String.Format ("Invalid attempt to create '{0}''{1}'", FullName, gen_args.ToString ()));
85                 }
86
87                 public PEAPI.Type ResolveInstance (CodeGen code_gen, GenericArguments gen_args)
88                 {
89                         throw new Exception (String.Format ("Invalid attempt to create '{0}''{1}'", FullName, gen_args.ToString ()));
90                 }
91                 
92                 public void ResolveNoTypeSpec (CodeGen code_gen)
93                 {
94                         if (is_resolved)
95                                 return;
96
97                         class_ref.Resolve (code_gen);
98                         p_gen_inst = (PEAPI.GenericTypeInst) class_ref.ResolveInstance (code_gen, gen_args);
99
100                         ptype = Modify (code_gen, p_gen_inst);
101
102                         is_resolved = true;
103                 }
104
105                 public void Resolve (CodeGen code_gen)
106                 {
107                         ResolveNoTypeSpec (code_gen);
108                         if (is_added)
109                                 return;
110
111                         code_gen.PEFile.AddGenericClass ((PEAPI.GenericTypeInst) p_gen_inst);
112                         is_added = true;
113                 }
114
115                 public void Resolve (GenericParameters type_gen_params, GenericParameters method_gen_params)
116                 {
117                         gen_args.Resolve (type_gen_params, method_gen_params);
118                 }
119
120                 public IMethodRef GetMethodRef (ITypeRef ret_type, PEAPI.CallConv call_conv,
121                                 string meth_name, ITypeRef[] param, int gen_param_count)
122                 {
123                         string key = FullName + MethodDef.CreateSignature (ret_type, meth_name, param, gen_param_count);
124                         TypeSpecMethodRef mr = method_table [key] as TypeSpecMethodRef;
125                         if (mr == null) {         
126                                 mr = new TypeSpecMethodRef (this, ret_type, call_conv, meth_name, param, gen_param_count);
127                                 method_table [key] = mr;
128                         }
129
130                         return mr;
131                 }
132
133                 public IFieldRef GetFieldRef (ITypeRef ret_type, string field_name)
134                 {
135                         return new TypeSpecFieldRef (this, ret_type, field_name);
136                 }
137         }
138 }
139