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

233 lines
6.5 KiB
C#

using System;
using System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp;
internal sealed class SymbolDistinguisher
{
private sealed class Description : IFormattable
{
private readonly SymbolDistinguisher _distinguisher;
private readonly int _index;
public Description(SymbolDistinguisher distinguisher, int index)
{
_distinguisher = distinguisher;
_index = index;
}
private Symbol GetSymbol()
{
if (_index != 0)
{
return _distinguisher._symbol1;
}
return _distinguisher._symbol0;
}
public override bool Equals(object obj)
{
if (obj is Description description && _distinguisher._compilation == description._distinguisher._compilation)
{
return GetSymbol() == description.GetSymbol();
}
return false;
}
public override int GetHashCode()
{
int num = GetSymbol().GetHashCode();
CSharpCompilation compilation = _distinguisher._compilation;
if (compilation != null)
{
num = Hash.Combine(num, ((object)compilation).GetHashCode());
}
return num;
}
public override string ToString()
{
return _distinguisher.GetDescription(_index);
}
string IFormattable.ToString(string format, IFormatProvider formatProvider)
{
return ToString();
}
}
private readonly CSharpCompilation _compilation;
private readonly Symbol _symbol0;
private readonly Symbol _symbol1;
private ImmutableArray<string> _lazyDescriptions;
public IFormattable First => new Description(this, 0);
public IFormattable Second => new Description(this, 1);
public SymbolDistinguisher(CSharpCompilation compilation, Symbol symbol0, Symbol symbol1)
{
_compilation = compilation;
_symbol0 = symbol0;
_symbol1 = symbol1;
}
[Conditional("DEBUG")]
private static void CheckSymbolKind(Symbol symbol)
{
//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_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Expected I4, but got Unknown
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
SymbolKind kind = symbol.Kind;
switch ((int)kind)
{
case 1:
case 3:
case 4:
case 5:
case 6:
case 9:
case 11:
case 13:
case 14:
case 15:
case 17:
case 20:
return;
}
throw ExceptionUtilities.UnexpectedValue((object)symbol.Kind);
}
private void MakeDescriptions()
{
if (!_lazyDescriptions.IsDefault)
{
return;
}
string text = _symbol0.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageNoParameterNamesFormat);
string text2 = _symbol1.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageNoParameterNamesFormat);
if (text == text2)
{
Symbol symbol = UnwrapSymbol(_symbol0);
Symbol symbol2 = UnwrapSymbol(_symbol1);
string text3 = GetLocationString(_compilation, symbol);
string text4 = GetLocationString(_compilation, symbol2);
if (text3 == text4)
{
AssemblySymbol containingAssembly = symbol.ContainingAssembly;
AssemblySymbol containingAssembly2 = symbol2.ContainingAssembly;
if ((object)containingAssembly != null && (object)containingAssembly2 != null)
{
text3 = ((object)containingAssembly.Identity).ToString();
text4 = ((object)containingAssembly2.Identity).ToString();
}
}
if (text3 != text4)
{
if (text3 != null)
{
text = text + " [" + text3 + "]";
}
if (text4 != null)
{
text2 = text2 + " [" + text4 + "]";
}
}
}
if (_lazyDescriptions.IsDefault)
{
ImmutableInterlocked.InterlockedInitialize(ref _lazyDescriptions, ImmutableArray.Create(text, text2));
}
}
private static Symbol UnwrapSymbol(Symbol symbol)
{
//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_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Invalid comparison between Unknown and I4
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Invalid comparison between Unknown and I4
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Invalid comparison between Unknown and I4
while (true)
{
SymbolKind kind = symbol.Kind;
if ((int)kind != 1)
{
if ((int)kind != 13)
{
if ((int)kind != 14)
{
break;
}
symbol = ((PointerTypeSymbol)symbol).PointedAtType;
}
else
{
symbol = ((ParameterSymbol)symbol).Type;
}
}
else
{
symbol = ((ArrayTypeSymbol)symbol).ElementType;
}
}
return symbol;
}
private static string GetLocationString(CSharpCompilation compilation, Symbol unwrappedSymbol)
{
//IL_0027: 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_002e: 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)
ImmutableArray<SyntaxReference> declaringSyntaxReferences = unwrappedSymbol.DeclaringSyntaxReferences;
if (declaringSyntaxReferences.Length > 0)
{
SyntaxTree syntaxTree = declaringSyntaxReferences[0].SyntaxTree;
TextSpan span = declaringSyntaxReferences[0].Span;
string displayPath = syntaxTree.GetDisplayPath(span, (compilation != null) ? ((CompilationOptions)compilation.Options).SourceReferenceResolver : null);
if (!string.IsNullOrEmpty(displayPath))
{
return $"{displayPath}({syntaxTree.GetDisplayLineNumber(span)})";
}
}
AssemblySymbol containingAssembly = unwrappedSymbol.ContainingAssembly;
if ((object)containingAssembly != null)
{
if (compilation != null)
{
MetadataReference? metadataReference = compilation.GetMetadataReference(containingAssembly);
PortableExecutableReference val = (PortableExecutableReference)(object)((metadataReference is PortableExecutableReference) ? metadataReference : null);
if (val != null)
{
string filePath = val.FilePath;
if (!string.IsNullOrEmpty(filePath))
{
return filePath;
}
}
}
return ((object)containingAssembly.Identity).ToString();
}
return null;
}
private string GetDescription(int index)
{
MakeDescriptions();
return _lazyDescriptions[index];
}
}