Пример #1
0
        public override MethodDesc GetDefaultConstructor()
        {
            if (IsAbstract)
                return null;

            MetadataReader metadataReader = this.MetadataReader;
            MetadataStringComparer stringComparer = metadataReader.StringComparer;

            foreach (var handle in _typeDefinition.GetMethods())
            {
                var methodDefinition = metadataReader.GetMethodDefinition(handle);
                MethodAttributes attributes = methodDefinition.Attributes;
                if (attributes.IsRuntimeSpecialName() && attributes.IsPublic()
                    && stringComparer.Equals(methodDefinition.Name, ".ctor"))
                {
                    var method = (EcmaMethod)_module.GetObject(handle);
                    MethodSignature sig = method.Signature;

                    if (sig.Length != 0)
                        continue;

                    if ((sig.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask) == MethodSignatureFlags.CallingConventionVarargs)
                        continue;

                    return method;
                }
            }

            return null;
        }
Пример #2
0
        public override MethodDesc GetDefaultConstructor()
        {
            if (IsAbstract)
            {
                return(null);
            }

            MetadataReader         metadataReader = this.MetadataReader;
            MetadataStringComparer stringComparer = metadataReader.StringComparer;

            foreach (var handle in _typeDefinition.GetMethods())
            {
                var methodDefinition        = metadataReader.GetMethodDefinition(handle);
                MethodAttributes attributes = methodDefinition.Attributes;
                if (attributes.IsRuntimeSpecialName() && attributes.IsPublic() &&
                    stringComparer.Equals(methodDefinition.Name, ".ctor"))
                {
                    MethodDesc method = (MethodDesc)_module.GetObject(handle);
                    if (method.Signature.Length != 0)
                    {
                        continue;
                    }

                    return(method);
                }
            }

            return(null);
        }
Пример #3
0
        private uint LookupIbcTypeToken(EcmaModule externalModule, uint ibcToken, Dictionary <IBCBlobKey, BlobEntry> blobs)
        {
            var    typeEntry     = (BlobEntry.ExternalTypeEntry)blobs[new IBCBlobKey(ibcToken, BlobType.ExternalTypeDef)];
            string typeNamespace = null;
            string typeName      = Encoding.UTF8.GetString(typeEntry.Name);
            TypeDefinitionHandle enclosingType = default;

            if (!Cor.Macros.IsNilToken(typeEntry.NamespaceToken))
            {
                if (!Cor.Macros.IsNilToken(typeEntry.NestedClassToken))
                {
                    // Do not support typedef with namespace that is nested
                    throw new Exception($"Ibc TypeToken {ibcToken:x} has both Namespace and NestedClass tokens");
                }

                uint nameSpaceToken = typeEntry.NamespaceToken;
                if (Cor.Macros.TypeFromToken(nameSpaceToken) != CorTokenType.ibcExternalNamespace)
                {
                    throw new Exception($"Ibc TypeToken {ibcToken:x} has Namespace tokens that is not a ibcExternalNamespace");
                }

                var namespaceEntry = (BlobEntry.ExternalNamespaceEntry)blobs[new IBCBlobKey(nameSpaceToken, BlobType.ExternalNamespaceDef)];
                typeNamespace = Encoding.UTF8.GetString(namespaceEntry.Name);
            }
            else if (!Cor.Macros.IsNilToken(typeEntry.NestedClassToken))
            {
                uint enclosingTypeTokenValue = LookupIbcTypeToken(externalModule, typeEntry.NestedClassToken, blobs);
                if (Cor.Macros.TypeFromToken(enclosingTypeTokenValue) != CorTokenType.mdtTypeDef)
                {
                    throw new Exception($"Ibc TypeToken {ibcToken:x} has NestedClass token which does not resolve to a type definition");
                }

                enclosingType = MetadataTokens.TypeDefinitionHandle((int)Cor.Macros.RidFromToken(enclosingTypeTokenValue));
                if (enclosingType.IsNil)
                {
                    throw new Exception($"Ibc TypeToken {ibcToken:x} has NestedClass token which resolves to a nil token");
                }
            }

            if (enclosingType.IsNil)
            {
                return((uint)externalModule.MetadataReader.GetToken(((EcmaType)externalModule.GetType(typeNamespace, typeName)).Handle));
            }
            else
            {
                TypeDefinition         nestedClassDefinition = externalModule.MetadataReader.GetTypeDefinition(enclosingType);
                MetadataStringComparer stringComparer        = externalModule.MetadataReader.StringComparer;
                foreach (TypeDefinitionHandle tdNested in nestedClassDefinition.GetNestedTypes())
                {
                    TypeDefinition candidateClassDefinition = externalModule.MetadataReader.GetTypeDefinition(tdNested);
                    if (stringComparer.Equals(candidateClassDefinition.Name, typeName))
                    {
                        return((uint)externalModule.MetadataReader.GetToken(tdNested));
                    }
                }

                throw new Exception($"Ibc TypeToken {ibcToken:x} unable to find nested type '{typeName}' on type '{externalModule.MetadataReader.GetToken(enclosingType):x}'");
            }
        }
