未验证 提交 ff930dec 编写于 作者: A Andy Gocke 提交者: GitHub

Merge pull request #39772 from dotnet/merges/release/dev16.4-to-release/dev16.4-vs-deps

Merge release/dev16.4 to release/dev16.4-vs-deps
......@@ -6685,6 +6685,48 @@ public async Task TestInheritdocInlineSummary()
Documentation("Summary documentation"));
}
[Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)]
public async Task TestInheritdocCycle1()
{
var markup =
@"
/// <inheritdoc cref=""M(int, int)""/>
void M(int x) { }
/// <inheritdoc cref=""M(int)""/>
void $$M(int x, int y) { }";
await TestInClassAsync(markup,
MainDescription("void C.M(int x, int y)"),
Documentation(""));
}
[Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)]
public async Task TestInheritdocCycle2()
{
var markup =
@"
/// <inheritdoc cref=""M(int)""/>
void $$M(int x) { }";
await TestInClassAsync(markup,
MainDescription("void C.M(int x)"),
Documentation(""));
}
[Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)]
public async Task TestInheritdocCycle3()
{
var markup =
@"
/// <inheritdoc cref=""M""/>
void $$M(int x) { }";
await TestInClassAsync(markup,
MainDescription("void C.M(int x)"),
Documentation(""));
}
[Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)]
[WorkItem(38794, "https://github.com/dotnet/roslyn/issues/38794")]
public async Task TestLinqGroupVariableDeclaration()
......
......@@ -894,6 +894,11 @@ public static DeclarationModifiers GetSymbolModifiers(this ISymbol symbol)
}
public static DocumentationComment GetDocumentationComment(this ISymbol symbol, Compilation compilation, CultureInfo? preferredCulture = null, bool expandIncludes = false, bool expandInheritdoc = false, CancellationToken cancellationToken = default)
{
return GetDocumentationComment(symbol, visitedSymbols: null, compilation, preferredCulture, expandIncludes, expandInheritdoc, cancellationToken);
}
private static DocumentationComment GetDocumentationComment(ISymbol symbol, HashSet<ISymbol>? visitedSymbols, Compilation compilation, CultureInfo? preferredCulture, bool expandIncludes, bool expandInheritdoc, CancellationToken cancellationToken)
{
var xmlText = symbol.GetDocumentationCommentXml(preferredCulture, expandIncludes, cancellationToken);
if (expandInheritdoc)
......@@ -906,7 +911,7 @@ public static DocumentationComment GetDocumentationComment(this ISymbol symbol,
try
{
var element = XElement.Parse(xmlText, LoadOptions.PreserveWhitespace);
element.ReplaceNodes(RewriteMany(symbol, compilation, element.Nodes().ToArray(), cancellationToken));
element.ReplaceNodes(RewriteMany(symbol, visitedSymbols, compilation, element.Nodes().ToArray(), cancellationToken));
xmlText = element.ToString(SaveOptions.DisableFormatting);
}
catch
......@@ -953,14 +958,14 @@ static bool IsEligibleForAutomaticInheritdoc(ISymbol symbol)
}
}
private static XNode[] RewriteInheritdocElements(ISymbol symbol, Compilation compilation, XNode node, CancellationToken cancellationToken)
private static XNode[] RewriteInheritdocElements(ISymbol symbol, HashSet<ISymbol>? visitedSymbols, Compilation compilation, XNode node, CancellationToken cancellationToken)
{
if (node.NodeType == XmlNodeType.Element)
{
var element = (XElement)node;
if (ElementNameIs(element, DocumentationCommentXmlNames.InheritdocElementName))
{
var rewritten = RewriteInheritdocElement(symbol, compilation, element, cancellationToken);
var rewritten = RewriteInheritdocElement(symbol, visitedSymbols, compilation, element, cancellationToken);
if (rewritten is object)
{
return rewritten;
......@@ -983,25 +988,25 @@ private static XNode[] RewriteInheritdocElements(ISymbol symbol, Compilation com
if (oldNodes != null)
{
XNode[] rewritten = RewriteMany(symbol, compilation, oldNodes.ToArray(), cancellationToken);
XNode[] rewritten = RewriteMany(symbol, visitedSymbols, compilation, oldNodes.ToArray(), cancellationToken);
container.ReplaceNodes(rewritten);
}
return new XNode[] { container };
}
private static XNode[] RewriteMany(ISymbol symbol, Compilation compilation, XNode[] nodes, CancellationToken cancellationToken)
private static XNode[] RewriteMany(ISymbol symbol, HashSet<ISymbol>? visitedSymbols, Compilation compilation, XNode[] nodes, CancellationToken cancellationToken)
{
var result = new List<XNode>();
foreach (var child in nodes)
{
result.AddRange(RewriteInheritdocElements(symbol, compilation, child, cancellationToken));
result.AddRange(RewriteInheritdocElements(symbol, visitedSymbols, compilation, child, cancellationToken));
}
return result.ToArray();
}
private static XNode[]? RewriteInheritdocElement(ISymbol memberSymbol, Compilation compilation, XElement element, CancellationToken cancellationToken)
private static XNode[]? RewriteInheritdocElement(ISymbol memberSymbol, HashSet<ISymbol>? visitedSymbols, Compilation compilation, XElement element, CancellationToken cancellationToken)
{
var crefAttribute = element.Attribute(XName.Get(DocumentationCommentXmlNames.CrefAttributeName));
var pathAttribute = element.Attribute(XName.Get(DocumentationCommentXmlNames.PathAttributeName));
......@@ -1033,9 +1038,16 @@ private static XNode[] RewriteMany(ISymbol symbol, Compilation compilation, XNod
}
}
visitedSymbols ??= new HashSet<ISymbol>();
if (!visitedSymbols.Add(symbol))
{
// Prevent recursion
return null;
}
try
{
var inheritedDocumentation = GetDocumentationComment(symbol, compilation, preferredCulture: null, expandIncludes: true, expandInheritdoc: true, cancellationToken);
var inheritedDocumentation = GetDocumentationComment(symbol, visitedSymbols, compilation, preferredCulture: null, expandIncludes: true, expandInheritdoc: true, cancellationToken);
if (inheritedDocumentation == DocumentationComment.Empty)
{
return Array.Empty<XNode>();
......@@ -1067,7 +1079,7 @@ private static XNode[] RewriteMany(ISymbol symbol, Compilation compilation, XNod
{
// change the current XML file path for nodes contained in the document:
// prototype(inheritdoc): what should the file path be?
var result = RewriteMany(symbol, compilation, loadedElements, cancellationToken);
var result = RewriteMany(symbol, visitedSymbols, compilation, loadedElements, cancellationToken);
// The elements could be rewritten away if they are includes that refer to invalid
// (but existing and accessible) XML files. If this occurs, behave as if we
......@@ -1084,6 +1096,10 @@ private static XNode[] RewriteMany(ISymbol symbol, Compilation compilation, XNod
{
return Array.Empty<XNode>();
}
finally
{
visitedSymbols.Remove(symbol);
}
// Local functions
static ISymbol? GetCandidateSymbol(ISymbol memberSymbol)
......
......@@ -44,7 +44,7 @@ public override async Task<IList<(Checksum, object)>> RequestAssetsAsync(int sco
(s, c) => ReadAssets(s, scopeId, checksums, serializerService, c), cancellationToken);
}, cancellationToken).ConfigureAwait(false);
}
catch (Exception ex) when (ReportUnlessCanceled(ex, cancellationToken))
catch (Exception ex) when (ReportUnlessCanceled(ex))
{
throw ExceptionUtilities.Unreachable;
}
......@@ -63,9 +63,10 @@ public override async Task<bool> IsExperimentEnabledAsync(string experimentName,
}
}
private bool ReportUnlessCanceled(Exception ex, CancellationToken cancellationToken)
private bool ReportUnlessCanceled(Exception ex)
{
if (!cancellationToken.IsCancellationRequested && _owner.IsDisposed)
// TODO: check !cancellationToken.IsCancellationRequeste instead (https://github.com/dotnet/roslyn/issues/39723)
if (!(ex is OperationCanceledException) && !(ex is TaskCanceledException) && _owner.IsDisposed)
{
// kill OOP if snapshot service got disconnected due to this exception.
FailFast.OnFatalException(ex);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册