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

Formatting and code generation options #60127

Merged
merged 14 commits into from
Apr 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
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
11 changes: 11 additions & 0 deletions eng/config/BannedSymbols.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,14 @@ M:Microsoft.VisualStudio.Shell.ServiceExtensions.GetService``2(System.IServicePr
M:Microsoft.VisualStudio.Shell.ServiceExtensions.GetServiceAsync``2(Microsoft.VisualStudio.Shell.IAsyncServiceProvider); Use RoslynServiceExtensions instead. This extension internally relies on ThreadHelper, which is incompatible with testing
M:Microsoft.VisualStudio.Shell.ServiceExtensions.GetServiceAsync``2(Microsoft.VisualStudio.Shell.IAsyncServiceProvider,System.Boolean); Use RoslynServiceExtensions instead. This extension internally relies on ThreadHelper, which is incompatible with testing
P:Microsoft.VisualStudio.Shell.ThreadHelper.JoinableTaskFactory; Use IThreadingContext.JoinableTaskFactory instead.
M:Microsoft.CodeAnalysis.Formatting.Formatter.FormatAsync(Microsoft.CodeAnalysis.Document,Microsoft.CodeAnalysis.Options.OptionSet,System.Threading.CancellationToken); Use internal overload instead
M:Microsoft.CodeAnalysis.Formatting.Formatter.FormatAsync(Microsoft.CodeAnalysis.Document,Microsoft.CodeAnalysis.Text.TextSpan,Microsoft.CodeAnalysis.Options.OptionSet,System.Threading.CancellationToken); Use overload with SyntaxFormattingOptions instead
M:Microsoft.CodeAnalysis.Formatting.Formatter.FormatAsync(Microsoft.CodeAnalysis.Document,System.Collections.Generic.IEnumerable{Microsoft.CodeAnalysis.Text.TextSpan},Microsoft.CodeAnalysis.Options.OptionSet,System.Threading.CancellationToken); Use overload with SyntaxFormattingOptions instead
M:Microsoft.CodeAnalysis.Formatting.Formatter.FormatAsync(Microsoft.CodeAnalysis.Document,Microsoft.CodeAnalysis.SyntaxAnnotation,Microsoft.CodeAnalysis.Options.OptionSet,System.Threading.CancellationToken); Use overload with SyntaxFormattingOptions instead
M:Microsoft.CodeAnalysis.Formatting.Formatter.Format(Microsoft.CodeAnalysis.SyntaxNode,Microsoft.CodeAnalysis.SyntaxAnnotation,Microsoft.CodeAnalysis.Workspace,Microsoft.CodeAnalysis.Options.OptionSet,System.Threading.CancellationToken); Use overload with SyntaxFormattingOptions instead
M:Microsoft.CodeAnalysis.Formatting.Formatter.Format(Microsoft.CodeAnalysis.SyntaxNode,Microsoft.CodeAnalysis.Workspace,Microsoft.CodeAnalysis.Options.OptionSet,System.Threading.CancellationToken); Use overload with SyntaxFormattingOptions instead
M:Microsoft.CodeAnalysis.Formatting.Formatter.Format(Microsoft.CodeAnalysis.SyntaxNode,Microsoft.CodeAnalysis.Text.TextSpan,Microsoft.CodeAnalysis.Workspace,Microsoft.CodeAnalysis.Options.OptionSet,System.Threading.CancellationToken); Use overload with SyntaxFormattingOptions instead
M:Microsoft.CodeAnalysis.Formatting.Formatter.Format(Microsoft.CodeAnalysis.SyntaxNode,System.Collections.Generic.IEnumerable{Microsoft.CodeAnalysis.Text.TextSpan},Microsoft.CodeAnalysis.Workspace,Microsoft.CodeAnalysis.Options.OptionSet,System.Threading.CancellationToken); Use overload with SyntaxFormattingOptions instead
M:Microsoft.CodeAnalysis.Formatting.Formatter.GetFormattedTextChanges(Microsoft.CodeAnalysis.SyntaxNode,Microsoft.CodeAnalysis.Workspace,Microsoft.CodeAnalysis.Options.OptionSet,System.Threading.CancellationToken); Use overload with SyntaxFormattingOptions instead
M:Microsoft.CodeAnalysis.Formatting.Formatter.GetFormattedTextChanges(Microsoft.CodeAnalysis.SyntaxNode,Microsoft.CodeAnalysis.Text.TextSpan,Microsoft.CodeAnalysis.Workspace,Microsoft.CodeAnalysis.Options.OptionSet,System.Threading.CancellationToken); Use overload with SyntaxFormattingOptions instead
M:Microsoft.CodeAnalysis.Formatting.Formatter.GetFormattedTextChanges(Microsoft.CodeAnalysis.SyntaxNode,System.Collections.Generic.IEnumerable{Microsoft.CodeAnalysis.Text.TextSpan},Microsoft.CodeAnalysis.Workspace,Microsoft.CodeAnalysis.Options.OptionSet,System.Threading.CancellationToken); Use overload with SyntaxFormattingOptions instead
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
using System.Composition;
using System.Diagnostics.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp.Formatting;
using Microsoft.CodeAnalysis.Formatting;
using Microsoft.CodeAnalysis.RemoveUnnecessaryImports;

namespace Microsoft.CodeAnalysis.CSharp.RemoveUnnecessaryImports
Expand All @@ -23,5 +25,8 @@ public CSharpRemoveUnnecessaryImportsCodeFixProvider()

protected override string GetTitle()
=> CSharpCodeFixesResources.Remove_Unnecessary_Usings;

protected override ISyntaxFormatting GetSyntaxFormatting()
=> CSharpSyntaxFormatting.Instance;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.Formatting;
using Microsoft.CodeAnalysis.Shared.Extensions;

namespace Microsoft.CodeAnalysis.RemoveUnnecessaryImports
{
internal abstract class AbstractRemoveUnnecessaryImportsCodeFixProvider : CodeFixProvider
{
protected abstract ISyntaxFormatting GetSyntaxFormatting();

public sealed override ImmutableArray<string> FixableDiagnosticIds
=> ImmutableArray.Create(AbstractRemoveUnnecessaryImportsDiagnosticAnalyzer.DiagnosticFixableId);

Expand All @@ -34,11 +37,22 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context)

protected abstract string GetTitle();

private static Task<Document> RemoveUnnecessaryImportsAsync(
Document document, CancellationToken cancellationToken)
#if CODE_STYLE
private async Task<Document> RemoveUnnecessaryImportsAsync(
#else
private static async Task<Document> RemoveUnnecessaryImportsAsync(
#endif
Document document,
CancellationToken cancellationToken)
{
#if CODE_STYLE
var syntaxTree = await document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
var formattingOptions = GetSyntaxFormatting().GetFormattingOptions(document.Project.AnalyzerOptions.AnalyzerConfigOptionsProvider.GetOptions(syntaxTree));
#else
var formattingOptions = await SyntaxFormattingOptions.FromDocumentAsync(document, cancellationToken).ConfigureAwait(false);
#endif
var service = document.GetRequiredLanguageService<IRemoveUnnecessaryImportsService>();
return service.RemoveUnnecessaryImportsAsync(document, cancellationToken);
return await service.RemoveUnnecessaryImportsAsync(document, formattingOptions, cancellationToken).ConfigureAwait(false);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
Imports System.Composition
Imports System.Diagnostics.CodeAnalysis
Imports Microsoft.CodeAnalysis.CodeFixes
Imports Microsoft.CodeAnalysis.Formatting
Imports Microsoft.CodeAnalysis.RemoveUnnecessaryImports
Imports Microsoft.CodeAnalysis.VisualBasic.Formatting

Namespace Microsoft.CodeAnalysis.VisualBasic.RemoveUnnecessaryImports

Expand All @@ -22,5 +24,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.RemoveUnnecessaryImports
Protected Overrides Function GetTitle() As String
Return VisualBasicCodeFixesResources.Remove_Unnecessary_Imports
End Function

Protected Overrides Function GetSyntaxFormatting() As ISyntaxFormatting
Return VisualBasicSyntaxFormatting.Instance
End Function
End Class
End Namespace
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,8 @@ protected override void ModifySelectedNode(
CancellationToken cancellationToken)
{
var root = document.GetRequiredSyntaxRootSynchronously(cancellationToken);
var documentOptions = document.GetOptionsAsync(cancellationToken).WaitAndGetResult(cancellationToken);
var formattingOptions = SyntaxFormattingOptions.FromDocumentAsync(document, cancellationToken).WaitAndGetResult(cancellationToken);

// Add braces for the selected node
if (addBrace)
{
Expand All @@ -350,7 +351,7 @@ or IfStatementSyntax
or ElseClauseSyntax)
{
// Add the braces and get the next caretPosition
var (newRoot, nextCaretPosition) = AddBraceToSelectedNode(document, root, selectedNode, documentOptions, cancellationToken);
var (newRoot, nextCaretPosition) = AddBraceToSelectedNode(document, root, selectedNode, formattingOptions, cancellationToken);
if (document.Project.Solution.Workspace.TryApplyChanges(document.WithSyntaxRoot(newRoot).Project.Solution))
{
args.TextView.TryMoveCaretToAndEnsureVisible(new SnapshotPoint(args.SubjectBuffer.CurrentSnapshot, nextCaretPosition));
Expand All @@ -375,7 +376,7 @@ or IfStatementSyntax
var insertionPosition = GetBraceInsertionPosition(selectedNode);

// 2. Insert the braces and move caret
InsertBraceAndMoveCaret(args.TextView, document, documentOptions, insertionPosition, cancellationToken);
InsertBraceAndMoveCaret(args.TextView, document, formattingOptions, insertionPosition, cancellationToken);
}
}
else
Expand All @@ -385,7 +386,7 @@ or IfStatementSyntax
document,
root,
selectedNode,
documentOptions,
formattingOptions,
cancellationToken);

if (document.Project.Solution.Workspace.TryApplyChanges(document.WithSyntaxRoot(newRoot).Project.Solution))
Expand All @@ -399,7 +400,7 @@ private static (SyntaxNode newRoot, int nextCaretPosition) AddBraceToSelectedNod
Document document,
SyntaxNode root,
SyntaxNode selectedNode,
DocumentOptionSet documentOptions,
SyntaxFormattingOptions formattingOptions,
CancellationToken cancellationToken)
{
// For these nodes, directly modify the node and replace it.
Expand All @@ -414,7 +415,7 @@ or EventFieldDeclarationSyntax
document,
root,
selectedNode,
WithBraces(selectedNode, documentOptions),
WithBraces(selectedNode, formattingOptions),
cancellationToken);
// Locate the open brace token, and move the caret after it.
var nextCaretPosition = GetOpenBraceSpanEnd(newRoot);
Expand All @@ -428,7 +429,7 @@ or EventFieldDeclarationSyntax
// var c = new Obje$$ct() => var c = new Object();
if (selectedNode is ObjectCreationExpressionSyntax objectCreationExpressionNode)
{
var (newNode, oldNode) = ModifyObjectCreationExpressionNode(objectCreationExpressionNode, addOrRemoveInitializer: true, documentOptions);
var (newNode, oldNode) = ModifyObjectCreationExpressionNode(objectCreationExpressionNode, addOrRemoveInitializer: true, formattingOptions);
var newRoot = ReplaceNodeAndFormat(
document,
root,
Expand Down Expand Up @@ -480,7 +481,7 @@ or EventFieldDeclarationSyntax
// In this case 'Print("Bar")' is considered as the innerStatement so when we inserted the empty block, we need also insert that
if (selectedNode.IsEmbeddedStatementOwner())
{
return AddBraceToEmbeddedStatementOwner(document, root, selectedNode, documentOptions, cancellationToken);
return AddBraceToEmbeddedStatementOwner(document, root, selectedNode, formattingOptions, cancellationToken);
}

throw ExceptionUtilities.UnexpectedValue(selectedNode);
Expand All @@ -490,7 +491,7 @@ private static (SyntaxNode newRoot, int nextCaretPosition) RemoveBraceFromSelect
Document document,
SyntaxNode root,
SyntaxNode selectedNode,
DocumentOptionSet documentOptions,
SyntaxFormattingOptions formattingOptions,
CancellationToken cancellationToken)
{
// Remove the initializer from ObjectCreationExpression
Expand All @@ -504,7 +505,7 @@ private static (SyntaxNode newRoot, int nextCaretPosition) RemoveBraceFromSelect
// e.g. var c = new Bar() => var c = new Bar();
if (selectedNode is BaseObjectCreationExpressionSyntax objectCreationExpressionNode)
{
var (newNode, oldNode) = ModifyObjectCreationExpressionNode(objectCreationExpressionNode, addOrRemoveInitializer: false, documentOptions);
var (newNode, oldNode) = ModifyObjectCreationExpressionNode(objectCreationExpressionNode, addOrRemoveInitializer: false, formattingOptions);
var newRoot = ReplaceNodeAndFormat(
document,
root,
Expand Down Expand Up @@ -634,19 +635,19 @@ private static bool IsTokenPartOfExpression(SyntaxToken syntaxToken)
return !syntaxToken.GetAncestors<ExpressionSyntax>().IsEmpty();
}

private static string GetBracePairString(DocumentOptionSet documentOptions)
private static string GetBracePairString(SyntaxFormattingOptions formattingOptions)
=> string.Concat(SyntaxFacts.GetText(SyntaxKind.OpenBraceToken),
documentOptions.GetOption(FormattingOptions2.NewLine),
formattingOptions.NewLine,
SyntaxFacts.GetText(SyntaxKind.CloseBraceToken));

private void InsertBraceAndMoveCaret(
ITextView textView,
Document document,
DocumentOptionSet documentOptions,
SyntaxFormattingOptions formattingOptions,
int insertionPosition,
CancellationToken cancellationToken)
{
var bracePair = GetBracePairString(documentOptions);
var bracePair = GetBracePairString(formattingOptions);

// 1. Insert { }.
var newDocument = document.InsertText(insertionPosition, bracePair, cancellationToken);
Expand Down
Loading