Serenity Operating System
at master 1556 lines 56 kB view raw
1/* 2 * Copyright (c) 2020, the SerenityOS developers. 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#pragma once 8 9#include "Forward.h" 10#include "Job.h" 11#include "NodeVisitor.h" 12#include <AK/Format.h> 13#include <AK/NonnullRefPtr.h> 14#include <AK/RefCounted.h> 15#include <AK/RefPtr.h> 16#include <AK/String.h> 17#include <AK/Types.h> 18#include <AK/Vector.h> 19#include <LibLine/Editor.h> 20#include <LibRegex/Regex.h> 21 22namespace Shell::AST { 23 24using AK::make_ref_counted; 25 26template<typename T> 27static inline NonnullRefPtr<T> make_ref_counted(std::initializer_list<NonnullRefPtr<Value>> arg) 28{ 29 return adopt_ref(*new T(arg)); 30} 31 32struct HighlightMetadata { 33 bool is_first_in_list { true }; 34}; 35 36struct Position { 37 size_t start_offset { 0 }; 38 size_t end_offset { 0 }; 39 struct Line { 40 size_t line_number { 0 }; 41 size_t line_column { 0 }; 42 43 bool operator==(Line const& other) const 44 { 45 return line_number == other.line_number && line_column == other.line_column; 46 } 47 } start_line, end_line; 48 49 bool contains(size_t offset) const { return start_offset <= offset && offset <= end_offset; } 50 51 Position with_end(Position const& end) const 52 { 53 return { 54 .start_offset = start_offset, 55 .end_offset = end.end_offset, 56 .start_line = start_line, 57 .end_line = end.end_line, 58 }; 59 } 60}; 61 62struct NameWithPosition { 63 String name; 64 Position position; 65}; 66 67struct FdRedirection; 68struct Rewiring : public RefCounted<Rewiring> { 69 int old_fd { -1 }; 70 int new_fd { -1 }; 71 FdRedirection* other_pipe_end { nullptr }; 72 enum class Close { 73 None, 74 Old, 75 New, 76 RefreshNew, 77 RefreshOld, 78 ImmediatelyCloseNew, 79 } fd_action { Close::None }; 80 81 Rewiring(int source, int dest, Close close = Close::None) 82 : old_fd(source) 83 , new_fd(dest) 84 , fd_action(close) 85 { 86 } 87 88 Rewiring(int source, int dest, FdRedirection* other_end, Close close) 89 : old_fd(source) 90 , new_fd(dest) 91 , other_pipe_end(other_end) 92 , fd_action(close) 93 { 94 } 95}; 96 97struct Redirection : public RefCounted<Redirection> { 98 virtual ErrorOr<NonnullRefPtr<Rewiring>> apply() const = 0; 99 virtual ~Redirection(); 100 virtual bool is_path_redirection() const { return false; } 101 virtual bool is_fd_redirection() const { return false; } 102 virtual bool is_close_redirection() const { return false; } 103}; 104 105struct CloseRedirection : public Redirection { 106 int fd { -1 }; 107 108 virtual ErrorOr<NonnullRefPtr<Rewiring>> apply() const override; 109 virtual ~CloseRedirection(); 110 CloseRedirection(int fd) 111 : fd(fd) 112 { 113 } 114 115private: 116 virtual bool is_close_redirection() const override { return true; } 117}; 118 119struct PathRedirection : public Redirection { 120 String path; 121 int fd { -1 }; 122 enum { 123 Read, 124 Write, 125 WriteAppend, 126 ReadWrite, 127 } direction { Read }; 128 129 static NonnullRefPtr<PathRedirection> create(String path, int fd, decltype(direction) direction) 130 { 131 return adopt_ref(*new PathRedirection(move(path), fd, direction)); 132 } 133 134 virtual ErrorOr<NonnullRefPtr<Rewiring>> apply() const override; 135 virtual ~PathRedirection(); 136 137private: 138 PathRedirection(String path, int fd, decltype(direction) direction) 139 : path(move(path)) 140 , fd(fd) 141 , direction(direction) 142 { 143 } 144 145 virtual bool is_path_redirection() const override { return true; } 146}; 147 148struct FdRedirection : public Redirection { 149public: 150 static NonnullRefPtr<FdRedirection> create(int old_fd, int new_fd, Rewiring::Close close) 151 { 152 return adopt_ref(*new FdRedirection(old_fd, new_fd, close)); 153 } 154 155 static NonnullRefPtr<FdRedirection> create(int old_fd, int new_fd, FdRedirection* pipe_end, Rewiring::Close close) 156 { 157 return adopt_ref(*new FdRedirection(old_fd, new_fd, pipe_end, close)); 158 } 159 160 virtual ~FdRedirection(); 161 162 virtual ErrorOr<NonnullRefPtr<Rewiring>> apply() const override 163 { 164 return adopt_ref(*new Rewiring(old_fd, new_fd, other_pipe_end, action)); 165 } 166 167 int old_fd { -1 }; 168 int new_fd { -1 }; 169 FdRedirection* other_pipe_end { nullptr }; 170 Rewiring::Close action { Rewiring::Close::None }; 171 172private: 173 FdRedirection(int source, int dest, Rewiring::Close close) 174 : FdRedirection(source, dest, nullptr, close) 175 { 176 } 177 178 FdRedirection(int old_fd, int new_fd, FdRedirection* pipe_end, Rewiring::Close close) 179 : old_fd(old_fd) 180 , new_fd(new_fd) 181 , other_pipe_end(pipe_end) 182 , action(close) 183 { 184 } 185 186 virtual bool is_fd_redirection() const override { return true; } 187}; 188 189class Pipeline : public RefCounted<Pipeline> { 190public: 191 pid_t pgid { -1 }; 192}; 193 194struct NodeWithAction { 195 mutable NonnullRefPtr<Node> node; 196 enum Action { 197 And, 198 Or, 199 Sequence, 200 } action; 201 202 NodeWithAction(Node& node, Action action) 203 : node(node) 204 , action(action) 205 { 206 } 207}; 208 209struct Command { 210 Vector<String> argv; 211 Vector<NonnullRefPtr<Redirection>> redirections; 212 bool should_wait { true }; 213 bool is_pipe_source { false }; 214 bool should_notify_if_in_background { true }; 215 bool should_immediately_execute_next { false }; 216 217 mutable RefPtr<Pipeline> pipeline; 218 Vector<NodeWithAction> next_chain; 219 Optional<Position> position; 220}; 221 222struct HitTestResult { 223 RefPtr<Node const> matching_node; 224 RefPtr<Node const> closest_node_with_semantic_meaning; // This is used if matching_node is a bareword 225 RefPtr<Node const> closest_command_node; // This is used if matching_node is a bareword, and it is not the first in a list 226}; 227 228class Value : public RefCounted<Value> { 229public: 230 virtual ErrorOr<Vector<String>> resolve_as_list(RefPtr<Shell>) = 0; 231 virtual ErrorOr<String> resolve_as_string(RefPtr<Shell> shell); 232 virtual ErrorOr<Vector<Command>> resolve_as_commands(RefPtr<Shell>); 233 virtual ErrorOr<NonnullRefPtr<Value>> resolve_without_cast(RefPtr<Shell>) { return *this; } 234 virtual ErrorOr<NonnullRefPtr<Value>> clone() const = 0; 235 virtual ErrorOr<NonnullRefPtr<Value>> with_slices(NonnullRefPtr<Slice> slice) const&; 236 virtual ErrorOr<NonnullRefPtr<Value>> with_slices(Vector<NonnullRefPtr<Slice>> slices) const&; 237 virtual ~Value(); 238 virtual bool is_command() const { return false; } 239 virtual bool is_glob() const { return false; } 240 virtual bool is_job() const { return false; } 241 virtual bool is_list() const { return false; } 242 virtual bool is_string() const { return false; } 243 virtual bool is_list_without_resolution() const { return false; } 244 245protected: 246 Value& set_slices(Vector<NonnullRefPtr<Slice>> slices) 247 { 248 m_slices = move(slices); 249 return *this; 250 } 251 Vector<NonnullRefPtr<Slice>> m_slices; 252}; 253 254class CommandValue final : public Value { 255public: 256 virtual ErrorOr<Vector<String>> resolve_as_list(RefPtr<Shell>) override; 257 virtual ErrorOr<Vector<Command>> resolve_as_commands(RefPtr<Shell>) override; 258 virtual ErrorOr<NonnullRefPtr<Value>> clone() const override { return TRY(try_make_ref_counted<CommandValue>(m_command))->set_slices(m_slices); } 259 virtual ~CommandValue(); 260 virtual bool is_command() const override { return true; } 261 CommandValue(Command command) 262 : m_command(move(command)) 263 { 264 } 265 266 CommandValue(Vector<String> argv, Position position) 267 : m_command({ move(argv), {}, true, false, true, false, nullptr, {}, move(position) }) 268 { 269 } 270 271private: 272 Command m_command; 273}; 274 275class CommandSequenceValue final : public Value { 276public: 277 virtual ErrorOr<Vector<String>> resolve_as_list(RefPtr<Shell>) override; 278 virtual ErrorOr<Vector<Command>> resolve_as_commands(RefPtr<Shell>) override; 279 virtual ErrorOr<NonnullRefPtr<Value>> clone() const override { return TRY(try_make_ref_counted<CommandSequenceValue>(m_contained_values))->set_slices(m_slices); } 280 virtual ~CommandSequenceValue(); 281 virtual bool is_command() const override { return true; } 282 CommandSequenceValue(Vector<Command> commands) 283 : m_contained_values(move(commands)) 284 { 285 } 286 287private: 288 Vector<Command> m_contained_values; 289}; 290 291class JobValue final : public Value { 292public: 293 virtual ErrorOr<Vector<String>> resolve_as_list(RefPtr<Shell>) override { VERIFY_NOT_REACHED(); } 294 virtual ErrorOr<String> resolve_as_string(RefPtr<Shell>) override { return String::formatted("%{}", m_job->job_id()); } 295 virtual ErrorOr<Vector<Command>> resolve_as_commands(RefPtr<Shell>) override { VERIFY_NOT_REACHED(); } 296 virtual ErrorOr<NonnullRefPtr<Value>> clone() const override { return TRY(try_make_ref_counted<JobValue>(m_job))->set_slices(m_slices); } 297 virtual ~JobValue(); 298 virtual bool is_job() const override { return true; } 299 JobValue(RefPtr<Job> job) 300 : m_job(move(job)) 301 { 302 } 303 304 RefPtr<Job> const job() const { return m_job; } 305 306private: 307 RefPtr<Job> m_job; 308}; 309 310class ListValue final : public Value { 311public: 312 virtual ErrorOr<Vector<String>> resolve_as_list(RefPtr<Shell>) override; 313 virtual ErrorOr<NonnullRefPtr<Value>> resolve_without_cast(RefPtr<Shell>) override; 314 virtual ErrorOr<NonnullRefPtr<Value>> clone() const override { return TRY(try_make_ref_counted<ListValue>(m_contained_values))->set_slices(m_slices); } 315 virtual ~ListValue(); 316 virtual bool is_list() const override { return true; } 317 virtual bool is_list_without_resolution() const override { return true; } 318 ListValue(Vector<String> values); 319 ListValue(Vector<NonnullRefPtr<Value>> values) 320 : m_contained_values(move(values)) 321 { 322 } 323 324 Vector<NonnullRefPtr<Value>> const& values() const { return m_contained_values; } 325 Vector<NonnullRefPtr<Value>>& values() { return m_contained_values; } 326 327private: 328 Vector<NonnullRefPtr<Value>> m_contained_values; 329}; 330 331class StringValue final : public Value { 332public: 333 virtual ErrorOr<Vector<String>> resolve_as_list(RefPtr<Shell>) override; 334 virtual ErrorOr<String> resolve_as_string(RefPtr<Shell> shell) override; 335 virtual ErrorOr<NonnullRefPtr<Value>> clone() const override { return TRY(try_make_ref_counted<StringValue>(m_string, m_split, m_keep_empty))->set_slices(m_slices); } 336 virtual ~StringValue(); 337 virtual bool is_string() const override { return m_split.is_empty(); } 338 virtual bool is_list() const override { return !m_split.is_empty(); } 339 ErrorOr<NonnullRefPtr<Value>> resolve_without_cast(RefPtr<Shell>) override; 340 StringValue(String string, String split_by = {}, bool keep_empty = false) 341 : m_string(move(string)) 342 , m_split(move(split_by)) 343 , m_keep_empty(keep_empty) 344 { 345 } 346 347private: 348 String m_string; 349 String m_split; 350 bool m_keep_empty { false }; 351}; 352 353class GlobValue final : public Value { 354public: 355 virtual ErrorOr<Vector<String>> resolve_as_list(RefPtr<Shell>) override; 356 virtual ErrorOr<NonnullRefPtr<Value>> clone() const override { return TRY(try_make_ref_counted<GlobValue>(m_glob, m_generation_position))->set_slices(m_slices); } 357 virtual ~GlobValue(); 358 virtual bool is_glob() const override { return true; } 359 GlobValue(String glob, Position position) 360 : m_glob(move(glob)) 361 , m_generation_position(move(position)) 362 { 363 } 364 365private: 366 String m_glob; 367 Position m_generation_position; 368}; 369 370class SimpleVariableValue final : public Value { 371public: 372 virtual ErrorOr<Vector<String>> resolve_as_list(RefPtr<Shell>) override; 373 virtual ErrorOr<String> resolve_as_string(RefPtr<Shell>) override; 374 virtual ErrorOr<NonnullRefPtr<Value>> resolve_without_cast(RefPtr<Shell>) override; 375 virtual ErrorOr<NonnullRefPtr<Value>> clone() const override { return TRY(try_make_ref_counted<SimpleVariableValue>(m_name))->set_slices(m_slices); } 376 virtual ~SimpleVariableValue(); 377 SimpleVariableValue(String name) 378 : m_name(move(name)) 379 { 380 } 381 382private: 383 String m_name; 384}; 385 386class SpecialVariableValue final : public Value { 387public: 388 virtual ErrorOr<Vector<String>> resolve_as_list(RefPtr<Shell>) override; 389 virtual ErrorOr<String> resolve_as_string(RefPtr<Shell>) override; 390 virtual ErrorOr<NonnullRefPtr<Value>> resolve_without_cast(RefPtr<Shell>) override; 391 virtual ErrorOr<NonnullRefPtr<Value>> clone() const override { return TRY(try_make_ref_counted<SpecialVariableValue>(m_name))->set_slices(m_slices); } 392 virtual ~SpecialVariableValue(); 393 SpecialVariableValue(char name) 394 : m_name(name) 395 { 396 } 397 398private: 399 char m_name { 0 }; 400}; 401 402class TildeValue final : public Value { 403public: 404 virtual ErrorOr<Vector<String>> resolve_as_list(RefPtr<Shell>) override; 405 virtual ErrorOr<String> resolve_as_string(RefPtr<Shell>) override; 406 virtual ErrorOr<NonnullRefPtr<Value>> clone() const override { return TRY(try_make_ref_counted<TildeValue>(m_username))->set_slices(m_slices); } 407 virtual ~TildeValue(); 408 virtual bool is_string() const override { return true; } 409 TildeValue(String name) 410 : m_username(move(name)) 411 { 412 } 413 414private: 415 String m_username; 416}; 417 418class Node : public RefCounted<Node> { 419 AK_MAKE_NONCOPYABLE(Node); 420 AK_MAKE_NONMOVABLE(Node); 421 422public: 423 virtual ErrorOr<void> dump(int level) const = 0; 424 virtual ErrorOr<void> for_each_entry(RefPtr<Shell> shell, Function<ErrorOr<IterationDecision>(NonnullRefPtr<Value>)> callback); 425 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) = 0; 426 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) = 0; 427 virtual ErrorOr<Vector<Line::CompletionSuggestion>> complete_for_editor(Shell&, size_t, HitTestResult const&) const; 428 ErrorOr<Vector<Line::CompletionSuggestion>> complete_for_editor(Shell& shell, size_t offset); 429 virtual HitTestResult hit_test_position(size_t offset) const 430 { 431 if (m_position.contains(offset)) 432 return { this, nullptr, nullptr }; 433 return { nullptr, nullptr, nullptr }; 434 } 435 virtual StringView class_name() const { return "Node"sv; } 436 Node(Position); 437 virtual ~Node() = default; 438 439 virtual bool is_bareword() const { return false; } 440 virtual bool is_command() const { return false; } 441 virtual bool is_execute() const { return false; } 442 virtual bool is_glob() const { return false; } 443 virtual bool is_tilde() const { return false; } 444 virtual bool is_variable_decls() const { return false; } 445 virtual bool is_simple_variable() const { return false; } 446 virtual bool is_syntax_error() const; 447 448 virtual bool is_list() const { return false; } 449 virtual bool would_execute() const { return false; } 450 virtual bool should_override_execution_in_current_process() const { return false; } 451 452 Position const& position() const { return m_position; } 453 virtual void clear_syntax_error(); 454 virtual void set_is_syntax_error(SyntaxError& error_node); 455 virtual SyntaxError& syntax_error_node() 456 { 457 VERIFY(is_syntax_error()); 458 return *m_syntax_error_node; 459 } 460 461 virtual RefPtr<Node const> leftmost_trivial_literal() const { return nullptr; } 462 463 ErrorOr<Vector<Command>> to_lazy_evaluated_commands(RefPtr<Shell> shell); 464 465 virtual void visit(NodeVisitor&) { VERIFY_NOT_REACHED(); } 466 virtual void visit(NodeVisitor& visitor) const { const_cast<Node*>(this)->visit(visitor); } 467 468 enum class Kind : u32 { 469 And, 470 Background, 471 BarewordLiteral, 472 BraceExpansion, 473 CastToCommand, 474 CastToList, 475 CloseFdRedirection, 476 CommandLiteral, 477 Comment, 478 ContinuationControl, 479 DoubleQuotedString, 480 DynamicEvaluate, 481 Execute, 482 Fd2FdRedirection, 483 ForLoop, 484 FunctionDeclaration, 485 Glob, 486 Heredoc, 487 HistoryEvent, 488 IfCond, 489 ImmediateExpression, 490 Join, 491 Juxtaposition, 492 ListConcatenate, 493 MatchExpr, 494 Or, 495 Pipe, 496 Range, 497 ReadRedirection, 498 ReadWriteRedirection, 499 Sequence, 500 Slice, 501 SimpleVariable, 502 SpecialVariable, 503 StringLiteral, 504 StringPartCompose, 505 Subshell, 506 SyntaxError, 507 SyntheticValue, 508 Tilde, 509 VariableDeclarations, 510 WriteAppendRedirection, 511 WriteRedirection, 512 __Count, 513 }; 514 515 virtual Kind kind() const = 0; 516 517protected: 518 Position m_position; 519 RefPtr<SyntaxError> m_syntax_error_node; 520}; 521 522#define NODE(name) \ 523 virtual StringView class_name() const override \ 524 { \ 525 return #name##sv; \ 526 } \ 527 virtual Kind kind() const override \ 528 { \ 529 return Kind::name; \ 530 } 531 532class PathRedirectionNode : public Node { 533public: 534 PathRedirectionNode(Position, int, NonnullRefPtr<Node>); 535 virtual ~PathRedirectionNode(); 536 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 537 virtual ErrorOr<Vector<Line::CompletionSuggestion>> complete_for_editor(Shell&, size_t, HitTestResult const&) const override; 538 virtual HitTestResult hit_test_position(size_t offset) const override; 539 virtual bool is_command() const override { return true; } 540 virtual bool is_list() const override { return true; } 541 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 542 543 NonnullRefPtr<Node> const& path() const { return m_path; } 544 int fd() const { return m_fd; } 545 546protected: 547 int m_fd { -1 }; 548 NonnullRefPtr<Node> m_path; 549}; 550 551class And final : public Node { 552public: 553 And(Position, NonnullRefPtr<Node>, NonnullRefPtr<Node>, Position and_position); 554 virtual ~And() = default; 555 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 556 557 NonnullRefPtr<Node> const& left() const { return m_left; } 558 NonnullRefPtr<Node> const& right() const { return m_right; } 559 Position const& and_position() const { return m_and_position; } 560 561private: 562 NODE(And); 563 virtual ErrorOr<void> dump(int level) const override; 564 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 565 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 566 virtual HitTestResult hit_test_position(size_t) const override; 567 568 NonnullRefPtr<Node> m_left; 569 NonnullRefPtr<Node> m_right; 570 Position m_and_position; 571}; 572 573class ListConcatenate final : public Node { 574public: 575 ListConcatenate(Position, Vector<NonnullRefPtr<Node>>); 576 virtual ~ListConcatenate() = default; 577 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 578 Vector<NonnullRefPtr<Node>> const list() const { return m_list; } 579 580private: 581 NODE(ListConcatenate); 582 virtual ErrorOr<void> dump(int level) const override; 583 virtual ErrorOr<void> for_each_entry(RefPtr<Shell> shell, Function<ErrorOr<IterationDecision>(NonnullRefPtr<Value>)> callback) override; 584 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 585 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 586 virtual HitTestResult hit_test_position(size_t) const override; 587 virtual bool is_list() const override { return true; } 588 virtual RefPtr<Node const> leftmost_trivial_literal() const override; 589 590 Vector<NonnullRefPtr<Node>> m_list; 591}; 592 593class Background final : public Node { 594public: 595 Background(Position, NonnullRefPtr<Node>); 596 virtual ~Background() = default; 597 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 598 599 NonnullRefPtr<Node> const& command() const { return m_command; } 600 601private: 602 NODE(Background); 603 virtual ErrorOr<void> dump(int level) const override; 604 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 605 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 606 virtual HitTestResult hit_test_position(size_t) const override; 607 608 NonnullRefPtr<Node> m_command; 609}; 610 611class BarewordLiteral final : public Node { 612public: 613 BarewordLiteral(Position, String); 614 virtual ~BarewordLiteral() = default; 615 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 616 617 String const& text() const { return m_text; } 618 619private: 620 NODE(BarewordLiteral); 621 virtual ErrorOr<void> dump(int level) const override; 622 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 623 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 624 virtual bool is_bareword() const override { return true; } 625 virtual RefPtr<Node const> leftmost_trivial_literal() const override { return this; } 626 627 String m_text; 628}; 629 630class BraceExpansion final : public Node { 631public: 632 BraceExpansion(Position, Vector<NonnullRefPtr<Node>>); 633 virtual ~BraceExpansion() = default; 634 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 635 636 Vector<NonnullRefPtr<Node>> const& entries() const { return m_entries; } 637 638private: 639 NODE(BraceExpansion); 640 virtual ErrorOr<void> dump(int level) const override; 641 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 642 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 643 virtual HitTestResult hit_test_position(size_t) const override; 644 645 Vector<NonnullRefPtr<Node>> m_entries; 646}; 647 648class CastToCommand final : public Node { 649public: 650 CastToCommand(Position, NonnullRefPtr<Node>); 651 virtual ~CastToCommand() = default; 652 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 653 654 NonnullRefPtr<Node> const& inner() const { return m_inner; } 655 656private: 657 NODE(CastToCommand); 658 virtual ErrorOr<void> dump(int level) const override; 659 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 660 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 661 virtual HitTestResult hit_test_position(size_t) const override; 662 virtual ErrorOr<Vector<Line::CompletionSuggestion>> complete_for_editor(Shell&, size_t, HitTestResult const&) const override; 663 virtual bool is_command() const override { return true; } 664 virtual bool is_list() const override { return true; } 665 virtual RefPtr<Node const> leftmost_trivial_literal() const override; 666 667 NonnullRefPtr<Node> m_inner; 668}; 669 670class CastToList final : public Node { 671public: 672 CastToList(Position, RefPtr<Node>); 673 virtual ~CastToList() = default; 674 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 675 676 RefPtr<Node> const& inner() const { return m_inner; } 677 678private: 679 NODE(CastToList); 680 virtual ErrorOr<void> dump(int level) const override; 681 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 682 virtual ErrorOr<void> for_each_entry(RefPtr<Shell> shell, Function<ErrorOr<IterationDecision>(NonnullRefPtr<Value>)> callback) override; 683 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 684 virtual HitTestResult hit_test_position(size_t) const override; 685 virtual bool is_list() const override { return true; } 686 virtual RefPtr<Node const> leftmost_trivial_literal() const override; 687 688 RefPtr<Node> m_inner; 689}; 690 691class CloseFdRedirection final : public Node { 692public: 693 CloseFdRedirection(Position, int); 694 virtual ~CloseFdRedirection(); 695 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 696 697 int fd() const { return m_fd; } 698 699private: 700 NODE(CloseFdRedirection); 701 virtual ErrorOr<void> dump(int level) const override; 702 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 703 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 704 virtual bool is_command() const override { return true; } 705 706 int m_fd { -1 }; 707}; 708 709class CommandLiteral final : public Node { 710public: 711 CommandLiteral(Position, Command); 712 virtual ~CommandLiteral(); 713 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 714 715 Command const& command() const { return m_command; } 716 717private: 718 NODE(CommandLiteral); 719 virtual ErrorOr<void> dump(int level) const override; 720 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 721 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override { VERIFY_NOT_REACHED(); } 722 virtual bool is_command() const override { return true; } 723 virtual bool is_list() const override { return true; } 724 725 Command m_command; 726}; 727 728class Comment : public Node { 729public: 730 Comment(Position, String); 731 virtual ~Comment(); 732 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 733 734 String const& text() const { return m_text; } 735 736private: 737 NODE(Comment); 738 virtual ErrorOr<void> dump(int level) const override; 739 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 740 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 741 742 String m_text; 743}; 744 745class ContinuationControl final : public Node { 746public: 747 enum ContinuationKind { 748 Break, 749 Continue, 750 }; 751 ContinuationControl(Position position, ContinuationKind kind) 752 : Node(move(position)) 753 , m_kind(kind) 754 { 755 } 756 virtual ~ContinuationControl() = default; 757 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 758 759 ContinuationKind continuation_kind() const { return m_kind; } 760 761private: 762 NODE(ContinuationControl); 763 764 virtual ErrorOr<void> dump(int level) const override; 765 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 766 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 767 768 ContinuationKind m_kind { ContinuationKind::Break }; 769}; 770 771class DynamicEvaluate final : public Node { 772public: 773 DynamicEvaluate(Position, NonnullRefPtr<Node>); 774 virtual ~DynamicEvaluate(); 775 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 776 777 NonnullRefPtr<Node> const& inner() const { return m_inner; } 778 779private: 780 NODE(DynamicEvaluate); 781 virtual ErrorOr<void> dump(int level) const override; 782 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 783 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 784 virtual HitTestResult hit_test_position(size_t) const override; 785 786 virtual bool is_bareword() const override { return m_inner->is_bareword(); } 787 virtual bool is_command() const override { return is_list(); } 788 virtual bool is_execute() const override { return true; } 789 virtual bool is_glob() const override { return m_inner->is_glob(); } 790 virtual bool is_list() const override 791 { 792 return m_inner->is_list() || m_inner->is_command() || m_inner->is_glob(); // Anything that generates a list. 793 } 794 795 NonnullRefPtr<Node> m_inner; 796}; 797 798class DoubleQuotedString final : public Node { 799public: 800 DoubleQuotedString(Position, RefPtr<Node>); 801 virtual ~DoubleQuotedString(); 802 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 803 804 RefPtr<Node> const& inner() const { return m_inner; } 805 806private: 807 NODE(DoubleQuotedString); 808 virtual ErrorOr<void> dump(int level) const override; 809 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 810 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 811 virtual HitTestResult hit_test_position(size_t) const override; 812 813 RefPtr<Node> m_inner; 814}; 815 816class Fd2FdRedirection final : public Node { 817public: 818 Fd2FdRedirection(Position, int, int); 819 virtual ~Fd2FdRedirection(); 820 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 821 822 int source_fd() const { return m_old_fd; } 823 int dest_fd() const { return m_new_fd; } 824 825private: 826 NODE(Fd2FdRedirection); 827 virtual ErrorOr<void> dump(int level) const override; 828 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 829 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 830 virtual bool is_command() const override { return true; } 831 832 int m_old_fd { -1 }; 833 int m_new_fd { -1 }; 834}; 835 836class FunctionDeclaration final : public Node { 837public: 838 FunctionDeclaration(Position, NameWithPosition name, Vector<NameWithPosition> argument_names, RefPtr<AST::Node> body); 839 virtual ~FunctionDeclaration(); 840 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 841 842 NameWithPosition const& name() const { return m_name; } 843 Vector<NameWithPosition> const arguments() const { return m_arguments; } 844 RefPtr<Node> const& block() const { return m_block; } 845 846private: 847 NODE(FunctionDeclaration); 848 virtual ErrorOr<void> dump(int level) const override; 849 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 850 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 851 virtual HitTestResult hit_test_position(size_t) const override; 852 virtual ErrorOr<Vector<Line::CompletionSuggestion>> complete_for_editor(Shell&, size_t, HitTestResult const&) const override; 853 virtual bool would_execute() const override { return true; } 854 virtual bool should_override_execution_in_current_process() const override { return true; } 855 856 NameWithPosition m_name; 857 Vector<NameWithPosition> m_arguments; 858 RefPtr<AST::Node> m_block; 859}; 860 861class ForLoop final : public Node { 862public: 863 ForLoop(Position, Optional<NameWithPosition> variable, Optional<NameWithPosition> index_variable, RefPtr<AST::Node> iterated_expr, RefPtr<AST::Node> block, Optional<Position> in_kw_position = {}, Optional<Position> index_kw_position = {}); 864 virtual ~ForLoop(); 865 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 866 867 Optional<NameWithPosition> const& variable() const { return m_variable; } 868 Optional<NameWithPosition> const& index_variable() const { return m_index_variable; } 869 RefPtr<Node> const& iterated_expression() const { return m_iterated_expression; } 870 RefPtr<Node> const& block() const { return m_block; } 871 Optional<Position> const index_keyword_position() const { return m_index_kw_position; } 872 Optional<Position> const in_keyword_position() const { return m_in_kw_position; } 873 874private: 875 NODE(ForLoop); 876 virtual ErrorOr<void> dump(int level) const override; 877 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 878 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 879 virtual HitTestResult hit_test_position(size_t) const override; 880 virtual bool would_execute() const override { return true; } 881 virtual bool should_override_execution_in_current_process() const override { return true; } 882 883 Optional<NameWithPosition> m_variable; 884 Optional<NameWithPosition> m_index_variable; 885 RefPtr<AST::Node> m_iterated_expression; 886 RefPtr<AST::Node> m_block; 887 Optional<Position> m_in_kw_position; 888 Optional<Position> m_index_kw_position; 889}; 890 891class Glob final : public Node { 892public: 893 Glob(Position, String); 894 virtual ~Glob(); 895 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 896 897 String const& text() const { return m_text; } 898 899private: 900 NODE(Glob); 901 virtual ErrorOr<void> dump(int level) const override; 902 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 903 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 904 virtual bool is_glob() const override { return true; } 905 virtual bool is_list() const override { return true; } 906 907 String m_text; 908}; 909 910struct HistorySelector { 911 enum EventKind { 912 IndexFromStart, 913 IndexFromEnd, 914 StartingStringLookup, 915 ContainingStringLookup, 916 }; 917 enum WordSelectorKind { 918 Index, 919 Last, 920 }; 921 922 struct { 923 EventKind kind { IndexFromStart }; 924 size_t index { 0 }; 925 Position text_position; 926 String text; 927 } event; 928 929 struct WordSelector { 930 WordSelectorKind kind { Index }; 931 size_t selector { 0 }; 932 Position position; 933 RefPtr<AST::SyntaxError> syntax_error_node; 934 935 size_t resolve(size_t size) const 936 { 937 if (kind == Index) 938 return selector; 939 if (kind == Last) 940 return size - selector - 1; 941 VERIFY_NOT_REACHED(); 942 } 943 }; 944 struct { 945 WordSelector start; 946 Optional<WordSelector> end; 947 } word_selector_range; 948}; 949 950class HistoryEvent final : public Node { 951public: 952 HistoryEvent(Position, HistorySelector); 953 virtual ~HistoryEvent(); 954 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 955 956 HistorySelector const& selector() const { return m_selector; } 957 958private: 959 NODE(HistoryEvent); 960 virtual ErrorOr<void> dump(int level) const override; 961 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 962 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 963 964 HistorySelector m_selector; 965}; 966 967class Execute final : public Node { 968public: 969 Execute(Position, NonnullRefPtr<Node>, bool capture_stdout = false); 970 virtual ~Execute(); 971 void capture_stdout() { m_capture_stdout = true; } 972 NonnullRefPtr<Node>& command() { return m_command; } 973 virtual ErrorOr<void> for_each_entry(RefPtr<Shell> shell, Function<ErrorOr<IterationDecision>(NonnullRefPtr<Value>)> callback) override; 974 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 975 976 NonnullRefPtr<Node> const& command() const { return m_command; } 977 bool does_capture_stdout() const { return m_capture_stdout; } 978 979private: 980 NODE(Execute); 981 virtual ErrorOr<void> dump(int level) const override; 982 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 983 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 984 virtual HitTestResult hit_test_position(size_t) const override; 985 virtual ErrorOr<Vector<Line::CompletionSuggestion>> complete_for_editor(Shell&, size_t, HitTestResult const&) const override; 986 virtual bool is_execute() const override { return true; } 987 virtual bool would_execute() const override { return true; } 988 989 NonnullRefPtr<Node> m_command; 990 bool m_capture_stdout { false }; 991}; 992 993class IfCond final : public Node { 994public: 995 IfCond(Position, Optional<Position> else_position, NonnullRefPtr<AST::Node> cond_expr, RefPtr<AST::Node> true_branch, RefPtr<AST::Node> false_branch); 996 virtual ~IfCond(); 997 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 998 999 NonnullRefPtr<Node> const& condition() const { return m_condition; } 1000 RefPtr<Node> const& true_branch() const { return m_true_branch; } 1001 RefPtr<Node> const& false_branch() const { return m_false_branch; } 1002 RefPtr<Node>& false_branch() { return m_false_branch; } 1003 Optional<Position> const else_position() const { return m_else_position; } 1004 1005private: 1006 NODE(IfCond); 1007 virtual ErrorOr<void> dump(int level) const override; 1008 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 1009 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 1010 virtual HitTestResult hit_test_position(size_t) const override; 1011 virtual bool should_override_execution_in_current_process() const override { return true; } 1012 1013 NonnullRefPtr<AST::Node> m_condition; 1014 RefPtr<AST::Node> m_true_branch; 1015 RefPtr<AST::Node> m_false_branch; 1016 1017 Optional<Position> m_else_position; 1018}; 1019 1020class ImmediateExpression final : public Node { 1021public: 1022 ImmediateExpression(Position, NameWithPosition function, Vector<NonnullRefPtr<AST::Node>> arguments, Optional<Position> closing_brace_position); 1023 virtual ~ImmediateExpression(); 1024 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 1025 1026 Vector<NonnullRefPtr<Node>> const& arguments() const { return m_arguments; } 1027 auto const& function() const { return m_function; } 1028 String const& function_name() const { return m_function.name; } 1029 Position const& function_position() const { return m_function.position; } 1030 bool has_closing_brace() const { return m_closing_brace_position.has_value(); } 1031 1032private: 1033 NODE(ImmediateExpression); 1034 virtual ErrorOr<void> dump(int level) const override; 1035 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 1036 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 1037 ErrorOr<Vector<Line::CompletionSuggestion>> complete_for_editor(Shell&, size_t, HitTestResult const&) const override; 1038 virtual HitTestResult hit_test_position(size_t) const override; 1039 1040 Vector<NonnullRefPtr<AST::Node>> m_arguments; 1041 NameWithPosition m_function; 1042 Optional<Position> m_closing_brace_position; 1043}; 1044 1045class Join final : public Node { 1046public: 1047 Join(Position, NonnullRefPtr<Node>, NonnullRefPtr<Node>); 1048 virtual ~Join(); 1049 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 1050 1051 NonnullRefPtr<Node> const& left() const { return m_left; } 1052 NonnullRefPtr<Node> const& right() const { return m_right; } 1053 1054private: 1055 NODE(Join); 1056 virtual ErrorOr<void> dump(int level) const override; 1057 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 1058 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 1059 virtual HitTestResult hit_test_position(size_t) const override; 1060 virtual bool is_command() const override { return true; } 1061 virtual bool is_list() const override { return true; } 1062 virtual RefPtr<Node const> leftmost_trivial_literal() const override; 1063 1064 NonnullRefPtr<Node> m_left; 1065 NonnullRefPtr<Node> m_right; 1066}; 1067 1068struct MatchEntry { 1069 Variant<Vector<NonnullRefPtr<Node>>, Vector<Regex<ECMA262>>> options; 1070 Optional<Vector<String>> match_names; 1071 Optional<Position> match_as_position; 1072 Vector<Position> pipe_positions; 1073 RefPtr<Node> body; 1074}; 1075 1076class MatchExpr final : public Node { 1077public: 1078 MatchExpr(Position, NonnullRefPtr<Node> expr, String name, Optional<Position> as_position, Vector<MatchEntry> entries); 1079 virtual ~MatchExpr(); 1080 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 1081 1082 NonnullRefPtr<Node> const& matched_expr() const { return m_matched_expr; } 1083 String const& expr_name() const { return m_expr_name; } 1084 Vector<MatchEntry> const& entries() const { return m_entries; } 1085 Optional<Position> const& as_position() const { return m_as_position; } 1086 1087private: 1088 NODE(MatchExpr); 1089 virtual ErrorOr<void> dump(int level) const override; 1090 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 1091 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 1092 virtual HitTestResult hit_test_position(size_t) const override; 1093 virtual bool would_execute() const override { return true; } 1094 virtual bool should_override_execution_in_current_process() const override { return true; } 1095 1096 NonnullRefPtr<Node> m_matched_expr; 1097 String m_expr_name; 1098 Optional<Position> m_as_position; 1099 Vector<MatchEntry> m_entries; 1100}; 1101 1102class Or final : public Node { 1103public: 1104 Or(Position, NonnullRefPtr<Node>, NonnullRefPtr<Node>, Position or_position); 1105 virtual ~Or(); 1106 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 1107 1108 NonnullRefPtr<Node> const& left() const { return m_left; } 1109 NonnullRefPtr<Node> const& right() const { return m_right; } 1110 Position const& or_position() const { return m_or_position; } 1111 1112private: 1113 NODE(Or); 1114 virtual ErrorOr<void> dump(int level) const override; 1115 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 1116 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 1117 virtual HitTestResult hit_test_position(size_t) const override; 1118 1119 NonnullRefPtr<Node> m_left; 1120 NonnullRefPtr<Node> m_right; 1121 Position m_or_position; 1122}; 1123 1124class Pipe final : public Node { 1125public: 1126 Pipe(Position, NonnullRefPtr<Node>, NonnullRefPtr<Node>); 1127 virtual ~Pipe(); 1128 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 1129 1130 NonnullRefPtr<Node> const& left() const { return m_left; } 1131 NonnullRefPtr<Node> const& right() const { return m_right; } 1132 1133private: 1134 NODE(Pipe); 1135 virtual ErrorOr<void> dump(int level) const override; 1136 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 1137 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 1138 virtual HitTestResult hit_test_position(size_t) const override; 1139 virtual bool is_command() const override { return true; } 1140 1141 NonnullRefPtr<Node> m_left; 1142 NonnullRefPtr<Node> m_right; 1143}; 1144 1145class Range final : public Node { 1146public: 1147 Range(Position, NonnullRefPtr<Node>, NonnullRefPtr<Node>); 1148 virtual ~Range(); 1149 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 1150 1151 NonnullRefPtr<Node> const& start() const { return m_start; } 1152 NonnullRefPtr<Node> const& end() const { return m_end; } 1153 1154private: 1155 NODE(Range); 1156 virtual ErrorOr<void> dump(int level) const override; 1157 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 1158 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 1159 virtual HitTestResult hit_test_position(size_t) const override; 1160 1161 NonnullRefPtr<Node> m_start; 1162 NonnullRefPtr<Node> m_end; 1163}; 1164 1165class ReadRedirection final : public PathRedirectionNode { 1166public: 1167 ReadRedirection(Position, int, NonnullRefPtr<Node>); 1168 virtual ~ReadRedirection(); 1169 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 1170 1171private: 1172 NODE(ReadRedirection); 1173 virtual ErrorOr<void> dump(int level) const override; 1174 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 1175}; 1176 1177class ReadWriteRedirection final : public PathRedirectionNode { 1178public: 1179 ReadWriteRedirection(Position, int, NonnullRefPtr<Node>); 1180 virtual ~ReadWriteRedirection(); 1181 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 1182 1183private: 1184 NODE(ReadWriteRedirection); 1185 virtual ErrorOr<void> dump(int level) const override; 1186 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 1187}; 1188 1189class Sequence final : public Node { 1190public: 1191 Sequence(Position, Vector<NonnullRefPtr<Node>>, Vector<Position> separator_positions); 1192 virtual ~Sequence(); 1193 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 1194 1195 Vector<NonnullRefPtr<Node>> const& entries() const { return m_entries; } 1196 1197 Vector<Position> const& separator_positions() const { return m_separator_positions; } 1198 1199private: 1200 NODE(Sequence); 1201 virtual ErrorOr<void> dump(int level) const override; 1202 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 1203 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 1204 virtual HitTestResult hit_test_position(size_t) const override; 1205 virtual bool is_list() const override { return true; } 1206 virtual bool should_override_execution_in_current_process() const override { return true; } 1207 virtual RefPtr<Node const> leftmost_trivial_literal() const override; 1208 1209 Vector<NonnullRefPtr<Node>> m_entries; 1210 Vector<Position> m_separator_positions; 1211}; 1212 1213class Subshell final : public Node { 1214public: 1215 Subshell(Position, RefPtr<Node> block); 1216 virtual ~Subshell(); 1217 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 1218 1219 RefPtr<Node> const& block() const { return m_block; } 1220 1221private: 1222 NODE(Subshell); 1223 virtual ErrorOr<void> dump(int level) const override; 1224 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 1225 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 1226 virtual HitTestResult hit_test_position(size_t) const override; 1227 virtual bool would_execute() const override { return false; } 1228 virtual bool should_override_execution_in_current_process() const override { return true; } 1229 1230 RefPtr<AST::Node> m_block; 1231}; 1232 1233class Slice final : public Node { 1234public: 1235 Slice(Position, NonnullRefPtr<AST::Node>); 1236 virtual ~Slice() override; 1237 1238 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 1239 1240 NonnullRefPtr<AST::Node> selector() const { return m_selector; } 1241 1242 virtual ErrorOr<void> dump(int level) const override; 1243 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 1244 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 1245 virtual ErrorOr<Vector<Line::CompletionSuggestion>> complete_for_editor(Shell&, size_t, HitTestResult const&) const override; 1246 virtual HitTestResult hit_test_position(size_t) const override; 1247 1248protected: 1249 NODE(Slice); 1250 NonnullRefPtr<AST::Node> m_selector; 1251}; 1252 1253class VariableNode : public Node { 1254public: 1255 VariableNode(Position position) 1256 : Node(move(position)) 1257 { 1258 } 1259 1260 void set_slice(NonnullRefPtr<Slice>&& slice) 1261 { 1262 VERIFY(!m_slice); 1263 m_slice = move(slice); 1264 if (m_slice->is_syntax_error()) 1265 set_is_syntax_error(m_slice->syntax_error_node()); 1266 } 1267 1268 Slice const* slice() const { return m_slice.ptr(); } 1269 1270protected: 1271 RefPtr<Slice> m_slice; 1272}; 1273 1274class SimpleVariable final : public VariableNode { 1275public: 1276 SimpleVariable(Position, String); 1277 virtual ~SimpleVariable(); 1278 1279 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 1280 String const& name() const { return m_name; } 1281 1282private: 1283 NODE(SimpleVariable); 1284 virtual ErrorOr<void> dump(int level) const override; 1285 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 1286 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 1287 virtual ErrorOr<Vector<Line::CompletionSuggestion>> complete_for_editor(Shell&, size_t, HitTestResult const&) const override; 1288 virtual HitTestResult hit_test_position(size_t) const override; 1289 virtual bool is_simple_variable() const override { return true; } 1290 1291 String m_name; 1292}; 1293 1294class SpecialVariable final : public VariableNode { 1295public: 1296 SpecialVariable(Position, char); 1297 virtual ~SpecialVariable(); 1298 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 1299 1300 char name() const { return m_name; } 1301 1302private: 1303 NODE(SpecialVariable); 1304 virtual ErrorOr<void> dump(int level) const override; 1305 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 1306 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 1307 virtual ErrorOr<Vector<Line::CompletionSuggestion>> complete_for_editor(Shell&, size_t, HitTestResult const&) const override; 1308 virtual HitTestResult hit_test_position(size_t) const override; 1309 1310 char m_name { 0 }; 1311}; 1312 1313class Juxtaposition final : public Node { 1314public: 1315 enum class Mode { 1316 ListExpand, 1317 StringExpand, 1318 }; 1319 Juxtaposition(Position, NonnullRefPtr<Node>, NonnullRefPtr<Node>, Mode = Mode::ListExpand); 1320 virtual ~Juxtaposition(); 1321 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 1322 1323 NonnullRefPtr<Node> const& left() const { return m_left; } 1324 NonnullRefPtr<Node> const& right() const { return m_right; } 1325 1326private: 1327 NODE(Juxtaposition); 1328 virtual ErrorOr<void> dump(int level) const override; 1329 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 1330 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 1331 virtual HitTestResult hit_test_position(size_t) const override; 1332 virtual ErrorOr<Vector<Line::CompletionSuggestion>> complete_for_editor(Shell&, size_t, HitTestResult const&) const override; 1333 1334 NonnullRefPtr<Node> m_left; 1335 NonnullRefPtr<Node> m_right; 1336 Mode m_mode { Mode::ListExpand }; 1337}; 1338 1339class Heredoc final : public Node { 1340public: 1341 Heredoc(Position, String end, bool allow_interpolation, bool deindent, Optional<int> target_fd = {}); 1342 virtual ~Heredoc(); 1343 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 1344 1345 String const& end() const { return m_end; } 1346 bool allow_interpolation() const { return m_allows_interpolation; } 1347 bool deindent() const { return m_deindent; } 1348 Optional<int> target_fd() const { return m_target_fd; } 1349 bool evaluates_to_string() const { return !m_target_fd.has_value(); } 1350 RefPtr<AST::Node> const& contents() const { return m_contents; } 1351 void set_contents(RefPtr<AST::Node> contents) 1352 { 1353 m_contents = move(contents); 1354 if (m_contents->is_syntax_error()) 1355 set_is_syntax_error(m_contents->syntax_error_node()); 1356 else if (is_syntax_error()) 1357 clear_syntax_error(); 1358 } 1359 1360private: 1361 NODE(Heredoc); 1362 virtual ErrorOr<void> dump(int level) const override; 1363 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 1364 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 1365 virtual HitTestResult hit_test_position(size_t) const override; 1366 virtual RefPtr<Node const> leftmost_trivial_literal() const override { return this; }; 1367 1368 String m_end; 1369 bool m_allows_interpolation { false }; 1370 bool m_deindent { false }; 1371 Optional<int> m_target_fd; 1372 RefPtr<AST::Node> m_contents; 1373}; 1374 1375class StringLiteral final : public Node { 1376public: 1377 enum class EnclosureType { 1378 None, 1379 SingleQuotes, 1380 DoubleQuotes, 1381 }; 1382 1383 StringLiteral(Position, String, EnclosureType); 1384 virtual ~StringLiteral(); 1385 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 1386 1387 String const& text() const { return m_text; } 1388 EnclosureType enclosure_type() const { return m_enclosure_type; } 1389 1390private: 1391 NODE(StringLiteral); 1392 virtual ErrorOr<void> dump(int level) const override; 1393 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 1394 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 1395 virtual RefPtr<Node const> leftmost_trivial_literal() const override { return this; }; 1396 1397 String m_text; 1398 EnclosureType m_enclosure_type; 1399}; 1400 1401class StringPartCompose final : public Node { 1402public: 1403 StringPartCompose(Position, NonnullRefPtr<Node>, NonnullRefPtr<Node>); 1404 virtual ~StringPartCompose(); 1405 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 1406 1407 NonnullRefPtr<Node> const& left() const { return m_left; } 1408 NonnullRefPtr<Node> const& right() const { return m_right; } 1409 1410private: 1411 NODE(StringPartCompose); 1412 virtual ErrorOr<void> dump(int level) const override; 1413 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 1414 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 1415 virtual HitTestResult hit_test_position(size_t) const override; 1416 1417 NonnullRefPtr<Node> m_left; 1418 NonnullRefPtr<Node> m_right; 1419}; 1420 1421class SyntaxError final : public Node { 1422public: 1423 SyntaxError(Position, String, bool is_continuable = false); 1424 virtual ~SyntaxError(); 1425 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 1426 1427 String const& error_text() const { return m_syntax_error_text; } 1428 bool is_continuable() const { return m_is_continuable; } 1429 1430 virtual void clear_syntax_error() override 1431 { 1432 m_is_cleared = true; 1433 } 1434 virtual void set_is_syntax_error(SyntaxError& error) override 1435 { 1436 m_position = error.position(); 1437 m_is_cleared = error.m_is_cleared; 1438 m_is_continuable = error.m_is_continuable; 1439 m_syntax_error_text = error.error_text(); 1440 } 1441 1442 virtual bool is_syntax_error() const override { return !m_is_cleared; } 1443 1444private: 1445 NODE(SyntaxError); 1446 virtual ErrorOr<void> dump(int level) const override; 1447 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 1448 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 1449 virtual HitTestResult hit_test_position(size_t) const override { return { nullptr, nullptr, nullptr }; } 1450 virtual SyntaxError& syntax_error_node() override; 1451 1452 String m_syntax_error_text; 1453 bool m_is_continuable { false }; 1454 bool m_is_cleared { false }; 1455}; 1456 1457class SyntheticNode final : public Node { 1458public: 1459 SyntheticNode(Position, NonnullRefPtr<Value>); 1460 virtual ~SyntheticNode() = default; 1461 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 1462 1463 Value const& value() const { return m_value; } 1464 1465private: 1466 NODE(SyntheticValue); 1467 virtual ErrorOr<void> dump(int level) const override; 1468 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 1469 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 1470 1471 NonnullRefPtr<Value> m_value; 1472}; 1473 1474class Tilde final : public Node { 1475public: 1476 Tilde(Position, String); 1477 virtual ~Tilde(); 1478 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 1479 1480 String text() const; 1481 1482private: 1483 NODE(Tilde); 1484 virtual ErrorOr<void> dump(int level) const override; 1485 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 1486 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 1487 virtual ErrorOr<Vector<Line::CompletionSuggestion>> complete_for_editor(Shell&, size_t, HitTestResult const&) const override; 1488 virtual HitTestResult hit_test_position(size_t) const override; 1489 virtual bool is_tilde() const override { return true; } 1490 1491 String m_username; 1492}; 1493 1494class VariableDeclarations final : public Node { 1495public: 1496 struct Variable { 1497 NonnullRefPtr<Node> name; 1498 NonnullRefPtr<Node> value; 1499 }; 1500 VariableDeclarations(Position, Vector<Variable> variables); 1501 virtual ~VariableDeclarations(); 1502 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 1503 1504 Vector<Variable> const& variables() const { return m_variables; } 1505 1506private: 1507 NODE(VariableDeclarations); 1508 virtual ErrorOr<void> dump(int level) const override; 1509 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 1510 virtual ErrorOr<void> highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; 1511 virtual HitTestResult hit_test_position(size_t) const override; 1512 virtual bool is_variable_decls() const override { return true; } 1513 1514 Vector<Variable> m_variables; 1515}; 1516 1517class WriteAppendRedirection final : public PathRedirectionNode { 1518public: 1519 WriteAppendRedirection(Position, int, NonnullRefPtr<Node>); 1520 virtual ~WriteAppendRedirection(); 1521 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 1522 1523private: 1524 NODE(WriteAppendRedirection); 1525 virtual ErrorOr<void> dump(int level) const override; 1526 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 1527}; 1528 1529class WriteRedirection final : public PathRedirectionNode { 1530public: 1531 WriteRedirection(Position, int, NonnullRefPtr<Node>); 1532 virtual ~WriteRedirection(); 1533 virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); } 1534 1535private: 1536 NODE(WriteRedirection); 1537 virtual ErrorOr<void> dump(int level) const override; 1538 virtual ErrorOr<RefPtr<Value>> run(RefPtr<Shell>) override; 1539}; 1540 1541} 1542 1543namespace AK { 1544 1545template<> 1546struct Formatter<Shell::AST::Command> : StandardFormatter { 1547 Formatter() = default; 1548 explicit Formatter(StandardFormatter formatter) 1549 : StandardFormatter(formatter) 1550 { 1551 } 1552 1553 ErrorOr<void> format(FormatBuilder&, Shell::AST::Command const& value); 1554}; 1555 1556}