Пример #1
0
        public void DoNotCrashOnBadInput()
        {
            // For error recovery, do not throw exceptions on bad inputs.
            var ctors = new IValueSetFactory[]
            {
                ForByte,
                ForSByte,
                ForChar,
                ForShort,
                ForUShort,
                ForInt,
                ForUInt,
                ForLong,
                ForULong,
                ForBool,
                ForFloat,
                ForDouble,
                ForString,
                ForDecimal,
                ForNint,
                ForNuint
            };
            ConstantValue badConstant = ConstantValue.Bad;

            foreach (IValueSetFactory fac in ctors)
            {
                foreach (BinaryOperatorKind relation in new[] { LessThan, Equal, NotEqual })
                {
                    IValueSet set = fac.Related(relation, badConstant);
                    _ = set.All(relation, badConstant);
                    _ = set.Any(relation, badConstant);
                }
            }
        }
            private ValueDispatchNode GatherValueDispatchNodes(
                BoundDecisionDagNode node,
                HashSet <BoundDecisionDagNode> loweredNodes,
                BoundDagTemp input,
                IValueSetFactory fac)
            {
                if (loweredNodes.Contains(node))
                {
                    bool foundLabel = this._dagNodeLabels.TryGetValue(node, out LabelSymbol label);
                    Debug.Assert(foundLabel);
                    return(new ValueDispatchNode.LeafDispatchNode(node.Syntax, label));
                }
                if (!(node is BoundTestDecisionDagNode testNode && testNode.Test.Input.Equals(input)))
                {
                    var label = GetDagNodeLabel(node);
                    return(new ValueDispatchNode.LeafDispatchNode(node.Syntax, label));
                }

                switch (testNode.Test)
                {
                case BoundDagRelationalTest relational:
                {
                    loweredNodes.Add(testNode);
                    var whenTrue  = GatherValueDispatchNodes(testNode.WhenTrue, loweredNodes, input, fac);
                    var whenFalse = GatherValueDispatchNodes(testNode.WhenFalse, loweredNodes, input, fac);
                    return(ValueDispatchNode.RelationalDispatch.CreateBalanced(testNode.Syntax, relational.Value, relational.OperatorKind, whenTrue: whenTrue, whenFalse: whenFalse));
                }

                case BoundDagValueTest value:
                {
                    // Gather up the (value, label) pairs, starting with the first one
                    loweredNodes.Add(testNode);
                    var cases = ArrayBuilder <(ConstantValue value, LabelSymbol label)> .GetInstance();

                    cases.Add((value: value.Value, label: GetDagNodeLabel(testNode.WhenTrue)));
                    BoundTestDecisionDagNode previous = testNode;
                    while (previous.WhenFalse is BoundTestDecisionDagNode p &&
                           p.Test is BoundDagValueTest vd &&
                           vd.Input.Equals(input) &&
                           !this._dagNodeLabels.ContainsKey(p) &&
                           !loweredNodes.Contains(p))
                    {
                        cases.Add((value: vd.Value, label: GetDagNodeLabel(p.WhenTrue)));
                        loweredNodes.Add(p);
                        previous = p;
                    }

                    var otherwise = GatherValueDispatchNodes(previous.WhenFalse, loweredNodes, input, fac);
                    return(PushEqualityTestsIntoTree(value.Syntax, otherwise, cases.ToImmutableAndFree(), fac));
                }

                default:
                {
                    var label = GetDagNodeLabel(node);
                    return(new ValueDispatchNode.LeafDispatchNode(node.Syntax, label));
                }
                }
            }
            private ValueDispatchNode GatherValueDispatchNodes(
                BoundDecisionDagNode node,
                HashSet <BoundDecisionDagNode> loweredNodes,
                BoundDagTemp input)
            {
                IValueSetFactory fac = ValueSetFactory.ForType(input.Type);

                return(GatherValueDispatchNodes(node, loweredNodes, input, fac));
            }