From 8fe41a011a0b21ec26df08a3cabc3f35e7273a11 Mon Sep 17 00:00:00 2001 From: AlekseyTs Date: Thu, 19 Nov 2020 09:35:34 -0800 Subject: [PATCH] Determinism fixes for AnonymousTypes in VB (#49467) Related to #48417. --- .../AnonymousDelegate_TemplateSymbol.vb | 26 +++++++++---------- .../AnonymousTypeOrDelegateTemplateSymbol.vb | 15 ++++++++++- ...nonymousTypeOrDelegate_ParameterSymbol.vb} | 14 +++++----- .../AnonymousType_ConstructorSymbol.vb | 2 +- .../AnonymousTypesEmittedSymbolsTests.vb | 6 +++++ 5 files changed, 41 insertions(+), 22 deletions(-) rename src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/{AnonymousDelegate_ParameterSymbol.vb => AnonymousTypeOrDelegate_ParameterSymbol.vb} (68%) diff --git a/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousDelegate_TemplateSymbol.vb b/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousDelegate_TemplateSymbol.vb index ec9e39bf24e12..28a3a6c238180 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousDelegate_TemplateSymbol.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousDelegate_TemplateSymbol.vb @@ -52,12 +52,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols returnType) For i = 0 To parameterDescriptors.Length - 2 - parameters.Add(New AnonymousDelegateParameterSymbol(delegateInvoke, - Me.TypeParameters(i), - i, - parameterDescriptors(i).IsByRef, - parameterDescriptors(i).Name, - i)) + parameters.Add(New AnonymousTypeOrDelegateParameterSymbol(delegateInvoke, + Me.TypeParameters(i), + i, + parameterDescriptors(i).IsByRef, + parameterDescriptors(i).Name, + i)) Next delegateInvoke.SetParameters(parameters.ToImmutable()) @@ -71,8 +71,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols delegateCtor.SetParameters( ImmutableArray.Create(Of ParameterSymbol)( - New AnonymousDelegateParameterSymbol(delegateCtor, manager.System_Object, 0, False, StringConstants.DelegateConstructorInstanceParameterName), - New AnonymousDelegateParameterSymbol(delegateCtor, manager.System_IntPtr, 1, False, StringConstants.DelegateConstructorMethodParameterName) + New AnonymousTypeOrDelegateParameterSymbol(delegateCtor, manager.System_Object, 0, False, StringConstants.DelegateConstructorInstanceParameterName), + New AnonymousTypeOrDelegateParameterSymbol(delegateCtor, manager.System_IntPtr, 1, False, StringConstants.DelegateConstructorMethodParameterName) )) Dim delegateBeginInvoke As SynthesizedDelegateMethodSymbol @@ -93,12 +93,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols For i = 0 To delegateInvoke.ParameterCount - 1 Dim parameter As ParameterSymbol = delegateInvoke.Parameters(i) - parameters.Add(New AnonymousDelegateParameterSymbol(delegateBeginInvoke, parameter.Type, i, parameter.IsByRef(), parameter.Name, i)) + parameters.Add(New AnonymousTypeOrDelegateParameterSymbol(delegateBeginInvoke, parameter.Type, i, parameter.IsByRef(), parameter.Name, i)) Next - parameters.Add(New AnonymousDelegateParameterSymbol(delegateBeginInvoke, manager.System_AsyncCallback, i, False, StringConstants.DelegateMethodCallbackParameterName)) + parameters.Add(New AnonymousTypeOrDelegateParameterSymbol(delegateBeginInvoke, manager.System_AsyncCallback, i, False, StringConstants.DelegateMethodCallbackParameterName)) i += 1 - parameters.Add(New AnonymousDelegateParameterSymbol(delegateBeginInvoke, manager.System_Object, i, False, StringConstants.DelegateMethodInstanceParameterName)) + parameters.Add(New AnonymousTypeOrDelegateParameterSymbol(delegateBeginInvoke, manager.System_Object, i, False, StringConstants.DelegateMethodInstanceParameterName)) delegateBeginInvoke.SetParameters(parameters.ToImmutable()) parameters.Clear() @@ -112,12 +112,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols Dim parameter As ParameterSymbol = delegateInvoke.Parameters(i) If parameter.IsByRef Then - parameters.Add(New AnonymousDelegateParameterSymbol(delegateEndInvoke, parameter.Type, ordinal, parameter.IsByRef(), parameter.Name, i)) + parameters.Add(New AnonymousTypeOrDelegateParameterSymbol(delegateEndInvoke, parameter.Type, ordinal, parameter.IsByRef(), parameter.Name, i)) ordinal += 1 End If Next - parameters.Add(New AnonymousDelegateParameterSymbol(delegateEndInvoke, manager.System_IAsyncResult, ordinal, False, StringConstants.DelegateMethodResultParameterName)) + parameters.Add(New AnonymousTypeOrDelegateParameterSymbol(delegateEndInvoke, manager.System_IAsyncResult, ordinal, False, StringConstants.DelegateMethodResultParameterName)) delegateEndInvoke.SetParameters(parameters.ToImmutable()) _members = ImmutableArray.Create(delegateCtor, delegateBeginInvoke, delegateEndInvoke, delegateInvoke) diff --git a/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousTypeOrDelegateTemplateSymbol.vb b/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousTypeOrDelegateTemplateSymbol.vb index fe00a78d5b548..2b07bd589d8da 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousTypeOrDelegateTemplateSymbol.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousTypeOrDelegateTemplateSymbol.vb @@ -37,6 +37,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols Private ReadOnly _typeParameters As ImmutableArray(Of TypeParameterSymbol) Private _adjustedPropertyNames As LocationAndNames +#If DEBUG Then + Private _locationAndNamesAreLocked As Boolean +#End If ''' ''' The key of the anonymous type descriptor used for this type template @@ -315,6 +318,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols Public ReadOnly Property SmallestLocation As Location Get +#If DEBUG Then + _locationAndNamesAreLocked = True +#End If Return Me._adjustedPropertyNames.Location End Get End Property @@ -335,12 +341,16 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols ' to set it ('location' in type descriptor is bigger that the one in m_adjustedPropertyNames) Dim currentAdjustedNames As LocationAndNames = Me._adjustedPropertyNames If currentAdjustedNames IsNot Nothing AndAlso - Me.Manager.Compilation.CompareSourceLocations(currentAdjustedNames.Location, newLocation) < 0 Then + Me.Manager.Compilation.CompareSourceLocations(currentAdjustedNames.Location, newLocation) <= 0 Then ' The template's adjusted property names do not need to be changed Exit Sub End If +#If DEBUG Then + Debug.Assert(Not _locationAndNamesAreLocked) +#End If + Dim newAdjustedNames As New LocationAndNames(typeDescr) If Interlocked.CompareExchange(Me._adjustedPropertyNames, newAdjustedNames, currentAdjustedNames) Is currentAdjustedNames Then @@ -351,6 +361,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols End Sub Friend Function GetAdjustedName(index As Integer) As String +#If DEBUG Then + _locationAndNamesAreLocked = True +#End If Dim names = Me._adjustedPropertyNames Debug.Assert(names IsNot Nothing) Debug.Assert(names.Names.Length > index) diff --git a/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousDelegate_ParameterSymbol.vb b/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousTypeOrDelegate_ParameterSymbol.vb similarity index 68% rename from src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousDelegate_ParameterSymbol.vb rename to src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousTypeOrDelegate_ParameterSymbol.vb index 151b4c152b7da..834f606b82e5d 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousDelegate_ParameterSymbol.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousTypeOrDelegate_ParameterSymbol.vb @@ -13,26 +13,26 @@ Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols Partial Friend NotInheritable Class AnonymousTypeManager - Private NotInheritable Class AnonymousDelegateParameterSymbol + Private NotInheritable Class AnonymousTypeOrDelegateParameterSymbol Inherits SynthesizedParameterSymbol - Public ReadOnly CorrespondingInvokeParameter As Integer + Public ReadOnly CorrespondingInvokeParameterOrProperty As Integer Public Sub New( - container As SynthesizedDelegateMethodSymbol, + container As MethodSymbol, type As TypeSymbol, ordinal As Integer, isByRef As Boolean, name As String, - Optional correspondingInvokeParameter As Integer = -1 + Optional correspondingInvokeParameterOrProperty As Integer = -1 ) MyBase.New(container, type, ordinal, isByRef, name) - Me.CorrespondingInvokeParameter = correspondingInvokeParameter + Me.CorrespondingInvokeParameterOrProperty = correspondingInvokeParameterOrProperty End Sub Public Overrides ReadOnly Property MetadataName As String Get - If CorrespondingInvokeParameter <> -1 Then - Return DirectCast(_container.ContainingSymbol, AnonymousDelegateTemplateSymbol).GetAdjustedName(CorrespondingInvokeParameter) + If CorrespondingInvokeParameterOrProperty <> -1 Then + Return DirectCast(_container.ContainingSymbol, AnonymousTypeOrDelegateTemplateSymbol).GetAdjustedName(CorrespondingInvokeParameterOrProperty) End If Return MyBase.MetadataName diff --git a/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType_ConstructorSymbol.vb b/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType_ConstructorSymbol.vb index 4354071e0347e..072a475fbc0e3 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType_ConstructorSymbol.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType_ConstructorSymbol.vb @@ -22,7 +22,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols Dim paramsArr = New ParameterSymbol(fieldsCount - 1) {} For index = 0 To fieldsCount - 1 Dim [property] As PropertySymbol = container.Properties(index) - paramsArr(index) = New SynthesizedParameterSimpleSymbol(Me, [property].Type, index, [property].Name) + paramsArr(index) = New AnonymousTypeOrDelegateParameterSymbol(Me, [property].Type, index, isByRef:=False, [property].Name, correspondingInvokeParameterOrProperty:=index) Next Me._parameters = paramsArr.AsImmutableOrNull() End Sub diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/AnonymousTypes/AnonymousTypesEmittedSymbolsTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/AnonymousTypes/AnonymousTypesEmittedSymbolsTests.vb index 3813bcb41073a..4b5a31722f9d7 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/AnonymousTypes/AnonymousTypesEmittedSymbolsTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/AnonymousTypes/AnonymousTypesEmittedSymbolsTests.vb @@ -688,6 +688,11 @@ End Module Assert.Equal("$" & propName, field.Name) Assert.Equal("$" & propName, field.MetadataName) Assert.Equal(Accessibility.Private, field.DeclaredAccessibility) + + Dim parameter = type.Constructors.Single().Parameters(0) + Assert.Equal(propType, parameter.Type) + Assert.Equal(propName, parameter.Name) + Assert.Equal(propName, parameter.MetadataName) End Sub Private Shared Sub CheckMethod(m As ModuleSymbol, method As MethodSymbol, @@ -702,6 +707,7 @@ End Module Assert.NotNull(method) Assert.Equal(name, method.Name) + Assert.Equal(name, method.MetadataName) Assert.Equal(paramCount, method.ParameterCount) If isSub Then