Skip to content

Commit

Permalink
[refactor] Simplify loc.OfCommand() using new fields
Browse files Browse the repository at this point in the history
I'm wondering if we need loc.TokenForCommand() as a helper function

Tokens are the things that point to lines, which we show the user
  • Loading branch information
Andy C committed May 13, 2023
1 parent dd83eab commit 4700c25
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 12 deletions.
2 changes: 2 additions & 0 deletions core/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ def GetLineSourceString(arena, line, quote_filename=False):

elif case(source_e.ArgvWord):
src = cast(source.ArgvWord, UP_src)

# TODO: check loc.Missing; otherwise get Token from loc_t, then line
span_id = location.GetSpanId(src.location)
if span_id == runtime.NO_SPID:
s = '[ %s word at ? ]' % src.what
Expand Down
21 changes: 13 additions & 8 deletions frontend/location.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ def GetSpanId(loc_):
def OfCommand(node):
# type: (command_t) -> loc_t
"""
Used in pipe_locs, for _CheckStatus(), _StrictErrExit, etc.
"""
UP_node = node # type: command_t
tag = node.tag()
Expand All @@ -88,41 +89,45 @@ def OfCommand(node):
node = cast(command.Simple, UP_node)
# It should have either words or redirects, e.g. '> foo'
if len(node.words):
# TODO: need token
return loc.Word(node.words[0])
elif len(node.redirects):
return node.redirects[0].op

if tag == command_e.ShAssignment:
node = cast(command.ShAssignment, UP_node)
return loc.Span(node.spids[0])
return node.var

# TODO: need tokens
if tag == command_e.Pipeline:
node = cast(command.Pipeline, UP_node)
return loc.Span(node.spids[0]) # first |
if tag == command_e.AndOr:
node = cast(command.AndOr, UP_node)
return loc.Span(node.spids[0]) # first && or ||

if tag == command_e.DoGroup:
node = cast(command.DoGroup, UP_node)
return loc.Span(node.spids[0]) # do spid
return node.left # 'do' token
if tag == command_e.BraceGroup:
node = cast(BraceGroup, UP_node)
return node.left # { spid
return node.left # { token
if tag == command_e.Subshell:
node = cast(command.Subshell, UP_node)
return loc.Span(node.spids[0]) # ( spid
return node.left # ( token

if tag == command_e.WhileUntil:
node = cast(command.WhileUntil, UP_node)
return loc.Span(node.spids[0]) # while spid
return node.keyword # while
if tag == command_e.If:
node = cast(command.If, UP_node)
return loc.Span(node.arms[0].spids[0]) # if spid is in FIRST arm.
return node.if_kw
if tag == command_e.Case:
node = cast(command.Case, UP_node)
return loc.Span(node.spids[0]) # case keyword spid
return node.case_kw
if tag == command_e.TimeBlock:
node = cast(command.TimeBlock, UP_node)
return loc.Span(node.spids[0]) # time keyword spid
return node.keyword

# We never have this case?
#if node.tag == command_e.CommandList:
Expand Down
5 changes: 4 additions & 1 deletion frontend/syntax.asdl
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,10 @@ module syntax
command =
NoOp
# Note: do_fork is semantic, not syntactic
| Simple(List[word] words, List[Redir] redirects, List[EnvPair] more_env,
| Simple(
# Token left,
List[EnvPair] more_env,
List[word] words, List[Redir] redirects,
ArgList? typed_args, BlockArg? block, bool do_fork)
# This doesn't technically belong in the LST, but it's convenient for
# execution
Expand Down
2 changes: 1 addition & 1 deletion osh/cmd_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ def _MakeSimpleCommand(
more_env = [] # type: List[EnvPair]
_AppendMoreEnv(preparsed_list, more_env)
# do_fork by default
node = command.Simple(words3, redirects, more_env, typed_args, block, True)
node = command.Simple(more_env, words3, redirects, typed_args, block, True)
return node


Expand Down
4 changes: 2 additions & 2 deletions tools/osh2oil.py
Original file line number Diff line number Diff line change
Expand Up @@ -621,8 +621,8 @@ def DoCommand(self, node, local_symbols, at_top_level=False):
self.f.write('for %s in @ARGV ' % node.iter_names[0])

# note: command_t doesn't have .spids
self.cursor.SkipUntil(
location.GetSpanId(location.OfCommand(node.body)))
body_spid = location.GetSpanId(location.OfCommand(node.body))
self.cursor.SkipUntil(body_spid)

elif case(for_iter_e.Words):
iterable = cast(for_iter.Words, UP_iterable)
Expand Down

0 comments on commit 4700c25

Please sign in to comment.