From 8c9ee77f15aa74f274e36cfe1592a3f13a557869 Mon Sep 17 00:00:00 2001 From: AlekseyTs Date: Wed, 18 Nov 2020 05:45:25 -0800 Subject: [PATCH 1/3] Determinism fixes for AnonymousTypes in VB Related to #48417. --- .../AnonymousDelegate_ParameterSymbol.vb | 14 +++++----- .../AnonymousDelegate_TemplateSymbol.vb | 26 +++++++++---------- .../AnonymousTypeOrDelegateTemplateSymbol.vb | 9 ++++++- .../AnonymousType_ConstructorSymbol.vb | 2 +- .../AnonymousTypesEmittedSymbolsTests.vb | 6 +++++ 5 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousDelegate_ParameterSymbol.vb b/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousDelegate_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/AnonymousDelegate_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/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..1adf6d45b4ec4 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousTypeOrDelegateTemplateSymbol.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousTypeOrDelegateTemplateSymbol.vb @@ -37,6 +37,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols Private ReadOnly _typeParameters As ImmutableArray(Of TypeParameterSymbol) Private _adjustedPropertyNames As LocationAndNames + Private _locationAndNamesAreLocked As Boolean ''' ''' The key of the anonymous type descriptor used for this type template @@ -315,6 +316,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols Public ReadOnly Property SmallestLocation As Location Get + _locationAndNamesAreLocked = True Return Me._adjustedPropertyNames.Location End Get End Property @@ -335,12 +337,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 _locationAndNamesAreLocked Then + Throw ExceptionUtilities.Unreachable + End If + Dim newAdjustedNames As New LocationAndNames(typeDescr) If Interlocked.CompareExchange(Me._adjustedPropertyNames, newAdjustedNames, currentAdjustedNames) Is currentAdjustedNames Then @@ -351,6 +357,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols End Sub Friend Function GetAdjustedName(index As Integer) As String + _locationAndNamesAreLocked = True 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/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 From 5303fb2df93c0e3e6e220f30b113ad5301ddde4b Mon Sep 17 00:00:00 2001 From: AlekseyTs Date: Wed, 18 Nov 2020 07:35:35 -0800 Subject: [PATCH 2/3] Rename file to reflect type name changes --- ...ameterSymbol.vb => AnonymousTypeOrDelegate_ParameterSymbol.vb} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/{AnonymousDelegate_ParameterSymbol.vb => AnonymousTypeOrDelegate_ParameterSymbol.vb} (100%) 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 100% rename from src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousDelegate_ParameterSymbol.vb rename to src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousTypeOrDelegate_ParameterSymbol.vb From 62ad3687b564cd4f5be50b7dcca3c999da3a8708 Mon Sep 17 00:00:00 2001 From: AlekseyTs Date: Wed, 18 Nov 2020 13:09:10 -0800 Subject: [PATCH 3/3] Fixup --- .../AnonymousTypeOrDelegateTemplateSymbol.vb | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousTypeOrDelegateTemplateSymbol.vb b/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousTypeOrDelegateTemplateSymbol.vb index 1adf6d45b4ec4..2b07bd589d8da 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousTypeOrDelegateTemplateSymbol.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousTypeOrDelegateTemplateSymbol.vb @@ -37,7 +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 @@ -316,7 +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 @@ -343,9 +347,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols Exit Sub End If - If _locationAndNamesAreLocked Then - Throw ExceptionUtilities.Unreachable - End If +#If DEBUG Then + Debug.Assert(Not _locationAndNamesAreLocked) +#End If Dim newAdjustedNames As New LocationAndNames(typeDescr) @@ -357,7 +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)