提交 fa83ec65 编写于 作者: V VSadov

Simple type/field binding works

上级 95877bf2
......@@ -4,6 +4,7 @@ Imports System.Collections.Generic
Imports System.Collections.Immutable
Imports System.Runtime.InteropServices
Imports System.Threading
Imports Microsoft.CodeAnalysis.Collections
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
......@@ -341,7 +342,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Dim diagName = GetBaseNamesForDiagnostic(typeSyntax)
diagInfo = NotFound(typeSyntax, diagName, binder, diagBag, reportedAnError)
Return Binder.GetErrorSymbol(diagName, diagInfo)
Return binder.GetErrorSymbol(diagName, diagInfo)
Else
If lookupResult.HasDiagnostic Then
Dim diagName = GetBaseNamesForDiagnostic(typeSyntax)
......@@ -371,7 +372,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Binder.ReportDiagnostic(diagBag, typeSyntax, diagInfo)
End If
Return Binder.GetErrorSymbol(GetBaseNamesForDiagnostic(typeSyntax), diagInfo, ImmutableArray.Create(Of Symbol)(sym), LookupResultKind.NotATypeOrNamespace)
Return binder.GetErrorSymbol(GetBaseNamesForDiagnostic(typeSyntax), diagInfo, ImmutableArray.Create(Of Symbol)(sym), LookupResultKind.NotATypeOrNamespace)
Else
' When we bind generic type reference, we pass through here with symbols for
' the generic type definition, each type argument and for the final constructed
......@@ -386,7 +387,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Emit.NoPia.EmbeddedTypesManager.IsValidEmbeddableType(DirectCast(typeSymbol, NamedTypeSymbol), typeSyntax, diagBag)
End If
Binder.ReportDiagnosticsIfObsolete(diagBag, sym, typeSyntax)
binder.ReportDiagnosticsIfObsolete(diagBag, sym, typeSyntax)
Return sym
End If
......@@ -596,7 +597,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Binder.ReportDiagnostic(diagBag, typeSyntax, diagInfo)
End If
Return Binder.GetErrorSymbol(diagName, diagInfo)
Return binder.GetErrorSymbol(diagName, diagInfo)
Else
If lookupResult.HasDiagnostic Then
If Not reportedAnError Then
......@@ -608,7 +609,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' LookupTypeOrNamespaceSyntax can't return more than one symbol.
Dim result = lookupResult.SingleSymbol
Binder.ReportDiagnosticsIfObsolete(diagBag, result, typeSyntax)
binder.ReportDiagnosticsIfObsolete(diagBag, result, typeSyntax)
Return result
End If
Finally
......@@ -657,28 +658,16 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
lookupResult.SetFrom(LookupGlobalName(DirectCast(typeSyntax, GlobalNameSyntax), binder))
Case SyntaxKind.PredefinedType
LookupResult.SetFrom(LookupPredefinedTypeName(DirectCast(typeSyntax, PredefinedTypeSyntax), binder, diagBag, reportedAnError, suppressUseSiteError))
lookupResult.SetFrom(LookupPredefinedTypeName(DirectCast(typeSyntax, PredefinedTypeSyntax), binder, diagBag, reportedAnError, suppressUseSiteError))
Case SyntaxKind.ArrayType
LookupResult.SetFrom(LookupArrayType(DirectCast(typeSyntax, ArrayTypeSyntax), binder, diagBag, suppressUseSiteError, inGetTypeContext:=inGetTypeContext))
lookupResult.SetFrom(LookupArrayType(DirectCast(typeSyntax, ArrayTypeSyntax), binder, diagBag, suppressUseSiteError, inGetTypeContext:=inGetTypeContext))
Case SyntaxKind.NullableType
LookupResult.SetFrom(LookupNullableType(DirectCast(typeSyntax, NullableTypeSyntax), binder, diagBag, suppressUseSiteError))
lookupResult.SetFrom(LookupNullableType(DirectCast(typeSyntax, NullableTypeSyntax), binder, diagBag, suppressUseSiteError))
Case SyntaxKind.TupleType
'PROTOTYPE: tuple binding
' bind the first element for now to prevent crashing
Dim tupleType = DirectCast(typeSyntax, TupleTypeSyntax)
LookupTypeOrNamespaceSyntax(lookupResult,
tupleType.TupleElements(0).Type,
binder,
diagBag,
reportedAnError,
unwrapAliases,
suppressUseSiteError,
inGetTypeContext,
resolvingBaseType)
lookupResult.SetFrom(LookupTupleType(DirectCast(typeSyntax, TupleTypeSyntax), binder, diagBag, suppressUseSiteError, inGetTypeContext, resolvingBaseType))
Case Else
Throw ExceptionUtilities.UnexpectedValue(typeSyntax.Kind)
......@@ -690,6 +679,109 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End If
End Sub
Private Shared Function LookupTupleType(syntax As TupleTypeSyntax,
binder As Binder,
diagnostics As DiagnosticBag,
suppressUseSiteError As Boolean,
inGetTypeContext As Boolean,
resolvingBaseType As Boolean) As TypeSymbol
Dim numElements As Integer = syntax.TupleElements.Count
Dim types = ArrayBuilder(Of TypeSymbol).GetInstance(numElements)
Dim locations = ArrayBuilder(Of Location).GetInstance(numElements)
Dim elementNames As ArrayBuilder(Of String) = Nothing
' set of names already used
Dim uniqueFieldNames = PooledHashSet(Of String).GetInstance()
Dim countOfExplicitNames As Integer = 0
For i As Integer = 0 To numElements - 1
Dim argumentSyntax = syntax.TupleElements(i)
Dim argumentType As TypeSymbol = binder.BindTypeSyntax(argumentSyntax.Type, diagnostics, suppressUseSiteError, inGetTypeContext, resolvingBaseType)
types.Add(argumentType)
If argumentType.IsRestrictedType() Then
Binder.ReportDiagnostic(diagnostics, argumentSyntax, ERRID.ERR_RestrictedType1, argumentType)
End If
Dim name As String = Nothing
Dim nameSyntax As IdentifierNameSyntax = argumentSyntax.IdentifierName
If nameSyntax IsNot Nothing Then
name = nameSyntax.Identifier.ValueText
' validate name if we have one
countOfExplicitNames += 1
CheckTupleMemberName(binder, name, i, nameSyntax, diagnostics, uniqueFieldNames)
locations.Add(nameSyntax.GetLocation)
Else
locations.Add(argumentSyntax.GetLocation)
End If
CollectTupleFieldMemberNames(name, i + 1, numElements, elementNames)
Next
uniqueFieldNames.Free()
If countOfExplicitNames <> 0 AndAlso countOfExplicitNames <> numElements Then
Binder.ReportDiagnostic(diagnostics, syntax, ERRID.ERR_TupleExplicitNamesOnAllMembersOrNone)
End If
Dim typesArray As ImmutableArray(Of TypeSymbol) = types.ToImmutableAndFree()
Dim locationsArray As ImmutableArray(Of Location) = locations.ToImmutableAndFree()
If typesArray.Length < 2 Then
'PROTOTYPE: tuples error ID
Dim diaginfo = diagnostics.Add(ERRID.ERR_TupleTooFewElements, syntax.GetLocation)
Return ErrorTypeSymbol.UnknownResultType
End If
Return TupleTypeSymbol.Create(syntax.GetLocation,
typesArray,
locationsArray,
If(elementNames Is Nothing, Nothing, elementNames.ToImmutableAndFree()),
binder.Compilation,
syntax,
diagnostics)
End Function
Private Shared Sub CollectTupleFieldMemberNames(name As String, position As Integer, tupleSize As Integer, ByRef elementNames As ArrayBuilder(Of String))
' add the name to the list
' names would typically all be there Or none at all
' but in case we need to handle this in error cases
If elementNames IsNot Nothing Then
elementNames.Add(If(name, TupleTypeSymbol.TupleMemberName(position)))
Else
If name IsNot Nothing Then
elementNames = ArrayBuilder(Of String).GetInstance(tupleSize)
For j As Integer = 1 To position - 1
elementNames.Add(TupleTypeSymbol.TupleMemberName(j))
Next
elementNames.Add(name)
End If
End If
End Sub
Private Shared Function CheckTupleMemberName(binder As Binder, name As String, position As Integer, syntax As VisualBasicSyntaxNode, diagnostics As DiagnosticBag, uniqueFieldNames As PooledHashSet(Of String)) As Boolean
Dim reserved As Integer = TupleTypeSymbol.IsElementNameReserved(name)
If reserved = 0 Then
Binder.ReportDiagnostic(diagnostics, syntax, ERRID.ERR_TupleReservedMemberNameAnyPosition, name)
Return False
ElseIf reserved > 0 AndAlso reserved <> position + 1 Then
Binder.ReportDiagnostic(diagnostics, syntax, ERRID.ERR_TupleReservedMemberName, name, reserved)
Return False
ElseIf (Not uniqueFieldNames.Add(name)) Then
Binder.ReportDiagnostic(diagnostics, syntax, ERRID.ERR_TupleDuplicateMemberName)
Return False
End If
Return True
End Function
Private Shared Sub AnalyzeLookupResultForIllegalBaseTypeReferences(lookupResult As LookupResult,
typeSyntax As TypeSyntax,
binder As Binder,
......@@ -748,9 +840,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Private Shared Function ErrorTypeFromLookupResult(name As String, result As LookupResult, binder As Binder) As ErrorTypeSymbol
If result.Kind = LookupResultKind.Ambiguous AndAlso result.HasSingleSymbol AndAlso TypeOf result.Diagnostic Is AmbiguousSymbolDiagnostic Then
' Special case: set of ambiguous symbols is stored in the diagnostics.
Return Binder.GetErrorSymbol(name, result.Diagnostic, DirectCast(result.Diagnostic, AmbiguousSymbolDiagnostic).AmbiguousSymbols, result.Kind)
Return binder.GetErrorSymbol(name, result.Diagnostic, DirectCast(result.Diagnostic, AmbiguousSymbolDiagnostic).AmbiguousSymbols, result.Kind)
End If
Return Binder.GetErrorSymbol(name, result.Diagnostic, result.Symbols.ToImmutable(), result.Kind)
Return binder.GetErrorSymbol(name, result.Diagnostic, result.Symbols.ToImmutable(), result.Kind)
End Function
''' <summary>
......@@ -764,7 +856,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
If sym.IsNamespace Then
Dim diagInfo = New BadSymbolDiagnostic(sym, ERRID.ERR_UnrecognizedType)
Binder.ReportDiagnostic(diagBag, syntax, diagInfo)
Return Binder.GetErrorSymbol(sym.Name, diagInfo, ImmutableArray.Create(Of Symbol)(sym), LookupResultKind.NotATypeOrNamespace)
Return binder.GetErrorSymbol(sym.Name, diagInfo, ImmutableArray.Create(Of Symbol)(sym), LookupResultKind.NotATypeOrNamespace)
Else
Return DirectCast(sym, TypeSymbol)
End If
......@@ -825,7 +917,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Throw ExceptionUtilities.UnexpectedValue(predefinedType)
End Select
Dim sym = Binder.GetSpecialType(type, node, diagBag, reportedAnError, suppressUseSiteError)
Dim sym = binder.GetSpecialType(type, node, diagBag, reportedAnError, suppressUseSiteError)
Return SingleLookupResult.Good(sym)
End Function
......@@ -837,7 +929,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
diagBag As DiagnosticBag,
suppressUseSiteError As Boolean,
inGetTypeContext As Boolean) As SingleLookupResult
Dim elementType As TypeSymbol = Binder.BindTypeSyntax(arrayTypeSyntax.ElementType,
Dim elementType As TypeSymbol = binder.BindTypeSyntax(arrayTypeSyntax.ElementType,
diagBag,
suppressUseSiteError:=suppressUseSiteError,
inGetTypeContext:=inGetTypeContext)
......@@ -851,8 +943,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
binder As Binder,
diagBag As DiagnosticBag,
suppressUseSiteError As Boolean) As SingleLookupResult
Dim elementType As TypeSymbol = Binder.BindTypeSyntax(nullableTypeSyntax.ElementType, diagBag, suppressUseSiteError)
Return SingleLookupResult.Good(Binder.CreateNullableOf(elementType, nullableTypeSyntax, nullableTypeSyntax.ElementType, diagBag))
Dim elementType As TypeSymbol = binder.BindTypeSyntax(nullableTypeSyntax.ElementType, diagBag, suppressUseSiteError)
Return SingleLookupResult.Good(binder.CreateNullableOf(elementType, nullableTypeSyntax, nullableTypeSyntax.ElementType, diagBag))
End Function
''' <summary>
......@@ -928,7 +1020,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' TODO: Dev10 squiggles type arguments for this error, but Roslyn will squiggle the whole type name.
' If we want to preserve Dev10 behavior, it should be possible to provide optional location/syntax node
' for the diagnostic attached to LookupResult.
LookupResult.SetFrom(SingleLookupResult.WrongArity(lookupResult.SingleSymbol,
lookupResult.SetFrom(SingleLookupResult.WrongArity(lookupResult.SingleSymbol,
New BadSymbolDiagnostic(lookupResult.SingleSymbol, ERRID.ERR_TypeOrMemberNotGeneric1, lookupResult.SingleSymbol)))
End If
Else
......@@ -939,11 +1031,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End If
' Construct the type and validate constraints.
Dim constructedType = Binder.ConstructAndValidateConstraints(
Dim constructedType = binder.ConstructAndValidateConstraints(
genericType, typeArguments, genericNameSyntax, typeArgumentsSyntax.Arguments, diagBag)
' Put the constructed type in. Note that this preserves any error associated with the lookupResult.
LookupResult.ReplaceSymbol(constructedType)
lookupResult.ReplaceSymbol(constructedType)
End If
End Sub
......@@ -985,7 +1077,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Dim leftSymbol As NamespaceOrTypeSymbol = DirectCast(lookupResult.SingleSymbol, NamespaceOrTypeSymbol)
Binder.ReportDiagnosticsIfObsolete(diagBag, leftSymbol, leftNameSyntax)
binder.ReportDiagnosticsIfObsolete(diagBag, leftSymbol, leftNameSyntax)
lookupResult.Clear()
Dim useSiteDiagnostics As HashSet(Of DiagnosticInfo) = Nothing
......@@ -1060,7 +1152,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Dim leftSymbol As NamespaceOrTypeSymbol = DirectCast(lookupResult.SingleSymbol, NamespaceOrTypeSymbol)
Binder.ReportDiagnosticsIfObsolete(diagBag, leftSymbol, leftNameSyntax)
binder.ReportDiagnosticsIfObsolete(diagBag, leftSymbol, leftNameSyntax)
' Lookup the generic type.
lookupResult.Clear()
......@@ -1087,11 +1179,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return
Else
' Construct the type and validate constraints.
Dim constructedType = Binder.ConstructAndValidateConstraints(
Dim constructedType = binder.ConstructAndValidateConstraints(
genericType, typeArguments, genDottedNameSyntax, typeArgumentsSyntax.Arguments, diagBag)
' Note: this preserves any error associated with the generic type, which is what we want.
LookupResult.ReplaceSymbol(constructedType)
lookupResult.ReplaceSymbol(constructedType)
End If
End Sub
......@@ -1114,7 +1206,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Dim types As TypeSymbol() = New TypeSymbol(0 To arity - 1) {}
For i As Integer = 0 To arity - 1
types(i) = Binder.BindTypeSyntax(typeArgumentsSyntax.Arguments(i), diagBag, suppressUseSiteError)
types(i) = binder.BindTypeSyntax(typeArgumentsSyntax.Arguments(i), diagBag, suppressUseSiteError)
Next
Return types.AsImmutableOrNull()
......
......@@ -120,6 +120,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
' Anonymous type being translated
If namedTypeSymbol.IsAnonymousType Then
namedTypeSymbol = AnonymousTypeManager.TranslateAnonymousTypeSymbol(namedTypeSymbol)
ElseIf (namedTypeSymbol.IsTupleType) Then
Debug.Assert(Not needDeclaration)
namedTypeSymbol = namedTypeSymbol.TupleUnderlyingType
End If
' Substitute error types with a special singleton object.
......@@ -234,6 +237,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
) As Microsoft.Cci.IFieldReference
Debug.Assert(fieldSymbol Is fieldSymbol.OriginalDefinition OrElse
Not fieldSymbol.Equals(fieldSymbol.OriginalDefinition))
If fieldSymbol.IsTupleField Then
fieldSymbol = fieldSymbol.TupleUnderlyingField
End If
Me.ProcessReferencedSymbol(fieldSymbol)
......@@ -473,6 +479,5 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
Friend Overloads Function Translate(symbol As ArrayTypeSymbol) As Microsoft.Cci.IArrayTypeReference
Return symbol
End Function
End Class
End Namespace
......@@ -1687,6 +1687,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
ERR_OptionMustBeAbsolutePath = 37257
ERR_TupleExplicitNamesOnAllMembersOrNone = 37258
ERR_TupleTooFewElements = 37259
ERR_TupleReservedMemberNameAnyPosition = 37260
ERR_TupleReservedMemberName = 37261
ERR_TupleDuplicateMemberName = 37262
ERR_LastPlusOne
......
......@@ -1237,5 +1237,66 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
#End Region
''' <summary>
''' Verify if the given type can be used to back a tuple type
''' and return cardinality of that tuple type in <paramref name="tupleCardinality"/>.
''' </summary>
''' <param name="tupleCardinality">If method returns true, contains cardinality of the compatible tuple type.</param>
''' <returns></returns>
Public Overrides Function IsTupleCompatible(<Out> ByRef tupleCardinality As Integer) As Boolean
If IsTupleType Then
tupleCardinality = 0
Return False
End If
' Should this be optimized for perf (caching for VT<0> to VT<7>, etc.)?
If (Not IsUnboundGenericType AndAlso
ContainingSymbol?.Kind = SymbolKind.Namespace AndAlso
ContainingNamespace.ContainingNamespace?.IsGlobalNamespace = True AndAlso
Name = TupleTypeSymbol.TupleTypeName AndAlso
ContainingNamespace.Name = MetadataHelpers.SystemString) Then
Dim arity = Me.Arity
If arity > 0 AndAlso arity < TupleTypeSymbol.RestPosition Then
tupleCardinality = arity
Return True
ElseIf arity = TupleTypeSymbol.RestPosition AndAlso Not IsDefinition Then
' Skip through "Rest" extensions
Dim typeToCheck As TypeSymbol = Me
Dim levelsOfNesting As Integer = 0
Do
levelsOfNesting += 1
typeToCheck = DirectCast(typeToCheck, NamedTypeSymbol).TypeArgumentsNoUseSiteDiagnostics(TupleTypeSymbol.RestPosition - 1)
Loop While typeToCheck.OriginalDefinition = Me.OriginalDefinition AndAlso Not typeToCheck.IsDefinition
If typeToCheck.IsTupleType Then
Dim underlying = typeToCheck.TupleUnderlyingType
If underlying.Arity = TupleTypeSymbol.RestPosition AndAlso underlying.OriginalDefinition <> Me.OriginalDefinition Then
tupleCardinality = 0
Return False
End If
tupleCardinality = (TupleTypeSymbol.RestPosition - 1) * levelsOfNesting + typeToCheck.TupleElementTypes.Length
Return True
End If
arity = If(TryCast(typeToCheck, NamedTypeSymbol)?.Arity, 0)
If arity > 0 AndAlso
arity < TupleTypeSymbol.RestPosition AndAlso
typeToCheck.IsTupleCompatible(tupleCardinality) Then
Debug.Assert(tupleCardinality < TupleTypeSymbol.RestPosition)
tupleCardinality += (TupleTypeSymbol.RestPosition - 1) * levelsOfNesting
Return True
End If
End If
End If
tupleCardinality = 0
Return False
End Function
End Class
End Namespace
......@@ -478,8 +478,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
End Function
Private Shared Function NumberOfValueTuples(numElements As Integer, <Out()> ByRef remainder As Integer) As Integer
remainder = (numElements - 1) Mod TupleTypeSymbol.RestPosition - 1 + 1
Return (numElements - 1) \ TupleTypeSymbol.RestPosition - 1 + 1
remainder = (numElements - 1) Mod (RestPosition - 1) + 1
Return (numElements - 1) \ (RestPosition - 1) + 1
End Function
Private Shared Function GetTupleUnderlyingType(elementTypes As ImmutableArray(Of TypeSymbol), syntax As VisualBasicSyntaxNode, compilation As VisualBasicCompilation, diagnostics As DiagnosticBag) As NamedTypeSymbol
......@@ -493,7 +493,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
Binder.ReportUseSiteError(diagnostics, syntax, wellKnownType)
End If
Dim namedTypeSymbol As NamedTypeSymbol = wellKnownType.Construct(ImmutableArray.Create(Of TypeSymbol)(elementTypes, (chainLength - 1) * TupleTypeSymbol.RestPosition - 1, remainder))
Dim namedTypeSymbol As NamedTypeSymbol = wellKnownType.Construct(ImmutableArray.Create(Of TypeSymbol)(elementTypes, (chainLength - 1) * (TupleTypeSymbol.RestPosition - 1), remainder))
Dim [loop] As Integer = chainLength - 1
If [loop] > 0 Then
Dim wellKnownType2 As NamedTypeSymbol = compilation.GetWellKnownType(TupleTypeSymbol.GetTupleType(TupleTypeSymbol.RestPosition))
......@@ -502,7 +502,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
Binder.ReportUseSiteError(diagnostics, syntax, wellKnownType2)
End If
Do
Dim typeArguments As ImmutableArray(Of TypeSymbol) = ImmutableArray.Create(Of TypeSymbol)(elementTypes, ([loop] - 1) * TupleTypeSymbol.RestPosition - 1, TupleTypeSymbol.RestPosition - 1).Add(namedTypeSymbol)
Dim typeArguments As ImmutableArray(Of TypeSymbol) = ImmutableArray.Create(Of TypeSymbol)(elementTypes, ([loop] - 1) * (TupleTypeSymbol.RestPosition - 1), TupleTypeSymbol.RestPosition - 1).Add(namedTypeSymbol)
namedTypeSymbol = wellKnownType2.Construct(typeArguments)
[loop] -= 1
Loop While [loop] > 0
......@@ -661,7 +661,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
Dim field = DirectCast(member, FieldSymbol)
Dim tupleFieldIndex = currentFieldsForElements.IndexOf(field, ReferenceEqualityComparer.Instance)
If tupleFieldIndex = 0 Then
If tupleFieldIndex >= 0 Then
' This Is a tuple backing field
Dim FieldSymbol = field.AsMember(currentUnderlying)
......
......@@ -10325,6 +10325,51 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Get
End Property
'''<summary>
''' Looks up a localized string similar to Tuple member names must be unique..
'''</summary>
Friend ReadOnly Property ERR_TupleDuplicateMemberName() As String
Get
Return ResourceManager.GetString("ERR_TupleDuplicateMemberName", resourceCulture)
End Get
End Property
'''<summary>
''' Looks up a localized string similar to Tuple member names must all be provided, if any one is provided..
'''</summary>
Friend ReadOnly Property ERR_TupleExplicitNamesOnAllMembersOrNone() As String
Get
Return ResourceManager.GetString("ERR_TupleExplicitNamesOnAllMembersOrNone", resourceCulture)
End Get
End Property
'''<summary>
''' Looks up a localized string similar to Tuple member name &apos;{0}&apos; is only allowed at position {1}..
'''</summary>
Friend ReadOnly Property ERR_TupleReservedMemberName() As String
Get
Return ResourceManager.GetString("ERR_TupleReservedMemberName", resourceCulture)
End Get
End Property
'''<summary>
''' Looks up a localized string similar to Tuple membername &apos;{0}&apos; is disallowed at any position..
'''</summary>
Friend ReadOnly Property ERR_TupleReservedMemberNameAnyPosition() As String
Get
Return ResourceManager.GetString("ERR_TupleReservedMemberNameAnyPosition", resourceCulture)
End Get
End Property
'''<summary>
''' Looks up a localized string similar to Tuple must contain at least two elements..
'''</summary>
Friend ReadOnly Property ERR_TupleTooFewElements() As String
Get
Return ResourceManager.GetString("ERR_TupleTooFewElements", resourceCulture)
End Get
End Property
'''<summary>
''' Looks up a localized string similar to Operator &apos;{0}&apos; must have two parameters..
'''</summary>
......
......@@ -5367,4 +5367,19 @@
<data name="ERR_OptionMustBeAbsolutePath" xml:space="preserve">
<value>Option '{0}' must be an absolute path.</value>
</data>
<data name="ERR_TupleDuplicateMemberName" xml:space="preserve">
<value>Tuple member names must be unique.</value>
</data>
<data name="ERR_TupleExplicitNamesOnAllMembersOrNone" xml:space="preserve">
<value>Tuple member names must all be provided, if any one is provided.</value>
</data>
<data name="ERR_TupleReservedMemberName" xml:space="preserve">
<value>Tuple member name '{0}' is only allowed at position {1}.</value>
</data>
<data name="ERR_TupleReservedMemberNameAnyPosition" xml:space="preserve">
<value>Tuple membername '{0}' is disallowed at any position.</value>
</data>
<data name="ERR_TupleTooFewElements" xml:space="preserve">
<value>Tuple must contain at least two elements.</value>
</data>
</root>
......@@ -98,6 +98,7 @@
<Compile Include="CodeGen\CodeGenAsyncTests.vb" />
<Compile Include="CodeGen\CodeGenClosureLambdaTests.vb" />
<Compile Include="CodeGen\CodeGenCollectionInitializer.vb" />
<Compile Include="CodeGen\CodeGenTuples.vb" />
<Compile Include="CodeGen\CodeGenConstLocal.vb" />
<Compile Include="CodeGen\CodeGenDelegateCreation.vb" />
<Compile Include="CodeGen\CodeGenEvents.vb" />
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.Test.Utilities
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports Microsoft.CodeAnalysis.VisualBasic.UnitTests.Emit
Imports Roslyn.Test.Utilities
Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests
Public Class CodeGenTuples
Inherits BasicTestBase
<Fact()>
Public Sub TupleTypeBinding()
Dim verifier = CompileAndVerify(
<compilation>
<file name="a.vb">
Imports System
Module C
Sub Main()
Dim t as (Integer, Integer)
console.writeline(t)
End Sub
End Module
Namespace System
Structure ValueTuple(Of T1, T2)
Public Overrides Function ToString() As String
Return "hello"
End Function
End Structure
End Namespace
</file>
</compilation>, expectedOutput:=<![CDATA[
hello
]]>)
verifier.VerifyIL("C.Main", <![CDATA[
{
// Code size 12 (0xc)
.maxstack 1
.locals init (System.ValueTuple(Of Integer, Integer) V_0) //t
IL_0000: ldloc.0
IL_0001: box "System.ValueTuple(Of Integer, Integer)"
IL_0006: call "Sub System.Console.WriteLine(Object)"
IL_000b: ret
}
]]>)
End Sub
<Fact()>
Public Sub TupleFieldBinding()
Dim verifier = CompileAndVerify(
<compilation>
<file name="a.vb">
Imports System
Module C
Sub Main()
Dim t as (Integer, Integer)
t.Item1 = 42
t.Item2 = t.Item1
console.writeline(t.Item2)
End Sub
End Module
Namespace System
Structure ValueTuple(Of T1, T2)
Public Item1 As T1
Public Item2 As T2
End Structure
End Namespace
</file>
</compilation>, expectedOutput:=<![CDATA[
42
]]>)
verifier.VerifyIL("C.Main", <![CDATA[
{
// Code size 34 (0x22)
.maxstack 2
.locals init (System.ValueTuple(Of Integer, Integer) V_0) //t
IL_0000: ldloca.s V_0
IL_0002: ldc.i4.s 42
IL_0004: stfld "System.ValueTuple(Of Integer, Integer).Item1 As Integer"
IL_0009: ldloca.s V_0
IL_000b: ldloc.0
IL_000c: ldfld "System.ValueTuple(Of Integer, Integer).Item1 As Integer"
IL_0011: stfld "System.ValueTuple(Of Integer, Integer).Item2 As Integer"
IL_0016: ldloc.0
IL_0017: ldfld "System.ValueTuple(Of Integer, Integer).Item2 As Integer"
IL_001c: call "Sub System.Console.WriteLine(Integer)"
IL_0021: ret
}
]]>)
End Sub
<Fact()>
Public Sub TupleNamedFieldBinding()
Dim verifier = CompileAndVerify(
<compilation>
<file name="a.vb">
Imports System
Module C
Sub Main()
Dim t As (a As Integer, b As Integer)
t.a = 42
t.b = t.a
Console.WriteLine(t.b)
End Sub
End Module
Namespace System
Structure ValueTuple(Of T1, T2)
Public Item1 As T1
Public Item2 As T2
End Structure
End Namespace
</file>
</compilation>, expectedOutput:=<![CDATA[
42
]]>)
verifier.VerifyIL("C.Main", <![CDATA[
{
// Code size 34 (0x22)
.maxstack 2
.locals init (System.ValueTuple(Of Integer, Integer) V_0) //t
IL_0000: ldloca.s V_0
IL_0002: ldc.i4.s 42
IL_0004: stfld "System.ValueTuple(Of Integer, Integer).Item1 As Integer"
IL_0009: ldloca.s V_0
IL_000b: ldloc.0
IL_000c: ldfld "System.ValueTuple(Of Integer, Integer).Item1 As Integer"
IL_0011: stfld "System.ValueTuple(Of Integer, Integer).Item2 As Integer"
IL_0016: ldloc.0
IL_0017: ldfld "System.ValueTuple(Of Integer, Integer).Item2 As Integer"
IL_001c: call "Sub System.Console.WriteLine(Integer)"
IL_0021: ret
}
]]>)
End Sub
End Class
End Namespace
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册