/// <summary> /// Constructs the node using information from the given state transitions /// and action bindings. /// </summary> /// <param name="stateTransitions">State transitions</param> /// <param name="actionBindings">Action bindings</param> /// <param name="visited">Already visited nodes</param> private void Construct(Dictionary <ClassDeclarationSyntax, HashSet <ClassDeclarationSyntax> > stateTransitions, Dictionary <ClassDeclarationSyntax, HashSet <MethodDeclarationSyntax> > actionBindings, HashSet <StateTransitionGraphNode> visited) { visited.Add(this); foreach (var method in this.State.ChildNodes().OfType <MethodDeclarationSyntax>()) { var summary = MethodSummary.Factory.Summarize(method); if (method.Modifiers.Any(SyntaxKind.OverrideKeyword) && method.Identifier.ValueText.Equals("OnEntry")) { this.OnEntry = summary; } else if (method.Modifiers.Any(SyntaxKind.OverrideKeyword) && method.Identifier.ValueText.Equals("OnExit")) { this.OnExit = summary; } } var actions = new HashSet <MethodDeclarationSyntax>(); if (actionBindings.ContainsKey(this.State)) { actions = actionBindings[this.State]; } foreach (var action in actions) { var actionSummary = MethodSummary.Factory.Summarize(action); this.Actions.Add(actionSummary); } var transitions = new HashSet <ClassDeclarationSyntax>(); if (stateTransitions.ContainsKey(this.State)) { transitions = stateTransitions[this.State]; } foreach (var successorState in transitions) { var successor = visited.FirstOrDefault(v => v.State.Equals(successorState)); if (successor != null) { this.ISuccessors.Add(successor); successor.IPredecessors.Add(this); } else { successor = new StateTransitionGraphNode(successorState, this.Machine); this.ISuccessors.Add(successor); successor.IPredecessors.Add(this); successor.Construct(stateTransitions, actionBindings, visited); } } }
/// <summary> /// Tries to construct the state transition graph for the given machine. /// </summary> /// <param name="machine">Machine</param> private static void ConstructGraphForMachine(ClassDeclarationSyntax machine) { var model = AnalysisContext.Compilation.GetSemanticModel(machine.SyntaxTree); Dictionary <ClassDeclarationSyntax, HashSet <ClassDeclarationSyntax> > stateTransitions = null; StateTransitionAnalysis.TryParseStateTransitions(out stateTransitions, machine, model); Dictionary <ClassDeclarationSyntax, HashSet <MethodDeclarationSyntax> > actionBindings = null; StateTransitionAnalysis.TryParseActionBindings(out actionBindings, machine, model); StateTransitionAnalysis.ComputeStatistics(stateTransitions, actionBindings); ClassDeclarationSyntax initState = null; foreach (var state in stateTransitions) { foreach (var attributeList in state.Key.AttributeLists) { foreach (var attribute in attributeList.Attributes) { if (attribute.Name.ToString().Equals("Microsoft.PSharp.Start")) { initState = state.Key; } } } } if (initState == null) { return; } var initNode = new StateTransitionGraphNode(initState, machine); initNode.IsStartNode = true; initNode.Construct(stateTransitions, actionBindings); AnalysisContext.StateTransitionGraphs.Add(machine, initNode); }
/// <summary> /// Tries to construct the state transition graph for the given machine. /// </summary> /// <param name="machine">Machine</param> private void ConstructGraphForMachine(ClassDeclarationSyntax machine) { var model = AnalysisContext.Compilation.GetSemanticModel(machine.SyntaxTree); Dictionary<ClassDeclarationSyntax, HashSet<ClassDeclarationSyntax>> stateTransitions = null; this.TryParseStateTransitions(out stateTransitions, machine, model); Dictionary<ClassDeclarationSyntax, HashSet<MethodDeclarationSyntax>> actionBindings = null; this.TryParseActionBindings(out actionBindings, machine, model); this.ComputeStatistics(stateTransitions, actionBindings); ClassDeclarationSyntax initState = null; foreach (var state in stateTransitions) { foreach (var attributeList in state.Key.AttributeLists) { foreach (var attribute in attributeList.Attributes) { if (attribute.Name.ToString().Equals("Microsoft.PSharp.Start")) { initState = state.Key; } } } } if (initState == null) { return; } var initNode = new StateTransitionGraphNode(this.AnalysisContext, initState, machine); initNode.IsStartNode = true; initNode.Construct(stateTransitions, actionBindings); AnalysisContext.StateTransitionGraphs.Add(machine, initNode); }
/// <summary> /// Constructs the node using information from the given state transitions /// and action bindings. /// </summary> /// <param name="stateTransitions">State transitions</param> /// <param name="actionBindings">Action bindings</param> /// <param name="visited">Already visited nodes</param> private void Construct(Dictionary<ClassDeclarationSyntax, HashSet<ClassDeclarationSyntax>> stateTransitions, Dictionary<ClassDeclarationSyntax, HashSet<MethodDeclarationSyntax>> actionBindings, HashSet<StateTransitionGraphNode> visited) { visited.Add(this); foreach (var method in this.State.ChildNodes().OfType<MethodDeclarationSyntax>()) { var summary = MethodSummary.Factory.Summarize(this.AnalysisContext, method); if (method.Modifiers.Any(SyntaxKind.OverrideKeyword) && method.Identifier.ValueText.Equals("OnEntry")) { this.OnEntry = summary; } else if (method.Modifiers.Any(SyntaxKind.OverrideKeyword) && method.Identifier.ValueText.Equals("OnExit")) { this.OnExit = summary; } } var actions = new HashSet<MethodDeclarationSyntax>(); if (actionBindings.ContainsKey(this.State)) { actions = actionBindings[this.State]; } foreach (var action in actions) { var actionSummary = MethodSummary.Factory.Summarize(this.AnalysisContext, action); this.Actions.Add(actionSummary); } var transitions = new HashSet<ClassDeclarationSyntax>(); if (stateTransitions.ContainsKey(this.State)) { transitions = stateTransitions[this.State]; } foreach (var successorState in transitions) { var successor = visited.FirstOrDefault(v => v.State.Equals(successorState)); if (successor != null) { this.ISuccessors.Add(successor); successor.IPredecessors.Add(this); } else { successor = new StateTransitionGraphNode(this.AnalysisContext, successorState, this.Machine); this.ISuccessors.Add(successor); successor.IPredecessors.Add(this); successor.Construct(stateTransitions, actionBindings, visited); } } }