Example #1
0
File: Dom.cs Project: zwkjgs/ILSpy
        public string GetGenericTypeParameterName(int index)
        {
            GenericParameterHandle genericParameter = GetGenericTypeParameterHandleOrNull(index);

            if (genericParameter.IsNil)
            {
                return(index.ToString());
            }
            return(metadata.GetString(metadata.GetGenericParameter(genericParameter).Name));
        }
Example #2
0
        private void InitGenericInstances(GenericParameterHandleCollection genericParams, GenericElementTypes[] instanceArgs, uint[] tok)
        {
            if (instanceArgs.Length != genericParams.Count || tok.Length != genericParams.Count)
            {
                throw new BadImageFormatException("Generic param indices out of bounds");
            }

            for (int i = 0; i < genericParams.Count; i++)
            {
                var key = _mdReader.GetString(_mdReader.GetGenericParameter(genericParams.ElementAt(i)).Name);

                if (instanceArgs[i] == GenericElementTypes.ValueType)
                {
                    string classname = _mdReader.GetString(_mdReader.GetTypeDefinition(MetadataTokens.TypeDefinitionHandle((int)tok[i])).Name);
                    _genericParamInstanceMap[key] = new GenericInstance(instanceArgs[i], classname);
                }
                else
                {
                    _genericParamInstanceMap[key] = new GenericInstance(instanceArgs[i], Enum.GetName(typeof(GenericElementTypes), instanceArgs[i]));
                }
            }

            if ((ReturnType.Flags & SignatureType.SignatureTypeFlags.GENERIC) != 0)
            {
                ReturnType.GenericInstance = _genericParamInstanceMap[ReturnType.TypeName];
            }

            for (int i = 0; i < ArgTypes.Length; i++)
            {
                if ((ArgTypes[i].Flags & SignatureType.SignatureTypeFlags.GENERIC) != 0)
                {
                    ArgTypes[i].GenericInstance = _genericParamInstanceMap[ArgTypes[i].TypeName];
                }
            }
        }
        public override string ToString()
        {
            MetadataReader   reader    = MetadataReader;
            GenericParameter parameter = reader.GetGenericParameter(_handle);

            return(parameter.Name.GetConstantStringValue(reader).Value);
        }
 public GenericParamEntry(PEFile module, GenericParameterHandle handle)
 {
     this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset;
     this.module         = module;
     this.metadata       = module.Metadata;
     this.handle         = handle;
     this.genericParam   = metadata.GetGenericParameter(handle);
 }
        public static void AddDependenciesDueToCustomAttributes(ref DependencyList dependencies, NodeFactory factory, EcmaMethod method)
        {
            MetadataReader         reader       = method.MetadataReader;
            MethodDefinitionHandle methodHandle = method.Handle;
            MethodDefinition       methodDef    = reader.GetMethodDefinition(methodHandle);

            // Handle custom attributes on the method
            AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, methodDef.GetCustomAttributes());

            // Handle custom attributes on method parameters
            foreach (ParameterHandle parameterHandle in methodDef.GetParameters())
            {
                Parameter parameter = reader.GetParameter(parameterHandle);
                AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, parameter.GetCustomAttributes());
            }

            // Handle custom attributes on generic method parameters
            foreach (GenericParameterHandle genericParameterHandle in methodDef.GetGenericParameters())
            {
                GenericParameter parameter = reader.GetGenericParameter(genericParameterHandle);
                AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, parameter.GetCustomAttributes());
            }

            // We don't model properties and events as separate entities within the compiler, so ensuring
            // we can generate custom attributes for the associated events and properties from here
            // is as good as any other place.
            //
            // As a performance optimization, we look for associated events and properties only
            // if the method is SpecialName. This is required for CLS compliance and compilers we
            // care about emit accessors like this.
            if ((methodDef.Attributes & MethodAttributes.SpecialName) != 0)
            {
                TypeDefinition declaringType = reader.GetTypeDefinition(methodDef.GetDeclaringType());

                foreach (PropertyDefinitionHandle propertyHandle in declaringType.GetProperties())
                {
                    PropertyDefinition property  = reader.GetPropertyDefinition(propertyHandle);
                    PropertyAccessors  accessors = property.GetAccessors();

                    if (accessors.Getter == methodHandle || accessors.Setter == methodHandle)
                    {
                        AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, property.GetCustomAttributes());
                    }
                }

                foreach (EventDefinitionHandle eventHandle in declaringType.GetEvents())
                {
                    EventDefinition @event    = reader.GetEventDefinition(eventHandle);
                    EventAccessors  accessors = @event.GetAccessors();

                    if (accessors.Adder == methodHandle || accessors.Remover == methodHandle || accessors.Raiser == methodHandle)
                    {
                        AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, @event.GetCustomAttributes());
                    }
                }
            }
        }
Example #6
0
 private static ImmutableArray <string> GetTypeParameterNames(
     MetadataReader reader,
     GenericParameterHandleCollection handles
     )
 {
     return(ImmutableArray.CreateRange(
                handles.Select(h => reader.GetString(reader.GetGenericParameter(h).Name))
                ));
 }
