Exemplo n.º 1
0
        internal override NamedTypeSymbol TryLookupForwardedMetadataTypeWithCycleDetection(ref MetadataTypeName emittedName, ConsList <AssemblySymbol> visitedAssemblies)
        {
            int forcedArity = emittedName.ForcedArity;

            if (emittedName.UseCLSCompliantNameArityEncoding)
            {
                if (forcedArity == -1)
                {
                    forcedArity = emittedName.InferredArity;
                }
                else if (forcedArity != emittedName.InferredArity)
                {
                    return(null);
                }

                Debug.Assert(forcedArity == emittedName.InferredArity);
            }

            //if (_lazyForwardedTypesFromSource == null)
            //{
            //    IDictionary<string, NamedTypeSymbol> forwardedTypesFromSource;
            //    CommonAssemblyWellKnownAttributeData<NamedTypeSymbol> wellKnownAttributeData = GetSourceDecodedWellKnownAttributeData();

            //    if (wellKnownAttributeData != null && wellKnownAttributeData.ForwardedTypes != null)
            //    {
            //        forwardedTypesFromSource = new Dictionary<string, NamedTypeSymbol>();

            //        foreach (NamedTypeSymbol forwardedType in wellKnownAttributeData.ForwardedTypes)
            //        {
            //            NamedTypeSymbol originalDefinition = forwardedType.OriginalDefinition;
            //            Debug.Assert((object)originalDefinition.ContainingType == null, "How did a nested type get forwarded?");

            //            string fullEmittedName = MetadataHelpers.BuildQualifiedName(originalDefinition.ContainingSymbol.ToDisplayString(SymbolDisplayFormat.QualifiedNameOnlyFormat),
            //                                                                        originalDefinition.MetadataName);
            //            // Since we need to allow multiple constructions of the same generic type at the source
            //            // level, we need to de-dup the original definitions.
            //            forwardedTypesFromSource[fullEmittedName] = originalDefinition;
            //        }
            //    }
            //    else
            //    {
            //        forwardedTypesFromSource = SpecializedCollections.EmptyDictionary<string, NamedTypeSymbol>();
            //    }

            //    _lazyForwardedTypesFromSource = forwardedTypesFromSource;
            //}

            //NamedTypeSymbol result;

            //if (_lazyForwardedTypesFromSource.TryGetValue(emittedName.FullName, out result))
            //{
            //    if ((forcedArity == -1 || result.Arity == forcedArity) &&
            //        (!emittedName.UseCLSCompliantNameArityEncoding || result.Arity == 0 || result.MangleName))
            //    {
            //        return result;
            //    }
            //}
            //else if (!_compilation.Options.OutputKind.IsNetModule())
            //{
            //    // See if any of added modules forward the type.

            //    // Similar to attributes, type forwarders from the second added module should override type forwarders from the first added module, etc.
            //    for (int i = _modules.Length - 1; i > 0; i--)
            //    {
            //        var peModuleSymbol = (Metadata.PE.PEModuleSymbol)_modules[i];

            //        var forwardedToAssembly = peModuleSymbol.GetAssemblyForForwardedType(ref emittedName);
            //        if ((object)forwardedToAssembly != null)
            //        {
            //            // Don't bother to check the forwarded-to assembly if we've already seen it.
            //            if (visitedAssemblies != null && visitedAssemblies.Contains(forwardedToAssembly))
            //            {
            //                return CreateCycleInTypeForwarderErrorTypeSymbol(ref emittedName);
            //            }
            //            else
            //            {
            //                visitedAssemblies = new ConsList<AssemblySymbol>(this, visitedAssemblies ?? ConsList<AssemblySymbol>.Empty);
            //                return forwardedToAssembly.LookupTopLevelMetadataTypeWithCycleDetection(ref emittedName, visitedAssemblies, digThroughForwardedTypes: true);
            //            }
            //        }
            //    }
            //}

            return(null);
        }
 internal override NamedTypeSymbol LookupTopLevelMetadataType(ref MetadataTypeName emittedName)
 {
     return new MissingMetadataTypeSymbol.TopLevel(this, ref emittedName);
 }
Exemplo n.º 3
0
 /// <summary>
 /// If this module forwards the given type to another assembly, return that assembly;
 /// otherwise, return null.
 /// </summary>
 /// <param name="fullName">Type to look up.</param>
 /// <returns>Assembly symbol or null.</returns>
 /// <remarks>
 /// The returned assembly may also forward the type.
 /// </remarks>
 internal AssemblySymbol GetAssemblyForForwardedType(ref MetadataTypeName fullName)
 {
     string matchedName;
     AssemblyReferenceHandle assemblyRef = Module.GetAssemblyForForwardedType(fullName.FullName, ignoreCase: false, matchedName: out matchedName);
     return assemblyRef.IsNil ? null : this.GetReferencedAssemblySymbol(assemblyRef);
 }
 public Nested(NamedTypeSymbol containingType, ref MetadataTypeName emittedName)
     : this(containingType, ref emittedName, emittedName.ForcedArity == -1 || emittedName.ForcedArity == emittedName.InferredArity)
 {
 }
Exemplo n.º 5
0
        internal NamedTypeSymbol LookupMetadataType(ref MetadataTypeName emittedTypeName, out bool isNoPiaLocalType)
        {
            NamedTypeSymbol result = LookupMetadataType(ref emittedTypeName);
            isNoPiaLocalType = false;

            if (result is MissingMetadataTypeSymbol)
            {
                EnsureAllMembersLoaded();
                TypeDefinitionHandle typeDef;

                // See if this is a NoPia local type, which we should unify.
                // Note, VB should use FullName.
                if (_lazyNoPiaLocalTypes != null && _lazyNoPiaLocalTypes.TryGetValue(emittedTypeName.TypeName, out typeDef))
                {
                    result = (NamedTypeSymbol)new MetadataDecoder(ContainingPEModule).GetTypeOfToken(typeDef, out isNoPiaLocalType);
                    Debug.Assert(isNoPiaLocalType);
                }
            }

            return result;
        }
