public void EmptyThrowExceptionNodeCreatedProperly() { var graphId = new FlowGraphId(1); var builder = new FlowGraphBuilder(graphId); var location = new TestRoutineLocation("ExceptionConstructor"); var node = builder.AddThrowExceptionNode(location); FlowGraphTestHelper.CheckThrowExceptionNode(node, builder.Graph, 0, 0, location, 0); }
public void EmptyCallNodeCreatedProperly() { var graphId = new FlowGraphId(1); var builder = new FlowGraphBuilder(graphId); var location = new TestRoutineLocation("CalledRoutine"); var node = builder.AddCallNode(location); FlowGraphTestHelper.CheckCallNode(node, builder.Graph, 0, 0, location, 0, 0); }
public static FlowGraph ComplexExampleGraph(FlowGraphId id) { var builder = new FlowGraphBuilder(id); var aVar = builder.AddLocalVariable(Sort.Int, "a"); var a = (IntHandle)aVar; var bVar = builder.AddLocalVariable(Sort.Int, "b"); var b = (IntHandle)bVar; var cVar = builder.AddLocalVariable(Sort.Bool, "c"); var c = (BoolHandle)cVar; var enterNode = builder.AddEnterNode(new[] { aVar, bVar, cVar }); var if1Var = builder.AddLocalVariable(Sort.Bool, "if!1"); var if1 = (BoolHandle)if1Var; var if1Node = builder.AddInnerNode(new Assignment(if1Var, a == 0)); var ret1Node = builder.AddReturnNode(new[] { ExpressionFactory.IntInterpretation(-1) }); var isNiceNumberLocation = new TestRoutineLocation("IsNiceNumber"); var if21Var = builder.AddLocalVariable(Sort.Bool, "if!2!1"); var if21 = (BoolHandle)if21Var; var if21Node = builder.AddCallNode(isNiceNumberLocation, new[] { aVar }, new[] { if21Var }); var if22CheckVar = builder.AddLocalVariable(Sort.Bool, "if!2!2!check"); var if22Check = (BoolHandle)if22CheckVar; var if22CheckNode = builder.AddInnerNode(new Assignment(if22CheckVar, b != 0)); var exceptionLocation = new TestRoutineLocation("DivisionByZeroException"); var if22ThrowNode = builder.AddThrowExceptionNode(exceptionLocation); var if22Var = builder.AddLocalVariable(Sort.Bool, "if!2!2"); var if22 = (BoolHandle)if22Var; var if22Node = builder.AddInnerNode(new Assignment(if22Var, a / b > 2 && b != -1)); var dVar = builder.AddLocalVariable(Sort.Int, "d"); var d = (IntHandle)dVar; var dEqualsBNode = builder.AddInnerNode(new Assignment(dVar, bVar)); var while1Var = builder.AddLocalVariable(Sort.Bool, "while!1"); var while1 = (BoolHandle)while1Var; var while1Node = builder.AddInnerNode(new[] { new Assignment(while1Var, a < b) }, FlowNodeFlags.LoopCondition); var assert1Var = builder.AddLocalVariable(Sort.Bool, "assert!1"); var assert1 = (BoolHandle)assert1Var; var whileBodyNode = builder.AddInnerNode( new[] { new Assignment(aVar, a + a), new Assignment(assert1Var, a != 0) }, FlowNodeFlags.LoopBody); var elseBodyNode = builder.AddInnerNode(new Assignment(aVar, a + b)); var ret2Node = builder.AddReturnNode(new[] { aVar }); builder.AddEdge(enterNode, if1Node); builder.AddEdge(if1Node, ret1Node, if1); builder.AddEdge(if1Node, if21Node, !if1); builder.AddEdge(if21Node, if22CheckNode, if21); builder.AddEdge(if22CheckNode, if22ThrowNode, !if22Check); builder.AddEdge(if22CheckNode, if22Node, if22Check); builder.AddEdge(if22Node, dEqualsBNode, if22); builder.AddEdge(dEqualsBNode, while1Node); builder.AddEdge(while1Node, whileBodyNode, while1); builder.AddEdge(whileBodyNode, while1Node); builder.AddEdge(while1Node, ret2Node, !while1); builder.AddEdge(if21Node, elseBodyNode, !if21); builder.AddEdge(if22Node, elseBodyNode, !if22); builder.AddEdge(elseBodyNode, ret2Node); return(builder.FreezeAndReleaseGraph()); }
public TestFlowGraphProvider(Type generatorClass) { Contract.Requires(generatorClass != null); var generators = generatorClass .GetMethods(BindingFlags.Public | BindingFlags.Static) .Where( methodInfo => methodInfo.ReturnType == typeof(FlowGraph) && !methodInfo.ContainsGenericParameters && methodInfo.GetParameters() .Select(p => p.ParameterType) .SequenceEqual(new[] { typeof(FlowGraphId) })); var generatorToGraphMap = new Dictionary <MethodInfo, FlowGraph>(); var locations = new List <TestRoutineLocation>(); var graphs = new List <FlowGraph>(); // We have to generate all the graphs beforehand due to immutability int id = 0; foreach (var generator in generators) { var props = generator.GetCustomAttribute <GeneratedMethodPropertiesAttribute>() ?? new GeneratedMethodPropertiesAttribute(); var graph = (FlowGraph)generator.Invoke(null, new object[] { new FlowGraphId(id) }); var location = new TestRoutineLocation(generator, props.IsConstructor); generatorToGraphMap.Add(generator, graph); graphs.Add(graph); locations.Add(location); id++; } // Gather a list of call nodes for each graph being called var graphCallSites = new List <CallFlowNode> [graphs.Count]; foreach (var callNode in graphs.SelectMany(g => g.Nodes).OfType <CallFlowNode>()) { if (callNode.Location.CanBeExplored) { var calledGen = ((TestRoutineLocation)callNode.Location).Generator; var calledId = generatorToGraphMap[calledGen].Id; if (graphCallSites[calledId.Value] == null) { graphCallSites[calledId.Value] = new List <CallFlowNode>() { callNode }; } else { graphCallSites[calledId.Value].Add(callNode); } } } this.generatorToGraphMap = new ReadOnlyDictionary <MethodInfo, FlowGraph>(generatorToGraphMap); this.graphs = graphs.ToImmutableArray(); this.graphCallSites = graphCallSites .Select(c => c?.ToImmutableArray() ?? ImmutableArray <CallFlowNode> .Empty) .ToImmutableArray(); this.locations = locations.ToImmutableArray(); this.GeneratedMethodLocations = locations.ToImmutableArray(); }