public bool Equals(NumericalValue <T> other) { var enumerateThis = ranges.GetEnumerator(); var enumerateOther = other.ranges.GetEnumerator(); while (true) { if (enumerateThis.MoveNext()) { if (enumerateOther.MoveNext()) { if (!enumerateThis.Current.Equals(enumerateOther.Current)) { return(false); } } else { return(false); } } else { if (enumerateOther.MoveNext()) { return(false); } else { return(true); } } } }
/* * private class Range * { * public MinPair min; * public MaxPair max; * * public Range(MinPair min, MaxPair max) * { * this.min = min; * this.max = max; * } * } * * private class MinPair * { * T value; * Inclusivity inclusivity; * * public MinPair(T value, Inclusivity inclusivity) * { * this.value = value; * this.inclusivity = inclusivity; * } * * public static bool operator==(MinPair self, MinPair other) * { * return self.value == other.value && self.inclusivity == other.inclusivity; * } * public static bool operator!=(MinPair self, MinPair other) { return self != other; } * } * * private class MaxPair * { * T value; * Inclusivity inclusivity; * * public MaxPair(T value, Inclusivity inclusivity) * { * this.value = value; * this.inclusivity = inclusivity; * } * } */ public void UnionWith(NumericalValue <T> other) { foreach (Range n in other.ranges) { UnionWith(n); } }
public void IntersectWith(NumericalValue <T> other) { NumericalValue <T> output = new NumericalValue <T>(); foreach (var r in other.ranges) { NumericalValue <T> c = this.Clone(); c.IntersectWith(r); output.UnionWith(c); } this.ranges = output.ranges; }
public void AssignValue(NumericalValue <T> other) { this.ranges = new SortedSet <Range>(other.ranges); }
private void analyze(ControlFlowGraph graph, SyntaxNode node, Dictionary <string, NumericalValue <int> > variables, Dictionary <SyntaxNode, Dictionary <string, NumericalValue <int> > > history) { #region Union usagesAfter with reachingDefinitions if (history.ContainsKey(node)) { bool anyChanged = false; foreach (var pair in history[node]) { if (variables.ContainsKey(pair.Key)) { var i = variables[pair.Key]; string old = i.ToString(); //Console.WriteLine("{0} vs {1} and {2}", old, i, pair.Value); i.UnionWith(pair.Value); if (!old.Equals(i.ToString())) { anyChanged = true; } } else { variables.Add(pair.Key, pair.Value.Clone()); anyChanged = true; } } if (history[node].Count == 0 && variables.Count != 0) { anyChanged = true; } if (!anyChanged) { return; } else { var clone = new Dictionary <string, NumericalValue <int> >(); foreach (var v in variables) { clone.Add(v.Key, v.Value.Clone()); } history[node] = clone; } } else { var clone = new Dictionary <string, NumericalValue <int> >(); foreach (var v in variables) { clone.Add(v.Key, v.Value.Clone()); } history.Add(node, clone); } #endregion NumericalValue <int> rangeTrue = null; NumericalValue <int> rangeFalse = null; string rangeVar = null; #region Process node if (node is LocalDeclarationStatementSyntax || node is VariableDeclarationSyntax) { VariableDeclarationSyntax s; if (node is LocalDeclarationStatementSyntax) { s = (node as LocalDeclarationStatementSyntax).Declaration; } else { s = node as VariableDeclarationSyntax; } foreach (var v in s.Variables) { if (v.Initializer != null) { if (v.Initializer.Value is LiteralExpressionSyntax) { var valS = (v.Initializer.Value as LiteralExpressionSyntax).Token.ValueText; int valI; if (int.TryParse(valS, out valI)) { var valNV = new NumericalValue <int>(valI); if (variables.ContainsKey(v.Identifier.ToString())) { variables[v.Identifier.ToString()].AssignValue(valNV); } else { variables.Add(v.Identifier.ToString(), valNV); } } } else if (v.Initializer.Value is IdentifierNameSyntax) { var valNV = variables[v.Initializer.Value.ToString()]; if (variables.ContainsKey(v.Identifier.ToString())) { variables[v.Identifier.ToString()].AssignValue(valNV); } else { variables.Add(v.Identifier.ToString(), valNV); } } else { var valNV = new NumericalValue <int>(int.MinValue, Inclusivity.INCLUSIVE, int.MaxValue, Inclusivity.INCLUSIVE); if (variables.ContainsKey(v.Identifier.ToString())) { variables[v.Identifier.ToString()].AssignValue(valNV); } else { variables.Add(v.Identifier.ToString(), valNV); } } } } } else if (node is ExpressionStatementSyntax && (node as ExpressionStatementSyntax).Expression is AssignmentExpressionSyntax) { var s = (node as ExpressionStatementSyntax).Expression as AssignmentExpressionSyntax; if (s.Right is LiteralExpressionSyntax) { var valS = (s.Right as LiteralExpressionSyntax).Token.ValueText; int valI; if (int.TryParse(valS, out valI)) { var valNV = new NumericalValue <int>(valI); if (variables.ContainsKey(s.Left.ToString())) { variables[s.Left.ToString()].AssignValue(valNV); } else { variables.Add(s.Left.ToString(), valNV); } } } else if (s.Right is IdentifierNameSyntax) { var valNV = variables[s.Right.ToString()]; if (variables.ContainsKey(s.Left.ToString())) { variables[s.Left.ToString()].AssignValue(valNV); } else { variables.Add(s.Left.ToString(), valNV); } } else { var valNV = new NumericalValue <int>(int.MinValue, Inclusivity.INCLUSIVE, int.MaxValue, Inclusivity.INCLUSIVE); if (variables.ContainsKey(s.Left.ToString())) { variables[s.Left.ToString()].AssignValue(valNV); } else { variables.Add(s.Left.ToString(), valNV); } } } else if (node is BinaryExpressionSyntax) { var n = node as BinaryExpressionSyntax; if (n.Right is LiteralExpressionSyntax) { int value; if (int.TryParse((n.Right as LiteralExpressionSyntax).Token.ValueText, out value)) { if (n.OperatorToken.ToString().Equals("<")) { rangeTrue = new NumericalValue <int>(int.MinValue, Inclusivity.INCLUSIVE, value, Inclusivity.EXCLUSIVE); rangeFalse = new NumericalValue <int>(value, Inclusivity.INCLUSIVE, int.MaxValue, Inclusivity.INCLUSIVE); rangeVar = n.Left.ToString(); } if (n.OperatorToken.ToString().Equals("<=")) { rangeTrue = new NumericalValue <int>(int.MinValue, Inclusivity.INCLUSIVE, value, Inclusivity.INCLUSIVE); rangeFalse = new NumericalValue <int>(value, Inclusivity.EXCLUSIVE, int.MaxValue, Inclusivity.INCLUSIVE); rangeVar = n.Left.ToString(); } if (n.OperatorToken.ToString().Equals(">")) { rangeTrue = new NumericalValue <int>(value, Inclusivity.EXCLUSIVE, int.MaxValue, Inclusivity.INCLUSIVE); rangeFalse = new NumericalValue <int>(int.MinValue, Inclusivity.INCLUSIVE, value, Inclusivity.INCLUSIVE); rangeVar = n.Left.ToString(); } if (n.OperatorToken.ToString().Equals(">=")) { rangeTrue = new NumericalValue <int>(value, Inclusivity.INCLUSIVE, int.MaxValue, Inclusivity.INCLUSIVE); rangeFalse = new NumericalValue <int>(int.MinValue, Inclusivity.INCLUSIVE, value, Inclusivity.EXCLUSIVE); rangeVar = n.Left.ToString(); } } } } if (debug) { Console.WriteLine("({0}): {1} {2}", node.GetLocation().GetLineSpan().StartLinePosition, node, node.GetType()); foreach (var pair in variables) { Console.WriteLine(" {0} -> {1}", pair.Key, pair.Value); } } #endregion #region Recurse foreach (var succ in graph.GetSuccessorsB(node)) { var variablesPrime = new Dictionary <string, NumericalValue <int> >(); foreach (var v in variables) { variablesPrime.Add(v.Key, v.Value.Clone()); } if (succ.Value == 0) { variablesPrime[rangeVar].IntersectWith(rangeFalse); } else if (succ.Value == 1) { variablesPrime[rangeVar].IntersectWith(rangeTrue); } analyze(graph, succ.Key, variablesPrime, history); } #endregion }