Exemplo n.º 6
0
 internal override NamedTypeSymbol LookupTopLevelMetadataTypeWithCycleDetection(ref MetadataTypeName emittedName, ConsList<AssemblySymbol> visitedAssemblies, bool digThroughForwardedTypes)
 {
     var result = this.moduleSymbol.LookupTopLevelMetadataType(ref emittedName);
     Debug.Assert(result is MissingMetadataTypeSymbol);
     return result;
 }
 public TopLevel(ModuleSymbol module, ref MetadataTypeName fullName, WellKnownType wellKnownType)
     : this(module, ref fullName, (int)wellKnownType)
 {
 }
        /// <summary>
        /// This method handles duplicate types in a few different ways:
        /// - for types before C# 7, the first candidate is returned with a warning
        /// - for types after C# 7, the type is considered missing
        /// - in both cases, when BinderFlags.IgnoreCorLibraryDuplicatedTypes is set, any duplicate coming from corlib will be ignored (ie not count as a duplicate)
        /// </summary>
        internal NamedTypeSymbol GetWellKnownType(WellKnownType type)
        {
            Debug.Assert(type.IsValid());

            bool ignoreCorLibraryDuplicatedTypes = this.Options.TopLevelBinderFlags.Includes(BinderFlags.IgnoreCorLibraryDuplicatedTypes);

            int index = (int)type - (int)WellKnownType.First;

            if (_lazyWellKnownTypes == null || (object)_lazyWellKnownTypes[index] == null)
            {
                if (_lazyWellKnownTypes == null)
                {
                    Interlocked.CompareExchange(ref _lazyWellKnownTypes, new NamedTypeSymbol[(int)WellKnownTypes.Count], null);
                }

                string          mdName   = type.GetMetadataName();
                var             warnings = DiagnosticBag.GetInstance();
                NamedTypeSymbol result;
                (AssemblySymbol, AssemblySymbol)conflicts = default;

                if (IsTypeMissing(type))
                {
                    result = null;
                }
                else
                {
                    // well-known types introduced before CSharp7 allow lookup ambiguity and report a warning
                    DiagnosticBag legacyWarnings = (type <= WellKnownType.CSharp7Sentinel) ? warnings : null;
                    result = this.Assembly.GetTypeByMetadataName(
                        mdName, includeReferences: true, useCLSCompliantNameArityEncoding: true, isWellKnownType: true, conflicts: out conflicts,
                        warnings: legacyWarnings, ignoreCorLibraryDuplicatedTypes: ignoreCorLibraryDuplicatedTypes);
                }

                if ((object)result == null)
                {
                    // TODO: should GetTypeByMetadataName rather return a missing symbol?
                    MetadataTypeName emittedName = MetadataTypeName.FromFullName(mdName, useCLSCompliantNameArityEncoding: true);
                    if (type.IsValueTupleType())
                    {
                        CSDiagnosticInfo errorInfo;
                        if (conflicts.Item1 is null)
                        {
                            Debug.Assert(conflicts.Item2 is null);
                            errorInfo = new CSDiagnosticInfo(ErrorCode.ERR_PredefinedValueTupleTypeNotFound, emittedName.FullName);
                        }
                        else
                        {
                            errorInfo = new CSDiagnosticInfo(ErrorCode.ERR_PredefinedValueTupleTypeAmbiguous3, emittedName.FullName, conflicts.Item1, conflicts.Item2);
                        }

                        result = new MissingMetadataTypeSymbol.TopLevelWithCustomErrorInfo(this.Assembly.Modules[0], ref emittedName, errorInfo, type);
                    }
                    else
                    {
                        result = new MissingMetadataTypeSymbol.TopLevel(this.Assembly.Modules[0], ref emittedName, type);
                    }
                }

                if ((object)Interlocked.CompareExchange(ref _lazyWellKnownTypes[index], result, null) != null)
                {
                    Debug.Assert(
                        TypeSymbol.Equals(result, _lazyWellKnownTypes[index], TypeCompareKind.ConsiderEverything2) || (_lazyWellKnownTypes[index].IsErrorType() && result.IsErrorType())
                        );
                }
                else
                {
                    AdditionalCodegenWarnings.AddRange(warnings);
                }

                warnings.Free();
            }

            return(_lazyWellKnownTypes[index]);
        }
Exemplo n.º 9
0
 /// <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 MissingMetadataSymbol if the type isn't found.
 /// </returns>
 /// <remarks></remarks>
 internal abstract NamedTypeSymbol LookupTopLevelMetadataType(ref MetadataTypeName emittedName);
Exemplo n.º 10
0
        internal NamedTypeSymbol GetTopLevelTypeByMetadataName(
            ref MetadataTypeName metadataName,
            AssemblyIdentity assemblyOpt,
            bool includeReferences,
            bool isWellKnownType,
            DiagnosticBag warnings = null)
        {
            NamedTypeSymbol result;

            // First try this assembly
            result = GetTopLevelTypeByMetadataName(this, ref metadataName, assemblyOpt);

            if (isWellKnownType && !IsValidWellKnownType(result))
            {
                result = null;
            }

            // ignore any types of the same name that might be in referenced assemblies (prefer the current assembly):
            if ((object)result != null || !includeReferences)
            {
                return result;
            }

            Debug.Assert(this is SourceAssemblySymbol,
                "Never include references for a non-source assembly, because they don't know about aliases.");

            // Lookup in references
            foreach (var reference in GetUnaliasedReferencedAssemblies())
            {
                Debug.Assert(!(this is SourceAssemblySymbol && reference.IsMissing)); // Non-source assemblies can have missing references

                NamedTypeSymbol candidate = GetTopLevelTypeByMetadataName(reference, ref metadataName, assemblyOpt);

                if (isWellKnownType && !IsValidWellKnownType(candidate))
                {
                    candidate = null;
                }

                if ((object)candidate == null)
                {
                    continue;
                }

                Debug.Assert(candidate != result);

                if ((object)result != null)
                {
                    // duplicate
                    if (warnings == null)
                    {
                        return null;
                    }
                    else
                    {
                        // The predefined type '{0}' is defined in multiple assemblies in the global alias; using definition from '{1}'
                        warnings.Add(ErrorCode.WRN_MultiplePredefTypes, NoLocation.Singleton, result, result.ContainingAssembly);
                        return result;
                    }
                }

                result = candidate;
            }

            return result;
        }
Exemplo n.º 11
0
 public string Type(MetadataTypeName typeName) => Type(typeName.Name, typeName.GenericArgs);
Exemplo n.º 12
0
        internal void AssertDeclaresType(PEModuleSymbol peModule, WellKnownType type, Accessibility expectedAccessibility)
        {
            var name = MetadataTypeName.FromFullName(type.GetMetadataName());

            Assert.Equal(expectedAccessibility, peModule.LookupTopLevelMetadataType(ref name).DeclaredAccessibility);
        }
Exemplo n.º 13
0
 internal override NamedTypeSymbol LookupMetadataType(ref MetadataTypeName typeName)
 {
     return(this.RetargetingTranslator.Retarget(_underlyingType.LookupMetadataType(ref typeName), RetargetOptions.RetargetPrimitiveTypesByName));
 }
Exemplo n.º 14
0
 public Nested(NamedTypeSymbol containingType, ref MetadataTypeName emittedName)
     : this(containingType, ref emittedName, emittedName.ForcedArity == -1 || emittedName.ForcedArity == emittedName.InferredArity)
 {
 }
 private void CacheTopLevelMetadataType(
     ref MetadataTypeName emittedName,
     NamedTypeSymbol result)
 {
     NamedTypeSymbol result1 = null;
     result1 = this.emittedNameToTypeMap.GetOrAdd(emittedName.ToKey(), result);
     System.Diagnostics.Debug.Assert(result1 == result); // object identity may differ in error cases
 }
Exemplo n.º 16
0
        internal override NamedTypeSymbol TryLookupForwardedMetadataTypeWithCycleDetection(ref MetadataTypeName emittedName, ConsList <AssemblySymbol> visitedAssemblies)
        {
            NamedTypeSymbol underlying = _underlyingAssembly.TryLookupForwardedMetadataType(ref emittedName);

            if ((object)underlying == null)
            {
                return(null);
            }

            return(this.RetargetingTranslator.Retarget(underlying, RetargetOptions.RetargetPrimitiveTypesByName));
        }
Exemplo n.º 17
0
 public TopLevelWithCustomErrorInfo(ModuleSymbol module, ref MetadataTypeName emittedName, DiagnosticInfo errorInfo)
     : base(module, ref emittedName)
 {
     Debug.Assert(errorInfo != null);
     this.errorInfo = errorInfo;
 }
