Browse Source

Fixed issues with control flow analysis on incomplete AST.

newNRvisualizers
Daniel Grunwald 13 years ago
parent
commit
6bb526a8e3
  1. 48
      ICSharpCode.NRefactory.CSharp/Analysis/ControlFlow.cs

48
ICSharpCode.NRefactory.CSharp/Analysis/ControlFlow.cs

@ -249,6 +249,8 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis
#region Create*Node #region Create*Node
ControlFlowNode CreateStartNode(Statement statement) ControlFlowNode CreateStartNode(Statement statement)
{ {
if (statement.IsNull)
return null;
ControlFlowNode node = CreateNode(null, statement, ControlFlowNodeType.StartNode); ControlFlowNode node = CreateNode(null, statement, ControlFlowNodeType.StartNode);
nodes.Add(node); nodes.Add(node);
return node; return node;
@ -295,6 +297,8 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis
/// <returns>The constant value of the expression; or null if the expression is not a constant.</returns> /// <returns>The constant value of the expression; or null if the expression is not a constant.</returns>
ResolveResult EvaluateConstant(Expression expr) ResolveResult EvaluateConstant(Expression expr)
{ {
if (expr.IsNull)
return null;
if (EvaluateOnlyPrimitiveConstants) { if (EvaluateOnlyPrimitiveConstants) {
if (!(expr is PrimitiveExpression || expr is NullReferenceExpression)) if (!(expr is PrimitiveExpression || expr is NullReferenceExpression))
return null; return null;
@ -337,6 +341,8 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis
internal ControlFlowEdge Connect(ControlFlowNode from, ControlFlowNode to, ControlFlowEdgeType type = ControlFlowEdgeType.Normal) internal ControlFlowEdge Connect(ControlFlowNode from, ControlFlowNode to, ControlFlowEdgeType type = ControlFlowEdgeType.Normal)
{ {
if (from == null || to == null)
return null;
ControlFlowEdge edge = builder.CreateEdge(from, to, type); ControlFlowEdge edge = builder.CreateEdge(from, to, type);
from.Outgoing.Add(edge); from.Outgoing.Add(edge);
to.Incoming.Add(edge); to.Incoming.Add(edge);
@ -406,30 +412,21 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis
public override ControlFlowNode VisitIfElseStatement(IfElseStatement ifElseStatement, ControlFlowNode data) public override ControlFlowNode VisitIfElseStatement(IfElseStatement ifElseStatement, ControlFlowNode data)
{ {
bool? cond = ifElseStatement.Condition.IsNull ? true : builder.EvaluateCondition(ifElseStatement.Condition); bool? cond = builder.EvaluateCondition(ifElseStatement.Condition);
if (ifElseStatement.TrueStatement.IsNull)
return data; ControlFlowNode trueBegin = builder.CreateStartNode(ifElseStatement.TrueStatement);
ControlFlowNode trueBegin; if (cond != false)
if (ifElseStatement.TrueStatement.IsNull) {
trueBegin = null;
} else {
trueBegin = builder.CreateStartNode(ifElseStatement.TrueStatement);
}
if (cond != false && trueBegin != null)
Connect(data, trueBegin, ControlFlowEdgeType.ConditionTrue); Connect(data, trueBegin, ControlFlowEdgeType.ConditionTrue);
ControlFlowNode trueEnd = trueBegin != null ? ifElseStatement.TrueStatement.AcceptVisitor(this, trueBegin) : null; ControlFlowNode trueEnd = ifElseStatement.TrueStatement.AcceptVisitor(this, trueBegin);
ControlFlowNode falseEnd;
if (ifElseStatement.FalseStatement.IsNull) { ControlFlowNode falseBegin = builder.CreateStartNode(ifElseStatement.FalseStatement);
falseEnd = null; if (cond != true)
} else { Connect(data, falseBegin, ControlFlowEdgeType.ConditionFalse);
ControlFlowNode falseBegin = builder.CreateStartNode(ifElseStatement.FalseStatement); ControlFlowNode falseEnd = ifElseStatement.FalseStatement.AcceptVisitor(this, falseBegin);
if (cond != true) // (if no else statement exists, both falseBegin and falseEnd will be null)
Connect(data, falseBegin, ControlFlowEdgeType.ConditionFalse);
falseEnd = ifElseStatement.FalseStatement.AcceptVisitor(this, falseBegin);
}
ControlFlowNode end = builder.CreateEndNode(ifElseStatement); ControlFlowNode end = builder.CreateEndNode(ifElseStatement);
if (trueEnd != null) Connect(trueEnd, end);
Connect(trueEnd, end);
if (falseEnd != null) { if (falseEnd != null) {
Connect(falseEnd, end); Connect(falseEnd, end);
} else if (cond != true) { } else if (cond != true) {
@ -543,7 +540,7 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis
Connect(data, conditionNode); Connect(data, conditionNode);
bool? cond = whileStatement.Condition.IsNull ? true : builder.EvaluateCondition(whileStatement.Condition); bool? cond = builder.EvaluateCondition(whileStatement.Condition);
ControlFlowNode bodyStart = builder.CreateStartNode(whileStatement.EmbeddedStatement); ControlFlowNode bodyStart = builder.CreateStartNode(whileStatement.EmbeddedStatement);
if (cond != false) if (cond != false)
Connect(conditionNode, bodyStart, ControlFlowEdgeType.ConditionTrue); Connect(conditionNode, bodyStart, ControlFlowEdgeType.ConditionTrue);
@ -571,7 +568,7 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis
ControlFlowNode bodyEnd = doWhileStatement.EmbeddedStatement.AcceptVisitor(this, bodyStart); ControlFlowNode bodyEnd = doWhileStatement.EmbeddedStatement.AcceptVisitor(this, bodyStart);
Connect(bodyEnd, conditionNode); Connect(bodyEnd, conditionNode);
bool? cond = doWhileStatement.Condition.IsNull ? true : builder.EvaluateCondition(doWhileStatement.Condition); bool? cond = builder.EvaluateCondition(doWhileStatement.Condition);
if (cond != false) if (cond != false)
Connect(conditionNode, bodyStart, ControlFlowEdgeType.ConditionTrue); Connect(conditionNode, bodyStart, ControlFlowEdgeType.ConditionTrue);
if (cond != true) if (cond != true)
@ -607,8 +604,7 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis
ControlFlowNode bodyStart = builder.CreateStartNode(forStatement.EmbeddedStatement); ControlFlowNode bodyStart = builder.CreateStartNode(forStatement.EmbeddedStatement);
ControlFlowNode bodyEnd = forStatement.EmbeddedStatement.AcceptVisitor(this, bodyStart); ControlFlowNode bodyEnd = forStatement.EmbeddedStatement.AcceptVisitor(this, bodyStart);
if (bodyEnd != null) Connect(bodyEnd, iteratorStart);
Connect(bodyEnd, iteratorStart);
breakTargets.Pop(); breakTargets.Pop();
continueTargets.Pop(); continueTargets.Pop();

Loading…
Cancel
Save