예제 #1
0
        private BoundPatternSwitchLabel BindPatternSwitchSectionLabel(
            Binder sectionBinder, BoundExpression boundSwitchExpression, SwitchLabelSyntax node, LabelSymbol label, ref BoundPatternSwitchLabel defaultLabel, DiagnosticBag diagnostics)
        {
            switch (node.Kind())
            {
            case SyntaxKind.CaseSwitchLabel:
            {
                var  caseLabelSyntax = (CaseSwitchLabelSyntax)node;
                bool wasExpression;
                var  pattern = sectionBinder.BindConstantPattern(
                    node, boundSwitchExpression, boundSwitchExpression.Type, caseLabelSyntax.Value, node.HasErrors, diagnostics, out wasExpression, wasSwitchCase: true);
                bool hasErrors     = pattern.HasErrors;
                var  constantValue = pattern.ConstantValue;
                if (!hasErrors &&
                    (object)constantValue != null &&
                    pattern.Value.Type == SwitchGoverningType &&
                    this.FindMatchingSwitchCaseLabel(constantValue, caseLabelSyntax) != label)
                {
                    diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, pattern.ConstantValue.GetValueToDisplay() ?? label.Name);
                    hasErrors = true;
                }
                return(new BoundPatternSwitchLabel(node, label, pattern, null, hasErrors));
            }

            case SyntaxKind.DefaultSwitchLabel:
            {
                var  defaultLabelSyntax = (DefaultSwitchLabelSyntax)node;
                var  pattern            = new BoundWildcardPattern(node);
                bool hasErrors          = pattern.HasErrors;
                if (defaultLabel != null)
                {
                    diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, label.Name);
                    hasErrors = true;
                }

                // Note that this is semantically last! The caller will place it in the decision tree
                // in the final position.
                defaultLabel = new BoundPatternSwitchLabel(node, label, pattern, null, hasErrors);
                return(defaultLabel);
            }

            case SyntaxKind.CasePatternSwitchLabel:
            {
                var matchLabelSyntax = (CasePatternSwitchLabelSyntax)node;
                var pattern          = sectionBinder.BindPattern(
                    matchLabelSyntax.Pattern, boundSwitchExpression, boundSwitchExpression.Type, node.HasErrors, diagnostics, wasSwitchCase: true);
                return(new BoundPatternSwitchLabel(node, label, pattern,
                                                   matchLabelSyntax.WhenClause != null ? sectionBinder.BindBooleanExpression(matchLabelSyntax.WhenClause.Condition, diagnostics) : null, node.HasErrors));
            }

            default:
                throw ExceptionUtilities.UnexpectedValue(node);
            }
        }
예제 #2
0
        private static BoundPatternSwitchLabel BindPatternSwitchSectionLabel(Binder sectionBinder, BoundExpression boundSwitchExpression, SwitchLabelSyntax node, ref DefaultSwitchLabelSyntax defaultLabel, DiagnosticBag diagnostics)
        {
            switch (node.Kind())
            {
                case SyntaxKind.CasePatternSwitchLabel:
                    {
                        var matchLabelSyntax = (CasePatternSwitchLabelSyntax)node;
                        var pattern = sectionBinder.BindPattern(
                            matchLabelSyntax.Pattern, boundSwitchExpression, boundSwitchExpression.Type, node.HasErrors, diagnostics, wasSwitchCase: true);
                        return new BoundPatternSwitchLabel(node, pattern,
                            matchLabelSyntax.WhenClause != null ? sectionBinder.BindBooleanExpression(matchLabelSyntax.WhenClause.Condition, diagnostics) : null, node.HasErrors);
                    }

                case SyntaxKind.CaseSwitchLabel:
                    {
                        var caseLabelSyntax = (CaseSwitchLabelSyntax)node;
                        bool wasExpression;
                        var pattern = sectionBinder.BindConstantPattern(
                            node, boundSwitchExpression, boundSwitchExpression.Type, caseLabelSyntax.Value, node.HasErrors, diagnostics, out wasExpression, wasSwitchCase: true);
                        return new BoundPatternSwitchLabel(node, pattern, null, node.HasErrors);
                    }

                case SyntaxKind.DefaultSwitchLabel:
                    {
                        var defaultLabelSyntax = (DefaultSwitchLabelSyntax)node;
                        var pattern = new BoundWildcardPattern(node);
                        if (defaultLabel != null)
                        {
                            diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, "default");
                        }

                        defaultLabel = defaultLabelSyntax;
                        return new BoundPatternSwitchLabel(node, pattern, null, node.HasErrors); // note that this is semantically last!
                    }

                default:
                    throw ExceptionUtilities.Unreachable;
            }
        }
        private static BoundPatternSwitchLabel BindPatternSwitchSectionLabel(Binder sectionBinder, BoundExpression boundSwitchExpression, SwitchLabelSyntax node, ref DefaultSwitchLabelSyntax defaultLabel, DiagnosticBag diagnostics)
        {
            switch (node.Kind())
            {
            case SyntaxKind.CasePatternSwitchLabel:
            {
                var matchLabelSyntax = (CasePatternSwitchLabelSyntax)node;
                var pattern          = sectionBinder.BindPattern(
                    matchLabelSyntax.Pattern, boundSwitchExpression, boundSwitchExpression.Type, node.HasErrors, diagnostics, wasSwitchCase: true);
                return(new BoundPatternSwitchLabel(node, pattern,
                                                   matchLabelSyntax.WhenClause != null ? sectionBinder.BindBooleanExpression(matchLabelSyntax.WhenClause.Condition, diagnostics) : null, node.HasErrors));
            }

            case SyntaxKind.CaseSwitchLabel:
            {
                var  caseLabelSyntax = (CaseSwitchLabelSyntax)node;
                bool wasExpression;
                var  pattern = sectionBinder.BindConstantPattern(
                    node, boundSwitchExpression, boundSwitchExpression.Type, caseLabelSyntax.Value, node.HasErrors, diagnostics, out wasExpression, wasSwitchCase: true);
                return(new BoundPatternSwitchLabel(node, pattern, null, node.HasErrors));
            }

            case SyntaxKind.DefaultSwitchLabel:
            {
                var defaultLabelSyntax = (DefaultSwitchLabelSyntax)node;
                var pattern            = new BoundWildcardPattern(node);
                if (defaultLabel != null)
                {
                    diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, "default");
                }

                defaultLabel = defaultLabelSyntax;
                return(new BoundPatternSwitchLabel(node, pattern, null, node.HasErrors));        // note that this is semantically last!
            }

            default:
                throw ExceptionUtilities.Unreachable;
            }
        }
