Browse Source

[CodeIssues] Fixed concurrency issue in variable reference graph.

newNRvisualizers
Mike Krüger 13 years ago
parent
commit
9648890f61
  1. 5
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/MultipleEnumerationIssue.cs
  2. 2
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantAssignmentIssue.cs
  3. 31
      ICSharpCode.NRefactory.CSharp/Refactoring/VariableReferenceGraph.cs

5
ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/MultipleEnumerationIssue.cs

@ -241,12 +241,13 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
FindReferences (variableDecl, rootNode, resolveResult.Variable); FindReferences (variableDecl, rootNode, resolveResult.Variable);
var statements = AnalysisStatementCollector.Collect (variableDecl); var statements = AnalysisStatementCollector.Collect (variableDecl);
var builder = new VariableReferenceGraphBuilder (ctx);
foreach (var statement in statements) { foreach (var statement in statements) {
var vrNode = VariableReferenceGraphBuilder.Build (statement, references, refStatements, ctx); var vrNode = builder.Build (statement, references, refStatements, ctx);
FindMultipleEnumeration (vrNode); FindMultipleEnumeration (vrNode);
} }
foreach (var lambda in lambdaExpressions) { foreach (var lambda in lambdaExpressions) {
var vrNode = VariableReferenceGraphBuilder.Build (references, ctx.Resolver, (Expression)lambda.Body); var vrNode = builder.Build (references, ctx.Resolver, (Expression)lambda.Body);
FindMultipleEnumeration (vrNode); FindMultipleEnumeration (vrNode);
} }
} }

2
ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantAssignmentIssue.cs

@ -121,7 +121,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
if (usedInLambda) if (usedInLambda)
return; return;
var startNode = VariableReferenceGraphBuilder.Build (rootStatement, references, refStatements, ctx); var startNode = new VariableReferenceGraphBuilder (ctx).Build (rootStatement, references, refStatements, ctx);
var variableInitializer = variableDecl as VariableInitializer; var variableInitializer = variableDecl as VariableInitializer;
if (variableInitializer != null && !variableInitializer.Initializer.IsNull) if (variableInitializer != null && !variableInitializer.Initializer.IsNull)
startNode.References.Insert (0, variableInitializer); startNode.References.Insert (0, variableInitializer);

31
ICSharpCode.NRefactory.CSharp/Refactoring/VariableReferenceGraph.cs

