|
// 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.
#nullable disable
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.Operations;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.FlowAnalysis.SymbolUsageAnalysis;
/// <summary>
/// Analysis to compute all the symbol writes for local and parameter
/// symbols in an executable code block, along with the information of whether or not the definition
/// may be read on some control flow path.
/// </summary>
internal static partial class SymbolUsageAnalysis
{
/// <summary>
/// Runs dataflow analysis on the given control flow graph to compute symbol usage results
/// for symbol read/writes.
/// </summary>
public static SymbolUsageResult Run(ControlFlowGraph cfg, ISymbol owningSymbol, CancellationToken cancellationToken)
=> DataFlowAnalyzer.RunAnalysis(cfg, owningSymbol, cancellationToken);
/// <summary>
/// Runs a fast, non-precise operation tree based analysis to compute symbol usage results
/// for symbol read/writes.
/// </summary>
public static SymbolUsageResult Run(IOperation rootOperation, ISymbol owningSymbol, CancellationToken cancellationToken)
{
AnalysisData analysisData = null;
using (analysisData = OperationTreeAnalysisData.Create(owningSymbol, AnalyzeLocalFunction))
{
var operations = SpecializedCollections.SingletonEnumerable(rootOperation);
Walker.AnalyzeOperationsAndUpdateData(owningSymbol, operations, analysisData, cancellationToken);
return analysisData.ToResult();
}
// Local functions.
BasicBlockAnalysisData AnalyzeLocalFunction(IMethodSymbol localFunction)
{
var localFunctionOperation = rootOperation.Descendants()
.FirstOrDefault(o => Equals((o as ILocalFunctionOperation)?.Symbol, localFunction));
// Can likely be null for broken code.
if (localFunctionOperation != null)
{
var operations = SpecializedCollections.SingletonEnumerable(localFunctionOperation);
Walker.AnalyzeOperationsAndUpdateData(localFunction, operations, analysisData, cancellationToken);
}
return analysisData.CurrentBlockAnalysisData;
}
}
}
|