| 1 | """optview.py."""
 | 
| 2 | from __future__ import print_function
 | 
| 3 | 
 | 
| 4 | from frontend import consts
 | 
| 5 | from frontend import option_def
 | 
| 6 | 
 | 
| 7 | from typing import List
 | 
| 8 | 
 | 
| 9 | 
 | 
| 10 | class _Getter(object):
 | 
| 11 | 
 | 
| 12 |     def __init__(self, opt0_array, opt_stacks, opt_name):
 | 
| 13 |         # type: (List[bool], List[List[bool]], str) -> None
 | 
| 14 |         self.opt0_array = opt0_array
 | 
| 15 |         self.opt_stacks = opt_stacks
 | 
| 16 |         self.num = consts.OptionNum(opt_name)
 | 
| 17 |         assert self.num != 0, opt_name
 | 
| 18 | 
 | 
| 19 |     def __call__(self):
 | 
| 20 |         # type: () -> bool
 | 
| 21 |         overlay = self.opt_stacks[self.num]
 | 
| 22 |         if overlay is None or len(overlay) == 0:
 | 
| 23 |             return self.opt0_array[self.num]
 | 
| 24 |         else:
 | 
| 25 |             return overlay[-1]  # The top value
 | 
| 26 | 
 | 
| 27 | 
 | 
| 28 | class _View(object):
 | 
| 29 |     """Allow read-only access to a subset of options."""
 | 
| 30 | 
 | 
| 31 |     def __init__(self, opt0_array, opt_stacks, allowed):
 | 
| 32 |         # type: (List[bool], List[List[bool]], List[str]) -> None
 | 
| 33 |         self.opt0_array = opt0_array
 | 
| 34 |         self.opt_stacks = opt_stacks
 | 
| 35 |         self.allowed = allowed
 | 
| 36 | 
 | 
| 37 |     def __getattr__(self, opt_name):
 | 
| 38 |         # type: (str) -> _Getter
 | 
| 39 |         """Make the API look like self.exec_opts.strict_control_flow()"""
 | 
| 40 |         if opt_name in self.allowed:
 | 
| 41 |             return _Getter(self.opt0_array, self.opt_stacks, opt_name)
 | 
| 42 |         else:
 | 
| 43 |             raise AttributeError(opt_name)
 | 
| 44 | 
 | 
| 45 | 
 | 
| 46 | class Parse(_View):
 | 
| 47 | 
 | 
| 48 |     def __init__(self, opt0_array, opt_stacks):
 | 
| 49 |         # type: (List[bool], List[List[bool]]) -> None
 | 
| 50 |         _View.__init__(self, opt0_array, opt_stacks,
 | 
| 51 |                        option_def.ParseOptNames())
 | 
| 52 | 
 | 
| 53 | 
 | 
| 54 | class Exec(_View):
 | 
| 55 | 
 | 
| 56 |     def __init__(self, opt0_array, opt_stacks):
 | 
| 57 |         # type: (List[bool], List[List[bool]]) -> None
 | 
| 58 |         _View.__init__(self, opt0_array, opt_stacks, option_def.ExecOptNames())
 |