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

463 lines
18 KiB
C#

using System.Collections.Immutable;
using System.Runtime.CompilerServices;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.Symbols;
internal class SourceLocalSymbol : LocalSymbol
{
private sealed class LocalWithInitializer : SourceLocalSymbol
{
private readonly EqualsValueClauseSyntax _initializer;
private readonly Binder _initializerBinder;
private EvaluatedConstant _constantTuple;
internal override SyntaxNode ForbiddenZone => (SyntaxNode)(object)_initializer;
public LocalWithInitializer(Symbol containingSymbol, Binder scopeBinder, TypeSyntax typeSyntax, SyntaxToken identifierToken, EqualsValueClauseSyntax initializer, Binder initializerBinder, LocalDeclarationKind declarationKind, bool allowScoped)
: base(containingSymbol, scopeBinder, allowRefKind: true, allowScoped, typeSyntax, identifierToken, declarationKind)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
_initializer = initializer;
_initializerBinder = initializerBinder;
}
protected override TypeWithAnnotations InferTypeOfVarVariable(BindingDiagnosticBag diagnostics)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
return TypeWithAnnotations.Create(_initializerBinder.BindInferredVariableInitializer(diagnostics, RefKind, _initializer, _initializer)?.Type);
}
private void MakeConstantTuple(LocalSymbol inProgress, BoundExpression boundInitValue)
{
//IL_0064: 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)
if (base.IsConst && _constantTuple == null)
{
ConstantValue bad = ConstantValue.Bad;
BindingDiagnosticBag instance = BindingDiagnosticBag.GetInstance();
TypeSymbol type = base.Type;
if (boundInitValue == null)
{
boundInitValue = new LocalInProgressBinder(this, _initializerBinder).BindVariableOrAutoPropInitializerValue(_initializer, RefKind, type, instance);
}
bad = ConstantValueUtils.GetAndValidateConstantValue(boundInitValue, this, type, (SyntaxNode)(object)_initializer.Value, instance);
Interlocked.CompareExchange(ref _constantTuple, new EvaluatedConstant(bad, ((BindingDiagnosticBag<AssemblySymbol>)(object)instance).ToReadOnlyAndFree()), null);
}
}
internal override ConstantValue GetConstantValue(SyntaxNode node, LocalSymbol inProgress, BindingDiagnosticBag diagnostics = null)
{
if (base.IsConst && inProgress == this)
{
diagnostics?.Add(ErrorCode.ERR_CircConstValue, node.GetLocation(), this);
return ConstantValue.Bad;
}
MakeConstantTuple(inProgress, null);
if (_constantTuple != null)
{
return _constantTuple.Value;
}
return null;
}
internal override ImmutableBindingDiagnostic<AssemblySymbol> GetConstantValueDiagnostics(BoundExpression boundInitValue)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
MakeConstantTuple(null, boundInitValue);
if (_constantTuple != null)
{
return _constantTuple.Diagnostics;
}
return ImmutableBindingDiagnostic<AssemblySymbol>.Empty;
}
}
private sealed class ForEachLocalSymbol : SourceLocalSymbol
{
private readonly ExpressionSyntax _collection;
private ForEachLoopBinder ForEachLoopBinder => (ForEachLoopBinder)base.ScopeBinder;
internal override SyntaxNode ForbiddenZone => null;
public ForEachLocalSymbol(Symbol containingSymbol, ForEachLoopBinder scopeBinder, TypeSyntax typeSyntax, SyntaxToken identifierToken, ExpressionSyntax collection, LocalDeclarationKind declarationKind)
: base(containingSymbol, scopeBinder, allowRefKind: true, allowScoped: true, typeSyntax, identifierToken, declarationKind)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
_collection = collection;
}
protected override TypeWithAnnotations InferTypeOfVarVariable(BindingDiagnosticBag diagnostics)
{
return ForEachLoopBinder.InferCollectionElementType(diagnostics, _collection);
}
}
private sealed class DeconstructionLocalSymbol : SourceLocalSymbol
{
private readonly SyntaxNode _deconstruction;
private readonly Binder _nodeBinder;
internal override SyntaxNode ForbiddenZone => (SyntaxNode)(_deconstruction.Kind() switch
{
SyntaxKind.SimpleAssignmentExpression => _deconstruction,
SyntaxKind.ForEachVariableStatement => ((ForEachVariableStatementSyntax)(object)_deconstruction).Variable,
_ => null,
});
public DeconstructionLocalSymbol(Symbol containingSymbol, Binder scopeBinder, Binder nodeBinder, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind declarationKind, SyntaxNode deconstruction)
: base(containingSymbol, scopeBinder, allowRefKind: false, allowScoped: true, typeSyntax, identifierToken, declarationKind)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
_deconstruction = deconstruction;
_nodeBinder = nodeBinder;
}
protected override TypeWithAnnotations InferTypeOfVarVariable(BindingDiagnosticBag diagnostics)
{
switch (_deconstruction.Kind())
{
case SyntaxKind.SimpleAssignmentExpression:
{
AssignmentExpressionSyntax assignmentExpressionSyntax = (AssignmentExpressionSyntax)(object)_deconstruction;
DeclarationExpressionSyntax declaration = null;
ExpressionSyntax expression = null;
_nodeBinder.BindDeconstruction(assignmentExpressionSyntax, assignmentExpressionSyntax.Left, assignmentExpressionSyntax.Right, diagnostics, ref declaration, ref expression);
break;
}
case SyntaxKind.ForEachVariableStatement:
_nodeBinder.BindForEachDeconstruction(diagnostics, _nodeBinder);
break;
default:
return TypeWithAnnotations.Create(_nodeBinder.CreateErrorType());
}
return _type.Value;
}
}
private sealed class LocalSymbolWithEnclosingContext : SourceLocalSymbol
{
private readonly SyntaxNode _forbiddenZone;
private readonly Binder _nodeBinder;
private readonly SyntaxNode _nodeToBind;
internal override SyntaxNode ForbiddenZone => _forbiddenZone;
internal override ErrorCode ForbiddenDiagnostic => ErrorCode.ERR_ImplicitlyTypedOutVariableUsedInTheSameArgumentList;
public LocalSymbolWithEnclosingContext(Symbol containingSymbol, Binder scopeBinder, Binder nodeBinder, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind declarationKind, SyntaxNode nodeToBind, SyntaxNode forbiddenZone)
: base(containingSymbol, scopeBinder, allowRefKind: false, allowScoped: true, typeSyntax, identifierToken, declarationKind)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
_nodeBinder = nodeBinder;
_nodeToBind = nodeToBind;
_forbiddenZone = forbiddenZone;
}
protected override TypeWithAnnotations InferTypeOfVarVariable(BindingDiagnosticBag diagnostics)
{
switch (_nodeToBind.Kind())
{
case SyntaxKind.BaseConstructorInitializer:
case SyntaxKind.ThisConstructorInitializer:
{
ConstructorInitializerSyntax initializer3 = (ConstructorInitializerSyntax)(object)_nodeToBind;
_nodeBinder.BindConstructorInitializer(initializer3, diagnostics);
break;
}
case SyntaxKind.PrimaryConstructorBaseType:
_nodeBinder.BindConstructorInitializer((PrimaryConstructorBaseTypeSyntax)(object)_nodeToBind, diagnostics);
break;
case SyntaxKind.ArgumentList:
{
SyntaxNode parent = _nodeToBind.Parent;
if (!(parent is ConstructorInitializerSyntax initializer))
{
if (!(parent is PrimaryConstructorBaseTypeSyntax initializer2))
{
throw ExceptionUtilities.UnexpectedValue((object)_nodeToBind.Parent);
}
_nodeBinder.BindConstructorInitializer(initializer2, diagnostics);
}
else
{
_nodeBinder.BindConstructorInitializer(initializer, diagnostics);
}
break;
}
case SyntaxKind.CasePatternSwitchLabel:
_nodeBinder.BindPatternSwitchLabelForInference((CasePatternSwitchLabelSyntax)(object)_nodeToBind, diagnostics);
break;
case SyntaxKind.VariableDeclarator:
_nodeBinder.BindDeclaratorArguments((VariableDeclaratorSyntax)(object)_nodeToBind, diagnostics);
break;
case SyntaxKind.SwitchExpressionArm:
{
SwitchExpressionArmSyntax node = (SwitchExpressionArmSyntax)(object)_nodeToBind;
((SwitchExpressionArmBinder)_nodeBinder).BindSwitchExpressionArm(node, diagnostics);
break;
}
case SyntaxKind.GotoCaseStatement:
_nodeBinder.BindStatement((GotoStatementSyntax)(object)_nodeToBind, diagnostics);
break;
default:
_nodeBinder.BindExpression((ExpressionSyntax)(object)_nodeToBind, diagnostics);
break;
}
if (_type == null)
{
SetTypeWithAnnotations(TypeWithAnnotations.Create(_nodeBinder.CreateErrorType("var")));
}
return _type.Value;
}
}
private readonly Binder _scopeBinder;
private readonly Symbol _containingSymbol;
private readonly SyntaxToken _identifierToken;
private readonly TypeSyntax _typeSyntax;
private readonly RefKind _refKind;
private readonly LocalDeclarationKind _declarationKind;
private readonly ScopedKind _scope;
private TypeWithAnnotations.Boxed _type;
internal Binder ScopeBinder => _scopeBinder;
internal override SyntaxNode ScopeDesignatorOpt => _scopeBinder.ScopeDesignator;
internal sealed override ScopedKind Scope => _scope;
internal Binder TypeSyntaxBinder => _scopeBinder;
internal override bool IsImportedFromMetadata => false;
internal override LocalDeclarationKind DeclarationKind => _declarationKind;
internal override SynthesizedLocalKind SynthesizedKind => (SynthesizedLocalKind)0;
internal override bool IsPinned => false;
internal sealed override bool IsKnownToReferToTempIfReferenceType => false;
public override Symbol ContainingSymbol => _containingSymbol;
public override string Name => ((SyntaxToken)(ref _identifierToken)).ValueText;
internal override SyntaxToken IdentifierToken => _identifierToken;
public override TypeWithAnnotations TypeWithAnnotations
{
get
{
if (_type == null)
{
TypeWithAnnotations typeSymbol = GetTypeSymbol();
SetTypeWithAnnotations(typeSymbol);
}
return _type.Value;
}
}
public bool IsVar
{
get
{
if (_typeSyntax == null)
{
return true;
}
bool isScoped;
TypeSyntax typeSyntax = _typeSyntax.SkipScoped(out isScoped).SkipRef();
if (typeSyntax.IsVar)
{
TypeSyntaxBinder.BindTypeOrVarKeyword(typeSyntax, BindingDiagnosticBag.Discarded, out var isVar);
return isVar;
}
return false;
}
}
public override ImmutableArray<Location> Locations => ImmutableArray.Create<Location>(GetFirstLocation());
internal override bool HasSourceLocation => true;
public override ImmutableArray<SyntaxReference> DeclaringSyntaxReferences => ImmutableArray.Create<SyntaxReference>(((SyntaxToken)(ref _identifierToken)).Parent.GetReference());
internal override bool IsCompilerGenerated => false;
public override RefKind RefKind => _refKind;
private SourceLocalSymbol(Symbol containingSymbol, Binder scopeBinder, bool allowRefKind, bool allowScoped, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind declarationKind)
{
//IL_0015: 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_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
_scopeBinder = scopeBinder;
_containingSymbol = containingSymbol;
_identifierToken = identifierToken;
_typeSyntax = typeSyntax;
typeSyntax = typeSyntax.SkipScoped(out var isScoped);
isScoped = isScoped && allowScoped;
if (allowRefKind)
{
typeSyntax.SkipRefInLocalOrReturn(null, out _refKind);
}
_scope = (ScopedKind)(((int)_refKind == 0) ? (isScoped ? 2 : 0) : (isScoped ? 1 : 0));
_declarationKind = declarationKind;
}
internal override string GetDebuggerDisplay()
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
if (_type == null)
{
return $"{Kind} <var> ${Name}";
}
return base.GetDebuggerDisplay();
}
public static SourceLocalSymbol MakeForeachLocal(MethodSymbol containingMethod, ForEachLoopBinder binder, TypeSyntax typeSyntax, SyntaxToken identifierToken, ExpressionSyntax collection)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
return new ForEachLocalSymbol(containingMethod, binder, typeSyntax, identifierToken, collection, LocalDeclarationKind.ForEachIterationVariable);
}
public static SourceLocalSymbol MakeDeconstructionLocal(Symbol containingSymbol, Binder scopeBinder, Binder nodeBinder, TypeSyntax closestTypeSyntax, SyntaxToken identifierToken, LocalDeclarationKind kind, SyntaxNode deconstruction)
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
if (!closestTypeSyntax.SkipScoped(out var _).SkipRef().IsVar)
{
return new SourceLocalSymbol(containingSymbol, scopeBinder, allowRefKind: false, allowScoped: true, closestTypeSyntax, identifierToken, kind);
}
return new DeconstructionLocalSymbol(containingSymbol, scopeBinder, nodeBinder, closestTypeSyntax, identifierToken, kind, deconstruction);
}
internal static LocalSymbol MakeLocalSymbolWithEnclosingContext(Symbol containingSymbol, Binder scopeBinder, Binder nodeBinder, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind kind, SyntaxNode nodeToBind, SyntaxNode forbiddenZone)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
if ((typeSyntax != null && !typeSyntax.SkipScoped(out var _).SkipRef().IsVar) || kind == LocalDeclarationKind.DeclarationExpressionVariable)
{
return new SourceLocalSymbol(containingSymbol, scopeBinder, allowRefKind: false, allowScoped: true, typeSyntax, identifierToken, kind);
}
return new LocalSymbolWithEnclosingContext(containingSymbol, scopeBinder, nodeBinder, typeSyntax, identifierToken, kind, nodeToBind, forbiddenZone);
}
public static SourceLocalSymbol MakeLocal(Symbol containingSymbol, Binder scopeBinder, bool allowRefKind, bool allowScoped, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind declarationKind, EqualsValueClauseSyntax initializer, Binder initializerBinderOpt = null)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
if (initializer == null)
{
return new SourceLocalSymbol(containingSymbol, scopeBinder, allowRefKind, allowScoped, typeSyntax, identifierToken, declarationKind);
}
return new LocalWithInitializer(containingSymbol, scopeBinder, typeSyntax, identifierToken, initializer, initializerBinderOpt ?? scopeBinder, declarationKind, allowScoped);
}
internal override LocalSymbol WithSynthesizedLocalKindAndSyntax(SynthesizedLocalKind kind, SyntaxNode syntax)
{
throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/Symbols/Source/SourceLocalSymbol.cs", 241);
}
private TypeWithAnnotations GetTypeSymbol()
{
BindingDiagnosticBag discarded = BindingDiagnosticBag.Discarded;
Binder typeSyntaxBinder = TypeSyntaxBinder;
bool isVar;
TypeWithAnnotations result;
if (_typeSyntax == null)
{
isVar = true;
result = default(TypeWithAnnotations);
}
else
{
result = typeSyntaxBinder.BindTypeOrVarKeyword(_typeSyntax.SkipScoped(out var _).SkipRef(), discarded, out isVar);
}
if (isVar)
{
TypeWithAnnotations typeWithAnnotations = InferTypeOfVarVariable(discarded);
result = ((!typeWithAnnotations.HasType || typeWithAnnotations.IsVoidType()) ? TypeWithAnnotations.Create(typeSyntaxBinder.CreateErrorType("var")) : typeWithAnnotations);
}
return result;
}
protected virtual TypeWithAnnotations InferTypeOfVarVariable(BindingDiagnosticBag diagnostics)
{
return _type?.Value ?? default(TypeWithAnnotations);
}
internal void SetTypeWithAnnotations(TypeWithAnnotations newType)
{
_ = _type?.Value;
if (_type == null)
{
Interlocked.CompareExchange(ref _type, new TypeWithAnnotations.Boxed(newType), null);
}
}
public override Location TryGetFirstLocation()
{
return ((SyntaxToken)(ref _identifierToken)).GetLocation();
}
internal sealed override SyntaxNode GetDeclaratorSyntax()
{
return ((SyntaxToken)(ref _identifierToken)).Parent;
}
internal override ConstantValue GetConstantValue(SyntaxNode node, LocalSymbol inProgress, BindingDiagnosticBag diagnostics)
{
return null;
}
internal override ImmutableBindingDiagnostic<AssemblySymbol> GetConstantValueDiagnostics(BoundExpression boundInitValue)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
return ImmutableBindingDiagnostic<AssemblySymbol>.Empty;
}
public sealed override bool Equals(Symbol obj, TypeCompareKind compareKind)
{
//IL_0012: 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)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
if ((object)obj == this)
{
return true;
}
if (obj is UpdatedContainingSymbolAndNullableAnnotationLocal updatedContainingSymbolAndNullableAnnotationLocal)
{
return updatedContainingSymbolAndNullableAnnotationLocal.Equals(this, compareKind);
}
if (obj is SourceLocalSymbol sourceLocalSymbol && ((SyntaxToken)(ref sourceLocalSymbol._identifierToken)).Equals(_identifierToken))
{
return sourceLocalSymbol._containingSymbol.Equals(_containingSymbol, compareKind);
}
return false;
}
public sealed override int GetHashCode()
{
return Hash.Combine(((object)Unsafe.As<SyntaxToken, SyntaxToken>(ref _identifierToken)/*cast due to constrained. prefix*/).GetHashCode(), _containingSymbol.GetHashCode());
}
}