Example #7
0
            private static void FillArray(IMetadataGenericTypeParameter[] array, GenericContext genericContext, MetadataReader reader, TypeReferenceTypeProvider typeProvider, GenericParameterHandleCollection genericParameters)
            {
                foreach (var handle in genericParameters)
                {
                    var genericParameter = reader.GetGenericParameter(handle);

                    // It's okay to pass in genericContext as we fill the array.
                    // It's coupling to an implementation detail in the same class.
                    array[genericParameter.Index] = new ReaderGenericTypeParameter(reader, typeProvider, genericParameter, genericContext);
                }
            }
        public static void AddDependenciesDueToCustomAttributes(ref DependencyList dependencies, NodeFactory factory, EcmaType type)
        {
            MetadataReader reader  = type.MetadataReader;
            TypeDefinition typeDef = reader.GetTypeDefinition(type.Handle);

            AddDependenciesDueToCustomAttributes(ref dependencies, factory, type.EcmaModule, typeDef.GetCustomAttributes());

            // Handle custom attributes on generic type parameters
            foreach (GenericParameterHandle genericParameterHandle in typeDef.GetGenericParameters())
            {
                GenericParameter parameter = reader.GetGenericParameter(genericParameterHandle);
                AddDependenciesDueToCustomAttributes(ref dependencies, factory, type.EcmaModule, parameter.GetCustomAttributes());
            }
        }
Example #9
0
 static bool FindUsesInGenericConstraints(MetadataReader metadata, GenericParameterHandleCollection collection, FindTypeDecoder decoder)
 {
     foreach (var h in collection)
     {
         var gp = metadata.GetGenericParameter(h);
         foreach (var hc in gp.GetConstraints())
         {
             var gc = metadata.GetGenericParameterConstraint(hc);
             if (decoder.GetTypeFromEntity(metadata, gc.Type))
             {
                 return(true);
             }
         }
     }
     return(false);
 }
Example #10
0
 private static bool TryGetAnonymousTypeKey(
     MetadataReader reader,
     TypeDefinition def,
     ArrayBuilder <AnonymousTypeKeyField> builder)
 {
     foreach (var typeParameterHandle in def.GetGenericParameters())
     {
         var    typeParameter = reader.GetGenericParameter(typeParameterHandle);
         string fieldName;
         if (!GeneratedNames.TryParseAnonymousTypeParameterName(reader.GetString(typeParameter.Name), out fieldName))
         {
             return(false);
         }
         builder.Add(AnonymousTypeKeyField.CreateField(fieldName));
     }
     return(true);
 }
Example #11
0
        private void InitGenericInstances(GenericParameterHandleCollection genericParams, GenericElementTypes[] instanceArgs, uint[] tok)
        {
            if (instanceArgs.Length != genericParams.Count || tok.Length != genericParams.Count)
            {
                throw new BadImageFormatException("Generic param indices out of bounds");
            }

            for (int i = 0; i < instanceArgs.Length; i++)
            {
                string key  = _mdReader.GetString(_mdReader.GetGenericParameter(genericParams.ElementAt(i)).Name);
                string name = instanceArgs[i].ToString();
                if (instanceArgs[i] == GenericElementTypes.ValueType)
                {
                    var t = _mdReader.GetTypeDefinition(MetadataTokens.TypeDefinitionHandle((int)tok[i]));
                    name = _mdReader.GetString(t.Name);
                }
                _genericParamInstanceMap[key] = name;
            }
        }
 void WriteTypeParameter(GenericParameterHandle paramRef, int index, ILNameSyntax syntax)
 {
     if (paramRef.IsNil || syntax == ILNameSyntax.SignatureNoNamedTypeParameters)
     {
         output.Write(index.ToString());
     }
     else
     {
         var param = metadata.GetGenericParameter(paramRef);
         if (param.Name.IsNil)
         {
             output.Write(param.Index.ToString());
         }
         else
         {
             output.Write(DisassemblerHelpers.Escape(metadata.GetString(param.Name)));
         }
     }
 }
Example #13
0
        private static ImmutableArray <string> DecodeTypeParameters(MetadataReader reader, int offset, GenericParameterHandleCollection typeParameters)
        {
            int arity = typeParameters.Count - offset;

            Debug.Assert(arity >= 0);
            if (arity == 0)
            {
                return(ImmutableArray <string> .Empty);
            }
            var builder = ImmutableArray.CreateBuilder <string>(arity);

            for (int i = 0; i < arity; i++)
            {
                var handle        = typeParameters[offset + i];
                var typeParameter = reader.GetGenericParameter(handle);
                builder.Add(reader.GetString(typeParameter.Name));
            }
            return(builder.ToImmutable());
        }
Example #14
0
        /// <summary>
        /// Initialize map of generic parameters names to the type in the instance
        /// </summary>
        private void InitGenericInstances(GenericParameterHandleCollection genericParams, CorElementType[] instanceArgs, uint[] tok)
        {
            if (instanceArgs.Length != genericParams.Count || tok.Length != genericParams.Count)
            {
                throw new BadImageFormatException("Generic param indices out of bounds");
            }

            for (int i = 0; i < instanceArgs.Length; i++)
            {
                string key  = _mdReader.GetString(_mdReader.GetGenericParameter(genericParams.ElementAt(i)).Name); // name of the generic param, eg. "T"
                string type = instanceArgs[i].ToString();                                                          // type of the generic param instance
                if (instanceArgs[i] == CorElementType.ELEMENT_TYPE_VALUETYPE)
                {
                    var t = _mdReader.GetTypeDefinition(MetadataTokens.TypeDefinitionHandle((int)tok[i]));
                    type = _mdReader.GetString(t.Name); // name of the struct
                }
                _genericParamInstanceMap[key] = type;
            }
        }
