1250 lines
52 KiB
C#
1250 lines
52 KiB
C#
using System;
|
|
using System.Collections.Immutable;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using Microsoft.CodeAnalysis.CSharp.Symbols;
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
using Microsoft.CodeAnalysis.PooledObjects;
|
|
using Microsoft.CodeAnalysis.Text;
|
|
using Roslyn.Utilities;
|
|
|
|
namespace Microsoft.CodeAnalysis.CSharp;
|
|
|
|
internal sealed class BinderFactory
|
|
{
|
|
private sealed class BinderFactoryVisitor : CSharpSyntaxVisitor<Binder>
|
|
{
|
|
private int _position;
|
|
|
|
private CSharpSyntaxNode _memberDeclarationOpt;
|
|
|
|
private Symbol _memberOpt;
|
|
|
|
private readonly BinderFactory _factory;
|
|
|
|
private CSharpCompilation compilation => _factory._compilation;
|
|
|
|
private SyntaxTree syntaxTree => _factory._syntaxTree;
|
|
|
|
private BuckStopsHereBinder buckStopsHereBinder => _factory._buckStopsHereBinder;
|
|
|
|
private ConcurrentCache<BinderCacheKey, Binder> binderCache => _factory._binderCache;
|
|
|
|
private bool InScript => _factory.InScript;
|
|
|
|
internal BinderFactoryVisitor(BinderFactory factory)
|
|
{
|
|
_factory = factory;
|
|
}
|
|
|
|
internal void Initialize(int position, CSharpSyntaxNode memberDeclarationOpt, Symbol memberOpt)
|
|
{
|
|
_position = position;
|
|
_memberDeclarationOpt = memberDeclarationOpt;
|
|
_memberOpt = memberOpt;
|
|
}
|
|
|
|
public override Binder DefaultVisit(SyntaxNode parent)
|
|
{
|
|
return VisitCore(parent.Parent);
|
|
}
|
|
|
|
public override Binder Visit(SyntaxNode node)
|
|
{
|
|
return VisitCore(node);
|
|
}
|
|
|
|
private Binder VisitCore(SyntaxNode node)
|
|
{
|
|
return ((CSharpSyntaxNode)(object)node).Accept(this);
|
|
}
|
|
|
|
public override Binder VisitGlobalStatement(GlobalStatementSyntax node)
|
|
{
|
|
if (SyntaxFacts.IsSimpleProgramTopLevelStatement(node))
|
|
{
|
|
CompilationUnitSyntax compilationUnitSyntax = (CompilationUnitSyntax)node.Parent;
|
|
if ((object)compilationUnitSyntax != syntaxTree.GetRoot(default(CancellationToken)))
|
|
{
|
|
throw new ArgumentOutOfRangeException("node", "node not part of tree");
|
|
}
|
|
BinderCacheKey binderCacheKey = CreateBinderCacheKey(compilationUnitSyntax, NodeUsage.MethodBody);
|
|
Binder binder = default(Binder);
|
|
if (!binderCache.TryGetValue(binderCacheKey, ref binder))
|
|
{
|
|
binder = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(compilation, (CompilationUnitSyntax)node.Parent, fallbackToMainEntryPoint: false).GetBodyBinder(_factory._ignoreAccessibility).GetBinder((SyntaxNode)(object)compilationUnitSyntax);
|
|
binderCache.TryAdd(binderCacheKey, binder);
|
|
}
|
|
return binder;
|
|
}
|
|
return base.VisitGlobalStatement(node);
|
|
}
|
|
|
|
public override Binder VisitMethodDeclaration(MethodDeclarationSyntax methodDecl)
|
|
{
|
|
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
|
|
if (!LookupPosition.IsInMethodDeclaration(_position, methodDecl))
|
|
{
|
|
return VisitCore((SyntaxNode)(object)methodDecl.Parent);
|
|
}
|
|
NodeUsage nodeUsage = (LookupPosition.IsInBody(_position, methodDecl) ? NodeUsage.MethodBody : (LookupPosition.IsInMethodTypeParameterScope(_position, methodDecl) ? NodeUsage.MethodTypeParameters : NodeUsage.Normal));
|
|
BinderCacheKey binderCacheKey = CreateBinderCacheKey(methodDecl, nodeUsage);
|
|
Binder binder = default(Binder);
|
|
if (!binderCache.TryGetValue(binderCacheKey, ref binder))
|
|
{
|
|
binder = ((!(methodDecl.Parent is TypeDeclarationSyntax parent)) ? VisitCore((SyntaxNode)(object)methodDecl.Parent) : VisitTypeDeclarationCore(parent, NodeUsage.MethodBody));
|
|
SourceMemberMethodSymbol sourceMemberMethodSymbol = null;
|
|
if (nodeUsage != NodeUsage.Normal && methodDecl.TypeParameterList != null)
|
|
{
|
|
sourceMemberMethodSymbol = GetMethodSymbol(methodDecl, binder);
|
|
binder = new WithMethodTypeParametersBinder(sourceMemberMethodSymbol, binder);
|
|
}
|
|
if (nodeUsage == NodeUsage.MethodBody)
|
|
{
|
|
sourceMemberMethodSymbol = sourceMemberMethodSymbol ?? GetMethodSymbol(methodDecl, binder);
|
|
binder = new InMethodBinder(sourceMemberMethodSymbol, binder);
|
|
}
|
|
binder = binder.WithUnsafeRegionIfNecessary(methodDecl.Modifiers);
|
|
binderCache.TryAdd(binderCacheKey, binder);
|
|
}
|
|
return binder;
|
|
}
|
|
|
|
public override Binder VisitConstructorDeclaration(ConstructorDeclarationSyntax parent)
|
|
{
|
|
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
|
|
if (!LookupPosition.IsInMethodDeclaration(_position, parent))
|
|
{
|
|
return VisitCore((SyntaxNode)(object)parent.Parent);
|
|
}
|
|
bool flag = LookupPosition.IsInConstructorParameterScope(_position, parent);
|
|
NodeUsage usage = (flag ? NodeUsage.MethodTypeParameters : NodeUsage.Normal);
|
|
BinderCacheKey binderCacheKey = CreateBinderCacheKey(parent, usage);
|
|
Binder binder = default(Binder);
|
|
if (!binderCache.TryGetValue(binderCacheKey, ref binder))
|
|
{
|
|
binder = VisitCore((SyntaxNode)(object)parent.Parent);
|
|
if (flag)
|
|
{
|
|
SourceMemberMethodSymbol methodSymbol = GetMethodSymbol(parent, binder);
|
|
if ((object)methodSymbol != null)
|
|
{
|
|
binder = new InMethodBinder(methodSymbol, binder);
|
|
}
|
|
}
|
|
binder = binder.WithUnsafeRegionIfNecessary(parent.Modifiers);
|
|
binderCache.TryAdd(binderCacheKey, binder);
|
|
}
|
|
return binder;
|
|
}
|
|
|
|
public override Binder VisitDestructorDeclaration(DestructorDeclarationSyntax parent)
|
|
{
|
|
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
|
|
if (!LookupPosition.IsInBody(_position, parent))
|
|
{
|
|
return VisitCore((SyntaxNode)(object)parent.Parent);
|
|
}
|
|
BinderCacheKey binderCacheKey = CreateBinderCacheKey(parent, NodeUsage.Normal);
|
|
Binder binder = default(Binder);
|
|
if (!binderCache.TryGetValue(binderCacheKey, ref binder))
|
|
{
|
|
binder = VisitCore((SyntaxNode)(object)parent.Parent);
|
|
binder = new InMethodBinder(GetMethodSymbol(parent, binder), binder);
|
|
binder = binder.WithUnsafeRegionIfNecessary(parent.Modifiers);
|
|
binderCache.TryAdd(binderCacheKey, binder);
|
|
}
|
|
return binder;
|
|
}
|
|
|
|
public override Binder VisitAccessorDeclaration(AccessorDeclarationSyntax parent)
|
|
{
|
|
if (!LookupPosition.IsInMethodDeclaration(_position, parent))
|
|
{
|
|
return VisitCore((SyntaxNode)(object)parent.Parent);
|
|
}
|
|
bool flag = LookupPosition.IsInBody(_position, parent);
|
|
NodeUsage usage = (flag ? NodeUsage.MethodTypeParameters : NodeUsage.Normal);
|
|
BinderCacheKey binderCacheKey = CreateBinderCacheKey(parent, usage);
|
|
Binder binder = default(Binder);
|
|
if (!binderCache.TryGetValue(binderCacheKey, ref binder))
|
|
{
|
|
binder = VisitCore((SyntaxNode)(object)parent.Parent);
|
|
if (flag)
|
|
{
|
|
CSharpSyntaxNode parent2 = parent.Parent.Parent;
|
|
MethodSymbol methodSymbol = null;
|
|
switch (parent2.Kind())
|
|
{
|
|
case SyntaxKind.PropertyDeclaration:
|
|
case SyntaxKind.IndexerDeclaration:
|
|
{
|
|
SourcePropertySymbol propertySymbol = GetPropertySymbol((BasePropertyDeclarationSyntax)parent2, binder);
|
|
if ((object)propertySymbol != null)
|
|
{
|
|
methodSymbol = ((parent.Kind() == SyntaxKind.GetAccessorDeclaration) ? propertySymbol.GetMethod : propertySymbol.SetMethod);
|
|
}
|
|
break;
|
|
}
|
|
case SyntaxKind.EventFieldDeclaration:
|
|
case SyntaxKind.EventDeclaration:
|
|
{
|
|
SourceEventSymbol eventSymbol = GetEventSymbol((EventDeclarationSyntax)parent2, binder);
|
|
if ((object)eventSymbol != null)
|
|
{
|
|
methodSymbol = ((parent.Kind() == SyntaxKind.AddAccessorDeclaration) ? eventSymbol.AddMethod : eventSymbol.RemoveMethod);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
throw ExceptionUtilities.UnexpectedValue((object)parent2.Kind());
|
|
}
|
|
if ((object)methodSymbol != null)
|
|
{
|
|
binder = new InMethodBinder(methodSymbol, binder);
|
|
}
|
|
}
|
|
binderCache.TryAdd(binderCacheKey, binder);
|
|
}
|
|
return binder;
|
|
}
|
|
|
|
private Binder VisitOperatorOrConversionDeclaration(BaseMethodDeclarationSyntax parent)
|
|
{
|
|
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
|
|
if (!LookupPosition.IsInMethodDeclaration(_position, parent))
|
|
{
|
|
return VisitCore((SyntaxNode)(object)parent.Parent);
|
|
}
|
|
bool flag = LookupPosition.IsInBody(_position, parent);
|
|
NodeUsage usage = (flag ? NodeUsage.MethodTypeParameters : NodeUsage.Normal);
|
|
BinderCacheKey binderCacheKey = CreateBinderCacheKey(parent, usage);
|
|
Binder binder = default(Binder);
|
|
if (!binderCache.TryGetValue(binderCacheKey, ref binder))
|
|
{
|
|
binder = VisitCore((SyntaxNode)(object)parent.Parent);
|
|
MethodSymbol methodSymbol = GetMethodSymbol(parent, binder);
|
|
if ((object)methodSymbol != null && flag)
|
|
{
|
|
binder = new InMethodBinder(methodSymbol, binder);
|
|
}
|
|
binder = binder.WithUnsafeRegionIfNecessary(parent.Modifiers);
|
|
binderCache.TryAdd(binderCacheKey, binder);
|
|
}
|
|
return binder;
|
|
}
|
|
|
|
public override Binder VisitOperatorDeclaration(OperatorDeclarationSyntax parent)
|
|
{
|
|
return VisitOperatorOrConversionDeclaration(parent);
|
|
}
|
|
|
|
public override Binder VisitConversionOperatorDeclaration(ConversionOperatorDeclarationSyntax parent)
|
|
{
|
|
return VisitOperatorOrConversionDeclaration(parent);
|
|
}
|
|
|
|
public override Binder VisitFieldDeclaration(FieldDeclarationSyntax parent)
|
|
{
|
|
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
|
|
return VisitCore((SyntaxNode)(object)parent.Parent).WithUnsafeRegionIfNecessary(parent.Modifiers);
|
|
}
|
|
|
|
public override Binder VisitEventDeclaration(EventDeclarationSyntax parent)
|
|
{
|
|
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
|
|
return VisitCore((SyntaxNode)(object)parent.Parent).WithUnsafeRegionIfNecessary(parent.Modifiers);
|
|
}
|
|
|
|
public override Binder VisitEventFieldDeclaration(EventFieldDeclarationSyntax parent)
|
|
{
|
|
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
|
|
return VisitCore((SyntaxNode)(object)parent.Parent).WithUnsafeRegionIfNecessary(parent.Modifiers);
|
|
}
|
|
|
|
public override Binder VisitPropertyDeclaration(PropertyDeclarationSyntax parent)
|
|
{
|
|
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
|
|
if (!LookupPosition.IsInBody(_position, parent))
|
|
{
|
|
return VisitCore((SyntaxNode)(object)parent.Parent).WithUnsafeRegionIfNecessary(parent.Modifiers);
|
|
}
|
|
return VisitPropertyOrIndexerExpressionBody(parent);
|
|
}
|
|
|
|
public override Binder VisitIndexerDeclaration(IndexerDeclarationSyntax parent)
|
|
{
|
|
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
|
|
if (!LookupPosition.IsInBody(_position, parent))
|
|
{
|
|
return VisitCore((SyntaxNode)(object)parent.Parent).WithUnsafeRegionIfNecessary(parent.Modifiers);
|
|
}
|
|
return VisitPropertyOrIndexerExpressionBody(parent);
|
|
}
|
|
|
|
private Binder VisitPropertyOrIndexerExpressionBody(BasePropertyDeclarationSyntax parent)
|
|
{
|
|
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
|
|
BinderCacheKey binderCacheKey = CreateBinderCacheKey(parent, NodeUsage.MethodTypeParameters);
|
|
Binder binder = default(Binder);
|
|
if (!binderCache.TryGetValue(binderCacheKey, ref binder))
|
|
{
|
|
binder = VisitCore((SyntaxNode)(object)parent.Parent).WithUnsafeRegionIfNecessary(parent.Modifiers);
|
|
MethodSymbol getMethod = GetPropertySymbol(parent, binder).GetMethod;
|
|
if ((object)getMethod != null)
|
|
{
|
|
binder = new InMethodBinder(getMethod, binder);
|
|
}
|
|
binderCache.TryAdd(binderCacheKey, binder);
|
|
}
|
|
return binder;
|
|
}
|
|
|
|
private NamedTypeSymbol GetContainerType(Binder binder, CSharpSyntaxNode node)
|
|
{
|
|
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
|
|
Symbol containingMemberOrLambda = binder.ContainingMemberOrLambda;
|
|
NamedTypeSymbol namedTypeSymbol = containingMemberOrLambda as NamedTypeSymbol;
|
|
if ((object)namedTypeSymbol == null)
|
|
{
|
|
namedTypeSymbol = ((node.Parent.Kind() != SyntaxKind.CompilationUnit || (int)syntaxTree.Options.Kind == 0) ? ((NamespaceSymbol)containingMemberOrLambda).ImplicitType : compilation.ScriptClass);
|
|
}
|
|
return namedTypeSymbol;
|
|
}
|
|
|
|
private static string GetMethodName(BaseMethodDeclarationSyntax baseMethodDeclarationSyntax, Binder outerBinder)
|
|
{
|
|
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
|
|
switch (baseMethodDeclarationSyntax.Kind())
|
|
{
|
|
case SyntaxKind.ConstructorDeclaration:
|
|
if (!baseMethodDeclarationSyntax.Modifiers.Any(SyntaxKind.StaticKeyword))
|
|
{
|
|
return ".ctor";
|
|
}
|
|
return ".cctor";
|
|
case SyntaxKind.DestructorDeclaration:
|
|
return "Finalize";
|
|
case SyntaxKind.OperatorDeclaration:
|
|
{
|
|
OperatorDeclarationSyntax operatorDeclarationSyntax = (OperatorDeclarationSyntax)baseMethodDeclarationSyntax;
|
|
return ExplicitInterfaceHelpers.GetMemberName(outerBinder, operatorDeclarationSyntax.ExplicitInterfaceSpecifier, OperatorFacts.OperatorNameFromDeclaration(operatorDeclarationSyntax));
|
|
}
|
|
case SyntaxKind.ConversionOperatorDeclaration:
|
|
{
|
|
ConversionOperatorDeclarationSyntax conversionOperatorDeclarationSyntax = (ConversionOperatorDeclarationSyntax)baseMethodDeclarationSyntax;
|
|
return ExplicitInterfaceHelpers.GetMemberName(outerBinder, conversionOperatorDeclarationSyntax.ExplicitInterfaceSpecifier, OperatorFacts.OperatorNameFromDeclaration(conversionOperatorDeclarationSyntax));
|
|
}
|
|
case SyntaxKind.MethodDeclaration:
|
|
{
|
|
MethodDeclarationSyntax methodDeclarationSyntax = (MethodDeclarationSyntax)baseMethodDeclarationSyntax;
|
|
ExplicitInterfaceSpecifierSyntax? explicitInterfaceSpecifier = methodDeclarationSyntax.ExplicitInterfaceSpecifier;
|
|
SyntaxToken identifier = methodDeclarationSyntax.Identifier;
|
|
return ExplicitInterfaceHelpers.GetMemberName(outerBinder, explicitInterfaceSpecifier, ((SyntaxToken)(ref identifier)).ValueText);
|
|
}
|
|
default:
|
|
throw ExceptionUtilities.UnexpectedValue((object)baseMethodDeclarationSyntax.Kind());
|
|
}
|
|
}
|
|
|
|
private static string GetPropertyOrEventName(BasePropertyDeclarationSyntax basePropertyDeclarationSyntax, Binder outerBinder)
|
|
{
|
|
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
|
|
ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier = basePropertyDeclarationSyntax.ExplicitInterfaceSpecifier;
|
|
SyntaxToken identifier;
|
|
switch (basePropertyDeclarationSyntax.Kind())
|
|
{
|
|
case SyntaxKind.PropertyDeclaration:
|
|
{
|
|
PropertyDeclarationSyntax propertyDeclarationSyntax = (PropertyDeclarationSyntax)basePropertyDeclarationSyntax;
|
|
identifier = propertyDeclarationSyntax.Identifier;
|
|
return ExplicitInterfaceHelpers.GetMemberName(outerBinder, explicitInterfaceSpecifier, ((SyntaxToken)(ref identifier)).ValueText);
|
|
}
|
|
case SyntaxKind.IndexerDeclaration:
|
|
return ExplicitInterfaceHelpers.GetMemberName(outerBinder, explicitInterfaceSpecifier, "this[]");
|
|
case SyntaxKind.EventFieldDeclaration:
|
|
case SyntaxKind.EventDeclaration:
|
|
{
|
|
EventDeclarationSyntax eventDeclarationSyntax = (EventDeclarationSyntax)basePropertyDeclarationSyntax;
|
|
identifier = eventDeclarationSyntax.Identifier;
|
|
return ExplicitInterfaceHelpers.GetMemberName(outerBinder, explicitInterfaceSpecifier, ((SyntaxToken)(ref identifier)).ValueText);
|
|
}
|
|
default:
|
|
throw ExceptionUtilities.UnexpectedValue((object)basePropertyDeclarationSyntax.Kind());
|
|
}
|
|
}
|
|
|
|
private SourceMemberMethodSymbol GetMethodSymbol(BaseMethodDeclarationSyntax baseMethodDeclarationSyntax, Binder outerBinder)
|
|
{
|
|
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
|
|
if (baseMethodDeclarationSyntax == _memberDeclarationOpt)
|
|
{
|
|
return (SourceMemberMethodSymbol)_memberOpt;
|
|
}
|
|
NamedTypeSymbol containerType = GetContainerType(outerBinder, baseMethodDeclarationSyntax);
|
|
if ((object)containerType == null)
|
|
{
|
|
return null;
|
|
}
|
|
string methodName = GetMethodName(baseMethodDeclarationSyntax, outerBinder);
|
|
return (SourceMemberMethodSymbol)GetMemberSymbol(methodName, ((SyntaxNode)baseMethodDeclarationSyntax).FullSpan, containerType, (SymbolKind)9);
|
|
}
|
|
|
|
private SourcePropertySymbol GetPropertySymbol(BasePropertyDeclarationSyntax basePropertyDeclarationSyntax, Binder outerBinder)
|
|
{
|
|
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
|
|
if (basePropertyDeclarationSyntax == _memberDeclarationOpt)
|
|
{
|
|
return (SourcePropertySymbol)_memberOpt;
|
|
}
|
|
NamedTypeSymbol containerType = GetContainerType(outerBinder, basePropertyDeclarationSyntax);
|
|
if ((object)containerType == null)
|
|
{
|
|
return null;
|
|
}
|
|
string propertyOrEventName = GetPropertyOrEventName(basePropertyDeclarationSyntax, outerBinder);
|
|
return (SourcePropertySymbol)GetMemberSymbol(propertyOrEventName, ((SyntaxNode)basePropertyDeclarationSyntax).Span, containerType, (SymbolKind)15);
|
|
}
|
|
|
|
private SourceEventSymbol GetEventSymbol(EventDeclarationSyntax eventDeclarationSyntax, Binder outerBinder)
|
|
{
|
|
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
|
|
if (eventDeclarationSyntax == _memberDeclarationOpt)
|
|
{
|
|
return (SourceEventSymbol)_memberOpt;
|
|
}
|
|
NamedTypeSymbol containerType = GetContainerType(outerBinder, eventDeclarationSyntax);
|
|
if ((object)containerType == null)
|
|
{
|
|
return null;
|
|
}
|
|
string propertyOrEventName = GetPropertyOrEventName(eventDeclarationSyntax, outerBinder);
|
|
return (SourceEventSymbol)GetMemberSymbol(propertyOrEventName, ((SyntaxNode)eventDeclarationSyntax).Span, containerType, (SymbolKind)5);
|
|
}
|
|
|
|
private Symbol GetMemberSymbol(string memberName, TextSpan memberSpan, NamedTypeSymbol container, SymbolKind kind)
|
|
{
|
|
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
|
|
if (container is SourceMemberContainerTypeSymbol { HasPrimaryConstructor: not false } sourceMemberContainerTypeSymbol)
|
|
{
|
|
ImmutableArray<Symbol>.Enumerator enumerator = sourceMemberContainerTypeSymbol.GetMembersToMatchAgainstDeclarationSpan().GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
Symbol current = enumerator.Current;
|
|
if (!current.IsAccessor() && current.Name == memberName && checkSymbol(current, memberSpan, kind, out var result))
|
|
{
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ImmutableArray<Symbol>.Enumerator enumerator = container.GetMembers(memberName).GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
Symbol current2 = enumerator.Current;
|
|
if (checkSymbol(current2, memberSpan, kind, out var result2))
|
|
{
|
|
return result2;
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
bool checkSymbol(Symbol sym, TextSpan span, SymbolKind val, out Symbol reference)
|
|
{
|
|
//IL_0005: 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)
|
|
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0017: Invalid comparison between Unknown and I4
|
|
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
|
|
reference = sym;
|
|
if (sym.Kind != val)
|
|
{
|
|
return false;
|
|
}
|
|
if ((int)sym.Kind == 9)
|
|
{
|
|
if (InSpan(sym.GetFirstLocation(), syntaxTree, span))
|
|
{
|
|
return true;
|
|
}
|
|
MethodSymbol partialImplementationPart = ((MethodSymbol)sym).PartialImplementationPart;
|
|
if ((object)partialImplementationPart != null && InSpan(partialImplementationPart.GetFirstLocation(), syntaxTree, span))
|
|
{
|
|
reference = partialImplementationPart;
|
|
return true;
|
|
}
|
|
}
|
|
else if (InSpan(sym.Locations, syntaxTree, span))
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private static bool InSpan(Location location, SyntaxTree syntaxTree, TextSpan span)
|
|
{
|
|
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
|
|
if (location.SourceTree == syntaxTree)
|
|
{
|
|
return ((TextSpan)(ref span)).Contains(location.SourceSpan);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private static bool InSpan(ImmutableArray<Location> locations, SyntaxTree syntaxTree, TextSpan span)
|
|
{
|
|
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
|
|
ImmutableArray<Location>.Enumerator enumerator = locations.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
if (InSpan(enumerator.Current, syntaxTree, span))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public override Binder VisitDelegateDeclaration(DelegateDeclarationSyntax parent)
|
|
{
|
|
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
|
|
if (!LookupPosition.IsInDelegateDeclaration(_position, parent))
|
|
{
|
|
return VisitCore((SyntaxNode)(object)parent.Parent);
|
|
}
|
|
BinderCacheKey binderCacheKey = CreateBinderCacheKey(parent, NodeUsage.Normal);
|
|
Binder binder = default(Binder);
|
|
if (!binderCache.TryGetValue(binderCacheKey, ref binder))
|
|
{
|
|
Binder binder2 = VisitCore((SyntaxNode)(object)parent.Parent);
|
|
SourceNamedTypeSymbol sourceTypeMember = ((NamespaceOrTypeSymbol)binder2.ContainingMemberOrLambda).GetSourceTypeMember(parent);
|
|
binder = new InContainerBinder(sourceTypeMember, binder2);
|
|
if (parent.TypeParameterList != null)
|
|
{
|
|
binder = new WithClassTypeParametersBinder(sourceTypeMember, binder);
|
|
}
|
|
binder = binder.WithUnsafeRegionIfNecessary(parent.Modifiers);
|
|
binderCache.TryAdd(binderCacheKey, binder);
|
|
}
|
|
return binder;
|
|
}
|
|
|
|
public override Binder VisitEnumDeclaration(EnumDeclarationSyntax parent)
|
|
{
|
|
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_000d: 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_006d: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0072: 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)
|
|
if (!LookupPosition.IsBetweenTokens(_position, parent.OpenBraceToken, parent.CloseBraceToken) && !LookupPosition.IsInAttributeSpecification(_position, parent.AttributeLists))
|
|
{
|
|
return VisitCore((SyntaxNode)(object)parent.Parent);
|
|
}
|
|
BinderCacheKey binderCacheKey = CreateBinderCacheKey(parent, NodeUsage.Normal);
|
|
Binder binder = default(Binder);
|
|
if (!binderCache.TryGetValue(binderCacheKey, ref binder))
|
|
{
|
|
Binder binder2 = VisitCore((SyntaxNode)(object)parent.Parent);
|
|
NamespaceOrTypeSymbol obj = (NamespaceOrTypeSymbol)binder2.ContainingMemberOrLambda;
|
|
SyntaxToken identifier = parent.Identifier;
|
|
binder = new InContainerBinder(obj.GetSourceTypeMember(((SyntaxToken)(ref identifier)).ValueText, 0, SyntaxKind.EnumDeclaration, parent), binder2);
|
|
binder = binder.WithUnsafeRegionIfNecessary(parent.Modifiers);
|
|
binderCache.TryAdd(binderCacheKey, binder);
|
|
}
|
|
return binder;
|
|
}
|
|
|
|
private Binder VisitTypeDeclarationCore(TypeDeclarationSyntax parent)
|
|
{
|
|
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
|
|
if (!LookupPosition.IsInTypeDeclaration(_position, parent))
|
|
{
|
|
return VisitCore((SyntaxNode)(object)parent.Parent);
|
|
}
|
|
NodeUsage extraInfo = NodeUsage.Normal;
|
|
if (parent.OpenBraceToken != default(SyntaxToken) && parent.CloseBraceToken != default(SyntaxToken) && LookupPosition.IsBetweenTokens(_position, parent.OpenBraceToken, parent.CloseBraceToken))
|
|
{
|
|
extraInfo = NodeUsage.MethodBody;
|
|
}
|
|
else if (LookupPosition.IsInAttributeSpecification(_position, parent.AttributeLists))
|
|
{
|
|
extraInfo = NodeUsage.MethodBody;
|
|
}
|
|
else if (LookupPosition.IsInTypeParameterList(_position, parent))
|
|
{
|
|
extraInfo = NodeUsage.MethodBody;
|
|
}
|
|
else if (LookupPosition.IsBetweenTokens(_position, parent.Keyword, parent.OpenBraceToken))
|
|
{
|
|
extraInfo = NodeUsage.NamedTypeBaseListOrParameterList;
|
|
}
|
|
return VisitTypeDeclarationCore(parent, extraInfo);
|
|
}
|
|
|
|
internal Binder VisitTypeDeclarationCore(TypeDeclarationSyntax parent, NodeUsage extraInfo)
|
|
{
|
|
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
|
|
BinderCacheKey binderCacheKey = CreateBinderCacheKey(parent, extraInfo);
|
|
Binder binder = default(Binder);
|
|
if (!binderCache.TryGetValue(binderCacheKey, ref binder))
|
|
{
|
|
binder = VisitCore((SyntaxNode)(object)parent.Parent);
|
|
if (extraInfo != NodeUsage.Normal)
|
|
{
|
|
SourceNamedTypeSymbol sourceTypeMember = ((NamespaceOrTypeSymbol)binder.ContainingMemberOrLambda).GetSourceTypeMember(parent);
|
|
if (extraInfo == NodeUsage.NamedTypeBaseListOrParameterList)
|
|
{
|
|
binder = new WithClassTypeParametersBinder(sourceTypeMember, binder);
|
|
}
|
|
else
|
|
{
|
|
binder = new WithPrimaryConstructorParametersBinder(sourceTypeMember, binder);
|
|
binder = new InContainerBinder(sourceTypeMember, binder);
|
|
if (parent.TypeParameterList != null)
|
|
{
|
|
binder = new WithClassTypeParametersBinder(sourceTypeMember, binder);
|
|
}
|
|
}
|
|
}
|
|
binder = binder.WithUnsafeRegionIfNecessary(parent.Modifiers);
|
|
binderCache.TryAdd(binderCacheKey, binder);
|
|
}
|
|
return binder;
|
|
}
|
|
|
|
public override Binder VisitClassDeclaration(ClassDeclarationSyntax node)
|
|
{
|
|
return VisitTypeDeclarationCore(node);
|
|
}
|
|
|
|
public override Binder VisitStructDeclaration(StructDeclarationSyntax node)
|
|
{
|
|
return VisitTypeDeclarationCore(node);
|
|
}
|
|
|
|
public override Binder VisitInterfaceDeclaration(InterfaceDeclarationSyntax node)
|
|
{
|
|
return VisitTypeDeclarationCore(node);
|
|
}
|
|
|
|
public override Binder VisitRecordDeclaration(RecordDeclarationSyntax node)
|
|
{
|
|
return VisitTypeDeclarationCore(node);
|
|
}
|
|
|
|
public sealed override Binder VisitNamespaceDeclaration(NamespaceDeclarationSyntax parent)
|
|
{
|
|
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
|
|
if (!LookupPosition.IsInNamespaceDeclaration(_position, parent))
|
|
{
|
|
return VisitCore((SyntaxNode)(object)parent.Parent);
|
|
}
|
|
bool inBody = LookupPosition.IsBetweenTokens(_position, parent.OpenBraceToken, parent.CloseBraceToken);
|
|
bool inUsing = IsInUsing(parent);
|
|
return VisitNamespaceDeclaration(parent, _position, inBody, inUsing);
|
|
}
|
|
|
|
public override Binder VisitFileScopedNamespaceDeclaration(FileScopedNamespaceDeclarationSyntax parent)
|
|
{
|
|
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
|
|
if (!LookupPosition.IsInNamespaceDeclaration(_position, parent))
|
|
{
|
|
return VisitCore((SyntaxNode)(object)parent.Parent);
|
|
}
|
|
int position = _position;
|
|
SyntaxToken semicolonToken = parent.SemicolonToken;
|
|
bool inBody = position >= ((SyntaxToken)(ref semicolonToken)).EndPosition;
|
|
bool inUsing = IsInUsing(parent);
|
|
return VisitNamespaceDeclaration(parent, _position, inBody, inUsing);
|
|
}
|
|
|
|
internal Binder VisitNamespaceDeclaration(BaseNamespaceDeclarationSyntax parent, int position, bool inBody, bool inUsing)
|
|
{
|
|
NodeUsage usage = (inUsing ? NodeUsage.MethodBody : (inBody ? NodeUsage.MethodTypeParameters : NodeUsage.Normal));
|
|
BinderCacheKey binderCacheKey = CreateBinderCacheKey(parent, usage);
|
|
Binder binder = default(Binder);
|
|
if (!binderCache.TryGetValue(binderCacheKey, ref binder))
|
|
{
|
|
CSharpSyntaxNode parent2 = parent.Parent;
|
|
Binder binder2 = ((!InScript || parent2.Kind() != SyntaxKind.CompilationUnit) ? _factory.GetBinder((SyntaxNode)(object)parent.Parent, position) : VisitCompilationUnit((CompilationUnitSyntax)parent2, inUsing: false, inScript: false));
|
|
binder = (inBody ? MakeNamespaceBinder(parent, parent.Name, binder2, inUsing) : binder2);
|
|
binderCache.TryAdd(binderCacheKey, binder);
|
|
}
|
|
return binder;
|
|
}
|
|
|
|
private static Binder MakeNamespaceBinder(CSharpSyntaxNode node, NameSyntax name, Binder outer, bool inUsing)
|
|
{
|
|
if (name is QualifiedNameSyntax qualifiedNameSyntax)
|
|
{
|
|
outer = MakeNamespaceBinder(qualifiedNameSyntax.Left, qualifiedNameSyntax.Left, outer, inUsing: false);
|
|
name = qualifiedNameSyntax.Right;
|
|
}
|
|
NamespaceOrTypeSymbol namespaceOrTypeSymbol = ((!(outer is InContainerBinder inContainerBinder)) ? outer.Compilation.GlobalNamespace : inContainerBinder.Container);
|
|
NamespaceSymbol nestedNamespace = ((NamespaceSymbol)namespaceOrTypeSymbol).GetNestedNamespace(name);
|
|
if ((object)nestedNamespace == null)
|
|
{
|
|
return outer;
|
|
}
|
|
if (node is BaseNamespaceDeclarationSyntax declarationSyntax)
|
|
{
|
|
outer = AddInImportsBinders((SourceNamespaceSymbol)outer.Compilation.SourceModule.GetModuleNamespace(nestedNamespace), declarationSyntax, outer, inUsing);
|
|
}
|
|
return new InContainerBinder(nestedNamespace, outer);
|
|
}
|
|
|
|
public override Binder VisitCompilationUnit(CompilationUnitSyntax parent)
|
|
{
|
|
return VisitCompilationUnit(parent, IsInUsing(parent), InScript);
|
|
}
|
|
|
|
internal Binder VisitCompilationUnit(CompilationUnitSyntax compilationUnit, bool inUsing, bool inScript)
|
|
{
|
|
if ((object)compilationUnit != syntaxTree.GetRoot(default(CancellationToken)))
|
|
{
|
|
throw new ArgumentOutOfRangeException("compilationUnit", "node not part of tree");
|
|
}
|
|
NodeUsage usage = ((!inUsing) ? (inScript ? NodeUsage.MethodBody : NodeUsage.Normal) : ((!inScript) ? NodeUsage.MethodTypeParameters : NodeUsage.NamedTypeBaseListOrParameterList));
|
|
BinderCacheKey binderCacheKey = CreateBinderCacheKey(compilationUnit, usage);
|
|
Binder binder = default(Binder);
|
|
if (!binderCache.TryGetValue(binderCacheKey, ref binder))
|
|
{
|
|
binder = buckStopsHereBinder;
|
|
if (inScript)
|
|
{
|
|
bool flag = compilation.IsSubmissionSyntaxTree(compilationUnit.SyntaxTree);
|
|
NamedTypeSymbol scriptClass = compilation.ScriptClass;
|
|
bool isSubmissionClass = scriptClass.IsSubmissionClass;
|
|
if (!inUsing)
|
|
{
|
|
binder = WithUsingNamespacesAndTypesBinder.Create(compilation.GlobalImports, binder, withImportChainEntry: true);
|
|
if (isSubmissionClass)
|
|
{
|
|
binder = WithUsingNamespacesAndTypesBinder.Create((SourceNamespaceSymbol)compilation.SourceModule.GlobalNamespace, compilationUnit, binder, compilation.PreviousSubmission != null && flag, withImportChainEntry: true);
|
|
}
|
|
}
|
|
binder = new InContainerBinder(compilation.GlobalNamespace, binder);
|
|
if (((Compilation)compilation).HostObjectType != null)
|
|
{
|
|
binder = new HostObjectModelBinder(binder);
|
|
}
|
|
if (isSubmissionClass)
|
|
{
|
|
binder = new InSubmissionClassBinder(scriptClass, binder, compilationUnit, inUsing);
|
|
}
|
|
else
|
|
{
|
|
binder = AddInImportsBinders((SourceNamespaceSymbol)compilation.SourceModule.GlobalNamespace, compilationUnit, binder, inUsing);
|
|
binder = new InContainerBinder(scriptClass, binder);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
NamespaceSymbol globalNamespace = compilation.GlobalNamespace;
|
|
binder = AddInImportsBinders((SourceNamespaceSymbol)compilation.SourceModule.GlobalNamespace, compilationUnit, binder, inUsing);
|
|
binder = new InContainerBinder(globalNamespace, binder);
|
|
if (!inUsing)
|
|
{
|
|
SynthesizedSimpleProgramEntryPointSymbol simpleProgramEntryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(compilation, compilationUnit, fallbackToMainEntryPoint: true);
|
|
if ((object)simpleProgramEntryPoint != null)
|
|
{
|
|
ExecutableCodeBinder bodyBinder = simpleProgramEntryPoint.GetBodyBinder(_factory._ignoreAccessibility);
|
|
binder = new SimpleProgramUnitBinder(binder, (SimpleProgramBinder)bodyBinder.GetBinder((SyntaxNode)(object)simpleProgramEntryPoint.SyntaxNode));
|
|
}
|
|
}
|
|
}
|
|
binderCache.TryAdd(binderCacheKey, binder);
|
|
}
|
|
return binder;
|
|
}
|
|
|
|
private static Binder AddInImportsBinders(SourceNamespaceSymbol declaringSymbol, CSharpSyntaxNode declarationSyntax, Binder next, bool inUsing)
|
|
{
|
|
if (inUsing)
|
|
{
|
|
return WithExternAliasesBinder.Create(declaringSymbol, declarationSyntax, next);
|
|
}
|
|
return WithExternAndUsingAliasesBinder.Create(declaringSymbol, declarationSyntax, WithUsingNamespacesAndTypesBinder.Create(declaringSymbol, declarationSyntax, next));
|
|
}
|
|
|
|
internal static BinderCacheKey CreateBinderCacheKey(CSharpSyntaxNode node, NodeUsage usage)
|
|
{
|
|
return new BinderCacheKey(node, usage);
|
|
}
|
|
|
|
private bool IsInUsing(CSharpSyntaxNode containingNode)
|
|
{
|
|
//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_0028: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
|
|
TextSpan span = ((SyntaxNode)containingNode).Span;
|
|
SyntaxToken val;
|
|
if (containingNode.Kind() != SyntaxKind.CompilationUnit && _position == ((TextSpan)(ref span)).End)
|
|
{
|
|
val = containingNode.GetLastToken();
|
|
}
|
|
else
|
|
{
|
|
if (_position < ((TextSpan)(ref span)).Start || _position > ((TextSpan)(ref span)).End)
|
|
{
|
|
return false;
|
|
}
|
|
val = containingNode.FindToken(_position);
|
|
}
|
|
SyntaxNode parent = ((SyntaxToken)(ref val)).Parent;
|
|
while (parent != null && (object)parent != containingNode)
|
|
{
|
|
if (parent.IsKind(SyntaxKind.UsingDirective) && (object)parent.Parent == containingNode)
|
|
{
|
|
return true;
|
|
}
|
|
parent = parent.Parent;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public override Binder VisitDocumentationCommentTrivia(DocumentationCommentTriviaSyntax parent)
|
|
{
|
|
//IL_0002: 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_000a: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
|
|
SyntaxTrivia parentTrivia = ((SyntaxNode)parent).ParentTrivia;
|
|
SyntaxToken token = ((SyntaxTrivia)(ref parentTrivia)).Token;
|
|
return VisitCore(((SyntaxToken)(ref token)).Parent);
|
|
}
|
|
|
|
public override Binder VisitCrefParameter(CrefParameterSyntax parent)
|
|
{
|
|
XmlCrefAttributeSyntax parent2 = ((SyntaxNode)parent).FirstAncestorOrSelf<XmlCrefAttributeSyntax>((Func<XmlCrefAttributeSyntax, bool>)null, false);
|
|
return VisitXmlCrefAttributeInternal(parent2, NodeUsage.MethodTypeParameters);
|
|
}
|
|
|
|
public override Binder VisitConversionOperatorMemberCref(ConversionOperatorMemberCrefSyntax parent)
|
|
{
|
|
//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)
|
|
TextSpan span = ((SyntaxNode)parent.Type).Span;
|
|
if (((TextSpan)(ref span)).Contains(_position))
|
|
{
|
|
XmlCrefAttributeSyntax parent2 = ((SyntaxNode)parent).FirstAncestorOrSelf<XmlCrefAttributeSyntax>((Func<XmlCrefAttributeSyntax, bool>)null, false);
|
|
return VisitXmlCrefAttributeInternal(parent2, NodeUsage.MethodTypeParameters);
|
|
}
|
|
return base.VisitConversionOperatorMemberCref(parent);
|
|
}
|
|
|
|
public override Binder VisitXmlCrefAttribute(XmlCrefAttributeSyntax parent)
|
|
{
|
|
if (!LookupPosition.IsInXmlAttributeValue(_position, parent))
|
|
{
|
|
return VisitCore((SyntaxNode)(object)parent.Parent);
|
|
}
|
|
NodeUsage extraInfo = NodeUsage.Normal;
|
|
return VisitXmlCrefAttributeInternal(parent, extraInfo);
|
|
}
|
|
|
|
private Binder VisitXmlCrefAttributeInternal(XmlCrefAttributeSyntax parent, NodeUsage extraInfo)
|
|
{
|
|
BinderCacheKey binderCacheKey = CreateBinderCacheKey(parent, extraInfo);
|
|
Binder binder = default(Binder);
|
|
if (!binderCache.TryGetValue(binderCacheKey, ref binder))
|
|
{
|
|
CrefSyntax cref = parent.Cref;
|
|
MemberDeclarationSyntax associatedMemberForXmlSyntax = GetAssociatedMemberForXmlSyntax(parent);
|
|
bool inParameterOrReturnType = extraInfo == NodeUsage.MethodTypeParameters;
|
|
binder = ((associatedMemberForXmlSyntax == null) ? MakeCrefBinderInternal(cref, VisitCore((SyntaxNode)(object)parent.Parent), inParameterOrReturnType) : MakeCrefBinder(cref, associatedMemberForXmlSyntax, _factory, inParameterOrReturnType));
|
|
binderCache.TryAdd(binderCacheKey, binder);
|
|
}
|
|
return binder;
|
|
}
|
|
|
|
public override Binder VisitXmlNameAttribute(XmlNameAttributeSyntax parent)
|
|
{
|
|
if (!LookupPosition.IsInXmlAttributeValue(_position, parent))
|
|
{
|
|
return VisitCore((SyntaxNode)(object)parent.Parent);
|
|
}
|
|
XmlNameAttributeElementKind elementKind = parent.GetElementKind();
|
|
NodeUsage usage;
|
|
switch (elementKind)
|
|
{
|
|
case XmlNameAttributeElementKind.Parameter:
|
|
case XmlNameAttributeElementKind.ParameterReference:
|
|
usage = NodeUsage.MethodTypeParameters;
|
|
break;
|
|
case XmlNameAttributeElementKind.TypeParameter:
|
|
usage = NodeUsage.MethodBody;
|
|
break;
|
|
case XmlNameAttributeElementKind.TypeParameterReference:
|
|
usage = NodeUsage.NamedTypeBaseListOrParameterList;
|
|
break;
|
|
default:
|
|
throw ExceptionUtilities.UnexpectedValue((object)elementKind);
|
|
}
|
|
BinderCacheKey binderCacheKey = CreateBinderCacheKey(GetEnclosingDocumentationComment(parent), usage);
|
|
Binder binder = default(Binder);
|
|
if (!binderCache.TryGetValue(binderCacheKey, ref binder))
|
|
{
|
|
binder = buckStopsHereBinder;
|
|
Binder binder2 = VisitCore((SyntaxNode)(object)GetEnclosingDocumentationComment(parent));
|
|
if (binder2 != null)
|
|
{
|
|
binder = binder.WithContainingMemberOrLambda(binder2.ContainingMemberOrLambda);
|
|
}
|
|
MemberDeclarationSyntax associatedMemberForXmlSyntax = GetAssociatedMemberForXmlSyntax(parent);
|
|
if (associatedMemberForXmlSyntax != null)
|
|
{
|
|
switch (elementKind)
|
|
{
|
|
case XmlNameAttributeElementKind.Parameter:
|
|
case XmlNameAttributeElementKind.ParameterReference:
|
|
binder = GetParameterNameAttributeValueBinder(associatedMemberForXmlSyntax, binder);
|
|
break;
|
|
case XmlNameAttributeElementKind.TypeParameter:
|
|
binder = GetTypeParameterNameAttributeValueBinder(associatedMemberForXmlSyntax, includeContainingSymbols: false, binder);
|
|
break;
|
|
case XmlNameAttributeElementKind.TypeParameterReference:
|
|
binder = GetTypeParameterNameAttributeValueBinder(associatedMemberForXmlSyntax, includeContainingSymbols: true, binder);
|
|
break;
|
|
}
|
|
}
|
|
binderCache.TryAdd(binderCacheKey, binder);
|
|
}
|
|
return binder;
|
|
}
|
|
|
|
private Binder GetParameterNameAttributeValueBinder(MemberDeclarationSyntax memberSyntax, Binder nextBinder)
|
|
{
|
|
if (memberSyntax is BaseMethodDeclarationSyntax baseMethodDeclarationSyntax)
|
|
{
|
|
ParameterListSyntax parameterList = baseMethodDeclarationSyntax.ParameterList;
|
|
if (parameterList != null && parameterList.ParameterCount > 0)
|
|
{
|
|
Binder outerBinder = VisitCore((SyntaxNode)(object)memberSyntax.Parent);
|
|
return new WithParametersBinder(GetMethodSymbol(baseMethodDeclarationSyntax, outerBinder).Parameters, nextBinder);
|
|
}
|
|
}
|
|
if (memberSyntax is TypeDeclarationSyntax typeDeclarationSyntax)
|
|
{
|
|
ParameterListSyntax parameterList = typeDeclarationSyntax.ParameterList;
|
|
if (parameterList != null && parameterList.ParameterCount > 0)
|
|
{
|
|
SynthesizedPrimaryConstructor primaryConstructor = ((NamespaceOrTypeSymbol)VisitCore((SyntaxNode)(object)memberSyntax).ContainingMemberOrLambda).GetSourceTypeMember((TypeDeclarationSyntax)memberSyntax).PrimaryConstructor;
|
|
if (primaryConstructor.SyntaxRef.SyntaxTree == memberSyntax.SyntaxTree && primaryConstructor.GetSyntax() == memberSyntax)
|
|
{
|
|
return new WithParametersBinder(primaryConstructor.Parameters, nextBinder);
|
|
}
|
|
}
|
|
}
|
|
switch (memberSyntax.Kind())
|
|
{
|
|
case SyntaxKind.PropertyDeclaration:
|
|
case SyntaxKind.IndexerDeclaration:
|
|
{
|
|
Binder outerBinder2 = VisitCore((SyntaxNode)(object)memberSyntax.Parent);
|
|
BasePropertyDeclarationSyntax basePropertyDeclarationSyntax = (BasePropertyDeclarationSyntax)memberSyntax;
|
|
PropertySymbol propertySymbol = GetPropertySymbol(basePropertyDeclarationSyntax, outerBinder2);
|
|
ImmutableArray<ParameterSymbol> immutableArray = propertySymbol.Parameters;
|
|
if ((object)propertySymbol.SetMethod != null)
|
|
{
|
|
immutableArray = immutableArray.Add(propertySymbol.SetMethod.Parameters.Last());
|
|
}
|
|
if (immutableArray.Any())
|
|
{
|
|
return new WithParametersBinder(immutableArray, nextBinder);
|
|
}
|
|
break;
|
|
}
|
|
case SyntaxKind.DelegateDeclaration:
|
|
{
|
|
ImmutableArray<ParameterSymbol> parameters = ((NamespaceOrTypeSymbol)VisitCore((SyntaxNode)(object)memberSyntax.Parent).ContainingMemberOrLambda).GetSourceTypeMember((DelegateDeclarationSyntax)memberSyntax).DelegateInvokeMethod.Parameters;
|
|
if (parameters.Any())
|
|
{
|
|
return new WithParametersBinder(parameters, nextBinder);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return nextBinder;
|
|
}
|
|
|
|
private Binder GetTypeParameterNameAttributeValueBinder(MemberDeclarationSyntax memberSyntax, bool includeContainingSymbols, Binder nextBinder)
|
|
{
|
|
if (includeContainingSymbols)
|
|
{
|
|
NamedTypeSymbol containingType = VisitCore((SyntaxNode)(object)memberSyntax.Parent).ContainingType;
|
|
while ((object)containingType != null)
|
|
{
|
|
if (containingType.Arity > 0)
|
|
{
|
|
nextBinder = new WithClassTypeParametersBinder(containingType, nextBinder);
|
|
}
|
|
containingType = containingType.ContainingType;
|
|
}
|
|
}
|
|
if (memberSyntax is TypeDeclarationSyntax { Arity: >0 } typeDeclarationSyntax)
|
|
{
|
|
return new WithClassTypeParametersBinder(((NamespaceOrTypeSymbol)VisitCore((SyntaxNode)(object)memberSyntax.Parent).ContainingMemberOrLambda).GetSourceTypeMember(typeDeclarationSyntax), nextBinder);
|
|
}
|
|
if (memberSyntax.Kind() == SyntaxKind.MethodDeclaration)
|
|
{
|
|
MethodDeclarationSyntax methodDeclarationSyntax = (MethodDeclarationSyntax)memberSyntax;
|
|
if (methodDeclarationSyntax.Arity > 0)
|
|
{
|
|
Binder outerBinder = VisitCore((SyntaxNode)(object)memberSyntax.Parent);
|
|
return new WithMethodTypeParametersBinder(GetMethodSymbol(methodDeclarationSyntax, outerBinder), nextBinder);
|
|
}
|
|
}
|
|
else if (memberSyntax.Kind() == SyntaxKind.DelegateDeclaration)
|
|
{
|
|
SourceNamedTypeSymbol sourceTypeMember = ((NamespaceOrTypeSymbol)VisitCore((SyntaxNode)(object)memberSyntax.Parent).ContainingMemberOrLambda).GetSourceTypeMember((DelegateDeclarationSyntax)memberSyntax);
|
|
if (sourceTypeMember.TypeParameters.Any())
|
|
{
|
|
return new WithClassTypeParametersBinder(sourceTypeMember, nextBinder);
|
|
}
|
|
}
|
|
return nextBinder;
|
|
}
|
|
}
|
|
|
|
private readonly struct BinderCacheKey(CSharpSyntaxNode syntaxNode, NodeUsage usage) : IEquatable<BinderCacheKey>
|
|
{
|
|
public readonly CSharpSyntaxNode syntaxNode = syntaxNode;
|
|
|
|
public readonly NodeUsage usage = usage;
|
|
|
|
bool IEquatable<BinderCacheKey>.Equals(BinderCacheKey other)
|
|
{
|
|
if (syntaxNode == other.syntaxNode)
|
|
{
|
|
return usage == other.usage;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public override int GetHashCode()
|
|
{
|
|
return Hash.Combine(((object)syntaxNode).GetHashCode(), (int)usage);
|
|
}
|
|
|
|
public override bool Equals(object obj)
|
|
{
|
|
throw new NotSupportedException();
|
|
}
|
|
}
|
|
|
|
internal enum NodeUsage : byte
|
|
{
|
|
Normal = 0,
|
|
MethodTypeParameters = 1,
|
|
MethodBody = 2,
|
|
ConstructorBodyOrInitializer = 1,
|
|
AccessorBody = 1,
|
|
OperatorBody = 1,
|
|
NamedTypeBodyOrTypeParameters = 2,
|
|
NamedTypeBaseListOrParameterList = 4,
|
|
NamespaceBody = 1,
|
|
NamespaceUsings = 2,
|
|
CompilationUnitUsings = 1,
|
|
CompilationUnitScript = 2,
|
|
CompilationUnitScriptUsings = 4,
|
|
DocumentationCommentParameter = 1,
|
|
DocumentationCommentTypeParameter = 2,
|
|
DocumentationCommentTypeParameterReference = 4,
|
|
CrefParameterOrReturnType = 1
|
|
}
|
|
|
|
private readonly ConcurrentCache<BinderCacheKey, Binder> _binderCache;
|
|
|
|
private readonly CSharpCompilation _compilation;
|
|
|
|
private readonly SyntaxTree _syntaxTree;
|
|
|
|
private readonly BuckStopsHereBinder _buckStopsHereBinder;
|
|
|
|
private readonly bool _ignoreAccessibility;
|
|
|
|
private readonly ObjectPool<BinderFactoryVisitor> _binderFactoryVisitorPool;
|
|
|
|
internal SyntaxTree SyntaxTree => _syntaxTree;
|
|
|
|
private bool InScript => (int)_syntaxTree.Options.Kind == 1;
|
|
|
|
internal static Binder MakeCrefBinder(CrefSyntax crefSyntax, MemberDeclarationSyntax memberSyntax, BinderFactory factory, bool inParameterOrReturnType = false)
|
|
{
|
|
Binder binder = ((memberSyntax is BaseTypeDeclarationSyntax baseTypeDeclaration) ? getBinder(baseTypeDeclaration) : factory.GetBinder((SyntaxNode)(object)memberSyntax));
|
|
return MakeCrefBinderInternal(crefSyntax, binder, inParameterOrReturnType);
|
|
Binder getBinder(BaseTypeDeclarationSyntax baseTypeDeclarationSyntax)
|
|
{
|
|
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0049: 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_0010: 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_0025: Unknown result type (might be due to invalid IL or missing references)
|
|
SyntaxToken openBraceToken;
|
|
if (baseTypeDeclarationSyntax is TypeDeclarationSyntax typeDecl)
|
|
{
|
|
SyntaxToken semicolonToken = baseTypeDeclarationSyntax.SemicolonToken;
|
|
if (((SyntaxToken)(ref semicolonToken)).RawKind == 8212)
|
|
{
|
|
openBraceToken = baseTypeDeclarationSyntax.OpenBraceToken;
|
|
if (((SyntaxToken)(ref openBraceToken)).RawKind == 0)
|
|
{
|
|
return factory.GetInTypeBodyBinder(typeDecl);
|
|
}
|
|
}
|
|
}
|
|
BinderFactory binderFactory = factory;
|
|
openBraceToken = baseTypeDeclarationSyntax.OpenBraceToken;
|
|
return binderFactory.GetBinder((SyntaxNode)(object)baseTypeDeclarationSyntax, ((SyntaxToken)(ref openBraceToken)).SpanStart);
|
|
}
|
|
}
|
|
|
|
private static Binder MakeCrefBinderInternal(CrefSyntax crefSyntax, Binder binder, bool inParameterOrReturnType)
|
|
{
|
|
BinderFlags binderFlags = BinderFlags.SuppressConstraintChecks | BinderFlags.Cref | BinderFlags.UnsafeRegion;
|
|
if (inParameterOrReturnType)
|
|
{
|
|
binderFlags |= BinderFlags.CrefParameterOrReturnType;
|
|
}
|
|
binder = binder.WithAdditionalFlags(binderFlags);
|
|
binder = new WithCrefTypeParametersBinder(crefSyntax, binder);
|
|
return binder;
|
|
}
|
|
|
|
internal static MemberDeclarationSyntax GetAssociatedMemberForXmlSyntax(CSharpSyntaxNode xmlSyntax)
|
|
{
|
|
//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_000e: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
|
|
SyntaxTrivia parentTrivia = ((SyntaxNode)GetEnclosingDocumentationComment(xmlSyntax)).ParentTrivia;
|
|
SyntaxToken token = ((SyntaxTrivia)(ref parentTrivia)).Token;
|
|
for (CSharpSyntaxNode cSharpSyntaxNode = (CSharpSyntaxNode)(object)((SyntaxToken)(ref token)).Parent; cSharpSyntaxNode != null; cSharpSyntaxNode = cSharpSyntaxNode.Parent)
|
|
{
|
|
if (cSharpSyntaxNode is MemberDeclarationSyntax result)
|
|
{
|
|
return result;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private static DocumentationCommentTriviaSyntax GetEnclosingDocumentationComment(CSharpSyntaxNode xmlSyntax)
|
|
{
|
|
CSharpSyntaxNode cSharpSyntaxNode = xmlSyntax;
|
|
while (!SyntaxFacts.IsDocumentationCommentTrivia(cSharpSyntaxNode.Kind()))
|
|
{
|
|
cSharpSyntaxNode = cSharpSyntaxNode.Parent;
|
|
}
|
|
return (DocumentationCommentTriviaSyntax)cSharpSyntaxNode;
|
|
}
|
|
|
|
internal BinderFactory(CSharpCompilation compilation, SyntaxTree syntaxTree, bool ignoreAccessibility)
|
|
{
|
|
_compilation = compilation;
|
|
_syntaxTree = syntaxTree;
|
|
_ignoreAccessibility = ignoreAccessibility;
|
|
_binderFactoryVisitorPool = new ObjectPool<BinderFactoryVisitor>((Factory<BinderFactoryVisitor>)(() => new BinderFactoryVisitor(this)), 64, true);
|
|
_binderCache = new ConcurrentCache<BinderCacheKey, Binder>(50);
|
|
_buckStopsHereBinder = new BuckStopsHereBinder(compilation, FileIdentifier.Create(syntaxTree));
|
|
}
|
|
|
|
internal Binder GetBinder(SyntaxNode node, CSharpSyntaxNode memberDeclarationOpt = null, Symbol memberOpt = null)
|
|
{
|
|
int spanStart = node.SpanStart;
|
|
if ((!InScript || node.Kind() != SyntaxKind.CompilationUnit) && node.Parent != null)
|
|
{
|
|
node = node.Parent;
|
|
}
|
|
return GetBinder(node, spanStart, memberDeclarationOpt, memberOpt);
|
|
}
|
|
|
|
internal Binder GetBinder(SyntaxNode node, int position, CSharpSyntaxNode memberDeclarationOpt = null, Symbol memberOpt = null)
|
|
{
|
|
BinderFactoryVisitor binderFactoryVisitor = _binderFactoryVisitorPool.Allocate();
|
|
binderFactoryVisitor.Initialize(position, memberDeclarationOpt, memberOpt);
|
|
Binder result = binderFactoryVisitor.Visit(node);
|
|
_binderFactoryVisitorPool.Free(binderFactoryVisitor);
|
|
return result;
|
|
}
|
|
|
|
internal InMethodBinder GetPrimaryConstructorInMethodBinder(SynthesizedPrimaryConstructor constructor)
|
|
{
|
|
TypeDeclarationSyntax syntax = constructor.GetSyntax();
|
|
NodeUsage usage = NodeUsage.MethodTypeParameters;
|
|
BinderCacheKey binderCacheKey = BinderFactoryVisitor.CreateBinderCacheKey(syntax, usage);
|
|
Binder binder = default(Binder);
|
|
if (!_binderCache.TryGetValue(binderCacheKey, ref binder))
|
|
{
|
|
binder = new InMethodBinder(constructor, GetInTypeBodyBinder(syntax));
|
|
_binderCache.TryAdd(binderCacheKey, binder);
|
|
}
|
|
return (InMethodBinder)binder;
|
|
}
|
|
|
|
internal Binder GetInTypeBodyBinder(TypeDeclarationSyntax typeDecl)
|
|
{
|
|
BinderFactoryVisitor binderFactoryVisitor = _binderFactoryVisitorPool.Allocate();
|
|
binderFactoryVisitor.Initialize(((SyntaxNode)typeDecl).SpanStart, null, null);
|
|
Binder result = binderFactoryVisitor.VisitTypeDeclarationCore(typeDecl, NodeUsage.MethodBody);
|
|
_binderFactoryVisitorPool.Free(binderFactoryVisitor);
|
|
return result;
|
|
}
|
|
|
|
internal Binder GetInNamespaceBinder(CSharpSyntaxNode unit)
|
|
{
|
|
switch (unit.Kind())
|
|
{
|
|
case SyntaxKind.NamespaceDeclaration:
|
|
case SyntaxKind.FileScopedNamespaceDeclaration:
|
|
{
|
|
BinderFactoryVisitor binderFactoryVisitor2 = _binderFactoryVisitorPool.Allocate();
|
|
binderFactoryVisitor2.Initialize(0, null, null);
|
|
Binder result2 = binderFactoryVisitor2.VisitNamespaceDeclaration((BaseNamespaceDeclarationSyntax)unit, ((SyntaxNode)unit).SpanStart, inBody: true, inUsing: false);
|
|
_binderFactoryVisitorPool.Free(binderFactoryVisitor2);
|
|
return result2;
|
|
}
|
|
case SyntaxKind.CompilationUnit:
|
|
{
|
|
BinderFactoryVisitor binderFactoryVisitor = _binderFactoryVisitorPool.Allocate();
|
|
binderFactoryVisitor.Initialize(0, null, null);
|
|
Binder result = binderFactoryVisitor.VisitCompilationUnit((CompilationUnitSyntax)unit, inUsing: false, InScript);
|
|
_binderFactoryVisitorPool.Free(binderFactoryVisitor);
|
|
return result;
|
|
}
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
}
|