Make parse_statement_decoration_t a class enum

This commit is contained in:
ridiculousfish 2020-07-07 16:28:39 -07:00
parent 71a8eb0aa4
commit 35cb449aa1
8 changed files with 45 additions and 48 deletions

View File

@ -262,20 +262,20 @@ static std::pair<source_range_t, const wchar_t *> find_block_open_keyword(const
}
/// \return the decoration for this statement.
parse_statement_decoration_t decorated_statement_t::decoration() const {
statement_decoration_t decorated_statement_t::decoration() const {
if (!opt_decoration) {
return parse_statement_decoration_none;
return statement_decoration_t::none;
}
switch (opt_decoration->kw) {
case parse_keyword_t::kw_command:
return parse_statement_decoration_command;
return statement_decoration_t::command;
case parse_keyword_t::kw_builtin:
return parse_statement_decoration_builtin;
return statement_decoration_t::builtin;
case parse_keyword_t::kw_exec:
return parse_statement_decoration_exec;
return statement_decoration_t::exec;
default:
assert(0 && "Unexpected keyword in statement decoration");
return parse_statement_decoration_none;
return statement_decoration_t::none;
}
}

View File

@ -674,7 +674,7 @@ struct decorated_statement_t final : public branch_t<type_t::decorated_statement
argument_or_redirection_list_t args_or_redirs;
// Helper to return the decoration.
parse_statement_decoration_t decoration() const;
statement_decoration_t decoration() const;
FIELDS(opt_decoration, command, args_or_redirs)
};

View File

