提交 8c9f7648 编写于 作者: A Abraham Hosch 提交者: Sam Harwell

Fix build, broken tests, and a few other comments

上级 4caa5fc3
......@@ -14,17 +14,14 @@ public class MakeFieldReadonlyTests : AbstractCSharpDiagnosticProviderBasedUserD
{
internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace)
=> (new CSharpMakeFieldReadonlyDiagnosticAnalyzer(), new CSharpMakeFieldReadonlyCodeFixProvider());
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)]
public async Task FieldIsPublic()
{
await TestMissingInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
{
public int [|_foo|];
}
public int [|_foo|];
}");
}
......@@ -32,12 +29,9 @@ class MyClass
public async Task FieldIsInternal()
{
await TestMissingInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
{
internal int [|_foo|];
}
internal int [|_foo|];
}");
}
......@@ -45,12 +39,9 @@ class MyClass
public async Task FieldIsProtected()
{
await TestMissingInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
{
protected int [|_foo|];
}
protected int [|_foo|];
}");
}
......@@ -58,12 +49,9 @@ class MyClass
public async Task FieldIsProtectedInternal()
{
await TestMissingInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
{
protected internal int [|_foo|];
}
protected internal int [|_foo|];
}");
}
......@@ -71,12 +59,9 @@ class MyClass
public async Task FieldIsEvent()
{
await TestMissingInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
{
private event System.EventHandler [|Foo|];
}
private event System.EventHandler [|Foo|];
}");
}
......@@ -84,12 +69,9 @@ class MyClass
public async Task FieldIsReadonly()
{
await TestMissingInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
{
private readonly int [|_foo|];
}
private readonly int [|_foo|];
}");
}
......@@ -97,19 +79,13 @@ class MyClass
public async Task FieldNotAssigned()
{
await TestInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
{
private int [|_foo|];
}
private int [|_foo|];
}",
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
{
private readonly int _foo;
}
private readonly int _foo;
}");
}
......@@ -117,19 +93,13 @@ class MyClass
public async Task FieldNotAssigned_Struct()
{
await TestInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"struct MyStruct
{
struct MyStruct
{
private int [|_foo|];
}
private int [|_foo|];
}",
@"namespace ConsoleApplication1
@"struct MyStruct
{
struct MyStruct
{
private readonly int _foo;
}
private readonly int _foo;
}");
}
......@@ -137,19 +107,13 @@ struct MyStruct
public async Task FieldAssignedInline()
{
await TestInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
{
private int [|_foo|] = 0;
}
private int [|_foo|] = 0;
}",
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
{
private readonly int _foo = 0;
}
private readonly int _foo = 0;
}");
}
......@@ -157,20 +121,14 @@ class MyClass
public async Task MultipleFieldsAssignedInline_AllCanBeReadonly()
{
await TestInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
{
private int [|_foo|] = 0, _bar = 0;
}
private int [|_foo|] = 0, _bar = 0;
}",
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
{
private int _bar = 0;
private readonly int _foo = 0;
}
private int _bar = 0;
private readonly int _foo = 0;
}");
}
......@@ -178,27 +136,21 @@ class MyClass
public async Task MultipleFieldsAssignedInline_OneIsAssignedInMethod()
{
await TestInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
private int _foo = 0, [|_bar|] = 0;
Foo()
{
private int _foo = 0, [|_bar|] = 0;
Foo()
{
_foo = 0;
}
_foo = 0;
}
}",
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
private int _foo = 0;
private readonly int _bar = 0;
Foo()
{
private int _foo = 0;
private readonly int _bar = 0;
Foo()
{
_foo = 0;
}
_foo = 0;
}
}");
}
......@@ -207,20 +159,14 @@ class MyClass
public async Task MultipleFieldsAssignedInline_NoInitializer()
{
await TestInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
{
private int [|_foo|], _bar = 0;
}
private int [|_foo|], _bar = 0;
}",
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
{
private int _bar = 0;
private readonly int _foo;
}
private int _bar = 0;
private readonly int _foo;
}");
}
......@@ -228,26 +174,20 @@ class MyClass
public async Task FieldAssignedInCtor()
{
await TestInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
private int [|_foo|];
MyClass()
{
private int [|_foo|];
MyClass()
{
_foo = 0;
}
_foo = 0;
}
}",
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
private readonly int _foo;
MyClass()
{
private readonly int _foo;
MyClass()
{
_foo = 0;
}
_foo = 0;
}
}");
}
......@@ -256,18 +196,15 @@ class MyClass
public async Task FieldAssignedInLambdaInCtor()
{
await TestMissingInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"public class MyClass
{
public class MyClass
private int [|_foo|];
public MyClass()
{
private int [|_foo|];
public MyClass()
{
this.E += (_, __) => this._foo = 0;
}
public event EventHandler E;
this.E += (_, __) => this._foo = 0;
}
public event EventHandler E;
}");
}
......@@ -275,18 +212,15 @@ public MyClass()
public async Task FieldAssignedInLambdaWithBlockInCtor()
{
await TestMissingInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"public class MyClass
{
public class MyClass
private int [|_foo|];
public MyClass()
{
private int [|_foo|];
public MyClass()
{
this.E += (_, __) => { this._foo = 0; }
}
public event EventHandler E;
this.E += (_, __) => { this._foo = 0; }
}
public event EventHandler E;
}");
}
......@@ -294,16 +228,13 @@ public MyClass()
public async Task FieldAssignedInCtor_DifferentInstance()
{
await TestMissingInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
private int [|_foo|];
MyClass()
{
private int [|_foo|];
MyClass()
{
var foo = new MyClass();
foo._foo = 0;
}
var foo = new MyClass();
foo._foo = 0;
}
}");
}
......@@ -312,15 +243,12 @@ class MyClass
public async Task FieldAssignedInCtor_DifferentInstance_ObjectInitializer()
{
await TestMissingInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
private int [|_foo|];
MyClass()
{
private int [|_foo|];
MyClass()
{
var foo = new MyClass { _foo = 0 };
}
var foo = new MyClass { _foo = 0 };
}
}");
}
......@@ -329,26 +257,20 @@ class MyClass
public async Task FieldAssignedInCtor_QualifiedWithThis()
{
await TestInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
private int [|_foo|];
MyClass()
{
private int [|_foo|];
MyClass()
{
this._foo = 0;
}
this._foo = 0;
}
}",
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
private readonly int _foo;
MyClass()
{
private readonly int _foo;
MyClass()
{
this._foo = 0;
}
this._foo = 0;
}
}");
}
......@@ -357,26 +279,20 @@ class MyClass
public async Task FieldReturnedInProperty()
{
await TestInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
private int [|_foo|];
int Foo
{
private int [|_foo|];
int Foo
{
get { return _foo; }
}
get { return _foo; }
}
}",
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
private readonly int _foo;
int Foo
{
private readonly int _foo;
int Foo
{
get { return _foo; }
}
get { return _foo; }
}
}");
}
......@@ -385,16 +301,13 @@ int Foo
public async Task FieldAssignedInProperty()
{
await TestMissingInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
private int [|_foo|];
int Foo
{
private int [|_foo|];
int Foo
{
get { return _foo; }
set { _foo = value; }
}
get { return _foo; }
set { _foo = value; }
}
}");
}
......@@ -403,15 +316,12 @@ int Foo
public async Task FieldAssignedInMethod()
{
await TestMissingInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
private int [|_foo|];
int Foo()
{
private int [|_foo|];
int Foo()
{
_foo = 0;
}
_foo = 0;
}
}");
}
......@@ -420,26 +330,20 @@ int Foo()
public async Task VariableAssignedToFieldInMethod()
{
await TestInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
private int [|_foo|];
int Foo()
{
private int [|_foo|];
int Foo()
{
var i = _foo;
}
var i = _foo;
}
}",
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
private readonly int _foo;
int Foo()
{
private readonly int _foo;
int Foo()
{
var i = _foo;
}
var i = _foo;
}
}");
}
......@@ -448,15 +352,12 @@ int Foo()
public async Task FieldAssignedInMethodWithCompoundOperator()
{
await TestMissingInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
private int [|_foo|] = 0;
int Foo(int value)
{
private int [|_foo|] = 0;
int Foo(int value)
{
_foo += value;
}
_foo += value;
}
}");
}
......@@ -465,15 +366,12 @@ int Foo(int value)
public async Task FieldUsedWithPostfixIncrement()
{
await TestMissingInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
private int [|_foo|] = 0;
int Foo(int value)
{
private int [|_foo|] = 0;
int Foo(int value)
{
_foo++;
}
_foo++;
}
}");
}
......@@ -482,15 +380,12 @@ int Foo(int value)
public async Task FieldUsedWithPrefixDecrement()
{
await TestMissingInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
private int [|_foo|] = 0;
int Foo(int value)
{
private int [|_foo|] = 0;
int Foo(int value)
{
--_foo;
}
--_foo;
}
}");
}
......@@ -499,18 +394,15 @@ int Foo(int value)
public async Task AssignedInPartialClass()
{
await TestMissingInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"partial class MyClass
{
partial class MyClass
{
private int [|_foo|];
}
partial class MyClass
private int [|_foo|];
}
partial class MyClass
{
void SetFoo()
{
void SetFoo()
{
_foo = 0;
}
_foo = 0;
}
}");
}
......@@ -519,32 +411,26 @@ void SetFoo()
public async Task PassedAsParameter()
{
await TestInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
private int [|_foo|];
void Foo()
{
Bar(_foo);
}
void Bar(int foo)
{
private int [|_foo|];
void Foo()
{
Bar(_foo);
}
void Bar(int foo)
{
}
}
}",
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
private readonly int _foo;
void Foo()
{
Bar(_foo);
}
void Bar(int foo)
{
private readonly int _foo;
void Foo()
{
Bar(_foo);
}
void Bar(int foo)
{
}
}
}");
}
......@@ -553,15 +439,12 @@ void Bar(int foo)
public async Task PassedAsOutParameter()
{
await TestMissingInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
private int [|_foo|];
void Foo()
{
private int [|_foo|];
void Foo()
{
int.TryParse(""123"", out _foo);
}
int.TryParse(""123"", out _foo);
}
}");
}
......@@ -570,18 +453,65 @@ void Foo()
public async Task PassedAsRefParameter()
{
await TestMissingInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
private int [|_foo|];
void Foo()
{
private int [|_foo|];
void Foo()
{
Bar(ref _foo);
Bar(ref _foo);
}
void Bar(ref int foo)
{
}
}");
}
void Bar(ref int foo)
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)]
public async Task PassedAsOutParameterInCtor()
{
await TestInRegularAndScriptAsync(
@"class MyClass
{
private int [|_foo|];
MyClass()
{
int.TryParse(""123"", out _foo);
}
}",
@"class MyClass
{
private readonly int _foo;
MyClass()
{
int.TryParse(""123"", out _foo);
}
}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)]
public async Task PassedAsRefParameterInCtor()
{
await TestInRegularAndScriptAsync(
@"class MyClass
{
private int [|_foo|];
MyClass()
{
Bar(ref _foo);
}
void Bar(ref int foo)
{
}
}",
@"class MyClass
{
private readonly int _foo;
MyClass()
{
Bar(ref _foo);
}
void Bar(ref int foo)
{
}
}");
}
......@@ -590,26 +520,20 @@ void Bar(ref int foo)
public async Task StaticFieldAssignedInStaticCtor()
{
await TestInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
private static int [|_foo|];
static MyClass()
{
private static int [|_foo|];
static MyClass()
{
_foo = 0;
}
_foo = 0;
}
}",
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
private static readonly int _foo;
static MyClass()
{
private static readonly int _foo;
static MyClass()
{
_foo = 0;
}
_foo = 0;
}
}");
}
......@@ -618,15 +542,12 @@ static MyClass()
public async Task StaticFieldAssignedInNonStaticCtor()
{
await TestMissingInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
private static int [|_foo|];
MyClass()
{
private static int [|_foo|];
MyClass()
{
_foo = 0;
}
_foo = 0;
}
}");
}
......@@ -635,22 +556,16 @@ class MyClass
public async Task FixAll()
{
await TestInRegularAndScriptAsync(
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
{
private int {|FixAllInDocument:_foo|} = 0, _bar = 0;
private int _fizz = 0;
}
private int {|FixAllInDocument:_foo|} = 0, _bar = 0;
private int _fizz = 0;
}",
@"namespace ConsoleApplication1
@"class MyClass
{
class MyClass
{
private readonly int _bar = 0;
private readonly int _foo = 0;
private readonly int _fizz = 0;
}
private readonly int _bar = 0;
private readonly int _foo = 0;
private readonly int _fizz = 0;
}");
}
}
......
......@@ -351,6 +351,27 @@ End Class")
End Class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)>
Public Async Function PassedAsByRefParameterInCtor() As Task
Await TestInRegularAndScriptAsync(
"Class C
Private [|_foo|] As Integer = 0
Sub New()
Bar(_foo)
End Sub
Sub Bar(ByRef value As Integer)
End Sub
End Class",
"Class C
Private ReadOnly _foo As Integer = 0
Sub New()
Bar(_foo)
End Sub
Sub Bar(ByRef value As Integer)
End Sub
End Class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)>
Public Async Function PassedAsByValParameter() As Task
Await TestInRegularAndScriptAsync(
......
......@@ -15,12 +15,10 @@ internal class CSharpMakeFieldReadonlyDiagnosticAnalyzer :
protected override void InitializeWorker(AnalysisContext context)
=> context.RegisterSyntaxNodeAction(AnalyzeType, SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration);
internal override bool CanBeReadonly(IdentifierNameSyntax name, SemanticModel model, CancellationToken cancellationToken)
{
return !name.IsWrittenTo();
}
protected override bool IsWrittenTo(IdentifierNameSyntax name, SemanticModel model, CancellationToken cancellationToken)
=> name.IsWrittenTo();
internal override bool IsMemberOfThisInstance(SyntaxNode node)
protected override bool IsMemberOfThisInstance(SyntaxNode node)
{
// if it is a qualified name, make sure it is `this.name`
if (node.Parent is MemberAccessExpressionSyntax memberAccess)
......
......@@ -71,7 +71,7 @@ private void GetUnassignedSymbols(SemanticModel model, SyntaxNode node, HashSet<
if (!(descendant is TIdentifierNameSyntax name))
{
return;
continue;
}
var symbol = model.GetSymbolInfo(descendant).Symbol as IFieldSymbol;
......@@ -102,7 +102,7 @@ private void GetUnassignedSymbols(SemanticModel model, SyntaxNode node, HashSet<
continue;
}
if (!CanBeReadonly(name, model, cancellationToken))
if (IsWrittenTo(name, model, cancellationToken))
{
unassignedSymbols.Remove(symbol);
}
......@@ -115,7 +115,7 @@ private void GetUnassignedSymbols(SemanticModel model, SyntaxNode node, HashSet<
return ctor != null;
}
internal abstract bool CanBeReadonly(TIdentifierNameSyntax node, SemanticModel model, CancellationToken cancellationToken);
internal abstract bool IsMemberOfThisInstance(SyntaxNode node);
protected abstract bool IsWrittenTo(TIdentifierNameSyntax node, SemanticModel model, CancellationToken cancellationToken);
protected abstract bool IsMemberOfThisInstance(SyntaxNode node);
}
}
......@@ -14,11 +14,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.MakeFieldReadonly
context.RegisterSyntaxNodeAction(AddressOf AnalyzeType, SyntaxKind.ClassBlock, SyntaxKind.StructureBlock, SyntaxKind.ModuleBlock)
End Sub
Friend Overrides Function CanBeReadonly(name As IdentifierNameSyntax, model As SemanticModel, cancellationToken As CancellationToken) As Boolean
Return Not name.IsWrittenTo(model, cancellationToken)
Protected Overrides Function IsWrittenTo(name As IdentifierNameSyntax, model As SemanticModel, cancellationToken As CancellationToken) As Boolean
Return name.IsWrittenTo(model, cancellationToken)
End Function
Friend Overrides Function IsMemberOfThisInstance(node As SyntaxNode) As Boolean
Protected Overrides Function IsMemberOfThisInstance(node As SyntaxNode) As Boolean
' if it is a qualified name, make sure it is `Me.name`
Dim memberAccess = TryCast(node.Parent, MemberAccessExpressionSyntax)
If memberAccess IsNot Nothing Then
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册