Exemplo n.º 18
0
        /// <summary>
        /// Lookup an immediately nested type referenced from metadata, names should be
        /// compared case-sensitively.
        /// </summary>
        /// <param name="emittedTypeName">
        /// Simple type name, possibly with generic name mangling.
        /// </param>
        /// <returns>
        /// Symbol for the type, or MissingMetadataSymbol if the type isn't found.
        /// </returns>
        internal virtual NamedTypeSymbol LookupMetadataType(ref MetadataTypeName emittedTypeName)
        {
            Debug.Assert(!emittedTypeName.IsNull);

            NamespaceOrTypeSymbol scope = this;

            if (scope.Kind == SymbolKind.ErrorType)
            {
                return(new MissingMetadataTypeSymbol.Nested((NamedTypeSymbol)scope, ref emittedTypeName));
            }

            NamedTypeSymbol namedType = null;

            ImmutableArray <NamedTypeSymbol> namespaceOrTypeMembers;
            bool isTopLevel = scope.IsNamespace;

            //Debug.Assert(!isTopLevel || scope.ToDisplayString(SymbolDisplayFormat.QualifiedNameOnlyFormat) == emittedTypeName.NamespaceName);

            if (emittedTypeName.IsMangled)
            {
                Debug.Assert(!emittedTypeName.UnmangledTypeName.Equals(emittedTypeName.TypeName) && emittedTypeName.InferredArity > 0);

                if (emittedTypeName.ForcedArity == -1 || emittedTypeName.ForcedArity == emittedTypeName.InferredArity)
                {
                    // Let's handle mangling case first.
                    namespaceOrTypeMembers = scope.Kind == SymbolKind.NamedType // we don't have proper namese symbols, only global one so FullName it is
                        ? scope.GetTypeMembers(emittedTypeName.UnmangledTypeName)
                        : scope.GetTypeMembers(emittedTypeName.FullName);

                    foreach (var named in namespaceOrTypeMembers)
                    {
                        if (emittedTypeName.InferredArity == named.Arity && named.MangleName)
                        {
                            if ((object)namedType != null)
                            {
                                namedType = null;
                                break;
                            }

                            namedType = named;
                        }
                    }
                }
            }
            else
            {
                Debug.Assert(ReferenceEquals(emittedTypeName.UnmangledTypeName, emittedTypeName.TypeName) && emittedTypeName.InferredArity == 0);
            }

            // Now try lookup without removing generic arity mangling.
            int forcedArity = emittedTypeName.ForcedArity;

            if (emittedTypeName.UseCLSCompliantNameArityEncoding)
            {
                // Only types with arity 0 are acceptable, we already examined types with mangled names.
                if (emittedTypeName.InferredArity > 0)
                {
                    goto Done;
                }
                else if (forcedArity == -1)
                {
                    forcedArity = 0;
                }
                else if (forcedArity != 0)
                {
                    goto Done;
                }
                else
                {
                    Debug.Assert(forcedArity == emittedTypeName.InferredArity);
                }
            }

            namespaceOrTypeMembers = scope.GetTypeMembers(emittedTypeName.FullName);

            foreach (var named in namespaceOrTypeMembers)
            {
                if (!named.MangleName && (forcedArity == -1 || forcedArity == named.Arity))
                {
                    if ((object)namedType != null)
                    {
                        namedType = null;
                        break;
                    }

                    namedType = named;
                }
            }

Done:
            if ((object)namedType == null)
            {
                return(new MissingMetadataTypeSymbol(emittedTypeName.FullName, emittedTypeName.ForcedArity, emittedTypeName.IsMangled));
                //if (isTopLevel)
                //{
                //    return new MissingMetadataTypeSymbol.TopLevel(scope.ContainingModule, ref emittedTypeName);
                //}
                //else
                //{
                //    return new MissingMetadataTypeSymbol.Nested((NamedTypeSymbol)scope, ref emittedTypeName);
                //}
            }

            return(namedType);
        }
Exemplo n.º 19
0
 public TopLevel(ModuleSymbol module, ref MetadataTypeName fullName)
     : this(module, ref fullName, -1)
 {
 }
Exemplo n.º 20
0
        internal override NamedTypeSymbol TryLookupForwardedMetadataTypeWithCycleDetection(ref MetadataTypeName emittedName, ConsList <AssemblySymbol> visitedAssemblies)
        {
            // Check if it is a forwarded type.
            var forwardedToAssembly = LookupAssemblyForForwardedMetadataType(ref emittedName);

            if ((object)forwardedToAssembly != null)
            {
                // Don't bother to check the forwarded-to assembly if we've already seen it.
                if (visitedAssemblies != null && visitedAssemblies.Contains(forwardedToAssembly))
                {
                    return(CreateCycleInTypeForwarderErrorTypeSymbol(ref emittedName));
                }
                else
                {
                    visitedAssemblies = new ConsList <AssemblySymbol>(this, visitedAssemblies ?? ConsList <AssemblySymbol> .Empty);
                    return(forwardedToAssembly.LookupTopLevelMetadataTypeWithCycleDetection(ref emittedName, visitedAssemblies, digThroughForwardedTypes: true));
                }
            }

            return(null);
        }
Exemplo n.º 21
0
 private TopLevel(ModuleSymbol module, ref MetadataTypeName fullName, bool mangleName)
     : this(module, fullName.NamespaceName,
            mangleName ? fullName.UnmangledTypeName : fullName.TypeName,
            mangleName ? fullName.InferredArity : fullName.ForcedArity,
            mangleName)
 {
 }
Exemplo n.º 22
0
 protected override TypeSymbol LookupNestedTypeDefSymbol(TypeSymbol container, ref MetadataTypeName emittedName)
 {
     return(container.LookupMetadataType(ref emittedName));
 }
Exemplo n.º 23
0
 internal override NamedTypeSymbol TryLookupForwardedMetadataTypeWithCycleDetection(ref MetadataTypeName emittedName, ConsList<AssemblySymbol> visitedAssemblies)
 {
     return null;
 }
Exemplo n.º 24
0
        protected override TypeSymbol LookupTopLevelTypeDefSymbol(int referencedAssemblyIndex, ref MetadataTypeName emittedName)
        {
            var assembly = this.GetAssemblies()[referencedAssemblyIndex];

            return(assembly.LookupTopLevelMetadataType(ref emittedName, digThroughForwardedTypes: true));
        }
        /// <summary>
        /// Look up the assembly to which the given metadata type is forwarded.
        /// </summary>
        /// <param name="emittedName"></param>
        /// <returns>
        /// The assembly to which the given type is forwarded or null, if there isn't one.
        /// </returns>
        /// <remarks>
        /// The returned assembly may also forward the type.
        /// </remarks>
        internal AssemblySymbol LookupAssemblyForForwardedMetadataType(ref MetadataTypeName emittedName)
        {
            // Look in the type forwarders of the primary module of this assembly, clr does not honor type forwarder
            // in non-primary modules.

            // Examine the type forwarders, but only from the primary module.
            return this.PrimaryModule.GetAssemblyForForwardedType(ref emittedName);
        }
Exemplo n.º 26
0
 public string Type(MetadataTypeName typeName, bool includeNested = false)
 {
     return(Type(typeName.Name, typeName.GenericArgs, includeNested: includeNested));
 }
 private MetadataType FindMetadataTypeByMetadataTypeName(List<MetadataType> allTypes,
     MetadataTypeName metadataTypeName)
 {
     if (metadataTypeName == null)
         return null;
     var metaDataType = allTypes.Where(x => x.Name == metadataTypeName.Name &&
                                            x.Namespace == metadataTypeName.Namespace)
         .FirstNonDefault();
     return metaDataType;
 }
