// 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