Пример #4
0
        // This is specially designed for a hot path so we make some compromises in the signature:
        //
        //     - "method" is passed by reference even though no side-effects are intended.
        //
        public static bool IsConstructor(ref MethodDefinition method, MetadataReader reader)
        {
            if ((method.Attributes & (MethodAttributes.RTSpecialName | MethodAttributes.SpecialName)) != (MethodAttributes.RTSpecialName | MethodAttributes.SpecialName))
            {
                return(false);
            }

            MetadataStringComparer stringComparer = reader.StringComparer;

            StringHandle nameHandle = method.Name;

            return(stringComparer.Equals(nameHandle, ConstructorInfo.ConstructorName) || stringComparer.Equals(nameHandle, ConstructorInfo.TypeConstructorName));
        }
Пример #5
0
        protected sealed override Guid?ComputeGuidFromCustomAttributes()
        {
            //
            // Look for a [Guid] attribute. If found, return that.
            //
            foreach (CustomAttributeHandle cah in _typeDefinition.GetCustomAttributes())
            {
                // We can't reference the GuidAttribute class directly as we don't have an official dependency on System.Runtime.InteropServices.
                // Following age-old CLR tradition, we search for the custom attribute using a name-based search. Since this makes it harder
                // to be sure we won't run into custom attribute constructors that comply with the GuidAttribute(String) signature,
                // we'll check that it does and silently skip the CA if it doesn't match the expected pattern.
                CustomAttribute attribute = Reader.GetCustomAttribute(cah);
                EntityHandle    ctorType;
                EcmaMetadataHelpers.GetAttributeTypeDefRefOrSpecHandle(_reader, attribute.Constructor, out ctorType);
                StringHandle typeNameHandle;
                StringHandle typeNamespaceHandle;
                if (EcmaMetadataHelpers.GetAttributeNamespaceAndName(Reader, ctorType, out typeNamespaceHandle, out typeNameHandle))
                {
                    MetadataStringComparer stringComparer = Reader.StringComparer;
                    if (stringComparer.Equals(typeNamespaceHandle, "System.Runtime.InteropServices"))
                    {
                        if (stringComparer.Equals(typeNameHandle, "GuidAttribute"))
                        {
                            ReflectionTypeProvider typeProvider = new ReflectionTypeProvider(throwOnError: false);

                            CustomAttributeValue <RuntimeTypeInfo> customAttributeValue = attribute.DecodeValue(typeProvider);
                            if (customAttributeValue.FixedArguments.Length != 1)
                            {
                                continue;
                            }

                            CustomAttributeTypedArgument <RuntimeTypeInfo> firstArg = customAttributeValue.FixedArguments[0];
                            if (firstArg.Value == null)
                            {
                                continue;
                            }

                            string guidString = firstArg.Value as string;
                            if (guidString == null)
                            {
                                continue;
                            }

                            return(new Guid(guidString));
                        }
                    }
                }
            }

            return(null);
        }
        /// <summary>Load our fields from the metadata of the file as represented by the provided metadata reader.</summary>
        /// <param name="metadataReader">The metadata reader for the CLI file this represents.</param>\
        /// <param name="isExe">true if the assembly represents an executable; false if it's a dll.</param>
        private void LoadManagedAssemblyMetadata(MetadataReader metadataReader, bool isExe)
        {
            AssemblyDefinition assemblyDefinition = metadataReader.GetAssemblyDefinition();

            // Set the internal and original names based on the assembly name.  We avoid using the
            // current filename for determinism and better alignment with behavior on Windows.
            string assemblyName = metadataReader.GetString(assemblyDefinition.Name);

            if (!assemblyName.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) &&
                !assemblyName.EndsWith(".exe", StringComparison.OrdinalIgnoreCase))
            {
                assemblyName += isExe ? ".exe" : ".dll";
            }
            _internalName = _originalFilename = assemblyName;

            // Set the product version based on the assembly's version (this may be overwritten
            // later in the method).
            Version productVersion = assemblyDefinition.Version;

            _productVersion = productVersion.ToString();
            _productMajor   = productVersion.Major;
            _productMinor   = productVersion.Minor;
            _productBuild   = productVersion.Build != -1 ? productVersion.Build : 0;
            _productPrivate = productVersion.Revision != -1 ? productVersion.Revision : 0;

            // "Language Neutral" is used on Win32 for unknown language identifiers.
            _language = "Language Neutral";

            // Set other fields to default values in case they're not overwritten by attributes
            _companyName     = string.Empty;
            _comments        = string.Empty;
            _fileDescription = " "; // this is what the managed compiler outputs when value isn't set
            _fileVersion     = string.Empty;
            _legalCopyright  = " "; // this is what the managed compiler outputs when value isn't set
            _legalTrademarks = string.Empty;
            _productName     = string.Empty;
            _privateBuild    = string.Empty;
            _specialBuild    = string.Empty;

            // Be explicit about initialization to suppress warning about fields not being set
            _isDebug        = false;
            _isPatched      = false;
            _isPreRelease   = false;
            _isPrivateBuild = false;
            _isSpecialBuild = false;

            bool sawAssemblyInformationalVersionAttribute = false;

            // Everything else is parsed from assembly attributes
            MetadataStringComparer comparer = metadataReader.StringComparer;

            foreach (CustomAttributeHandle attrHandle in assemblyDefinition.GetCustomAttributes())
            {
                CustomAttribute attr = metadataReader.GetCustomAttribute(attrHandle);
                StringHandle    typeNamespaceHandle = default(StringHandle), typeNameHandle = default(StringHandle);
                if (TryGetAttributeName(metadataReader, attr, out typeNamespaceHandle, out typeNameHandle) &&
                    comparer.Equals(typeNamespaceHandle, "System.Reflection"))
                {
                    if (comparer.Equals(typeNameHandle, "AssemblyCompanyAttribute"))
                    {
                        GetStringAttributeArgumentValue(metadataReader, attr, ref _companyName);
                    }
                    else if (comparer.Equals(typeNameHandle, "AssemblyCopyrightAttribute"))
                    {
                        GetStringAttributeArgumentValue(metadataReader, attr, ref _legalCopyright);
                    }
                    else if (comparer.Equals(typeNameHandle, "AssemblyDescriptionAttribute"))
                    {
                        GetStringAttributeArgumentValue(metadataReader, attr, ref _comments);
                    }
                    else if (comparer.Equals(typeNameHandle, "AssemblyFileVersionAttribute"))
                    {
                        GetStringAttributeArgumentValue(metadataReader, attr, ref _fileVersion);
                        ParseVersion(_fileVersion, out _fileMajor, out _fileMinor, out _fileBuild, out _filePrivate);
                    }
                    else if (comparer.Equals(typeNameHandle, "AssemblyInformationalVersionAttribute"))
                    {
                        GetStringAttributeArgumentValue(metadataReader, attr, ref _productVersion);
                        ParseVersion(_productVersion, out _productMajor, out _productMinor, out _productBuild, out _productPrivate);
                        sawAssemblyInformationalVersionAttribute = true;
                    }
                    else if (comparer.Equals(typeNameHandle, "AssemblyProductAttribute"))
                    {
                        GetStringAttributeArgumentValue(metadataReader, attr, ref _productName);
                    }
                    else if (comparer.Equals(typeNameHandle, "AssemblyTrademarkAttribute"))
                    {
                        GetStringAttributeArgumentValue(metadataReader, attr, ref _legalTrademarks);
                    }
                    else if (comparer.Equals(typeNameHandle, "AssemblyTitleAttribute"))
                    {
                        GetStringAttributeArgumentValue(metadataReader, attr, ref _fileDescription);
                    }
                }
            }

            // When the managed compiler sees an [AssemblyVersion(...)] attribute, it uses that to set
            // both the assembly version and the product version in the Win32 resources. If it doesn't
            // see an [AssemblyVersion(...)], then it sets the assembly version to 0.0.0.0, however it
            // sets the product version in the Win32 resources to whatever was defined in the
            // [AssemblyFileVersionAttribute(...)] if there was one (unless there is an AssemblyInformationalVersionAttribute,
            // in which case it always uses that for the product version).  Without parsing the Win32 resources,
            // we can't differentiate these two cases, so given the rarity of explicitly setting an
            // assembly's version number to 0.0.0.0, we assume that if it is 0.0.0.0 then the attribute
            // wasn't specified and we use the file version.

            if (!sawAssemblyInformationalVersionAttribute && _productVersion == "0.0.0.0")
            {
                _productVersion = _fileVersion;
                _productMajor   = _fileMajor;
                _productMinor   = _fileMinor;
                _productBuild   = _fileBuild;
                _productPrivate = _filePrivate;
            }
        }