Exemplo n.º 28
0
 public string Type(MetadataTypeName typeName)
 {
     return(Type(typeName.Name, typeName.GenericArgs));
 }
Exemplo n.º 29
0
        public MetadataType FindType(MetadataTypeName typeName)
        {
            if (typeName == null)
                return null;

            var foundType = AllTypes
                .FirstOrDefault(x => (typeName.Namespace == null || x.Namespace == typeName.Namespace)
                    && x.Name == typeName.Name
                    && x.GenericArgs.Safe().Count() == typeName.GenericArgs.Safe().Count());

            if (foundType != null)
                return foundType;

            if (typeName.Name == typeof(QueryBase).Name || typeName.Name == typeof(QueryBase<>).Name)
                return CreateType(typeof(QueryBase)); //Properties are on QueryBase


            if (typeName.Name == typeof(AuthUserSession).Name)
                return CreateType(typeof(AuthUserSession));

            return null;
        }
Exemplo n.º 30
0
        protected override TypeSymbol LookupNestedTypeDefSymbol(TypeSymbol container, ref MetadataTypeName emittedName)
        {
            var result = container.LookupMetadataType(ref emittedName);

            Debug.Assert((object)result != null);

            return(result);
        }
        private NamedTypeSymbol LookupTopLevelMetadataTypeInCache(ref MetadataTypeName emittedName)
        {
            NamedTypeSymbol result = null;
            if (this.emittedNameToTypeMap.TryGetValue(emittedName.ToKey(), out result))
            {
                return result;
            }

            return null;
        }
Exemplo n.º 32
0
 /// <summary>
 /// Lookup a type defined in this module.
 /// This method will be called only if the type we are
 /// looking for hasn't been loaded yet. Otherwise, MetadataDecoder
 /// would have found the type in TypeDefRowIdToTypeMap based on its
 /// TypeDef row id.
 /// </summary>
 protected override TypeSymbol LookupTopLevelTypeDefSymbol(ref MetadataTypeName emittedName, out bool isNoPiaLocalType)
 {
     return(moduleSymbol.LookupTopLevelMetadataType(ref emittedName, out isNoPiaLocalType));
 }
        /// <summary>
        /// Lookup a top level type referenced from metadata, names should be
        /// compared case-sensitively.  Detect cycles during lookup.
        /// </summary>
        /// <param name="emittedName">
        /// Full type name, possibly with generic name mangling.
        /// </param>
        /// <param name="visitedAssemblies">
        /// List of assemblies lookup has already visited (since type forwarding can introduce cycles).
        /// </param>
        /// <param name="digThroughForwardedTypes">
        /// Take forwarded types into account.
        /// </param>
        internal sealed override NamedTypeSymbol LookupTopLevelMetadataTypeWithCycleDetection(ref MetadataTypeName emittedName, ConsList<AssemblySymbol> visitedAssemblies, bool digThroughForwardedTypes)
        {
            NamedTypeSymbol result = null;

            // This is a cache similar to the one used by MetaImport::GetTypeByName in native
            // compiler. The difference is that native compiler pre-populates the cache when it
            // loads types. Here we are populating the cache only with things we looked for, so that
            // next time we are looking for the same thing, the lookup is fast. This cache also
            // takes care of TypeForwarders. Gives about 8% win on subsequent lookups in some
            // scenarios.     
            //    
            // CONSIDER !!!
            //
            // However, it is questionable how often subsequent lookup by name  is going to happen.
            // Currently it doesn't happen for TypeDef tokens at all, for TypeRef tokens, the
            // lookup by name is done once and the result is cached. So, multiple lookups by name
            // for the same type are going to happen only in these cases:
            // 1) Resolving GetType() in attribute application, type is encoded by name.
            // 2) TypeRef token isn't reused within the same module, i.e. multiple TypeRefs point to
            //    the same type.
            // 3) Different Module refers to the same type, lookup once per Module (with exception of #2).
            // 4) Multitargeting - retargeting the type to a different version of assembly
            result = LookupTopLevelMetadataTypeInCache(ref emittedName);

            if ((object)result != null)
            {
                // We only cache result equivalent to digging through type forwarders, which
                // might produce an forwarder specific ErrorTypeSymbol. We don't want to 
                // return that error symbol, unless digThroughForwardedTypes is true.
                if (digThroughForwardedTypes || (!result.IsErrorType() && (object)result.ContainingAssembly == (object)this))
                {
                    return result;
                }

                // According to the cache, the type wasn't found, or isn't declared in this assembly (forwarded).
                return new MissingMetadataTypeSymbol.TopLevel(this.Modules[0], ref emittedName);
            }
            else
            {
                // Now we will look for the type in each module of the assembly and pick the first type
                // we find, this is what native VB compiler does.

                var modules = this.Modules;
                var count = modules.Length;
                var i = 0;

                result = modules[i].LookupTopLevelMetadataType(ref emittedName);

                if (result is MissingMetadataTypeSymbol)
                {
                    for (i = 1; i < count; i++)
                    {
                        var newResult = modules[i].LookupTopLevelMetadataType(ref emittedName);

                        // Hold on to the first missing type result, unless we found the type.
                        if (!(newResult is MissingMetadataTypeSymbol))
                        {
                            result = newResult;
                            break;
                        }
                    }
                }

                bool foundMatchInThisAssembly = (i < count);

                Debug.Assert(!foundMatchInThisAssembly || (object)result.ContainingAssembly == (object)this);

                if (!foundMatchInThisAssembly && digThroughForwardedTypes)
                {
                    // We didn't find the type
                    System.Diagnostics.Debug.Assert(result is MissingMetadataTypeSymbol);

                    NamedTypeSymbol forwarded = TryLookupForwardedMetadataTypeWithCycleDetection(ref emittedName, visitedAssemblies);
                    if ((object)forwarded != null)
                    {
                        result = forwarded;
                    }
                }

                System.Diagnostics.Debug.Assert((object)result != null);

                // Add result of the lookup into the cache
                if (digThroughForwardedTypes || foundMatchInThisAssembly)
                {
                    CacheTopLevelMetadataType(ref emittedName, result);
                }

                return result;
            }
        }
