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

519 lines
22 KiB
C#

using System.Collections.Generic;
using System.Collections.Immutable;
using System.Threading;
using Microsoft.Cci;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.Symbols;
internal sealed class LocalFunctionSymbol : LocalFunctionOrSourceMemberMethodSymbol
{
private readonly Binder _binder;
private readonly Symbol _containingSymbol;
private readonly DeclarationModifiers _declarationModifiers;
private readonly ImmutableArray<SourceMethodTypeParameterSymbol> _typeParameters;
private readonly RefKind _refKind;
private ImmutableArray<ParameterSymbol> _lazyParameters;
private bool _lazyIsVarArg;
private ImmutableArray<ImmutableArray<TypeWithAnnotations>> _lazyTypeParameterConstraintTypes;
private ImmutableArray<TypeParameterConstraintKind> _lazyTypeParameterConstraintKinds;
private TypeWithAnnotations.Boxed? _lazyReturnType;
private readonly DiagnosticBag _declarationDiagnostics;
private readonly HashSet<AssemblySymbol> _declarationDependencies;
internal Binder ScopeBinder { get; }
internal override Binder OuterBinder => _binder;
internal override Binder WithTypeParametersBinder
{
get
{
if (!_typeParameters.IsEmpty)
{
return new WithMethodTypeParametersBinder(this, _binder);
}
return _binder;
}
}
internal LocalFunctionStatementSyntax Syntax => (LocalFunctionStatementSyntax)(object)syntaxReferenceOpt.GetSyntax(default(CancellationToken));
public override bool RequiresInstanceReceiver => false;
public override bool IsVararg
{
get
{
ComputeParameters();
return _lazyIsVarArg;
}
}
public override ImmutableArray<ParameterSymbol> Parameters
{
get
{
ComputeParameters();
return _lazyParameters;
}
}
public override TypeWithAnnotations ReturnTypeWithAnnotations
{
get
{
ComputeReturnType();
return _lazyReturnType.Value;
}
}
public override RefKind RefKind => _refKind;
public override bool ReturnsVoid => base.ReturnType.IsVoidType();
public override int Arity => TypeParameters.Length;
public override ImmutableArray<TypeWithAnnotations> TypeArgumentsWithAnnotations => GetTypeParametersAsTypeArguments();
public override ImmutableArray<TypeParameterSymbol> TypeParameters => ImmutableArrayExtensions.Cast<SourceMethodTypeParameterSymbol, TypeParameterSymbol>(_typeParameters);
public override bool IsExtensionMethod
{
get
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
ParameterSyntax parameterSyntax = Syntax.ParameterList.Parameters.FirstOrDefault();
if (parameterSyntax != null && !parameterSyntax.IsArgList)
{
return parameterSyntax.Modifiers.Any(SyntaxKind.ThisKeyword);
}
return false;
}
}
public override MethodKind MethodKind => (MethodKind)17;
public sealed override Symbol ContainingSymbol => _containingSymbol;
public override string Name
{
get
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
SyntaxToken identifier = Syntax.Identifier;
return ((SyntaxToken)(ref identifier)).ValueText ?? "";
}
}
public SyntaxToken NameToken => Syntax.Identifier;
public override ImmutableArray<MethodSymbol> ExplicitInterfaceImplementations => ImmutableArray<MethodSymbol>.Empty;
public override ImmutableArray<Location> Locations
{
get
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
SyntaxToken identifier = Syntax.Identifier;
return ImmutableArray.Create<Location>(((SyntaxToken)(ref identifier)).GetLocation());
}
}
internal override bool GenerateDebugInfo => true;
public override ImmutableArray<CustomModifier> RefCustomModifiers => ImmutableArray<CustomModifier>.Empty;
internal override CallingConvention CallingConvention => (CallingConvention)0;
public override Symbol? AssociatedSymbol => null;
public override Accessibility DeclaredAccessibility => ModifierUtils.EffectiveAccessibility(_declarationModifiers);
public override bool IsAsync => (_declarationModifiers & DeclarationModifiers.Async) != 0;
public override bool IsStatic => (_declarationModifiers & DeclarationModifiers.Static) != 0;
public override bool IsVirtual => (_declarationModifiers & DeclarationModifiers.Virtual) != 0;
public override bool IsOverride => (_declarationModifiers & DeclarationModifiers.Override) != 0;
public override bool IsAbstract => (_declarationModifiers & DeclarationModifiers.Abstract) != 0;
public override bool IsSealed => (_declarationModifiers & DeclarationModifiers.Sealed) != 0;
public override bool IsExtern => (_declarationModifiers & DeclarationModifiers.Extern) != 0;
public bool IsUnsafe => (_declarationModifiers & DeclarationModifiers.Unsafe) != 0;
internal bool IsExpressionBodied
{
get
{
LocalFunctionStatementSyntax syntax = Syntax;
if (syntax != null && syntax.Body == null)
{
return syntax.ExpressionBody != null;
}
return false;
}
}
internal override bool IsDeclaredReadOnly => false;
internal override bool IsInitOnly => false;
public LocalFunctionSymbol(Binder binder, Symbol containingSymbol, LocalFunctionStatementSyntax syntax)
: base(syntax.GetReference(), SyntaxFacts.HasYieldOperations((SyntaxNode?)(object)syntax.Body))
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Expected O, but got Unknown
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
_containingSymbol = containingSymbol;
_declarationDiagnostics = new DiagnosticBag();
_declarationDependencies = new HashSet<AssemblySymbol>();
_declarationModifiers = DeclarationModifiers.Private | syntax.Modifiers.ToDeclarationModifiers(isForTypeDeclaration: false, _declarationDiagnostics);
BindingDiagnosticBag instance = BindingDiagnosticBag.GetInstance();
this.CheckUnsafeModifier(_declarationModifiers, instance);
ScopeBinder = binder;
binder = binder.WithUnsafeRegionIfNecessary(syntax.Modifiers);
if (syntax.TypeParameterList != null)
{
_typeParameters = MakeTypeParameters(instance);
}
else
{
_typeParameters = ImmutableArray<SourceMethodTypeParameterSymbol>.Empty;
Symbol.ReportErrorIfHasConstraints(syntax.ConstraintClauses, _declarationDiagnostics);
}
if (IsExtensionMethod)
{
_declarationDiagnostics.Add(ErrorCode.ERR_BadExtensionAgg, GetFirstLocation());
}
Enumerator<ParameterSyntax> enumerator = syntax.ParameterList.Parameters.GetEnumerator();
while (enumerator.MoveNext())
{
ParameterSyntax current = enumerator.Current;
ReportAttributesDisallowed(current.AttributeLists, instance);
}
syntax.ReturnType.SkipRefInLocalOrReturn(instance, out _refKind);
_declarationDiagnostics.AddRange(((BindingDiagnosticBag)instance).DiagnosticBag);
ISetExtensions.AddAll<AssemblySymbol>((ISet<AssemblySymbol>)_declarationDependencies, (IEnumerable<AssemblySymbol>)((BindingDiagnosticBag<AssemblySymbol>)(object)instance).DependenciesBag);
((BindingDiagnosticBag<AssemblySymbol>)(object)instance).Free();
_binder = binder;
}
internal void GetDeclarationDiagnostics(BindingDiagnosticBag addTo)
{
//IL_0119: Unknown result type (might be due to invalid IL or missing references)
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
ImmutableArray<SourceMethodTypeParameterSymbol>.Enumerator enumerator = _typeParameters.GetEnumerator();
while (enumerator.MoveNext())
{
enumerator.Current.ForceComplete(null, default(CancellationToken));
}
ComputeParameters();
ImmutableArray<ParameterSymbol>.Enumerator enumerator2 = _lazyParameters.GetEnumerator();
while (enumerator2.MoveNext())
{
enumerator2.Current.ForceComplete(null, default(CancellationToken));
}
ComputeReturnType();
GetAttributes();
GetReturnTypeAttributes();
CSharpCompilation declaringCompilation = DeclaringCompilation;
ParameterHelpers.EnsureRefKindAttributesExist(declaringCompilation, Parameters, addTo, modifyCompilation: false);
ParameterHelpers.EnsureNativeIntegerAttributeExists(declaringCompilation, Parameters, addTo, modifyCompilation: false);
ParameterHelpers.EnsureScopedRefAttributeExists(declaringCompilation, Parameters, addTo, modifyCompilation: false);
ParameterHelpers.EnsureNullableAttributeExists(declaringCompilation, this, Parameters, addTo, modifyCompilation: false);
((BindingDiagnosticBag<AssemblySymbol>)(object)addTo).AddRange(_declarationDiagnostics);
((BindingDiagnosticBag<AssemblySymbol>)(object)addTo).AddDependencies((IReadOnlyCollection<AssemblySymbol>)_declarationDependencies);
AsyncMethodChecks(addTo);
BindingDiagnosticBag instance = BindingDiagnosticBag.GetInstance(withDiagnostics: false, ((BindingDiagnosticBag<AssemblySymbol>)(object)addTo).AccumulatesDependencies);
if (base.IsEntryPointCandidate && !IsGenericMethod && ContainingSymbol is SynthesizedSimpleProgramEntryPointSymbol && declaringCompilation.HasEntryPointSignature(this, instance).IsCandidate)
{
SyntaxToken identifier = Syntax.Identifier;
addTo.Add(ErrorCode.WRN_MainIgnored, ((SyntaxToken)(ref identifier)).GetLocation(), this);
}
((BindingDiagnosticBag<AssemblySymbol>)(object)addTo).AddRangeAndFree((BindingDiagnosticBag<AssemblySymbol>)(object)instance);
}
internal override void AddDeclarationDiagnostics(BindingDiagnosticBag diagnostics)
{
DiagnosticBag diagnosticBag = ((BindingDiagnosticBag)diagnostics).DiagnosticBag;
if (diagnosticBag != null)
{
_declarationDiagnostics.AddRange(diagnosticBag);
}
ICollection<AssemblySymbol> dependenciesBag = ((BindingDiagnosticBag<AssemblySymbol>)(object)diagnostics).DependenciesBag;
if (dependenciesBag != null)
{
ISetExtensions.AddAll<AssemblySymbol>((ISet<AssemblySymbol>)_declarationDependencies, (IEnumerable<AssemblySymbol>)dependenciesBag);
}
}
private void ComputeParameters()
{
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
if (_lazyParameters != null)
{
return;
}
BindingDiagnosticBag instance = BindingDiagnosticBag.GetInstance();
SyntaxToken arglistToken;
ImmutableArray<ParameterSymbol> lazyParameters = ImmutableArrayExtensions.Cast<SourceParameterSymbol, ParameterSymbol>(ParameterHelpers.MakeParameters(WithTypeParametersBinder, this, Syntax.ParameterList, out arglistToken, instance, allowRefOrOut: true, allowThis: true, addRefReadOnlyModifier: false));
bool flag = arglistToken.Kind() == SyntaxKind.ArgListKeyword;
if (flag)
{
instance.Add(ErrorCode.ERR_IllegalVarArgs, ((SyntaxToken)(ref arglistToken)).GetLocation());
}
lock (_declarationDiagnostics)
{
if (_lazyParameters != null)
{
((BindingDiagnosticBag<AssemblySymbol>)(object)instance).Free();
return;
}
_declarationDiagnostics.AddRange(((BindingDiagnosticBag)instance).DiagnosticBag);
ISetExtensions.AddAll<AssemblySymbol>((ISet<AssemblySymbol>)_declarationDependencies, (IEnumerable<AssemblySymbol>)((BindingDiagnosticBag<AssemblySymbol>)(object)instance).DependenciesBag);
((BindingDiagnosticBag<AssemblySymbol>)(object)instance).Free();
_lazyIsVarArg = flag;
_lazyParameters = lazyParameters;
}
}
internal void ComputeReturnType()
{
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Invalid comparison between Unknown and I4
if (_lazyReturnType != null)
{
return;
}
BindingDiagnosticBag instance = BindingDiagnosticBag.GetInstance();
TypeSyntax returnType = Syntax.ReturnType;
bool isScoped;
TypeWithAnnotations value = WithTypeParametersBinder.BindType(returnType.SkipScoped(out isScoped).SkipRef(), instance);
CSharpCompilation declaringCompilation = DeclaringCompilation;
if (declaringCompilation != null)
{
Location val = null;
if ((int)_refKind == 3)
{
declaringCompilation.EnsureIsReadOnlyAttributeExists(instance, val ?? (val = ((SyntaxNode)returnType).Location), modifyCompilation: false);
}
if (declaringCompilation.ShouldEmitNativeIntegerAttributes(value.Type))
{
declaringCompilation.EnsureNativeIntegerAttributeExists(instance, val ?? (val = ((SyntaxNode)returnType).Location), modifyCompilation: false);
}
if (declaringCompilation.ShouldEmitNullableAttributes(this) && value.NeedsNullableAttribute())
{
declaringCompilation.EnsureNullableAttributeExists(instance, val ?? (val = ((SyntaxNode)returnType).Location), modifyCompilation: false);
}
}
if (value.IsRestrictedType(ignoreSpanLikeTypes: true))
{
instance.Add(ErrorCode.ERR_MethodReturnCantBeRefAny, ((SyntaxNode)returnType).Location, value.Type);
}
lock (_declarationDiagnostics)
{
if (_lazyReturnType != null)
{
((BindingDiagnosticBag<AssemblySymbol>)(object)instance).Free();
return;
}
_declarationDiagnostics.AddRange(((BindingDiagnosticBag)instance).DiagnosticBag);
ISetExtensions.AddAll<AssemblySymbol>((ISet<AssemblySymbol>)_declarationDependencies, (IEnumerable<AssemblySymbol>)((BindingDiagnosticBag<AssemblySymbol>)(object)instance).DependenciesBag);
((BindingDiagnosticBag<AssemblySymbol>)(object)instance).Free();
Interlocked.CompareExchange(ref _lazyReturnType, new TypeWithAnnotations.Boxed(value), null);
}
}
public override Location TryGetFirstLocation()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
SyntaxToken identifier = Syntax.Identifier;
return ((SyntaxToken)(ref identifier)).GetLocation();
}
internal override OneOrMany<SyntaxList<AttributeListSyntax>> GetAttributeDeclarations()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
return OneOrMany.Create<SyntaxList<AttributeListSyntax>>(Syntax.AttributeLists);
}
protected override void NoteAttributesComplete(bool forReturnType)
{
}
internal override bool IsMetadataNewSlot(bool ignoreInterfaceImplementationChanges = false)
{
return false;
}
internal override bool IsMetadataVirtual(bool ignoreInterfaceImplementationChanges = false)
{
return false;
}
internal override int CalculateLocalSyntaxOffset(int localPosition, SyntaxTree localTree)
{
throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs", 385);
}
internal override bool TryGetThisParameter(out ParameterSymbol? thisParameter)
{
thisParameter = null;
return true;
}
private void ReportAttributesDisallowed(SyntaxList<AttributeListSyntax> attributes, BindingDiagnosticBag diagnostics)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
CSDiagnosticInfo featureAvailabilityDiagnosticInfo = MessageID.IDS_FeatureLocalFunctionAttributes.GetFeatureAvailabilityDiagnosticInfo((CSharpParseOptions)(object)syntaxReferenceOpt.SyntaxTree.Options);
if (featureAvailabilityDiagnosticInfo != null)
{
Enumerator<AttributeListSyntax> enumerator = attributes.GetEnumerator();
while (enumerator.MoveNext())
{
AttributeListSyntax current = enumerator.Current;
diagnostics.Add((DiagnosticInfo?)(object)featureAvailabilityDiagnosticInfo, ((SyntaxNode)current).Location);
}
}
}
private ImmutableArray<SourceMethodTypeParameterSymbol> MakeTypeParameters(BindingDiagnosticBag diagnostics)
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_010e: Unknown result type (might be due to invalid IL or missing references)
//IL_0115: Invalid comparison between Unknown and I4
ArrayBuilder<SourceMethodTypeParameterSymbol> instance = ArrayBuilder<SourceMethodTypeParameterSymbol>.GetInstance();
SeparatedSyntaxList<TypeParameterSyntax> val = Syntax.TypeParameterList?.Parameters ?? default(SeparatedSyntaxList<TypeParameterSyntax>);
for (int i = 0; i < val.Count; i++)
{
TypeParameterSyntax typeParameterSyntax = val[i];
if (typeParameterSyntax.VarianceKeyword.Kind() != SyntaxKind.None)
{
SyntaxToken varianceKeyword = typeParameterSyntax.VarianceKeyword;
diagnostics.Add(ErrorCode.ERR_IllegalVarianceSyntax, ((SyntaxToken)(ref varianceKeyword)).GetLocation());
}
ReportAttributesDisallowed(typeParameterSyntax.AttributeLists, diagnostics);
SyntaxToken identifier = typeParameterSyntax.Identifier;
Location location = ((SyntaxToken)(ref identifier)).GetLocation();
string text = ((SyntaxToken)(ref identifier)).ValueText ?? "";
Enumerator<SourceMethodTypeParameterSymbol> enumerator = instance.GetEnumerator();
while (enumerator.MoveNext())
{
SourceMethodTypeParameterSymbol current = enumerator.Current;
if (text == current.Name)
{
diagnostics.Add(ErrorCode.ERR_DuplicateTypeParameter, location, text);
break;
}
}
SourceMemberContainerTypeSymbol.ReportReservedTypeName(((SyntaxToken)(ref identifier)).Text, DeclaringCompilation, ((BindingDiagnosticBag)diagnostics).DiagnosticBag, location);
TypeParameterSymbol typeParameterSymbol = ContainingSymbol.FindEnclosingTypeParameter(text);
if ((object)typeParameterSymbol != null)
{
ErrorCode code = (((int)typeParameterSymbol.ContainingSymbol.Kind != 9) ? ErrorCode.WRN_TypeParameterSameAsOuterTypeParameter : ErrorCode.WRN_TypeParameterSameAsOuterMethodTypeParameter);
diagnostics.Add(code, location, text, typeParameterSymbol.ContainingSymbol);
}
SourceMethodTypeParameterSymbol sourceMethodTypeParameterSymbol = new SourceMethodTypeParameterSymbol(this, text, i, ImmutableArray.Create<Location>(location), ImmutableArray.Create<SyntaxReference>(typeParameterSyntax.GetReference()));
instance.Add(sourceMethodTypeParameterSymbol);
}
return instance.ToImmutableAndFree();
}
public override ImmutableArray<ImmutableArray<TypeWithAnnotations>> GetTypeParameterConstraintTypes()
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
if (_lazyTypeParameterConstraintTypes.IsDefault)
{
GetTypeParameterConstraintKinds();
LocalFunctionStatementSyntax syntax = Syntax;
BindingDiagnosticBag instance = BindingDiagnosticBag.GetInstance();
ImmutableArray<ImmutableArray<TypeWithAnnotations>> lazyTypeParameterConstraintTypes = this.MakeTypeParameterConstraintTypes(WithTypeParametersBinder, TypeParameters, syntax.TypeParameterList, syntax.ConstraintClauses, instance);
lock (_declarationDiagnostics)
{
if (_lazyTypeParameterConstraintTypes.IsDefault)
{
_declarationDiagnostics.AddRange(((BindingDiagnosticBag)instance).DiagnosticBag);
ISetExtensions.AddAll<AssemblySymbol>((ISet<AssemblySymbol>)_declarationDependencies, (IEnumerable<AssemblySymbol>)((BindingDiagnosticBag<AssemblySymbol>)(object)instance).DependenciesBag);
_lazyTypeParameterConstraintTypes = lazyTypeParameterConstraintTypes;
}
}
((BindingDiagnosticBag<AssemblySymbol>)(object)instance).Free();
}
return _lazyTypeParameterConstraintTypes;
}
public override ImmutableArray<TypeParameterConstraintKind> GetTypeParameterConstraintKinds()
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
if (_lazyTypeParameterConstraintKinds.IsDefault)
{
LocalFunctionStatementSyntax syntax = Syntax;
ImmutableArray<TypeParameterConstraintKind> value = this.MakeTypeParameterConstraintKinds(WithTypeParametersBinder, TypeParameters, syntax.TypeParameterList, syntax.ConstraintClauses);
ImmutableInterlocked.InterlockedInitialize(ref _lazyTypeParameterConstraintKinds, value);
}
return _lazyTypeParameterConstraintKinds;
}
internal override bool IsNullableAnalysisEnabled()
{
throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs", 516);
}
public override int GetHashCode()
{
return ((object)Syntax).GetHashCode();
}
public sealed override bool Equals(Symbol symbol, TypeCompareKind compareKind)
{
if ((object)this == symbol)
{
return true;
}
return (symbol as LocalFunctionSymbol)?.Syntax == Syntax;
}
}