Exemplo n.º 1
0
        protected override void VisitPatternSwitchSection(BoundPatternSwitchSection node, BoundExpression switchExpression, bool isLastSection)
        {
            foreach (var label in node.SwitchLabels)
            {
                NoteDeclaredPatternVariables(label.Pattern);
            }

            base.VisitPatternSwitchSection(node, switchExpression, isLastSection);
        }
        protected virtual void VisitPatternSwitchSection(BoundPatternSwitchSection node, BoundExpression switchExpression, bool isLastSection)
        {
            SetState(UnreachableState());
            foreach (var label in node.SwitchLabels)
            {
                VisitLabel(label.Label, node);
            }

            VisitStatementList(node);
        }
Exemplo n.º 3
0
        protected override void VisitPatternSwitchSection(BoundPatternSwitchSection node, BoundExpression switchExpression, bool isLastSection)
        {
            base.VisitPatternSwitchSection(node, switchExpression, isLastSection);

            // Check for switch section fall through error
            if (this.State.Alive)
            {
                var syntax = node.SwitchLabels.Last().Pattern.Syntax;
                Diagnostics.Add(isLastSection ? ErrorCode.ERR_SwitchFallOut : ErrorCode.ERR_SwitchFallThrough,
                                new SourceLocation(syntax), syntax.ToString());
            }
        }
Exemplo n.º 4
0
 public Guarded(
     BoundExpression expression,
     TypeSymbol type,
     ImmutableArray <KeyValuePair <BoundExpression, BoundExpression> > bindings,
     BoundPatternSwitchSection section,
     BoundExpression guard,
     BoundPatternSwitchLabel label)
     : base(expression, type, null)
 {
     this.Guard    = guard;
     this.Label    = label;
     this.Bindings = bindings;
     this.Section  = section;
     Debug.Assert(guard?.ConstantValue != ConstantValue.False);
     base.MatchIsComplete =
         (guard == null) || (guard.ConstantValue == ConstantValue.True);
 }
        protected virtual void VisitPatternSwitchSection(BoundPatternSwitchSection node, BoundExpression switchExpression, bool isLastSection)
        {
            // visit switch section labels
            var initialState    = this.State;
            var afterGuardState = UnreachableState();

            foreach (var label in node.PatternSwitchLabels)
            {
                SetState(initialState.Clone());
                VisitPattern(switchExpression, label.Pattern);
                SetState(StateWhenTrue);
                if (label.Guard != null)
                {
                    VisitCondition(label.Guard);
                    SetState(StateWhenTrue);
                }
                IntersectWith(ref afterGuardState, ref this.State);
            }

            // visit switch section body
            SetState(afterGuardState);
            VisitStatementList(node);
        }
Exemplo n.º 6
0
        internal DecisionTree ComputeDecisionTree()
        {
            Debug.Assert(_section == null);
            var expression = _switchStatement.Expression;

            if (expression.ConstantValue == null && expression.Kind != BoundKind.Local)
            {
                // unless the expression is simple enough, copy it into a local
                var localSymbol = new SynthesizedLocal(_enclosingSymbol as MethodSymbol, expression.Type, SynthesizedLocalKind.PatternMatchingTemp, _switchStatement.Syntax, false, RefKind.None);
                expression = new BoundLocal(expression.Syntax, localSymbol, null, expression.Type);
            }

            var result          = DecisionTree.Create(_switchStatement.Expression, _switchStatement.Expression.Type, _enclosingSymbol);
            var subsumptionTree = DecisionTree.Create(_switchStatement.Expression, _switchStatement.Expression.Type, _enclosingSymbol);
            BoundPatternSwitchLabel   defaultLabel   = null;
            BoundPatternSwitchSection defaultSection = null;

            foreach (var section in _switchStatement.SwitchSections)
            {
                this._section = section;
                foreach (var label in section.SwitchLabels)
                {
                    if (label.Syntax.Kind() == SyntaxKind.DefaultSwitchLabel)
                    {
                        if (defaultLabel != null)
                        {
                            // duplicate switch label will have been reported during initial binding.
                        }
                        else
                        {
                            defaultLabel   = label;
                            defaultSection = section;
                        }
                    }
                    else
                    {
                        this._syntax = label.Syntax;
                        // For purposes of subsumption, we do not take into consideration the value
                        // of the input expression. Therefore we consider null possible if the type permits.
                        var subsumedErrorCode = CheckSubsumed(label.Pattern, subsumptionTree, inputCouldBeNull: true);
                        if (subsumedErrorCode != 0 && subsumedErrorCode != ErrorCode.ERR_NoImplicitConvCast)
                        {
                            if (!label.HasErrors)
                            {
                                _diagnostics.Add(subsumedErrorCode, label.Pattern.Syntax.Location);
                            }
                        }
                        else
                        {
                            AddToDecisionTree(result, label);
                            if (label.Guard == null || label.Guard.ConstantValue == ConstantValue.True)
                            {
                                // Only unconditional switch labels contribute to subsumption
                                AddToDecisionTree(subsumptionTree, label);
                            }
                        }
                    }
                }
            }

            if (defaultLabel != null)
            {
                Add(result, (e, t) => new DecisionTree.Guarded(_switchStatement.Expression, _switchStatement.Expression.Type, default(ImmutableArray <KeyValuePair <BoundExpression, BoundExpression> >), defaultSection, null, defaultLabel));
            }

            return(result);
        }