| File: Symbols\NonMissingModuleSymbol.cs | Web Access |
| Project: src\roslyn\src\Compilers\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.csproj (Microsoft.CodeAnalysis.CSharp) |
// 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.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp.Symbols { /// <summary> /// A <see cref="NonMissingModuleSymbol"/> is a special kind of <see cref="ModuleSymbol"/> that represents /// a module that is not missing, i.e. the "real" thing. /// </summary> internal abstract class NonMissingModuleSymbol : ModuleSymbol { /// <summary> /// An array of <see cref="AssemblySymbol"/> objects corresponding to assemblies directly referenced by this module. /// </summary> /// <remarks> /// The contents are provided by ReferenceManager and may not be modified. /// </remarks> private ModuleReferences<AssemblySymbol> _moduleReferences; /// <summary> /// Does this symbol represent a missing module. /// </summary> internal sealed override bool IsMissing { get { return false; } } /// <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. /// </summary> internal sealed override ImmutableArray<AssemblyIdentity> GetReferencedAssemblies() { AssertReferencesInitialized(); return _moduleReferences.Identities; } /// <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. /// </summary> internal sealed override ImmutableArray<AssemblySymbol> GetReferencedAssemblySymbols() { AssertReferencesInitialized(); return _moduleReferences.Symbols; } internal ImmutableArray<UnifiedAssembly<AssemblySymbol>> GetUnifiedAssemblies() { AssertReferencesInitialized(); return _moduleReferences.UnifiedAssemblies; } internal override bool HasUnifiedReferences { get { return GetUnifiedAssemblies().Length > 0; } } internal override bool GetUnificationUseSiteDiagnostic(ref DiagnosticInfo result, TypeSymbol dependentType) { AssertReferencesInitialized(); var ownerModule = this; var ownerAssembly = ownerModule.ContainingAssembly; var dependentAssembly = dependentType.ContainingAssembly; if (ownerAssembly == dependentAssembly) { return false; } // TODO (tomat): we should report an error/warning for all unified references, not just the first one. foreach (var unifiedAssembly in GetUnifiedAssemblies()) { if (!ReferenceEquals(unifiedAssembly.TargetAssembly, dependentAssembly)) { continue; } var referenceId = unifiedAssembly.OriginalReference; var definitionId = dependentAssembly.Identity; var involvedAssemblies = ImmutableArray.Create<Symbol>(ownerAssembly, dependentAssembly); DiagnosticInfo info; if (definitionId.Version > referenceId.Version) { // unified with a definition whose version is higher than the reference ErrorCode warning = (definitionId.Version.Major == referenceId.Version.Major && definitionId.Version.Minor == referenceId.Version.Minor) ? ErrorCode.WRN_UnifyReferenceBldRev : ErrorCode.WRN_UnifyReferenceMajMin; // warning: Assuming assembly reference '{0}' used by '{1}' matches identity '{2}' of '{3}', you may need to supply runtime policy. info = new CSDiagnosticInfo( warning, new object[] { referenceId.GetDisplayName(), ownerAssembly.Name, // TODO (tomat): should rather be MetadataReference.Display for the corresponding reference definitionId.GetDisplayName(), dependentAssembly.Name }, involvedAssemblies, ImmutableArray<Location>.Empty); } else { // unified with a definition whose version is lower than the reference // error: Assembly '{0}' with identity '{1}' uses '{2}' which has a higher version than referenced assembly '{3}' with identity '{4}' info = new CSDiagnosticInfo( ErrorCode.ERR_AssemblyMatchBadVersion, new object[] { ownerAssembly.Name, // TODO (tomat): should rather be MetadataReference.Display for the corresponding reference ownerAssembly.Identity.GetDisplayName(), referenceId.GetDisplayName(), dependentAssembly.Name, // TODO (tomat): should rather be MetadataReference.Display for the corresponding reference definitionId.GetDisplayName() }, involvedAssemblies, ImmutableArray<Location>.Empty); } if (MergeUseSiteDiagnostics(ref result, info)) { return true; } } return false; } /// <summary> /// A helper method for ReferenceManager to set assembly identities for assemblies /// referenced by this module and corresponding AssemblySymbols. /// </summary> internal override void SetReferences(ModuleReferences<AssemblySymbol> moduleReferences, SourceAssemblySymbol originatingSourceAssemblyDebugOnly = null) { Debug.Assert(moduleReferences != null); AssertReferencesUninitialized(); _moduleReferences = moduleReferences; } [Conditional("DEBUG")] internal void AssertReferencesUninitialized() { Debug.Assert(_moduleReferences == null); } [Conditional("DEBUG")] internal void AssertReferencesInitialized() { Debug.Assert(_moduleReferences != null); } #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 sealed override NamedTypeSymbol? LookupTopLevelMetadataType(ref MetadataTypeName emittedName) { NamedTypeSymbol? result; NamespaceSymbol? scope = this.GlobalNamespace.LookupNestedNamespace(emittedName.NamespaceSegmentsMemory); if ((object?)scope == null) { // We failed to locate the namespace result = null; } else { result = scope.LookupMetadataType(ref emittedName); } Debug.Assert(result?.IsErrorType() != true); return result; } } }