mirror of
https://github.com/github/codeql.git
synced 2025-12-18 18:10:39 +01:00
101 lines
3.4 KiB
C#
101 lines
3.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reflection.Metadata;
|
|
|
|
namespace Semmle.Extraction.CIL.Entities
|
|
{
|
|
/// <summary>
|
|
/// A CIL attribute.
|
|
/// </summary>
|
|
interface IAttribute : IExtractedEntity
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Entity representing a CIL attribute.
|
|
/// </summary>
|
|
class Attribute : UnlabelledEntity, IAttribute
|
|
{
|
|
readonly CustomAttribute attrib;
|
|
readonly IEntity @object;
|
|
|
|
public Attribute(Context cx, IEntity @object, CustomAttributeHandle handle) : base(cx)
|
|
{
|
|
attrib = cx.mdReader.GetCustomAttribute(handle);
|
|
this.@object = @object;
|
|
}
|
|
|
|
public override IEnumerable<IExtractionProduct> Contents
|
|
{
|
|
get
|
|
{
|
|
var constructor = (Method)cx.Create(attrib.Constructor);
|
|
yield return constructor;
|
|
|
|
yield return Tuples.cil_attribute(this, @object, constructor);
|
|
|
|
CustomAttributeValue<Type> decoded;
|
|
|
|
try
|
|
{
|
|
decoded = attrib.DecodeValue(new CustomAttributeDecoder(cx));
|
|
}
|
|
catch (NotImplementedException)
|
|
{
|
|
// Attribute decoding is only partial at this stage.
|
|
yield break;
|
|
}
|
|
|
|
for (int index = 0; index < decoded.FixedArguments.Length; ++index)
|
|
{
|
|
object value = decoded.FixedArguments[index].Value;
|
|
yield return Tuples.cil_attribute_positional_argument(this, index, value == null ? "null" : value.ToString());
|
|
}
|
|
|
|
foreach (var p in decoded.NamedArguments)
|
|
{
|
|
object value = p.Value;
|
|
yield return Tuples.cil_attribute_named_argument(this, p.Name, value == null ? "null" : value.ToString());
|
|
}
|
|
}
|
|
}
|
|
|
|
public static IEnumerable<IExtractionProduct> Populate(Context cx, IEntity @object, CustomAttributeHandleCollection attributes)
|
|
{
|
|
foreach (var attrib in attributes)
|
|
{
|
|
yield return new Attribute(cx, @object, attrib);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Helper class to decode the attribute structure.
|
|
/// Note that there are some unhandled cases that should be fixed in due course.
|
|
/// </summary>
|
|
class CustomAttributeDecoder : ICustomAttributeTypeProvider<Type>
|
|
{
|
|
readonly Context cx;
|
|
public CustomAttributeDecoder(Context cx) { this.cx = cx; }
|
|
|
|
public Type GetPrimitiveType(PrimitiveTypeCode typeCode) => cx.Populate(new PrimitiveType(cx, typeCode));
|
|
|
|
public Type GetSystemType() => throw new NotImplementedException();
|
|
|
|
public Type GetSZArrayType(Type elementType) =>
|
|
cx.Populate(new ArrayType(cx, elementType));
|
|
|
|
public Type GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind) =>
|
|
(Type)cx.Create(handle);
|
|
|
|
public Type GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind) =>
|
|
(Type)cx.Create(handle);
|
|
|
|
public Type GetTypeFromSerializedName(string name) => throw new NotImplementedException();
|
|
|
|
public PrimitiveTypeCode GetUnderlyingEnumType(Type type) => throw new NotImplementedException();
|
|
|
|
public bool IsSystemType(Type type) => type is PrimitiveType; // ??
|
|
}
|
|
}
|