BOO-988: Added else block to the for and while statements, and include a suite of...
[boo.git] / src / Boo.Lang.Compiler / TypeSystem / ExternalMethod.cs
blob8adf11dd17ee0926f75149dfe4b49930a1c9f398
1 #region license
2 // Copyright (c) 2004, 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.Reflection;
34 public class ExternalMethod : ExternalEntity<MethodBase>, IMethod
36 IParameter[] _parameters;
38 ICallableType _type;
40 // TODO: replace by bool?
41 int _acceptVarArgs = -1;
43 int _isExtension = -1;
45 int _isPInvoke = -1;
47 private int _isMeta = -1;
49 internal ExternalMethod(TypeSystemServices manager, MethodBase mi) : base(manager, mi)
53 public bool IsMeta
55 get
57 if (-1 == _isMeta)
59 _isMeta = IsStatic && MetadataUtil.IsAttributeDefined(_memberInfo, typeof(Boo.Lang.MetaAttribute))
60 ? 1
61 : 0;
63 return _isMeta == 1;
67 public bool IsExtension
69 get
71 if (-1 == _isExtension)
73 bool defined = MetadataUtil.IsAttributeDefined(_memberInfo, Types.BooExtensionAttribute);
74 if( defined == false && MetadataUtil.HasClrExtensions())
76 defined = MetadataUtil.IsAttributeDefined(_memberInfo, Types.ClrExtensionAttribute);
78 _isExtension = IsStatic && defined
79 ? 1
80 : 0;
82 return 1 == _isExtension;
86 public bool IsPInvoke
88 get
90 if (-1 == _isPInvoke)
92 _isPInvoke = IsStatic && MetadataUtil.IsAttributeDefined(_memberInfo, Types.DllImportAttribute)
93 ? 1
94 : 0;
96 return 1 == _isPInvoke;
100 public virtual IType DeclaringType
104 return _typeSystemServices.Map(_memberInfo.DeclaringType);
108 public bool IsStatic
112 return _memberInfo.IsStatic;
116 public bool IsPublic
120 return _memberInfo.IsPublic;
124 public bool IsProtected
128 return _memberInfo.IsFamily || _memberInfo.IsFamilyOrAssembly;
132 public bool IsPrivate
136 return _memberInfo.IsPrivate;
140 public bool IsAbstract
144 return _memberInfo.IsAbstract;
148 public bool IsInternal
152 return _memberInfo.IsAssembly;
156 public bool IsVirtual
160 return _memberInfo.IsVirtual;
164 public bool IsSpecialName
168 return _memberInfo.IsSpecialName;
172 public bool AcceptVarArgs
176 if (_acceptVarArgs == -1)
178 ParameterInfo[] parameters = _memberInfo.GetParameters();
180 _acceptVarArgs =
181 parameters.Length > 0 && IsParamArray(parameters[parameters.Length-1]) ? 1 : 0;
183 return _acceptVarArgs == 1;
187 private bool IsParamArray(ParameterInfo parameter)
189 /* Hack to fix problem with mono-1.1.8.* and older */
190 return parameter.ParameterType.IsArray
191 && (
192 Attribute.IsDefined(parameter, Types.ParamArrayAttribute)
193 || parameter.GetCustomAttributes(Types.ParamArrayAttribute, false).Length > 0);
197 override public EntityType EntityType
201 return EntityType.Method;
205 public ICallableType CallableType
209 if (null != _type) return _type;
211 return _type = _typeSystemServices.GetCallableType(this);
215 public IType Type
219 return CallableType;
223 public virtual IParameter[] GetParameters()
225 if (null != _parameters) return _parameters;
226 return _parameters = _typeSystemServices.Map(_memberInfo.GetParameters());
229 public virtual IType ReturnType
233 MethodInfo mi = _memberInfo as MethodInfo;
234 if (null != mi) return _typeSystemServices.Map(mi.ReturnType);
235 return null;
239 public MethodBase MethodInfo
241 get { return _memberInfo; }
244 override public bool Equals(object other)
246 ExternalMethod rhs = other as ExternalMethod;
247 if (null == rhs) return false;
248 return _memberInfo.MethodHandle.Value == rhs._memberInfo.MethodHandle.Value;
251 override public int GetHashCode()
253 return _memberInfo.MethodHandle.Value.GetHashCode();
256 override public string ToString()
258 return _typeSystemServices.GetSignature(this);
261 ExternalGenericMethodInfo _genericMethodDefinitionInfo = null;
262 public IGenericMethodInfo GenericInfo
266 if (MethodInfo.IsGenericMethodDefinition)
268 if (_genericMethodDefinitionInfo == null)
270 _genericMethodDefinitionInfo =
271 new ExternalGenericMethodInfo(_typeSystemServices, this);
273 return _genericMethodDefinitionInfo;
275 return null;
279 ExternalConstructedMethodInfo _genericMethodInfo = null;
280 public virtual IConstructedMethodInfo ConstructedInfo
284 if (MethodInfo.IsGenericMethod)
286 if (_genericMethodInfo == null)
288 _genericMethodInfo = new ExternalConstructedMethodInfo(_typeSystemServices, this);
290 return _genericMethodInfo;
292 return null;
296 protected override Type MemberType
300 MethodInfo mi = _memberInfo as MethodInfo;
301 if (null != mi) return mi.ReturnType;
302 return null;