/// <summary> /// Wires an else/else if block. The block starts at <paramref name="stepIndex"/> in steps. The complete wiring is made and <paramref name="stepIndex"/> finally is set to the index of the end if step. /// The given lists/matrices are correctly updated. /// </summary> /// <param name="steps">See <paramref name="steps"/> in <see cref="SetEdgesInstepBlock"/>.</param> /// <param name="edgeMatrix">See <paramref name="edgeMatrix"/> in <see cref="SetEdgesInstepBlock"/>.</param> /// <param name="externalEdges">See <paramref name="externalEdges"/> in <see cref="SetEdgesInstepBlock"/>.</param> /// <param name="possibleInvalidIfEdges">See <paramref name="possibleInvalidIfEdges"/> in <see cref="SetEdgesInstepBlock"/>.</param> /// <param name="conditionMatrix">See <paramref name="conditionMatrix"/> in <see cref="SetEdgesInstepBlock"/>.</param> /// <param name="stepIndex">On call the current index in the steps where the else/else if start step is located and after the call the index of the end if step.</param> public static void SetEdgesInElseElseIfStatement( IReadOnlyList <Node> steps, ref Matrix <bool> edgeMatrix, ref List <ExternalEdge> externalEdges, ref List <InternalEdge> possibleInvalidIfEdges, ref Matrix <Condition?> conditionMatrix, ref int stepIndex) { List <int> importantIfSteps = GraphBuilder.GetImportantIfStatementSteps(steps, stepIndex); // Handle nested blocks int lastBlockStartIndex = -1, endIfStepIndex = importantIfSteps.Last(); for (int blockIndex = 0; blockIndex < importantIfSteps.Count - 1; blockIndex++) { int blockStartIndex = importantIfSteps[blockIndex], blockEndIndex = importantIfSteps[blockIndex + 1], blockSize = blockEndIndex - blockStartIndex - 1; StepType blockStartStepType = GraphBuilder.GetStepType(steps[blockStartIndex].StepDescription); // Set edge from last step to start of block if (blockIndex > 0) { edgeMatrix[lastBlockStartIndex, blockStartIndex] = true; conditionMatrix[lastBlockStartIndex, blockStartIndex] = new Condition(steps[lastBlockStartIndex].StepDescription, false); } if (blockSize > 0) { GraphBuilder.SetEdgesInNestedBlock( steps, ref edgeMatrix, ref externalEdges, ref possibleInvalidIfEdges, ref conditionMatrix, blockStartIndex, blockEndIndex, endIfStepIndex, blockStartStepType == StepType.Else ? (Condition?)null : new Condition(steps[blockStartIndex].StepDescription, true)); } else { // Wire block start step to endif step edgeMatrix[blockStartIndex, endIfStepIndex] = true; } lastBlockStartIndex = blockStartIndex; } // If last block is not a else block make an edge from the block start with false conditon to end if step. lastBlockStartIndex = importantIfSteps[importantIfSteps.Count - 2]; int lastBlockEndIndex = importantIfSteps[importantIfSteps.Count - 1], lastBlockSize = lastBlockEndIndex - lastBlockStartIndex - 1; StepType lastBlockStartStepType = GraphBuilder.GetStepType(steps[lastBlockStartIndex].StepDescription); if (lastBlockStartStepType != StepType.Else && lastBlockSize > 0) { edgeMatrix[lastBlockStartIndex, lastBlockEndIndex] = true; conditionMatrix[lastBlockStartIndex, lastBlockEndIndex] = new Condition(steps[lastBlockStartIndex].StepDescription, false); } // Set current step index to end if step. stepIndex = endIfStepIndex; }
/// <summary> /// Wires an if block. The if block starts at <paramref name="stepIndex"/> in steps. The complete wiring is made and <paramref name="stepIndex"/> finally is set to the index of the end if step. /// The given lists/matrices are correctly updated. /// <para/> /// To visualize what is assumed a block if talking about it: /// <para/> /// IF /// <para/> /// Nested block step /// <para/> /// ELSE /// </summary> /// <param name="steps">See <paramref name="steps"/> in <see cref="SetEdgesInstepBlock"/>.</param> /// <param name="edgeMatrix">See <paramref name="edgeMatrix"/> in <see cref="SetEdgesInstepBlock"/>.</param> /// <param name="externalEdges">See <paramref name="externalEdges"/> in <see cref="SetEdgesInstepBlock"/>.</param> /// <param name="possibleInvalidIfEdges">See <paramref name="possibleInvalidIfEdges"/> in <see cref="SetEdgesInstepBlock"/>.</param> /// <param name="conditionMatrix">See <paramref name="conditionMatrix"/> in <see cref="SetEdgesInstepBlock"/>.</param> /// <param name="stepIndex">On call the current index in the steps where the if start step is located and after the call the index of the end if step.</param> public static void SetEdgesInIfStatement( IReadOnlyList <Node> steps, ref Matrix <bool> edgeMatrix, ref List <ExternalEdge> externalEdges, ref List <InternalEdge> possibleInvalidIfEdges, ref Matrix <Condition?> conditionMatrix, ref int stepIndex) { List <int> importantIfSteps = GraphBuilder.GetImportantIfStatementSteps(steps, stepIndex); // Handle nested blocks int ifStepIndex = importantIfSteps.First(), lastBlockStartIndex = -1, endIfStepIndex = importantIfSteps.Last(); for (int blockIndex = 0; blockIndex < importantIfSteps.Count - 1; blockIndex++) { int blockStartIndex = importantIfSteps[blockIndex], blockEndIndex = importantIfSteps[blockIndex + 1], blockSize = blockEndIndex - blockStartIndex - 1; StepType blockStartStepType = GraphBuilder.GetStepType(steps[blockStartIndex].StepDescription); // Set edge from last step to start of block if (blockIndex > 0) { edgeMatrix[lastBlockStartIndex, blockStartIndex] = true; conditionMatrix[lastBlockStartIndex, blockStartIndex] = new Condition(steps[lastBlockStartIndex].StepDescription, false); } if (blockSize > 0) { GraphBuilder.SetEdgesInNestedBlock( steps, ref edgeMatrix, ref externalEdges, ref possibleInvalidIfEdges, ref conditionMatrix, blockStartIndex, blockEndIndex, endIfStepIndex, blockStartStepType == StepType.Else ? (Condition?)null : new Condition(steps[blockStartIndex].StepDescription, true)); } else { // Wire block start step to endif step edgeMatrix[blockStartIndex, endIfStepIndex] = true; // If it is not the last block then the edge to the end if has a condition if (blockIndex < importantIfSteps.Count - 2) { conditionMatrix[blockStartIndex, endIfStepIndex] = new Condition(steps[blockStartIndex].StepDescription, true); } } lastBlockStartIndex = blockStartIndex; } // If last block is not a else block make an edge from the block start with false conditon to end if step. lastBlockStartIndex = importantIfSteps[importantIfSteps.Count - 2]; int lastBlockEndIndex = importantIfSteps[importantIfSteps.Count - 1], lastBlockSize = lastBlockEndIndex - lastBlockStartIndex - 1; StepType lastBlockStartStepType = GraphBuilder.GetStepType(steps[lastBlockStartIndex].StepDescription); if (lastBlockStartStepType != StepType.Else && lastBlockSize > 0) { edgeMatrix[lastBlockStartIndex, lastBlockEndIndex] = true; conditionMatrix[lastBlockStartIndex, lastBlockEndIndex] = new Condition(steps[lastBlockStartIndex].StepDescription, false); } // If there are no else if or else blocks it might be that they are located in alternative flows or that there are none. // List that edge as possible invalid as it was previously created. if (importantIfSteps.Count <= 2) { possibleInvalidIfEdges.Add(new InternalEdge(ifStepIndex, endIfStepIndex)); } // Set current step index to end if step. stepIndex = endIfStepIndex; }