public MetadataManager ToAnalysisBasedMetadataManager()
        {
            var reflectableTypes = ReflectableEntityBuilder <TypeDesc> .Create();

            // Collect the list of types that are generating reflection metadata
            foreach (var typeWithMetadata in _typesWithMetadata)
            {
                reflectableTypes[typeWithMetadata] = MetadataCategory.Description;
            }

            foreach (var constructedType in GetTypesWithRuntimeMapping())
            {
                if (!IsReflectionBlocked(constructedType))
                {
                    reflectableTypes[constructedType] |= MetadataCategory.RuntimeMapping;

                    // Also set the description bit if the definition is getting metadata.
                    TypeDesc constructedTypeDefinition = constructedType.GetTypeDefinition();
                    if (constructedType != constructedTypeDefinition &&
                        (reflectableTypes[constructedTypeDefinition] & MetadataCategory.Description) != 0)
                    {
                        reflectableTypes[constructedType] |= MetadataCategory.Description;
                    }
                }
            }

            var reflectableMethods = ReflectableEntityBuilder <MethodDesc> .Create();

            foreach (var methodWithMetadata in _methodsWithMetadata)
            {
                reflectableMethods[methodWithMetadata] = MetadataCategory.Description;
            }

            foreach (var method in GetCompiledMethods())
            {
                if (!method.IsCanonicalMethod(CanonicalFormKind.Specific) &&
                    !IsReflectionBlocked(method))
                {
                    if ((reflectableTypes[method.OwningType] & MetadataCategory.RuntimeMapping) != 0)
                    {
                        reflectableMethods[method] |= MetadataCategory.RuntimeMapping;
                    }

                    // Also set the description bit if the definition is getting metadata.
                    MethodDesc typicalMethod = method.GetTypicalMethodDefinition();
                    if (method != typicalMethod &&
                        (reflectableMethods[typicalMethod] & MetadataCategory.Description) != 0)
                    {
                        reflectableMethods[method]          |= MetadataCategory.Description;
                        reflectableTypes[method.OwningType] |= MetadataCategory.Description;
                    }
                }
            }

            var reflectableFields = ReflectableEntityBuilder <FieldDesc> .Create();

            foreach (var fieldWithMetadata in _fieldsWithMetadata)
            {
                reflectableFields[fieldWithMetadata] = MetadataCategory.Description;
            }

            if (_hasPreciseFieldUsageInformation)
            {
                // TODO
            }
            else
            {
                // If we don't have precise field usage information we apply a policy that
                // says the fields inherit the setting from the type, potentially restricted by blocking.
                // (I.e. if a type has RuntimeMapping metadata, the field has RuntimeMapping too, unless blocked.)
                foreach (var reflectableType in reflectableTypes.ToEnumerable())
                {
                    if (reflectableType.Entity.IsGenericDefinition)
                    {
                        continue;
                    }

                    if (reflectableType.Entity.IsCanonicalSubtype(CanonicalFormKind.Specific))
                    {
                        continue;
                    }

                    if ((reflectableType.Category & MetadataCategory.RuntimeMapping) == 0)
                    {
                        continue;
                    }

                    foreach (var field in reflectableType.Entity.GetFields())
                    {
                        if (!IsReflectionBlocked(field))
                        {
                            reflectableFields[field] |= MetadataCategory.RuntimeMapping;

                            // Also set the description bit if the definition is getting metadata.
                            FieldDesc typicalField = field.GetTypicalFieldDefinition();
                            if (field != typicalField &&
                                (reflectableFields[typicalField] & MetadataCategory.Description) != 0)
                            {
                                reflectableFields[field] |= MetadataCategory.Description;
                            }
                        }
                    }
                }
            }

            return(new AnalysisBasedMetadataManager(
                       _typeSystemContext, _blockingPolicy, _resourceBlockingPolicy, _metadataLogFile, _stackTraceEmissionPolicy,
                       _modulesWithMetadata, reflectableTypes.ToEnumerable(), reflectableMethods.ToEnumerable(),
                       reflectableFields.ToEnumerable()));
        }
