BOO-973: Compile error when attaching to an event on a locally defined generic or...
[boo.git] / src / Boo.Lang.Compiler / TypeSystem / GenericConstructedType.cs
blob5d74801727b588318edb7bf0498ed3a93ef6775f
1 #region license
2 // Copyright (c) 2003, 2004, 2005 Rodrigo B. de Oliveira (rbo@acm.org)
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
7 //
8 // * Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright notice,
11 // this list of conditions and the following disclaimer in the documentation
12 // and/or other materials provided with the distribution.
13 // * Neither the name of Rodrigo B. de Oliveira nor the names of its
14 // contributors may be used to endorse or promote products derived from this
15 // software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #endregion
29 namespace Boo.Lang.Compiler.TypeSystem
31 using System;
32 using System.Collections.Generic;
33 using Boo.Lang.Compiler.TypeSystem;
34 using Boo.Lang.Compiler.Ast;
35 using System.Text;
37 /// <summary>
38 /// A type constructed by supplying type parameters to a generic type, involving internal types.
39 /// </summary>
40 /// <remarks>
41 /// Constructed types constructed from an external generic type with external type arguments
42 /// are themselves external, and are represented as ExternalType instances. All other cases
43 /// are represented by this type.
44 /// </remarks>
45 public class GenericConstructedType : IType, IConstructedTypeInfo
47 protected TypeSystemServices _tss;
48 protected IType _definition;
49 IType[] _arguments;
50 GenericMapping _genericMapping;
51 bool _fullyConstructed;
53 string _fullName = null;
55 public GenericConstructedType(TypeSystemServices tss, IType definition, IType[] arguments)
57 _tss = tss;
58 _definition = definition;
59 _arguments = arguments;
60 _genericMapping = new GenericMapping(tss, this, arguments);
61 _fullyConstructed = IsFullyConstructed();
64 protected bool IsFullyConstructed()
66 return GenericsServices.GetTypeGenerity(this) == 0;
69 protected string BuildFullName()
71 string[] argumentNames = Array.ConvertAll<IType, string>(
72 GenericArguments,
73 delegate(IType t) { return t.FullName; });
75 return string.Format("{0}[{1}]", _definition.FullName, string.Join(", ", argumentNames));
78 public GenericMapping GenericMapping
80 get { return _genericMapping; }
83 public bool IsClass
85 get { return _definition.IsClass; }
88 public bool IsAbstract
90 get { return _definition.IsAbstract; }
93 public bool IsInterface
95 get { return _definition.IsInterface; }
98 public bool IsEnum
100 get { return _definition.IsEnum; }
103 public bool IsByRef
105 get { return _definition.IsByRef; }
108 public bool IsValueType
110 get { return _definition.IsValueType; }
113 public bool IsFinal
115 get { return _definition.IsFinal; }
118 public bool IsArray
120 get { return _definition.IsArray; }
123 public int GetTypeDepth()
125 return _definition.GetTypeDepth();
128 public IType GetElementType()
130 return GenericMapping.Map(_definition.GetElementType());
133 public IType BaseType
135 get { return GenericMapping.Map(_definition.BaseType); }
138 public IEntity GetDefaultMember()
140 return GenericMapping.Map(_definition.GetDefaultMember());
143 public IConstructor[] GetConstructors()
145 return Array.ConvertAll<IConstructor, IConstructor>(
146 _definition.GetConstructors(),
147 delegate(IConstructor c) { return GenericMapping.Map(c); });
150 public IType[] GetInterfaces()
152 return Array.ConvertAll<IType, IType>(
153 _definition.GetInterfaces(),
154 GenericMapping.Map);
157 public bool IsSubclassOf(IType other)
159 if (BaseType != null && (BaseType == other || BaseType.IsSubclassOf(other)))
161 return true;
164 if (other.IsInterface && Array.Exists(
165 GetInterfaces(),
166 delegate(IType i) { return other.IsAssignableFrom(i); }))
168 return true;
171 return false;
174 public virtual bool IsAssignableFrom(IType other)
176 if (other == null)
178 return false;
181 if (other == this || other.IsSubclassOf(this) || (other == Null.Default && !IsValueType))
183 return true;
186 return false;
189 public IGenericTypeInfo GenericInfo
191 get { return null; }
194 public IConstructedTypeInfo ConstructedInfo
196 get { return this; }
199 public IType Type
201 get { return this; }
204 public INamespace ParentNamespace
206 get
208 return GenericMapping.Map(_definition.ParentNamespace as IEntity) as INamespace;
212 public bool Resolve(List targetList, string name, EntityType filter)
214 // Resolve name using definition, and then map the matching members
215 List definitionMatches = new List();
216 if (_definition.Resolve(definitionMatches, name, filter))
218 foreach (IEntity match in definitionMatches)
220 if(GenericMapping.EntityNeedsMapping(match))
222 targetList.AddUnique(GenericMapping.Map(match));
224 else
226 targetList.AddUnique(match);
229 return true;
231 return false;
234 public IEntity[] GetMembers()
236 return Array.ConvertAll<IEntity, IEntity>(_definition.GetMembers(), GenericMapping.Map);
239 public string Name
241 get { return _definition.Name; }
244 public string FullName
246 get { return _fullName ?? (_fullName = BuildFullName()); }
249 public EntityType EntityType
251 get { return EntityType.Type; }
254 public IType[] GenericArguments
256 get { return _arguments; }
259 public IType GenericDefinition
261 get { return _definition; }
264 public bool FullyConstructed
266 get { return _fullyConstructed; }
269 public IMethod GetMethodTemplate(IMethod method)
271 return _genericMapping.UnMap(method);
274 public override string ToString()
276 return FullName;
280 public class GenericConstructedCallableType : GenericConstructedType, ICallableType
282 CallableSignature _signature;
284 public GenericConstructedCallableType(TypeSystemServices tss, ICallableType definition, IType[] arguments)
285 : base(tss, definition, arguments)
289 public CallableSignature GetSignature()
291 if (_signature == null)
293 CallableSignature definitionSignature = ((ICallableType)_definition).GetSignature();
295 IParameter[] parameters = GenericMapping.Map(definitionSignature.Parameters);
296 IType returnType = GenericMapping.Map(definitionSignature.ReturnType);
298 _signature = new CallableSignature(parameters, returnType);
301 return _signature;
304 override public bool IsAssignableFrom(IType other)
306 return _tss.IsCallableTypeAssignableFrom(this, other);