|
// 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.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Threading;
namespace Microsoft.CodeAnalysis
{
/// <summary>
/// Represents a symbol (namespace, class, method, parameter, etc.)
/// exposed by the compiler.
/// </summary>
/// <remarks>
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
/// </remarks>
[InternalImplementationOnly]
public interface ISymbol : IEquatable<ISymbol?>
{
/// <summary>
/// Gets the <see cref="SymbolKind"/> indicating what kind of symbol it is.
/// </summary>
SymbolKind Kind { get; }
/// <summary>
/// Gets the source language ("C#" or "Visual Basic").
/// </summary>
string Language { get; }
/// <summary>
/// Gets the symbol name. Returns the empty string if unnamed.
/// </summary>
string Name { get; }
/// <summary>
/// Gets the name of a symbol as it appears in metadata. Most of the time, this
/// is the same as the Name property, with the following exceptions:
/// <list type="number">
/// <item>
/// <description>The metadata name of generic types includes the "`1", "`2" etc. suffix that
/// indicates the number of type parameters (it does not include, however, names of
/// containing types or namespaces). </description>
/// </item>
/// <item>
/// <description>The metadata name of explicit interface names have spaces removed, compared to
/// the name property.</description>
/// </item>
/// <item>
/// <description>The length of names is limited to not exceed metadata restrictions.</description>
/// </item>
/// </list>
/// </summary>
string MetadataName { get; }
/// <summary>
/// Gets the metadata token associated with this symbol, or 0 if the symbol is not loaded from metadata.
/// </summary>
int MetadataToken { get; }
#nullable disable // Skipped for now https://github.com/dotnet/roslyn/issues/39166
#pragma warning disable RS0041 // uses oblivious reference types
/// <summary>
/// Gets the <see cref="ISymbol"/> for the immediately containing symbol.
/// </summary>
ISymbol ContainingSymbol { get; }
/// <summary>
/// Gets the <see cref="IAssemblySymbol"/> for the containing assembly. Returns null if the
/// symbol is shared across multiple assemblies.
/// </summary>
IAssemblySymbol ContainingAssembly { get; }
/// <summary>
/// Gets the <see cref="IModuleSymbol"/> for the containing module. Returns null if the
/// symbol is shared across multiple modules.
/// </summary>
IModuleSymbol ContainingModule { get; }
/// <summary>
/// Gets the <see cref="INamedTypeSymbol"/> for the containing type. Returns null if the
/// symbol is not contained within a type.
/// </summary>
INamedTypeSymbol ContainingType { get; }
/// <summary>
/// Gets the <see cref="INamespaceSymbol"/> for the nearest enclosing namespace. Returns null if the
/// symbol isn't contained in a namespace.
/// </summary>
INamespaceSymbol ContainingNamespace { get; }
#nullable enable
#pragma warning restore RS0041 // uses oblivious reference types
/// <summary>
/// Gets a value indicating whether the symbol is the original definition. Returns false
/// if the symbol is derived from another symbol, by type substitution for instance.
/// </summary>
bool IsDefinition { get; }
/// <summary>
/// Gets a value indicating whether the symbol is static.
/// </summary>
bool IsStatic { get; }
/// <summary>
/// Gets a value indicating whether the symbol is virtual.
/// </summary>
bool IsVirtual { get; }
/// <summary>
/// Gets a value indicating whether the symbol is an override of a base class symbol.
/// </summary>
bool IsOverride { get; }
/// <summary>
/// Gets a value indicating whether the symbol is abstract.
/// </summary>
bool IsAbstract { get; }
/// <summary>
/// Gets a value indicating whether the symbol is sealed.
/// </summary>
bool IsSealed { get; }
/// <summary>
/// Gets a value indicating whether the symbol is defined externally.
/// </summary>
bool IsExtern { get; }
/// <summary>
/// Returns true if this symbol was automatically created by the compiler, and does not have
/// an explicit corresponding source code declaration.
/// </summary>
/// <remarks>
/// This is intended for symbols that are ordinary symbols in the language sense, and may be
/// used by code, but that are simply declared implicitly rather than with explicit language
/// syntax.
///
/// <para>
/// Examples include (this list is not exhaustive):
/// <list type="bullet">
/// <item><description>The default constructor for a class or struct that is created if one is not provided.</description></item>
/// <item><description>The BeginInvoke/Invoke/EndInvoke methods for a delegate.</description></item>
/// <item><description>The generated backing field for an auto property or a field-like event.</description></item>
/// <item><description>The "this" parameter for non-static methods.</description></item>
/// <item><description>The "value" parameter for a property setter.</description></item>
/// <item><description>The parameters on indexer accessor methods (not on the indexer itself).</description></item>
/// <item><description>Methods in anonymous types.</description></item>
/// </list>
/// </para>
/// <para>
/// The class and entry point method for top-level statements are not considered as implicitly declared.
/// </para>
/// </remarks>
bool IsImplicitlyDeclared { get; }
/// <summary>
/// Returns true if this symbol can be referenced by its name in code.
/// </summary>
bool CanBeReferencedByName { get; }
/// <summary>
/// Gets the locations where the symbol was originally defined, either in source or
/// metadata. Some symbols (for example, partial classes) may be defined in more than one
/// location.
/// </summary>
ImmutableArray<Location> Locations { get; }
/// <summary>
/// Get the syntax node(s) where this symbol was declared in source. Some symbols (for example,
/// partial classes) may be defined in more than one location. This property should return
/// one or more syntax nodes only if the symbol was declared in source code and also was
/// not implicitly declared (see the IsImplicitlyDeclared property).
///
/// <para>
/// Note that for namespace symbol, the declaring syntax might be declaring a nested namespace.
/// For example, the declaring syntax node for N1 in "namespace N1.N2 {...}" is the entire
/// NamespaceDeclarationSyntax for N1.N2. For the global namespace, the declaring syntax will
/// be the CompilationUnitSyntax.
/// </para>
/// </summary>
/// <returns>
/// The syntax node(s) that declared the symbol. If the symbol was declared in metadata
/// or was implicitly declared, returns an empty read-only array.
/// </returns>
ImmutableArray<SyntaxReference> DeclaringSyntaxReferences { get; }
/// <summary>
/// Gets the attributes for the symbol. Returns an empty <see cref="ImmutableArray{AttributeData}"/>
/// if there are no attributes.
/// </summary>
ImmutableArray<AttributeData> GetAttributes();
/// <summary>
/// Gets a <see cref="Accessibility"/> indicating the declared accessibility for the symbol.
/// Returns NotApplicable if no accessibility is declared.
/// </summary>
Accessibility DeclaredAccessibility { get; }
/// <summary>
/// Gets the <see cref="ISymbol"/> for the original definition of the symbol.
/// If this symbol is derived from another symbol, by type substitution for instance,
/// this gets the original symbol, as it was defined in source or metadata.
/// </summary>
ISymbol OriginalDefinition { get; }
void Accept(SymbolVisitor visitor);
TResult? Accept<TResult>(SymbolVisitor<TResult> visitor);
TResult Accept<TArgument, TResult>(SymbolVisitor<TArgument, TResult> visitor, TArgument argument);
/// <summary>
/// Returns the Documentation Comment ID for the symbol, or null if the symbol doesn't
/// support documentation comments.
/// </summary>
string? GetDocumentationCommentId();
/// <summary>
/// Gets the XML (as text) for the comment associated with the symbol.
/// </summary>
/// <param name="preferredCulture">Preferred culture or null for the default.</param>
/// <param name="expandIncludes">Optionally, expand <include> elements. No impact on non-source documentation comments.</param>
/// <param name="cancellationToken">Token allowing cancellation of request.</param>
/// <returns>The XML that would be written to the documentation file for the symbol.</returns>
string? GetDocumentationCommentXml(CultureInfo? preferredCulture = null, bool expandIncludes = false, CancellationToken cancellationToken = default);
/// <summary>
/// Converts the symbol to a string representation.
/// </summary>
/// <param name="format">Format or null for the default.</param>
/// <returns>A formatted string representation of the symbol.</returns>
string ToDisplayString(SymbolDisplayFormat? format = null);
/// <summary>
/// Convert a symbol to an array of string parts, each of which has a kind. Useful for
/// colorizing the display string.
/// </summary>
/// <param name="format">Formatting rules - null implies
/// SymbolDisplayFormat.ErrorMessageFormat.</param>
/// <returns>A read-only array of string parts.</returns>
ImmutableArray<SymbolDisplayPart> ToDisplayParts(SymbolDisplayFormat? format = null);
/// <summary>
/// Convert 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="position">A position in the source code (context).</param>
/// <param name="format">Formatting rules - null implies
/// SymbolDisplayFormat.MinimallyQualifiedFormat.</param>
/// <returns>A formatted string that can be displayed to the user.</returns>
string ToMinimalDisplayString(
SemanticModel semanticModel,
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="position">A position in the source code (context).</param>
/// <param name="format">Formatting rules - null implies
/// SymbolDisplayFormat.MinimallyQualifiedFormat.</param>
/// <returns>A read-only array of string parts.</returns>
ImmutableArray<SymbolDisplayPart> ToMinimalDisplayParts(
SemanticModel semanticModel,
int position,
SymbolDisplayFormat? format = null);
/// <summary>
/// Indicates that this symbol uses metadata that cannot be supported by the language.
///
/// <para>
/// Examples include:
/// <list type="bullet">
/// <item><description>Pointer types in VB</description></item>
/// <item><description>ByRef return type</description></item>
/// <item><description>Required custom modifiers</description></item>
/// </list>
/// </para>
///
/// <para>
/// This is distinguished from, for example, references to metadata symbols defined in assemblies that weren't referenced.
/// Symbols where this returns true can never be used successfully, and thus should never appear in any IDE feature.
/// </para>
///
/// <para>
/// This is set for metadata symbols, as follows:
/// <list type="bullet">
/// <item><description>Type - if a type is unsupported (for example, a pointer type)</description></item>
/// <item><description>Method - parameter or return type is unsupported</description></item>
/// <item><description>Field - type is unsupported</description></item>
/// <item><description>Event - type is unsupported</description></item>
/// <item><description>Property - type is unsupported</description></item>
/// <item><description>Parameter - type is unsupported</description></item>
/// </list>
/// </para>
/// </summary>
bool HasUnsupportedMetadata { get; }
/// <summary>
/// Determines if this symbol is equal to another, according to the rules of the provided <see cref="SymbolEqualityComparer"/>
/// </summary>
/// <param name="other">The other symbol to compare against</param>
/// <param name="equalityComparer">The <see cref="SymbolEqualityComparer"/> to use when comparing symbols</param>
/// <returns>True if the symbols are equivalent.</returns>
bool Equals([NotNullWhen(returnValue: true)] ISymbol? other, SymbolEqualityComparer equalityComparer);
}
}
|