using System.Collections.Generic;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.IO;
namespace Semmle.Extraction.CIL.Entities
{
///
/// A property.
///
internal sealed class Property : LabelledEntity, ICustomModifierReceiver
{
private readonly Handle handle;
private readonly Type type;
private readonly PropertyDefinition pd;
private readonly IGenericContext gc;
public Property(IGenericContext gc, Type type, PropertyDefinitionHandle handle) : base(gc.Context)
{
this.gc = gc;
this.handle = handle;
pd = Context.MdReader.GetPropertyDefinition(handle);
this.type = type;
}
public override void WriteId(TextWriter trapFile)
{
trapFile.WriteSubId(type);
trapFile.Write('.');
trapFile.Write(Context.GetString(pd.Name));
trapFile.Write("(");
var index = 0;
var signature = pd.DecodeSignature(new SignatureDecoder(), gc);
foreach (var param in signature.ParameterTypes)
{
trapFile.WriteSeparator(",", ref index);
param.WriteId(trapFile, gc);
}
trapFile.Write(")");
trapFile.Write(";cil-property");
}
public override bool Equals(object? obj)
{
return obj is Property property && Equals(handle, property.handle);
}
public override int GetHashCode() => handle.GetHashCode();
public override IEnumerable Contents
{
get
{
yield return Tuples.metadata_handle(this, Context.Assembly, MetadataTokens.GetToken(handle));
var sig = pd.DecodeSignature(Context.TypeSignatureDecoder, type);
var name = Context.ShortName(pd.Name);
var t = sig.ReturnType;
if (t is ModifiedType mt)
{
t = mt.Unmodified;
yield return Tuples.cil_custom_modifiers(this, mt.Modifier, mt.IsRequired);
}
if (t is ByRefType brt)
{
t = brt.ElementType;
yield return Tuples.cil_type_annotation(this, TypeAnnotation.Ref);
}
yield return Tuples.cil_property(this, type, name, t);
var accessors = pd.GetAccessors();
if (!accessors.Getter.IsNil)
{
var getter = (Method)Context.CreateGeneric(type, accessors.Getter);
yield return getter;
yield return Tuples.cil_getter(this, getter);
}
if (!accessors.Setter.IsNil)
{
var setter = (Method)Context.CreateGeneric(type, accessors.Setter);
yield return setter;
yield return Tuples.cil_setter(this, setter);
}
foreach (var c in Attribute.Populate(Context, this, pd.GetCustomAttributes()))
yield return c;
}
}
}
}