/// <summary> /// Returns true when the current position is inside user code (e.g. not strings) and the closing token /// matches the expected closing token for this brace completion service. /// Helper method used by <see cref="AllowOverType(BraceCompletionContext, CancellationToken)"/> implementations. /// </summary> protected bool AllowOverTypeInUserCodeWithValidClosingToken(BraceCompletionContext context, CancellationToken cancellationToken) { var tree = context.Document.SyntaxTree; var syntaxFactsService = context.Document.LanguageServices.GetRequiredService <ISyntaxFactsService>(); return(!syntaxFactsService.IsInNonUserCode(tree, context.CaretLocation, cancellationToken) && CheckClosingTokenKind(context.Document, context.ClosingPoint)); }
/// <summary> /// Returns true when the closing token matches the expected closing token for this brace completion service. /// Used by <see cref="AllowOverTypeAsync(BraceCompletionContext, CancellationToken)"/> implementations /// when the over type could be triggered from outside of user code (e.g. overtyping end quotes in a string). /// </summary> protected Task <bool> AllowOverTypeWithValidClosingTokenAsync( BraceCompletionContext context, CancellationToken cancellationToken ) { return(CheckClosingTokenKindAsync( context.Document, context.ClosingPoint, cancellationToken )); }
public async Task <BraceCompletionResult?> GetBraceCompletionAsync( BraceCompletionContext braceCompletionContext, CancellationToken cancellationToken ) { var closingPoint = braceCompletionContext.ClosingPoint; if (closingPoint < 1) { return(null); } var openingPoint = braceCompletionContext.OpeningPoint; var document = braceCompletionContext.Document; var sourceText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); if (sourceText[openingPoint] != OpeningBrace) { return(null); } var root = await document .GetRequiredSyntaxRootAsync(cancellationToken) .ConfigureAwait(false); var token = root.FindToken(openingPoint, findInsideTrivia: true); var validOpeningPoint = await IsValidOpenBraceTokenAtPositionAsync( token, openingPoint, document, cancellationToken ) .ConfigureAwait(false); if (!validOpeningPoint) { return(null); } var braceTextEdit = new TextChange( TextSpan.FromBounds(closingPoint, closingPoint), ClosingBrace.ToString() ); // The caret location should be in between the braces. var originalOpeningLinePosition = sourceText.Lines.GetLinePosition(openingPoint); var caretLocation = new LinePosition( originalOpeningLinePosition.Line, originalOpeningLinePosition.Character + 1 ); return(new BraceCompletionResult(ImmutableArray.Create(braceTextEdit), caretLocation)); }
public async Task <BraceCompletionResult?> GetBraceCompletionAsync(BraceCompletionContext braceCompletionContext, CancellationToken cancellationToken) { var closingPoint = braceCompletionContext.ClosingPoint; if (closingPoint < 1) { return(null); } var openingPoint = braceCompletionContext.OpeningPoint; var document = braceCompletionContext.Document; var sourceText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); if (sourceText[openingPoint] != OpeningBrace) { return(null); } var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var token = root.FindToken(openingPoint, findInsideTrivia: true); if (NeedsSemantics) { // Pass along a document with frozen partial semantics. Brace completion is a highly latency sensitive // operation. We don't want to wait on things like source generators to figure things out. var validOpeningPoint = await IsValidOpenBraceTokenAtPositionAsync( document.WithFrozenPartialSemantics(cancellationToken), token, openingPoint, cancellationToken).ConfigureAwait(false); if (!validOpeningPoint) { return(null); } } else { var validOpeningPoint = IsValidOpenBraceTokenAtPosition(sourceText, token, openingPoint); if (!validOpeningPoint) { return(null); } } var braceTextEdit = new TextChange(TextSpan.FromBounds(closingPoint, closingPoint), ClosingBrace.ToString()); // The caret location should be in between the braces. var originalOpeningLinePosition = sourceText.Lines.GetLinePosition(openingPoint); var caretLocation = new LinePosition(originalOpeningLinePosition.Line, originalOpeningLinePosition.Character + 1); return(new BraceCompletionResult(ImmutableArray.Create(braceTextEdit), caretLocation)); }
public BraceCompletionResult GetBraceCompletion(BraceCompletionContext context) { Debug.Assert(context.HasCompletionForOpeningBrace(OpeningBrace)); var closingPoint = context.ClosingPoint; var braceTextEdit = new TextChange(TextSpan.FromBounds(closingPoint, closingPoint), ClosingBrace.ToString()); // The caret location should be in between the braces. var originalOpeningLinePosition = context.Document.Text.Lines.GetLinePosition(context.OpeningPoint); var caretLocation = new LinePosition(originalOpeningLinePosition.Line, originalOpeningLinePosition.Character + 1); return(new BraceCompletionResult(ImmutableArray.Create(braceTextEdit), caretLocation)); }
public Task <bool> HasBraceCompletionAsync(BraceCompletionContext context, Document document, CancellationToken cancellationToken) { if (!context.HasCompletionForOpeningBrace(OpeningBrace)) { return(Task.FromResult(false)); } var openingToken = context.GetOpeningToken(); if (!NeedsSemantics) { return(Task.FromResult(IsValidOpenBraceTokenAtPosition(context.Document.Text, openingToken, context.OpeningPoint))); } // Pass along a document with frozen partial semantics. Brace completion is a highly latency sensitive // operation. We don't want to wait on things like source generators to figure things out. return(IsValidOpenBraceTokenAtPositionAsync(document.WithFrozenPartialSemantics(cancellationToken), openingToken, context.OpeningPoint, cancellationToken)); }
/// <summary> /// Returns true when the current position is inside user code (e.g. not strings) and the closing token /// matches the expected closing token for this brace completion service. /// Helper method used by <see cref="AllowOverTypeAsync(BraceCompletionContext, CancellationToken)"/> implementations. /// </summary> protected async Task <bool> AllowOverTypeInUserCodeWithValidClosingTokenAsync( BraceCompletionContext context, CancellationToken cancellationToken ) { var tree = await context.Document .GetRequiredSyntaxTreeAsync(cancellationToken) .ConfigureAwait(false); var syntaxFactsService = context.Document.GetRequiredLanguageService <ISyntaxFactsService>(); return(!syntaxFactsService.IsInNonUserCode( tree, context.CaretLocation, cancellationToken ) && await CheckClosingTokenKindAsync( context.Document, context.ClosingPoint, cancellationToken ) .ConfigureAwait(false)); }
public virtual Task <BraceCompletionResult?> GetTextChangeAfterReturnAsync(BraceCompletionContext braceCompletionContext, IndentationOptions options, CancellationToken cancellationToken) => SpecializedTasks.Default <BraceCompletionResult?>();
public abstract Task <bool> AllowOverTypeAsync(BraceCompletionContext braceCompletionContext, CancellationToken cancellationToken);
public virtual Task <BraceCompletionResult?> GetTextChangesAfterCompletionAsync( BraceCompletionContext braceCompletionContext, CancellationToken cancellationToken ) => SpecializedTasks.Default <BraceCompletionResult?>();
public virtual BraceCompletionResult?GetTextChangeAfterReturn(BraceCompletionContext braceCompletionContext, IndentationOptions options, CancellationToken cancellationToken) => null;
public abstract bool AllowOverType(BraceCompletionContext braceCompletionContext, CancellationToken cancellationToken);
/// <summary> /// Returns true when the closing token matches the expected closing token for this brace completion service. /// Used by <see cref="AllowOverType(BraceCompletionContext, CancellationToken)"/> implementations /// when the over type could be triggered from outside of user code (e.g. overtyping end quotes in a string). /// </summary> protected bool AllowOverTypeWithValidClosingToken(BraceCompletionContext context) { return(CheckClosingTokenKind(context.Document, context.ClosingPoint)); }