提交 2b9d5352 编写于 作者: C Cyrus Najmabadi

Add feature to suggest moving to simplified using statements

上级 c1bf7a51
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Composition;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.Formatting;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.UseSimpleUsingDeclaration
{
[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(UseSimpleUsingStatementCodeFixProvider)), Shared]
internal class UseSimpleUsingStatementCodeFixProvider : SyntaxEditorBasedCodeFixProvider
{
public override ImmutableArray<string> FixableDiagnosticIds { get; } =
ImmutableArray.Create(IDEDiagnosticIds.UseSimpleUsingStatementDiagnosticId);
public override Task RegisterCodeFixesAsync(CodeFixContext context)
{
context.RegisterCodeFix(new MyCodeAction(
c => FixAsync(context.Document, context.Diagnostics[0], c)),
context.Diagnostics);
return Task.CompletedTask;
}
protected override Task FixAllAsync(
Document document, ImmutableArray<Diagnostic> diagnostics,
SyntaxEditor editor, CancellationToken cancellationToken)
{
var usingStatements = diagnostics.Select(d => (UsingStatementSyntax)d.AdditionalLocations[0].FindNode(cancellationToken)).ToSet();
var rewriter = new Rewriter(usingStatements);
var root = editor.OriginalRoot;
var updatedRoot = rewriter.Visit(root);
editor.ReplaceNode(root, updatedRoot);
return Task.CompletedTask;
}
private class Rewriter : CSharpSyntaxRewriter
{
private readonly ISet<UsingStatementSyntax> _usingStatements;
public Rewriter(ISet<UsingStatementSyntax> usingStatements)
{
_usingStatements = usingStatements;
}
private static SyntaxList<StatementSyntax> Expand(UsingStatementSyntax usingStatement)
{
var builder = ArrayBuilder<StatementSyntax>.GetInstance();
builder.Add(Convert(usingStatement));
if (usingStatement.Statement is BlockSyntax block)
{
builder.AddRange(block.Statements);
}
else
{
builder.Add(usingStatement.Statement);
}
var statements = new SyntaxList<StatementSyntax>(builder);
builder.Free();
return statements;
}
private bool ShouldExpand(StatementSyntax beforeStatement, StatementSyntax afterStatement)
=> _usingStatements.Contains(beforeStatement) &&
afterStatement is UsingStatementSyntax usingStatement &&
usingStatement.Declaration != null;
private static LocalDeclarationStatementSyntax Convert(UsingStatementSyntax usingStatement)
{
return SyntaxFactory.LocalDeclarationStatement(
usingStatement.AwaitKeyword,
usingStatement.UsingKeyword,
modifiers: default,
usingStatement.Declaration,
SyntaxFactory.Token(SyntaxKind.SemicolonToken));
}
public override SyntaxNode VisitElseClause(ElseClauseSyntax node)
{
// First, descend into the else-clause so we fixup any using statements contained
// inside of it.
var rewrittenElse = (ElseClauseSyntax)base.VisitElseClause(node);
// Now, if the else-clause previous pointed at a using statement we wanted to
// rewrite, and it still points at a using statement, then expand that using
// statemnet into the else-clause.
var rewrittenStatement = rewrittenElse.Statement;
if (ShouldExpand(node.Statement, rewrittenStatement))
{
// Can't expand a using-statement directly inside an else-clause.
// have to add a block around it to make sure scoping is preserved
// properly.
var expanded = Expand((UsingStatementSyntax)rewrittenStatement);
return rewrittenElse.WithStatement(SyntaxFactory.Block(expanded))
.WithAdditionalAnnotations(Formatter.Annotation);
}
return rewrittenElse;
}
private bool ExpandAppropriateStatements(
SyntaxList<StatementSyntax> originalStatements,
SyntaxList<StatementSyntax> rewrittenStatements,
ArrayBuilder<StatementSyntax> finalStatements)
{
var changed = false;
if (originalStatements.Count == rewrittenStatements.Count)
{
for (int i = 0, n = rewrittenStatements.Count; i < n; i++)
{
var rewrittenStatement = rewrittenStatements[i];
if (ShouldExpand(originalStatements[i], rewrittenStatement))
{
var expanded = Expand((UsingStatementSyntax)rewrittenStatement);
finalStatements.AddRange(expanded);
changed = true;
}
else
{
finalStatements.Add(rewrittenStatement);
}
}
}
return changed;
}
public override SyntaxNode VisitBlock(BlockSyntax node)
{
var finalStatements = ArrayBuilder<StatementSyntax>.GetInstance();
var result = VisitBlockWorker(node, finalStatements);
finalStatements.Free();
return result;
}
private SyntaxNode VisitBlockWorker(BlockSyntax node, ArrayBuilder<StatementSyntax> finalStatements)
{
var rewrittenBlock = (BlockSyntax)base.VisitBlock(node);
var changed = ExpandAppropriateStatements(node.Statements, rewrittenBlock.Statements, finalStatements);
if (!changed)
{
// Didn't update any children. Just return as is.
return rewrittenBlock;
}
return rewrittenBlock.WithStatements(new SyntaxList<StatementSyntax>(finalStatements))
.WithAdditionalAnnotations(Formatter.Annotation);
}
public override SyntaxNode VisitSwitchSection(SwitchSectionSyntax node)
{
var finalStatements = ArrayBuilder<StatementSyntax>.GetInstance();
var result = VisitSwitchSectionWorker(node, finalStatements);
finalStatements.Free();
return result;
}
private SyntaxNode VisitSwitchSectionWorker(SwitchSectionSyntax node, ArrayBuilder<StatementSyntax> finalStatements)
{
var rewrittenSwitchSection = (SwitchSectionSyntax)base.VisitSwitchSection(node);
var changed = ExpandAppropriateStatements(node.Statements, rewrittenSwitchSection.Statements, finalStatements);
if (!changed)
{
// Didn't update any children. Just return as is.
return rewrittenSwitchSection;
}
return rewrittenSwitchSection.WithStatements(new SyntaxList<StatementSyntax>(finalStatements))
.WithAdditionalAnnotations(Formatter.Annotation);
}
}
private class MyCodeAction : CodeAction.DocumentChangeAction
{
public MyCodeAction(Func<CancellationToken, Task<Document>> createChangedDocument)
: base(FeaturesResources.Use_simple_using_statement, createChangedDocument, FeaturesResources.Use_simple_using_statement)
{
}
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Immutable;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.UseSimpleUsingStatement
{
[DiagnosticAnalyzer(LanguageNames.CSharp)]
internal class UseSimpleUsingStatementDiagnosticAnalyzer : AbstractBuiltInCodeStyleDiagnosticAnalyzer
{
public UseSimpleUsingStatementDiagnosticAnalyzer()
: base(IDEDiagnosticIds.UseSimpleUsingStatementDiagnosticId,
new LocalizableResourceString(nameof(FeaturesResources.Use_simple_using_statement), FeaturesResources.ResourceManager, typeof(FeaturesResources)),
new LocalizableResourceString(nameof(FeaturesResources.using_statment_can_be_simplified), FeaturesResources.ResourceManager, typeof(FeaturesResources)))
{
}
public override bool OpenFileOnly(Workspace workspace) => false;
public override DiagnosticAnalyzerCategory GetAnalyzerCategory()
=> DiagnosticAnalyzerCategory.SemanticSpanAnalysis;
protected override void InitializeWorker(AnalysisContext context)
=> context.RegisterSyntaxNodeAction(AnalyzeSyntax, SyntaxKind.UsingStatement);
private void AnalyzeSyntax(SyntaxNodeAnalysisContext context)
{
var usingStatement = (UsingStatementSyntax)context.Node;
if (usingStatement.Declaration == null)
{
return;
}
var syntaxTree = context.Node.SyntaxTree;
//var options = (CSharpParseOptions)syntaxTree.Options;
//if (options.LanguageVersion < LanguageVersion.CSharp8)
//{
// return;
//}
var cancellationToken = context.CancellationToken;
var optionSet = context.Options.GetDocumentOptionSetAsync(syntaxTree, cancellationToken).GetAwaiter().GetResult();
if (optionSet == null)
{
return;
}
var option = optionSet.GetOption(CSharpCodeStyleOptions.PreferStaticLocalFunction);
if (!option.Value)
{
return;
}
var parent = usingStatement.Parent;
var okParent = parent is BlockSyntax ||
parent is SwitchSectionSyntax;
if (!okParent)
{
return;
}
// Has to be one of the following forms:
// 1. Using statement is the last statement in the parent.
// 2. Using statement is not the last statment in parent, but is followed by
// something that is unaffected by simplifying the using statement. i.e.
// `return`/`break`/`continue`. *Note*. `return expr` would *not* be ok.
// In that case, `expr` would now be evaluated *before* the using disposed
// the resource, instead of afterwards. Effectly, the statement following
// cannot actually execute any code that might depend on the .Dispose method
// being called or not.
var statements = GetStatements(parent, usingStatement);
if (CanConvertUsingStatement(statements, usingStatement))
{
context.ReportDiagnostic(DiagnosticHelper.Create(
Descriptor,
usingStatement.UsingKeyword.GetLocation(),
option.Notification.Severity,
additionalLocations: ImmutableArray.Create(usingStatement.GetLocation()),
properties: null));
}
}
private bool CanConvertUsingStatement(
SyntaxList<StatementSyntax> statements,
UsingStatementSyntax usingStatement)
{
var index = statements.IndexOf(usingStatement);
if (index == statements.Count - 1)
{
// very last statement in the block. Can be converted.
return true;
}
// Not the last statement, get the next statement and examine that.
var nextStatement = statements[index + 1];
if (nextStatement is BreakStatementSyntax ||
nextStatement is ContinueStatementSyntax)
{
// using statemnet followed by break/continue. Can conver this as executing
// the break/continue will cause the code to exit the using scope, causing
// Dispose to be called at the same place as before.
return true;
}
if (nextStatement is ReturnStatementSyntax returnStatement &&
returnStatement.Expression == null)
{
// using statemnet followed by `return`. Can conver this as executing
// the `return` will cause the code to exit the using scope, causing
// Dispose to be called at the same place as before.
//
// Note: the expr has to be null. If it was non-null, then the expr would
// now execute before hte using called 'Dispose' instead of after, potentially
// changing semantics.
return true;
}
// Add any additional cases here in the future.
return false;
}
private SyntaxList<StatementSyntax> GetStatements(SyntaxNode parent, UsingStatementSyntax usingStatement)
{
switch (parent)
{
case BlockSyntax block: return block.Statements;
case SwitchSectionSyntax switchSection: return switchSection.Statements;
default: throw ExceptionUtilities.UnexpectedValue(parent);
}
}
}
}
......@@ -103,6 +103,7 @@ internal static class IDEDiagnosticIds
public const string UseExpressionBodyForLocalFunctionsDiagnosticId = "IDE0061";
public const string MakeLocalFunctionStaticDiagnosticId = "IDE0062";
public const string UseSimpleUsingStatementDiagnosticId = "IDE0063";
// Analyzer error Ids
public const string AnalyzerChangedId = "IDE1001";
......
......@@ -4402,6 +4402,15 @@ internal class FeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to Use simple &apos;using&apos; statement.
/// </summary>
internal static string Use_simple_using_statement {
get {
return ResourceManager.GetString("Use_simple_using_statement", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Use &apos;throw&apos; expression.
/// </summary>
......@@ -4447,6 +4456,15 @@ internal class FeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to &apos;using&apos; statement can be simplified.
/// </summary>
internal static string using_statment_can_be_simplified {
get {
return ResourceManager.GetString("using_statment_can_be_simplified", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Value assigned to &apos;{0}&apos; is never used.
/// </summary>
......
......@@ -1631,4 +1631,10 @@ This version used in: {2}</value>
<data name="Make_local_function_static" xml:space="preserve">
<value>Make local function 'static'</value>
</data>
<data name="Use_simple_using_statement" xml:space="preserve">
<value>Use simple 'using' statement</value>
</data>
<data name="using_statment_can_be_simplified" xml:space="preserve">
<value>'using' statement can be simplified</value>
</data>
</root>
\ No newline at end of file
......@@ -377,6 +377,11 @@
<target state="new">Use interpolated verbatim string</target>
<note />
</trans-unit>
<trans-unit id="Use_simple_using_statement">
<source>Use simple 'using' statement</source>
<target state="new">Use simple 'using' statement</target>
<note />
</trans-unit>
<trans-unit id="Warning_colon_changing_namespace_may_produce_invalid_code_and_change_code_meaning">
<source>Warning: Changing namespace may produce invalid code and change code meaning.</source>
<target state="new">Warning: Changing namespace may produce invalid code and change code meaning.</target>
......@@ -2470,6 +2475,11 @@ Tato verze se používá zde: {2}.</target>
<target state="new">updating usages in dependent projects</target>
<note />
</trans-unit>
<trans-unit id="using_statment_can_be_simplified">
<source>'using' statement can be simplified</source>
<target state="new">'using' statement can be simplified</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -377,6 +377,11 @@
<target state="new">Use interpolated verbatim string</target>
<note />
</trans-unit>
<trans-unit id="Use_simple_using_statement">
<source>Use simple 'using' statement</source>
<target state="new">Use simple 'using' statement</target>
<note />
</trans-unit>
<trans-unit id="Warning_colon_changing_namespace_may_produce_invalid_code_and_change_code_meaning">
<source>Warning: Changing namespace may produce invalid code and change code meaning.</source>
<target state="new">Warning: Changing namespace may produce invalid code and change code meaning.</target>
......@@ -2470,6 +2475,11 @@ Diese Version wird verwendet in: {2}</target>
<target state="new">updating usages in dependent projects</target>
<note />
</trans-unit>
<trans-unit id="using_statment_can_be_simplified">
<source>'using' statement can be simplified</source>
<target state="new">'using' statement can be simplified</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -377,6 +377,11 @@
<target state="new">Use interpolated verbatim string</target>
<note />
</trans-unit>
<trans-unit id="Use_simple_using_statement">
<source>Use simple 'using' statement</source>
<target state="new">Use simple 'using' statement</target>
<note />
</trans-unit>
<trans-unit id="Warning_colon_changing_namespace_may_produce_invalid_code_and_change_code_meaning">
<source>Warning: Changing namespace may produce invalid code and change code meaning.</source>
<target state="new">Warning: Changing namespace may produce invalid code and change code meaning.</target>
......@@ -2470,6 +2475,11 @@ Esta versión se utiliza en: {2}</target>
<target state="new">updating usages in dependent projects</target>
<note />
</trans-unit>
<trans-unit id="using_statment_can_be_simplified">
<source>'using' statement can be simplified</source>
<target state="new">'using' statement can be simplified</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -377,6 +377,11 @@
<target state="new">Use interpolated verbatim string</target>
<note />
</trans-unit>
<trans-unit id="Use_simple_using_statement">
<source>Use simple 'using' statement</source>
<target state="new">Use simple 'using' statement</target>
<note />
</trans-unit>
<trans-unit id="Warning_colon_changing_namespace_may_produce_invalid_code_and_change_code_meaning">
<source>Warning: Changing namespace may produce invalid code and change code meaning.</source>
<target state="new">Warning: Changing namespace may produce invalid code and change code meaning.</target>
......@@ -2470,6 +2475,11 @@ Version utilisée dans : {2}</target>
<target state="new">updating usages in dependent projects</target>
<note />
</trans-unit>
<trans-unit id="using_statment_can_be_simplified">
<source>'using' statement can be simplified</source>
<target state="new">'using' statement can be simplified</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -377,6 +377,11 @@
<target state="new">Use interpolated verbatim string</target>
<note />
</trans-unit>
<trans-unit id="Use_simple_using_statement">
<source>Use simple 'using' statement</source>
<target state="new">Use simple 'using' statement</target>
<note />
</trans-unit>
<trans-unit id="Warning_colon_changing_namespace_may_produce_invalid_code_and_change_code_meaning">
<source>Warning: Changing namespace may produce invalid code and change code meaning.</source>
<target state="new">Warning: Changing namespace may produce invalid code and change code meaning.</target>
......@@ -2470,6 +2475,11 @@ Questa versione è usata {2}</target>
<target state="new">updating usages in dependent projects</target>
<note />
</trans-unit>
<trans-unit id="using_statment_can_be_simplified">
<source>'using' statement can be simplified</source>
<target state="new">'using' statement can be simplified</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -377,6 +377,11 @@
<target state="new">Use interpolated verbatim string</target>
<note />
</trans-unit>
<trans-unit id="Use_simple_using_statement">
<source>Use simple 'using' statement</source>
<target state="new">Use simple 'using' statement</target>
<note />
</trans-unit>
<trans-unit id="Warning_colon_changing_namespace_may_produce_invalid_code_and_change_code_meaning">
<source>Warning: Changing namespace may produce invalid code and change code meaning.</source>
<target state="new">Warning: Changing namespace may produce invalid code and change code meaning.</target>
......@@ -2470,6 +2475,11 @@ This version used in: {2}</source>
<target state="new">updating usages in dependent projects</target>
<note />
</trans-unit>
<trans-unit id="using_statment_can_be_simplified">
<source>'using' statement can be simplified</source>
<target state="new">'using' statement can be simplified</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -377,6 +377,11 @@
<target state="new">Use interpolated verbatim string</target>
<note />
</trans-unit>
<trans-unit id="Use_simple_using_statement">
<source>Use simple 'using' statement</source>
<target state="new">Use simple 'using' statement</target>
<note />
</trans-unit>
<trans-unit id="Warning_colon_changing_namespace_may_produce_invalid_code_and_change_code_meaning">
<source>Warning: Changing namespace may produce invalid code and change code meaning.</source>
<target state="new">Warning: Changing namespace may produce invalid code and change code meaning.</target>
......@@ -2470,6 +2475,11 @@ This version used in: {2}</source>
<target state="new">updating usages in dependent projects</target>
<note />
</trans-unit>
<trans-unit id="using_statment_can_be_simplified">
<source>'using' statement can be simplified</source>
<target state="new">'using' statement can be simplified</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -377,6 +377,11 @@
<target state="new">Use interpolated verbatim string</target>
<note />
</trans-unit>
<trans-unit id="Use_simple_using_statement">
<source>Use simple 'using' statement</source>
<target state="new">Use simple 'using' statement</target>
<note />
</trans-unit>
<trans-unit id="Warning_colon_changing_namespace_may_produce_invalid_code_and_change_code_meaning">
<source>Warning: Changing namespace may produce invalid code and change code meaning.</source>
<target state="new">Warning: Changing namespace may produce invalid code and change code meaning.</target>
......@@ -2470,6 +2475,11 @@ Ta wersja jest używana wersja: {2}</target>
<target state="new">updating usages in dependent projects</target>
<note />
</trans-unit>
<trans-unit id="using_statment_can_be_simplified">
<source>'using' statement can be simplified</source>
<target state="new">'using' statement can be simplified</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -377,6 +377,11 @@
<target state="new">Use interpolated verbatim string</target>
<note />
</trans-unit>
<trans-unit id="Use_simple_using_statement">
<source>Use simple 'using' statement</source>
<target state="new">Use simple 'using' statement</target>
<note />
</trans-unit>
<trans-unit id="Warning_colon_changing_namespace_may_produce_invalid_code_and_change_code_meaning">
<source>Warning: Changing namespace may produce invalid code and change code meaning.</source>
<target state="new">Warning: Changing namespace may produce invalid code and change code meaning.</target>
......@@ -2470,6 +2475,11 @@ Essa versão é usada no: {2}</target>
<target state="new">updating usages in dependent projects</target>
<note />
</trans-unit>
<trans-unit id="using_statment_can_be_simplified">
<source>'using' statement can be simplified</source>
<target state="new">'using' statement can be simplified</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -377,6 +377,11 @@
<target state="new">Use interpolated verbatim string</target>
<note />
</trans-unit>
<trans-unit id="Use_simple_using_statement">
<source>Use simple 'using' statement</source>
<target state="new">Use simple 'using' statement</target>
<note />
</trans-unit>
<trans-unit id="Warning_colon_changing_namespace_may_produce_invalid_code_and_change_code_meaning">
<source>Warning: Changing namespace may produce invalid code and change code meaning.</source>
<target state="new">Warning: Changing namespace may produce invalid code and change code meaning.</target>
......@@ -2470,6 +2475,11 @@ This version used in: {2}</source>
<target state="new">updating usages in dependent projects</target>
<note />
</trans-unit>
<trans-unit id="using_statment_can_be_simplified">
<source>'using' statement can be simplified</source>
<target state="new">'using' statement can be simplified</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -377,6 +377,11 @@
<target state="new">Use interpolated verbatim string</target>
<note />
</trans-unit>
<trans-unit id="Use_simple_using_statement">
<source>Use simple 'using' statement</source>
<target state="new">Use simple 'using' statement</target>
<note />
</trans-unit>
<trans-unit id="Warning_colon_changing_namespace_may_produce_invalid_code_and_change_code_meaning">
<source>Warning: Changing namespace may produce invalid code and change code meaning.</source>
<target state="new">Warning: Changing namespace may produce invalid code and change code meaning.</target>
......@@ -2470,6 +2475,11 @@ Bu sürüm şurada kullanılır: {2}</target>
<target state="new">updating usages in dependent projects</target>
<note />
</trans-unit>
<trans-unit id="using_statment_can_be_simplified">
<source>'using' statement can be simplified</source>
<target state="new">'using' statement can be simplified</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -377,6 +377,11 @@
<target state="new">Use interpolated verbatim string</target>
<note />
</trans-unit>
<trans-unit id="Use_simple_using_statement">
<source>Use simple 'using' statement</source>
<target state="new">Use simple 'using' statement</target>
<note />
</trans-unit>
<trans-unit id="Warning_colon_changing_namespace_may_produce_invalid_code_and_change_code_meaning">
<source>Warning: Changing namespace may produce invalid code and change code meaning.</source>
<target state="new">Warning: Changing namespace may produce invalid code and change code meaning.</target>
......@@ -2470,6 +2475,11 @@ This version used in: {2}</source>
<target state="new">updating usages in dependent projects</target>
<note />
</trans-unit>
<trans-unit id="using_statment_can_be_simplified">
<source>'using' statement can be simplified</source>
<target state="new">'using' statement can be simplified</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -377,6 +377,11 @@
<target state="new">Use interpolated verbatim string</target>
<note />
</trans-unit>
<trans-unit id="Use_simple_using_statement">
<source>Use simple 'using' statement</source>
<target state="new">Use simple 'using' statement</target>
<note />
</trans-unit>
<trans-unit id="Warning_colon_changing_namespace_may_produce_invalid_code_and_change_code_meaning">
<source>Warning: Changing namespace may produce invalid code and change code meaning.</source>
<target state="new">Warning: Changing namespace may produce invalid code and change code meaning.</target>
......@@ -2470,6 +2475,11 @@ This version used in: {2}</source>
<target state="new">updating usages in dependent projects</target>
<note />
</trans-unit>
<trans-unit id="using_statment_can_be_simplified">
<source>'using' statement can be simplified</source>
<target state="new">'using' statement can be simplified</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -213,6 +213,13 @@ private static Option<T> CreateOption<T>(OptionGroup group, string name, T defau
EditorConfigStorageLocation.ForBoolCodeStyleOption("csharp_prefer_static_local_function"),
new RoamingProfileStorageLocation($"TextEditor.CSharp.Specific.{nameof(PreferStaticLocalFunction)}")});
public static readonly Option<CodeStyleOption<bool>> PreferSimpleUsingStatement = CreateOption(
CSharpCodeStyleOptionGroups.CodeBlockPreferences, nameof(PreferSimpleUsingStatement),
defaultValue: CodeStyleOptions.TrueWithSuggestionEnforcement,
storageLocations: new OptionStorageLocation[] {
EditorConfigStorageLocation.ForBoolCodeStyleOption("csharp_prefer_simple_using_statement"),
new RoamingProfileStorageLocation($"TextEditor.CSharp.Specific.{nameof(PreferSimpleUsingStatement)}")});
public static readonly Option<CodeStyleOption<bool>> PreferLocalOverAnonymousFunction = CreateOption(
CSharpCodeStyleOptionGroups.ExpressionLevelPreferences, nameof(PreferLocalOverAnonymousFunction),
defaultValue: CodeStyleOptions.TrueWithSuggestionEnforcement,
......
......@@ -201,8 +201,7 @@ public static (SyntaxToken openBrace, SyntaxToken closeBrace) GetBraces(this Syn
public static bool IsEmbeddedStatementOwner(this SyntaxNode node)
{
return
node is DoStatementSyntax ||
return node is DoStatementSyntax ||
node is ElseClauseSyntax ||
node is FixedStatementSyntax ||
node is CommonForEachStatementSyntax ||
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册