Files
PURErat-crack-scode/decompiled/Libraries/microsoft.codeanalysis.csharp/Microsoft.CodeAnalysis.CSharp/CSharpDataFlowAnalysis.cs
T

321 lines
9.5 KiB
C#
Raw Normal View History

2026-08-27 10:56:38 -06:00
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace Microsoft.CodeAnalysis.CSharp;
internal class CSharpDataFlowAnalysis : DataFlowAnalysis
{
private readonly RegionAnalysisContext _context;
private ImmutableArray<ISymbol> _variablesDeclared;
private HashSet<Symbol> _unassignedVariables;
private ImmutableArray<ISymbol> _dataFlowsIn;
private ImmutableArray<ISymbol> _dataFlowsOut;
private ImmutableArray<ISymbol> _definitelyAssignedOnEntry;
private ImmutableArray<ISymbol> _definitelyAssignedOnExit;
private ImmutableArray<ISymbol> _alwaysAssigned;
private ImmutableArray<ISymbol> _readInside;
private ImmutableArray<ISymbol> _writtenInside;
private ImmutableArray<ISymbol> _readOutside;
private ImmutableArray<ISymbol> _writtenOutside;
private ImmutableArray<ISymbol> _captured;
private ImmutableArray<IMethodSymbol> _usedLocalFunctions;
private ImmutableArray<ISymbol> _capturedInside;
private ImmutableArray<ISymbol> _capturedOutside;
private ImmutableArray<ISymbol> _unsafeAddressTaken;
private HashSet<PrefixUnaryExpressionSyntax> _unassignedVariableAddressOfSyntaxes;
private bool? _succeeded;
public override ImmutableArray<ISymbol> VariablesDeclared
{
get
{
if (_variablesDeclared.IsDefault)
{
ImmutableArray<ISymbol> value = (((DataFlowAnalysis)this).Succeeded ? Normalize(VariablesDeclaredWalker.Analyze(_context.Compilation, _context.Member, _context.BoundNode, _context.FirstInRegion, _context.LastInRegion)) : ImmutableArray<ISymbol>.Empty);
ImmutableInterlocked.InterlockedInitialize(ref _variablesDeclared, value);
}
return _variablesDeclared;
}
}
private HashSet<Symbol> UnassignedVariables
{
get
{
if (_unassignedVariables == null)
{
HashSet<Symbol> value = (((DataFlowAnalysis)this).Succeeded ? UnassignedVariablesWalker.Analyze(_context.Compilation, _context.Member, _context.BoundNode) : new HashSet<Symbol>());
Interlocked.CompareExchange(ref _unassignedVariables, value, null);
}
return _unassignedVariables;
}
}
public override ImmutableArray<ISymbol> DataFlowsIn
{
get
{
if (_dataFlowsIn.IsDefault)
{
_succeeded = !_context.Failed;
ImmutableArray<ISymbol> value = (_context.Failed ? ImmutableArray<ISymbol>.Empty : Normalize(DataFlowsInWalker.Analyze(_context.Compilation, _context.Member, _context.BoundNode, _context.FirstInRegion, _context.LastInRegion, UnassignedVariables, UnassignedVariableAddressOfSyntaxes, out _succeeded)));
ImmutableInterlocked.InterlockedInitialize(ref _dataFlowsIn, value);
}
return _dataFlowsIn;
}
}
public override ImmutableArray<ISymbol> DefinitelyAssignedOnEntry => ComputeDefinitelyAssignedValues().onEntry;
public override ImmutableArray<ISymbol> DefinitelyAssignedOnExit => ComputeDefinitelyAssignedValues().onExit;
public override ImmutableArray<ISymbol> DataFlowsOut
{
get
{
_ = ((DataFlowAnalysis)this).DataFlowsIn;
if (_dataFlowsOut.IsDefault)
{
ImmutableArray<ISymbol> value = (((DataFlowAnalysis)this).Succeeded ? Normalize(DataFlowsOutWalker.Analyze(_context.Compilation, _context.Member, _context.BoundNode, _context.FirstInRegion, _context.LastInRegion, UnassignedVariables, _dataFlowsIn)) : ImmutableArray<ISymbol>.Empty);
ImmutableInterlocked.InterlockedInitialize(ref _dataFlowsOut, value);
}
return _dataFlowsOut;
}
}
public override ImmutableArray<ISymbol> AlwaysAssigned
{
get
{
if (_alwaysAssigned.IsDefault)
{
ImmutableArray<ISymbol> value = (((DataFlowAnalysis)this).Succeeded ? Normalize(AlwaysAssignedWalker.Analyze(_context.Compilation, _context.Member, _context.BoundNode, _context.FirstInRegion, _context.LastInRegion)) : ImmutableArray<ISymbol>.Empty);
ImmutableInterlocked.InterlockedInitialize(ref _alwaysAssigned, value);
}
return _alwaysAssigned;
}
}
public override ImmutableArray<ISymbol> ReadInside
{
get
{
if (_readInside.IsDefault)
{
AnalyzeReadWrite();
}
return _readInside;
}
}
public override ImmutableArray<ISymbol> WrittenInside
{
get
{
if (_writtenInside.IsDefault)
{
AnalyzeReadWrite();
}
return _writtenInside;
}
}
public override ImmutableArray<ISymbol> ReadOutside
{
get
{
if (_readOutside.IsDefault)
{
AnalyzeReadWrite();
}
return _readOutside;
}
}
public override ImmutableArray<ISymbol> WrittenOutside
{
get
{
if (_writtenOutside.IsDefault)
{
AnalyzeReadWrite();
}
return _writtenOutside;
}
}
public override ImmutableArray<ISymbol> Captured
{
get
{
if (_captured.IsDefault)
{
AnalyzeReadWrite();
}
return _captured;
}
}
public override ImmutableArray<ISymbol> CapturedInside
{
get
{
if (_capturedInside.IsDefault)
{
AnalyzeReadWrite();
}
return _capturedInside;
}
}
public override ImmutableArray<ISymbol> CapturedOutside
{
get
{
if (_capturedOutside.IsDefault)
{
AnalyzeReadWrite();
}
return _capturedOutside;
}
}
public override ImmutableArray<ISymbol> UnsafeAddressTaken
{
get
{
if (_unsafeAddressTaken.IsDefault)
{
AnalyzeReadWrite();
}
return _unsafeAddressTaken;
}
}
public override ImmutableArray<IMethodSymbol> UsedLocalFunctions
{
get
{
if (_usedLocalFunctions.IsDefault)
{
AnalyzeReadWrite();
}
return _usedLocalFunctions;
}
}
private HashSet<PrefixUnaryExpressionSyntax> UnassignedVariableAddressOfSyntaxes
{
get
{
if (_unassignedVariableAddressOfSyntaxes == null)
{
HashSet<PrefixUnaryExpressionSyntax> value = (((DataFlowAnalysis)this).Succeeded ? UnassignedAddressTakenVariablesWalker.Analyze(_context.Compilation, _context.Member, _context.BoundNode) : new HashSet<PrefixUnaryExpressionSyntax>());
Interlocked.CompareExchange(ref _unassignedVariableAddressOfSyntaxes, value, null);
}
return _unassignedVariableAddressOfSyntaxes;
}
}
public sealed override bool Succeeded
{
get
{
if (!_succeeded.HasValue)
{
_ = ((DataFlowAnalysis)this).DataFlowsIn;
}
return _succeeded.Value;
}
}
internal CSharpDataFlowAnalysis(RegionAnalysisContext context)
{
_context = context;
}
private (ImmutableArray<ISymbol> onEntry, ImmutableArray<ISymbol> onExit) ComputeDefinitelyAssignedValues()
{
if (_definitelyAssignedOnExit.IsDefault)
{
ImmutableArray<ISymbol> value = ImmutableArray<ISymbol>.Empty;
ImmutableArray<ISymbol> value2 = ImmutableArray<ISymbol>.Empty;
if (((DataFlowAnalysis)this).Succeeded)
{
(HashSet<Symbol> entry, HashSet<Symbol> exit) tuple = DefinitelyAssignedWalker.Analyze(_context.Compilation, _context.Member, _context.BoundNode, _context.FirstInRegion, _context.LastInRegion);
HashSet<Symbol> item = tuple.entry;
HashSet<Symbol> item2 = tuple.exit;
value = Normalize(item);
value2 = Normalize(item2);
}
ImmutableInterlocked.InterlockedInitialize(ref _definitelyAssignedOnEntry, value);
ImmutableInterlocked.InterlockedInitialize(ref _definitelyAssignedOnExit, value2);
}
return (onEntry: _definitelyAssignedOnEntry, onExit: _definitelyAssignedOnExit);
}
private void AnalyzeReadWrite()
{
IEnumerable<Symbol> readInside;
IEnumerable<Symbol> writtenInside;
IEnumerable<Symbol> readOutside;
IEnumerable<Symbol> writtenOutside;
IEnumerable<Symbol> captured;
IEnumerable<Symbol> unsafeAddressTaken;
IEnumerable<Symbol> capturedInside;
IEnumerable<Symbol> capturedOutside;
IEnumerable<MethodSymbol> usedLocalFunctions;
if (((DataFlowAnalysis)this).Succeeded)
{
ReadWriteWalker.Analyze(_context.Compilation, _context.Member, _context.BoundNode, _context.FirstInRegion, _context.LastInRegion, UnassignedVariableAddressOfSyntaxes, out readInside, out writtenInside, out readOutside, out writtenOutside, out captured, out unsafeAddressTaken, out capturedInside, out capturedOutside, out usedLocalFunctions);
}
else
{
readInside = (writtenInside = (readOutside = (writtenOutside = (captured = (unsafeAddressTaken = (capturedInside = (capturedOutside = Enumerable.Empty<Symbol>())))))));
usedLocalFunctions = Enumerable.Empty<MethodSymbol>();
}
ImmutableInterlocked.InterlockedInitialize(ref _readInside, Normalize(readInside));
ImmutableInterlocked.InterlockedInitialize(ref _writtenInside, Normalize(writtenInside));
ImmutableInterlocked.InterlockedInitialize(ref _readOutside, Normalize(readOutside));
ImmutableInterlocked.InterlockedInitialize(ref _writtenOutside, Normalize(writtenOutside));
ImmutableInterlocked.InterlockedInitialize(ref _captured, Normalize(captured));
ImmutableInterlocked.InterlockedInitialize(ref _capturedInside, Normalize(capturedInside));
ImmutableInterlocked.InterlockedInitialize(ref _capturedOutside, Normalize(capturedOutside));
ImmutableInterlocked.InterlockedInitialize(ref _unsafeAddressTaken, Normalize(unsafeAddressTaken));
ImmutableInterlocked.InterlockedInitialize(ref _usedLocalFunctions, Normalize(usedLocalFunctions));
}
private static ImmutableArray<ISymbol> Normalize(IEnumerable<Symbol> data)
{
return ImmutableArray.CreateRange(data.Where((Symbol s) => s.CanBeReferencedByName).OrderBy((Symbol s) => s, LexicalOrderSymbolComparer.Instance).GetPublicSymbols());
}
private static ImmutableArray<IMethodSymbol> Normalize(IEnumerable<MethodSymbol> data)
{
return ImmutableArray.CreateRange(from p in data.Where((MethodSymbol s) => s.CanBeReferencedByName).OrderBy((MethodSymbol s) => s, LexicalOrderSymbolComparer.Instance)
select p.GetPublicSymbol());
}
}