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

Avoid accessing Document from formatter services #61928

Merged
merged 4 commits into from
Jun 16, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ public async Task<ImmutableArray<TextChange>> GetFormattingChangesOnPasteAsync(D
var fallbackOptions = _globalOptions.GetCSharpSyntaxFormattingOptions();
var options = await _indentationManager.GetInferredFormattingOptionsAsync(document, fallbackOptions, explicitFormat: true, cancellationToken).ConfigureAwait(false);
var service = document.GetRequiredLanguageService<ISyntaxFormattingService>();
return await service.GetFormattingChangesOnPasteAsync(document, textSpan, options, cancellationToken).ConfigureAwait(false);
var documentSyntax = await DocumentSyntax.CreateAsync(document, cancellationToken).ConfigureAwait(false);
return service.GetFormattingChangesOnPaste(documentSyntax, textSpan, options, cancellationToken);
}

Task<ImmutableArray<TextChange>> IFormattingInteractionService.GetFormattingChangesOnReturnAsync(
Expand All @@ -117,8 +118,9 @@ Task<ImmutableArray<TextChange>> IFormattingInteractionService.GetFormattingChan
public async Task<ImmutableArray<TextChange>> GetFormattingChangesAsync(Document document, char typedChar, int position, CancellationToken cancellationToken)
{
var service = document.GetRequiredLanguageService<ISyntaxFormattingService>();
var documentSyntax = await DocumentSyntax.CreateAsync(document, cancellationToken).ConfigureAwait(false);

if (await service.ShouldFormatOnTypedCharacterAsync(document, typedChar, position, cancellationToken).ConfigureAwait(false))
if (service.ShouldFormatOnTypedCharacter(documentSyntax, typedChar, position, cancellationToken))
{
var fallbackOptions = _globalOptions.GetCSharpSyntaxFormattingOptions();
var formattingOptions = await _indentationManager.GetInferredFormattingOptionsAsync(document, fallbackOptions, explicitFormat: false, cancellationToken).ConfigureAwait(false);
Expand All @@ -129,7 +131,7 @@ public async Task<ImmutableArray<TextChange>> GetFormattingChangesAsync(Document
IndentStyle = _globalOptions.GetOption(IndentationOptionsStorage.SmartIndent, LanguageNames.CSharp)
};

return await service.GetFormattingChangesOnTypedCharacterAsync(document, position, indentationOptions, cancellationToken).ConfigureAwait(false);
return service.GetFormattingChangesOnTypedCharacter(documentSyntax, position, indentationOptions, cancellationToken);
}

return ImmutableArray<TextChange>.Empty;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,20 +72,20 @@ protected static async Task<string> TokenFormatAsync(
private static async Task TokenFormatWorkerAsync(TestWorkspace workspace, ITextBuffer buffer, int indentationLine, char ch, bool useTabs)
{
var document = buffer.CurrentSnapshot.GetRelatedDocumentsWithChanges().First();
var root = (CompilationUnitSyntax)await document.GetSyntaxRootAsync();
var documentSyntax = await DocumentSyntax.CreateAsync(document, CancellationToken.None);

var line = root.GetText().Lines[indentationLine];
var line = documentSyntax.Text.Lines[indentationLine];

var index = line.ToString().LastIndexOf(ch);
Assert.InRange(index, 0, int.MaxValue);

// get token
var position = line.Start + index;
var token = root.FindToken(position);
var token = documentSyntax.Root.FindToken(position);

var formattingRuleProvider = workspace.Services.GetService<IHostDependentFormattingRuleFactoryService>();

var rules = ImmutableArray.Create(formattingRuleProvider.CreateRule(document, position)).AddRange(Formatter.GetDefaultFormattingRules(document));
var rules = ImmutableArray.Create(formattingRuleProvider.CreateRule(documentSyntax, position)).AddRange(Formatter.GetDefaultFormattingRules(document));

var options = new IndentationOptions(
new CSharpSyntaxFormattingOptions
Expand All @@ -96,8 +96,8 @@ private static async Task TokenFormatWorkerAsync(TestWorkspace workspace, ITextB
}
});

var formatter = new CSharpSmartTokenFormatter(options, rules, root);
var changes = await formatter.FormatTokenAsync(token, CancellationToken.None);
var formatter = new CSharpSmartTokenFormatter(options, rules, (CompilationUnitSyntax)documentSyntax.Root, documentSyntax.Text);
var changes = formatter.FormatToken(token, CancellationToken.None);

ApplyChanges(buffer, changes);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3576,6 +3576,7 @@ private static async Task AutoFormatOnMarkerAsync(string initialMarkup, string e
var position = testDocument.CursorPosition.Value;

var document = workspace.CurrentSolution.GetDocument(testDocument.Id);
var documentSyntax = await DocumentSyntax.CreateAsync(document, CancellationToken.None);
var rules = Formatter.GetDefaultFormattingRules(document);

var root = (CompilationUnitSyntax)await document.GetSyntaxRootAsync();
Expand All @@ -3590,7 +3591,7 @@ private static async Task AutoFormatOnMarkerAsync(string initialMarkup, string e
var options = new IndentationOptions(
CSharpSyntaxFormattingOptions.Default.With(new LineFormattingOptions { UseTabs = useTabs }));

var formatter = new CSharpSmartTokenFormatter(options, rules, root);
var formatter = new CSharpSmartTokenFormatter(options, rules, (CompilationUnitSyntax)documentSyntax.Root, documentSyntax.Text);

var tokenRange = FormattingRangeHelper.FindAppropriateRange(endToken);
if (tokenRange == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ private void ExecuteCommandWorker(PasteCommandArgs args, SnapshotPoint? caretPos

var services = solution.Workspace.Services;
var formattingRuleService = services.GetService<IHostDependentFormattingRuleFactoryService>();
if (formattingRuleService != null && formattingRuleService.ShouldNotFormatOrCommitOnPaste(document))
if (formattingRuleService != null && formattingRuleService.ShouldNotFormatOrCommitOnPaste(document.Id))
{
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ private static void ApplyChanges(Document document, IList<TextChange> changes, T
{
var ruleFactory = document.Project.Solution.Workspace.Services.GetRequiredService<IHostDependentFormattingRuleFactoryService>();

changes = ruleFactory.FilterFormattedChanges(document, selectionOpt.Value, changes).ToList();
changes = ruleFactory.FilterFormattedChanges(document.Id, selectionOpt.Value, changes).ToList();
if (changes.Count == 0)
{
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ public static void FormatAndApplyToBuffer(this ITextSnapshot snapshot, TextSpan
return;
}

var rules = document.GetFormattingRules(span, additionalRules: null);
var documentSyntax = DocumentSyntax.CreateSynchronously(document, cancellationToken);
var rules = FormattingRuleUtilities.GetFormattingRules(documentSyntax, document.Project.LanguageServices, span, additionalRules: null);

var root = document.GetRequiredSyntaxRootSynchronously(cancellationToken);
var formatter = document.GetRequiredLanguageService<ISyntaxFormattingService>();

var options = document.GetSyntaxFormattingOptionsAsync(globalOptions, cancellationToken).AsTask().WaitAndGetResult(cancellationToken);
var result = formatter.GetFormattingResult(root, SpecializedCollections.SingletonEnumerable(span), options, rules, cancellationToken);
var result = formatter.GetFormattingResult(documentSyntax.Root, SpecializedCollections.SingletonEnumerable(span), options, rules, cancellationToken);
var changes = result.GetTextChanges(cancellationToken);

using (Logger.LogBlock(FunctionId.Formatting_ApplyResultToBuffer, cancellationToken))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ private protected async Task AssertFormatAsync(string expected, string code, IEn
var buffer = hostdoc.GetTextBuffer();

var document = workspace.CurrentSolution.GetDocument(hostdoc.Id);
var syntaxTree = await document.GetSyntaxTreeAsync();
var documentSyntax = await DocumentSyntax.CreateAsync(document, CancellationToken.None).ConfigureAwait(false);

// create new buffer with cloned content
var clonedBuffer = EditorFactory.CreateBuffer(
Expand All @@ -195,23 +195,20 @@ private protected async Task AssertFormatAsync(string expected, string code, IEn
{
var factory = (TestFormattingRuleFactoryServiceFactory.Factory)formattingRuleProvider;
factory.BaseIndentation = baseIndentation.Value;
factory.TextSpan = spans?.First() ?? syntaxTree.GetRoot(CancellationToken.None).FullSpan;
factory.TextSpan = spans?.First() ?? documentSyntax.Root.FullSpan;
}

var root = await syntaxTree.GetRootAsync();

var formattingService = document.GetRequiredLanguageService<ISyntaxFormattingService>();

var formattingOptions = (options != null) ?
formattingService.GetFormattingOptions(options.ToAnalyzerConfigOptions(document.Project.LanguageServices), fallbackOptions: null) :
formattingService.DefaultOptions;

document = workspace.CurrentSolution.GetDocument(syntaxTree);
var rules = formattingRuleProvider.CreateRule(document, 0).Concat(Formatter.GetDefaultFormattingRules(document));
AssertFormat(workspace, expected, formattingOptions, rules, clonedBuffer, root, spans);
var rules = formattingRuleProvider.CreateRule(documentSyntax, 0).Concat(Formatter.GetDefaultFormattingRules(document));
AssertFormat(workspace, expected, formattingOptions, rules, clonedBuffer, documentSyntax.Root, spans);

// format with node and transform
AssertFormatWithTransformation(workspace, expected, formattingOptions, rules, root, spans);
AssertFormatWithTransformation(workspace, expected, formattingOptions, rules, documentSyntax.Root, spans);
}

internal void AssertFormatWithTransformation(Workspace workspace, string expected, SyntaxFormattingOptions options, IEnumerable<AbstractFormattingRule> rules, SyntaxNode root, IEnumerable<TextSpan> spans)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,25 +35,24 @@ public sealed class Factory : IHostDependentFormattingRuleFactoryService
public TextSpan TextSpan = default;
public bool UseBaseIndentation = false;

public bool ShouldUseBaseIndentation(Document document)
public bool ShouldUseBaseIndentation(DocumentId documentId)
=> UseBaseIndentation;

public AbstractFormattingRule CreateRule(Document document, int position)
public bool ShouldNotFormatOrCommitOnPaste(DocumentId documentId)
=> UseBaseIndentation;

public AbstractFormattingRule CreateRule(DocumentSyntax document, int position)
{
if (BaseIndentation == 0)
{
return NoOpFormattingRule.Instance;
}

var root = document.GetSyntaxRootAsync().Result;
return new BaseIndentationFormattingRule(root, TextSpan, BaseIndentation + 4);
return new BaseIndentationFormattingRule(document.Root, TextSpan, BaseIndentation + 4);
}

public IEnumerable<TextChange> FilterFormattedChanges(Document document, TextSpan span, IList<TextChange> changes)
public IEnumerable<TextChange> FilterFormattedChanges(DocumentId document, TextSpan span, IList<TextChange> changes)
=> changes;

public bool ShouldNotFormatOrCommitOnPaste(Document document)
=> UseBaseIndentation;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.LineCommit
Dim document = args.SubjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges()
If document IsNot Nothing Then
Dim formattingRuleService = document.Project.Solution.Workspace.Services.GetService(Of IHostDependentFormattingRuleFactoryService)()
If formattingRuleService.ShouldNotFormatOrCommitOnPaste(document) Then
If formattingRuleService.ShouldNotFormatOrCommitOnPaste(document.Id) Then
transaction.Complete()
Return
End If
Expand Down
Loading