|
// 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.
#nullable disable
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Reflection;
using System.Reflection.PortableExecutable;
using System.Runtime.InteropServices;
using Microsoft.CodeAnalysis.Symbols;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.Symbols
{
/// <summary>
/// Represents a module within an assembly. Every assembly contains one or more modules.
/// </summary>
internal abstract class ModuleSymbol : Symbol, IModuleSymbolInternal
{
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Changes to the public interface of this class should remain synchronized with the VB version.
// Do not make any changes to the public interface without making the corresponding change
// to the VB version.
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
/// <summary>
/// Returns a NamespaceSymbol representing the global (root) namespace, with
/// module extent, that can be used to browse all of the symbols defined in this module.
/// </summary>
public abstract NamespaceSymbol GlobalNamespace { get; }
/// <summary>
/// Returns the containing assembly. Modules are always directly contained by an assembly,
/// so this property always returns the same as ContainingSymbol.
/// </summary>
public override AssemblySymbol ContainingAssembly
{
get
{
return (AssemblySymbol)ContainingSymbol;
}
}
internal sealed override ModuleSymbol ContainingModule
{
get
{
return null;
}
}
/// <summary>
/// Returns value 'NetModule' of the <see cref="SymbolKind"/>
/// </summary>
public sealed override SymbolKind Kind
{
get
{
return SymbolKind.NetModule;
}
}
internal override TResult Accept<TArgument, TResult>(CSharpSymbolVisitor<TArgument, TResult> visitor, TArgument argument)
{
return visitor.VisitModule(this, argument);
}
public override void Accept(CSharpSymbolVisitor visitor)
{
visitor.VisitModule(this);
}
public override TResult Accept<TResult>(CSharpSymbolVisitor<TResult> visitor)
{
return visitor.VisitModule(this);
}
// Only the compiler can create ModuleSymbols.
internal ModuleSymbol()
{
}
/// <summary>
/// Module's ordinal within containing assembly's Modules array.
/// 0 - for a source module, etc.
/// -1 - for a module that doesn't have containing assembly, or has it, but is not part of Modules array.
/// </summary>
internal abstract int Ordinal { get; }
/// <summary>
/// Target architecture of the machine.
/// </summary>
internal abstract Machine Machine { get; }
/// <summary>
/// Indicates that this PE file makes Win32 calls. See CorPEKind.pe32BitRequired for more information (http://msdn.microsoft.com/en-us/library/ms230275.aspx).
/// </summary>
internal abstract bool Bit32Required { get; }
/// <summary>
/// Does this symbol represent a missing module.
/// </summary>
internal abstract bool IsMissing
{
get;
}
/// <summary>
/// Returns 'NotApplicable'
/// </summary>
public sealed override Accessibility DeclaredAccessibility
{
get
{
return Accessibility.NotApplicable;
}
}
/// <summary>
/// Returns false because module can't be declared as 'static'.
/// </summary>
public sealed override bool IsStatic
{
get
{
return false;
}
}
/// <summary>
/// Returns false because module can't be virtual.
/// </summary>
public sealed override bool IsVirtual
{
get
{
return false;
}
}
/// <summary>
/// Returns false because module can't be overridden.
/// </summary>
public sealed override bool IsOverride
{
get
{
return false;
}
}
/// <summary>
/// Returns false because module can't be abstract.
/// </summary>
public sealed override bool IsAbstract
{
get
{
return false;
}
}
/// <summary>
/// Returns false because module can't be sealed.
/// </summary>
public sealed override bool IsSealed
{
get
{
return false;
}
}
/// <summary>
/// Returns false because module can't be defined externally.
/// </summary>
public sealed override bool IsExtern
{
get
{
return false;
}
}
public override ImmutableArray<SyntaxReference> DeclaringSyntaxReferences
{
get
{
return ImmutableArray<SyntaxReference>.Empty;
}
}
/// <summary>
/// Returns an array of assembly identities for assemblies referenced by this module.
/// Items at the same position from ReferencedAssemblies and from ReferencedAssemblySymbols
/// correspond to each other.
/// </summary>
public ImmutableArray<AssemblyIdentity> ReferencedAssemblies
{
get
{
return GetReferencedAssemblies();
}
}
/// <summary>
/// Returns an array of assembly identities for assemblies referenced by this module.
/// Items at the same position from GetReferencedAssemblies and from GetReferencedAssemblySymbols
/// should correspond to each other.
///
/// The array and its content is provided by ReferenceManager and must not be modified.
/// </summary>
/// <returns></returns>
internal abstract ImmutableArray<AssemblyIdentity> GetReferencedAssemblies(); // TODO: Remove this method and make ReferencedAssemblies property abstract instead.
/// <summary>
/// Returns an array of AssemblySymbol objects corresponding to assemblies referenced
/// by this module. Items at the same position from ReferencedAssemblies and
/// from ReferencedAssemblySymbols correspond to each other.
/// </summary>
public ImmutableArray<AssemblySymbol> ReferencedAssemblySymbols
{
get
{
return GetReferencedAssemblySymbols();
}
}
/// <summary>
/// Returns an array of AssemblySymbol objects corresponding to assemblies referenced
/// by this module. Items at the same position from GetReferencedAssemblies and
/// from GetReferencedAssemblySymbols should correspond to each other. If reference is
/// not resolved by compiler, GetReferencedAssemblySymbols returns MissingAssemblySymbol in the
/// corresponding item.
///
/// The array and its content is provided by ReferenceManager and must not be modified.
/// </summary>
internal abstract ImmutableArray<AssemblySymbol> GetReferencedAssemblySymbols(); // TODO: Remove this method and make ReferencedAssemblySymbols property abstract instead.
internal AssemblySymbol GetReferencedAssemblySymbol(int referencedAssemblyIndex)
{
var referencedAssemblies = GetReferencedAssemblySymbols();
if (referencedAssemblyIndex < referencedAssemblies.Length)
{
return referencedAssemblies[referencedAssemblyIndex];
}
// This module must be a corlib where the original metadata contains assembly
// references (see https://github.com/dotnet/roslyn/issues/13275).
var assembly = ContainingAssembly;
if ((object)assembly != assembly.CorLibrary)
{
throw new ArgumentOutOfRangeException(nameof(referencedAssemblyIndex));
}
return null;
}
/// <summary>
/// A helper method for ReferenceManager to set assembly identities for assemblies
/// referenced by this module and corresponding AssemblySymbols.
/// </summary>
/// <param name="moduleReferences">A description of the assemblies referenced by this module.</param>
/// <param name="originatingSourceAssemblyDebugOnly">
/// Source assembly that triggered creation of this module symbol.
/// For debug purposes only, this assembly symbol should not be persisted within
/// this module symbol because the module can be shared across multiple source
/// assemblies. This method will only be called for the first one.
/// </param>
internal abstract void SetReferences(ModuleReferences<AssemblySymbol> moduleReferences, SourceAssemblySymbol originatingSourceAssemblyDebugOnly = null);
/// <summary>
/// True if this module has any unified references.
/// </summary>
internal abstract bool HasUnifiedReferences { get; }
/// <summary>
/// Returns a unification use-site error (if any) for a symbol contained in this module
/// that is referring to a specified <paramref name="dependentType"/>.
/// </summary>
/// <remarks>
/// If an assembly referenced by this module isn't exactly matching any reference given to compilation
/// the Assembly Manager might decide to use another reference if it matches except for version
/// (it unifies the version with the existing reference).
/// </remarks>
internal abstract bool GetUnificationUseSiteDiagnostic(ref DiagnosticInfo result, TypeSymbol dependentType);
#nullable enable
/// <summary>
/// Lookup a top level type referenced from metadata, names should be
/// compared case-sensitively.
/// </summary>
/// <param name="emittedName">
/// Full type name, possibly with generic name mangling.
/// </param>
/// <returns>
/// Symbol for the type, or null if the type isn't found.
/// </returns>
/// <remarks></remarks>
internal abstract NamedTypeSymbol? LookupTopLevelMetadataType(ref MetadataTypeName emittedName);
#nullable disable
internal abstract ICollection<string> TypeNames { get; }
internal abstract ICollection<string> NamespaceNames { get; }
/// <summary>
/// Returns true if there is any applied CompilationRelaxationsAttribute assembly attribute for this module.
/// </summary>
internal abstract bool HasAssemblyCompilationRelaxationsAttribute { get; }
/// <summary>
/// Returns true if there is any applied RuntimeCompatibilityAttribute assembly attribute for this module.
/// </summary>
internal abstract bool HasAssemblyRuntimeCompatibilityAttribute { get; }
internal abstract bool UseUpdatedEscapeRules { get; }
/// <summary>
/// Default char set for contained types, or null if not specified.
/// </summary>
internal abstract CharSet? DefaultMarshallingCharSet { get; }
internal virtual ImmutableArray<byte> GetHash(AssemblyHashAlgorithm algorithmId)
{
throw ExceptionUtilities.Unreachable();
}
/// <summary>
/// Given a namespace symbol, returns the corresponding module specific namespace symbol
/// </summary>
public NamespaceSymbol GetModuleNamespace(INamespaceSymbol namespaceSymbol)
{
if (namespaceSymbol == null)
{
throw new ArgumentNullException(nameof(namespaceSymbol));
}
if (namespaceSymbol.NamespaceKind == NamespaceKind.Module)
{
var moduleNs = (namespaceSymbol as PublicModel.NamespaceSymbol)?.UnderlyingNamespaceSymbol;
if ((object)moduleNs != null && moduleNs.ContainingModule == this)
{
// this is already the correct module namespace
return moduleNs;
}
}
if (namespaceSymbol.IsGlobalNamespace || (object)namespaceSymbol.ContainingNamespace == null)
{
return this.GlobalNamespace;
}
else
{
var cns = GetModuleNamespace(namespaceSymbol.ContainingNamespace);
if ((object)cns != null)
{
return cns.GetNestedNamespace(namespaceSymbol.Name);
}
return null;
}
}
/// <summary>
/// Given a namespace symbol, returns the corresponding module specific namespace symbol
/// </summary>
public NamespaceSymbol GetModuleNamespace(NamespaceSymbol namespaceSymbol)
{
if (namespaceSymbol == null)
{
throw new ArgumentNullException(nameof(namespaceSymbol));
}
if (namespaceSymbol.Extent.Kind == NamespaceKind.Module && namespaceSymbol.ContainingModule == this)
{
// this is already the correct module namespace
return namespaceSymbol;
}
if (namespaceSymbol.IsGlobalNamespace || (object)namespaceSymbol.ContainingNamespace == null)
{
return this.GlobalNamespace;
}
else
{
var cns = GetModuleNamespace(namespaceSymbol.ContainingNamespace);
if ((object)cns != null)
{
return cns.GetNestedNamespace(namespaceSymbol.Name);
}
return null;
}
}
public abstract bool AreLocalsZeroed { get; }
/// <summary>
/// If this symbol represents a metadata module returns the underlying <see cref="ModuleMetadata"/>.
///
/// Otherwise, this returns <see langword="null"/>.
/// </summary>
public abstract ModuleMetadata GetMetadata();
protected override ISymbol CreateISymbol()
{
return new PublicModel.ModuleSymbol(this);
}
}
}
|