/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/VisualBasic/Portable/Emit/PEModuleBuilder.vb
772 строки
39 KB
AlekseyTs
Properly populate ExportedType metadata table for forwarded extension blocks. (#80361)
22 сен 2025, 19:27
Не верифицирован
22 сен 2025, 19:27
b8daa4c
Код
Авторство
О чём код?
' 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.Concurrent Imports System.Collections.Immutable Imports System.Reflection.PortableExecutable Imports System.Runtime.InteropServices Imports Microsoft.CodeAnalysis.CodeGen Imports Microsoft.CodeAnalysis.Collections Imports Microsoft.CodeAnalysis.Emit Imports Microsoft.CodeAnalysis.PooledObjects Imports Microsoft.CodeAnalysis.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Namespace Microsoft.CodeAnalysis.VisualBasic.Emit Partial Friend MustInherit Class PEModuleBuilder Inherits PEModuleBuilder(Of VisualBasicCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, NoPia.EmbeddedTypesManager, ModuleCompilationState) ' Not many methods should end up here. Private ReadOnly _disableJITOptimization As ConcurrentDictionary(Of MethodSymbol, Boolean) = New ConcurrentDictionary(Of MethodSymbol, Boolean)(ReferenceEqualityComparer.Instance) ' Gives the name of this module (may not reflect the name of the underlying symbol). ' See Assembly.MetadataName. Private ReadOnly _metadataName As String Private _lazyExportedTypes As ImmutableArray(Of Cci.ExportedType) Private _lazyTranslatedImports As ImmutableArray(Of Cci.UsedNamespaceOrType) Private _lazyDefaultNamespace As String Friend Sub New(sourceModule As SourceModuleSymbol, emitOptions As EmitOptions, outputKind As OutputKind, serializationProperties As Cci.ModulePropertiesForSerialization, manifestResources As IEnumerable(Of ResourceDescription)) MyBase.New(sourceModule.ContainingSourceAssembly.DeclaringCompilation, sourceModule, serializationProperties, manifestResources, outputKind, emitOptions, New ModuleCompilationState()) Dim specifiedName = sourceModule.MetadataName _metadataName = If(specifiedName <> CodeAnalysis.Compilation.UnspecifiedModuleAssemblyName, specifiedName, If(emitOptions.OutputNameOverride, specifiedName)) m_AssemblyOrModuleSymbolToModuleRefMap.Add(sourceModule, Me) If sourceModule.AnyReferencedAssembliesAreLinked Then _embeddedTypesManagerOpt = New NoPia.EmbeddedTypesManager(Me) End If End Sub ''' <summary> ''' True if conditional calls may be omitted when the required preprocessor symbols are not defined. ''' </summary> ''' <remarks> ''' Only false in debugger scenarios (where calls should never be omitted). ''' </remarks> Friend MustOverride ReadOnly Property AllowOmissionOfConditionalCalls As Boolean Public Overrides ReadOnly Property Name As String Get Return _metadataName End Get End Property Friend NotOverridable Overrides ReadOnly Property ModuleName As String Get Return _metadataName End Get End Property Friend NotOverridable Overrides ReadOnly Property CorLibrary As AssemblySymbol Get Return SourceModule.ContainingSourceAssembly.CorLibrary End Get End Property Public NotOverridable Overrides ReadOnly Property GenerateVisualBasicStylePdb As Boolean Get Return True End Get End Property Public Overrides ReadOnly Property LinkedAssembliesDebugInfo As IEnumerable(Of String) Get ' NOTE: Dev12 does not seem to emit anything but the name (i.e. no version, token, etc). ' See Builder::WriteNoPiaPdbList Return SourceModule.ReferencedAssemblySymbols.Where(Function(a) a.IsLinked).Select(Function(a) a.Name) End Get End Property Public NotOverridable Overrides Function GetImports() As ImmutableArray(Of Cci.UsedNamespaceOrType) ' Imports should have been translated in code gen phase. Debug.Assert(Not _lazyTranslatedImports.IsDefault) Return _lazyTranslatedImports End Function Public Sub TranslateImports(diagnostics As DiagnosticBag) If _lazyTranslatedImports.IsDefault Then ImmutableInterlocked.InterlockedInitialize( _lazyTranslatedImports, NamespaceScopeBuilder.BuildNamespaceScope(Me, SourceModule.XmlNamespaces, SourceModule.AliasImports, SourceModule.MemberImports, diagnostics)) End If End Sub Public NotOverridable Overrides ReadOnly Property DefaultNamespace As String Get If _lazyDefaultNamespace IsNot Nothing Then Return _lazyDefaultNamespace End If Dim rootNamespace = SourceModule.RootNamespace If rootNamespace.IsGlobalNamespace Then Return String.Empty End If _lazyDefaultNamespace = rootNamespace.ToDisplayString(SymbolDisplayFormat.QualifiedNameOnlyFormat) Return _lazyDefaultNamespace End Get End Property Protected NotOverridable Overrides Iterator Function GetAssemblyReferencesFromAddedModules(diagnostics As DiagnosticBag) As IEnumerable(Of Cci.IAssemblyReference) Dim modules As ImmutableArray(Of ModuleSymbol) = SourceModule.ContainingAssembly.Modules For i As Integer = 1 To modules.Length - 1 For Each aRef As AssemblySymbol In modules(i).GetReferencedAssemblySymbols() Yield Translate(aRef, diagnostics) Next Next End Function Private Sub ValidateReferencedAssembly(assembly As AssemblySymbol, asmRef As AssemblyReference, diagnostics As DiagnosticBag) Dim asmIdentity As AssemblyIdentity = SourceModule.ContainingAssembly.Identity Dim refIdentity As AssemblyIdentity = asmRef.Identity If asmIdentity.IsStrongName AndAlso Not refIdentity.IsStrongName AndAlso asmRef.Identity.ContentType <> Reflection.AssemblyContentType.WindowsRuntime Then ' Dev12 reported error, we have changed it to a warning to allow referencing libraries ' built for platforms that don't support strong names. diagnostics.Add(ErrorFactory.ErrorInfo(ERRID.WRN_ReferencedAssemblyDoesNotHaveStrongName, assembly), NoLocation.Singleton) End If If OutputKind <> OutputKind.NetModule AndAlso Not String.IsNullOrEmpty(refIdentity.CultureName) AndAlso Not String.Equals(refIdentity.CultureName, asmIdentity.CultureName, StringComparison.OrdinalIgnoreCase) Then diagnostics.Add(ErrorFactory.ErrorInfo(ERRID.WRN_RefCultureMismatch, assembly, refIdentity.CultureName), NoLocation.Singleton) End If Dim refMachine = assembly.Machine ' If other assembly is agnostic, this is always safe ' Also, if no mscorlib was specified for back compat we add a reference to mscorlib ' that resolves to the current framework directory. If the compiler Is 64-bit ' this Is a 64-bit mscorlib, which will produce a warning if /platform:x86 Is ' specified.A reference to the default mscorlib should always succeed without ' warning so we ignore it here. If assembly IsNot assembly.CorLibrary AndAlso Not (refMachine = Machine.I386 AndAlso Not assembly.Bit32Required) Then Dim machine = SourceModule.Machine If Not (machine = Machine.I386 AndAlso Not SourceModule.Bit32Required) AndAlso machine <> refMachine Then ' Different machine types, and neither is agnostic diagnostics.Add(ErrorFactory.ErrorInfo(ERRID.WRN_ConflictingMachineAssembly, assembly), NoLocation.Singleton) End If End If If _embeddedTypesManagerOpt IsNot Nothing AndAlso _embeddedTypesManagerOpt.IsFrozen Then _embeddedTypesManagerOpt.ReportIndirectReferencesToLinkedAssemblies(assembly, diagnostics) End If End Sub Friend NotOverridable Overrides Function SynthesizeAttribute(attributeConstructor As WellKnownMember) As Cci.ICustomAttribute Return Me.Compilation.TrySynthesizeAttribute(attributeConstructor) End Function Public NotOverridable Overrides Function GetSourceAssemblyAttributes(isRefAssembly As Boolean) As IEnumerable(Of Cci.ICustomAttribute) Return SourceModule.ContainingSourceAssembly.GetAssemblyCustomAttributesToEmit(Me, isRefAssembly, emittingAssemblyAttributesInNetModule:=OutputKind.IsNetModule()) End Function Public NotOverridable Overrides Function GetSourceAssemblySecurityAttributes() As IEnumerable(Of Cci.SecurityAttribute) Return SourceModule.ContainingSourceAssembly.GetSecurityAttributes() End Function Public NotOverridable Overrides Function GetSourceModuleAttributes() As IEnumerable(Of Cci.ICustomAttribute) Return SourceModule.GetCustomAttributesToEmit(Me) End Function Public NotOverridable Overrides Function GetSymbolToLocationMap() As MultiDictionary(Of Cci.DebugSourceDocument, Cci.DefinitionWithLocation) Dim result As New MultiDictionary(Of Cci.DebugSourceDocument, Cci.DefinitionWithLocation)() Dim namespacesAndTypesToProcess As New Stack(Of NamespaceOrTypeSymbol)() namespacesAndTypesToProcess.Push(SourceModule.GlobalNamespace) Dim location As Location = Nothing While namespacesAndTypesToProcess.Count > 0 Dim symbol As NamespaceOrTypeSymbol = namespacesAndTypesToProcess.Pop() Select Case symbol.Kind Case SymbolKind.Namespace location = GetSmallestSourceLocationOrNull(symbol) ' filtering out synthesized symbols not having real source ' locations such as anonymous types, my types, etc... If location IsNot Nothing Then For Each member In symbol.GetMembers() Select Case member.Kind Case SymbolKind.Namespace, SymbolKind.NamedType namespacesAndTypesToProcess.Push(DirectCast(member, NamespaceOrTypeSymbol)) Case Else Throw ExceptionUtilities.UnexpectedValue(member.Kind) End Select Next End If Case SymbolKind.NamedType location = GetSmallestSourceLocationOrNull(symbol) If location IsNot Nothing Then ' add this named type location AddSymbolLocation(result, location, DirectCast(symbol.GetCciAdapter(), Cci.IDefinition)) For Each member In symbol.GetMembers() Select Case member.Kind Case SymbolKind.NamedType namespacesAndTypesToProcess.Push(DirectCast(member, NamespaceOrTypeSymbol)) Case SymbolKind.Method Dim method = DirectCast(member, MethodSymbol) If method.IsDefaultValueTypeConstructor() OrElse method.IsPartialWithoutImplementation Then Exit Select End If AddSymbolLocation(result, member) Case SymbolKind.Property, SymbolKind.Field AddSymbolLocation(result, member) Case SymbolKind.Event AddSymbolLocation(result, member) Dim AssociatedField = (DirectCast(member, EventSymbol)).AssociatedField If AssociatedField IsNot Nothing Then ' event backing fields do not show up in GetMembers AddSymbolLocation(result, AssociatedField) End If Case Else Throw ExceptionUtilities.UnexpectedValue(member.Kind) End Select Next End If Case Else Throw ExceptionUtilities.UnexpectedValue(symbol.Kind) End Select End While Return result End Function Private Sub AddSymbolLocation(result As MultiDictionary(Of Cci.DebugSourceDocument, Cci.DefinitionWithLocation), symbol As Symbol) Dim location As Location = GetSmallestSourceLocationOrNull(symbol) If location IsNot Nothing Then AddSymbolLocation(result, location, DirectCast(symbol.GetCciAdapter(), Cci.IDefinition)) End If End Sub Private Sub AddSymbolLocation(result As MultiDictionary(Of Cci.DebugSourceDocument, Cci.DefinitionWithLocation), location As Location, definition As Cci.IDefinition) Dim span As FileLinePositionSpan = location.GetLineSpan() Dim doc As Cci.DebugSourceDocument = DebugDocumentsBuilder.TryGetDebugDocument(span.Path, basePath:=location.SourceTree.FilePath) If (doc IsNot Nothing) Then result.Add(doc, New Cci.DefinitionWithLocation( definition, span.StartLinePosition.Line, span.StartLinePosition.Character, span.EndLinePosition.Line, span.EndLinePosition.Character)) End If End Sub Private Function GetSmallestSourceLocationOrNull(symbol As Symbol) As Location Dim compilation As VisualBasicCompilation = symbol.DeclaringCompilation Debug.Assert(Me.Compilation Is compilation, "How did we get symbol from different compilation?") Dim result As Location = Nothing For Each loc In symbol.Locations If loc.IsInSource AndAlso (result Is Nothing OrElse compilation.CompareSourceLocations(result, loc) > 0) Then result = loc End If Next Return result End Function ''' <summary> ''' Ignore accessibility when resolving well-known type ''' members, in particular for generic type arguments ''' (e.g.: binding to internal types in the EE). ''' </summary> Friend Overridable ReadOnly Property IgnoreAccessibility As Boolean Get Return False End Get End Property Friend Overridable Function TryCreateVariableSlotAllocator(method As MethodSymbol, topLevelMethod As MethodSymbol, diagnostics As DiagnosticBag) As VariableSlotAllocator Return Nothing End Function Friend Overridable Function GetMethodBodyInstrumentations(method As MethodSymbol) As MethodInstrumentation Return New MethodInstrumentation() With {.Kinds = EmitOptions.InstrumentationKinds} End Function Friend Overridable Function GetNextAnonymousTypeIndex(fromDelegates As Boolean) As Integer Return 0 End Function Friend Overridable Function TryGetAnonymousTypeName(template As AnonymousTypeManager.AnonymousTypeOrDelegateTemplateSymbol, <Out> ByRef name As String, <Out> ByRef index As Integer) As Boolean Debug.Assert(Compilation Is template.DeclaringCompilation) name = Nothing index = -1 Return False End Function Public NotOverridable Overrides Function GetAnonymousTypeDefinitions(context As EmitContext) As IEnumerable(Of Cci.INamespaceTypeDefinition) If context.MetadataOnly Then Return SpecializedCollections.EmptyEnumerable(Of Cci.INamespaceTypeDefinition) End If #If DEBUG Then Return SourceModule.ContainingSourceAssembly.DeclaringCompilation.AnonymousTypeManager.AllCreatedTemplates.Select(Function(t) t.GetCciAdapter()) #Else Return SourceModule.ContainingSourceAssembly.DeclaringCompilation.AnonymousTypeManager.AllCreatedTemplates #End If End Function Public Overrides Iterator Function GetTopLevelSourceTypeDefinitions(context As EmitContext) As IEnumerable(Of Cci.INamespaceTypeDefinition) Dim embeddedSymbolManager As EmbeddedSymbolManager = SourceModule.ContainingSourceAssembly.DeclaringCompilation.EmbeddedSymbolManager Dim stack As New Stack(Of NamespaceOrTypeSymbol)() stack.Push(SourceModule.GlobalNamespace) Do Dim sym As NamespaceOrTypeSymbol = stack.Pop() If sym.Kind = SymbolKind.NamedType Then Debug.Assert(sym Is sym.OriginalDefinition) Debug.Assert(sym.ContainingType Is Nothing) ' Skip unreferenced embedded types. If Not sym.IsEmbedded OrElse embeddedSymbolManager.IsSymbolReferenced(sym) Then Yield DirectCast(sym, NamedTypeSymbol).GetCciAdapter() End If Else Debug.Assert(sym.Kind = SymbolKind.Namespace) Dim members As ImmutableArray(Of Symbol) = sym.GetMembers() For i As Integer = members.Length - 1 To 0 Step -1 Dim namespaceOrType As NamespaceOrTypeSymbol = TryCast(members(i), NamespaceOrTypeSymbol) If namespaceOrType IsNot Nothing Then stack.Push(namespaceOrType) End If Next End If Loop While stack.Count > 0 End Function Public NotOverridable Overrides Function GetExportedTypes(context As EmitContext) As ImmutableArray(Of Cci.ExportedType) Debug.Assert(HaveDeterminedTopLevelTypes) If _lazyExportedTypes.IsDefault Then Dim initialized = ImmutableInterlocked.InterlockedInitialize(_lazyExportedTypes, CalculateExportedTypes()) If initialized AndAlso _lazyExportedTypes.Length > 0 Then ReportExportedTypeNameCollisions(_lazyExportedTypes, context.Diagnostics) End If End If Return _lazyExportedTypes End Function ''' <summary> ''' Builds an array of public type symbols defined in netmodules included in the compilation ''' And type forwarders defined in this compilation Or any included netmodule (in this order). ''' </summary> Private Function CalculateExportedTypes() As ImmutableArray(Of Cci.ExportedType) Dim builder = ArrayBuilder(Of Cci.ExportedType).GetInstance() Dim sourceAssembly As SourceAssemblySymbol = SourceModule.ContainingSourceAssembly If Not OutputKind.IsNetModule() Then Dim modules = sourceAssembly.Modules For i As Integer = 1 To modules.Length - 1 'NOTE: skipping modules(0) GetExportedTypes(modules(i).GlobalNamespace, -1, builder) Next End If Debug.Assert(OutputKind.IsNetModule() = sourceAssembly.DeclaringCompilation.Options.OutputKind.IsNetModule()) GetForwardedTypes(sourceAssembly, builder) Return builder.ToImmutableAndFree() End Function ''' <summary> ''' Returns a set of top-level forwarded types ''' </summary> Friend Shared Function GetForwardedTypes(sourceAssembly As SourceAssemblySymbol, builderOpt As ArrayBuilder(Of Cci.ExportedType)) As HashSet(Of NamedTypeSymbol) Dim seenTopLevelForwardedTypes = New HashSet(Of NamedTypeSymbol)() GetForwardedTypes(seenTopLevelForwardedTypes, sourceAssembly.GetSourceDecodedWellKnownAttributeData(), builderOpt) If Not sourceAssembly.DeclaringCompilation.Options.OutputKind.IsNetModule() Then GetForwardedTypes(seenTopLevelForwardedTypes, sourceAssembly.GetNetModuleDecodedWellKnownAttributeData(), builderOpt) End If Return seenTopLevelForwardedTypes End Function Private Sub ReportExportedTypeNameCollisions(exportedTypes As ImmutableArray(Of Cci.ExportedType), diagnostics As DiagnosticBag) Dim sourceAssembly As SourceAssemblySymbol = SourceModule.ContainingSourceAssembly Dim exportedNamesMap = New Dictionary(Of String, NamedTypeSymbol)() For Each exportedType In _lazyExportedTypes Dim typeReference As Cci.ITypeReference = exportedType.Type Dim type = DirectCast(typeReference.GetInternalSymbol(), NamedTypeSymbol) Debug.Assert(type.IsDefinition) If type.ContainingType IsNot Nothing Then Continue For End If ' exported types are not emitted in EnC deltas (hence generation 0): Dim fullEmittedName As String = MetadataHelpers.BuildQualifiedName( DirectCast(typeReference, Cci.INamespaceTypeReference).NamespaceName, Cci.MetadataWriter.GetMetadataName(DirectCast(typeReference, Cci.INamedTypeReference), generation:=0)) ' First check against types declared in the primary module If ContainsTopLevelType(fullEmittedName) Then If type.ContainingAssembly Is sourceAssembly Then diagnostics.Add(ERRID.ERR_ExportedTypeConflictsWithDeclaration, NoLocation.Singleton, type, type.ContainingModule) Else diagnostics.Add(ERRID.ERR_ForwardedTypeConflictsWithDeclaration, NoLocation.Singleton, CustomSymbolDisplayFormatter.DefaultErrorFormat(type)) End If Continue For End If Dim contender As NamedTypeSymbol = Nothing ' Now check against other exported types If exportedNamesMap.TryGetValue(fullEmittedName, contender) Then If type.ContainingAssembly Is sourceAssembly Then ' all exported types precede forwarded types, therefore contender cannot be a forwarded type. Debug.Assert(contender.ContainingAssembly Is sourceAssembly) diagnostics.Add(ERRID.ERR_ExportedTypesConflict, NoLocation.Singleton, CustomSymbolDisplayFormatter.DefaultErrorFormat(type), CustomSymbolDisplayFormatter.DefaultErrorFormat(type.ContainingModule), CustomSymbolDisplayFormatter.DefaultErrorFormat(contender), CustomSymbolDisplayFormatter.DefaultErrorFormat(contender.ContainingModule)) ElseIf contender.ContainingAssembly Is sourceAssembly Then ' Forwarded type conflicts with exported type diagnostics.Add(ERRID.ERR_ForwardedTypeConflictsWithExportedType, NoLocation.Singleton, CustomSymbolDisplayFormatter.DefaultErrorFormat(type), type.ContainingAssembly, CustomSymbolDisplayFormatter.DefaultErrorFormat(contender), CustomSymbolDisplayFormatter.DefaultErrorFormat(contender.ContainingModule)) Else ' Forwarded type conflicts with another forwarded type diagnostics.Add(ERRID.ERR_ForwardedTypesConflict, NoLocation.Singleton, CustomSymbolDisplayFormatter.DefaultErrorFormat(type), type.ContainingAssembly, CustomSymbolDisplayFormatter.DefaultErrorFormat(contender), contender.ContainingAssembly) End If Continue For End If exportedNamesMap.Add(fullEmittedName, type) Next End Sub Private Overloads Sub GetExportedTypes(symbol As NamespaceOrTypeSymbol, parentIndex As Integer, builder As ArrayBuilder(Of Cci.ExportedType)) Dim index As Integer If symbol.Kind = SymbolKind.NamedType Then If symbol.DeclaredAccessibility <> Accessibility.Public Then Return End If Debug.Assert(symbol.IsDefinition) index = builder.Count builder.Add(New Cci.ExportedType(DirectCast(symbol, NamedTypeSymbol).GetCciAdapter(), parentIndex, isForwarder:=False)) Else index = -1 End If For Each member In symbol.GetMembers() Dim namespaceOrType = TryCast(member, NamespaceOrTypeSymbol) If namespaceOrType IsNot Nothing Then GetExportedTypes(namespaceOrType, index, builder) End If Next End Sub Private Shared Sub GetForwardedTypes( seenTopLevelTypes As HashSet(Of NamedTypeSymbol), wellKnownAttributeData As CommonAssemblyWellKnownAttributeData(Of NamedTypeSymbol), builderOpt As ArrayBuilder(Of Cci.ExportedType)) If wellKnownAttributeData?.ForwardedTypes?.Count > 0 Then ' (type, index of the parent exported type in builder, or -1 if the type is a top-level type) Dim stack = ArrayBuilder(Of (type As NamedTypeSymbol, parentIndex As Integer)).GetInstance() ' Hashset enumeration is not guaranteed to be deterministic. Emitting in the order of fully qualified names. Dim orderedForwardedTypes As IEnumerable(Of NamedTypeSymbol) = wellKnownAttributeData.ForwardedTypes If builderOpt IsNot Nothing Then orderedForwardedTypes = orderedForwardedTypes.OrderBy(Function(t) t.OriginalDefinition.ToDisplayString(SymbolDisplayFormat.QualifiedNameArityFormat)) End If For Each forwardedType As NamedTypeSymbol In orderedForwardedTypes Dim originalDefinition As NamedTypeSymbol = forwardedType.OriginalDefinition Debug.Assert(originalDefinition.ContainingType Is Nothing, "How did a nested type get forwarded?") ' De-dup the original definitions before emitting. If Not seenTopLevelTypes.Add(originalDefinition) Then Continue For End If If builderOpt IsNot Nothing Then ' Return all nested types. ' Note the order: depth first, children in reverse order (to match dev10, not a requirement). Debug.Assert(stack.Count = 0) stack.Push((originalDefinition, -1)) While stack.Count > 0 Dim entry = stack.Pop() ' In general, we don't want private types to appear in the ExportedTypes table. If entry.type.DeclaredAccessibility = Accessibility.Private Then ' NOTE: this will also exclude nested types of curr. Continue While End If ' NOTE: not bothering to put nested types in seenTypes - the top-level type is adequate protection. Dim index = builderOpt.Count builderOpt.Add(New Cci.ExportedType(entry.type.GetCciAdapter(), entry.parentIndex, isForwarder:=True)) ' Iterate backwards so they get popped in forward order. Dim nested As ImmutableArray(Of NamedTypeSymbol) = entry.type.GetTypeMembers() ' Ordered. For i As Integer = nested.Length - 1 To 0 Step -1 stack.Push((nested(i), index)) Next End While End If Next stack.Free() End If End Sub Friend Iterator Function GetReferencedAssembliesUsedSoFar() As IEnumerable(Of AssemblySymbol) For Each assembly In SourceModule.GetReferencedAssemblySymbols() If Not assembly.IsLinked AndAlso Not assembly.IsMissing AndAlso m_AssemblyOrModuleSymbolToModuleRefMap.ContainsKey(assembly) Then Yield assembly End If Next End Function Friend NotOverridable Overrides Function GetSpecialType(specialType As SpecialType, syntaxNodeOpt As SyntaxNode, diagnostics As DiagnosticBag) As Cci.INamedTypeReference Return Translate(GetUntranslatedSpecialType(specialType, syntaxNodeOpt, diagnostics), needDeclaration:=True, syntaxNodeOpt:=syntaxNodeOpt, diagnostics:=diagnostics) End Function Private Function GetUntranslatedSpecialType(specialType As SpecialType, syntaxNodeOpt As SyntaxNode, diagnostics As DiagnosticBag) As NamedTypeSymbol Dim typeSymbol = SourceModule.ContainingAssembly.GetSpecialType(specialType) Dim info = Binder.GetUseSiteInfoForSpecialType(typeSymbol) If info.DiagnosticInfo IsNot Nothing Then Binder.ReportDiagnostic(diagnostics, If(syntaxNodeOpt IsNot Nothing, syntaxNodeOpt.GetLocation(), NoLocation.Singleton), info.DiagnosticInfo) End If Return typeSymbol End Function Public NotOverridable Overrides Function GetInitArrayHelper() As Cci.IMethodReference Return DirectCast(Compilation.GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_RuntimeHelpers__InitializeArrayArrayRuntimeFieldHandle), MethodSymbol)?.GetCciAdapter() End Function Public NotOverridable Overrides Function IsPlatformType(typeRef As Cci.ITypeReference, platformType As Cci.PlatformType) As Boolean Dim namedType = TryCast(typeRef.GetInternalSymbol(), NamedTypeSymbol) If namedType IsNot Nothing Then If platformType = Cci.PlatformType.SystemType Then Return namedType Is Compilation.GetWellKnownType(WellKnownType.System_Type) End If Return namedType.SpecialType = CType(platformType, SpecialType) End If Return False End Function Protected NotOverridable Overrides Function GetCorLibraryReferenceToEmit(context As EmitContext) As Cci.IAssemblyReference Dim corLib = CorLibrary If Not corLib.IsMissing AndAlso Not corLib.IsLinked AndAlso corLib IsNot SourceModule.ContainingAssembly Then Return Translate(corLib, context.Diagnostics) End If Return Nothing End Function Friend NotOverridable Overrides Function GetSynthesizedNestedTypes(container As NamedTypeSymbol) As IEnumerable(Of Cci.INestedTypeDefinition) Return container.GetSynthesizedNestedTypes() End Function Public Overrides Iterator Function GetTypeToDebugDocumentMap(context As EmitContext) As IEnumerable(Of (Cci.ITypeDefinition, ImmutableArray(Of Cci.DebugSourceDocument))) Dim typesToProcess = ArrayBuilder(Of Cci.ITypeDefinition).GetInstance() Dim debugDocuments = ArrayBuilder(Of Cci.DebugSourceDocument).GetInstance() Dim methodDocumentList = PooledHashSet(Of Cci.DebugSourceDocument).GetInstance() Dim namespacesAndTopLevelTypesToProcess = ArrayBuilder(Of NamespaceOrTypeSymbol).GetInstance() namespacesAndTopLevelTypesToProcess.Push(SourceModule.GlobalNamespace) While namespacesAndTopLevelTypesToProcess.Count > 0 Dim symbol = namespacesAndTopLevelTypesToProcess.Pop() If symbol.Locations.Length = 0 Then Continue While End If Select Case symbol.Kind Case SymbolKind.Namespace Dim location = GetSmallestSourceLocationOrNull(symbol) ' filtering out synthesized symbols not having real source ' locations such as anonymous types, my types, etc... If location IsNot Nothing Then For Each member In symbol.GetMembers() Select Case member.Kind Case SymbolKind.Namespace, SymbolKind.NamedType namespacesAndTopLevelTypesToProcess.Push(DirectCast(member, NamespaceOrTypeSymbol)) Case Else Throw ExceptionUtilities.UnexpectedValue(member.Kind) End Select Next End If Case SymbolKind.NamedType ' We only process top level types in this method, and only return documents for types if there are no ' methods that would refer to the same document, either in the type or in any nested type. Debug.Assert(debugDocuments.Count = 0) Debug.Assert(methodDocumentList.Count = 0) Debug.Assert(typesToProcess.Count = 0) Dim typeDefinition = DirectCast(symbol.GetCciAdapter(), Cci.ITypeDefinition) typesToProcess.Push(typeDefinition) GetDocumentsForMethodsAndNestedTypes(methodDocumentList, typesToProcess, context) For Each loc In symbol.Locations If Not loc.IsInSource Then Continue For End If Dim span = loc.GetLineSpan() Dim debugDocument = DebugDocumentsBuilder.TryGetDebugDocument(span.Path, basePath:=Nothing) If debugDocument IsNot Nothing AndAlso Not methodDocumentList.Contains(debugDocument) Then debugDocuments.Add(debugDocument) End If Next If debugDocuments.Count > 0 Then Yield (typeDefinition, debugDocuments.ToImmutable()) End If debugDocuments.Clear() methodDocumentList.Clear() Case Else Throw ExceptionUtilities.UnexpectedValue(symbol.Kind) End Select End While namespacesAndTopLevelTypesToProcess.Free() debugDocuments.Free() methodDocumentList.Free() typesToProcess.Free() End Function Private Shared Sub GetDocumentsForMethodsAndNestedTypes(documentList As PooledHashSet(Of Cci.DebugSourceDocument), typesToProcess As ArrayBuilder(Of Cci.ITypeDefinition), context As EmitContext) ' Temporarily disable assert to unblock getting net8.0 testing re-enabled on Unix. Will ' remove this shortly. ' https://github.com/dotnet/roslyn/issues/71571 ' Debug.Assert(Not context.MetadataOnly) While typesToProcess.Count > 0 Dim definition = typesToProcess.Pop() Dim typeMethods = definition.GetMethods(context) For Each method In typeMethods Dim body = method.GetBody(context) If body Is Nothing Then Continue For End If For Each point In body.SequencePoints documentList.Add(point.Document) Next Next Dim nestedTypes = definition.GetNestedTypes(context) For Each nestedTypeDefinition In nestedTypes typesToProcess.Push(nestedTypeDefinition) Next End While End Sub Public Sub SetDisableJITOptimization(methodSymbol As MethodSymbol) Debug.Assert(methodSymbol.ContainingModule Is Me.SourceModule AndAlso methodSymbol Is methodSymbol.OriginalDefinition) _disableJITOptimization.TryAdd(methodSymbol, True) End Sub Public Function JITOptimizationIsDisabled(methodSymbol As MethodSymbol) As Boolean Debug.Assert(methodSymbol Is methodSymbol.OriginalDefinition) Return _disableJITOptimization.ContainsKey(methodSymbol) End Function Protected NotOverridable Overrides Function CreatePrivateImplementationDetailsStaticConstructor(syntaxOpt As SyntaxNode, diagnostics As DiagnosticBag) As Cci.IMethodDefinition Return New SynthesizedPrivateImplementationDetailsSharedConstructor(SourceModule, GetPrivateImplClass(syntaxOpt, diagnostics), GetUntranslatedSpecialType(SpecialType.System_Void, syntaxOpt, diagnostics)).GetCciAdapter() End Function Public Overrides Function GetAdditionalTopLevelTypeDefinitions(context As EmitContext) As IEnumerable(Of Cci.INamespaceTypeDefinition) #If DEBUG Then Return GetAdditionalTopLevelTypes().Select(Function(t) t.GetCciAdapter()) #Else Return GetAdditionalTopLevelTypes() #End If End Function Public Overrides Function GetEmbeddedTypeDefinitions(context As EmitContext) As IEnumerable(Of Cci.INamespaceTypeDefinition) #If DEBUG Then Return GetEmbeddedTypes(context.Diagnostics).Select(Function(t) t.GetCciAdapter()) #Else Return GetEmbeddedTypes(context.Diagnostics) #End If End Function End Class End Namespace