Example #15
0
        string ToCSharpString(MetadataReader metadata, TypeDefinitionHandle handle, bool fullName)
        {
            StringBuilder builder = new StringBuilder();
            var           currentTypeDefHandle = handle;
            var           typeDef = metadata.GetTypeDefinition(currentTypeDefHandle);

            while (!currentTypeDefHandle.IsNil)
            {
                if (builder.Length > 0)
                {
                    builder.Insert(0, '.');
                }
                typeDef = metadata.GetTypeDefinition(currentTypeDefHandle);
                var part          = ReflectionHelper.SplitTypeParameterCountFromReflectionName(metadata.GetString(typeDef.Name), out int typeParamCount);
                var genericParams = typeDef.GetGenericParameters();
                if (genericParams.Count > 0)
                {
                    builder.Insert(0, '>');
                    int firstIndex = genericParams.Count - typeParamCount;
                    for (int i = genericParams.Count - 1; i >= genericParams.Count - typeParamCount; i--)
                    {
                        builder.Insert(0, metadata.GetString(metadata.GetGenericParameter(genericParams[i]).Name));
                        builder.Insert(0, i == firstIndex ? '<' : ',');
                    }
                }
                builder.Insert(0, part);
                currentTypeDefHandle = typeDef.GetDeclaringType();
                if (!fullName)
                {
                    break;
                }
            }

            if (fullName && !typeDef.Namespace.IsNil)
            {
                builder.Insert(0, '.');
                builder.Insert(0, metadata.GetString(typeDef.Namespace));
            }

            return(builder.ToString());
        }
Example #16
0
        private static bool TryGetAnonymousTypeKey(
            MetadataReader reader,
            TypeDefinition def,
            ArrayBuilder <AnonymousTypeKeyField> builder)
        {
            foreach (var typeParameterHandle in def.GetGenericParameters())
            {
                var    typeParameter = reader.GetGenericParameter(typeParameterHandle);
                string fieldName;
                if (!GeneratedNames.TryParseAnonymousTypeParameterName(reader.GetString(typeParameter.Name), out fieldName))
                {
                    return(false);
                }

#if XSHARP
                builder.Add(new AnonymousTypeKeyField(fieldName, isKey: false, ignoreCase: XSharpString.IgnoreCase));
#else
                builder.Add(new AnonymousTypeKeyField(fieldName, isKey: false, ignoreCase: false));
#endif
            }
            return(true);
        }
Example #17
0
        public SignatureType(ref BlobReader signatureReader, MetadataReader mdReader, GenericParameterHandleCollection genericParams)
        {
            SignatureTypeCode signatureTypeCode = signatureReader.ReadSignatureTypeCode();

            Flags = 0;
            if (signatureTypeCode == SignatureTypeCode.SZArray)
            {
                Flags            |= SignatureTypeFlags.ARRAY;
                signatureTypeCode = signatureReader.ReadSignatureTypeCode();
            }

            TypeName = signatureTypeCode.ToString();
            if (signatureTypeCode == SignatureTypeCode.TypeHandle || signatureTypeCode == SignatureTypeCode.ByReference)
            {
                if (signatureTypeCode == SignatureTypeCode.ByReference)
                {
                    Flags |= SignatureTypeFlags.REFERENCE;
                }

                EntityHandle handle = signatureReader.ReadTypeHandle();
                if (handle.Kind == HandleKind.TypeDefinition)
                {
                    TypeDefinition typeDef = mdReader.GetTypeDefinition((TypeDefinitionHandle)handle);
                    TypeName = mdReader.GetString(typeDef.Name);
                }
                else if (handle.Kind == HandleKind.TypeReference)
                {
                    TypeReference typeRef = mdReader.GetTypeReference((TypeReferenceHandle)handle);
                    TypeName = mdReader.GetString(typeRef.Name);
                }
            }
            else if (signatureTypeCode == SignatureTypeCode.GenericMethodParameter)
            {
                int index = signatureReader.ReadCompressedInteger();
                GenericParameter generic = mdReader.GetGenericParameter(genericParams[index]);
                TypeName = mdReader.GetString(generic.Name);
                Flags   |= SignatureTypeFlags.GENERIC;
            }
        }
        private void WriteGenericParam()
        {
            AddHeader(
                "Name",
                "Seq#",
                "Attributes",
                "TypeConstraints"
                );

            for (int i = 1, count = reader.GetTableRowCount(TableIndex.GenericParam); i <= count; i++)
            {
                var entry = reader.GetGenericParameter(MetadataTokens.GenericParameterHandle(i));

                AddRow(
                    Literal(entry.Name),
                    entry.Index.ToString(),
                    EnumValue <int>(entry.Attributes),
                    TokenRange(entry.GetConstraints(), h => h)
                    );
            }

            WriteRows("GenericParam (0x2a):");
        }
Example #19
0
 public static string ToString(this MetadataReader reader, GenericParameterHandle x) => reader.ToString(reader.GetGenericParameter(x));
