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

206 lines
7.3 KiB
C#

using System.Collections.Immutable;
using System.Threading;
namespace Microsoft.CodeAnalysis.CSharp.Symbols;
internal abstract class SourceOrdinaryMethodOrUserDefinedOperatorSymbol : SourceMemberMethodSymbol
{
private ImmutableArray<MethodSymbol> _lazyExplicitInterfaceImplementations;
private ImmutableArray<CustomModifier> _lazyRefCustomModifiers;
private ImmutableArray<ParameterSymbol> _lazyParameters;
private TypeWithAnnotations _lazyReturnType;
protected abstract Location ReturnTypeLocation { get; }
public sealed override bool ReturnsVoid
{
get
{
LazyMethodChecks();
return base.ReturnsVoid;
}
}
protected abstract TypeSymbol? ExplicitInterfaceType { get; }
internal sealed override int ParameterCount
{
get
{
if (!_lazyParameters.IsDefault)
{
return _lazyParameters.Length;
}
return GetParameterCountFromSyntax();
}
}
public sealed override ImmutableArray<ParameterSymbol> Parameters
{
get
{
LazyMethodChecks();
return _lazyParameters;
}
}
public sealed override TypeWithAnnotations ReturnTypeWithAnnotations
{
get
{
LazyMethodChecks();
return _lazyReturnType;
}
}
internal sealed override bool IsExplicitInterfaceImplementation => (int)MethodKind == 8;
public sealed override ImmutableArray<MethodSymbol> ExplicitInterfaceImplementations
{
get
{
LazyMethodChecks();
return _lazyExplicitInterfaceImplementations;
}
}
public sealed override ImmutableArray<CustomModifier> RefCustomModifiers
{
get
{
LazyMethodChecks();
return _lazyRefCustomModifiers;
}
}
protected SourceOrdinaryMethodOrUserDefinedOperatorSymbol(NamedTypeSymbol containingType, SyntaxReference syntaxReferenceOpt, Location location, bool isIterator, (DeclarationModifiers declarationModifiers, Flags flags) modifiersAndFlags)
: base(containingType, syntaxReferenceOpt, location, isIterator, modifiersAndFlags)
{
}
protected MethodSymbol? MethodChecks(TypeWithAnnotations returnType, ImmutableArray<ParameterSymbol> parameters, BindingDiagnosticBag diagnostics)
{
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Invalid comparison between Unknown and I4
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
//IL_00f1: Invalid comparison between Unknown and I4
//IL_0133: Unknown result type (might be due to invalid IL or missing references)
//IL_0139: Invalid comparison between Unknown and I4
_lazyReturnType = returnType;
_lazyParameters = parameters;
SetReturnsVoid(_lazyReturnType.IsVoidType());
CheckEffectiveAccessibility(_lazyReturnType, _lazyParameters, diagnostics);
CheckFileTypeUsage(_lazyReturnType, _lazyParameters, diagnostics);
if (Name == "Finalize" && ParameterCount == 0 && Arity == 0 && ReturnsVoid)
{
diagnostics.Add(ErrorCode.WRN_FinalizeMethod, _location);
}
ExtensionMethodChecks(diagnostics);
if (base.IsPartial)
{
if ((int)MethodKind == 8)
{
diagnostics.Add(ErrorCode.ERR_PartialMethodNotExplicit, _location);
}
if (!ContainingType.IsPartial())
{
diagnostics.Add(ErrorCode.ERR_PartialMethodOnlyInPartialClass, _location);
}
}
if (!base.IsPartial)
{
LazyAsyncMethodChecks(CancellationToken.None);
}
_lazyRefCustomModifiers = ImmutableArray<CustomModifier>.Empty;
MethodSymbol methodSymbol = null;
if ((int)MethodKind != 8)
{
_lazyExplicitInterfaceImplementations = ImmutableArray<MethodSymbol>.Empty;
if (IsOverride)
{
methodSymbol = base.OverriddenMethod;
if ((object)methodSymbol != null)
{
CustomModifierUtils.CopyMethodCustomModifiers(methodSymbol, this, out _lazyReturnType, out _lazyRefCustomModifiers, out _lazyParameters, alsoCopyParamsModifier: true);
}
}
else if ((int)RefKind == 3)
{
NamedTypeSymbol wellKnownType = Binder.GetWellKnownType(DeclaringCompilation, (WellKnownType)273, diagnostics, ReturnTypeLocation);
_lazyRefCustomModifiers = ImmutableArray.Create<CustomModifier>(CSharpCustomModifier.CreateRequired(wellKnownType));
}
}
else if ((object)ExplicitInterfaceType != null)
{
methodSymbol = FindExplicitlyImplementedMethod(diagnostics);
if ((object)methodSymbol != null)
{
_lazyExplicitInterfaceImplementations = ImmutableArray.Create(methodSymbol);
CustomModifierUtils.CopyMethodCustomModifiers(methodSymbol, this, out _lazyReturnType, out _lazyRefCustomModifiers, out _lazyParameters, alsoCopyParamsModifier: false);
this.FindExplicitlyImplementedMemberVerification(methodSymbol, diagnostics);
TypeSymbol.CheckModifierMismatchOnImplementingMember(ContainingType, this, methodSymbol, isExplicit: true, diagnostics);
}
else
{
_lazyExplicitInterfaceImplementations = ImmutableArray<MethodSymbol>.Empty;
}
}
return methodSymbol;
}
protected abstract void ExtensionMethodChecks(BindingDiagnosticBag diagnostics);
protected abstract MethodSymbol? FindExplicitlyImplementedMethod(BindingDiagnosticBag diagnostics);
protected abstract int GetParameterCountFromSyntax();
internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, BindingDiagnosticBag diagnostics)
{
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Invalid comparison between Unknown and I4
base.AfterAddingTypeMembersChecks(conversions, diagnostics);
Location returnTypeLocation = null;
CSharpCompilation declaringCompilation = DeclaringCompilation;
CheckConstraintsForExplicitInterfaceType(conversions, diagnostics);
base.ReturnType.CheckAllConstraints(declaringCompilation, conversions, GetFirstLocation(), diagnostics);
ImmutableArray<ParameterSymbol>.Enumerator enumerator = Parameters.GetEnumerator();
while (enumerator.MoveNext())
{
ParameterSymbol current = enumerator.Current;
current.Type.CheckAllConstraints(declaringCompilation, conversions, current.GetFirstLocation(), diagnostics);
}
PartialMethodChecks(diagnostics);
if ((int)RefKind == 3)
{
declaringCompilation.EnsureIsReadOnlyAttributeExists(diagnostics, getReturnTypeLocation(), modifyCompilation: true);
}
ParameterHelpers.EnsureRefKindAttributesExist(declaringCompilation, Parameters, diagnostics, modifyCompilation: true);
if (declaringCompilation.ShouldEmitNativeIntegerAttributes(base.ReturnType))
{
declaringCompilation.EnsureNativeIntegerAttributeExists(diagnostics, getReturnTypeLocation(), modifyCompilation: true);
}
ParameterHelpers.EnsureNativeIntegerAttributeExists(declaringCompilation, Parameters, diagnostics, modifyCompilation: true);
ParameterHelpers.EnsureScopedRefAttributeExists(declaringCompilation, Parameters, diagnostics, modifyCompilation: true);
if (declaringCompilation.ShouldEmitNullableAttributes(this) && ReturnTypeWithAnnotations.NeedsNullableAttribute())
{
declaringCompilation.EnsureNullableAttributeExists(diagnostics, getReturnTypeLocation(), modifyCompilation: true);
}
ParameterHelpers.EnsureNullableAttributeExists(declaringCompilation, this, Parameters, diagnostics, modifyCompilation: true);
Location getReturnTypeLocation()
{
if (returnTypeLocation == null)
{
returnTypeLocation = ReturnTypeLocation;
}
return returnTypeLocation;
}
}
protected abstract void CheckConstraintsForExplicitInterfaceType(ConversionsBase conversions, BindingDiagnosticBag diagnostics);
protected abstract void PartialMethodChecks(BindingDiagnosticBag diagnostics);
}