diff --git a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs index fdd7fd478bc45..ac71975fdc237 100644 --- a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs +++ b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs @@ -7,6 +7,7 @@ using System.Linq; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Symbols; +using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.Semantics { @@ -179,12 +180,16 @@ private IOperation CreateInternal(BoundNode boundNode) return CreateBoundInterpolationOperation((BoundStringInsert)boundNode); case BoundKind.LocalFunctionStatement: return CreateBoundLocalFunctionStatementOperation((BoundLocalFunctionStatement)boundNode); + case BoundKind.AnonymousObjectCreationExpression: + return CreateBoundAnonymousObjectCreationExpressionOperation((BoundAnonymousObjectCreationExpression)boundNode); + case BoundKind.AnonymousPropertyDeclaration: + return CreateBoundAnonymousPropertyDeclarationOperation((BoundAnonymousPropertyDeclaration)boundNode); case BoundKind.ConstantPattern: return CreateBoundConstantPatternOperation((BoundConstantPattern)boundNode); case BoundKind.DeclarationPattern: return CreateBoundDeclarationPatternOperation((BoundDeclarationPattern)boundNode); case BoundKind.WildcardPattern: - return null; + throw ExceptionUtilities.Unreachable; case BoundKind.PatternSwitchStatement: return CreateBoundPatternSwitchStatementOperation((BoundPatternSwitchStatement)boundNode); case BoundKind.PatternSwitchLabel: @@ -352,6 +357,29 @@ private ILiteralExpression CreateBoundLiteralOperation(BoundLiteral boundLiteral return new LiteralExpression(text, isInvalid, syntax, type, constantValue); } + private IAnonymousObjectCreationExpression CreateBoundAnonymousObjectCreationExpressionOperation(BoundAnonymousObjectCreationExpression boundAnonymousObjectCreationExpression) + { + Lazy> memberInitializers = new Lazy>(() => GetAnonymousObjectCreationInitializers(boundAnonymousObjectCreationExpression)); + bool isInvalid = boundAnonymousObjectCreationExpression.HasErrors; + SyntaxNode syntax = boundAnonymousObjectCreationExpression.Syntax; + ITypeSymbol type = boundAnonymousObjectCreationExpression.Type; + Optional constantValue = ConvertToOptional(boundAnonymousObjectCreationExpression.ConstantValue); + return new LazyAnonymousObjectCreationExpression(memberInitializers, isInvalid, syntax, type, constantValue); + } + + private IPropertyReferenceExpression CreateBoundAnonymousPropertyDeclarationOperation(BoundAnonymousPropertyDeclaration boundAnonymousPropertyDeclaration) + { + PropertySymbol property = boundAnonymousPropertyDeclaration.Property; + Lazy instance = new Lazy(() => null); + ISymbol member = boundAnonymousPropertyDeclaration.Property; + Lazy> argumentsInEvaluationOrder = new Lazy>(() => ImmutableArray.Empty); + bool isInvalid = boundAnonymousPropertyDeclaration.HasErrors; + SyntaxNode syntax = boundAnonymousPropertyDeclaration.Syntax; + ITypeSymbol type = boundAnonymousPropertyDeclaration.Type; + Optional constantValue = ConvertToOptional(boundAnonymousPropertyDeclaration.ConstantValue); + return new LazyPropertyReferenceExpression(property, instance, member, argumentsInEvaluationOrder, isInvalid, syntax, type, constantValue); + } + private IObjectCreationExpression CreateBoundObjectCreationExpressionOperation(BoundObjectCreationExpression boundObjectCreationExpression) { IMethodSymbol constructor = boundObjectCreationExpression.Constructor; diff --git a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory_Methods.cs b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory_Methods.cs index 29bef75d9535c..b02a1ceb0e430 100644 --- a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory_Methods.cs +++ b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory_Methods.cs @@ -1,6 +1,8 @@ // 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; using System.Collections.Immutable; +using System.Diagnostics; using System.Linq; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Symbols; @@ -92,6 +94,33 @@ private ImmutableArray DeriveArguments( invokedAsExtensionMethod: invokedAsExtensionMethod); } + private ImmutableArray GetAnonymousObjectCreationInitializers(BoundAnonymousObjectCreationExpression expression) + { + // For error cases, the binder generates only the argument. + Debug.Assert(expression.Arguments.Length >= expression.Declarations.Length); + + var builder = ArrayBuilder.GetInstance(expression.Arguments.Length); + for (int i = 0; i < expression.Arguments.Length; i++) + { + IOperation value = Create(expression.Arguments[i]); + if (i >= expression.Declarations.Length) + { + builder.Add(value); + continue; + } + + IOperation target = Create(expression.Declarations[i]); + bool isInvalid = target.IsInvalid || value.IsInvalid; + SyntaxNode syntax = value.Syntax?.Parent ?? expression.Syntax; + ITypeSymbol type = target.Type; + Optional constantValue = value.ConstantValue; + var assignment = new SimpleAssignmentExpression(target, value, isInvalid, syntax, type, constantValue); + builder.Add(assignment); + } + + return builder.ToImmutableAndFree(); + } + private ImmutableArray GetObjectCreationInitializers(BoundObjectCreationExpression expression) { return BoundObjectCreationExpression.GetChildInitializers(expression.InitializerExpressionOpt).SelectAsArray(n => Create(n)); diff --git a/src/Compilers/CSharp/Test/Semantic/FlowAnalysis/FlowTestBase.cs b/src/Compilers/CSharp/Test/Semantic/FlowAnalysis/FlowTestBase.cs index cae1140266adb..4681d698a4c91 100644 --- a/src/Compilers/CSharp/Test/Semantic/FlowAnalysis/FlowTestBase.cs +++ b/src/Compilers/CSharp/Test/Semantic/FlowAnalysis/FlowTestBase.cs @@ -93,8 +93,8 @@ protected T CompileAndGetModelAndExpression(string program, Func()) { @@ -114,8 +114,8 @@ protected T CompileAndGetModelAndStatements(string program, Func()) { diff --git a/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IParameterReferenceExpression.cs b/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IParameterReferenceExpression.cs index b185d0c10cb29..e60bd664def32 100644 --- a/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IParameterReferenceExpression.cs +++ b/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IParameterReferenceExpression.cs @@ -90,11 +90,15 @@ public void M(int x, string y) } "; string expectedOperationTree = @" -IOperation: (OperationKind.None) (Syntax: 'new { Amoun ... ello"" + y }') - Children(2): IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x') - IBinaryOperatorExpression (BinaryOperationKind.StringConcatenate) (OperationKind.BinaryOperatorExpression, Type: System.String) (Syntax: '""Hello"" + y') - Left: ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: ""Hello"") (Syntax: '""Hello""') - Right: IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: System.String) (Syntax: 'y') +IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: ) (Syntax: 'new { Amoun ... ello"" + y }') + Initializers(2): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32) (Syntax: 'Amount = x') + Left: IPropertyReferenceExpression: System.Int32 .Amount { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: 'Amount') + Right: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x') + ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.String) (Syntax: 'Message = ""Hello"" + y') + Left: IPropertyReferenceExpression: System.String .Message { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: System.String) (Syntax: 'Message') + Right: IBinaryOperatorExpression (BinaryOperationKind.StringConcatenate) (OperationKind.BinaryOperatorExpression, Type: System.String) (Syntax: '""Hello"" + y') + Left: ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: ""Hello"") (Syntax: '""Hello""') + Right: IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: System.String) (Syntax: 'y') "; var expectedDiagnostics = DiagnosticDescription.None; diff --git a/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IPatternSwitchCase.cs b/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IPatternSwitchCase.cs index c33412318af03..443b1ccd54782 100644 --- a/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IPatternSwitchCase.cs +++ b/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IPatternSwitchCase.cs @@ -675,5 +675,54 @@ void M(int? x) VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } + + [Fact, WorkItem(19927, "https://github.com/dotnet/roslyn/issues/19927")] + public void TestPatternCaseClause_RedundantPatternDeclarationClauses() + { + string source = @" +using System; +class X +{ + void M(object p) + { + /**/switch (p) + { + case int x: + break; + case int y: + break; + case X z: + break; + }/**/ + } +} +"; + string expectedOperationTree = @" +ISwitchStatement (3 cases) (OperationKind.SwitchStatement) (Syntax: 'switch (p) ... }') + Switch expression: IParameterReferenceExpression: p (OperationKind.ParameterReferenceExpression, Type: System.Object) (Syntax: 'p') + Sections: ISwitchCase (1 case clauses, 1 statements) (OperationKind.SwitchCase) (Syntax: 'case int x: ... break;') + Clauses: IPatternCaseClause (Label Symbol: case int x:) (CaseKind.Pattern) (OperationKind.PatternCaseClause) (Syntax: 'case int x:') + Pattern: IDeclarationPattern (Declared Symbol: System.Int32 x) (OperationKind.DeclarationPattern) (Syntax: 'int x') + Body: IBranchStatement (BranchKind.Break) (OperationKind.BranchStatement) (Syntax: 'break;') + ISwitchCase (1 case clauses, 1 statements) (OperationKind.SwitchCase) (Syntax: 'case int y: ... break;') + Clauses: IPatternCaseClause (Label Symbol: case int y:) (CaseKind.Pattern) (OperationKind.PatternCaseClause) (Syntax: 'case int y:') + Pattern: IDeclarationPattern (Declared Symbol: System.Int32 y) (OperationKind.DeclarationPattern) (Syntax: 'int y') + Body: IBranchStatement (BranchKind.Break) (OperationKind.BranchStatement) (Syntax: 'break;') + ISwitchCase (1 case clauses, 1 statements) (OperationKind.SwitchCase) (Syntax: 'case X z: ... break;') + Clauses: IPatternCaseClause (Label Symbol: case X z:) (CaseKind.Pattern) (OperationKind.PatternCaseClause) (Syntax: 'case X z:') + Pattern: IDeclarationPattern (Declared Symbol: X z) (OperationKind.DeclarationPattern) (Syntax: 'X z') + Body: IBranchStatement (BranchKind.Break) (OperationKind.BranchStatement) (Syntax: 'break;') +"; + var expectedDiagnostics = new DiagnosticDescription[] { + // CS8120: The switch case has already been handled by a previous case. + // case int y: + Diagnostic(ErrorCode.ERR_PatternIsSubsumed, "int y").WithLocation(11, 18), + // CS0162: Unreachable code detected + // break; + Diagnostic(ErrorCode.WRN_UnreachableCode, "break").WithLocation(12, 17) + }; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } } } \ No newline at end of file diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/InteractiveSemanticModelTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/InteractiveSemanticModelTests.cs index e185f64e1c21b..7a2e17813ef8a 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/InteractiveSemanticModelTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/InteractiveSemanticModelTests.cs @@ -265,60 +265,6 @@ public void BindQueryVariable() #region helpers - protected List GetSyntaxNodeList(SyntaxTree syntaxTree) - { - return GetSyntaxNodeList(syntaxTree.GetCompilationUnitRoot(), null); - } - - protected List GetSyntaxNodeList(SyntaxNode node, List synList) - { - if (synList == null) - synList = new List(); - - synList.Add(node); - - foreach (var child in node.ChildNodesAndTokens()) - { - if (child.IsNode) - synList = GetSyntaxNodeList(child.AsNode(), synList); - } - - return synList; - } - - protected SyntaxNode GetSyntaxNodeForBinding(List synList) - { - foreach (var node in synList) - { - string exprFullText = node.ToFullString(); - exprFullText = exprFullText.Trim(); - - if (exprFullText.StartsWith("/**/", StringComparison.Ordinal)) - { - if (exprFullText.Contains("/**/")) - if (exprFullText.EndsWith("/**/", StringComparison.Ordinal)) - return node; - else - continue; - else - return node; - } - - if (exprFullText.EndsWith("/**/", StringComparison.Ordinal)) - { - if (exprFullText.Contains("/**/")) - if (exprFullText.StartsWith("/**/", StringComparison.Ordinal)) - return node; - else - continue; - else - return node; - } - } - - return null; - } - private List GetExprSyntaxList(SyntaxTree syntaxTree) { return GetExprSyntaxList(syntaxTree.GetCompilationUnitRoot(), null); diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/AnonymousTypesSemanticsTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/AnonymousTypesSemanticsTests.cs index e3c66205af048..cb84be4b83ca1 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/AnonymousTypesSemanticsTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/AnonymousTypesSemanticsTests.cs @@ -83,6 +83,104 @@ public int aa Assert.Equal(info3.Type, info4.Type); } + [Fact()] + public void AnonymousTypeSymbols_Simple_OperationTree() + { + string source = @" +class ClassA +{ + public struct SSS + { + } + + public static void Test1(int x) + /**/{ + object v1 = new + { + aa = 1, + BB = """", + CCC = new SSS() + }; + + object v2 = new + { + aa = new SSS(), + BB = 123.456, + CCC = new + { + (new ClassA()).aa, + ClassA.BB, + ClassA.CCC + } + }; + + object v3 = new { }; + var v4 = new { }; + }/**/ + + public int aa + { + get { return 123; } + } + + public const string BB = ""-=-= -""; + + public static SSS CCC = new SSS(); +} +"; + string expectedOperationTree = @" +IBlockStatement (4 statements, 4 locals) (OperationKind.BlockStatement) (Syntax: '{ ... }') + Locals: Local_1: System.Object v1 + Local_2: System.Object v2 + Local_3: System.Object v3 + Local_4: v4 + IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement) (Syntax: 'object v1 = ... };') + IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'object v1 = ... };') + Variables: Local_1: System.Object v1 + Initializer: IConversionExpression (ConversionKind.Cast, Implicit) (OperationKind.ConversionExpression, Type: System.Object) (Syntax: 'new ... }') + IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: ) (Syntax: 'new ... }') + Initializers(3): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32, Constant: 1) (Syntax: 'aa = 1') + Left: IPropertyReferenceExpression: System.Int32 .aa { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: 'aa') + Right: ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1') + ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.String, Constant: """") (Syntax: 'BB = """"') + Left: IPropertyReferenceExpression: System.String .BB { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: System.String) (Syntax: 'BB') + Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: """") (Syntax: '""""') + ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: ClassA.SSS) (Syntax: 'CCC = new SSS()') + Left: IPropertyReferenceExpression: ClassA.SSS .CCC { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: ClassA.SSS) (Syntax: 'CCC') + Right: IObjectCreationExpression (Constructor: ClassA.SSS..ctor()) (OperationKind.ObjectCreationExpression, Type: ClassA.SSS) (Syntax: 'new SSS()') + IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement) (Syntax: 'object v2 = ... };') + IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'object v2 = ... };') + Variables: Local_1: System.Object v2 + Initializer: IConversionExpression (ConversionKind.Cast, Implicit) (OperationKind.ConversionExpression, Type: System.Object) (Syntax: 'new ... }') + IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: CCC>) (Syntax: 'new ... }') + Initializers(3): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: ClassA.SSS) (Syntax: 'aa = new SSS()') + Left: IPropertyReferenceExpression: ClassA.SSS CCC>.aa { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: ClassA.SSS) (Syntax: 'aa') + Right: IObjectCreationExpression (Constructor: ClassA.SSS..ctor()) (OperationKind.ObjectCreationExpression, Type: ClassA.SSS) (Syntax: 'new SSS()') + ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Double, Constant: 123.456) (Syntax: 'BB = 123.456') + Left: IPropertyReferenceExpression: System.Double CCC>.BB { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: System.Double) (Syntax: 'BB') + Right: ILiteralExpression (Text: 123.456) (OperationKind.LiteralExpression, Type: System.Double, Constant: 123.456) (Syntax: '123.456') + ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: ) (Syntax: 'CCC = new ... }') + Left: IPropertyReferenceExpression: CCC>.CCC { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: ) (Syntax: 'CCC') + Right: IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: ) (Syntax: 'new ... }') + Initializers(3): IPropertyReferenceExpression: System.Int32 ClassA.aa { get; } (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: '(new ClassA()).aa') + Instance Receiver: IObjectCreationExpression (Constructor: ClassA..ctor()) (OperationKind.ObjectCreationExpression, Type: ClassA) (Syntax: 'new ClassA()') + IFieldReferenceExpression: System.String ClassA.BB (Static) (OperationKind.FieldReferenceExpression, Type: System.String, Constant: ""-=-= -"") (Syntax: 'ClassA.BB') + IFieldReferenceExpression: ClassA.SSS ClassA.CCC (Static) (OperationKind.FieldReferenceExpression, Type: ClassA.SSS) (Syntax: 'ClassA.CCC') + IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement) (Syntax: 'object v3 = new { };') + IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'object v3 = new { };') + Variables: Local_1: System.Object v3 + Initializer: IConversionExpression (ConversionKind.Cast, Implicit) (OperationKind.ConversionExpression, Type: System.Object) (Syntax: 'new { }') + IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: ) (Syntax: 'new { }') + IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement) (Syntax: 'var v4 = new { };') + IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'var v4 = new { };') + Variables: Local_1: v4 + Initializer: IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: ) (Syntax: 'new { }') +"; + var expectedDiagnostics = DiagnosticDescription.None; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } + [Fact()] public void AnonymousTypeSymbols_ContextualKeywordsInFields() { @@ -129,6 +227,54 @@ public int select info1.Symbol.ToTestDisplayString()); } + [Fact()] + public void AnonymousTypeSymbols_ContextualKeywordsInFields_OperationTree() + { + string source = @" +class ClassA +{ + static void Test1(int x) + { + object v1 = /**/new + { + var = ""var"", + get = new { }, + partial = new + { + (new ClassA()).select, + global + } + }/**/; + } + + public int select + { + get { return 123; } + } + + public const string global = "" -=-= -""; +} +"; + string expectedOperationTree = @" +IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: get, partial>) (Syntax: 'new ... }') + Initializers(3): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.String, Constant: ""var"") (Syntax: 'var = ""var""') + Left: IPropertyReferenceExpression: System.String get, partial>.var { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: System.String) (Syntax: 'var') + Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: ""var"") (Syntax: '""var""') + ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: ) (Syntax: 'get = new { }') + Left: IPropertyReferenceExpression: get, partial>.get { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: ) (Syntax: 'get') + Right: IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: ) (Syntax: 'new { }') + ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: ) (Syntax: 'partial = n ... }') + Left: IPropertyReferenceExpression: get, partial>.partial { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: ) (Syntax: 'partial') + Right: IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: ) (Syntax: 'new ... }') + Initializers(2): IPropertyReferenceExpression: System.Int32 ClassA.select { get; } (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: '(new ClassA()).select') + Instance Receiver: IObjectCreationExpression (Constructor: ClassA..ctor()) (OperationKind.ObjectCreationExpression, Type: ClassA) (Syntax: 'new ClassA()') + IFieldReferenceExpression: System.String ClassA.global (Static) (OperationKind.FieldReferenceExpression, Type: System.String, Constant: "" -=-= -"") (Syntax: 'global') +"; + var expectedDiagnostics = DiagnosticDescription.None; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } + [Fact()] public void AnonymousTypeSymbols_DelegateMembers() { @@ -151,6 +297,34 @@ void Main() Assert.Equal("..ctor(D1 module)", info0.Symbol.ToTestDisplayString()); } + [Fact()] + public void AnonymousTypeSymbols_DelegateMembers_OperationTree() + { + string source = @" +delegate bool D1(); +class ClassA +{ + void Main() + { + var at1 = /**/new { module = (D1)(() => false) }/**/.module(); + } +} +"; + string expectedOperationTree = @" +IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: ) (Syntax: 'new { modul ... => false) }') + Initializers(1): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: D1) (Syntax: 'module = (D ... ) => false)') + Left: IPropertyReferenceExpression: D1 .module { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: D1) (Syntax: 'module') + Right: IConversionExpression (ConversionKind.CSharp, Explicit) (OperationKind.ConversionExpression, Type: D1) (Syntax: '(D1)(() => false)') + ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: '() => false') + IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'false') + IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'false') + ILiteralExpression (OperationKind.LiteralExpression, Type: System.Boolean, Constant: False) (Syntax: 'false') +"; + var expectedDiagnostics = DiagnosticDescription.None; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } + [Fact()] public void AnonymousTypeSymbols_BaseAccessInMembers() { @@ -180,6 +354,33 @@ void Main() Assert.Equal("System.Int32 System.Func.Invoke(System.Int32 arg)", info1.Symbol.ToTestDisplayString()); } + [Fact()] + public void AnonymousTypeSymbols_BaseAccessInMembers_OperationTree() + { + string source = @" +delegate bool D1(); +class ClassB +{ + protected System.Func F = x => x; +} +class ClassA : ClassB +{ + void Main() + { + var at1 = /**/new { base.F }/**/.F(1); + } +} +"; + string expectedOperationTree = @" +IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: F>) (Syntax: 'new { base.F }') + Initializers(1): IFieldReferenceExpression: System.Func ClassB.F (OperationKind.FieldReferenceExpression, Type: System.Func) (Syntax: 'base.F') + Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.BaseClass) (OperationKind.InstanceReferenceExpression, Type: ClassB) (Syntax: 'base') +"; + var expectedDiagnostics = DiagnosticDescription.None; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } + [Fact()] public void AnonymousTypeSymbols_InFieldInitializer() { @@ -197,6 +398,26 @@ class ClassA Assert.Equal("", info0.Type.ToTestDisplayString()); } + [Fact()] + public void AnonymousTypeSymbols_InFieldInitializer_OperationTree() + { + string source = @" +class ClassA +{ + private static object F = /**/new { F123 = typeof(ClassA) }/**/; +} +"; + string expectedOperationTree = @" +IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: ) (Syntax: 'new { F123 ... f(ClassA) }') + Initializers(1): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Type) (Syntax: 'F123 = typeof(ClassA)') + Left: IPropertyReferenceExpression: System.Type .F123 { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: System.Type) (Syntax: 'F123') + Right: ITypeOfExpression (Type: ClassA) (OperationKind.TypeOfExpression, Type: System.Type) (Syntax: 'typeof(ClassA)') +"; + var expectedDiagnostics = DiagnosticDescription.None; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } + [Fact()] public void AnonymousTypeSymbols_Equals() { @@ -218,6 +439,36 @@ static void Test1(int x) Assert.Equal("object.Equals(object)", method.ToDisplayString()); } + [Fact()] + public void AnonymousTypeSymbols_Equals_OperationTree() + { + string source = @" +class ClassA +{ + static void Test1(int x) + { + bool result = /**/new { f1 = 1, f2 = """" }.Equals(new { })/**/; + } +} +"; + string expectedOperationTree = @" +IInvocationExpression (virtual System.Boolean System.Object.Equals(System.Object obj)) (OperationKind.InvocationExpression, Type: System.Boolean) (Syntax: 'new { f1 = ... ls(new { })') + Instance Receiver: IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: ) (Syntax: 'new { f1 = 1, f2 = """" }') + Initializers(2): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32, Constant: 1) (Syntax: 'f1 = 1') + Left: IPropertyReferenceExpression: System.Int32 .f1 { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: 'f1') + Right: ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1') + ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.String, Constant: """") (Syntax: 'f2 = """"') + Left: IPropertyReferenceExpression: System.String .f2 { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: System.String) (Syntax: 'f2') + Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: """") (Syntax: '""""') + Arguments(1): IArgument (ArgumentKind.Explicit, Matching Parameter: obj) (OperationKind.Argument) (Syntax: 'new { }') + IConversionExpression (ConversionKind.Cast, Implicit) (OperationKind.ConversionExpression, Type: System.Object) (Syntax: 'new { }') + IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: ) (Syntax: 'new { }') +"; + var expectedDiagnostics = DiagnosticDescription.None; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } + [Fact()] public void AnonymousTypeSymbols_ToString() { @@ -364,6 +615,33 @@ void m() Assert.Equal("System.Int32 .y { get; }", info2.Symbol.ToTestDisplayString()); } + [Fact()] + public void AnonymousTypeFieldCreatedInQuery_OperationTree() + { + string source = @" +using System.Collections.Generic; +using System.Linq; + +class ClassA +{ + void m() + { + var o = from x in new List() { 1, 2, 3 } select /**/new { x, y = x }/**/; + } +} +"; + string expectedOperationTree = @" +IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: ) (Syntax: 'new { x, y = x }') + Initializers(2): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32) (Syntax: 'x') + Left: IPropertyReferenceExpression: System.Int32 .y { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: 'y') + Right: IOperation: (OperationKind.None) (Syntax: 'x') + IOperation: (OperationKind.None) (Syntax: 'x') +"; + var expectedDiagnostics = DiagnosticDescription.None; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } + [Fact()] public void AnonymousTypeFieldCreatedInQuery2() { @@ -394,6 +672,32 @@ void m() Assert.Equal("y", info2.Symbol.ToDisplayString()); } + [Fact()] + public void AnonymousTypeFieldCreatedInQuery2_OperationTree() + { + string source = @" +using System.Collections.Generic; +using System.Linq; + +class ClassA +{ + void m() + { + var o = from x in new List() { 1, 2, 3 } let y = """" select /**/new { x, y }/**/; + } +} +"; + // OperationKind.None is for Range variables, IOperation support for it is NYI. + string expectedOperationTree = @" +IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: ) (Syntax: 'new { x, y }') + Initializers(2): IOperation: (OperationKind.None) (Syntax: 'x') + IOperation: (OperationKind.None) (Syntax: 'y') +"; + var expectedDiagnostics = DiagnosticDescription.None; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } + [Fact()] public void AnonymousTypeFieldCreatedInLambda() { @@ -418,6 +722,33 @@ void m() Assert.Equal(" y>..ctor(System.Int32 x, y)", info0.Symbol.ToTestDisplayString()); } + [Fact()] + public void AnonymousTypeFieldCreatedInLambda_OperationTree() + { + string source = @" +using System; +class ClassA +{ + void m() + { + var o = (Action)(() => (/**/new { x = 1, y = new { } }/**/).ToString()); ; + } +} +"; + string expectedOperationTree = @" +IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: y>) (Syntax: 'new { x = 1 ... = new { } }') + Initializers(2): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32, Constant: 1) (Syntax: 'x = 1') + Left: IPropertyReferenceExpression: System.Int32 y>.x { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: 'x') + Right: ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1') + ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: ) (Syntax: 'y = new { }') + Left: IPropertyReferenceExpression: y>.y { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: ) (Syntax: 'y') + Right: IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: ) (Syntax: 'new { }') +"; + var expectedDiagnostics = DiagnosticDescription.None; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } + [Fact()] public void AnonymousTypeFieldCreatedInLambda2() { @@ -445,6 +776,36 @@ void m() Assert.Equal(" y>..ctor(System.Int32 x, y)", info0.Symbol.ToTestDisplayString()); } + [Fact()] + public void AnonymousTypeFieldCreatedInLambda2_OperationTree() + { + string source = @" +using System; +class ClassA +{ + void m() + { + var o = (Action) + (() => + ((Func)(() => (/**/new { x = 1, y = new { } }/**/).ToString()) + ).Invoke()); + } +} +"; + string expectedOperationTree = @" +IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: y>) (Syntax: 'new { x = 1 ... = new { } }') + Initializers(2): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32, Constant: 1) (Syntax: 'x = 1') + Left: IPropertyReferenceExpression: System.Int32 y>.x { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: 'x') + Right: ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1') + ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: ) (Syntax: 'y = new { }') + Left: IPropertyReferenceExpression: y>.y { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: ) (Syntax: 'y') + Right: IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: ) (Syntax: 'new { }') +"; + var expectedDiagnostics = DiagnosticDescription.None; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } + [ClrOnlyFact] public void AnonymousTypeSymbols_DontCrashIfNameIsQueriedBeforeEmit() { @@ -563,6 +924,98 @@ public static void Test1(int x) Assert.Equal("", info2.Type.ToTestDisplayString()); } + [Fact()] + public void AnonymousTypeSymbols_Error_Simple_OperationTree() + { + string source = @" +class ClassA +{ + public static void Test1(int x) + /**/{ + object v1 = new + { + aa = xyz, + BB = """", + CCC = new SSS() + }; + + object v2 = new + { + aa = new SSS(), + BB = 123.456, + CCC = new + { + (new ClassA()).aa, + ClassA.BB, + ClassA.CCC + } + }; + }/**/ +} +"; + string expectedOperationTree = @" +IBlockStatement (2 statements, 2 locals) (OperationKind.BlockStatement, IsInvalid) (Syntax: '{ ... }') + Locals: Local_1: System.Object v1 + Local_2: System.Object v2 + IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement, IsInvalid) (Syntax: 'object v1 = ... };') + IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration, IsInvalid) (Syntax: 'object v1 = ... };') + Variables: Local_1: System.Object v1 + Initializer: IConversionExpression (ConversionKind.Cast, Implicit) (OperationKind.ConversionExpression, Type: System.Object, IsInvalid) (Syntax: 'new ... }') + IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: , IsInvalid) (Syntax: 'new ... }') + Initializers(3): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: ?, IsInvalid) (Syntax: 'aa = xyz') + Left: IPropertyReferenceExpression: ? .aa { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: ?) (Syntax: 'aa') + Right: IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: 'xyz') + ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.String, Constant: """") (Syntax: 'BB = """"') + Left: IPropertyReferenceExpression: System.String .BB { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: System.String) (Syntax: 'BB') + Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: """") (Syntax: '""""') + ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: SSS, IsInvalid) (Syntax: 'CCC = new SSS()') + Left: IPropertyReferenceExpression: SSS .CCC { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: SSS) (Syntax: 'CCC') + Right: IInvalidExpression (OperationKind.InvalidExpression, Type: SSS, IsInvalid) (Syntax: 'new SSS()') + IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement, IsInvalid) (Syntax: 'object v2 = ... };') + IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration, IsInvalid) (Syntax: 'object v2 = ... };') + Variables: Local_1: System.Object v2 + Initializer: IConversionExpression (ConversionKind.Cast, Implicit) (OperationKind.ConversionExpression, Type: System.Object, IsInvalid) (Syntax: 'new ... }') + IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: CCC>, IsInvalid) (Syntax: 'new ... }') + Initializers(3): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: SSS, IsInvalid) (Syntax: 'aa = new SSS()') + Left: IPropertyReferenceExpression: SSS CCC>.aa { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: SSS) (Syntax: 'aa') + Right: IInvalidExpression (OperationKind.InvalidExpression, Type: SSS, IsInvalid) (Syntax: 'new SSS()') + ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Double, Constant: 123.456) (Syntax: 'BB = 123.456') + Left: IPropertyReferenceExpression: System.Double CCC>.BB { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: System.Double) (Syntax: 'BB') + Right: ILiteralExpression (Text: 123.456) (OperationKind.LiteralExpression, Type: System.Double, Constant: 123.456) (Syntax: '123.456') + ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: , IsInvalid) (Syntax: 'CCC = new ... }') + Left: IPropertyReferenceExpression: CCC>.CCC { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: ) (Syntax: 'CCC') + Right: IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: , IsInvalid) (Syntax: 'new ... }') + Initializers(3): IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: '(new ClassA()).aa') + Children(1): IObjectCreationExpression (Constructor: ClassA..ctor()) (OperationKind.ObjectCreationExpression, Type: ClassA) (Syntax: 'new ClassA()') + IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: 'ClassA.BB') + Children(1): IOperation: (OperationKind.None) (Syntax: 'ClassA') + IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: 'ClassA.CCC') + Children(1): IOperation: (OperationKind.None) (Syntax: 'ClassA') +"; + var expectedDiagnostics = new DiagnosticDescription[] { + // CS0103: The name 'xyz' does not exist in the current context + // aa = xyz, + Diagnostic(ErrorCode.ERR_NameNotInContext, "xyz").WithArguments("xyz").WithLocation(8, 18), + // CS0246: The type or namespace name 'SSS' could not be found (are you missing a using directive or an assembly reference?) + // CCC = new SSS() + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "SSS").WithArguments("SSS").WithLocation(10, 23), + // CS0246: The type or namespace name 'SSS' could not be found (are you missing a using directive or an assembly reference?) + // aa = new SSS(), + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "SSS").WithArguments("SSS").WithLocation(15, 22), + // CS1061: 'ClassA' does not contain a definition for 'aa' and no extension method 'aa' accepting a first argument of type 'ClassA' could be found (are you missing a using directive or an assembly reference?) + // (new ClassA()).aa, + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "aa").WithArguments("ClassA", "aa").WithLocation(19, 32), + // CS0117: 'ClassA' does not contain a definition for 'BB' + // ClassA.BB, + Diagnostic(ErrorCode.ERR_NoSuchMember, "BB").WithArguments("ClassA", "BB").WithLocation(20, 24), + // CS0117: 'ClassA' does not contain a definition for 'CCC' + // ClassA.CCC + Diagnostic(ErrorCode.ERR_NoSuchMember, "CCC").WithArguments("ClassA", "CCC").WithLocation(21, 24) + }; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } + [Fact()] public void AnonymousTypeSymbols_Error_InUsingStatement() { @@ -588,6 +1041,37 @@ public static void Test1(int x) Assert.Equal("", info0.Type.ToTestDisplayString()); } + [Fact()] + public void AnonymousTypeSymbols_Error_InUsingStatement_OperationTree() + { + string source = @" +class ClassA +{ + public static void Test1(int x) + { + using (/**/var v1 = new { }/**/) + { + } + } +} +"; + string expectedOperationTree = @" +IUsingStatement (OperationKind.UsingStatement, IsInvalid) (Syntax: 'using (/* v1 + Initializer: IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: ) (Syntax: 'new { }') + Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }') +"; + var expectedDiagnostics = new DiagnosticDescription[] { + // CS1674: '': type used in a using statement must be implicitly convertible to 'System.IDisposable' + // using (/**/var v1 = new { }/**/) + Diagnostic(ErrorCode.ERR_NoConvToIDisp, "var v1 = new { }").WithArguments("").WithLocation(6, 26) + }; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } + [Fact()] public void AnonymousTypeSymbols_Error_DuplicateName() { @@ -626,6 +1110,44 @@ public static void Test1(int x) Assert.Equal("System.Double .bb { get; }", properties[2].ToTestDisplayString()); } + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/20338")] + public void AnonymousTypeSymbols_Error_DuplicateName_OperationTree() + { + string source = @" +class ClassA +{ + public static void Test1(int x) + { + object v1 = /**/new + { + aa = 1, + ClassA.aa, + bb = 1.2 + }/**/; + } + + public static string aa = ""-field-aa-""; +} +"; + string expectedOperationTree = @" +IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: , IsInvalid) (Syntax: 'new ... }') + Initializers(3): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32, Constant: 1) (Syntax: 'aa = 1') + Left: IPropertyReferenceExpression: System.Int32 .aa { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: 'aa') + Right: ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1') + IFieldReferenceExpression: System.String ClassA.aa (Static) (OperationKind.FieldReferenceExpression, Type: System.String) (Syntax: 'ClassA.aa') + ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Double) (Syntax: 'ClassA.aa') + Left: IPropertyReferenceExpression: System.Double .bb { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: System.Double) (Syntax: 'bb') + Right: ILiteralExpression (Text: 1.2) (OperationKind.LiteralExpression, Type: System.Double, Constant: 1.2) (Syntax: '1.2') +"; + var expectedDiagnostics = new DiagnosticDescription[] { + // CS0833: An anonymous type cannot have multiple properties with the same name + // ClassA.aa, + Diagnostic(ErrorCode.ERR_AnonymousTypeDuplicatePropertyName, "ClassA.aa").WithLocation(9, 13) + }; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } + [Fact()] public void AnonymousTypeSymbols_LookupSymbols() { @@ -699,6 +1221,30 @@ public class A Assert.Equal(".a", info.Symbol.ToDisplayString()); } + [Fact()] + public void CheckAnonymousTypeAsConstValue_OperationTree() + { + string source = @" +class A +{ + const int i = (/**/new { a = 2 }/**/).a; +} +"; + string expectedOperationTree = @" +IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: , IsInvalid) (Syntax: 'new { a = 2 }') + Initializers(1): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32, Constant: 2) (Syntax: 'a = 2') + Left: IPropertyReferenceExpression: System.Int32 .a { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: 'a') + Right: ILiteralExpression (Text: 2) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 2) (Syntax: '2') +"; + var expectedDiagnostics = new DiagnosticDescription[] { + // CS0836: Cannot use anonymous type in a constant expression + // const int i = (/**/new { a = 2 }/**/).a; + Diagnostic(ErrorCode.ERR_AnonymousTypeNotAvailable, "new").WithLocation(4, 30) + }; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } + [WorkItem(546416, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546416")] [ClrOnlyFact] public void TestAnonymousTypeInsideGroupBy_Queryable() @@ -727,6 +1273,71 @@ public static void Main() }", additionalRefs: new[] { SystemCoreRef }).VerifyDiagnostics(); } + [WorkItem(546416, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546416")] + [ClrOnlyFact] + public void TestAnonymousTypeInsideGroupBy_Queryable_OperationTree() + { + string source = @" +using System.Linq; + +class Product +{ + public int ProductID; + public string ProductName; + public int SupplierID; +} +class DB +{ + public IQueryable Products; +} + +class Program +{ + public static void Main() + { + var db = new DB(); + var q0 = db.Products.GroupBy(p => /**/new { Conditional = false ? new { p.ProductID, p.ProductName, p.SupplierID } : new { p.ProductID, p.ProductName, p.SupplierID } }/**/).ToList(); + } +} +"; + string expectedOperationTree = @" +IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: Conditional>) (Syntax: 'new { Condi ... plierID } }') + Initializers(1): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: ) (Syntax: 'Conditional ... upplierID }') + Left: IPropertyReferenceExpression: Conditional>.Conditional { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: ) (Syntax: 'Conditional') + Right: IConditionalChoiceExpression (OperationKind.ConditionalChoiceExpression, Type: ) (Syntax: 'false ? new ... upplierID }') + Condition: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Boolean, Constant: False) (Syntax: 'false') + IfTrue: IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: ) (Syntax: 'new { p.Pro ... upplierID }') + Initializers(3): IFieldReferenceExpression: System.Int32 Product.ProductID (OperationKind.FieldReferenceExpression, Type: System.Int32) (Syntax: 'p.ProductID') + Instance Receiver: IParameterReferenceExpression: p (OperationKind.ParameterReferenceExpression, Type: Product) (Syntax: 'p') + IFieldReferenceExpression: System.String Product.ProductName (OperationKind.FieldReferenceExpression, Type: System.String) (Syntax: 'p.ProductName') + Instance Receiver: IParameterReferenceExpression: p (OperationKind.ParameterReferenceExpression, Type: Product) (Syntax: 'p') + IFieldReferenceExpression: System.Int32 Product.SupplierID (OperationKind.FieldReferenceExpression, Type: System.Int32) (Syntax: 'p.SupplierID') + Instance Receiver: IParameterReferenceExpression: p (OperationKind.ParameterReferenceExpression, Type: Product) (Syntax: 'p') + IfFalse: IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: ) (Syntax: 'new { p.Pro ... upplierID }') + Initializers(3): IFieldReferenceExpression: System.Int32 Product.ProductID (OperationKind.FieldReferenceExpression, Type: System.Int32) (Syntax: 'p.ProductID') + Instance Receiver: IParameterReferenceExpression: p (OperationKind.ParameterReferenceExpression, Type: Product) (Syntax: 'p') + IFieldReferenceExpression: System.String Product.ProductName (OperationKind.FieldReferenceExpression, Type: System.String) (Syntax: 'p.ProductName') + Instance Receiver: IParameterReferenceExpression: p (OperationKind.ParameterReferenceExpression, Type: Product) (Syntax: 'p') + IFieldReferenceExpression: System.Int32 Product.SupplierID (OperationKind.FieldReferenceExpression, Type: System.Int32) (Syntax: 'p.SupplierID') + Instance Receiver: IParameterReferenceExpression: p (OperationKind.ParameterReferenceExpression, Type: Product) (Syntax: 'p') +"; + var expectedDiagnostics = new DiagnosticDescription[] { + // CS0649: Field 'Product.ProductName' is never assigned to, and will always have its default value null + // public string ProductName; + Diagnostic(ErrorCode.WRN_UnassignedInternalField, "ProductName").WithArguments("Product.ProductName", "null").WithLocation(7, 19), + // CS0649: Field 'Product.SupplierID' is never assigned to, and will always have its default value 0 + // public int SupplierID; + Diagnostic(ErrorCode.WRN_UnassignedInternalField, "SupplierID").WithArguments("Product.SupplierID", "0").WithLocation(8, 16), + // CS0649: Field 'Product.ProductID' is never assigned to, and will always have its default value 0 + // public int ProductID; + Diagnostic(ErrorCode.WRN_UnassignedInternalField, "ProductID").WithArguments("Product.ProductID", "0").WithLocation(6, 16), + // CS0649: Field 'DB.Products' is never assigned to, and will always have its default value null + // public IQueryable Products; + Diagnostic(ErrorCode.WRN_UnassignedInternalField, "Products").WithArguments("DB.Products", "null").WithLocation(12, 32) + }; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } [WorkItem(546416, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546416")] [ClrOnlyFact] public void TestAnonymousTypeInsideGroupBy_Enumerable() diff --git a/src/Compilers/Core/Portable/CodeAnalysis.csproj b/src/Compilers/Core/Portable/CodeAnalysis.csproj index 40afe23ad89af..d4b70526435d3 100644 --- a/src/Compilers/Core/Portable/CodeAnalysis.csproj +++ b/src/Compilers/Core/Portable/CodeAnalysis.csproj @@ -45,6 +45,7 @@ + diff --git a/src/Compilers/Core/Portable/Generated/Operations.xml.Generated.cs b/src/Compilers/Core/Portable/Generated/Operations.xml.Generated.cs index d32f9490d1770..19f5aef198e7f 100644 --- a/src/Compilers/Core/Portable/Generated/Operations.xml.Generated.cs +++ b/src/Compilers/Core/Portable/Generated/Operations.xml.Generated.cs @@ -2976,6 +2976,62 @@ public LazyObjectCreationExpression(IMethodSymbol constructor, Lazy ArgumentsInEvaluationOrder => _lazyArgumentsInEvaluationOrder.Value; } + /// + /// Represents a C# or VB new/New anonymous object creation expression. + /// + internal abstract partial class BaseAnonymousObjectCreationExpression : Operation, IAnonymousObjectCreationExpression + { + protected BaseAnonymousObjectCreationExpression(bool isInvalid, SyntaxNode syntax, ITypeSymbol type, Optional constantValue) : + base(OperationKind.AnonymousObjectCreationExpression, isInvalid, syntax, type, constantValue) + { + } + /// + /// Explicitly-specified member initializers. + /// + public abstract ImmutableArray Initializers { get; } + public override void Accept(OperationVisitor visitor) + { + visitor.VisitAnonymousObjectCreationExpression(this); + } + public override TResult Accept(OperationVisitor visitor, TArgument argument) + { + return visitor.VisitAnonymousObjectCreationExpression(this, argument); + } + } + + /// + /// Represents a C# or VB new/New anonymous object creation expression. + /// + internal sealed partial class AnonymousObjectCreationExpression : BaseAnonymousObjectCreationExpression, IAnonymousObjectCreationExpression + { + public AnonymousObjectCreationExpression(ImmutableArray initializers, bool isInvalid, SyntaxNode syntax, ITypeSymbol type, Optional constantValue) : + base(isInvalid, syntax, type, constantValue) + { + Initializers = initializers; + } + /// + /// Explicitly-specified member initializers. + /// + public override ImmutableArray Initializers { get; } + } + + /// + /// Represents a C# or VB new/New anonymous object creation expression. + /// + internal sealed partial class LazyAnonymousObjectCreationExpression : BaseAnonymousObjectCreationExpression, IAnonymousObjectCreationExpression + { + private readonly Lazy> _lazyInitializers; + + public LazyAnonymousObjectCreationExpression(Lazy> initializers, bool isInvalid, SyntaxNode syntax, ITypeSymbol type, Optional constantValue) : base(isInvalid, syntax, type, constantValue) + { + _lazyInitializers = initializers; + } + /// + /// Explicitly-specified member initializers. + /// + public override ImmutableArray Initializers => _lazyInitializers.Value; + } + /// /// Represents an argument value that has been omitted in an invocation. /// diff --git a/src/Compilers/Core/Portable/Operations/IAnonymousObjectCreationExpression.cs b/src/Compilers/Core/Portable/Operations/IAnonymousObjectCreationExpression.cs new file mode 100644 index 0000000000000..8e77722c31c3b --- /dev/null +++ b/src/Compilers/Core/Portable/Operations/IAnonymousObjectCreationExpression.cs @@ -0,0 +1,22 @@ +// 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 +{ + /// + /// Represents a C# "new { ... }" or VB "New With { ... }" anonymous object creation expression. + /// + /// + /// This interface is reserved for implementation by its associated APIs. We reserve the right to + /// change it in the future. + /// + public interface IAnonymousObjectCreationExpression : IOperation + { + /// + /// Property initializers. + /// + ImmutableArray Initializers { get; } + } +} + diff --git a/src/Compilers/Core/Portable/Operations/OperationKind.cs b/src/Compilers/Core/Portable/Operations/OperationKind.cs index e38463c7dbcbf..8a3d52fdbfce4 100644 --- a/src/Compilers/Core/Portable/Operations/OperationKind.cs +++ b/src/Compilers/Core/Portable/Operations/OperationKind.cs @@ -126,7 +126,9 @@ public enum OperationKind ConditionalAccessInstanceExpression = 0x11d, /// Indicates an . InterpolatedStringExpression = 0x11e, - + /// Indicates an . + AnonymousObjectCreationExpression = 0x11f, + // Expressions that occur only in C#. /// Indicates an . diff --git a/src/Compilers/Core/Portable/Operations/OperationVisitor.cs b/src/Compilers/Core/Portable/Operations/OperationVisitor.cs index 995826c707d78..e4c69a2f36918 100644 --- a/src/Compilers/Core/Portable/Operations/OperationVisitor.cs +++ b/src/Compilers/Core/Portable/Operations/OperationVisitor.cs @@ -310,6 +310,11 @@ public virtual void VisitObjectCreationExpression(IObjectCreationExpression oper DefaultVisit(operation); } + public virtual void VisitAnonymousObjectCreationExpression(IAnonymousObjectCreationExpression operation) + { + DefaultVisit(operation); + } + public virtual void VisitFieldInitializer(IFieldInitializer operation) { DefaultVisit(operation); @@ -735,6 +740,11 @@ public virtual TResult VisitObjectCreationExpression(IObjectCreationExpression o return DefaultVisit(operation, argument); } + public virtual TResult VisitAnonymousObjectCreationExpression(IAnonymousObjectCreationExpression operation, TArgument argument) + { + return DefaultVisit(operation, argument); + } + public virtual TResult VisitFieldInitializer(IFieldInitializer operation, TArgument argument) { return DefaultVisit(operation, argument); diff --git a/src/Compilers/Core/Portable/Operations/OperationWalker.cs b/src/Compilers/Core/Portable/Operations/OperationWalker.cs index 772b7bc6aee92..b73070cc7cc45 100644 --- a/src/Compilers/Core/Portable/Operations/OperationWalker.cs +++ b/src/Compilers/Core/Portable/Operations/OperationWalker.cs @@ -348,6 +348,11 @@ public override void VisitObjectCreationExpression(IObjectCreationExpression ope VisitArray(operation.Initializers); } + public override void VisitAnonymousObjectCreationExpression(IAnonymousObjectCreationExpression operation) + { + VisitArray(operation.Initializers); + } + public override void VisitFieldInitializer(IFieldInitializer operation) { Visit(operation.Value); diff --git a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt index a21299c980871..7f08b116274c9 100644 --- a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt @@ -51,6 +51,7 @@ Microsoft.CodeAnalysis.IOperation.Syntax.get -> Microsoft.CodeAnalysis.SyntaxNod Microsoft.CodeAnalysis.IOperation.Type.get -> Microsoft.CodeAnalysis.ITypeSymbol Microsoft.CodeAnalysis.OperationKind Microsoft.CodeAnalysis.OperationKind.AddressOfExpression = 515 -> Microsoft.CodeAnalysis.OperationKind +Microsoft.CodeAnalysis.OperationKind.AnonymousObjectCreationExpression = 287 -> Microsoft.CodeAnalysis.OperationKind Microsoft.CodeAnalysis.OperationKind.Argument = 1031 -> Microsoft.CodeAnalysis.OperationKind Microsoft.CodeAnalysis.OperationKind.ArrayCreationExpression = 276 -> Microsoft.CodeAnalysis.OperationKind Microsoft.CodeAnalysis.OperationKind.ArrayElementReferenceExpression = 260 -> Microsoft.CodeAnalysis.OperationKind @@ -331,6 +332,8 @@ Microsoft.CodeAnalysis.Semantics.ConversionKind.OperatorMethod = 5 -> Microsoft. Microsoft.CodeAnalysis.Semantics.ConversionKind.TryCast = 2 -> Microsoft.CodeAnalysis.Semantics.ConversionKind Microsoft.CodeAnalysis.Semantics.IAddressOfExpression Microsoft.CodeAnalysis.Semantics.IAddressOfExpression.Reference.get -> Microsoft.CodeAnalysis.IOperation +Microsoft.CodeAnalysis.Semantics.IAnonymousObjectCreationExpression +Microsoft.CodeAnalysis.Semantics.IAnonymousObjectCreationExpression.Initializers.get -> System.Collections.Immutable.ImmutableArray Microsoft.CodeAnalysis.Semantics.IArgument Microsoft.CodeAnalysis.Semantics.IArgument.ArgumentKind.get -> Microsoft.CodeAnalysis.Semantics.ArgumentKind Microsoft.CodeAnalysis.Semantics.IArgument.InConversion.get -> Microsoft.CodeAnalysis.IOperation @@ -699,6 +702,7 @@ abstract Microsoft.CodeAnalysis.SemanticModel.GetOperationCore(Microsoft.CodeAna const Microsoft.CodeAnalysis.LanguageNames.FSharp = "F#" -> string override Microsoft.CodeAnalysis.Semantics.OperationWalker.Visit(Microsoft.CodeAnalysis.IOperation operation) -> void override Microsoft.CodeAnalysis.Semantics.OperationWalker.VisitAddressOfExpression(Microsoft.CodeAnalysis.Semantics.IAddressOfExpression operation) -> void +override Microsoft.CodeAnalysis.Semantics.OperationWalker.VisitAnonymousObjectCreationExpression(Microsoft.CodeAnalysis.Semantics.IAnonymousObjectCreationExpression operation) -> void override Microsoft.CodeAnalysis.Semantics.OperationWalker.VisitArgument(Microsoft.CodeAnalysis.Semantics.IArgument operation) -> void override Microsoft.CodeAnalysis.Semantics.OperationWalker.VisitArrayCreationExpression(Microsoft.CodeAnalysis.Semantics.IArrayCreationExpression operation) -> void override Microsoft.CodeAnalysis.Semantics.OperationWalker.VisitArrayElementReferenceExpression(Microsoft.CodeAnalysis.Semantics.IArrayElementReferenceExpression operation) -> void @@ -803,6 +807,7 @@ virtual Microsoft.CodeAnalysis.Diagnostics.CompilationStartAnalysisContext.Regis virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.DefaultVisit(Microsoft.CodeAnalysis.IOperation operation) -> void virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.Visit(Microsoft.CodeAnalysis.IOperation operation) -> void virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitAddressOfExpression(Microsoft.CodeAnalysis.Semantics.IAddressOfExpression operation) -> void +virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitAnonymousObjectCreationExpression(Microsoft.CodeAnalysis.Semantics.IAnonymousObjectCreationExpression operation) -> void virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitArgument(Microsoft.CodeAnalysis.Semantics.IArgument operation) -> void virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitArrayCreationExpression(Microsoft.CodeAnalysis.Semantics.IArrayCreationExpression operation) -> void virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitArrayElementReferenceExpression(Microsoft.CodeAnalysis.Semantics.IArrayElementReferenceExpression operation) -> void @@ -884,6 +889,7 @@ virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitYieldBreakStateme virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.DefaultVisit(Microsoft.CodeAnalysis.IOperation operation, TArgument argument) -> TResult virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.Visit(Microsoft.CodeAnalysis.IOperation operation, TArgument argument) -> TResult virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitAddressOfExpression(Microsoft.CodeAnalysis.Semantics.IAddressOfExpression operation, TArgument argument) -> TResult +virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitAnonymousObjectCreationExpression(Microsoft.CodeAnalysis.Semantics.IAnonymousObjectCreationExpression operation, TArgument argument) -> TResult virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitArgument(Microsoft.CodeAnalysis.Semantics.IArgument operation, TArgument argument) -> TResult virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitArrayCreationExpression(Microsoft.CodeAnalysis.Semantics.IArrayCreationExpression operation, TArgument argument) -> TResult virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitArrayElementReferenceExpression(Microsoft.CodeAnalysis.Semantics.IArrayElementReferenceExpression operation, TArgument argument) -> TResult diff --git a/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs b/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs index 5a64a5de0d2d8..124d3e028302f 100644 --- a/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs +++ b/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs @@ -705,6 +705,84 @@ internal CompilationVerifier CompileAndVerifyException(CSharpCompilation comp return CompileAndVerify(comp); } + protected static List GetSyntaxNodeList(SyntaxTree syntaxTree) + { + return GetSyntaxNodeList(syntaxTree.GetRoot(), null); + } + + protected static List GetSyntaxNodeList(SyntaxNode node, List synList) + { + if (synList == null) + synList = new List(); + + synList.Add(node); + + foreach (var child in node.ChildNodesAndTokens()) + { + if (child.IsNode) + synList = GetSyntaxNodeList(child.AsNode(), synList); + } + + return synList; + } + + protected static SyntaxNode GetSyntaxNodeForBinding(List synList) + { + return GetSyntaxNodeOfTypeForBinding(synList); + } + + protected const string StartString = "/**/"; + protected const string EndString = "/**/"; + + protected static TNode GetSyntaxNodeOfTypeForBinding(List synList) where TNode : SyntaxNode + { + foreach (var node in synList.OfType()) + { + string exprFullText = node.ToFullString(); + exprFullText = exprFullText.Trim(); + + if (exprFullText.StartsWith(StartString, StringComparison.Ordinal)) + { + if (exprFullText.Contains(EndString)) + { + if (exprFullText.EndsWith(EndString, StringComparison.Ordinal)) + { + return node; + } + else + { + continue; + } + } + else + { + return node; + } + } + + if (exprFullText.EndsWith(EndString, StringComparison.Ordinal)) + { + if (exprFullText.Contains(StartString)) + { + if (exprFullText.StartsWith(StartString, StringComparison.Ordinal)) + { + return node; + } + else + { + continue; + } + } + else + { + return node; + } + } + } + + return null; + } + #endregion #region Semantic Model Helpers @@ -1045,5 +1123,97 @@ public override string VisualizeLocalType(object type) } #endregion + + #region IOperation tree validation + + protected static (IOperation operation, SyntaxNode node) GetOperationAndSyntaxForTest(CSharpCompilation compilation) + where TSyntaxNode : SyntaxNode + { + var tree = compilation.SyntaxTrees[0]; + var model = compilation.GetSemanticModel(tree); + SyntaxNode syntaxNode = GetSyntaxNodeOfTypeForBinding(GetSyntaxNodeList(tree)); + if (syntaxNode == null) + { + return (null, null); + } + + return (model.GetOperationInternal(syntaxNode), syntaxNode); + } + + protected static string GetOperationTreeForTest(CSharpCompilation compilation) + where TSyntaxNode : SyntaxNode + { + var (operation, syntax) = GetOperationAndSyntaxForTest(compilation); + return operation != null ? OperationTreeVerifier.GetOperationTree(operation) : null; + } + + protected static string GetOperationTreeForTest(IOperation operation) + { + return operation != null ? OperationTreeVerifier.GetOperationTree(operation) : null; + } + + protected static string GetOperationTreeForTest(string testSrc, string expectedOperationTree, CSharpCompilationOptions compilationOptions = null, CSharpParseOptions parseOptions = null) + where TSyntaxNode : SyntaxNode + { + var compilation = CreateStandardCompilation(testSrc, new[] { SystemCoreRef, ValueTupleRef, SystemRuntimeFacadeRef }, options: compilationOptions ?? TestOptions.ReleaseDll, parseOptions: parseOptions); + return GetOperationTreeForTest(compilation); + } + + protected static void VerifyOperationTreeForTest(CSharpCompilation compilation, string expectedOperationTree, Action AdditionalOperationTreeVerifier = null) + where TSyntaxNode : SyntaxNode + { + var (actualOperation, syntaxNode) = GetOperationAndSyntaxForTest(compilation); + var actualOperationTree = GetOperationTreeForTest(actualOperation); + OperationTreeVerifier.Verify(expectedOperationTree, actualOperationTree); + AdditionalOperationTreeVerifier?.Invoke(actualOperation, compilation, syntaxNode); + } + + protected static void VerifyOperationTreeForTest(string testSrc, string expectedOperationTree, CSharpCompilationOptions compilationOptions = null, CSharpParseOptions parseOptions = null) + where TSyntaxNode : SyntaxNode + { + var actualOperationTree = GetOperationTreeForTest(testSrc, expectedOperationTree, compilationOptions, parseOptions); + OperationTreeVerifier.Verify(expectedOperationTree, actualOperationTree); + } + + protected static void VerifyOperationTreeAndDiagnosticsForTest(CSharpCompilation compilation, string expectedOperationTree, DiagnosticDescription[] expectedDiagnostics, Action AdditionalOperationTreeVerifier = null) + where TSyntaxNode : SyntaxNode + { + var actualDiagnostics = compilation.GetDiagnostics().Where(d => d.Severity != DiagnosticSeverity.Hidden); + actualDiagnostics.Verify(expectedDiagnostics); + VerifyOperationTreeForTest(compilation, expectedOperationTree, AdditionalOperationTreeVerifier); + } + + private static readonly MetadataReference[] s_defaultOperationReferences = new[] { SystemRef, SystemCoreRef, ValueTupleRef, SystemRuntimeFacadeRef }; + + protected static void VerifyOperationTreeAndDiagnosticsForTest(string testSrc, + string expectedOperationTree, + DiagnosticDescription[] expectedDiagnostics, + CSharpCompilationOptions compilationOptions = null, + CSharpParseOptions parseOptions = null, + MetadataReference[] additionalReferences = null, + Action AdditionalOperationTreeVerifier = null) + where TSyntaxNode : SyntaxNode + { + var references = additionalReferences == null ? s_defaultOperationReferences : additionalReferences.Concat(s_defaultOperationReferences); + var compilation = CreateStandardCompilation(testSrc, references, sourceFileName: "file.cs", options: compilationOptions ?? TestOptions.ReleaseDll, parseOptions: parseOptions); + VerifyOperationTreeAndDiagnosticsForTest(compilation, expectedOperationTree, expectedDiagnostics, AdditionalOperationTreeVerifier); + } + + protected static MetadataReference VerifyOperationTreeAndDiagnosticsForTestWithIL(string testSrc, + string ilSource, + string expectedOperationTree, + DiagnosticDescription[] expectedDiagnostics, + CSharpCompilationOptions compilationOptions = null, + CSharpParseOptions parseOptions = null, + MetadataReference[] additionalReferences = null, + Action AdditionalOperationTreeVerifier = null) + where TSyntaxNode : SyntaxNode + { + var ilReference = CreateMetadataReferenceFromIlSource(ilSource); + VerifyOperationTreeAndDiagnosticsForTest(testSrc, expectedOperationTree, expectedDiagnostics, compilationOptions, parseOptions, new[] { ilReference }, AdditionalOperationTreeVerifier); + return ilReference; + } + + #endregion } } diff --git a/src/Compilers/Test/Utilities/CSharp/SemanticModelTestBase.cs b/src/Compilers/Test/Utilities/CSharp/SemanticModelTestBase.cs index dabcdefe5728c..4e8e871982a5a 100644 --- a/src/Compilers/Test/Utilities/CSharp/SemanticModelTestBase.cs +++ b/src/Compilers/Test/Utilities/CSharp/SemanticModelTestBase.cs @@ -14,27 +14,6 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests { public abstract class SemanticModelTestBase : CSharpTestBase { - protected List GetSyntaxNodeList(SyntaxTree syntaxTree) - { - return GetSyntaxNodeList(syntaxTree.GetRoot(), null); - } - - protected List GetSyntaxNodeList(SyntaxNode node, List synList) - { - if (synList == null) - synList = new List(); - - synList.Add(node); - - foreach (var child in node.ChildNodesAndTokens()) - { - if (child.IsNode) - synList = GetSyntaxNodeList(child.AsNode(), synList); - } - - return synList; - } - protected int GetPositionForBinding(SyntaxTree tree) { return GetSyntaxNodeForBinding(GetSyntaxNodeList(tree)).SpanStart; @@ -47,47 +26,6 @@ protected int GetPositionForBinding(string code) return code.IndexOf(tag, StringComparison.Ordinal) + tag.Length; } - protected SyntaxNode GetSyntaxNodeForBinding(List synList) - { - return GetSyntaxNodeOfTypeForBinding(synList); - } - - protected readonly string startString = "/**/"; - protected readonly string endString = "/**/"; - - protected TNode GetSyntaxNodeOfTypeForBinding(List synList) where TNode : SyntaxNode - { - foreach (var node in synList.OfType()) - { - string exprFullText = node.ToFullString(); - exprFullText = exprFullText.Trim(); - - if (exprFullText.StartsWith(startString, StringComparison.Ordinal)) - { - if (exprFullText.Contains(endString)) - if (exprFullText.EndsWith(endString, StringComparison.Ordinal)) - return node; - else - continue; - else - return node; - } - - if (exprFullText.EndsWith(endString, StringComparison.Ordinal)) - { - if (exprFullText.Contains(startString)) - if (exprFullText.StartsWith(startString, StringComparison.Ordinal)) - return node; - else - continue; - else - return node; - } - } - - return null; - } - protected List GetExprSyntaxList(SyntaxTree syntaxTree) { return GetExprSyntaxList(syntaxTree.GetRoot(), null); @@ -220,93 +158,5 @@ protected CompilationUtils.SemanticInfoSummary GetSemanticInfoForTest(string tes { return GetSemanticInfoForTest(testSrc); } - - protected (IOperation operation, SyntaxNode node) GetOperationAndSyntaxForTest(CSharpCompilation compilation) - where TSyntaxNode : SyntaxNode - { - var tree = compilation.SyntaxTrees[0]; - var model = compilation.GetSemanticModel(tree); - SyntaxNode syntaxNode = GetSyntaxNodeOfTypeForBinding(GetSyntaxNodeList(tree)); - if (syntaxNode == null) - { - return (null, null); - } - - return (model.GetOperationInternal(syntaxNode), syntaxNode); - } - - protected string GetOperationTreeForTest(CSharpCompilation compilation) - where TSyntaxNode : SyntaxNode - { - var (operation, syntax) = GetOperationAndSyntaxForTest(compilation); - return operation != null ? OperationTreeVerifier.GetOperationTree(operation) : null; - } - - protected string GetOperationTreeForTest(IOperation operation) - { - return operation != null ? OperationTreeVerifier.GetOperationTree(operation) : null; - } - - protected string GetOperationTreeForTest(string testSrc, string expectedOperationTree, CSharpCompilationOptions compilationOptions = null, CSharpParseOptions parseOptions = null) - where TSyntaxNode : SyntaxNode - { - var compilation = CreateStandardCompilation(testSrc, new[] { SystemCoreRef, ValueTupleRef, SystemRuntimeFacadeRef }, options: compilationOptions ?? TestOptions.ReleaseDll, parseOptions: parseOptions); - return GetOperationTreeForTest(compilation); - } - - protected void VerifyOperationTreeForTest(CSharpCompilation compilation, string expectedOperationTree, Action AdditionalOperationTreeVerifier = null) - where TSyntaxNode : SyntaxNode - { - var (actualOperation, syntaxNode) = GetOperationAndSyntaxForTest(compilation); - var actualOperationTree = GetOperationTreeForTest(actualOperation); - OperationTreeVerifier.Verify(expectedOperationTree, actualOperationTree); - AdditionalOperationTreeVerifier?.Invoke(actualOperation, compilation, syntaxNode); - } - - protected void VerifyOperationTreeForTest(string testSrc, string expectedOperationTree, CSharpCompilationOptions compilationOptions = null, CSharpParseOptions parseOptions = null) - where TSyntaxNode : SyntaxNode - { - var actualOperationTree = GetOperationTreeForTest(testSrc, expectedOperationTree, compilationOptions, parseOptions); - OperationTreeVerifier.Verify(expectedOperationTree, actualOperationTree); - } - - protected void VerifyOperationTreeAndDiagnosticsForTest(CSharpCompilation compilation, string expectedOperationTree, DiagnosticDescription[] expectedDiagnostics, Action AdditionalOperationTreeVerifier = null) - where TSyntaxNode : SyntaxNode - { - var actualDiagnostics = compilation.GetDiagnostics().Where(d => d.Severity != DiagnosticSeverity.Hidden); - actualDiagnostics.Verify(expectedDiagnostics); - VerifyOperationTreeForTest(compilation, expectedOperationTree, AdditionalOperationTreeVerifier); - } - - private static readonly MetadataReference[] s_defaultOperationReferences = new[] { SystemRef, SystemCoreRef, ValueTupleRef, SystemRuntimeFacadeRef }; - - protected void VerifyOperationTreeAndDiagnosticsForTest(string testSrc, - string expectedOperationTree, - DiagnosticDescription[] expectedDiagnostics, - CSharpCompilationOptions compilationOptions = null, - CSharpParseOptions parseOptions = null, - MetadataReference[] additionalReferences = null, - Action AdditionalOperationTreeVerifier = null) - where TSyntaxNode : SyntaxNode - { - var references = additionalReferences == null ? s_defaultOperationReferences : additionalReferences.Concat(s_defaultOperationReferences); - var compilation = CreateStandardCompilation(testSrc, references, sourceFileName: "file.cs", options: compilationOptions ?? TestOptions.ReleaseDll, parseOptions: parseOptions); - VerifyOperationTreeAndDiagnosticsForTest(compilation, expectedOperationTree, expectedDiagnostics, AdditionalOperationTreeVerifier); - } - - protected MetadataReference VerifyOperationTreeAndDiagnosticsForTestWithIL(string testSrc, - string ilSource, - string expectedOperationTree, - DiagnosticDescription[] expectedDiagnostics, - CSharpCompilationOptions compilationOptions = null, - CSharpParseOptions parseOptions = null, - MetadataReference[] additionalReferences = null, - Action AdditionalOperationTreeVerifier = null) - where TSyntaxNode : SyntaxNode - { - var ilReference = CreateMetadataReferenceFromIlSource(ilSource); - VerifyOperationTreeAndDiagnosticsForTest(testSrc, expectedOperationTree, expectedDiagnostics, compilationOptions, parseOptions, new[] { ilReference }, AdditionalOperationTreeVerifier); - return ilReference; - } } } diff --git a/src/Compilers/Test/Utilities/VisualBasic/BasicTestBase.vb b/src/Compilers/Test/Utilities/VisualBasic/BasicTestBase.vb index 795ccfcfe58b2..310de28acafc3 100644 --- a/src/Compilers/Test/Utilities/VisualBasic/BasicTestBase.vb +++ b/src/Compilers/Test/Utilities/VisualBasic/BasicTestBase.vb @@ -788,4 +788,59 @@ Public MustInherit Class BasicTestBaseBase End Function End Class +#Region "IOperation tree validation" + + Friend Shared Function GetOperationTreeForTest(Of TSyntaxNode As SyntaxNode)(compilation As VisualBasicCompilation, fileName As String, Optional which As Integer = 0) As String + Dim node As SyntaxNode = CompilationUtils.FindBindingText(Of TSyntaxNode)(compilation, fileName, which, prefixMatch:=True) + If node Is Nothing Then + Return Nothing + End If + + Dim tree = (From t In compilation.SyntaxTrees Where t.FilePath = fileName).Single() + Dim semanticModel = compilation.GetSemanticModel(tree) + Dim operation = semanticModel.GetOperationInternal(node) + Return If(operation IsNot Nothing, OperationTreeVerifier.GetOperationTree(operation), Nothing) + End Function + + Friend Shared Function GetOperationTreeForTest(Of TSyntaxNode As SyntaxNode)(testSrc As String, Optional compilationOptions As VisualBasicCompilationOptions = Nothing, Optional parseOptions As VisualBasicParseOptions = Nothing, Optional which As Integer = 0) As String + Dim fileName = "a.vb" + Dim syntaxTree = Parse(testSrc, fileName, parseOptions) + Dim compilation = CreateCompilationWithMscorlib45AndVBRuntime({syntaxTree}, references:=DefaultVbReferences.Append({ValueTupleRef, SystemRuntimeFacadeRef}), options:=If(compilationOptions, TestOptions.ReleaseDll)) + Return GetOperationTreeForTest(Of TSyntaxNode)(compilation, fileName, which) + End Function + + Friend Shared Sub VerifyOperationTreeForTest(Of TSyntaxNode As SyntaxNode)(compilation As VisualBasicCompilation, fileName As String, expectedOperationTree As String, Optional which As Integer = 0) + Dim actualOperationTree = GetOperationTreeForTest(Of TSyntaxNode)(compilation, fileName, which) + OperationTreeVerifier.Verify(expectedOperationTree, actualOperationTree) + End Sub + + Friend Shared Sub VerifyOperationTreeForTest(Of TSyntaxNode As SyntaxNode)(testSrc As String, expectedOperationTree As String, Optional compilationOptions As VisualBasicCompilationOptions = Nothing, Optional parseOptions As VisualBasicParseOptions = Nothing, Optional which As Integer = 0) + Dim actualOperationTree = GetOperationTreeForTest(Of TSyntaxNode)(testSrc, compilationOptions, parseOptions, which) + OperationTreeVerifier.Verify(expectedOperationTree, actualOperationTree) + End Sub + + Friend Shared Sub VerifyNoOperationTreeForTest(Of TSyntaxNode As SyntaxNode)(testSrc As String, Optional compilationOptions As VisualBasicCompilationOptions = Nothing, Optional parseOptions As VisualBasicParseOptions = Nothing, Optional which As Integer = 0) + Dim actualOperationTree = GetOperationTreeForTest(Of TSyntaxNode)(testSrc, compilationOptions, parseOptions, which) + Assert.Null(actualOperationTree) + End Sub + + Friend Shared Sub VerifyOperationTreeAndDiagnosticsForTest(Of TSyntaxNode As SyntaxNode)(compilation As VisualBasicCompilation, fileName As String, expectedOperationTree As String, expectedDiagnostics As String, Optional which As Integer = 0) + compilation.AssertTheseDiagnostics(FilterString(expectedDiagnostics)) + VerifyOperationTreeForTest(Of TSyntaxNode)(compilation, fileName, expectedOperationTree, which) + End Sub + + Friend Shared Sub VerifyOperationTreeAndDiagnosticsForTest(Of TSyntaxNode As SyntaxNode)(testSrc As String, expectedOperationTree As String, expectedDiagnostics As String, Optional compilationOptions As VisualBasicCompilationOptions = Nothing, Optional parseOptions As VisualBasicParseOptions = Nothing, Optional which As Integer = 0, Optional additionalReferences As IEnumerable(Of MetadataReference) = Nothing) + Dim fileName = "a.vb" + Dim syntaxTree = Parse(testSrc, fileName, parseOptions) + Dim references = DefaultVbReferences.Concat({ValueTupleRef, SystemRuntimeFacadeRef}) + references = If(additionalReferences IsNot Nothing, references.Concat(additionalReferences), references) + Dim compilation = CreateCompilationWithMscorlib45AndVBRuntime({syntaxTree}, references:=references, options:=If(compilationOptions, TestOptions.ReleaseDll)) + VerifyOperationTreeAndDiagnosticsForTest(Of TSyntaxNode)(compilation, fileName, expectedOperationTree, expectedDiagnostics, which) + End Sub + + Public Shared Function GetAssertTheseDiagnosticsString(allDiagnostics As ImmutableArray(Of Diagnostic), suppressInfos As Boolean) As String + Return DumpAllDiagnostics(allDiagnostics, suppressInfos) + End Function +#End Region + End Class diff --git a/src/Compilers/Test/Utilities/VisualBasic/SemanticModelTestBase.vb b/src/Compilers/Test/Utilities/VisualBasic/SemanticModelTestBase.vb index 0e7f292fd9e34..53d1e9dfb8ba1 100644 --- a/src/Compilers/Test/Utilities/VisualBasic/SemanticModelTestBase.vb +++ b/src/Compilers/Test/Utilities/VisualBasic/SemanticModelTestBase.vb @@ -153,54 +153,4 @@ Public MustInherit Class SemanticModelTestBase : Inherits BasicTestBase binding.LookupSymbols(position, container, name, includeReducedExtensionMethods) ).Where(Function(s) anyArity OrElse DirectCast(s, Symbol).GetArity() = arity.Value).ToList() End Function - - Friend Function GetOperationTreeForTest(Of TSyntaxNode As SyntaxNode)(compilation As VisualBasicCompilation, fileName As String, Optional which As Integer = 0) As String - Dim node As SyntaxNode = CompilationUtils.FindBindingText(Of TSyntaxNode)(compilation, fileName, which, prefixMatch:=True) - If node Is Nothing Then - Return Nothing - End If - - Dim tree = (From t In compilation.SyntaxTrees Where t.FilePath = fileName).Single() - Dim semanticModel = compilation.GetSemanticModel(tree) - Dim operation = semanticModel.GetOperationInternal(node) - Return If(operation IsNot Nothing, OperationTreeVerifier.GetOperationTree(operation), Nothing) - End Function - - Friend Function GetOperationTreeForTest(Of TSyntaxNode As SyntaxNode)(testSrc As String, Optional compilationOptions As VisualBasicCompilationOptions = Nothing, Optional parseOptions As VisualBasicParseOptions = Nothing, Optional which As Integer = 0) As String - Dim fileName = "a.vb" - Dim syntaxTree = Parse(testSrc, fileName, parseOptions) - Dim compilation = CreateCompilationWithMscorlib45AndVBRuntime({syntaxTree}, references:=DefaultVbReferences.Append({ValueTupleRef, SystemRuntimeFacadeRef}), options:=If(compilationOptions, TestOptions.ReleaseDll)) - Return GetOperationTreeForTest(Of TSyntaxNode)(compilation, fileName, which) - End Function - - Friend Sub VerifyOperationTreeForTest(Of TSyntaxNode As SyntaxNode)(compilation As VisualBasicCompilation, fileName As String, expectedOperationTree As String, Optional which As Integer = 0) - Dim actualOperationTree = GetOperationTreeForTest(Of TSyntaxNode)(compilation, fileName, which) - OperationTreeVerifier.Verify(expectedOperationTree, actualOperationTree) - End Sub - - Friend Sub VerifyOperationTreeForTest(Of TSyntaxNode As SyntaxNode)(testSrc As String, expectedOperationTree As String, Optional compilationOptions As VisualBasicCompilationOptions = Nothing, Optional parseOptions As VisualBasicParseOptions = Nothing, Optional which As Integer = 0) - Dim actualOperationTree = GetOperationTreeForTest(Of TSyntaxNode)(testSrc, compilationOptions, parseOptions, which) - OperationTreeVerifier.Verify(expectedOperationTree, actualOperationTree) - End Sub - - Friend Sub VerifyNoOperationTreeForTest(Of TSyntaxNode As SyntaxNode)(testSrc As String, Optional compilationOptions As VisualBasicCompilationOptions = Nothing, Optional parseOptions As VisualBasicParseOptions = Nothing, Optional which As Integer = 0) - Dim actualOperationTree = GetOperationTreeForTest(Of TSyntaxNode)(testSrc, compilationOptions, parseOptions, which) - Assert.Null(actualOperationTree) - End Sub - - Friend Sub VerifyOperationTreeAndDiagnosticsForTest(Of TSyntaxNode As SyntaxNode)(compilation As VisualBasicCompilation, fileName As String, expectedOperationTree As String, expectedDiagnostics As String, Optional which As Integer = 0) - compilation.AssertTheseDiagnostics(FilterString(expectedDiagnostics)) - VerifyOperationTreeForTest(Of TSyntaxNode)(compilation, fileName, expectedOperationTree, which) - End Sub - - Friend Sub VerifyOperationTreeAndDiagnosticsForTest(Of TSyntaxNode As SyntaxNode)(testSrc As String, expectedOperationTree As String, expectedDiagnostics As String, Optional compilationOptions As VisualBasicCompilationOptions = Nothing, Optional parseOptions As VisualBasicParseOptions = Nothing, Optional which As Integer = 0) - Dim fileName = "a.vb" - Dim syntaxTree = Parse(testSrc, fileName, parseOptions) - Dim compilation = CreateCompilationWithMscorlib45AndVBRuntime({syntaxTree}, references:=DefaultVbReferences.Append({ValueTupleRef, SystemRuntimeFacadeRef}), options:=If(compilationOptions, TestOptions.ReleaseDll)) - VerifyOperationTreeAndDiagnosticsForTest(Of TSyntaxNode)(compilation, fileName, expectedOperationTree, expectedDiagnostics, which) - End Sub - - Public Shared Function GetAssertTheseDiagnosticsString(allDiagnostics As ImmutableArray(Of Diagnostic), suppressInfos As Boolean) As String - Return DumpAllDiagnostics(allDiagnostics, suppressInfos) - End Function End Class diff --git a/src/Compilers/VisualBasic/Portable/Operations/VisualBasicOperationFactory.vb b/src/Compilers/VisualBasic/Portable/Operations/VisualBasicOperationFactory.vb index f530acf4228d5..0969ffc39c890 100644 --- a/src/Compilers/VisualBasic/Portable/Operations/VisualBasicOperationFactory.vb +++ b/src/Compilers/VisualBasic/Portable/Operations/VisualBasicOperationFactory.vb @@ -166,6 +166,12 @@ Namespace Microsoft.CodeAnalysis.Semantics Return CreateBoundInterpolatedStringExpressionOperation(DirectCast(boundNode, BoundInterpolatedStringExpression)) Case BoundKind.Interpolation Return CreateBoundInterpolationOperation(DirectCast(boundNode, BoundInterpolation)) + Case BoundKind.AnonymousTypeCreationExpression + Return CreateBoundAnonymousTypeCreationExpressionOperation(DirectCast(boundNode, BoundAnonymousTypeCreationExpression)) + Case BoundKind.AnonymousTypeFieldInitializer + Return Create(DirectCast(boundNode, BoundAnonymousTypeFieldInitializer).Value) + Case BoundKind.AnonymousTypePropertyAccess + Return CreateBoundAnonymousTypePropertyAccessOperation(DirectCast(boundNode, BoundAnonymousTypePropertyAccess)) Case Else Dim constantValue = ConvertToOptional(TryCast(boundNode, BoundExpression)?.ConstantValueOpt) Return Operation.CreateOperationNone(boundNode.HasErrors, boundNode.Syntax, constantValue, Function() GetIOperationChildren(boundNode)) @@ -1068,6 +1074,31 @@ Namespace Microsoft.CodeAnalysis.Semantics Dim constantValue As [Optional](Of Object) = Nothing Return New LazyInterpolatedStringText(text, isInvalid, syntax, type, constantValue) End Function + + Private Function CreateBoundAnonymousTypeCreationExpressionOperation(boundAnonymousTypeCreationExpression As BoundAnonymousTypeCreationExpression) As IAnonymousObjectCreationExpression + Dim initializers As Lazy(Of ImmutableArray(Of IOperation)) = New Lazy(Of ImmutableArray(Of IOperation))( + Function() + Return GetAnonymousTypeCreationInitializers(boundAnonymousTypeCreationExpression) + End Function) + + Dim isInvalid As Boolean = boundAnonymousTypeCreationExpression.HasErrors + Dim syntax As SyntaxNode = boundAnonymousTypeCreationExpression.Syntax + Dim type As ITypeSymbol = boundAnonymousTypeCreationExpression.Type + Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundAnonymousTypeCreationExpression.ConstantValueOpt) + Return New LazyAnonymousObjectCreationExpression(initializers, isInvalid, syntax, type, constantValue) + End Function + + Private Function CreateBoundAnonymousTypePropertyAccessOperation(boundAnonymousTypePropertyAccess As BoundAnonymousTypePropertyAccess) As IPropertyReferenceExpression + Dim instance As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Nothing) + Dim [property] As IPropertySymbol = DirectCast(boundAnonymousTypePropertyAccess.ExpressionSymbol, IPropertySymbol) + Dim member As ISymbol = boundAnonymousTypePropertyAccess.ExpressionSymbol + Dim argumentsInEvaluationOrder As Lazy(Of ImmutableArray(Of IArgument)) = New Lazy(Of ImmutableArray(Of IArgument))(Function() ImmutableArray(Of IArgument).Empty) + Dim isInvalid As Boolean = boundAnonymousTypePropertyAccess.HasErrors + Dim syntax As SyntaxNode = boundAnonymousTypePropertyAccess.Syntax + Dim type As ITypeSymbol = boundAnonymousTypePropertyAccess.Type + Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundAnonymousTypePropertyAccess.ConstantValueOpt) + Return New LazyPropertyReferenceExpression([property], instance, member, argumentsInEvaluationOrder, isInvalid, syntax, type, constantValue) + End Function End Class End Namespace diff --git a/src/Compilers/VisualBasic/Portable/Operations/VisualBasicOperationFactory_Methods.vb b/src/Compilers/VisualBasic/Portable/Operations/VisualBasicOperationFactory_Methods.vb index 5b7da31ef7b13..d65d2dbb7e96b 100644 --- a/src/Compilers/VisualBasic/Portable/Operations/VisualBasicOperationFactory_Methods.vb +++ b/src/Compilers/VisualBasic/Portable/Operations/VisualBasicOperationFactory_Methods.vb @@ -158,6 +158,29 @@ Namespace Microsoft.CodeAnalysis.Semantics Return If(expression.InitializerOpt IsNot Nothing, expression.InitializerOpt.Initializers.SelectAsArray(Function(n) Create(n)), ImmutableArray(Of IOperation).Empty) End Function + Private Function GetAnonymousTypeCreationInitializers(expression As BoundAnonymousTypeCreationExpression) As ImmutableArray(Of IOperation) + Debug.Assert(expression.Arguments.Length >= expression.Declarations.Length) + + Dim builder = ArrayBuilder(Of IOperation).GetInstance(expression.Arguments.Length) + For i As Integer = 0 To expression.Arguments.Length - 1 + Dim value As IOperation = Create(expression.Arguments(i)) + If i >= expression.Declarations.Length Then + builder.Add(value) + Continue For + End If + + Dim target As IOperation = Create(expression.Declarations(i)) + Dim isInvalid = target.IsInvalid OrElse value.IsInvalid + Dim syntax As SyntaxNode = If(value.Syntax?.Parent, expression.Syntax) + Dim type As ITypeSymbol = target.Type + Dim constantValue As [Optional](Of Object) = value.ConstantValue + Dim assignment = New SimpleAssignmentExpression(target, value, isInvalid, syntax, type, constantValue) + builder.Add(assignment) + Next i + + Return builder.ToImmutableAndFree() + End Function + Private Function GetSwitchStatementCases(statement As BoundSelectStatement) As ImmutableArray(Of ISwitchCase) Return statement.CaseBlocks.SelectAsArray( Function(boundCaseBlock) diff --git a/src/Compilers/VisualBasic/Test/Semantic/IOperation/IOperationTests_IParameterReferenceExpression.vb b/src/Compilers/VisualBasic/Test/Semantic/IOperation/IOperationTests_IParameterReferenceExpression.vb index d13b4b47ae273..3d18d686acf07 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/IOperation/IOperationTests_IParameterReferenceExpression.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/IOperation/IOperationTests_IParameterReferenceExpression.vb @@ -45,11 +45,13 @@ Class Class1 End Class]]>.Value Dim expectedOperationTree = ) (Syntax: 'New With {' ... }') + Initializers(2): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32) (Syntax: 'Key .Amount = x') + Left: IPropertyReferenceExpression: ReadOnly Property .Amount As System.Int32 (Static) (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: 'Amount') + Right: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x') + ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.String) (Syntax: 'Key .Messag ... "Hello" + y') + Left: IPropertyReferenceExpression: ReadOnly Property .Message As System.String (Static) (OperationKind.PropertyReferenceExpression, Type: System.String) (Syntax: 'Message') + Right: IBinaryOperatorExpression (BinaryOperationKind.StringConcatenate) (OperationKind.BinaryOperatorExpression, Type: System.String) (Syntax: '"Hello" + y') Left: ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: "Hello") (Syntax: '"Hello"') Right: IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: System.String) (Syntax: 'y') ]]>.Value @@ -204,16 +206,16 @@ IOperation: (OperationKind.None) (Syntax: 'From y In x ... nto Count()') Arguments(2): IArgument (ArgumentKind.DefaultValue, Matching Parameter: keySelector) (OperationKind.Argument) (Syntax: 'x') IConversionExpression (ConversionKind.Basic, Implicit) (OperationKind.ConversionExpression, Type: System.Func(Of System.String, )) (Syntax: 'x') IOperation: (OperationKind.None) (Syntax: 'x') - Children(1): IOperation: (OperationKind.None) (Syntax: 'Group By w ... nto Count()') - Children(2): IOperation: (OperationKind.None) (Syntax: 'w = x') + Children(1): IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: ) (Syntax: 'Group By w ... nto Count()') + Initializers(2): IOperation: (OperationKind.None) (Syntax: 'w = x') Children(1): IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.String()) (Syntax: 'x') IOperation: (OperationKind.None) (Syntax: 'z = y') Children(1): IOperation: (OperationKind.None) (Syntax: 'y') IArgument (ArgumentKind.DefaultValue, Matching Parameter: resultSelector) (OperationKind.Argument) (Syntax: 'Group By w ... nto Count()') IConversionExpression (ConversionKind.Basic, Implicit) (OperationKind.ConversionExpression, Type: System.Func(Of , System.Collections.Generic.IEnumerable(Of System.String), )) (Syntax: 'Group By w ... nto Count()') IOperation: (OperationKind.None) (Syntax: 'Group By w ... nto Count()') - Children(1): IOperation: (OperationKind.None) (Syntax: 'Group By w ... nto Count()') - Children(3): IOperation: (OperationKind.None) (Syntax: 'w') + Children(1): IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: ) (Syntax: 'Group By w ... nto Count()') + Initializers(3): IOperation: (OperationKind.None) (Syntax: 'w') IOperation: (OperationKind.None) (Syntax: 'z') IOperation: (OperationKind.None) (Syntax: 'Count()') Children(1): IOperation: (OperationKind.None) (Syntax: 'Count()') diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/AnonymousTypesTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/AnonymousTypesTests.vb index 1656db801a6bd..0a936fa35f349 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/AnonymousTypesTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/AnonymousTypesTests.vb @@ -11,315 +11,426 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.ExtensionMethods Public Sub AnonymousTypeFieldsReferences() - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime( - - + Dim source = -) - - CompilationUtils.AssertNoErrors(compilation) +End Module]]>.Value + + Dim expectedOperationTree = ) (Syntax: 'New With {. ... = .b + .a}') + Initializers(3): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32, Constant: 1) (Syntax: '.a = 1') + Left: IPropertyReferenceExpression: Property .a As System.Int32 (Static) (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: 'a') + Right: ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1') + ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32) (Syntax: '.b = .a') + Left: IPropertyReferenceExpression: Property .b As System.Int32 (Static) (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: 'b') + Right: IPropertyReferenceExpression: Property .a As System.Int32 (Static) (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: '.a') + ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32) (Syntax: '.c = .b + .a') + Left: IPropertyReferenceExpression: Property .c As System.Int32 (Static) (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: 'c') + Right: IBinaryOperatorExpression (BinaryOperationKind.IntegerAdd) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: '.b + .a') + Left: IPropertyReferenceExpression: Property .b As System.Int32 (Static) (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: '.b') + Right: IPropertyReferenceExpression: Property .a As System.Int32 (Static) (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: '.a') +]]>.Value + + Dim expectedDiagnostics = String.Empty + + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub Public Sub AnonymousTypeErrorInFieldReference() - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime( - - + Dim source = -) - - CompilationUtils.AssertTheseDiagnostics(compilation, - +End Module]]>.Value + + Dim expectedOperationTree = , IsInvalid) (Syntax: 'New With {. ... s, .b = .a}') + Initializers(2): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: ?, IsInvalid) (Syntax: '.a = sss') + Left: IPropertyReferenceExpression: Property .a As ? (Static) (OperationKind.PropertyReferenceExpression, Type: ?) (Syntax: 'a') + Right: IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: 'sss') + ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: ?) (Syntax: '.b = .a') + Left: IPropertyReferenceExpression: Property .b As ? (Static) (OperationKind.PropertyReferenceExpression, Type: ?) (Syntax: 'b') + Right: IPropertyReferenceExpression: Property .a As ? (Static) (OperationKind.PropertyReferenceExpression, Type: ?) (Syntax: '.a') +]]>.Value + + Dim expectedDiagnostics = ) + Dim v1 As Object = New With {.a = sss, .b = .a}'BIND:"New With {.a = sss, .b = .a}" + ~~~ +]]>.Value + + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub Public Sub AnonymousTypeFieldOfRestrictedType() - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime( - - + Dim source = -) - - CompilationUtils.AssertTheseDiagnostics(compilation, - +End Module]]>.Value + + Dim expectedOperationTree = ) (Syntax: 'New With {.a = tr}') + Initializers(1): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.TypedReference) (Syntax: '.a = tr') + Left: IPropertyReferenceExpression: Property .a As System.TypedReference (Static) (OperationKind.PropertyReferenceExpression, Type: System.TypedReference) (Syntax: 'a') + Right: IParameterReferenceExpression: tr (OperationKind.ParameterReferenceExpression, Type: System.TypedReference) (Syntax: 'tr') + IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement) (Syntax: 'Dim v2 As O ... a = {{tr}}}') + IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'v2') + Variables: Local_1: v2 As System.Object + Initializer: IConversionExpression (ConversionKind.Basic, Implicit) (OperationKind.ConversionExpression, Type: System.Object) (Syntax: 'New With {.a = {{tr}}}') + IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: ) (Syntax: 'New With {.a = {{tr}}}') + Initializers(1): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.TypedReference(,)) (Syntax: '.a = {{tr}}') + Left: IPropertyReferenceExpression: Property .a As System.TypedReference(,) (Static) (OperationKind.PropertyReferenceExpression, Type: System.TypedReference(,)) (Syntax: 'a') + Right: IArrayCreationExpression (Element Type: System.TypedReference) (OperationKind.ArrayCreationExpression, Type: System.TypedReference(,)) (Syntax: '{{tr}}') + Dimension Sizes(2): ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '{{tr}}') + ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '{{tr}}') + Initializer: IArrayInitializer (1 elements) (OperationKind.ArrayInitializer) (Syntax: '{{tr}}') + Element Values(1): IArrayInitializer (1 elements) (OperationKind.ArrayInitializer) (Syntax: '{tr}') + Element Values(1): IParameterReferenceExpression: tr (OperationKind.ParameterReferenceExpression, Type: System.TypedReference) (Syntax: 'tr') + ILabelStatement (Label: exit) (OperationKind.LabelStatement) (Syntax: 'End Sub') + IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'End Sub') +]]>.Value + + Dim expectedDiagnostics = ) + Dim v2 As Object = New With {.a = {{tr}}} + ~~~~~~ +]]>.Value + + VerifyOperationTreeAndDiagnosticsForTest(Of MethodBlockSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub Public Sub AnonymousTypeReferenceToOuterTypeField() - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime( - - + Dim source = -) - - CompilationUtils.AssertTheseDiagnostics(compilation, - -BC36557: 'a' is not a member of '<anonymous type>'; it does not exist in the current context. - Dim c = New With {.a = 1, .b = New With {.c = .a}} +End Module]]>.Value + + Dim expectedOperationTree = >, IsInvalid) (Syntax: 'New With {. ... {.c = .a}}') + Initializers(2): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32, Constant: 1) (Syntax: '.a = 1') + Left: IPropertyReferenceExpression: Property >.a As System.Int32 (Static) (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: 'a') + Right: ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1') + ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: , IsInvalid) (Syntax: '.b = New With {.c = .a}') + Left: IPropertyReferenceExpression: Property >.b As (Static) (OperationKind.PropertyReferenceExpression, Type: ) (Syntax: 'b') + Right: IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: , IsInvalid) (Syntax: 'New With {.c = .a}') + Initializers(1): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: ?, IsInvalid) (Syntax: '.c = .a') + Left: IPropertyReferenceExpression: Property .c As ? (Static) (OperationKind.PropertyReferenceExpression, Type: ?) (Syntax: 'c') + Right: IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: '.a') +]]>.Value + + Dim expectedDiagnostics = '; it does not exist in the current context. + Dim c = New With {.a = 1, .b = New With {.c = .a}}'BIND:"New With {.a = 1, .b = New With {.c = .a}}" ~~ -) +]]>.Value + + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub Public Sub AnonymousTypeFieldReferenceOutOfOrder01() - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime( - - + Dim source = -) - - CompilationUtils.AssertTheseDiagnostics(compilation, - +End Module]]>.Value + + Dim expectedOperationTree = , IsInvalid) (Syntax: 'New With {. ... c, .c = .b}') + Initializers(2): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: ?, IsInvalid) (Syntax: '.b = .c') + Left: IPropertyReferenceExpression: Property .b As ? (Static) (OperationKind.PropertyReferenceExpression, Type: ?) (Syntax: 'b') + Right: IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: '.c') + ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: ?) (Syntax: '.c = .b') + Left: IPropertyReferenceExpression: Property .c As ? (Static) (OperationKind.PropertyReferenceExpression, Type: ?) (Syntax: 'c') + Right: IPropertyReferenceExpression: Property .b As ? (Static) (OperationKind.PropertyReferenceExpression, Type: ?) (Syntax: '.b') +]]>.Value + + Dim expectedDiagnostics = ) +]]>.Value + + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub Public Sub AnonymousTypeFieldReferenceOutOfOrder02() - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime( - - + Dim source = -) - - CompilationUtils.AssertTheseDiagnostics(compilation, - +End Module]]>.Value + + Dim expectedOperationTree = , IsInvalid) (Syntax: 'New With {. ... .c, .c = 1}') + Initializers(2): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: ?, IsInvalid) (Syntax: '.b = .c') + Left: IPropertyReferenceExpression: Property .b As ? (Static) (OperationKind.PropertyReferenceExpression, Type: ?) (Syntax: 'b') + Right: IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: '.c') + ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32, Constant: 1) (Syntax: '.c = 1') + Left: IPropertyReferenceExpression: Property .c As System.Int32 (Static) (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: 'c') + Right: ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1') +]]>.Value + + Dim expectedDiagnostics = ) +]]>.Value + + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub Public Sub AnonymousTypeFieldInitializedWithInstanceMethod() - ' WARNING: NO ERROR IN DEV10 - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime( - - + Dim source = -) - - CompilationUtils.AssertTheseDiagnostics(compilation, - -BC36557: 'ToString' is not a member of '<anonymous type>'; it does not exist in the current context. - Dim b = New With {.a = .ToString()} +End Module]]>.Value + + Dim expectedOperationTree = , IsInvalid) (Syntax: 'New With {. ... ToString()}') + Initializers(1): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: ?, IsInvalid) (Syntax: '.a = .ToString()') + Left: IPropertyReferenceExpression: Property .a As ? (Static) (OperationKind.PropertyReferenceExpression, Type: ?) (Syntax: 'a') + Right: IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: '.ToString()') + Children(1): IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: '.ToString') +]]>.Value + + Dim expectedDiagnostics = '; it does not exist in the current context. + Dim b = New With {.a = .ToString()}'BIND:"New With {.a = .ToString()}" ~~~~~~~~~ -) +]]>.Value + + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub Public Sub AnonymousTypeFieldInitializedWithSharedMethod() - ' WARNING: NO ERROR IN DEV10 - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime( - - + Dim source = -) - - CompilationUtils.AssertTheseDiagnostics(compilation, - -BC36557: 'ReferenceEquals' is not a member of '<anonymous type>'; it does not exist in the current context. - Dim b = New With {.a = .ReferenceEquals(Nothing, Nothing)} +End Module]]>.Value + + Dim expectedOperationTree = , IsInvalid) (Syntax: 'New With {. ... , Nothing)}') + Initializers(1): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: ?, IsInvalid) (Syntax: '.a = .Refer ... g, Nothing)') + Left: IPropertyReferenceExpression: Property .a As ? (Static) (OperationKind.PropertyReferenceExpression, Type: ?) (Syntax: 'a') + Right: IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: '.ReferenceE ... g, Nothing)') + Children(3): IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: '.ReferenceEquals') + ILiteralExpression (OperationKind.LiteralExpression, Type: null, Constant: null) (Syntax: 'Nothing') + ILiteralExpression (OperationKind.LiteralExpression, Type: null, Constant: null) (Syntax: 'Nothing') +]]>.Value + + Dim expectedDiagnostics = '; it does not exist in the current context. + Dim b = New With {.a = .ReferenceEquals(Nothing, Nothing)}'BIND:"New With {.a = .ReferenceEquals(Nothing, Nothing)}" ~~~~~~~~~~~~~~~~ -) +]]>.Value + + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub Public Sub AnonymousTypeFieldInitializedWithExtensionMethod() - ' WARNING: NO ERROR IN DEV10 - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntimeAndReferences( - - + Dim source = Public Function EM(o As Object) As String Return "!" End Function -End Module - -, {SystemCoreRef}) - - CompilationUtils.AssertTheseDiagnostics(compilation, - -BC36557: 'EM' is not a member of '<anonymous type>'; it does not exist in the current context. - Dim a = New With {.a = .EM()} +End Module]]>.Value + + Dim expectedOperationTree = , IsInvalid) (Syntax: 'New With {.a = .EM()}') + Initializers(1): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: ?, IsInvalid) (Syntax: '.a = .EM()') + Left: IPropertyReferenceExpression: Property .a As ? (Static) (OperationKind.PropertyReferenceExpression, Type: ?) (Syntax: 'a') + Right: IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: '.EM()') + Children(1): IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: '.EM') +]]>.Value + + Dim expectedDiagnostics = '; it does not exist in the current context. + Dim a = New With {.a = .EM()}'BIND:"New With {.a = .EM()}" ~~~ -) +]]>.Value + + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub Public Sub AnonymousTypeFieldInitializedWithConstructorCall() - ' WARNING: Dev10 reports BC30282 - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntimeAndReferences( - - + Dim source = -, {SystemCoreRef}) - - CompilationUtils.AssertTheseDiagnostics(compilation, - -BC36557: 'New' is not a member of '<anonymous type>'; it does not exist in the current context. - Dim a = New With {.a = .New()} +End Module]]>.Value + + Dim expectedOperationTree = , IsInvalid) (Syntax: 'New With {.a = .New()}') + Initializers(1): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: ?, IsInvalid) (Syntax: '.a = .New()') + Left: IPropertyReferenceExpression: Property .a As ? (Static) (OperationKind.PropertyReferenceExpression, Type: ?) (Syntax: 'a') + Right: IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: '.New()') + Children(1): IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: '.New') +]]>.Value + + Dim expectedDiagnostics = '; it does not exist in the current context. + Dim a = New With {.a = .New()}'BIND:"New With {.a = .New()}" ~~~~ -) +]]>.Value + + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub Public Sub AnonymousTypeFieldOfVoidType() - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime( - - + Dim source = -) +End Module]]>.Value + + Dim expectedOperationTree = , IsInvalid) (Syntax: 'New With {. ... SubName()}') + Initializers(1): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: ?, IsInvalid) (Syntax: '.a = SubName()') + Left: IPropertyReferenceExpression: Property .a As ? (Static) (OperationKind.PropertyReferenceExpression, Type: ?) (Syntax: 'a') + Right: IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: 'SubName()') + Children(1): IInvocationExpression (static Sub ModuleA.SubName()) (OperationKind.InvocationExpression, Type: System.Void) (Syntax: 'SubName()') +]]>.Value - CompilationUtils.AssertTheseDiagnostics(compilation, - + Dim expectedDiagnostics = ) +]]>.Value + + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub Public Sub AnonymousTypeFieldNameWithGeneric() - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime( - - + Dim source = -) - - CompilationUtils.AssertTheseDiagnostics(compilation, - +End Module]]>.Value + + Dim expectedOperationTree = , IsInvalid) (Syntax: 'New With {. ... f Integer)}') + Initializers(2): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32, Constant: 1) (Syntax: '.a = 1') + Left: IPropertyReferenceExpression: Property .a As System.Int32 (Static) (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: 'a') + Right: ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1') + ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32, IsInvalid) (Syntax: '.b = .a(Of Integer)') + Left: IPropertyReferenceExpression: Property .b As System.Int32 (Static) (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: 'b') + Right: IPropertyReferenceExpression: Property .a As System.Int32 (Static) (OperationKind.PropertyReferenceExpression, Type: System.Int32, IsInvalid) (Syntax: '.a(Of Integer)') +]]>.Value + + Dim expectedDiagnostics = ) +]]>.Value + + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub Public Sub AnonymousTypeFieldWithSyntaxError() - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime( - - + Dim source = -) +End Module]]>.Value + + Dim expectedOperationTree = , IsInvalid) (Syntax: 'New With {.a = .}') + Initializers(1): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: ?, IsInvalid) (Syntax: '.a = .') + Left: IPropertyReferenceExpression: Property .a As ? (Static) (OperationKind.PropertyReferenceExpression, Type: ?) (Syntax: 'a') + Right: IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: '.') +]]>.Value - CompilationUtils.AssertTheseDiagnostics(compilation, - + Dim expectedDiagnostics = ) +]]>.Value + + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub Public Sub AnonymousTypeFieldWithNothingLiteral() - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime( - - + Dim source = -) +End Module]]>.Value + + Dim expectedOperationTree = ) (Syntax: 'New With {.a = Nothing}') + Initializers(1): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Object, Constant: null) (Syntax: '.a = Nothing') + Left: IPropertyReferenceExpression: Property .a As System.Object (Static) (OperationKind.PropertyReferenceExpression, Type: System.Object) (Syntax: 'a') + Right: IConversionExpression (ConversionKind.Basic, Implicit) (OperationKind.ConversionExpression, Type: System.Object, Constant: null) (Syntax: 'Nothing') + ILiteralExpression (OperationKind.LiteralExpression, Type: null, Constant: null) (Syntax: 'Nothing') +]]>.Value - CompilationUtils.AssertNoErrors(compilation) + Dim expectedDiagnostics = String.Empty + + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub - Public Sub AnonymousTypeFieldNameInferenceFromGeneric01() - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime( - - + Dim source = -) +End Module]]>.Value + + Dim expectedOperationTree = ) (Syntax: 'New With {N ... f Integer)}') + Initializers(1): IInvocationExpression ( Function AM.A.F(Of System.Int32)() As System.Int32) (OperationKind.InvocationExpression, Type: System.Int32) (Syntax: 'New A().F(Of Integer)') + Instance Receiver: IObjectCreationExpression (Constructor: Sub AM.A..ctor()) (OperationKind.ObjectCreationExpression, Type: AM.A) (Syntax: 'New A()') +]]>.Value - 'BC36556: Anonymous type member name can be inferred only from a simple or qualified name with no arguments. - compilation.VerifyDiagnostics(Diagnostic(ERRID.ERR_AnonymousTypeFieldNameInference, "New A().F(Of Integer)")) + Dim expectedDiagnostics = .Value + + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub Public Sub AnonymousTypeFieldNameInferenceFromXml01() - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntimeAndReferences( - - } + Dim b = New With {}'BIND:"New With {}" End Sub End Module - ]]> -, additionalRefs:=XmlReferences) +]]>.Value - CompilationUtils.AssertTheseDiagnostics(compilation, -) (Syntax: 'New With {< ... some-name>}') + Initializers(1): IOperation: (OperationKind.None) (Syntax: '') +]]>.Value + + Dim expectedDiagnostics = } + Dim b = New With {}'BIND:"New With {}" ~~~~~~~~~~~~~~~~~~~~~~~ -]]>) +]]>.Value + + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics, additionalReferences:=XmlReferences) End Sub Public Sub AnonymousTypeFieldNameInferenceFromXml02() - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntimeAndReferences( - - .@aa} + Dim b = New With {.@aa}'BIND:"New With {.@aa}" End Sub -End Module - ]]> -, additionalRefs:=XmlReferences) +End Module]]>.Value + + Dim expectedOperationTree = ) (Syntax: 'New With {< ... -name>.@aa}') + Initializers(1): IOperation: (OperationKind.None) (Syntax: ' ... e-name>.@aa') +]]>.Value + + Dim expectedDiagnostics = String.Empty - CompilationUtils.AssertNoErrors(compilation) + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics, additionalReferences:=XmlReferences) End Sub Public Sub AnonymousTypeFieldNameInferenceFromXml03() - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntimeAndReferences( - - .@} + Dim b = New With {.@}'BIND:"New With {.@}" End Sub -End Module - ]]> -, additionalRefs:=XmlReferences) +End Module]]>.Value + + Dim expectedOperationTree = ) (Syntax: 'New With {< ... me>.@}') + Initializers(1): IOperation: (OperationKind.None) (Syntax: '.@') +]]>.Value - CompilationUtils.AssertTheseDiagnostics(compilation, -.@} + Dim b = New With {.@}'BIND:"New With {.@}" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -]]>) +]]>.Value + + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics, additionalReferences:=XmlReferences) End Sub Public Sub AnonymousTypeFieldNameInferenceFromXml04() - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntimeAndReferences( - - .<_>} Dim ok = New With {.<__>} End Sub -End Module - ]]> -, additionalRefs:=XmlReferences) - - CompilationUtils.AssertTheseDiagnostics(compilation, -.Value + + Dim expectedOperationTree = + Local_2: ok As + IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement) (Syntax: 'Dim err = N ... {.<_>}') + IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'err') + Variables: Local_1: err As + Initializer: IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: ) (Syntax: 'New With {.<_>}') + Initializers(1): IOperation: (OperationKind.None) (Syntax: '.<_>') + IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement) (Syntax: 'Dim ok = Ne ... {.<__>}') + IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'ok') + Variables: Local_1: ok As + Initializer: IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: ) (Syntax: 'New With {.<__>}') + Initializers(1): IOperation: (OperationKind.None) (Syntax: '.<__>') + ILabelStatement (Label: exit) (OperationKind.LabelStatement) (Syntax: 'End Sub') + IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'End Sub') +]]>.Value + + Dim expectedDiagnostics = .<_>} ~~~~~~~~ -]]>) +]]>.Value + + VerifyOperationTreeAndDiagnosticsForTest(Of MethodBlockSyntax)(source, expectedOperationTree, expectedDiagnostics, additionalReferences:=XmlReferences) End Sub Public Sub AnonymousTypeFieldNameInferenceFromExpression01() - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime( - - + Dim source = -) +End Module]]>.Value - CompilationUtils.AssertTheseDiagnostics(compilation, - + Dim expectedOperationTree = ) (Syntax: 'New With {a * 2}') + Initializers(1): IBinaryOperatorExpression (BinaryOperationKind.IntegerMultiply) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: 'a * 2') + Left: ILocalReferenceExpression: a (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'a') + Right: ILiteralExpression (Text: 2) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 2) (Syntax: '2') +]]>.Value + + Dim expectedDiagnostics = ) + Dim b = New With {a * 2}'BIND:"New With {a * 2}" + ~~~~~ +]]>.Value + + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub Public Sub AnonymousTypeFieldNameInferenceFromExpression02() - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime( - - + Dim source = -) - CompilationUtils.AssertTheseDiagnostics(compilation, - +End Module]]>.Value + + Dim expectedOperationTree = ) (Syntax: 'New With {.a = 1, a}') + Initializers(2): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32, Constant: 1) (Syntax: '.a = 1') + Left: IPropertyReferenceExpression: Property .a As System.Int32 (Static) (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: 'a') + Right: ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1') + ILocalReferenceExpression: a (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'a') +]]>.Value + + Dim expectedDiagnostics = ) + Dim b = New With {.a = 1, a}'BIND:"New With {.a = 1, a}" + ~ +]]>.Value + + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub Public Sub AnonymousTypeFieldNameInferenceFromExpression03() - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime( - - + Dim source = -) - CompilationUtils.AssertTheseDiagnostics(compilation, - +End Module]]>.Value + + Dim expectedOperationTree = ) (Syntax: 'New With {a ... D, a.FLD()}') + Initializers(2): IPropertyReferenceExpression: Property ModuleA.S.FLD As System.Int32 (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: 'a.FLD') + Instance Receiver: ILocalReferenceExpression: a (OperationKind.LocalReferenceExpression, Type: ModuleA.S) (Syntax: 'a') + IPropertyReferenceExpression: Property ModuleA.S.FLD As System.Int32 (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: 'a.FLD()') + Instance Receiver: ILocalReferenceExpression: a (OperationKind.LocalReferenceExpression, Type: ModuleA.S) (Syntax: 'a') +]]>.Value + + Dim expectedDiagnostics = ) + Dim b = New With {a.FLD, a.FLD()}'BIND:"New With {a.FLD, a.FLD()}" + ~~~~~~~ +]]>.Value + + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub Public Sub AnonymousTypeFieldNameInferenceFromExpression04() - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime( - - + Dim source = -) - - CompilationUtils.AssertTheseDiagnostics(compilation, - +End Module]]>.Value + + Dim expectedOperationTree = ) (Syntax: 'New With {.x = 1, a!x}') + Initializers(2): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32, Constant: 1) (Syntax: '.x = 1') + Left: IPropertyReferenceExpression: Property .x As System.Int32 (Static) (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: 'x') + Right: ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1') + IPropertyReferenceExpression: Property System.Collections.Generic.Dictionary(Of System.String, System.Int32).Item(key As System.String) As System.Int32 (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: 'a!x') + Instance Receiver: ILocalReferenceExpression: a (OperationKind.LocalReferenceExpression, Type: System.Collections.Generic.Dictionary(Of System.String, System.Int32)) (Syntax: 'a') + Arguments(1): IArgument (ArgumentKind.Explicit, Matching Parameter: key) (OperationKind.Argument) (Syntax: 'x') + ILiteralExpression (Text: x) (OperationKind.LiteralExpression, Type: System.String, Constant: "x") (Syntax: 'x') +]]>.Value + + Dim expectedDiagnostics = ) +]]>.Value + + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub Public Sub AnonymousTypeFieldInitializedWithAddressOf() - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime( - - + Dim source = -) +End Module]]>.Value - CompilationUtils.AssertTheseDiagnostics(compilation, - + Dim expectedOperationTree = , IsInvalid) (Syntax: 'New With {K ... ddressOf S}') + Initializers(1): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: ?, IsInvalid) (Syntax: 'Key .a = AddressOf S') + Left: IPropertyReferenceExpression: ReadOnly Property .a As ? (Static) (OperationKind.PropertyReferenceExpression, Type: ?) (Syntax: 'a') + Right: IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: 'AddressOf S') + Children(1): IOperation: (OperationKind.None) (Syntax: 'AddressOf S') +]]>.Value + + Dim expectedDiagnostics = ) +]]>.Value + + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub Public Sub AnonymousTypeFieldInitializedWithDelegate01() - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime( - - + Dim source = -) - - CompilationUtils.AssertTheseDiagnostics(compilation, - +End Module]]>.Value + + ' The IOperation tree for this test seems to have an unexpected ILocalReferenceExpression within ILambdaExpression. + ' See https://github.com/dotnet/roslyn/issues/20357. + Dim expectedOperationTree = , IsInvalid) (Syntax: 'New With {' ... ).Invoke()}') + Initializers(2): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.String, Constant: "--value--") (Syntax: 'Key .x = "--value--"') + Left: IPropertyReferenceExpression: ReadOnly Property .x As System.String (Static) (OperationKind.PropertyReferenceExpression, Type: System.String) (Syntax: 'x') + Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: "--value--") (Syntax: '"--value--"') + ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.String, IsInvalid) (Syntax: 'Key .a = Di ... )).Invoke()') + Left: IPropertyReferenceExpression: ReadOnly Property .a As System.String (Static) (OperationKind.PropertyReferenceExpression, Type: System.String) (Syntax: 'a') + Right: IInvocationExpression (virtual Function System.Func(Of System.String).Invoke() As System.String) (OperationKind.InvocationExpression, Type: System.String, IsInvalid) (Syntax: 'DirectCast( ... )).Invoke()') + Instance Receiver: IConversionExpression (ConversionKind.Cast, Explicit) (OperationKind.ConversionExpression, Type: System.Func(Of System.String), IsInvalid) (Syntax: 'DirectCast( ... Of String))') + ILambdaExpression (Signature: Function () As System.String) (OperationKind.LambdaExpression, Type: null, IsInvalid) (Syntax: 'Function() ... nd Function') + IBlockStatement (3 statements, 1 locals) (OperationKind.BlockStatement) (Syntax: 'Function() ... nd Function') + Locals: Local_1: As System.String + IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'Return .x.ToString()') + IInvocationExpression (virtual Function System.String.ToString() As System.String) (OperationKind.InvocationExpression, Type: System.String) (Syntax: '.x.ToString()') + Instance Receiver: IPropertyReferenceExpression: ReadOnly Property .x As System.String (Static) (OperationKind.PropertyReferenceExpression, Type: System.String) (Syntax: '.x') + ILabelStatement (Label: exit) (OperationKind.LabelStatement) (Syntax: 'End Function') + IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'End Function') + ILocalReferenceExpression: (OperationKind.LocalReferenceExpression, Type: System.String) (Syntax: 'End Function') +]]>.Value + + Dim expectedDiagnostics = ) +]]>.Value + + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub Public Sub AnonymousTypeFieldInitializedWithDelegate02() - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime( - - + Dim source = -) - - CompilationUtils.AssertTheseDiagnostics(compilation, - +End Module]]>.Value + + ' The IOperation tree for this test seems to have an unexpected ILocalReferenceExpression within ILambdaExpression. + ' See https://github.com/dotnet/roslyn/issues/20357. + Dim expectedOperationTree = , IsInvalid) (Syntax: 'New With {' ... ).Invoke()}') + Initializers(1): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.String, IsInvalid) (Syntax: 'Key .a = Di ... )).Invoke()') + Left: IPropertyReferenceExpression: ReadOnly Property .a As System.String (Static) (OperationKind.PropertyReferenceExpression, Type: System.String) (Syntax: 'a') + Right: IInvocationExpression (virtual Function System.Func(Of System.String).Invoke() As System.String) (OperationKind.InvocationExpression, Type: System.String, IsInvalid) (Syntax: 'DirectCast( ... )).Invoke()') + Instance Receiver: IConversionExpression (ConversionKind.Cast, Explicit) (OperationKind.ConversionExpression, Type: System.Func(Of System.String), IsInvalid) (Syntax: 'DirectCast( ... Of String))') + ILambdaExpression (Signature: Function () As System.String) (OperationKind.LambdaExpression, Type: null, IsInvalid) (Syntax: 'Function() ... nd Function') + IBlockStatement (3 statements, 1 locals) (OperationKind.BlockStatement, IsInvalid) (Syntax: 'Function() ... nd Function') + Locals: Local_1: As System.String + IReturnStatement (OperationKind.ReturnStatement, IsInvalid) (Syntax: 'Return .a.ToString()') + IConversionExpression (ConversionKind.Basic, Implicit) (OperationKind.ConversionExpression, Type: System.String, IsInvalid) (Syntax: '.a.ToString()') + IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: '.a.ToString()') + Children(1): IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: '.a.ToString') + Children(1): IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: '.a.ToString') + Children(1): IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: '.a') + ILabelStatement (Label: exit) (OperationKind.LabelStatement) (Syntax: 'End Function') + IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'End Function') + ILocalReferenceExpression: (OperationKind.LocalReferenceExpression, Type: System.String) (Syntax: 'End Function') +]]>.Value + + Dim expectedDiagnostics = ) +]]>.Value + + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub Public Sub AnonymousTypeFieldInitializedWithDelegate03() - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime( - - + Dim source = -) - - CompilationUtils.AssertTheseDiagnostics(compilation, - -BC36557: 'x' is not a member of '<anonymous type>'; it does not exist in the current context. +End Module]]>.Value + + ' The IOperation tree for this test seems to have an unexpected ILocalReferenceExpression within ILambdaExpression. + ' See https://github.com/dotnet/roslyn/issues/20357. + Dim expectedOperationTree = , IsInvalid) (Syntax: 'New With {' ... ).Invoke()}') + Initializers(1): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.String, IsInvalid) (Syntax: 'Key .a = Di ... )).Invoke()') + Left: IPropertyReferenceExpression: ReadOnly Property .a As System.String (Static) (OperationKind.PropertyReferenceExpression, Type: System.String) (Syntax: 'a') + Right: IInvocationExpression (virtual Function System.Func(Of System.String).Invoke() As System.String) (OperationKind.InvocationExpression, Type: System.String, IsInvalid) (Syntax: 'DirectCast( ... )).Invoke()') + Instance Receiver: IConversionExpression (ConversionKind.Cast, Explicit) (OperationKind.ConversionExpression, Type: System.Func(Of System.String), IsInvalid) (Syntax: 'DirectCast( ... Of String))') + ILambdaExpression (Signature: Function () As System.String) (OperationKind.LambdaExpression, Type: null, IsInvalid) (Syntax: 'Function() ... nd Function') + IBlockStatement (3 statements, 1 locals) (OperationKind.BlockStatement, IsInvalid) (Syntax: 'Function() ... nd Function') + Locals: Local_1: As System.String + IReturnStatement (OperationKind.ReturnStatement, IsInvalid) (Syntax: 'Return .x.ToString()') + IConversionExpression (ConversionKind.Basic, Implicit) (OperationKind.ConversionExpression, Type: System.String, IsInvalid) (Syntax: '.x.ToString()') + IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: '.x.ToString()') + Children(1): IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: '.x.ToString') + Children(1): IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: '.x.ToString') + Children(1): IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: '.x') + ILabelStatement (Label: exit) (OperationKind.LabelStatement) (Syntax: 'End Function') + IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'End Function') + ILocalReferenceExpression: (OperationKind.LocalReferenceExpression, Type: System.String) (Syntax: 'End Function') +]]>.Value + + Dim expectedDiagnostics = '; it does not exist in the current context. Return .x.ToString() ~~ -) +]]>.Value + + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub Public Sub AnonymousTypeFieldInitializedWithDelegate04() - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime( - - + Dim source = -) - - CompilationUtils.AssertTheseDiagnostics(compilation, - -BC36557: 'x' is not a member of '<anonymous type>'; it does not exist in the current context. +End Module]]>.Value + + ' The IOperation tree for this test seems to have an unexpected ILocalReferenceExpression within ILambdaExpression. + ' See https://github.com/dotnet/roslyn/issues/20357. + Dim expectedOperationTree = , IsInvalid) (Syntax: 'New With {' ... ).Invoke()}') + Initializers(1): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.String, IsInvalid) (Syntax: 'Key .a = Di ... )).Invoke()') + Left: IPropertyReferenceExpression: ReadOnly Property .a As System.String (Static) (OperationKind.PropertyReferenceExpression, Type: System.String) (Syntax: 'a') + Right: IInvocationExpression (virtual Function System.Func(Of System.String).Invoke() As System.String) (OperationKind.InvocationExpression, Type: System.String, IsInvalid) (Syntax: 'DirectCast( ... )).Invoke()') + Instance Receiver: IConversionExpression (ConversionKind.Cast, Explicit) (OperationKind.ConversionExpression, Type: System.Func(Of System.String), IsInvalid) (Syntax: 'DirectCast( ... Of String))') + ILambdaExpression (Signature: Function () As System.String) (OperationKind.LambdaExpression, Type: null, IsInvalid) (Syntax: 'Function() ... nd Function') + IBlockStatement (3 statements, 1 locals) (OperationKind.BlockStatement, IsInvalid) (Syntax: 'Function() ... nd Function') + Locals: Local_1: As System.String + IReturnStatement (OperationKind.ReturnStatement, IsInvalid) (Syntax: 'Return Dire ... )).Invoke()') + IInvocationExpression (virtual Function System.Func(Of System.String).Invoke() As System.String) (OperationKind.InvocationExpression, Type: System.String, IsInvalid) (Syntax: 'DirectCast( ... )).Invoke()') + Instance Receiver: IConversionExpression (ConversionKind.Cast, Explicit) (OperationKind.ConversionExpression, Type: System.Func(Of System.String), IsInvalid) (Syntax: 'DirectCast( ... Of String))') + ILambdaExpression (Signature: Function () As System.String) (OperationKind.LambdaExpression, Type: null, IsInvalid) (Syntax: 'Function() ... nd Function') + IBlockStatement (3 statements, 1 locals) (OperationKind.BlockStatement, IsInvalid) (Syntax: 'Function() ... nd Function') + Locals: Local_1: As System.String + IReturnStatement (OperationKind.ReturnStatement, IsInvalid) (Syntax: 'Return .x.ToString()') + IConversionExpression (ConversionKind.Basic, Implicit) (OperationKind.ConversionExpression, Type: System.String, IsInvalid) (Syntax: '.x.ToString()') + IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: '.x.ToString()') + Children(1): IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: '.x.ToString') + Children(1): IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: '.x.ToString') + Children(1): IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: '.x') + ILabelStatement (Label: exit) (OperationKind.LabelStatement) (Syntax: 'End Function') + IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'End Function') + ILocalReferenceExpression: (OperationKind.LocalReferenceExpression, Type: System.String) (Syntax: 'End Function') + ILabelStatement (Label: exit) (OperationKind.LabelStatement) (Syntax: 'End Function') + IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'End Function') + ILocalReferenceExpression: (OperationKind.LocalReferenceExpression, Type: System.String) (Syntax: 'End Function') +]]>.Value + + Dim expectedDiagnostics = '; it does not exist in the current context. Return .x.ToString() ~~ -) +]]>.Value + + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub Public Sub LambdaReturningAnonymousType() - Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime( - - + Dim source = -, TestOptions.ReleaseExe) +End Module]]>.Value + + Dim expectedOperationTree = ) (Syntax: 'New With {. ... t = "Test"}') + Initializers(1): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.String, Constant: "Test") (Syntax: '.Default = "Test"') + Left: IPropertyReferenceExpression: Property .Default As System.String (Static) (OperationKind.PropertyReferenceExpression, Type: System.String) (Syntax: 'Default') + Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: "Test") (Syntax: '"Test"') +]]>.Value - CompilationUtils.AssertNoErrors(compilation) + Dim expectedDiagnostics = String.Empty - CompileAndVerify(compilation, expectedOutput:=) + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) End Sub @@ -683,6 +941,35 @@ End Module Dim verifier = CompileAndVerify(compilation, expectedOutput:="{ x2 = 0 }") End Sub + + Public Sub AnonymousTypeInALambdaInGenericMethod1_OperationTree() + Dim source = .Value + + Dim expectedOperationTree = ) (Syntax: 'New With {x2}') + Initializers(1): ILocalReferenceExpression: x2 (OperationKind.LocalReferenceExpression, Type: T) (Syntax: 'x2') +]]>.Value + + Dim expectedDiagnostics = String.Empty + + VerifyOperationTreeAndDiagnosticsForTest(Of AnonymousObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics) + End Sub + Public Sub AnonymousTypeInALambdaInGenericMethod2() diff --git a/src/Test/Utilities/Portable/Compilation/OperationTreeVerifier.cs b/src/Test/Utilities/Portable/Compilation/OperationTreeVerifier.cs index 70776bedb3c38..2e10f00144236 100644 --- a/src/Test/Utilities/Portable/Compilation/OperationTreeVerifier.cs +++ b/src/Test/Utilities/Portable/Compilation/OperationTreeVerifier.cs @@ -877,6 +877,14 @@ public override void VisitObjectCreationExpression(IObjectCreationExpression ope VisitArray(operation.Initializers, "Initializers", logElementCount: true); } + public override void VisitAnonymousObjectCreationExpression(IAnonymousObjectCreationExpression operation) + { + LogString(nameof(IAnonymousObjectCreationExpression)); + LogCommonPropertiesAndNewLine(operation); + + VisitArray(operation.Initializers, "Initializers", logElementCount: true); + } + public override void VisitFieldInitializer(IFieldInitializer operation) { LogString(nameof(IFieldInitializer)); diff --git a/src/Test/Utilities/Portable/Compilation/TestOperationWalker.cs b/src/Test/Utilities/Portable/Compilation/TestOperationWalker.cs index 97cc7ad90b072..1276260bac784 100644 --- a/src/Test/Utilities/Portable/Compilation/TestOperationWalker.cs +++ b/src/Test/Utilities/Portable/Compilation/TestOperationWalker.cs @@ -416,6 +416,11 @@ public override void VisitObjectCreationExpression(IObjectCreationExpression ope base.VisitObjectCreationExpression(operation); } + public override void VisitAnonymousObjectCreationExpression(IAnonymousObjectCreationExpression operation) + { + base.VisitAnonymousObjectCreationExpression(operation); + } + public override void VisitFieldInitializer(IFieldInitializer operation) { foreach (var field in operation.InitializedFields)