Example #20
0
 private EcmaFormatRuntimeGenericParameterTypeInfoForTypes(MetadataReader reader, GenericParameterHandle genericParameterHandle, RuntimeTypeDefinitionTypeInfo declaringType)
     : base(reader, genericParameterHandle, reader.GetGenericParameter(genericParameterHandle))
 {
     _declaringType = declaringType;
 }
Example #21
0
            protected override TypeAnnotations CreateValueFromKey(TypeDesc key)
            {
                // We scan the entire type at this point; the reason for doing that is properties.
                //
                // We allow annotating properties, but those annotations need to flow onto individual get/set methods
                // and backing fields. Without scanning all properties, we can't answer questions about fields/methods.
                // And if we're going over all properties, we might as well go over everything else to keep things simple.

                Debug.Assert(key.IsTypeDefinition);
                if (key is not EcmaType ecmaType)
                {
                    return(new TypeAnnotations(key, DynamicallyAccessedMemberTypes.None, null, null, null));
                }

                MetadataReader reader = ecmaType.MetadataReader;

                // class, interface, struct can have annotations
                TypeDefinition typeDef = reader.GetTypeDefinition(ecmaType.Handle);
                DynamicallyAccessedMemberTypes typeAnnotation = GetMemberTypesForDynamicallyAccessedMembersAttribute(reader, typeDef.GetCustomAttributes());

                try
                {
                    // Also inherit annotation from bases
                    TypeDesc baseType = key.BaseType;
                    while (baseType != null)
                    {
                        TypeDefinition baseTypeDef = reader.GetTypeDefinition(((EcmaType)baseType.GetTypeDefinition()).Handle);
                        typeAnnotation |= GetMemberTypesForDynamicallyAccessedMembersAttribute(reader, baseTypeDef.GetCustomAttributes());
                        baseType        = baseType.BaseType;
                    }

                    // And inherit them from interfaces
                    foreach (DefType runtimeInterface in key.RuntimeInterfaces)
                    {
                        TypeDefinition interfaceTypeDef = reader.GetTypeDefinition(((EcmaType)runtimeInterface.GetTypeDefinition()).Handle);
                        typeAnnotation |= GetMemberTypesForDynamicallyAccessedMembersAttribute(reader, interfaceTypeDef.GetCustomAttributes());
                    }
                }
                catch (TypeSystemException)
                {
                    // If the class hierarchy is not walkable, just stop collecting the annotations.
                }

                var annotatedFields = new ArrayBuilder <FieldAnnotation>();

                // First go over all fields with an explicit annotation
                foreach (EcmaField field in ecmaType.GetFields())
                {
                    FieldDefinition fieldDef = reader.GetFieldDefinition(field.Handle);
                    DynamicallyAccessedMemberTypes annotation =
                        GetMemberTypesForDynamicallyAccessedMembersAttribute(reader, fieldDef.GetCustomAttributes());
                    if (annotation == DynamicallyAccessedMemberTypes.None)
                    {
                        continue;
                    }

                    if (!IsTypeInterestingForDataflow(field.FieldType))
                    {
                        // Already know that there's a non-empty annotation on a field which is not System.Type/String and we're about to ignore it
                        _logger.LogWarning(field, DiagnosticId.DynamicallyAccessedMembersOnFieldCanOnlyApplyToTypesOrStrings, field.GetDisplayName());
                        continue;
                    }

                    annotatedFields.Add(new FieldAnnotation(field, annotation));
                }

                var annotatedMethods = new ArrayBuilder <MethodAnnotations>();

                // Next go over all methods with an explicit annotation
                foreach (EcmaMethod method in ecmaType.GetMethods())
                {
                    DynamicallyAccessedMemberTypes[]? paramAnnotations = null;

                    // We convert indices from metadata space to IL space here.
                    // IL space assigns index 0 to the `this` parameter on instance methods.

                    DynamicallyAccessedMemberTypes methodMemberTypes =
                        GetMemberTypesForDynamicallyAccessedMembersAttribute(reader, reader.GetMethodDefinition(method.Handle).GetCustomAttributes());

                    MethodSignature signature;
                    try
                    {
                        signature = method.Signature;
                    }
                    catch (TypeSystemException)
                    {
                        // If we cannot resolve things in the signature, just move along.
                        continue;
                    }

                    int offset;
                    if (!signature.IsStatic)
                    {
                        offset = 1;
                    }
                    else
                    {
                        offset = 0;
                    }

                    // If there's an annotation on the method itself and it's one of the special types (System.Type for example)
                    // treat that annotation as annotating the "this" parameter.
                    if (methodMemberTypes != DynamicallyAccessedMemberTypes.None)
                    {
                        if (IsTypeInterestingForDataflow(method.OwningType) && !signature.IsStatic)
                        {
                            paramAnnotations    = new DynamicallyAccessedMemberTypes[signature.Length + offset];
                            paramAnnotations[0] = methodMemberTypes;
                        }
                        else
                        {
                            _logger.LogWarning(method, DiagnosticId.DynamicallyAccessedMembersIsNotAllowedOnMethods);
                        }
                    }

                    MethodDefinition          methodDef        = reader.GetMethodDefinition(method.Handle);
                    ParameterHandleCollection parameterHandles = methodDef.GetParameters();

                    DynamicallyAccessedMemberTypes returnAnnotation = DynamicallyAccessedMemberTypes.None;

                    foreach (ParameterHandle parameterHandle in parameterHandles)
                    {
                        Parameter parameter = reader.GetParameter(parameterHandle);

                        if (parameter.SequenceNumber == 0)
                        {
                            // this is the return parameter
                            returnAnnotation = GetMemberTypesForDynamicallyAccessedMembersAttribute(reader, parameter.GetCustomAttributes());
                            if (returnAnnotation != DynamicallyAccessedMemberTypes.None && !IsTypeInterestingForDataflow(signature.ReturnType))
                            {
                                _logger.LogWarning(method, DiagnosticId.DynamicallyAccessedMembersOnMethodReturnValueCanOnlyApplyToTypesOrStrings, method.GetDisplayName());
                            }
                        }
                        else
                        {
                            DynamicallyAccessedMemberTypes pa = GetMemberTypesForDynamicallyAccessedMembersAttribute(reader, parameter.GetCustomAttributes());
                            if (pa == DynamicallyAccessedMemberTypes.None)
                            {
                                continue;
                            }

                            if (!IsTypeInterestingForDataflow(signature[parameter.SequenceNumber - 1]))
                            {
                                _logger.LogWarning(method, DiagnosticId.DynamicallyAccessedMembersOnMethodParameterCanOnlyApplyToTypesOrStrings, DiagnosticUtilities.GetParameterNameForErrorMessage(method, parameter.SequenceNumber - 1), method.GetDisplayName());
                                continue;
                            }

                            if (paramAnnotations == null)
                            {
                                paramAnnotations = new DynamicallyAccessedMemberTypes[signature.Length + offset];
                            }
                            paramAnnotations[parameter.SequenceNumber - 1 + offset] = pa;
                        }
                    }

                    DynamicallyAccessedMemberTypes[]? genericParameterAnnotations = null;
                    foreach (EcmaGenericParameter genericParameter in method.Instantiation)
                    {
                        GenericParameter genericParameterDef = reader.GetGenericParameter(genericParameter.Handle);
                        var annotation = GetMemberTypesForDynamicallyAccessedMembersAttribute(reader, genericParameterDef.GetCustomAttributes());
                        if (annotation != DynamicallyAccessedMemberTypes.None)
                        {
                            if (genericParameterAnnotations == null)
                            {
                                genericParameterAnnotations = new DynamicallyAccessedMemberTypes[method.Instantiation.Length];
                            }
                            genericParameterAnnotations[genericParameter.Index] = annotation;
                        }
                    }

                    if (returnAnnotation != DynamicallyAccessedMemberTypes.None || paramAnnotations != null || genericParameterAnnotations != null)
                    {
                        annotatedMethods.Add(new MethodAnnotations(method, paramAnnotations, returnAnnotation, genericParameterAnnotations));
                    }
                }

                // Next up are properties. Annotations on properties are kind of meta because we need to
                // map them to annotations on methods/fields. They're syntactic sugar - what they do is expressible
                // by placing attribute on the accessor/backing field. For complex properties, that's what people
                // will need to do anyway. Like so:
                //
                // [field: Attribute]
                // Type MyProperty
                // {
                //     [return: Attribute]
                //     get;
                //     [value: Attribute]
                //     set;
                //  }

                foreach (PropertyDefinitionHandle propertyHandle in reader.GetTypeDefinition(ecmaType.Handle).GetProperties())
                {
                    DynamicallyAccessedMemberTypes annotation = GetMemberTypesForDynamicallyAccessedMembersAttribute(
                        reader, reader.GetPropertyDefinition(propertyHandle).GetCustomAttributes());
                    if (annotation == DynamicallyAccessedMemberTypes.None)
                    {
                        continue;
                    }

                    PropertyPseudoDesc property = new PropertyPseudoDesc(ecmaType, propertyHandle);

                    if (!IsTypeInterestingForDataflow(property.Signature.ReturnType))
                    {
                        _logger.LogWarning(property, DiagnosticId.DynamicallyAccessedMembersOnPropertyCanOnlyApplyToTypesOrStrings, property.GetDisplayName());
                        continue;
                    }

                    FieldDesc?backingFieldFromSetter = null;

                    // Propagate the annotation to the setter method
                    MethodDesc setMethod = property.SetMethod;
                    if (setMethod != null)
                    {
                        // Abstract property backing field propagation doesn't make sense, and any derived property will be validated
                        // to have the exact same annotations on getter/setter, and thus if it has a detectable backing field that will be validated as well.
                        MethodIL methodBody = _ilProvider.GetMethodIL(setMethod);
                        if (methodBody != null)
                        {
                            // Look for the compiler generated backing field. If it doesn't work out simply move on. In such case we would still
                            // propagate the annotation to the setter/getter and later on when analyzing the setter/getter we will warn
                            // that the field (which ever it is) must be annotated as well.
                            ScanMethodBodyForFieldAccess(methodBody, write: true, out backingFieldFromSetter);
                        }

                        if (annotatedMethods.Any(a => a.Method == setMethod))
                        {
                            _logger.LogWarning(setMethod, DiagnosticId.DynamicallyAccessedMembersConflictsBetweenPropertyAndAccessor, property.GetDisplayName(), setMethod.GetDisplayName());
                        }
                        else
                        {
                            int offset = setMethod.Signature.IsStatic ? 0 : 1;
                            if (setMethod.Signature.Length > 0)
                            {
                                DynamicallyAccessedMemberTypes[] paramAnnotations = new DynamicallyAccessedMemberTypes[setMethod.Signature.Length + offset];
                                paramAnnotations[paramAnnotations.Length - 1] = annotation;
                                annotatedMethods.Add(new MethodAnnotations(setMethod, paramAnnotations, DynamicallyAccessedMemberTypes.None, null));
                            }
                        }
                    }

                    FieldDesc?backingFieldFromGetter = null;

                    // Propagate the annotation to the getter method
                    MethodDesc getMethod = property.GetMethod;
                    if (getMethod != null)
                    {
                        // Abstract property backing field propagation doesn't make sense, and any derived property will be validated
                        // to have the exact same annotations on getter/setter, and thus if it has a detectable backing field that will be validated as well.
                        MethodIL methodBody = _ilProvider.GetMethodIL(getMethod);
                        if (methodBody != null)
                        {
                            // Look for the compiler generated backing field. If it doesn't work out simply move on. In such case we would still
                            // propagate the annotation to the setter/getter and later on when analyzing the setter/getter we will warn
                            // that the field (which ever it is) must be annotated as well.
                            ScanMethodBodyForFieldAccess(methodBody, write: false, out backingFieldFromGetter);
                        }

                        if (annotatedMethods.Any(a => a.Method == getMethod))
                        {
                            _logger.LogWarning(getMethod, DiagnosticId.DynamicallyAccessedMembersConflictsBetweenPropertyAndAccessor, property.GetDisplayName(), getMethod.GetDisplayName());
                        }
                        else
                        {
                            annotatedMethods.Add(new MethodAnnotations(getMethod, null, annotation, null));
                        }
                    }

                    FieldDesc?backingField;
                    if (backingFieldFromGetter != null && backingFieldFromSetter != null &&
                        backingFieldFromGetter != backingFieldFromSetter)
                    {
                        _logger.LogWarning(property, DiagnosticId.DynamicallyAccessedMembersCouldNotFindBackingField, property.GetDisplayName());
                        backingField = null;
                    }
                    else
                    {
                        backingField = backingFieldFromGetter ?? backingFieldFromSetter;
                    }

                    if (backingField != null)
                    {
                        if (annotatedFields.Any(a => a.Field == backingField))
                        {
                            _logger.LogWarning(backingField, DiagnosticId.DynamicallyAccessedMembersOnPropertyConflictsWithBackingField, property.GetDisplayName(), backingField.GetDisplayName());
                        }
                        else
                        {
                            annotatedFields.Add(new FieldAnnotation(backingField, annotation));
                        }
                    }
                }

                DynamicallyAccessedMemberTypes[]? typeGenericParameterAnnotations = null;
                foreach (EcmaGenericParameter genericParameter in ecmaType.Instantiation)
                {
                    GenericParameter genericParameterDef = reader.GetGenericParameter(genericParameter.Handle);

                    var annotation = GetMemberTypesForDynamicallyAccessedMembersAttribute(reader, genericParameterDef.GetCustomAttributes());
                    if (annotation != DynamicallyAccessedMemberTypes.None)
                    {
                        if (typeGenericParameterAnnotations == null)
                        {
                            typeGenericParameterAnnotations = new DynamicallyAccessedMemberTypes[ecmaType.Instantiation.Length];
                        }
                        typeGenericParameterAnnotations[genericParameter.Index] = annotation;
                    }
                }

                return(new TypeAnnotations(ecmaType, typeAnnotation, annotatedMethods.ToArray(), annotatedFields.ToArray(), typeGenericParameterAnnotations));
            }
