Пример #1
0
            private void PopulateInheritance(MetadataDefinition metadataTypeDefinition)
            {
                var derivedTypeDefinition = metadataTypeDefinition.Type;
                var interfaceImplHandles  = derivedTypeDefinition.GetInterfaceImplementations();

                if (derivedTypeDefinition.BaseType.IsNil &&
                    interfaceImplHandles.Count == 0)
                {
                    return;
                }

                var derivedTypeSimpleName = metadataTypeDefinition.Name;

                PopulateInheritance(derivedTypeSimpleName, derivedTypeDefinition.BaseType);

                foreach (var interfaceImplHandle in interfaceImplHandles)
                {
                    if (!interfaceImplHandle.IsNil)
                    {
                        var interfaceImpl = _metadataReader.GetInterfaceImplementation(interfaceImplHandle);
                        PopulateInheritance(derivedTypeSimpleName, interfaceImpl.Interface);
                    }
                }
            }
Пример #2
0
            private void LookupMetadataDefinitions(
                TypeDefinition typeDefinition,
                OrderPreservingMultiDictionary <string, MetadataDefinition> definitionMap)
            {
                // Only bother looking for extension methods in static types.
                // Note this check means we would ignore extension methods declared in assemblies
                // compiled from VB code, since a module in VB is compiled into class with
                // "sealed" attribute but not "abstract".
                // Although this can be addressed by checking custom attributes,
                // we believe this is not a common scenario to warrant potential perf impact.
                if ((typeDefinition.Attributes & TypeAttributes.Abstract) != 0 &&
                    (typeDefinition.Attributes & TypeAttributes.Sealed) != 0)
                {
                    foreach (var child in typeDefinition.GetMethods())
                    {
                        var method = _metadataReader.GetMethodDefinition(child);
                        if ((method.Attributes & MethodAttributes.SpecialName) != 0 ||
                            (method.Attributes & MethodAttributes.RTSpecialName) != 0)
                        {
                            continue;
                        }

                        // SymbolTreeInfo is only searched for types and extension methods.
                        // So we don't want to pull in all methods here.  As a simple approximation
                        // we just pull in methods that have attributes on them.
                        if ((method.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public &&
                            (method.Attributes & MethodAttributes.Static) != 0 &&
                            method.GetParameters().Count > 0 &&
                            method.GetCustomAttributes().Count > 0)
                        {
                            // Decode method signature to get the receiver type name (i.e. type name for the first parameter)
                            var blob      = _metadataReader.GetBlobReader(method.Signature);
                            var decoder   = new SignatureDecoder <ParameterTypeInfo, object>(ParameterTypeInfoProvider.Instance, _metadataReader, genericContext: null);
                            var signature = decoder.DecodeMethodSignature(ref blob);

                            // It'd be good if we don't need to go through all parameters and make unnecessary allocations.
                            // However, this is not possible with meatadata reader API right now (although it's possible by copying code from meatadata reader implementaion)
                            if (signature.ParameterTypes.Length > 0)
                            {
                                _containsExtensionsMethod = true;
                                var firstParameterTypeInfo = signature.ParameterTypes[0];
                                var definition             = new MetadataDefinition(MetadataDefinitionKind.Member, _metadataReader.GetString(method.Name), firstParameterTypeInfo);
                                definitionMap.Add(definition.Name, definition);
                            }
                        }
                    }
                }

                foreach (var child in typeDefinition.GetNestedTypes())
                {
                    var type = _metadataReader.GetTypeDefinition(child);

                    // We don't include internals from metadata assemblies.  It's less likely that
                    // a project would have IVT to it and so it helps us save on memory.  It also
                    // means we can avoid loading lots and lots of obfuscated code in the case the
                    // dll was obfuscated.
                    if (IsPublic(type.Attributes))
                    {
                        var definition = MetadataDefinition.Create(_metadataReader, type);
                        definitionMap.Add(definition.Name, definition);
                        _allTypeDefinitions.Add(definition);
                    }
                }
            }