AST.h 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214
  1. /*
  2. * Copyright (c) 2020, the SerenityOS developers.
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright notice, this
  9. * list of conditions and the following disclaimer.
  10. *
  11. * 2. Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  16. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  19. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  21. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  22. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  23. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  24. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #pragma once
  27. #include "Forward.h"
  28. #include "Job.h"
  29. #include "NodeVisitor.h"
  30. #include <AK/InlineLinkedList.h>
  31. #include <AK/NonnullRefPtr.h>
  32. #include <AK/RefCounted.h>
  33. #include <AK/RefPtr.h>
  34. #include <AK/String.h>
  35. #include <AK/Types.h>
  36. #include <AK/Vector.h>
  37. #include <LibLine/Editor.h>
  38. namespace AST {
  39. struct HighlightMetadata {
  40. bool is_first_in_list { true };
  41. };
  42. struct Position {
  43. size_t start_offset { 0 };
  44. size_t end_offset { 0 };
  45. struct Line {
  46. size_t line_number { 0 };
  47. size_t line_column { 0 };
  48. bool operator==(const Line& other) const
  49. {
  50. return line_number == other.line_number && line_column == other.line_column;
  51. }
  52. } start_line, end_line;
  53. bool contains(size_t offset) const { return start_offset <= offset && offset <= end_offset; }
  54. };
  55. struct FdRedirection;
  56. struct Rewiring : public RefCounted<Rewiring> {
  57. int source_fd { -1 };
  58. int dest_fd { -1 };
  59. FdRedirection* other_pipe_end { nullptr };
  60. enum class Close {
  61. None,
  62. Source,
  63. Destination,
  64. RefreshDestination,
  65. ImmediatelyCloseDestination,
  66. } fd_action { Close::None };
  67. Rewiring(int source, int dest, Close close = Close::None)
  68. : source_fd(source)
  69. , dest_fd(dest)
  70. , fd_action(close)
  71. {
  72. }
  73. Rewiring(int source, int dest, FdRedirection* other_end, Close close)
  74. : source_fd(source)
  75. , dest_fd(dest)
  76. , other_pipe_end(other_end)
  77. , fd_action(close)
  78. {
  79. }
  80. };
  81. struct Redirection : public RefCounted<Redirection> {
  82. virtual Result<NonnullRefPtr<Rewiring>, String> apply() const = 0;
  83. virtual ~Redirection();
  84. virtual bool is_path_redirection() const { return false; }
  85. virtual bool is_fd_redirection() const { return false; }
  86. virtual bool is_close_redirection() const { return false; }
  87. };
  88. struct CloseRedirection : public Redirection {
  89. int fd { -1 };
  90. virtual Result<NonnullRefPtr<Rewiring>, String> apply() const override;
  91. virtual ~CloseRedirection();
  92. CloseRedirection(int fd)
  93. : fd(fd)
  94. {
  95. }
  96. private:
  97. virtual bool is_close_redirection() const override { return true; }
  98. };
  99. struct PathRedirection : public Redirection {
  100. String path;
  101. int fd { -1 };
  102. enum {
  103. Read,
  104. Write,
  105. WriteAppend,
  106. ReadWrite,
  107. } direction { Read };
  108. static NonnullRefPtr<PathRedirection> create(String path, int fd, decltype(direction) direction)
  109. {
  110. return adopt(*new PathRedirection(move(path), fd, direction));
  111. }
  112. virtual Result<NonnullRefPtr<Rewiring>, String> apply() const override;
  113. virtual ~PathRedirection();
  114. private:
  115. PathRedirection(String path, int fd, decltype(direction) direction)
  116. : path(move(path))
  117. , fd(fd)
  118. , direction(direction)
  119. {
  120. }
  121. virtual bool is_path_redirection() const override { return true; }
  122. };
  123. struct FdRedirection : public Redirection {
  124. public:
  125. static NonnullRefPtr<FdRedirection> create(int source, int dest, Rewiring::Close close)
  126. {
  127. return adopt(*new FdRedirection(source, dest, close));
  128. }
  129. static NonnullRefPtr<FdRedirection> create(int source, int dest, FdRedirection* pipe_end, Rewiring::Close close)
  130. {
  131. return adopt(*new FdRedirection(source, dest, pipe_end, close));
  132. }
  133. virtual ~FdRedirection();
  134. virtual Result<NonnullRefPtr<Rewiring>, String> apply() const override
  135. {
  136. return adopt(*new Rewiring(source_fd, dest_fd, other_pipe_end, action));
  137. }
  138. int source_fd { -1 };
  139. int dest_fd { -1 };
  140. FdRedirection* other_pipe_end { nullptr };
  141. Rewiring::Close action { Rewiring::Close::None };
  142. private:
  143. FdRedirection(int source, int dest, Rewiring::Close close)
  144. : FdRedirection(source, dest, nullptr, close)
  145. {
  146. }
  147. FdRedirection(int source, int dest, FdRedirection* pipe_end, Rewiring::Close close)
  148. : source_fd(source)
  149. , dest_fd(dest)
  150. , other_pipe_end(pipe_end)
  151. , action(close)
  152. {
  153. }
  154. virtual bool is_fd_redirection() const override { return true; }
  155. };
  156. class Pipeline : public RefCounted<Pipeline> {
  157. public:
  158. pid_t pgid { -1 };
  159. };
  160. struct NodeWithAction {
  161. mutable NonnullRefPtr<Node> node;
  162. enum Action {
  163. And,
  164. Or,
  165. Sequence,
  166. } action;
  167. NodeWithAction(Node& node, Action action)
  168. : node(node)
  169. , action(action)
  170. {
  171. }
  172. };
  173. struct Command {
  174. Vector<String> argv;
  175. NonnullRefPtrVector<Redirection> redirections;
  176. bool should_wait { true };
  177. bool is_pipe_source { false };
  178. bool should_notify_if_in_background { true };
  179. bool should_immediately_execute_next { false };
  180. mutable RefPtr<Pipeline> pipeline;
  181. Vector<NodeWithAction> next_chain;
  182. };
  183. struct HitTestResult {
  184. RefPtr<Node> matching_node;
  185. RefPtr<Node> closest_node_with_semantic_meaning; // This is used if matching_node is a bareword
  186. RefPtr<Node> closest_command_node; // This is used if matching_node is a bareword, and it is not the first in a list
  187. };
  188. class Value : public RefCounted<Value> {
  189. public:
  190. virtual Vector<String> resolve_as_list(RefPtr<Shell>) = 0;
  191. virtual Vector<Command> resolve_as_commands(RefPtr<Shell>);
  192. virtual NonnullRefPtr<Value> resolve_without_cast(RefPtr<Shell>) { return *this; }
  193. virtual ~Value();
  194. virtual bool is_command() const { return false; }
  195. virtual bool is_glob() const { return false; }
  196. virtual bool is_job() const { return false; }
  197. virtual bool is_list() const { return false; }
  198. virtual bool is_string() const { return false; }
  199. virtual bool is_list_without_resolution() const { return false; }
  200. };
  201. class CommandValue final : public Value {
  202. public:
  203. virtual Vector<String> resolve_as_list(RefPtr<Shell>) override;
  204. virtual Vector<Command> resolve_as_commands(RefPtr<Shell>) override;
  205. virtual ~CommandValue();
  206. virtual bool is_command() const override { return true; }
  207. CommandValue(Command command)
  208. : m_command(move(command))
  209. {
  210. }
  211. CommandValue(Vector<String> argv)
  212. : m_command({ move(argv), {}, true, false, true, false, nullptr, {} })
  213. {
  214. }
  215. private:
  216. Command m_command;
  217. };
  218. class CommandSequenceValue final : public Value {
  219. public:
  220. virtual Vector<String> resolve_as_list(RefPtr<Shell>) override;
  221. virtual Vector<Command> resolve_as_commands(RefPtr<Shell>) override;
  222. virtual ~CommandSequenceValue();
  223. virtual bool is_command() const override { return true; }
  224. CommandSequenceValue(Vector<Command> commands)
  225. : m_contained_values(move(commands))
  226. {
  227. }
  228. private:
  229. Vector<Command> m_contained_values;
  230. };
  231. class JobValue final : public Value {
  232. public:
  233. virtual Vector<String> resolve_as_list(RefPtr<Shell>) override { ASSERT_NOT_REACHED(); }
  234. virtual Vector<Command> resolve_as_commands(RefPtr<Shell>) override { ASSERT_NOT_REACHED(); }
  235. virtual ~JobValue();
  236. virtual bool is_job() const override { return true; }
  237. JobValue(RefPtr<Job> job)
  238. : m_job(move(job))
  239. {
  240. }
  241. const RefPtr<Job> job() const { return m_job; }
  242. private:
  243. RefPtr<Job> m_job;
  244. };
  245. class ListValue final : public Value {
  246. public:
  247. virtual Vector<String> resolve_as_list(RefPtr<Shell>) override;
  248. virtual NonnullRefPtr<Value> resolve_without_cast(RefPtr<Shell>) override;
  249. virtual ~ListValue();
  250. virtual bool is_list() const override { return true; }
  251. virtual bool is_list_without_resolution() const override { return true; }
  252. ListValue(Vector<String> values);
  253. ListValue(Vector<NonnullRefPtr<Value>> values)
  254. : m_contained_values(move(static_cast<NonnullRefPtrVector<Value>&>(values)))
  255. {
  256. }
  257. const NonnullRefPtrVector<Value>& values() const { return m_contained_values; }
  258. NonnullRefPtrVector<Value>& values() { return m_contained_values; }
  259. private:
  260. NonnullRefPtrVector<Value> m_contained_values;
  261. };
  262. class StringValue final : public Value {
  263. public:
  264. virtual Vector<String> resolve_as_list(RefPtr<Shell>) override;
  265. virtual ~StringValue();
  266. virtual bool is_string() const override { return m_split.is_null(); }
  267. virtual bool is_list() const override { return !m_split.is_null(); }
  268. StringValue(String string, String split_by = {}, bool keep_empty = false)
  269. : m_string(move(string))
  270. , m_split(move(split_by))
  271. , m_keep_empty(keep_empty)
  272. {
  273. }
  274. private:
  275. String m_string;
  276. String m_split;
  277. bool m_keep_empty { false };
  278. };
  279. class GlobValue final : public Value {
  280. public:
  281. virtual Vector<String> resolve_as_list(RefPtr<Shell>) override;
  282. virtual ~GlobValue();
  283. virtual bool is_glob() const override { return true; }
  284. GlobValue(String glob)
  285. : m_glob(move(glob))
  286. {
  287. }
  288. private:
  289. String m_glob;
  290. };
  291. class SimpleVariableValue final : public Value {
  292. public:
  293. virtual Vector<String> resolve_as_list(RefPtr<Shell>) override;
  294. virtual NonnullRefPtr<Value> resolve_without_cast(RefPtr<Shell>) override;
  295. virtual ~SimpleVariableValue();
  296. SimpleVariableValue(String name)
  297. : m_name(move(name))
  298. {
  299. }
  300. private:
  301. String m_name;
  302. };
  303. class SpecialVariableValue final : public Value {
  304. public:
  305. virtual Vector<String> resolve_as_list(RefPtr<Shell>) override;
  306. virtual ~SpecialVariableValue();
  307. SpecialVariableValue(char name)
  308. : m_name(name)
  309. {
  310. }
  311. private:
  312. char m_name { -1 };
  313. };
  314. class TildeValue final : public Value {
  315. public:
  316. virtual Vector<String> resolve_as_list(RefPtr<Shell>) override;
  317. virtual ~TildeValue();
  318. virtual bool is_string() const override { return true; }
  319. TildeValue(String name)
  320. : m_username(move(name))
  321. {
  322. }
  323. private:
  324. String m_username;
  325. };
  326. class Node : public RefCounted<Node> {
  327. public:
  328. virtual void dump(int level) const = 0;
  329. virtual void for_each_entry(RefPtr<Shell> shell, Function<IterationDecision(NonnullRefPtr<Value>)> callback);
  330. virtual RefPtr<Value> run(RefPtr<Shell>) = 0;
  331. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) = 0;
  332. virtual Vector<Line::CompletionSuggestion> complete_for_editor(Shell&, size_t, const HitTestResult&);
  333. Vector<Line::CompletionSuggestion> complete_for_editor(Shell& shell, size_t offset);
  334. virtual HitTestResult hit_test_position(size_t offset)
  335. {
  336. if (m_position.contains(offset))
  337. return { this, nullptr, nullptr };
  338. return { nullptr, nullptr, nullptr };
  339. }
  340. virtual String class_name() const { return "Node"; }
  341. Node(Position);
  342. virtual ~Node();
  343. virtual bool is_bareword() const { return false; }
  344. virtual bool is_command() const { return false; }
  345. virtual bool is_execute() const { return false; }
  346. virtual bool is_glob() const { return false; }
  347. virtual bool is_tilde() const { return false; }
  348. virtual bool is_variable_decls() const { return false; }
  349. virtual bool is_simple_variable() const { return false; }
  350. virtual bool is_syntax_error() const { return m_is_syntax_error; }
  351. virtual bool is_list() const { return false; }
  352. virtual bool would_execute() const { return false; }
  353. const Position& position() const { return m_position; }
  354. void set_is_syntax_error(const SyntaxError& error_node)
  355. {
  356. m_is_syntax_error = true;
  357. m_syntax_error_node = error_node;
  358. }
  359. virtual const SyntaxError& syntax_error_node() const
  360. {
  361. ASSERT(is_syntax_error());
  362. return *m_syntax_error_node;
  363. }
  364. virtual RefPtr<Node> leftmost_trivial_literal() const { return nullptr; }
  365. Vector<Command> to_lazy_evaluated_commands(RefPtr<Shell> shell);
  366. virtual void visit(NodeVisitor&) { ASSERT_NOT_REACHED(); }
  367. virtual void visit(NodeVisitor& visitor) const { const_cast<Node*>(this)->visit(visitor); }
  368. enum class Kind : u32 {
  369. And,
  370. ListConcatenate,
  371. Background,
  372. BarewordLiteral,
  373. CastToCommand,
  374. CastToList,
  375. CloseFdRedirection,
  376. CommandLiteral,
  377. Comment,
  378. DynamicEvaluate,
  379. DoubleQuotedString,
  380. Fd2FdRedirection,
  381. FunctionDeclaration,
  382. ForLoop,
  383. Glob,
  384. Execute,
  385. IfCond,
  386. Join,
  387. MatchExpr,
  388. Or,
  389. Pipe,
  390. ReadRedirection,
  391. ReadWriteRedirection,
  392. Sequence,
  393. Subshell,
  394. SimpleVariable,
  395. SpecialVariable,
  396. Juxtaposition,
  397. StringLiteral,
  398. StringPartCompose,
  399. SyntaxError,
  400. Tilde,
  401. VariableDeclarations,
  402. WriteAppendRedirection,
  403. WriteRedirection,
  404. __Count,
  405. };
  406. virtual Kind kind() const = 0;
  407. protected:
  408. Position m_position;
  409. bool m_is_syntax_error { false };
  410. RefPtr<const SyntaxError> m_syntax_error_node;
  411. };
  412. #define NODE(name) \
  413. virtual String class_name() const override { return #name; } \
  414. virtual Kind kind() const override { return Kind::name; }
  415. class PathRedirectionNode : public Node {
  416. public:
  417. PathRedirectionNode(Position, int, NonnullRefPtr<Node>);
  418. virtual ~PathRedirectionNode();
  419. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  420. virtual Vector<Line::CompletionSuggestion> complete_for_editor(Shell&, size_t, const HitTestResult&) override;
  421. virtual HitTestResult hit_test_position(size_t offset) override;
  422. virtual bool is_command() const override { return true; }
  423. virtual bool is_list() const override { return true; }
  424. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  425. const NonnullRefPtr<Node>& path() const { return m_path; }
  426. int fd() const { return m_fd; }
  427. protected:
  428. int m_fd { -1 };
  429. NonnullRefPtr<Node> m_path;
  430. };
  431. class And final : public Node {
  432. public:
  433. And(Position, NonnullRefPtr<Node>, NonnullRefPtr<Node>, Position and_position);
  434. virtual ~And();
  435. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  436. const NonnullRefPtr<Node>& left() const { return m_left; }
  437. const NonnullRefPtr<Node>& right() const { return m_right; }
  438. const Position& and_position() const { return m_and_position; }
  439. private:
  440. NODE(And);
  441. virtual void dump(int level) const override;
  442. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  443. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  444. virtual HitTestResult hit_test_position(size_t) override;
  445. NonnullRefPtr<Node> m_left;
  446. NonnullRefPtr<Node> m_right;
  447. Position m_and_position;
  448. };
  449. class ListConcatenate final : public Node {
  450. public:
  451. ListConcatenate(Position, Vector<NonnullRefPtr<Node>>);
  452. virtual ~ListConcatenate();
  453. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  454. const Vector<NonnullRefPtr<Node>> list() const { return m_list; }
  455. private:
  456. NODE(ListConcatenate);
  457. virtual void dump(int level) const override;
  458. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  459. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  460. virtual HitTestResult hit_test_position(size_t) override;
  461. virtual bool is_list() const override { return true; }
  462. virtual RefPtr<Node> leftmost_trivial_literal() const override;
  463. Vector<NonnullRefPtr<Node>> m_list;
  464. };
  465. class Background final : public Node {
  466. public:
  467. Background(Position, NonnullRefPtr<Node>);
  468. virtual ~Background();
  469. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  470. const NonnullRefPtr<Node>& command() const { return m_command; }
  471. private:
  472. NODE(Background);
  473. virtual void dump(int level) const override;
  474. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  475. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  476. virtual HitTestResult hit_test_position(size_t) override;
  477. NonnullRefPtr<Node> m_command;
  478. };
  479. class BarewordLiteral final : public Node {
  480. public:
  481. BarewordLiteral(Position, String);
  482. virtual ~BarewordLiteral();
  483. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  484. const String& text() const { return m_text; }
  485. private:
  486. NODE(BarewordLiteral);
  487. virtual void dump(int level) const override;
  488. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  489. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  490. virtual bool is_bareword() const override { return true; }
  491. virtual RefPtr<Node> leftmost_trivial_literal() const override { return this; }
  492. String m_text;
  493. };
  494. class CastToCommand final : public Node {
  495. public:
  496. CastToCommand(Position, NonnullRefPtr<Node>);
  497. virtual ~CastToCommand();
  498. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  499. const NonnullRefPtr<Node>& inner() const { return m_inner; }
  500. private:
  501. NODE(CastToCommand);
  502. virtual void dump(int level) const override;
  503. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  504. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  505. virtual HitTestResult hit_test_position(size_t) override;
  506. virtual Vector<Line::CompletionSuggestion> complete_for_editor(Shell&, size_t, const HitTestResult&) override;
  507. virtual bool is_command() const override { return true; }
  508. virtual bool is_list() const override { return true; }
  509. virtual RefPtr<Node> leftmost_trivial_literal() const override;
  510. NonnullRefPtr<Node> m_inner;
  511. };
  512. class CastToList final : public Node {
  513. public:
  514. CastToList(Position, RefPtr<Node>);
  515. virtual ~CastToList();
  516. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  517. const RefPtr<Node>& inner() const { return m_inner; }
  518. private:
  519. NODE(CastToList);
  520. virtual void dump(int level) const override;
  521. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  522. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  523. virtual HitTestResult hit_test_position(size_t) override;
  524. virtual bool is_list() const override { return true; }
  525. virtual RefPtr<Node> leftmost_trivial_literal() const override;
  526. RefPtr<Node> m_inner;
  527. };
  528. class CloseFdRedirection final : public Node {
  529. public:
  530. CloseFdRedirection(Position, int);
  531. virtual ~CloseFdRedirection();
  532. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  533. int fd() const { return m_fd; }
  534. private:
  535. NODE(CloseFdRedirection);
  536. virtual void dump(int level) const override;
  537. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  538. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  539. virtual bool is_command() const override { return true; }
  540. int m_fd { -1 };
  541. };
  542. class CommandLiteral final : public Node {
  543. public:
  544. CommandLiteral(Position, Command);
  545. virtual ~CommandLiteral();
  546. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  547. const Command& command() const { return m_command; }
  548. private:
  549. NODE(CommandLiteral);
  550. virtual void dump(int level) const override;
  551. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  552. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override { ASSERT_NOT_REACHED(); }
  553. virtual bool is_command() const override { return true; }
  554. virtual bool is_list() const override { return true; }
  555. Command m_command;
  556. };
  557. class Comment : public Node {
  558. public:
  559. Comment(Position, String);
  560. virtual ~Comment();
  561. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  562. const String& text() const { return m_text; }
  563. private:
  564. NODE(Comment);
  565. virtual void dump(int level) const override;
  566. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  567. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  568. String m_text;
  569. };
  570. class DynamicEvaluate final : public Node {
  571. public:
  572. DynamicEvaluate(Position, NonnullRefPtr<Node>);
  573. virtual ~DynamicEvaluate();
  574. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  575. const NonnullRefPtr<Node>& inner() const { return m_inner; }
  576. private:
  577. NODE(DynamicEvaluate);
  578. virtual void dump(int level) const override;
  579. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  580. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  581. virtual HitTestResult hit_test_position(size_t) override;
  582. virtual bool is_bareword() const override { return m_inner->is_bareword(); }
  583. virtual bool is_command() const override { return is_list(); }
  584. virtual bool is_execute() const override { return true; }
  585. virtual bool is_glob() const override { return m_inner->is_glob(); }
  586. virtual bool is_list() const override
  587. {
  588. return m_inner->is_list() || m_inner->is_command() || m_inner->is_glob(); // Anything that generates a list.
  589. }
  590. NonnullRefPtr<Node> m_inner;
  591. };
  592. class DoubleQuotedString final : public Node {
  593. public:
  594. DoubleQuotedString(Position, RefPtr<Node>);
  595. virtual ~DoubleQuotedString();
  596. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  597. const RefPtr<Node>& inner() const { return m_inner; }
  598. private:
  599. NODE(DoubleQuotedString);
  600. virtual void dump(int level) const override;
  601. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  602. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  603. virtual HitTestResult hit_test_position(size_t) override;
  604. RefPtr<Node> m_inner;
  605. };
  606. class Fd2FdRedirection final : public Node {
  607. public:
  608. Fd2FdRedirection(Position, int, int);
  609. virtual ~Fd2FdRedirection();
  610. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  611. int source_fd() const { return m_source_fd; }
  612. int dest_fd() const { return m_dest_fd; }
  613. private:
  614. NODE(Fd2FdRedirection);
  615. virtual void dump(int level) const override;
  616. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  617. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  618. virtual bool is_command() const override { return true; }
  619. int m_source_fd { -1 };
  620. int m_dest_fd { -1 };
  621. };
  622. class FunctionDeclaration final : public Node {
  623. public:
  624. struct NameWithPosition {
  625. String name;
  626. Position position;
  627. };
  628. FunctionDeclaration(Position, NameWithPosition name, Vector<NameWithPosition> argument_names, RefPtr<AST::Node> body);
  629. virtual ~FunctionDeclaration();
  630. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  631. const NameWithPosition& name() const { return m_name; }
  632. const Vector<NameWithPosition> arguments() const { return m_arguments; }
  633. const RefPtr<Node>& block() const { return m_block; }
  634. private:
  635. NODE(FunctionDeclaration);
  636. virtual void dump(int level) const override;
  637. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  638. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  639. virtual HitTestResult hit_test_position(size_t) override;
  640. virtual Vector<Line::CompletionSuggestion> complete_for_editor(Shell&, size_t, const HitTestResult&) override;
  641. virtual bool would_execute() const override { return true; }
  642. NameWithPosition m_name;
  643. Vector<NameWithPosition> m_arguments;
  644. RefPtr<AST::Node> m_block;
  645. };
  646. class ForLoop final : public Node {
  647. public:
  648. ForLoop(Position, String variable_name, NonnullRefPtr<AST::Node> iterated_expr, RefPtr<AST::Node> block, Optional<Position> in_kw_position = {});
  649. virtual ~ForLoop();
  650. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  651. const String& variable_name() const { return m_variable_name; }
  652. const NonnullRefPtr<Node>& iterated_expression() const { return m_iterated_expression; }
  653. const RefPtr<Node>& block() const { return m_block; }
  654. const Optional<Position> in_keyword_position() const { return m_in_kw_position; }
  655. private:
  656. NODE(ForLoop);
  657. virtual void dump(int level) const override;
  658. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  659. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  660. virtual HitTestResult hit_test_position(size_t) override;
  661. virtual bool would_execute() const override { return true; }
  662. String m_variable_name;
  663. NonnullRefPtr<AST::Node> m_iterated_expression;
  664. RefPtr<AST::Node> m_block;
  665. Optional<Position> m_in_kw_position;
  666. };
  667. class Glob final : public Node {
  668. public:
  669. Glob(Position, String);
  670. virtual ~Glob();
  671. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  672. const String& text() const { return m_text; }
  673. private:
  674. NODE(Glob);
  675. virtual void dump(int level) const override;
  676. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  677. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  678. virtual bool is_glob() const override { return true; }
  679. virtual bool is_list() const override { return true; }
  680. String m_text;
  681. };
  682. class Execute final : public Node {
  683. public:
  684. Execute(Position, NonnullRefPtr<Node>, bool capture_stdout = false);
  685. virtual ~Execute();
  686. void capture_stdout() { m_capture_stdout = true; }
  687. NonnullRefPtr<Node>& command() { return m_command; }
  688. virtual void for_each_entry(RefPtr<Shell> shell, Function<IterationDecision(NonnullRefPtr<Value>)> callback) override;
  689. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  690. const NonnullRefPtr<Node>& command() const { return m_command; }
  691. bool does_capture_stdout() const { return m_capture_stdout; }
  692. private:
  693. NODE(Execute);
  694. virtual void dump(int level) const override;
  695. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  696. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  697. virtual HitTestResult hit_test_position(size_t) override;
  698. virtual Vector<Line::CompletionSuggestion> complete_for_editor(Shell&, size_t, const HitTestResult&) override;
  699. virtual bool is_execute() const override { return true; }
  700. virtual bool would_execute() const override { return true; }
  701. NonnullRefPtr<Node> m_command;
  702. bool m_capture_stdout { false };
  703. };
  704. class IfCond final : public Node {
  705. public:
  706. IfCond(Position, Optional<Position> else_position, NonnullRefPtr<AST::Node> cond_expr, RefPtr<AST::Node> true_branch, RefPtr<AST::Node> false_branch);
  707. virtual ~IfCond();
  708. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  709. const NonnullRefPtr<Node>& condition() const { return m_condition; }
  710. const RefPtr<Node>& true_branch() const { return m_true_branch; }
  711. const RefPtr<Node>& false_branch() const { return m_false_branch; }
  712. const Optional<Position> else_position() const { return m_else_position; }
  713. private:
  714. NODE(IfCond);
  715. virtual void dump(int level) const override;
  716. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  717. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  718. virtual HitTestResult hit_test_position(size_t) override;
  719. virtual bool would_execute() const override { return true; }
  720. NonnullRefPtr<AST::Node> m_condition;
  721. RefPtr<AST::Node> m_true_branch;
  722. RefPtr<AST::Node> m_false_branch;
  723. Optional<Position> m_else_position;
  724. };
  725. class Join final : public Node {
  726. public:
  727. Join(Position, NonnullRefPtr<Node>, NonnullRefPtr<Node>);
  728. virtual ~Join();
  729. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  730. const NonnullRefPtr<Node>& left() const { return m_left; }
  731. const NonnullRefPtr<Node>& right() const { return m_right; }
  732. private:
  733. NODE(Join);
  734. virtual void dump(int level) const override;
  735. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  736. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  737. virtual HitTestResult hit_test_position(size_t) override;
  738. virtual bool is_command() const override { return true; }
  739. virtual bool is_list() const override { return true; }
  740. virtual RefPtr<Node> leftmost_trivial_literal() const override;
  741. NonnullRefPtr<Node> m_left;
  742. NonnullRefPtr<Node> m_right;
  743. };
  744. struct MatchEntry {
  745. NonnullRefPtrVector<Node> options;
  746. Vector<Position> pipe_positions;
  747. RefPtr<Node> body;
  748. };
  749. class MatchExpr final : public Node {
  750. public:
  751. MatchExpr(Position, NonnullRefPtr<Node> expr, String name, Optional<Position> as_position, Vector<MatchEntry> entries);
  752. virtual ~MatchExpr();
  753. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  754. const NonnullRefPtr<Node>& matched_expr() const { return m_matched_expr; }
  755. const String& expr_name() const { return m_expr_name; }
  756. const Vector<MatchEntry>& entries() const { return m_entries; }
  757. const Optional<Position>& as_position() const { return m_as_position; }
  758. private:
  759. NODE(MatchExpr);
  760. virtual void dump(int level) const override;
  761. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  762. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  763. virtual HitTestResult hit_test_position(size_t) override;
  764. virtual bool would_execute() const override { return true; }
  765. NonnullRefPtr<Node> m_matched_expr;
  766. String m_expr_name;
  767. Optional<Position> m_as_position;
  768. Vector<MatchEntry> m_entries;
  769. };
  770. class Or final : public Node {
  771. public:
  772. Or(Position, NonnullRefPtr<Node>, NonnullRefPtr<Node>, Position or_position);
  773. virtual ~Or();
  774. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  775. const NonnullRefPtr<Node>& left() const { return m_left; }
  776. const NonnullRefPtr<Node>& right() const { return m_right; }
  777. const Position& or_position() const { return m_or_position; }
  778. private:
  779. NODE(Or);
  780. virtual void dump(int level) const override;
  781. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  782. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  783. virtual HitTestResult hit_test_position(size_t) override;
  784. NonnullRefPtr<Node> m_left;
  785. NonnullRefPtr<Node> m_right;
  786. Position m_or_position;
  787. };
  788. class Pipe final : public Node {
  789. public:
  790. Pipe(Position, NonnullRefPtr<Node>, NonnullRefPtr<Node>);
  791. virtual ~Pipe();
  792. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  793. const NonnullRefPtr<Node>& left() const { return m_left; }
  794. const NonnullRefPtr<Node>& right() const { return m_right; }
  795. private:
  796. NODE(Pipe);
  797. virtual void dump(int level) const override;
  798. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  799. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  800. virtual HitTestResult hit_test_position(size_t) override;
  801. virtual bool is_command() const override { return true; }
  802. NonnullRefPtr<Node> m_left;
  803. NonnullRefPtr<Node> m_right;
  804. };
  805. class ReadRedirection final : public PathRedirectionNode {
  806. public:
  807. ReadRedirection(Position, int, NonnullRefPtr<Node>);
  808. virtual ~ReadRedirection();
  809. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  810. private:
  811. NODE(ReadRedirection);
  812. virtual void dump(int level) const override;
  813. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  814. };
  815. class ReadWriteRedirection final : public PathRedirectionNode {
  816. public:
  817. ReadWriteRedirection(Position, int, NonnullRefPtr<Node>);
  818. virtual ~ReadWriteRedirection();
  819. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  820. private:
  821. NODE(ReadWriteRedirection);
  822. virtual void dump(int level) const override;
  823. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  824. };
  825. class Sequence final : public Node {
  826. public:
  827. Sequence(Position, NonnullRefPtr<Node>, NonnullRefPtr<Node>, Position separator_position);
  828. virtual ~Sequence();
  829. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  830. const NonnullRefPtr<Node>& left() const { return m_left; }
  831. const NonnullRefPtr<Node>& right() const { return m_right; }
  832. const Position& separator_position() const { return m_separator_position; }
  833. private:
  834. NODE(Sequence);
  835. virtual void dump(int level) const override;
  836. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  837. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  838. virtual HitTestResult hit_test_position(size_t) override;
  839. virtual bool is_list() const override { return true; }
  840. virtual bool would_execute() const override { return m_left->would_execute() || m_right->would_execute(); }
  841. NonnullRefPtr<Node> m_left;
  842. NonnullRefPtr<Node> m_right;
  843. Position m_separator_position;
  844. };
  845. class Subshell final : public Node {
  846. public:
  847. Subshell(Position, RefPtr<Node> block);
  848. virtual ~Subshell();
  849. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  850. const RefPtr<Node>& block() const { return m_block; }
  851. private:
  852. NODE(Subshell);
  853. virtual void dump(int level) const override;
  854. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  855. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  856. virtual HitTestResult hit_test_position(size_t) override;
  857. virtual bool would_execute() const override { return true; }
  858. RefPtr<AST::Node> m_block;
  859. };
  860. class SimpleVariable final : public Node {
  861. public:
  862. SimpleVariable(Position, String);
  863. virtual ~SimpleVariable();
  864. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  865. const String& name() const { return m_name; }
  866. private:
  867. NODE(SimpleVariable);
  868. virtual void dump(int level) const override;
  869. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  870. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  871. virtual Vector<Line::CompletionSuggestion> complete_for_editor(Shell&, size_t, const HitTestResult&) override;
  872. virtual HitTestResult hit_test_position(size_t) override;
  873. virtual bool is_simple_variable() const override { return true; }
  874. String m_name;
  875. };
  876. class SpecialVariable final : public Node {
  877. public:
  878. SpecialVariable(Position, char);
  879. virtual ~SpecialVariable();
  880. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  881. char name() const { return m_name; }
  882. private:
  883. NODE(SpecialVariable);
  884. virtual void dump(int level) const override;
  885. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  886. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  887. virtual Vector<Line::CompletionSuggestion> complete_for_editor(Shell&, size_t, const HitTestResult&) override;
  888. virtual HitTestResult hit_test_position(size_t) override;
  889. char m_name { -1 };
  890. };
  891. class Juxtaposition final : public Node {
  892. public:
  893. Juxtaposition(Position, NonnullRefPtr<Node>, NonnullRefPtr<Node>);
  894. virtual ~Juxtaposition();
  895. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  896. const NonnullRefPtr<Node>& left() const { return m_left; }
  897. const NonnullRefPtr<Node>& right() const { return m_right; }
  898. private:
  899. NODE(Juxtaposition);
  900. virtual void dump(int level) const override;
  901. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  902. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  903. virtual HitTestResult hit_test_position(size_t) override;
  904. virtual Vector<Line::CompletionSuggestion> complete_for_editor(Shell&, size_t, const HitTestResult&) override;
  905. NonnullRefPtr<Node> m_left;
  906. NonnullRefPtr<Node> m_right;
  907. };
  908. class StringLiteral final : public Node {
  909. public:
  910. StringLiteral(Position, String);
  911. virtual ~StringLiteral();
  912. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  913. const String& text() const { return m_text; }
  914. private:
  915. NODE(StringLiteral);
  916. virtual void dump(int level) const override;
  917. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  918. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  919. virtual RefPtr<Node> leftmost_trivial_literal() const override { return this; };
  920. String m_text;
  921. };
  922. class StringPartCompose final : public Node {
  923. public:
  924. StringPartCompose(Position, NonnullRefPtr<Node>, NonnullRefPtr<Node>);
  925. virtual ~StringPartCompose();
  926. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  927. const NonnullRefPtr<Node>& left() const { return m_left; }
  928. const NonnullRefPtr<Node>& right() const { return m_right; }
  929. private:
  930. NODE(StringPartCompose);
  931. virtual void dump(int level) const override;
  932. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  933. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  934. virtual HitTestResult hit_test_position(size_t) override;
  935. NonnullRefPtr<Node> m_left;
  936. NonnullRefPtr<Node> m_right;
  937. };
  938. class SyntaxError final : public Node {
  939. public:
  940. SyntaxError(Position, String);
  941. virtual ~SyntaxError();
  942. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  943. const String& error_text() const { return m_syntax_error_text; }
  944. private:
  945. NODE(SyntaxError);
  946. virtual void dump(int level) const override;
  947. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  948. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  949. virtual HitTestResult hit_test_position(size_t) override { return { nullptr, nullptr, nullptr }; }
  950. virtual bool is_syntax_error() const override { return true; }
  951. virtual const SyntaxError& syntax_error_node() const override;
  952. String m_syntax_error_text;
  953. };
  954. class Tilde final : public Node {
  955. public:
  956. Tilde(Position, String);
  957. virtual ~Tilde();
  958. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  959. String text() const;
  960. private:
  961. NODE(Tilde);
  962. virtual void dump(int level) const override;
  963. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  964. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  965. virtual Vector<Line::CompletionSuggestion> complete_for_editor(Shell&, size_t, const HitTestResult&) override;
  966. virtual HitTestResult hit_test_position(size_t) override;
  967. virtual bool is_tilde() const override { return true; }
  968. String m_username;
  969. };
  970. class VariableDeclarations final : public Node {
  971. public:
  972. struct Variable {
  973. NonnullRefPtr<Node> name;
  974. NonnullRefPtr<Node> value;
  975. };
  976. VariableDeclarations(Position, Vector<Variable> variables);
  977. virtual ~VariableDeclarations();
  978. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  979. const Vector<Variable>& variables() const { return m_variables; }
  980. private:
  981. NODE(VariableDeclarations);
  982. virtual void dump(int level) const override;
  983. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  984. virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
  985. virtual HitTestResult hit_test_position(size_t) override;
  986. virtual bool is_variable_decls() const override { return true; }
  987. Vector<Variable> m_variables;
  988. };
  989. class WriteAppendRedirection final : public PathRedirectionNode {
  990. public:
  991. WriteAppendRedirection(Position, int, NonnullRefPtr<Node>);
  992. virtual ~WriteAppendRedirection();
  993. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  994. private:
  995. NODE(WriteAppendRedirection);
  996. virtual void dump(int level) const override;
  997. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  998. };
  999. class WriteRedirection final : public PathRedirectionNode {
  1000. public:
  1001. WriteRedirection(Position, int, NonnullRefPtr<Node>);
  1002. virtual ~WriteRedirection();
  1003. virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
  1004. private:
  1005. NODE(WriteRedirection);
  1006. virtual void dump(int level) const override;
  1007. virtual RefPtr<Value> run(RefPtr<Shell>) override;
  1008. };
  1009. }