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

320 lines
12 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp;
internal sealed class InMethodBinder : LocalScopeBinder
{
private MultiDictionary<string, ParameterSymbol> _lazyParameterMap;
private readonly MethodSymbol _methodSymbol;
private SmallDictionary<string, Symbol> _lazyDefinitionMap;
protected override bool InExecutableBinder => true;
internal override Symbol ContainingMemberOrLambda => _methodSymbol;
internal override bool IsInMethodBody => true;
internal override bool IsNestedFunctionBinder => (int)_methodSymbol.MethodKind == 17;
internal override bool IsDirectlyInIterator => _methodSymbol.IsIterator;
internal override bool IsIndirectlyInIterator => IsDirectlyInIterator;
internal override GeneratedLabelSymbol BreakLabel => null;
internal override GeneratedLabelSymbol ContinueLabel => null;
public InMethodBinder(MethodSymbol owner, Binder enclosing)
: base(enclosing, (BinderFlags)((uint)enclosing.Flags & 0xFFC0FFFFu))
{
_methodSymbol = owner;
}
private static void RecordDefinition<T>(SmallDictionary<string, Symbol> declarationMap, ImmutableArray<T> definitions) where T : Symbol
{
ImmutableArray<T>.Enumerator enumerator = definitions.GetEnumerator();
while (enumerator.MoveNext())
{
Symbol current = enumerator.Current;
if (!declarationMap.ContainsKey(current.Name))
{
declarationMap.Add(current.Name, current);
}
}
}
protected override SourceLocalSymbol LookupLocal(SyntaxToken nameToken)
{
return null;
}
protected override LocalFunctionSymbol LookupLocalFunction(SyntaxToken nameToken)
{
return null;
}
protected override void ValidateYield(YieldStatementSyntax node, BindingDiagnosticBag diagnostics)
{
}
internal override TypeWithAnnotations GetIteratorElementType()
{
//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)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
RefKind refKind = _methodSymbol.RefKind;
TypeSymbol returnType = _methodSymbol.ReturnType;
if (!IsDirectlyInIterator)
{
TypeWithAnnotations iteratorElementTypeFromReturnType = GetIteratorElementTypeFromReturnType(base.Compilation, refKind, returnType, null, null);
if (iteratorElementTypeFromReturnType.IsDefault)
{
return TypeWithAnnotations.Create(CreateErrorType());
}
return iteratorElementTypeFromReturnType;
}
return _methodSymbol.IteratorElementTypeWithAnnotations;
}
internal static TypeWithAnnotations GetIteratorElementTypeFromReturnType(CSharpCompilation compilation, RefKind refKind, TypeSymbol returnType, Location errorLocation, BindingDiagnosticBag diagnostics)
{
//IL_0000: 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_000e: Invalid comparison between Unknown and I4
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Expected I4, but got Unknown
if ((int)refKind == 0 && (int)returnType.Kind == 11)
{
TypeSymbol originalDefinition = returnType.OriginalDefinition;
SpecialType specialType = originalDefinition.SpecialType;
switch (specialType - 24)
{
case 0:
case 4:
{
NamedTypeSymbol specialType2 = compilation.GetSpecialType((SpecialType)1);
if (diagnostics != null)
{
Binder.ReportUseSite(specialType2, diagnostics, errorLocation);
}
return TypeWithAnnotations.Create(specialType2);
}
case 1:
case 5:
return ((NamedTypeSymbol)returnType).TypeArgumentsWithAnnotationsNoUseSiteDiagnostics[0];
}
if (TypeSymbol.Equals(originalDefinition, compilation.GetWellKnownType((WellKnownType)288), (TypeCompareKind)0) || TypeSymbol.Equals(originalDefinition, compilation.GetWellKnownType((WellKnownType)289), (TypeCompareKind)0))
{
return ((NamedTypeSymbol)returnType).TypeArgumentsWithAnnotationsNoUseSiteDiagnostics[0];
}
}
return default(TypeWithAnnotations);
}
internal static bool IsAsyncStreamInterface(CSharpCompilation compilation, RefKind refKind, TypeSymbol returnType)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Invalid comparison between Unknown and I4
if ((int)refKind == 0 && (int)returnType.Kind == 11)
{
TypeSymbol originalDefinition = returnType.OriginalDefinition;
if (TypeSymbol.Equals(originalDefinition, compilation.GetWellKnownType((WellKnownType)288), (TypeCompareKind)0) || TypeSymbol.Equals(originalDefinition, compilation.GetWellKnownType((WellKnownType)289), (TypeCompareKind)0))
{
return true;
}
}
return false;
}
internal override void LookupSymbolsInSingleBinder(LookupResult result, string name, int arity, ConsList<TypeSymbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref CompoundUseSiteInfo<AssemblySymbol> useSiteInfo)
{
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
if (_methodSymbol.ParameterCount == 0 || (options & LookupOptions.NamespaceAliasesOnly) != LookupOptions.Default)
{
return;
}
MultiDictionary<string, ParameterSymbol> val = _lazyParameterMap;
if (val == null)
{
ImmutableArray<ParameterSymbol> parameters = _methodSymbol.Parameters;
val = new MultiDictionary<string, ParameterSymbol>(parameters.Length, (IEqualityComparer<string>)EqualityComparer<string>.Default, (IEqualityComparer<ParameterSymbol>)null);
ImmutableArray<ParameterSymbol>.Enumerator enumerator = parameters.GetEnumerator();
while (enumerator.MoveNext())
{
ParameterSymbol current = enumerator.Current;
if ((Flags & BinderFlags.InEEMethodBinder) == 0 || !current.Type.IsDisplayClassType())
{
val.Add(current.Name, current);
}
}
_lazyParameterMap = val;
}
Enumerator<string, ParameterSymbol> enumerator2 = val[name].GetEnumerator();
try
{
while (enumerator2.MoveNext())
{
ParameterSymbol current2 = enumerator2.Current;
result.MergeEqual(originalBinder.CheckViability(current2, arity, options, null, diagnose, ref useSiteInfo));
}
}
finally
{
((IDisposable)enumerator2/*cast due to constrained. prefix*/).Dispose();
}
}
internal override void AddLookupSymbolsInfoInSingleBinder(LookupSymbolsInfo result, LookupOptions options, Binder originalBinder)
{
if (!options.CanConsiderMembers())
{
return;
}
ImmutableArray<ParameterSymbol>.Enumerator enumerator = _methodSymbol.Parameters.GetEnumerator();
while (enumerator.MoveNext())
{
ParameterSymbol current = enumerator.Current;
if (originalBinder.CanAddLookupSymbolInfo(current, options, result, null))
{
((AbstractLookupSymbolsInfo<Symbol>)result).AddSymbol((Symbol)current, current.Name, 0);
}
}
}
private static bool ReportConflictWithParameter(Symbol parameter, Symbol newSymbol, string name, Location newLocation, BindingDiagnosticBag diagnostics)
{
//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_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Invalid comparison between Unknown and I4
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Invalid comparison between Unknown and I4
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Invalid comparison between Unknown and I4
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Invalid comparison between Unknown and I4
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Invalid comparison between Unknown and I4
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Invalid comparison between Unknown and I4
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Invalid comparison between Unknown and I4
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Invalid comparison between Unknown and I4
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Expected I4, but got Unknown
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Invalid comparison between Unknown and I4
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Expected I4, but got Unknown
SymbolKind kind = parameter.Kind;
SymbolKind val = (SymbolKind)(((object)newSymbol == null) ? 13 : ((int)newSymbol.Kind));
if ((int)val == 4)
{
return true;
}
if ((int)kind == 13)
{
if ((int)val != 8)
{
if ((int)val != 9)
{
switch (val - 13)
{
case 0:
break;
case 4:
return false;
case 3:
diagnostics.Add(ErrorCode.ERR_QueryRangeVariableOverrides, newLocation, name);
return true;
default:
goto IL_008f;
}
}
else if ((int)((MethodSymbol)newSymbol).MethodKind != 17)
{
goto IL_008f;
}
}
diagnostics.Add(ErrorCode.ERR_LocalIllegallyOverrides, newLocation, name);
return true;
}
goto IL_008f;
IL_0103:
diagnostics.Add(ErrorCode.ERR_InternalError, newLocation);
return true;
IL_008f:
if ((int)kind == 17)
{
if ((int)val != 8)
{
if ((int)val != 9)
{
switch (val - 13)
{
case 0:
break;
case 4:
return false;
case 3:
diagnostics.Add(ErrorCode.ERR_QueryRangeVariableSameAsTypeParam, newLocation, name);
return true;
default:
goto IL_0103;
}
}
else if ((int)((MethodSymbol)newSymbol).MethodKind != 17)
{
goto IL_0103;
}
}
diagnostics.Add(ErrorCode.ERR_LocalSameNameAsTypeParam, newLocation, name);
return true;
}
goto IL_0103;
}
internal override bool EnsureSingleDefinition(Symbol symbol, string name, Location location, BindingDiagnosticBag diagnostics)
{
ImmutableArray<ParameterSymbol> parameters = _methodSymbol.Parameters;
ImmutableArray<TypeParameterSymbol> typeParameters = _methodSymbol.TypeParameters;
if (parameters.IsEmpty && typeParameters.IsEmpty)
{
return false;
}
SmallDictionary<string, Symbol> val = _lazyDefinitionMap;
if (val == null)
{
val = new SmallDictionary<string, Symbol>();
RecordDefinition(val, parameters);
RecordDefinition(val, typeParameters);
_lazyDefinitionMap = val;
}
Symbol parameter = default(Symbol);
if (val.TryGetValue(name, ref parameter))
{
return ReportConflictWithParameter(parameter, symbol, name, location, diagnostics);
}
return false;
}
}