File: Linker.Dataflow\MethodProxy.cs
Web Access
Project: src\src\tools\illink\src\linker\Mono.Linker.csproj (illink)
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
 
using System;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using Mono.Cecil;
using Mono.Linker;
 
namespace ILLink.Shared.TypeSystemProxy
{
    internal readonly partial struct MethodProxy : IEquatable<MethodProxy>
    {
        public static bool TryCreate(MethodReference method, ITryResolveMetadata resolver, [NotNullWhen(true)] out MethodProxy? methodProxy)
        {
            if (resolver.TryResolve(method) is not MethodDefinition methodDef)
            {
                methodProxy = null;
                return false;
            }
 
            methodProxy = new MethodProxy(method, methodDef);
            return true;
        }
 
        private MethodProxy(MethodReference method, MethodDefinition methodDef)
        {
            Method = method;
            Definition = methodDef;
        }
 
        public static implicit operator MethodProxy(MethodDefinition method) => new(method, method);
 
        public readonly MethodReference Method;
 
        internal MethodDefinition Definition { get; }
 
        public string Name { get => Method.Name; }
 
        public string GetDisplayName() => Method.GetDisplayName();
 
        internal partial bool IsDeclaredOnType(string fullTypeName) => Method.IsDeclaredOnType(fullTypeName);
 
        internal partial bool HasMetadataParameters() => Definition.HasMetadataParameters();
 
        /// <summary>
        /// Gets the number of entries in the 'Parameters' section of a method's metadata (i.e. excludes the implicit 'this' from the count)
        /// </summary>
        internal partial int GetMetadataParametersCount() => Definition.GetMetadataParametersCount();
 
        /// <summary>
        /// Returns the number of parameters that are passed to the method in IL (including the implicit 'this' parameter).
        /// In pseudocode: <code>method.HasImplicitThis() ? 1 + MetadataParametersCount : MetadataParametersCount;</code>
        /// </summary>
        internal partial int GetParametersCount() => Definition.GetParametersCount();
 
        /// <summary>
        /// Use only when iterating over all parameters. When wanting to index, use GetParameters(ParameterIndex)
        /// </summary>
        internal partial ParameterProxyEnumerable GetParameters()
        {
            return new ParameterProxyEnumerable(0, Definition.GetParametersCount(), this);
        }
 
        internal partial ParameterProxy GetParameter(ParameterIndex index) => Definition.GetParameter(index);
 
        internal partial bool HasGenericParameters() => Method.HasGenericParameters;
 
        internal partial bool HasGenericArgumentsCount(int genericArgumentCount) => Method is GenericInstanceMethod generic && generic.GenericArguments.Count == genericArgumentCount;
 
        internal partial ImmutableArray<GenericParameterProxy> GetGenericParameters()
        {
            if (!Method.HasGenericParameters)
                return ImmutableArray<GenericParameterProxy>.Empty;
 
            var builder = ImmutableArray.CreateBuilder<GenericParameterProxy>(Method.GenericParameters.Count);
            foreach (var genericParameter in Method.GenericParameters)
            {
                builder.Add(new GenericParameterProxy(genericParameter));
            }
 
            return builder.ToImmutableArray();
        }
 
        internal partial bool IsConstructor() => Definition.IsConstructor;
 
        internal partial bool IsStatic() => Definition.IsStatic;
 
        internal partial bool HasImplicitThis() => Method.HasImplicitThis();
 
        internal partial bool ReturnsVoid() => Method.ReturnsVoid();
 
        public override string ToString() => Method.ToString();
 
        public bool Equals(MethodProxy other) => Method.Equals(other.Method);
 
        public override bool Equals(object? obj) => obj is MethodProxy other && Equals(other);
 
        public override int GetHashCode() => Method.GetHashCode();
    }
}