Exemplo n.º 34
0
        /// <summary>
        /// Find canonical type for NoPia embedded type.
        /// </summary>
        /// <returns>
        /// Symbol for the canonical type or an ErrorTypeSymbol. Never returns null.
        /// </returns>
        internal static NamedTypeSymbol SubstituteNoPiaLocalType(
            ref MetadataTypeName name,
            bool isInterface,
            TypeSymbol baseType,
            string interfaceGuid,
            string scope,
            string identifier,
            AssemblySymbol referringAssembly)
        {
            NamedTypeSymbol result = null;

            Guid interfaceGuidValue     = new Guid();
            bool haveInterfaceGuidValue = false;
            Guid scopeGuidValue         = new Guid();
            bool haveScopeGuidValue     = false;

            if (isInterface && interfaceGuid != null)
            {
                haveInterfaceGuidValue = Guid.TryParse(interfaceGuid, out interfaceGuidValue);

                if (haveInterfaceGuidValue)
                {
                    // To have consistent errors.
                    scope      = null;
                    identifier = null;
                }
            }

            if (scope != null)
            {
                haveScopeGuidValue = Guid.TryParse(scope, out scopeGuidValue);
            }

            foreach (AssemblySymbol assembly in referringAssembly.GetNoPiaResolutionAssemblies())
            {
                Debug.Assert((object)assembly != null);
                if (ReferenceEquals(assembly, referringAssembly))
                {
                    continue;
                }

                NamedTypeSymbol candidate = assembly.LookupTopLevelMetadataType(ref name, digThroughForwardedTypes: false);
                Debug.Assert(!candidate.IsGenericType);

                // Ignore type forwarders, error symbols and non-public types
                if (candidate.Kind == SymbolKind.ErrorType ||
                    !ReferenceEquals(candidate.ContainingAssembly, assembly) ||
                    candidate.DeclaredAccessibility != Accessibility.Public)
                {
                    continue;
                }

                // Ignore NoPia local types.
                // If candidate is coming from metadata, we don't need to do any special check,
                // because we do not create symbols for local types. However, local types defined in source
                // is another story. However, if compilation explicitly defines a local type, it should be
                // represented by a retargeting assembly, which is supposed to hide the local type.
                Debug.Assert(!(assembly is SourceAssemblySymbol) || !((SourceAssemblySymbol)assembly).SourceModule.MightContainNoPiaLocalTypes());

                string candidateGuid;
                bool   haveCandidateGuidValue = false;
                Guid   candidateGuidValue     = new Guid();

                // The type must be of the same kind (interface, struct, delegate or enum).
                switch (candidate.TypeKind)
                {
                case TypeKind.Interface:
                    if (!isInterface)
                    {
                        continue;
                    }

                    // Get candidate's Guid
                    if (candidate.GetGuidString(out candidateGuid) && candidateGuid != null)
                    {
                        haveCandidateGuidValue = Guid.TryParse(candidateGuid, out candidateGuidValue);
                    }

                    break;

                case TypeKind.Delegate:
                case TypeKind.Enum:
                case TypeKind.Struct:

                    if (isInterface)
                    {
                        continue;
                    }

                    // Let's use a trick. To make sure the kind is the same, make sure
                    // base type is the same.
                    if (!ReferenceEquals(baseType, candidate.BaseTypeNoUseSiteDiagnostics))
                    {
                        continue;
                    }

                    break;

                default:
                    continue;
                }

                if (haveInterfaceGuidValue || haveCandidateGuidValue)
                {
                    if (!haveInterfaceGuidValue || !haveCandidateGuidValue ||
                        candidateGuidValue != interfaceGuidValue)
                    {
                        continue;
                    }
                }
                else
                {
                    if (!haveScopeGuidValue || identifier == null || !identifier.Equals(name.FullName))
                    {
                        continue;
                    }

                    // Scope guid must match candidate's assembly guid.
                    haveCandidateGuidValue = false;
                    if (assembly.GetGuidString(out candidateGuid) && candidateGuid != null)
                    {
                        haveCandidateGuidValue = Guid.TryParse(candidateGuid, out candidateGuidValue);
                    }

                    if (!haveCandidateGuidValue || scopeGuidValue != candidateGuidValue)
                    {
                        continue;
                    }
                }

                // OK. It looks like we found canonical type definition.
                if ((object)result != null)
                {
                    // Ambiguity
                    result = new NoPiaAmbiguousCanonicalTypeSymbol(referringAssembly, result, candidate);
                    break;
                }

                result = candidate;
            }

            if ((object)result == null)
            {
                result = new NoPiaMissingCanonicalTypeSymbol(
                    referringAssembly,
                    name.FullName,
                    interfaceGuid,
                    scope,
                    identifier);
            }

            return(result);
        }
 internal override NamedTypeSymbol LookupMetadataType(ref MetadataTypeName typeName)
 {
     return this.RetargetingTranslator.Retarget(this.underlyingType.LookupMetadataType(ref typeName), RetargetOptions.RetargetPrimitiveTypesByName);
 }
Exemplo n.º 36
0
        /// <summary>
        /// For test purposes only.
        /// </summary>
        internal NamedTypeSymbol CachedTypeByEmittedName(string emittedname)
        {
            MetadataTypeName mdName = MetadataTypeName.FromFullName(emittedname);

            return(_emittedNameToTypeMap[mdName.ToKey()]);
        }
Exemplo n.º 37
0
        /// <summary>
        /// Lookup an immediately nested type referenced from metadata, names should be
        /// compared case-sensitively.
        /// </summary>
        /// <param name="emittedTypeName">
        /// Simple type name, possibly with generic name mangling.
        /// </param>
        /// <returns>
        /// Symbol for the type, or MissingMetadataSymbol if the type isn't found.
        /// </returns>
        internal virtual NamedTypeSymbol LookupMetadataType(ref MetadataTypeName emittedTypeName)
        {
            Debug.Assert(!emittedTypeName.IsNull);

            NamespaceOrTypeSymbol scope = this;

            if (scope.Kind == SymbolKind.ErrorType)
            {
                return new MissingMetadataTypeSymbol.Nested((NamedTypeSymbol)scope, ref emittedTypeName);
            }

            NamedTypeSymbol namedType = null;

            ImmutableArray<NamedTypeSymbol> namespaceOrTypeMembers;
            bool isTopLevel = scope.IsNamespace;

            Debug.Assert(!isTopLevel || scope.ToDisplayString(SymbolDisplayFormat.QualifiedNameOnlyFormat) == emittedTypeName.NamespaceName);

            if (emittedTypeName.IsMangled)
            {
                Debug.Assert(!emittedTypeName.UnmangledTypeName.Equals(emittedTypeName.TypeName) && emittedTypeName.InferredArity > 0);

                if (emittedTypeName.ForcedArity == -1 || emittedTypeName.ForcedArity == emittedTypeName.InferredArity)
                {
                    // Let's handle mangling case first.
                    namespaceOrTypeMembers = scope.GetTypeMembers(emittedTypeName.UnmangledTypeName);

                    foreach (var named in namespaceOrTypeMembers)
                    {
                        if (emittedTypeName.InferredArity == named.Arity && named.MangleName)
                        {
                            if ((object)namedType != null)
                            {
                                namedType = null;
                                break;
                            }

                            namedType = named;
                        }
                    }
                }
            }
            else
            {
                Debug.Assert(ReferenceEquals(emittedTypeName.UnmangledTypeName, emittedTypeName.TypeName) && emittedTypeName.InferredArity == 0);
            }

            // Now try lookup without removing generic arity mangling.
            int forcedArity = emittedTypeName.ForcedArity;

            if (emittedTypeName.UseCLSCompliantNameArityEncoding)
            {
                // Only types with arity 0 are acceptable, we already examined types with mangled names.
                if (emittedTypeName.InferredArity > 0)
                {
                    goto Done;
                }
                else if (forcedArity == -1)
                {
                    forcedArity = 0;
                }
                else if (forcedArity != 0)
                {
                    goto Done;
                }
                else
                {
                    Debug.Assert(forcedArity == emittedTypeName.InferredArity);
                }
            }

            namespaceOrTypeMembers = scope.GetTypeMembers(emittedTypeName.TypeName);

            foreach (var named in namespaceOrTypeMembers)
            {
                if (!named.MangleName && (forcedArity == -1 || forcedArity == named.Arity))
                {
                    if ((object)namedType != null)
                    {
                        namedType = null;
                        break;
                    }

                    namedType = named;
                }
            }

        Done:
            if ((object)namedType == null)
            {
                if (isTopLevel)
                {
                    return new MissingMetadataTypeSymbol.TopLevel(scope.ContainingModule, ref emittedTypeName);
                }
                else
                {
                    return new MissingMetadataTypeSymbol.Nested((NamedTypeSymbol)scope, ref emittedTypeName);
                }
            }

            return namedType;
        }