@ -65,23 +65,30 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
class VariableReferenceGraphBuilder class VariableReferenceGraphBuilder
{ {
static ControlFlowGraphBuilder cfgBuilder = new ControlFlowGraphBuilder (); ControlFlowGraphBuilder cfgBuilder = new ControlFlowGraphBuilder ();
static CfgVariableReferenceNodeBuilder cfgVrNodeBuilder = new CfgVariableReferenceNodeBuilder (); CfgVariableReferenceNodeBuilder cfgVrNodeBuilder;
BaseRefactoringContext ctx;
public static VariableReferenceNode Build (ISet<AstNode> references, CSharpAstResolver resolver, public VariableReferenceGraphBuilder(BaseRefactoringContext ctx)
{
this.ctx = ctx;
cfgVrNodeBuilder = new CfgVariableReferenceNodeBuilder (this);
}
public VariableReferenceNode Build (ISet<AstNode> references, CSharpAstResolver resolver,
Expression expression) Expression expression)
{ {
return ExpressionNodeCreationVisitor.CreateNode (references, resolver, new [] { expression }); return ExpressionNodeCreationVisitor.CreateNode (references, resolver, new [] { expression });
} }
public static VariableReferenceNode Build (Statement statement, ISet<AstNode> references, public VariableReferenceNode Build (Statement statement, ISet<AstNode> references,
ISet<Statement> refStatements, BaseRefactoringContext context) ISet<Statement> refStatements, BaseRefactoringContext context)
{ {
var cfg = cfgBuilder.BuildControlFlowGraph (statement, context.Resolver, context.CancellationToken); var cfg = cfgBuilder.BuildControlFlowGraph (statement, context.Resolver, context.CancellationToken);
return cfgVrNodeBuilder.Build (cfg [0], references, refStatements, context.Resolver); return cfgVrNodeBuilder.Build (cfg [0], references, refStatements, context.Resolver);
} }
public static VariableReferenceNode Build (Statement statement, ISet<AstNode> references, public VariableReferenceNode Build (Statement statement, ISet<AstNode> references,
ISet<Statement> refStatements, CSharpAstResolver resolver, CancellationToken cancellationToken = default(CancellationToken)) ISet<Statement> refStatements, CSharpAstResolver resolver, CancellationToken cancellationToken = default(CancellationToken))
{ {
var cfg = cfgBuilder.BuildControlFlowGraph (statement, resolver, cancellationToken); var cfg = cfgBuilder.BuildControlFlowGraph (statement, resolver, cancellationToken);
@ -169,13 +176,19 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
class CfgVariableReferenceNodeBuilder class CfgVariableReferenceNodeBuilder
{ {
static GetExpressionsVisitor getExpr = new GetExpressionsVisitor (); readonly VariableReferenceGraphBuilder variableReferenceGraphBuilder;
GetExpressionsVisitor getExpr = new GetExpressionsVisitor ();
ISet<AstNode> references; ISet<AstNode> references;
ISet<Statement> refStatements; ISet<Statement> refStatements;
CSharpAstResolver resolver; CSharpAstResolver resolver;
Dictionary<ControlFlowNode, VariableReferenceNode> nodeDict; Dictionary<ControlFlowNode, VariableReferenceNode> nodeDict;
public CfgVariableReferenceNodeBuilder(VariableReferenceGraphBuilder variableReferenceGraphBuilder)
{
this.variableReferenceGraphBuilder = variableReferenceGraphBuilder;
}
public VariableReferenceNode Build (ControlFlowNode startNode, ISet<AstNode> references, public VariableReferenceNode Build (ControlFlowNode startNode, ISet<AstNode> references,
ISet<Statement> refStatements, CSharpAstResolver resolver) ISet<Statement> refStatements, CSharpAstResolver resolver)
{ {
@ -214,6 +227,8 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
var node = new VariableReferenceNode (); var node = new VariableReferenceNode ();
var cfNode = startNode; var cfNode = startNode;
while (true) { while (true) {
if (variableReferenceGraphBuilder.ctx.CancellationToken.IsCancellationRequested)
return null;
if (nodeDict.ContainsKey (cfNode)) { if (nodeDict.ContainsKey (cfNode)) {
node.AddNextNode (nodeDict [cfNode]); node.AddNextNode (nodeDict [cfNode]);
break; break;
@ -246,12 +261,12 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
if (tryc != null) { if (tryc != null) {
VariableReferenceNode outNode = null; VariableReferenceNode outNode = null;
foreach (var n in tryc.CatchClauses) { foreach (var n in tryc.CatchClauses) {
var catchNode = VariableReferenceGraphBuilder.Build(n.Body, references, refStatements, this.resolver); var catchNode = variableReferenceGraphBuilder.Build(n.Body, references, refStatements, this.resolver);
(outNode ?? node).AddNextNode (catchNode); (outNode ?? node).AddNextNode (catchNode);
outNode = catchNode; outNode = catchNode;
} }
if (!tryc.FinallyBlock.IsNull) { if (!tryc.FinallyBlock.IsNull) {
var finallyNode = VariableReferenceGraphBuilder.Build(tryc.FinallyBlock, references, refStatements, this.resolver); var finallyNode = variableReferenceGraphBuilder.Build(tryc.FinallyBlock, references, refStatements, this.resolver);
(outNode ?? node).AddNextNode (finallyNode); (outNode ?? node).AddNextNode (finallyNode);
outNode = finallyNode; outNode = finallyNode;
} }

Loading…
Cancel
Save