예제 #4
0
        private BoundPatternSwitchLabel BindPatternSwitchSectionLabel(
            Binder sectionBinder, BoundExpression boundSwitchExpression, SwitchLabelSyntax node, LabelSymbol label, ref BoundPatternSwitchLabel defaultLabel, DiagnosticBag diagnostics)
        {
            switch (node.Kind())
            {
                case SyntaxKind.CaseSwitchLabel:
                    {
                        var caseLabelSyntax = (CaseSwitchLabelSyntax)node;
                        bool wasExpression;
                        var pattern = sectionBinder.BindConstantPattern(
                            node, boundSwitchExpression, boundSwitchExpression.Type, caseLabelSyntax.Value, node.HasErrors, diagnostics, out wasExpression, wasSwitchCase: true);
                        bool hasErrors = pattern.HasErrors;
                        var constantValue = pattern.ConstantValue;
                        if (!hasErrors &&
                            (object)constantValue != null &&
                            pattern.Value.Type == SwitchGoverningType &&
                            this.FindMatchingSwitchCaseLabel(constantValue, caseLabelSyntax) != label)
                        {
                            diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, pattern.ConstantValue.GetValueToDisplay() ?? label.Name);
                            hasErrors = true;
                        }

                        // Until we've determined whether or not the switch label is reachable, we assume it
                        // is. The caller updates isReachable after determining if the label is subsumed.
                        const bool isReachable = true;
                        return new BoundPatternSwitchLabel(node, label, pattern, null, isReachable, hasErrors);
                    }

                case SyntaxKind.DefaultSwitchLabel:
                    {
                        var defaultLabelSyntax = (DefaultSwitchLabelSyntax)node;
                        var pattern = new BoundWildcardPattern(node);
                        bool hasErrors = pattern.HasErrors;
                        if (defaultLabel != null)
                        {
                            diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, label.Name);
                            hasErrors = true;
                        }

                        // We always treat the default label as reachable, even if the switch is complete.
                        const bool isReachable = true;

                        // Note that this is semantically last! The caller will place it in the decision tree
                        // in the final position.
                        defaultLabel = new BoundPatternSwitchLabel(node, label, pattern, null, isReachable, hasErrors);
                        return defaultLabel;
                    }

                case SyntaxKind.CasePatternSwitchLabel:
                    {
                        var matchLabelSyntax = (CasePatternSwitchLabelSyntax)node;
                        var pattern = sectionBinder.BindPattern(
                            matchLabelSyntax.Pattern, boundSwitchExpression, boundSwitchExpression.Type, node.HasErrors, diagnostics, wasSwitchCase: true);
                        return new BoundPatternSwitchLabel(node, label, pattern,
                            matchLabelSyntax.WhenClause != null ? sectionBinder.BindBooleanExpression(matchLabelSyntax.WhenClause.Condition, diagnostics) : null,
                            true, node.HasErrors);
                    }

                default:
                    throw ExceptionUtilities.UnexpectedValue(node);
            }
        }
