diff --git a/Userland/Libraries/LibCpp/Parser.cpp b/Userland/Libraries/LibCpp/Parser.cpp index d4c5a3c540..56b1a421db 100644 --- a/Userland/Libraries/LibCpp/Parser.cpp +++ b/Userland/Libraries/LibCpp/Parser.cpp @@ -699,7 +699,7 @@ bool Parser::done() StringView Parser::text_of_token(const Cpp::Token& token) const { - return token.text(); + return token.text(); } StringView Parser::text_of_node(const ASTNode& node) const @@ -776,18 +776,33 @@ RefPtr Parser::eof_node() const } RefPtr Parser::node_at(Position pos) const +{ + auto index = index_of_node_at(pos); + if (!index.has_value()) + return nullptr; + return m_nodes[index.value()]; +} + +Optional Parser::index_of_node_at(Position pos) const { VERIFY(!m_tokens.is_empty()); - RefPtr match_node; - for (auto& node : m_nodes) { + Optional match_node_index; + + auto node_span = [](const ASTNode& node) { + VERIFY(node.end().line >= node.start().line); + VERIFY((node.end().line > node.start().line) || (node.end().column >= node.start().column)); + return Position { node.end().line - node.start().line, node.start().line != node.end().line ? 0 : node.end().column - node.start().column }; + }; + + for (size_t node_index = 0; node_index < m_nodes.size(); ++node_index) { + auto& node = m_nodes[node_index]; if (node.start() > pos || node.end() < pos) continue; - if (!match_node) - match_node = node; - else if (node_span_size(node) < node_span_size(*match_node)) - match_node = node; + + if (!match_node_index.has_value() || (node_span(node) < node_span(m_nodes[match_node_index.value()]))) + match_node_index = node_index; } - return match_node; + return match_node_index; } Optional Parser::token_at(Position pos) const @@ -800,18 +815,6 @@ Optional Parser::token_at(Position pos) const return {}; } -size_t Parser::node_span_size(const ASTNode& node) const -{ - if (node.start().line == node.end().line) - return node.end().column - node.start().column; - - size_t span_size = m_lines[node.start().line].length() - node.start().column; - for (size_t line = node.start().line + 1; line < node.end().line; ++line) { - span_size += m_lines[line].length(); - } - return span_size + m_lines[node.end().line].length() - node.end().column; -} - void Parser::print_tokens() const { for (auto& token : m_tokens) { diff --git a/Userland/Libraries/LibCpp/Parser.h b/Userland/Libraries/LibCpp/Parser.h index 789f0618aa..c78a901320 100644 --- a/Userland/Libraries/LibCpp/Parser.h +++ b/Userland/Libraries/LibCpp/Parser.h @@ -45,6 +45,7 @@ public: RefPtr eof_node() const; RefPtr node_at(Position) const; + Optional index_of_node_at(Position) const; Optional token_at(Position) const; RefPtr root_node() const { return m_root_node; } StringView text_of_node(const ASTNode&) const; @@ -135,8 +136,6 @@ private: void error(StringView message = {}); - size_t node_span_size(const ASTNode& node) const; - template NonnullRefPtr create_ast_node(ASTNode& parent, const Position& start, Optional end, Args&&... args)