diff --git a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs index 8b7c8788ce7684073dc7e855e7eaaee5afe9c30b..83040adddda2b381e4df1effe371780998ecc962 100644 --- a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs +++ b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs @@ -715,9 +715,10 @@ private IIsTypeExpression CreateBoundIsOperatorOperation(BoundIsOperator boundIs ITypeSymbol isType = boundIsOperator.TargetType.Type; SyntaxNode syntax = boundIsOperator.Syntax; ITypeSymbol type = boundIsOperator.Type; + bool isNotTypeExpression = false; Optional constantValue = ConvertToOptional(boundIsOperator.ConstantValue); bool isImplicit = boundIsOperator.WasCompilerGenerated; - return new LazyIsTypeExpression(operand, isType, _semanticModel, syntax, type, constantValue, isImplicit); + return new LazyIsTypeExpression(operand, isType, isNotTypeExpression, _semanticModel, syntax, type, constantValue, isImplicit); } private ISizeOfExpression CreateBoundSizeOfOperatorOperation(BoundSizeOfOperator boundSizeOfOperator) diff --git a/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IIsTypeExpression.cs b/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IIsTypeExpression.cs new file mode 100644 index 0000000000000000000000000000000000000000..01574225c1d8e6eaec1ab2d3b1f518786eb31b65 --- /dev/null +++ b/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IIsTypeExpression.cs @@ -0,0 +1,287 @@ +// 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 Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Test.Utilities; +using Xunit; + +namespace Microsoft.CodeAnalysis.CSharp.UnitTests +{ + public partial class IOperationTests : SemanticModelTestBase + { + [CompilerTrait(CompilerFeature.IOperation)] + [Fact] + public void TestIsOperator_ObjectExpressionStringType() + { + string source = @" +namespace TestIsOperator +{ + class TestType + { + } + + class C + { + static void M(string myStr) + { + object o = myStr; + bool b = /**/o is string/**/; + } + } +} +"; + string expectedOperationTree = @" +IIsTypeExpression (OperationKind.IsTypeExpression, Type: System.Boolean) (Syntax: 'o is string') + Operand: ILocalReferenceExpression: o (OperationKind.LocalReferenceExpression, Type: System.Object) (Syntax: 'o') + IsType: System.String +"; + var expectedDiagnostics = DiagnosticDescription.None; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } + + [CompilerTrait(CompilerFeature.IOperation)] + [Fact] + public void TestIsOperator_IntExpressionIntType() + { + string source = @" +namespace TestIsOperator +{ + class TestType + { + } + + class C + { + static void M(string myStr) + { + int myInt = 3; + bool b = /**/myInt is int/**/; + } + } +} +"; + string expectedOperationTree = @" +IIsTypeExpression (OperationKind.IsTypeExpression, Type: System.Boolean) (Syntax: 'myInt is int') + Operand: ILocalReferenceExpression: myInt (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'myInt') + IsType: System.Int32 +"; + var expectedDiagnostics = new DiagnosticDescription[] { + // CS0183: The given expression is always of the provided ('int') type + // bool b = /**/myInt is int/**/; + Diagnostic(ErrorCode.WRN_IsAlwaysTrue, "myInt is int").WithArguments("int").WithLocation(13, 32) + }; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } + + [CompilerTrait(CompilerFeature.IOperation)] + [Fact] + public void TestIsOperator_ObjectExpressionUserDefinedType() + { + string source = @" +namespace TestIsOperator +{ + class TestType + { + } + + class C + { + static void M(string myStr) + { + TestType tt = null; + object o = tt; + bool b = /**/o is TestType/**/; + } + } +} +"; + string expectedOperationTree = @" +IIsTypeExpression (OperationKind.IsTypeExpression, Type: System.Boolean) (Syntax: 'o is TestType') + Operand: ILocalReferenceExpression: o (OperationKind.LocalReferenceExpression, Type: System.Object) (Syntax: 'o') + IsType: TestIsOperator.TestType +"; + var expectedDiagnostics = DiagnosticDescription.None; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } + + [CompilerTrait(CompilerFeature.IOperation)] + [Fact] + public void TestIsOperator_NullExpressionUserDefinedType() + { + string source = @" +namespace TestIsOperator +{ + class TestType + { + } + + class C + { + static void M(string myStr) + { + TestType tt = null; + object o = tt; + bool b = /**/null is TestType/**/; + } + } +} +"; + string expectedOperationTree = @" +IIsTypeExpression (OperationKind.IsTypeExpression, Type: System.Boolean) (Syntax: 'null is TestType') + Operand: ILiteralExpression (OperationKind.LiteralExpression, Type: null, Constant: null) (Syntax: 'null') + IsType: TestIsOperator.TestType +"; + var expectedDiagnostics = new DiagnosticDescription[] { + // CS0184: The given expression is never of the provided ('TestType') type + // bool b = /**/null is TestType/**/; + Diagnostic(ErrorCode.WRN_IsAlwaysFalse, "null is TestType").WithArguments("TestIsOperator.TestType").WithLocation(14, 32) + }; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } + + [CompilerTrait(CompilerFeature.IOperation)] + [Fact] + public void TestIsOperator_IntExpressionEnumType() + { + string source = @" +class IsTest +{ + static void Main() + { + var b = /**/1 is color/**/; + System.Console.WriteLine(b); + } +} +enum color +{ } +"; + string expectedOperationTree = @" +IIsTypeExpression (OperationKind.IsTypeExpression, Type: System.Boolean) (Syntax: '1 is color') + Operand: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1') + IsType: color +"; + var expectedDiagnostics = new DiagnosticDescription[] { + // CS0184: The given expression is never of the provided ('color') type + // var b = /**/1 is color/**/; + Diagnostic(ErrorCode.WRN_IsAlwaysFalse, "1 is color").WithArguments("color").WithLocation(6, 27) + }; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } + + [CompilerTrait(CompilerFeature.IOperation)] + [Fact] + public void TestIsOperatorGeneric_TypeParameterExpressionIntType() + { + string source = @" +namespace TestIsOperatorGeneric +{ + class C + { + public static void M(T t, U u) + where T : class + where U : class + { + bool test = /**/t is int/**/; + } + } +} +"; + string expectedOperationTree = @" +IIsTypeExpression (OperationKind.IsTypeExpression, Type: System.Boolean) (Syntax: 't is int') + Operand: IParameterReferenceExpression: t (OperationKind.ParameterReferenceExpression, Type: T) (Syntax: 't') + IsType: System.Int32 +"; + var expectedDiagnostics = DiagnosticDescription.None; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } + + [CompilerTrait(CompilerFeature.IOperation)] + [Fact] + public void TestIsOperatorGeneric_TypeParameterExpressionObjectType() + { + string source = @" +namespace TestIsOperatorGeneric +{ + class C + { + public static void M(T t, U u) + where T : class + where U : class + { + bool test = /**/u is object/**/; + } + } +} +"; + string expectedOperationTree = @" +IIsTypeExpression (OperationKind.IsTypeExpression, Type: System.Boolean) (Syntax: 'u is object') + Operand: IParameterReferenceExpression: u (OperationKind.ParameterReferenceExpression, Type: U) (Syntax: 'u') + IsType: System.Object +"; + var expectedDiagnostics = DiagnosticDescription.None; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } + + [CompilerTrait(CompilerFeature.IOperation)] + [Fact] + public void TestIsOperatorGeneric_TypeParameterExpressionDifferentTypeParameterType() + { + string source = @" +namespace TestIsOperatorGeneric +{ + class C + { + public static void M(T t, U u) + where T : class + where U : class + { + bool test = /**/t is U/**/; + } + } +} +"; + string expectedOperationTree = @" +IIsTypeExpression (OperationKind.IsTypeExpression, Type: System.Boolean) (Syntax: 't is U') + Operand: IParameterReferenceExpression: t (OperationKind.ParameterReferenceExpression, Type: T) (Syntax: 't') + IsType: U +"; + var expectedDiagnostics = DiagnosticDescription.None; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } + + [CompilerTrait(CompilerFeature.IOperation)] + [Fact] + public void TestIsOperatorGeneric_TypeParameterExpressionSameTypeParameterType() + { + string source = @" +namespace TestIsOperatorGeneric +{ + class C + { + public static void M(T t, U u) + where T : class + where U : class + { + bool test = /**/t is T/**/; + } + } +} +"; + string expectedOperationTree = @" +IIsTypeExpression (OperationKind.IsTypeExpression, Type: System.Boolean) (Syntax: 't is T') + Operand: IParameterReferenceExpression: t (OperationKind.ParameterReferenceExpression, Type: T) (Syntax: 't') + IsType: T +"; + var expectedDiagnostics = DiagnosticDescription.None; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } + } +} diff --git a/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IWhileUntilLoopStatement.cs b/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IWhileUntilLoopStatement.cs index 5df0e1aaf0c434d7a43f9c2d6ca7ebfd3485b716..4092f7316f31b83f00698b97267c6e7129c58da8 100644 --- a/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IWhileUntilLoopStatement.cs +++ b/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IWhileUntilLoopStatement.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +// 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 Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Test.Utilities; diff --git a/src/Compilers/Core/Portable/Generated/Operations.xml.Generated.cs b/src/Compilers/Core/Portable/Generated/Operations.xml.Generated.cs index b7b9ed291a46230a750e55e54cbb3c41cd39e9b7..1bd554fc98b91bbe49cc728a35c6082ea6486316 100644 --- a/src/Compilers/Core/Portable/Generated/Operations.xml.Generated.cs +++ b/src/Compilers/Core/Portable/Generated/Operations.xml.Generated.cs @@ -2553,10 +2553,11 @@ public LazyInvocationExpression(IMethodSymbol targetMethod, Lazy ins /// internal abstract partial class BaseIsTypeExpression : Operation, IIsTypeExpression { - protected BaseIsTypeExpression(ITypeSymbol isType, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + protected BaseIsTypeExpression(ITypeSymbol isType, bool isNotTypeExpression, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(OperationKind.IsTypeExpression, semanticModel, syntax, type, constantValue, isImplicit) { IsType = isType; + IsNotTypeExpression = isNotTypeExpression; } protected abstract IOperation OperandImpl { get; } @@ -2564,6 +2565,12 @@ internal abstract partial class BaseIsTypeExpression : Operation, IIsTypeExpress /// Type for which to test. /// public ITypeSymbol IsType { get; } + /// + /// Flag indicating if this is an "is not" type expression. + /// True for VB "TypeOf ... IsNot ..." expression. + /// False, otherwise. + /// + public bool IsNotTypeExpression { get; } public override IEnumerable Children { get @@ -2590,8 +2597,8 @@ public override void Accept(OperationVisitor visitor) /// internal sealed partial class IsTypeExpression : BaseIsTypeExpression, IIsTypeExpression { - public IsTypeExpression(IOperation operand, ITypeSymbol isType, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : - base(isType, semanticModel, syntax, type, constantValue, isImplicit) + public IsTypeExpression(IOperation operand, ITypeSymbol isType, bool isNotTypeExpression, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + base(isType, isNotTypeExpression, semanticModel, syntax, type, constantValue, isImplicit) { OperandImpl = operand; } @@ -2606,7 +2613,7 @@ internal sealed partial class LazyIsTypeExpression : BaseIsTypeExpression, IIsTy { private readonly Lazy _lazyOperand; - public LazyIsTypeExpression(Lazy operand, ITypeSymbol isType, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(isType, semanticModel, syntax, type, constantValue, isImplicit) + public LazyIsTypeExpression(Lazy operand, ITypeSymbol isType, bool isNotTypeExpression, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(isType, isNotTypeExpression, semanticModel, syntax, type, constantValue, isImplicit) { _lazyOperand = operand ?? throw new System.ArgumentNullException(nameof(operand)); } diff --git a/src/Compilers/Core/Portable/Operations/IIsTypeExpression.cs b/src/Compilers/Core/Portable/Operations/IIsTypeExpression.cs index b06f159c9ff383c16ac9f3aee7b2048dd7e172fc..89cdd50ddb7fe7091c453651432059a7b75f2650 100644 --- a/src/Compilers/Core/Portable/Operations/IIsTypeExpression.cs +++ b/src/Compilers/Core/Portable/Operations/IIsTypeExpression.cs @@ -1,7 +1,5 @@ // 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; - namespace Microsoft.CodeAnalysis.Semantics { /// @@ -17,10 +15,17 @@ public interface IIsTypeExpression : IOperation /// Value to test. /// IOperation Operand { get; } + /// /// Type for which to test. /// ITypeSymbol IsType { get; } + + /// + /// Flag indicating if this is an "is not" type expression. + /// True for VB "TypeOf ... IsNot ..." expression. + /// False, otherwise. + /// + bool IsNotTypeExpression { get; } } } - diff --git a/src/Compilers/Core/Portable/Operations/OperationCloner.cs b/src/Compilers/Core/Portable/Operations/OperationCloner.cs index fc33e539db6bceee72684bc0232ad86523f09637..5456a93835a7d455740edc52d79b2a33f34c1d76 100644 --- a/src/Compilers/Core/Portable/Operations/OperationCloner.cs +++ b/src/Compilers/Core/Portable/Operations/OperationCloner.cs @@ -276,7 +276,7 @@ public override IOperation VisitCoalesceExpression(ICoalesceExpression operation public override IOperation VisitIsTypeExpression(IIsTypeExpression operation, object argument) { - return new IsTypeExpression(Visit(operation.Operand), operation.IsType, ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit); + return new IsTypeExpression(Visit(operation.Operand), operation.IsType, operation.IsNotTypeExpression, ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit); } public override IOperation VisitSizeOfExpression(ISizeOfExpression operation, object argument) diff --git a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt index 879fe82df108da14e9de1c11b0ffb196a5fbf085..8b65a558ebc1cd3fce989e13055a315ba03d3b6d 100644 --- a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt @@ -344,6 +344,7 @@ Microsoft.CodeAnalysis.Semantics.IIsPatternExpression.Expression.get -> Microsof Microsoft.CodeAnalysis.Semantics.IIsPatternExpression.Pattern.get -> Microsoft.CodeAnalysis.Semantics.IPattern Microsoft.CodeAnalysis.Semantics.IIsTypeExpression Microsoft.CodeAnalysis.Semantics.IIsTypeExpression.IsType.get -> Microsoft.CodeAnalysis.ITypeSymbol +Microsoft.CodeAnalysis.Semantics.IIsTypeExpression.IsNotTypeExpression.get -> bool Microsoft.CodeAnalysis.Semantics.IIsTypeExpression.Operand.get -> Microsoft.CodeAnalysis.IOperation Microsoft.CodeAnalysis.Semantics.ILabeledStatement Microsoft.CodeAnalysis.Semantics.ILabeledStatement.Label.get -> Microsoft.CodeAnalysis.ILabelSymbol diff --git a/src/Compilers/VisualBasic/Portable/Operations/VisualBasicOperationFactory.vb b/src/Compilers/VisualBasic/Portable/Operations/VisualBasicOperationFactory.vb index 8ef0b35f89787c5b308291360eefd395f9158990..390da1d149203b3c09893bd8e876db48c681d450 100644 --- a/src/Compilers/VisualBasic/Portable/Operations/VisualBasicOperationFactory.vb +++ b/src/Compilers/VisualBasic/Portable/Operations/VisualBasicOperationFactory.vb @@ -565,11 +565,12 @@ Namespace Microsoft.CodeAnalysis.Semantics Private Function CreateBoundTypeOfOperation(boundTypeOf As BoundTypeOf) As IIsTypeExpression Dim operand As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundTypeOf.Operand)) Dim isType As ITypeSymbol = boundTypeOf.TargetType + Dim isNotTypeExpression As Boolean = boundTypeOf.IsTypeOfIsNotExpression Dim syntax As SyntaxNode = boundTypeOf.Syntax Dim type As ITypeSymbol = boundTypeOf.Type Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundTypeOf.ConstantValueOpt) Dim isImplicit As Boolean = boundTypeOf.WasCompilerGenerated - Return New LazyIsTypeExpression(operand, isType, _semanticModel, syntax, type, constantValue, isImplicit) + Return New LazyIsTypeExpression(operand, isType, isNotTypeExpression, _semanticModel, syntax, type, constantValue, isImplicit) End Function Private Function CreateBoundObjectCreationExpressionOperation(boundObjectCreationExpression As BoundObjectCreationExpression) As IObjectCreationExpression diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/TypeOfTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/TypeOfTests.vb index 7f00618a1ffe68151ba73052997dce7b25eb2270..b9881248e6ecfb20cdea432614093555defd227a 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/TypeOfTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/TypeOfTests.vb @@ -1,21 +1,18 @@ -' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. Imports System.Collections.Immutable -Imports Microsoft.CodeAnalysis.Text -Imports Microsoft.CodeAnalysis.VisualBasic.Symbols +Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports Roslyn.Test.Utilities -Imports VB = Microsoft.CodeAnalysis.VisualBasic Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.Semantics Public Class TypeOfTests Inherits BasicTestBase + - Public Sub ProducesNoErrorsOnBoxedValueTypes() - Dim source = - - + Public Sub ProducesNoErrorsOnBoxedValueTypes_ObjectExpressionAndPrimitiveType() + Dim source = .Value + + Dim expectedOperationTree = .Value + + Dim expectedDiagnostics = String.Empty + + VerifyOperationTreeAndDiagnosticsForTest(Of TypeOfExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) + End Sub + + + + Public Sub ProducesNoErrorsOnBoxedValueTypes_ObjectExpressionAndIComparableType() + Dim source = .Value + + Dim expectedOperationTree = .Value + + Dim expectedDiagnostics = String.Empty + + VerifyOperationTreeAndDiagnosticsForTest(Of TypeOfExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) + End Sub + + + + Public Sub ProducesNoErrorsOnBoxedValueTypes_ValueTypeExpressionAndEnumType() + Dim source = .Value + + Dim expectedOperationTree = .Value + + Dim expectedDiagnostics = String.Empty + + VerifyOperationTreeAndDiagnosticsForTest(Of TypeOfExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) + End Sub + + + + Public Sub ProducesNoErrorsOnBoxedValueTypes_EnumTypeExpressionAndEnumType() + Dim source = - +End Module]]>.Value - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime(source) - CompilationUtils.AssertNoErrors(compilation) + Dim expectedOperationTree = .Value + + Dim expectedDiagnostics = String.Empty + + VerifyOperationTreeAndDiagnosticsForTest(Of TypeOfExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub + - Public Sub ProducesNoErrorsWithClassTypeUnconstrainedTypeParameterTargetTypes() - Dim source = - - + Public Sub ProducesNoErrorsWithClassTypeUnconstrainedTypeParameterTargetTypes_ClassConstraint() + Dim source = .Value + + Dim expectedOperationTree = .Value + + Dim expectedDiagnostics = String.Empty + + VerifyOperationTreeAndDiagnosticsForTest(Of TypeOfExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) + End Sub + + + + Public Sub ProducesNoErrorsWithClassTypeUnconstrainedTypeParameterTargetTypes_StructureConstraint() + Dim source = .Value + + Dim expectedOperationTree = .Value + + Dim expectedDiagnostics = String.Empty + + VerifyOperationTreeAndDiagnosticsForTest(Of TypeOfExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) + End Sub + + + + Public Sub ProducesNoErrorsWithClassTypeUnconstrainedTypeParameterTargetTypes_StructureAndClassConstraint() + Dim source = .Value + + Dim expectedOperationTree = .Value + + Dim expectedDiagnostics = String.Empty + + VerifyOperationTreeAndDiagnosticsForTest(Of TypeOfExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) + End Sub + + + + Public Sub ProducesNoErrorsWithClassTypeUnconstrainedTypeParameterTargetTypes_StringType() + Dim source = - +End Module]]>.Value - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime(source) - CompilationUtils.AssertNoErrors(compilation) + Dim expectedOperationTree = .Value + + Dim expectedDiagnostics = String.Empty + + VerifyOperationTreeAndDiagnosticsForTest(Of TypeOfExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub + - Public Sub ProducesErrorsWhenNoReferenceConversionExists() - Dim source = - - + Public Sub ProducesErrorsWhenNoReferenceConversionExists_BC30371() + Dim source = .Value + + Dim expectedOperationTree = .Value + + Dim expectedDiagnostics = .Value + + VerifyOperationTreeAndDiagnosticsForTest(Of TypeOfExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) + End Sub + + + + Public Sub ProducesErrorsWhenNoReferenceConversionExists_BC31430() + Dim source = .Value - If TypeOf s Is Integer Then + Dim expectedOperationTree = .Value + + Dim expectedDiagnostics = .Value + + VerifyOperationTreeAndDiagnosticsForTest(Of TypeOfExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) + End Sub + + + + Public Sub ProducesErrorsWhenNoReferenceConversionExists_BC31430_02() + Dim source = .Value + + Dim expectedOperationTree = .Value + + Dim expectedDiagnostics = .Value + + VerifyOperationTreeAndDiagnosticsForTest(Of TypeOfExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) + End Sub + + + + Public Sub ProducesErrorsWhenNoReferenceConversionExists_BC30021() + Dim source = - +End Module]]>.Value - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntimeAndReferences(source, , TestOptions.ReleaseExe) - CompilationUtils.AssertTheseDiagnostics(compilation, - -BC30371: Module 'Program' cannot be used as a type. - If TypeOf obj Is Program Then - ~~~~~~~ -BC31430: Expression of type 'String' can never be of type 'AppDomain'. - If TypeOf s Is AppDomain Then - ~~~~~~~~~~~~~~~~~~~~~ -BC31430: Expression of type 'String' can never be of type 'Integer'. - If TypeOf s Is Integer Then - ~~~~~~~~~~~~~~~~~~~ + Dim expectedOperationTree = .Value + + Dim expectedDiagnostics = ) +]]>.Value + + VerifyOperationTreeAndDiagnosticsForTest(Of TypeOfExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub @@ -167,49 +417,49 @@ BC30021: 'TypeOf ... Is' requires its left operand to have a reference type, but Option Strict On Imports System Module Program - + Sub Main() End Sub - + Class A : End Class Class B : End Class - + Sub M(Of T, TA As A, TB As B, TC As Structure, TD As IDisposable)(x As T, a As TA, b As TB, c As TC, d As TD, s As String) - + If TypeOf x Is TA OrElse TypeOf x Is TB OrElse TypeOf x Is TC OrElse TypeOf x Is TD OrElse TypeOf x Is String Then Console.WriteLine("Success!") End If - + If TypeOf a Is TB OrElse TypeOf a Is TC OrElse TypeOf a Is String Then Console.WriteLine("Fail!") ElseIf TypeOf a Is T OrElse TypeOf a Is TD Then Console.WriteLine("Success!") End If - + If TypeOf b Is TA OrElse TypeOf b Is TC OrElse TypeOf b Is String Then Console.WriteLine("Fail!") ElseIf TypeOf b Is T OrElse TypeOf b Is TD Then Console.WriteLine("Success!") End If - + If TypeOf c Is TA OrElse TypeOf c Is TB OrElse TypeOf c Is String Then Console.WriteLine("Fail!") ElseIf TypeOf c Is T OrElse TypeOf c Is TD Then Console.WriteLine("Success!") End If - + If TypeOf d Is T OrElse TypeOf d Is TA OrElse TypeOf d Is TB OrElse TypeOf d Is TC OrElse TypeOf d Is String Then Console.WriteLine("Success!") End If - + If TypeOf s Is TA OrElse TypeOf s Is TB OrElse TypeOf s Is TC Then Console.WriteLine("Fail!") ElseIf TypeOf s Is T OrElse TypeOf s Is T OrElse TypeOf s Is TD Then Console.WriteLine("Success!") End If - + End Sub - + End Module @@ -262,28 +512,28 @@ BC31430: Expression of type 'String' can never be of type 'TC'. Option Strict On - + Imports HRESULT = System.Int32 Imports CharacterSequence = System.String - + Module Program Sub Main(args As String()) - + Dim o As Object = "" - + Dim isString = TypeOf o Is CharacterSequence - + Dim isInteger = TypeOf o Is HRESULT - + Dim isNotString = TypeOf o IsNot CharacterSequence - + Dim isNotInteger = TypeOf o IsNot HRESULT - + System.Console.WriteLine(isString) System.Console.WriteLine(isInteger) System.Console.WriteLine(isNotString) System.Console.WriteLine(isNotInteger) - + End Sub End Module @@ -302,6 +552,125 @@ True End Sub + + + Public Sub SeesThroughTypeAndNamespaceAliases_IsStringAliasIOperationTest() + Dim source = .Value + + Dim expectedOperationTree = .Value + + Dim expectedDiagnostics = String.Empty + + VerifyOperationTreeAndDiagnosticsForTest(Of TypeOfExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) + End Sub + + + + Public Sub SeesThroughTypeAndNamespaceAliases_IsIntegerAliasIOperationTest() + Dim source = .Value + + Dim expectedOperationTree = .Value + + Dim expectedDiagnostics = String.Empty + + VerifyOperationTreeAndDiagnosticsForTest(Of TypeOfExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) + End Sub + + + + Public Sub SeesThroughTypeAndNamespaceAliases_IsNotStringAliasIOperationTest() + Dim source = .Value + + Dim expectedOperationTree = .Value + + Dim expectedDiagnostics = String.Empty + + VerifyOperationTreeAndDiagnosticsForTest(Of TypeOfExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) + End Sub + + + + Public Sub SeesThroughTypeAndNamespaceAliases_IsNotIntegerAliasIOperationTest() + Dim source = .Value + + Dim expectedOperationTree = .Value + + Dim expectedDiagnostics = String.Empty + + VerifyOperationTreeAndDiagnosticsForTest(Of TypeOfExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) + End Sub + Public Sub ReturnsExpectedValuesFromSemanticModelApi() diff --git a/src/Test/Utilities/Portable/Compilation/OperationTreeVerifier.cs b/src/Test/Utilities/Portable/Compilation/OperationTreeVerifier.cs index 548ef993067ced84961ecff6111e1aa5c8eef667..5b314b0471492b0140f5ad8b3f50c14af4ee0638 100644 --- a/src/Test/Utilities/Portable/Compilation/OperationTreeVerifier.cs +++ b/src/Test/Utilities/Portable/Compilation/OperationTreeVerifier.cs @@ -886,12 +886,18 @@ public override void VisitCoalesceExpression(ICoalesceExpression operation) public override void VisitIsTypeExpression(IIsTypeExpression operation) { LogString(nameof(IIsTypeExpression)); + if (operation.IsNotTypeExpression) + { + LogString(" (IsNotExpression)"); + } + LogCommonPropertiesAndNewLine(operation); Visit(operation.Operand, "Operand"); Indent(); - LogType(operation.Type); + LogType(operation.IsType, "IsType"); + LogNewLine(); Unindent(); }