|
' Licensed to the .NET Foundation under one or more agreements.
' The .NET Foundation licenses this file to you under the MIT license.
' See the LICENSE file in the project root for more information.
Imports System.Collections.Immutable
Imports System.Runtime.CompilerServices
Imports Microsoft.CodeAnalysis.Test.Utilities
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports Roslyn.Test.Utilities
Imports ReferenceEqualityComparer = Roslyn.Utilities.ReferenceEqualityComparer
Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.Symbols
Friend Module InstantiatingGenericsExtensions
' Check generic instantiation invariants.
<Extension()>
Public Sub VerifyGenericInstantiationInvariants(instantiation As Symbol)
If instantiation.IsDefinition Then
Return
End If
Dim originalDefinition As Symbol = instantiation.OriginalDefinition
Dim constructedFrom As Symbol
Dim constructedFromConstructedFrom As Symbol
Dim typeParameters As ImmutableArray(Of TypeParameterSymbol)
Dim typeArguments As ImmutableArray(Of TypeSymbol)
Dim constructedFromTypeParameters As ImmutableArray(Of TypeParameterSymbol)
Dim constructedFromTypeArguments As ImmutableArray(Of TypeSymbol)
Dim originalDefinitionTypeParameters As ImmutableArray(Of TypeParameterSymbol)
Dim type = TryCast(instantiation, NamedTypeSymbol)
Dim method As MethodSymbol = Nothing
If type IsNot Nothing Then
typeParameters = type.TypeParameters
typeArguments = type.TypeArguments
constructedFrom = type.ConstructedFrom
constructedFromTypeParameters = type.ConstructedFrom.TypeParameters
constructedFromTypeArguments = type.ConstructedFrom.TypeArguments
originalDefinitionTypeParameters = type.OriginalDefinition.TypeParameters
constructedFromConstructedFrom = type.ConstructedFrom.ConstructedFrom
Else
method = DirectCast(instantiation, MethodSymbol)
typeParameters = method.TypeParameters
typeArguments = method.TypeArguments
constructedFrom = method.ConstructedFrom
constructedFromTypeParameters = method.ConstructedFrom.TypeParameters
constructedFromTypeArguments = method.ConstructedFrom.TypeArguments
originalDefinitionTypeParameters = method.OriginalDefinition.TypeParameters
constructedFromConstructedFrom = method.ConstructedFrom.ConstructedFrom
End If
Assert.Equal(instantiation.DeclaringCompilation, originalDefinition.DeclaringCompilation)
Assert.True(originalDefinition.IsDefinition)
' Check ConstructedFrom invariants.
Assert.Same(originalDefinition, constructedFrom.OriginalDefinition)
Assert.Same(constructedFrom, constructedFromConstructedFrom)
Assert.Same(instantiation.ContainingSymbol, constructedFrom.ContainingSymbol)
Assert.True(constructedFromTypeArguments.SequenceEqual(constructedFromTypeParameters, ReferenceEqualityComparer.Instance))
Assert.Equal(constructedFrom.Name, originalDefinition.Name)
Assert.Equal(constructedFrom.Kind, originalDefinition.Kind)
Assert.Equal(constructedFrom.DeclaredAccessibility, originalDefinition.DeclaredAccessibility)
Assert.Equal(constructedFrom.IsShared, originalDefinition.IsShared)
For Each typeParam In constructedFromTypeParameters
Assert.Same(constructedFrom, typeParam.ContainingSymbol)
Next
Dim constructedFromIsDefinition As Boolean = constructedFrom.IsDefinition
For Each typeParam In constructedFromTypeParameters
Assert.Equal(constructedFromIsDefinition, typeParam.IsDefinition)
Assert.Same(originalDefinitionTypeParameters(typeParam.Ordinal), typeParam.OriginalDefinition)
Next
' Check instantiation invariants.
Assert.True(typeParameters.SequenceEqual(constructedFromTypeParameters, ReferenceEqualityComparer.Instance))
Assert.True(instantiation Is constructedFrom OrElse Not typeArguments.SequenceEqual(typeParameters), String.Format("Constructed symbol {0} uses its own type parameters as type arguments", instantiation.ToTestDisplayString()))
Assert.Equal(instantiation Is constructedFrom, typeArguments.SequenceEqual(typeParameters, ReferenceEqualityComparer.Instance))
Assert.Equal(instantiation.Name, constructedFrom.Name)
Assert.Equal(instantiation.Kind, originalDefinition.Kind)
Assert.Equal(instantiation.DeclaredAccessibility, originalDefinition.DeclaredAccessibility)
Assert.Equal(instantiation.IsShared, originalDefinition.IsShared)
' TODO: Check constraints and other TypeParameter's properties.
If type IsNot Nothing Then
Assert.Equal(type.ConstructedFrom.Arity, type.OriginalDefinition.Arity)
Assert.Equal(type.Arity, type.ConstructedFrom.Arity)
Assert.False(type.OriginalDefinition.IsUnboundGenericType)
Assert.True(type.Arity > 0 OrElse type.ConstructedFrom Is type, String.Format("Condition [{0} > 0 OrElse {1} Is {2}] failed.", type.Arity, type.ConstructedFrom.ToTestDisplayString(), type.ToTestDisplayString()))
Assert.True(type Is constructedFrom OrElse Not type.CanConstruct, String.Format("Condition [{0} Is constructedFrom OrElse Not {1}] failed.", type.ToTestDisplayString(), type.CanConstruct))
Assert.True(type.Arity > 0 OrElse Not type.CanConstruct, String.Format("Condition [{0} > 0 OrElse Not {1}] failed.", type.Arity, type.CanConstruct))
Assert.Equal(type.OriginalDefinition.IsAnonymousType, type.ConstructedFrom.IsAnonymousType)
Assert.Equal(type.ConstructedFrom.IsAnonymousType, type.IsAnonymousType)
Assert.Same(type.OriginalDefinition.EnumUnderlyingType, type.ConstructedFrom.EnumUnderlyingType)
Assert.Same(type.ConstructedFrom.EnumUnderlyingType, type.EnumUnderlyingType)
Assert.Equal(type.OriginalDefinition.TypeKind, type.ConstructedFrom.TypeKind)
Assert.Equal(type.ConstructedFrom.TypeKind, type.TypeKind)
Assert.Equal(type.OriginalDefinition.IsMustInherit, type.ConstructedFrom.IsMustInherit)
Assert.Equal(type.ConstructedFrom.IsMustInherit, type.IsMustInherit)
Assert.Equal(type.OriginalDefinition.IsNotInheritable, type.ConstructedFrom.IsNotInheritable)
Assert.Equal(type.ConstructedFrom.IsNotInheritable, type.IsNotInheritable)
Assert.False(type.OriginalDefinition.MightContainExtensionMethods)
Assert.False(type.ConstructedFrom.MightContainExtensionMethods)
Assert.False(type.MightContainExtensionMethods)
' Check UnboundGenericType invariants.
Dim containingType As NamedTypeSymbol = type.ContainingType
If containingType IsNot Nothing Then
containingType.VerifyGenericInstantiationInvariants()
If Not type.IsUnboundGenericType AndAlso containingType.IsUnboundGenericType Then
Assert.False(type.CanConstruct)
Assert.Null(type.BaseType)
Assert.Equal(0, type.Interfaces.Length)
End If
End If
If type.IsUnboundGenericType OrElse (containingType IsNot Nothing AndAlso containingType.IsUnboundGenericType) Then
Assert.Null(type.DefaultPropertyName)
Assert.Null(type.ConstructedFrom.DefaultPropertyName)
Else
Assert.Equal(type.OriginalDefinition.DefaultPropertyName, type.ConstructedFrom.DefaultPropertyName)
Assert.Equal(type.ConstructedFrom.DefaultPropertyName, type.DefaultPropertyName)
End If
If type.IsUnboundGenericType Then
Assert.False(type.CanConstruct)
Assert.Null(type.BaseType)
Assert.Equal(0, type.Interfaces.Length)
If containingType IsNot Nothing Then
Assert.Equal(containingType.IsGenericType, containingType.IsUnboundGenericType)
End If
For Each typeArgument In typeArguments
Assert.Same(UnboundGenericType.UnboundTypeArgument, typeArgument)
Next
ElseIf containingType IsNot Nothing AndAlso Not containingType.IsUnboundGenericType Then
containingType = containingType.ContainingType
While containingType IsNot Nothing
Assert.False(containingType.IsUnboundGenericType)
containingType = containingType.ContainingType
End While
End If
Dim testArgs() As TypeSymbol = GetTestArgs(type.Arity)
If type.CanConstruct Then
Dim constructed = type.Construct(testArgs)
Assert.NotSame(type, constructed)
Assert.Same(type, constructedFrom)
constructed.VerifyGenericInstantiationInvariants()
Assert.Same(type, type.Construct(type.TypeParameters.As(Of TypeSymbol)()))
Else
Assert.Throws(Of InvalidOperationException)(Sub() type.Construct(testArgs))
Assert.Throws(Of InvalidOperationException)(Sub() type.Construct(testArgs.AsImmutableOrNull()))
End If
Else
Assert.True(method Is constructedFrom OrElse Not method.CanConstruct, String.Format("Condition [{0} Is constructedFrom OrElse Not {1}] failed.", method.ToTestDisplayString(), method.CanConstruct))
Assert.True(method.Arity > 0 OrElse Not method.CanConstruct, String.Format("Condition [{0} > 0 OrElse Not {1}] failed.", method.Arity, method.CanConstruct))
Assert.Equal(method.ConstructedFrom.Arity, method.OriginalDefinition.Arity)
Assert.Equal(method.Arity, method.ConstructedFrom.Arity)
Assert.Equal(method.Arity = 0, method.ConstructedFrom Is method)
Assert.Same(method.OriginalDefinition.IsExtensionMethod, method.ConstructedFrom.IsExtensionMethod)
Assert.Same(method.ConstructedFrom.IsExtensionMethod, method.IsExtensionMethod)
Dim testArgs() As TypeSymbol = GetTestArgs(type.Arity)
If method.CanConstruct Then
Dim constructed = method.Construct(testArgs)
Assert.NotSame(method, constructed)
Assert.Same(method, constructedFrom)
constructed.VerifyGenericInstantiationInvariants()
Assert.Throws(Of InvalidOperationException)(Sub() method.Construct(method.TypeParameters.As(Of TypeSymbol)()))
Else
Assert.Throws(Of InvalidOperationException)(Sub() method.Construct(testArgs))
Assert.Throws(Of InvalidOperationException)(Sub() method.Construct(testArgs.AsImmutableOrNull()))
End If
End If
End Sub
Private Function GetTestArgs(arity As Integer) As TypeSymbol()
Dim a(arity - 1) As TypeSymbol
For i = 0 To a.Length - 1
a(i) = ErrorTypeSymbol.UnknownResultType
Next
Return a
End Function
End Module
Public Class InstantiatingGenerics
Inherits BasicTestBase
<Fact, WorkItem(910574, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/910574")>
Public Sub Test1()
Dim assembly = MetadataTestHelpers.LoadFromBytes(TestResources.General.MDTestLib1)
Dim module0 = assembly.Modules(0)
Dim C1 = module0.GlobalNamespace.GetTypeMembers("C1").Single()
Dim C1_T = C1.TypeParameters(0)
Assert.Equal("C1(Of C1_T)", C1.ToTestDisplayString())
Dim C2 = C1.GetTypeMembers("C2").Single()
Dim C2_T = C2.TypeParameters(0)
Assert.Equal("C1(Of C1_T).C2(Of C2_T)", C2.ToTestDisplayString())
Dim C3 = C1.GetTypeMembers("C3").Single()
Assert.Equal("C1(Of C1_T).C3", C3.ToTestDisplayString())
Dim C4 = C3.GetTypeMembers("C4").Single()
Dim C4_T = C4.TypeParameters(0)
Assert.Equal("C1(Of C1_T).C3.C4(Of C4_T)", C4.ToTestDisplayString())
Dim TC2 = module0.GlobalNamespace.GetTypeMembers("TC2").Single()
Dim TC2_T1 = TC2.TypeParameters(0)
Dim TC2_T2 = TC2.TypeParameters(1)
Assert.Equal("TC2(Of TC2_T1, TC2_T2)", TC2.ToTestDisplayString())
Dim C107 = module0.GlobalNamespace.GetTypeMembers("C107").Single()
Dim C108 = C107.GetTypeMembers("C108").Single()
Dim C108_T = C108.TypeParameters(0)
Assert.Equal("C107.C108(Of C108_T)", C108.ToTestDisplayString())
Dim g1 = C1.Construct({TC2_T1})
Assert.Equal("C1(Of TC2_T1)", g1.ToTestDisplayString())
Assert.Equal(C1, g1.ConstructedFrom)
Dim g1_C2 = g1.GetTypeMembers("C2").Single()
Assert.Equal("C1(Of TC2_T1).C2(Of C2_T)", g1_C2.ToTestDisplayString())
Assert.Equal(g1_C2, g1_C2.ConstructedFrom)
Assert.NotEqual(C2.TypeParameters(0), g1_C2.TypeParameters(0))
Assert.Same(C2.TypeParameters(0), g1_C2.TypeParameters(0).OriginalDefinition)
Assert.Same(g1_C2.TypeParameters(0), g1_C2.TypeArguments(0))
Dim g2 = g1_C2.Construct({TC2_T2})
Assert.Equal("C1(Of TC2_T1).C2(Of TC2_T2)", g2.ToTestDisplayString())
Assert.Equal(g1_C2, g2.ConstructedFrom)
Dim g1_C3 = g1.GetTypeMembers("C3").Single()
Assert.Equal("C1(Of TC2_T1).C3", g1_C3.ToTestDisplayString())
Assert.Equal(g1_C3, g1_C3.ConstructedFrom)
Dim g1_C3_C4 = g1_C3.GetTypeMembers("C4").Single()
Assert.Equal("C1(Of TC2_T1).C3.C4(Of C4_T)", g1_C3_C4.ToTestDisplayString())
Assert.Equal(g1_C3_C4, g1_C3_C4.ConstructedFrom)
Dim g4 = g1_C3_C4.Construct({TC2_T2})
Assert.Equal("C1(Of TC2_T1).C3.C4(Of TC2_T2)", g4.ToTestDisplayString())
Assert.Equal(g1_C3_C4, g4.ConstructedFrom)
Dim g108 = C108.Construct({TC2_T1})
Assert.Equal("C107.C108(Of TC2_T1)", g108.ToTestDisplayString())
Assert.Equal(C108, g108.ConstructedFrom)
Dim g_TC2 = TC2.Construct({C107, C108})
Assert.Equal("TC2(Of C107, C107.C108(Of C108_T))", g_TC2.ToTestDisplayString())
Assert.Equal(TC2, g_TC2.ConstructedFrom)
Assert.Equal(TC2, TC2.Construct({TC2_T1, TC2_T2}))
Assert.Null(TypeSubstitution.Create(TC2, {TC2_T1, TC2_T2}, {TC2_T1, TC2_T2}))
Dim s1 = TypeSubstitution.Create(C1, {C1_T}, {TC2_T1})
Dim g1_1 = DirectCast(C1.Construct(s1), NamedTypeSymbol)
Assert.Equal("C1(Of TC2_T1)", g1_1.ToTestDisplayString())
Assert.Equal(C1, g1_1.ConstructedFrom)
Assert.Equal(g1, g1_1)
Dim s2 = TypeSubstitution.Create(C2, {C1_T, C2_T}, {TC2_T1, TC2_T2})
Dim g2_1 = DirectCast(C2.Construct(s2), NamedTypeSymbol)
Assert.Equal("C1(Of TC2_T1).C2(Of TC2_T2)", g2_1.ToTestDisplayString())
Assert.Equal(g1_C2, g2_1.ConstructedFrom)
Assert.Equal(g2, g2_1)
Dim s2_1 = TypeSubstitution.Create(C2, {C2_T}, {TC2_T2})
Dim s3 = TypeSubstitution.Concat(s2_1.TargetGenericDefinition, s1, s2_1)
Dim g2_2 = DirectCast(C2.Construct(s3), NamedTypeSymbol)
Assert.Equal("C1(Of TC2_T1).C2(Of TC2_T2)", g2_2.ToTestDisplayString())
Assert.Equal(g1_C2, g2_2.ConstructedFrom)
Assert.Equal(g2, g2_2)
Dim g2_3 = DirectCast(C2.Construct(s2_1), NamedTypeSymbol)
Assert.Equal("C1(Of C1_T).C2(Of TC2_T2)", g2_3.ToTestDisplayString())
Assert.Equal(C2, g2_3.ConstructedFrom)
Dim s4 = TypeSubstitution.Create(C4, {C1_T, C4_T}, {TC2_T1, TC2_T2})
Dim g4_1 = DirectCast(C4.Construct(s4), NamedTypeSymbol)
Assert.Equal("C1(Of TC2_T1).C3.C4(Of TC2_T2)", g4_1.ToTestDisplayString())
Assert.Equal(g1_C3_C4, g4_1.ConstructedFrom)
Assert.Equal(g4, g4_1)
Dim s108 = TypeSubstitution.Create(C108, {C108_T}, {TC2_T1})
Dim g108_1 = DirectCast(C108.Construct(s108), NamedTypeSymbol)
Assert.Equal("C107.C108(Of TC2_T1)", g108_1.ToTestDisplayString())
Assert.Equal(C108, g108_1.ConstructedFrom)
Assert.Equal(g108, g108_1)
Dim sTC2 = TypeSubstitution.Create(TC2, {TC2_T1, TC2_T2}, {C107, C108})
Dim g_TC2_1 = DirectCast(TC2.Construct(sTC2), NamedTypeSymbol)
Assert.Equal("TC2(Of C107, C107.C108(Of C108_T))", g_TC2_1.ToTestDisplayString())
Assert.Equal(TC2, g_TC2_1.ConstructedFrom)
Assert.Equal(g_TC2, g_TC2_1)
g1.VerifyGenericInstantiationInvariants()
g2.VerifyGenericInstantiationInvariants()
g4.VerifyGenericInstantiationInvariants()
g108.VerifyGenericInstantiationInvariants()
g_TC2.VerifyGenericInstantiationInvariants()
g1_1.VerifyGenericInstantiationInvariants()
g2_2.VerifyGenericInstantiationInvariants()
g_TC2_1.VerifyGenericInstantiationInvariants()
End Sub
<Fact>
Public Sub AlphaRename()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(
<compilation name="C">
<file name="a.vb">
Module Module1
Sub Main()
Dim x1 As New C1(Of Byte, Byte)()
Dim x2 As New C1(Of Byte, Byte).C2(Of Byte, Byte)()
Dim x3 As New C1(Of Byte, Byte).C2(Of Byte, Byte).C3(Of Byte, Byte)()
Dim x4 As New C1(Of Byte, Byte).C2(Of Byte, Byte).C3(Of Byte, Byte).C4(Of Byte)()
Dim x5 As New C1(Of Byte, Byte).C5()
End Sub
End Module
Class C1(Of C1T1, C1T2)
Class C2(Of C2T1, C2T2)
Class C3(Of C3T1, C3T2 As C1T1)
Function F1() As C1T1
Return Nothing
End Function
Function F2() As C2T1
Return Nothing
End Function
Function F3() As C3T1
Return Nothing
End Function
Function F4() As C1T2
Return Nothing
End Function
Function F5() As C2T2
Return Nothing
End Function
Function F6() As C3T2
Return Nothing
End Function
' error BC32044: Type argument 'C3T2' does not inherit from or implement the constraint type 'Integer'.
Dim x As C1(Of Integer, Integer).C2(Of C2T1, C2T2).C3(Of C3T1, C3T2)
Class C4(Of C4T1)
End Class
End Class
Public V1 As C1(Of Integer, C2T2).C5
Public V2 As C1(Of C2T1, C2T2).C5
Public V3 As C1(Of Integer, Integer).C5
Public V4 As C2(Of Byte, Byte)
Public V5 As C1(Of C1T2, C1T1).C2(Of C2T1, C2T2)
Public V6 As C1(Of C1T2, C1T1).C2(Of C2T2, C2T1)
Public V7 As C1(Of C1T2, C1T1).C2(Of Byte, Integer)
Public V8 As C2(Of C2T1, C2T2)
Public V9 As C2(Of Byte, C2T2)
Sub Test12(x As C2(Of Integer, Integer))
Dim y As C1(Of C1T1, C1T2).C2(Of Byte, Integer) = x.V9
End Sub
Sub Test11(x As C1(Of Integer, Integer).C2(Of Byte, Byte))
Dim y As C1(Of Integer, Integer).C2(Of Byte, Byte) = x.V8
End Sub
Sub Test6(x As C1(Of C1T2, C1T1).C2(Of C2T1, C2T2))
Dim y As C1(Of C1T1, C1T2).C2(Of C2T1, C2T2) = x.V5
End Sub
Sub Test7(x As C1(Of C1T2, C1T1).C2(Of C2T2, C2T1))
Dim y As C1(Of C1T1, C1T2).C2(Of C2T1, C2T2) = x.V6
End Sub
Sub Test8(x As C1(Of C1T2, C1T1).C2(Of C2T2, C2T1))
Dim y As C1(Of C1T1, C1T2).C2(Of Byte, Integer) = x.V7
End Sub
Sub Test9(x As C1(Of Integer, Byte).C2(Of C2T2, C2T1))
Dim y As C1(Of Byte, Integer).C2(Of Byte, Integer) = x.V7
End Sub
Sub Test10(x As C1(Of C1T1, C1T2).C2(Of C2T2, C2T1))
Dim y As C1(Of C1T2, C1T1).C2(Of Byte, Integer) = x.V7
End Sub
End Class
Class C5
End Class
Sub Test1(x As C2(Of C1T1, Integer))
Dim y As C1(Of Integer, Integer).C5 = x.V1
End Sub
Sub Test2(x As C2(Of C1T1, C1T2))
Dim y As C5 = x.V2
End Sub
Sub Test3(x As C2(Of C1T2, C1T1))
Dim y As C1(Of Integer, Integer).C5 = x.V3
End Sub
Sub Test4(x As C1(Of Integer, Integer).C2(Of C1T1, C1T2))
Dim y As C1(Of Integer, Integer).C2(Of Byte, Byte) = x.V4
End Sub
End Class
</file>
</compilation>, TestOptions.ReleaseExe)
Dim int = compilation.GetSpecialType(SpecialType.System_Int32)
Assert.Throws(Of InvalidOperationException)(Function() int.Construct())
Dim c1 = compilation.GetTypeByMetadataName("C1`2")
Dim c2 = c1.GetTypeMembers("C2").Single()
Dim c3 = c2.GetTypeMembers("C3").Single()
Dim c4 = c3.GetTypeMembers("C4").Single()
Dim c5 = c1.GetTypeMembers("C5").Single()
Dim c3OfIntInt = c3.Construct(int, int)
Dim c2_c3OfIntInt = c3OfIntInt.ContainingType
Dim c1_c2_c3OfIntInt = c2_c3OfIntInt.ContainingType
Assert.Equal("C1(Of C1T1, C1T2).C2(Of C2T1, C2T2).C3(Of System.Int32, System.Int32)", c3OfIntInt.ToTestDisplayString())
Assert.Same(c1, c1_c2_c3OfIntInt)
Assert.Same(c2, c2_c3OfIntInt)
Assert.Same(c3.TypeParameters(0), c3OfIntInt.TypeParameters(0))
Assert.Same(c3, c3OfIntInt.ConstructedFrom)
Dim substitution As TypeSubstitution
substitution = TypeSubstitution.Create(c1, {c1.TypeParameters(0), c1.TypeParameters(1)}, {int, int})
Dim c1OfIntInt_c2_c3 = DirectCast(c3.Construct(substitution), NamedTypeSymbol)
Dim c1OfIntInt_c2 = c1OfIntInt_c2_c3.ContainingType
Dim c1OfIntInt = c1OfIntInt_c2.ContainingType
Assert.Equal("C1(Of System.Int32, System.Int32).C2(Of C2T1, C2T2).C3(Of C3T1, C3T2)", c1OfIntInt_c2_c3.ToTestDisplayString())
Assert.Equal("C1(Of System.Int32, System.Int32).C2(Of C2T1, C2T2)", c1OfIntInt_c2.ToTestDisplayString())
Assert.Equal("C1(Of System.Int32, System.Int32)", c1OfIntInt.ToTestDisplayString())
Assert.Same(c1.TypeParameters(0), c1OfIntInt.TypeParameters(0))
Assert.Same(int, c1OfIntInt.TypeArguments(0))
Assert.NotSame(c2.TypeParameters(0), c1OfIntInt_c2.TypeParameters(0))
Assert.Same(c1OfIntInt_c2.TypeParameters(0), c1OfIntInt_c2.TypeArguments(0))
Assert.Same(c1OfIntInt_c2, c1OfIntInt_c2.TypeParameters(0).ContainingSymbol)
Assert.NotSame(c3.TypeParameters(0), c1OfIntInt_c2_c3.TypeParameters(0))
Assert.Same(c1OfIntInt_c2_c3.TypeParameters(0), c1OfIntInt_c2_c3.TypeArguments(0))
Assert.Same(c1OfIntInt_c2_c3, c1OfIntInt_c2_c3.TypeParameters(0).ContainingSymbol)
Dim c1OfIntInt_c2_c3_F1 = DirectCast(c1OfIntInt_c2_c3.GetMembers("F1").Single(), MethodSymbol)
Dim c1OfIntInt_c2_c3_F2 = DirectCast(c1OfIntInt_c2_c3.GetMembers("F2").Single(), MethodSymbol)
Dim c1OfIntInt_c2_c3_F3 = DirectCast(c1OfIntInt_c2_c3.GetMembers("F3").Single(), MethodSymbol)
Dim c1OfIntInt_c2_c3_F4 = DirectCast(c1OfIntInt_c2_c3.GetMembers("F4").Single(), MethodSymbol)
Dim c1OfIntInt_c2_c3_F5 = DirectCast(c1OfIntInt_c2_c3.GetMembers("F5").Single(), MethodSymbol)
Dim c1OfIntInt_c2_c3_F6 = DirectCast(c1OfIntInt_c2_c3.GetMembers("F6").Single(), MethodSymbol)
Assert.Same(c1OfIntInt.TypeArguments(0), c1OfIntInt_c2_c3_F1.ReturnType)
Assert.Same(c1OfIntInt_c2.TypeArguments(0), c1OfIntInt_c2_c3_F2.ReturnType)
Assert.Same(c1OfIntInt_c2_c3.TypeArguments(0), c1OfIntInt_c2_c3_F3.ReturnType)
Assert.Same(c1OfIntInt.TypeArguments(1), c1OfIntInt_c2_c3_F4.ReturnType)
Assert.Same(c1OfIntInt_c2.TypeArguments(1), c1OfIntInt_c2_c3_F5.ReturnType)
Assert.Same(c1OfIntInt_c2_c3.TypeArguments(1), c1OfIntInt_c2_c3_F6.ReturnType)
substitution = TypeSubstitution.Create(c3, {c1.TypeParameters(0), c1.TypeParameters(1)}, {int, int})
Dim c1OfIntInt_c2Of_c3Of = DirectCast(c3.Construct(substitution), NamedTypeSymbol)
' We need to distinguish these two things in order to be able to detect constraint violation.
' error BC32044: Type argument 'C3T2' does not inherit from or implement the constraint type 'Integer'.
Assert.NotEqual(c1OfIntInt_c2Of_c3Of.ConstructedFrom, c1OfIntInt_c2Of_c3Of)
Dim c1OfIntInt_c2Of = c1OfIntInt_c2Of_c3Of.ContainingType
Assert.Equal(c1OfIntInt, c1OfIntInt_c2Of.ContainingType)
c1OfIntInt = c1OfIntInt_c2Of.ContainingType
Assert.Equal("C1(Of System.Int32, System.Int32).C2(Of C2T1, C2T2).C3(Of C3T1, C3T2)", c1OfIntInt_c2Of_c3Of.ToTestDisplayString())
Assert.Equal("C1(Of System.Int32, System.Int32).C2(Of C2T1, C2T2)", c1OfIntInt_c2Of.ToTestDisplayString())
Assert.Equal("C1(Of System.Int32, System.Int32)", c1OfIntInt.ToTestDisplayString())
Assert.Same(c1.TypeParameters(0), c1OfIntInt.TypeParameters(0))
Assert.Same(int, c1OfIntInt.TypeArguments(0))
Assert.NotSame(c2.TypeParameters(0), c1OfIntInt_c2Of.TypeParameters(0))
Assert.NotSame(c1OfIntInt_c2Of.TypeParameters(0), c1OfIntInt_c2Of.TypeArguments(0))
Assert.Same(c1OfIntInt_c2Of.TypeParameters(0).OriginalDefinition, c1OfIntInt_c2Of.TypeArguments(0))
Assert.NotSame(c1OfIntInt_c2Of, c1OfIntInt_c2Of.TypeParameters(0).ContainingSymbol)
Assert.Same(c1OfIntInt_c2Of.ConstructedFrom, c1OfIntInt_c2Of.TypeParameters(0).ContainingSymbol)
Assert.NotSame(c3.TypeParameters(0), c1OfIntInt_c2Of_c3Of.TypeParameters(0))
Assert.NotSame(c1OfIntInt_c2Of_c3Of.TypeParameters(0), c1OfIntInt_c2Of_c3Of.TypeArguments(0))
Assert.Same(c1OfIntInt_c2Of_c3Of.TypeParameters(0).OriginalDefinition, c1OfIntInt_c2Of_c3Of.TypeArguments(0))
Assert.NotSame(c1OfIntInt_c2Of_c3Of, c1OfIntInt_c2Of_c3Of.TypeParameters(0).ContainingSymbol)
Assert.Same(c1OfIntInt_c2Of_c3Of.ConstructedFrom, c1OfIntInt_c2Of_c3Of.TypeParameters(0).ContainingSymbol)
Dim c1OfIntInt_c2Of_c3Of_F1 = DirectCast(c1OfIntInt_c2Of_c3Of.GetMembers("F1").Single(), MethodSymbol)
Dim c1OfIntInt_c2Of_c3Of_F2 = DirectCast(c1OfIntInt_c2Of_c3Of.GetMembers("F2").Single(), MethodSymbol)
Dim c1OfIntInt_c2Of_c3Of_F3 = DirectCast(c1OfIntInt_c2Of_c3Of.GetMembers("F3").Single(), MethodSymbol)
Dim c1OfIntInt_c2Of_c3Of_F4 = DirectCast(c1OfIntInt_c2Of_c3Of.GetMembers("F4").Single(), MethodSymbol)
Dim c1OfIntInt_c2Of_c3Of_F5 = DirectCast(c1OfIntInt_c2Of_c3Of.GetMembers("F5").Single(), MethodSymbol)
Dim c1OfIntInt_c2Of_c3Of_F6 = DirectCast(c1OfIntInt_c2Of_c3Of.GetMembers("F6").Single(), MethodSymbol)
Assert.Same(c1OfIntInt.TypeArguments(0), c1OfIntInt_c2Of_c3Of_F1.ReturnType)
Assert.Same(c1OfIntInt_c2Of.TypeArguments(0), c1OfIntInt_c2Of_c3Of_F2.ReturnType)
Assert.Same(c1OfIntInt_c2Of_c3Of.TypeArguments(0), c1OfIntInt_c2Of_c3Of_F3.ReturnType)
Assert.Same(c1OfIntInt.TypeArguments(1), c1OfIntInt_c2Of_c3Of_F4.ReturnType)
Assert.Same(c1OfIntInt_c2Of.TypeArguments(1), c1OfIntInt_c2Of_c3Of_F5.ReturnType)
Assert.Same(c1OfIntInt_c2Of_c3Of.TypeArguments(1), c1OfIntInt_c2Of_c3Of_F6.ReturnType)
substitution = TypeSubstitution.Create(c2,
{c1.TypeParameters(0), c1.TypeParameters(1), c2.TypeParameters(0), c2.TypeParameters(1)},
{int, int, c2.TypeParameters(0), c2.TypeParameters(1)})
Dim c1OfIntInt_c2Of_c3 = c3.Construct(substitution)
Assert.NotEqual(c1OfIntInt_c2_c3, c1OfIntInt_c2Of_c3)
Dim c1OfIntInt_c2Of_c3OfInt = c1OfIntInt_c2Of_c3.Construct(int, c3.TypeParameters(1))
Assert.Equal("C1(Of System.Int32, System.Int32).C2(Of C2T1, C2T2).C3(Of System.Int32, C3T2)", c1OfIntInt_c2Of_c3OfInt.ToTestDisplayString())
Assert.True(c1OfIntInt_c2Of_c3OfInt.TypeArguments(1).IsDefinition)
Assert.False(c1OfIntInt_c2Of_c3OfInt.TypeParameters(1).IsDefinition)
Assert.NotEqual(c1OfIntInt_c2_c3, c1OfIntInt_c2Of_c3OfInt.ConstructedFrom)
Assert.Same(c1OfIntInt_c2Of_c3, c1OfIntInt_c2Of_c3OfInt.ConstructedFrom)
Assert.NotEqual(c1OfIntInt_c2Of_c3.TypeParameters(1), c1OfIntInt_c2Of_c3OfInt.TypeArguments(1))
Assert.Same(c1OfIntInt_c2Of_c3.TypeParameters(1).OriginalDefinition, c1OfIntInt_c2Of_c3OfInt.TypeArguments(1))
Assert.Same(c3.TypeParameters(1), c1OfIntInt_c2Of_c3.TypeParameters(1).OriginalDefinition)
Assert.Same(c3.TypeParameters(1).Name, c1OfIntInt_c2Of_c3.TypeParameters(1).Name)
Assert.Equal(c3.TypeParameters(1).HasConstructorConstraint, c1OfIntInt_c2Of_c3.TypeParameters(1).HasConstructorConstraint)
Assert.Equal(c3.TypeParameters(1).HasReferenceTypeConstraint, c1OfIntInt_c2Of_c3.TypeParameters(1).HasReferenceTypeConstraint)
Assert.Equal(c3.TypeParameters(1).HasValueTypeConstraint, c1OfIntInt_c2Of_c3.TypeParameters(1).HasValueTypeConstraint)
Assert.Equal(c3.TypeParameters(1).Ordinal, c1OfIntInt_c2Of_c3.TypeParameters(1).Ordinal)
Assert.Throws(Of InvalidOperationException)(Sub() c1OfIntInt_c2_c3.Construct(c3.TypeParameters(0), c3.TypeParameters(1)))
Dim c1OfIntInt_c2Of_c3Constructed = c1OfIntInt_c2Of_c3.Construct(c3.TypeParameters(0), c3.TypeParameters(1))
Assert.Same(c1OfIntInt_c2Of_c3, c1OfIntInt_c2Of_c3Constructed.ConstructedFrom)
Assert.False(c1OfIntInt_c2Of_c3Constructed.CanConstruct)
Assert.False(c1OfIntInt_c2Of_c3Constructed.ContainingType.CanConstruct)
Assert.NotEqual(c1OfIntInt_c2Of_c3Constructed.ContainingType, c1OfIntInt_c2Of_c3Constructed.ContainingType.ConstructedFrom)
' We need to distinguish these two things in order to be able to detect constraint violation.
' error BC32044: Type argument 'C3T2' does not inherit from or implement the constraint type 'Integer'.
Assert.NotEqual(c1OfIntInt_c2Of_c3, c1OfIntInt_c2Of_c3Constructed)
Assert.Same(c3, c3.Construct(c3.TypeParameters(0), c3.TypeParameters(1)))
substitution = TypeSubstitution.Create(c1, {c1.TypeParameters(0), c1.TypeParameters(1)}, {int, int})
Dim c1OfIntInt_C5_1 = c5.Construct(substitution)
substitution = TypeSubstitution.Create(c5, {c1.TypeParameters(0), c1.TypeParameters(1)}, {int, int})
Dim c1OfIntInt_C5_2 = c5.Construct(substitution)
Assert.Equal(c1OfIntInt_C5_1, c1OfIntInt_C5_2)
Assert.Equal(0, c1OfIntInt_C5_1.TypeParameters.Length)
CompilationUtils.AssertTheseDiagnostics(compilation,
<errors>
BC32044: Type argument 'C3T2' does not inherit from or implement the constraint type 'Integer'.
Dim x As C1(Of Integer, Integer).C2(Of C2T1, C2T2).C3(Of C3T1, C3T2)
~
</errors>)
Assert.Throws(Of InvalidOperationException)(Sub() c5.Construct(c1))
c3OfIntInt.VerifyGenericInstantiationInvariants()
c1OfIntInt_c2_c3.VerifyGenericInstantiationInvariants()
c1OfIntInt_c2Of_c3Of.VerifyGenericInstantiationInvariants()
c1OfIntInt_c2Of_c3.VerifyGenericInstantiationInvariants()
c1OfIntInt_c2Of_c3OfInt.VerifyGenericInstantiationInvariants()
c1OfIntInt_c2Of_c3Constructed.VerifyGenericInstantiationInvariants()
c1OfIntInt_C5_1.VerifyGenericInstantiationInvariants()
c1OfIntInt_C5_2.VerifyGenericInstantiationInvariants()
c1OfIntInt_c2.VerifyGenericInstantiationInvariants()
Dim c1OfIntInt_c2_1 = c1OfIntInt.GetTypeMembers("c2").Single()
Assert.Equal(c1OfIntInt_c2, c1OfIntInt_c2_1)
Assert.NotSame(c1OfIntInt_c2, c1OfIntInt_c2_1) ' Checks below need equal, but not identical symbols to test target scenarios!
Assert.Same(c1OfIntInt_c2, c1OfIntInt_c2.Construct(New List(Of TypeSymbol) From {c1OfIntInt_c2.TypeParameters(0), c1OfIntInt_c2.TypeParameters(1)}))
Assert.Same(c1OfIntInt_c2, c1OfIntInt_c2.Construct(c1OfIntInt_c2_1.TypeParameters(0), c1OfIntInt_c2_1.TypeParameters(1)))
Dim alphaConstructedC2 = c1OfIntInt_c2.Construct(c1OfIntInt_c2_1.TypeParameters(1), c1OfIntInt_c2_1.TypeParameters(0))
Assert.Same(c1OfIntInt_c2, alphaConstructedC2.ConstructedFrom)
Assert.Same(alphaConstructedC2.TypeArguments(0), c1OfIntInt_c2.TypeParameters(1))
Assert.NotSame(alphaConstructedC2.TypeArguments(0), c1OfIntInt_c2_1.TypeParameters(1))
Assert.Same(alphaConstructedC2.TypeArguments(1), c1OfIntInt_c2.TypeParameters(0))
Assert.NotSame(alphaConstructedC2.TypeArguments(1), c1OfIntInt_c2_1.TypeParameters(0))
alphaConstructedC2 = c1OfIntInt_c2.Construct(c1OfIntInt_c2_1.TypeParameters(0), c1OfIntInt)
Assert.Same(c1OfIntInt_c2, alphaConstructedC2.ConstructedFrom)
Assert.Same(alphaConstructedC2.TypeArguments(0), c1OfIntInt_c2.TypeParameters(0))
Assert.NotSame(alphaConstructedC2.TypeArguments(0), c1OfIntInt_c2_1.TypeParameters(0))
Assert.Same(alphaConstructedC2.TypeArguments(1), c1OfIntInt)
alphaConstructedC2 = c1OfIntInt_c2.Construct(c1OfIntInt, c1OfIntInt_c2_1.TypeParameters(1))
Assert.Same(c1OfIntInt_c2, alphaConstructedC2.ConstructedFrom)
Assert.Same(alphaConstructedC2.TypeArguments(0), c1OfIntInt)
Assert.Same(alphaConstructedC2.TypeArguments(1), c1OfIntInt_c2.TypeParameters(1))
Assert.NotSame(alphaConstructedC2.TypeArguments(1), c1OfIntInt_c2_1.TypeParameters(1))
End Sub
<Fact>
Public Sub TypeSubstitutionTypeTest()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="C">
<file name="a.vb">
Class C1(Of C1T1, C1T2)
Class C2(Of C2T1, C2T2)
Class C3(Of C3T1, C3T2 As C1T1)
Class C4(Of C4T1)
End Class
End Class
End Class
Class C5
End Class
End Class
</file>
</compilation>)
Dim int = compilation.GetSpecialType(SpecialType.System_Int32)
Dim bte = compilation.GetSpecialType(SpecialType.System_Byte)
Dim chr = compilation.GetSpecialType(SpecialType.System_Char)
Dim c1 = compilation.GetTypeByMetadataName("C1`2")
Dim c2 = c1.GetTypeMembers("C2").Single()
Dim c3 = c2.GetTypeMembers("C3").Single()
Dim c4 = c3.GetTypeMembers("C4").Single()
Dim c5 = c1.GetTypeMembers("C5").Single()
Dim substitution1 As TypeSubstitution
Dim substitution2 As TypeSubstitution
Dim substitution3 As TypeSubstitution
substitution1 = TypeSubstitution.Create(c1, {c1.TypeParameters(0), c1.TypeParameters(1)}, {int, int})
Assert.Equal("C1(Of C1T1, C1T2) : {C1T1->Integer, C1T2->Integer}", substitution1.ToString())
substitution2 = TypeSubstitution.Create(c4, {c3.TypeParameters(0), c4.TypeParameters(0)}, {bte, chr})
Assert.Equal("C1(Of C1T1, C1T2).C2(Of C2T1, C2T2).C3(Of C3T1, C3T2).C4(Of C4T1) : {C3T1->Byte}, {C4T1->Char}", substitution2.ToString())
Assert.Same(substitution1, TypeSubstitution.Concat(c1, Nothing, substitution1))
Assert.Same(substitution1, TypeSubstitution.Concat(c1, substitution1, Nothing))
Assert.Null(TypeSubstitution.Concat(c1, Nothing, Nothing))
substitution3 = TypeSubstitution.Concat(c2, substitution1, Nothing)
Assert.Equal("C1(Of C1T1, C1T2).C2(Of C2T1, C2T2) : {C1T1->Integer, C1T2->Integer}, {}", substitution3.ToString())
substitution3 = TypeSubstitution.Concat(c4, substitution1, substitution2)
Assert.Equal("C1(Of C1T1, C1T2).C2(Of C2T1, C2T2).C3(Of C3T1, C3T2).C4(Of C4T1) : {C1T1->Integer, C1T2->Integer}, {}, {C3T1->Byte}, {C4T1->Char}", substitution3.ToString())
Assert.Null(TypeSubstitution.Create(c4, {c1.TypeParameters(0)}, {c1.TypeParameters(0)}))
End Sub
<Fact>
Public Sub ConstructionWithAlphaRenaming()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="C">
<file name="a.vb">
Module M
Public G As C1(Of Integer)
End Module
Class C1(Of T)
Class C2(Of U)
Public F As U()
End Class
End Class
</file>
</compilation>)
Dim globalNS = compilation.GlobalNamespace
Dim moduleM = DirectCast(globalNS.GetMembers("M").First(), NamedTypeSymbol)
Dim fieldG = DirectCast(moduleM.GetMembers("G").First(), FieldSymbol)
Dim typeC1OfInteger = fieldG.Type
Dim typeC2 = DirectCast(typeC1OfInteger.GetMembers("C2").First(), NamedTypeSymbol)
Dim fieldF = DirectCast(typeC2.GetMembers("F").First(), FieldSymbol)
Dim fieldFType = fieldF.Type
Assert.Equal("U()", fieldF.Type.ToTestDisplayString())
End Sub
End Class
End Namespace
|