| File: Symbols\ITypeSymbol.cs | Web Access |
| Project: src\roslyn\src\Compilers\Core\Portable\Microsoft.CodeAnalysis.csproj (Microsoft.CodeAnalysis) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Collections.Immutable; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Threading; namespace Microsoft.CodeAnalysis { /// <summary> /// Represents a type. /// </summary> /// <remarks> /// This interface is reserved for implementation by its associated APIs. We reserve the right to /// change it in the future. /// </remarks> public interface ITypeSymbol : INamespaceOrTypeSymbol { /// <summary> /// An enumerated value that identifies whether this type is an array, pointer, enum, and so on. /// </summary> TypeKind TypeKind { get; } /// <summary> /// The declared base type of this type, or null. The object type, interface types, /// pointer types, and type parameters do not have a base type. /// </summary> INamedTypeSymbol? BaseType { get; } /// <summary> /// Gets the set of interfaces that this type directly implements. This set does not include /// interfaces that are base interfaces of directly implemented interfaces. This does /// include the interfaces declared as constraints on type parameters. /// </summary> ImmutableArray<INamedTypeSymbol> Interfaces { get; } /// <summary> /// The list of all interfaces of which this type is a declared subtype, excluding this type /// itself. This includes all declared base interfaces, all declared base interfaces of base /// types, and all declared base interfaces of those results (recursively). This also is the effective /// interface set of a type parameter. Each result /// appears exactly once in the list. This list is topologically sorted by the inheritance /// relationship: if interface type A extends interface type B, then A precedes B in the /// list. This is not quite the same as "all interfaces of which this type is a proper /// subtype" because it does not take into account variance: AllInterfaces for /// IEnumerable<string> will not include IEnumerable<object>. /// </summary> ImmutableArray<INamedTypeSymbol> AllInterfaces { get; } /// <summary> /// True if this type is known to be a reference type. It is never the case that /// <see cref="IsReferenceType"/> and <see cref="IsValueType"/> both return true. However, for an unconstrained type /// parameter, <see cref="IsReferenceType"/> and <see cref="IsValueType"/> will both return false. /// </summary> bool IsReferenceType { get; } /// <summary> /// True if this type is known to be a value type. It is never the case that /// <see cref="IsReferenceType"/> and <see cref="IsValueType"/> both return true. However, for an unconstrained type /// parameter, <see cref="IsReferenceType"/> and <see cref="IsValueType"/> will both return false. /// </summary> bool IsValueType { get; } /// <summary> /// Is this a symbol for an anonymous type (including anonymous VB delegate). /// </summary> bool IsAnonymousType { get; } /// <summary> /// Is this a symbol for a tuple . /// </summary> bool IsTupleType { get; } /// <summary> /// True if the type represents a native integer. In C#, the types represented /// by language keywords 'nint' and 'nuint'. /// </summary> bool IsNativeIntegerType { get; } // 4.14 BACKCOMPAT OVERLOAD -- DO NOT TOUCH [EditorBrowsable(EditorBrowsableState.Never)] bool IsExtension { get; } // 4.14 BACKCOMPAT OVERLOAD -- DO NOT TOUCH [EditorBrowsable(EditorBrowsableState.Never)] IParameterSymbol? ExtensionParameter { get; } /// <summary> /// The original definition of this symbol. If this symbol is constructed from another /// symbol by type substitution then <see cref="OriginalDefinition"/> gets the original symbol as it was defined in /// source or metadata. /// </summary> new ITypeSymbol OriginalDefinition { get; } /// <summary> /// An enumerated value that identifies certain 'special' types such as <see cref="System.Object"/>. /// Returns <see cref="Microsoft.CodeAnalysis.SpecialType.None"/> if the type is not special. /// </summary> SpecialType SpecialType { get; } /// <summary> /// Returns the corresponding symbol in this type or a base type that implements /// interfaceMember (either implicitly or explicitly), or null if no such symbol exists /// (which might be either because this type doesn't implement the container of /// interfaceMember, or this type doesn't supply a member that successfully implements /// interfaceMember). /// </summary> /// <param name="interfaceMember"> /// Must be a non-null interface property, method, or event. /// </param> ISymbol? FindImplementationForInterfaceMember(ISymbol interfaceMember); /// <summary> /// True if the type is ref-like, meaning it follows rules similar to CLR by-ref variables. False if the type /// is not ref-like or if the language has no concept of ref-like types. /// </summary> /// <remarks> /// <see cref="Span{T}" /> is a commonly used ref-like type. /// </remarks> bool IsRefLikeType { get; } /// <summary> /// True if the type is unmanaged according to language rules. False if managed or if the language /// has no concept of unmanaged types. /// </summary> bool IsUnmanagedType { get; } /// <summary> /// True if the type is readonly. /// </summary> bool IsReadOnly { get; } /// <summary> /// For source symbols, true if the type is a record. /// For metadata symbols, true if the type is a record and a reference type. /// </summary> /// <remarks> /// Returns false for record structs in metadata since they don't have any distinctive marker. /// </remarks> bool IsRecord { get; } /// <summary> /// True if language treats the type as a Union. /// </summary> bool IsUnion { [Experimental(RoslynExperiments.PreviewLanguageFeatureApi, UrlFormat = "https://github.com/dotnet/roslyn/issues/82567")] get; } /// <summary> /// Indicates that the type is restricted from being inherited from outside its containing module. /// </summary> [Experimental(RoslynExperiments.PreviewLanguageFeatureApi, UrlFormat = "https://github.com/dotnet/roslyn/issues/83717")] bool IsClosed { get; } /// <summary> /// Gets the direct derived types of a closed type. /// </summary> /// <exception cref="InvalidOperationException">If this is not a closed type.</exception> [Experimental(RoslynExperiments.PreviewLanguageFeatureApi, UrlFormat = "https://github.com/dotnet/roslyn/issues/83717")] ClosedDerivedTypeInfo GetClosedDerivedTypeInfo(CancellationToken cancellationToken); /// <summary> /// Converts an <c>ITypeSymbol</c> and a nullable flow state to a string representation. /// </summary> /// <param name="topLevelNullability">The top-level nullability to use for formatting.</param> /// <param name="format">Format or null for the default.</param> /// <returns>A formatted string representation of the symbol with the given nullability.</returns> string ToDisplayString(NullableFlowState topLevelNullability, SymbolDisplayFormat? format = null); /// <summary> /// Converts a symbol to an array of string parts, each of which has a kind. Useful /// for colorizing the display string. /// </summary> /// <param name="topLevelNullability">The top-level nullability to use for formatting.</param> /// <param name="format">Format or null for the default.</param> /// <returns>A read-only array of string parts.</returns> ImmutableArray<SymbolDisplayPart> ToDisplayParts(NullableFlowState topLevelNullability, SymbolDisplayFormat? format = null); /// <summary> /// Converts a symbol to a string that can be displayed to the user. May be tailored to a /// specific location in the source code. /// </summary> /// <param name="semanticModel">Binding information (for determining names appropriate to /// the context).</param> /// <param name="topLevelNullability">The top-level nullability to use for formatting.</param> /// <param name="position">A position in the source code (context).</param> /// <param name="format">Formatting rules - null implies <see cref="SymbolDisplayFormat.MinimallyQualifiedFormat"/></param> /// <returns>A formatted string that can be displayed to the user.</returns> string ToMinimalDisplayString( SemanticModel semanticModel, NullableFlowState topLevelNullability, int position, SymbolDisplayFormat? format = null); /// <summary> /// Convert a symbol to an array of string parts, each of which has a kind. May be tailored /// to a specific location in the source code. Useful for colorizing the display string. /// </summary> /// <param name="semanticModel">Binding information (for determining names appropriate to /// the context).</param> /// <param name="topLevelNullability">The top-level nullability to use for formatting.</param> /// <param name="position">A position in the source code (context).</param> /// <param name="format">Formatting rules - null implies <see cref="SymbolDisplayFormat.MinimallyQualifiedFormat"/></param> /// <returns>A read-only array of string parts.</returns> ImmutableArray<SymbolDisplayPart> ToMinimalDisplayParts( SemanticModel semanticModel, NullableFlowState topLevelNullability, int position, SymbolDisplayFormat? format = null); /// <summary> /// Nullable annotation associated with the type, or <see cref="NullableAnnotation.None"/> if there are none. /// </summary> NullableAnnotation NullableAnnotation { get; } /// <summary> /// Returns the same type as this type but with the given nullable annotation. /// </summary> /// <param name="nullableAnnotation">The nullable annotation to use</param> ITypeSymbol WithNullableAnnotation(NullableAnnotation nullableAnnotation); } // Intentionally not extension methods. We don't want them ever be called for symbol classes // Once Default Interface Implementations are supported, we can move these methods into the interface. internal static class ITypeSymbolHelpers { internal static bool IsNullableType([NotNullWhen(returnValue: true)] ITypeSymbol? typeOpt) { return typeOpt?.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T; } internal static bool IsNullableOfBoolean([NotNullWhen(returnValue: true)] ITypeSymbol? type) { return IsNullableType(type) && IsBooleanType(GetNullableUnderlyingType(type)); } internal static ITypeSymbol GetNullableUnderlyingType(ITypeSymbol type) { Debug.Assert(IsNullableType(type)); return ((INamedTypeSymbol)type).TypeArguments[0]; } internal static bool IsBooleanType([NotNullWhen(returnValue: true)] ITypeSymbol? type) { return type?.SpecialType == SpecialType.System_Boolean; } internal static bool IsObjectType([NotNullWhen(returnValue: true)] ITypeSymbol? type) { return type?.SpecialType == SpecialType.System_Object; } internal static bool IsSignedIntegralType([NotNullWhen(returnValue: true)] ITypeSymbol? type) { return type?.SpecialType.IsSignedIntegralType() == true; } internal static bool IsUnsignedIntegralType([NotNullWhen(returnValue: true)] ITypeSymbol? type) { return type?.SpecialType.IsUnsignedIntegralType() == true; } internal static bool IsNumericType([NotNullWhen(returnValue: true)] ITypeSymbol? type) { return type?.SpecialType.IsNumericType() == true; } internal static ITypeSymbol? GetEnumUnderlyingType(ITypeSymbol? type) { return (type as INamedTypeSymbol)?.EnumUnderlyingType; } [return: NotNullIfNotNull(parameterName: nameof(type))] internal static ITypeSymbol? GetEnumUnderlyingTypeOrSelf(ITypeSymbol? type) { return GetEnumUnderlyingType(type) ?? type; } internal static bool IsDynamicType([NotNullWhen(returnValue: true)] ITypeSymbol? type) { return type?.Kind == SymbolKind.DynamicType; } } }