Files
2026-08-27 10:56:38 -06:00

248 lines
7.2 KiB
C#

using System.Collections.Immutable;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.Symbols;
internal static class MethodSymbolExtensions
{
public static bool IsParams(this MethodSymbol method)
{
if (method.ParameterCount != 0)
{
return method.Parameters[method.ParameterCount - 1].IsParams;
}
return false;
}
internal static bool IsSynthesizedLambda(this MethodSymbol method)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Invalid comparison between Unknown and I4
if (method.IsImplicitlyDeclared)
{
return (int)method.MethodKind == 0;
}
return false;
}
public static bool IsRuntimeFinalizer(this MethodSymbol method, bool skipFirstMethodKindCheck = false)
{
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Invalid comparison between Unknown and I4
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Invalid comparison between Unknown and I4
if ((object)method == null || method.Name != "Finalize" || method.ParameterCount != 0 || method.Arity != 0 || !method.IsMetadataVirtual(ignoreInterfaceImplementationChanges: true))
{
return false;
}
while ((object)method != null)
{
if (!skipFirstMethodKindCheck && (int)method.MethodKind == 4)
{
return true;
}
if ((int)method.ContainingType.SpecialType == 1)
{
return true;
}
if (method.IsMetadataNewSlot(ignoreInterfaceImplementationChanges: true))
{
return false;
}
method = method.GetFirstRuntimeOverriddenMethodIgnoringNewSlot(out var _);
skipFirstMethodKindCheck = false;
}
return false;
}
public static MethodSymbol ConstructIfGeneric(this MethodSymbol method, ImmutableArray<TypeWithAnnotations> typeArguments)
{
if (!method.IsGenericMethod)
{
return method;
}
return method.Construct(typeArguments);
}
public static bool CanBeHiddenByMemberKind(this MethodSymbol hiddenMethod, SymbolKind hidingMemberKind)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Expected I4, but got Unknown
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Invalid comparison between Unknown and I4
if ((int)hiddenMethod.MethodKind == 4)
{
return false;
}
switch (hidingMemberKind - 4)
{
default:
if ((int)hidingMemberKind != 15)
{
break;
}
goto case 0;
case 0:
case 5:
case 7:
return CanBeHiddenByMethodPropertyOrType(hiddenMethod);
case 1:
case 2:
return true;
case 3:
case 4:
case 6:
break;
}
throw ExceptionUtilities.UnexpectedValue((object)hidingMemberKind);
}
private static bool CanBeHiddenByMethodPropertyOrType(MethodSymbol method)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Expected I4, but got Unknown
MethodKind methodKind = method.MethodKind;
switch (methodKind - 1)
{
case 0:
case 1:
case 3:
case 8:
case 13:
return false;
case 4:
case 6:
case 10:
case 11:
return method.IsIndexedPropertyAccessor();
default:
return true;
}
}
public static bool IsAsyncReturningVoid(this MethodSymbol method)
{
if (method.IsAsync)
{
return method.ReturnsVoid;
}
return false;
}
public static bool IsAsyncEffectivelyReturningTask(this MethodSymbol method, CSharpCompilation compilation)
{
if (method.IsAsync && method.ReturnType is NamedTypeSymbol { Arity: 0 })
{
if (!method.HasAsyncMethodBuilderAttribute(out object _))
{
return method.ReturnType.IsNonGenericTaskType(compilation);
}
return true;
}
return false;
}
public static bool IsAsyncEffectivelyReturningGenericTask(this MethodSymbol method, CSharpCompilation compilation)
{
if (method.IsAsync && method.ReturnType is NamedTypeSymbol { Arity: 1 })
{
if (!method.HasAsyncMethodBuilderAttribute(out object _))
{
return method.ReturnType.IsGenericTaskType(compilation);
}
return true;
}
return false;
}
public static bool IsAsyncReturningIAsyncEnumerable(this MethodSymbol method, CSharpCompilation compilation)
{
if (method.IsAsync)
{
return method.ReturnType.IsIAsyncEnumerableType(compilation);
}
return false;
}
public static bool IsAsyncReturningIAsyncEnumerator(this MethodSymbol method, CSharpCompilation compilation)
{
if (method.IsAsync)
{
return method.ReturnType.IsIAsyncEnumeratorType(compilation);
}
return false;
}
internal static CSharpSyntaxNode ExtractReturnTypeSyntax(this MethodSymbol method)
{
if (method is SynthesizedSimpleProgramEntryPointSymbol synthesizedSimpleProgramEntryPointSymbol)
{
return (CSharpSyntaxNode)(object)synthesizedSimpleProgramEntryPointSymbol.ReturnTypeSyntax;
}
method = method.PartialDefinitionPart ?? method;
ImmutableArray<SyntaxReference>.Enumerator enumerator = method.DeclaringSyntaxReferences.GetEnumerator();
while (enumerator.MoveNext())
{
SyntaxNode syntax = enumerator.Current.GetSyntax(default(CancellationToken));
if (syntax is MethodDeclarationSyntax methodDeclarationSyntax)
{
return methodDeclarationSyntax.ReturnType;
}
if (syntax is LocalFunctionStatementSyntax localFunctionStatementSyntax)
{
return localFunctionStatementSyntax.ReturnType;
}
}
return (CSharpSyntaxNode)(object)CSharpSyntaxTree.Dummy.GetRoot(default(CancellationToken));
}
internal static bool IsValidUnscopedRefAttributeTarget(this MethodSymbol method)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Invalid comparison between Unknown and I4
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Invalid comparison between Unknown and I4
bool flag = !method.IsStatic && (method.ContainingType?.IsStructType() ?? false);
if (flag)
{
MethodKind methodKind = method.MethodKind;
bool flag2 = (((int)methodKind == 8 || methodKind - 10 <= 2) ? true : false);
flag = flag2;
}
if (flag)
{
return !method.IsInitOnly;
}
return false;
}
internal static bool HasUnscopedRefAttributeOnMethodOrProperty(this MethodSymbol? method)
{
if ((object)method == null)
{
return false;
}
if (!method.HasUnscopedRefAttribute)
{
if (method.AssociatedSymbol is PropertySymbol propertySymbol)
{
return propertySymbol.HasUnscopedRefAttribute;
}
return false;
}
return true;
}
}