305 lines
8.1 KiB
C#
305 lines
8.1 KiB
C#
using System;
|
|
using System.Collections.Immutable;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using Microsoft.CodeAnalysis.CSharp.Symbols;
|
|
using Microsoft.CodeAnalysis.PooledObjects;
|
|
|
|
namespace Microsoft.CodeAnalysis.CSharp;
|
|
|
|
internal sealed class DocumentationCommentIDVisitor : CSharpSymbolVisitor<StringBuilder, object>
|
|
{
|
|
private sealed class PartVisitor : CSharpSymbolVisitor<StringBuilder, object>
|
|
{
|
|
internal static readonly PartVisitor Instance = new PartVisitor(inParameterOrReturnType: false);
|
|
|
|
private static readonly PartVisitor s_parameterOrReturnTypeInstance = new PartVisitor(inParameterOrReturnType: true);
|
|
|
|
private readonly bool _inParameterOrReturnType;
|
|
|
|
private PartVisitor(bool inParameterOrReturnType)
|
|
{
|
|
_inParameterOrReturnType = inParameterOrReturnType;
|
|
}
|
|
|
|
public override object VisitArrayType(ArrayTypeSymbol symbol, StringBuilder builder)
|
|
{
|
|
Visit(symbol.ElementType, builder);
|
|
if (symbol.IsSZArray)
|
|
{
|
|
builder.Append("[]");
|
|
}
|
|
else
|
|
{
|
|
builder.Append("[0:");
|
|
for (int i = 0; i < symbol.Rank - 1; i++)
|
|
{
|
|
builder.Append(",0:");
|
|
}
|
|
builder.Append(']');
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public override object VisitField(FieldSymbol symbol, StringBuilder builder)
|
|
{
|
|
Visit(symbol.ContainingType, builder);
|
|
builder.Append('.');
|
|
builder.Append(symbol.Name);
|
|
return null;
|
|
}
|
|
|
|
private void VisitParameters(ImmutableArray<ParameterSymbol> parameters, bool isVararg, StringBuilder builder)
|
|
{
|
|
builder.Append('(');
|
|
bool flag = false;
|
|
ImmutableArray<ParameterSymbol>.Enumerator enumerator = parameters.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
ParameterSymbol current = enumerator.Current;
|
|
if (flag)
|
|
{
|
|
builder.Append(',');
|
|
}
|
|
Visit(current, builder);
|
|
flag = true;
|
|
}
|
|
if (isVararg && flag)
|
|
{
|
|
builder.Append(',');
|
|
}
|
|
builder.Append(')');
|
|
}
|
|
|
|
public override object VisitMethod(MethodSymbol symbol, StringBuilder builder)
|
|
{
|
|
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0078: Invalid comparison between Unknown and I4
|
|
Visit(symbol.ContainingType, builder);
|
|
builder.Append('.');
|
|
builder.Append(GetEscapedMetadataName(symbol));
|
|
if (symbol.Arity != 0)
|
|
{
|
|
builder.Append("``");
|
|
builder.Append(symbol.Arity);
|
|
}
|
|
if (symbol.Parameters.Any() || symbol.IsVararg)
|
|
{
|
|
s_parameterOrReturnTypeInstance.VisitParameters(symbol.Parameters, symbol.IsVararg, builder);
|
|
}
|
|
if ((int)symbol.MethodKind == 2)
|
|
{
|
|
builder.Append('~');
|
|
s_parameterOrReturnTypeInstance.Visit(symbol.ReturnType, builder);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public override object VisitProperty(PropertySymbol symbol, StringBuilder builder)
|
|
{
|
|
Visit(symbol.ContainingType, builder);
|
|
builder.Append('.');
|
|
builder.Append(GetEscapedMetadataName(symbol));
|
|
if (symbol.Parameters.Any())
|
|
{
|
|
s_parameterOrReturnTypeInstance.VisitParameters(symbol.Parameters, isVararg: false, builder);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public override object VisitEvent(EventSymbol symbol, StringBuilder builder)
|
|
{
|
|
Visit(symbol.ContainingType, builder);
|
|
builder.Append('.');
|
|
builder.Append(GetEscapedMetadataName(symbol));
|
|
return null;
|
|
}
|
|
|
|
public override object VisitTypeParameter(TypeParameterSymbol symbol, StringBuilder builder)
|
|
{
|
|
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0011: Invalid comparison between Unknown and I4
|
|
int num = 0;
|
|
Symbol containingSymbol = symbol.ContainingSymbol;
|
|
if ((int)containingSymbol.Kind == 9)
|
|
{
|
|
builder.Append("``");
|
|
}
|
|
else
|
|
{
|
|
NamedTypeSymbol containingType = containingSymbol.ContainingType;
|
|
while ((object)containingType != null)
|
|
{
|
|
num += containingType.Arity;
|
|
containingType = containingType.ContainingType;
|
|
}
|
|
builder.Append('`');
|
|
}
|
|
builder.Append(symbol.Ordinal + num);
|
|
return null;
|
|
}
|
|
|
|
public override object VisitNamedType(NamedTypeSymbol symbol, StringBuilder builder)
|
|
{
|
|
if ((object)symbol.ContainingSymbol != null && symbol.ContainingSymbol.Name.Length != 0)
|
|
{
|
|
Visit(symbol.ContainingSymbol, builder);
|
|
builder.Append('.');
|
|
}
|
|
builder.Append(symbol.Name);
|
|
if (symbol.Arity != 0)
|
|
{
|
|
if (!_inParameterOrReturnType && TypeSymbol.Equals(symbol, symbol.ConstructedFrom, (TypeCompareKind)63))
|
|
{
|
|
builder.Append('`');
|
|
builder.Append(symbol.Arity);
|
|
}
|
|
else
|
|
{
|
|
builder.Append('{');
|
|
bool flag = false;
|
|
ImmutableArray<TypeWithAnnotations>.Enumerator enumerator = symbol.TypeArgumentsWithAnnotationsNoUseSiteDiagnostics.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
TypeWithAnnotations current = enumerator.Current;
|
|
if (flag)
|
|
{
|
|
builder.Append(',');
|
|
}
|
|
Visit(current.Type, builder);
|
|
flag = true;
|
|
}
|
|
builder.Append('}');
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public override object VisitPointerType(PointerTypeSymbol symbol, StringBuilder builder)
|
|
{
|
|
Visit(symbol.PointedAtType, builder);
|
|
builder.Append('*');
|
|
return null;
|
|
}
|
|
|
|
public override object VisitNamespace(NamespaceSymbol symbol, StringBuilder builder)
|
|
{
|
|
if ((object)symbol.ContainingNamespace != null && symbol.ContainingNamespace.Name.Length != 0)
|
|
{
|
|
Visit(symbol.ContainingNamespace, builder);
|
|
builder.Append('.');
|
|
}
|
|
builder.Append(symbol.Name);
|
|
return null;
|
|
}
|
|
|
|
public override object VisitParameter(ParameterSymbol symbol, StringBuilder builder)
|
|
{
|
|
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
|
|
Visit(symbol.Type, builder);
|
|
if ((int)symbol.RefKind != 0)
|
|
{
|
|
builder.Append('@');
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public override object VisitErrorType(ErrorTypeSymbol symbol, StringBuilder builder)
|
|
{
|
|
return VisitNamedType(symbol, builder);
|
|
}
|
|
|
|
public override object VisitDynamicType(DynamicTypeSymbol symbol, StringBuilder builder)
|
|
{
|
|
builder.Append("System.Object");
|
|
return null;
|
|
}
|
|
|
|
private static string GetEscapedMetadataName(Symbol symbol)
|
|
{
|
|
string metadataName = symbol.MetadataName;
|
|
int num = metadataName.IndexOf("::", StringComparison.Ordinal);
|
|
int num2 = ((num >= 0) ? (num + 2) : 0);
|
|
PooledStringBuilder instance = PooledStringBuilder.GetInstance();
|
|
instance.Builder.Append(metadataName, num2, metadataName.Length - num2);
|
|
instance.Builder.Replace('.', '#').Replace('<', '{').Replace('>', '}');
|
|
return instance.ToStringAndFree();
|
|
}
|
|
}
|
|
|
|
public static readonly DocumentationCommentIDVisitor Instance = new DocumentationCommentIDVisitor();
|
|
|
|
private DocumentationCommentIDVisitor()
|
|
{
|
|
}
|
|
|
|
public override object DefaultVisit(Symbol symbol, StringBuilder builder)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
public override object VisitNamespace(NamespaceSymbol symbol, StringBuilder builder)
|
|
{
|
|
if (!symbol.IsGlobalNamespace)
|
|
{
|
|
builder.Append("N:");
|
|
PartVisitor.Instance.Visit(symbol, builder);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public override object VisitMethod(MethodSymbol symbol, StringBuilder builder)
|
|
{
|
|
builder.Append("M:");
|
|
PartVisitor.Instance.Visit(symbol, builder);
|
|
return null;
|
|
}
|
|
|
|
public override object VisitField(FieldSymbol symbol, StringBuilder builder)
|
|
{
|
|
builder.Append("F:");
|
|
PartVisitor.Instance.Visit(symbol, builder);
|
|
return null;
|
|
}
|
|
|
|
public override object VisitEvent(EventSymbol symbol, StringBuilder builder)
|
|
{
|
|
builder.Append("E:");
|
|
PartVisitor.Instance.Visit(symbol, builder);
|
|
return null;
|
|
}
|
|
|
|
public override object VisitProperty(PropertySymbol symbol, StringBuilder builder)
|
|
{
|
|
builder.Append("P:");
|
|
PartVisitor.Instance.Visit(symbol, builder);
|
|
return null;
|
|
}
|
|
|
|
public override object VisitNamedType(NamedTypeSymbol symbol, StringBuilder builder)
|
|
{
|
|
builder.Append("T:");
|
|
PartVisitor.Instance.Visit(symbol, builder);
|
|
return null;
|
|
}
|
|
|
|
public override object VisitDynamicType(DynamicTypeSymbol symbol, StringBuilder builder)
|
|
{
|
|
return DefaultVisit(symbol, builder);
|
|
}
|
|
|
|
public override object VisitErrorType(ErrorTypeSymbol symbol, StringBuilder builder)
|
|
{
|
|
builder.Append("!:");
|
|
PartVisitor.Instance.Visit(symbol, builder);
|
|
return null;
|
|
}
|
|
|
|
public override object VisitTypeParameter(TypeParameterSymbol symbol, StringBuilder builder)
|
|
{
|
|
builder.Append("!:");
|
|
builder.Append(symbol.Name);
|
|
return null;
|
|
}
|
|
}
|