Exemplo n.º 38
0
        /// <summary>
        /// Lookup a top level type referenced from metadata, names should be
        /// compared case-sensitively.  Detect cycles during lookup.
        /// </summary>
        /// <param name="emittedName">
        /// Full type name, possibly with generic name mangling.
        /// </param>
        /// <param name="visitedAssemblies">
        /// List of assemblies lookup has already visited (since type forwarding can introduce cycles).
        /// </param>
        /// <param name="digThroughForwardedTypes">
        /// Take forwarded types into account.
        /// </param>
        internal sealed override NamedTypeSymbol LookupTopLevelMetadataTypeWithCycleDetection(ref MetadataTypeName emittedName, ConsList <AssemblySymbol> visitedAssemblies, bool digThroughForwardedTypes)
        {
            NamedTypeSymbol result = null;

            // This is a cache similar to the one used by MetaImport::GetTypeByName in native
            // compiler. The difference is that native compiler pre-populates the cache when it
            // loads types. Here we are populating the cache only with things we looked for, so that
            // next time we are looking for the same thing, the lookup is fast. This cache also
            // takes care of TypeForwarders. Gives about 8% win on subsequent lookups in some
            // scenarios.
            //
            // CONSIDER !!!
            //
            // However, it is questionable how often subsequent lookup by name  is going to happen.
            // Currently it doesn't happen for TypeDef tokens at all, for TypeRef tokens, the
            // lookup by name is done once and the result is cached. So, multiple lookups by name
            // for the same type are going to happen only in these cases:
            // 1) Resolving GetType() in attribute application, type is encoded by name.
            // 2) TypeRef token isn't reused within the same module, i.e. multiple TypeRefs point to
            //    the same type.
            // 3) Different Module refers to the same type, lookup once per Module (with exception of #2).
            // 4) Multitargeting - retargeting the type to a different version of assembly
            result = LookupTopLevelMetadataTypeInCache(ref emittedName);

            if ((object)result != null)
            {
                // We only cache result equivalent to digging through type forwarders, which
                // might produce an forwarder specific ErrorTypeSymbol. We don't want to
                // return that error symbol, unless digThroughForwardedTypes is true.
                if (digThroughForwardedTypes || (!result.IsErrorType() && (object)result.ContainingAssembly == (object)this))
                {
                    return(result);
                }

                // According to the cache, the type wasn't found, or isn't declared in this assembly (forwarded).
                throw new NotImplementedException();
                //return new MissingMetadataTypeSymbol.TopLevel(this.Modules[0], ref emittedName);
            }
            else
            {
                // Now we will look for the type in each module of the assembly and pick the first type
                // we find, this is what native VB compiler does.

                var modules = this.Modules;
                var count   = modules.Length;
                var i       = 0;

                result = modules[i].LookupTopLevelMetadataType(ref emittedName);

                if (result is ErrorTypeSymbol)
                {
                    for (i = 1; i < count; i++)
                    {
                        var newResult = modules[i].LookupTopLevelMetadataType(ref emittedName);

                        // Hold on to the first missing type result, unless we found the type.
                        if (!(newResult is ErrorTypeSymbol))
                        {
                            result = newResult;
                            break;
                        }
                    }
                }

                bool foundMatchInThisAssembly = (i < count);

                Debug.Assert(!foundMatchInThisAssembly || (object)result.ContainingAssembly == (object)this);

                if (!foundMatchInThisAssembly && digThroughForwardedTypes)
                {
                    // We didn't find the type
                    Debug.Assert(result is ErrorTypeSymbol);

                    NamedTypeSymbol forwarded = TryLookupForwardedMetadataTypeWithCycleDetection(ref emittedName, visitedAssemblies);
                    if ((object)forwarded != null)
                    {
                        result = forwarded;
                    }
                }

                Debug.Assert((object)result != null);

                // Add result of the lookup into the cache
                if (digThroughForwardedTypes || foundMatchInThisAssembly)
                {
                    CacheTopLevelMetadataType(ref emittedName, result);
                }

                return(result);
            }
        }
Exemplo n.º 39
0
 public TopLevel(ModuleSymbol module, ref MetadataTypeName fullName, SpecialType specialType)
     : this(module, ref fullName, (int)specialType)
 {
 }
Exemplo n.º 40
0
 /// <summary>
 /// Lookup a top level type referenced from metadata, names should be
 /// compared case-sensitively.
 /// </summary>
 /// <param name="emittedName">
 /// Full type name with generic name mangling.
 /// </param>
 /// <param name="digThroughForwardedTypes">
 /// Take forwarded types into account.
 /// </param>
 /// <remarks></remarks>
 internal NamedTypeSymbol LookupTopLevelMetadataType(ref MetadataTypeName emittedName, bool digThroughForwardedTypes)
 {
     return(LookupTopLevelMetadataTypeWithCycleDetection(ref emittedName, visitedAssemblies: null, digThroughForwardedTypes: digThroughForwardedTypes));
 }
Exemplo n.º 41
0
 private TopLevel(ModuleSymbol module, ref MetadataTypeName fullName, int typeId)
     : this(module, ref fullName, fullName.ForcedArity == -1 || fullName.ForcedArity == fullName.InferredArity)
 {
     Debug.Assert(typeId == -1 || typeId == (int)SpecialType.None || Arity == 0 || MangleName);
     _lazyTypeId = typeId;
 }
Exemplo n.º 42
0
 /// <summary>
 /// Lookup a top level type referenced from metadata, names should be
 /// compared case-sensitively.  Detect cycles during lookup.
 /// </summary>
 /// <param name="emittedName">
 /// Full type name, possibly with generic name mangling.
 /// </param>
 /// <param name="visitedAssemblies">
 /// List of assemblies lookup has already visited (since type forwarding can introduce cycles).
 /// </param>
 /// <param name="digThroughForwardedTypes">
 /// Take forwarded types into account.
 /// </param>
 internal abstract NamedTypeSymbol LookupTopLevelMetadataTypeWithCycleDetection(ref MetadataTypeName emittedName, ConsList <AssemblySymbol> visitedAssemblies, bool digThroughForwardedTypes);
Exemplo n.º 43
0
 public TopLevelWithCustomErrorInfo(ModuleSymbol module, ref MetadataTypeName emittedName, DiagnosticInfo errorInfo, WellKnownType typeId)
     : base(module, ref emittedName, typeId)
 {
     Debug.Assert(errorInfo != null);
     _errorInfo = errorInfo;
 }
Exemplo n.º 44
0
 /// <summary>
 /// Look up the given metadata type, if it is forwarded.
 /// </summary>
 internal NamedTypeSymbol TryLookupForwardedMetadataType(ref MetadataTypeName emittedName)
 {
     return(TryLookupForwardedMetadataTypeWithCycleDetection(ref emittedName, visitedAssemblies: null));
 }
