/// <summary> /// Record declared variables in the pattern. /// </summary> private void NoteDeclaredPatternVariables(BoundPattern pattern) { if (IsInside) { switch (pattern) { case BoundDeclarationPattern decl: { // The variable may be null if it is a discard designation `_`. if (decl.Variable?.Kind == SymbolKind.Local) { // Because this API only returns local symbols and parameters, // we exclude pattern variables that have become fields in scripts. _variablesDeclared.Add(decl.Variable); } } break; case BoundRecursivePattern recur: { if (recur.Variable?.Kind == SymbolKind.Local) { _variablesDeclared.Add(recur.Variable); } } break; } } }
internal override BoundSwitchExpressionArm BindSwitchExpressionArm(SwitchExpressionArmSyntax node, DiagnosticBag diagnostics) { Debug.Assert(node == _arm); Binder armBinder = this.GetBinder(node); bool hasErrors = _switchExpressionBinder.SwitchGoverningType.IsErrorType(); ImmutableArray <LocalSymbol> locals = _armScopeBinder.Locals; BoundPattern pattern = armBinder.BindPattern(node.Pattern, _switchExpressionBinder.SwitchGoverningType, _switchExpressionBinder.SwitchGoverningValEscape, hasErrors, diagnostics); BoundExpression whenClause = node.WhenClause != null ? armBinder.BindBooleanExpression(node.WhenClause.Condition, diagnostics) : null; BoundExpression armResult = armBinder.BindValue(node.Expression, diagnostics, BindValueKind.RValue); var label = new GeneratedLabelSymbol("arm"); return(new BoundSwitchExpressionArm(node, locals, pattern, whenClause, armResult, label, hasErrors | pattern.HasErrors)); }
public BoundExpression LowerIsPattern( BoundIsPatternExpression isPatternExpression, BoundPattern pattern, CSharpCompilation compilation, DiagnosticBag diagnostics) { BoundDecisionDag decisionDag = isPatternExpression.DecisionDag; LabelSymbol whenTrueLabel = isPatternExpression.WhenTrueLabel; LabelSymbol whenFalseLabel = isPatternExpression.WhenFalseLabel; BoundExpression loweredInput = _localRewriter.VisitExpression(isPatternExpression.Expression); // The optimization of sharing pattern-matching temps with user variables can always apply to // an is-pattern expression because there is no when clause that could possibly intervene during // the execution of the pattern-matching automaton and change one of those variables. decisionDag = ShareTempsAndEvaluateInput(loweredInput, decisionDag, expr => _sideEffectBuilder.Add(expr), out _); var node = decisionDag.RootNode; // We follow the "good" path in the decision dag. We depend on it being nicely linear in structure. // If we add "or" patterns that assumption breaks down. while (node.Kind != BoundKind.LeafDecisionDagNode && node.Kind != BoundKind.WhenDecisionDagNode) { switch (node) { case BoundEvaluationDecisionDagNode evalNode: { LowerOneTest(evalNode.Evaluation); node = evalNode.Next; } break; case BoundTestDecisionDagNode testNode: { Debug.Assert(testNode.WhenFalse is BoundLeafDecisionDagNode x && x.Label == whenFalseLabel); if (testNode.WhenTrue is BoundEvaluationDecisionDagNode e && TryLowerTypeTestAndCast(testNode.Test, e.Evaluation, out BoundExpression sideEffect, out BoundExpression testExpression)) { _sideEffectBuilder.Add(sideEffect); AddConjunct(testExpression); node = e.Next; }
public override void VisitPattern(BoundPattern pattern) { base.VisitPattern(pattern); NoteDeclaredPatternVariables(pattern); }