Пример #7
0
        protected override TypeFlags ComputeTypeFlags(TypeFlags mask)
        {
            TypeFlags flags = 0;

            if ((mask & TypeFlags.CategoryMask) != 0)
            {
                TypeDesc baseType = this.BaseType;

                if (baseType != null && baseType.IsWellKnownType(WellKnownType.ValueType))
                {
                    flags |= TypeFlags.ValueType;
                }
                else
                if (baseType != null && baseType.IsWellKnownType(WellKnownType.Enum))
                {
                    flags |= TypeFlags.Enum;
                }
                else
                {
                    if ((_typeDefinition.Attributes & TypeAttributes.Interface) != 0)
                        flags |= TypeFlags.Interface;
                    else
                        flags |= TypeFlags.Class;
                }

                // All other cases are handled during TypeSystemContext intitialization
            }

            if ((mask & TypeFlags.HasGenericVarianceComputed) != 0)
            {
                flags |= TypeFlags.HasGenericVarianceComputed;

                foreach (GenericParameterDesc genericParam in Instantiation)
                {
                    if (genericParam.Variance != GenericVariance.None)
                    {
                        flags |= TypeFlags.HasGenericVariance;
                        break;
                    }
                }
            }

            if ((mask & TypeFlags.HasFinalizerComputed) != 0)
            {
                flags |= TypeFlags.HasFinalizerComputed;

                if (GetFinalizer() != null)
                    flags |= TypeFlags.HasFinalizer;
            }

            if ((mask & TypeFlags.AttributeCacheComputed) != 0)
            {
                MetadataReader reader = MetadataReader;
                MetadataStringComparer stringComparer = reader.StringComparer;
                bool isValueType = IsValueType;

                flags |= TypeFlags.AttributeCacheComputed;

                foreach (CustomAttributeHandle attributeHandle in _typeDefinition.GetCustomAttributes())
                {
                    if (MetadataReader.GetAttributeNamespaceAndName(attributeHandle, out StringHandle namespaceHandle, out StringHandle nameHandle))
                    {
                        if (isValueType &&
                            stringComparer.Equals(nameHandle, "IsByRefLikeAttribute") &&
                            stringComparer.Equals(namespaceHandle, "System.Runtime.CompilerServices"))
                            flags |= TypeFlags.IsByRefLike;

                        if (stringComparer.Equals(nameHandle, "IntrinsicAttribute") &&
                            stringComparer.Equals(namespaceHandle, "System.Runtime.CompilerServices"))
                            flags |= TypeFlags.IsIntrinsic;
                    }
                }
            }

            return flags;
        }
