/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/VisualBasic/Portable/Symbols/PropertySignatureComparer.vb
247 строк
12 KB
AlekseyTs
Handle interaction of VB with Static Abstract Members in interfaces (#56375)
18 сен 2021, 00:12
Не верифицирован
18 сен 2021, 00:12
e3756cc
Код
Авторство
О чём код?
' 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.Generic Imports System.Diagnostics Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols ''' <summary> ''' Implementation of IEqualityComparer for PropertySymbols, with options for various aspects ''' to compare. ''' </summary> Friend NotInheritable Class PropertySignatureComparer Implements IEqualityComparer(Of PropertySymbol) ''' <summary> ''' This instance is intended to reflect the definition of signature equality used by the runtime (ECMA 335 Section 8.6.1.6). ''' It considers type, name, parameters, and custom modifiers. ''' </summary> Public Shared ReadOnly RuntimePropertySignatureComparer As PropertySignatureComparer = New PropertySignatureComparer(considerName:=True, considerType:=True, considerReadWriteModifiers:=False, considerOptionalParameters:=True, considerCustomModifiers:=True, considerTupleNames:=False) ''' <summary> ''' This instance is used to search for properties that have identical signatures in every regard. ''' </summary> Public Shared ReadOnly RetargetedExplicitPropertyImplementationComparer As PropertySignatureComparer = New PropertySignatureComparer(considerName:=True, considerType:=True, considerReadWriteModifiers:=True, considerOptionalParameters:=True, considerCustomModifiers:=True, considerTupleNames:=False) ''' <summary> ''' This instance is used to compare potential WinRT fake properties in type projection. ''' ''' FIXME(angocke): This is almost certainly wrong. The semantics of WinRT conflict ''' comparison should probably match overload resolution (i.e., we should not add a member ''' to lookup that would result in ambiguity), but this is closer to what Dev12 does. ''' ''' The real fix here is to establish a spec for how WinRT conflict comparison should be ''' performed. Once this is done we should remove these comments. ''' </summary> Public Shared ReadOnly WinRTConflictComparer As PropertySignatureComparer = New PropertySignatureComparer(considerName:=True, considerType:=False, considerReadWriteModifiers:=False, considerOptionalParameters:=False, considerCustomModifiers:=False, considerTupleNames:=False) ' Compare the property name (no explicit part) Private ReadOnly _considerName As Boolean ' Compare the property type Private ReadOnly _considerType As Boolean ' Consider if property is read-only, read-write, write-only Private ReadOnly _considerReadWriteModifiers As Boolean ' Consider optional parameters Private ReadOnly _considerOptionalParameters As Boolean ' Consider custom modifiers on/in parameters and return types (if return is considered). Private ReadOnly _considerCustomModifiers As Boolean ' Consider tuple names in parameters and return types (if return is considered). Private ReadOnly _considerTupleNames As Boolean Private Sub New(considerName As Boolean, considerType As Boolean, considerReadWriteModifiers As Boolean, considerOptionalParameters As Boolean, considerCustomModifiers As Boolean, considerTupleNames As Boolean) Me._considerName = considerName Me._considerType = considerType Me._considerReadWriteModifiers = considerReadWriteModifiers Me._considerOptionalParameters = considerOptionalParameters Me._considerCustomModifiers = considerCustomModifiers Me._considerTupleNames = considerTupleNames End Sub #Region "IEqualityComparer(Of PropertySymbol) Members" Public Overloads Function Equals(prop1 As PropertySymbol, prop2 As PropertySymbol) As Boolean _ Implements IEqualityComparer(Of PropertySymbol).Equals If prop1 = prop2 Then Return True End If If prop1 Is Nothing OrElse prop2 Is Nothing Then Return False End If If _considerName AndAlso Not IdentifierComparison.Equals(prop1.Name, prop2.Name) Then Return False End If If _considerReadWriteModifiers AndAlso ((prop1.IsReadOnly <> prop2.IsReadOnly) OrElse (prop1.IsWriteOnly <> prop2.IsWriteOnly)) Then Return False End If If _considerType Then Dim comparison As TypeCompareKind = MethodSignatureComparer.MakeTypeCompareKind(_considerCustomModifiers, _considerTupleNames) If Not HaveSameTypes(prop1, prop2, comparison) Then Return False End If End If If prop1.ParameterCount > 0 OrElse prop2.ParameterCount > 0 Then If Not MethodSignatureComparer.HaveSameParameterTypes(prop1.Parameters, Nothing, prop2.Parameters, Nothing, False, _considerCustomModifiers, _considerTupleNames) Then Return False End If End If Return True End Function Public Overloads Function GetHashCode(prop As PropertySymbol) As Integer _ Implements IEqualityComparer(Of PropertySymbol).GetHashCode Dim _hash As Integer = 1 If prop IsNot Nothing Then If _considerName Then _hash = Hash.Combine(prop.Name, _hash) End If If _considerType AndAlso Not _considerCustomModifiers Then _hash = Hash.Combine(prop.Type, _hash) End If _hash = Hash.Combine(_hash, prop.ParameterCount) End If Return _hash End Function #End Region #Region "Detailed comparison functions" Public Shared Function DetailedCompare( prop1 As PropertySymbol, prop2 As PropertySymbol, comparisons As SymbolComparisonResults, Optional stopIfAny As SymbolComparisonResults = 0 ) As SymbolComparisonResults Dim results As SymbolComparisonResults = Nothing If prop1 = prop2 Then Return Nothing End If If (comparisons And SymbolComparisonResults.PropertyAccessorMismatch) <> 0 Then If ((prop1.IsReadOnly <> prop2.IsReadOnly) OrElse (prop1.IsWriteOnly <> prop2.IsWriteOnly)) Then results = results Or SymbolComparisonResults.PropertyAccessorMismatch If (stopIfAny And SymbolComparisonResults.PropertyAccessorMismatch) <> 0 Then GoTo Done End If End If If (comparisons And SymbolComparisonResults.PropertyInitOnlyMismatch) <> 0 AndAlso prop1.SetMethod?.IsInitOnly <> prop2.SetMethod?.IsInitOnly Then results = results Or SymbolComparisonResults.PropertyInitOnlyMismatch If (stopIfAny And SymbolComparisonResults.PropertyInitOnlyMismatch) <> 0 Then GoTo Done End If End If End If If (comparisons And (SymbolComparisonResults.ReturnTypeMismatch Or SymbolComparisonResults.CustomModifierMismatch Or SymbolComparisonResults.TupleNamesMismatch)) <> 0 Then results = results Or MethodSignatureComparer.DetailedReturnTypeCompare(prop1.ReturnsByRef, New TypeWithModifiers(prop1.Type, prop1.TypeCustomModifiers), prop1.RefCustomModifiers, Nothing, prop2.ReturnsByRef, New TypeWithModifiers(prop2.Type, prop2.TypeCustomModifiers), prop2.RefCustomModifiers, Nothing, comparisons, stopIfAny) If (stopIfAny And results) <> 0 Then GoTo Done End If End If If (comparisons And SymbolComparisonResults.AllParameterMismatches) <> 0 Then results = results Or MethodSignatureComparer.DetailedParameterCompare(prop1.Parameters, Nothing, prop2.Parameters, Nothing, comparisons, stopIfAny) If (stopIfAny And results) <> 0 Then GoTo Done End If End If If (comparisons And SymbolComparisonResults.CallingConventionMismatch) <> 0 Then If prop1.IsShared <> prop2.IsShared Then results = results Or SymbolComparisonResults.CallingConventionMismatch If (stopIfAny And SymbolComparisonResults.CallingConventionMismatch) <> 0 Then GoTo Done End If End If End If ' It turns out name comparison is rather expensive relative to the other checks. If (comparisons And SymbolComparisonResults.NameMismatch) <> 0 Then If Not IdentifierComparison.Equals(prop1.Name, prop2.Name) Then results = results Or SymbolComparisonResults.NameMismatch If (stopIfAny And SymbolComparisonResults.NameMismatch) <> 0 Then GoTo Done End If End If End If Done: Return results And comparisons End Function #End Region Private Shared Function HaveSameTypes(prop1 As PropertySymbol, prop2 As PropertySymbol, comparison As TypeCompareKind) As Boolean If prop1.ReturnsByRef <> prop2.ReturnsByRef Then Return False End If Dim type1 = prop1.Type Dim type2 = prop2.Type ' the runtime compares custom modifiers using (effectively) SequenceEqual If (comparison And TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds) = 0 AndAlso (Not prop1.TypeCustomModifiers.SequenceEqual(prop2.TypeCustomModifiers) OrElse Not prop1.RefCustomModifiers.SequenceEqual(prop2.RefCustomModifiers)) Then Return False End If Return type1.IsSameType(type2, comparison) End Function End Class End Namespace