2 // Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
3 // All rights reserved.
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
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.
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.
29 namespace Boo
.Lang
.Compiler
.TypeSystem
32 using System
.Collections
;
33 using System
.Reflection
;
34 using Boo
.Lang
.Compiler
.Ast
;
35 using Attribute
= Boo
.Lang
.Compiler
.Ast
.Attribute
;
36 using System
.Collections
.Generic
;
38 public abstract class AbstractInternalType
: IInternalEntity
, IType
, INamespace
, IGenericTypeInfo
40 public static readonly IConstructor
[] NoConstructors
= new IConstructor
[0];
42 protected TypeSystemServices _typeSystemServices
;
44 protected TypeDefinition _typeDefinition
;
46 protected INamespace _parentNamespace
;
48 private string _fullName
= null;
50 private IGenericParameter
[] _genericParameters
= null;
52 private Dictionary
<IType
[], IType
> _constructedTypes
= new Dictionary
<IType
[], IType
>(ArrayEqualityComparer
<IType
>.Default
);
54 protected AbstractInternalType(TypeSystemServices typeSystemServices
, TypeDefinition typeDefinition
)
56 _typeSystemServices
= typeSystemServices
;
57 _typeDefinition
= typeDefinition
;
60 protected virtual string BuildFullName()
62 string fullName
= _typeDefinition
.FullName
;
64 if (GenericInfo
!= null)
66 fullName
= string.Format("{0}`{1}", fullName
, GenericInfo
.GenericParameters
.Length
);
72 public string FullName
74 get { return _fullName ?? (_fullName = BuildFullName()); }
81 return _typeDefinition
.Name
;
89 return _typeDefinition
;
93 public IType NestingType
97 return _typeDefinition
.ParentNode
.Entity
as IType
;
101 public virtual INamespace ParentNamespace
105 if (null == _parentNamespace
)
107 _parentNamespace
= (INamespace
)TypeSystemServices
.GetEntity(_typeDefinition
.ParentNode
);
109 return _parentNamespace
;
113 public virtual bool Resolve(List targetList
, string name
, EntityType flags
)
117 // Try to resolve name as a generic parameter
118 if (NameResolutionService
.IsFlagSet(flags
, EntityType
.Type
))
120 foreach (GenericParameterDeclaration gpd
in _typeDefinition
.GenericParameters
)
122 if (gpd
.Name
== name
)
124 targetList
.AddUnique(gpd
.Entity
);
130 // Try to resolve name as a member
131 foreach (IEntity entity
in GetMembers())
133 if (entity
.Name
== name
&& NameResolutionService
.IsFlagSet(flags
, entity
.EntityType
))
135 targetList
.AddUnique(entity
);
143 public virtual IType BaseType
151 public TypeDefinition TypeDefinition
155 return _typeDefinition
;
175 public IType
GetElementType()
184 return NodeType
.ClassDefinition
== _typeDefinition
.NodeType
;
188 public bool IsAbstract
192 return _typeDefinition
.IsAbstract
;
196 virtual public bool IsFinal
200 return _typeDefinition
.IsFinal
|| IsValueType
;
204 public bool IsInterface
208 return NodeType
.InterfaceDefinition
== _typeDefinition
.NodeType
;
216 return NodeType
.EnumDefinition
== _typeDefinition
.NodeType
;
220 virtual public bool IsValueType
236 public virtual int GetTypeDepth()
241 public IEntity
GetDefaultMember()
243 IType defaultMemberAttribute
= _typeSystemServices
.Map(Types
.DefaultMemberAttribute
);
244 foreach (Attribute attribute
in _typeDefinition
.Attributes
)
246 IConstructor tag
= TypeSystemServices
.GetEntity(attribute
) as IConstructor
;
249 if (defaultMemberAttribute
== tag
.DeclaringType
)
251 StringLiteralExpression memberName
= attribute
.Arguments
[0] as StringLiteralExpression
;
252 if (null != memberName
)
254 List buffer
= new List();
255 Resolve(buffer
, memberName
.Value
, EntityType
.Any
);
256 return NameResolutionService
.GetEntityFromList(buffer
);
261 if (_typeDefinition
.BaseTypes
.Count
> 0)
263 List buffer
= new List();
265 foreach (TypeReference baseType
in _typeDefinition
.BaseTypes
)
267 IType tag
= TypeSystemServices
.GetType(baseType
);
268 IEntity defaultMember
= tag
.GetDefaultMember();
269 if (defaultMember
!= null)
273 buffer
.AddUnique(defaultMember
);
275 else //non-interface base class trumps interfaces
277 return defaultMember
;
281 return NameResolutionService
.GetEntityFromList(buffer
);
286 public virtual EntityType EntityType
290 return EntityType
.Type
;
294 public virtual bool IsSubclassOf(IType other
)
299 public virtual bool IsAssignableFrom(IType other
)
301 return this == other
||
302 (!this.IsValueType
&& Null
.Default
== other
) ||
303 other
.IsSubclassOf(this);
306 public virtual IConstructor
[] GetConstructors()
308 return NoConstructors
;
311 public IType
[] GetInterfaces()
313 List buffer
= new List(_typeDefinition
.BaseTypes
.Count
);
314 foreach (TypeReference baseType
in _typeDefinition
.BaseTypes
)
316 IType type
= TypeSystemServices
.GetType(baseType
);
317 if (type
.IsInterface
) buffer
.AddUnique(type
);
319 return (IType
[])buffer
.ToArray(new IType
[buffer
.Count
]);
322 public virtual IEntity
[] GetMembers()
324 return GetMemberEntities(_typeDefinition
.Members
);
327 private IEntity
[] GetMemberEntities(TypeMemberCollection members
)
329 IEntity
[] entities
= new IEntity
[members
.Count
];
330 for (int i
= 0; i
< entities
.Length
; ++i
)
332 entities
[i
] = _typeSystemServices
.GetMemberEntity(members
[i
]);
338 override public string ToString()
343 public IGenericTypeInfo GenericInfo
347 if (TypeDefinition
.GenericParameters
.Count
!= 0)
355 public IConstructedTypeInfo ConstructedInfo
360 IGenericParameter
[] IGenericTypeInfo
.GenericParameters
364 if (_genericParameters
== null)
366 _genericParameters
= Array
.ConvertAll
<GenericParameterDeclaration
, IGenericParameter
>(
367 _typeDefinition
.GenericParameters
.ToArray(),
368 delegate(GenericParameterDeclaration gpd
) { return (IGenericParameter)gpd.Entity; }
);
371 return _genericParameters
;
375 IType IGenericTypeInfo
.ConstructType(IType
[] arguments
)
377 IType constructed
= null;
378 if (!_constructedTypes
.TryGetValue(arguments
, out constructed
))
380 constructed
= CreateConstructedType(arguments
);
381 _constructedTypes
.Add(arguments
, constructed
);
387 protected virtual IType
CreateConstructedType(IType
[] arguments
)
389 return new GenericConstructedType(_typeSystemServices
, this, arguments
);