| 80 | |
| 81 | |
| 82 | class BranchStatement: |
| 83 | def __init__(self, initial_state: BranchState | None = None) -> None: |
| 84 | if initial_state is None: |
| 85 | initial_state = BranchState() |
| 86 | self.initial_state = initial_state |
| 87 | self.branches: list[BranchState] = [ |
| 88 | BranchState( |
| 89 | must_be_defined=self.initial_state.must_be_defined, |
| 90 | may_be_defined=self.initial_state.may_be_defined, |
| 91 | ) |
| 92 | ] |
| 93 | |
| 94 | def copy(self) -> BranchStatement: |
| 95 | result = BranchStatement(self.initial_state) |
| 96 | result.branches = [b.copy() for b in self.branches] |
| 97 | return result |
| 98 | |
| 99 | def next_branch(self) -> None: |
| 100 | self.branches.append( |
| 101 | BranchState( |
| 102 | must_be_defined=self.initial_state.must_be_defined, |
| 103 | may_be_defined=self.initial_state.may_be_defined, |
| 104 | ) |
| 105 | ) |
| 106 | |
| 107 | def record_definition(self, name: str) -> None: |
| 108 | assert len(self.branches) > 0 |
| 109 | self.branches[-1].must_be_defined.add(name) |
| 110 | self.branches[-1].may_be_defined.discard(name) |
| 111 | |
| 112 | def delete_var(self, name: str) -> None: |
| 113 | assert len(self.branches) > 0 |
| 114 | self.branches[-1].must_be_defined.discard(name) |
| 115 | self.branches[-1].may_be_defined.discard(name) |
| 116 | |
| 117 | def record_nested_branch(self, state: BranchState) -> None: |
| 118 | assert len(self.branches) > 0 |
| 119 | current_branch = self.branches[-1] |
| 120 | if state.skipped: |
| 121 | current_branch.skipped = True |
| 122 | return |
| 123 | current_branch.must_be_defined.update(state.must_be_defined) |
| 124 | current_branch.may_be_defined.update(state.may_be_defined) |
| 125 | current_branch.may_be_defined.difference_update(current_branch.must_be_defined) |
| 126 | |
| 127 | def skip_branch(self) -> None: |
| 128 | assert len(self.branches) > 0 |
| 129 | self.branches[-1].skipped = True |
| 130 | |
| 131 | def is_possibly_undefined(self, name: str) -> bool: |
| 132 | assert len(self.branches) > 0 |
| 133 | return name in self.branches[-1].may_be_defined |
| 134 | |
| 135 | def is_undefined(self, name: str) -> bool: |
| 136 | assert len(self.branches) > 0 |
| 137 | branch = self.branches[-1] |
| 138 | return name not in branch.may_be_defined and name not in branch.must_be_defined |
| 139 |
no outgoing calls
no test coverage detected
searching dependent graphs…