@ -4421,11 +4421,11 @@ static void test_new_parser_fuzzing() {
// Parse a statement, returning the command, args (joined by spaces), and the decoration. Returns
// true if successful.
static bool test_1_parse_ll2(const wcstring &src, wcstring *out_cmd, wcstring *out_joined_args,
enum parse_statement_decoration_t *out_deco) {
enum statement_decoration_t *out_deco) {
using namespace ast;
out_cmd->clear();
out_joined_args->clear();
*out_deco = parse_statement_decoration_none;
*out_deco = statement_decoration_t::none;
auto ast = ast_t::parse(src);
if (ast.errored()) return false;
@ -4490,25 +4490,24 @@ static void test_new_parser_ll2() {
wcstring src;
wcstring cmd;
wcstring args;
enum parse_statement_decoration_t deco;
} tests[] = {
{L"echo hello", L"echo", L"hello", parse_statement_decoration_none},
{L"command echo hello", L"echo", L"hello", parse_statement_decoration_command},
{L"exec echo hello", L"echo", L"hello", parse_statement_decoration_exec},
{L"command command hello", L"command", L"hello", parse_statement_decoration_command},
{L"builtin command hello", L"command", L"hello", parse_statement_decoration_builtin},
{L"command --help", L"command", L"--help", parse_statement_decoration_none},
{L"command -h", L"command", L"-h", parse_statement_decoration_none},
{L"command", L"command", L"", parse_statement_decoration_none},
{L"command -", L"command", L"-", parse_statement_decoration_none},
{L"command --", L"command", L"--", parse_statement_decoration_none},
{L"builtin --names", L"builtin", L"--names", parse_statement_decoration_none},
{L"function", L"function", L"", parse_statement_decoration_none},
{L"function --help", L"function", L"--help", parse_statement_decoration_none}};
enum statement_decoration_t deco;
} tests[] = {{L"echo hello", L"echo", L"hello", statement_decoration_t::none},
{L"command echo hello", L"echo", L"hello", statement_decoration_t::command},
{L"exec echo hello", L"echo", L"hello", statement_decoration_t::exec},
{L"command command hello", L"command", L"hello", statement_decoration_t::command},
{L"builtin command hello", L"command", L"hello", statement_decoration_t::builtin},
{L"command --help", L"command", L"--help", statement_decoration_t::none},
{L"command -h", L"command", L"-h", statement_decoration_t::none},
{L"command", L"command", L"", statement_decoration_t::none},
{L"command -", L"command", L"-", statement_decoration_t::none},
{L"command --", L"command", L"--", statement_decoration_t::none},
{L"builtin --names", L"builtin", L"--names", statement_decoration_t::none},
{L"function", L"function", L"", statement_decoration_t::none},
{L"function --help", L"function", L"--help", statement_decoration_t::none}};
for (const auto &test : tests) {
wcstring cmd, args;
enum parse_statement_decoration_t deco = parse_statement_decoration_none;
enum statement_decoration_t deco = statement_decoration_t::none;
bool success = test_1_parse_ll2(test.src, &cmd, &args, &deco);
if (!success) err(L"Parse of '%ls' failed on line %ld", test.cmd.c_str(), (long)__LINE__);
if (cmd != test.cmd)

View File

@ -381,7 +381,7 @@ rgb_color_t highlight_get_color(const highlight_spec_t &highlight, bool is_backg
return result;
}
static bool command_is_valid(const wcstring &cmd, enum parse_statement_decoration_t decoration,
static bool command_is_valid(const wcstring &cmd, enum statement_decoration_t decoration,
const wcstring &working_directory, const environment_t &vars);
static bool has_expand_reserved(const wcstring &str) {
@ -1190,19 +1190,19 @@ void highlighter_t::visit(const ast::redirection_t &redir) {
}
/// Determine if a command is valid.
static bool command_is_valid(const wcstring &cmd, enum parse_statement_decoration_t decoration,
static bool command_is_valid(const wcstring &cmd, enum statement_decoration_t decoration,
const wcstring &working_directory, const environment_t &vars) {
// Determine which types we check, based on the decoration.
bool builtin_ok = true, function_ok = true, abbreviation_ok = true, command_ok = true,
implicit_cd_ok = true;
if (decoration == parse_statement_decoration_command ||
decoration == parse_statement_decoration_exec) {
if (decoration == statement_decoration_t::command ||
decoration == statement_decoration_t::exec) {
builtin_ok = false;
function_ok = false;
abbreviation_ok = false;
command_ok = true;
implicit_cd_ok = false;
} else if (decoration == parse_statement_decoration_builtin) {
} else if (decoration == statement_decoration_t::builtin) {
builtin_ok = true;
function_ok = false;
abbreviation_ok = false;

View File

@ -1291,7 +1291,7 @@ void history_t::add_pending_with_file_detection(const wcstring &str,
// Also skip it for 'echo'. This is because echo doesn't take file paths, but also
// because the history file test wants to find the commands in the history file
// immediately after running them, so it can't tolerate the asynchronous file detection.
if (stmt->decoration() == parse_statement_decoration_exec) {
if (stmt->decoration() == statement_decoration_t::exec) {
needs_sync_write = true;
}

View File

@ -108,14 +108,12 @@ const enum_map<parse_keyword_t> keyword_enum_map[] = {{parse_keyword_t::kw_excla
{parse_keyword_t::none, nullptr}};
#define keyword_enum_map_len (sizeof keyword_enum_map / sizeof *keyword_enum_map)
// Node tag values.
// Statement decorations.
enum parse_statement_decoration_t {
parse_statement_decoration_none,
parse_statement_decoration_command,
parse_statement_decoration_builtin,
parse_statement_decoration_exec,
// Statement decorations like 'command' or 'exec'.
enum class statement_decoration_t {
none,
command,
builtin,
exec,
};
// Parse error code list.

View File

@ -161,7 +161,7 @@ parse_execution_context_t::infinite_recursive_statement_in_job_list(const ast::j
// Ignore statements with decorations like 'builtin' or 'command', since those
// are not infinite recursion. In particular that is what enables 'wrapper functions'.
if (dc->decoration() != parse_statement_decoration_none) return nullptr;
if (dc->decoration() != statement_decoration_t::none) return nullptr;
// Check the command.
wcstring cmd = dc->command.source(pstree->src);
@ -201,16 +201,16 @@ process_type_t parse_execution_context_t::process_type_for_command(
// Determine the process type, which depends on the statement decoration (command, builtin,
// etc).
switch (statement.decoration()) {
case parse_statement_decoration_exec:
case statement_decoration_t::exec:
process_type = process_type_t::exec;
break;
case parse_statement_decoration_command:
case statement_decoration_t::command:
process_type = process_type_t::external;
break;
case parse_statement_decoration_builtin:
case statement_decoration_t::builtin:
process_type = process_type_t::builtin;
break;
case parse_statement_decoration_none:
case statement_decoration_t::none:
if (function_exists(cmd, *parser)) {
process_type = process_type_t::function;
} else if (builtin_exists(cmd)) {
@ -816,7 +816,7 @@ end_execution_reason_t parse_execution_context_t::populate_plain_process(
const int no_cmd_err_code = errno;
// If the specified command does not exist, and is undecorated, try using an implicit cd.
if (!has_command && statement.decoration() == parse_statement_decoration_none) {
if (!has_command && statement.decoration() == statement_decoration_t::none) {
// Implicit cd requires an empty argument and redirection list.
if (statement.args_or_redirs.empty()) {
// Ok, no arguments or redirections; check to see if the command is a directory.

View File

@ -1061,7 +1061,7 @@ static bool detect_errors_in_decorated_statement(const wcstring &buff_src,
using namespace ast;
bool errored = false;
auto source_start = dst.source_range().start;
const parse_statement_decoration_t decoration = dst.decoration();
const statement_decoration_t decoration = dst.decoration();
// Determine if the first argument is help.
bool first_arg_is_help = false;
@ -1093,7 +1093,7 @@ static bool detect_errors_in_decorated_statement(const wcstring &buff_src,
// Check that we don't try to pipe through exec.
bool is_in_pipeline = (pipe_pos != pipeline_position_t::none);
if (is_in_pipeline && decoration == parse_statement_decoration_exec) {
if (is_in_pipeline && decoration == statement_decoration_t::exec) {
errored = append_syntax_error(parse_errors, source_start, EXEC_ERR_MSG, L"exec");
}
@ -1176,7 +1176,7 @@ static bool detect_errors_in_decorated_statement(const wcstring &buff_src,
}
// Check that we don't do an invalid builtin (issue #1252).
if (!errored && decoration == parse_statement_decoration_builtin &&
if (!errored && decoration == statement_decoration_t::builtin &&
expand_one(*unexp_command, expand_flag::skip_cmdsubst, operation_context_t::empty(),
parse_errors) &&
!builtin_exists(*unexp_command)) {