Exemplo n.º 45
0
 private Nested(NamedTypeSymbol containingType, ref MetadataTypeName emittedName, bool mangleName)
     : this(containingType,
            mangleName ? emittedName.UnmangledTypeName : emittedName.TypeName,
            mangleName ? emittedName.InferredArity : emittedName.ForcedArity,
            mangleName)
 {
 }
Exemplo n.º 46
0
 /// <summary>
 /// Look up the given metadata type, if it is forwarded.
 /// </summary>
 internal virtual NamedTypeSymbol TryLookupForwardedMetadataTypeWithCycleDetection(ref MetadataTypeName emittedName, ConsList <AssemblySymbol> visitedAssemblies)
 {
     return(null);
 }
Exemplo n.º 47
0
        /// <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 MissingMetadataSymbol 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.NamespaceSegments);

            if ((object)scope == null)
            {
                // We failed to locate the namespace
                result = new MissingMetadataTypeSymbol.TopLevel(this, ref emittedName);
            }
            else
            {
                result = scope.LookupMetadataType(ref emittedName);
            }

            Debug.Assert((object)result != null);
            return result;
        }
Exemplo n.º 48
0
        internal ErrorTypeSymbol CreateCycleInTypeForwarderErrorTypeSymbol(ref MetadataTypeName emittedName)
        {
            DiagnosticInfo diagnosticInfo = new CSDiagnosticInfo(ErrorCode.ERR_CycleInTypeForwarder, emittedName.FullName, this.Name);

            return(new MissingMetadataTypeSymbol.TopLevelWithCustomErrorInfo(this.Modules[0], ref emittedName, diagnosticInfo));
        }
        internal override NamedTypeSymbol TryLookupForwardedMetadataTypeWithCycleDetection(ref MetadataTypeName emittedName, ConsList<AssemblySymbol> visitedAssemblies)
        {
            NamedTypeSymbol underlying = _underlyingAssembly.TryLookupForwardedMetadataType(ref emittedName);

            if ((object)underlying == null)
            {
                return null;
            }

            return this.RetargetingTranslator.Retarget(underlying, RetargetOptions.RetargetPrimitiveTypesByName);
        }
Exemplo n.º 50
0
        internal ErrorTypeSymbol CreateMultipleForwardingErrorTypeSymbol(ref MetadataTypeName emittedName, ModuleSymbol forwardingModule, AssemblySymbol destination1, AssemblySymbol destination2)
        {
            var diagnosticInfo = new CSDiagnosticInfo(ErrorCode.ERR_TypeForwardedToMultipleAssemblies, forwardingModule, this, emittedName.FullName, destination1, destination2);

            return(new MissingMetadataTypeSymbol.TopLevelWithCustomErrorInfo(forwardingModule, ref emittedName, diagnosticInfo));
        }
        internal override NamedTypeSymbol TryLookupForwardedMetadataTypeWithCycleDetection(ref MetadataTypeName emittedName, ConsList<AssemblySymbol> visitedAssemblies)
        {
            // Check if it is a forwarded type.
            var forwardedToAssembly = LookupAssemblyForForwardedMetadataType(ref emittedName);
            if ((object)forwardedToAssembly != null)
            {
                // Don't bother to check the forwarded-to assembly if we've already seen it.
                if (visitedAssemblies != null && visitedAssemblies.Contains(forwardedToAssembly))
                {
                    return CreateCycleInTypeForwarderErrorTypeSymbol(ref emittedName);
                }
                else
                {
                    visitedAssemblies = new ConsList<AssemblySymbol>(this, visitedAssemblies ?? ConsList<AssemblySymbol>.Empty);
                    return forwardedToAssembly.LookupTopLevelMetadataTypeWithCycleDetection(ref emittedName, visitedAssemblies, digThroughForwardedTypes: true);
                }
            }

            return null;
        }
Exemplo n.º 52
0
        /// <summary>
        /// Resolves <see cref="System.Type"/> to a <see cref="TypeSymbol"/> available in this assembly
        /// its referenced assemblies.
        /// </summary>
        /// <param name="type">The type to resolve.</param>
        /// <param name="includeReferences">Use referenced assemblies for resolution.</param>
        /// <returns>The resolved symbol if successful or null on failure.</returns>
        internal TypeSymbol GetTypeByReflectionType(Type type, bool includeReferences)
        {
            System.Reflection.TypeInfo typeInfo = type.GetTypeInfo();

            Debug.Assert(!typeInfo.IsByRef);

            // not supported (we don't accept open types as submission results nor host types):
            Debug.Assert(!typeInfo.ContainsGenericParameters);

            if (typeInfo.IsArray)
            {
                TypeSymbol symbol = GetTypeByReflectionType(typeInfo.GetElementType(), includeReferences);
                if ((object)symbol == null)
                {
                    return(null);
                }

                int rank = typeInfo.GetArrayRank();

                return(ArrayTypeSymbol.CreateCSharpArray(this, symbol, ImmutableArray <CustomModifier> .Empty, rank));
            }
            else if (typeInfo.IsPointer)
            {
                TypeSymbol symbol = GetTypeByReflectionType(typeInfo.GetElementType(), includeReferences);
                if ((object)symbol == null)
                {
                    return(null);
                }

                return(new PointerTypeSymbol(symbol));
            }
            else if (typeInfo.DeclaringType != null)
            {
                Debug.Assert(!typeInfo.IsArray);

                // consolidated generic arguments (includes arguments of all declaring types):
                Type[] genericArguments  = typeInfo.GenericTypeArguments;
                int    typeArgumentIndex = 0;

                var currentTypeInfo = typeInfo.IsGenericType ? typeInfo.GetGenericTypeDefinition().GetTypeInfo() : typeInfo;
                var nestedTypes     = ArrayBuilder <System.Reflection.TypeInfo> .GetInstance();

                while (true)
                {
                    Debug.Assert(currentTypeInfo.IsGenericTypeDefinition || !currentTypeInfo.IsGenericType);

                    nestedTypes.Add(currentTypeInfo);
                    if (currentTypeInfo.DeclaringType == null)
                    {
                        break;
                    }

                    currentTypeInfo = currentTypeInfo.DeclaringType.GetTypeInfo();
                }

                int i      = nestedTypes.Count - 1;
                var symbol = (NamedTypeSymbol)GetTypeByReflectionType(nestedTypes[i].AsType(), includeReferences);
                if ((object)symbol == null)
                {
                    return(null);
                }

                while (--i >= 0)
                {
                    int forcedArity         = nestedTypes[i].GenericTypeParameters.Length - nestedTypes[i + 1].GenericTypeParameters.Length;
                    MetadataTypeName mdName = MetadataTypeName.FromTypeName(nestedTypes[i].Name, forcedArity: forcedArity);

                    symbol = symbol.LookupMetadataType(ref mdName);
                    if ((object)symbol == null || symbol.IsErrorType())
                    {
                        return(null);
                    }

                    symbol = ApplyGenericArguments(symbol, genericArguments, ref typeArgumentIndex, includeReferences);
                    if ((object)symbol == null)
                    {
                        return(null);
                    }
                }

                nestedTypes.Free();
                Debug.Assert(typeArgumentIndex == genericArguments.Length);
                return(symbol);
            }
            else
            {
                AssemblyIdentity assemblyId = AssemblyIdentity.FromAssemblyDefinition(typeInfo.Assembly);

                MetadataTypeName mdName = MetadataTypeName.FromNamespaceAndTypeName(
                    typeInfo.Namespace ?? string.Empty,
                    typeInfo.Name,
                    forcedArity: typeInfo.GenericTypeArguments.Length);

                NamedTypeSymbol symbol = GetTopLevelTypeByMetadataName(ref mdName, assemblyId, includeReferences, isWellKnownType: false);

                if ((object)symbol == null || symbol.IsErrorType())
                {
                    return(null);
                }

                int    typeArgumentIndex = 0;
                Type[] genericArguments  = typeInfo.GenericTypeArguments;
                symbol = ApplyGenericArguments(symbol, genericArguments, ref typeArgumentIndex, includeReferences);
                Debug.Assert(typeArgumentIndex == genericArguments.Length);
                return(symbol);
            }
        }
 /// <summary>
 /// If this module forwards the given type to another assembly, return that assembly;
 /// otherwise, return null.
 /// </summary>
 /// <param name="fullName">Type to look up.</param>
 /// <returns>Assembly symbol or null.</returns>
 /// <remarks>
 /// The returned assembly may also forward the type.
 /// </remarks>
 internal AssemblySymbol GetAssemblyForForwardedType(ref MetadataTypeName fullName)
 {
     try
     {
         string matchedName;
         AssemblyReferenceHandle assemblyRef = Module.GetAssemblyForForwardedType(fullName.FullName, ignoreCase: false, matchedName: out matchedName);
         return assemblyRef.IsNil ? null : this.GetReferencedAssemblySymbols()[Module.GetAssemblyReferenceIndexOrThrow(assemblyRef)];
     }
     catch (BadImageFormatException)
     {
         return null;
     }
 }
