diff --git a/Userland/Shell/Parser.cpp b/Userland/Shell/Parser.cpp index 44127b5f774..4fbd8b75a54 100644 --- a/Userland/Shell/Parser.cpp +++ b/Userland/Shell/Parser.cpp @@ -1373,7 +1373,7 @@ RefPtr Parser::parse_history_designator() // Event selector AST::HistorySelector selector; - RefPtr syntax_error; + RefPtr syntax_error; selector.event.kind = AST::HistorySelector::EventKind::StartingStringLookup; selector.event.text_position = { m_offset, m_offset, m_line, m_line }; selector.word_selector_range = { @@ -1410,7 +1410,7 @@ RefPtr Parser::parse_history_designator() } selector.event.text = static_ptr_cast(bareword)->text(); - selector.event.text_position = (bareword ?: syntax_error)->position(); + selector.event.text_position = bareword->position(); auto it = selector.event.text.begin(); bool is_negative = false; if (*it == '-') { @@ -1422,14 +1422,22 @@ RefPtr Parser::parse_history_designator() selector.event.kind = AST::HistorySelector::EventKind::IndexFromEnd; else selector.event.kind = AST::HistorySelector::EventKind::IndexFromStart; - selector.event.index = abs(selector.event.text.to_int().value()); + auto number = selector.event.text.to_int(); + if (number.has_value()) + selector.event.index = abs(number.value()); + else + syntax_error = create("History entry index value invalid or out of range"); } break; } } - if (peek() != ':') - return create(move(selector)); + if (peek() != ':') { + auto node = create(move(selector)); + if (syntax_error) + node->set_is_syntax_error(*syntax_error); + return node; + } consume(); @@ -1445,14 +1453,14 @@ RefPtr Parser::parse_history_designator() AST::HistorySelector::WordSelectorKind::Index, 0, { m_rule_start_offsets.last(), m_offset, m_rule_start_lines.last(), line() }, - create("Word selector value invalid or out of range") + syntax_error ? NonnullRefPtr(*syntax_error) : create("Word selector value invalid or out of range") }; } return AST::HistorySelector::WordSelector { AST::HistorySelector::WordSelectorKind::Index, value.value(), { m_rule_start_offsets.last(), m_offset, m_rule_start_lines.last(), line() }, - nullptr + syntax_error }; } if (c == '^') { @@ -1461,7 +1469,7 @@ RefPtr Parser::parse_history_designator() AST::HistorySelector::WordSelectorKind::Index, 0, { m_rule_start_offsets.last(), m_offset, m_rule_start_lines.last(), line() }, - nullptr + syntax_error }; } if (c == '$') { @@ -1470,7 +1478,7 @@ RefPtr Parser::parse_history_designator() AST::HistorySelector::WordSelectorKind::Last, 0, { m_rule_start_offsets.last(), m_offset, m_rule_start_lines.last(), line() }, - nullptr + syntax_error }; } return {}; @@ -1478,9 +1486,10 @@ RefPtr Parser::parse_history_designator() auto start = parse_word_selector(); if (!start.has_value()) { - syntax_error = create("Expected a word selector after ':' in a history event designator", true); + if (!syntax_error) + syntax_error = create("Expected a word selector after ':' in a history event designator", true); auto node = create(move(selector)); - node->set_is_syntax_error(syntax_error->syntax_error_node()); + node->set_is_syntax_error(*syntax_error); return node; } selector.word_selector_range.start = start.release_value(); @@ -1489,9 +1498,10 @@ RefPtr Parser::parse_history_designator() consume(); auto end = parse_word_selector(); if (!end.has_value()) { - syntax_error = create("Expected a word selector after '-' in a history event designator word selector", true); + if (!syntax_error) + syntax_error = create("Expected a word selector after '-' in a history event designator word selector", true); auto node = create(move(selector)); - node->set_is_syntax_error(syntax_error->syntax_error_node()); + node->set_is_syntax_error(*syntax_error); return node; } selector.word_selector_range.end = move(end); @@ -1499,7 +1509,10 @@ RefPtr Parser::parse_history_designator() selector.word_selector_range.end.clear(); } - return create(move(selector)); + auto node = create(move(selector)); + if (syntax_error) + node->set_is_syntax_error(*syntax_error); + return node; } RefPtr Parser::parse_comment()