示例#2
0
        public MetadataManager ToAnalysisBasedMetadataManager()
        {
            var reflectableTypes = ReflectableEntityBuilder <TypeDesc> .Create();

            // Collect the list of types that are generating reflection metadata
            foreach (var typeWithMetadata in _typesWithMetadata)
            {
                reflectableTypes[typeWithMetadata] = MetadataCategory.Description;
            }

            // All the constructed types we generated that are not blocked are required to have runtime artifacts
            foreach (var constructedType in GetTypesWithConstructedEETypes())
            {
                if (!IsReflectionBlocked(constructedType))
                {
                    reflectableTypes[constructedType] |= MetadataCategory.RuntimeMapping;

                    // Also set the description bit if the definition is getting metadata.
                    TypeDesc constructedTypeDefinition = constructedType.GetTypeDefinition();
                    if (constructedType != constructedTypeDefinition &&
                        (reflectableTypes[constructedTypeDefinition] & MetadataCategory.Description) != 0)
                    {
                        reflectableTypes[constructedType] |= MetadataCategory.Description;
                    }
                }
            }

            // All the necessary types for which this is the higest load level are required to have runtime artifacts
            foreach (var necessaryType in GetTypesWithEETypes())
            {
                if (!ConstructedEETypeNode.CreationAllowed(necessaryType) &&
                    !IsReflectionBlocked(necessaryType))
                {
                    reflectableTypes[necessaryType] |= MetadataCategory.RuntimeMapping;

                    // Also set the description bit if the definition is getting metadata.
                    TypeDesc necessaryTypeDefinition = necessaryType.GetTypeDefinition();
                    if (necessaryType != necessaryTypeDefinition &&
                        (reflectableTypes[necessaryTypeDefinition] & MetadataCategory.Description) != 0)
                    {
                        reflectableTypes[necessaryType] |= MetadataCategory.Description;
                    }
                }
            }

            var reflectableMethods = ReflectableEntityBuilder <MethodDesc> .Create();

            foreach (var methodWithMetadata in _methodsWithMetadata)
            {
                reflectableMethods[methodWithMetadata] = MetadataCategory.Description;
            }

            foreach (var method in GetCompiledMethods())
            {
                if (!method.IsCanonicalMethod(CanonicalFormKind.Specific) &&
                    !IsReflectionBlocked(method))
                {
                    if ((reflectableTypes[method.OwningType] & MetadataCategory.RuntimeMapping) != 0)
                    {
                        reflectableMethods[method] |= MetadataCategory.RuntimeMapping;
                    }

                    // Also set the description bit if the definition is getting metadata.
                    MethodDesc typicalMethod = method.GetTypicalMethodDefinition();
                    if (method != typicalMethod &&
                        (reflectableMethods[typicalMethod] & MetadataCategory.Description) != 0)
                    {
                        reflectableMethods[method]          |= MetadataCategory.Description;
                        reflectableTypes[method.OwningType] |= MetadataCategory.Description;
                    }
                }
            }

            var reflectableFields = ReflectableEntityBuilder <FieldDesc> .Create();

            foreach (var fieldWithMetadata in _fieldsWithMetadata)
            {
                reflectableFields[fieldWithMetadata] = MetadataCategory.Description;
            }

            // TODO: this should be more precise
            foreach (var reflectableType in reflectableTypes.ToEnumerable())
            {
                if (reflectableType.Entity.IsGenericDefinition)
                {
                    continue;
                }

                if (reflectableType.Entity.IsCanonicalSubtype(CanonicalFormKind.Specific))
                {
                    continue;
                }

                foreach (var field in reflectableType.Entity.GetFields())
                {
                    if (CanGenerateMetadata(field.GetTypicalFieldDefinition()))
                    {
                        reflectableFields[field] |= reflectableType.Category;
                    }
                }
            }

            return(new AnalysisBasedMetadataManager(_compilationModuleGroup.GeneratedAssembly,
                                                    _typeSystemContext, _blockingPolicy, _metadataLogFile, _stackTraceEmissionPolicy,
                                                    _modulesWithMetadata, reflectableTypes.ToEnumerable(), reflectableMethods.ToEnumerable(),
                                                    reflectableFields.ToEnumerable()));
        }