Exemplo n.º 54
0
        internal NamedTypeSymbol GetTopLevelTypeByMetadataName(
            ref MetadataTypeName metadataName,
            AssemblyIdentity assemblyOpt,
            bool includeReferences,
            bool isWellKnownType,
            DiagnosticBag warnings = null,
            bool ignoreCorLibraryDuplicatedTypes = false)
        {
            NamedTypeSymbol result;

            // First try this assembly
            result = GetTopLevelTypeByMetadataName(this, ref metadataName, assemblyOpt);

            if (isWellKnownType && !IsValidWellKnownType(result))
            {
                result = null;
            }

            // ignore any types of the same name that might be in referenced assemblies (prefer the current assembly):
            if ((object)result != null || !includeReferences)
            {
                return(result);
            }

            Debug.Assert(this is SourceAssemblySymbol,
                         "Never include references for a non-source assembly, because they don't know about aliases.");

            var assemblies = ArrayBuilder <AssemblySymbol> .GetInstance();

            // ignore reference aliases if searching for a type from a specific assembly:
            if (assemblyOpt != null)
            {
                assemblies.AddRange(DeclaringCompilation.GetBoundReferenceManager().ReferencedAssemblies);
            }
            else
            {
                DeclaringCompilation.GetUnaliasedReferencedAssemblies(assemblies);
            }

            // Lookup in references
            foreach (var assembly in assemblies)
            {
                Debug.Assert(!(this is SourceAssemblySymbol && assembly.IsMissing)); // Non-source assemblies can have missing references

                NamedTypeSymbol candidate = GetTopLevelTypeByMetadataName(assembly, ref metadataName, assemblyOpt);

                if (isWellKnownType && !IsValidWellKnownType(candidate))
                {
                    candidate = null;
                }

                if ((object)candidate == null)
                {
                    continue;
                }

                Debug.Assert(candidate != result);

                if ((object)result != null)
                {
                    // duplicate
                    if (ignoreCorLibraryDuplicatedTypes)
                    {
                        if (IsInCorLib(candidate))
                        {
                            // ignore candidate
                            continue;
                        }
                        if (IsInCorLib(result))
                        {
                            // drop previous result
                            result = candidate;
                            continue;
                        }
                    }

                    if (warnings == null)
                    {
                        result = null;
                    }
                    else
                    {
                        // The predefined type '{0}' is defined in multiple assemblies in the global alias; using definition from '{1}'
                        warnings.Add(ErrorCode.WRN_MultiplePredefTypes, NoLocation.Singleton, result, result.ContainingAssembly);
                    }

                    break;
                }

                result = candidate;
            }

            assemblies.Free();
            return(result);
        }
Exemplo n.º 55
0
        internal NamedTypeSymbol LookupTopLevelMetadataType(ref MetadataTypeName emittedName, out bool isNoPiaLocalType)
        {
            NamedTypeSymbol result;
            PENamespaceSymbol scope = (PENamespaceSymbol)this.GlobalNamespace.LookupNestedNamespace(emittedName.NamespaceSegments);

            if ((object)scope == null)
            {
                // We failed to locate the namespace
                isNoPiaLocalType = false;
                result = new MissingMetadataTypeSymbol.TopLevel(this, ref emittedName);
            }
            else
            {
                result = scope.LookupMetadataType(ref emittedName, out isNoPiaLocalType);
                Debug.Assert((object)result != null);
            }

            return result;
        }
Exemplo n.º 56
0
        private static NamedTypeSymbol GetTopLevelTypeByMetadataName(AssemblySymbol assembly, ref MetadataTypeName metadataName, AssemblyIdentity assemblyOpt)
        {
            var result = assembly.LookupTopLevelMetadataType(ref metadataName, digThroughForwardedTypes: false);

            if (!IsAcceptableMatchForGetTypeByMetadataName(result))
            {
                return(null);
            }

            if (assemblyOpt != null && !assemblyOpt.Equals(assembly.Identity))
            {
                return(null);
            }

            return(result);
        }
Exemplo n.º 57
0
 public string Type(MetadataTypeName typeName, bool includeNested = false)
 {
     return Type(typeName.Name, typeName.GenericArgs, includeNested: includeNested);
 }
        internal override NamedTypeSymbol LookupMetadataType(ref MetadataTypeName typeName)
        {
            // This method is invoked when looking up a type by metadata type
            // name through a RetargetingAssemblySymbol. For instance, in
            // UnitTests.Symbols.Metadata.PE.NoPia.LocalTypeSubstitution2.
            NamedTypeSymbol underlying = this.underlyingNamespace.LookupMetadataType(ref typeName);

            Debug.Assert((object)underlying.ContainingModule == (object)retargetingModule.UnderlyingModule);

            if (!underlying.IsErrorType() && underlying.IsExplicitDefinitionOfNoPiaLocalType)
            {
                // Explicitly defined local types should be hidden.
                return new MissingMetadataTypeSymbol.TopLevel(retargetingModule, ref typeName);
            }

            return this.RetargetingTranslator.Retarget(underlying, RetargetOptions.RetargetPrimitiveTypesByName);
        }
Exemplo n.º 59
0
 public string Type(MetadataTypeName typeName)
 {
     return Type(typeName.Name, typeName.GenericArgs);
 }
Exemplo n.º 60
0
 internal override NamedTypeSymbol LookupTopLevelMetadataTypeWithCycleDetection(ref MetadataTypeName emittedName, ConsList <AssemblySymbol> visitedAssemblies, bool digThroughForwardedTypes)
 {
     return(new MissingMetadataTypeSymbol(emittedName.FullName, emittedName.ForcedArity, emittedName.IsMangled));
 }