Example #22
0
        public override string ToString()
        {
            MetadataReader reader = _module.MetadataReader;

            return(reader.GetString(reader.GetGenericParameter(_handle).Name));
        }
Example #23
0
 public static GenericParameter GetGenericParameter(MetadataReader reader, GenericParameterHandle handle)
 {
     return(reader.GetGenericParameter(handle));
 }
Example #24
0
        public override string GetEntityName(PEFile module, EntityHandle handle, bool fullName)
        {
            MetadataReader metadata = module.Metadata;

            switch (handle.Kind)
            {
            case HandleKind.TypeDefinition:
                return(ToCSharpString(metadata, (TypeDefinitionHandle)handle, fullName));

            case HandleKind.FieldDefinition:
                var fd            = metadata.GetFieldDefinition((FieldDefinitionHandle)handle);
                var declaringType = fd.GetDeclaringType();
                if (fullName)
                {
                    return(ToCSharpString(metadata, declaringType, fullName) + "." + metadata.GetString(fd.Name));
                }
                return(metadata.GetString(fd.Name));

            case HandleKind.MethodDefinition:
                var md = metadata.GetMethodDefinition((MethodDefinitionHandle)handle);
                declaringType = md.GetDeclaringType();
                string methodName = metadata.GetString(md.Name);
                switch (methodName)
                {
                case ".ctor":
                case ".cctor":
                    var td = metadata.GetTypeDefinition(declaringType);
                    methodName = ReflectionHelper.SplitTypeParameterCountFromReflectionName(metadata.GetString(td.Name));
                    break;

                case "Finalize":
                    const MethodAttributes finalizerAttributes = (MethodAttributes.Virtual | MethodAttributes.Family | MethodAttributes.HideBySig);
                    if ((md.Attributes & finalizerAttributes) != finalizerAttributes)
                    {
                        goto default;
                    }
                    MethodSignature <IType> methodSignature = md.DecodeSignature(MetadataExtensions.MinimalSignatureTypeProvider, default);
                    if (methodSignature.GenericParameterCount != 0 || methodSignature.ParameterTypes.Length != 0)
                    {
                        goto default;
                    }
                    td         = metadata.GetTypeDefinition(declaringType);
                    methodName = "~" + ReflectionHelper.SplitTypeParameterCountFromReflectionName(metadata.GetString(td.Name));
                    break;

                default:
                    var genericParams = md.GetGenericParameters();
                    if (genericParams.Count > 0)
                    {
                        methodName += "<";
                        int i = 0;
                        foreach (var h in genericParams)
                        {
                            if (i > 0)
                            {
                                methodName += ",";
                            }
                            var gp = metadata.GetGenericParameter(h);
                            methodName += metadata.GetString(gp.Name);
                        }
                        methodName += ">";
                    }
                    break;
                }
                if (fullName)
                {
                    return(ToCSharpString(metadata, declaringType, fullName) + "." + methodName);
                }
                return(methodName);

            case HandleKind.EventDefinition:
                var ed = metadata.GetEventDefinition((EventDefinitionHandle)handle);
                declaringType = metadata.GetMethodDefinition(ed.GetAccessors().GetAny()).GetDeclaringType();
                if (fullName)
                {
                    return(ToCSharpString(metadata, declaringType, fullName) + "." + metadata.GetString(ed.Name));
                }
                return(metadata.GetString(ed.Name));

            case HandleKind.PropertyDefinition:
                var pd = metadata.GetPropertyDefinition((PropertyDefinitionHandle)handle);
                declaringType = metadata.GetMethodDefinition(pd.GetAccessors().GetAny()).GetDeclaringType();
                if (fullName)
                {
                    return(ToCSharpString(metadata, declaringType, fullName) + "." + metadata.GetString(pd.Name));
                }
                return(metadata.GetString(pd.Name));

            default:
                return(null);
            }
        }
