public override BoundNode VisitIsOperator(BoundIsOperator node) { BoundSpillSequenceBuilder builder = null; var operand = VisitExpression(ref builder, node.Operand); return(UpdateExpression(builder, node.Update(operand, node.TargetType, node.Conversion, node.Type))); }
private BoundExpression MakeIsOperator( BoundIsOperator oldNode, SyntaxNode 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(operandType is { } || rewrittenOperand.ConstantValue !.IsNull);
internal void Parse(BoundIsOperator boundIsOperator) { base.Parse(boundIsOperator); this.ConversionKind = boundIsOperator.Conversion.Kind; this.TargetType = Deserialize(boundIsOperator.TargetType) as TypeExpression; this.Operand = Deserialize(boundIsOperator.Operand) as Expression; }
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))); }
private BoundExpression MakeIsOperator( BoundIsOperator oldNode, SyntaxNode 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 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)); }
public override BoundNode VisitIsOperator(BoundIsOperator node) { // rewrite is needed only for cases where there are no errors and // no warnings (i.e. non-constant result) generated during binding if (!node.HasErrors && node.ConstantValue == null) { BoundExpression operand = node.Operand; var targetType = node.TargetType.Type; var operandType = operand.Type; Debug.Assert(operandType != null); if (operandType.IsNullableType()) { //TODO: handle nullable types once nullable conversions are implemented } else if (!operandType.IsValueType) { if (operandType.IsSameType(targetType)) { // operand with bound identity or implicit conversion // We can replace the "is" instruction with a null check Visit(operand); 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 operand = new BoundConversion(operand.Syntax, operand.SyntaxTree, operand, ConversionKind.Boxing, this.containingSymbol, false, false, null, compilation.GetSpecialType(SpecialType.System_Object)); } return(new BoundBinaryOperator(node.Syntax, node.SyntaxTree, BinaryOperatorKind.NotEqual, operand, new BoundLiteral(null, null, ConstantValue.Null, null), null, node.Type)); } } } return(base.VisitIsOperator(node)); }
public override BoundNode VisitIsOperator(BoundIsOperator node) { // rewrite is needed only for cases where there are no errors and // no warnings (i.e. non-constant result) generated during binding if (!node.HasErrors && node.ConstantValue == null) { BoundExpression operand = node.Operand; var targetType = node.TargetType.Type; var operandType = operand.Type; Debug.Assert(operandType != null); if (operandType.IsNullableType()) { //TODO: handle nullable types once nullable conversions are implemented } else if (!operandType.IsValueType) { if (operandType.IsSameType(targetType)) { // operand with bound identity or implicit conversion // We can replace the "is" instruction with a null check Visit(operand); 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 operand = new BoundConversion(operand.Syntax, operand.SyntaxTree, operand, ConversionKind.Boxing, this.containingSymbol, false, false, null, compilation.GetSpecialType(SpecialType.System_Object)); } return new BoundBinaryOperator(node.Syntax, node.SyntaxTree, BinaryOperatorKind.NotEqual, operand, new BoundLiteral(null, null, ConstantValue.Null, null), null, node.Type); } } } return base.VisitIsOperator(node); }
private void EmitIsExpression(BoundIsOperator isOp, bool used) { var operand = isOp.Operand; EmitExpression(operand, used); if (used) { Debug.Assert((object)operand.Type != null); if (!operand.Type.IsVerifierReference()) { // box the operand for isinst if it is not a verifier reference EmitBox(operand.Type, operand.Syntax); } _builder.EmitOpCode(ILOpCode.Isinst); EmitSymbolToken(isOp.TargetType.Type, isOp.Syntax); _builder.EmitOpCode(ILOpCode.Ldnull); _builder.EmitOpCode(ILOpCode.Cgt_un); } }
private BoundExpression MakeIsOperator( BoundIsOperator oldNode, SyntaxNode 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 = MakeConversionNode( syntax: rewrittenOperand.Syntax, rewrittenOperand: rewrittenOperand, conversion: Conversion.Boxing, rewrittenType: _compilation.GetSpecialType(SpecialType.System_Object), @checked: false); } return(MakeNullCheck(syntax, rewrittenOperand, BinaryOperatorKind.NotEqual)); } } return(oldNode.Update(rewrittenOperand, rewrittenTargetType, conversion, rewrittenType)); }
public override object VisitIsOperator(BoundIsOperator node, object arg) { VisitExpression(node.Operand); return(null); }