Пример #8
0
        /// <summary>Load our fields from the metadata of the file as represented by the provided metadata reader.</summary>
        /// <param name="metadataReader">The metadata reader for the CLI file this represents.</param>
        private void LoadManagedAssemblyMetadata(MetadataReader metadataReader)
        {
            AssemblyDefinition assemblyDefinition = metadataReader.GetAssemblyDefinition();

            // Set the internal and original names based on the file name.
            _internalName = _originalFilename = Path.GetFileName(_fileName);

            // Set the product version based on the assembly's version (this may be overwritten
            // later in the method).
            Version productVersion = assemblyDefinition.Version;

            _productVersion = productVersion.ToString();
            _productMajor   = productVersion.Major;
            _productMinor   = productVersion.Minor;
            _productBuild   = productVersion.Build != -1 ? productVersion.Build : 0;
            _productPrivate = productVersion.Revision != -1 ? productVersion.Revision : 0;

            // "Language Neutral" is used on Win32 for unknown language identifiers.
            _language = "Language Neutral";

            // Set other fields to default values in case they're not overwritten by attributes
            _companyName     = string.Empty;
            _comments        = string.Empty;
            _fileDescription = " "; // this is what the managed compiler outputs when value isn't set
            _fileVersion     = string.Empty;
            _legalCopyright  = " "; // this is what the managed compiler outputs when value isn't set
            _legalTrademarks = string.Empty;
            _productName     = string.Empty;
            _privateBuild    = string.Empty;
            _specialBuild    = string.Empty;

            // Be explicit about initialization to suppress warning about fields not being set
            _isDebug        = false;
            _isPatched      = false;
            _isPreRelease   = false;
            _isPrivateBuild = false;
            _isSpecialBuild = false;

            // Everything else is parsed from assembly attributes
            MetadataStringComparer comparer = metadataReader.StringComparer;

            foreach (CustomAttributeHandle attrHandle in assemblyDefinition.GetCustomAttributes())
            {
                CustomAttribute attr = metadataReader.GetCustomAttribute(attrHandle);
                StringHandle    typeNamespaceHandle = default(StringHandle), typeNameHandle = default(StringHandle);
                if (TryGetAttributeName(metadataReader, attr, out typeNamespaceHandle, out typeNameHandle) &&
                    comparer.Equals(typeNamespaceHandle, "System.Reflection"))
                {
                    if (comparer.Equals(typeNameHandle, "AssemblyCompanyAttribute"))
                    {
                        GetStringAttributeArgumentValue(metadataReader, attr, ref _companyName);
                    }
                    else if (comparer.Equals(typeNameHandle, "AssemblyCopyrightAttribute"))
                    {
                        GetStringAttributeArgumentValue(metadataReader, attr, ref _legalCopyright);
                    }
                    else if (comparer.Equals(typeNameHandle, "AssemblyDescriptionAttribute"))
                    {
                        GetStringAttributeArgumentValue(metadataReader, attr, ref _comments);
                    }
                    else if (comparer.Equals(typeNameHandle, "AssemblyFileVersionAttribute"))
                    {
                        string versionString = string.Empty;
                        GetStringAttributeArgumentValue(metadataReader, attr, ref versionString);
                        Version v;
                        if (Version.TryParse(versionString, out v))
                        {
                            _fileVersion = v.ToString();
                            _fileMajor   = v.Major;
                            _fileMinor   = v.Minor;
                            _fileBuild   = v.Build != -1 ? v.Build : 0;
                            _filePrivate = v.Revision != -1 ? v.Revision : 0;

                            // When the managed compiler sees an [AssemblyVersion(...)] attribute, it uses that to set
                            // both the assembly version and the product version in the Win32 resources. If it doesn't
                            // see an [AssemblyVersion(...)], then it sets the assembly version to 0.0.0.0, however it
                            // sets the product version in the Win32 resources to whatever was defined in the
                            // [AssemblyFileVersionAttribute(...)] if there was one.  Without parsing the Win32 resources,
                            // we can't differentiate these two cases, so given the rarity of explicitly setting an
                            // assembly's version number to 0.0.0.0, we assume that if it is 0.0.0.0 then the attribute
                            // wasn't specified and we use the file version.
                            if (_productVersion == "0.0.0.0")
                            {
                                _productVersion = _fileVersion;
                                _productMajor   = _fileMajor;
                                _productMinor   = _fileMinor;
                                _productBuild   = _fileBuild;
                                _productPrivate = _filePrivate;
                            }
                        }
                    }
                    else if (comparer.Equals(typeNameHandle, "AssemblyProductAttribute"))
                    {
                        GetStringAttributeArgumentValue(metadataReader, attr, ref _productName);
                    }
                    else if (comparer.Equals(typeNameHandle, "AssemblyTrademarkAttribute"))
                    {
                        GetStringAttributeArgumentValue(metadataReader, attr, ref _legalTrademarks);
                    }
                    else if (comparer.Equals(typeNameHandle, "AssemblyTitleAttribute"))
                    {
                        GetStringAttributeArgumentValue(metadataReader, attr, ref _fileDescription);
                    }
                }
            }
        }
