| File: BraceCompletion\IBraceCompletionService.cs | Web Access |
| Project: src\roslyn\src\Features\Core\Portable\Microsoft.CodeAnalysis.Features.csproj (Microsoft.CodeAnalysis.Features) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Collections.Immutable; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Indentation; using Microsoft.CodeAnalysis.Text; namespace Microsoft.CodeAnalysis.BraceCompletion; internal interface IBraceCompletionService { /// <summary> /// Checks if this brace completion service should be the service used to provide brace completions at /// the specified position with the specified opening brace. /// /// Only one implementation of <see cref="IBraceCompletionService"/> should return true /// for a given brace, opening position, and document. Only that service will be asked /// for brace completion results. /// </summary> /// <param name="brace"> /// The opening brace character to be inserted at the opening position.</param> /// <param name="openingPosition"> /// The opening position to insert the brace. /// Note that the brace is not yet inserted at this position in the document. /// </param> /// <param name="document">The document to insert the brace at the position.</param> bool CanProvideBraceCompletion(char brace, int openingPosition, ParsedDocument document, CancellationToken cancellationToken); /// <summary> /// True if <see cref="BraceCompletionResult"/> is available in the given <paramref name="context"/>. /// Completes synchronously unless the service needs Semantic Model to determine the brace completion result. /// </summary> ValueTask<bool> HasBraceCompletionAsync(BraceCompletionContext context, Document document, CancellationToken cancellationToken); /// <summary> /// Returns the text change to add the closing brace given the context. /// </summary> BraceCompletionResult GetBraceCompletion(BraceCompletionContext braceCompletionContext); /// <summary> /// Returns any text changes that need to be made after adding the closing brace. /// </summary> /// <remarks> /// This cannot be merged with <see cref="GetBraceCompletion(BraceCompletionContext)"/> /// as we need to swap the editor tracking mode of the closing point from positive to negative /// in BraceCompletionSessionProvider.BraceCompletionSession.Start after completing the brace and before /// doing any kind of formatting on it. So these must be two distinct steps until we fully move to LSP. /// </remarks> BraceCompletionResult? GetTextChangesAfterCompletion(BraceCompletionContext braceCompletionContext, IndentationOptions options, CancellationToken cancellationToken); /// <summary> /// Get any text changes that should be applied after the enter key is typed inside a brace completion context. /// </summary> BraceCompletionResult? GetTextChangeAfterReturn(BraceCompletionContext braceCompletionContext, IndentationOptions options, CancellationToken cancellationToken); /// <summary> /// Returns the brace completion context if the caret is located between an already completed /// set of braces with only whitespace in between. /// </summary> BraceCompletionContext? GetCompletedBraceContext(ParsedDocument document, StructuredAnalyzerConfigOptions fallbackOptions, int caretLocation); /// <summary> /// Returns true if over typing should be allowed given the caret location and completed pair of braces. /// For example some providers allow over typing in non-user code and others do not. /// </summary> bool AllowOverType(BraceCompletionContext braceCompletionContext, CancellationToken cancellationToken); } internal readonly struct BraceCompletionResult(ImmutableArray<TextChange> textChanges, LinePosition caretLocation) { /// <summary> /// The set of text changes that should be applied to the input text to retrieve the /// brace completion result. /// </summary> public ImmutableArray<TextChange> TextChanges { get; } = textChanges; /// <summary> /// The caret location in the new text created by applying all <see cref="TextChanges"/> /// to the input text. Note the column in the line position can be virtual in that it points /// to a location in the line which does not actually contain whitespace. /// Hosts can determine how best to handle that virtual location. /// For example, placing the character in virtual space (when suppported) /// or inserting an appropriate number of spaces into the document". /// </summary> public LinePosition CaretLocation { get; } = caretLocation; } internal readonly struct BraceCompletionContext(ParsedDocument document, StructuredAnalyzerConfigOptions fallbackOptions, int openingPoint, int closingPoint, int caretLocation) { public ParsedDocument Document { get; } = document; public StructuredAnalyzerConfigOptions FallbackOptions { get; } = fallbackOptions; public int OpeningPoint { get; } = openingPoint; public int ClosingPoint { get; } = closingPoint; public int CaretLocation { get; } = caretLocation; public bool HasCompletionForOpeningBrace(char openingBrace) => ClosingPoint >= 1 && Document.Text[OpeningPoint] == openingBrace; public SyntaxToken GetOpeningToken() => Document.Root.FindToken(OpeningPoint, findInsideTrivia: true); }