提交 38db5289 编写于 作者: S Sam Harwell

Implement code review feedback (code style and additional tests)

上级 1491c335
......@@ -20,6 +20,7 @@ internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProvider
[InlineData("internal")]
[InlineData("protected")]
[InlineData("protected internal")]
[InlineData("private protected")]
public async Task NonPrivateField(string accessibility)
{
await TestMissingInRegularAndScriptAsync(
......@@ -696,12 +697,20 @@ public async Task FixAll()
@"class MyClass
{
private int {|FixAllInDocument:_goo|} = 0, _bar = 0;
private int _x = 0, _y = 0, _z = 0;
private int _fizz = 0;
void Method() { _z = 1; }
}",
@"class MyClass
{
private readonly int _goo = 0, _bar = 0;
private readonly int _x = 0;
private readonly int _y = 0;
private int _z = 0;
private readonly int _fizz = 0;
void Method() { _z = 1; }
}");
}
......
......@@ -143,6 +143,142 @@ End Class",
End Class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)>
Public Async Function MultipleFieldsAssignedInline_VBSpecialForms01() As Task
Await TestInRegularAndScriptAsync(
"Class C
Dim [|x|] As Integer, y As String
End Class",
"Class C
Private ReadOnly x As Integer
Private y As String
End Class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)>
Public Async Function MultipleFieldsAssignedInline_VBSpecialForms02() As Task
Await TestInRegularAndScriptAsync(
"Class C
Dim x As Integer, [|y|] As String
End Class",
"Class C
Private x As Integer
Private ReadOnly y As String
End Class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)>
Public Async Function MultipleFieldsAssignedInline_VBSpecialForms03() As Task
Await TestInRegularAndScriptAsync(
"Class C
Dim [|x|], y As Integer, z, w As String
End Class",
"Class C
Private ReadOnly x As Integer
Private y As Integer
Private z As String
Private w As String
End Class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)>
Public Async Function MultipleFieldsAssignedInline_VBSpecialForms04() As Task
Await TestInRegularAndScriptAsync(
"Class C
Dim x, [|y|] As Integer, z, w As String
End Class",
"Class C
Private x As Integer
Private ReadOnly y As Integer
Private z As String
Private w As String
End Class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)>
Public Async Function MultipleFieldsAssignedInline_VBSpecialForms05() As Task
Await TestInRegularAndScriptAsync(
"Class C
Dim x, y As Integer, [|z|], w As String
End Class",
"Class C
Private x As Integer
Private y As Integer
Private ReadOnly z As String
Private w As String
End Class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)>
Public Async Function MultipleFieldsAssignedInline_VBSpecialForms06() As Task
Await TestInRegularAndScriptAsync(
"Class C
Dim x, y As Integer, z, [|w|] As String
End Class",
"Class C
Private x As Integer
Private y As Integer
Private z As String
Private ReadOnly w As String
End Class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)>
Public Async Function MultipleFieldsAssignedInline_VBSpecialForms07() As Task
Await TestInRegularAndScriptAsync(
"Class C
Dim [|x|], y() As Integer, z(), w As String
End Class",
"Class C
Private ReadOnly x As Integer
Private y As Integer()
Private z As String()
Private w As String
End Class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)>
Public Async Function MultipleFieldsAssignedInline_VBSpecialForms08() As Task
Await TestInRegularAndScriptAsync(
"Class C
Dim x, [|y|]() As Integer, z(), w As String
End Class",
"Class C
Private x As Integer
Private ReadOnly y As Integer()
Private z As String()
Private w As String
End Class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)>
Public Async Function MultipleFieldsAssignedInline_VBSpecialForms09() As Task
Await TestInRegularAndScriptAsync(
"Class C
Dim x, y() As Integer, [|z|](), w As String
End Class",
"Class C
Private x As Integer
Private y As Integer()
Private ReadOnly z As String()
Private w As String
End Class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)>
Public Async Function MultipleFieldsAssignedInline_VBSpecialForms10() As Task
Await TestInRegularAndScriptAsync(
"Class C
Dim x, y() As Integer, z(), [|w|] As String
End Class",
"Class C
Private x As Integer
Private y As Integer()
Private z As String()
Private ReadOnly w As String
End Class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)>
Public Async Function MultipleFieldsAssignedInline_OneAssignedInMethod() As Task
Await TestInRegularAndScriptAsync(
......@@ -502,10 +638,12 @@ End Class")
Await TestInRegularAndScriptAsync(
"Class C
Private {|FixAllInDocument:_goo|} As Integer = 0, _bar As Integer = 0
Dim a, b(), c As Integer, x, y As String
Private _fizz As Integer = 0
End Class",
"Class C
Private ReadOnly _goo As Integer = 0, _bar As Integer = 0
ReadOnly a, b(), c As Integer, x, y As String
Private ReadOnly _fizz As Integer = 0
End Class")
End Function
......
......@@ -16,8 +16,8 @@ internal class CSharpMakeFieldReadonlyDiagnosticAnalyzer :
protected override void InitializeWorker(AnalysisContext context)
=> context.RegisterSyntaxNodeAction(AnalyzeType, SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration);
protected override ISyntaxFactsService GetSyntaxFactsService() =>
CSharpSyntaxFactsService.Instance;
protected override ISyntaxFactsService GetSyntaxFactsService()
=> CSharpSyntaxFactsService.Instance;
protected override bool IsWrittenTo(IdentifierNameSyntax name, SemanticModel model, CancellationToken cancellationToken)
=> name.IsWrittenTo();
......
......@@ -15,8 +15,7 @@
namespace Microsoft.CodeAnalysis.MakeFieldReadonly
{
internal abstract class AbstractMakeFieldReadonlyCodeFixProvider
<TSymbolSyntax, TFieldDeclarationSyntax>
internal abstract class AbstractMakeFieldReadonlyCodeFixProvider<TSymbolSyntax, TFieldDeclarationSyntax>
: SyntaxEditorBasedCodeFixProvider
where TSymbolSyntax : SyntaxNode
where TFieldDeclarationSyntax : SyntaxNode
......@@ -24,6 +23,9 @@ internal abstract class AbstractMakeFieldReadonlyCodeFixProvider
public override ImmutableArray<string> FixableDiagnosticIds
=> ImmutableArray.Create(IDEDiagnosticIds.MakeFieldReadonlyDiagnosticId);
protected abstract SyntaxNode GetInitializerNode(TSymbolSyntax declaration);
protected abstract ImmutableList<TSymbolSyntax> GetVariableDeclarators(TFieldDeclarationSyntax declaration);
public override Task RegisterCodeFixesAsync(CodeFixContext context)
{
context.RegisterCodeFix(new MyCodeAction(
......@@ -87,9 +89,6 @@ private async void MakeFieldReadonly(Document document, SyntaxEditor editor, Lis
}
}
}
protected abstract SyntaxNode GetInitializerNode(TSymbolSyntax declaration);
protected abstract ImmutableList<TSymbolSyntax> GetVariableDeclarators(TFieldDeclarationSyntax declaration);
protected override Task FixAllAsync(
Document document,
......
......@@ -13,20 +13,23 @@ internal abstract class AbstractMakeFieldReadonlyDiagnosticAnalyzer<TIdentifierN
where TIdentifierNameSyntax : SyntaxNode
where TConstructorDeclarationSyntax : SyntaxNode
{
private static readonly LocalizableString s_localizableTitle = new LocalizableResourceString(nameof(FeaturesResources.Add_readonly_modifier), FeaturesResources.ResourceManager, typeof(FeaturesResources));
private static readonly LocalizableString s_localizableMessage = new LocalizableResourceString(nameof(FeaturesResources.Make_field_readonly), WorkspacesResources.ResourceManager, typeof(WorkspacesResources));
public AbstractMakeFieldReadonlyDiagnosticAnalyzer()
: base(IDEDiagnosticIds.MakeFieldReadonlyDiagnosticId,
s_localizableTitle, s_localizableMessage)
protected AbstractMakeFieldReadonlyDiagnosticAnalyzer()
: base(
IDEDiagnosticIds.MakeFieldReadonlyDiagnosticId,
new LocalizableResourceString(nameof(FeaturesResources.Add_readonly_modifier), FeaturesResources.ResourceManager, typeof(FeaturesResources)),
new LocalizableResourceString(nameof(FeaturesResources.Make_field_readonly), WorkspacesResources.ResourceManager, typeof(WorkspacesResources)))
{
}
protected abstract ISyntaxFactsService GetSyntaxFactsService();
protected abstract bool IsWrittenTo(TIdentifierNameSyntax node, SemanticModel model, CancellationToken cancellationToken);
protected abstract bool IsMemberOfThisInstance(SyntaxNode node);
public override bool OpenFileOnly(Workspace workspace) => false;
public override DiagnosticAnalyzerCategory GetAnalyzerCategory() => DiagnosticAnalyzerCategory.SemanticDocumentAnalysis;
internal void AnalyzeType(SyntaxNodeAnalysisContext context)
protected void AnalyzeType(SyntaxNodeAnalysisContext context)
{
var optionSet = context.Options.GetDocumentOptionSetAsync(context.Node.SyntaxTree, context.CancellationToken).GetAwaiter().GetResult();
if (optionSet == null)
......@@ -126,7 +129,7 @@ private void RemoveAssignedSymbols(SemanticModel model, ISyntaxFactsService synt
var isInAnonymousOrLocalFunction = false;
for (var current = descendant.Parent; current != ctorNode; current = current.Parent)
{
if (syntaxFactsService.IsAnonymousOrLocalFunction(current))
if (syntaxFactsService.IsAnonymousFunction(current) || syntaxFactsService.IsLocalFunction(current))
{
isInAnonymousOrLocalFunction = true;
break;
......@@ -186,9 +189,5 @@ private bool IsMutableValueType(ITypeSymbol type)
return false;
}
protected abstract ISyntaxFactsService GetSyntaxFactsService();
protected abstract bool IsWrittenTo(TIdentifierNameSyntax node, SemanticModel model, CancellationToken cancellationToken);
protected abstract bool IsMemberOfThisInstance(SyntaxNode node);
}
}
......@@ -201,10 +201,9 @@ public bool IsAnonymousFunction(SyntaxNode node)
node is AnonymousMethodExpressionSyntax;
}
public bool IsAnonymousOrLocalFunction(SyntaxNode node)
public bool IsLocalFunction(SyntaxNode node)
{
return IsAnonymousFunction(node) ||
node is LocalFunctionStatementSyntax;
return node is LocalFunctionStatementSyntax;
}
public bool IsGenericName(SyntaxNode node)
......
......@@ -250,7 +250,7 @@ internal interface ISyntaxFactsService : ILanguageService
bool IsAnonymousFunction(SyntaxNode n);
bool IsAnonymousOrLocalFunction(SyntaxNode n);
bool IsLocalFunction(SyntaxNode n);
bool IsInConstantContext(SyntaxNode node);
bool IsInConstructor(SyntaxNode node);
......
......@@ -201,8 +201,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return TypeOf node Is LambdaExpressionSyntax
End Function
Public Function IsAnonymousOrLocalFunction(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsAnonymousOrLocalFunction
Return IsAnonymousFunction(node)
Public Function IsLocalFunction(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsLocalFunction
Return False
End Function
Public Function IsGenericName(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsGenericName
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册