Remove specific_statements_for_job

This commit is contained in:
ridiculousfish 2018-01-15 16:33:36 -08:00
parent 05e8cf13f7
commit 3e7e92dfff
3 changed files with 21 additions and 60 deletions

View file

@ -127,39 +127,30 @@ tnode_t<g::plain_statement> parse_execution_context_t::infinite_recursive_statem
// Here's the statement node we find that's infinite recursive.
tnode_t<grammar::plain_statement> infinite_recursive_statement;
// Get the list of statements.
const parse_node_tree_t::parse_node_list_t statements =
tree().specific_statements_for_job(*first_job);
// Find all the decorated statements. We are interested in statements with no decoration (i.e.
// not command, not builtin) whose command expands to the forbidden function.
for (size_t i = 0; i < statements.size(); i++) {
// We only care about decorated statements, not while statements, etc.
const parse_node_t &statement = *statements.at(i);
if (statement.type != symbol_decorated_statement) {
continue;
}
tnode_t<grammar::decorated_statement> dec_statement(&tree(), &statement);
auto plain_statement = tree().find_child<grammar::plain_statement>(dec_statement);
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;
}
// Ok, this is an undecorated plain statement. Get and expand its command.
maybe_t<wcstring> cmd = command_for_plain_statement(plain_statement, pstree->src);
if (cmd && expand_one(*cmd, EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_VARIABLES, NULL) &&
cmd == forbidden_function_name) {
// This is it.
infinite_recursive_statement = plain_statement;
if (out_func_name != NULL) {
*out_func_name = forbidden_function_name;
// Get the list of plain statements.
// Ignore statements with decorations like 'builtin' or 'command', since those
// are not infinite recursion. In particular that is what enables 'wrapper functions'.
tnode_t<g::statement> statement = first_job.child<0>();
tnode_t<g::job_continuation> continuation = first_job.child<1>();
while (statement) {
tnode_t<g::plain_statement> plain_statement =
statement.try_get_child<g::decorated_statement, 0>()
.try_get_child<g::plain_statement, 0>();
if (plain_statement) {
maybe_t<wcstring> cmd = command_for_plain_statement(plain_statement, pstree->src);
if (cmd && expand_one(*cmd, EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_VARIABLES, NULL) &&
cmd == forbidden_function_name) {
// This is it.
infinite_recursive_statement = plain_statement;
if (out_func_name != NULL) {
*out_func_name = forbidden_function_name;
}
break;
}
break;
}
statement = continuation.next_in_list<g::statement>();
}
return infinite_recursive_statement;
}

View file

@ -1389,32 +1389,6 @@ const parse_node_t *parse_node_tree_t::header_node_for_block_statement(
return result;
}
parse_node_tree_t::parse_node_list_t parse_node_tree_t::specific_statements_for_job(
const parse_node_t &job) const {
assert(job.type == symbol_job);
parse_node_list_t result;
// Initial statement (non-specific).
result.push_back(get_child(job, 0, symbol_statement));
// Our cursor variable. Walk over the list of continuations.
const parse_node_t *continuation = get_child(job, 1, symbol_job_continuation);
while (continuation != NULL && continuation->child_count > 0) {
result.push_back(get_child(*continuation, 1, symbol_statement));
continuation = get_child(*continuation, 2, symbol_job_continuation);
}
// Result now contains a list of statements. But we want a list of specific statements e.g.
// symbol_switch_statement. So replace them in-place in the vector.
for (size_t i = 0; i < result.size(); i++) {
const parse_node_t *statement = result.at(i);
assert(statement->type == symbol_statement);
result.at(i) = this->get_child(*statement, 0);
}
return result;
}
parse_node_tree_t::parse_node_list_t parse_node_tree_t::comment_nodes_for_node(
const parse_node_t &parent) const {
parse_node_list_t result;

View file

@ -211,10 +211,6 @@ class parse_node_tree_t : public std::vector<parse_node_t> {
parse_token_type_t item_type,
const parse_node_t **list_tail) const;
/// Given a job, return all of its statements. These are 'specific statements' (e.g.
/// symbol_decorated_statement, not symbol_statement).
parse_node_list_t specific_statements_for_job(const parse_node_t &job) const;
/// Given a node, return all of its comment nodes.
parse_node_list_t comment_nodes_for_node(const parse_node_t &node) const;