/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/VisualBasic/Portable/Symbols/Source/SourceAssemblySymbol.vb
1 839 строк
103 KB
Miha Zupan
Replace string.Compare == 0 patterns with Equals/StartsWith calls (#84036)
16 июн 2026, 19:27
Не верифицирован
16 июн 2026, 19:27
6128161
Код
Авторство
О чём код?
' 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 Imports System.Runtime.InteropServices Imports System.Threading Imports Microsoft.CodeAnalysis.Collections Imports Microsoft.CodeAnalysis.PooledObjects Imports Microsoft.CodeAnalysis.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Emit Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports CommonAssemblyWellKnownAttributeData = Microsoft.CodeAnalysis.CommonAssemblyWellKnownAttributeData(Of Microsoft.CodeAnalysis.VisualBasic.Symbols.NamedTypeSymbol) Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols ''' <summary> ''' Represents an assembly built by compiler. ''' </summary> ''' <remarks></remarks> Partial Friend NotInheritable Class SourceAssemblySymbol Inherits MetadataOrSourceAssemblySymbol Implements ISourceAssemblySymbol, ISourceAssemblySymbolInternal, IAttributeTargetSymbol ''' <summary> ''' A Compilation the assembly is created for. ''' </summary> ''' <remarks></remarks> Private ReadOnly _compilation As VisualBasicCompilation Private _lazyStrongNameKeys As StrongNameKeys ''' <summary> ''' Assembly's identity. ''' </summary> ''' <remarks></remarks> Friend m_lazyIdentity As AssemblyIdentity ''' <summary> ''' A list of modules the assembly consists of. ''' The first (index=0) module is a SourceModuleSymbol, which is a primary module, the rest are net-modules. ''' </summary> Private ReadOnly _modules As ImmutableArray(Of ModuleSymbol) Private _lazySourceAttributesBag As CustomAttributesBag(Of VisualBasicAttributeData) Private _lazyNetModuleAttributesBag As CustomAttributesBag(Of VisualBasicAttributeData) ''' <summary> ''' Indices of duplicate assembly attributes, i.e. attributes that bind to the same constructor and have identical arguments, that must not be emitted. ''' </summary> ''' <remarks> ''' These indices correspond to the merged assembly attributes from source and added net modules, i.e. attributes returned by <see cref="GetAttributes"/> method. ''' </remarks> Private _lazyDuplicateAttributeIndices As HashSet(Of Integer) Private _lazyEmitExtensionAttribute As Byte = ThreeState.Unknown Private _lazyIsVbRuntime As ThreeState = ThreeState.Unknown Private _lazyAssemblyLevelDeclarationErrors As ImmutableArray(Of Diagnostic) Private _lazyAssemblyLevelDeclarationDependencies As ImmutableArray(Of AssemblySymbol) Private ReadOnly _assemblySimpleName As String 'This maps from assembly name to a set of public keys. It uses concurrent dictionaries because it is built, 'one attribute at a time, in the callback that validates an attribute's application to a symbol. It is assumed 'to be complete after a call to GetAttributes(). The second dictionary is acting like a set. The value element is 'only used when the key is empty in which case it stores the location and value of the attribute string which 'may be used to construct a diagnostic if the assembly being compiled is found to be strong named. Private _lazyInternalsVisibleToMap As ConcurrentDictionary(Of String, ConcurrentDictionary(Of ImmutableArray(Of Byte), Tuple(Of Location, String))) Friend Sub New(compilation As VisualBasicCompilation, assemblySimpleName As String, moduleName As String, netModules As ImmutableArray(Of PEModule)) Debug.Assert(compilation IsNot Nothing) Debug.Assert(assemblySimpleName IsNot Nothing) Debug.Assert(Not String.IsNullOrWhiteSpace(moduleName)) Debug.Assert(Not netModules.IsDefault) _compilation = compilation _assemblySimpleName = assemblySimpleName Dim moduleBuilder As New ArrayBuilder(Of ModuleSymbol)(1 + netModules.Length) moduleBuilder.Add(New SourceModuleSymbol(Me, compilation.Declarations, compilation.Options, moduleName)) Dim importOptions = If(compilation.Options.MetadataImportOptions = MetadataImportOptions.All, MetadataImportOptions.All, MetadataImportOptions.Internal) For Each netModule As PEModule In netModules moduleBuilder.Add(New PEModuleSymbol(Me, netModule, importOptions, moduleBuilder.Count)) ' SetReferences will be called later by the ReferenceManager (in CreateSourceAssemblyFullBind for ' a fresh manager, in CreateSourceAssemblyReuseData for a reused one). Next _modules = moduleBuilder.ToImmutableAndFree() If Not compilation.Options.CryptoPublicKey.IsEmpty Then ' Private key Is Not necessary for assembly identity, only when emitting. For this reason, the private key can remain null. _lazyStrongNameKeys = StrongNameKeys.Create(compilation.Options.CryptoPublicKey, privateKey:=Nothing, hasCounterSignature:=False, MessageProvider.Instance) End If End Sub ''' <summary> ''' This override is essential - it's a base case of the recursive definition. ''' </summary> Friend Overrides ReadOnly Property DeclaringCompilation As VisualBasicCompilation Get Return _compilation End Get End Property Public Overrides ReadOnly Property IsInteractive As Boolean Get Return _compilation.IsSubmission End Get End Property Friend Function MightContainNoPiaLocalTypes() As Boolean For i As Integer = 1 To _modules.Length - 1 Dim peModuleSymbol = DirectCast(_modules(i), Symbols.Metadata.PE.PEModuleSymbol) If peModuleSymbol.[Module].ContainsNoPiaLocalTypes() Then Return True End If Next Return SourceModule.MightContainNoPiaLocalTypes() End Function Public Overrides ReadOnly Property Identity As AssemblyIdentity Get If m_lazyIdentity Is Nothing Then Interlocked.CompareExchange(m_lazyIdentity, ComputeIdentity(), Nothing) End If Return m_lazyIdentity End Get End Property Public Overrides ReadOnly Property HasImportedFromTypeLibAttribute As Boolean Get Return (GetSourceDecodedWellKnownAttributeData()?.HasImportedFromTypeLibAttribute).GetValueOrDefault() End Get End Property Public Overrides ReadOnly Property HasPrimaryInteropAssemblyAttribute As Boolean Get Return (GetSourceDecodedWellKnownAttributeData()?.HasPrimaryInteropAssemblyAttribute).GetValueOrDefault() End Get End Property Friend Overrides Function GetSpecialTypeMember(member As SpecialMember) As Symbol If _compilation.IsMemberMissing(member) Then Return Nothing End If Return MyBase.GetSpecialTypeMember(member) End Function Public Overrides ReadOnly Property Name As String Get Return _assemblySimpleName End Get End Property Private Function IsKnownAssemblyAttribute(attribute As VisualBasicAttributeData) As Boolean ' TODO: This list used to include AssemblyOperatingSystemAttribute and AssemblyProcessorAttribute, ' but it doesn't look like they are defined, cannot find them on MSDN. If attribute.IsTargetAttribute(AttributeDescription.AssemblyTitleAttribute) OrElse attribute.IsTargetAttribute(AttributeDescription.AssemblyDescriptionAttribute) OrElse attribute.IsTargetAttribute(AttributeDescription.AssemblyConfigurationAttribute) OrElse attribute.IsTargetAttribute(AttributeDescription.AssemblyCultureAttribute) OrElse attribute.IsTargetAttribute(AttributeDescription.AssemblyVersionAttribute) OrElse attribute.IsTargetAttribute(AttributeDescription.AssemblyCompanyAttribute) OrElse attribute.IsTargetAttribute(AttributeDescription.AssemblyProductAttribute) OrElse attribute.IsTargetAttribute(AttributeDescription.AssemblyInformationalVersionAttribute) OrElse attribute.IsTargetAttribute(AttributeDescription.AssemblyCopyrightAttribute) OrElse attribute.IsTargetAttribute(AttributeDescription.AssemblyTrademarkAttribute) OrElse attribute.IsTargetAttribute(AttributeDescription.AssemblyKeyFileAttribute) OrElse attribute.IsTargetAttribute(AttributeDescription.AssemblyKeyNameAttribute) OrElse attribute.IsTargetAttribute(AttributeDescription.AssemblyAlgorithmIdAttribute) OrElse attribute.IsTargetAttribute(AttributeDescription.AssemblyFlagsAttribute) OrElse attribute.IsTargetAttribute(AttributeDescription.AssemblyDelaySignAttribute) OrElse attribute.IsTargetAttribute(AttributeDescription.AssemblyFileVersionAttribute) OrElse attribute.IsTargetAttribute(AttributeDescription.SatelliteContractVersionAttribute) OrElse attribute.IsTargetAttribute(AttributeDescription.AssemblySignatureKeyAttribute) Then Return True End If Return False End Function ''' <summary> ''' Gets unique source assembly attributes that should be emitted, ''' i.e. filters out attributes with errors and duplicate attributes. ''' </summary> Private Function GetUniqueSourceAssemblyAttributes(<Out> ByRef attributeIndicesToSkip As HashSet(Of Integer)) As HashSet(Of VisualBasicAttributeData) Dim appliedSourceAttributes As ImmutableArray(Of VisualBasicAttributeData) = Me.GetSourceAttributesBag().Attributes Dim uniqueAttributes As HashSet(Of VisualBasicAttributeData) = Nothing attributeIndicesToSkip = Nothing For i As Integer = 0 To appliedSourceAttributes.Length - 1 Dim attribute As VisualBasicAttributeData = appliedSourceAttributes(i) If Not attribute.HasErrors Then If Not AddUniqueAssemblyAttribute(attribute, uniqueAttributes) Then If attributeIndicesToSkip Is Nothing Then attributeIndicesToSkip = New HashSet(Of Integer) End If attributeIndicesToSkip.Add(i) End If End If Next Return uniqueAttributes End Function Private Shared Function AddUniqueAssemblyAttribute(attribute As VisualBasicAttributeData, ByRef uniqueAttributes As HashSet(Of VisualBasicAttributeData)) As Boolean Debug.Assert(Not attribute.HasErrors) If uniqueAttributes Is Nothing Then uniqueAttributes = New HashSet(Of VisualBasicAttributeData)(comparer:=CommonAttributeDataComparer.Instance) End If Return uniqueAttributes.Add(attribute) End Function Private Function ValidateAttributeUsageForNetModuleAttribute(attribute As VisualBasicAttributeData, netModuleName As String, diagnostics As BindingDiagnosticBag, ByRef uniqueAttributes As HashSet(Of VisualBasicAttributeData)) As Boolean Debug.Assert(Not attribute.HasErrors) Dim attributeClass = attribute.AttributeClass If attributeClass.GetAttributeUsageInfo().AllowMultiple Then ' Duplicate attributes are allowed, but native compiler doesn't emit duplicate attributes, i.e. attributes with same constructor and arguments. Return AddUniqueAssemblyAttribute(attribute, uniqueAttributes) Else ' Duplicate attributes with same attribute type are not allowed. ' Check if there is an existing assembly attribute with same attribute type. If uniqueAttributes Is Nothing OrElse Not uniqueAttributes.Contains(Function(a) TypeSymbol.Equals(a.AttributeClass, attributeClass, TypeCompareKind.ConsiderEverything)) Then ' Attribute with unique attribute type, not a duplicate. Dim success As Boolean = AddUniqueAssemblyAttribute(attribute, uniqueAttributes) Debug.Assert(success) Return True Else ' Duplicate attribute with same attribute type, we should report an error. ' Native compiler suppresses the error for ' (a) Duplicate well-known assembly attributes and ' (b) Identical duplicates, i.e. attributes with same constructor and arguments. ' For (a), native compiler picks the last of these duplicate well-known netmodule attributes, but these can vary based on the ordering of referenced netmodules. If IsKnownAssemblyAttribute(attribute) Then If Not uniqueAttributes.Contains(attribute) Then ' This attribute application will be ignored. diagnostics.Add(ERRID.WRN_AssemblyAttributeFromModuleIsOverridden, NoLocation.Singleton, attribute.AttributeClass, netModuleName) End If ElseIf AddUniqueAssemblyAttribute(attribute, uniqueAttributes) Then ' Error diagnostics.Add(ERRID.ERR_InvalidMultipleAttributeUsageInNetModule2, NoLocation.Singleton, attribute.AttributeClass.Name, netModuleName) End If Return False End If End If ' CONSIDER Handling badly targeted assembly attributes from netmodules 'If (attributeUsage.ValidTargets And AttributeTargets.Assembly) = 0 Then ' If Not attribute.HasErrors Then ' 'Error and skip ' diagnostics.Add(ERRID.ERR_InvalidAssemblyAttributeInNetModule2, NoLocation.Singleton, attribute.AttributeClass.Name, netModuleName, attributeUsage.GetValidTargetsString()) ' End If 'End If End Function Private Function GetNetModuleAttributes(<Out> ByRef netModuleNames As ImmutableArray(Of String)) As ImmutableArray(Of VisualBasicAttributeData) Dim netModuleNamesBuilder As ArrayBuilder(Of String) = Nothing Dim moduleAssemblyAttributesBuilder As ArrayBuilder(Of VisualBasicAttributeData) = Nothing For i As Integer = 1 To _modules.Length - 1 Dim peModuleSymbol = DirectCast(_modules(i), Symbols.Metadata.PE.PEModuleSymbol) Dim netModuleName As String = peModuleSymbol.Name For Each attributeData In peModuleSymbol.GetAssemblyAttributes() If netModuleNamesBuilder Is Nothing Then netModuleNamesBuilder = ArrayBuilder(Of String).GetInstance() moduleAssemblyAttributesBuilder = ArrayBuilder(Of VisualBasicAttributeData).GetInstance() End If netModuleNamesBuilder.Add(netModuleName) moduleAssemblyAttributesBuilder.Add(attributeData) Next Next If netModuleNamesBuilder Is Nothing Then netModuleNames = ImmutableArray(Of String).Empty Return ImmutableArray(Of VisualBasicAttributeData).Empty End If netModuleNames = netModuleNamesBuilder.ToImmutableAndFree() Return moduleAssemblyAttributesBuilder.ToImmutableAndFree() End Function Private Function ValidateAttributeUsageAndDecodeWellKnownNetModuleAttributes( attributesFromNetModules As ImmutableArray(Of VisualBasicAttributeData), netModuleNames As ImmutableArray(Of String), diagnostics As BindingDiagnosticBag, <Out> ByRef attributeIndicesToSkip As HashSet(Of Integer)) As WellKnownAttributeData Debug.Assert(attributesFromNetModules.Any()) Debug.Assert(netModuleNames.Any()) Debug.Assert(attributesFromNetModules.Length = netModuleNames.Length) Dim tree = VisualBasicSyntaxTree.Dummy Dim node = tree.GetRoot() Dim binder As Binder = BinderBuilder.CreateSourceModuleBinder(Me.SourceModule) Dim netModuleAttributesCount As Integer = attributesFromNetModules.Length Dim sourceAttributesCount As Integer = Me.GetSourceAttributesBag().Attributes.Length ' Get unique source assembly attributes. Dim uniqueAttributes As HashSet(Of VisualBasicAttributeData) = GetUniqueSourceAssemblyAttributes(attributeIndicesToSkip) Dim arguments = New DecodeWellKnownAttributeArguments(Of AttributeSyntax, VisualBasicAttributeData, AttributeLocation)() arguments.AttributesCount = netModuleAttributesCount arguments.Diagnostics = diagnostics arguments.SymbolPart = AttributeLocation.None ' Attributes from the second added module should override attributes from the first added module, etc. ' Attributes from source should override attributes from added modules. ' That is why we are iterating attributes backwards. For i As Integer = netModuleAttributesCount - 1 To 0 Step -1 Dim attribute As VisualBasicAttributeData = attributesFromNetModules(i) Dim errorInfo As DiagnosticInfo = attribute.ErrorInfo If errorInfo IsNot Nothing Then diagnostics.Add(errorInfo, NoLocation.Singleton) End If If Not attribute.HasErrors AndAlso ValidateAttributeUsageForNetModuleAttribute(attribute, netModuleNames(i), diagnostics, uniqueAttributes) Then arguments.Attribute = attribute arguments.Index = i ' CONSIDER Provide usable AttributeSyntax node for diagnostics of malformed netmodule assembly attributes arguments.AttributeSyntaxOpt = Nothing Me.DecodeWellKnownAttribute(arguments) Else If attributeIndicesToSkip Is Nothing Then attributeIndicesToSkip = New HashSet(Of Integer) End If attributeIndicesToSkip.Add(i + sourceAttributesCount) End If Next Return If(arguments.HasDecodedData, arguments.DecodedData, Nothing) End Function Private Sub LoadAndValidateNetModuleAttributes(ByRef lazyNetModuleAttributesBag As CustomAttributesBag(Of VisualBasicAttributeData)) ' Indices of duplicate assembly attributes, i.e. attributes that bind to the same constructor and have identical arguments, that must not be emitted. Dim attributeIndicesToSkip As HashSet(Of Integer) = Nothing If _compilation.Options.OutputKind.IsNetModule() Then ' Compute duplicate source assembly attributes, i.e. attributes with same constructor and arguments, that must not be emitted. Dim unused = GetUniqueSourceAssemblyAttributes(attributeIndicesToSkip) Interlocked.CompareExchange(lazyNetModuleAttributesBag, CustomAttributesBag(Of VisualBasicAttributeData).Empty, Nothing) Else Dim diagnostics = BindingDiagnosticBag.GetInstance() Dim netModuleNames As ImmutableArray(Of String) = Nothing Dim attributesFromNetModules As ImmutableArray(Of VisualBasicAttributeData) = GetNetModuleAttributes(netModuleNames) Dim wellKnownData As WellKnownAttributeData = Nothing If attributesFromNetModules.Any() Then wellKnownData = ValidateAttributeUsageAndDecodeWellKnownNetModuleAttributes(attributesFromNetModules, netModuleNames, diagnostics, attributeIndicesToSkip) Else ' Compute duplicate source assembly attributes, i.e. attributes with same constructor and arguments, that must not be emitted. Dim unused = GetUniqueSourceAssemblyAttributes(attributeIndicesToSkip) End If ' Load type forwarders from modules Dim forwardedTypes As HashSet(Of NamedTypeSymbol) = Nothing ' Similar to attributes, type forwarders from the second added module should override type forwarders from the first added module, etc. ' This affects only diagnostics. For i As Integer = _modules.Length - 1 To 1 Step -1 Dim peModuleSymbol = DirectCast(_modules(i), PEModuleSymbol) For Each forwarded As NamedTypeSymbol In peModuleSymbol.GetForwardedTypes() If forwardedTypes Is Nothing Then If wellKnownData Is Nothing Then wellKnownData = New CommonAssemblyWellKnownAttributeData() End If forwardedTypes = DirectCast(wellKnownData, CommonAssemblyWellKnownAttributeData).ForwardedTypes If forwardedTypes Is Nothing Then forwardedTypes = New HashSet(Of NamedTypeSymbol)() DirectCast(wellKnownData, CommonAssemblyWellKnownAttributeData).ForwardedTypes = forwardedTypes End If End If If forwardedTypes.Add(forwarded) Then If forwarded.IsErrorType() Then Dim info As DiagnosticInfo = If(forwarded.GetUseSiteInfo().DiagnosticInfo, DirectCast(forwarded, ErrorTypeSymbol).ErrorInfo) If info IsNot Nothing Then diagnostics.Add(info, NoLocation.Singleton) End If End If End If Next Next Dim netModuleAttributesBag As CustomAttributesBag(Of VisualBasicAttributeData) If wellKnownData IsNot Nothing OrElse attributesFromNetModules.Any() Then netModuleAttributesBag = New CustomAttributesBag(Of VisualBasicAttributeData)() netModuleAttributesBag.SetEarlyDecodedWellKnownAttributeData(Nothing) netModuleAttributesBag.SetDecodedWellKnownAttributeData(wellKnownData) netModuleAttributesBag.SetAttributes(attributesFromNetModules) Else netModuleAttributesBag = CustomAttributesBag(Of VisualBasicAttributeData).Empty End If ' Check if we have any duplicate assembly attribute that must not be emitted, ' unless we are emitting a net module. If attributeIndicesToSkip IsNot Nothing Then Debug.Assert(attributeIndicesToSkip.Any()) Interlocked.CompareExchange(_lazyDuplicateAttributeIndices, attributeIndicesToSkip, Nothing) End If SourceModule.AtomicStoreReferenceAndDiagnostics(lazyNetModuleAttributesBag, netModuleAttributesBag, diagnostics) diagnostics.Free() Debug.Assert(attributeIndicesToSkip Is Nothing OrElse Not attributeIndicesToSkip.Any(Function(index) index < 0 OrElse index >= Me.GetAttributes().Length)) End If Debug.Assert(lazyNetModuleAttributesBag.IsSealed) End Sub Friend Overrides Function GetAllTopLevelForwardedTypes() As IEnumerable(Of NamedTypeSymbol) Return Emit.PEModuleBuilder.GetForwardedTypes(Me, builderOpt:=Nothing) End Function Private Sub EnsureNetModuleAttributesAreBound() If _lazyNetModuleAttributesBag Is Nothing Then LoadAndValidateNetModuleAttributes(_lazyNetModuleAttributesBag) End If End Sub ''' <summary> ''' Returns true if the assembly attribute at the given index is a duplicate assembly attribute that must not be emitted. ''' Duplicate assembly attributes are attributes that bind to the same constructor and have identical arguments. ''' </summary> ''' <remarks> ''' This method must be invoked only after all the assembly attributes have been bound. ''' </remarks> Friend Function IsIndexOfDuplicateAssemblyAttribute(index As Integer) As Boolean Debug.Assert(Me._lazySourceAttributesBag.IsSealed) Debug.Assert(Me._lazyNetModuleAttributesBag.IsSealed) Debug.Assert(index >= 0) Debug.Assert(index < Me.GetAttributes().Length) Debug.Assert(Me._lazyDuplicateAttributeIndices Is Nothing OrElse Not IsNetModule) Return Me._lazyDuplicateAttributeIndices IsNot Nothing AndAlso Me._lazyDuplicateAttributeIndices.Contains(index) End Function Public ReadOnly Property DefaultAttributeLocation As AttributeLocation Implements IAttributeTargetSymbol.DefaultAttributeLocation Get Return AttributeLocation.Assembly End Get End Property Friend Function GetAttributeDeclarations() As ImmutableArray(Of SyntaxList(Of AttributeListSyntax)) Dim attributeBlocks = ArrayBuilder(Of SyntaxList(Of AttributeListSyntax)).GetInstance() Dim declarations = DeclaringCompilation.MergedRootDeclaration.Declarations For Each rootNs As RootSingleNamespaceDeclaration In declarations If rootNs.HasAssemblyAttributes Then Dim compilationUnitSyntax = DirectCast(rootNs.Location.SourceTree.GetRoot(), CompilationUnitSyntax) Dim attributeStatements = compilationUnitSyntax.Attributes If attributeStatements.Any Then For Each statement In attributeStatements 'For Each block In statement.AttributeLists 'attributeBlocks.Add(block) 'Next attributeBlocks.Add(statement.AttributeLists) Next End If End If Next Return attributeBlocks.ToImmutableAndFree() End Function ''' <summary> ''' Returns a bag of netmodule assembly attributes and data decoded from well-known attributes. Returns null if there are no attributes applied on the symbol. ''' </summary> ''' <remarks> ''' Forces binding and decoding of attributes. ''' </remarks> Friend Function GetNetModuleAttributesBag() As CustomAttributesBag(Of VisualBasicAttributeData) EnsureNetModuleAttributesAreBound() Return _lazyNetModuleAttributesBag End Function Friend Function GetNetModuleDecodedWellKnownAttributeData() As CommonAssemblyWellKnownAttributeData Dim attributesBag = Me.GetNetModuleAttributesBag() Debug.Assert(attributesBag.IsSealed) Return DirectCast(attributesBag.DecodedWellKnownAttributeData, CommonAssemblyWellKnownAttributeData) End Function ''' <summary> ''' Gets the attributes applied on this symbol. ''' Returns an empty array if there are no attributes. ''' </summary> ''' <remarks> ''' NOTE: This method should always be kept as a NotOverridable method. ''' If you want to override attribute binding logic for a sub-class, then override <see cref="GetSourceAttributesBag"/> method. ''' </remarks> Public Overloads Overrides Function GetAttributes() As ImmutableArray(Of VisualBasicAttributeData) Dim attributes = Me.GetSourceAttributesBag().Attributes Dim netmoduleAttributes = Me.GetNetModuleAttributesBag().Attributes Debug.Assert(Not attributes.IsDefault) Debug.Assert(Not netmoduleAttributes.IsDefault) If attributes.Length > 0 Then If netmoduleAttributes.Length > 0 Then attributes = attributes.Concat(netmoduleAttributes) End If Else attributes = netmoduleAttributes End If Debug.Assert(Not attributes.IsDefault) Return attributes End Function Friend Function GetSourceAttributesBag() As CustomAttributesBag(Of VisualBasicAttributeData) EnsureAttributesAreBound() Return Me._lazySourceAttributesBag End Function ''' <summary> ''' Returns data decoded from source assembly attributes or null if there are none. ''' </summary> ''' <returns> ''' Forces binding and decoding of attributes. ''' TODO: We should replace methods GetSourceDecodedWellKnownAttributeData and GetNetModuleDecodedWellKnownAttributeData with ''' a single method GetDecodedWellKnownAttributeData, which merges DecodedWellKnownAttributeData from source and netmodule attributes. ''' </returns> ''' <remarks></remarks> Friend Function GetSourceDecodedWellKnownAttributeData() As CommonAssemblyWellKnownAttributeData Dim attributesBag As CustomAttributesBag(Of VisualBasicAttributeData) = Me._lazySourceAttributesBag If attributesBag Is Nothing OrElse Not attributesBag.IsDecodedWellKnownAttributeDataComputed Then attributesBag = Me.GetSourceAttributesBag() End If Return DirectCast(attributesBag.DecodedWellKnownAttributeData, CommonAssemblyWellKnownAttributeData) End Function Private Function GetWellKnownAttributeDataStringField(fieldGetter As Func(Of CommonAssemblyWellKnownAttributeData, String), Optional missingValue As String = Nothing) As String Dim defaultValue As String = missingValue Dim fieldValue = defaultValue Dim data = GetSourceDecodedWellKnownAttributeData() If data IsNot Nothing Then fieldValue = fieldGetter(data) End If If fieldValue Is missingValue Then data = GetNetModuleDecodedWellKnownAttributeData() If data IsNot Nothing Then fieldValue = fieldGetter(data) End If End If Return fieldValue End Function Friend Function GetSecurityAttributes() As IEnumerable(Of Cci.SecurityAttribute) Dim sourceSecurityAttributes As IEnumerable(Of Cci.SecurityAttribute) = Nothing Dim attributesBag As CustomAttributesBag(Of VisualBasicAttributeData) = Me.GetSourceAttributesBag() Dim wellKnownAttributeData = DirectCast(attributesBag.DecodedWellKnownAttributeData, CommonAssemblyWellKnownAttributeData(Of NamedTypeSymbol)) If wellKnownAttributeData IsNot Nothing Then Dim securityData As SecurityWellKnownAttributeData = wellKnownAttributeData.SecurityInformation If securityData IsNot Nothing Then sourceSecurityAttributes = securityData.GetSecurityAttributes(attributesBag.Attributes) End If End If Dim netmoduleSecurityAttributes As IEnumerable(Of Cci.SecurityAttribute) = Nothing attributesBag = Me.GetNetModuleAttributesBag() wellKnownAttributeData = DirectCast(attributesBag.DecodedWellKnownAttributeData, CommonAssemblyWellKnownAttributeData(Of NamedTypeSymbol)) If wellKnownAttributeData IsNot Nothing Then Dim securityData As SecurityWellKnownAttributeData = wellKnownAttributeData.SecurityInformation If securityData IsNot Nothing Then netmoduleSecurityAttributes = securityData.GetSecurityAttributes(attributesBag.Attributes) End If End If Dim securityAttributes As IEnumerable(Of Cci.SecurityAttribute) = Nothing If sourceSecurityAttributes IsNot Nothing Then If netmoduleSecurityAttributes IsNot Nothing Then securityAttributes = sourceSecurityAttributes.Concat(netmoduleSecurityAttributes) Else securityAttributes = sourceSecurityAttributes End If Else If netmoduleSecurityAttributes IsNot Nothing Then securityAttributes = netmoduleSecurityAttributes Else securityAttributes = SpecializedCollections.EmptyEnumerable(Of Cci.SecurityAttribute)() End If End If Debug.Assert(securityAttributes IsNot Nothing) Return securityAttributes End Function Friend ReadOnly Property FileVersion As String Get Return GetWellKnownAttributeDataStringField(Function(data) data.AssemblyFileVersionAttributeSetting) End Get End Property Friend ReadOnly Property Title As String Get Return GetWellKnownAttributeDataStringField(Function(data) data.AssemblyTitleAttributeSetting) End Get End Property Friend ReadOnly Property Description As String Get Return GetWellKnownAttributeDataStringField(Function(data) data.AssemblyDescriptionAttributeSetting) End Get End Property Friend ReadOnly Property Company As String Get Return GetWellKnownAttributeDataStringField(Function(data) data.AssemblyCompanyAttributeSetting) End Get End Property Friend ReadOnly Property Product As String Get Return GetWellKnownAttributeDataStringField(Function(data) data.AssemblyProductAttributeSetting) End Get End Property Friend ReadOnly Property InformationalVersion As String Get Return GetWellKnownAttributeDataStringField(Function(data) data.AssemblyInformationalVersionAttributeSetting) End Get End Property Friend ReadOnly Property Copyright As String Get Return GetWellKnownAttributeDataStringField(Function(data) data.AssemblyCopyrightAttributeSetting) End Get End Property Friend ReadOnly Property Trademark As String Get Return GetWellKnownAttributeDataStringField(Function(data) data.AssemblyTrademarkAttributeSetting) End Get End Property ''' <summary> ''' This represents what the user claimed in source through the AssemblyFlagsAttribute. ''' It may be modified as emitted due to presence or absence of the public key. ''' </summary> Public ReadOnly Property AssemblyFlags As AssemblyFlags Implements ISourceAssemblySymbolInternal.AssemblyFlags Get Dim fieldValue As AssemblyFlags = Nothing Dim data = GetSourceDecodedWellKnownAttributeData() If data IsNot Nothing Then fieldValue = data.AssemblyFlagsAttributeSetting End If data = GetNetModuleDecodedWellKnownAttributeData() If data IsNot Nothing Then fieldValue = fieldValue Or data.AssemblyFlagsAttributeSetting End If Return fieldValue End Get End Property Private ReadOnly Property DelaySignAttributeSetting As Boolean Get Dim defaultValue = False Dim fieldValue = defaultValue Dim data = GetSourceDecodedWellKnownAttributeData() If data IsNot Nothing Then fieldValue = (data.AssemblyDelaySignAttributeSetting = ThreeState.True) End If If fieldValue = defaultValue Then data = GetNetModuleDecodedWellKnownAttributeData() If data IsNot Nothing Then fieldValue = (data.AssemblyDelaySignAttributeSetting = ThreeState.True) End If End If Return fieldValue End Get End Property Public ReadOnly Property SignatureKey As String Implements ISourceAssemblySymbolInternal.SignatureKey Get Return GetWellKnownAttributeDataStringField(Function(data) data.AssemblySignatureKeyAttributeSetting) End Get End Property Private ReadOnly Property AssemblyKeyContainerAttributeSetting As String Get Return GetWellKnownAttributeDataStringField(Function(data) data.AssemblyKeyContainerAttributeSetting, CommonAssemblyWellKnownAttributeData.StringMissingValue) End Get End Property Private ReadOnly Property AssemblyKeyFileAttributeSetting As String Get Return GetWellKnownAttributeDataStringField(Function(data) data.AssemblyKeyFileAttributeSetting, CommonAssemblyWellKnownAttributeData.StringMissingValue) End Get End Property Private ReadOnly Property AssemblyCultureAttributeSetting As String Get Return GetWellKnownAttributeDataStringField(Function(data) data.AssemblyCultureAttributeSetting) End Get End Property Private ReadOnly Property AssemblyVersionAttributeSetting As Version Get Dim defaultValue As Version = Nothing Dim fieldValue = defaultValue Dim data = GetSourceDecodedWellKnownAttributeData() If data IsNot Nothing Then fieldValue = data.AssemblyVersionAttributeSetting End If If fieldValue Is defaultValue Then data = GetNetModuleDecodedWellKnownAttributeData() If data IsNot Nothing Then fieldValue = data.AssemblyVersionAttributeSetting End If End If Return fieldValue End Get End Property Public Overrides ReadOnly Property AssemblyVersionPattern As Version Implements ISourceAssemblySymbolInternal.AssemblyVersionPattern Get Dim attributeValue = AssemblyVersionAttributeSetting Return If(attributeValue Is Nothing OrElse (attributeValue.Build <> UShort.MaxValue AndAlso attributeValue.Revision <> UShort.MaxValue), Nothing, attributeValue) End Get End Property Public ReadOnly Property HashAlgorithm As AssemblyHashAlgorithm Implements ISourceAssemblySymbolInternal.HashAlgorithm Get Return If(AssemblyAlgorithmIdAttributeSetting, AssemblyHashAlgorithm.Sha1) End Get End Property Friend ReadOnly Property AssemblyAlgorithmIdAttributeSetting As AssemblyHashAlgorithm? Get Dim fieldValue As AssemblyHashAlgorithm? = Nothing Dim data = GetSourceDecodedWellKnownAttributeData() If data IsNot Nothing Then fieldValue = data.AssemblyAlgorithmIdAttributeSetting End If If fieldValue Is Nothing Then data = GetNetModuleDecodedWellKnownAttributeData() If data IsNot Nothing Then fieldValue = data.AssemblyAlgorithmIdAttributeSetting End If End If Return fieldValue End Get End Property Private Sub EnsureAttributesAreBound() If _lazySourceAttributesBag Is Nothing OrElse Not _lazySourceAttributesBag.IsSealed Then LoadAndValidateAttributes(OneOrMany.Create(GetAttributeDeclarations()), _lazySourceAttributesBag) End If End Sub ' TODO: cache Public Overrides ReadOnly Property Locations As ImmutableArray(Of Location) Get Return Me.Modules.SelectMany(Function(m) m.Locations).AsImmutable() End Get End Property Public Overrides ReadOnly Property Modules As ImmutableArray(Of ModuleSymbol) Get Return _modules End Get End Property Friend Overrides Function GetNoPiaResolutionAssemblies() As ImmutableArray(Of AssemblySymbol) Return SourceModule.GetReferencedAssemblySymbols() End Function Friend Overrides Sub SetNoPiaResolutionAssemblies(assemblies As ImmutableArray(Of AssemblySymbol)) Throw ExceptionUtilities.Unreachable End Sub Friend Overrides Function GetLinkedReferencedAssemblies() As ImmutableArray(Of AssemblySymbol) ' SourceAssemblySymbol is never used directly as a reference ' when it is or any of its references is linked. Return Nothing End Function Friend Overrides Sub SetLinkedReferencedAssemblies(assemblies As ImmutableArray(Of AssemblySymbol)) ' SourceAssemblySymbol is never used directly as a reference ' when it is or any of its references is linked. Throw ExceptionUtilities.Unreachable End Sub Friend Overrides ReadOnly Property IsLinked As Boolean Get Return False End Get End Property ' Computing the identity requires computing the public key. Computing the public key ' can require binding attributes that contain version or strong name information. ' Attribute binding will check type visibility which will possibly ' check IVT relationships. To correctly determine the IVT relationship requires the public key. ' To avoid infinite recursion, this type notes, per thread, the assembly for which the thread ' is actively computing the public key (s_AssemblyForWhichCurrentThreadIsComputingKeys). Should a request to determine IVT ' relationship occur on the thread that is computing the public key, access is optimistically ' granted provided the simple assembly names match. When such access is granted ' the assembly to which we have been granted access is noted (m_optimisticallyGrantedInternalsAccess). ' After the public key has been computed, the set of optimistic grants is reexamined ' to ensure that full identities match. This may produce diagnostics. ' EDMAURER please don't use thread local storage widely. This is hoped to be a one-off usage. <ThreadStatic()> Private Shared s_AssemblyForWhichCurrentThreadIsComputingKeys As AssemblySymbol ' A collection of assemblies to which we were granted internals access by only checking matches for assembly name ' and ignoring public key. This just acts as a set. The Boolean is ignored. Private _optimisticallyGrantedInternalsAccess As ConcurrentDictionary(Of AssemblySymbol, Boolean) ' Once the computation of the AssemblyIdentity is complete, check whether ' any of the IVT access grants that were optimistically made during AssemblyIdentity computation ' are in fact invalid now that the full identity is known. Private Sub CheckOptimisticIVTAccessGrants(bag As BindingDiagnosticBag) Dim haveGrantedAssemblies As ConcurrentDictionary(Of AssemblySymbol, Boolean) = _optimisticallyGrantedInternalsAccess If haveGrantedAssemblies IsNot Nothing Then For Each otherAssembly In haveGrantedAssemblies.Keys Dim conclusion As IVTConclusion = MakeFinalIVTDetermination(otherAssembly, assertUnexpectedGiver:=True) Debug.Assert(conclusion <> IVTConclusion.NoRelationshipClaimed) If conclusion = IVTConclusion.PublicKeyDoesntMatch Then bag.Add(New VBDiagnostic(ErrorFactory.ErrorInfo(ERRID.ERR_FriendRefNotEqualToThis, otherAssembly.Identity, Me.Identity), NoLocation.Singleton)) ElseIf conclusion = IVTConclusion.OneSignedOneNot Then bag.Add(New VBDiagnostic(ErrorFactory.ErrorInfo(ERRID.ERR_FriendRefSigningMismatch, otherAssembly.Identity, Me.Identity), NoLocation.Singleton)) End If Next End If End Sub Friend Overrides Function GetInternalsVisibleToPublicKeys(simpleName As String) As IEnumerable(Of ImmutableArray(Of Byte)) 'EDMAURER assume that if EnsureAttributesAreBound() returns, then the internals visible to map has been populated. 'Do not optimize by checking if m_lazyInternalsVisibleToMap is Nothing. It may be non-null yet still 'incomplete because another thread is in the process of building it. EnsureAttributesAreBound() If _lazyInternalsVisibleToMap Is Nothing Then Return SpecializedCollections.EmptyEnumerable(Of ImmutableArray(Of Byte))() End If Dim result As ConcurrentDictionary(Of ImmutableArray(Of Byte), Tuple(Of Location, String)) = Nothing _lazyInternalsVisibleToMap.TryGetValue(simpleName, result) Return If(result IsNot Nothing, result.Keys, SpecializedCollections.EmptyEnumerable(Of ImmutableArray(Of Byte))()) End Function Friend Overrides Function GetInternalsVisibleToAssemblyNames() As IEnumerable(Of String) EnsureAttributesAreBound() If _lazyInternalsVisibleToMap Is Nothing Then Return SpecializedCollections.EmptyEnumerable(Of String)() End If Return _lazyInternalsVisibleToMap.Keys End Function Friend ReadOnly Property DeclaresTheObjectClass As Boolean Get If Me.CorLibrary IsNot Me Then Return False End If Dim obj = GetSpecialType(SpecialType.System_Object) Return Not obj.IsErrorType() AndAlso obj.DeclaredAccessibility = Accessibility.Public End Get End Property Friend ReadOnly Property SourceModule As SourceModuleSymbol Get Return DirectCast(_modules(0), SourceModuleSymbol) End Get End Property Public Overrides ReadOnly Property MightContainExtensionMethods As Boolean Get ' Only primary module of an assembly marked with an Extension attribute ' can contain extension methods recognized by the language (Dev10 behavior). Return SourceModule.MightContainExtensionMethods End Get End Property Private Function ProcessOneInternalsVisibleToAttribute(nodeOpt As AttributeSyntax, attrData As VisualBasicAttributeData, diagnostics As BindingDiagnosticBag) As Boolean 'assume that this code won't be called unless we bound a well-formed, semantically 'correct ctor call. Dim displayName As String = TryCast(attrData.CommonConstructorArguments(0).ValueInternal, String) If displayName Is Nothing Then diagnostics.Add(ERRID.ERR_FriendAssemblyNameInvalid, If(nodeOpt IsNot Nothing, nodeOpt.GetLocation(), NoLocation.Singleton), "") Return False End If Dim identity As AssemblyIdentity = Nothing Dim parts As AssemblyIdentityParts = Nothing If Not AssemblyIdentity.TryParseDisplayName(displayName, identity, parts) Then diagnostics.Add(ERRID.ERR_FriendAssemblyNameInvalid, If(nodeOpt IsNot Nothing, nodeOpt.GetLocation(), NoLocation.Singleton), displayName) Return False End If ' Allow public key token due to compatibility reasons, but we are not going to use its value. Const allowedParts = AssemblyIdentityParts.Name Or AssemblyIdentityParts.PublicKey Or AssemblyIdentityParts.PublicKeyToken If (parts And Not allowedParts) <> 0 Then diagnostics.Add(ERRID.ERR_FriendAssemblyBadArguments, If(nodeOpt IsNot Nothing, nodeOpt.GetLocation(), NoLocation.Singleton), displayName) Return False End If If _lazyInternalsVisibleToMap Is Nothing Then Interlocked.CompareExchange(_lazyInternalsVisibleToMap, New ConcurrentDictionary(Of String, ConcurrentDictionary(Of ImmutableArray(Of Byte), Tuple(Of Location, String)))(StringComparer.OrdinalIgnoreCase), Nothing) End If 'later, once the identity is established we confirm that if the assembly being 'compiled is signed all of the IVT attributes specify a key. Stash the location for that ' in the event that a diagnostic needs to be produced. Dim locationAndValue As Tuple(Of Location, String) = Nothing ' only need to store anything when there is no public key. The only reason to store ' this stuff is for production of errors when the assembly is signed but the IVT attrib ' doesn't contain a public key. If identity.PublicKey.IsEmpty Then locationAndValue = New Tuple(Of Location, String)(If(nodeOpt IsNot Nothing, nodeOpt.GetLocation(), NoLocation.Singleton), displayName) End If 'when two threads are attempting to update the internalsVisibleToMap one of these TryAdd() 'calls can fail. We assume that the 'other' thread in that case will successfully add the same 'contents eventually. Dim keys As ConcurrentDictionary(Of ImmutableArray(Of Byte), Tuple(Of Location, String)) = Nothing If _lazyInternalsVisibleToMap.TryGetValue(identity.Name, keys) Then keys.TryAdd(identity.PublicKey, locationAndValue) Else keys = New ConcurrentDictionary(Of ImmutableArray(Of Byte), Tuple(Of Location, String)) keys.TryAdd(identity.PublicKey, locationAndValue) _lazyInternalsVisibleToMap.TryAdd(identity.Name, keys) End If Return True End Function Friend Overrides Sub DecodeWellKnownAttribute(ByRef arguments As DecodeWellKnownAttributeArguments(Of AttributeSyntax, VisualBasicAttributeData, AttributeLocation)) Dim attrData = arguments.Attribute Debug.Assert(Not attrData.HasErrors) Debug.Assert(arguments.SymbolPart = AttributeLocation.None) Dim diagnostics = DirectCast(arguments.Diagnostics, BindingDiagnosticBag) If attrData.IsTargetAttribute(AttributeDescription.CaseInsensitiveExtensionAttribute) Then ' Already have an attribute, no need to add another one. Debug.Assert(_lazyEmitExtensionAttribute <> ThreeState.True) _lazyEmitExtensionAttribute = ThreeState.False ElseIf attrData.IsTargetAttribute(AttributeDescription.InternalsVisibleToAttribute) Then ProcessOneInternalsVisibleToAttribute(arguments.AttributeSyntaxOpt, attrData, diagnostics) ElseIf attrData.IsTargetAttribute(AttributeDescription.AssemblySignatureKeyAttribute) Then Dim signatureKey = DirectCast(attrData.CommonConstructorArguments(0).ValueInternal, String) arguments.GetOrCreateData(Of CommonAssemblyWellKnownAttributeData)().AssemblySignatureKeyAttributeSetting = signatureKey If Not StrongNameKeys.IsValidPublicKeyString(signatureKey) Then diagnostics.Add(ERRID.ERR_InvalidSignaturePublicKey, GetAssemblyAttributeFirstArgumentLocation(arguments.AttributeSyntaxOpt)) End If ElseIf attrData.IsTargetAttribute(AttributeDescription.AssemblyKeyFileAttribute) Then arguments.GetOrCreateData(Of CommonAssemblyWellKnownAttributeData)().AssemblyKeyFileAttributeSetting = DirectCast(attrData.CommonConstructorArguments(0).ValueInternal, String) ElseIf attrData.IsTargetAttribute(AttributeDescription.AssemblyKeyNameAttribute) Then arguments.GetOrCreateData(Of CommonAssemblyWellKnownAttributeData)().AssemblyKeyContainerAttributeSetting = DirectCast(attrData.CommonConstructorArguments(0).ValueInternal, String) ElseIf attrData.IsTargetAttribute(AttributeDescription.AssemblyDelaySignAttribute) Then arguments.GetOrCreateData(Of CommonAssemblyWellKnownAttributeData)().AssemblyDelaySignAttributeSetting = If(DirectCast(attrData.CommonConstructorArguments(0).ValueInternal, Boolean), ThreeState.True, ThreeState.False) ElseIf attrData.IsTargetAttribute(AttributeDescription.AssemblyVersionAttribute) Then Dim verString = DirectCast(attrData.CommonConstructorArguments(0).ValueInternal, String) Dim version As Version = Nothing If Not VersionHelper.TryParseAssemblyVersion(verString, allowWildcard:=Not _compilation.IsEmitDeterministic, version:=version) Then Dim attributeArgumentSyntaxLocation As Location = GetAssemblyAttributeFirstArgumentLocation(arguments.AttributeSyntaxOpt) If _compilation.IsEmitDeterministic AndAlso verString?.Contains("*"c) = True Then diagnostics.Add(ERRID.ERR_InvalidVersionFormatDeterministic, attributeArgumentSyntaxLocation) Else diagnostics.Add(ERRID.ERR_InvalidVersionFormat, attributeArgumentSyntaxLocation) End If End If arguments.GetOrCreateData(Of CommonAssemblyWellKnownAttributeData)().AssemblyVersionAttributeSetting = version ElseIf attrData.IsTargetAttribute(AttributeDescription.AssemblyFileVersionAttribute) Then Dim dummy As Version = Nothing Dim verString = DirectCast(attrData.CommonConstructorArguments(0).ValueInternal, String) If Not VersionHelper.TryParse(verString, version:=dummy) Then diagnostics.Add(ERRID.WRN_InvalidVersionFormat, GetAssemblyAttributeFirstArgumentLocation(arguments.AttributeSyntaxOpt)) End If arguments.GetOrCreateData(Of CommonAssemblyWellKnownAttributeData)().AssemblyFileVersionAttributeSetting = verString ElseIf attrData.IsTargetAttribute(AttributeDescription.AssemblyInformationalVersionAttribute) Then arguments.GetOrCreateData(Of CommonAssemblyWellKnownAttributeData)().AssemblyInformationalVersionAttributeSetting = DirectCast(attrData.CommonConstructorArguments(0).ValueInternal, String) ElseIf attrData.IsTargetAttribute(AttributeDescription.AssemblyTitleAttribute) Then arguments.GetOrCreateData(Of CommonAssemblyWellKnownAttributeData)().AssemblyTitleAttributeSetting = DirectCast(attrData.CommonConstructorArguments(0).ValueInternal, String) ElseIf attrData.IsTargetAttribute(AttributeDescription.AssemblyDescriptionAttribute) Then arguments.GetOrCreateData(Of CommonAssemblyWellKnownAttributeData)().AssemblyDescriptionAttributeSetting = DirectCast(attrData.CommonConstructorArguments(0).ValueInternal, String) ElseIf attrData.IsTargetAttribute(AttributeDescription.AssemblyCultureAttribute) Then Dim cultureString = DirectCast(attrData.CommonConstructorArguments(0).ValueInternal, String) If Not String.IsNullOrEmpty(cultureString) Then If Me.DeclaringCompilation.Options.OutputKind.IsApplication() Then diagnostics.Add(ERRID.ERR_InvalidAssemblyCultureForExe, GetAssemblyAttributeFirstArgumentLocation(arguments.AttributeSyntaxOpt)) ElseIf Not AssemblyIdentity.IsValidCultureName(cultureString) Then diagnostics.Add(ERRID.ERR_InvalidAssemblyCulture, GetAssemblyAttributeFirstArgumentLocation(arguments.AttributeSyntaxOpt)) cultureString = Nothing End If End If arguments.GetOrCreateData(Of CommonAssemblyWellKnownAttributeData)().AssemblyCultureAttributeSetting = cultureString ElseIf attrData.IsTargetAttribute(AttributeDescription.AssemblyCompanyAttribute) Then arguments.GetOrCreateData(Of CommonAssemblyWellKnownAttributeData)().AssemblyCompanyAttributeSetting = DirectCast(attrData.CommonConstructorArguments(0).ValueInternal, String) ElseIf attrData.IsTargetAttribute(AttributeDescription.AssemblyProductAttribute) Then arguments.GetOrCreateData(Of CommonAssemblyWellKnownAttributeData)().AssemblyProductAttributeSetting = DirectCast(attrData.CommonConstructorArguments(0).ValueInternal, String) ElseIf attrData.IsTargetAttribute(AttributeDescription.SatelliteContractVersionAttribute) Then 'just check the format of this one, don't do anything else with it. Dim dummy As Version = Nothing Dim verString = DirectCast(attrData.CommonConstructorArguments(0).ValueInternal, String) If Not VersionHelper.TryParseAssemblyVersion(verString, allowWildcard:=False, version:=dummy) Then diagnostics.Add(ERRID.ERR_InvalidVersionFormat2, GetAssemblyAttributeFirstArgumentLocation(arguments.AttributeSyntaxOpt)) End If ElseIf attrData.IsTargetAttribute(AttributeDescription.AssemblyCopyrightAttribute) Then arguments.GetOrCreateData(Of CommonAssemblyWellKnownAttributeData)().AssemblyCopyrightAttributeSetting = DirectCast(attrData.CommonConstructorArguments(0).ValueInternal, String) ElseIf attrData.IsTargetAttribute(AttributeDescription.AssemblyTrademarkAttribute) Then arguments.GetOrCreateData(Of CommonAssemblyWellKnownAttributeData)().AssemblyTrademarkAttributeSetting = DirectCast(attrData.CommonConstructorArguments(0).ValueInternal, String) ElseIf attrData.IsSecurityAttribute(Me.DeclaringCompilation) Then attrData.DecodeSecurityAttribute(Of CommonAssemblyWellKnownAttributeData)(Me, Me.DeclaringCompilation, arguments) ElseIf attrData.IsTargetAttribute(AttributeDescription.ClassInterfaceAttribute) Then attrData.DecodeClassInterfaceAttribute(arguments.AttributeSyntaxOpt, diagnostics) ElseIf attrData.IsTargetAttribute(AttributeDescription.TypeLibVersionAttribute) Then ValidateIntegralAttributeNonNegativeArguments(attrData, arguments.AttributeSyntaxOpt, diagnostics) ElseIf attrData.IsTargetAttribute(AttributeDescription.ComCompatibleVersionAttribute) Then ValidateIntegralAttributeNonNegativeArguments(attrData, arguments.AttributeSyntaxOpt, diagnostics) ElseIf attrData.IsTargetAttribute(AttributeDescription.GuidAttribute) Then Dim guidString As String = attrData.DecodeGuidAttribute(arguments.AttributeSyntaxOpt, diagnostics) arguments.GetOrCreateData(Of CommonAssemblyWellKnownAttributeData)().GuidAttribute = guidString ElseIf attrData.IsTargetAttribute(AttributeDescription.ImportedFromTypeLibAttribute) Then If attrData.CommonConstructorArguments.Length = 1 Then arguments.GetOrCreateData(Of CommonAssemblyWellKnownAttributeData)().HasImportedFromTypeLibAttribute = True End If ElseIf attrData.IsTargetAttribute(AttributeDescription.PrimaryInteropAssemblyAttribute) Then If attrData.CommonConstructorArguments.Length = 2 Then arguments.GetOrCreateData(Of CommonAssemblyWellKnownAttributeData)().HasPrimaryInteropAssemblyAttribute = True End If ElseIf attrData.IsTargetAttribute(AttributeDescription.CompilationRelaxationsAttribute) Then arguments.GetOrCreateData(Of CommonAssemblyWellKnownAttributeData)().HasCompilationRelaxationsAttribute = True ElseIf attrData.IsTargetAttribute(AttributeDescription.ReferenceAssemblyAttribute) Then arguments.GetOrCreateData(Of CommonAssemblyWellKnownAttributeData)().HasReferenceAssemblyAttribute = True ElseIf attrData.IsTargetAttribute(AttributeDescription.RuntimeCompatibilityAttribute) Then ' VB doesn't need to decode argument values arguments.GetOrCreateData(Of CommonAssemblyWellKnownAttributeData)().RuntimeCompatibilityWrapNonExceptionThrows = True ElseIf attrData.IsTargetAttribute(AttributeDescription.DebuggableAttribute) Then arguments.GetOrCreateData(Of CommonAssemblyWellKnownAttributeData)().HasDebuggableAttribute = True ElseIf attrData.IsTargetAttribute(AttributeDescription.ExperimentalAttribute) Then arguments.GetOrCreateData(Of CommonAssemblyWellKnownAttributeData)().ExperimentalAttributeData = attrData.DecodeExperimentalAttribute() Else Dim signature As Integer = attrData.GetTargetAttributeSignatureIndex(AttributeDescription.AssemblyAlgorithmIdAttribute) If signature <> -1 Then Dim value As Object = attrData.CommonConstructorArguments(0).ValueInternal Dim algorithmId As AssemblyHashAlgorithm If signature = 0 Then algorithmId = CType(value, AssemblyHashAlgorithm) Else algorithmId = CType(CUInt(value), AssemblyHashAlgorithm) End If arguments.GetOrCreateData(Of CommonAssemblyWellKnownAttributeData)().AssemblyAlgorithmIdAttributeSetting = algorithmId Else signature = attrData.GetTargetAttributeSignatureIndex(AttributeDescription.AssemblyFlagsAttribute) If signature <> -1 Then Dim value As Object = attrData.CommonConstructorArguments(0).ValueInternal Dim nameFlags As AssemblyFlags If signature = 0 OrElse signature = 1 Then nameFlags = CType(CType(value, AssemblyNameFlags), AssemblyFlags) Else nameFlags = CType(CUInt(value), AssemblyFlags) End If arguments.GetOrCreateData(Of CommonAssemblyWellKnownAttributeData)().AssemblyFlagsAttributeSetting = nameFlags End If End If End If MyBase.DecodeWellKnownAttribute(arguments) End Sub Private Shared Function GetAssemblyAttributeFirstArgumentLocation(attributeSyntaxOpt As AttributeSyntax) As Location If attributeSyntaxOpt Is Nothing Then Return NoLocation.Singleton End If Return attributeSyntaxOpt.ArgumentList.Arguments.First().GetLocation() End Function ' Checks that the integral arguments for the given well-known attribute are non-negative. Private Sub ValidateIntegralAttributeNonNegativeArguments(attrData As VisualBasicAttributeData, nodeOpt As AttributeSyntax, diagnostics As BindingDiagnosticBag) Debug.Assert(Not attrData.HasErrors) Dim argCount As Integer = attrData.CommonConstructorArguments.Length For i = 0 To argCount - 1 Dim arg As Integer = attrData.GetConstructorArgument(Of Integer)(i, SpecialType.System_Int32) If arg < 0 Then diagnostics.Add(ERRID.ERR_BadAttribute1, VisualBasicAttributeData.GetArgumentLocation(nodeOpt, i), attrData.AttributeClass) End If Next End Sub Friend Sub AnErrorHasBeenReportedAboutExtensionAttribute() ' Note, we are storing false because, even though we might be required to emit the attribute, ' we can't do that due to the error that we just reported. Debug.Assert(_lazyEmitExtensionAttribute <> ThreeState.True) _lazyEmitExtensionAttribute = ThreeState.False End Sub Friend Sub GetAllDeclarationErrors(diagnostics As BindingDiagnosticBag, Optional cancellationToken As CancellationToken = Nothing) Dim hasExtensionMethods As Boolean = False SourceModule.GetAllDeclarationErrors(diagnostics, cancellationToken, hasExtensionMethods) diagnostics.AddRange(GetAssemblyLevelDeclarationErrors(hasExtensionMethods), allowMismatchInDependencyAccumulation:=True) End Sub ''' <summary> ''' Get assembly level declaration errors. ''' </summary> Private Function GetAssemblyLevelDeclarationErrors( haveExtensionMethodsInSource As Boolean) As ReadOnlyBindingDiagnostic(Of AssemblySymbol) If _lazyAssemblyLevelDeclarationErrors.IsDefault OrElse _lazyAssemblyLevelDeclarationDependencies.IsDefault Then Dim diagnostics = BindingDiagnosticBag.GetInstance() Dim emitExtensionAttribute As ThreeState = CType(_lazyEmitExtensionAttribute, ThreeState) If emitExtensionAttribute = ThreeState.Unknown Then Dim needAttribute As Boolean = haveExtensionMethodsInSource If Not needAttribute Then emitExtensionAttribute = ThreeState.False Else ' We need to emit an Extension attribute on the assembly. ' Can we locate it? Dim useSiteInfo As UseSiteInfo(Of AssemblySymbol) = Nothing _compilation.GetExtensionAttributeConstructor(useSiteInfo:=useSiteInfo) If useSiteInfo.DiagnosticInfo IsNot Nothing Then ' Note, we are storing false because, even though we should emit the attribute, ' we can't do that due to the use site error. ' The diagnostic itself was already reported at the location where the attribute was applied to. ' Reporting it also on a place where it's implicitly used would not be expected by developers. emitExtensionAttribute = ThreeState.False Else emitExtensionAttribute = ThreeState.True End If End If End If Debug.Assert(_lazyEmitExtensionAttribute = ThreeState.Unknown OrElse _lazyEmitExtensionAttribute = emitExtensionAttribute) _lazyEmitExtensionAttribute = emitExtensionAttribute 'strong name key settings are not validated when building netmodules. 'They are validated when the netmodule is added to an assembly. If StrongNameKeys.DiagnosticOpt IsNot Nothing AndAlso Not IsNetModule Then diagnostics.Add(StrongNameKeys.DiagnosticOpt) End If ValidateIVTPublicKeys(diagnostics) CheckOptimisticIVTAccessGrants(diagnostics) DetectAttributeAndOptionConflicts(diagnostics) If IsDelaySigned AndAlso Not Identity.HasPublicKey Then diagnostics.Add(ERRID.WRN_DelaySignButNoKey, NoLocation.Singleton) End If If DeclaringCompilation.Options.PublicSign Then If IsNetModule Then diagnostics.Add(ERRID.ERR_PublicSignNetModule, NoLocation.Singleton) ElseIf Not Identity.HasPublicKey Then diagnostics.Add(ERRID.ERR_PublicSignNoKey, NoLocation.Singleton) End If End If ' If the options and attributes applied on the compilation imply real signing, ' but we have no private key to sign it with report an error. ' Note that if public key is set and delay sign is off we do OSS signing, which doesn't require private key. ' Consider: should we allow to OSS sign if the key file only contains public key? If DeclaringCompilation.Options.OutputKind <> OutputKind.NetModule AndAlso DeclaringCompilation.Options.CryptoPublicKey.IsEmpty AndAlso Identity.HasPublicKey AndAlso Not IsDelaySigned AndAlso Not DeclaringCompilation.Options.PublicSign AndAlso Not StrongNameKeys.CanSign Then ' Since the container always contains both keys, the problem is that the key file didn't contain private key. diagnostics.Add(ERRID.ERR_SignButNoPrivateKey, NoLocation.Singleton, StrongNameKeys.KeyFilePath) End If ReportDiagnosticsForSynthesizedAttributes(DeclaringCompilation, diagnostics) ReportDiagnosticsForAddedModules(diagnostics) Dim immutableBindingDiagnostic As ReadOnlyBindingDiagnostic(Of AssemblySymbol) = diagnostics.ToReadOnlyAndFree() ImmutableInterlocked.InterlockedInitialize(_lazyAssemblyLevelDeclarationDependencies, immutableBindingDiagnostic.Dependencies) ImmutableInterlocked.InterlockedInitialize(_lazyAssemblyLevelDeclarationErrors, immutableBindingDiagnostic.Diagnostics) End If Debug.Assert(Not _lazyAssemblyLevelDeclarationErrors.IsDefault) Debug.Assert(Not _lazyAssemblyLevelDeclarationDependencies.IsDefault) Return New ReadOnlyBindingDiagnostic(Of AssemblySymbol)(_lazyAssemblyLevelDeclarationErrors, _lazyAssemblyLevelDeclarationDependencies) End Function Private Sub DetectAttributeAndOptionConflicts(diagnostics As BindingDiagnosticBag) EnsureAttributesAreBound() If _compilation.Options.PublicSign AndAlso DelaySignAttributeSetting Then diagnostics.Add(ERRID.ERR_CmdOptionConflictsSource, NoLocation.Singleton, AttributeDescription.AssemblyDelaySignAttribute.FullName, NameOf(_compilation.Options.PublicSign)) End If If _compilation.Options.OutputKind = OutputKind.NetModule Then If Not String.IsNullOrEmpty(_compilation.Options.CryptoKeyContainer) Then Dim assemblyKeyContainerAttributeSetting As String = Me.AssemblyKeyContainerAttributeSetting If assemblyKeyContainerAttributeSetting Is CommonAssemblyWellKnownAttributeData.StringMissingValue Then ' We need to synthesize this attribute for .NET module, ' touch the constructor in order to generate proper use-site diagnostics Binder.ReportUseSiteInfoForSynthesizedAttribute( WellKnownMember.System_Reflection_AssemblyKeyNameAttribute__ctor, _compilation, NoLocation.Singleton, diagnostics) ElseIf Not String.Equals(_compilation.Options.CryptoKeyContainer, assemblyKeyContainerAttributeSetting, StringComparison.OrdinalIgnoreCase) Then ' If we are building a .NET module, things get more complicated. In particular, we don't sign the module, we emit an attribute with the key ' information, which will be used to sign an assembly once the module is linked into it. If there is already an attribute like that in source, ' native compiler emits both of them, synthetic attribute is emitted after the one from source. Incidentally, ALink picks the last attribute ' for signing and things seem to work out. However, relying on the order of attributes feels fragile, especially given that Roslyn emits ' synthetic attributes before attributes from source. The behavior we settled on for .NET modules is that, if the attribute in source has the ' same value as the one in compilation options, we won't emit the synthetic attribute. If the value doesn't match, we report an error, which ' is a breaking change. Bottom line, we will never produce a module or an assembly with two attributes, regardless whether values are the same ' or not. diagnostics.Add(ERRID.ERR_CmdOptionConflictsSource, NoLocation.Singleton, AttributeDescription.AssemblyKeyNameAttribute.FullName, "CryptoKeyContainer") End If End If If Not String.IsNullOrEmpty(_compilation.Options.CryptoKeyFile) Then Dim assemblyKeyFileAttributeSetting As String = Me.AssemblyKeyFileAttributeSetting If assemblyKeyFileAttributeSetting Is CommonAssemblyWellKnownAttributeData.StringMissingValue Then ' We need to synthesize this attribute for .NET module, ' touch the constructor in order to generate proper use-site diagnostics Binder.ReportUseSiteInfoForSynthesizedAttribute( WellKnownMember.System_Reflection_AssemblyKeyFileAttribute__ctor, _compilation, NoLocation.Singleton, diagnostics) ElseIf Not String.Equals(_compilation.Options.CryptoKeyFile, assemblyKeyFileAttributeSetting, StringComparison.OrdinalIgnoreCase) Then ' Comment in similar section for CryptoKeyContainer is applicable here as well. diagnostics.Add(ERRID.ERR_CmdOptionConflictsSource, NoLocation.Singleton, AttributeDescription.AssemblyKeyFileAttribute.FullName, "CryptoKeyFile") End If End If ElseIf _compilation.Options.PublicSign Then If Me.AssemblyKeyContainerAttributeSetting IsNot CommonAssemblyWellKnownAttributeData.StringMissingValue Then diagnostics.Add(ERRID.WRN_AttributeIgnoredWhenPublicSigning, NoLocation.Singleton, AttributeDescription.AssemblyKeyNameAttribute.FullName) End If If Me.AssemblyKeyFileAttributeSetting IsNot CommonAssemblyWellKnownAttributeData.StringMissingValue Then diagnostics.Add(ERRID.WRN_AttributeIgnoredWhenPublicSigning, NoLocation.Singleton, AttributeDescription.AssemblyKeyFileAttribute.FullName) End If End If End Sub Private Sub ReportDiagnosticsForAddedModules(diagnostics As BindingDiagnosticBag) For Each pair In _compilation.GetBoundReferenceManager().ReferencedModuleIndexMap Dim fileRef = TryCast(pair.Key, PortableExecutableReference) If fileRef IsNot Nothing AndAlso fileRef.FilePath IsNot Nothing Then Dim fileName As String = FileNameUtilities.GetFileName(fileRef.FilePath) Dim moduleName As String = _modules(pair.Value).Name If Not String.Equals(fileName, moduleName, StringComparison.OrdinalIgnoreCase) Then ' Used to be ERR_UnableToEmitAssembly diagnostics.Add(ERRID.ERR_NetModuleNameMismatch, NoLocation.Singleton, moduleName, fileName) End If End If Next ' Alink performed these checks only when emitting an assembly. If _modules.Length > 1 AndAlso Not _compilation.Options.OutputKind.IsNetModule() Then Dim assemblyMachine = Me.Machine Dim isPlatformAgnostic As Boolean = (assemblyMachine = PortableExecutable.Machine.I386 AndAlso Not Me.Bit32Required) Dim knownModuleNames As New HashSet(Of String)(StringComparer.OrdinalIgnoreCase) For i As Integer = 1 To Modules.Length - 1 Dim m As ModuleSymbol = Modules(i) If Not knownModuleNames.Add(m.Name) Then diagnostics.Add(ERRID.ERR_NetModuleNameMustBeUnique, NoLocation.Singleton, m.Name) End If If Not DirectCast(m, PEModuleSymbol).Module.IsCOFFOnly Then Dim moduleMachine = m.Machine If moduleMachine = PortableExecutable.Machine.I386 AndAlso Not m.Bit32Required Then ' Other module is agnostic, this is always safe ElseIf isPlatformAgnostic Then diagnostics.Add(ERRID.ERR_AgnosticToMachineModule, NoLocation.Singleton, m) ElseIf assemblyMachine <> moduleMachine Then ' Different machine types, and neither is agnostic ' So it is a conflict diagnostics.Add(ERRID.ERR_ConflictingMachineModule, NoLocation.Singleton, m) End If End If Next ' Assembly main module must explicitly reference all the modules referenced by other assembly ' modules, i.e. all modules from transitive closure must be referenced explicitly here For i As Integer = 1 To Modules.Length - 1 Dim m = DirectCast(Modules(i), PEModuleSymbol) Try For Each referencedModuleName In m.Module.GetReferencedManagedModulesOrThrow() ' Do not report error for this module twice If knownModuleNames.Add(referencedModuleName) Then diagnostics.Add(ERRID.ERR_MissingNetModuleReference, NoLocation.Singleton, referencedModuleName) End If Next Catch mrEx As BadImageFormatException diagnostics.Add(ERRID.ERR_UnsupportedModule1, NoLocation.Singleton, m) End Try Next End If End Sub Friend ReadOnly Property IsDelaySigned As Boolean Get EnsureAttributesAreBound() 'TODO need to figure out the right behavior when command line and 'attribute value conflict. Does command line setting need to be three-valued? If (DeclaringCompilation.Options.DelaySign.HasValue) Then Return DeclaringCompilation.Options.DelaySign.Value End If Return DelaySignAttributeSetting End Get End Property Protected Sub ValidateIVTPublicKeys(diagnostics As BindingDiagnosticBag) EnsureAttributesAreBound() If Not Me.Identity.IsStrongName Then Return End If If _lazyInternalsVisibleToMap IsNot Nothing Then For Each keys In _lazyInternalsVisibleToMap.Values For Each oneKey In keys If oneKey.Key.IsDefaultOrEmpty Then diagnostics.Add(ERRID.ERR_FriendAssemblyStrongNameRequired, oneKey.Value.Item1, oneKey.Value.Item2) End If Next Next End If End Sub ''' <summary> ''' True if internals are exposed at all. ''' </summary> ''' <remarks> ''' Forces binding and decoding of attributes. ''' This property shouldn't be accessed during binding as it can lead to attribute binding cycle. ''' </remarks> Public ReadOnly Property InternalsAreVisible As Boolean Implements ISourceAssemblySymbolInternal.InternalsAreVisible Get EnsureAttributesAreBound() Return _lazyInternalsVisibleToMap IsNot Nothing End Get End Property ''' <summary> ''' We may synthesize some well-known attributes for this assembly symbol. However, at synthesis time, it is ''' too late to report diagnostics or cancel the emit. Instead, we check for use site errors on the types and members ''' we know we'll need at synthesis time. ''' </summary> Private Shared Sub ReportDiagnosticsForSynthesizedAttributes(compilation As VisualBasicCompilation, diagnostics As BindingDiagnosticBag) ' May need to synthesize CompilationRelaxationsAttribute and/or RuntimeCompatibilityAttribute if we are not building a net-module. ' NOTE: Native compiler skips synthesizing these attributes if the respective well-known attribute types aren't available, we do the same. Dim compilationOptions As VisualBasicCompilationOptions = compilation.Options If Not compilationOptions.OutputKind.IsNetModule() Then Dim compilationRelaxationsAttributeType = compilation.GetWellKnownType(WellKnownType.System_Runtime_CompilerServices_CompilationRelaxationsAttribute) If TryCast(compilationRelaxationsAttributeType, MissingMetadataTypeSymbol) Is Nothing Then Binder.ReportUseSiteInfoForSynthesizedAttribute(WellKnownMember.System_Runtime_CompilerServices_CompilationRelaxationsAttribute__ctorInt32, compilation, NoLocation.Singleton, diagnostics) End If Dim runtimeCompatibilityAttributeType = compilation.GetWellKnownType(WellKnownType.System_Runtime_CompilerServices_RuntimeCompatibilityAttribute) If TryCast(runtimeCompatibilityAttributeType, MissingMetadataTypeSymbol) Is Nothing Then Binder.ReportUseSiteInfoForSynthesizedAttribute(WellKnownMember.System_Runtime_CompilerServices_RuntimeCompatibilityAttribute__ctor, compilation, NoLocation.Singleton, diagnostics) Binder.ReportUseSiteInfoForSynthesizedAttribute(WellKnownMember.System_Runtime_CompilerServices_RuntimeCompatibilityAttribute__WrapNonExceptionThrows, compilation, NoLocation.Singleton, diagnostics) End If End If End Sub Private ReadOnly Property HasAssemblyOrModuleDebuggableAttribute As Boolean Get Dim assemblyData As CommonAssemblyWellKnownAttributeData = Me.GetSourceDecodedWellKnownAttributeData() If assemblyData IsNot Nothing AndAlso assemblyData.HasDebuggableAttribute Then Return True End If Dim moduleData As CommonModuleWellKnownAttributeData = Me.SourceModule.GetDecodedWellKnownAttributeData() If moduleData IsNot Nothing AndAlso moduleData.HasDebuggableAttribute Then Return True End If Return False End Get End Property Private ReadOnly Property HasReferenceAssemblyAttribute As Boolean Get Dim assemblyData As CommonAssemblyWellKnownAttributeData = Me.GetSourceDecodedWellKnownAttributeData() Return assemblyData IsNot Nothing AndAlso assemblyData.HasReferenceAssemblyAttribute End Get End Property Friend Overrides Function GetGuidString(ByRef guidString As String) As Boolean guidString = GetSourceDecodedWellKnownAttributeData()?.GuidAttribute Return guidString IsNot Nothing End Function Friend Overrides Sub AddSynthesizedAttributes(moduleBuilder As PEModuleBuilder, ByRef attributes As ArrayBuilder(Of VisualBasicAttributeData)) MyBase.AddSynthesizedAttributes(moduleBuilder, attributes) Debug.Assert(_lazyEmitExtensionAttribute <> ThreeState.Unknown) Debug.Assert(_lazySourceAttributesBag.IsSealed) Dim options As VisualBasicCompilationOptions = Me.DeclaringCompilation.Options Dim isBuildingNetModule As Boolean = options.OutputKind.IsNetModule() Dim emitExtensionAttribute As Boolean = _lazyEmitExtensionAttribute = ThreeState.True If emitExtensionAttribute Then AddSynthesizedAttribute(attributes, _compilation.SynthesizeExtensionAttribute()) End If ' Note that manager's collection of referenced symbols may not be sealed ' yet in case this and previous emits didn't emit IL, but only metadata Dim emitEmbeddedAttribute As Boolean = Me.DeclaringCompilation.EmbeddedSymbolManager.IsAnySymbolReferenced If emitEmbeddedAttribute Then AddSynthesizedAttribute(attributes, DeclaringCompilation.TrySynthesizeAttribute(WellKnownMember.Microsoft_VisualBasic_Embedded__ctor)) End If ' Synthesize CompilationRelaxationsAttribute only if all the following requirements are met: ' (a) We are not building a netmodule. ' (b) There is no applied CompilationRelaxationsAttribute assembly attribute in source. ' (c) There is no applied CompilationRelaxationsAttribute assembly attribute for any of the added PE modules. ' Above requirements also hold for synthesizing RuntimeCompatibilityAttribute attribute. Dim emitCompilationRelaxationsAttribute As Boolean = Not isBuildingNetModule AndAlso Not Me.Modules.Any(Function(m) m.HasAssemblyCompilationRelaxationsAttribute) If emitCompilationRelaxationsAttribute Then ' Synthesize attribute: <CompilationRelaxationsAttribute(CompilationRelaxations.NoStringInterning)> ' NOTE: Native compiler skips synthesizing these attributes if the respective well-known attribute types aren't available, we do the same. Dim compilationRelaxationsAttributeType = DeclaringCompilation.GetWellKnownType(WellKnownType.System_Runtime_CompilerServices_CompilationRelaxationsAttribute) If TryCast(compilationRelaxationsAttributeType, MissingMetadataTypeSymbol) Is Nothing Then Dim int32Type = Me.DeclaringCompilation.GetSpecialType(SpecialType.System_Int32) Debug.Assert(int32Type.GetUseSiteInfo().DiagnosticInfo Is Nothing, "Use site errors should have been checked ahead of time (type int).") Dim typedConstantNoStringInterning = New TypedConstant(int32Type, TypedConstantKind.Primitive, Cci.Constants.CompilationRelaxations_NoStringInterning) AddSynthesizedAttribute(attributes, DeclaringCompilation.TrySynthesizeAttribute( WellKnownMember.System_Runtime_CompilerServices_CompilationRelaxationsAttribute__ctorInt32, ImmutableArray.Create(typedConstantNoStringInterning))) End If End If Dim emitRuntimeCompatibilityAttribute As Boolean = Not isBuildingNetModule AndAlso Not Me.Modules.Any(Function(m) m.HasAssemblyRuntimeCompatibilityAttribute) If emitRuntimeCompatibilityAttribute Then ' Synthesize attribute: <RuntimeCompatibilityAttribute(WrapNonExceptionThrows = true)> ' NOTE: Native compiler skips synthesizing these attributes if the respective well-known attribute types aren't available, we do the same. Dim runtimeCompatibilityAttributeType = DeclaringCompilation.GetWellKnownType(WellKnownType.System_Runtime_CompilerServices_RuntimeCompatibilityAttribute) If TryCast(runtimeCompatibilityAttributeType, MissingMetadataTypeSymbol) Is Nothing Then Dim boolType = Me.DeclaringCompilation.GetSpecialType(SpecialType.System_Boolean) Debug.Assert(boolType.GetUseSiteInfo().DiagnosticInfo Is Nothing, "Use site errors should have been checked ahead of time (type bool).") Dim typedConstantTrue = New TypedConstant(boolType, TypedConstantKind.Primitive, True) AddSynthesizedAttribute(attributes, DeclaringCompilation.TrySynthesizeAttribute( WellKnownMember.System_Runtime_CompilerServices_RuntimeCompatibilityAttribute__ctor, ImmutableArray(Of TypedConstant).Empty, ImmutableArray.Create(New KeyValuePair(Of WellKnownMember, TypedConstant)( WellKnownMember.System_Runtime_CompilerServices_RuntimeCompatibilityAttribute__WrapNonExceptionThrows, typedConstantTrue)))) End If End If ' Synthesize DebuggableAttribute only if all the following requirements are met: ' (a) We are not building a netmodule. ' (b) We are emitting debug information (full or pdbonly). ' (c) There is no applied DebuggableAttribute assembly attribute in source. ' (d) There is no applied DebuggableAttribute module attribute in source (NOTE: Native C# compiler and Roslyn C# compiler doesn't check this). If Not isBuildingNetModule AndAlso Not Me.HasAssemblyOrModuleDebuggableAttribute Then ' Synthesize attribute: <DebuggableAttribute(DebuggableAttribute.DebuggingMode.<Value>)> Dim int32Type = Me.DeclaringCompilation.GetSpecialType(SpecialType.System_Int32) If int32Type.GetUseSiteInfo().DiagnosticInfo Is Nothing Then Dim debuggingMode = DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints ' Since .NET 2.0 the combinations of None, Default And DisableOptimizations have the following effect ' ' None JIT optimizations enabled ' Default JIT optimizations enabled ' DisableOptimizations JIT optimizations enabled ' Default | DisableOptimizations JIT optimizations disabled If options.OptimizationLevel = OptimizationLevel.Debug Then debuggingMode = debuggingMode Or DebuggableAttribute.DebuggingModes.Default Or DebuggableAttribute.DebuggingModes.DisableOptimizations End If If options.EnableEditAndContinue Then debuggingMode = debuggingMode Or DebuggableAttribute.DebuggingModes.EnableEditAndContinue End If Dim typedConstantDebugMode = New TypedConstant(int32Type, TypedConstantKind.Enum, CInt(debuggingMode)) AddSynthesizedAttribute(attributes, DeclaringCompilation.TrySynthesizeAttribute( WellKnownMember.System_Diagnostics_DebuggableAttribute__ctorDebuggingModes, ImmutableArray.Create(typedConstantDebugMode))) End If End If If _compilation.Options.OutputKind = OutputKind.NetModule Then ' If the attribute is applied in source, do not add synthetic one. ' If its value is different from the supplied through options, an error should have been reported by now. If Not String.IsNullOrEmpty(_compilation.Options.CryptoKeyContainer) AndAlso AssemblyKeyContainerAttributeSetting Is CommonAssemblyWellKnownAttributeData.StringMissingValue Then Dim stringType = _compilation.GetSpecialType(SpecialType.System_String) Debug.Assert(stringType.GetUseSiteInfo.DiagnosticInfo Is Nothing, "Use site errors should have been checked ahead of time (type string).") Dim typedConstant = New TypedConstant(stringType, TypedConstantKind.Primitive, _compilation.Options.CryptoKeyContainer) AddSynthesizedAttribute(attributes, _compilation.TrySynthesizeAttribute(WellKnownMember.System_Reflection_AssemblyKeyNameAttribute__ctor, ImmutableArray.Create(typedConstant))) End If If Not String.IsNullOrEmpty(_compilation.Options.CryptoKeyFile) AndAlso AssemblyKeyFileAttributeSetting Is CommonAssemblyWellKnownAttributeData.StringMissingValue Then Dim stringType = _compilation.GetSpecialType(SpecialType.System_String) Debug.Assert(stringType.GetUseSiteInfo.DiagnosticInfo Is Nothing, "Use site errors should have been checked ahead of time (type string).") Dim typedConstant = New TypedConstant(stringType, TypedConstantKind.Primitive, _compilation.Options.CryptoKeyFile) AddSynthesizedAttribute(attributes, _compilation.TrySynthesizeAttribute(WellKnownMember.System_Reflection_AssemblyKeyFileAttribute__ctor, ImmutableArray.Create(typedConstant))) End If End If End Sub Friend Overrides ReadOnly Property PublicKey As ImmutableArray(Of Byte) Get Return StrongNameKeys.PublicKey End Get End Property Friend Overrides Function AreInternalsVisibleToThisAssembly(potentialGiverOfAccess As AssemblySymbol) As Boolean ' Ensure that optimistic IVT access is only granted to requests that originated on the thread ' that is trying to compute the assembly identity. This gives us deterministic behavior when ' two threads are checking IVT access but only one of them is in the process of computing identity. 'as an optimization confirm that the identity has not yet been computed to avoid testing TLS If _lazyStrongNameKeys Is Nothing Then Dim assemblyWhoseKeysAreBeingComputed = s_AssemblyForWhichCurrentThreadIsComputingKeys If assemblyWhoseKeysAreBeingComputed IsNot Nothing Then Debug.Assert(assemblyWhoseKeysAreBeingComputed Is Me) If Not potentialGiverOfAccess.GetInternalsVisibleToPublicKeys(Me.Name).IsEmpty() Then If _optimisticallyGrantedInternalsAccess Is Nothing Then Interlocked.CompareExchange(_optimisticallyGrantedInternalsAccess, New ConcurrentDictionary(Of AssemblySymbol, Boolean), Nothing) End If _optimisticallyGrantedInternalsAccess.TryAdd(potentialGiverOfAccess, True) Return True Else Return False End If End If End If Dim conclusion As IVTConclusion = MakeFinalIVTDetermination(potentialGiverOfAccess, assertUnexpectedGiver:=True) Return conclusion = IVTConclusion.Match ' Note that C#, for error recovery, includes OrElse conclusion = IVTConclusion.OneSignedOneNot End Function Friend ReadOnly Property StrongNameKeys As StrongNameKeys Get If _lazyStrongNameKeys Is Nothing Then Try Debug.Assert(s_AssemblyForWhichCurrentThreadIsComputingKeys Is Nothing) s_AssemblyForWhichCurrentThreadIsComputingKeys = Me ComputeAndSetStrongNameKeys() Finally s_AssemblyForWhichCurrentThreadIsComputingKeys = Nothing End Try End If Return _lazyStrongNameKeys End Get End Property Private Sub ComputeAndSetStrongNameKeys() ' TODO ' In order to allow users to escape problems that we create with our provisional granting of IVT access, ' consider not binding the attributes if the command line options were specified, then later bind them ' and report warnings if both were used. ' make sure keycontainer and keyfile attribute contents fields will be set EnsureAttributesAreBound() ' Creating strong names is a potentially expensive operation, so we will check ' if keys could have been created and published already. If _lazyStrongNameKeys IsNot Nothing Then Return End If Dim keys As StrongNameKeys Dim keyFile As String = _compilation.Options.CryptoKeyFile ' Public sign requires a keyfile If DeclaringCompilation.Options.PublicSign Then If Not String.IsNullOrEmpty(keyFile) AndAlso Not PathUtilities.IsAbsolute(keyFile) Then ' If keyFile has a relative path then there should be a diagnostic ' about it Debug.Assert(Not DeclaringCompilation.Options.Errors.IsEmpty) keys = StrongNameKeys.None Else keys = StrongNameKeys.Create(keyFile, MessageProvider.Instance) End If ' Public signing doesn't require a strong name provider to be used. Interlocked.CompareExchange(_lazyStrongNameKeys, keys, Nothing) Return End If ' when both attributes and command-line options specified, cmd line wins. If String.IsNullOrEmpty(keyFile) Then keyFile = Me.AssemblyKeyFileAttributeSetting If keyFile Is CommonAssemblyWellKnownAttributeData.StringMissingValue Then keyFile = Nothing End If End If Dim keyContainer As String = _compilation.Options.CryptoKeyContainer If String.IsNullOrEmpty(keyContainer) Then keyContainer = Me.AssemblyKeyContainerAttributeSetting If keyContainer Is CommonAssemblyWellKnownAttributeData.StringMissingValue Then keyContainer = Nothing End If End If Dim hasCounterSignature = Not String.IsNullOrEmpty(SignatureKey) keys = StrongNameKeys.Create(DeclaringCompilation.Options.StrongNameProvider, keyFile, keyContainer, hasCounterSignature, MessageProvider.Instance) Interlocked.CompareExchange(_lazyStrongNameKeys, keys, Nothing) End Sub Private Function ComputeIdentity() As AssemblyIdentity EnsureAttributesAreBound() Return New AssemblyIdentity(_assemblySimpleName, VersionHelper.GenerateVersionFromPatternAndCurrentTime(_compilation.Options.CurrentLocalTime, AssemblyVersionAttributeSetting), Me.AssemblyCultureAttributeSetting, StrongNameKeys.PublicKey, hasPublicKey:=Not StrongNameKeys.PublicKey.IsDefault, isRetargetable:=(AssemblyFlags And AssemblyFlags.Retargetable) = AssemblyFlags.Retargetable) End Function Friend ReadOnly Property IsVbRuntime As Boolean Get If Me._lazyIsVbRuntime = ThreeState.Unknown Then Me._lazyIsVbRuntime = CheckForRuntime().ToThreeState End If Return Me._lazyIsVbRuntime = ThreeState.True End Get End Property Private Function CheckForRuntime() As Boolean Dim stdmodule = Me.DeclaringCompilation.GetWellKnownType(WellKnownType.Microsoft_VisualBasic_CompilerServices_StandardModuleAttribute) Return Not stdmodule.IsErrorType AndAlso Not stdmodule.IsEmbedded AndAlso stdmodule.ContainingAssembly Is Me End Function Friend Overrides Function TryLookupForwardedMetadataTypeWithCycleDetection(ByRef emittedName As MetadataTypeName, visitedAssemblies As ConsList(Of AssemblySymbol), ignoreCase As Boolean) As NamedTypeSymbol If Not _compilation.Options.OutputKind.IsNetModule() Then ' See if any of added modules forward the type. Dim matchedName As String = Nothing ' Similar to attributes, type forwarders from the second added module should override type forwarders from the first added module, etc. For i As Integer = _modules.Length - 1 To 1 Step -1 Dim peModuleSymbol = DirectCast(_modules(i), PEModuleSymbol) Dim forwardedToAssemblies = peModuleSymbol.GetAssembliesForForwardedType(emittedName, ignoreCase, matchedName) If forwardedToAssemblies.FirstSymbol IsNot Nothing Then If forwardedToAssemblies.SecondSymbol IsNot Nothing Then Return CreateMultipleForwardingErrorTypeSymbol(emittedName, peModuleSymbol, forwardedToAssemblies.FirstSymbol, forwardedToAssemblies.SecondSymbol) End If ' Don't bother to check the forwarded-to assembly if we've already seen it. If visitedAssemblies IsNot Nothing AndAlso visitedAssemblies.Contains(forwardedToAssemblies.FirstSymbol) Then Return CreateCycleInTypeForwarderErrorTypeSymbol(emittedName) Else visitedAssemblies = New ConsList(Of AssemblySymbol)(Me, If(visitedAssemblies, ConsList(Of AssemblySymbol).Empty)) If ignoreCase AndAlso Not String.Equals(emittedName.FullName, matchedName, StringComparison.Ordinal) Then emittedName = MetadataTypeName.FromFullName(matchedName, emittedName.UseCLSCompliantNameArityEncoding, emittedName.ForcedArity) End If Return forwardedToAssemblies.FirstSymbol.LookupDeclaredOrForwardedTopLevelMetadataType(emittedName, visitedAssemblies) End If End If Next End If Return Nothing End Function Public Overrides Function GetMetadata() As AssemblyMetadata Return Nothing End Function Private ReadOnly Property ISourceAssemblySymbol_Compilation As Compilation Implements ISourceAssemblySymbol.Compilation Get Return _compilation End Get End Property Friend Overrides ReadOnly Property ObsoleteAttributeData As ObsoleteAttributeData Get ' <assembly: Experimental> may have been specified in the assembly or one of the modules Dim attributesBag As CustomAttributesBag(Of VisualBasicAttributeData) = Me._lazySourceAttributesBag If attributesBag IsNot Nothing AndAlso attributesBag.IsDecodedWellKnownAttributeDataComputed Then Dim experimentalData = DirectCast(attributesBag.DecodedWellKnownAttributeData, CommonAssemblyWellKnownAttributeData)?.ExperimentalAttributeData If experimentalData IsNot Nothing Then Return experimentalData End If End If attributesBag = Me._lazyNetModuleAttributesBag If attributesBag IsNot Nothing AndAlso attributesBag.IsDecodedWellKnownAttributeDataComputed Then Return DirectCast(attributesBag.DecodedWellKnownAttributeData, CommonAssemblyWellKnownAttributeData)?.ExperimentalAttributeData End If If GetAttributeDeclarations().IsEmpty Then Return Nothing End If Return ObsoleteAttributeData.Uninitialized End Get End Property End Class End Namespace