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

140 lines
4.7 KiB
C#

using System;
using System.Collections.Immutable;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Symbols;
namespace Microsoft.CodeAnalysis.CSharp;
internal sealed class ExecutableCodeBinder : Binder
{
private readonly Symbol _memberSymbol;
private readonly SyntaxNode _root;
private readonly Action<Binder, SyntaxNode> _binderUpdatedHandler;
private SmallDictionary<SyntaxNode, Binder> _lazyBinderMap;
internal override Symbol ContainingMemberOrLambda => _memberSymbol ?? base.Next.ContainingMemberOrLambda;
protected override bool InExecutableBinder => true;
internal Symbol MemberSymbol => _memberSymbol;
private SmallDictionary<SyntaxNode, Binder> BinderMap
{
get
{
if (_lazyBinderMap == null)
{
ComputeBinderMap();
}
return _lazyBinderMap;
}
}
internal ExecutableCodeBinder(SyntaxNode root, Symbol memberSymbol, Binder next, Action<Binder, SyntaxNode> binderUpdatedHandler = null)
: this(root, memberSymbol, next, next.Flags)
{
_binderUpdatedHandler = binderUpdatedHandler;
}
internal ExecutableCodeBinder(SyntaxNode root, Symbol memberSymbol, Binder next, BinderFlags additionalFlags)
: base(next, (BinderFlags)((uint)(next.Flags | additionalFlags) & 0xFFC0FFFFu))
{
_memberSymbol = memberSymbol;
_root = root;
}
internal override Binder GetBinder(SyntaxNode node)
{
Binder result = default(Binder);
if (!BinderMap.TryGetValue(node, ref result))
{
return base.Next.GetBinder(node);
}
return result;
}
private void ComputeBinderMap()
{
SmallDictionary<SyntaxNode, Binder> val;
if (!(_memberSymbol is SynthesizedSimpleProgramEntryPointSymbol synthesizedSimpleProgramEntryPointSymbol) || (object)_root != synthesizedSimpleProgramEntryPointSymbol.SyntaxNode)
{
val = (((object)_memberSymbol == null || _root == null) ? SmallDictionary<SyntaxNode, Binder>.Empty : LocalBinderFactory.BuildMap(_memberSymbol, _root, this, _binderUpdatedHandler));
}
else
{
SimpleProgramBinder simpleProgramBinder = new SimpleProgramBinder(this, synthesizedSimpleProgramEntryPointSymbol);
val = LocalBinderFactory.BuildMap(_memberSymbol, _root, simpleProgramBinder, _binderUpdatedHandler);
val.Add(_root, (Binder)simpleProgramBinder);
}
Interlocked.CompareExchange(ref _lazyBinderMap, val, null);
}
public static void ValidateIteratorMethod(CSharpCompilation compilation, MethodSymbol iterator, BindingDiagnosticBag diagnostics)
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
//IL_0146: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
if (!iterator.IsIterator)
{
return;
}
ImmutableArray<ParameterSymbol>.Enumerator enumerator = iterator.Parameters.GetEnumerator();
while (enumerator.MoveNext())
{
ParameterSymbol current = enumerator.Current;
if ((int)current.RefKind != 0)
{
diagnostics.Add(ErrorCode.ERR_BadIteratorArgType, current.GetFirstLocation());
}
else if (current.Type.IsPointerOrFunctionPointer())
{
diagnostics.Add(ErrorCode.ERR_UnsafeIteratorArgType, current.GetFirstLocation());
}
}
SynthesizedSimpleProgramEntryPointSymbol obj = iterator as SynthesizedSimpleProgramEntryPointSymbol;
Location val = (((object)obj != null) ? obj.ReturnTypeSyntax.GetLocation() : null) ?? iterator.GetFirstLocation();
if (iterator.IsVararg)
{
diagnostics.Add(ErrorCode.ERR_VarargsIterator, val);
}
SourceMemberMethodSymbol obj2 = iterator as SourceMemberMethodSymbol;
if ((object)obj2 == null || !obj2.IsUnsafe)
{
LocalFunctionSymbol obj3 = iterator as LocalFunctionSymbol;
if ((object)obj3 == null || !obj3.IsUnsafe)
{
goto IL_00e6;
}
}
if (compilation.Options.AllowUnsafe)
{
diagnostics.Add(ErrorCode.ERR_IllegalInnerUnsafe, val);
}
goto IL_00e6;
IL_00e6:
TypeSymbol returnType = iterator.ReturnType;
RefKind refKind = iterator.RefKind;
if (InMethodBinder.GetIteratorElementTypeFromReturnType(compilation, refKind, returnType, val, diagnostics).IsDefault)
{
if ((int)refKind != 0)
{
Binder.Error(diagnostics, ErrorCode.ERR_BadIteratorReturnRef, val, iterator);
}
else if (!returnType.IsErrorType())
{
Binder.Error(diagnostics, ErrorCode.ERR_BadIteratorReturn, val, iterator, returnType);
}
}
if (InMethodBinder.IsAsyncStreamInterface(compilation, refKind, returnType) && !iterator.IsAsync)
{
diagnostics.Add(ErrorCode.ERR_IteratorMustBeAsync, val, iterator, returnType);
}
}
}