提交 0b73276c 编写于 作者: C CyrusNajmabadi

Support locations being provided for Tuples and Anonymous types.

Support setting if an anonymous type's properties are mutable or not.
上级 c232013b
// 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<ITypeSymbol, TypeSymbol>("elementType"));
}
protected override INamedTypeSymbol CommonCreateTupleTypeSymbol(ImmutableArray<ITypeSymbol> elementTypes, ImmutableArray<string> elementNames)
{
if (elementTypes.IsDefault)
{
throw new ArgumentNullException(nameof(elementTypes));
}
if (elementTypes.Length <= 1)
protected override INamedTypeSymbol CommonCreateTupleTypeSymbol(
ImmutableArray<ITypeSymbol> elementTypes,
ImmutableArray<string> elementNames,
ImmutableArray<Location> elementLocations)
{
throw new ArgumentException(CodeAnalysisResources.TuplesNeedAtLeastTwoElements, nameof(elementNames));
}
elementNames = CheckTupleElementNames(elementTypes.Length, elementNames);
var typesBuilder = ArrayBuilder<TypeSymbol>.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<ITypeSymbol, TypeSymbol>($"{nameof(elementTypes)}[{i}]"));
}
return TupleTypeSymbol.Create(null, // no location for the type declaration
typesBuilder.ToImmutableAndFree(), default(ImmutableArray<Location>), elementNames, this);
}
/// <summary>
/// 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).
/// </summary>
private static ImmutableArray<string> CheckTupleElementNames(int cardinality, ImmutableArray<string> elementNames)
{
if (!elementNames.IsDefault)
{
if (elementNames.Length != cardinality)
{
throw new ArgumentException(CodeAnalysisResources.TupleElementNameCountMismatch, nameof(elementNames));
}
if (elementNames.All(n => n == null))
{
return default(ImmutableArray<string>);
}
}
return elementNames;
typesBuilder.ToImmutableAndFree(), elementLocations, elementNames, this);
}
protected override INamedTypeSymbol CommonCreateTupleTypeSymbol(INamedTypeSymbol underlyingType, ImmutableArray<string> elementNames)
......@@ -2775,15 +2741,32 @@ protected override INamedTypeSymbol CommonCreateTupleTypeSymbol(INamedTypeSymbol
}
protected override INamedTypeSymbol CommonCreateAnonymousTypeSymbol(
ImmutableArray<ITypeSymbol> memberTypes, ImmutableArray<string> memberNames)
ImmutableArray<ITypeSymbol> memberTypes,
ImmutableArray<string> memberNames,
ImmutableArray<Location> memberLocations,
ImmutableArray<bool> memberIsReadOnly)
{
for (int i = 0, n = memberTypes.Length; i < n; i++)
{
memberTypes[i].EnsureCSharpSymbolOrNull<ITypeSymbol, TypeSymbol>($"{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<AnonymousTypeField>.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);
}
......
// 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
......
......@@ -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<ArgumentException>(() =>
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<ArgumentException>(() =>
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<ArgumentException>(() =>
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<ArgumentException>(() =>
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()
{
......
......@@ -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
/// <summary>
/// Returns a new INamedTypeSymbol with the given element types and (optional) element names.
/// </summary>
public INamedTypeSymbol CreateTupleTypeSymbol(ImmutableArray<ITypeSymbol> elementTypes, ImmutableArray<string> elementNames = default(ImmutableArray<string>))
public INamedTypeSymbol CreateTupleTypeSymbol(
ImmutableArray<ITypeSymbol> elementTypes,
ImmutableArray<string> elementNames = default(ImmutableArray<string>),
ImmutableArray<Location> elementLocations = default(ImmutableArray<Location>))
{
return CommonCreateTupleTypeSymbol(elementTypes, elementNames);
if (elementTypes.IsDefault)
{
throw new ArgumentNullException(nameof(elementTypes));
}
if (elementTypes.Length <= 1)
{
throw new ArgumentException(CodeAnalysisResources.TuplesNeedAtLeastTwoElements, nameof(elementNames));
}
protected abstract INamedTypeSymbol CommonCreateTupleTypeSymbol(ImmutableArray<ITypeSymbol> elementTypes, ImmutableArray<string> 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
/// <summary>
/// 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).
/// </summary>
protected static ImmutableArray<string> CheckTupleElementNames(int cardinality, ImmutableArray<string> elementNames)
{
if (!elementNames.IsDefault)
{
if (elementNames.Length != cardinality)
{
throw new ArgumentException(CodeAnalysisResources.TupleElementNameCountMismatch, nameof(elementNames));
}
if (elementNames.All(n => n == null))
{
return default(ImmutableArray<string>);
}
}
return elementNames;
}
protected abstract INamedTypeSymbol CommonCreateTupleTypeSymbol(
ImmutableArray<ITypeSymbol> elementTypes,
ImmutableArray<string> elementNames,
ImmutableArray<Location> elementLocations);
/// <summary>
/// Returns a new INamedTypeSymbol with the given underlying type and (optional) element names.
......@@ -850,9 +910,17 @@ public INamedTypeSymbol CreateTupleTypeSymbol(INamedTypeSymbol underlyingType, I
/// <summary>
/// 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 <code>false</code> in the
/// appropriate locations in <paramref name="memberIsReadOnly"/>.
///
/// Source locations can also be provided through <paramref name="memberLocations"/>
/// </summary>
public INamedTypeSymbol CreateAnonymousTypeSymbol(
ImmutableArray<ITypeSymbol> memberTypes, ImmutableArray<string> memberNames)
ImmutableArray<ITypeSymbol> memberTypes,
ImmutableArray<string> memberNames,
ImmutableArray<bool> memberIsReadOnly = default(ImmutableArray<bool>),
ImmutableArray<Location> memberLocations = default(ImmutableArray<Location>))
{
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<ITypeSymbol> memberTypes, ImmutableArray<string> memberNames);
ImmutableArray<ITypeSymbol> memberTypes,
ImmutableArray<string> memberNames,
ImmutableArray<Location> memberLocations,
ImmutableArray<bool> memberIsReadOnly);
#endregion
......
......@@ -9,9 +9,9 @@
Microsoft.CodeAnalysis.CommandLineArguments.DisplayVersion.get -> bool
Microsoft.CodeAnalysis.CommandLineArguments.EmbeddedFiles.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.CommandLineSourceFile>
Microsoft.CodeAnalysis.CommandLineArguments.SourceLink.get -> string
Microsoft.CodeAnalysis.Compilation.CreateAnonymousTypeSymbol(System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.ITypeSymbol> memberTypes, System.Collections.Immutable.ImmutableArray<string> memberNames) -> Microsoft.CodeAnalysis.INamedTypeSymbol
Microsoft.CodeAnalysis.Compilation.CreateAnonymousTypeSymbol(System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.ITypeSymbol> memberTypes, System.Collections.Immutable.ImmutableArray<string> memberNames, System.Collections.Immutable.ImmutableArray<bool> memberIsReadOnly = default(System.Collections.Immutable.ImmutableArray<bool>), System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Location> memberLocations = default(System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Location>)) -> Microsoft.CodeAnalysis.INamedTypeSymbol
Microsoft.CodeAnalysis.Compilation.CreateTupleTypeSymbol(Microsoft.CodeAnalysis.INamedTypeSymbol underlyingType, System.Collections.Immutable.ImmutableArray<string> elementNames = default(System.Collections.Immutable.ImmutableArray<string>)) -> Microsoft.CodeAnalysis.INamedTypeSymbol
Microsoft.CodeAnalysis.Compilation.CreateTupleTypeSymbol(System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.ITypeSymbol> elementTypes, System.Collections.Immutable.ImmutableArray<string> elementNames = default(System.Collections.Immutable.ImmutableArray<string>)) -> Microsoft.CodeAnalysis.INamedTypeSymbol
Microsoft.CodeAnalysis.Compilation.CreateTupleTypeSymbol(System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.ITypeSymbol> elementTypes, System.Collections.Immutable.ImmutableArray<string> elementNames = default(System.Collections.Immutable.ImmutableArray<string>), System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Location> elementLocations = default(System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Location>)) -> 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<Microsoft.CodeAnalysis.ResourceDescription> manifestResources = null, Microsoft.CodeAnalysis.Emit.EmitOptions options = null, Microsoft.CodeAnalysis.IMethodSymbol debugEntryPoint = null, System.IO.Stream sourceLinkStream = null, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.EmbeddedText> 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<Microsoft.CodeAnalysis.ResourceDescription> 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
......
......@@ -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
''' <summary>
''' Check that if any names are provided, their number matches the expected cardinality and they are not null.
''' </summary>
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
......
......@@ -1303,6 +1303,45 @@ BC2014: the value '_' is invalid for option 'RootNamespace'
End Function)
End Sub
<Fact>
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
<Fact>
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
<Fact>
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("<anonymous type: m1 As Integer, m2 As Integer>", type.ToDisplayString())
End Sub
<Fact()>
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("<anonymous type: Key m1 As Integer>", type.ToDisplayString())
End Sub
<Fact()>
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("<anonymous type: m1 As Integer>", 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("<anonymous type: m1 As Integer, m2 As Boolean>", type.ToDisplayString())
Assert.Equal("<anonymous type: Key m1 As Integer, Key m2 As Boolean>", type.ToDisplayString())
End Sub
<Fact()>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册