2 // System.CodeDom CodeTypeReferenceExpression Class implementation
5 // Daniel Stodden (stodden@in.tum.de)
6 // Marek Safar (marek.safar@seznam.cz)
8 // (C) 2001 Ximian, Inc.
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Runtime.InteropServices;
35 namespace System.CodeDom
38 [ClassInterface(ClassInterfaceType.AutoDispatch)]
40 public class CodeTypeReference : CodeObject
42 private string baseType;
43 private CodeTypeReference arrayType;
45 private bool isInterface;
48 CodeTypeReferenceCollection typeArguments;
49 CodeTypeReferenceOptions codeTypeReferenceOption;
57 public CodeTypeReference ()
63 [MonoTODO("We should parse basetype from right to left in 2.0 profile.")]
65 public CodeTypeReference (string baseType)
71 [MonoTODO("We should parse basetype from right to left in 2.0 profile.")]
73 public CodeTypeReference (Type baseType)
76 if (baseType == null) {
77 throw new ArgumentNullException ("baseType");
80 if (baseType.IsGenericParameter) {
81 this.baseType = baseType.Name;
82 this.codeTypeReferenceOption = CodeTypeReferenceOptions.GenericTypeParameter;
84 else if (baseType.IsGenericTypeDefinition)
85 this.baseType = baseType.FullName;
86 else if (baseType.IsGenericType) {
87 this.baseType = baseType.GetGenericTypeDefinition ().FullName;
88 foreach (Type arg in baseType.GetGenericArguments ()) {
89 if (arg.IsGenericParameter)
90 TypeArguments.Add (new CodeTypeReference (new CodeTypeParameter (arg.Name)));
92 TypeArguments.Add (new CodeTypeReference (arg));
97 if (baseType.IsArray) {
98 this.rank = baseType.GetArrayRank ();
99 this.arrayType = new CodeTypeReference (baseType.GetElementType ());
100 this.baseType = arrayType.BaseType;
102 Parse (baseType.FullName);
104 this.isInterface = baseType.IsInterface;
107 public CodeTypeReference( CodeTypeReference arrayType, int rank )
109 this.baseType = null;
111 this.arrayType = arrayType;
115 [MonoTODO("We should parse basetype from right to left in 2.0 profile.")]
117 public CodeTypeReference( string baseType, int rank )
118 : this (new CodeTypeReference (baseType), rank)
123 public CodeTypeReference( CodeTypeParameter typeParameter ) :
124 this (typeParameter.Name)
126 this.codeTypeReferenceOption = CodeTypeReferenceOptions.GenericTypeParameter;
129 public CodeTypeReference( string typeName, CodeTypeReferenceOptions codeTypeReferenceOption ) :
132 this.codeTypeReferenceOption = codeTypeReferenceOption;
135 public CodeTypeReference( Type type, CodeTypeReferenceOptions codeTypeReferenceOption ) :
138 this.codeTypeReferenceOption = codeTypeReferenceOption;
141 public CodeTypeReference( string typeName, params CodeTypeReference[] typeArguments ) :
144 TypeArguments.AddRange (typeArguments);
145 if (this.baseType.IndexOf ('`') < 0)
146 this.baseType += "`" + TypeArguments.Count;
154 public CodeTypeReference ArrayElementType
164 public int ArrayRank {
173 public string BaseType {
175 if (arrayType != null && rank > 0) {
176 return arrayType.BaseType;
179 if (baseType == null)
189 internal bool IsInterface {
190 get { return isInterface; }
193 private void Parse (string baseType)
195 if (baseType == null || baseType.Length == 0) {
196 this.baseType = typeof (void).FullName;
201 int array_start = baseType.IndexOf ('[');
202 if (array_start == -1) {
203 this.baseType = baseType;
207 int array_end = baseType.LastIndexOf (']');
208 if (array_end < array_start) {
209 this.baseType = baseType;
213 string[] args = baseType.Substring (array_start + 1, array_end - array_start - 1).Split (',');
215 if ((array_end - array_start) != args.Length) {
216 this.baseType = baseType.Substring (0, array_start);
218 int scanPos = array_start;
219 StringBuilder tb = new StringBuilder();
220 while (scanPos < baseType.Length) {
221 char currentChar = baseType[scanPos];
223 switch (currentChar) {
225 if (escapeCount > 1 && tb.Length > 0) {
226 tb.Append (currentChar);
232 if (escapeCount > 1 && tb.Length > 0) {
233 tb.Append (currentChar);
236 if (tb.Length != 0 && (escapeCount % 2) == 0) {
237 TypeArguments.Add (tb.ToString ());
242 if (escapeCount > 1) {
243 // skip anything after the type name until we
244 // reach the next separator
245 while (scanPos + 1 < baseType.Length) {
246 if (baseType[scanPos + 1] == ']') {
251 } else if (tb.Length > 0) {
252 CodeTypeReference typeArg = new CodeTypeReference (tb.ToString ());
253 TypeArguments.Add (typeArg);
258 tb.Append (currentChar);
264 arrayType = new CodeTypeReference (baseType.Substring (0, array_start));
268 int array_start = baseType.LastIndexOf ('[');
269 if (array_start == -1) {
270 this.baseType = baseType;
274 int array_end = baseType.LastIndexOf (']');
275 if (array_end < array_start) {
276 this.baseType = baseType;
280 string[] args = baseType.Substring (array_start + 1, array_end - array_start - 1).Split (',');
283 foreach (string arg in args) {
284 if (arg.Length != 0) {
290 arrayType = new CodeTypeReference (baseType.Substring (0, array_start));
293 this.baseType = baseType;
300 public CodeTypeReferenceOptions Options {
302 return codeTypeReferenceOption;
305 codeTypeReferenceOption = value;
310 public CodeTypeReferenceCollection TypeArguments {
312 if (typeArguments == null)
313 typeArguments = new CodeTypeReferenceCollection ();
314 return typeArguments;