|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using Internal.Metadata.NativeFormat.Writer;
using Cts = Internal.TypeSystem;
using Ecma = System.Reflection.Metadata;
using MethodSemanticsAttributes = Internal.Metadata.NativeFormat.MethodSemanticsAttributes;
using CallingConventions = System.Reflection.CallingConventions;
namespace ILCompiler.Metadata
{
internal partial class Transform<TPolicy>
{
private Property HandleProperty(Cts.Ecma.EcmaModule module, Ecma.PropertyDefinitionHandle property)
{
Ecma.MetadataReader reader = module.MetadataReader;
Ecma.PropertyDefinition propDef = reader.GetPropertyDefinition(property);
Ecma.PropertyAccessors acc = propDef.GetAccessors();
Cts.MethodDesc getterMethod = acc.Getter.IsNil ? null : module.GetMethod(acc.Getter);
Cts.MethodDesc setterMethod = acc.Setter.IsNil ? null : module.GetMethod(acc.Setter);
bool getterHasMetadata = getterMethod != null && _policy.GeneratesMetadata(getterMethod);
bool setterHasMetadata = setterMethod != null && _policy.GeneratesMetadata(setterMethod);
// Policy: If neither the getter nor setter have metadata, property doesn't have metadata
if (!getterHasMetadata && !setterHasMetadata)
return null;
Ecma.BlobReader sigBlobReader = reader.GetBlobReader(propDef.Signature);
Cts.PropertySignature sig = new Cts.Ecma.EcmaSignatureParser(module, sigBlobReader, Cts.NotFoundBehavior.Throw).ParsePropertySignature();
Property result = new Property
{
Name = HandleString(reader.GetString(propDef.Name)),
Flags = propDef.Attributes,
Signature = new PropertySignature
{
CallingConvention = sig.IsStatic ? CallingConventions.Standard : CallingConventions.HasThis,
},
};
result.Signature.Parameters.Capacity = sig.Length;
if (!sig.HasEmbeddedSignatureData)
{
result.Signature.Type = HandleType(sig.ReturnType);
for (int i = 0; i < sig.Length; i++)
result.Signature.Parameters.Add(HandleType(sig[i]));
}
else
{
sigBlobReader.ReadSignatureHeader();
int count = sigBlobReader.ReadCompressedInteger();
result.Signature.Type = HandleType(module, ref sigBlobReader);
for (int i = 0; i < count; i++)
result.Signature.Parameters.Add(HandleType(module, ref sigBlobReader));
}
if (getterHasMetadata)
{
result.MethodSemantics.Add(new MethodSemantics
{
Attributes = MethodSemanticsAttributes.Getter,
Method = HandleMethodDefinition(getterMethod),
});
}
if (setterHasMetadata)
{
result.MethodSemantics.Add(new MethodSemantics
{
Attributes = MethodSemanticsAttributes.Setter,
Method = HandleMethodDefinition(setterMethod),
});
}
Ecma.ConstantHandle defaultValue = propDef.GetDefaultValue();
if (!defaultValue.IsNil)
{
result.DefaultValue = HandleConstant(module, defaultValue);
}
Ecma.CustomAttributeHandleCollection customAttributes = propDef.GetCustomAttributes();
if (customAttributes.Count > 0)
{
result.CustomAttributes = HandleCustomAttributes(module, customAttributes);
}
return result;
}
}
}
|