提交 af16c2ad 编写于 作者: I Ivan Basov 提交者: GitHub

Supporting complex types in ENC (#19283)

上级 b0573484
......@@ -498,7 +498,7 @@ public override Symbol VisitNamedType(NamedTypeSymbol sourceType)
return null;
}
return TupleTypeSymbol.Create(otherDef, sourceType.TupleElementNames);
return otherDef;
}
Debug.Assert(sourceType.IsDefinition);
......@@ -888,6 +888,12 @@ public override Symbol VisitDynamicType(DynamicTypeSymbol symbol)
public override Symbol VisitNamedType(NamedTypeSymbol type)
{
if (type.IsTupleType)
{
type = type.TupleUnderlyingType;
Debug.Assert(!type.IsTupleType);
}
var originalDef = type.OriginalDefinition;
if ((object)originalDef != type)
{
......
......@@ -3824,5 +3824,204 @@ .maxstack 2
}
", methodToken: diff1.UpdatedMethods.Single());
}
[Fact]
public void ComplexTypes()
{
var sourceText = @"
using System;
using System.Collections.Generic;
class C1<T>
{
public enum E
{
A
}
}
class C
{
public unsafe static void G()
{
var <N:0>a</N:0> = new { key = ""a"", value = new List<(int, int)>()};
var <N:1>b</N:1> = (number: 5, value: a);
var <N:2>c</N:2> = new[] { b };
int[] <N:3>array</N:3> = { 1, 2, 3 };
ref int <N:4>d</N:4> = ref array[0];
C1<(int, dynamic)>.E***[,,] <N:5>x</N:5> = null;
}
}
";
var source0 = MarkedSource(sourceText);
var source1 = MarkedSource(sourceText);
var source2 = MarkedSource(sourceText);
var compilation0 = CreateStandardCompilation(source0.Tree, options: ComSafeDebugDll.WithAllowUnsafe(true), references: s_valueTupleRefs);
var compilation1 = compilation0.WithSource(source1.Tree);
var compilation2 = compilation1.WithSource(source2.Tree);
var f0 = compilation0.GetMember<MethodSymbol>("C.G");
var f1 = compilation1.GetMember<MethodSymbol>("C.G");
var f2 = compilation2.GetMember<MethodSymbol>("C.G");
var v0 = CompileAndVerify(compilation0);
v0.VerifyIL("C.G", @"
{
// Code size 72 (0x48)
.maxstack 4
.locals init (<>f__AnonymousType0<string, System.Collections.Generic.List<(int, int)>> V_0, //a
System.ValueTuple<int, <anonymous type: string key, System.Collections.Generic.List<(int, int)> value>> V_1, //b
(int number, <anonymous type: string key, System.Collections.Generic.List<(int, int)> value> value)[] V_2, //c
int[] V_3, //array
int& V_4, //d
C1<(int, dynamic)>.E***[,,] V_5) //x
IL_0000: nop
IL_0001: ldstr ""a""
IL_0006: newobj ""System.Collections.Generic.List<(int, int)>..ctor()""
IL_000b: newobj ""<>f__AnonymousType0<string, System.Collections.Generic.List<(int, int)>>..ctor(string, System.Collections.Generic.List<(int, int)>)""
IL_0010: stloc.0
IL_0011: ldloca.s V_1
IL_0013: ldc.i4.5
IL_0014: ldloc.0
IL_0015: call ""System.ValueTuple<int, <anonymous type: string key, System.Collections.Generic.List<(int, int)> value>>..ctor(int, <anonymous type: string key, System.Collections.Generic.List<(int, int)> value>)""
IL_001a: ldc.i4.1
IL_001b: newarr ""System.ValueTuple<int, <anonymous type: string key, System.Collections.Generic.List<(int, int)> value>>""
IL_0020: dup
IL_0021: ldc.i4.0
IL_0022: ldloc.1
IL_0023: stelem ""System.ValueTuple<int, <anonymous type: string key, System.Collections.Generic.List<(int, int)> value>>""
IL_0028: stloc.2
IL_0029: ldc.i4.3
IL_002a: newarr ""int""
IL_002f: dup
IL_0030: ldtoken ""<PrivateImplementationDetails>.__StaticArrayInitTypeSize=12 <PrivateImplementationDetails>.E429CCA3F703A39CC5954A6572FEC9086135B34E""
IL_0035: call ""void System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)""
IL_003a: stloc.3
IL_003b: ldloc.3
IL_003c: ldc.i4.0
IL_003d: ldelema ""int""
IL_0042: stloc.s V_4
IL_0044: ldnull
IL_0045: stloc.s V_5
IL_0047: ret
}
");
var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData);
var generation0 = EmitBaseline.CreateInitialBaseline(md0, v0.CreateSymReader().GetEncMethodDebugInfo);
var diff1 = compilation1.EmitDifference(
generation0,
ImmutableArray.Create(
new SemanticEdit(SemanticEditKind.Update, f0, f1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables: true)));
diff1.VerifyIL("C.G", @"
{
// Code size 73 (0x49)
.maxstack 4
.locals init (<>f__AnonymousType0<string, System.Collections.Generic.List<(int, int)>> V_0, //a
System.ValueTuple<int, <anonymous type: string key, System.Collections.Generic.List<(int, int)> value>> V_1, //b
(int number, <anonymous type: string key, System.Collections.Generic.List<(int, int)> value> value)[] V_2, //c
int[] V_3, //array
int& V_4, //d
C1<(int, dynamic)>.E***[,,] V_5) //x
IL_0000: nop
IL_0001: ldstr ""a""
IL_0006: newobj ""System.Collections.Generic.List<(int, int)>..ctor()""
IL_000b: newobj ""<>f__AnonymousType0<string, System.Collections.Generic.List<(int, int)>>..ctor(string, System.Collections.Generic.List<(int, int)>)""
IL_0010: stloc.0
IL_0011: ldloca.s V_1
IL_0013: ldc.i4.5
IL_0014: ldloc.0
IL_0015: call ""System.ValueTuple<int, <anonymous type: string key, System.Collections.Generic.List<(int, int)> value>>..ctor(int, <anonymous type: string key, System.Collections.Generic.List<(int, int)> value>)""
IL_001a: ldc.i4.1
IL_001b: newarr ""System.ValueTuple<int, <anonymous type: string key, System.Collections.Generic.List<(int, int)> value>>""
IL_0020: dup
IL_0021: ldc.i4.0
IL_0022: ldloc.1
IL_0023: stelem ""System.ValueTuple<int, <anonymous type: string key, System.Collections.Generic.List<(int, int)> value>>""
IL_0028: stloc.2
IL_0029: ldc.i4.3
IL_002a: newarr ""int""
IL_002f: dup
IL_0030: ldc.i4.0
IL_0031: ldc.i4.1
IL_0032: stelem.i4
IL_0033: dup
IL_0034: ldc.i4.1
IL_0035: ldc.i4.2
IL_0036: stelem.i4
IL_0037: dup
IL_0038: ldc.i4.2
IL_0039: ldc.i4.3
IL_003a: stelem.i4
IL_003b: stloc.3
IL_003c: ldloc.3
IL_003d: ldc.i4.0
IL_003e: ldelema ""int""
IL_0043: stloc.s V_4
IL_0045: ldnull
IL_0046: stloc.s V_5
IL_0048: ret
}
");
var diff2 = compilation2.EmitDifference(
diff1.NextGeneration,
ImmutableArray.Create(
new SemanticEdit(SemanticEditKind.Update, f1, f2, GetSyntaxMapFromMarkers(source1, source2), preserveLocalVariables: true)));
diff2.VerifyIL("C.G", @"
{
// Code size 73 (0x49)
.maxstack 4
.locals init (<>f__AnonymousType0<string, System.Collections.Generic.List<(int, int)>> V_0, //a
System.ValueTuple<int, <anonymous type: string key, System.Collections.Generic.List<(int, int)> value>> V_1, //b
(int number, <anonymous type: string key, System.Collections.Generic.List<(int, int)> value> value)[] V_2, //c
int[] V_3, //array
int& V_4, //d
C1<(int, dynamic)>.E***[,,] V_5) //x
IL_0000: nop
IL_0001: ldstr ""a""
IL_0006: newobj ""System.Collections.Generic.List<(int, int)>..ctor()""
IL_000b: newobj ""<>f__AnonymousType0<string, System.Collections.Generic.List<(int, int)>>..ctor(string, System.Collections.Generic.List<(int, int)>)""
IL_0010: stloc.0
IL_0011: ldloca.s V_1
IL_0013: ldc.i4.5
IL_0014: ldloc.0
IL_0015: call ""System.ValueTuple<int, <anonymous type: string key, System.Collections.Generic.List<(int, int)> value>>..ctor(int, <anonymous type: string key, System.Collections.Generic.List<(int, int)> value>)""
IL_001a: ldc.i4.1
IL_001b: newarr ""System.ValueTuple<int, <anonymous type: string key, System.Collections.Generic.List<(int, int)> value>>""
IL_0020: dup
IL_0021: ldc.i4.0
IL_0022: ldloc.1
IL_0023: stelem ""System.ValueTuple<int, <anonymous type: string key, System.Collections.Generic.List<(int, int)> value>>""
IL_0028: stloc.2
IL_0029: ldc.i4.3
IL_002a: newarr ""int""
IL_002f: dup
IL_0030: ldc.i4.0
IL_0031: ldc.i4.1
IL_0032: stelem.i4
IL_0033: dup
IL_0034: ldc.i4.1
IL_0035: ldc.i4.2
IL_0036: stelem.i4
IL_0037: dup
IL_0038: ldc.i4.2
IL_0039: ldc.i4.3
IL_003a: stelem.i4
IL_003b: stloc.3
IL_003c: ldloc.3
IL_003d: ldc.i4.0
IL_003e: ldelema ""int""
IL_0043: stloc.s V_4
IL_0045: ldnull
IL_0046: stloc.s V_5
IL_0048: ret
}
");
}
}
}
\ No newline at end of file
......@@ -769,7 +769,7 @@ public class C
public delegate (int, int) F();
}";
var source1 = @"
public struct C
public class C
{
public delegate (int, bool) F();
}";
......@@ -799,7 +799,7 @@ public class C
public delegate (int, int) F();
}";
var source1 = @"
public struct C
public class C
{
public delegate (int x, int y) F();
}";
......
......@@ -402,7 +402,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
Return Nothing
End If
Return TupleTypeSymbol.Create(otherDef, type.TupleElementNames)
Return otherDef
End If
Debug.Assert(type.IsDefinition)
......@@ -652,10 +652,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
End Sub
Public Overloads Function Equals(source As TypeSymbol, other As TypeSymbol) As Boolean
Dim visitedSource = _matcher.Visit(source)
Dim visitedOther = If(_deepTranslatorOpt IsNot Nothing, _deepTranslatorOpt.Visit(other), other)
Dim visitedSource = DirectCast(_matcher.Visit(source), TypeSymbol)
Dim visitedOther = If(_deepTranslatorOpt IsNot Nothing, DirectCast(_deepTranslatorOpt.Visit(other), TypeSymbol), other)
Return visitedSource = visitedOther
' If both visitedSource and visitedOther are Nothing, return false meaning that the method was not able to verify the equality.
Return visitedSource IsNot Nothing AndAlso visitedOther IsNot Nothing AndAlso visitedSource.IsSameType(visitedOther, TypeCompareKind.IgnoreTupleNames)
End Function
End Class
End Class
......@@ -692,6 +693,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
End Function
Public Overrides Function VisitNamedType(type As NamedTypeSymbol) As Symbol
If type.IsTupleType Then
type = type.TupleUnderlyingType
Debug.Assert(Not type.IsTupleType)
End If
Dim originalDef As NamedTypeSymbol = type.OriginalDefinition
If originalDef IsNot type Then
Dim translatedTypeArguments = type.GetAllTypeArgumentsWithModifiers().SelectAsArray(Function(t, v) New TypeWithModifiers(DirectCast(v.Visit(t.Type), TypeSymbol),
......
......@@ -14776,7 +14776,7 @@ options:=TestOptions.DebugExe, additionalRefs:=s_valueTupleRefs)
Next
For i = 0 To members1.Length - 1
For j = 0 To members2.Length
For j = 0 To members2.Length - 1
If i <> j Then
Assert.NotSame(members1(i), members2(j))
Assert.False(members1(i).Equals(members2(j)))
......@@ -14824,7 +14824,8 @@ options:=TestOptions.DebugExe, additionalRefs:=s_valueTupleRefs)
End Sub
Private Shared Sub AssertTestDisplayString(symbols As ImmutableArray(Of Symbol), ParamArray baseLine As String())
AssertEx.Equal(symbols.Select(Function(s) s.ToTestDisplayString()), baseLine)
' Re-ordering arguments because expected is usually first.
AssertEx.Equal(baseLine, symbols.Select(Function(s) s.ToTestDisplayString()))
End Sub
<Fact>
......
......@@ -21,6 +21,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests
' PDB reader can only be accessed from a single thread, so avoid concurrent compilation:
Protected Shared ReadOnly ComSafeDebugDll As VisualBasicCompilationOptions = TestOptions.DebugDll.WithConcurrentBuild(False)
Protected Shared ReadOnly ValueTupleRefs As MetadataReference() = {SystemRuntimeFacadeRef, ValueTupleRef}
Friend Shared ReadOnly EmptyLocalsProvider As Func(Of MethodDefinitionHandle, EditAndContinueMethodDebugInformation) = Function(token) Nothing
Friend Shared Function Visualize(baseline As ModuleMetadata, ParamArray deltas As PinnedMetadata()) As String
......
......@@ -924,5 +924,125 @@ End Class
End Sub
<Fact>
Public Sub ComplexTypes()
Dim sourceText = "
Imports System
Imports System.Collections.Generic
Class C
Sub G()
Dim <N:0>a</N:0> = New With {.Key = ""a"", .Value = New List(Of Tuple(Of Integer, Integer))()}
Dim <N:1>b</N:1> = (5, a)
Dim <N:2>c</N:2> = {b}
End Sub
End Class
"
Dim source0 = MarkedSource(sourceText)
Dim source1 = MarkedSource(sourceText)
Dim source2 = MarkedSource(sourceText)
Dim compilation0 = CreateCompilationWithMscorlib(source0.Tree, options:=ComSafeDebugDll, references:=ValueTupleRefs)
Dim compilation1 = compilation0.WithSource(source1.Tree)
Dim compilation2 = compilation1.WithSource(source2.Tree)
Dim f0 = compilation0.GetMember(Of MethodSymbol)("C.G")
Dim f1 = compilation1.GetMember(Of MethodSymbol)("C.G")
Dim f2 = compilation2.GetMember(Of MethodSymbol)("C.G")
Dim v0 = CompileAndVerify(compilation0)
v0.VerifyIL("C.G", "
{
// Code size 42 (0x2a)
.maxstack 4
.locals init (VB$AnonymousType_0(Of String, System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer))) V_0, //a
System.ValueTuple(Of Integer, <anonymous type: Key As String, Value As System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer))>) V_1, //b
(Integer, a As <anonymous type: Key As String, Value As System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer))>)() V_2) //c
IL_0000: nop
IL_0001: ldstr ""a""
IL_0006: newobj ""Sub System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer))..ctor()""
IL_000b: newobj ""Sub VB$AnonymousType_0(Of String, System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer)))..ctor(String, System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer)))""
IL_0010: stloc.0
IL_0011: ldloca.s V_1
IL_0013: ldc.i4.5
IL_0014: ldloc.0
IL_0015: call ""Sub System.ValueTuple(Of Integer, <anonymous type: Key As String, Value As System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer))>)..ctor(Integer, <anonymous type: Key As String, Value As System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer))>)""
IL_001a: ldc.i4.1
IL_001b: newarr ""System.ValueTuple(Of Integer, <anonymous type: Key As String, Value As System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer))>)""
IL_0020: dup
IL_0021: ldc.i4.0
IL_0022: ldloc.1
IL_0023: stelem ""System.ValueTuple(Of Integer, <anonymous type: Key As String, Value As System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer))>)""
IL_0028: stloc.2
IL_0029: ret
}
")
Dim md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData)
Dim generation0 = EmitBaseline.CreateInitialBaseline(md0, AddressOf v0.CreateSymReader().GetEncMethodDebugInfo)
Dim diff1 = compilation1.EmitDifference(
generation0,
ImmutableArray.Create(New SemanticEdit(SemanticEditKind.Update, f0, f1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables:=True)))
diff1.VerifyIL("C.G", "
{
// Code size 42 (0x2a)
.maxstack 4
.locals init (VB$AnonymousType_0(Of String, System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer))) V_0, //a
System.ValueTuple(Of Integer, <anonymous type: Key As String, Value As System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer))>) V_1, //b
(Integer, a As <anonymous type: Key As String, Value As System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer))>)() V_2) //c
IL_0000: nop
IL_0001: ldstr ""a""
IL_0006: newobj ""Sub System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer))..ctor()""
IL_000b: newobj ""Sub VB$AnonymousType_0(Of String, System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer)))..ctor(String, System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer)))""
IL_0010: stloc.0
IL_0011: ldloca.s V_1
IL_0013: ldc.i4.5
IL_0014: ldloc.0
IL_0015: call ""Sub System.ValueTuple(Of Integer, <anonymous type: Key As String, Value As System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer))>)..ctor(Integer, <anonymous type: Key As String, Value As System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer))>)""
IL_001a: ldc.i4.1
IL_001b: newarr ""System.ValueTuple(Of Integer, <anonymous type: Key As String, Value As System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer))>)""
IL_0020: dup
IL_0021: ldc.i4.0
IL_0022: ldloc.1
IL_0023: stelem ""System.ValueTuple(Of Integer, <anonymous type: Key As String, Value As System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer))>)""
IL_0028: stloc.2
IL_0029: ret
}
")
Dim diff2 = compilation2.EmitDifference(
diff1.NextGeneration,
ImmutableArray.Create(New SemanticEdit(SemanticEditKind.Update, f1, f2, GetSyntaxMapFromMarkers(source1, source2), preserveLocalVariables:=True)))
diff2.VerifyIL("C.G", "
{
// Code size 42 (0x2a)
.maxstack 4
.locals init (VB$AnonymousType_0(Of String, System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer))) V_0, //a
System.ValueTuple(Of Integer, <anonymous type: Key As String, Value As System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer))>) V_1, //b
(Integer, a As <anonymous type: Key As String, Value As System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer))>)() V_2) //c
IL_0000: nop
IL_0001: ldstr ""a""
IL_0006: newobj ""Sub System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer))..ctor()""
IL_000b: newobj ""Sub VB$AnonymousType_0(Of String, System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer)))..ctor(String, System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer)))""
IL_0010: stloc.0
IL_0011: ldloca.s V_1
IL_0013: ldc.i4.5
IL_0014: ldloc.0
IL_0015: call ""Sub System.ValueTuple(Of Integer, <anonymous type: Key As String, Value As System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer))>)..ctor(Integer, <anonymous type: Key As String, Value As System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer))>)""
IL_001a: ldc.i4.1
IL_001b: newarr ""System.ValueTuple(Of Integer, <anonymous type: Key As String, Value As System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer))>)""
IL_0020: dup
IL_0021: ldc.i4.0
IL_0022: ldloc.1
IL_0023: stelem ""System.ValueTuple(Of Integer, <anonymous type: Key As String, Value As System.Collections.Generic.List(Of System.Tuple(Of Integer, Integer))>)""
IL_0028: stloc.2
IL_0029: ret
}
")
End Sub
End Class
End Namespace
......@@ -512,5 +512,397 @@ End Class
Assert.Equal("$VB$Local_x1", mappedX1.Name)
Assert.Null(mappedX2)
End Sub
<Fact>
Public Sub TupleField_TypeChange()
Dim source0 = "
Class C
{
Public x As (a As Integer, b As Integer)
}"
Dim source1 = "
Class C
{
Public x As (a As Integer, b As Boolean)
}"
Dim compilation0 = CreateCompilationWithMscorlib(source0, options:=TestOptions.DebugDll, references:=ValueTupleRefs)
Dim compilation1 = compilation0.WithSource(source1)
Dim matcher = New VisualBasicSymbolMatcher(
Nothing,
compilation1.SourceAssembly,
New EmitContext(),
compilation0.SourceAssembly,
New EmitContext(),
Nothing)
Dim member = compilation1.GetMember(Of FieldSymbol)("C.x")
Dim other = matcher.MapDefinition(member)
' If a type changes within a tuple, we do not expect types to match.
Assert.Null(other)
End Sub
<Fact>
Public Sub TupleField_NameChange()
Dim source0 = "
Class C
{
Public x As (a As Integer, b As Integer)
}"
Dim source1 = "
Class C
{
Public x As (a As Integer, c As Integer)
}"
Dim compilation0 = CreateCompilationWithMscorlib(source0, options:=TestOptions.DebugDll, references:=ValueTupleRefs)
Dim compilation1 = compilation0.WithSource(source1)
Dim matcher = New VisualBasicSymbolMatcher(
Nothing,
compilation1.SourceAssembly,
New EmitContext(),
compilation0.SourceAssembly,
New EmitContext(),
Nothing)
Dim member = compilation1.GetMember(Of FieldSymbol)("C.x")
Dim other = matcher.MapDefinition(member)
' Types must match because just an element name was changed.
Dim otherSymbol = DirectCast(other, SourceFieldSymbol)
Assert.NotNull(otherSymbol)
Assert.Equal("C.x As (a As System.Int32, b As System.Int32)", otherSymbol.ToTestDisplayString())
End Sub
<Fact>
Public Sub TupleMethod_TypeToNoTupleChange()
Dim source0 = "
Class C
Public Function X() As (a As Integer, b As Integer)
Return Nothing
End Function
End Class
"
Dim source1 = "
Class C
Public Function X() As Integer()
Return Nothing
End Function
End Class
"
Dim compilation0 = CreateCompilationWithMscorlib(source0, options:=TestOptions.DebugDll, references:=ValueTupleRefs)
Dim compilation1 = compilation0.WithSource(source1)
Dim matcher = New VisualBasicSymbolMatcher(
Nothing,
compilation1.SourceAssembly,
New EmitContext(),
compilation0.SourceAssembly,
New EmitContext(),
Nothing)
Dim member = compilation1.GetMember(Of MethodSymbol)("C.X")
Dim other = matcher.MapDefinition(member)
' Types should not match: one is tuple and another is not.
Assert.Null(other)
End Sub
<Fact>
Public Sub TupleMethod_TypeFromNoTupleChange()
Dim source0 = "
Class C
Public Function X() As Integer()
Return Nothing
End Function
End Class
"
Dim source1 = "
Class C
Public Function X() As (a As Integer, b As Boolean)
Return Nothing
End Function
End Class
"
Dim compilation0 = CreateCompilationWithMscorlib(source0, options:=TestOptions.DebugDll, references:=ValueTupleRefs)
Dim compilation1 = compilation0.WithSource(source1)
Dim matcher = New VisualBasicSymbolMatcher(
Nothing,
compilation1.SourceAssembly,
New EmitContext(),
compilation0.SourceAssembly,
New EmitContext(),
Nothing)
Dim member = compilation1.GetMember(Of MethodSymbol)("C.X")
Dim other = matcher.MapDefinition(member)
' Types should not match: one is tuple and another is not.
Assert.Null(other)
End Sub
<Fact>
Public Sub TupleMethod_TypeChange()
Dim source0 = "
Class C
Public Function X() As (a As Integer, b As Integer)
Return Nothing
End Function
End Class
"
Dim source1 = "
Class C
Public Function X() As (a As Integer, b As Boolean)
Return Nothing
End Function
End Class
"
Dim compilation0 = CreateCompilationWithMscorlib(source0, options:=TestOptions.DebugDll, references:=ValueTupleRefs)
Dim compilation1 = compilation0.WithSource(source1)
Dim matcher = New VisualBasicSymbolMatcher(
Nothing,
compilation1.SourceAssembly,
New EmitContext(),
compilation0.SourceAssembly,
New EmitContext(),
Nothing)
Dim member = compilation1.GetMember(Of MethodSymbol)("C.X")
Dim other = matcher.MapDefinition(member)
' If a type changes within a tuple, we do not expect types to match.
Assert.Null(other)
End Sub
<Fact>
Public Sub TupleMethod_NameChange()
Dim source0 = "
Class C
Public Function X() As (a As Integer, b As Integer)
Return Nothing
End Function
End Class
"
Dim source1 = "
Class C
Public Function X() As (a As Integer, c As Integer)
Return Nothing
End Function
End Class
"
Dim compilation0 = CreateCompilationWithMscorlib(source0, options:=TestOptions.DebugDll, references:=ValueTupleRefs)
Dim compilation1 = compilation0.WithSource(source1)
Dim matcher = New VisualBasicSymbolMatcher(
Nothing,
compilation1.SourceAssembly,
New EmitContext(),
compilation0.SourceAssembly,
New EmitContext(),
Nothing)
Dim member = compilation1.GetMember(Of MethodSymbol)("C.X")
Dim other = matcher.MapDefinition(member)
' Types must match because just an element name was changed.
Dim otherSymbol = DirectCast(other, SourceMemberMethodSymbol)
Assert.NotNull(otherSymbol)
Assert.Equal("Function C.X() As (a As System.Int32, b As System.Int32)", otherSymbol.ToTestDisplayString())
End Sub
<Fact>
Public Sub TupleProperty_TypeChange()
Dim source0 = "
Class C
Public ReadOnly Property X As (a As Integer, b As Integer)
Get
Return Nothing
End Get
End Property
End Class
"
Dim source1 = "
Class C
Public ReadOnly Property X As (a As Integer, b As Boolean)
Get
Return Nothing
End Get
End Property
End Class
"
Dim compilation0 = CreateCompilationWithMscorlib(source0, options:=TestOptions.DebugDll, references:=ValueTupleRefs)
Dim compilation1 = compilation0.WithSource(source1)
Dim matcher = New VisualBasicSymbolMatcher(
Nothing,
compilation1.SourceAssembly,
New EmitContext(),
compilation0.SourceAssembly,
New EmitContext(),
Nothing)
Dim member = compilation1.GetMember(Of PropertySymbol)("C.X")
Dim other = matcher.MapDefinition(member)
' If a type changes within a tuple, we do not expect types to match.
Assert.Null(other)
End Sub
<Fact>
Public Sub TupleProperty_NameChange()
Dim source0 = "
Class C
Public ReadOnly Property X As (a As Integer, b As Integer)
Get
Return Nothing
End Get
End Property
End Class
"
Dim source1 = "
Class C
Public ReadOnly Property X As (a As Integer, c As Integer)
Get
Return Nothing
End Get
End Property
End Class
"
Dim compilation0 = CreateCompilationWithMscorlib(source0, options:=TestOptions.DebugDll, references:=ValueTupleRefs)
Dim compilation1 = compilation0.WithSource(source1)
Dim matcher = New VisualBasicSymbolMatcher(
Nothing,
compilation1.SourceAssembly,
New EmitContext(),
compilation0.SourceAssembly,
New EmitContext(),
Nothing)
Dim member = compilation1.GetMember(Of PropertySymbol)("C.X")
Dim other = matcher.MapDefinition(member)
' Types must match because just an element name was changed.
Dim otherSymbol = DirectCast(other, SourcePropertySymbol)
Assert.NotNull(otherSymbol)
Assert.Equal("ReadOnly Property C.X As (a As System.Int32, b As System.Int32)", otherSymbol.ToTestDisplayString())
End Sub
<Fact>
Public Sub TupleStructField_TypeChange()
Dim source0 = "
Public Structure Vector
Public Coordinates As (x As Integer, y As Integer)
End Structure
"
Dim source1 = "
Public Structure Vector
Public Coordinates As (x As Integer, y As Integer, z As Integer)
End Structure
"
Dim compilation0 = CreateCompilationWithMscorlib(source0, options:=TestOptions.DebugDll, references:=ValueTupleRefs)
Dim compilation1 = compilation0.WithSource(source1)
Dim matcher = New VisualBasicSymbolMatcher(
Nothing,
compilation1.SourceAssembly,
New EmitContext(),
compilation0.SourceAssembly,
New EmitContext(),
Nothing)
Dim member = compilation1.GetMember(Of FieldSymbol)("Vector.Coordinates")
Dim other = matcher.MapDefinition(member)
' If a type changes within a tuple, we do not expect types to match.
Assert.Null(other)
End Sub
<Fact>
Public Sub TupleStructField_NameChange()
Dim source0 = "
Public Structure Vector
Public Coordinates As (x As Integer, y As Integer)
End Structure
"
Dim source1 = "
Public Structure Vector
Public Coordinates As (x As Integer, z As Integer)
End Structure
"
Dim compilation0 = CreateCompilationWithMscorlib(source0, options:= TestOptions.DebugDll, references:= ValueTupleRefs)
Dim compilation1 = compilation0.WithSource(source1)
Dim matcher = New VisualBasicSymbolMatcher(
Nothing,
compilation1.SourceAssembly,
New EmitContext(),
compilation0.SourceAssembly,
New EmitContext(),
Nothing)
Dim member = compilation1.GetMember(Of FieldSymbol)("Vector.Coordinates")
Dim other = matcher.MapDefinition(member)
' Types must match because just an element name was changed.
Dim otherSymbol = DirectCast(other, SourceFieldSymbol)
Assert.NotNull(otherSymbol)
Assert.Equal("Vector.Coordinates As (x As System.Int32, y As System.Int32)", otherSymbol.ToTestDisplayString())
End Sub
<Fact>
Public Sub TupleDelegate_TypeChange()
Dim source0 = "
Public Class C
Public Delegate Function F() As (Integer, Integer)
End Class
"
Dim source1 = "
Public Class C
Public Delegate Function F() As (Integer, Boolean)
End Class
"
Dim compilation0 = CreateCompilationWithMscorlib(source0, options:= TestOptions.DebugDll, references:= ValueTupleRefs)
Dim compilation1 = compilation0.WithSource(source1)
Dim matcher = New VisualBasicSymbolMatcher(
Nothing,
compilation1.SourceAssembly,
New EmitContext(),
compilation0.SourceAssembly,
New EmitContext(),
Nothing)
Dim member = compilation1.GetMember(Of SourceNamedTypeSymbol)("C.F")
Dim other = matcher.MapDefinition(member)
' Tuple delegate defines a type. We should be able to match old and new types by name.
Dim otherSymbol = DirectCast(other, SourceNamedTypeSymbol)
Assert.NotNull(otherSymbol)
Assert.Equal("C.F", otherSymbol.ToTestDisplayString())
End Sub
<Fact>
Public Sub TupleDeletagate_NameChange()
Dim source0 = "
Public Class C
Public Delegate Function F() As (x as Integer, y as Integer)
End Class
"
Dim source1 = "
Public Class C
Public Delegate Function F() As (x as Integer, z as Integer)
End Class"
Dim compilation0 = CreateCompilationWithMscorlib(source0, options:=TestOptions.DebugDll, references:=ValueTupleRefs)
Dim compilation1 = compilation0.WithSource(source1)
Dim matcher = New VisualBasicSymbolMatcher(
Nothing,
compilation1.SourceAssembly,
New EmitContext(),
compilation0.SourceAssembly,
New EmitContext(),
Nothing)
Dim member = compilation1.GetMember(Of SourceNamedTypeSymbol)("C.F")
Dim other = matcher.MapDefinition(member)
' Types must match because just an element name was changed.
Dim otherSymbol = DirectCast(other, SourceNamedTypeSymbol)
Assert.NotNull(otherSymbol)
Assert.Equal("C.F", otherSymbol.ToTestDisplayString())
End Sub
End Class
End Namespace
End Namespace
\ No newline at end of file
......@@ -448,6 +448,10 @@ public static string GetAssertMessage<T>(IEnumerable<T> expected, IEnumerable<T>
{
itemInspector = b => $"0x{b:X2}";
}
else if (expected is IEnumerable<string>)
{
itemInspector = new Func<T, string>(obj => (obj != null) ? string.Format("\"{0}\"", obj.ToString()) : "<null>");
}
else
{
itemInspector = new Func<T, string>(obj => (obj != null) ? obj.ToString() : "<null>");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册