Browse Source

AccessToModifiedClosureIssue: always use "var" keyword to avoid some null type issues, fixed "fails for field declaration" issue.

newNRvisualizers
Mansheng Yang 14 years ago
parent
commit
754adbcf51
  1. 29
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/AccessToClosureIssues/AccessToClosureIssue.cs
  2. 2
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/AccessToClosureIssues/AccessToDisposedClosureIssue.cs
  3. 9
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/AccessToClosureIssues/AccessToModifiedClosureIssue.cs
  4. 48
      ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/AccessToModifiedClosureTests.cs

29
ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/AccessToClosureIssues/AccessToClosureIssue.cs

@ -70,7 +70,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
} }
protected abstract IEnumerable<CodeAction> GetFixes (BaseRefactoringContext context, Node env, protected abstract IEnumerable<CodeAction> GetFixes (BaseRefactoringContext context, Node env,
string variableName, AstType variableType); string variableName);
#region GatherVisitor #region GatherVisitor
@ -92,11 +92,8 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
public override void VisitVariableInitializer (VariableInitializer variableInitializer) public override void VisitVariableInitializer (VariableInitializer variableInitializer)
{ {
var variableDecl = variableInitializer.Parent as VariableDeclarationStatement; var variableDecl = variableInitializer.Parent as VariableDeclarationStatement;
if (variableDecl == null) if (variableDecl != null)
return;
CheckVariable (((LocalResolveResult)ctx.Resolve (variableInitializer)).Variable, CheckVariable (((LocalResolveResult)ctx.Resolve (variableInitializer)).Variable,
variableDecl.Type,
variableDecl.GetParent<Statement> ()); variableDecl.GetParent<Statement> ());
base.VisitVariableInitializer (variableInitializer); base.VisitVariableInitializer (variableInitializer);
} }
@ -104,7 +101,6 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
public override void VisitForeachStatement (ForeachStatement foreachStatement) public override void VisitForeachStatement (ForeachStatement foreachStatement)
{ {
CheckVariable (((LocalResolveResult)ctx.Resolve (foreachStatement.VariableNameToken)).Variable, CheckVariable (((LocalResolveResult)ctx.Resolve (foreachStatement.VariableNameToken)).Variable,
foreachStatement.VariableType,
foreachStatement); foreachStatement);
base.VisitForeachStatement (foreachStatement); base.VisitForeachStatement (foreachStatement);
} }
@ -121,10 +117,11 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
body = ((LambdaExpression)parent).Body as Statement; body = ((LambdaExpression)parent).Body as Statement;
} else if (parent is ConstructorDeclaration) { } else if (parent is ConstructorDeclaration) {
body = ((ConstructorDeclaration)parent).Body; body = ((ConstructorDeclaration)parent).Body;
} else if (parent is OperatorDeclaration) {
body = ((OperatorDeclaration)parent).Body;
} }
if (body != null) if (body != null)
CheckVariable (((LocalResolveResult)ctx.Resolve (parameterDeclaration)).Variable, CheckVariable (((LocalResolveResult)ctx.Resolve (parameterDeclaration)).Variable, body);
parameterDeclaration.Type, body);
base.VisitParameterDeclaration (parameterDeclaration); base.VisitParameterDeclaration (parameterDeclaration);
} }
@ -134,7 +131,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
ctx.CancellationToken); ctx.CancellationToken);
} }
void CheckVariable (IVariable variable, AstType type, Statement env) void CheckVariable (IVariable variable, Statement env)
{ {
if (!issueProvider.IsTargetVariable (variable)) if (!issueProvider.IsTargetVariable (variable))
return; return;
@ -147,10 +144,10 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
AddNode (envLookup, new Node (astNode, issueProvider.GetNodeKind (astNode)))); AddNode (envLookup, new Node (astNode, issueProvider.GetNodeKind (astNode))));
root.SortChildren (); root.SortChildren ();
CollectIssues (root, variable.Name, type); CollectIssues (root, variable.Name);
} }
void CollectIssues (Environment env, string variableName, AstType variableType) void CollectIssues (Environment env, string variableName)
{ {
IList<ControlFlowNode> cfg = null; IList<ControlFlowNode> cfg = null;
IDictionary<Statement, IList<Node>> modifications = null; IDictionary<Statement, IList<Node>> modifications = null;
@ -171,20 +168,20 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
foreach (var child in env.GetChildEnvironments ()) { foreach (var child in env.GetChildEnvironments ()) {
if (!child.IssueCollected && cfg != null && if (!child.IssueCollected && cfg != null &&
CanReachModification (cfg, child, modifications)) CanReachModification (cfg, child, modifications))
CollectAllIssues (child, variableName, variableType); CollectAllIssues (child, variableName);
CollectIssues (child, variableName, variableType); CollectIssues (child, variableName);
} }
} }
void CollectAllIssues (Environment env, string variableName, AstType variableType) void CollectAllIssues (Environment env, string variableName)
{ {
var fixes = issueProvider.GetFixes (ctx, env, variableName, variableType).ToArray (); var fixes = issueProvider.GetFixes (ctx, env, variableName).ToArray ();
env.IssueCollected = true; env.IssueCollected = true;
foreach (var child in env.Children) { foreach (var child in env.Children) {
if (child is Environment) { if (child is Environment) {
CollectAllIssues ((Environment)child, variableName, variableType); CollectAllIssues ((Environment)child, variableName);
} else { } else {
if (child.Kind != NodeKind.Modification) if (child.Kind != NodeKind.Modification)
AddIssue (child.AstNode, title, fixes); AddIssue (child.AstNode, title, fixes);

2
ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/AccessToClosureIssues/AccessToDisposedClosureIssue.cs

@ -86,7 +86,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
} }
protected override IEnumerable<CodeAction> GetFixes (BaseRefactoringContext context, Node env, protected override IEnumerable<CodeAction> GetFixes (BaseRefactoringContext context, Node env,
string variableName, AstType variableType) string variableName)
{ {
yield break; yield break;
} }

9
ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/AccessToClosureIssues/AccessToModifiedClosureIssue.cs

@ -66,7 +66,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
} }
protected override IEnumerable<CodeAction> GetFixes (BaseRefactoringContext context, Node env, protected override IEnumerable<CodeAction> GetFixes (BaseRefactoringContext context, Node env,
string variableName, AstType variableType) string variableName)
{ {
var containingStatement = env.ContainingStatement; var containingStatement = env.ContainingStatement;
@ -82,12 +82,11 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
Action<Script> action = script => Action<Script> action = script =>
{ {
AstNode parent = containingStatement.GetParent<MethodDeclaration> () ?? var newName = LocalVariableNamePicker.PickSafeName (
(AstNode)containingStatement.GetParent<ConstructorDeclaration> (); containingStatement.GetParent<EntityDeclaration> (),
var newName = LocalVariableNamePicker.PickSafeName (parent,
Enumerable.Range (1, 100).Select (i => variableName + i)); Enumerable.Range (1, 100).Select (i => variableName + i));
var variableDecl = new VariableDeclarationStatement (variableType.Clone (), newName, var variableDecl = new VariableDeclarationStatement (new SimpleType("var"), newName,
new IdentifierExpression (variableName)); new IdentifierExpression (variableName));
if (containingStatement.Parent is BlockStatement || containingStatement.Parent is SwitchSection) { if (containingStatement.Parent is BlockStatement || containingStatement.Parent is SwitchSection) {

48
ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/AccessToModifiedClosureTests.cs

@ -98,7 +98,7 @@ class TestClass
void TestMethod () void TestMethod ()
{ {
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
int i1 = i; var i1 = i;
var f = new System.Func<int, int> (x => x + i1); var f = new System.Func<int, int> (x => x + i1);
} }
} }
@ -143,7 +143,7 @@ class TestClass
void TestMethod () void TestMethod ()
{ {
for (int i = 0; i < 10;) { for (int i = 0; i < 10;) {
int i1 = i; var i1 = i;
var f = new System.Func<int, int> (delegate (int x) { return x + i1; }); var f = new System.Func<int, int> (delegate (int x) { return x + i1; });
i++; i++;
} }
@ -175,7 +175,7 @@ class TestClass
int i = 0; int i = 0;
while (i < 10) { while (i < 10) {
i++; i++;
int i1 = i; var i1 = i;
var f = new System.Func<int, int> (x => x + i1); var f = new System.Func<int, int> (x => x + i1);
} }
} }
@ -204,7 +204,7 @@ class TestClass
{ {
int i = 0; int i = 0;
while (i++ < 10) { while (i++ < 10) {
int i1 = i; var i1 = i;
var f = new System.Func<int, int> (delegate (int x) { return x + i1; }); var f = new System.Func<int, int> (delegate (int x) { return x + i1; });
} }
} }
@ -235,7 +235,7 @@ class TestClass
int i = 0; int i = 0;
do { do {
i += 1; i += 1;
int i1 = i; var i1 = i;
var f = new System.Func<int, int> (x => x + i1); var f = new System.Func<int, int> (x => x + i1);
} while (i < 10); } while (i < 10);
} }
@ -264,7 +264,7 @@ class TestClass
{ {
int i = 0; int i = 0;
while (i++ < 10) { while (i++ < 10) {
int i1 = i; var i1 = i;
var f = new System.Func<int, int> (x => x + i1); var f = new System.Func<int, int> (x => x + i1);
} }
} }
@ -491,7 +491,7 @@ class TestClass
void TestMethod () void TestMethod ()
{ {
int i = 0; int i = 0;
int i1 = i; var i1 = i;
System.Func<int, int> f = x => i1 + x; System.Func<int, int> f = x => i1 + x;
i += 1; i += 1;
} }
@ -563,7 +563,7 @@ class TestClass
{ {
void TestMethod (int i) void TestMethod (int i)
{ {
int i1 = i; var i1 = i;
System.Func<int, int> f = x => i1 + x; System.Func<int, int> f = x => i1 + x;
i += 1; i += 1;
} }
@ -595,7 +595,7 @@ class TestClass
{ {
void TestMethod3 (System.Func<int, int> a, int b) void TestMethod3 (System.Func<int, int> a, int b)
{ {
int b1 = b; var b1 = b;
TestMethod3 (c => c + b1, b++); TestMethod3 (c => c + b1, b++);
} }
}"; }";
@ -624,7 +624,7 @@ class TestClass
{ {
int i = 0; int i = 0;
System.Func<int, int> f = null; System.Func<int, int> f = null;
int i1 = i; var i1 = i;
if ((f = x => x + i1) != null) if ((f = x => x + i1) != null)
i++; i++;
} }
@ -655,7 +655,7 @@ class TestClass
System.Func<int, int> f = null; System.Func<int, int> f = null;
switch (k) { switch (k) {
default: default:
int i1 = i; var i1 = i;
f = x => x + i1; f = x => x + i1;
break; break;
} }
@ -778,5 +778,31 @@ class TestClass
Test (input, 1, output); Test (input, 1, output);
} }
[Test]
public void TestField ()
{
var input = @"
class TestClass
{
System.Action<int> a = i =>
{
System.Func<int> f = () => i + 1;
i++;
};
}";
var output = @"
class TestClass
{
System.Action<int> a = i =>
{
var i1 = i;
System.Func<int> f = () => i1 + 1;
i++;
};
}";
Test (input, 1, output);
}
} }
} }

Loading…
Cancel
Save