Some adopton of tnode_t in complete.cpp

This commit is contained in:
ridiculousfish 2018-01-11 09:41:49 -08:00
parent cfe355554c
commit 618996a166
3 changed files with 35 additions and 13 deletions

View file

@ -1294,10 +1294,10 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> *out_c
while (position_in_statement > 0 && cmd.at(position_in_statement - 1) == L' ') {
position_in_statement--;
}
const parse_node_t *plain_statement = tree.find_node_matching_source_location(
symbol_plain_statement, position_in_statement, NULL);
if (plain_statement == NULL) {
auto plain_statement = tnode_t<grammar::plain_statement>{
&tree, tree.find_node_matching_source_location(symbol_plain_statement,
position_in_statement, NULL)};
if (!plain_statement) {
// Not part of a plain statement. This could be e.g. a for loop header, case expression,
// etc. Do generic file completions (issue #1309). If we had to backtrack, it means
// there was whitespace; don't do an autosuggestion in that case. Also don't do it if we
@ -1327,15 +1327,14 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> *out_c
}
completer.complete_param_expand(current_token, do_file);
} else {
assert(plain_statement->has_source() &&
plain_statement->type == symbol_plain_statement);
assert(plain_statement && plain_statement.has_source());
// Get the command node.
const parse_node_t *cmd_node =
tree.get_child(*plain_statement, 0, parse_token_type_string);
tnode_t<grammar::tok_string> cmd_node = plain_statement.child<0>();
assert(cmd_node && cmd_node.has_source() && "Expected command node to be valid");
// Get the actual command string.
if (cmd_node) current_command = cmd_node->get_source(cmd);
current_command = cmd_node.get_source(cmd);
// Check the decoration.
switch (tree.decoration_for_plain_statement(*plain_statement)) {
@ -1363,7 +1362,7 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> *out_c
}
}
if (cmd_node && cmd_node->location_in_or_at_end_of_source_range(pos)) {
if (cmd_node.location_in_or_at_end_of_source_range(pos)) {
// Complete command filename.
completer.complete_cmd(current_token, use_function, use_builtin, use_command,
use_implicit_cd);
@ -1394,7 +1393,7 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> *out_c
// of the argument, then the current argument is the matching one, and the
// previous argument is the one before it.
bool cursor_in_whitespace =
!plain_statement->location_in_or_at_end_of_source_range(pos);
!plain_statement.location_in_or_at_end_of_source_range(pos);
if (cursor_in_whitespace) {
current_argument = L"";
previous_argument = matching_arg;
@ -1452,8 +1451,9 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> *out_c
assert(wrap_chain.at(i) == current_command_unescape);
} else if (!(flags & COMPLETION_REQUEST_AUTOSUGGESTION)) {
wcstring faux_cmdline = cmd;
faux_cmdline.replace(cmd_node->source_start,
cmd_node->source_length, wrap_chain.at(i));
faux_cmdline.replace(cmd_node.source_range()->start,
cmd_node.source_range()->length,
wrap_chain.at(i));
transient_cmd = make_unique<builtin_commandline_scoped_transient_t>(
faux_cmdline);
}

View file

@ -116,6 +116,7 @@ struct alternative {
#define DEF_ALT(T) struct T : public alternative
#define ALT_BODY(T) \
BODY(T) \
using type_tuple = std::tuple<>; \
static const production_element_t *resolve(const parse_token_t &, const parse_token_t &, \
parse_node_tag_t *);

View file

@ -256,6 +256,14 @@ class tnode_t {
assert((!n || n->type == Type::token) && "node has wrong type");
}
/// Temporary conversion to parse_node_t to assist in migration.
/* implicit */ operator const parse_node_t &() const {
assert(nodeptr && "Empty tnode_t");
return *nodeptr;
}
/* implicit */ operator const parse_node_t *() const { return nodeptr; }
/// Return the underlying (type-erased) node.
const parse_node_t *node() const { return nodeptr; }
@ -274,6 +282,10 @@ class tnode_t {
return nodeptr->get_source(str);
}
bool location_in_or_at_end_of_source_range(size_t loc) const {
return nodeptr && nodeptr->location_in_or_at_end_of_source_range(loc);
}
/// Type-safe access to a child at the given index.
template <node_offset_t Index>
tnode_t<child_at<Type, Index>> child() const {
@ -282,6 +294,15 @@ class tnode_t {
if (nodeptr) child = tree->get_child(*nodeptr, Index, child_type::token);
return tnode_t<child_type>{tree, child};
}
/// Type-safe access to a node's parent.
/// If the parent exists and has type ParentType, return it.
/// Otherwise return a missing tnode.
template <class ParentType>
tnode_t<ParentType> try_get_parent() const {
if (!nodeptr) return {};
return {tree, tree->get_parent(*nodeptr, ParentType::token)};
}
};
/// The big entry point. Parse a string, attempting to produce a tree for the given goal type.