320 lines
12 KiB
C#
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;
|
|
}
|
|
}
|