Пример #9
0
        // LookupIbcTypeToken and (possibly) find the module associated with it.
        // externalModule may be null if the exact assembly isn't known
        private uint LookupIbcTypeToken(ref EcmaModule externalModule, uint ibcToken, Dictionary <IBCBlobKey, BlobEntry> blobs)
        {
            if (!blobs.TryGetValue(new IBCBlobKey(ibcToken, BlobType.ExternalTypeDef), out BlobEntry externalTypeDefBlob))
            {
                if (_logger.IsVerbose)
                {
                    _logger.Writer.WriteLine($"Ibc TypeToken {ibcToken:x} unable to find external typedef");
                }
                return(Cor.Macros.RidToToken(0, CorTokenType.mdtTypeDef)); // Nil TypeDef token
            }

            var typeEntry = (BlobEntry.ExternalTypeEntry)externalTypeDefBlob;

            string typeNamespace = "";
            string typeName      = Encoding.UTF8.GetString(typeEntry.Name, 0, typeEntry.Name.Length - 1 /* these strings are null terminated */);
            TypeDefinitionHandle enclosingType = default;

            if (!Cor.Macros.IsNilToken(typeEntry.NamespaceToken))
            {
                if (!Cor.Macros.IsNilToken(typeEntry.NestedClassToken))
                {
                    // Do not support typedef with namespace that is nested
                    throw new Exception($"Ibc TypeToken {ibcToken:x} has both Namespace and NestedClass tokens");
                }

                uint nameSpaceToken = typeEntry.NamespaceToken;
                if (Cor.Macros.TypeFromToken(nameSpaceToken) != CorTokenType.ibcExternalNamespace)
                {
                    throw new Exception($"Ibc TypeToken {ibcToken:x} has Namespace tokens that is not a ibcExternalNamespace");
                }


                if (!blobs.TryGetValue(new IBCBlobKey(nameSpaceToken, BlobType.ExternalNamespaceDef), out BlobEntry namespaceEntryBlob))
                {
                    if (_logger.IsVerbose)
                    {
                        _logger.Writer.WriteLine($"Ibc TypeToken {ibcToken:x} unable to find external namespace blob '{nameSpaceToken:x}");
                    }
                    return(Cor.Macros.RidToToken(0, CorTokenType.mdtTypeDef)); // Nil TypeDef token
                }

                var namespaceEntry = (BlobEntry.ExternalNamespaceEntry)namespaceEntryBlob;
                typeNamespace = Encoding.UTF8.GetString(namespaceEntry.Name, 0, namespaceEntry.Name.Length - 1 /* these strings are null terminated */);
            }
            else if (!Cor.Macros.IsNilToken(typeEntry.NestedClassToken))
            {
                uint enclosingTypeTokenValue = LookupIbcTypeToken(ref externalModule, typeEntry.NestedClassToken, blobs);
                if (Cor.Macros.TypeFromToken(enclosingTypeTokenValue) != CorTokenType.mdtTypeDef)
                {
                    throw new Exception($"Ibc TypeToken {ibcToken:x} has NestedClass token which does not resolve to a type definition");
                }

                enclosingType = MetadataTokens.TypeDefinitionHandle((int)Cor.Macros.RidFromToken(enclosingTypeTokenValue));
                if (enclosingType.IsNil && _logger.IsVerbose)
                {
                    _logger.Writer.WriteLine($"Ibc TypeToken {ibcToken:x} has NestedClass token which resolves to a nil token");
                }
            }

            if (enclosingType.IsNil)
            {
                EcmaType foundType = null;
                if (externalModule == null)
                {
                    // Lookup actual module scenario.
                    foreach (ModuleDesc m in _possibleReferenceModules)
                    {
                        if (!(m is EcmaModule))
                        {
                            continue;
                        }

                        foundType = (EcmaType)m.GetType(typeNamespace, typeName, throwIfNotFound: false);
                        if (foundType != null)
                        {
                            externalModule = foundType.EcmaModule;
                            break;
                        }
                    }
                }
                else
                {
                    foundType = (EcmaType)externalModule.GetType(typeNamespace, typeName, throwIfNotFound: false);
                }

                if (foundType == null)
                {
                    if (_logger.IsVerbose)
                    {
                        _logger.Writer.WriteLine($"Ibc TypeToken {ibcToken:x} has type token which resolves to a nil token");
                    }
                    return(Cor.Macros.RidToToken(0, CorTokenType.mdtTypeDef)); // Nil TypeDef token
                }

                return((uint)externalModule.MetadataReader.GetToken(foundType.Handle));
            }
            else
            {
                TypeDefinition         nestedClassDefinition = externalModule.MetadataReader.GetTypeDefinition(enclosingType);
                MetadataStringComparer stringComparer        = externalModule.MetadataReader.StringComparer;
                foreach (TypeDefinitionHandle tdNested in nestedClassDefinition.GetNestedTypes())
                {
                    TypeDefinition candidateClassDefinition = externalModule.MetadataReader.GetTypeDefinition(tdNested);
                    if (stringComparer.Equals(candidateClassDefinition.Name, typeName))
                    {
                        return((uint)externalModule.MetadataReader.GetToken(tdNested));
                    }
                }

                if (_logger.IsVerbose)
                {
                    _logger.Writer.WriteLine($"Ibc TypeToken {ibcToken:x} unable to find nested type '{typeName}' on type '{externalModule.MetadataReader.GetToken(enclosingType):x}'");
                }
                return(Cor.Macros.RidToToken(0, CorTokenType.mdtTypeDef)); // Nil TypeDef token
            }
        }
