提交 449e50ab 编写于 作者: A Andrew Casey

Merge pull request #2794 from amcasey/DD1139013VB

Expand transparent identifier in the (VB) EE
......@@ -17,6 +17,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
StateMachineStateField
StateMachineHoistedUserVariableField
StaticLocalField
TransparentIdentifier
AnonymousTransparentIdentifier
AnonymousType
LambdaCacheField
End Enum
......@@ -43,6 +46,16 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
Return GeneratedNameKind.StateMachineAwaiterField
ElseIf name.StartsWith(StringConstants.StateMachineHoistedUserVariablePrefix, StringComparison.Ordinal) Then
Return GeneratedNameKind.StateMachineHoistedUserVariableField
ElseIf name.StartsWith(AnonymousTypeTemplateNamePrefix, StringComparison.Ordinal) Then
Return GeneratedNameKind.AnonymousType
ElseIf name.Equals(StringConstants.It, StringComparison.Ordinal) OrElse
name.Equals(StringConstants.It1, StringComparison.Ordinal) OrElse
name.Equals(StringConstants.It2, StringComparison.Ordinal) Then
Return GeneratedNameKind.TransparentIdentifier
ElseIf name.Equals(StringConstants.ItAnonymous, StringComparison.Ordinal) Then
' We distinguish StringConstants.ItAnonymous, because it won't be an instance
' of an anonymous type.
Return GeneratedNameKind.AnonymousTransparentIdentifier
End If
Return GeneratedNameKind.None
......
......@@ -151,8 +151,7 @@ internal sealed class EEMethodSymbol : MethodSymbol
var variable = pair.Value;
var oldDisplayClassInstance = variable.DisplayClassInstance;
// Note: the code path for DisplayClassInstanceFromLocal is equivalent to calling
// oldDisplayClassInstance.ToOtherMethod, except that doing that would produce
// Note: we don't call ToOtherMethod in the local case because doing so would produce
// a new LocalSymbol that would not be ReferenceEquals to the one in this.LocalsForBinding.
var oldDisplayClassInstanceFromLocal = oldDisplayClassInstance as DisplayClassInstanceFromLocal;
var newDisplayClassInstance = (oldDisplayClassInstanceFromLocal == null) ?
......
......@@ -2820,7 +2820,6 @@ .maxstack 1
testData = new CompilationTestData();
context.CompileExpression("z", out error, testData);
Assert.Null(error);
testData.GetMethodData("<>x.<>m0").VerifyIL(zIL);
testData = new CompilationTestData();
......@@ -2923,7 +2922,6 @@ .maxstack 1
testData = new CompilationTestData();
context.CompileExpression("z", out error, testData);
Assert.Null(error);
testData.GetMethodData("<>x.<>m0").VerifyIL(zIL);
testData = new CompilationTestData();
......
......@@ -28,7 +28,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Dim nameToSymbolMap As New Dictionary(Of String, Symbol)(CaseInsensitiveComparison.Comparer)
For Each parameter In parameters
nameToSymbolMap(parameter.Name) = parameter
Dim name As String = parameter.Name
Dim kind As GeneratedNameKind = GeneratedNames.GetKind(name)
If kind = GeneratedNameKind.None OrElse kind = GeneratedNameKind.HoistedMeField Then
nameToSymbolMap(name) = parameter
Else
Debug.Assert(kind = GeneratedNameKind.TransparentIdentifier OrElse
kind = GeneratedNameKind.AnonymousTransparentIdentifier)
End If
Next
For Each local In locals
......
......@@ -276,7 +276,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
' Method parameters (except those that have been hoisted).
Dim parameterIndex = If(m.IsShared, 0, 1)
For Each parameter In m.Parameters
If Not _hoistedParameterNames.Contains(parameter.Name) Then
Dim parameterName As String = parameter.Name
If Not _hoistedParameterNames.Contains(parameterName) AndAlso GeneratedNames.GetKind(parameterName) = GeneratedNameKind.None Then
AppendParameterAndMethod(localBuilder, methodBuilder, parameter, container, parameterIndex)
End If
......@@ -1006,12 +1007,20 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
End If
Next
For Each parameter As ParameterSymbol In method.Parameters
If GeneratedNames.GetKind(parameter.Name) = GeneratedNameKind.TransparentIdentifier Then
Dim instance As New DisplayClassInstanceFromParameter(parameter)
displayClassTypes.Add(instance.Type)
displayClassInstances.Add(New DisplayClassInstanceAndFields(instance))
End If
Next
Dim containingType = method.ContainingType
Dim isIteratorOrAsyncMethod = False
If containingType.IsClosureOrStateMachineType() Then
If Not method.IsShared Then
' Add "Me" display class instance.
Dim instance As New DisplayClassInstanceFromMe(method.MeParameter)
Dim instance As New DisplayClassInstanceFromParameter(method.MeParameter)
displayClassTypes.Add(instance.Type)
displayClassInstances.Add(New DisplayClassInstanceAndFields(instance))
End If
......@@ -1104,6 +1113,19 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
name.StartsWith(StringConstants.HoistedSpecialVariablePrefix & StringConstants.DisplayClassPrefix, StringComparison.Ordinal) ' Async lambda case
End Function
Private Shared Function IsTransparentIdentifierField(field As FieldSymbol) As Boolean
Dim fieldName = field.Name
Dim unmangledName As String = Nothing
If GeneratedNames.TryParseHoistedUserVariableName(fieldName, unmangledName) Then
fieldName = unmangledName
ElseIf field.IsAnonymousTypeField(unmangledName) Then
fieldName = unmangledName
End If
Return GeneratedNames.GetKind(fieldName) = GeneratedNameKind.TransparentIdentifier
End Function
Private Shared Function IsGeneratedLocalName(name As String) As Boolean
Debug.Assert(name IsNot Nothing) ' Verified by caller.
' If a local's name contains "$", then it is a generated local.
......@@ -1157,7 +1179,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Dim field = DirectCast(member, FieldSymbol)
Dim fieldType = field.Type
Dim fieldName As String = field.Name
If IsDisplayClassInstanceFieldName(fieldName) Then
If IsDisplayClassInstanceFieldName(fieldName) OrElse
IsTransparentIdentifierField(field) Then
Debug.Assert(Not field.IsShared)
' A local that is itself a display class instance.
If displayClassTypes.Add(DirectCast(fieldType, NamedTypeSymbol)) Then
......@@ -1187,6 +1210,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Dim field = DirectCast(member, FieldSymbol)
Dim fieldName = field.Name
Dim unmangledName As String = Nothing
If field.IsAnonymousTypeField(unmangledName) Then
fieldName = unmangledName
End If
Dim variableKind As DisplayClassVariableKind
Dim variableName As String
......@@ -1213,6 +1241,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
variableName = fieldName ' As in C#, we retain the mangled name. It shouldn't be used, other than as a dictionary key.
ElseIf fieldName.StartsWith(StringConstants.LambdaCacheFieldPrefix, StringComparison.Ordinal) Then
Continue For
ElseIf GeneratedNames.GetKind(fieldName) = GeneratedNameKind.TransparentIdentifier
' A transparent identifier (field) in an anonymous type synthesized for a transparent identifier.
Debug.Assert(Not field.IsShared)
Continue For
Else
variableKind = DisplayClassVariableKind.Local
variableName = fieldName
......@@ -1393,7 +1425,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Friend Sub New(instance As DisplayClassInstance)
MyClass.New(instance, ConsList(Of FieldSymbol).Empty)
Debug.Assert(instance.Type.IsClosureOrStateMachineType())
Debug.Assert(instance.Type.IsClosureOrStateMachineType() OrElse
GeneratedNames.GetKind(instance.Type.Name) = GeneratedNameKind.AnonymousType)
End Sub
Private Sub New(instance As DisplayClassInstance, fields As ConsList(Of FieldSymbol))
......@@ -1414,7 +1447,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
End Property
Friend Function FromField(field As FieldSymbol) As DisplayClassInstanceAndFields
Debug.Assert(field.Type.IsClosureOrStateMachineType())
Debug.Assert(field.Type.IsClosureOrStateMachineType() OrElse
GeneratedNames.GetKind(field.Type.Name) = GeneratedNameKind.AnonymousType)
Return New DisplayClassInstanceAndFields(Me.Instance, Me.Fields.Prepend(field))
End Function
......
......@@ -122,12 +122,15 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
End Function
Private Function RewriteParameter(syntax As VisualBasicSyntaxNode, symbol As ParameterSymbol, node As BoundExpression) As BoundExpression
Dim variable = Me.GetVariable(symbol.Name)
Dim name As String = symbol.Name
Dim variable = Me.GetVariable(name)
If variable Is Nothing Then
' The state machine case is for async lambdas. The state machine
' will have a hoisted "me" field if it needs access to the containing
' display class, but the display class may not have a "me" field.
If symbol.Type.IsClosureOrStateMachineType() Then
If symbol.Type.IsClosureOrStateMachineType() AndAlso
GeneratedNames.GetKind(name) <> GeneratedNameKind.TransparentIdentifier Then
ReportMissingMe(syntax)
End If
......
......@@ -2,6 +2,7 @@
Imports System.Collections.Immutable
Imports System.Runtime.CompilerServices
Imports System.Runtime.InteropServices
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
......@@ -70,5 +71,20 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
builder.AddRange(method.TypeParameters)
Return builder.ToImmutableAndFree()
End Function
<Extension>
Friend Function IsAnonymousTypeField(field As FieldSymbol, <Out> ByRef unmangledName As String) As Boolean
If GeneratedNames.GetKind(field.ContainingType.Name) <> GeneratedNameKind.AnonymousType Then
unmangledName = Nothing
Return False
End If
unmangledName = field.Name
If unmangledName(0) = "$"c Then
unmangledName = unmangledName.Substring(1)
End If
Return True
End Function
End Module
End Namespace
......@@ -44,36 +44,40 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
End Function
End Class
Friend NotInheritable Class DisplayClassInstanceFromMe
Friend NotInheritable Class DisplayClassInstanceFromParameter
Inherits DisplayClassInstance
Friend ReadOnly MeParameter As ParameterSymbol
Friend ReadOnly Parameter As ParameterSymbol
Friend Sub New(meParameter As ParameterSymbol)
Debug.Assert(meParameter IsNot Nothing)
Me.MeParameter = meParameter
Friend Sub New(parameter As ParameterSymbol)
Debug.Assert(parameter IsNot Nothing)
Debug.Assert(parameter.Name.Equals("Me", StringComparison.Ordinal) OrElse
parameter.Name.IndexOf("$Me", StringComparison.Ordinal) >= 0 OrElse
parameter.Name.IndexOf("$It", StringComparison.Ordinal) >= 0)
Me.Parameter = parameter
End Sub
Friend Overrides ReadOnly Property ContainingSymbol As Symbol
Get
Return Me.MeParameter.ContainingSymbol
Return Me.Parameter.ContainingSymbol
End Get
End Property
Friend Overrides ReadOnly Property Type As NamedTypeSymbol
Get
Return DirectCast(Me.MeParameter.Type, NamedTypeSymbol)
Return DirectCast(Me.Parameter.Type, NamedTypeSymbol)
End Get
End Property
Friend Overrides Function ToOtherMethod(method As MethodSymbol, typeMap As TypeSubstitution) As DisplayClassInstance
Debug.Assert(method.IsShared)
Dim otherParameter = method.Parameters(0)
Return New DisplayClassInstanceFromMe(otherParameter)
Dim otherOrdinal = If(Me.ContainingSymbol.IsShared, Me.Parameter.Ordinal, Me.Parameter.Ordinal + 1)
Dim otherParameter = method.Parameters(otherOrdinal)
Return New DisplayClassInstanceFromParameter(otherParameter)
End Function
Friend Overrides Function ToBoundExpression(syntax As VisualBasicSyntaxNode) As BoundExpression
Return New BoundParameter(syntax, Me.MeParameter, Me.MeParameter.Type).MakeCompilerGenerated()
Return New BoundParameter(syntax, Me.Parameter, Me.Parameter.Type).MakeCompilerGenerated()
End Function
End Class
End Namespace
......@@ -84,7 +84,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Private Shared Function SubstituteField(field As FieldSymbol, typeMap As TypeSubstitution) As FieldSymbol
Debug.Assert(Not field.IsShared)
Debug.Assert(Not field.IsReadOnly)
Debug.Assert(Not field.IsReadOnly OrElse field.IsAnonymousTypeField(Nothing))
Debug.Assert(field.CustomModifiers.Length = 0)
Debug.Assert(Not field.HasConstantValue)
Return New EEDisplayClassFieldSymbol(typeMap.SubstituteNamedType(field.ContainingType), field.Name, typeMap.SubstituteType(field.Type), field.DeclaredAccessibility)
......
......@@ -132,24 +132,40 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Me.LocalsForBinding = localsBuilder.ToImmutableAndFree()
' Create a map from variable name to display class field.
Dim displayClassVariables = PooledDictionary(Of String, DisplayClassVariable).GetInstance()
For Each pair In sourceDisplayClassVariables
Dim variable = pair.Value
Dim displayClassInstanceFromLocal = TryCast(variable.DisplayClassInstance, DisplayClassInstanceFromLocal)
Dim displayClassInstance = If(displayClassInstanceFromLocal Is Nothing,
DirectCast(New DisplayClassInstanceFromMe(Me.Parameters(0)), DisplayClassInstance),
New DisplayClassInstanceFromLocal(DirectCast(localsMap(displayClassInstanceFromLocal.Local), EELocalSymbol)))
variable = variable.SubstituteFields(displayClassInstance, Me.TypeMap)
displayClassVariables.Add(pair.Key, variable)
Next
_displayClassVariables = displayClassVariables.ToImmutableDictionary()
displayClassVariables.Free()
_displayClassVariables = SubstituteDisplayClassVariables(sourceDisplayClassVariables, localsMap, Me, Me.TypeMap)
localsMap.Free()
_generateMethodBody = generateMethodBody
End Sub
Private Shared Function SubstituteDisplayClassVariables(
oldDisplayClassVariables As ImmutableDictionary(Of String, DisplayClassVariable),
localsMap As Dictionary(Of LocalSymbol, LocalSymbol),
otherMethod As MethodSymbol,
typeMap As TypeSubstitution) As ImmutableDictionary(Of String, DisplayClassVariable)
' Create a map from variable name to display class field.
Dim newDisplayClassVariables = PooledDictionary(Of String, DisplayClassVariable).GetInstance()
For Each pair In oldDisplayClassVariables
Dim variable = pair.Value
Dim oldDisplayClassInstance = variable.DisplayClassInstance
' Note: we don't call ToOtherMethod in the local case because doing so would produce
' a new LocalSymbol that would not be ReferenceEquals to the one in this.LocalsForBinding.
Dim oldDisplayClassInstanceFromLocal = TryCast(oldDisplayClassInstance, DisplayClassInstanceFromLocal)
Dim newDisplayClassInstance = If(oldDisplayClassInstanceFromLocal Is Nothing,
oldDisplayClassInstance.ToOtherMethod(otherMethod, typeMap),
New DisplayClassInstanceFromLocal(DirectCast(localsMap(oldDisplayClassInstanceFromLocal.Local), EELocalSymbol)))
variable = variable.SubstituteFields(newDisplayClassInstance, typeMap)
newDisplayClassVariables.Add(pair.Key, variable)
Next
Dim result = newDisplayClassVariables.ToImmutableDictionary()
newDisplayClassVariables.Free()
Return result
End Function
Private Function MakeParameterSymbol(ordinal As Integer, name As String, sourceParameter As ParameterSymbol) As ParameterSymbol
Return New SynthesizedParameterSymbolWithCustomModifiers(
Me,
......@@ -510,25 +526,15 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
' is triggered by overriding PreserveOriginalLocals to return "True".
' Create a map from variable name to display class field.
Dim displayClassVariables = PooledDictionary(Of String, DisplayClassVariable).GetInstance()
For Each pair In _displayClassVariables
Dim variable = pair.Value
Dim displayClassInstanceFromLocal = TryCast(variable.DisplayClassInstance, DisplayClassInstanceFromLocal)
Dim displayClassInstance = If(displayClassInstanceFromLocal Is Nothing,
DirectCast(New DisplayClassInstanceFromMe(Me.Parameters(0)), DisplayClassInstance),
New DisplayClassInstanceFromLocal(DirectCast(localMap(displayClassInstanceFromLocal.Local), EELocalSymbol)))
variable = New DisplayClassVariable(variable.Name, variable.Kind, displayClassInstance, variable.DisplayClassFields)
displayClassVariables.Add(pair.Key, variable)
Next
Dim displayClassVariables = SubstituteDisplayClassVariables(_displayClassVariables, localMap, Me, Me.TypeMap)
' Rewrite references to "Me" to refer to this method's "Me" parameter.
' Rewrite variables within body to reference existing display classes.
newBody = DirectCast(CapturedVariableRewriter.Rewrite(
If(Me.SubstitutedSourceMethod.IsShared, Nothing, Me.Parameters(0)),
displayClassVariables.ToImmutableDictionary(),
displayClassVariables,
newBody,
diagnostics), BoundBlock)
displayClassVariables.Free()
If diagnostics.HasAnyErrors() Then
Return newBody
......
......@@ -2729,6 +2729,400 @@ End Class"
locals.Free()
End Sub
<WorkItem(1139013, "DevDiv")>
<Fact>
Public Sub TransparentIdentifiers_FromParameter()
Const source = "
Imports System.Linq
Class C
Sub M(args As String())
Dim concat =
From x In args
Let y = x.ToString()
Let z = x.GetHashCode()
Select x & y & z
End Sub
End Class
"
Const methodName = "C._Closure$__._Lambda$__1-2"
Const zIL = "
{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.1
IL_0001: ldfld ""VB$AnonymousType_1(Of VB$AnonymousType_0(Of String, String), Integer).$z As Integer""
IL_0006: ret
}
"
Const xIL = "
{
// Code size 12 (0xc)
.maxstack 1
IL_0000: ldarg.1
IL_0001: ldfld ""VB$AnonymousType_1(Of VB$AnonymousType_0(Of String, String), Integer).$$VB$It As VB$AnonymousType_0(Of String, String)""
IL_0006: ldfld ""VB$AnonymousType_0(Of String, String).$x As String""
IL_000b: ret
}
"
Const yIL = "
{
// Code size 12 (0xc)
.maxstack 1
IL_0000: ldarg.1
IL_0001: ldfld ""VB$AnonymousType_1(Of VB$AnonymousType_0(Of String, String), Integer).$$VB$It As VB$AnonymousType_0(Of String, String)""
IL_0006: ldfld ""VB$AnonymousType_0(Of String, String).$y As String""
IL_000b: ret
}
"
Dim comp = CreateCompilationWithMscorlib({source}, {SystemCoreRef, MsvbRef}, TestOptions.DebugDll)
Dim runtime = CreateRuntimeInstance(comp)
Dim typeName As String = Nothing
Dim locals = ArrayBuilder(Of LocalAndMethod).GetInstance()
Dim testData As CompilationTestData = Nothing
GetLocals(runtime, methodName, argumentsOnly:=False, locals:=locals, count:=3, typeName:=typeName, testData:=testData)
VerifyLocal(testData, typeName, locals(0), "<>m0", "z", expectedILOpt:=zIL)
VerifyLocal(testData, typeName, locals(1), "<>m1", "x", expectedILOpt:=xIL)
VerifyLocal(testData, typeName, locals(2), "<>m2", "y", expectedILOpt:=yIL)
locals.Free()
Dim context = CreateMethodContext(runtime, methodName)
Dim errorMessage As String = Nothing
testData = New CompilationTestData()
context.CompileExpression("z", errorMessage, testData)
Assert.Null(errorMessage)
testData.GetMethodData("<>x.<>m0").VerifyIL(zIL)
testData = New CompilationTestData()
context.CompileExpression("x", errorMessage, testData)
Assert.Null(errorMessage)
testData.GetMethodData("<>x.<>m0").VerifyIL(xIL)
testData = New CompilationTestData()
context.CompileExpression("y", errorMessage, testData)
Assert.Null(errorMessage)
testData.GetMethodData("<>x.<>m0").VerifyIL(yIL)
End Sub
<WorkItem(1139013, "DevDiv")>
<Fact>
Public Sub TransparentIdentifiers_FromDisplayClassField()
Const source = "
Imports System.Linq
Class C
Sub M(args As String())
Dim concat =
From x In args
Let y = x.ToString()
Let z = x.GetHashCode()
Select x.Select(Function(c) y & z)
End Sub
End Class
"
Const methodName = "C._Closure$__1-0._Lambda$__3"
Const cIL = "
{
// Code size 2 (0x2)
.maxstack 1
.locals init (String V_0)
IL_0000: ldarg.1
IL_0001: ret
}
"
Const zIL = "
{
// Code size 12 (0xc)
.maxstack 1
.locals init (String V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""C._Closure$__1-0.$VB$Local_$VB$It As VB$AnonymousType_1(Of VB$AnonymousType_0(Of String, String), Integer)""
IL_0006: ldfld ""VB$AnonymousType_1(Of VB$AnonymousType_0(Of String, String), Integer).$z As Integer""
IL_000b: ret
}
"
Const xIL = "
{
// Code size 17 (0x11)
.maxstack 1
.locals init (String V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""C._Closure$__1-0.$VB$Local_$VB$It As VB$AnonymousType_1(Of VB$AnonymousType_0(Of String, String), Integer)""
IL_0006: ldfld ""VB$AnonymousType_1(Of VB$AnonymousType_0(Of String, String), Integer).$$VB$It As VB$AnonymousType_0(Of String, String)""
IL_000b: ldfld ""VB$AnonymousType_0(Of String, String).$x As String""
IL_0010: ret
}
"
Const yIL = "
{
// Code size 17 (0x11)
.maxstack 1
.locals init (String V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""C._Closure$__1-0.$VB$Local_$VB$It As VB$AnonymousType_1(Of VB$AnonymousType_0(Of String, String), Integer)""
IL_0006: ldfld ""VB$AnonymousType_1(Of VB$AnonymousType_0(Of String, String), Integer).$$VB$It As VB$AnonymousType_0(Of String, String)""
IL_000b: ldfld ""VB$AnonymousType_0(Of String, String).$y As String""
IL_0010: ret
}
"
Dim comp = CreateCompilationWithMscorlib({source}, {SystemCoreRef, MsvbRef}, TestOptions.DebugDll)
Dim runtime = CreateRuntimeInstance(comp)
Dim typeName As String = Nothing
Dim locals = ArrayBuilder(Of LocalAndMethod).GetInstance()
Dim testData As CompilationTestData = Nothing
GetLocals(runtime, methodName, argumentsOnly:=False, locals:=locals, count:=4, typeName:=typeName, testData:=testData)
VerifyLocal(testData, typeName, locals(0), "<>m0", "c", expectedILOpt:=cIL)
VerifyLocal(testData, typeName, locals(1), "<>m1", "z", expectedILOpt:=zIL)
VerifyLocal(testData, typeName, locals(2), "<>m2", "x", expectedILOpt:=xIL)
VerifyLocal(testData, typeName, locals(3), "<>m3", "y", expectedILOpt:=yIL)
locals.Free()
Dim context = CreateMethodContext(runtime, methodName)
Dim errorMessage As String = Nothing
testData = New CompilationTestData()
context.CompileExpression("c", errorMessage, testData)
Assert.Null(errorMessage)
testData.GetMethodData("<>x.<>m0").VerifyIL(cIL)
testData = New CompilationTestData()
context.CompileExpression("z", errorMessage, testData)
Assert.Null(errorMessage)
testData.GetMethodData("<>x.<>m0").VerifyIL(zIL)
testData = New CompilationTestData()
context.CompileExpression("x", errorMessage, testData)
Assert.Null(errorMessage)
testData.GetMethodData("<>x.<>m0").VerifyIL(xIL)
testData = New CompilationTestData()
context.CompileExpression("y", errorMessage, testData)
Assert.Null(errorMessage)
testData.GetMethodData("<>x.<>m0").VerifyIL(yIL)
End Sub
<WorkItem(1139013, "DevDiv")>
<Fact>
Public Sub TransparentIdentifiers_It1()
Const source = "
Imports System.Linq
Class C
Sub M(args As String())
Dim concat =
From x In args, y In args
From z In args
Select x & y & z
End Sub
End Class
"
Const methodName = "C._Closure$__._Lambda$__1-3"
Const zIL = "
{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldarg.2
IL_0001: ret
}
"
Const xIL = "
{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.1
IL_0001: ldfld ""VB$AnonymousType_0(Of String, String).$x As String""
IL_0006: ret
}
"
Const yIL = "
{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.1
IL_0001: ldfld ""VB$AnonymousType_0(Of String, String).$y As String""
IL_0006: ret
}
"
Dim comp = CreateCompilationWithMscorlib({source}, {SystemCoreRef, MsvbRef}, TestOptions.DebugDll)
Dim runtime = CreateRuntimeInstance(comp)
Dim typeName As String = Nothing
Dim locals = ArrayBuilder(Of LocalAndMethod).GetInstance()
Dim testData As CompilationTestData = Nothing
GetLocals(runtime, methodName, argumentsOnly:=False, locals:=locals, count:=3, typeName:=typeName, testData:=testData)
VerifyLocal(testData, typeName, locals(0), "<>m0", "z", expectedILOpt:=zIL)
VerifyLocal(testData, typeName, locals(1), "<>m1", "x", expectedILOpt:=xIL)
VerifyLocal(testData, typeName, locals(2), "<>m2", "y", expectedILOpt:=yIL)
locals.Free()
Dim context = CreateMethodContext(runtime, methodName)
Dim errorMessage As String = Nothing
testData = New CompilationTestData()
context.CompileExpression("z", errorMessage, testData)
Assert.Null(errorMessage)
testData.GetMethodData("<>x.<>m0").VerifyIL(zIL)
testData = New CompilationTestData()
context.CompileExpression("x", errorMessage, testData)
Assert.Null(errorMessage)
testData.GetMethodData("<>x.<>m0").VerifyIL(xIL)
testData = New CompilationTestData()
context.CompileExpression("y", errorMessage, testData)
Assert.Null(errorMessage)
testData.GetMethodData("<>x.<>m0").VerifyIL(yIL)
End Sub
<WorkItem(1139013, "DevDiv")>
<Fact>
Public Sub TransparentIdentifiers_It2()
Const source = "
Imports System.Linq
Class C
Sub M(nums As Integer())
Dim q = From x In nums
Join y In nums
Join z In nums
On z Equals y
On x Equals y And z Equals x
End Sub
End Class
"
Const methodName = "C._Closure$__._Lambda$__1-5"
Const xIL = "
{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldarg.1
IL_0001: ret
}
"
Const yIL = "
{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.2
IL_0001: ldfld ""VB$AnonymousType_1(Of Integer, Integer).$y As Integer""
IL_0006: ret
}
"
Const zIL = "
{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.2
IL_0001: ldfld ""VB$AnonymousType_1(Of Integer, Integer).$z As Integer""
IL_0006: ret
}
"
Dim comp = CreateCompilationWithMscorlib({source}, {SystemCoreRef, MsvbRef}, TestOptions.DebugDll)
Dim runtime = CreateRuntimeInstance(comp)
Dim typeName As String = Nothing
Dim locals = ArrayBuilder(Of LocalAndMethod).GetInstance()
Dim testData As CompilationTestData = Nothing
GetLocals(runtime, methodName, argumentsOnly:=False, locals:=locals, count:=3, typeName:=typeName, testData:=testData)
VerifyLocal(testData, typeName, locals(0), "<>m0", "x", expectedILOpt:=xIL)
VerifyLocal(testData, typeName, locals(1), "<>m1", "y", expectedILOpt:=yIL)
VerifyLocal(testData, typeName, locals(2), "<>m2", "z", expectedILOpt:=zIL)
locals.Free()
Dim context = CreateMethodContext(runtime, methodName)
Dim errorMessage As String = Nothing
testData = New CompilationTestData()
context.CompileExpression("x", errorMessage, testData)
Assert.Null(errorMessage)
testData.GetMethodData("<>x.<>m0").VerifyIL(xIL)
testData = New CompilationTestData()
context.CompileExpression("y", errorMessage, testData)
Assert.Null(errorMessage)
testData.GetMethodData("<>x.<>m0").VerifyIL(yIL)
testData = New CompilationTestData()
context.CompileExpression("z", errorMessage, testData)
Assert.Null(errorMessage)
testData.GetMethodData("<>x.<>m0").VerifyIL(zIL)
End Sub
<WorkItem(1139013, "DevDiv")>
<Fact>
Public Sub TransparentIdentifiers_ItAnonymous()
Const source = "
Imports System.Linq
Class C
Sub M(args As String())
Dim concat =
From x In args
Group y = x.GetHashCode() By x
Into s = Sum(y + 3)
End Sub
End Class
"
Const methodName = "C._Closure$__._Lambda$__1-2"
Const xIL = "
{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldarg.1
IL_0001: ret
}
"
Dim comp = CreateCompilationWithMscorlib({source}, {SystemCoreRef, MsvbRef}, TestOptions.DebugDll)
Dim runtime = CreateRuntimeInstance(comp)
Dim typeName As String = Nothing
Dim locals = ArrayBuilder(Of LocalAndMethod).GetInstance()
Dim testData As CompilationTestData = Nothing
GetLocals(runtime, methodName, argumentsOnly:=False, locals:=locals, count:=1, typeName:=typeName, testData:=testData)
VerifyLocal(testData, typeName, locals(0), "<>m0", "x", expectedILOpt:=xIL)
locals.Free()
Dim context = CreateMethodContext(runtime, methodName)
Dim errorMessage As String = Nothing
testData = New CompilationTestData()
context.CompileExpression("x", errorMessage, testData)
Assert.Null(errorMessage)
testData.GetMethodData("<>x.<>m0").VerifyIL(xIL)
End Sub
Private Shared Sub GetLocals(runtime As RuntimeInstance, methodName As String, argumentsOnly As Boolean, locals As ArrayBuilder(Of LocalAndMethod), count As Integer, ByRef typeName As String, ByRef testData As CompilationTestData)
Dim context = CreateMethodContext(runtime, methodName)
testData = New CompilationTestData()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册