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 core 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)
|