// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Threading; using Microsoft.CodeAnalysis.Semantics; using Microsoft.CodeAnalysis.Text; namespace Microsoft.CodeAnalysis { /// /// Allows asking semantic questions about a tree of syntax nodes in a Compilation. Typically, /// an instance is obtained by a call to GetBinding on a Compilation or Compilation. /// /// /// An instance of SemanticModel caches local symbols and semantic information. Thus, it /// is much more efficient to use a single instance of SemanticModel when asking multiple /// questions about a syntax tree, because information from the first question may be reused. /// This also means that holding onto an instance of SemanticModel for a long time may keep a /// significant amount of memory from being garbage collected. /// /// /// When an answer is a named symbol that is reachable by traversing from the root of the symbol /// table, (that is, from an AssemblySymbol of the Compilation), that symbol will be returned /// (i.e. the returned value will be reference-equal to one reachable from the root of the /// symbol table). Symbols representing entities without names (e.g. array-of-int) may or may /// not exhibit reference equality. However, some named symbols (such as local variables) are /// not reachable from the root. These symbols are visible as answers to semantic questions. /// When the same SemanticModel object is used, the answers exhibit reference-equality. /// /// public abstract class SemanticModel { /// /// Gets the source language ("C#" or "Visual Basic"). /// public abstract string Language { get; } /// /// The compilation this model was obtained from. /// public Compilation Compilation { get { return CompilationCore; } } /// /// The compilation this model was obtained from. /// protected abstract Compilation CompilationCore { get; } /// /// The syntax tree this model was obtained from. /// public SyntaxTree SyntaxTree { get { return SyntaxTreeCore; } } /// /// The syntax tree this model was obtained from. /// protected abstract SyntaxTree SyntaxTreeCore { get; } /// /// Gets the operation corresponding to the expression or statement syntax node. /// /// The expression or statement syntax node. /// An optional cancellation token. /// public IOperation GetOperation(SyntaxNode node, CancellationToken cancellationToken = default(CancellationToken)) { return GetOperationCore(node, cancellationToken); } protected abstract IOperation GetOperationCore(SyntaxNode node, CancellationToken cancellationToken); /// /// Returns true if this is a SemanticModel that ignores accessibility rules when answering semantic questions. /// public virtual bool IgnoresAccessibility { get { return false; } } /// /// Gets symbol information about a syntax node. /// /// The syntax node to get semantic information for. /// A cancellation token that can be used to cancel the /// process of obtaining the semantic info. internal SymbolInfo GetSymbolInfo(SyntaxNode node, CancellationToken cancellationToken = default(CancellationToken)) { return GetSymbolInfoCore(node, cancellationToken); } /// /// Gets symbol information about a syntax node. /// /// The syntax node to get semantic information for. /// A cancellation token that can be used to cancel the /// process of obtaining the semantic info. protected abstract SymbolInfo GetSymbolInfoCore(SyntaxNode node, CancellationToken cancellationToken = default(CancellationToken)); /// /// Binds the node in the context of the specified location and get semantic information /// such as type, symbols and diagnostics. This method is used to get semantic information /// about an expression that did not actually appear in the source code. /// /// A character position used to identify a declaration scope and /// accessibility. This character position must be within the FullSpan of the Root syntax /// node in this SemanticModel. /// /// A syntax node that represents a parsed expression. This syntax /// node need not and typically does not appear in the source code referred to SemanticModel /// instance. /// Indicates whether to binding the expression as a full expressions, /// or as a type or namespace. If SpeculativeBindingOption.BindAsTypeOrNamespace is supplied, then /// expression should derive from TypeSyntax. /// The semantic information for the topmost node of the expression. /// The passed in expression is interpreted as a stand-alone expression, as if it /// appeared by itself somewhere within the scope that encloses "position". internal SymbolInfo GetSpeculativeSymbolInfo(int position, SyntaxNode expression, SpeculativeBindingOption bindingOption) { return GetSpeculativeSymbolInfoCore(position, expression, bindingOption); } /// /// Binds the node in the context of the specified location and get semantic information /// such as type, symbols and diagnostics. This method is used to get semantic information /// about an expression that did not actually appear in the source code. /// /// A character position used to identify a declaration scope and /// accessibility. This character position must be within the FullSpan of the Root syntax /// node in this SemanticModel. /// /// A syntax node that represents a parsed expression. This syntax /// node need not and typically does not appear in the source code referred to SemanticModel /// instance. /// Indicates whether to binding the expression as a full expressions, /// or as a type or namespace. If SpeculativeBindingOption.BindAsTypeOrNamespace is supplied, then /// expression should derive from TypeSyntax. /// The semantic information for the topmost node of the expression. /// The passed in expression is interpreted as a stand-alone expression, as if it /// appeared by itself somewhere within the scope that encloses "position". protected abstract SymbolInfo GetSpeculativeSymbolInfoCore(int position, SyntaxNode expression, SpeculativeBindingOption bindingOption); /// /// Binds the node in the context of the specified location and get semantic information /// such as type, symbols and diagnostics. This method is used to get semantic information /// about an expression that did not actually appear in the source code. /// /// A character position used to identify a declaration scope and /// accessibility. This character position must be within the FullSpan of the Root syntax /// node in this SemanticModel. /// /// A syntax node that represents a parsed expression. This syntax /// node need not and typically does not appear in the source code referred to SemanticModel /// instance. /// Indicates whether to binding the expression as a full expressions, /// or as a type or namespace. If SpeculativeBindingOption.BindAsTypeOrNamespace is supplied, then /// expression should derive from TypeSyntax. /// The semantic information for the topmost node of the expression. /// The passed in expression is interpreted as a stand-alone expression, as if it /// appeared by itself somewhere within the scope that encloses "position". internal TypeInfo GetSpeculativeTypeInfo(int position, SyntaxNode expression, SpeculativeBindingOption bindingOption) { return GetSpeculativeTypeInfoCore(position, expression, bindingOption); } /// /// Binds the node in the context of the specified location and get semantic information /// such as type, symbols and diagnostics. This method is used to get semantic information /// about an expression that did not actually appear in the source code. /// /// A character position used to identify a declaration scope and /// accessibility. This character position must be within the FullSpan of the Root syntax /// node in this SemanticModel. /// /// A syntax node that represents a parsed expression. This syntax /// node need not and typically does not appear in the source code referred to SemanticModel /// instance. /// Indicates whether to binding the expression as a full expressions, /// or as a type or namespace. If SpeculativeBindingOption.BindAsTypeOrNamespace is supplied, then /// expression should derive from TypeSyntax. /// The semantic information for the topmost node of the expression. /// The passed in expression is interpreted as a stand-alone expression, as if it /// appeared by itself somewhere within the scope that encloses "position". protected abstract TypeInfo GetSpeculativeTypeInfoCore(int position, SyntaxNode expression, SpeculativeBindingOption bindingOption); /// /// Gets type information about a syntax node. /// /// The syntax node to get semantic information for. /// A cancellation token that can be used to cancel the /// process of obtaining the semantic info. internal TypeInfo GetTypeInfo(SyntaxNode node, CancellationToken cancellationToken = default(CancellationToken)) { return GetTypeInfoCore(node, cancellationToken); } /// /// Gets type information about a syntax node. /// /// The syntax node to get semantic information for. /// A cancellation token that can be used to cancel the /// process of obtaining the semantic info. protected abstract TypeInfo GetTypeInfoCore(SyntaxNode node, CancellationToken cancellationToken = default(CancellationToken)); /// /// If "nameSyntax" resolves to an alias name, return the IAliasSymbol corresponding /// to A. Otherwise return null. /// /// Name to get alias info for. /// A cancellation token that can be used to cancel the /// process of obtaining the alias information. internal IAliasSymbol GetAliasInfo(SyntaxNode nameSyntax, CancellationToken cancellationToken = default(CancellationToken)) { return GetAliasInfoCore(nameSyntax, cancellationToken); } /// /// If "nameSyntax" resolves to an alias name, return the IAliasSymbol corresponding /// to A. Otherwise return null. /// /// Name to get alias info for. /// A cancellation token that can be used to cancel the /// process of obtaining the alias information. protected abstract IAliasSymbol GetAliasInfoCore(SyntaxNode nameSyntax, CancellationToken cancellationToken = default(CancellationToken)); /// /// Returns true if this is a speculative semantic model created with any of the TryGetSpeculativeSemanticModel methods. /// public abstract bool IsSpeculativeSemanticModel { get; } /// /// If this is a speculative semantic model, returns the original position at which the speculative model was created. /// Otherwise, returns 0. /// public abstract int OriginalPositionForSpeculation { get; } /// /// If this is a speculative semantic model, then returns its parent semantic model. /// Otherwise, returns null. /// public SemanticModel ParentModel { get { return this.ParentModelCore; } } /// /// If this is a speculative semantic model, then returns its parent semantic model. /// Otherwise, returns null. /// protected abstract SemanticModel ParentModelCore { get; } /// /// Binds the name in the context of the specified location and sees if it resolves to an /// alias name. If it does, return the AliasSymbol corresponding to it. Otherwise, return null. /// /// A character position used to identify a declaration scope and /// accessibility. This character position must be within the FullSpan of the Root syntax /// node in this SemanticModel. /// /// A syntax node that represents a name. This syntax /// node need not and typically does not appear in the source code referred to by the /// SemanticModel instance. /// Indicates whether to binding the name as a full expression, /// or as a type or namespace. If SpeculativeBindingOption.BindAsTypeOrNamespace is supplied, then /// expression should derive from TypeSyntax. /// The passed in name is interpreted as a stand-alone name, as if it /// appeared by itself somewhere within the scope that encloses "position". internal IAliasSymbol GetSpeculativeAliasInfo(int position, SyntaxNode nameSyntax, SpeculativeBindingOption bindingOption) { return GetSpeculativeAliasInfoCore(position, nameSyntax, bindingOption); } /// /// Binds the name in the context of the specified location and sees if it resolves to an /// alias name. If it does, return the AliasSymbol corresponding to it. Otherwise, return null. /// /// A character position used to identify a declaration scope and /// accessibility. This character position must be within the FullSpan of the Root syntax /// node in this SemanticModel. /// /// A syntax node that represents a name. This syntax /// node need not and typically does not appear in the source code referred to by the /// SemanticModel instance. /// Indicates whether to binding the name as a full expression, /// or as a type or namespace. If SpeculativeBindingOption.BindAsTypeOrNamespace is supplied, then /// expression should derive from TypeSyntax. /// The passed in name is interpreted as a stand-alone name, as if it /// appeared by itself somewhere within the scope that encloses "position". protected abstract IAliasSymbol GetSpeculativeAliasInfoCore(int position, SyntaxNode nameSyntax, SpeculativeBindingOption bindingOption); /// /// Get all of the syntax errors within the syntax tree associated with this /// object. Does not get errors involving declarations or compiling method bodies or initializers. /// /// Optional span within the syntax tree for which to get diagnostics. /// If no argument is specified, then diagnostics for the entire tree are returned. /// A cancellation token that can be used to cancel the /// process of obtaining the diagnostics. public abstract ImmutableArray GetSyntaxDiagnostics(TextSpan? span = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Get all of the declaration errors within the syntax tree associated with this /// object. Does not get errors involving incorrect syntax, compiling method bodies or initializers. /// /// Optional span within the syntax tree for which to get diagnostics. /// If no argument is specified, then diagnostics for the entire tree are returned. /// A cancellation token that can be used to cancel the /// process of obtaining the diagnostics. /// The declaration errors for a syntax tree are cached. The first time this method /// is called, all declarations are analyzed for diagnostics. Calling this a second time /// will return the cached diagnostics. /// public abstract ImmutableArray GetDeclarationDiagnostics(TextSpan? span = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Get all of the method body and initializer errors within the syntax tree associated with this /// object. Does not get errors involving incorrect syntax or declarations. /// /// Optional span within the syntax tree for which to get diagnostics. /// If no argument is specified, then diagnostics for the entire tree are returned. /// A cancellation token that can be used to cancel the /// process of obtaining the diagnostics. /// The method body errors for a syntax tree are not cached. The first time this method /// is called, all method bodies are analyzed for diagnostics. Calling this a second time /// will repeat this work. /// public abstract ImmutableArray GetMethodBodyDiagnostics(TextSpan? span = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Get all the errors within the syntax tree associated with this object. Includes errors /// involving compiling method bodies or initializers, in addition to the errors returned by /// GetDeclarationDiagnostics. /// /// Optional span within the syntax tree for which to get diagnostics. /// If no argument is specified, then diagnostics for the entire tree are returned. /// A cancellation token that can be used to cancel the /// process of obtaining the diagnostics. /// /// Because this method must semantically bind all method bodies and initializers to check /// for diagnostics, it may take a significant amount of time. Unlike /// GetDeclarationDiagnostics, diagnostics for method bodies and initializers are not /// cached, any semantic information used to obtain the diagnostics is discarded. /// public abstract ImmutableArray GetDiagnostics(TextSpan? span = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Gets the symbol associated with a declaration syntax node. /// /// A syntax node that is a declaration. This can be any type /// derived from MemberDeclarationSyntax, TypeDeclarationSyntax, EnumDeclarationSyntax, /// NamespaceDeclarationSyntax, ParameterSyntax, TypeParameterSyntax, or the alias part of a /// UsingDirectiveSyntax /// The cancellation token. /// The symbol declared by the node or null if the node is not a declaration. internal ISymbol GetDeclaredSymbolForNode(SyntaxNode declaration, CancellationToken cancellationToken = default(CancellationToken)) { return GetDeclaredSymbolCore(declaration, cancellationToken); } /// /// Gets the symbol associated with a declaration syntax node. /// /// A syntax node that is a declaration. This can be any type /// derived from MemberDeclarationSyntax, TypeDeclarationSyntax, EnumDeclarationSyntax, /// NamespaceDeclarationSyntax, ParameterSyntax, TypeParameterSyntax, or the alias part of a /// UsingDirectiveSyntax /// The cancellation token. /// The symbol declared by the node or null if the node is not a declaration. protected abstract ISymbol GetDeclaredSymbolCore(SyntaxNode declaration, CancellationToken cancellationToken = default(CancellationToken)); /// /// Gets the symbol associated with a declaration syntax node. Unlike , /// this method returns all symbols declared by a given declaration syntax node. Specifically, in the case of field declaration syntax nodes, /// which can declare multiple symbols, this method returns all declared symbols. /// /// A syntax node that is a declaration. This can be any type /// derived from MemberDeclarationSyntax, TypeDeclarationSyntax, EnumDeclarationSyntax, /// NamespaceDeclarationSyntax, ParameterSyntax, TypeParameterSyntax, or the alias part of a /// UsingDirectiveSyntax /// The cancellation token. /// The symbols declared by the node. internal ImmutableArray GetDeclaredSymbolsForNode(SyntaxNode declaration, CancellationToken cancellationToken = default(CancellationToken)) { return GetDeclaredSymbolsCore(declaration, cancellationToken); } /// /// Gets the symbol associated with a declaration syntax node. Unlike , /// this method returns all symbols declared by a given declaration syntax node. Specifically, in the case of field declaration syntax nodes, /// which can declare multiple symbols, this method returns all declared symbols. /// /// A syntax node that is a declaration. This can be any type /// derived from MemberDeclarationSyntax, TypeDeclarationSyntax, EnumDeclarationSyntax, /// NamespaceDeclarationSyntax, ParameterSyntax, TypeParameterSyntax, or the alias part of a /// UsingDirectiveSyntax /// The cancellation token. /// The symbols declared by the node. protected abstract ImmutableArray GetDeclaredSymbolsCore(SyntaxNode declaration, CancellationToken cancellationToken = default(CancellationToken)); /// /// Gets the available named symbols in the context of the specified location and optional container. Only /// symbols that are accessible and visible from the given location are returned. /// /// The character position for determining the enclosing declaration scope and /// accessibility. /// The container to search for symbols within. If null then the enclosing declaration /// scope around position is used. /// The name of the symbol to find. If null is specified then symbols /// with any names are returned. /// Consider (reduced) extension methods. /// A list of symbols that were found. If no symbols were found, an empty list is returned. /// /// The "position" is used to determine what variables are visible and accessible. Even if "container" is /// specified, the "position" location is significant for determining which members of "containing" are /// accessible. /// /// Labels are not considered (see ). /// /// Non-reduced extension methods are considered regardless of the value of . /// public ImmutableArray LookupSymbols( int position, INamespaceOrTypeSymbol container = null, string name = null, bool includeReducedExtensionMethods = false) { return LookupSymbolsCore(position, container, name, includeReducedExtensionMethods); } /// /// Backing implementation of . /// protected abstract ImmutableArray LookupSymbolsCore( int position, INamespaceOrTypeSymbol container, string name, bool includeReducedExtensionMethods); /// /// Gets the available base type members in the context of the specified location. Akin to /// calling with the container set to the immediate base type of /// the type in which occurs. However, the accessibility rules /// are different: protected members of the base type will be visible. /// /// Consider the following example: /// /// public class Base /// { /// protected void M() { } /// } /// /// public class Derived : Base /// { /// void Test(Base b) /// { /// b.M(); // Error - cannot access protected member. /// base.M(); /// } /// } /// /// Protected members of an instance of another type are only accessible if the instance is known /// to be "this" instance (as indicated by the "base" keyword). /// /// The character position for determining the enclosing declaration scope and /// accessibility. /// The name of the symbol to find. If null is specified then symbols /// with any names are returned. /// A list of symbols that were found. If no symbols were found, an empty list is returned. /// /// The "position" is used to determine what variables are visible and accessible. /// /// Non-reduced extension methods are considered, but reduced extension methods are not. /// public ImmutableArray LookupBaseMembers( int position, string name = null) { return LookupBaseMembersCore(position, name); } /// /// Backing implementation of . /// protected abstract ImmutableArray LookupBaseMembersCore( int position, string name); /// /// Gets the available named static member symbols in the context of the specified location and optional container. /// Only members that are accessible and visible from the given location are returned. /// /// Non-reduced extension methods are considered, since they are static methods. /// /// The character position for determining the enclosing declaration scope and /// accessibility. /// The container to search for symbols within. If null then the enclosing declaration /// scope around position is used. /// The name of the symbol to find. If null is specified then symbols /// with any names are returned. /// A list of symbols that were found. If no symbols were found, an empty list is returned. /// /// The "position" is used to determine what variables are visible and accessible. Even if "container" is /// specified, the "position" location is significant for determining which members of "containing" are /// accessible. /// /// Essentially the same as filtering instance members out of the results of an analogous call. /// public ImmutableArray LookupStaticMembers( int position, INamespaceOrTypeSymbol container = null, string name = null) { return LookupStaticMembersCore(position, container, name); } /// /// Backing implementation of . /// protected abstract ImmutableArray LookupStaticMembersCore( int position, INamespaceOrTypeSymbol container, string name); /// /// Gets the available named namespace and type symbols in the context of the specified location and optional container. /// Only members that are accessible and visible from the given location are returned. /// /// The character position for determining the enclosing declaration scope and /// accessibility. /// The container to search for symbols within. If null then the enclosing declaration /// scope around position is used. /// The name of the symbol to find. If null is specified then symbols /// with any names are returned. /// A list of symbols that were found. If no symbols were found, an empty list is returned. /// /// The "position" is used to determine what variables are visible and accessible. Even if "container" is /// specified, the "position" location is significant for determining which members of "containing" are /// accessible. /// /// Does not return INamespaceOrTypeSymbol, because there could be aliases. /// public ImmutableArray LookupNamespacesAndTypes( int position, INamespaceOrTypeSymbol container = null, string name = null) { return LookupNamespacesAndTypesCore(position, container, name); } /// /// Backing implementation of . /// protected abstract ImmutableArray LookupNamespacesAndTypesCore( int position, INamespaceOrTypeSymbol container, string name); /// /// Gets the available named label symbols in the context of the specified location and optional container. /// Only members that are accessible and visible from the given location are returned. /// /// The character position for determining the enclosing declaration scope and /// accessibility. /// The name of the symbol to find. If null is specified then symbols /// with any names are returned. /// A list of symbols that were found. If no symbols were found, an empty list is returned. /// /// The "position" is used to determine what variables are visible and accessible. Even if "container" is /// specified, the "position" location is significant for determining which members of "containing" are /// accessible. /// public ImmutableArray LookupLabels( int position, string name = null) { return LookupLabelsCore(position, name); } /// /// Backing implementation of . /// protected abstract ImmutableArray LookupLabelsCore( int position, string name); /// /// Analyze control-flow within a part of a method body. /// /// The first node to be included within the analysis. /// The last node to be included within the analysis. /// An object that can be used to obtain the result of the control flow analysis. /// The span is not with a method /// body. /// /// The first and last nodes must be fully inside the same method body. /// internal ControlFlowAnalysis AnalyzeControlFlow(SyntaxNode firstStatement, SyntaxNode lastStatement) { return AnalyzeControlFlowCore(firstStatement, lastStatement); } /// /// Analyze control-flow within a part of a method body. /// /// The first node to be included within the analysis. /// The last node to be included within the analysis. /// An object that can be used to obtain the result of the control flow analysis. /// The span is not with a method /// body. /// /// The first and last nodes must be fully inside the same method body. /// protected abstract ControlFlowAnalysis AnalyzeControlFlowCore(SyntaxNode firstStatement, SyntaxNode lastStatement); /// /// Analyze control-flow within a part of a method body. /// /// The statement to be analyzed. /// An object that can be used to obtain the result of the control flow analysis. /// The span is not with a method /// body. /// /// The statement must be fully inside the same method body. /// internal ControlFlowAnalysis AnalyzeControlFlow(SyntaxNode statement) { return AnalyzeControlFlowCore(statement); } /// /// Analyze control-flow within a part of a method body. /// /// The statement to be analyzed. /// An object that can be used to obtain the result of the control flow analysis. /// The span is not with a method /// body. /// /// The statement must be fully inside the same method body. /// protected abstract ControlFlowAnalysis AnalyzeControlFlowCore(SyntaxNode statement); /// /// Analyze data-flow within a part of a method body. /// /// The first node to be included within the analysis. /// The last node to be included within the analysis. /// An object that can be used to obtain the result of the data flow analysis. /// The span is not with a method /// body. /// /// The first and last nodes must be fully inside the same method body. /// internal DataFlowAnalysis AnalyzeDataFlow(SyntaxNode firstStatement, SyntaxNode lastStatement) { return AnalyzeDataFlowCore(firstStatement, lastStatement); } /// /// Analyze data-flow within a part of a method body. /// /// The first node to be included within the analysis. /// The last node to be included within the analysis. /// An object that can be used to obtain the result of the data flow analysis. /// The span is not with a method /// body. /// /// The first and last nodes must be fully inside the same method body. /// protected abstract DataFlowAnalysis AnalyzeDataFlowCore(SyntaxNode firstStatement, SyntaxNode lastStatement); /// /// Analyze data-flow within a part of a method body. /// /// The statement or expression to be analyzed. /// An object that can be used to obtain the result of the data flow analysis. /// The statement or expression is not with a method /// body or field or property initializer. /// /// The statement or expression must be fully inside a method body. /// internal DataFlowAnalysis AnalyzeDataFlow(SyntaxNode statementOrExpression) { return AnalyzeDataFlowCore(statementOrExpression); } /// /// Analyze data-flow within a part of a method body. /// /// The statement or expression to be analyzed. /// An object that can be used to obtain the result of the data flow analysis. /// The statement or expression is not with a method /// body or field or property initializer. /// /// The statement or expression must be fully inside a method body. /// protected abstract DataFlowAnalysis AnalyzeDataFlowCore(SyntaxNode statementOrExpression); /// /// If the node provided has a constant value an Optional value will be returned with /// HasValue set to true and with Value set to the constant. If the node does not have an /// constant value, an Optional will be returned with HasValue set to false. /// public Optional GetConstantValue(SyntaxNode node, CancellationToken cancellationToken = default(CancellationToken)) { return GetConstantValueCore(node, cancellationToken); } /// /// If the node provided has a constant value an Optional value will be returned with /// HasValue set to true and with Value set to the constant. If the node does not have an /// constant value, an Optional will be returned with HasValue set to false. /// protected abstract Optional GetConstantValueCore(SyntaxNode node, CancellationToken cancellationToken = default(CancellationToken)); /// /// When getting information for a symbol that resolves to a method group or property group, /// from which a method is then chosen; the chosen method or property is present in Symbol; /// all methods in the group that was consulted are placed in this property. /// internal ImmutableArray GetMemberGroup(SyntaxNode node, CancellationToken cancellationToken = default(CancellationToken)) { return GetMemberGroupCore(node, cancellationToken); } /// /// When getting information for a symbol that resolves to a method group or property group, /// from which a method is then chosen; the chosen method or property is present in Symbol; /// all methods in the group that was consulted are placed in this property. /// protected abstract ImmutableArray GetMemberGroupCore(SyntaxNode node, CancellationToken cancellationToken = default(CancellationToken)); /// /// Given a position in the SyntaxTree for this SemanticModel returns the innermost Symbol /// that the position is considered inside of. /// public ISymbol GetEnclosingSymbol(int position, CancellationToken cancellationToken = default(CancellationToken)) { return GetEnclosingSymbolCore(position, cancellationToken); } /// /// Given a position in the SyntaxTree for this SemanticModel returns the innermost Symbol /// that the position is considered inside of. /// protected abstract ISymbol GetEnclosingSymbolCore(int position, CancellationToken cancellationToken = default(CancellationToken)); /// /// Determines if the symbol is accessible from the specified location. /// /// A character position used to identify a declaration scope and /// accessibility. This character position must be within the FullSpan of the Root syntax /// node in this SemanticModel. /// /// The symbol that we are checking to see if it accessible. /// /// True if "symbol is accessible, false otherwise. /// /// This method only checks accessibility from the point of view of the accessibility /// modifiers on symbol and its containing types. Even if true is returned, the given symbol /// may not be able to be referenced for other reasons, such as name hiding. /// public bool IsAccessible(int position, ISymbol symbol) { return IsAccessibleCore(position, symbol); } /// /// Determines if the symbol is accessible from the specified location. /// /// A character position used to identify a declaration scope and /// accessibility. This character position must be within the FullSpan of the Root syntax /// node in this SemanticModel. /// /// The symbol that we are checking to see if it accessible. /// /// True if "symbol is accessible, false otherwise. /// /// This method only checks accessibility from the point of view of the accessibility /// modifiers on symbol and its containing types. Even if true is returned, the given symbol /// may not be able to be referenced for other reasons, such as name hiding. /// protected abstract bool IsAccessibleCore(int position, ISymbol symbol); /// /// Field-like events can be used as fields in types that can access private /// members of the declaring type of the event. /// /// /// Always false for VB events. /// public bool IsEventUsableAsField(int position, IEventSymbol eventSymbol) { return IsEventUsableAsFieldCore(position, eventSymbol); } /// /// Field-like events can be used as fields in types that can access private /// members of the declaring type of the event. /// /// /// Always false for VB events. /// protected abstract bool IsEventUsableAsFieldCore(int position, IEventSymbol eventSymbol); /// /// If is an identifier name syntax node, return the corresponding /// to it. /// /// The nameSyntax node to get semantic information for. public PreprocessingSymbolInfo GetPreprocessingSymbolInfo(SyntaxNode nameSyntax) { return GetPreprocessingSymbolInfoCore(nameSyntax); } /// /// If is an identifier name syntax node, return the corresponding /// to it. /// /// The nameSyntax node to get semantic information for. protected abstract PreprocessingSymbolInfo GetPreprocessingSymbolInfoCore(SyntaxNode nameSyntax); /// /// Gets the for all the declarations whose span overlaps with the given . /// /// Span to get declarations. /// Flag indicating whether should be computed for the returned declaration infos. /// If false, then is always null. /// Builder to add declarations. /// Cancellation token. internal abstract void ComputeDeclarationsInSpan(TextSpan span, bool getSymbol, List builder, CancellationToken cancellationToken); /// /// Takes a node and returns a set of declarations that overlap the node's span. /// internal abstract void ComputeDeclarationsInNode(SyntaxNode node, bool getSymbol, List builder, CancellationToken cancellationToken, int? levelsToCompute = null); /// /// Takes a Symbol and syntax for one of its declaring syntax reference and returns the topmost syntax node to be used by syntax analyzer. /// protected internal virtual SyntaxNode GetTopmostNodeForDiagnosticAnalysis(ISymbol symbol, SyntaxNode declaringSyntax) { return declaringSyntax; } } }