// Copyright (c) 2010-2013 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. #nullable enable using System; using System.Collections.Generic; namespace ICSharpCode.Decompiler.TypeSystem { /// /// This interface represents a resolved type in the type system. /// /// /// /// A type is potentially /// - a type definition (, i.e. a class, struct, interface, delegate, or built-in primitive type) /// - a parameterized type (, e.g. List<int>) /// - a type parameter (, e.g. T) /// - an array () /// - a pointer () /// - a managed reference () /// - one of the special types (, , /// , ) /// /// The property can be used to switch on the kind of a type. /// /// /// IType uses the null object pattern: serves as the null object. /// Methods or properties returning IType never return null unless documented otherwise. /// /// /// Types should be compared for equality using the method. /// Identical types do not necessarily use the same object reference. /// /// public interface IType : INamedElement, IEquatable { /// /// Gets the type kind. /// TypeKind Kind { get; } /// /// Gets whether the type is a reference type or value type. /// /// /// 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) /// bool? IsReferenceType { get; } /// /// Gets whether this type is "ref-like": a ByReferenceType or "ref struct". /// bool IsByRefLike { get; } /// /// Gets the nullability annotation on this type. /// Nullability Nullability { get; } /// /// Creates a new type that is a copy of this type, with the changed nullability annotation. /// IType ChangeNullability(Nullability newNullability); /// /// Gets the underlying type definition. /// Can return null for types which do not have a type definition (for example arrays, pointers, type parameters). /// ITypeDefinition? GetDefinition(); /// /// Gets the underlying type definition or UnkownType, if unknown. /// Can return null for types which do not have a type definition (for example arrays, pointers, type parameters). /// ITypeDefinitionOrUnknown? GetDefinitionOrUnknown(); /// /// Gets the parent type, if this is a nested type. /// Returns null for top-level types. /// IType? DeclaringType { get; } /// /// Gets the number of type parameters. /// int TypeParameterCount { get; } /// /// Gets the type parameters. /// Returns an empty list if this type is not generic. /// IReadOnlyList TypeParameters { get; } /// /// Gets the type arguments passed to this type. /// If this type is a generic type definition that is not parameterized, this property returns the type parameters, /// as if the type was parameterized with its own type arguments (class C<T> { C<T> field; }). /// IReadOnlyList TypeArguments { get; } /// /// Calls ITypeVisitor.Visit for this type. /// /// The return value of the ITypeVisitor.Visit call IType AcceptVisitor(TypeVisitor visitor); /// /// 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. /// /// 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 this. /// IType VisitChildren(TypeVisitor visitor); /// /// Gets the direct base types. /// /// Returns the direct base types including interfaces IEnumerable DirectBaseTypes { get; } /// /// Gets a type visitor that performs the substitution of class type parameters with the type arguments /// of this parameterized type. /// Returns TypeParameterSubstitution.Identity if the type is not parametrized. /// TypeParameterSubstitution GetSubstitution(); /// /// Gets inner classes (including inherited inner classes). /// /// The filter used to select which types to return. /// The filter is tested on the original type definitions (before parameterization). /// Specified additional options for the GetMembers() operation. /// /// /// If the nested type is generic, this method will return a parameterized type, /// where the additional type parameters are set to . /// /// /// 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 and 'leaks' type parameters in member signatures. /// /// /// /// /// 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] } /// /// IEnumerable GetNestedTypes(Predicate? 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 { class Nested {} } // class Derived : Base { } // // Derived.GetNestedTypes() = Base+Nested // Derived.GetNestedTypes() = Base+Nested<`1, > // Here `1 refers to B, and there's no way to return X as it would collide with B. /// /// Gets inner classes (including inherited inner classes) /// that have typeArguments.Count additional type parameters. /// /// The type arguments passed to the inner class /// The filter used to select which types to return. /// The filter is tested on the original type definitions (before parameterization). /// Specified additional options for the GetMembers() operation. /// /// 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 and 'leaks' type parameters in member signatures. /// IEnumerable GetNestedTypes(IReadOnlyList typeArguments, Predicate? filter = null, GetMemberOptions options = GetMemberOptions.None); /// /// Gets all instance constructors for this type. /// /// The filter used to select which constructors to return. /// The filter is tested on the original method definitions (before specialization). /// Specified additional options for the GetMembers() operation. /// /// The result does not include static constructors. /// Constructors in base classes are not returned by default, as GetMemberOptions.IgnoreInheritedMembers is the default value. /// /// For methods on parameterized types, type substitution will be performed on the method signature, /// and the appropriate will be returned. /// /// IEnumerable GetConstructors(Predicate? filter = null, GetMemberOptions options = GetMemberOptions.IgnoreInheritedMembers); /// /// Gets all methods that can be called on this type. /// /// The filter used to select which methods to return. /// The filter is tested on the original method definitions (before specialization). /// Specified additional options for the GetMembers() operation. /// /// /// The result does not include constructors or accessors. /// /// /// For methods on parameterized types, type substitution will be performed on the method signature, /// and the appropriate will be returned. /// /// /// 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. /// /// IEnumerable GetMethods(Predicate? filter = null, GetMemberOptions options = GetMemberOptions.None); /// /// Gets all generic methods that can be called on this type with the specified type arguments. /// /// The type arguments used for the method call. /// The filter used to select which methods to return. /// The filter is tested on the original method definitions (before specialization). /// Specified additional options for the GetMembers() operation. /// /// The result does not include constructors or accessors. /// /// Type substitution will be performed on the method signature, creating a /// with the specified type arguments. /// /// /// 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. /// /// IEnumerable GetMethods(IReadOnlyList typeArguments, Predicate? filter = null, GetMemberOptions options = GetMemberOptions.None); /// /// Gets all properties that can be called on this type. /// /// The filter used to select which properties to return. /// The filter is tested on the original property definitions (before specialization). /// Specified additional options for the GetMembers() operation. /// /// For properties on parameterized types, type substitution will be performed on the property signature, /// and the appropriate will be returned. /// IEnumerable GetProperties(Predicate? filter = null, GetMemberOptions options = GetMemberOptions.None); /// /// Gets all fields that can be accessed on this type. /// /// The filter used to select which constructors to return. /// The filter is tested on the original field definitions (before specialization). /// Specified additional options for the GetMembers() operation. /// /// For fields on parameterized types, type substitution will be performed on the field's return type, /// and the appropriate will be returned. /// IEnumerable GetFields(Predicate? filter = null, GetMemberOptions options = GetMemberOptions.None); /// /// Gets all events that can be accessed on this type. /// /// The filter used to select which events to return. /// The filter is tested on the original event definitions (before specialization). /// Specified additional options for the GetMembers() operation. /// /// For fields on parameterized types, type substitution will be performed on the event's return type, /// and the appropriate will be returned. /// IEnumerable GetEvents(Predicate? filter = null, GetMemberOptions options = GetMemberOptions.None); /// /// Gets all members that can be called on this type. /// /// The filter used to select which members to return. /// The filter is tested on the original member definitions (before specialization). /// Specified additional options for the GetMembers() operation. /// /// /// 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. /// /// /// For generic methods, the remarks about ambiguous signatures from the /// method apply here as well. /// /// IEnumerable GetMembers(Predicate? filter = null, GetMemberOptions options = GetMemberOptions.None); /// /// Gets all accessors belonging to properties or events on this type. /// /// The filter used to select which members to return. /// The filter is tested on the original member definitions (before specialization). /// Specified additional options for the GetMembers() operation. /// /// Accessors are not returned by GetMembers() or GetMethods(). /// IEnumerable GetAccessors(Predicate? filter = null, GetMemberOptions options = GetMemberOptions.None); } [Flags] public enum GetMemberOptions { /// /// No options specified - this is the default. /// Members will be specialized, and inherited members will be included. /// None = 0x00, /// /// Do not specialize the returned members - directly return the definitions. /// ReturnMemberDefinitions = 0x01, /// /// Do not list inherited members - only list members defined directly on this type. /// IgnoreInheritedMembers = 0x02 } }