1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
|
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
namespace ICSharpCode.NRefactory.TypeSystem
{
/// <summary>
/// This interface represents a resolved type in the type system.
/// </summary>
/// <remarks>
/// <para>
/// A type is potentially
/// - a type definition (<see cref="ITypeDefinition"/>, i.e. a class, struct, interface, delegate, or built-in primitive type)
/// - a parameterized type (<see cref="ParameterizedType"/>, e.g. List<int>)
/// - a type parameter (<see cref="ITypeParameter"/>, e.g. T)
/// - an array (<see cref="ArrayType"/>)
/// - a pointer (<see cref="PointerType"/>)
/// - a managed reference (<see cref="ByReferenceType"/>)
/// - one of the special types (<see cref="SpecialType.UnknownType"/>, <see cref="SpecialType.NullType"/>,
/// <see cref="SpecialType.Dynamic"/>, <see cref="SpecialType.UnboundTypeArgument"/>)
///
/// The <see cref="IType.Kind"/> property can be used to switch on the kind of a type.
/// </para>
/// <para>
/// IType uses the null object pattern: <see cref="SpecialType.UnknownType"/> serves as the null object.
/// Methods or properties returning IType never return null unless documented otherwise.
/// </para>
/// <para>
/// Types should be compared for equality using the <see cref="IEquatable{IType}.Equals(IType)"/> method.
/// Identical types do not necessarily use the same object reference.
/// </para>
/// </remarks>
public interface IType : INamedElement, IEquatable<IType>
{
/// <summary>
/// Gets the type kind.
/// </summary>
TypeKind Kind { get; }
/// <summary>
/// Gets whether the type is a reference type or value type.
/// </summary>
/// <returns>
/// true, if the type is a reference type.
/// false, if the type is a value type.
/// null, if the type is not known (e.g. unconstrained generic type parameter or type not found)
/// </returns>
bool? IsReferenceType { get; }
/// <summary>
/// Gets the underlying type definition.
/// Can return null for types which do not have a type definition (for example arrays, pointers, type parameters).
/// </summary>
ITypeDefinition GetDefinition();
/// <summary>
/// Gets the parent type, if this is a nested type.
/// Returns null for top-level types.
/// </summary>
IType DeclaringType { get; }
/// <summary>
/// Gets the number of type parameters.
/// </summary>
int TypeParameterCount { get; }
/// <summary>
/// Calls ITypeVisitor.Visit for this type.
/// </summary>
/// <returns>The return value of the ITypeVisitor.Visit call</returns>
IType AcceptVisitor(TypeVisitor visitor);
/// <summary>
/// Calls ITypeVisitor.Visit for all children of this type, and reconstructs this type with the children based
/// on the return values of the visit calls.
/// </summary>
/// <returns>A copy of this type, with all children replaced by the return value of the corresponding visitor call.
/// If the visitor returned the original types for all children (or if there are no children), returns <c>this</c>.
/// </returns>
IType VisitChildren(TypeVisitor visitor);
/// <summary>
/// Gets the direct base types.
/// </summary>
/// <returns>Returns the direct base types including interfaces</returns>
IEnumerable<IType> DirectBaseTypes { get; }
/// <summary>
/// Creates a type reference that can be used to look up a type equivalent to this type in another compilation.
/// </summary>
/// <remarks>
/// If this type contains open generics, the resulting type reference will need to be looked up in an appropriate generic context.
/// Otherwise, the main resolve context of a compilation is sufficient.
/// </remarks>
ITypeReference ToTypeReference();
/// <summary>
/// Gets inner classes (including inherited inner classes).
/// </summary>
/// <param name="filter">The filter used to select which types to return.
/// The filter is tested on the original type definitions (before parameterization).</param>
/// <param name="options">Specified additional options for the GetMembers() operation.</param>
/// <remarks>
/// <para>
/// If the nested type is generic, this method will return a parameterized type,
/// where the additional type parameters are set to <see cref="SpecialType.UnboundTypeArgument"/>.
/// </para>
/// <para>
/// Type parameters belonging to the outer class will have the value copied from the outer type
/// if it is a parameterized type. Otherwise, those existing type parameters will be self-parameterized,
/// and thus 'leaked' to the caller in the same way the GetMembers() method does not specialize members
/// from an <see cref="ITypeDefinition"/> and 'leaks' type parameters in member signatures.
/// </para>
/// </remarks>
/// <example>
/// <code>
/// class Base<T> {
/// class Nested<X> {}
/// }
/// class Derived<A, B> : Base<B> {}
///
/// Derived[string,int].GetNestedTypes() = { Base`1+Nested`1[int, unbound] }
/// Derived.GetNestedTypes() = { Base`1+Nested`1[`1, unbound] }
/// Base[`1].GetNestedTypes() = { Base`1+Nested`1[`1, unbound] }
/// Base.GetNestedTypes() = { Base`1+Nested`1[`0, unbound] }
/// </code>
/// </example>
IEnumerable<IType> GetNestedTypes(Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None);
// Note that we cannot 'leak' the additional type parameter as we leak the normal type parameters, because
// the index might collide. For example,
// class Base<T> { class Nested<X> {} }
// class Derived<A, B> : Base<B> { }
//
// Derived<string, int>.GetNestedTypes() = Base+Nested<int, UnboundTypeArgument>
// Derived.GetNestedTypes() = Base+Nested<`1, >
// Here `1 refers to B, and there's no way to return X as it would collide with B.
/// <summary>
/// Gets inner classes (including inherited inner classes)
/// that have <c>typeArguments.Count</c> additional type parameters.
/// </summary>
/// <param name="typeArguments">The type arguments passed to the inner class</param>
/// <param name="filter">The filter used to select which types to return.
/// The filter is tested on the original type definitions (before parameterization).</param>
/// <param name="options">Specified additional options for the GetMembers() operation.</param>
/// <remarks>
/// Type parameters belonging to the outer class will have the value copied from the outer type
/// if it is a parameterized type. Otherwise, those existing type parameters will be self-parameterized,
/// and thus 'leaked' to the caller in the same way the GetMembers() method does not specialize members
/// from an <see cref="ITypeDefinition"/> and 'leaks' type parameters in member signatures.
/// </remarks>
IEnumerable<IType> GetNestedTypes(IList<IType> typeArguments, Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None);
/// <summary>
/// Gets all instance constructors for this type.
/// </summary>
/// <param name="filter">The filter used to select which constructors to return.
/// The filter is tested on the original method definitions (before specialization).</param>
/// <param name="options">Specified additional options for the GetMembers() operation.</param>
/// <remarks>
/// <para>The result does not include static constructors.
/// Constructors in base classes are not returned by default, as GetMemberOptions.IgnoreInheritedMembers is the default value.</para>
/// <para>
/// For methods on parameterized types, type substitution will be performed on the method signature,
/// and the appropriate <see cref="Implementation.SpecializedMethod"/> will be returned.
/// </para>
/// </remarks>
IEnumerable<IMethod> GetConstructors(Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.IgnoreInheritedMembers);
/// <summary>
/// Gets all methods that can be called on this type.
/// </summary>
/// <param name="filter">The filter used to select which methods to return.
/// The filter is tested on the original method definitions (before specialization).</param>
/// <param name="options">Specified additional options for the GetMembers() operation.</param>
/// <remarks>
/// <para>
/// The result does not include constructors.
/// </para>
/// <para>
/// For methods on parameterized types, type substitution will be performed on the method signature,
/// and the appropriate <see cref="Implementation.SpecializedMethod"/> will be returned.
/// </para>
/// <para>
/// If the method being returned is generic, and this type is a parameterized type where the type
/// arguments involve another method's type parameters, the resulting specialized signature
/// will be ambiguous as to which method a type parameter belongs to.
/// For example, "List[[``0]].GetMethods()" will return "ConvertAll(Converter`2[[``0, ``0]])".
///
/// If possible, use the other GetMethods() overload to supply type arguments to the method,
/// so that both class and method type parameter can be substituted at the same time, so that
/// the ambiguity can be avoided.
/// </para>
/// </remarks>
IEnumerable<IMethod> GetMethods(Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None);
/// <summary>
/// Gets all generic methods that can be called on this type with the specified type arguments.
/// </summary>
/// <param name="typeArguments">The type arguments used for the method call.</param>
/// <param name="filter">The filter used to select which methods to return.
/// The filter is tested on the original method definitions (before specialization).</param>
/// <param name="options">Specified additional options for the GetMembers() operation.</param>
/// <remarks>
/// <para>The result does not include constructors.</para>
/// <para>
/// Type substitution will be performed on the method signature, creating a <see cref="Implementation.SpecializedMethod"/>
/// with the specified type arguments.
/// </para>
/// <para>
/// When the list of type arguments is empty, this method acts like the GetMethods() overload without
/// the type arguments parameter - that is, it also returns generic methods,
/// and the other overload's remarks about ambiguous signatures apply here as well.
/// </para>
/// </remarks>
IEnumerable<IMethod> GetMethods(IList<IType> typeArguments, Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None);
/// <summary>
/// Gets all properties that can be called on this type.
/// </summary>
/// <param name="filter">The filter used to select which properties to return.
/// The filter is tested on the original property definitions (before specialization).</param>
/// <param name="options">Specified additional options for the GetMembers() operation.</param>
/// <remarks>
/// For properties on parameterized types, type substitution will be performed on the property signature,
/// and the appropriate <see cref="Implementation.SpecializedProperty"/> will be returned.
/// </remarks>
IEnumerable<IProperty> GetProperties(Predicate<IUnresolvedProperty> filter = null, GetMemberOptions options = GetMemberOptions.None);
/// <summary>
/// Gets all fields that can be accessed on this type.
/// </summary>
/// <param name="filter">The filter used to select which constructors to return.
/// The filter is tested on the original field definitions (before specialization).</param>
/// <param name="options">Specified additional options for the GetMembers() operation.</param>
/// <remarks>
/// For fields on parameterized types, type substitution will be performed on the field's return type,
/// and the appropriate <see cref="Implementation.SpecializedField"/> will be returned.
/// </remarks>
IEnumerable<IField> GetFields(Predicate<IUnresolvedField> filter = null, GetMemberOptions options = GetMemberOptions.None);
/// <summary>
/// Gets all events that can be accessed on this type.
/// </summary>
/// <param name="filter">The filter used to select which events to return.
/// The filter is tested on the original event definitions (before specialization).</param>
/// <param name="options">Specified additional options for the GetMembers() operation.</param>
/// <remarks>
/// For fields on parameterized types, type substitution will be performed on the event's return type,
/// and the appropriate <see cref="Implementation.SpecializedEvent"/> will be returned.
/// </remarks>
IEnumerable<IEvent> GetEvents(Predicate<IUnresolvedEvent> filter = null, GetMemberOptions options = GetMemberOptions.None);
/// <summary>
/// Gets all members that can be called on this type.
/// </summary>
/// <param name="filter">The filter used to select which members to return.
/// The filter is tested on the original member definitions (before specialization).</param>
/// <param name="options">Specified additional options for the GetMembers() operation.</param>
/// <remarks>
/// <para>
/// The resulting list is the union of GetFields(), GetProperties(), GetMethods() and GetEvents().
/// It does not include constructors.
/// For parameterized types, type substitution will be performed.
/// </para>
/// <para>
/// For generic methods, the remarks about ambiguous signatures from the
/// <see cref="GetMethods(Predicate{IUnresolvedMethod}, GetMemberOptions)"/> method apply here as well.
/// </para>
/// </remarks>
IEnumerable<IMember> GetMembers(Predicate<IUnresolvedMember> filter = null, GetMemberOptions options = GetMemberOptions.None);
}
[Flags]
public enum GetMemberOptions
{
/// <summary>
/// No options specified - this is the default.
/// Members will be specialized, and inherited members will be included.
/// </summary>
None = 0x00,
/// <summary>
/// Do not specialize the returned members - directly return the definitions.
/// </summary>
ReturnMemberDefinitions = 0x01,
/// <summary>
/// Do not list inherited members - only list members defined directly on this type.
/// </summary>
IgnoreInheritedMembers = 0x02
}
}
|