예제 #1
0
        public override BoundNode VisitIsPatternExpression(BoundIsPatternExpression node)
        {
            var loweredExpression = VisitExpression(node.Expression);
            var loweredPattern    = LowerPattern(node.Pattern);

            return(MakeIsPattern(loweredPattern, loweredExpression));
        }
예제 #2
0
        public override BoundNode VisitIsPatternExpression(BoundIsPatternExpression node)
        {
            var expression = VisitExpression(node.Expression);
            var result     = LowerPattern(node.Pattern, expression);

            return(result);
        }
 public override BoundNode VisitIsPatternExpression(BoundIsPatternExpression node)
 {
     if (canProduceLinearSequence(node.DecisionDag.RootNode, whenTrueLabel: node.WhenTrueLabel, whenFalseLabel: node.WhenFalseLabel))
     {
         // If we can build a linear test sequence `(e1 && e2 && e3)` for the dag, do so.
         var             isPatternRewriter = new IsPatternExpressionLinearLocalRewriter(node, this);
         BoundExpression result            = isPatternRewriter.LowerIsPatternAsLinearTestSequence(node, whenTrueLabel: node.WhenTrueLabel, whenFalseLabel: node.WhenFalseLabel);
         isPatternRewriter.Free();
         return(result);
     }
     else if (canProduceLinearSequence(node.DecisionDag.RootNode, whenTrueLabel: node.WhenFalseLabel, whenFalseLabel: node.WhenTrueLabel))
     {
         // If we can build a linear test sequence with the whenTrue and whenFalse labels swapped, then negate the
         // result.  This would typically arise when the source contains `e is not pattern`.
         var             isPatternRewriter = new IsPatternExpressionLinearLocalRewriter(node, this);
         BoundExpression result            = isPatternRewriter.LowerIsPatternAsLinearTestSequence(node, whenTrueLabel: node.WhenFalseLabel, whenFalseLabel: node.WhenTrueLabel);
         result = this._factory.Not(result);
         isPatternRewriter.Free();
         return(result);
     }
     else
     {
         // We need to lower a generalized dag, so we produce a label for the true and false branches and assign to a temporary containing the result.
         var             isPatternRewriter = new IsPatternExpressionGeneralLocalRewriter(node.Syntax, this);
         BoundExpression result            = isPatternRewriter.LowerGeneralIsPattern(node);
         isPatternRewriter.Free();
         return(result);
     }
예제 #4
0
        public override BoundNode VisitIsPatternExpression(BoundIsPatternExpression node)
        {
            var             isPatternRewriter = new IsPatternExpressionLocalRewriter(node.Syntax, this);
            BoundExpression result            = isPatternRewriter.LowerIsPattern(node, node.Pattern, this._compilation, this._diagnostics);

            isPatternRewriter.Free();
            return(result);
        }
예제 #5
0
        public override BoundNode VisitIsPatternExpression(BoundIsPatternExpression node)
        {
            if (_inExpressionLambda)
            {
                Error(ErrorCode.ERR_ExpressionTreeContainsIsMatch, node);
            }

            return(base.VisitIsPatternExpression(node));
        }
            internal BoundExpression LowerGeneralIsPattern(BoundIsPatternExpression node)
            {
                _factory.Syntax = node.Syntax;
                var resultBuilder = ArrayBuilder <BoundStatement> .GetInstance();

                var inputExpression          = _localRewriter.VisitExpression(node.Expression);
                BoundDecisionDag decisionDag = ShareTempsIfPossibleAndEvaluateInput(
                    node.DecisionDag, inputExpression, resultBuilder, out _);

                // lower the decision dag.
                ImmutableArray <BoundStatement> loweredDag = LowerDecisionDagCore(decisionDag);

                resultBuilder.Add(_factory.Block(loweredDag));
                Debug.Assert(node.Type is { SpecialType: SpecialType.System_Boolean });
예제 #7
0
            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;
                        }