From a7c027ef6f4f98f60f558800006facaf812f281c Mon Sep 17 00:00:00 2001 From: AlekseyTs Date: Tue, 9 Dec 2014 12:23:05 -0800 Subject: [PATCH] VB: Define special error type symbol to represent a pointer type, enables accurate comparison of signatures of methods imported from metadata. ***NO_CI*** (changeset 1383354) --- .../Portable/BasicCodeAnalysis.vbproj | 1 + .../Portable/Symbols/ArrayTypeSymbol.vb | 2 +- .../Symbols/Metadata/PE/MetadataDecoder.vb | 2 +- .../Portable/Symbols/PointerTypeSymbol.vb | 65 +++++++++++++++ .../Portable/Symbols/TypeSymbolExtensions.vb | 2 +- .../Metadata/PE/LoadCustomModifiers.vb | 3 +- .../SymbolsTests/Source/OverridesTests.vb | 81 ++++++++++++++++++- 7 files changed, 151 insertions(+), 5 deletions(-) create mode 100644 Src/Compilers/VisualBasic/Portable/Symbols/PointerTypeSymbol.vb diff --git a/Src/Compilers/VisualBasic/Portable/BasicCodeAnalysis.vbproj b/Src/Compilers/VisualBasic/Portable/BasicCodeAnalysis.vbproj index 3b4c48cd6f4..da3429a6eef 100644 --- a/Src/Compilers/VisualBasic/Portable/BasicCodeAnalysis.vbproj +++ b/Src/Compilers/VisualBasic/Portable/BasicCodeAnalysis.vbproj @@ -689,6 +689,7 @@ + diff --git a/Src/Compilers/VisualBasic/Portable/Symbols/ArrayTypeSymbol.vb b/Src/Compilers/VisualBasic/Portable/Symbols/ArrayTypeSymbol.vb index 3a9c738317f..0b3a111c8fc 100644 --- a/Src/Compilers/VisualBasic/Portable/Symbols/ArrayTypeSymbol.vb +++ b/Src/Compilers/VisualBasic/Portable/Symbols/ArrayTypeSymbol.vb @@ -329,7 +329,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols ' And then hash that with the "T" type. Dim hashCode = 0 - Dim current As ITypeSymbol = Me + Dim current As TypeSymbol = Me While (current.TypeKind = TypeKind.Array) Dim cur = DirectCast(current, ArrayTypeSymbol) hashCode = Hash.Combine(cur.Rank, hashCode) diff --git a/Src/Compilers/VisualBasic/Portable/Symbols/Metadata/PE/MetadataDecoder.vb b/Src/Compilers/VisualBasic/Portable/Symbols/Metadata/PE/MetadataDecoder.vb index cbb364d49b0..18adc515100 100644 --- a/Src/Compilers/VisualBasic/Portable/Symbols/Metadata/PE/MetadataDecoder.vb +++ b/Src/Compilers/VisualBasic/Portable/Symbols/Metadata/PE/MetadataDecoder.vb @@ -230,7 +230,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE End Function Protected Overrides Function MakePointerTypeSymbol(type As TypeSymbol, customModifiers As ImmutableArray(Of ModifierInfo)) As TypeSymbol - Return GetUnsupportedMetadataTypeSymbol() + Return New PointerTypeSymbol(type, VisualBasicCustomModifier.Convert(customModifiers)) End Function Protected Overrides Function SubstituteWithUnboundIfGeneric(type As TypeSymbol) As TypeSymbol diff --git a/Src/Compilers/VisualBasic/Portable/Symbols/PointerTypeSymbol.vb b/Src/Compilers/VisualBasic/Portable/Symbols/PointerTypeSymbol.vb new file mode 100644 index 00000000000..c82bdff3afa --- /dev/null +++ b/Src/Compilers/VisualBasic/Portable/Symbols/PointerTypeSymbol.vb @@ -0,0 +1,65 @@ +Imports System.Collections.Immutable +' Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols + + ''' + ''' An error type symbol to represent a pointer type. + ''' Pointer types are not supported by VB language, but internally + ''' we need to be able to match them in signatures of methods + ''' imported from metadata. + ''' + Friend NotInheritable Class PointerTypeSymbol + Inherits ErrorTypeSymbol + + Private ReadOnly m_PointedAtType As TypeSymbol + Private ReadOnly m_CustomModifiers As ImmutableArray(Of CustomModifier) + + Public Sub New(pointedAtType As TypeSymbol, customModifiers As ImmutableArray(Of CustomModifier)) + Debug.Assert(pointedAtType IsNot Nothing) + + m_PointedAtType = pointedAtType + m_CustomModifiers = customModifiers.NullToEmpty() + End Sub + + Friend Overrides ReadOnly Property MangleName As Boolean + Get + Return False + End Get + End Property + + Friend Overrides ReadOnly Property ErrorInfo As DiagnosticInfo + Get + Return ErrorFactory.ErrorInfo(ERRID.ERR_UnsupportedType1, String.Empty) + End Get + End Property + + Public Overrides Function GetHashCode() As Integer + ' We don't want to blow the stack if we have a type like T***************...***, + ' so we do not recurse until we have a non-pointer. + + Dim indirections As Integer = 0 + Dim current As PointerTypeSymbol = Me + Dim last As TypeSymbol + + Do + indirections += 1 + last = current.m_PointedAtType + current = TryCast(last, PointerTypeSymbol) + Loop While current IsNot Nothing + + Return Hash.Combine(last, indirections) + End Function + + Public Overrides Function Equals(obj As Object) As Boolean + If Me Is obj Then + Return True + End If + + Dim other = TryCast(obj, PointerTypeSymbol) + Return other IsNot Nothing AndAlso other.m_PointedAtType.Equals(m_PointedAtType) AndAlso other.m_CustomModifiers.SequenceEqual(m_CustomModifiers) + End Function + + End Class + +End Namespace diff --git a/Src/Compilers/VisualBasic/Portable/Symbols/TypeSymbolExtensions.vb b/Src/Compilers/VisualBasic/Portable/Symbols/TypeSymbolExtensions.vb index dc77e425bc8..87ee7b617fa 100644 --- a/Src/Compilers/VisualBasic/Portable/Symbols/TypeSymbolExtensions.vb +++ b/Src/Compilers/VisualBasic/Portable/Symbols/TypeSymbolExtensions.vb @@ -207,7 +207,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols If Not t1IsDefinition Then ' This is a generic instantiation - If t1.OriginalDefinition IsNot t2.OriginalDefinition Then + If t1.OriginalDefinition <> t2.OriginalDefinition Then Return False ' different definition End If diff --git a/Src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadCustomModifiers.vb b/Src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadCustomModifiers.vb index cf687df92ec..05529ecbfe4 100644 --- a/Src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadCustomModifiers.vb +++ b/Src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadCustomModifiers.vb @@ -93,7 +93,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.Symbols.Metadata.PE Dim p6Type As TypeSymbol = p6.Type - Assert.IsType(Of UnsupportedMetadataTypeSymbol)(p6Type) + Assert.IsType(Of PointerTypeSymbol)(p6Type) + Assert.Equal(ERRID.ERR_UnsupportedType1, p6Type.GetUseSiteErrorInfo().Code) Assert.False(m7.IsSub) Assert.Equal(1, m7.ReturnTypeCustomModifiers.Length) diff --git a/Src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/OverridesTests.vb b/Src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/OverridesTests.vb index c185a81aca3..646abc1f4bb 100644 --- a/Src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/OverridesTests.vb +++ b/Src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/OverridesTests.vb @@ -6824,6 +6824,85 @@ BC31417: 'Friend Overrides Property Set r(Value As Object)' cannot override 'Fri End Sub - End Class + + + Sub Bug1067044() + Dim il = + + Dim source = + + +Public Class C3 + Inherits C2 + + Public Overrides Sub M2() + End Sub +End Class + + + + Dim compilation = CreateCompilationWithCustomILSource(source, il.Value, options:=TestOptions.DebugDll) + + CompileAndVerify(compilation) + End Sub + + End Class End Namespace -- GitLab