using System.Collections.Generic; using Microsoft.CodeAnalysis.CSharp.Symbols; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp; internal class AlwaysAssignedWalker : AbstractRegionDataFlowPass { private LocalState _endOfRegionState; private readonly HashSet _labelsInside = new HashSet(); private AlwaysAssignedWalker(CSharpCompilation compilation, Symbol member, BoundNode node, BoundNode firstInRegion, BoundNode lastInRegion) : base(compilation, member, node, firstInRegion, lastInRegion) { } internal static IEnumerable Analyze(CSharpCompilation compilation, Symbol member, BoundNode node, BoundNode firstInRegion, BoundNode lastInRegion) { AlwaysAssignedWalker alwaysAssignedWalker = new AlwaysAssignedWalker(compilation, member, node, firstInRegion, lastInRegion); bool badRegion = false; try { List list = alwaysAssignedWalker.Analyze(ref badRegion); IEnumerable result; if (!badRegion) { IEnumerable enumerable = list; result = enumerable; } else { result = SpecializedCollections.EmptyEnumerable(); } return result; } finally { alwaysAssignedWalker.Free(); } } private List Analyze(ref bool badRegion) { Analyze(ref badRegion, null); List list = new List(); if (_endOfRegionState.Reachable) { foreach (int item in ((BitVector)(ref _endOfRegionState.Assigned)).TrueBits()) { if (item < variableBySlot.Count) { LocalDataFlowPass.VariableIdentifier variableIdentifier = variableBySlot[item]; if (variableIdentifier.Exists && !(variableIdentifier.Symbol is FieldSymbol)) { list.Add(variableIdentifier.Symbol); } } } } return list; } protected override void WriteArgument(BoundExpression arg, RefKind refKind, MethodSymbol method) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 if ((int)refKind == 2) { Assign(arg, null); } } protected override void ResolveBranch(PendingBranch pending, LabelSymbol label, BoundStatement target, ref bool labelStateChanged) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (base.IsInside && pending.Branch != null && !RegionContains(pending.Branch.Syntax.Span)) { pending.State = (pending.State.Reachable ? TopState() : UnreachableState()); } base.ResolveBranch(pending, label, target, ref labelStateChanged); } public override BoundNode VisitLabel(BoundLabel node) { ResolveLabel(node, node.Label); return base.VisitLabel(node); } public override BoundNode VisitLabeledStatement(BoundLabeledStatement node) { ResolveLabel(node, node.Label); return base.VisitLabeledStatement(node); } private void ResolveLabel(BoundNode node, LabelSymbol label) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (node.Syntax != null && RegionContains(node.Syntax.Span)) { _labelsInside.Add(label); } } protected override LocalState TopState() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return new LocalState(BitVector.Empty); } protected override void EnterRegion() { State = TopState(); base.EnterRegion(); } protected override void LeaveRegion() { //IL_006d: Unknown result type (might be due to invalid IL or missing references) if (IsConditionalState) { _endOfRegionState = StateWhenTrue.Clone(); Join(ref _endOfRegionState, ref StateWhenFalse); } else { _endOfRegionState = State.Clone(); } foreach (AbstractFlowPass.PendingBranch item in base.PendingBranches.AsEnumerable()) { if (item.Branch != null && RegionContains(item.Branch.Syntax.Span) && !_labelsInside.Contains(item.Label)) { Join(ref _endOfRegionState, ref item.State); } } base.LeaveRegion(); } }