diff --git a/Shell/AST.cpp b/Shell/AST.cpp index 1568c2bf03..0ca39ed2da 100644 --- a/Shell/AST.cpp +++ b/Shell/AST.cpp @@ -83,7 +83,7 @@ static inline Vector join_commands(Vector left, Vector shell, Function)> callback) +void Node::for_each_entry(RefPtr shell, Function)> callback) { auto value = run(shell)->resolve_without_cast(shell); if (value->is_job()) { @@ -219,13 +219,14 @@ HitTestResult And::hit_test_position(size_t offset) result.closest_command_node = m_right; return result; } + result = m_right->hit_test_position(offset); if (!result.closest_command_node) result.closest_command_node = m_right; return result; } -And::And(Position position, RefPtr left, RefPtr right) +And::And(Position position, NonnullRefPtr left, NonnullRefPtr right) : Node(move(position)) , m_left(move(left)) , m_right(move(right)) @@ -324,7 +325,7 @@ RefPtr ListConcatenate::leftmost_trivial_literal() const return m_list.first()->leftmost_trivial_literal(); } -ListConcatenate::ListConcatenate(Position position, Vector> list) +ListConcatenate::ListConcatenate(Position position, Vector> list) : Node(move(position)) , m_list(move(list)) { @@ -368,7 +369,7 @@ HitTestResult Background::hit_test_position(size_t offset) return m_command->hit_test_position(offset); } -Background::Background(Position position, RefPtr command) +Background::Background(Position position, NonnullRefPtr command) : Node(move(position)) , m_command(move(command)) { @@ -491,7 +492,7 @@ RefPtr CastToCommand::leftmost_trivial_literal() const return m_inner->leftmost_trivial_literal(); } -CastToCommand::CastToCommand(Position position, RefPtr inner) +CastToCommand::CastToCommand(Position position, NonnullRefPtr inner) : Node(move(position)) , m_inner(move(inner)) { @@ -723,7 +724,7 @@ HitTestResult DynamicEvaluate::hit_test_position(size_t offset) return m_inner->hit_test_position(offset); } -DynamicEvaluate::DynamicEvaluate(Position position, RefPtr inner) +DynamicEvaluate::DynamicEvaluate(Position position, NonnullRefPtr inner) : Node(move(position)) , m_inner(move(inner)) { @@ -807,6 +808,9 @@ HitTestResult FunctionDeclaration::hit_test_position(size_t offset) if (!position().contains(offset)) return {}; + if (!m_block) + return {}; + auto result = m_block->hit_test_position(offset); if (result.matching_node && result.matching_node->is_simple_variable()) result.closest_node_with_semantic_meaning = this; @@ -927,10 +931,13 @@ HitTestResult ForLoop::hit_test_position(size_t offset) if (auto result = m_iterated_expression->hit_test_position(offset); result.matching_node) return result; + if (!m_block) + return {}; + return m_block->hit_test_position(offset); } -ForLoop::ForLoop(Position position, String variable_name, RefPtr iterated_expr, RefPtr block, Optional in_kw_position) +ForLoop::ForLoop(Position position, String variable_name, NonnullRefPtr iterated_expr, RefPtr block, Optional in_kw_position) : Node(move(position)) , m_variable_name(move(variable_name)) , m_iterated_expression(move(iterated_expr)) @@ -984,7 +991,7 @@ void Execute::dump(int level) const m_command->dump(level + 1); } -void Execute::for_each_entry(RefPtr shell, Function)> callback) +void Execute::for_each_entry(RefPtr shell, Function)> callback) { if (m_command->would_execute()) return m_command->for_each_entry(shell, move(callback)); @@ -1176,7 +1183,7 @@ Vector Execute::complete_for_editor(Shell& shell, si return shell.complete_program_name(node->text(), corrected_offset); } -Execute::Execute(Position position, RefPtr command, bool capture_stdout) +Execute::Execute(Position position, NonnullRefPtr command, bool capture_stdout) : Node(move(position)) , m_command(move(command)) , m_capture_stdout(capture_stdout) @@ -1266,7 +1273,7 @@ HitTestResult IfCond::hit_test_position(size_t offset) return {}; } -IfCond::IfCond(Position position, Optional else_position, RefPtr condition, RefPtr true_branch, RefPtr false_branch) +IfCond::IfCond(Position position, Optional else_position, NonnullRefPtr condition, RefPtr true_branch, RefPtr false_branch) : Node(move(position)) , m_condition(move(condition)) , m_true_branch(move(true_branch)) @@ -1281,10 +1288,16 @@ IfCond::IfCond(Position position, Optional else_position, RefPtr set_is_syntax_error(m_false_branch->syntax_error_node()); m_condition = create(m_condition->position(), m_condition); - if (m_true_branch) - m_true_branch = create(m_true_branch->position(), m_true_branch); - if (m_false_branch) - m_false_branch = create(m_false_branch->position(), m_false_branch); + + if (m_true_branch) { + auto true_branch = m_true_branch.release_nonnull(); + m_true_branch = create(true_branch->position(), true_branch); + } + + if (m_false_branch) { + auto false_branch = m_false_branch.release_nonnull(); + m_false_branch = create(false_branch->position(), false_branch); + } } IfCond::~IfCond() @@ -1322,6 +1335,7 @@ HitTestResult Join::hit_test_position(size_t offset) auto result = m_left->hit_test_position(offset); if (result.matching_node) return result; + return m_right->hit_test_position(offset); } @@ -1332,7 +1346,7 @@ RefPtr Join::leftmost_trivial_literal() const return m_right->leftmost_trivial_literal(); } -Join::Join(Position position, RefPtr left, RefPtr right) +Join::Join(Position position, NonnullRefPtr left, NonnullRefPtr right) : Node(move(position)) , m_left(move(left)) , m_right(move(right)) @@ -1428,8 +1442,7 @@ void MatchExpr::highlight_in_editor(Line::Editor& editor, Shell& shell, Highligh editor.stylize({ m_as_position.value().start_offset, m_as_position.value().end_offset }, { Line::Style::Foreground(Line::Style::XtermColor::Yellow) }); metadata.is_first_in_list = false; - if (m_matched_expr) - m_matched_expr->highlight_in_editor(editor, shell, metadata); + m_matched_expr->highlight_in_editor(editor, shell, metadata); for (auto& entry : m_entries) { metadata.is_first_in_list = false; @@ -1465,14 +1478,14 @@ HitTestResult MatchExpr::hit_test_position(size_t offset) return {}; } -MatchExpr::MatchExpr(Position position, RefPtr expr, String name, Optional as_position, Vector entries) +MatchExpr::MatchExpr(Position position, NonnullRefPtr expr, String name, Optional as_position, Vector entries) : Node(move(position)) , m_matched_expr(move(expr)) , m_expr_name(move(name)) , m_as_position(move(as_position)) , m_entries(move(entries)) { - if (m_matched_expr && m_matched_expr->is_syntax_error()) { + if (m_matched_expr->is_syntax_error()) { set_is_syntax_error(m_matched_expr->syntax_error_node()); } else { for (auto& entry : m_entries) { @@ -1521,13 +1534,14 @@ HitTestResult Or::hit_test_position(size_t offset) result.closest_command_node = m_right; return result; } + result = m_right->hit_test_position(offset); if (!result.closest_command_node) result.closest_command_node = m_right; return result; } -Or::Or(Position position, RefPtr left, RefPtr right) +Or::Or(Position position, NonnullRefPtr left, NonnullRefPtr right) : Node(move(position)) , m_left(move(left)) , m_right(move(right)) @@ -1595,10 +1609,11 @@ HitTestResult Pipe::hit_test_position(size_t offset) auto result = m_left->hit_test_position(offset); if (result.matching_node) return result; + return m_right->hit_test_position(offset); } -Pipe::Pipe(Position position, RefPtr left, RefPtr right) +Pipe::Pipe(Position position, NonnullRefPtr left, NonnullRefPtr right) : Node(move(position)) , m_left(move(left)) , m_right(move(right)) @@ -1613,7 +1628,7 @@ Pipe::~Pipe() { } -PathRedirectionNode::PathRedirectionNode(Position position, int fd, RefPtr path) +PathRedirectionNode::PathRedirectionNode(Position position, int fd, NonnullRefPtr path) : Node(move(position)) , m_fd(fd) , m_path(move(path)) @@ -1687,7 +1702,7 @@ RefPtr ReadRedirection::run(RefPtr shell) return create(move(command)); } -ReadRedirection::ReadRedirection(Position position, int fd, RefPtr path) +ReadRedirection::ReadRedirection(Position position, int fd, NonnullRefPtr path) : PathRedirectionNode(move(position), fd, move(path)) { } @@ -1714,7 +1729,7 @@ RefPtr ReadWriteRedirection::run(RefPtr shell) return create(move(command)); } -ReadWriteRedirection::ReadWriteRedirection(Position position, int fd, RefPtr path) +ReadWriteRedirection::ReadWriteRedirection(Position position, int fd, NonnullRefPtr path) : PathRedirectionNode(move(position), fd, move(path)) { } @@ -1781,7 +1796,7 @@ HitTestResult Sequence::hit_test_position(size_t offset) return m_right->hit_test_position(offset); } -Sequence::Sequence(Position position, RefPtr left, RefPtr right) +Sequence::Sequence(Position position, NonnullRefPtr left, NonnullRefPtr right) : Node(move(position)) , m_left(move(left)) , m_right(move(right)) @@ -2049,7 +2064,7 @@ HitTestResult Juxtaposition::hit_test_position(size_t offset) return result; } -Juxtaposition::Juxtaposition(Position position, RefPtr left, RefPtr right) +Juxtaposition::Juxtaposition(Position position, NonnullRefPtr left, NonnullRefPtr right) : Node(move(position)) , m_left(move(left)) , m_right(move(right)) @@ -2129,7 +2144,7 @@ HitTestResult StringPartCompose::hit_test_position(size_t offset) return m_right->hit_test_position(offset); } -StringPartCompose::StringPartCompose(Position position, RefPtr left, RefPtr right) +StringPartCompose::StringPartCompose(Position position, NonnullRefPtr left, NonnullRefPtr right) : Node(move(position)) , m_left(move(left)) , m_right(move(right)) @@ -2252,7 +2267,7 @@ RefPtr WriteAppendRedirection::run(RefPtr shell) return create(move(command)); } -WriteAppendRedirection::WriteAppendRedirection(Position position, int fd, RefPtr path) +WriteAppendRedirection::WriteAppendRedirection(Position position, int fd, NonnullRefPtr path) : PathRedirectionNode(move(position), fd, move(path)) { } @@ -2279,7 +2294,7 @@ RefPtr WriteRedirection::run(RefPtr shell) return create(move(command)); } -WriteRedirection::WriteRedirection(Position position, int fd, RefPtr path) +WriteRedirection::WriteRedirection(Position position, int fd, NonnullRefPtr path) : PathRedirectionNode(move(position), fd, move(path)) { } diff --git a/Shell/AST.h b/Shell/AST.h index f632221d9c..db2f060ed5 100644 --- a/Shell/AST.h +++ b/Shell/AST.h @@ -371,7 +371,7 @@ private: class Node : public RefCounted { public: virtual void dump(int level) const = 0; - virtual void for_each_entry(RefPtr shell, Function)> callback); + virtual void for_each_entry(RefPtr shell, Function)> callback); virtual RefPtr run(RefPtr) = 0; virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) = 0; virtual Vector complete_for_editor(Shell&, size_t, const HitTestResult&); @@ -422,7 +422,7 @@ protected: class PathRedirectionNode : public Node { public: - PathRedirectionNode(Position, int, RefPtr); + PathRedirectionNode(Position, int, NonnullRefPtr); virtual ~PathRedirectionNode(); virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; virtual Vector complete_for_editor(Shell&, size_t, const HitTestResult&) override; @@ -432,12 +432,12 @@ public: protected: int m_fd { -1 }; - RefPtr m_path; + NonnullRefPtr m_path; }; class And final : public Node { public: - And(Position, RefPtr, RefPtr); + And(Position, NonnullRefPtr, NonnullRefPtr); virtual ~And(); private: @@ -447,13 +447,13 @@ private: virtual HitTestResult hit_test_position(size_t) override; virtual String class_name() const override { return "And"; } - RefPtr m_left; - RefPtr m_right; + NonnullRefPtr m_left; + NonnullRefPtr m_right; }; class ListConcatenate final : public Node { public: - ListConcatenate(Position, Vector>); + ListConcatenate(Position, Vector>); virtual ~ListConcatenate(); private: @@ -465,12 +465,12 @@ private: virtual bool is_list() const override { return true; } virtual RefPtr leftmost_trivial_literal() const override; - Vector> m_list; + Vector> m_list; }; class Background final : public Node { public: - Background(Position, RefPtr); + Background(Position, NonnullRefPtr); virtual ~Background(); private: @@ -480,7 +480,7 @@ private: virtual HitTestResult hit_test_position(size_t) override; virtual String class_name() const override { return "Background"; } - RefPtr m_command; + NonnullRefPtr m_command; }; class BarewordLiteral final : public Node { @@ -502,7 +502,7 @@ private: class CastToCommand final : public Node { public: - CastToCommand(Position, RefPtr); + CastToCommand(Position, NonnullRefPtr); virtual ~CastToCommand(); private: @@ -516,7 +516,7 @@ private: virtual bool is_list() const override { return true; } virtual RefPtr leftmost_trivial_literal() const override; - RefPtr m_inner; + NonnullRefPtr m_inner; }; class CastToList final : public Node { @@ -584,7 +584,7 @@ private: class DynamicEvaluate final : public Node { public: - DynamicEvaluate(Position, RefPtr); + DynamicEvaluate(Position, NonnullRefPtr); virtual ~DynamicEvaluate(); private: @@ -603,7 +603,7 @@ private: return m_inner->is_list() || m_inner->is_command() || m_inner->is_glob(); // Anything that generates a list. } - RefPtr m_inner; + NonnullRefPtr m_inner; }; class DoubleQuotedString final : public Node { @@ -662,7 +662,7 @@ private: class ForLoop final : public Node { public: - ForLoop(Position, String variable_name, RefPtr iterated_expr, RefPtr block, Optional in_kw_position = {}); + ForLoop(Position, String variable_name, NonnullRefPtr iterated_expr, RefPtr block, Optional in_kw_position = {}); virtual ~ForLoop(); private: @@ -674,7 +674,7 @@ private: virtual bool would_execute() const override { return true; } String m_variable_name; - RefPtr m_iterated_expression; + NonnullRefPtr m_iterated_expression; RefPtr m_block; Optional m_in_kw_position; }; @@ -698,11 +698,11 @@ private: class Execute final : public Node { public: - Execute(Position, RefPtr, bool capture_stdout = false); + Execute(Position, NonnullRefPtr, bool capture_stdout = false); virtual ~Execute(); void capture_stdout() { m_capture_stdout = true; } - RefPtr command() { return m_command; } - virtual void for_each_entry(RefPtr shell, Function)> callback) override; + NonnullRefPtr command() { return m_command; } + virtual void for_each_entry(RefPtr shell, Function)> callback) override; private: virtual void dump(int level) const override; @@ -714,13 +714,13 @@ private: virtual bool is_execute() const override { return true; } virtual bool would_execute() const override { return true; } - RefPtr m_command; + NonnullRefPtr m_command; bool m_capture_stdout { false }; }; class IfCond final : public Node { public: - IfCond(Position, Optional else_position, RefPtr cond_expr, RefPtr true_branch, RefPtr false_branch); + IfCond(Position, Optional else_position, NonnullRefPtr cond_expr, RefPtr true_branch, RefPtr false_branch); virtual ~IfCond(); private: @@ -731,7 +731,7 @@ private: virtual String class_name() const override { return "IfCond"; } virtual bool would_execute() const override { return true; } - RefPtr m_condition; + NonnullRefPtr m_condition; RefPtr m_true_branch; RefPtr m_false_branch; @@ -740,7 +740,7 @@ private: class Join final : public Node { public: - Join(Position, RefPtr, RefPtr); + Join(Position, NonnullRefPtr, NonnullRefPtr); virtual ~Join(); private: @@ -753,8 +753,8 @@ private: virtual bool is_list() const override { return true; } virtual RefPtr leftmost_trivial_literal() const override; - RefPtr m_left; - RefPtr m_right; + NonnullRefPtr m_left; + NonnullRefPtr m_right; }; struct MatchEntry { @@ -765,7 +765,7 @@ struct MatchEntry { class MatchExpr final : public Node { public: - MatchExpr(Position, RefPtr expr, String name, Optional as_position, Vector entries); + MatchExpr(Position, NonnullRefPtr expr, String name, Optional as_position, Vector entries); virtual ~MatchExpr(); private: @@ -776,7 +776,7 @@ private: virtual String class_name() const override { return "MatchExpr"; } virtual bool would_execute() const override { return true; } - RefPtr m_matched_expr; + NonnullRefPtr m_matched_expr; String m_expr_name; Optional m_as_position; Vector m_entries; @@ -784,7 +784,7 @@ private: class Or final : public Node { public: - Or(Position, RefPtr, RefPtr); + Or(Position, NonnullRefPtr, NonnullRefPtr); virtual ~Or(); private: @@ -794,13 +794,13 @@ private: virtual HitTestResult hit_test_position(size_t) override; virtual String class_name() const override { return "Or"; } - RefPtr m_left; - RefPtr m_right; + NonnullRefPtr m_left; + NonnullRefPtr m_right; }; class Pipe final : public Node { public: - Pipe(Position, RefPtr, RefPtr); + Pipe(Position, NonnullRefPtr, NonnullRefPtr); virtual ~Pipe(); private: @@ -811,13 +811,13 @@ private: virtual String class_name() const override { return "Pipe"; } virtual bool is_list() const override { return true; } - RefPtr m_left; - RefPtr m_right; + NonnullRefPtr m_left; + NonnullRefPtr m_right; }; class ReadRedirection final : public PathRedirectionNode { public: - ReadRedirection(Position, int, RefPtr); + ReadRedirection(Position, int, NonnullRefPtr); virtual ~ReadRedirection(); private: @@ -828,7 +828,7 @@ private: class ReadWriteRedirection final : public PathRedirectionNode { public: - ReadWriteRedirection(Position, int, RefPtr); + ReadWriteRedirection(Position, int, NonnullRefPtr); virtual ~ReadWriteRedirection(); private: @@ -839,7 +839,7 @@ private: class Sequence final : public Node { public: - Sequence(Position, RefPtr, RefPtr); + Sequence(Position, NonnullRefPtr, NonnullRefPtr); virtual ~Sequence(); private: @@ -851,8 +851,8 @@ private: virtual bool is_list() const override { return true; } virtual bool would_execute() const override { return m_left->would_execute() || m_right->would_execute(); } - RefPtr m_left; - RefPtr m_right; + NonnullRefPtr m_left; + NonnullRefPtr m_right; }; class Subshell final : public Node { @@ -908,7 +908,7 @@ private: class Juxtaposition final : public Node { public: - Juxtaposition(Position, RefPtr, RefPtr); + Juxtaposition(Position, NonnullRefPtr, NonnullRefPtr); virtual ~Juxtaposition(); private: @@ -919,8 +919,8 @@ private: virtual Vector complete_for_editor(Shell&, size_t, const HitTestResult&) override; virtual String class_name() const override { return "Juxtaposition"; } - RefPtr m_left; - RefPtr m_right; + NonnullRefPtr m_left; + NonnullRefPtr m_right; }; class StringLiteral final : public Node { @@ -941,7 +941,7 @@ private: class StringPartCompose final : public Node { public: - StringPartCompose(Position, RefPtr, RefPtr); + StringPartCompose(Position, NonnullRefPtr, NonnullRefPtr); virtual ~StringPartCompose(); private: @@ -951,8 +951,8 @@ private: virtual HitTestResult hit_test_position(size_t) override; virtual String class_name() const override { return "StringPartCompose"; } - RefPtr m_left; - RefPtr m_right; + NonnullRefPtr m_left; + NonnullRefPtr m_right; }; class SyntaxError final : public Node { @@ -1016,7 +1016,7 @@ private: class WriteAppendRedirection final : public PathRedirectionNode { public: - WriteAppendRedirection(Position, int, RefPtr); + WriteAppendRedirection(Position, int, NonnullRefPtr); virtual ~WriteAppendRedirection(); private: @@ -1027,7 +1027,7 @@ private: class WriteRedirection final : public PathRedirectionNode { public: - WriteRedirection(Position, int, RefPtr); + WriteRedirection(Position, int, NonnullRefPtr); virtual ~WriteRedirection(); private: diff --git a/Shell/Parser.cpp b/Shell/Parser.cpp index f3ec66bd93..1cdb69144e 100644 --- a/Shell/Parser.cpp +++ b/Shell/Parser.cpp @@ -128,9 +128,10 @@ RefPtr Parser::parse() auto error_start = push_start(); m_offset = m_input.length(); auto syntax_error_node = create("Unexpected tokens past the end"); - if (toplevel) - return create(move(toplevel), move(syntax_error_node)); - return syntax_error_node; + if (!toplevel) + toplevel = move(syntax_error_node); + else + toplevel->set_is_syntax_error(*syntax_error_node); } return toplevel; @@ -141,7 +142,7 @@ RefPtr Parser::parse_toplevel() auto rule_start = push_start(); if (auto sequence = parse_sequence()) - return create(sequence); + return create(sequence.release_nonnull()); return nullptr; } @@ -164,7 +165,7 @@ RefPtr Parser::parse_sequence() consume_while(is_any_of("\n;")); auto rest = parse_sequence(); if (rest) - return create(move(var_decls), move(rest)); + return create(var_decls.release_nonnull(), rest.release_nonnull()); return var_decls; } default: @@ -180,7 +181,7 @@ RefPtr Parser::parse_sequence() return var_decls; if (var_decls) - first = create(move(var_decls), move(first)); + first = create(var_decls.release_nonnull(), first.release_nonnull()); consume_while(is_whitespace); @@ -189,15 +190,15 @@ RefPtr Parser::parse_sequence() case '\n': consume_while(is_any_of("\n;")); if (auto expr = parse_sequence()) { - return create(move(first), move(expr)); // Sequence + return create(first.release_nonnull(), expr.release_nonnull()); // Sequence } return first; case '&': { - auto execute_pipe_seq = first->would_execute() ? first : static_cast>(create(first)); + auto execute_pipe_seq = first->would_execute() ? first.release_nonnull() : static_cast>(create(first.release_nonnull())); consume(); - auto bg = create(move(first)); // Execute Background + auto bg = create(execute_pipe_seq); // Execute Background if (auto rest = parse_sequence()) - return create(move(bg), move(rest)); // Sequence Background Sequence + return create(move(bg), rest.release_nonnull()); // Sequence Background Sequence return bg; } @@ -369,7 +370,7 @@ RefPtr Parser::parse_or_logical_sequence() if (!right_and_sequence) right_and_sequence = create("Expected an expression after '||'"); - return create(move(and_sequence), move(right_and_sequence)); + return create(and_sequence.release_nonnull(), right_and_sequence.release_nonnull()); } RefPtr Parser::parse_and_logical_sequence() @@ -391,7 +392,7 @@ RefPtr Parser::parse_and_logical_sequence() if (!right_and_sequence) right_and_sequence = create("Expected an expression after '&&'"); - return create(move(pipe_sequence), move(right_and_sequence)); + return create(pipe_sequence.release_nonnull(), right_and_sequence.release_nonnull()); } RefPtr Parser::parse_pipe_sequence() @@ -413,7 +414,7 @@ RefPtr Parser::parse_pipe_sequence() consume(); if (auto pipe_seq = parse_pipe_sequence()) { - return create(move(left), move(pipe_seq)); // Pipe + return create(left.release_nonnull(), pipe_seq.release_nonnull()); // Pipe } putback(); @@ -431,20 +432,20 @@ RefPtr Parser::parse_command() if (!list_expr) return nullptr; - auto cast = create(move(list_expr)); // Cast List Command + auto cast = create(list_expr.release_nonnull()); // Cast List Command auto next_command = parse_command(); if (!next_command) return cast; - return create(move(cast), move(next_command)); // Join List Command + return create(move(cast), next_command.release_nonnull()); // Join List Command } auto command = parse_command(); if (!command) return redir; - return create(move(redir), command); // Join Command Command + return create(redir.release_nonnull(), command.release_nonnull()); // Join Command Command } RefPtr Parser::parse_control_structure() @@ -509,7 +510,7 @@ RefPtr Parser::parse_for_loop() auto obrace_error_start = push_start(); if (!expect('{')) { auto syntax_error = create("Expected an open brace '{' to start a 'for' loop body"); - return create(move(variable_name), move(iterated_expression), move(syntax_error), move(in_start_position)); // ForLoop Var Iterated Block + return create(move(variable_name), iterated_expression.release_nonnull(), move(syntax_error), move(in_start_position)); // ForLoop Var Iterated Block } } @@ -519,7 +520,7 @@ RefPtr Parser::parse_for_loop() auto cbrace_error_start = push_start(); if (!expect('}')) { auto error_start = push_start(); - RefPtr syntax_error = create("Expected a close brace '}' to end a 'for' loop body"); + auto syntax_error = create("Expected a close brace '}' to end a 'for' loop body"); if (body) body->set_is_syntax_error(*syntax_error); else @@ -527,7 +528,7 @@ RefPtr Parser::parse_for_loop() } } - return create(move(variable_name), move(iterated_expression), move(body), move(in_start_position)); // ForLoop Var Iterated Block + return create(move(variable_name), iterated_expression.release_nonnull(), move(body), move(in_start_position)); // ForLoop Var Iterated Block } RefPtr Parser::parse_if_expr() @@ -547,22 +548,21 @@ RefPtr Parser::parse_if_expr() { auto cond_error_start = push_start(); condition = parse_or_logical_sequence(); - if (!condition) { - auto syntax_error = create("Expected a logical sequence after 'if'"); - return create(Optional {}, move(syntax_error), nullptr, nullptr); - } + if (!condition) + condition = create("Expected a logical sequence after 'if'"); } auto parse_braced_toplevel = [&]() -> RefPtr { + RefPtr body; { auto obrace_error_start = push_start(); if (!expect('{')) { - auto syntax_error = create("Expected an open brace '{' to start an 'if' true branch"); - return syntax_error; + body = create("Expected an open brace '{' to start an 'if' true branch"); } } - auto body = parse_toplevel(); + if (!body) + body = parse_toplevel(); { auto cbrace_error_start = push_start(); @@ -582,9 +582,6 @@ RefPtr Parser::parse_if_expr() consume_while(is_whitespace); auto true_branch = parse_braced_toplevel(); - if (true_branch && true_branch->is_syntax_error()) - return create(Optional {}, move(condition), move(true_branch), nullptr); // If expr syntax_error - consume_while(is_whitespace); Optional else_position; { @@ -597,14 +594,14 @@ RefPtr Parser::parse_if_expr() consume_while(is_whitespace); if (peek() == '{') { auto false_branch = parse_braced_toplevel(); - return create(else_position, move(condition), move(true_branch), move(false_branch)); // If expr true_branch Else false_branch + return create(else_position, condition.release_nonnull(), move(true_branch), move(false_branch)); // If expr true_branch Else false_branch } auto else_if_branch = parse_if_expr(); - return create(else_position, move(condition), move(true_branch), move(else_if_branch)); // If expr true_branch Else If ... + return create(else_position, condition.release_nonnull(), move(true_branch), move(else_if_branch)); // If expr true_branch Else If ... } - return create(else_position, move(condition), move(true_branch), nullptr); // If expr true_branch + return create(else_position, condition.release_nonnull(), move(true_branch), nullptr); // If expr true_branch } RefPtr Parser::parse_subshell() @@ -658,7 +655,7 @@ RefPtr Parser::parse_match_expr() if (consume_while(is_any_of(" \t\n")).is_empty()) { auto node = create( - move(match_expression), + match_expression.release_nonnull(), String {}, move(as_position), Vector {}); node->set_is_syntax_error(create("Expected whitespace after 'as' in 'match'")); return node; @@ -667,7 +664,7 @@ RefPtr Parser::parse_match_expr() match_name = consume_while(is_word_character); if (match_name.is_empty()) { auto node = create( - move(match_expression), + match_expression.release_nonnull(), String {}, move(as_position), Vector {}); node->set_is_syntax_error(create("Expected an identifier after 'as' in 'match'")); return node; @@ -678,7 +675,7 @@ RefPtr Parser::parse_match_expr() if (!expect('{')) { auto node = create( - move(match_expression), + match_expression.release_nonnull(), move(match_name), move(as_position), Vector {}); node->set_is_syntax_error(create("Expected an open brace '{' to start a 'match' entry list")); return node; @@ -700,13 +697,13 @@ RefPtr Parser::parse_match_expr() if (!expect('}')) { auto node = create( - move(match_expression), + match_expression.release_nonnull(), move(match_name), move(as_position), move(entries)); node->set_is_syntax_error(create("Expected a close brace '}' to end a 'match' entry list")); return node; } - return create(move(match_expression), move(match_name), move(as_position), move(entries)); + return create(match_expression.release_nonnull(), move(match_name), move(as_position), move(entries)); } AST::MatchEntry Parser::parse_match_entry() @@ -792,9 +789,9 @@ RefPtr Parser::parse_redirection() // Eat a character and hope the problem goes away consume(); } - return create("Expected a path"); + path = create("Expected a path after redirection"); } - return create(pipe_fd, move(path)); // Redirection WriteAppend + return create(pipe_fd, path.release_nonnull()); // Redirection WriteAppend } if (peek() == '&') { consume(); @@ -827,9 +824,9 @@ RefPtr Parser::parse_redirection() // Eat a character and hope the problem goes away consume(); } - return create("Expected a path"); + path = create("Expected a path after redirection"); } - return create(pipe_fd, move(path)); // Redirection Write + return create(pipe_fd, path.release_nonnull()); // Redirection Write } case '<': { consume(); @@ -851,12 +848,12 @@ RefPtr Parser::parse_redirection() // Eat a character and hope the problem goes away consume(); } - return create("Expected a path"); + path = create("Expected a path after redirection"); } if (mode == Read) - return create(pipe_fd, move(path)); // Redirection Read + return create(pipe_fd, path.release_nonnull()); // Redirection Read - return create(pipe_fd, move(path)); // Redirection ReadWrite + return create(pipe_fd, path.release_nonnull()); // Redirection ReadWrite } default: m_offset = rule_start->offset; @@ -869,13 +866,13 @@ RefPtr Parser::parse_list_expression() consume_while(is_whitespace); auto rule_start = push_start(); - Vector> nodes; + Vector> nodes; do { auto expr = parse_expression(); if (!expr) break; - nodes.append(move(expr)); + nodes.append(expr.release_nonnull()); } while (!consume_while(is_whitespace).is_empty()); if (nodes.is_empty()) @@ -889,14 +886,14 @@ RefPtr Parser::parse_expression() auto rule_start = push_start(); auto starting_char = peek(); - auto read_concat = [&](auto expr) -> RefPtr { + auto read_concat = [&](auto&& expr) -> NonnullRefPtr { if (is_whitespace(peek())) - return expr; + return move(expr); if (auto next_expr = parse_expression()) - return create(move(expr), move(next_expr)); + return create(move(expr), next_expr.release_nonnull()); - return expr; + return move(expr); }; if (strchr("&|){} ;<>\n", starting_char) != nullptr) @@ -912,10 +909,10 @@ RefPtr Parser::parse_expression() if (starting_char == '$') { if (auto variable = parse_variable()) - return read_concat(variable); + return read_concat(variable.release_nonnull()); if (auto inline_exec = parse_evaluate()) - return read_concat(inline_exec); + return read_concat(inline_exec.release_nonnull()); } if (starting_char == '#') @@ -931,7 +928,10 @@ RefPtr Parser::parse_expression() return read_concat(create(move(list))); // Cast To List } - return read_concat(parse_string_composite()); + if (auto composite = parse_string_composite()) + return read_concat(composite.release_nonnull()); + + return nullptr; } RefPtr Parser::parse_string_composite() @@ -939,35 +939,35 @@ RefPtr Parser::parse_string_composite() auto rule_start = push_start(); if (auto string = parse_string()) { if (auto next_part = parse_string_composite()) - return create(move(string), move(next_part)); // Concatenate String StringComposite + return create(string.release_nonnull(), next_part.release_nonnull()); // Concatenate String StringComposite return string; } if (auto variable = parse_variable()) { if (auto next_part = parse_string_composite()) - return create(move(variable), move(next_part)); // Concatenate Variable StringComposite + return create(variable.release_nonnull(), next_part.release_nonnull()); // Concatenate Variable StringComposite return variable; } if (auto glob = parse_glob()) { if (auto next_part = parse_string_composite()) - return create(move(glob), move(next_part)); // Concatenate Glob StringComposite + return create(glob.release_nonnull(), next_part.release_nonnull()); // Concatenate Glob StringComposite return glob; } if (auto bareword = parse_bareword()) { if (auto next_part = parse_string_composite()) - return create(move(bareword), move(next_part)); // Concatenate Bareword StringComposite + return create(bareword.release_nonnull(), next_part.release_nonnull()); // Concatenate Bareword StringComposite return bareword; } if (auto inline_command = parse_evaluate()) { if (auto next_part = parse_string_composite()) - return create(move(inline_command), move(next_part)); // Concatenate Execute StringComposite + return create(inline_command.release_nonnull(), next_part.release_nonnull()); // Concatenate Execute StringComposite return inline_command; } @@ -1067,10 +1067,10 @@ RefPtr Parser::parse_doublequoted_string_inner() if (auto variable = parse_variable()) { auto inner = create( move(string_literal), - move(variable)); // Compose String Variable + variable.release_nonnull()); // Compose String Variable if (auto string = parse_doublequoted_string_inner()) { - return create(move(inner), move(string)); // Compose Composition Composition + return create(move(inner), string.release_nonnull()); // Compose Composition Composition } return inner; @@ -1079,10 +1079,10 @@ RefPtr Parser::parse_doublequoted_string_inner() if (auto evaluate = parse_evaluate()) { auto composition = create( move(string_literal), - move(evaluate)); // Compose String Sequence + evaluate.release_nonnull()); // Compose String Sequence if (auto string = parse_doublequoted_string_inner()) { - return create(move(composition), move(string)); // Compose Composition Composition + return create(move(composition), string.release_nonnull()); // Compose Composition Composition } return composition; @@ -1142,7 +1142,8 @@ RefPtr Parser::parse_evaluate() inner = create("Unexpected EOF in list"); if (!expect(')')) inner->set_is_syntax_error(*create("Expected a terminating close paren")); - return create(move(inner), true); + + return create(inner.release_nonnull(), true); } auto inner = parse_expression(); @@ -1150,11 +1151,11 @@ RefPtr Parser::parse_evaluate() inner = create("Expected a command"); } else { if (inner->is_list()) { - auto execute_inner = create(move(inner), true); - inner = execute_inner; + auto execute_inner = create(inner.release_nonnull(), true); + inner = move(execute_inner); } else { - auto dyn_inner = create(move(inner)); - inner = dyn_inner; + auto dyn_inner = create(inner.release_nonnull()); + inner = move(dyn_inner); } } @@ -1237,7 +1238,7 @@ RefPtr Parser::parse_bareword() text = create(move(string)); } - return create(move(tilde), move(text)); // Juxtaposition Varible Bareword + return create(tilde.release_nonnull(), text.release_nonnull()); // Juxtaposition Varible Bareword } if (string.starts_with("\\~")) { diff --git a/Shell/Shell.cpp b/Shell/Shell.cpp index 1344068485..c6f60e7270 100644 --- a/Shell/Shell.cpp +++ b/Shell/Shell.cpp @@ -292,7 +292,9 @@ Vector Shell::expand_aliases(Vector initial_commands auto* ast = static_cast(subcommand_ast.ptr()); subcommand_ast = ast->command(); } - RefPtr substitute = adopt(*new AST::Join(subcommand_ast->position(), subcommand_ast, adopt(*new AST::CommandLiteral(subcommand_ast->position(), command)))); + NonnullRefPtr substitute = adopt(*new AST::Join(subcommand_ast->position(), + subcommand_ast.release_nonnull(), + adopt(*new AST::CommandLiteral(subcommand_ast->position(), command)))); for (auto& subst_command : substitute->run(*this)->resolve_as_commands(*this)) { if (!subst_command.argv.is_empty() && subst_command.argv.first() == argv0) // Disallow an alias resolving to itself. commands.append(subst_command);