Example #25
0
        public override string GetEntityName(PEFile module, EntityHandle handle, bool fullName)
        {
            MetadataReader metadata = module.Metadata;

            switch (handle.Kind)
            {
            case HandleKind.TypeDefinition:
                return(ToCSharpString(metadata, (TypeDefinitionHandle)handle, fullName));

            case HandleKind.FieldDefinition:
                var fd            = metadata.GetFieldDefinition((FieldDefinitionHandle)handle);
                var declaringType = fd.GetDeclaringType();
                if (fullName)
                {
                    return(ToCSharpString(metadata, declaringType, fullName) + "." + metadata.GetString(fd.Name));
                }
                return(metadata.GetString(fd.Name));

            case HandleKind.MethodDefinition:
                var md = metadata.GetMethodDefinition((MethodDefinitionHandle)handle);
                declaringType = md.GetDeclaringType();
                string methodName = metadata.GetString(md.Name);
                if (methodName == ".ctor" || methodName == ".cctor")
                {
                    var td = metadata.GetTypeDefinition(declaringType);
                    methodName = ReflectionHelper.SplitTypeParameterCountFromReflectionName(metadata.GetString(td.Name));
                }
                else
                {
                    var genericParams = md.GetGenericParameters();
                    if (genericParams.Count > 0)
                    {
                        methodName += "<";
                        int i = 0;
                        foreach (var h in genericParams)
                        {
                            if (i > 0)
                            {
                                methodName += ",";
                            }
                            var gp = metadata.GetGenericParameter(h);
                            methodName += metadata.GetString(gp.Name);
                        }
                        methodName += ">";
                    }
                }
                if (fullName)
                {
                    return(ToCSharpString(metadata, declaringType, fullName) + "." + methodName);
                }
                return(methodName);

            case HandleKind.EventDefinition:
                var ed = metadata.GetEventDefinition((EventDefinitionHandle)handle);
                declaringType = metadata.GetMethodDefinition(ed.GetAccessors().GetAny()).GetDeclaringType();
                if (fullName)
                {
                    return(ToCSharpString(metadata, declaringType, fullName) + "." + metadata.GetString(ed.Name));
                }
                return(metadata.GetString(ed.Name));

            case HandleKind.PropertyDefinition:
                var pd = metadata.GetPropertyDefinition((PropertyDefinitionHandle)handle);
                declaringType = metadata.GetMethodDefinition(pd.GetAccessors().GetAny()).GetDeclaringType();
                if (fullName)
                {
                    return(ToCSharpString(metadata, declaringType, fullName) + "." + metadata.GetString(pd.Name));
                }
                return(metadata.GetString(pd.Name));

            default:
                return(null);
            }
        }