예제 #5
0
        private BoundPatternSwitchLabel BindPatternSwitchSectionLabel(
            Binder sectionBinder, BoundExpression boundSwitchExpression, SwitchLabelSyntax node, LabelSymbol label, ref BoundPatternSwitchLabel defaultLabel, DiagnosticBag diagnostics)
        {
            switch (node.Kind())
            {
            case SyntaxKind.CaseSwitchLabel:
            {
                var  caseLabelSyntax = (CaseSwitchLabelSyntax)node;
                bool wasExpression;
                var  pattern = sectionBinder.BindConstantPattern(
                    node, boundSwitchExpression, boundSwitchExpression.Type, caseLabelSyntax.Value, node.HasErrors, diagnostics, out wasExpression, wasSwitchCase: true);
                bool hasErrors     = pattern.HasErrors;
                var  constantValue = pattern.ConstantValue;
                if (!hasErrors &&
                    (object)constantValue != null &&
                    pattern.Value.Type == SwitchGoverningType &&
                    this.FindMatchingSwitchCaseLabel(constantValue, caseLabelSyntax) != label)
                {
                    diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, pattern.ConstantValue.GetValueToDisplay() ?? label.Name);
                    hasErrors = true;
                }

                if (caseLabelSyntax.Value.Kind() == SyntaxKind.DefaultLiteralExpression)
                {
                    diagnostics.Add(ErrorCode.WRN_DefaultInSwitch, caseLabelSyntax.Value.Location);
                }

                // Until we've determined whether or not the switch label is reachable, we assume it
                // is. The caller updates isReachable after determining if the label is subsumed.
                const bool isReachable = true;
                return(new BoundPatternSwitchLabel(node, label, pattern, null, isReachable, hasErrors));
            }

            case SyntaxKind.DefaultSwitchLabel:
            {
                var  defaultLabelSyntax = (DefaultSwitchLabelSyntax)node;
                var  pattern            = new BoundWildcardPattern(node);
                bool hasErrors          = pattern.HasErrors;
                if (defaultLabel != null)
                {
                    diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, label.Name);
                    hasErrors = true;
                }

                // We always treat the default label as reachable, even if the switch is complete.
                const bool isReachable = true;

                // Note that this is semantically last! The caller will place it in the decision tree
                // in the final position.
                defaultLabel = new BoundPatternSwitchLabel(node, label, pattern, null, isReachable, hasErrors);
                return(defaultLabel);
            }

            case SyntaxKind.CasePatternSwitchLabel:
            {
                var matchLabelSyntax = (CasePatternSwitchLabelSyntax)node;
                var pattern          = sectionBinder.BindPattern(
                    matchLabelSyntax.Pattern, boundSwitchExpression, boundSwitchExpression.Type, node.HasErrors, diagnostics, wasSwitchCase: true);
                return(new BoundPatternSwitchLabel(node, label, pattern,
                                                   matchLabelSyntax.WhenClause != null ? sectionBinder.BindBooleanExpression(matchLabelSyntax.WhenClause.Condition, diagnostics) : null,
                                                   true, node.HasErrors));
            }

            default:
                throw ExceptionUtilities.UnexpectedValue(node);
            }
        }
        private BoundPatternSwitchLabel BindPatternSwitchSectionLabel(
            Binder sectionBinder, BoundExpression boundSwitchExpression, SwitchLabelSyntax node, LabelSymbol label, ref BoundPatternSwitchLabel defaultLabel, DiagnosticBag diagnostics)
        {
            switch (node.Kind())
            {
                case SyntaxKind.CaseSwitchLabel:
                    {
                        var caseLabelSyntax = (CaseSwitchLabelSyntax)node;
                        bool wasExpression;
                        var pattern = sectionBinder.BindConstantPattern(
                            node, boundSwitchExpression, boundSwitchExpression.Type, caseLabelSyntax.Value, node.HasErrors, diagnostics, out wasExpression, wasSwitchCase: true);
                        bool hasErrors = pattern.HasErrors;
                        var constantValue = pattern.ConstantValue;
                        if (!hasErrors && (object)constantValue != null && this.FindMatchingSwitchCaseLabel(constantValue, caseLabelSyntax) != label)
                        {
                            diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, pattern.ConstantValue.GetValueToDisplay() ?? label.Name);
                            hasErrors = true;
                        }
                        return new BoundPatternSwitchLabel(node, label, pattern, null, hasErrors);
                    }

                case SyntaxKind.DefaultSwitchLabel:
                    {
                        var defaultLabelSyntax = (DefaultSwitchLabelSyntax)node;
                        var pattern = new BoundWildcardPattern(node);
                        bool hasErrors = pattern.HasErrors;
                        if (defaultLabel != null)
                        {
                            diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, "default");
                            hasErrors = true;
                        }

                        // Note that this is semantically last! The caller will place it in the decision tree
                        // in the final position.
                        defaultLabel = new BoundPatternSwitchLabel(node, label, pattern, null, hasErrors);
                        return defaultLabel;
                    }

                case SyntaxKind.CasePatternSwitchLabel:
                    {
                        var matchLabelSyntax = (CasePatternSwitchLabelSyntax)node;
                        var pattern = sectionBinder.BindPattern(
                            matchLabelSyntax.Pattern, boundSwitchExpression, boundSwitchExpression.Type, node.HasErrors, diagnostics, wasSwitchCase: true);
                        return new BoundPatternSwitchLabel(node, label, pattern,
                            matchLabelSyntax.WhenClause != null ? sectionBinder.BindBooleanExpression(matchLabelSyntax.WhenClause.Condition, diagnostics) : null, node.HasErrors);
                    }

                default:
                    throw ExceptionUtilities.UnexpectedValue(node);
            }
        }