Пример #10
0
        //
        // Main routine to resolve a typeReference.
        //
        private static RuntimeTypeInfo TryResolveTypeReference(this TypeReferenceHandle typeReferenceHandle, MetadataReader reader, ref Exception exception)
        {
            TypeReference typeReference   = reader.GetTypeReference(typeReferenceHandle);
            EntityHandle  resolutionScope = typeReference.ResolutionScope;

            if (resolutionScope.IsNil)
            {
                // Search for an entry in the exported type table for this type
                return(TryResolveTypeByName(reader, typeReference.GetFullyQualifiedTypeName(reader), ref exception));
            }

            switch (resolutionScope.Kind)
            {
            case HandleKind.ModuleReference:
                // multi-module assemblies are not supported by this runtime
                exception = new PlatformNotSupportedException();
                return(null);

            case HandleKind.TypeReference:
            {
                // This is a nested type. Find the enclosing type, then search for a matching nested type
                RuntimeTypeInfo enclosingType = ((TypeReferenceHandle)typeReference.ResolutionScope).TryResolveTypeReference(reader, ref exception);
                if (enclosingType == null)
                {
                    Debug.Assert(exception != null);
                    return(null);
                }
                MetadataStringComparer stringComparer = reader.StringComparer;
                foreach (var nestedType in enclosingType.GetNestedTypes())
                {
                    if (stringComparer.Equals(typeReference.Name, nestedType.Name))
                    {
                        if (stringComparer.Equals(typeReference.Namespace, nestedType.Namespace))
                        {
                            return((RuntimeTypeInfo)nestedType.GetTypeInfo());
                        }
                    }
                }
                exception = ReflectionCoreExecution.ExecutionDomain.CreateMissingMetadataException(enclosingType, reader.GetString(typeReference.Name));
                return(null);
            }

            case HandleKind.AssemblyReference:
            {
                string fullName = typeReference.GetFullyQualifiedTypeName(reader);

                RuntimeAssemblyName runtimeAssemblyName = ((AssemblyReferenceHandle)resolutionScope).ToRuntimeAssemblyName(reader);
                RuntimeAssembly     runtimeAssembly;
                exception = RuntimeAssembly.TryGetRuntimeAssembly(runtimeAssemblyName, out runtimeAssembly);
                if (exception != null)
                {
                    return(null);
                }
                RuntimeTypeInfo runtimeType = runtimeAssembly.GetTypeCore(fullName, ignoreCase: false);
                if (runtimeType == null)
                {
                    exception = Helpers.CreateTypeLoadException(fullName, runtimeAssemblyName.FullName);
                    return(null);
                }
                return(runtimeType);
            }

            case HandleKind.ModuleDefinition:
                return(TryResolveTypeByName(reader, typeReference.GetFullyQualifiedTypeName(reader), ref exception));

            default:
                exception = new BadImageFormatException();
                return(null);
            }
        }