Permalink
Switch branches/tags
version-2.9.0 version-2.8.2 version-2.8.0 version-2.7.0-beta3 version-2.6.0-beta3 version-2.4.0 version-2.3.5 version-2.3.4 version-2.3.2 version-2.3.2-beta1 version-2.3.0-beta3 version-2.3.0-beta2 version-2.3.0-beta1 version-2.2.0 version-2.1.0 version-2.0.0 version-2.0.0-rc4 version-2.0.0-rc3 version-2.0.0-rc2 version-2.0.0-rc version-2.0.0-beta5 version-2.0.0-beta4 version-2.0.0-beta3 version-2.0.0-beta1 version-1.3.2 version-1.3.1 version-1.3.0 version-1.3.0-beta1-20160429-01 version-1.2.2 version-1.2.1 version-1.2.0 version-1.2.0-beta1-20160108-01 version-1.2.0-beta version-1.2.0-beta-20151211-01 version-1.1.1 version-1.1.0 version-1.1.0-rc1-20151109-01 version-1.0.0 version-1.0.0-beta1-20141031-01 toolset_5 toolset_3 toolset_2 toolset_1_1 toolset_1 Visual.Studio.2015.Update.1.RC Visual.Studio.2015.Update.1.CTP Visual-Studio-2017 Visual-Studio-2017-Version-15.8 Visual-Studio-2017-Version-15.7.2 Visual-Studio-2017-Version-15.7 Visual-Studio-2017-Version-15.6 Visual-Studio-2017-Version-15.5 Visual-Studio-2017-Version-15.4 Visual-Studio-2017-Version-15.3.5 Visual-Studio-2017-Version-15.3.4 Visual-Studio-2017-Version-15.3.2 Visual-Studio-2017-Version-15.3 Visual-Studio-2017-Version-15.2 Visual-Studio-2017-Version-15.1 Visual-Studio-2017-RC4 Visual-Studio-2017-RC3 Visual-Studio-2017-RC2 Visual-Studio-2017-RC Visual-Studio-2017-Preview-Version-15.3 Visual-Studio-2017-Preview-6-Version-15.7 Visual-Studio-2017-Preview-3-Version-15.4 Visual-Studio-2017-Preview-3-Version-15.3 Visual-Studio-2017-Preview-2-Version-15.4 Visual-Studio-2017-Preview-2-Version-15.3 Visual-Studio-2017-Preview-1-Version-15.4 Visual-Studio-2015 Visual-Studio-2015-Update-3 Visual-Studio-2015-Update-3-Micro-Update-1 Visual-Studio-2015-Update-2 Visual-Studio-2015-Update-2-RC Visual-Studio-2015-Update-2-Micro-Update-3 Visual-Studio-2015-Update-2-Micro-Update-1 Visual-Studio-2015-Update-1 Visual-Studio-2015-Update-1-RC Visual-Studio-2015-Update-1-CTP Visual-Studio-2015-RC Visual-Studio-2015-Preview Visual-Studio-2015-CTP-6 Visual-Studio-2015-CTP-5 Visual-Studio-15-Preview Visual-Studio-15-Preview-5 Visual-Studio-15-Preview-4 Visual-Studio-15-Preview-3 VS.Toolset.Roslyn.1.1.0-beta1-20150727-01 VS.Tools.X86.Managed.V45.1.0.150513.2 Oss.Scan.2015.03.13 Oss.Scan.2013.03.13 NetFx.Toolset.150729
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
104 lines (89 sloc) 4.38 KB
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.CSharp
{
internal sealed partial class LocalRewriter
{
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 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);
}
private BoundExpression RewriteConstantIsOperator(
SyntaxNode syntax,
BoundExpression loweredOperand,
ConstantValue constantValue,
TypeSymbol type)
{
Debug.Assert(constantValue == ConstantValue.True || constantValue == ConstantValue.False);
Debug.Assert((object)type != null);
return new BoundSequence(
syntax: syntax,
locals: ImmutableArray<LocalSymbol>.Empty,
sideEffects: ImmutableArray.Create<BoundExpression>(loweredOperand),
value: MakeLiteral(syntax, constantValue, type),
type: type);
}
}
}