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 _lazyParameterMap; private readonly MethodSymbol _methodSymbol; private SmallDictionary _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(SmallDictionary declarationMap, ImmutableArray definitions) where T : Symbol { ImmutableArray.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 basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref CompoundUseSiteInfo 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 val = _lazyParameterMap; if (val == null) { ImmutableArray parameters = _methodSymbol.Parameters; val = new MultiDictionary(parameters.Length, (IEqualityComparer)EqualityComparer.Default, (IEqualityComparer)null); ImmutableArray.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 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.Enumerator enumerator = _methodSymbol.Parameters.GetEnumerator(); while (enumerator.MoveNext()) { ParameterSymbol current = enumerator.Current; if (originalBinder.CanAddLookupSymbolInfo(current, options, result, null)) { ((AbstractLookupSymbolsInfo)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 parameters = _methodSymbol.Parameters; ImmutableArray typeParameters = _methodSymbol.TypeParameters; if (parameters.IsEmpty && typeParameters.IsEmpty) { return false; } SmallDictionary val = _lazyDefinitionMap; if (val == null) { val = new SmallDictionary(); 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; } }