Files
2026-08-27 10:56:38 -06:00

629 lines
29 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp;
internal class SwitchBinder : LocalScopeBinder
{
protected readonly SwitchStatementSyntax SwitchSyntax;
private readonly GeneratedLabelSymbol _breakLabel;
private BoundExpression _switchGoverningExpression;
private ImmutableArray<Diagnostic> _switchGoverningDiagnostics;
private ImmutableArray<AssemblySymbol> _switchGoverningDependencies;
private Dictionary<object, SourceLabelSymbol> _lazySwitchLabelsMap;
private static readonly object s_defaultKey = new object();
private static readonly object s_nullKey = new object();
private Dictionary<SyntaxNode, LabelSymbol> _labelsByNode;
protected bool PatternsEnabled => ((CSharpParseOptions)(object)SwitchSyntax.SyntaxTree.Options)?.IsFeatureEnabled(MessageID.IDS_FeaturePatternMatching) ?? true;
protected BoundExpression SwitchGoverningExpression
{
get
{
EnsureSwitchGoverningExpressionAndDiagnosticsBound();
return _switchGoverningExpression;
}
}
protected TypeSymbol SwitchGoverningType => SwitchGoverningExpression.Type;
protected ImmutableBindingDiagnostic<AssemblySymbol> SwitchGoverningDiagnostics
{
get
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
EnsureSwitchGoverningExpressionAndDiagnosticsBound();
return new ImmutableBindingDiagnostic<AssemblySymbol>(_switchGoverningDiagnostics, _switchGoverningDependencies);
}
}
private Dictionary<object, SourceLabelSymbol> LabelsByValue
{
get
{
if (_lazySwitchLabelsMap == null && Labels.Length > 0)
{
_lazySwitchLabelsMap = BuildLabelsByValue(Labels);
}
return _lazySwitchLabelsMap;
}
}
internal override bool IsLocalFunctionsScopeBinder => true;
internal override GeneratedLabelSymbol BreakLabel => _breakLabel;
internal override bool IsLabelsScopeBinder => true;
internal override SyntaxNode ScopeDesignator => (SyntaxNode)(object)SwitchSyntax;
protected Dictionary<SyntaxNode, LabelSymbol> LabelsByNode
{
get
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
if (_labelsByNode == null)
{
Dictionary<SyntaxNode, LabelSymbol> dictionary = new Dictionary<SyntaxNode, LabelSymbol>();
ImmutableArray<LabelSymbol>.Enumerator enumerator = Labels.GetEnumerator();
while (enumerator.MoveNext())
{
LabelSymbol current = enumerator.Current;
SyntaxNodeOrToken identifierNodeOrToken = ((SourceLabelSymbol)current).IdentifierNodeOrToken;
SyntaxNode val = ((SyntaxNodeOrToken)(ref identifierNodeOrToken)).AsNode();
if (val != null)
{
dictionary.Add(val, current);
}
}
_labelsByNode = dictionary;
}
return _labelsByNode;
}
}
private SwitchBinder(Binder next, SwitchStatementSyntax switchSyntax)
: base(next)
{
SwitchSyntax = switchSyntax;
_breakLabel = new GeneratedLabelSymbol("break");
}
private void EnsureSwitchGoverningExpressionAndDiagnosticsBound()
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
if (_switchGoverningExpression == null)
{
BindingDiagnosticBag instance = BindingDiagnosticBag.GetInstance();
BoundExpression value = BindSwitchGoverningExpression(instance);
ImmutableBindingDiagnostic<AssemblySymbol> val = ((BindingDiagnosticBag<AssemblySymbol>)(object)instance).ToReadOnlyAndFree();
ImmutableInterlocked.InterlockedInitialize(ref _switchGoverningDiagnostics, val.Diagnostics);
ImmutableInterlocked.InterlockedInitialize(ref _switchGoverningDependencies, val.Dependencies);
Interlocked.CompareExchange(ref _switchGoverningExpression, value, null);
}
}
private static Dictionary<object, SourceLabelSymbol> BuildLabelsByValue(ImmutableArray<LabelSymbol> labels)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
Dictionary<object, SourceLabelSymbol> dictionary = new Dictionary<object, SourceLabelSymbol>(labels.Length, (IEqualityComparer<object>?)new SwitchLabelsComparer());
ImmutableArray<LabelSymbol>.Enumerator enumerator = labels.GetEnumerator();
while (enumerator.MoveNext())
{
SourceLabelSymbol sourceLabelSymbol = (SourceLabelSymbol)enumerator.Current;
SyntaxKind syntaxKind = sourceLabelSymbol.IdentifierNodeOrToken.Kind();
if (syntaxKind != SyntaxKind.IdentifierToken)
{
ConstantValue switchCaseLabelConstant = sourceLabelSymbol.SwitchCaseLabelConstant;
object key;
if (switchCaseLabelConstant != null && !switchCaseLabelConstant.IsBad)
{
key = KeyForConstant(switchCaseLabelConstant);
}
else if (syntaxKind == SyntaxKind.DefaultSwitchLabel)
{
key = s_defaultKey;
}
else
{
SyntaxNodeOrToken identifierNodeOrToken = sourceLabelSymbol.IdentifierNodeOrToken;
key = ((SyntaxNodeOrToken)(ref identifierNodeOrToken)).AsNode();
}
if (!dictionary.ContainsKey(key))
{
dictionary.Add(key, sourceLabelSymbol);
}
}
}
return dictionary;
}
protected override ImmutableArray<LocalSymbol> BuildLocals()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
ArrayBuilder<LocalSymbol> instance = ArrayBuilder<LocalSymbol>.GetInstance();
Enumerator<SwitchSectionSyntax> enumerator = SwitchSyntax.Sections.GetEnumerator();
while (enumerator.MoveNext())
{
SwitchSectionSyntax current = enumerator.Current;
instance.AddRange(BuildLocals(current.Statements, GetBinder((SyntaxNode)(object)current)));
}
return instance.ToImmutableAndFree();
}
protected override ImmutableArray<LocalFunctionSymbol> BuildLocalFunctions()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
ArrayBuilder<LocalFunctionSymbol> instance = ArrayBuilder<LocalFunctionSymbol>.GetInstance();
Enumerator<SwitchSectionSyntax> enumerator = SwitchSyntax.Sections.GetEnumerator();
while (enumerator.MoveNext())
{
SwitchSectionSyntax current = enumerator.Current;
instance.AddRange(BuildLocalFunctions(current.Statements));
}
return instance.ToImmutableAndFree();
}
protected override ImmutableArray<LabelSymbol> BuildLabels()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
ArrayBuilder<LabelSymbol> labels = ArrayBuilder<LabelSymbol>.GetInstance();
Enumerator<SwitchSectionSyntax> enumerator = SwitchSyntax.Sections.GetEnumerator();
while (enumerator.MoveNext())
{
SwitchSectionSyntax current = enumerator.Current;
BuildSwitchLabels(current.Labels, GetBinder((SyntaxNode)(object)current), labels, BindingDiagnosticBag.Discarded);
BuildLabels(current.Statements, ref labels);
}
return labels.ToImmutableAndFree();
}
private void BuildSwitchLabels(SyntaxList<SwitchLabelSyntax> labelsSyntax, Binder sectionBinder, ArrayBuilder<LabelSymbol> labels, BindingDiagnosticBag tempDiagnosticBag)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
Enumerator<SwitchLabelSyntax> enumerator = labelsSyntax.GetEnumerator();
while (enumerator.MoveNext())
{
SwitchLabelSyntax current = enumerator.Current;
ConstantValue constantValueOpt = null;
switch (current.Kind())
{
case SyntaxKind.CaseSwitchLabel:
{
CaseSwitchLabelSyntax caseSwitchLabelSyntax = (CaseSwitchLabelSyntax)current;
BoundExpression boundExpression = sectionBinder.BindTypeOrRValue(caseSwitchLabelSyntax.Value, tempDiagnosticBag);
if (!(boundExpression is BoundTypeExpression))
{
ConvertCaseExpression(current, boundExpression, out constantValueOpt, tempDiagnosticBag);
}
break;
}
case SyntaxKind.CasePatternSwitchLabel:
{
CasePatternSwitchLabelSyntax casePatternSwitchLabelSyntax = (CasePatternSwitchLabelSyntax)current;
sectionBinder.BindPattern(casePatternSwitchLabelSyntax.Pattern, SwitchGoverningType, permitDesignations: true, ((SyntaxNode)current).HasErrors, tempDiagnosticBag);
break;
}
}
labels.Add((LabelSymbol)new SourceLabelSymbol((MethodSymbol)ContainingMemberOrLambda, SyntaxNodeOrToken.op_Implicit((SyntaxNode)(object)current), constantValueOpt));
}
}
protected BoundExpression ConvertCaseExpression(CSharpSyntaxNode node, BoundExpression caseExpression, out ConstantValue constantValueOpt, BindingDiagnosticBag diagnostics, bool isGotoCaseExpr = false)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
bool hasErrors = false;
if (isGotoCaseExpr)
{
CompoundUseSiteInfo<AssemblySymbol> useSiteInfo = GetNewCompoundUseSiteInfo(diagnostics);
Conversion conversion = base.Conversions.ClassifyConversionFromExpression(caseExpression, SwitchGoverningType, base.CheckOverflowAtRuntime, ref useSiteInfo);
((BindingDiagnosticBag<AssemblySymbol>)(object)diagnostics).Add((SyntaxNode)(object)node, useSiteInfo);
if (!conversion.IsValid)
{
GenerateImplicitConversionError(diagnostics, (SyntaxNode)(object)node, conversion, caseExpression, SwitchGoverningType);
hasErrors = true;
}
else if (!conversion.IsImplicit)
{
diagnostics.Add(ErrorCode.WRN_GotoCaseShouldConvert, ((SyntaxNode)node).Location, SwitchGoverningType);
hasErrors = true;
}
caseExpression = CreateConversion(caseExpression, conversion, SwitchGoverningType, diagnostics);
}
Conversion patternExpressionConversion;
return ConvertPatternExpression(SwitchGoverningType, node, caseExpression, out constantValueOpt, hasErrors, diagnostics, out patternExpressionConversion);
}
protected static object KeyForConstant(ConstantValue constantValue)
{
if (!constantValue.IsNull)
{
return constantValue.Value;
}
return s_nullKey;
}
protected SourceLabelSymbol FindMatchingSwitchCaseLabel(ConstantValue constantValue, CSharpSyntaxNode labelSyntax)
{
object key = ((constantValue == null || constantValue.IsBad) ? labelSyntax : KeyForConstant(constantValue));
return FindMatchingSwitchLabel(key);
}
private SourceLabelSymbol GetDefaultLabel()
{
return FindMatchingSwitchLabel(s_defaultKey);
}
private SourceLabelSymbol FindMatchingSwitchLabel(object key)
{
Dictionary<object, SourceLabelSymbol> labelsByValue = LabelsByValue;
if (labelsByValue != null && labelsByValue.TryGetValue(key, out var value))
{
return value;
}
return null;
}
internal override ImmutableArray<LocalSymbol> GetDeclaredLocalsForScope(SyntaxNode scopeDesignator)
{
if ((object)SwitchSyntax == scopeDesignator)
{
return Locals;
}
throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/Binder/SwitchBinder.cs", 335);
}
internal override ImmutableArray<LocalFunctionSymbol> GetDeclaredLocalFunctionsForScope(CSharpSyntaxNode scopeDesignator)
{
if (SwitchSyntax == scopeDesignator)
{
return LocalFunctions;
}
throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/Binder/SwitchBinder.cs", 345);
}
private BoundExpression BindSwitchGoverningExpression(BindingDiagnosticBag diagnostics)
{
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Invalid comparison between Unknown and I4
ExpressionSyntax expression = SwitchSyntax.Expression;
Binder binder = GetBinder((SyntaxNode)(object)expression);
BoundExpression boundExpression = binder.BindRValueWithoutTargetType(expression, diagnostics);
TypeSymbol typeSymbol = boundExpression.Type;
if ((object)typeSymbol != null && !typeSymbol.IsErrorType())
{
if (typeSymbol.IsValidV6SwitchGoverningType())
{
if ((int)typeSymbol.SpecialType == 7)
{
Binder.CheckFeatureAvailability((SyntaxNode)(object)expression, MessageID.IDS_FeatureSwitchOnBool, diagnostics);
}
return boundExpression;
}
CompoundUseSiteInfo<AssemblySymbol> useSiteInfo = GetNewCompoundUseSiteInfo(diagnostics);
TypeSymbol switchGoverningType;
Conversion conversion = binder.Conversions.ClassifyImplicitUserDefinedConversionForV6SwitchGoverningType(typeSymbol, out switchGoverningType, ref useSiteInfo);
((BindingDiagnosticBag<AssemblySymbol>)(object)diagnostics).Add((SyntaxNode)(object)expression, useSiteInfo);
if (conversion.IsValid)
{
return binder.CreateConversion((SyntaxNode)(object)expression, boundExpression, conversion, isCast: false, null, switchGoverningType, diagnostics);
}
if (!typeSymbol.IsVoidType())
{
if (!PatternsEnabled)
{
diagnostics.Add(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, ((SyntaxNode)expression).Location);
}
return boundExpression;
}
typeSymbol = CreateErrorType(typeSymbol.Name);
}
if (!boundExpression.HasAnyErrors)
{
diagnostics.Add(ErrorCode.ERR_SwitchExpressionValueExpected, ((SyntaxNode)expression).Location, boundExpression.Display);
}
return new BoundBadExpression((SyntaxNode)(object)expression, LookupResultKind.Empty, ImmutableArray<Symbol>.Empty, ImmutableArray.Create(boundExpression), typeSymbol ?? CreateErrorType());
}
internal BoundStatement BindGotoCaseOrDefault(GotoStatementSyntax node, Binder gotoBinder, BindingDiagnosticBag diagnostics)
{
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
BoundExpression boundExpression = null;
if (!((SyntaxNode)node).HasErrors)
{
ConstantValue constantValueOpt = null;
bool flag = false;
SourceLabelSymbol sourceLabelSymbol;
if (node.Expression != null)
{
boundExpression = gotoBinder.BindValue(node.Expression, diagnostics, BindValueKind.RValue);
boundExpression = ConvertCaseExpression(node, boundExpression, out constantValueOpt, diagnostics, isGotoCaseExpr: true);
flag = flag || boundExpression.HasAnyErrors;
if (!flag && constantValueOpt == (ConstantValue)null)
{
diagnostics.Add(ErrorCode.ERR_ConstantExpected, ((SyntaxNode)node).Location);
flag = true;
}
ConstantValueUtils.CheckLangVersionForConstantValue(boundExpression, diagnostics);
sourceLabelSymbol = FindMatchingSwitchCaseLabel(constantValueOpt, node);
}
else
{
sourceLabelSymbol = GetDefaultLabel();
}
if ((object)sourceLabelSymbol != null)
{
return new BoundGotoStatement((SyntaxNode)(object)node, sourceLabelSymbol, boundExpression, null, flag);
}
if (!flag)
{
string text = SyntaxFacts.GetText(node.CaseOrDefaultKeyword.Kind());
if (node.Kind() == SyntaxKind.GotoCaseStatement)
{
text = text + " " + constantValueOpt.Value;
}
text += ":";
diagnostics.Add(ErrorCode.ERR_LabelNotFound, ((SyntaxNode)node).Location, text);
flag = true;
}
}
return new BoundBadStatement((SyntaxNode)(object)node, (boundExpression != null) ? ImmutableArray.Create((BoundNode)boundExpression) : ImmutableArray<BoundNode>.Empty, hasErrors: true);
}
internal static SwitchBinder Create(Binder next, SwitchStatementSyntax switchSyntax)
{
return new SwitchBinder(next, switchSyntax);
}
internal override BoundStatement BindSwitchStatementCore(SwitchStatementSyntax node, Binder originalBinder, BindingDiagnosticBag diagnostics)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
if (node.Sections.Count == 0)
{
SyntaxToken openBraceToken = node.OpenBraceToken;
diagnostics.Add(ErrorCode.WRN_EmptySwitch, ((SyntaxToken)(ref openBraceToken)).GetLocation());
}
BoundExpression switchGoverningExpression = SwitchGoverningExpression;
((BindingDiagnosticBag<AssemblySymbol>)(object)diagnostics).AddRange(SwitchGoverningDiagnostics, true);
BoundSwitchLabel defaultLabel;
ImmutableArray<BoundSwitchSection> switchSections = BindSwitchSections(originalBinder, diagnostics, out defaultLabel);
ImmutableArray<LocalSymbol> declaredLocalsForScope = GetDeclaredLocalsForScope((SyntaxNode)(object)node);
ImmutableArray<LocalFunctionSymbol> declaredLocalFunctionsForScope = GetDeclaredLocalFunctionsForScope(node);
BoundDecisionDag boundDecisionDag = DecisionDagBuilder.CreateDecisionDagForSwitchStatement(base.Compilation, (SyntaxNode)(object)node, switchGoverningExpression, switchSections, defaultLabel?.Label ?? BreakLabel, diagnostics);
CheckSwitchErrors(ref switchSections, boundDecisionDag, diagnostics);
boundDecisionDag = boundDecisionDag.SimplifyDecisionDagIfConstantInput(switchGoverningExpression);
ImmutableArray<BoundSwitchSection> switchSections2 = switchSections;
BoundSwitchLabel defaultLabel2 = defaultLabel;
GeneratedLabelSymbol breakLabel = BreakLabel;
return new BoundSwitchStatement((SyntaxNode)(object)node, switchGoverningExpression, declaredLocalsForScope, declaredLocalFunctionsForScope, switchSections2, boundDecisionDag, defaultLabel2, breakLabel);
}
private void CheckSwitchErrors(ref ImmutableArray<BoundSwitchSection> switchSections, BoundDecisionDag decisionDag, BindingDiagnosticBag diagnostics)
{
ImmutableHashSet<LabelSymbol> reachableLabels = decisionDag.ReachableLabels;
if (!ImmutableArrayExtensions.Any<BoundSwitchSection, ImmutableHashSet<LabelSymbol>>(switchSections, (Func<BoundSwitchSection, ImmutableHashSet<LabelSymbol>, bool>)((BoundSwitchSection s, ImmutableHashSet<LabelSymbol> immutableHashSet) => ImmutableArrayExtensions.Any<BoundSwitchLabel, ImmutableHashSet<LabelSymbol>>(s.SwitchLabels, (Func<BoundSwitchLabel, ImmutableHashSet<LabelSymbol>, bool>)isSubsumed, immutableHashSet)), reachableLabels))
{
return;
}
ArrayBuilder<BoundSwitchSection> instance = ArrayBuilder<BoundSwitchSection>.GetInstance(switchSections.Length);
bool flag = false;
ImmutableArray<BoundSwitchSection>.Enumerator enumerator = switchSections.GetEnumerator();
while (enumerator.MoveNext())
{
BoundSwitchSection current = enumerator.Current;
ArrayBuilder<BoundSwitchLabel> instance2 = ArrayBuilder<BoundSwitchLabel>.GetInstance(current.SwitchLabels.Length);
ImmutableArray<BoundSwitchLabel>.Enumerator enumerator2 = current.SwitchLabels.GetEnumerator();
while (enumerator2.MoveNext())
{
BoundSwitchLabel current2 = enumerator2.Current;
BoundSwitchLabel boundSwitchLabel = current2;
if (!current2.HasErrors && isSubsumed(current2, reachableLabels) && current2.Syntax.Kind() != SyntaxKind.DefaultSwitchLabel)
{
SyntaxNode syntax = current2.Syntax;
if (!(syntax is CasePatternSwitchLabelSyntax casePatternSwitchLabelSyntax))
{
if (!(syntax is CaseSwitchLabelSyntax caseSwitchLabelSyntax))
{
throw ExceptionUtilities.UnexpectedValue((object)syntax.Kind());
}
if (current2.Pattern is BoundConstantPattern boundConstantPattern && !boundConstantPattern.ConstantValue.IsBad && FindMatchingSwitchCaseLabel(boundConstantPattern.ConstantValue, caseSwitchLabelSyntax) != current2.Label)
{
diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, syntax.Location, boundConstantPattern.ConstantValue.GetValueToDisplay());
}
else if (!current2.Pattern.HasErrors && !flag)
{
diagnostics.Add(ErrorCode.ERR_SwitchCaseSubsumed, ((SyntaxNode)caseSwitchLabelSyntax.Value).Location);
}
}
else if (!((SyntaxNode)casePatternSwitchLabelSyntax.Pattern).HasErrors && !flag)
{
diagnostics.Add(ErrorCode.ERR_SwitchCaseSubsumed, ((SyntaxNode)casePatternSwitchLabelSyntax.Pattern).Location);
}
boundSwitchLabel = new BoundSwitchLabel(current2.Syntax, current2.Label, current2.Pattern, current2.WhenClause, hasErrors: true);
}
flag |= current2.HasErrors;
instance2.Add(boundSwitchLabel);
}
instance.Add(current.Update(current.Locals, instance2.ToImmutableAndFree(), current.Statements));
}
switchSections = instance.ToImmutableAndFree();
static bool isSubsumed(BoundSwitchLabel switchLabel, ImmutableHashSet<LabelSymbol> immutableHashSet)
{
return !immutableHashSet.Contains(switchLabel.Label);
}
}
internal override void BindPatternSwitchLabelForInference(CasePatternSwitchLabelSyntax node, BindingDiagnosticBag diagnostics)
{
BoundSwitchLabel defaultLabel = null;
BindSwitchSectionLabel(GetBinder((SyntaxNode)(object)node.Parent), node, LabelsByNode[(SyntaxNode)(object)node], ref defaultLabel, diagnostics);
}
private ImmutableArray<BoundSwitchSection> BindSwitchSections(Binder originalBinder, BindingDiagnosticBag diagnostics, out BoundSwitchLabel defaultLabel)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
ArrayBuilder<BoundSwitchSection> instance = ArrayBuilder<BoundSwitchSection>.GetInstance(SwitchSyntax.Sections.Count);
defaultLabel = null;
Enumerator<SwitchSectionSyntax> enumerator = SwitchSyntax.Sections.GetEnumerator();
while (enumerator.MoveNext())
{
SwitchSectionSyntax current = enumerator.Current;
BoundSwitchSection boundSwitchSection = BindSwitchSection(current, originalBinder, ref defaultLabel, diagnostics);
instance.Add(boundSwitchSection);
}
return instance.ToImmutableAndFree();
}
private BoundSwitchSection BindSwitchSection(SwitchSectionSyntax node, Binder originalBinder, ref BoundSwitchLabel defaultLabel, BindingDiagnosticBag diagnostics)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
ArrayBuilder<BoundSwitchLabel> instance = ArrayBuilder<BoundSwitchLabel>.GetInstance(node.Labels.Count);
Binder binder = originalBinder.GetBinder((SyntaxNode)(object)node);
Dictionary<SyntaxNode, LabelSymbol> labelsByNode = LabelsByNode;
Enumerator<SwitchLabelSyntax> enumerator = node.Labels.GetEnumerator();
while (enumerator.MoveNext())
{
SwitchLabelSyntax current = enumerator.Current;
LabelSymbol label = labelsByNode[(SyntaxNode)(object)current];
BoundSwitchLabel boundSwitchLabel = BindSwitchSectionLabel(binder, current, label, ref defaultLabel, diagnostics);
instance.Add(boundSwitchLabel);
}
ArrayBuilder<BoundStatement> instance2 = ArrayBuilder<BoundStatement>.GetInstance(node.Statements.Count);
Enumerator<StatementSyntax> enumerator2 = node.Statements.GetEnumerator();
while (enumerator2.MoveNext())
{
StatementSyntax current2 = enumerator2.Current;
BoundStatement boundStatement = binder.BindStatement(current2, diagnostics);
if (ContainsUsingVariable(boundStatement))
{
diagnostics.Add(ErrorCode.ERR_UsingVarInSwitchCase, ((SyntaxNode)current2).Location);
}
instance2.Add(boundStatement);
}
return new BoundSwitchSection((SyntaxNode)(object)node, binder.GetDeclaredLocalsForScope((SyntaxNode)(object)node), instance.ToImmutableAndFree(), instance2.ToImmutableAndFree());
}
internal static bool ContainsUsingVariable(BoundStatement boundStatement)
{
if (boundStatement is BoundLocalDeclaration boundLocalDeclaration)
{
return boundLocalDeclaration.LocalSymbol.IsUsing;
}
if (boundStatement is BoundMultipleLocalDeclarationsBase boundMultipleLocalDeclarationsBase && !boundMultipleLocalDeclarationsBase.LocalDeclarations.IsDefaultOrEmpty)
{
return boundMultipleLocalDeclarationsBase.LocalDeclarations[0].LocalSymbol.IsUsing;
}
return false;
}
private BoundSwitchLabel BindSwitchSectionLabel(Binder sectionBinder, SwitchLabelSyntax node, LabelSymbol label, ref BoundSwitchLabel defaultLabel, BindingDiagnosticBag diagnostics)
{
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
switch (node.Kind())
{
case SyntaxKind.CaseSwitchLabel:
{
CaseSwitchLabelSyntax caseSwitchLabelSyntax = (CaseSwitchLabelSyntax)node;
bool hasErrors = ((SyntaxNode)node).HasErrors;
BoundPattern boundPattern = sectionBinder.BindConstantPatternWithFallbackToTypePattern((SyntaxNode)(object)caseSwitchLabelSyntax.Value, caseSwitchLabelSyntax.Value, SwitchGoverningType, hasErrors, diagnostics);
boundPattern.WasCompilerGenerated = true;
reportIfConstantNamedUnderscore(boundPattern, caseSwitchLabelSyntax.Value);
return new BoundSwitchLabel((SyntaxNode)(object)node, label, boundPattern, null, boundPattern.HasErrors);
}
case SyntaxKind.DefaultSwitchLabel:
{
BoundDiscardPattern boundDiscardPattern = new BoundDiscardPattern((SyntaxNode)(object)node, SwitchGoverningType, SwitchGoverningType);
bool hasErrors2 = boundDiscardPattern.HasErrors;
if (defaultLabel != null)
{
diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, ((SyntaxNode)node).Location, label.Name);
hasErrors2 = true;
return new BoundSwitchLabel((SyntaxNode)(object)node, label, boundDiscardPattern, null, hasErrors2);
}
return defaultLabel = new BoundSwitchLabel((SyntaxNode)(object)node, label, boundDiscardPattern, null, hasErrors2);
}
case SyntaxKind.CasePatternSwitchLabel:
{
CasePatternSwitchLabelSyntax casePatternSwitchLabelSyntax = (CasePatternSwitchLabelSyntax)node;
MessageID.IDS_FeaturePatternMatching.CheckFeatureAvailability(diagnostics, node.Keyword);
BoundPattern pattern = sectionBinder.BindPattern(casePatternSwitchLabelSyntax.Pattern, SwitchGoverningType, permitDesignations: true, ((SyntaxNode)node).HasErrors, diagnostics);
if (casePatternSwitchLabelSyntax.Pattern is ConstantPatternSyntax constantPatternSyntax)
{
reportIfConstantNamedUnderscore(pattern, constantPatternSyntax.Expression);
}
return new BoundSwitchLabel((SyntaxNode)(object)node, label, pattern, (casePatternSwitchLabelSyntax.WhenClause != null) ? sectionBinder.BindBooleanExpression(casePatternSwitchLabelSyntax.WhenClause.Condition, diagnostics) : null, ((SyntaxNode)node).HasErrors);
}
default:
throw ExceptionUtilities.UnexpectedValue((object)node);
}
void reportIfConstantNamedUnderscore(BoundPattern boundPattern2, ExpressionSyntax expression)
{
if (boundPattern2 is BoundConstantPattern && !boundPattern2.HasErrors && Binder.IsUnderscore(expression))
{
diagnostics.Add(ErrorCode.WRN_CaseConstantNamedUnderscore, ((SyntaxNode)expression).Location);
}
}
}
}