public override BoundNode VisitIsOperator(BoundIsOperator node)
        {
            BoundExpression rewrittenOperand = VisitExpression(node.Operand);
            var rewrittenTargetType = (BoundTypeExpression)VisitTypeExpression(node.TargetType);
            TypeSymbol rewrittenType = VisitType(node.Type);

            return MakeIsOperator(node, node.Syntax, rewrittenOperand, rewrittenTargetType, node.Conversion, rewrittenType);
        }
        private BoundExpression VisitIsOperator(BoundIsOperator node)
        {
            var operand = node.Operand;
            if ((object)operand.Type == null && operand.ConstantValue != null && operand.ConstantValue.IsNull)
            {
                operand = _bound.Null(_objectType);
            }

            return ExprFactory("TypeIs", Visit(operand), _bound.Typeof(node.TargetType.Type));
        }
Esempio n. 3
0
 public override BoundNode VisitIsOperator(BoundIsOperator node)
 {
     BoundSpillSequence2 ss = null;
     var operand = VisitExpression(ref ss, node.Operand);
     return UpdateExpression(ss, node.Update(operand, node.TargetType, node.Conversion, node.Type));
 }
        private BoundExpression MakeIsOperator(
            BoundIsOperator oldNode,
            CSharpSyntaxNode syntax,
            BoundExpression rewrittenOperand,
            BoundTypeExpression rewrittenTargetType,
            Conversion conversion,
            TypeSymbol rewrittenType)
        {
            if (rewrittenOperand.Kind == BoundKind.MethodGroup)
            {
                var methodGroup = (BoundMethodGroup)rewrittenOperand;
                BoundExpression receiver = methodGroup.ReceiverOpt;
                if (receiver != null && receiver.Kind != BoundKind.ThisReference)
                {
                    // possible side-effect
                    return RewriteConstantIsOperator(receiver.Syntax, receiver, ConstantValue.False, rewrittenType);
                }
                else
                {
                    return MakeLiteral(syntax, ConstantValue.False, rewrittenType);
                }
            }

            var operandType = rewrittenOperand.Type;
            var targetType = rewrittenTargetType.Type;

            Debug.Assert((object)operandType != null || rewrittenOperand.ConstantValue.IsNull);
            Debug.Assert((object)targetType != null);

            // TODO: Handle dynamic operand type and target type

            if (!inExpressionLambda)
            {
                ConstantValue constantValue = Binder.GetIsOperatorConstantResult(operandType, targetType, conversion.Kind, rewrittenOperand.ConstantValue);

                if (constantValue != null)
                {
                    return RewriteConstantIsOperator(syntax, rewrittenOperand, constantValue, rewrittenType);
                }
                else if (conversion.IsImplicit)
                {
                    // operand is a reference type with bound identity or implicit conversion
                    // We can replace the "is" instruction with a null check

                    Debug.Assert((object)operandType != null);
                    if (operandType.TypeKind == TypeKind.TypeParameter)
                    {
                        // We need to box the type parameter even if it is a known
                        // reference type to ensure there are no verifier errors
                        rewrittenOperand = MakeConversion(
                            syntax: rewrittenOperand.Syntax,
                            rewrittenOperand: rewrittenOperand,
                            conversionKind: ConversionKind.Boxing,
                            rewrittenType: compilation.GetSpecialType(SpecialType.System_Object),
                            @checked: false);
                    }

                    return MakeNullCheck(syntax, rewrittenOperand, BinaryOperatorKind.NotEqual);
                }
            }

            return oldNode.Update(rewrittenOperand, rewrittenTargetType, conversion, rewrittenType);
        }
        public override BoundNode VisitIsOperator(BoundIsOperator node)
        {
            BoundExpression operand = (BoundExpression)this.Visit(node.Operand);
            BoundTypeExpression targetType = (BoundTypeExpression)this.Visit(node.TargetType);
            TypeSymbol type = this.VisitType(node.Type);

            if (operand.Kind != BoundKind.SpillSequence)
            {
                return node.Update(operand, targetType, node.Conversion, type);
            }

            var spill = (BoundSpillSequence)operand;
            var newIsOperator = node.Update(spill.Value, targetType, node.Conversion, type);
            return RewriteSpillSequence(spill, newIsOperator);
        }