mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-28 12:13:55 +08:00
tnode_t adoption of find_nodes
This commit is contained in:
parent
618996a166
commit
4d68877f51
|
@ -1294,9 +1294,9 @@ 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' ') {
|
while (position_in_statement > 0 && cmd.at(position_in_statement - 1) == L' ') {
|
||||||
position_in_statement--;
|
position_in_statement--;
|
||||||
}
|
}
|
||||||
auto plain_statement = tnode_t<grammar::plain_statement>{
|
auto plain_statement =
|
||||||
&tree, tree.find_node_matching_source_location(symbol_plain_statement,
|
tnode_t<grammar::plain_statement>::find_node_matching_source_location(
|
||||||
position_in_statement, NULL)};
|
&tree, position_in_statement, nullptr);
|
||||||
if (!plain_statement) {
|
if (!plain_statement) {
|
||||||
// Not part of a plain statement. This could be e.g. a for loop header, case expression,
|
// 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
|
// etc. Do generic file completions (issue #1309). If we had to backtrack, it means
|
||||||
|
@ -1368,15 +1368,14 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> *out_c
|
||||||
use_implicit_cd);
|
use_implicit_cd);
|
||||||
} else {
|
} else {
|
||||||
// Get all the arguments.
|
// Get all the arguments.
|
||||||
const parse_node_tree_t::parse_node_list_t all_arguments =
|
auto all_arguments = tnode_t<grammar::argument>::find_nodes(&tree, plain_statement);
|
||||||
tree.find_nodes(*plain_statement, symbol_argument);
|
|
||||||
|
|
||||||
// See whether we are in an argument. We may also be in a redirection, or nothing at
|
// See whether we are in an argument. We may also be in a redirection, or nothing at
|
||||||
// all.
|
// all.
|
||||||
size_t matching_arg_index = -1;
|
size_t matching_arg_index = -1;
|
||||||
for (size_t i = 0; i < all_arguments.size(); i++) {
|
for (size_t i = 0; i < all_arguments.size(); i++) {
|
||||||
const parse_node_t *node = all_arguments.at(i);
|
tnode_t<grammar::argument> arg = all_arguments.at(i);
|
||||||
if (node->location_in_or_at_end_of_source_range(position_in_statement)) {
|
if (arg.location_in_or_at_end_of_source_range(position_in_statement)) {
|
||||||
matching_arg_index = i;
|
matching_arg_index = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1386,7 +1385,7 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> *out_c
|
||||||
wcstring current_argument, previous_argument;
|
wcstring current_argument, previous_argument;
|
||||||
if (matching_arg_index != (size_t)(-1)) {
|
if (matching_arg_index != (size_t)(-1)) {
|
||||||
const wcstring matching_arg =
|
const wcstring matching_arg =
|
||||||
all_arguments.at(matching_arg_index)->get_source(cmd);
|
all_arguments.at(matching_arg_index).get_source(cmd);
|
||||||
|
|
||||||
// If the cursor is in whitespace, then the "current" argument is empty and the
|
// If the cursor is in whitespace, then the "current" argument is empty and the
|
||||||
// previous argument is the matching one. But if the cursor was in or at the end
|
// previous argument is the matching one. But if the cursor was in or at the end
|
||||||
|
@ -1401,13 +1400,13 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> *out_c
|
||||||
current_argument = matching_arg;
|
current_argument = matching_arg;
|
||||||
if (matching_arg_index > 0) {
|
if (matching_arg_index > 0) {
|
||||||
previous_argument =
|
previous_argument =
|
||||||
all_arguments.at(matching_arg_index - 1)->get_source(cmd);
|
all_arguments.at(matching_arg_index - 1).get_source(cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check to see if we have a preceding double-dash.
|
// Check to see if we have a preceding double-dash.
|
||||||
for (size_t i = 0; i < matching_arg_index; i++) {
|
for (size_t i = 0; i < matching_arg_index; i++) {
|
||||||
if (all_arguments.at(i)->get_source(cmd) == L"--") {
|
if (all_arguments.at(i).get_source(cmd) == L"--") {
|
||||||
had_ddash = true;
|
had_ddash = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1417,9 +1416,10 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> *out_c
|
||||||
// If we are not in an argument, we may be in a redirection.
|
// If we are not in an argument, we may be in a redirection.
|
||||||
bool in_redirection = false;
|
bool in_redirection = false;
|
||||||
if (matching_arg_index == (size_t)(-1)) {
|
if (matching_arg_index == (size_t)(-1)) {
|
||||||
const parse_node_t *redirection = tree.find_node_matching_source_location(
|
if (tnode_t<grammar::redirection>::find_node_matching_source_location(
|
||||||
symbol_redirection, position_in_statement, plain_statement);
|
&tree, position_in_statement, plain_statement)) {
|
||||||
in_redirection = (redirection != NULL);
|
in_redirection = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool do_file = false, handle_as_special_cd = false;
|
bool do_file = false, handle_as_special_cd = false;
|
||||||
|
|
|
@ -3394,14 +3394,12 @@ static bool test_1_parse_ll2(const wcstring &src, wcstring *out_cmd, wcstring *o
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the statement. Should only have one.
|
// Get the statement. Should only have one.
|
||||||
const parse_node_tree_t::parse_node_list_t stmt_nodes =
|
auto stmts = tnode_t<grammar::plain_statement>::find_nodes(&tree, &tree.at(0));
|
||||||
tree.find_nodes(tree.at(0), symbol_plain_statement);
|
if (stmts.size() != 1) {
|
||||||
if (stmt_nodes.size() != 1) {
|
say(L"Unexpected number of statements (%lu) found in '%ls'", stmts.size(), src.c_str());
|
||||||
say(L"Unexpected number of statements (%lu) found in '%ls'", stmt_nodes.size(),
|
|
||||||
src.c_str());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const parse_node_t &stmt = *stmt_nodes.at(0);
|
tnode_t<grammar::plain_statement> stmt = stmts.at(0);
|
||||||
|
|
||||||
// Return its decoration.
|
// Return its decoration.
|
||||||
*out_deco = tree.decoration_for_plain_statement(stmt);
|
*out_deco = tree.decoration_for_plain_statement(stmt);
|
||||||
|
|
|
@ -166,7 +166,7 @@ class parse_node_tree_t : public std::vector<parse_node_t> {
|
||||||
// Find all the nodes of a given type underneath a given node, up to max_count of them.
|
// Find all the nodes of a given type underneath a given node, up to max_count of them.
|
||||||
typedef std::vector<const parse_node_t *> parse_node_list_t;
|
typedef std::vector<const parse_node_t *> parse_node_list_t;
|
||||||
parse_node_list_t find_nodes(const parse_node_t &parent, parse_token_type_t type,
|
parse_node_list_t find_nodes(const parse_node_t &parent, parse_token_type_t type,
|
||||||
size_t max_count = (size_t)(-1)) const;
|
size_t max_count = size_t(-1)) const;
|
||||||
|
|
||||||
// Finds the last node of a given type underneath a given node, or NULL if it could not be
|
// Finds the last node of a given type underneath a given node, or NULL if it could not be
|
||||||
// found. If parent is NULL, this finds the last node in the tree of that type.
|
// found. If parent is NULL, this finds the last node in the tree of that type.
|
||||||
|
@ -286,6 +286,14 @@ class tnode_t {
|
||||||
return nodeptr && nodeptr->location_in_or_at_end_of_source_range(loc);
|
return nodeptr && nodeptr->location_in_or_at_end_of_source_range(loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static tnode_t find_node_matching_source_location(const parse_node_tree_t *tree,
|
||||||
|
size_t source_loc,
|
||||||
|
const parse_node_t *parent) {
|
||||||
|
assert(tree && "null tree");
|
||||||
|
return tnode_t{tree,
|
||||||
|
tree->find_node_matching_source_location(Type::token, source_loc, parent)};
|
||||||
|
}
|
||||||
|
|
||||||
/// Type-safe access to a child at the given index.
|
/// Type-safe access to a child at the given index.
|
||||||
template <node_offset_t Index>
|
template <node_offset_t Index>
|
||||||
tnode_t<child_at<Type, Index>> child() const {
|
tnode_t<child_at<Type, Index>> child() const {
|
||||||
|
@ -303,6 +311,20 @@ class tnode_t {
|
||||||
if (!nodeptr) return {};
|
if (!nodeptr) return {};
|
||||||
return {tree, tree->get_parent(*nodeptr, ParentType::token)};
|
return {tree, tree->get_parent(*nodeptr, ParentType::token)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::vector<tnode_t> find_nodes(const parse_node_tree_t *tree,
|
||||||
|
const parse_node_t *parent,
|
||||||
|
size_t max_count = size_t(-1)) {
|
||||||
|
assert(tree && "null tree");
|
||||||
|
assert(parent && "null parent");
|
||||||
|
auto ptrs = tree->find_nodes(*parent, Type::token, max_count);
|
||||||
|
std::vector<tnode_t> result;
|
||||||
|
result.reserve(ptrs.size());
|
||||||
|
for (const parse_node_t *np : ptrs) {
|
||||||
|
result.emplace_back(tree, np);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The big entry point. Parse a string, attempting to produce a tree for the given goal type.
|
/// The big entry point. Parse a string, attempting to produce a tree for the given goal type.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user