mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-27 05:13:10 +00:00
Teach decoration_for_plain_statement about tnode, rename it get_decoration
This commit is contained in:
parent
84dcb24682
commit
f0f56a6910
9 changed files with 29 additions and 41 deletions
|
@ -1336,7 +1336,7 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> *out_c
|
|||
current_command = cmd_node.get_source(cmd);
|
||||
|
||||
// Check the decoration.
|
||||
switch (tree.decoration_for_plain_statement(*plain_statement)) {
|
||||
switch (get_decoration(plain_statement)) {
|
||||
case parse_statement_decoration_none: {
|
||||
use_command = true;
|
||||
use_function = true;
|
||||
|
|
|
@ -3402,7 +3402,7 @@ static bool test_1_parse_ll2(const wcstring &src, wcstring *out_cmd, wcstring *o
|
|||
tnode_t<grammar::plain_statement> stmt = stmts.at(0);
|
||||
|
||||
// Return its decoration and command.
|
||||
*out_deco = tree.decoration_for_plain_statement(stmt);
|
||||
*out_deco = get_decoration(stmt);
|
||||
*out_cmd = *command_for_plain_statement(stmt, src);
|
||||
|
||||
// Return arguments separated by spaces.
|
||||
|
|
|
@ -1071,14 +1071,14 @@ const highlighter_t::color_array_t &highlighter_t::highlight() {
|
|||
break;
|
||||
}
|
||||
case symbol_plain_statement: {
|
||||
tnode_t<g::plain_statement> stmt(&parse_tree, &node);
|
||||
// Get the decoration from the parent.
|
||||
enum parse_statement_decoration_t decoration =
|
||||
parse_tree.decoration_for_plain_statement(node);
|
||||
enum parse_statement_decoration_t decoration = get_decoration(stmt);
|
||||
|
||||
// Color the command.
|
||||
const parse_node_t *cmd_node =
|
||||
parse_tree.get_child(node, 0, parse_token_type_string);
|
||||
if (cmd_node == NULL || !cmd_node->has_source()) {
|
||||
tnode_t<g::tok_string> cmd_node = stmt.child<0>();
|
||||
maybe_t<wcstring> cmd = cmd_node.get_source(buff);
|
||||
if (!cmd) {
|
||||
break; // not much as we can do without a node that has source text
|
||||
}
|
||||
|
||||
|
@ -1088,13 +1088,11 @@ const highlighter_t::color_array_t &highlighter_t::highlight() {
|
|||
is_valid_cmd = true;
|
||||
} else {
|
||||
// Check to see if the command is valid.
|
||||
wcstring cmd(buff, cmd_node->source_start, cmd_node->source_length);
|
||||
|
||||
// Try expanding it. If we cannot, it's an error.
|
||||
bool expanded = expand_one(
|
||||
cmd, EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_VARIABLES | EXPAND_SKIP_JOBS);
|
||||
if (expanded && !has_expand_reserved(cmd)) {
|
||||
is_valid_cmd = command_is_valid(cmd, decoration, working_directory, vars);
|
||||
*cmd, EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_VARIABLES | EXPAND_SKIP_JOBS);
|
||||
if (expanded && !has_expand_reserved(*cmd)) {
|
||||
is_valid_cmd = command_is_valid(*cmd, decoration, working_directory, vars);
|
||||
}
|
||||
}
|
||||
this->color_node(*cmd_node,
|
||||
|
|
|
@ -1892,11 +1892,9 @@ void history_t::add_pending_with_file_detection(const wcstring &str) {
|
|||
bool impending_exit = false;
|
||||
parse_node_tree_t tree;
|
||||
parse_tree_from_string(str, parse_flag_none, &tree, NULL);
|
||||
size_t count = tree.size();
|
||||
|
||||
path_list_t potential_paths;
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
const parse_node_t &node = tree.at(i);
|
||||
for (const parse_node_t &node : tree) {
|
||||
if (!node.has_source()) {
|
||||
continue;
|
||||
}
|
||||
|
@ -1911,7 +1909,7 @@ void history_t::add_pending_with_file_detection(const wcstring &str) {
|
|||
// Hack hack hack - if the command is likely to trigger an exit, then don't do
|
||||
// background file detection, because we won't be able to write it to our history file
|
||||
// before we exit.
|
||||
if (tree.decoration_for_plain_statement(node) == parse_statement_decoration_exec) {
|
||||
if (get_decoration({&tree, &node}) == parse_statement_decoration_exec) {
|
||||
impending_exit = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -148,8 +148,7 @@ parse_execution_context_t::infinite_recursive_statement_in_job_list(const parse_
|
|||
tnode_t<grammar::decorated_statement> dec_statement(&tree(), &statement);
|
||||
|
||||
auto plain_statement = tree().find_child<grammar::plain_statement>(dec_statement);
|
||||
if (tree().decoration_for_plain_statement(plain_statement) !=
|
||||
parse_statement_decoration_none) {
|
||||
if (get_decoration(plain_statement) != parse_statement_decoration_none) {
|
||||
// This statement has a decoration like 'builtin' or 'command', and therefore is not
|
||||
// infinite recursion. In particular this is what enables 'wrapper functions'.
|
||||
continue;
|
||||
|
@ -177,8 +176,7 @@ enum process_type_t parse_execution_context_t::process_type_for_command(
|
|||
|
||||
// Determine the process type, which depends on the statement decoration (command, builtin,
|
||||
// etc).
|
||||
enum parse_statement_decoration_t decoration =
|
||||
tree().decoration_for_plain_statement(plain_statement);
|
||||
enum parse_statement_decoration_t decoration = get_decoration({&tree(), &plain_statement});
|
||||
|
||||
if (decoration == parse_statement_decoration_exec) {
|
||||
// Always exec.
|
||||
|
@ -857,7 +855,7 @@ parse_execution_result_t parse_execution_context_t::populate_plain_process(
|
|||
|
||||
// If the specified command does not exist, and is undecorated, try using an implicit cd.
|
||||
if (!has_command &&
|
||||
tree().decoration_for_plain_statement(statement) == parse_statement_decoration_none) {
|
||||
get_decoration({&tree(), &statement}) == parse_statement_decoration_none) {
|
||||
// Implicit cd requires an empty argument and redirection list.
|
||||
const parse_node_t *args =
|
||||
get_child(statement, 1, symbol_arguments_or_redirections_list);
|
||||
|
|
|
@ -1319,13 +1319,10 @@ bool parse_node_tree_t::argument_list_is_root(const parse_node_t &node) const {
|
|||
return result;
|
||||
}
|
||||
|
||||
enum parse_statement_decoration_t parse_node_tree_t::decoration_for_plain_statement(
|
||||
const parse_node_t &node) const {
|
||||
assert(node.type == symbol_plain_statement);
|
||||
enum parse_statement_decoration_t get_decoration(tnode_t<grammar::plain_statement> stmt) {
|
||||
parse_statement_decoration_t decoration = parse_statement_decoration_none;
|
||||
const parse_node_t *decorated_statement = this->get_parent(node, symbol_decorated_statement);
|
||||
if (decorated_statement) {
|
||||
decoration = static_cast<parse_statement_decoration_t>(decorated_statement->tag);
|
||||
if (auto decorated_statement = stmt.try_get_parent<grammar::decorated_statement>()) {
|
||||
decoration = static_cast<parse_statement_decoration_t>(decorated_statement.tag());
|
||||
}
|
||||
return decoration;
|
||||
}
|
||||
|
|
|
@ -195,11 +195,6 @@ class parse_node_tree_t : public std::vector<parse_node_t> {
|
|||
|
||||
// Utilities
|
||||
|
||||
/// Given a plain statement, get the decoration (from the parent node), or none if there is no
|
||||
/// decoration.
|
||||
enum parse_statement_decoration_t decoration_for_plain_statement(
|
||||
const parse_node_t &node) const;
|
||||
|
||||
/// Given a plain statement, return true if the statement is part of a pipeline. If
|
||||
/// include_first is set, the first command in a pipeline is considered part of it; otherwise
|
||||
/// only the second or additional commands are.
|
||||
|
@ -287,6 +282,9 @@ class tnode_t {
|
|||
|
||||
bool has_source() const { return nodeptr && nodeptr->has_source(); }
|
||||
|
||||
// return the tag, or 0 if missing.
|
||||
parse_node_tag_t tag() const { return nodeptr ? nodeptr->tag : 0; }
|
||||
|
||||
maybe_t<source_range_t> source_range() const {
|
||||
if (!has_source()) return none();
|
||||
return source_range_t{nodeptr->source_start, nodeptr->source_length};
|
||||
|
@ -385,6 +383,9 @@ std::vector<tnode_t<Type>> parse_node_tree_t::find_nodes(const parse_node_t &par
|
|||
maybe_t<wcstring> command_for_plain_statement(tnode_t<grammar::plain_statement> stmt,
|
||||
const wcstring &src);
|
||||
|
||||
/// Return the decoration for a plain statement.
|
||||
parse_statement_decoration_t get_decoration(tnode_t<grammar::plain_statement> stmt);
|
||||
|
||||
/// The big entry point. Parse a string, attempting to produce a tree for the given goal type.
|
||||
bool parse_tree_from_string(const wcstring &str, parse_tree_flags_t flags,
|
||||
parse_node_tree_t *output, parse_error_list_t *errors,
|
||||
|
|
|
@ -1174,7 +1174,7 @@ parser_test_error_bits_t parse_util_detect_errors(const wcstring &buff_src,
|
|||
|
||||
// We need to know the decoration.
|
||||
const enum parse_statement_decoration_t decoration =
|
||||
node_tree.decoration_for_plain_statement(node);
|
||||
get_decoration({&node_tree, &node});
|
||||
|
||||
// Check that we don't try to pipe through exec.
|
||||
if (is_in_pipeline && decoration == parse_statement_decoration_exec) {
|
||||
|
|
|
@ -582,21 +582,17 @@ bool reader_expand_abbreviation_in_command(const wcstring &cmdline, size_t curso
|
|||
// Look for plain statements where the cursor is at the end of the command.
|
||||
using namespace grammar;
|
||||
tnode_t<tok_string> matching_cmd_node;
|
||||
const size_t len = parse_tree.size();
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
const parse_node_t &node = parse_tree.at(i);
|
||||
|
||||
for (const parse_node_t &node : parse_tree) {
|
||||
// Only interested in plain statements with source.
|
||||
if (node.type != symbol_plain_statement || !node.has_source()) continue;
|
||||
|
||||
// Skip decorated statements.
|
||||
if (parse_tree.decoration_for_plain_statement(node) != parse_statement_decoration_none)
|
||||
continue;
|
||||
|
||||
// Get the command node. Skip it if we can't or it has no source.
|
||||
tnode_t<plain_statement> statement(&parse_tree, &node);
|
||||
tnode_t<tok_string> cmd_node = statement.child<0>();
|
||||
|
||||
// Skip decorated statements.
|
||||
if (get_decoration(statement) != parse_statement_decoration_none) continue;
|
||||
|
||||
auto msource = cmd_node.source_range();
|
||||
if (!msource) continue;
|
||||
|
||||
|
|
Loading…
Reference in a new issue