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

1748 lines
64 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Text;
using System.Threading;
using System.Xml;
using System.Xml.Linq;
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 class DocumentationCommentCompiler : CSharpSymbolVisitor
{
private readonly struct TemporaryStringBuilder(int indentDepth)
{
public readonly PooledStringBuilder Pooled = PooledStringBuilder.GetInstance();
public readonly int InitialIndentDepth = indentDepth;
}
[DebuggerDisplay("{GetDebuggerDisplay(),nq}")]
private class DocumentationCommentWalker : CSharpSyntaxWalker
{
private readonly CSharpCompilation _compilation;
private readonly BindingDiagnosticBag _diagnostics;
private readonly Symbol _memberSymbol;
private readonly StringWriter _writer;
private readonly ArrayBuilder<CSharpSyntaxNode> _includeElementNodes;
private HashSet<ParameterSymbol> _documentedParameters;
private HashSet<TypeParameterSymbol> _documentedTypeParameters;
private DocumentationCommentWalker(CSharpCompilation compilation, BindingDiagnosticBag diagnostics, Symbol memberSymbol, StringWriter writer, ArrayBuilder<CSharpSyntaxNode> includeElementNodes, HashSet<ParameterSymbol> documentedParameters, HashSet<TypeParameterSymbol> documentedTypeParameters)
: base((SyntaxWalkerDepth)3)
{
_compilation = compilation;
_diagnostics = diagnostics;
_memberSymbol = memberSymbol;
_writer = writer;
_includeElementNodes = includeElementNodes;
_documentedParameters = documentedParameters;
_documentedTypeParameters = documentedTypeParameters;
}
public static void GetSubstitutedText(CSharpCompilation compilation, SynthesizedRecordPropertySymbol symbol, ArrayBuilder<XmlElementSyntax> paramElements, ArrayBuilder<CSharpSyntaxNode> includeElementNodes, StringBuilder builder)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: 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_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: 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_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
StringWriter stringWriter = new StringWriter(builder, CultureInfo.InvariantCulture);
DocumentationCommentWalker documentationCommentWalker = new DocumentationCommentWalker(compilation, BindingDiagnosticBag.Discarded, symbol, stringWriter, includeElementNodes, null, null);
Enumerator<XmlElementSyntax> enumerator = paramElements.GetEnumerator();
while (enumerator.MoveNext())
{
XmlElementSyntax current = enumerator.Current;
SyntaxToken lessThanToken = current.StartTag.LessThanToken;
if (!((SyntaxToken)(ref lessThanToken)).LeadingTrivia.Any(SyntaxKind.DocumentationCommentExteriorTrivia))
{
documentationCommentWalker.VisitToken(((SyntaxToken)(ref lessThanToken)).GetPreviousToken(false, false, false, false));
}
documentationCommentWalker.VisitToken(lessThanToken);
stringWriter.Write("summary");
documentationCommentWalker.VisitToken(current.StartTag.GreaterThanToken);
Enumerator<XmlNodeSyntax> enumerator2 = current.Content.GetEnumerator();
while (enumerator2.MoveNext())
{
XmlNodeSyntax current2 = enumerator2.Current;
documentationCommentWalker.Visit((SyntaxNode?)(object)current2);
}
documentationCommentWalker.VisitToken(current.EndTag.LessThanSlashToken);
stringWriter.Write("summary");
SyntaxToken greaterThanToken = current.EndTag.GreaterThanToken;
documentationCommentWalker.VisitToken(greaterThanToken);
SyntaxToken nextToken = ((SyntaxToken)(ref greaterThanToken)).GetNextToken(false, false, false, false);
if (nextToken.IsKind(SyntaxKind.XmlTextLiteralNewLineToken))
{
documentationCommentWalker.VisitToken(nextToken);
}
}
}
public static string GetSubstitutedText(CSharpCompilation compilation, BindingDiagnosticBag diagnostics, Symbol symbol, DocumentationCommentTriviaSyntax trivia, ArrayBuilder<CSharpSyntaxNode> includeElementNodes, ref HashSet<ParameterSymbol> documentedParameters, ref HashSet<TypeParameterSymbol> documentedTypeParameters)
{
PooledStringBuilder instance = PooledStringBuilder.GetInstance();
using (StringWriter writer = new StringWriter(instance.Builder, CultureInfo.InvariantCulture))
{
DocumentationCommentWalker documentationCommentWalker = new DocumentationCommentWalker(compilation, diagnostics, symbol, writer, includeElementNodes, documentedParameters, documentedTypeParameters);
documentationCommentWalker.Visit((SyntaxNode?)(object)trivia);
documentedParameters = documentationCommentWalker._documentedParameters;
documentedTypeParameters = documentationCommentWalker._documentedTypeParameters;
}
return instance.ToStringAndFree();
}
public override void DefaultVisit(SyntaxNode node)
{
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_0182: Unknown result type (might be due to invalid IL or missing references)
//IL_0187: Unknown result type (might be due to invalid IL or missing references)
SyntaxKind syntaxKind = node.Kind();
bool flag = node.SyntaxTree.ReportDocumentationCommentDiagnostics();
SyntaxToken val;
if (syntaxKind == SyntaxKind.XmlCrefAttribute)
{
XmlCrefAttributeSyntax xmlCrefAttributeSyntax = (XmlCrefAttributeSyntax)(object)node;
CrefSyntax cref = xmlCrefAttributeSyntax.Cref;
Binder binder = _compilation.GetBinderFactory(cref.SyntaxTree).GetBinder((SyntaxNode)(object)cref);
BindingDiagnosticBag bindingDiagnosticBag = (flag ? _diagnostics : BindingDiagnosticBag.GetInstance(withDiagnostics: false, ((BindingDiagnosticBag<AssemblySymbol>)(object)_diagnostics).AccumulatesDependencies));
string documentationCommentId = GetDocumentationCommentId(cref, binder, bindingDiagnosticBag);
if (!flag)
{
((BindingDiagnosticBag<AssemblySymbol>)(object)_diagnostics).AddRangeAndFree((BindingDiagnosticBag<AssemblySymbol>)(object)bindingDiagnosticBag);
}
if (_writer != null)
{
Visit((SyntaxNode?)(object)xmlCrefAttributeSyntax.Name);
VisitToken(xmlCrefAttributeSyntax.EqualsToken);
val = xmlCrefAttributeSyntax.StartQuoteToken;
((SyntaxToken)(ref val)).WriteTo((TextWriter)_writer, true, false);
_writer.Write(documentationCommentId);
val = xmlCrefAttributeSyntax.EndQuoteToken;
((SyntaxToken)(ref val)).WriteTo((TextWriter)_writer, false, true);
}
return;
}
if (flag && syntaxKind == SyntaxKind.XmlNameAttribute)
{
XmlNameAttributeSyntax xmlNameAttributeSyntax = (XmlNameAttributeSyntax)(object)node;
Binder binder2 = _compilation.GetBinderFactory(xmlNameAttributeSyntax.SyntaxTree).GetBinder((SyntaxNode)(object)xmlNameAttributeSyntax, ((SyntaxNode)xmlNameAttributeSyntax.Identifier).SpanStart);
BindName(xmlNameAttributeSyntax, binder2, _memberSymbol, ref _documentedParameters, ref _documentedTypeParameters, _diagnostics);
}
if (_includeElementNodes != null)
{
XmlNameSyntax xmlNameSyntax = null;
switch (syntaxKind)
{
case SyntaxKind.XmlEmptyElement:
xmlNameSyntax = ((XmlEmptyElementSyntax)(object)node).Name;
break;
case SyntaxKind.XmlElementStartTag:
xmlNameSyntax = ((XmlElementStartTagSyntax)(object)node).Name;
break;
}
if (xmlNameSyntax != null && xmlNameSyntax.Prefix == null)
{
val = xmlNameSyntax.LocalName;
if (DocumentationCommentXmlNames.ElementEquals(((SyntaxToken)(ref val)).ValueText, "include", false))
{
_includeElementNodes.Add((CSharpSyntaxNode)(object)node);
}
}
}
base.DefaultVisit(node);
}
public override void VisitToken(SyntaxToken token)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
if (_writer != null)
{
((SyntaxToken)(ref token)).WriteTo((TextWriter)_writer);
}
base.VisitToken(token);
}
private string GetDebuggerDisplay()
{
return _writer.GetStringBuilder().ToString();
}
}
private class IncludeElementExpander
{
private readonly Symbol _memberSymbol;
private readonly ImmutableArray<CSharpSyntaxNode> _sourceIncludeElementNodes;
private readonly CSharpCompilation _compilation;
private readonly BindingDiagnosticBag _diagnostics;
private readonly CancellationToken _cancellationToken;
private int _nextSourceIncludeElementIndex;
private HashSet<Location> _inProgressIncludeElementNodes;
private HashSet<ParameterSymbol> _documentedParameters;
private HashSet<TypeParameterSymbol> _documentedTypeParameters;
private DocumentationCommentIncludeCache _includedFileCache;
private IncludeElementExpander(Symbol memberSymbol, ImmutableArray<CSharpSyntaxNode> sourceIncludeElementNodes, CSharpCompilation compilation, HashSet<ParameterSymbol> documentedParameters, HashSet<TypeParameterSymbol> documentedTypeParameters, DocumentationCommentIncludeCache includedFileCache, BindingDiagnosticBag diagnostics, CancellationToken cancellationToken)
{
_memberSymbol = memberSymbol;
_sourceIncludeElementNodes = sourceIncludeElementNodes;
_compilation = compilation;
_diagnostics = diagnostics;
_cancellationToken = cancellationToken;
_documentedParameters = documentedParameters;
_documentedTypeParameters = documentedTypeParameters;
_includedFileCache = includedFileCache;
_nextSourceIncludeElementIndex = 0;
}
public static void ProcessIncludes(string unprocessed, Symbol memberSymbol, ImmutableArray<CSharpSyntaxNode> sourceIncludeElementNodes, CSharpCompilation compilation, ref HashSet<ParameterSymbol> documentedParameters, ref HashSet<TypeParameterSymbol> documentedTypeParameters, ref DocumentationCommentIncludeCache includedFileCache, TextWriter writer, BindingDiagnosticBag diagnostics, CancellationToken cancellationToken)
{
if (sourceIncludeElementNodes.IsEmpty)
{
writer?.Write(unprocessed);
return;
}
XDocument node;
try
{
node = XDocument.Parse(unprocessed, LoadOptions.PreserveWhitespace);
}
catch (XmlException)
{
writer?.Write(unprocessed);
return;
}
cancellationToken.ThrowIfCancellationRequested();
IncludeElementExpander includeElementExpander = new IncludeElementExpander(memberSymbol, sourceIncludeElementNodes, compilation, documentedParameters, documentedTypeParameters, includedFileCache, diagnostics, cancellationToken);
XNode[] array = includeElementExpander.Rewrite(node, null, null);
foreach (XNode value in array)
{
cancellationToken.ThrowIfCancellationRequested();
writer?.Write(value);
}
documentedParameters = includeElementExpander._documentedParameters;
documentedTypeParameters = includeElementExpander._documentedTypeParameters;
includedFileCache = includeElementExpander._includedFileCache;
}
private XNode[] RewriteMany(XNode[] nodes, string currentXmlFilePath, CSharpSyntaxNode originatingSyntax)
{
ArrayBuilder<XNode> val = null;
foreach (XNode node in nodes)
{
if (val == null)
{
val = ArrayBuilder<XNode>.GetInstance();
}
val.AddRange(Rewrite(node, currentXmlFilePath, originatingSyntax));
}
if (val != null)
{
return val.ToArrayAndFree();
}
return Array.Empty<XNode>();
}
private XNode[] Rewrite(XNode node, string currentXmlFilePath, CSharpSyntaxNode originatingSyntax)
{
CancellationToken cancellationToken = _cancellationToken;
cancellationToken.ThrowIfCancellationRequested();
string commentMessage = null;
if (node.NodeType == XmlNodeType.Element)
{
XElement xElement = (XElement)node;
if (ElementNameIs(xElement, "include"))
{
XNode[] array = RewriteIncludeElement(xElement, currentXmlFilePath, originatingSyntax, out commentMessage);
if (array != null)
{
return array;
}
}
}
if (node is XContainer xContainer)
{
IEnumerable<XNode> enumerable = xContainer.Nodes();
XContainer xContainer2 = XmlUtilities.Copy<XContainer>(xContainer, false);
if (enumerable != null)
{
XNode[] array2 = RewriteMany(enumerable.ToArray(), currentXmlFilePath, originatingSyntax);
object[] content = array2;
xContainer2.ReplaceNodes(content);
}
if (xContainer2.NodeType == XmlNodeType.Element && originatingSyntax != null)
{
XElement xElement2 = (XElement)xContainer2;
foreach (XAttribute item in xElement2.Attributes())
{
if (AttributeNameIs(item, "cref"))
{
BindAndReplaceCref(item, originatingSyntax);
}
else if (AttributeNameIs(item, "name"))
{
if (ElementNameIs(xElement2, "param") || ElementNameIs(xElement2, "paramref"))
{
BindName(item, originatingSyntax, isParameter: true, isTypeParameterRef: false);
}
else if (ElementNameIs(xElement2, "typeparam"))
{
BindName(item, originatingSyntax, isParameter: false, isTypeParameterRef: false);
}
else if (ElementNameIs(xElement2, "typeparamref"))
{
BindName(item, originatingSyntax, isParameter: false, isTypeParameterRef: true);
}
}
}
}
if (commentMessage != null)
{
XComment xComment = new XComment(commentMessage);
return new XNode[2] { xComment, xContainer2 };
}
return new XNode[1] { xContainer2 };
}
return new XNode[1] { XmlUtilities.Copy<XNode>(node, false) };
}
private static bool ElementNameIs(XElement element, string name)
{
if (string.IsNullOrEmpty(element.Name.NamespaceName))
{
return DocumentationCommentXmlNames.ElementEquals(element.Name.LocalName, name, false);
}
return false;
}
private static bool AttributeNameIs(XAttribute attribute, string name)
{
if (string.IsNullOrEmpty(attribute.Name.NamespaceName))
{
return DocumentationCommentXmlNames.AttributeEquals(attribute.Name.LocalName, name);
}
return false;
}
private XNode[] RewriteIncludeElement(XElement includeElement, string currentXmlFilePath, CSharpSyntaxNode originatingSyntax, out string commentMessage)
{
//IL_018e: Unknown result type (might be due to invalid IL or missing references)
//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
//IL_0215: Unknown result type (might be due to invalid IL or missing references)
//IL_021f: Expected O, but got Unknown
Location includeElementLocation = GetIncludeElementLocation(includeElement, ref currentXmlFilePath, ref originatingSyntax);
bool flag = originatingSyntax.SyntaxTree.ReportDocumentationCommentDiagnostics();
if (!EnterIncludeElement(includeElementLocation))
{
XAttribute xAttribute = includeElement.Attribute(XName.Get("file"));
XAttribute? xAttribute2 = includeElement.Attribute(XName.Get("path"));
string value = xAttribute.Value;
string value2 = xAttribute2.Value;
if (flag)
{
_diagnostics.Add(ErrorCode.WRN_FailedInclude, includeElementLocation, value, value2, new LocalizableErrorArgument(MessageID.IDS_OperationCausedStackOverflow));
}
commentMessage = ErrorFacts.GetMessage(MessageID.IDS_XMLNOINCLUDE, CultureInfo.CurrentUICulture);
return new XNode[2]
{
new XComment(commentMessage),
XmlUtilities.Copy<XElement>(includeElement, false)
};
}
DiagnosticBag instance = DiagnosticBag.GetInstance();
try
{
XAttribute xAttribute3 = includeElement.Attribute(XName.Get("file"));
XAttribute xAttribute4 = includeElement.Attribute(XName.Get("path"));
bool flag2 = xAttribute3 != null;
bool flag3 = xAttribute4 != null;
if (!flag2 || !flag3)
{
LocalizableErrorArgument localizableErrorArgument = (flag2 ? MessageID.IDS_XMLMISSINGINCLUDEPATH.Localize() : MessageID.IDS_XMLMISSINGINCLUDEFILE.Localize());
instance.Add(ErrorCode.WRN_InvalidInclude, includeElementLocation, localizableErrorArgument);
commentMessage = MakeCommentMessage(includeElementLocation, MessageID.IDS_XMLBADINCLUDE);
return null;
}
string value3 = xAttribute4.Value;
string value4 = xAttribute3.Value;
XmlReferenceResolver xmlReferenceResolver = ((CompilationOptions)_compilation.Options).XmlReferenceResolver;
if (xmlReferenceResolver == null)
{
instance.Add(ErrorCode.WRN_FailedInclude, includeElementLocation, value4, value3, (object)new CodeAnalysisResourcesLocalizableErrorArgument("XmlReferencesNotSupported"));
commentMessage = MakeCommentMessage(includeElementLocation, MessageID.IDS_XMLFAILEDINCLUDE);
return null;
}
string text = xmlReferenceResolver.ResolveReference(value4, currentXmlFilePath);
if (text == null)
{
instance.Add(ErrorCode.WRN_FailedInclude, includeElementLocation, value4, value3, (object)new CodeAnalysisResourcesLocalizableErrorArgument("FileNotFound"));
commentMessage = MakeCommentMessage(includeElementLocation, MessageID.IDS_XMLFAILEDINCLUDE);
return null;
}
if (_includedFileCache == null)
{
_includedFileCache = new DocumentationCommentIncludeCache(xmlReferenceResolver);
}
try
{
XDocument orMakeDocument;
try
{
orMakeDocument = _includedFileCache.GetOrMakeDocument(text);
}
catch (IOException ex)
{
instance.Add(ErrorCode.WRN_FailedInclude, includeElementLocation, value4, value3, ex.Message);
commentMessage = MakeCommentMessage(includeElementLocation, MessageID.IDS_XMLFAILEDINCLUDE);
return null;
}
string text2 = default(string);
bool flag4 = default(bool);
XElement[] array = XmlUtilities.TrySelectElements((XNode)orMakeDocument, value3, ref text2, ref flag4);
if (array == null)
{
instance.Add(ErrorCode.WRN_FailedInclude, includeElementLocation, value4, value3, text2);
commentMessage = MakeCommentMessage(includeElementLocation, MessageID.IDS_XMLFAILEDINCLUDE);
if (flag4)
{
return null;
}
if (includeElementLocation.IsInSource)
{
return new XNode[1]
{
new XComment(commentMessage)
};
}
commentMessage = null;
return Array.Empty<XNode>();
}
if (array != null && array.Length != 0)
{
XNode[] nodes = array;
XNode[] array2 = RewriteMany(nodes, text, originatingSyntax);
if (array2.Length != 0)
{
commentMessage = null;
return array2;
}
}
commentMessage = MakeCommentMessage(includeElementLocation, MessageID.IDS_XMLNOINCLUDE);
return null;
}
catch (XmlException ex2)
{
Location location = (Location)(object)XmlLocation.Create(ex2, text);
instance.Add(ErrorCode.WRN_XMLParseIncludeError, location, GetDescription(ex2));
if (includeElementLocation.IsInSource)
{
commentMessage = string.Format(ErrorFacts.GetMessage(MessageID.IDS_XMLIGNORED2, CultureInfo.CurrentUICulture), text);
return new XNode[1]
{
new XComment(commentMessage)
};
}
commentMessage = null;
return Array.Empty<XNode>();
}
}
finally
{
if (flag)
{
((BindingDiagnosticBag<AssemblySymbol>)(object)_diagnostics).AddRange(instance);
}
instance.Free();
LeaveIncludeElement(includeElementLocation);
}
}
private static string MakeCommentMessage(Location location, MessageID messageId)
{
if (location.IsInSource)
{
return ErrorFacts.GetMessage(messageId, CultureInfo.CurrentUICulture);
}
return null;
}
private bool EnterIncludeElement(Location location)
{
if (_inProgressIncludeElementNodes == null)
{
_inProgressIncludeElementNodes = new HashSet<Location>();
}
return _inProgressIncludeElementNodes.Add(location);
}
private bool LeaveIncludeElement(Location location)
{
return _inProgressIncludeElementNodes.Remove(location);
}
private Location GetIncludeElementLocation(XElement includeElement, ref string currentXmlFilePath, ref CSharpSyntaxNode originatingSyntax)
{
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
Location val = includeElement.Annotation<Location>();
if (val != (Location)null)
{
return val;
}
if (currentXmlFilePath == null)
{
originatingSyntax = _sourceIncludeElementNodes[_nextSourceIncludeElementIndex];
val = ((SyntaxNode)originatingSyntax).Location;
_nextSourceIncludeElementIndex++;
FileLinePositionSpan lineSpan = val.GetLineSpan();
currentXmlFilePath = ((FileLinePositionSpan)(ref lineSpan)).Path;
}
else
{
val = (Location)(object)XmlLocation.Create((XObject)includeElement, currentXmlFilePath);
}
includeElement.AddAnnotation(val);
return val;
}
private void BindAndReplaceCref(XAttribute attribute, CSharpSyntaxNode originatingSyntax)
{
CrefSyntax crefSyntax = SyntaxFactory.ParseCref(attribute.Value);
if (crefSyntax != null)
{
Location location = ((SyntaxNode)originatingSyntax).Location;
RecordSyntaxDiagnostics(crefSyntax, location);
MemberDeclarationSyntax associatedMemberForXmlSyntax = BinderFactory.GetAssociatedMemberForXmlSyntax(originatingSyntax);
Binder binder = BinderFactory.MakeCrefBinder(crefSyntax, associatedMemberForXmlSyntax, _compilation.GetBinderFactory(associatedMemberForXmlSyntax.SyntaxTree));
BindingDiagnosticBag instance = BindingDiagnosticBag.GetInstance(_diagnostics);
attribute.Value = GetDocumentationCommentId(crefSyntax, binder, instance);
RecordBindingDiagnostics(instance, location);
((BindingDiagnosticBag<AssemblySymbol>)(object)instance).Free();
}
}
private void BindName(XAttribute attribute, CSharpSyntaxNode originatingSyntax, bool isParameter, bool isTypeParameterRef)
{
XmlNameAttributeSyntax xmlNameAttributeSyntax = ParseNameAttribute(attribute.ToString(), attribute.Parent.Name.LocalName);
Location location = ((SyntaxNode)originatingSyntax).Location;
RecordSyntaxDiagnostics(xmlNameAttributeSyntax, location);
BinderFactory.GetAssociatedMemberForXmlSyntax(originatingSyntax);
BindingDiagnosticBag instance = BindingDiagnosticBag.GetInstance(_diagnostics);
Binder binder = MakeNameBinder(isParameter, isTypeParameterRef, _memberSymbol, _compilation, originatingSyntax.SyntaxTree);
DocumentationCommentCompiler.BindName(xmlNameAttributeSyntax, binder, _memberSymbol, ref _documentedParameters, ref _documentedTypeParameters, instance);
RecordBindingDiagnostics(instance, location);
((BindingDiagnosticBag<AssemblySymbol>)(object)instance).Free();
}
private static Binder MakeNameBinder(bool isParameter, bool isTypeParameterRef, Symbol memberSymbol, CSharpCompilation compilation, SyntaxTree syntaxTree)
{
//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_0032: Invalid comparison between Unknown and I4
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Invalid comparison between Unknown and I4
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Invalid comparison between Unknown and I4
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Invalid comparison between Unknown and I4
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: Invalid comparison between Unknown and I4
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Invalid comparison between Unknown and I4
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Invalid comparison between Unknown and I4
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Invalid comparison between Unknown and I4
Binder binder = new BuckStopsHereBinder(compilation, FileIdentifier.Create(syntaxTree));
Symbol containingSymbol = memberSymbol.ContainingSymbol;
binder = binder.WithContainingMemberOrLambda(containingSymbol);
ImmutableArray<ParameterSymbol> parameters;
if (isParameter)
{
parameters = ImmutableArray<ParameterSymbol>.Empty;
SymbolKind kind = memberSymbol.Kind;
if ((int)kind <= 9)
{
if ((int)kind == 4)
{
goto IL_006b;
}
if ((int)kind == 9)
{
parameters = ((MethodSymbol)memberSymbol).Parameters;
}
}
else
{
if ((int)kind == 11)
{
goto IL_006b;
}
if ((int)kind == 15)
{
parameters = ((PropertySymbol)memberSymbol).Parameters;
}
}
goto IL_0086;
}
Symbol symbol = memberSymbol;
do
{
SymbolKind kind = symbol.Kind;
if ((int)kind == 4)
{
goto IL_00b7;
}
if ((int)kind != 9)
{
if ((int)kind == 11)
{
goto IL_00b7;
}
}
else
{
MethodSymbol methodSymbol = (MethodSymbol)symbol;
if (methodSymbol.Arity > 0)
{
binder = new WithMethodTypeParametersBinder(methodSymbol, binder);
}
}
goto IL_00f1;
IL_00b7:
NamedTypeSymbol namedTypeSymbol = (NamedTypeSymbol)symbol;
if (namedTypeSymbol.Arity > 0)
{
binder = new WithClassTypeParametersBinder(namedTypeSymbol, binder);
}
goto IL_00f1;
IL_00f1:
symbol = symbol.ContainingSymbol;
}
while (isTypeParameterRef && (object)symbol != null);
goto IL_0101;
IL_006b:
NamedTypeSymbol namedTypeSymbol2 = (NamedTypeSymbol)memberSymbol;
if (namedTypeSymbol2.IsDelegateType())
{
parameters = namedTypeSymbol2.DelegateInvokeMethod.Parameters;
}
goto IL_0086;
IL_0086:
if (parameters.Length > 0)
{
binder = new WithParametersBinder(parameters, binder);
}
goto IL_0101;
IL_0101:
return binder;
}
private static XmlNameAttributeSyntax ParseNameAttribute(string attributeText, string elementName)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: 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)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
SyntaxTriviaList val = SyntaxFactory.ParseLeadingTrivia($"/// <{elementName} {attributeText}/>", CSharpParseOptions.Default.WithDocumentationMode((DocumentationMode)2));
SyntaxTrivia val2 = ((SyntaxTriviaList)(ref val)).ElementAt(0);
return (XmlNameAttributeSyntax)((XmlEmptyElementSyntax)((DocumentationCommentTriviaSyntax)(object)((SyntaxTrivia)(ref val2)).GetStructure()).Content[1]).Attributes[0];
}
private void RecordSyntaxDiagnostics(CSharpSyntaxNode treelessSyntax, Location sourceLocation)
{
if (!((SyntaxNode)treelessSyntax).ContainsDiagnostics || !sourceLocation.SourceTree.ReportDocumentationCommentDiagnostics())
{
return;
}
foreach (Diagnostic diagnostic in CSharpSyntaxTree.Dummy.GetDiagnostics((SyntaxNode)(object)treelessSyntax))
{
((BindingDiagnosticBag)_diagnostics).Add(diagnostic.WithLocation(sourceLocation));
}
}
private void RecordBindingDiagnostics(BindingDiagnosticBag bindingDiagnostics, Location sourceLocation)
{
if (sourceLocation.SourceTree.ReportDocumentationCommentDiagnostics())
{
DiagnosticBag diagnosticBag = ((BindingDiagnosticBag)bindingDiagnostics).DiagnosticBag;
if (diagnosticBag != null && !diagnosticBag.IsEmptyWithoutResolution)
{
foreach (Diagnostic item in ((BindingDiagnosticBag)bindingDiagnostics).DiagnosticBag.AsEnumerable())
{
((BindingDiagnosticBag)_diagnostics).Add(item.WithLocation(sourceLocation));
}
}
}
((BindingDiagnosticBag<AssemblySymbol>)(object)_diagnostics).AddDependencies((BindingDiagnosticBag<AssemblySymbol>)(object)bindingDiagnostics, false);
}
}
private readonly string _assemblyName;
private readonly CSharpCompilation _compilation;
private readonly TextWriter _writer;
private readonly SyntaxTree _filterTree;
private readonly TextSpan? _filterSpanWithinTree;
private readonly bool _processIncludes;
private readonly bool _isForSingleSymbol;
private readonly BindingDiagnosticBag _diagnostics;
private readonly CancellationToken _cancellationToken;
private SyntaxNodeLocationComparer _lazyComparer;
private DocumentationCommentIncludeCache _includedFileCache;
private int _indentDepth;
private Stack<TemporaryStringBuilder> _temporaryStringBuilders;
private static readonly string[] s_newLineSequences = new string[3] { "\r\n", "\r", "\n" };
private IComparer<CSharpSyntaxNode> Comparer
{
get
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Expected O, but got Unknown
if (_lazyComparer == null)
{
_lazyComparer = new SyntaxNodeLocationComparer((Compilation)(object)_compilation);
}
return (IComparer<CSharpSyntaxNode>)_lazyComparer;
}
}
private DocumentationCommentCompiler(string assemblyName, CSharpCompilation compilation, TextWriter writer, SyntaxTree filterTree, TextSpan? filterSpanWithinTree, bool processIncludes, bool isForSingleSymbol, BindingDiagnosticBag diagnostics, CancellationToken cancellationToken)
{
_assemblyName = assemblyName;
_compilation = compilation;
_writer = writer;
_filterTree = filterTree;
_filterSpanWithinTree = filterSpanWithinTree;
_processIncludes = processIncludes;
_isForSingleSymbol = isForSingleSymbol;
_diagnostics = diagnostics;
_cancellationToken = cancellationToken;
}
public static void WriteDocumentationCommentXml(CSharpCompilation compilation, string? assemblyName, Stream? xmlDocStream, BindingDiagnosticBag diagnostics, CancellationToken cancellationToken, SyntaxTree? filterTree = null, TextSpan? filterSpanWithinTree = null)
{
StreamWriter streamWriter = null;
if (xmlDocStream != null && xmlDocStream.CanWrite)
{
streamWriter = new StreamWriter(xmlDocStream, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: false), 1024, leaveOpen: true);
}
try
{
using (streamWriter)
{
new DocumentationCommentCompiler(assemblyName ?? compilation.SourceAssembly.Name, compilation, streamWriter, filterTree, filterSpanWithinTree, processIncludes: true, isForSingleSymbol: false, diagnostics, cancellationToken).Visit(compilation.SourceAssembly.GlobalNamespace);
streamWriter?.Flush();
}
}
catch (Exception ex)
{
diagnostics.Add(ErrorCode.ERR_DocFileGen, Location.None, ex.Message);
}
DiagnosticBag diagnosticBag = ((BindingDiagnosticBag)diagnostics).DiagnosticBag;
if (diagnosticBag == null)
{
return;
}
if (filterTree != null)
{
UnprocessedDocumentationCommentFinder.ReportUnprocessed(filterTree, filterSpanWithinTree, diagnosticBag, cancellationToken);
return;
}
ImmutableArray<SyntaxTree>.Enumerator enumerator = compilation.SyntaxTrees.GetEnumerator();
while (enumerator.MoveNext())
{
UnprocessedDocumentationCommentFinder.ReportUnprocessed(enumerator.Current, null, diagnosticBag, cancellationToken);
}
}
internal static string GetDocumentationCommentXml(Symbol symbol, bool processIncludes, CancellationToken cancellationToken)
{
CSharpCompilation declaringCompilation = symbol.DeclaringCompilation;
PooledStringBuilder instance = PooledStringBuilder.GetInstance();
StringWriter stringWriter = new StringWriter(instance.Builder);
new DocumentationCommentCompiler(null, declaringCompilation, stringWriter, null, null, processIncludes, isForSingleSymbol: true, BindingDiagnosticBag.Discarded, cancellationToken).Visit(symbol);
stringWriter.Dispose();
return instance.ToStringAndFree();
}
public override void VisitNamespace(NamespaceSymbol symbol)
{
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
CancellationToken cancellationToken = _cancellationToken;
cancellationToken.ThrowIfCancellationRequested();
if (symbol.IsGlobalNamespace)
{
WriteLine("<?xml version=\"1.0\"?>");
WriteLine("<doc>");
Indent();
if (!EnumBounds.IsNetModule(((CompilationOptions)_compilation.Options).OutputKind))
{
WriteLine("<assembly>");
Indent();
WriteLine("<name>{0}</name>", _assemblyName);
Unindent();
WriteLine("</assembly>");
}
WriteLine("<members>");
Indent();
}
ImmutableArray<Symbol>.Enumerator enumerator = symbol.GetMembers().GetEnumerator();
while (enumerator.MoveNext())
{
Symbol current = enumerator.Current;
cancellationToken = _cancellationToken;
cancellationToken.ThrowIfCancellationRequested();
current.Accept(this);
}
if (symbol.IsGlobalNamespace)
{
Unindent();
WriteLine("</members>");
Unindent();
WriteLine("</doc>");
}
}
public override void VisitNamedType(NamedTypeSymbol symbol)
{
CancellationToken cancellationToken = _cancellationToken;
cancellationToken.ThrowIfCancellationRequested();
if (_filterTree != null && !symbol.IsDefinedInSourceTree(_filterTree, _filterSpanWithinTree))
{
return;
}
DefaultVisit(symbol);
if (!_isForSingleSymbol)
{
ImmutableArray<Symbol>.Enumerator enumerator = symbol.GetMembers().GetEnumerator();
while (enumerator.MoveNext())
{
Symbol current = enumerator.Current;
cancellationToken = _cancellationToken;
cancellationToken.ThrowIfCancellationRequested();
current.Accept(this);
}
}
}
public override void DefaultVisit(Symbol symbol)
{
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0113: Unknown result type (might be due to invalid IL or missing references)
//IL_0115: Invalid comparison between Unknown and I4
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
CancellationToken cancellationToken = _cancellationToken;
cancellationToken.ThrowIfCancellationRequested();
if (ShouldSkip(symbol) || (_filterTree != null && !symbol.IsDefinedInSourceTree(_filterTree, _filterSpanWithinTree)))
{
return;
}
bool flag = false;
if (symbol.IsPartialDefinition())
{
if (symbol is MethodSymbol { PartialImplementationPart: { } partialImplementationPart })
{
Visit(partialImplementationPart);
SyntaxTriviaList leadingTrivia = partialImplementationPart.GetNonNullSyntaxNode().GetLeadingTrivia();
Enumerator enumerator = ((SyntaxTriviaList)(ref leadingTrivia)).GetEnumerator();
while (((Enumerator)(ref enumerator)).MoveNext())
{
SyntaxKind syntaxKind = ((Enumerator)(ref enumerator)).Current.Kind();
if (syntaxKind - 8544 <= SyntaxKind.List)
{
flag = true;
break;
}
}
}
else
{
flag = !_isForSingleSymbol;
}
}
Symbol symbol2 = ((symbol is SynthesizedRecordPropertySymbol) ? symbol.ContainingType : symbol);
if (!TryGetDocumentationCommentNodes(symbol2, out var maxDocumentationMode, out var nodes))
{
string message = ErrorFacts.GetMessage(MessageID.IDS_XMLIGNORED, CultureInfo.CurrentUICulture);
WriteLine(string.Format(CultureInfo.CurrentUICulture, message, symbol.GetDocumentationCommentId()));
return;
}
if (nodes.IsEmpty)
{
if ((int)maxDocumentationMode >= 2 && RequiresDocumentationComment(symbol) && !symbol.IsPartialImplementation() && !flag)
{
Location locationInTreeReportingDocumentationCommentDiagnostics = GetLocationInTreeReportingDocumentationCommentDiagnostics(symbol);
if (locationInTreeReportingDocumentationCommentDiagnostics != (Location)null)
{
_diagnostics.Add(ErrorCode.WRN_MissingXMLComment, locationInTreeReportingDocumentationCommentDiagnostics, symbol);
}
}
return;
}
cancellationToken = _cancellationToken;
cancellationToken.ThrowIfCancellationRequested();
if (!TryProcessDocumentationCommentTriviaNodes(symbol, flag, nodes, out var withUnprocessedIncludes, out var haveParseError, out var documentedTypeParameters, out var documentedParameters, out var includeElementNodes))
{
return;
}
if (haveParseError)
{
string message2 = ErrorFacts.GetMessage(MessageID.IDS_XMLIGNORED, CultureInfo.CurrentUICulture);
WriteLine(string.Format(CultureInfo.CurrentUICulture, message2, symbol.GetDocumentationCommentId()));
return;
}
if (!includeElementNodes.IsDefaultOrEmpty)
{
cancellationToken = _cancellationToken;
cancellationToken.ThrowIfCancellationRequested();
TextWriter writer = (flag ? null : _writer);
IncludeElementExpander.ProcessIncludes(withUnprocessedIncludes, symbol, includeElementNodes, _compilation, ref documentedParameters, ref documentedTypeParameters, ref _includedFileCache, writer, _diagnostics, _cancellationToken);
}
else if (_writer != null && !flag)
{
Write(withUnprocessedIncludes);
}
if (!(GetLocationInTreeReportingDocumentationCommentDiagnostics(symbol) != (Location)null))
{
return;
}
cancellationToken = _cancellationToken;
cancellationToken.ThrowIfCancellationRequested();
if (documentedParameters != null)
{
ImmutableArray<ParameterSymbol>.Enumerator enumerator2 = GetParameters(symbol).GetEnumerator();
while (enumerator2.MoveNext())
{
ParameterSymbol current = enumerator2.Current;
if (!documentedParameters.Contains(current))
{
Location firstLocation = current.GetFirstLocation();
_diagnostics.Add(ErrorCode.WRN_MissingParamTag, firstLocation, current.Name, symbol);
}
}
}
if (documentedTypeParameters == null)
{
return;
}
ImmutableArray<TypeParameterSymbol>.Enumerator enumerator3 = GetTypeParameters(symbol).GetEnumerator();
while (enumerator3.MoveNext())
{
TypeParameterSymbol current2 = enumerator3.Current;
if (!documentedTypeParameters.Contains(current2))
{
Location firstLocation2 = current2.GetFirstLocation();
_diagnostics.Add(ErrorCode.WRN_MissingTypeParamTag, firstLocation2, current2, symbol);
}
}
}
private static bool ShouldSkip(Symbol symbol)
{
if (!symbol.IsImplicitlyDeclared && !symbol.IsAccessor())
{
return symbol is SynthesizedSimpleProgramEntryPointSymbol;
}
return true;
}
private bool TryProcessRecordPropertyDocumentation(SynthesizedRecordPropertySymbol recordPropertySymbol, ImmutableArray<DocumentationCommentTriviaSyntax> docCommentNodes, [NotNullWhen(true)] out string? withUnprocessedIncludes, out ImmutableArray<CSharpSyntaxNode> includeElementNodes)
{
CancellationToken cancellationToken = _cancellationToken;
cancellationToken.ThrowIfCancellationRequested();
ArrayBuilder<XmlElementSyntax> val = getMatchingParamTags(recordPropertySymbol.Name, docCommentNodes);
if (val == null)
{
withUnprocessedIncludes = null;
includeElementNodes = default(ImmutableArray<CSharpSyntaxNode>);
return false;
}
BeginTemporaryString();
WriteLine("<member name=\"{0}\">", recordPropertySymbol.GetDocumentationCommentId());
Indent();
PooledStringBuilder instance = PooledStringBuilder.GetInstance();
ArrayBuilder<CSharpSyntaxNode> val2 = (_processIncludes ? ArrayBuilder<CSharpSyntaxNode>.GetInstance() : null);
DocumentationCommentWalker.GetSubstitutedText(_compilation, recordPropertySymbol, val, val2, instance.Builder);
string substitutedText = instance.ToStringAndFree();
string indentedAndWrappedString = FormatComment(substitutedText);
Write(indentedAndWrappedString);
Unindent();
WriteLine("</member>");
withUnprocessedIncludes = GetAndEndTemporaryString();
includeElementNodes = val2?.ToImmutableAndFree() ?? default(ImmutableArray<CSharpSyntaxNode>);
val.Free();
return true;
static ArrayBuilder<XmlElementSyntax>? getMatchingParamTags(string propertyName, ImmutableArray<DocumentationCommentTriviaSyntax> immutableArray)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: 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)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: 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_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
ArrayBuilder<XmlElementSyntax> val3 = null;
ImmutableArray<DocumentationCommentTriviaSyntax>.Enumerator enumerator = immutableArray.GetEnumerator();
while (enumerator.MoveNext())
{
Enumerator<XmlNodeSyntax> enumerator2 = enumerator.Current.Content.GetEnumerator();
while (enumerator2.MoveNext())
{
if (enumerator2.Current is XmlElementSyntax xmlElementSyntax)
{
Enumerator<XmlAttributeSyntax> enumerator3 = xmlElementSyntax.StartTag.Attributes.GetEnumerator();
while (enumerator3.MoveNext())
{
if (enumerator3.Current is XmlNameAttributeSyntax xmlNameAttributeSyntax && xmlNameAttributeSyntax.GetElementKind() == XmlNameAttributeElementKind.Parameter)
{
SyntaxToken identifier = xmlNameAttributeSyntax.Identifier.Identifier;
if (string.Equals(((SyntaxToken)(ref identifier)).ValueText, propertyName, StringComparison.Ordinal))
{
if (val3 == null)
{
val3 = ArrayBuilder<XmlElementSyntax>.GetInstance();
}
val3.Add(xmlElementSyntax);
break;
}
}
}
}
}
}
return val3;
}
}
private bool TryProcessDocumentationCommentTriviaNodes(Symbol symbol, bool shouldSkipPartialDefinitionComments, ImmutableArray<DocumentationCommentTriviaSyntax> docCommentNodes, out string withUnprocessedIncludes, out bool haveParseError, out HashSet<TypeParameterSymbol> documentedTypeParameters, out HashSet<ParameterSymbol> documentedParameters, out ImmutableArray<CSharpSyntaxNode> includeElementNodes)
{
//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
//IL_00f3: Expected O, but got Unknown
bool flag = false;
ArrayBuilder<CSharpSyntaxNode> val = null;
documentedParameters = null;
documentedTypeParameters = null;
haveParseError = false;
if (symbol is SynthesizedRecordPropertySymbol recordPropertySymbol)
{
return TryProcessRecordPropertyDocumentation(recordPropertySymbol, docCommentNodes, out withUnprocessedIncludes, out includeElementNodes);
}
ImmutableArray<DocumentationCommentTriviaSyntax>.Enumerator enumerator = docCommentNodes.GetEnumerator();
while (enumerator.MoveNext())
{
DocumentationCommentTriviaSyntax current = enumerator.Current;
CancellationToken cancellationToken = _cancellationToken;
cancellationToken.ThrowIfCancellationRequested();
bool flag2 = current.SyntaxTree.ReportDocumentationCommentDiagnostics();
if (!flag)
{
BeginTemporaryString();
if (_processIncludes)
{
val = ArrayBuilder<CSharpSyntaxNode>.GetInstance();
}
if (!shouldSkipPartialDefinitionComments || _processIncludes)
{
WriteLine("<member name=\"{0}\">", symbol.GetDocumentationCommentId());
Indent();
}
flag = true;
}
string substitutedText = DocumentationCommentWalker.GetSubstitutedText(_compilation, _diagnostics, symbol, current, val, ref documentedParameters, ref documentedTypeParameters);
string text = FormatComment(substitutedText);
XmlException ex = XmlDocumentationCommentTextReader.ParseAndGetException(text);
if (ex != null)
{
haveParseError = true;
if (flag2)
{
Location location = (Location)new SourceLocation(current.SyntaxTree, new TextSpan(((SyntaxNode)current).SpanStart, 0));
_diagnostics.Add(ErrorCode.WRN_XMLParseError, location, GetDescription(ex));
}
}
if (!shouldSkipPartialDefinitionComments || _processIncludes)
{
Write(text);
}
}
if (!flag)
{
withUnprocessedIncludes = null;
includeElementNodes = default(ImmutableArray<CSharpSyntaxNode>);
return false;
}
if (!shouldSkipPartialDefinitionComments || _processIncludes)
{
Unindent();
WriteLine("</member>");
}
withUnprocessedIncludes = GetAndEndTemporaryString();
includeElementNodes = (_processIncludes ? val.ToImmutableAndFree() : default(ImmutableArray<CSharpSyntaxNode>));
return true;
}
private static Location GetLocationInTreeReportingDocumentationCommentDiagnostics(Symbol symbol)
{
ImmutableArray<Location>.Enumerator enumerator = symbol.Locations.GetEnumerator();
while (enumerator.MoveNext())
{
Location current = enumerator.Current;
if (current.SourceTree.ReportDocumentationCommentDiagnostics())
{
return current;
}
}
return null;
}
private static ImmutableArray<ParameterSymbol> GetParameters(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_000a: Invalid comparison between Unknown and I4
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Invalid comparison between Unknown and I4
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Invalid comparison between Unknown and I4
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: 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
SymbolKind kind = symbol.Kind;
if ((int)kind <= 9)
{
if ((int)kind == 5 || (int)kind == 9)
{
goto IL_0039;
}
}
else if ((int)kind != 11)
{
if ((int)kind == 15)
{
goto IL_0039;
}
}
else
{
MethodSymbol delegateInvokeMethod = ((NamedTypeSymbol)symbol).DelegateInvokeMethod;
if ((object)delegateInvokeMethod != null)
{
return delegateInvokeMethod.Parameters;
}
}
return ImmutableArray<ParameterSymbol>.Empty;
IL_0039:
return symbol.GetParameters();
}
private static ImmutableArray<TypeParameterSymbol> GetTypeParameters(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
SymbolKind kind = symbol.Kind;
if ((int)kind == 4 || (int)kind == 9 || (int)kind == 11)
{
return symbol.GetMemberTypeParameters();
}
return ImmutableArray<TypeParameterSymbol>.Empty;
}
private static bool RequiresDocumentationComment(Symbol symbol)
{
//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_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Invalid comparison between Unknown and I4
//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_0019: Invalid comparison between Unknown and I4
if (ShouldSkip(symbol))
{
return false;
}
while ((object)symbol != null)
{
Accessibility declaredAccessibility = symbol.DeclaredAccessibility;
if ((int)declaredAccessibility == 3 || declaredAccessibility - 5 <= 1)
{
symbol = symbol.ContainingType;
continue;
}
return false;
}
return true;
}
private bool TryGetDocumentationCommentNodes(Symbol symbol, out DocumentationMode maxDocumentationMode, out ImmutableArray<DocumentationCommentTriviaSyntax> nodes)
{
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Invalid comparison between Unknown and I4
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
maxDocumentationMode = (DocumentationMode)0;
nodes = default(ImmutableArray<DocumentationCommentTriviaSyntax>);
ArrayBuilder<DocumentationCommentTriviaSyntax> val = null;
DiagnosticBag val2 = ((BindingDiagnosticBag)_diagnostics).DiagnosticBag ?? DiagnosticBag.GetInstance();
ImmutableArray<SyntaxReference>.Enumerator enumerator = symbol.DeclaringSyntaxReferences.GetEnumerator();
while (enumerator.MoveNext())
{
SyntaxReference current = enumerator.Current;
DocumentationMode documentationMode = current.SyntaxTree.Options.DocumentationMode;
maxDocumentationMode = (DocumentationMode)(((int)documentationMode <= (int)maxDocumentationMode) ? ((int)maxDocumentationMode) : ((int)documentationMode));
ImmutableArray<DocumentationCommentTriviaSyntax>.Enumerator enumerator2 = SourceDocumentationCommentUtils.GetDocumentationCommentTriviaFromSyntaxNode((CSharpSyntaxNode)(object)current.GetSyntax(default(CancellationToken)), val2).GetEnumerator();
while (enumerator2.MoveNext())
{
DocumentationCommentTriviaSyntax current2 = enumerator2.Current;
if (ContainsXmlParseDiagnostic(current2))
{
val?.Free();
return false;
}
if (val == null)
{
val = ArrayBuilder<DocumentationCommentTriviaSyntax>.GetInstance();
}
val.Add(current2);
}
}
if (val2 != ((BindingDiagnosticBag)_diagnostics).DiagnosticBag)
{
val2.Free();
}
if (val == null)
{
nodes = ImmutableArray<DocumentationCommentTriviaSyntax>.Empty;
}
else
{
val.Sort((IComparer<DocumentationCommentTriviaSyntax>)Comparer);
nodes = val.ToImmutableAndFree();
}
return true;
}
private static bool ContainsXmlParseDiagnostic(DocumentationCommentTriviaSyntax node)
{
if (!((SyntaxNode)node).ContainsDiagnostics)
{
return false;
}
foreach (Diagnostic diagnostic in node.GetDiagnostics())
{
if (diagnostic.Code == 1570)
{
return true;
}
}
return false;
}
private string FormatComment(string substitutedText)
{
BeginTemporaryString();
if (TrimmedStringStartsWith(substitutedText, "///"))
{
WriteFormattedSingleLineComment(substitutedText);
}
else
{
string[] array = substitutedText.Split(s_newLineSequences, StringSplitOptions.None);
int num = array.Length;
if (string.IsNullOrEmpty(array[num - 1]))
{
num--;
}
WriteFormattedMultiLineComment(array, num);
}
return GetAndEndTemporaryString();
}
private static int GetIndexOfFirstNonWhitespaceChar(string str)
{
return GetIndexOfFirstNonWhitespaceChar(str, 0, str.Length);
}
private static int GetIndexOfFirstNonWhitespaceChar(string str, int start, int end)
{
while (start < end && SyntaxFacts.IsWhitespace(str[start]))
{
start++;
}
return start;
}
private static bool TrimmedStringStartsWith(string str, string prefix)
{
int indexOfFirstNonWhitespaceChar = GetIndexOfFirstNonWhitespaceChar(str);
if (str.Length - indexOfFirstNonWhitespaceChar < prefix.Length)
{
return false;
}
for (int i = 0; i < prefix.Length; i++)
{
if (prefix[i] != str[i + indexOfFirstNonWhitespaceChar])
{
return false;
}
}
return true;
}
private static int IndexOfNewLine(string str, int start, out int newLineLength)
{
while (start < str.Length)
{
switch (str[start])
{
case '\r':
if (start + 1 < str.Length && str[start + 1] == '\n')
{
newLineLength = 2;
}
else
{
newLineLength = 1;
}
return start;
case '\n':
newLineLength = 1;
return start;
}
start++;
}
newLineLength = 0;
return start;
}
private void WriteFormattedSingleLineComment(string text)
{
bool flag = true;
int num = 0;
while (num < text.Length)
{
int newLineLength;
int num2 = IndexOfNewLine(text, num, out newLineLength);
int indexOfFirstNonWhitespaceChar = GetIndexOfFirstNonWhitespaceChar(text, num, num2);
if (num2 - indexOfFirstNonWhitespaceChar < 4 || !SyntaxFacts.IsWhitespace(text[indexOfFirstNonWhitespaceChar + 3]))
{
flag = false;
break;
}
num = num2 + newLineLength;
}
int num3 = (flag ? 4 : 3);
int num4 = 0;
while (num4 < text.Length)
{
int newLineLength2;
int num5 = IndexOfNewLine(text, num4, out newLineLength2);
int num6 = GetIndexOfFirstNonWhitespaceChar(text, num4, num5) + num3;
WriteSubStringLine(text, num6, num5 - num6);
num4 = num5 + newLineLength2;
}
}
private void WriteFormattedMultiLineComment(string[] lines, int numLines)
{
bool flag = lines[0].Trim() == "/**";
bool flag2 = lines[numLines - 1].Trim() == "*/";
if (flag2)
{
numLines--;
}
int startIndex = 0;
if (numLines > 1)
{
string text = FindMultiLineCommentPattern(lines[1]);
if (text != null)
{
bool flag3 = true;
for (int i = 2; i < numLines; i++)
{
string text2 = LongestCommonPrefix(text, lines[i]);
if (string.IsNullOrWhiteSpace(text2))
{
flag3 = false;
break;
}
text = text2;
}
if (flag3)
{
startIndex = text.Length;
}
}
}
if (!flag)
{
string text3 = lines[0].TrimStart(null);
if (!flag2 && numLines == 1)
{
text3 = TrimEndOfMultiLineComment(text3);
}
WriteLine(text3.Substring(text3.StartsWith("/** ") ? 4 : (text3.StartsWith("/**") ? 3 : (text3.StartsWith("* ") ? 2 : (text3.StartsWith("*") ? 1 : 0)))));
}
for (int j = 1; j < numLines; j++)
{
string text4 = lines[j].Substring(startIndex);
if (!flag2 && j == numLines - 1)
{
text4 = TrimEndOfMultiLineComment(text4);
}
WriteLine(text4);
}
}
private static string TrimEndOfMultiLineComment(string trimmed)
{
int num = trimmed.IndexOf("*/", StringComparison.Ordinal);
if (num >= 0)
{
trimmed = trimmed.Substring(0, num);
}
return trimmed;
}
private static string FindMultiLineCommentPattern(string line)
{
int num = 0;
bool flag = false;
foreach (char c in line)
{
if (SyntaxFacts.IsWhitespace(c))
{
num++;
continue;
}
if (flag || c != '*')
{
break;
}
num++;
flag = true;
}
if (!flag)
{
return null;
}
return line.Substring(0, num);
}
private static string LongestCommonPrefix(string str1, string str2)
{
int i = 0;
for (int num = Math.Min(str1.Length, str2.Length); i < num && str1[i] == str2[i]; i++)
{
}
return str1.Substring(0, i);
}
private static string GetDocumentationCommentId(CrefSyntax crefSyntax, Binder binder, BindingDiagnosticBag diagnostics)
{
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
if (((SyntaxNode)crefSyntax).ContainsDiagnostics)
{
return ToBadCrefString(crefSyntax);
}
Symbol ambiguityWinner;
ImmutableArray<Symbol> immutableArray = binder.BindCref(crefSyntax, out ambiguityWinner, diagnostics);
Symbol symbol;
switch (immutableArray.Length)
{
case 0:
return ToBadCrefString(crefSyntax);
case 1:
symbol = immutableArray[0];
break;
default:
symbol = ambiguityWinner;
break;
}
if ((int)symbol.Kind == 0)
{
symbol = ((AliasSymbol)symbol).GetAliasTarget(null);
}
if (symbol is NamespaceSymbol ns)
{
diagnostics.AddAssembliesUsedByNamespaceReference(ns);
}
else
{
diagnostics.AddDependencies((symbol as TypeSymbol) ?? symbol.ContainingType);
}
return symbol.OriginalDefinition.GetDocumentationCommentId();
}
private static string ToBadCrefString(CrefSyntax cref)
{
using StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture);
((SyntaxNode)cref).WriteTo((TextWriter)stringWriter);
return "!:" + stringWriter.ToString().Replace("{", "&lt;").Replace("}", "&gt;");
}
private static void BindName(XmlNameAttributeSyntax syntax, Binder binder, Symbol memberSymbol, ref HashSet<ParameterSymbol> documentedParameters, ref HashSet<TypeParameterSymbol> documentedTypeParameters, BindingDiagnosticBag diagnostics)
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
XmlNameAttributeElementKind elementKind = syntax.GetElementKind();
switch (elementKind)
{
case XmlNameAttributeElementKind.Parameter:
if (documentedParameters == null)
{
documentedParameters = new HashSet<ParameterSymbol>();
}
break;
case XmlNameAttributeElementKind.TypeParameter:
if (documentedTypeParameters == null)
{
documentedTypeParameters = new HashSet<TypeParameterSymbol>();
}
break;
}
IdentifierNameSyntax identifier = syntax.Identifier;
if (((SyntaxNode)identifier).ContainsDiagnostics)
{
return;
}
CompoundUseSiteInfo<AssemblySymbol> useSiteInfo = binder.GetNewCompoundUseSiteInfo(diagnostics);
ImmutableArray<Symbol> immutableArray = binder.BindXmlNameAttribute(syntax, ref useSiteInfo);
((BindingDiagnosticBag<AssemblySymbol>)(object)diagnostics).Add((SyntaxNode)(object)syntax, useSiteInfo);
if (immutableArray.IsEmpty)
{
switch (elementKind)
{
case XmlNameAttributeElementKind.Parameter:
diagnostics.Add(ErrorCode.WRN_UnmatchedParamTag, ((SyntaxNode)identifier).Location, identifier);
break;
case XmlNameAttributeElementKind.ParameterReference:
diagnostics.Add(ErrorCode.WRN_UnmatchedParamRefTag, ((SyntaxNode)identifier).Location, identifier, memberSymbol);
break;
case XmlNameAttributeElementKind.TypeParameter:
diagnostics.Add(ErrorCode.WRN_UnmatchedTypeParamTag, ((SyntaxNode)identifier).Location, identifier);
break;
case XmlNameAttributeElementKind.TypeParameterReference:
diagnostics.Add(ErrorCode.WRN_UnmatchedTypeParamRefTag, ((SyntaxNode)identifier).Location, identifier, memberSymbol);
break;
default:
throw ExceptionUtilities.UnexpectedValue((object)elementKind);
}
return;
}
ImmutableArray<Symbol>.Enumerator enumerator = immutableArray.GetEnumerator();
while (enumerator.MoveNext())
{
Symbol current = enumerator.Current;
switch (elementKind)
{
case XmlNameAttributeElementKind.Parameter:
{
ParameterSymbol parameterSymbol = (ParameterSymbol)current;
if (!parameterSymbol.ContainingSymbol.IsAccessor() && !documentedParameters.Add(parameterSymbol))
{
diagnostics.Add(ErrorCode.WRN_DuplicateParamTag, ((SyntaxNode)syntax).Location, identifier);
}
break;
}
case XmlNameAttributeElementKind.TypeParameter:
if (!documentedTypeParameters.Add((TypeParameterSymbol)current))
{
diagnostics.Add(ErrorCode.WRN_DuplicateTypeParamTag, ((SyntaxNode)syntax).Location, identifier);
}
break;
}
}
}
private void BeginTemporaryString()
{
if (_temporaryStringBuilders == null)
{
_temporaryStringBuilders = new Stack<TemporaryStringBuilder>();
}
_temporaryStringBuilders.Push(new TemporaryStringBuilder(_indentDepth));
}
private string GetAndEndTemporaryString()
{
TemporaryStringBuilder temporaryStringBuilder = _temporaryStringBuilders.Pop();
_indentDepth = temporaryStringBuilder.InitialIndentDepth;
return temporaryStringBuilder.Pooled.ToStringAndFree();
}
private void Indent()
{
_indentDepth++;
}
private void Unindent()
{
_indentDepth--;
}
private void Write(string indentedAndWrappedString)
{
if (_temporaryStringBuilders != null && _temporaryStringBuilders.Count > 0)
{
_temporaryStringBuilders.Peek().Pooled.Builder.Append(indentedAndWrappedString);
}
else if (_writer != null)
{
_writer.Write(indentedAndWrappedString);
}
}
private void WriteLine(string message)
{
Stack<TemporaryStringBuilder> temporaryStringBuilders = _temporaryStringBuilders;
if (temporaryStringBuilders != null && temporaryStringBuilders.Count > 0)
{
StringBuilder builder = _temporaryStringBuilders.Peek().Pooled.Builder;
builder.Append(MakeIndent(_indentDepth));
builder.AppendLine(message);
}
else if (_writer != null)
{
_writer.Write(MakeIndent(_indentDepth));
_writer.WriteLine(message);
}
}
private void WriteSubStringLine(string message, int start, int length)
{
Stack<TemporaryStringBuilder> temporaryStringBuilders = _temporaryStringBuilders;
if (temporaryStringBuilders != null && temporaryStringBuilders.Count > 0)
{
StringBuilder builder = _temporaryStringBuilders.Peek().Pooled.Builder;
builder.Append(MakeIndent(_indentDepth));
builder.Append(message, start, length);
builder.AppendLine();
}
else if (_writer != null)
{
_writer.Write(MakeIndent(_indentDepth));
for (int i = 0; i < length; i++)
{
_writer.Write(message[start + i]);
}
_writer.WriteLine();
}
}
private void WriteLine(string format, params object[] args)
{
WriteLine(string.Format(format, args));
}
private static string MakeIndent(int depth)
{
return depth switch
{
0 => "",
1 => " ",
2 => " ",
3 => " ",
_ => new string(' ', depth * 4),
};
}
private static string GetDescription(XmlException e)
{
string message = e.Message;
try
{
string text = string.Format(new ResourceManager("System.Xml", typeof(XmlException).GetTypeInfo().Assembly).GetString("Xml_MessageWithErrorPosition"), "", e.LineNumber, e.LinePosition);
int num = message.IndexOf(text, StringComparison.Ordinal);
return (num < 0) ? message : message.Remove(num, text.Length);
}
catch
{
return message;
}
}
}