using System;
using System.Reflection.Metadata;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using Semmle.Util;
namespace Semmle.Extraction.CIL.Entities
{
///
/// A method entity.
///
internal abstract class Method : TypeContainer, IMember
{
protected MethodTypeParameter[]? genericParams;
protected GenericContext gc;
protected MethodSignature signature;
protected Method(GenericContext gc) : base(gc.Cx)
{
this.gc = gc;
}
public override IEnumerable TypeParameters => gc.TypeParameters.Concat(DeclaringType.TypeParameters);
public override IEnumerable MethodParameters =>
genericParams == null ? gc.MethodParameters : gc.MethodParameters.Concat(genericParams);
public int GenericParameterCount => signature.GenericParameterCount;
public virtual Method? SourceDeclaration => this;
public abstract Type DeclaringType { get; }
public abstract string Name { get; }
public virtual IList? LocalVariables => throw new NotImplementedException();
public IList? Parameters { get; protected set; }
public override void WriteId(TextWriter trapFile) => WriteMethodId(trapFile, DeclaringType, NameLabel);
public abstract string NameLabel { get; }
protected internal void WriteMethodId(TextWriter trapFile, Type parent, string methodName)
{
signature.ReturnType.WriteId(trapFile, this);
trapFile.Write(' ');
parent.WriteId(trapFile);
trapFile.Write('.');
trapFile.Write(methodName);
if (signature.GenericParameterCount > 0)
{
trapFile.Write('`');
trapFile.Write(signature.GenericParameterCount);
}
trapFile.Write('(');
var index = 0;
foreach (var param in signature.ParameterTypes)
{
trapFile.WriteSeparator(",", ref index);
param.WriteId(trapFile, this);
}
trapFile.Write(')');
}
public override string IdSuffix => ";cil-method";
protected IEnumerable PopulateFlags
{
get
{
if (IsStatic)
yield return Tuples.cil_static(this);
}
}
public abstract bool IsStatic { get; }
protected IEnumerable MakeParameters(IEnumerable parameterTypes)
{
var i = 0;
if (!IsStatic)
{
yield return Cx.Populate(new Parameter(Cx, this, i++, DeclaringType));
}
foreach (var p in parameterTypes)
yield return Cx.Populate(new Parameter(Cx, this, i++, p));
}
}
}