Example #26
0
 public static GenericParameter GetGenericParameter(this GenericParameterHandle handle, MetadataReader reader) => reader.GetGenericParameter(handle);
        public void SimpleSignatureProviderCoverage()
        {
            using (FileStream stream = File.OpenRead(AssemblyPathHelper.GetAssemblyLocation(typeof(SignaturesToDecode <>).GetTypeInfo().Assembly)))
                using (var peReader = new PEReader(stream))
                {
                    MetadataReader       reader     = peReader.GetMetadataReader();
                    var                  provider   = new DisassemblingTypeProvider();
                    TypeDefinitionHandle typeHandle = TestMetadataResolver.FindTestType(reader, typeof(SignaturesToDecode <>));
                    Assert.Equal("System.Reflection.Metadata.Decoding.Tests.SignatureDecoderTests/SignaturesToDecode`1", provider.GetTypeFromHandle(reader, genericContext: null, handle: typeHandle));

                    TypeDefinition type = reader.GetTypeDefinition(typeHandle);
                    Dictionary <string, string> expectedFields        = GetExpectedFieldSignatures();
                    ImmutableArray <string>     genericTypeParameters = type.GetGenericParameters().Select(h => reader.GetString(reader.GetGenericParameter(h).Name)).ToImmutableArray();

                    var genericTypeContext = new DisassemblingGenericContext(genericTypeParameters, ImmutableArray <string> .Empty);

                    foreach (var fieldHandle in type.GetFields())
                    {
                        FieldDefinition field     = reader.GetFieldDefinition(fieldHandle);
                        string          fieldName = reader.GetString(field.Name);
                        string          expected;
                        Assert.True(expectedFields.TryGetValue(fieldName, out expected), "Unexpected field: " + fieldName);
                        Assert.Equal(expected, field.DecodeSignature(provider, genericTypeContext));
                    }

                    Dictionary <string, string> expectedMethods = GetExpectedMethodSignatures();
                    foreach (var methodHandle in type.GetMethods())
                    {
                        MethodDefinition method = reader.GetMethodDefinition(methodHandle);

                        ImmutableArray <string> genericMethodParameters = method.GetGenericParameters().Select(h => reader.GetString(reader.GetGenericParameter(h).Name)).ToImmutableArray();
                        var genericMethodContext = new DisassemblingGenericContext(genericTypeParameters, genericMethodParameters);

                        string methodName = reader.GetString(method.Name);
                        string expected;
                        Assert.True(expectedMethods.TryGetValue(methodName, out expected), "Unexpected method: " + methodName);
                        MethodSignature <string> signature = method.DecodeSignature(provider, genericMethodContext);
                        Assert.True(signature.Header.Kind == SignatureKind.Method);

                        if (methodName.StartsWith("Generic"))
                        {
                            Assert.Equal(1, signature.GenericParameterCount);
                        }
                        else
                        {
                            Assert.Equal(0, signature.GenericParameterCount);
                        }

                        Assert.True(signature.GenericParameterCount <= 1 && (methodName != "GenericMethodParameter" || signature.GenericParameterCount == 1));
                        Assert.Equal(expected, provider.GetFunctionPointerType(signature));
                    }

                    Dictionary <string, string> expectedProperties = GetExpectedPropertySignatures();
                    foreach (var propertyHandle in type.GetProperties())
                    {
                        PropertyDefinition property     = reader.GetPropertyDefinition(propertyHandle);
                        string             propertyName = reader.GetString(property.Name);
                        string             expected;
                        Assert.True(expectedProperties.TryGetValue(propertyName, out expected), "Unexpected property: " + propertyName);
                        MethodSignature <string> signature = property.DecodeSignature(provider, genericTypeContext);
                        Assert.True(signature.Header.Kind == SignatureKind.Property);
                        Assert.Equal(expected, provider.GetFunctionPointerType(signature));
                    }

                    Dictionary <string, string> expectedEvents = GetExpectedEventSignatures();
                    foreach (var eventHandle in type.GetEvents())
                    {
                        EventDefinition @event    = reader.GetEventDefinition(eventHandle);
                        string          eventName = reader.GetString(@event.Name);
                        string          expected;
                        Assert.True(expectedEvents.TryGetValue(eventName, out expected), "Unexpected event: " + eventName);

                        Assert.Equal(expected, provider.GetTypeFromHandle(reader, genericTypeContext, @event.Type));
                    }

                    Assert.Equal($"[{CollectionsAssemblyName}]System.Collections.Generic.List`1<!T>", provider.GetTypeFromHandle(reader, genericTypeContext, handle: type.BaseType));
                }
        }
 private EcmaFormatRuntimeGenericParameterTypeInfoForTypes(MetadataReader reader, GenericParameterHandle genericParameterHandle, RuntimeTypeInfo declaringRuntimeNamedTypeInfo)
     : base(reader, genericParameterHandle, reader.GetGenericParameter(genericParameterHandle))
 {
     _declaringRuntimeNamedTypeInfo = declaringRuntimeNamedTypeInfo;
 }
Example #29
0
 private EcmaFormatRuntimeGenericParameterTypeInfoForMethods(MetadataReader reader, GenericParameterHandle genericParameterHandle, RuntimeNamedMethodInfo declaringRuntimeNamedMethodInfo)
     : base(reader, genericParameterHandle, reader.GetGenericParameter(genericParameterHandle))
 {
     Debug.Assert(declaringRuntimeNamedMethodInfo.DeclaringType.IsTypeDefinition);
     _declaringRuntimeNamedMethodInfo = declaringRuntimeNamedMethodInfo;
 }