Skip to content

Commit c2274ab

Browse files
authored
Generate documentation - update API shape (#78067)
* update generate documentation API shape * returns an immutable array for the fix-all scenario. * fix * comments * deconstruct
1 parent bc763ff commit c2274ab

File tree

11 files changed

+42
-27
lines changed

11 files changed

+42
-27
lines changed

src/EditorFeatures/Core/DocumentationComments/CopilotGenerateDocumentationCommentManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ private async Task GenerateDocumentationCommentProposalsAsync(Document document,
5151
var generateDocumentationCommentProvider = await CreateProviderAsync(document, textView, snippet.MemberNode, cancellationToken).ConfigureAwait(false);
5252
if (generateDocumentationCommentProvider is not null)
5353
{
54-
await generateDocumentationCommentProvider.GenerateDocumentationProposalAsync(snippet, snapshot, caret, cancellationToken).ConfigureAwait(false);
54+
await generateDocumentationCommentProvider.GenerateDocumentationProposalAsync(document, snippet, snapshot, caret, cancellationToken).ConfigureAwait(false);
5555
}
5656
}
5757

src/EditorFeatures/Core/DocumentationComments/CopilotGenerateDocumentationCommentProvider.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Collections.Generic;
88
using System.Collections.Immutable;
99
using System.Diagnostics.CodeAnalysis;
10+
using System.Linq;
1011
using System.Text;
1112
using System.Text.RegularExpressions;
1213
using System.Threading;
@@ -46,7 +47,7 @@ public async Task InitializeAsync(ITextView textView, SuggestionServiceBase sugg
4647
_suggestionManager ??= await suggestionServiceBase.TryRegisterProviderAsync(this, textView, "AmbientAIDocumentationComments", cancellationToken).ConfigureAwait(false);
4748
}
4849

49-
public async Task GenerateDocumentationProposalAsync(DocumentationCommentSnippet snippet,
50+
public async Task GenerateDocumentationProposalAsync(Document document, DocumentationCommentSnippet snippet,
5051
ITextSnapshot oldSnapshot, VirtualSnapshotPoint oldCaret, CancellationToken cancellationToken)
5152
{
5253
// Checks to see if the feature is enabled and if the suggestionManager is available
@@ -58,7 +59,7 @@ public async Task GenerateDocumentationProposalAsync(DocumentationCommentSnippet
5859
await TaskScheduler.Default;
5960

6061
// MemberNode is not null at this point, checked when determining if the file is excluded.
61-
var snippetProposal = GetSnippetProposal(snippet.SnippetText, snippet.MemberNode!, snippet.Position, snippet.CaretOffset);
62+
var snippetProposal = GetSnippetProposal(document, snippet.SnippetText, snippet.MemberNode!, snippet.Position, snippet.CaretOffset);
6263

6364
if (snippetProposal is null)
6465
{
@@ -85,7 +86,7 @@ public async Task GenerateDocumentationProposalAsync(DocumentationCommentSnippet
8586
/// <summary>
8687
/// Traverses the documentation comment shell and retrieves the pieces that are needed to generate the documentation comment.
8788
/// </summary>
88-
private static DocumentationCommentProposal? GetSnippetProposal(string comments, SyntaxNode memberNode, int? position, int caret)
89+
private static DocumentationCommentProposal? GetSnippetProposal(Document document, string comments, SyntaxNode memberNode, int? position, int caret)
8990
{
9091
if (position is null)
9192
{
@@ -175,7 +176,7 @@ public async Task GenerateDocumentationProposalAsync(DocumentationCommentSnippet
175176
index = exceptionEndTag + "</exception>".Length;
176177
}
177178

178-
return new DocumentationCommentProposal(memberNode.ToFullString(), proposedEdits.ToImmutableArray());
179+
return new DocumentationCommentProposal(document, memberNode, proposedEdits.ToImmutableArray());
179180
}
180181

181182
/// <summary>
@@ -186,7 +187,9 @@ private static async Task<IReadOnlyList<ProposedEdit>> GetProposedEditsAsync(
186187
ITextSnapshot oldSnapshot, string? indentText, CancellationToken cancellationToken)
187188
{
188189
var list = new List<ProposedEdit>();
189-
var (documentationCommentDictionary, isQuotaExceeded) = await copilotService.GetDocumentationCommentAsync(proposal, cancellationToken).ConfigureAwait(false);
190+
var documentationCommentResults = await copilotService.GetDocumentationCommentAsync([proposal], cancellationToken).ConfigureAwait(false);
191+
192+
var (documentationCommentDictionary, isQuotaExceeded) = documentationCommentResults.FirstOrDefault();
190193

191194
// Quietly fail if the quota has been exceeded.
192195
if (isQuotaExceeded)

src/EditorFeatures/Test2/CodeFixes/CodeFixServiceTests.vb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,8 +363,8 @@ Namespace Microsoft.CodeAnalysis.Editor.Implementation.CodeFixes.UnitTests
363363
Return Task.FromResult(False)
364364
End Function
365365

366-
Public Function GetDocumentationCommentAsync(proposal As DocumentationCommentProposal, cancellationToken As CancellationToken) As Task(Of (responseDictionary As Dictionary(Of String, String), isQuotaExceeded As Boolean)) Implements ICopilotCodeAnalysisService.GetDocumentationCommentAsync
367-
Return Task.FromResult((New Dictionary(Of String, String), False))
366+
Public Function GetDocumentationCommentAsync(proposals As ImmutableArray(Of DocumentationCommentProposal), cancellationToken As CancellationToken) As Task(Of ImmutableArray(Of (responseDictionary As Dictionary(Of String, String), isQuotaExceeded As Boolean))) Implements ICopilotCodeAnalysisService.GetDocumentationCommentAsync
367+
Return Task.FromResult(ImmutableArray.Create((New Dictionary(Of String, String), False)))
368368
End Function
369369

370370
Public Function GetOnTheFlyDocsPromptAsync(onTheFlyDocsInfo As OnTheFlyDocsInfo, cancellationToken As CancellationToken) As Task(Of String) Implements ICopilotCodeAnalysisService.GetOnTheFlyDocsPromptAsync

src/Features/CSharpTest/Copilot/CSharpImplementNotImplementedExceptionFixProviderTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,7 @@ public Task<bool> IsFileExcludedAsync(string filePath, CancellationToken cancell
666666
public Task StartRefinementSessionAsync(Document oldDocument, Document newDocument, Diagnostic? primaryDiagnostic, CancellationToken cancellationToken)
667667
=> throw new NotImplementedException();
668668

669-
Task<(Dictionary<string, string>? responseDictionary, bool isQuotaExceeded)> ICopilotCodeAnalysisService.GetDocumentationCommentAsync(DocumentationCommentProposal proposal, CancellationToken cancellationToken)
669+
Task<ImmutableArray<(Dictionary<string, string>? responseDictionary, bool isQuotaExceeded)>> ICopilotCodeAnalysisService.GetDocumentationCommentAsync(ImmutableArray<DocumentationCommentProposal> proposals, CancellationToken cancellationToken)
670670
=> throw new NotImplementedException();
671671

672672
public Task<ImmutableDictionary<SyntaxNode, ImplementationDetails>> ImplementNotImplementedExceptionsAsync(

src/Features/Core/Portable/Copilot/ICopilotCodeAnalysisService.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,10 @@ internal interface ICopilotCodeAnalysisService : ILanguageService
8383
Task<bool> IsFileExcludedAsync(string filePath, CancellationToken cancellationToken);
8484

8585
/// <summary>
86-
/// Method to retrieve the documentation comment for a given <paramref name="proposal"/>
86+
/// Method to retrieve the documentation comment for given <paramref name="proposals"/>
8787
/// </summary>
88-
/// <param name="proposal">The documentation comment that has been broken down into its individual pieces.</param>
89-
Task<(Dictionary<string, string>? responseDictionary, bool isQuotaExceeded)> GetDocumentationCommentAsync(DocumentationCommentProposal proposal, CancellationToken cancellationToken);
88+
/// <param name="proposals">The documentation comments that have been broken down into its individual pieces.</param>
89+
Task<ImmutableArray<(Dictionary<string, string>? responseDictionary, bool isQuotaExceeded)>> GetDocumentationCommentAsync(ImmutableArray<DocumentationCommentProposal> proposals, CancellationToken cancellationToken);
9090

9191
/// <summary>
9292
/// Checks if the feature for implementing <see cref="System.NotImplementedException"/> is available.

src/Features/Core/Portable/DocumentationComments/DocumentationCommentProposal.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,19 @@ namespace Microsoft.CodeAnalysis.DocumentationComments;
1111
/// </summary>
1212
internal sealed record DocumentationCommentProposal
1313
{
14-
public string SymbolToAnalyze { get; }
14+
public Document Document { get; }
15+
16+
/// <summary>
17+
/// Represents the node that is getting an auto-inserted documentation comment.
18+
/// </summary>
19+
public SyntaxNode MemberNode { get; }
1520

1621
public ImmutableArray<DocumentationCommentProposedEdit> ProposedEdits { get; }
1722

18-
public DocumentationCommentProposal(string symbolToAnalyze, ImmutableArray<DocumentationCommentProposedEdit> proposedEdits)
23+
public DocumentationCommentProposal(Document document, SyntaxNode memberNode, ImmutableArray<DocumentationCommentProposedEdit> proposedEdits)
1924
{
20-
SymbolToAnalyze = symbolToAnalyze;
25+
Document = document;
26+
MemberNode = memberNode;
2127
ProposedEdits = proposedEdits;
2228
}
2329
}

src/Features/ExternalAccess/Copilot/GenerateDocumentation/CopilotDocumentationCommentProposalWrapper.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ public CopilotDocumentationCommentProposalWrapper(DocumentationCommentProposal d
1919

2020
}
2121

22-
public string SymbolToAnalyze => _documentationCommentProposal.SymbolToAnalyze;
22+
public Document Document => _documentationCommentProposal.Document;
23+
public SyntaxNode MemberNode => _documentationCommentProposal.MemberNode;
2324
public ImmutableArray<CopilotDocumentationCommentProposedEditWrapper> ProposedEdits => _wrappedProposedEdits;
2425
}
2526
}

src/Features/ExternalAccess/Copilot/GenerateDocumentation/IExternalCSharpCopilotGenerateDocumentationService.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
// See the LICENSE file in the project root for more information.
44

55
using System.Collections.Generic;
6+
using System.Collections.Immutable;
67
using System.Threading;
78
using System.Threading.Tasks;
89

910
namespace Microsoft.CodeAnalysis.ExternalAccess.Copilot
1011
{
1112
internal interface IExternalCSharpCopilotGenerateDocumentationService
1213
{
13-
Task<(Dictionary<string, string>? responseDictionary, bool isQuotaExceeded)> GetDocumentationCommentAsync(CopilotDocumentationCommentProposalWrapper proposal, CancellationToken cancellationToken);
14+
Task<ImmutableArray<(Dictionary<string, string>? responseDictionary, bool isQuotaExceeded)>> GetDocumentationCommentAsync(ImmutableArray<CopilotDocumentationCommentProposalWrapper> proposals, CancellationToken cancellationToken);
1415
}
1516
}

src/Features/ExternalAccess/Copilot/Internal/Analyzer/AbstractCopilotCodeAnalysisService.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ internal abstract class AbstractCopilotCodeAnalysisService(IDiagnosticsRefresher
4444
protected abstract Task<string> GetOnTheFlyDocsPromptCoreAsync(OnTheFlyDocsInfo onTheFlyDocsInfo, CancellationToken cancellationToken);
4545
protected abstract Task<(string responseString, bool isQuotaExceeded)> GetOnTheFlyDocsResponseCoreAsync(string prompt, CancellationToken cancellationToken);
4646
protected abstract Task<bool> IsFileExcludedCoreAsync(string filePath, CancellationToken cancellationToken);
47-
protected abstract Task<(Dictionary<string, string>? responseDictionary, bool isQuotaExceeded)> GetDocumentationCommentCoreAsync(DocumentationCommentProposal proposal, CancellationToken cancellationToken);
47+
protected abstract Task<ImmutableArray<(Dictionary<string, string>? responseDictionary, bool isQuotaExceeded)>> GetDocumentationCommentCoreAsync(ImmutableArray<DocumentationCommentProposal> proposals, CancellationToken cancellationToken);
4848
protected abstract Task<ImmutableDictionary<SyntaxNode, ImplementationDetails>> ImplementNotImplementedExceptionsCoreAsync(Document document, ImmutableDictionary<SyntaxNode, ImmutableArray<ReferencedSymbol>> methodOrProperties, CancellationToken cancellationToken);
4949
protected abstract bool IsImplementNotImplementedExceptionsAvailableCore();
5050

@@ -183,6 +183,7 @@ public async Task<string> GetOnTheFlyDocsPromptAsync(OnTheFlyDocsInfo onTheFlyDo
183183
{
184184
return await GetOnTheFlyDocsPromptCoreAsync(onTheFlyDocsInfo, cancellationToken).ConfigureAwait(false);
185185
}
186+
186187
public async Task<(string responseString, bool isQuotaExceeded)> GetOnTheFlyDocsResponseAsync(string prompt, CancellationToken cancellationToken)
187188
{
188189
if (!await IsAvailableAsync(cancellationToken).ConfigureAwait(false))
@@ -199,12 +200,12 @@ public async Task<bool> IsFileExcludedAsync(string filePath, CancellationToken c
199200
return await IsFileExcludedCoreAsync(filePath, cancellationToken).ConfigureAwait(false);
200201
}
201202

202-
public async Task<(Dictionary<string, string>? responseDictionary, bool isQuotaExceeded)> GetDocumentationCommentAsync(DocumentationCommentProposal proposal, CancellationToken cancellationToken)
203+
public async Task<ImmutableArray<(Dictionary<string, string>? responseDictionary, bool isQuotaExceeded)>> GetDocumentationCommentAsync(ImmutableArray<DocumentationCommentProposal> proposals, CancellationToken cancellationToken)
203204
{
204205
if (!await IsAvailableAsync(cancellationToken).ConfigureAwait(false))
205-
return (null, false);
206+
return [(null, false)];
206207

207-
return await GetDocumentationCommentCoreAsync(proposal, cancellationToken).ConfigureAwait(false);
208+
return await GetDocumentationCommentCoreAsync(proposals, cancellationToken).ConfigureAwait(false);
208209
}
209210

210211
public async Task<bool> IsImplementNotImplementedExceptionsAvailableAsync(CancellationToken cancellationToken)

src/Features/ExternalAccess/Copilot/Internal/Analyzer/CSharp/CSharpCopilotCodeAnalysisService.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,12 +143,14 @@ protected override Task<bool> IsFileExcludedCoreAsync(string filePath, Cancellat
143143
return Task.FromResult(false);
144144
}
145145

146-
protected override Task<(Dictionary<string, string>? responseDictionary, bool isQuotaExceeded)> GetDocumentationCommentCoreAsync(DocumentationCommentProposal proposal, CancellationToken cancellationToken)
146+
protected override Task<ImmutableArray<(Dictionary<string, string>? responseDictionary, bool isQuotaExceeded)>> GetDocumentationCommentCoreAsync(ImmutableArray<DocumentationCommentProposal> proposals, CancellationToken cancellationToken)
147147
{
148148
if (GenerateDocumentationService is not null)
149-
return GenerateDocumentationService.GetDocumentationCommentAsync(new CopilotDocumentationCommentProposalWrapper(proposal), cancellationToken);
150-
151-
return Task.FromResult<(Dictionary<string, string>?, bool)>((null, false));
149+
{
150+
var wrappedProposals = proposals.SelectAsArray(p => new CopilotDocumentationCommentProposalWrapper(p));
151+
return GenerateDocumentationService.GetDocumentationCommentAsync(wrappedProposals, cancellationToken);
152+
}
153+
return Task.FromResult(ImmutableArray.Create<(Dictionary<string, string>?, bool)>((null, false)));
152154
}
153155

154156
protected override bool IsImplementNotImplementedExceptionsAvailableCore()

0 commit comments

Comments
 (0)