| File: Symbols\MetadataOrSourceAssemblySymbol.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.Concurrent; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; using System.Linq; using System.Threading; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp.Symbols { /// <summary> /// Represents source or metadata assembly. /// </summary> internal abstract class MetadataOrSourceAssemblySymbol : MetadataOrSourceOrRetargetingAssemblySymbol { /// <summary> /// An array of cached Cor types defined in this assembly. /// Lazily filled by GetDeclaredSpecialType method. /// </summary> private NamedTypeSymbol[] _lazySpecialTypes; private TypeConversions _lazyTypeConversions; /// <summary> /// How many Cor types have we cached so far. /// </summary> private int _cachedSpecialTypes; private NativeIntegerTypeSymbol[] _lazyNativeIntegerTypes; #nullable enable /// <summary> /// Lookup declaration for predefined CorLib type in this Assembly. /// </summary> /// <param name="type"></param> /// <returns></returns> internal sealed override NamedTypeSymbol GetDeclaredSpecialType(ExtendedSpecialType type) { #if DEBUG foreach (var module in this.Modules) { Debug.Assert(module.GetReferencedAssemblies().Length == 0); } #endif if (_lazySpecialTypes == null || (object)_lazySpecialTypes[(int)type] == null) { MetadataTypeName emittedName = MetadataTypeName.FromFullName(type.GetMetadataName(), useCLSCompliantNameArityEncoding: true); ModuleSymbol module = this.Modules[0]; NamedTypeSymbol? result = module.LookupTopLevelMetadataType(ref emittedName); Debug.Assert(result?.IsErrorType() != true); if (result is null || result.DeclaredAccessibility != Accessibility.Public) { result = new MissingMetadataTypeSymbol.TopLevel(module, ref emittedName, type); } RegisterDeclaredSpecialType(result); } Debug.Assert(_lazySpecialTypes is not null); return _lazySpecialTypes[(int)type]; } #nullable disable /// <summary> /// Register declaration of predefined CorLib type in this Assembly. /// </summary> /// <param name="corType"></param> internal sealed override void RegisterDeclaredSpecialType(NamedTypeSymbol corType) { ExtendedSpecialType typeId = corType.ExtendedSpecialType; Debug.Assert(typeId != SpecialType.None); Debug.Assert(ReferenceEquals(corType.ContainingAssembly, this)); Debug.Assert(corType.ContainingModule.Ordinal == 0); Debug.Assert(ReferenceEquals(this.CorLibrary, this)); if (_lazySpecialTypes == null) { Interlocked.CompareExchange(ref _lazySpecialTypes, new NamedTypeSymbol[(int)InternalSpecialType.NextAvailable], null); } if ((object)Interlocked.CompareExchange(ref _lazySpecialTypes[(int)typeId], corType, null) != null) { Debug.Assert(ReferenceEquals(corType, _lazySpecialTypes[(int)typeId]) || (corType.Kind == SymbolKind.ErrorType && _lazySpecialTypes[(int)typeId].Kind == SymbolKind.ErrorType)); } else { Interlocked.Increment(ref _cachedSpecialTypes); Debug.Assert(_cachedSpecialTypes > 0 && _cachedSpecialTypes < (int)InternalSpecialType.NextAvailable); } } /// <summary> /// Continue looking for declaration of predefined CorLib type in this Assembly /// while symbols for new type declarations are constructed. /// </summary> internal override bool KeepLookingForDeclaredSpecialTypes { get { return ReferenceEquals(this.CorLibrary, this) && _cachedSpecialTypes < (int)InternalSpecialType.NextAvailable - 1; } } private ICollection<string> _lazyTypeNames; private ICollection<string> _lazyNamespaceNames; public override ICollection<string> TypeNames { get { if (_lazyTypeNames == null) { Interlocked.CompareExchange(ref _lazyTypeNames, UnionCollection<string>.Create(this.Modules, m => m.TypeNames), null); } return _lazyTypeNames; } } internal sealed override NamedTypeSymbol GetNativeIntegerType(NamedTypeSymbol underlyingType) { Debug.Assert(!underlyingType.IsNativeIntegerType); if (_lazyNativeIntegerTypes == null) { Interlocked.CompareExchange(ref _lazyNativeIntegerTypes, new NativeIntegerTypeSymbol[2], null); } int index = underlyingType.SpecialType switch { SpecialType.System_IntPtr => 0, SpecialType.System_UIntPtr => 1, _ => throw ExceptionUtilities.UnexpectedValue(underlyingType.SpecialType), }; if (_lazyNativeIntegerTypes[index] is null) { Interlocked.CompareExchange(ref _lazyNativeIntegerTypes[index], new NativeIntegerTypeSymbol(underlyingType), null); } return _lazyNativeIntegerTypes[index]; } public override ICollection<string> NamespaceNames { get { if (_lazyNamespaceNames == null) { Interlocked.CompareExchange(ref _lazyNamespaceNames, UnionCollection<string>.Create(this.Modules, m => m.NamespaceNames), null); } return _lazyNamespaceNames; } } /// <summary> /// Not yet known value is represented by ErrorTypeSymbol.UnknownResultType /// </summary> private Symbol[] _lazySpecialTypeMembers; /// <summary> /// Lookup member declaration in predefined CorLib type in this Assembly. Only valid if this /// assembly is the Cor Library /// </summary> internal override Symbol GetDeclaredSpecialTypeMember(SpecialMember member) { #if DEBUG foreach (var module in this.Modules) { Debug.Assert(module.GetReferencedAssemblies().Length == 0); } #endif if (_lazySpecialTypeMembers == null || ReferenceEquals(_lazySpecialTypeMembers[(int)member], ErrorTypeSymbol.UnknownResultType)) { if (_lazySpecialTypeMembers == null) { var specialTypeMembers = new Symbol[(int)SpecialMember.Count]; for (int i = 0; i < specialTypeMembers.Length; i++) { specialTypeMembers[i] = ErrorTypeSymbol.UnknownResultType; } Interlocked.CompareExchange(ref _lazySpecialTypeMembers, specialTypeMembers, null); } var descriptor = SpecialMembers.GetDescriptor(member); NamedTypeSymbol type = GetDeclaredSpecialType(descriptor.DeclaringSpecialType); Symbol result = null; if (!type.IsErrorType()) { result = CSharpCompilation.GetRuntimeMember(type, descriptor, CSharpCompilation.SpecialMembersSignatureComparer.Instance, accessWithinOpt: null); } Interlocked.CompareExchange(ref _lazySpecialTypeMembers[(int)member], result, ErrorTypeSymbol.UnknownResultType); } return _lazySpecialTypeMembers[(int)member]; } internal sealed override TypeConversions TypeConversions { get { if (this != CorLibrary) { return CorLibrary.TypeConversions; } if (_lazyTypeConversions is null) { Interlocked.CompareExchange(ref _lazyTypeConversions, new TypeConversions(this), null); } return _lazyTypeConversions; } } } }