| 1 | from __future__ import print_function
|
| 2 |
|
| 3 | from _devbuild.gen.runtime_asdl import scope_e
|
| 4 | from _devbuild.gen.syntax_asdl import loc
|
| 5 | from _devbuild.gen.value_asdl import (value, value_e)
|
| 6 |
|
| 7 | from core import error
|
| 8 | from core import state
|
| 9 | from display import ui
|
| 10 | from core import vm
|
| 11 | from frontend import args
|
| 12 | from frontend import flag_util
|
| 13 | from mycpp.mylib import log
|
| 14 |
|
| 15 | from typing import Dict, cast, TYPE_CHECKING
|
| 16 | if TYPE_CHECKING:
|
| 17 | from _devbuild.gen.runtime_asdl import cmd_value
|
| 18 | from core import optview
|
| 19 |
|
| 20 | _ = log
|
| 21 |
|
| 22 |
|
| 23 | class IsMain(vm._Builtin):
|
| 24 | """is-main builtin.
|
| 25 | """
|
| 26 |
|
| 27 | def __init__(self, mem):
|
| 28 | # type: (state.Mem) -> None
|
| 29 | self.mem = mem
|
| 30 |
|
| 31 | def Run(self, cmd_val):
|
| 32 | # type: (cmd_value.Argv) -> int
|
| 33 | return 0 if self.mem.is_main else 1
|
| 34 |
|
| 35 |
|
| 36 | class SourceGuard(vm._Builtin):
|
| 37 | """source-guard builtin.
|
| 38 |
|
| 39 | source-guard main || return
|
| 40 | """
|
| 41 |
|
| 42 | def __init__(self, guards, exec_opts, errfmt):
|
| 43 | # type: (Dict[str, bool], optview.Exec, ui.ErrorFormatter) -> None
|
| 44 | self.guards = guards
|
| 45 | self.exec_opts = exec_opts
|
| 46 | self.errfmt = errfmt
|
| 47 |
|
| 48 | def Run(self, cmd_val):
|
| 49 | # type: (cmd_value.Argv) -> int
|
| 50 | _, arg_r = flag_util.ParseCmdVal('source-guard', cmd_val)
|
| 51 | name, _ = arg_r.ReadRequired2('requires a name')
|
| 52 | #log('guards %s', self.guards)
|
| 53 | if name in self.guards:
|
| 54 | # already defined
|
| 55 | if self.exec_opts.redefine_module():
|
| 56 | self.errfmt.PrintMessage(
|
| 57 | '(interactive) Reloading source file %r' % name)
|
| 58 | return 0
|
| 59 | else:
|
| 60 | return 1
|
| 61 | self.guards[name] = True
|
| 62 | return 0
|
| 63 |
|
| 64 |
|
| 65 | class Use(vm._Builtin):
|
| 66 | """use bin, use dialect to control the 'first word'.
|
| 67 |
|
| 68 | Examples:
|
| 69 | use bin grep sed
|
| 70 |
|
| 71 | use dialect ninja # I think it must be in a 'dialect' scope
|
| 72 | use dialect travis
|
| 73 | """
|
| 74 |
|
| 75 | def __init__(self, mem, errfmt):
|
| 76 | # type: (state.Mem, ui.ErrorFormatter) -> None
|
| 77 | self.mem = mem
|
| 78 | self.errfmt = errfmt
|
| 79 |
|
| 80 | def Run(self, cmd_val):
|
| 81 | # type: (cmd_value.Argv) -> int
|
| 82 | arg_r = args.Reader(cmd_val.argv, locs=cmd_val.arg_locs)
|
| 83 | arg_r.Next() # skip 'use'
|
| 84 |
|
| 85 | arg, arg_loc = arg_r.Peek2()
|
| 86 | if arg is None:
|
| 87 | raise error.Usage("expected 'bin' or 'dialect'", loc.Missing)
|
| 88 | arg_r.Next()
|
| 89 |
|
| 90 | if arg == 'dialect':
|
| 91 | expected, e_loc = arg_r.Peek2()
|
| 92 | if expected is None:
|
| 93 | raise error.Usage('expected dialect name', loc.Missing)
|
| 94 |
|
| 95 | UP_actual = self.mem.GetValue('_DIALECT', scope_e.Dynamic)
|
| 96 | if UP_actual.tag() == value_e.Str:
|
| 97 | actual = cast(value.Str, UP_actual).s
|
| 98 | if actual == expected:
|
| 99 | return 0 # OK
|
| 100 | else:
|
| 101 | self.errfmt.Print_('Expected dialect %r, got %r' %
|
| 102 | (expected, actual),
|
| 103 | blame_loc=e_loc)
|
| 104 |
|
| 105 | return 1
|
| 106 | else:
|
| 107 | # Not printing expected value
|
| 108 | self.errfmt.Print_('Expected dialect %r' % expected,
|
| 109 | blame_loc=e_loc)
|
| 110 | return 1
|
| 111 |
|
| 112 | # 'use bin' can be used for static analysis. Although could it also
|
| 113 | # simplify the SearchPath logic? Maybe ensure that it is memoized?
|
| 114 | if arg == 'bin':
|
| 115 | rest = arg_r.Rest()
|
| 116 | for name in rest:
|
| 117 | log('bin %s', name)
|
| 118 | return 0
|
| 119 |
|
| 120 | raise error.Usage("expected 'bin' or 'dialect'", arg_loc)
|