Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds 💡 Implement Using Copilot for NotImplementedException #77299

Open
wants to merge 120 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
120 commits
Select commit Hold shift + click to select a range
b6b952a
wip
akhera99 Nov 26, 2024
5ed5ee7
wip
akhera99 Nov 27, 2024
f416e98
wip
akhera99 Nov 27, 2024
38fa91a
wip
akhera99 Nov 27, 2024
1f6a30f
wip
akhera99 Nov 29, 2024
6de1307
wip
akhera99 Nov 29, 2024
ed36e8f
wip
akhera99 Nov 29, 2024
9fd8f89
remove some commented out code
akhera99 Dec 3, 2024
36a8305
Merge branch 'main' into dev/ankitakhera/aai_doc_comments
akhera99 Jan 6, 2025
9c33d32
still cleaning up
akhera99 Jan 7, 2025
f2ec7f1
revert file
akhera99 Jan 7, 2025
0f8e4f3
clean up + option
akhera99 Jan 9, 2025
c096031
wip
akhera99 Jan 21, 2025
f46e751
dispose of disable of intellicode line completions
akhera99 Jan 27, 2025
0676f73
comments
akhera99 Jan 27, 2025
c028cc9
Merge branch 'main' into dev/ankitakhera/aai_doc_comments
akhera99 Jan 27, 2025
5ffb800
comments
akhera99 Jan 27, 2025
30c4aaf
add quota exceeded checks
akhera99 Jan 27, 2025
1f93a1f
fix tests
akhera99 Jan 28, 2025
8f64473
revert file
akhera99 Jan 28, 2025
2e2f6f0
remove unused optional params
akhera99 Jan 28, 2025
77a3f0c
last few fixes
akhera99 Jan 30, 2025
ae0ffe6
feedback
akhera99 Feb 4, 2025
ce330fe
fix tests
akhera99 Feb 4, 2025
ed65b3b
small fix
akhera99 Feb 4, 2025
73e3e8e
Merge branch 'main' into dev/ankitakhera/aai_doc_comments
akhera99 Feb 7, 2025
c756a4a
fix
akhera99 Feb 7, 2025
5fef68f
feedback
akhera99 Feb 7, 2025
dde66ab
feedback
akhera99 Feb 7, 2025
4e8f752
removed per comments
akhera99 Feb 11, 2025
b6688d6
remove unused usings
akhera99 Feb 11, 2025
ab35eeb
Fixer/Analyzer for implementing method
maryamariyan Feb 11, 2025
5decd9b
feedback
akhera99 Feb 12, 2025
daff7a1
feedback
akhera99 Feb 12, 2025
4dc63b8
move stuff around with new EA structure in roslyn
akhera99 Feb 13, 2025
96bd8e2
wip
akhera99 Feb 13, 2025
906aed9
feedback
akhera99 Feb 13, 2025
61acead
feedbacl
akhera99 Feb 15, 2025
ae609fa
fix
akhera99 Feb 15, 2025
423a6df
feedback
akhera99 Feb 15, 2025
7683098
feedback
akhera99 Feb 18, 2025
ec34831
feedback
akhera99 Feb 18, 2025
b6b8e8c
revert
akhera99 Feb 18, 2025
dbff122
remove null check
akhera99 Feb 18, 2025
41be07f
clean up
akhera99 Feb 18, 2025
a63b731
fix
akhera99 Feb 19, 2025
835c7ec
Merge remote-tracking branch 'origin/main' into dev/maryamariyan/dev1…
maryamariyan Feb 19, 2025
faea3a8
fix tests
akhera99 Feb 19, 2025
3851626
Merge remote-tracking branch 'origin/main' into dev/ankitakhera/aai_d…
maryamariyan Feb 19, 2025
b98a886
local ad ons
maryamariyan Feb 20, 2025
7b6d468
local ad ons
maryamariyan Feb 20, 2025
6d46c43
Merge branch 'dev/maryamariyan/dev17-implement-method-fixer' into dev…
maryamariyan Feb 20, 2025
2c62d7b
Add main bits for generating method implementation
maryamariyan Feb 20, 2025
c49fdcc
todo next
maryamariyan Feb 20, 2025
ee3b104
update APIs
maryamariyan Feb 20, 2025
bdcfbf4
trial 1
maryamariyan Feb 21, 2025
9db6634
Merge remote-tracking branch 'origin/main' into dev/maryamariyan/repl…
maryamariyan Feb 21, 2025
7431087
Fix compile after merge
maryamariyan Feb 21, 2025
e6153f0
temp1
maryamariyan Feb 22, 2025
b2c0584
temp2
maryamariyan Feb 22, 2025
e1e6fd3
Implement method, end-to-end for one-off code action
maryamariyan Feb 22, 2025
ba32b2b
corrections
maryamariyan Feb 22, 2025
e6c9ef2
cleanup
maryamariyan Feb 24, 2025
d595c6a
cleanup preliminary check
maryamariyan Feb 24, 2025
86e8bf9
Fix bug
maryamariyan Feb 24, 2025
d993617
cleanup and fixes
maryamariyan Feb 25, 2025
3360777
remove local changes for pr
maryamariyan Feb 25, 2025
de14ec1
correct spacing
maryamariyan Feb 25, 2025
56b16f9
cleanup
maryamariyan Feb 25, 2025
8c89fee
Add unit test - takes code block suggestion to replace with method body
maryamariyan Feb 25, 2025
5150992
Add test, support expression body clause later
maryamariyan Feb 25, 2025
47c913c
Change the FAR API call
maryamariyan Feb 25, 2025
b8f70c6
using `.Parent.FirstAncestorOrSelf`
maryamariyan Feb 25, 2025
b02349f
Improve wrapper implementation
maryamariyan Feb 25, 2025
ba4b470
Apply first round code review
maryamariyan Feb 26, 2025
688b3ea
Merge DualChangeAction into DocumentChangeAction
sharwell Feb 28, 2025
42b8763
Make IDE3000 not configurable
sharwell Feb 28, 2025
998a3d8
Simplify analyzer code and improve robustness
sharwell Feb 28, 2025
0aa9356
Simplifies fixer and applies most remaining feedback
maryamariyan Mar 1, 2025
f5116f2
Merge remote-tracking branch 'maryam/dev/maryamariyan/replicate-for-f…
maryamariyan Mar 1, 2025
1c9ba44
Fix compile related to DocumentChangeAction
maryamariyan Mar 1, 2025
2ed4649
Cleanup messaging
maryamariyan Mar 1, 2025
24f76b2
Add resources for messaging
maryamariyan Mar 1, 2025
744eb42
Adds a few basic tests
maryamariyan Mar 1, 2025
b077c3f
Merge remote-tracking branch 'origin/main' into dev/maryamariyan/repl…
maryamariyan Mar 2, 2025
70209d7
Undo most recent analyzer changes,
maryamariyan Mar 2, 2025
ffd9bce
Apply PR feedback
maryamariyan Mar 2, 2025
e8596bc
Tests renamed
maryamariyan Mar 2, 2025
1923930
Correct test setup
maryamariyan Mar 2, 2025
0cc13f3
Improves readability and removes unreachable code
maryamariyan Mar 3, 2025
fbcd111
Correct mistakes in tests
maryamariyan Mar 3, 2025
41a421f
Adds more unit tests
maryamariyan Mar 3, 2025
9222c16
Fix formatting (https://learn.microsoft.com/dotnet/fundamentals/code-…
maryamariyan Mar 3, 2025
1452aa0
Fixes Analyzer tests
maryamariyan Mar 3, 2025
6fb4938
Makes sure original and replacement text are properly aligned
maryamariyan Mar 3, 2025
c270a76
Apply partial PR feedback
maryamariyan Mar 3, 2025
061d448
cleanup
maryamariyan Mar 3, 2025
faa4722
Applies feedback to change API surface
maryamariyan Mar 4, 2025
f48bf92
All tests pass
maryamariyan Mar 4, 2025
af8ca36
tests are actually failing
maryamariyan Mar 4, 2025
770fc86
Fix Quota bug and show failing tests
maryamariyan Mar 4, 2025
6d20484
Update tests for error conditions where diagnostics are not corrected
sharwell Mar 4, 2025
2b7487a
undo IsImplementNotImplementedExceptionEnabledAsync change
maryamariyan Mar 5, 2025
8b53fe0
Fixes remaining tests
maryamariyan Mar 5, 2025
dbc3919
cleanup
maryamariyan Mar 5, 2025
3e3bd88
Add back referencedSymbols to API call to help with perf
maryamariyan Mar 5, 2025
16d2481
Gracefully comment when result is unexpected
maryamariyan Mar 5, 2025
3b0ba9a
Remove unused resource
maryamariyan Mar 5, 2025
b20b2cb
Simplify error messages
maryamariyan Mar 5, 2025
384ce72
Cleanup tests
maryamariyan Mar 5, 2025
79bebb1
Add missing entry for IDE3000
maryamariyan Mar 5, 2025
517d977
Add Missing Help Link
maryamariyan Mar 5, 2025
8aaa595
mid stage
maryamariyan Mar 6, 2025
9eb2e7c
Removes QuotaExceeds property, received as message
maryamariyan Mar 6, 2025
d088c36
Update signature
maryamariyan Mar 6, 2025
7127ff7
Merge remote-tracking branch 'origin/main' into dev/maryamariyan/repl…
maryamariyan Mar 6, 2025
2f934a6
Fix missed out warning
maryamariyan Mar 6, 2025
4eecdc6
Fix test correctness issue picked up by CI
maryamariyan Mar 6, 2025
44a65e1
Add logging
maryamariyan Mar 6, 2025
960a9cd
Apply PR feedback
maryamariyan Mar 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feedback
  • Loading branch information
akhera99 committed Feb 12, 2025
commit daff7a1f06ef86e10c9a45ba9b618f9c3df6d416
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,10 @@ internal sealed class DocumentationCommentCommandHandler(
ITextUndoHistoryRegistry undoHistoryRegistry,
IEditorOperationsFactoryService editorOperationsFactoryService,
EditorOptionsService editorOptionsService,
[Import(AllowDefault = true)] SuggestionServiceBase suggestionServiceBase,
IThreadingContext threadingContext,
CopilotGenerateDocumentationCommentManager generateDocumentationCommentManager,
IAsynchronousOperationListenerProvider listenerProvider)
: AbstractDocumentationCommentCommandHandler(uiThreadOperationExecutor, undoHistoryRegistry,
editorOperationsFactoryService, editorOptionsService, suggestionServiceBase, threadingContext, listenerProvider)
editorOperationsFactoryService, editorOptionsService, generateDocumentationCommentManager, listenerProvider)
{
protected override string ExteriorTriviaText => "///";
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

namespace Microsoft.CodeAnalysis.DocumentationComments;

internal abstract class AbstractDocumentationCommentCommandHandler : SuggestionProviderBase,
internal abstract class AbstractDocumentationCommentCommandHandler :
IChainedCommandHandler<TypeCharCommandArgs>,
ICommandHandler<ReturnKeyCommandArgs>,
ICommandHandler<InsertCommentCommandArgs>,
Expand All @@ -44,23 +44,15 @@ internal abstract class AbstractDocumentationCommentCommandHandler : SuggestionP
private readonly ITextUndoHistoryRegistry _undoHistoryRegistry;
private readonly IEditorOperationsFactoryService _editorOperationsFactoryService;
private readonly EditorOptionsService _editorOptionsService;
private readonly SuggestionServiceBase? _suggestionServiceBase;
private readonly CopilotGenerateDocumentationCommentManager _generateDocumentationCommentManager;
private readonly IAsynchronousOperationListener _asyncListener;

private SuggestionManagerBase? _suggestionManagerBase;
private VisualStudio.Threading.IAsyncDisposable? _intellicodeLineCompletionsDisposable;

internal SuggestionSessionBase? _suggestionSession;

public readonly IThreadingContext? ThreadingContext;

protected AbstractDocumentationCommentCommandHandler(
IUIThreadOperationExecutor uiThreadOperationExecutor,
ITextUndoHistoryRegistry undoHistoryRegistry,
IEditorOperationsFactoryService editorOperationsFactoryService,
EditorOptionsService editorOptionsService,
SuggestionServiceBase? suggestionServiceBase,
IThreadingContext? threadingContext,
CopilotGenerateDocumentationCommentManager generateDocumentationCommentManager,
IAsynchronousOperationListenerProvider listenerProvider)
{
Contract.ThrowIfNull(uiThreadOperationExecutor);
Expand All @@ -71,9 +63,8 @@ protected AbstractDocumentationCommentCommandHandler(
_undoHistoryRegistry = undoHistoryRegistry;
_editorOperationsFactoryService = editorOperationsFactoryService;
_editorOptionsService = editorOptionsService;
_suggestionServiceBase = suggestionServiceBase;
_generateDocumentationCommentManager = generateDocumentationCommentManager;
_asyncListener = listenerProvider.GetListener(FeatureAttribute.GenerateDocumentation);
ThreadingContext = threadingContext;
}

protected abstract string ExteriorTriviaText { get; }
Expand Down Expand Up @@ -125,292 +116,25 @@ private bool CompleteComment(
if (snippet != null)
{
ApplySnippet(snippet, subjectBuffer, textView);
/*var oldSnapshot = subjectBuffer.CurrentSnapshot;
var oldCaret = textView.Caret.Position.VirtualBufferPosition;*/
var oldSnapshot = subjectBuffer.CurrentSnapshot;
var oldCaret = textView.Caret.Position.VirtualBufferPosition;

returnValue = true;

/* // Only calls into the suggestion manager is available, the shell of the comment still gets inserted regardless.
if (_suggestionManagerBase != null && ThreadingContext != null)
{
ThreadingContext.ThrowIfNotOnUIThread();

var token = _asyncListener.BeginAsyncOperation(nameof(GenerateDocumentationProposalAsync));
_ = GenerateDocumentationProposalAsync(document, snippet, oldSnapshot, oldCaret, cancellationToken).CompletesAsyncOperation(token);
}*/
var token = _asyncListener.BeginAsyncOperation(nameof(GenerateDocumentationCommentProposalsAsync));
_ = GenerateDocumentationCommentProposalsAsync(document, snippet, oldSnapshot, oldCaret, textView, cancellationToken).CompletesAsyncOperation(token);
}
}

return returnValue;
}

/*private async Task GenerateDocumentationProposalAsync(Document document, DocumentationCommentSnippet snippet,
ITextSnapshot oldSnapshot, VirtualSnapshotPoint oldCaret, CancellationToken cancellationToken)
{
await Task.Yield().ConfigureAwait(false);

// Bailing out if copilot is not available or the option is not enabled.
if (document.GetRequiredLanguageService<ICopilotCodeAnalysisService>() is not { } copilotService ||
await copilotService.IsAvailableAsync(cancellationToken).ConfigureAwait(false) is false)
{
return;
}

if (document.GetLanguageService<ICopilotOptionsService>() is not { } copilotOptionService ||
!await copilotOptionService.IsGenerateDocumentationCommentOptionEnabledAsync().ConfigureAwait(false))
{
return;
}

var snippetProposal = GetSnippetProposal(snippet.SnippetText, snippet.MemberNode, snippet.Position, snippet.CaretOffset);

if (snippetProposal is null)
{
return;
}

// Do not do IntelliCode line completions if we're about to generate a documentation comment
// so that won't have interfering grey text.
_intellicodeLineCompletionsDisposable = await _suggestionManagerBase!.DisableProviderAsync(SuggestionServiceNames.IntelliCodeLineCompletions, cancellationToken).ConfigureAwait(false);

var proposalEdits = await GetProposedEditsAsync(snippetProposal, copilotService, oldSnapshot, snippet.IndentText, cancellationToken).ConfigureAwait(false);

var proposal = Proposal.TryCreateProposal(null, proposalEdits, oldCaret, flags: ProposalFlags.SingleTabToAccept);

if (proposal is null)
{
return;
}

var suggestion = new DocumentationCommentSuggestion(this, proposal);

var session = this._suggestionSession = await (_suggestionManagerBase.TryDisplaySuggestionAsync(suggestion, cancellationToken)).ConfigureAwait(false);

if (session != null)
{
await TryDisplaySuggestionAsync(session, suggestion, cancellationToken).ConfigureAwait(false);
}
}*/

/* /// <summary>
/// Traverses the documentation comment shell and retrieves the pieces that are needed to generate the documentation comment.
/// </summary>
private static DocumentationCommentProposal? GetSnippetProposal(string? comments, SyntaxNode? memberNode, int? position, int caret)
{
if (comments is null)
{
return null;
}

if (memberNode is null)
{
return null;
}

if (position is null)
{
return null;
}

var startIndex = position.Value;
var proposedEdits = new List<DocumentationCommentProposedEdit>();
var index = 0;

var summaryStartTag = comments.IndexOf("<summary>", index, StringComparison.Ordinal);
var summaryEndTag = comments.IndexOf("</summary>", index, StringComparison.Ordinal);
if (summaryEndTag != -1 && summaryStartTag != -1)
{
proposedEdits.Add(new DocumentationCommentProposedEdit(new TextSpan(caret + startIndex, 0), null, DocumentationCommentTagType.Summary));
}

while (true)
{
var paramEndTag = comments.IndexOf("</param>", index, StringComparison.Ordinal);
var paramStartTag = comments.IndexOf("<param name=\"", index, StringComparison.Ordinal);

if (paramStartTag == -1 || paramEndTag == -1)
{
break;
}

var paramNameStart = paramStartTag + "<param name=\"".Length;
var paramNameEnd = comments.IndexOf("\">", paramNameStart, StringComparison.Ordinal);
if (paramNameEnd != -1)
{
var parameterName = comments.Substring(paramNameStart, paramNameEnd - paramNameStart);
proposedEdits.Add(new DocumentationCommentProposedEdit(new TextSpan(paramEndTag + startIndex, 0), parameterName, DocumentationCommentTagType.Param));
}

index = paramEndTag + "</param>".Length;
}

var returnsEndTag = comments.IndexOf("</returns>", index, StringComparison.Ordinal);
if (returnsEndTag != -1)
{
proposedEdits.Add(new DocumentationCommentProposedEdit(new TextSpan(returnsEndTag + startIndex, 0), null, DocumentationCommentTagType.Returns));
}

while (true)
{
var exceptionEndTag = comments.IndexOf("</exception>", index, StringComparison.Ordinal);
var exceptionStartTag = comments.IndexOf("<exception cref=\"", index, StringComparison.Ordinal);

if (exceptionEndTag == -1 || exceptionStartTag == -1)
{
break;
}

var exceptionNameStart = exceptionStartTag + "<exception cref=\"".Length;
var exceptionNameEnd = comments.IndexOf("\">", exceptionNameStart, StringComparison.Ordinal);
if (exceptionNameEnd != -1)
{
var exceptionName = comments.Substring(exceptionNameStart, exceptionNameEnd - exceptionNameStart);
proposedEdits.Add(new DocumentationCommentProposedEdit(new TextSpan(exceptionEndTag + startIndex, 0), exceptionName, DocumentationCommentTagType.Exception));
}

index = exceptionEndTag + "</exception>".Length;
}

return new DocumentationCommentProposal(memberNode.ToFullString(), proposedEdits.ToImmutableArray());
}

/// <summary>
/// Calls into the copilot service to get the pieces for the documentation comment.
/// </summary>
private static async Task<IReadOnlyList<ProposedEdit>> GetProposedEditsAsync(
DocumentationCommentProposal proposal, ICopilotCodeAnalysisService copilotService,
ITextSnapshot oldSnapshot, string? indentText, CancellationToken cancellationToken)
{
var list = new List<ProposedEdit>();
var (copilotText, isQuotaExceeded) = await copilotService.GetDocumentationCommentAsync(proposal, cancellationToken).ConfigureAwait(false);

// Quietly fail if the quota has been exceeded.
if (isQuotaExceeded)
{
return list;
}

// The response from Copilot is structured like a JSON object, so make sure it is being returned appropriately.
if (copilotText is null || copilotText.AsSpan().Trim() is "{}" or "{ }" or "")
{
return list;
}

// If the response can't be properly converted, something went wrong and bail out.
Dictionary<string, string>? props;
try
{
props = JsonConvert.DeserializeObject<Dictionary<string, string>>(copilotText);
}
catch (Exception)
{
return list;
}

if (props is null)
{
return list;
}

foreach (var edit in proposal.ProposedEdits)
{
string? copilotStatement = null;
var textSpan = edit.SpanToReplace;

if (edit.TagType == DocumentationCommentTagType.Summary && props.TryGetValue(DocumentationCommentTagType.Summary.ToString(), out var summary) && !string.IsNullOrEmpty(summary))
{
copilotStatement = summary;
}
else if (edit.TagType == DocumentationCommentTagType.Param && props.TryGetValue(edit.SymbolName!, out var param) && !string.IsNullOrEmpty(param))
{
copilotStatement = param;
}
else if (edit.TagType == DocumentationCommentTagType.Returns && props.TryGetValue(DocumentationCommentTagType.Returns.ToString(), out var returns) && !string.IsNullOrEmpty(returns))
{
copilotStatement = returns;
}
else if (edit.TagType == DocumentationCommentTagType.Exception && props.TryGetValue(edit.SymbolName!, out var exception) && !string.IsNullOrEmpty(exception))
{
copilotStatement = exception;
}

var proposedEdit = new ProposedEdit(new SnapshotSpan(oldSnapshot, textSpan.Start, textSpan.Length),
AddNewLinesToCopilotText(copilotStatement!, indentText, characterLimit: 120));
list.Add(proposedEdit);
}

return list;

static string AddNewLinesToCopilotText(string copilotText, string? indentText, int characterLimit)
{
var builder = new StringBuilder();
var words = copilotText.Split(' ');
var currentLineLength = 0;
characterLimit -= (indentText!.Length + "/// ".Length);
foreach (var word in words)
{
if (currentLineLength + word.Length >= characterLimit)
{
builder.AppendLine();
builder.Append(indentText);
builder.Append("/// ");
currentLineLength = 0;
}

if (currentLineLength > 0)
{
builder.Append(' ');
currentLineLength++;
}

builder.Append(word);
currentLineLength += word.Length;
}

return builder.ToString();
}
}

private async Task<bool> TryDisplaySuggestionAsync(SuggestionSessionBase session, DocumentationCommentSuggestion suggestion, CancellationToken cancellationToken)
{
if (ThreadingContext is null)
{
return false;
}

try
{
await ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
await session.DisplayProposalAsync(suggestion.Proposal, cancellationToken).ConfigureAwait(false);
return true;
}
catch (OperationCanceledException)
{
}

return false;
}

public async Task ClearSuggestionAsync(ReasonForDismiss reason, CancellationToken cancellationToken)
private async Task GenerateDocumentationCommentProposalsAsync(Document document, DocumentationCommentSnippet snippet, ITextSnapshot snapshot, VirtualSnapshotPoint caret, ITextView textView, CancellationToken cancellationToken)
{
if (_suggestionSession != null)
{
await _suggestionSession.DismissAsync(reason, cancellationToken).ConfigureAwait(false);
}

_suggestionSession = null;
await DisposeAsync().ConfigureAwait(false);
var generateDocumentationCommentProvider = await _generateDocumentationCommentManager.CreateProviderAsync(textView, cancellationToken).ConfigureAwait(false);
await generateDocumentationCommentProvider.GenerateDocumentationProposalAsync(document, snippet, snapshot, caret, cancellationToken).ConfigureAwait(false);
}

public async Task DisposeAsync()
{
if (_intellicodeLineCompletionsDisposable != null)
{
await _intellicodeLineCompletionsDisposable.DisposeAsync().ConfigureAwait(false);
_intellicodeLineCompletionsDisposable = null;
}
}*/

public CommandState GetCommandState(TypeCharCommandArgs args, Func<CommandState> nextHandler)
=> nextHandler();

Expand All @@ -426,14 +150,6 @@ public void ExecuteCommand(TypeCharCommandArgs args, Action nextHandler, Command
if (args.SubjectBuffer.IsInLspEditorContext())
return;

/*ThreadingContext?.JoinableTaskFactory.Run(async () =>
{
if (_suggestionServiceBase is not null)
{
_suggestionManagerBase = await _suggestionServiceBase.TryRegisterProviderAsync(this, args.TextView, "AmbientAIDocumentationComments", context.OperationContext.UserCancellationToken).ConfigureAwait(false);
}
});*/

CompleteComment(args.SubjectBuffer, args.TextView, InsertOnCharacterTyped, CancellationToken.None);
}

Expand Down
Loading
Loading