From 0b73276c5179ead5c53ec33e1307c6a4ab38c222 Mon Sep 17 00:00:00 2001 From: CyrusNajmabadi Date: Wed, 5 Oct 2016 11:58:54 -0700 Subject: [PATCH] Support locations being provided for Tuples and Anonymous types. Support setting if an anonymous type's properties are mutable or not. --- .../Portable/Compilation/CSharpCompilation.cs | 87 +++++++--------- .../AnonymousType.PropertySymbol.cs | 8 -- .../Symbol/Compilation/CompilationAPITests.cs | 48 +++++++++ .../Core/Portable/Compilation/Compilation.cs | 98 +++++++++++++++++-- .../Core/Portable/PublicAPI.Unshipped.txt | 4 +- .../Compilation/VisualBasicCompilation.vb | 59 ++++------- .../Compilation/CompilationAPITests.vb | 54 +++++++++- 7 files changed, 251 insertions(+), 107 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs b/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs index bc6294b669a..9937c7b6acc 100644 --- a/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs +++ b/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs @@ -1,15 +1,5 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using Microsoft.CodeAnalysis.CodeGen; -using Microsoft.CodeAnalysis.Collections; -using Microsoft.CodeAnalysis.CSharp.Emit; -using Microsoft.CodeAnalysis.CSharp.Symbols; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.Emit; -using Microsoft.CodeAnalysis.Symbols; -using Microsoft.CodeAnalysis.Text; -using Roslyn.Utilities; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -21,6 +11,16 @@ using System.Reflection.Metadata; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeGen; +using Microsoft.CodeAnalysis.Collections; +using Microsoft.CodeAnalysis.CSharp.Emit; +using Microsoft.CodeAnalysis.CSharp.Symbols; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Emit; +using Microsoft.CodeAnalysis.Symbols; +using Microsoft.CodeAnalysis.Text; +using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp { @@ -2703,55 +2703,21 @@ protected override IPointerTypeSymbol CommonCreatePointerTypeSymbol(ITypeSymbol return CreatePointerTypeSymbol(elementType.EnsureCSharpSymbolOrNull("elementType")); } - protected override INamedTypeSymbol CommonCreateTupleTypeSymbol(ImmutableArray elementTypes, ImmutableArray elementNames) + protected override INamedTypeSymbol CommonCreateTupleTypeSymbol( + ImmutableArray elementTypes, + ImmutableArray elementNames, + ImmutableArray elementLocations) { - if (elementTypes.IsDefault) - { - throw new ArgumentNullException(nameof(elementTypes)); - } - - if (elementTypes.Length <= 1) - { - throw new ArgumentException(CodeAnalysisResources.TuplesNeedAtLeastTwoElements, nameof(elementNames)); - } - elementNames = CheckTupleElementNames(elementTypes.Length, elementNames); var typesBuilder = ArrayBuilder.GetInstance(elementTypes.Length); for (int i = 0; i < elementTypes.Length; i++) { - if (elementTypes[i] == null) - { - throw new ArgumentNullException($"{nameof(elementTypes)}[{i}]"); - } - typesBuilder.Add(elementTypes[i].EnsureCSharpSymbolOrNull($"{nameof(elementTypes)}[{i}]")); } return TupleTypeSymbol.Create(null, // no location for the type declaration - typesBuilder.ToImmutableAndFree(), default(ImmutableArray), elementNames, this); - } - - /// - /// Check that if any names are provided, and their number matches the expected cardinality. - /// Returns a normalized version of the element names (empty array if all the names are null). - /// - private static ImmutableArray CheckTupleElementNames(int cardinality, ImmutableArray elementNames) - { - if (!elementNames.IsDefault) - { - if (elementNames.Length != cardinality) - { - throw new ArgumentException(CodeAnalysisResources.TupleElementNameCountMismatch, nameof(elementNames)); - } - - if (elementNames.All(n => n == null)) - { - return default(ImmutableArray); - } - } - - return elementNames; + typesBuilder.ToImmutableAndFree(), elementLocations, elementNames, this); } protected override INamedTypeSymbol CommonCreateTupleTypeSymbol(INamedTypeSymbol underlyingType, ImmutableArray elementNames) @@ -2775,15 +2741,32 @@ protected override INamedTypeSymbol CommonCreateTupleTypeSymbol(INamedTypeSymbol } protected override INamedTypeSymbol CommonCreateAnonymousTypeSymbol( - ImmutableArray memberTypes, ImmutableArray memberNames) + ImmutableArray memberTypes, + ImmutableArray memberNames, + ImmutableArray memberLocations, + ImmutableArray memberIsReadOnly) { for (int i = 0, n = memberTypes.Length; i < n; i++) { memberTypes[i].EnsureCSharpSymbolOrNull($"{nameof(memberTypes)}[{i}]"); } - var fields = memberTypes.ZipAsArray(memberNames, (type, name) => new AnonymousTypeField(name, Location.None, (TypeSymbol)type)); - var descriptor = new AnonymousTypeDescriptor(fields, Location.None); + if (!memberIsReadOnly.IsDefault && memberIsReadOnly.Any(v => !v)) + { + throw new ArgumentException($"Non-ReadOnly members are not supported in C# anonymous types."); + } + + var fields = ArrayBuilder.GetInstance(); + + for (int i = 0, n = memberTypes.Length; i < n; i++) + { + var type = memberTypes[i]; + var name = memberNames[i]; + var location = memberLocations.IsDefault ? Location.None : memberLocations[i]; + fields.Add(new AnonymousTypeField(name, location, (TypeSymbol)type)); + } + + var descriptor = new AnonymousTypeDescriptor(fields.ToImmutableAndFree(), Location.None); return this.AnonymousTypeManager.ConstructAnonymousTypeSymbol(descriptor); } diff --git a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.PropertySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.PropertySymbol.cs index 6f57ce352de..f4b3db18d2c 100644 --- a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.PropertySymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.PropertySymbol.cs @@ -1,15 +1,7 @@ // 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.Concurrent; -using System.Collections.Generic; using System.Collections.Immutable; -using System.Diagnostics; -using System.Linq; -using System.Text; -using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp.Symbols diff --git a/src/Compilers/CSharp/Test/Symbol/Compilation/CompilationAPITests.cs b/src/Compilers/CSharp/Test/Symbol/Compilation/CompilationAPITests.cs index 37cf845ea5f..55d0b389a63 100644 --- a/src/Compilers/CSharp/Test/Symbol/Compilation/CompilationAPITests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Compilation/CompilationAPITests.cs @@ -2218,6 +2218,54 @@ public void CreateAnonymousType_IncorrectLengths() ImmutableArray.Create("m1", "m2"))); } + [Fact()] + public void CreateAnonymousType_IncorrectLengths_IsReadOnly() + { + var compilation = CSharpCompilation.Create("HelloWorld"); + Assert.Throws(() => + compilation.CreateAnonymousTypeSymbol( + ImmutableArray.Create((ITypeSymbol)compilation.GetSpecialType(SpecialType.System_Int32), + (ITypeSymbol)compilation.GetSpecialType(SpecialType.System_Int32)), + ImmutableArray.Create("m1", "m2"), + ImmutableArray.Create(true))); + } + + [Fact()] + public void CreateAnonymousType_IncorrectLengths_Locations() + { + var compilation = CSharpCompilation.Create("HelloWorld"); + Assert.Throws(() => + compilation.CreateAnonymousTypeSymbol( + ImmutableArray.Create((ITypeSymbol)compilation.GetSpecialType(SpecialType.System_Int32), + (ITypeSymbol)compilation.GetSpecialType(SpecialType.System_Int32)), + ImmutableArray.Create("m1", "m2"), + memberLocations: ImmutableArray.Create(Location.None))); + } + + [Fact()] + public void CreateAnonymousType_WritableProperty() + { + var compilation = CSharpCompilation.Create("HelloWorld"); + Assert.Throws(() => + compilation.CreateAnonymousTypeSymbol( + ImmutableArray.Create((ITypeSymbol)compilation.GetSpecialType(SpecialType.System_Int32), + (ITypeSymbol)compilation.GetSpecialType(SpecialType.System_Int32)), + ImmutableArray.Create("m1", "m2"), + ImmutableArray.Create(false, false))); + } + + [Fact()] + public void CreateAnonymousType_NullLocations() + { + var compilation = CSharpCompilation.Create("HelloWorld"); + Assert.Throws(() => + compilation.CreateAnonymousTypeSymbol( + ImmutableArray.Create((ITypeSymbol)compilation.GetSpecialType(SpecialType.System_Int32), + (ITypeSymbol)compilation.GetSpecialType(SpecialType.System_Int32)), + ImmutableArray.Create("m1", "m2"), + memberLocations: ImmutableArray.Create(Location.None, null))); + } + [Fact()] public void CreateAnonymousType_NullArgument1() { diff --git a/src/Compilers/Core/Portable/Compilation/Compilation.cs b/src/Compilers/Core/Portable/Compilation/Compilation.cs index d5b3550c8a2..d655e3dbaf6 100644 --- a/src/Compilers/Core/Portable/Compilation/Compilation.cs +++ b/src/Compilers/Core/Portable/Compilation/Compilation.cs @@ -824,15 +824,75 @@ public INamedTypeSymbol GetTypeByMetadataName(string fullyQualifiedMetadataName) protected abstract INamedTypeSymbol CommonGetTypeByMetadataName(string metadataName); +#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters /// /// Returns a new INamedTypeSymbol with the given element types and (optional) element names. /// - public INamedTypeSymbol CreateTupleTypeSymbol(ImmutableArray elementTypes, ImmutableArray elementNames = default(ImmutableArray)) + public INamedTypeSymbol CreateTupleTypeSymbol( + ImmutableArray elementTypes, + ImmutableArray elementNames = default(ImmutableArray), + ImmutableArray elementLocations = default(ImmutableArray)) { - return CommonCreateTupleTypeSymbol(elementTypes, elementNames); + if (elementTypes.IsDefault) + { + throw new ArgumentNullException(nameof(elementTypes)); + } + + if (elementTypes.Length <= 1) + { + throw new ArgumentException(CodeAnalysisResources.TuplesNeedAtLeastTwoElements, nameof(elementNames)); + } + + elementNames = CheckTupleElementNames(elementTypes.Length, elementNames); + + if (!elementLocations.IsDefault && elementLocations.Length != elementTypes.Length) + { + throw new ArgumentException($"{nameof(elementLocations)} must either be 'default' or have the same length as {nameof(elementTypes)}."); + } + + for (int i = 0, n = elementTypes.Length; i < n; i++) + { + if (elementTypes[i] == null) + { + throw new ArgumentNullException($"{nameof(elementTypes)}[{i}]"); + } + + if (!elementLocations.IsDefault && elementLocations[i] == null) + { + throw new ArgumentNullException($"{nameof(elementLocations)}[{i}]"); + } + } + + return CommonCreateTupleTypeSymbol(elementTypes, elementNames, elementLocations); } +#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters - protected abstract INamedTypeSymbol CommonCreateTupleTypeSymbol(ImmutableArray elementTypes, ImmutableArray elementNames); + /// + /// Check that if any names are provided, and their number matches the expected cardinality. + /// Returns a normalized version of the element names (empty array if all the names are null). + /// + protected static ImmutableArray CheckTupleElementNames(int cardinality, ImmutableArray elementNames) + { + if (!elementNames.IsDefault) + { + if (elementNames.Length != cardinality) + { + throw new ArgumentException(CodeAnalysisResources.TupleElementNameCountMismatch, nameof(elementNames)); + } + + if (elementNames.All(n => n == null)) + { + return default(ImmutableArray); + } + } + + return elementNames; + } + + protected abstract INamedTypeSymbol CommonCreateTupleTypeSymbol( + ImmutableArray elementTypes, + ImmutableArray elementNames, + ImmutableArray elementLocations); /// /// Returns a new INamedTypeSymbol with the given underlying type and (optional) element names. @@ -850,9 +910,17 @@ public INamedTypeSymbol CreateTupleTypeSymbol(INamedTypeSymbol underlyingType, I /// /// Returns a new anonymous type symbol with the given member types member names. + /// Anonymous type members will be readonly by default. Writable properties are + /// supported in VB and can be created by passing in false in the + /// appropriate locations in . + /// + /// Source locations can also be provided through /// public INamedTypeSymbol CreateAnonymousTypeSymbol( - ImmutableArray memberTypes, ImmutableArray memberNames) + ImmutableArray memberTypes, + ImmutableArray memberNames, + ImmutableArray memberIsReadOnly = default(ImmutableArray), + ImmutableArray memberLocations = default(ImmutableArray)) { if (memberTypes.IsDefault) { @@ -869,6 +937,16 @@ public INamedTypeSymbol CreateTupleTypeSymbol(INamedTypeSymbol underlyingType, I throw new ArgumentException($"{nameof(memberTypes)} and {nameof(memberNames)} must have the same length."); } + if (!memberLocations.IsDefault && memberLocations.Length != memberTypes.Length) + { + throw new ArgumentException($"{nameof(memberLocations)} must either be 'default' or have the same length as {nameof(memberNames)}."); + } + + if (!memberIsReadOnly.IsDefault && memberIsReadOnly.Length != memberTypes.Length) + { + throw new ArgumentException($"{nameof(memberIsReadOnly)} must either be 'default' or have the same length as {nameof(memberNames)}."); + } + for (int i = 0, n = memberTypes.Length; i < n; i++) { if (memberTypes[i] == null) @@ -880,13 +958,21 @@ public INamedTypeSymbol CreateTupleTypeSymbol(INamedTypeSymbol underlyingType, I { throw new ArgumentNullException($"{nameof(memberNames)}[{i}]"); } + + if (!memberLocations.IsDefault && memberLocations[i] == null) + { + throw new ArgumentNullException($"{nameof(memberLocations)}[{i}]"); + } } - return CommonCreateAnonymousTypeSymbol(memberTypes, memberNames); + return CommonCreateAnonymousTypeSymbol(memberTypes, memberNames, memberLocations, memberIsReadOnly); } protected abstract INamedTypeSymbol CommonCreateAnonymousTypeSymbol( - ImmutableArray memberTypes, ImmutableArray memberNames); + ImmutableArray memberTypes, + ImmutableArray memberNames, + ImmutableArray memberLocations, + ImmutableArray memberIsReadOnly); #endregion diff --git a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt index 4681388b0ab..96c5f93c930 100644 --- a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt @@ -9,9 +9,9 @@ Microsoft.CodeAnalysis.CommandLineArguments.DisplayVersion.get -> bool Microsoft.CodeAnalysis.CommandLineArguments.EmbeddedFiles.get -> System.Collections.Immutable.ImmutableArray Microsoft.CodeAnalysis.CommandLineArguments.SourceLink.get -> string -Microsoft.CodeAnalysis.Compilation.CreateAnonymousTypeSymbol(System.Collections.Immutable.ImmutableArray memberTypes, System.Collections.Immutable.ImmutableArray memberNames) -> Microsoft.CodeAnalysis.INamedTypeSymbol +Microsoft.CodeAnalysis.Compilation.CreateAnonymousTypeSymbol(System.Collections.Immutable.ImmutableArray memberTypes, System.Collections.Immutable.ImmutableArray memberNames, System.Collections.Immutable.ImmutableArray memberIsReadOnly = default(System.Collections.Immutable.ImmutableArray), System.Collections.Immutable.ImmutableArray memberLocations = default(System.Collections.Immutable.ImmutableArray)) -> Microsoft.CodeAnalysis.INamedTypeSymbol Microsoft.CodeAnalysis.Compilation.CreateTupleTypeSymbol(Microsoft.CodeAnalysis.INamedTypeSymbol underlyingType, System.Collections.Immutable.ImmutableArray elementNames = default(System.Collections.Immutable.ImmutableArray)) -> Microsoft.CodeAnalysis.INamedTypeSymbol -Microsoft.CodeAnalysis.Compilation.CreateTupleTypeSymbol(System.Collections.Immutable.ImmutableArray elementTypes, System.Collections.Immutable.ImmutableArray elementNames = default(System.Collections.Immutable.ImmutableArray)) -> Microsoft.CodeAnalysis.INamedTypeSymbol +Microsoft.CodeAnalysis.Compilation.CreateTupleTypeSymbol(System.Collections.Immutable.ImmutableArray elementTypes, System.Collections.Immutable.ImmutableArray elementNames = default(System.Collections.Immutable.ImmutableArray), System.Collections.Immutable.ImmutableArray elementLocations = default(System.Collections.Immutable.ImmutableArray)) -> Microsoft.CodeAnalysis.INamedTypeSymbol Microsoft.CodeAnalysis.Compilation.Emit(System.IO.Stream peStream, System.IO.Stream pdbStream = null, System.IO.Stream xmlDocumentationStream = null, System.IO.Stream win32Resources = null, System.Collections.Generic.IEnumerable manifestResources = null, Microsoft.CodeAnalysis.Emit.EmitOptions options = null, Microsoft.CodeAnalysis.IMethodSymbol debugEntryPoint = null, System.IO.Stream sourceLinkStream = null, System.Collections.Generic.IEnumerable embeddedTexts = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.CodeAnalysis.Emit.EmitResult Microsoft.CodeAnalysis.Compilation.Emit(System.IO.Stream peStream, System.IO.Stream pdbStream, System.IO.Stream xmlDocumentationStream, System.IO.Stream win32Resources, System.Collections.Generic.IEnumerable manifestResources, Microsoft.CodeAnalysis.Emit.EmitOptions options, Microsoft.CodeAnalysis.IMethodSymbol debugEntryPoint, System.Threading.CancellationToken cancellationToken) -> Microsoft.CodeAnalysis.Emit.EmitResult Microsoft.CodeAnalysis.CompilationOptions.WithConcurrentBuild(bool concurrent) -> Microsoft.CodeAnalysis.CompilationOptions diff --git a/src/Compilers/VisualBasic/Portable/Compilation/VisualBasicCompilation.vb b/src/Compilers/VisualBasic/Portable/Compilation/VisualBasicCompilation.vb index e8fc140794e..d626216756c 100644 --- a/src/Compilers/VisualBasic/Portable/Compilation/VisualBasicCompilation.vb +++ b/src/Compilers/VisualBasic/Portable/Compilation/VisualBasicCompilation.vb @@ -2577,45 +2577,19 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Return CreateArrayTypeSymbol(elementType.EnsureVbSymbolOrNothing(Of TypeSymbol)(NameOf(elementType)), rank) End Function - Protected Overrides Function CommonCreateTupleTypeSymbol(elementTypes As ImmutableArray(Of ITypeSymbol), elementNames As ImmutableArray(Of String)) As INamedTypeSymbol - If elementTypes.IsDefault Then - Throw New ArgumentNullException(NameOf(elementTypes)) - End If - - If elementTypes.Length <= 1 Then - Throw New ArgumentException(CodeAnalysisResources.TuplesNeedAtLeastTwoElements, NameOf(elementNames)) - End If - - elementNames = CheckTupleElementNames(elementTypes.Length, elementNames) - + Protected Overrides Function CommonCreateTupleTypeSymbol(elementTypes As ImmutableArray(Of ITypeSymbol), + elementNames As ImmutableArray(Of String), + elementLocations As ImmutableArray(Of Location)) As INamedTypeSymbol Dim typesBuilder = ArrayBuilder(Of TypeSymbol).GetInstance(elementTypes.Length) For i As Integer = 0 To elementTypes.Length - 1 - If elementTypes(i) Is Nothing Then - Throw New ArgumentNullException($"{NameOf(elementTypes)}[{i}]") - End If - typesBuilder.Add(elementTypes(i).EnsureVbSymbolOrNothing(Of TypeSymbol)($"{NameOf(elementTypes)}[{i}]")) Next 'no location for the type declaration - Return TupleTypeSymbol.Create(locationOpt:=Nothing, elementTypes:=typesBuilder.ToImmutableAndFree(), elementLocations:=Nothing, elementNames:=elementNames, compilation:=Me) - End Function - - ''' - ''' Check that if any names are provided, their number matches the expected cardinality and they are not null. - ''' - Private Shared Function CheckTupleElementNames(cardinality As Integer, elementNames As ImmutableArray(Of String)) As ImmutableArray(Of String) - If Not elementNames.IsDefault Then - If elementNames.Length <> cardinality Then - Throw New ArgumentException(CodeAnalysisResources.TupleElementNameCountMismatch, NameOf(elementNames)) - End If - - If elementNames.All(Function(n As String) n Is Nothing) Then - Return Nothing - End If - End If - - Return elementNames + Return TupleTypeSymbol.Create(locationOpt:=Nothing, + elementTypes:=typesBuilder.ToImmutableAndFree(), + elementLocations:=elementLocations, + elementNames:=elementNames, compilation:=Me) End Function Protected Overrides Function CommonCreateTupleTypeSymbol(underlyingType As INamedTypeSymbol, elementNames As ImmutableArray(Of String)) As INamedTypeSymbol @@ -2645,7 +2619,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Protected Overrides Function CommonCreateAnonymousTypeSymbol( memberTypes As ImmutableArray(Of ITypeSymbol), - memberNames As ImmutableArray(Of String)) As INamedTypeSymbol + memberNames As ImmutableArray(Of String), + memberLocations As ImmutableArray(Of Location), + memberIsReadOnly As ImmutableArray(Of Boolean)) As INamedTypeSymbol Dim i = 0 For Each t In memberTypes @@ -2654,11 +2630,18 @@ Namespace Microsoft.CodeAnalysis.VisualBasic i = i + 1 Next - Dim fields = memberTypes.ZipAsArray( - memberNames, - Function(type, name) New AnonymousTypeField(name, DirectCast(type, TypeSymbol), Location.None)) + Dim fields = ArrayBuilder(Of AnonymousTypeField).GetInstance() + + For i = 0 To memberTypes.Length - 1 + Dim type = memberTypes(i) + Dim name = memberNames(i) + Dim loc = If(memberLocations.IsDefault, Location.None, memberLocations(i)) + Dim isReadOnly = memberIsReadOnly.IsDefault OrElse memberIsReadOnly(i) + fields.Add(New AnonymousTypeField(name, DirectCast(type, TypeSymbol), loc, isReadOnly)) + Next - Dim descriptor = New AnonymousTypeDescriptor(fields, Location.None, isImplicitlyDeclared:=False) + Dim descriptor = New AnonymousTypeDescriptor( + fields.ToImmutableAndFree(), Location.None, isImplicitlyDeclared:=False) Return Me.AnonymousTypeManager.ConstructAnonymousTypeSymbol(descriptor) End Function diff --git a/src/Compilers/VisualBasic/Test/Semantic/Compilation/CompilationAPITests.vb b/src/Compilers/VisualBasic/Test/Semantic/Compilation/CompilationAPITests.vb index da6702c1659..4a876be9047 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Compilation/CompilationAPITests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Compilation/CompilationAPITests.vb @@ -1303,6 +1303,45 @@ BC2014: the value '_' is invalid for option 'RootNamespace' End Function) End Sub + + Public Sub CreateAnonymousType_IncorrectLengths_IsReadOnly() + Dim compilation = VisualBasicCompilation.Create("HelloWorld") + Assert.Throws(Of ArgumentException)( + Sub() + compilation.CreateAnonymousTypeSymbol( + ImmutableArray.Create(DirectCast(compilation.GetSpecialType(SpecialType.System_Int32), ITypeSymbol), + DirectCast(compilation.GetSpecialType(SpecialType.System_Int32), ITypeSymbol)), + ImmutableArray.Create("m1", "m2"), + ImmutableArray.Create(True)) + End Sub) + End Sub + + + Public sub CreateAnonymousType_IncorrectLengths_Locations() + Dim Compilation = VisualBasicCompilation.Create("HelloWorld") + Assert.Throws(Of ArgumentException)( + Sub() + Compilation.CreateAnonymousTypeSymbol( + ImmutableArray.Create(DirectCast(Compilation.GetSpecialType(SpecialType.System_Int32), ITypeSymbol), + DirectCast(Compilation.GetSpecialType(SpecialType.System_Int32), ITypeSymbol)), + ImmutableArray.Create("m1", "m2"), + memberLocations:=ImmutableArray.Create(Location.None)) + End Sub) + End Sub + + + Public Sub CreateAnonymousType_WritableProperty() + Dim compilation = VisualBasicCompilation.Create("HelloWorld") + Dim type = compilation.CreateAnonymousTypeSymbol( + ImmutableArray.Create(DirectCast(compilation.GetSpecialType(SpecialType.System_Int32), ITypeSymbol), + DirectCast(compilation.GetSpecialType(SpecialType.System_Int32), ITypeSymbol)), + ImmutableArray.Create("m1", "m2"), + ImmutableArray.Create(False, False)) + Assert.True(type.IsAnonymousType) + Assert.Equal(2, type.GetMembers().OfType(Of IPropertySymbol).Count()) + Assert.Equal("", type.ToDisplayString()) + End Sub + Public Sub CreateAnonymousType_NothingArgument() Dim compilation = VisualBasicCompilation.Create("HelloWorld") @@ -1321,6 +1360,19 @@ BC2014: the value '_' is invalid for option 'RootNamespace' ImmutableArray.Create(Of ITypeSymbol)(compilation.GetSpecialType(SpecialType.System_Int32)), ImmutableArray.Create("m1")) + Assert.True(type.IsAnonymousType) + Assert.Equal(1, type.GetMembers().OfType(Of IPropertySymbol).Count()) + Assert.Equal("", type.ToDisplayString()) + End Sub + + + Public Sub CreateMutableAnonymousType1() + Dim compilation = VisualBasicCompilation.Create("HelloWorld") + Dim type = compilation.CreateAnonymousTypeSymbol( + ImmutableArray.Create(Of ITypeSymbol)(compilation.GetSpecialType(SpecialType.System_Int32)), + ImmutableArray.Create("m1"), + ImmutableArray.Create(False)) + Assert.True(type.IsAnonymousType) Assert.Equal(1, type.GetMembers().OfType(Of IPropertySymbol).Count()) Assert.Equal("", type.ToDisplayString()) @@ -1335,7 +1387,7 @@ BC2014: the value '_' is invalid for option 'RootNamespace' Assert.True(type.IsAnonymousType) Assert.Equal(2, type.GetMembers().OfType(Of IPropertySymbol).Count()) - Assert.Equal("", type.ToDisplayString()) + Assert.Equal("", type.ToDisplayString()) End Sub -- GitLab