(strandsContext, conditional)
| 36 | } |
| 37 | } |
| 38 | function buildConditional(strandsContext, conditional) { |
| 39 | const cfg = strandsContext.cfg; |
| 40 | const branches = conditional.branches; |
| 41 | const mergeBlock = CFG.createBasicBlock(cfg, BlockType.MERGE); |
| 42 | const results = []; |
| 43 | const branchBlocks = []; |
| 44 | const branchEndBlocks = []; |
| 45 | const mergedAssignments = {}; |
| 46 | const phiBlockDependencies = {}; |
| 47 | // Create a BRANCH block to handle phi node declarations |
| 48 | const branchBlock = CFG.createBasicBlock(cfg, BlockType.BRANCH); |
| 49 | CFG.addEdge(cfg, cfg.currentBlock, branchBlock); |
| 50 | CFG.addEdge(cfg, branchBlock, mergeBlock); |
| 51 | let previousBlock = branchBlock; |
| 52 | for (let i = 0; i < branches.length; i++) { |
| 53 | const { condition, branchCallback, blockType } = branches[i]; |
| 54 | if (condition !== null) { |
| 55 | const conditionBlock = CFG.createBasicBlock(cfg, BlockType.IF_COND); |
| 56 | CFG.addEdge(cfg, previousBlock, conditionBlock); |
| 57 | CFG.pushBlock(cfg, conditionBlock); |
| 58 | cfg.blockConditions[conditionBlock] = condition.id; |
| 59 | previousBlock = conditionBlock; |
| 60 | CFG.popBlock(cfg); |
| 61 | } else { |
| 62 | const elseCondBlock = CFG.createBasicBlock(cfg, BlockType.ELSE_COND); |
| 63 | CFG.addEdge(cfg, previousBlock, elseCondBlock); |
| 64 | previousBlock = elseCondBlock; |
| 65 | } |
| 66 | const scopeStartBlock = CFG.createBasicBlock(cfg, BlockType.SCOPE_START); |
| 67 | CFG.addEdge(cfg, previousBlock, scopeStartBlock); |
| 68 | const branchContentBlock = CFG.createBasicBlock(cfg, blockType); |
| 69 | CFG.addEdge(cfg, scopeStartBlock, branchContentBlock); |
| 70 | branchBlocks.push(branchContentBlock); |
| 71 | CFG.pushBlock(cfg, branchContentBlock); |
| 72 | const branchResults = branchCallback(); |
| 73 | for (const key in branchResults) { |
| 74 | branchResults[key] = strandsContext.p5.strandsNode(branchResults[key]); |
| 75 | } |
| 76 | for (const key in branchResults) { |
| 77 | if (!phiBlockDependencies[key]) { |
| 78 | phiBlockDependencies[key] = [{ value: branchResults[key], blockId: branchContentBlock }]; |
| 79 | } else { |
| 80 | phiBlockDependencies[key].push({ value: branchResults[key], blockId: branchContentBlock }); |
| 81 | } |
| 82 | } |
| 83 | results.push(branchResults); |
| 84 | |
| 85 | // Create BRANCH_END block for phi assignments |
| 86 | const branchEndBlock = CFG.createBasicBlock(cfg, BlockType.DEFAULT); |
| 87 | CFG.addEdge(cfg, cfg.currentBlock, branchEndBlock); |
| 88 | branchEndBlocks.push(branchEndBlock); |
| 89 | CFG.popBlock(cfg); |
| 90 | |
| 91 | const scopeEndBlock = CFG.createBasicBlock(cfg, BlockType.SCOPE_END); |
| 92 | CFG.addEdge(cfg, branchEndBlock, scopeEndBlock); |
| 93 | CFG.addEdge(cfg, scopeEndBlock, mergeBlock); |
| 94 | previousBlock = scopeStartBlock; |
| 95 | } |
no test coverage detected