From 3d51bcaa4ed551132fd676e53323b3999f9506c1 Mon Sep 17 00:00:00 2001 From: AnotherTest Date: Sun, 3 Jan 2021 12:36:25 +0330 Subject: Shell: Give commands and globs a source position This will help us have nicer error reporting. --- Shell/AST.cpp | 37 ++++++++++++++++++++++++++++++------- Shell/AST.h | 9 ++++++--- 2 files changed, 36 insertions(+), 10 deletions(-) (limited to 'Shell') diff --git a/Shell/AST.cpp b/Shell/AST.cpp index 1998c67404..6e56aa93a0 100644 --- a/Shell/AST.cpp +++ b/Shell/AST.cpp @@ -130,6 +130,22 @@ static inline void print_indented(const String& str, int indent) dbgprintf("%s\n", str.characters()); } +static inline Optional merge_positions(const Optional& left, const Optional& right) +{ + if (!left.has_value()) + return right; + + if (!right.has_value()) + return left; + + return Position { + .start_offset = left->start_offset, + .end_offset = right->end_offset, + .start_line = left->start_line, + .end_line = right->end_line, + }; +} + static inline Vector join_commands(Vector left, Vector right) { Command command; @@ -147,6 +163,8 @@ static inline Vector join_commands(Vector left, Vector commands; commands.append(left); commands.append(command); @@ -184,7 +202,7 @@ Vector Node::to_lazy_evaluated_commands(RefPtr shell) if (would_execute()) { // Wrap the node in a "should immediately execute next" command. return { - Command { {}, {}, true, false, true, true, {}, { NodeWithAction(*this, NodeWithAction::Sequence) } } + Command { {}, {}, true, false, true, true, {}, { NodeWithAction(*this, NodeWithAction::Sequence) }, position() } }; } @@ -343,10 +361,13 @@ RefPtr ListConcatenate::run(RefPtr shell) if (result->is_command() || element_value->is_command()) { auto joined_commands = join_commands(result->resolve_as_commands(shell), element_value->resolve_as_commands(shell)); - if (joined_commands.size() == 1) - result = create(joined_commands[0]); - else + if (joined_commands.size() == 1) { + auto& command = joined_commands[0]; + command.position = position(); + result = create(command); + } else { result = create(move(joined_commands)); + } } else { NonnullRefPtrVector values; @@ -594,7 +615,7 @@ RefPtr CastToCommand::run(RefPtr shell) return value; auto argv = value->resolve_as_list(shell); - return create(move(argv)); + return create(move(argv), position()); } void CastToCommand::highlight_in_editor(Line::Editor& editor, Shell& shell, HighlightMetadata metadata) @@ -715,6 +736,7 @@ void CloseFdRedirection::dump(int level) const RefPtr CloseFdRedirection::run(RefPtr) { Command command; + command.position = position(); command.redirections.append(adopt(*new CloseRedirection(m_fd))); return create(move(command)); } @@ -870,7 +892,7 @@ RefPtr DynamicEvaluate::run(RefPtr shell) // If it's anything else, we're just gonna cast it to a list. auto list = result->resolve_as_list(shell); - return create(move(list)); + return create(move(list), position()); } void DynamicEvaluate::highlight_in_editor(Line::Editor& editor, Shell& shell, HighlightMetadata metadata) @@ -908,6 +930,7 @@ void Fd2FdRedirection::dump(int level) const RefPtr Fd2FdRedirection::run(RefPtr) { Command command; + command.position = position(); command.redirections.append(FdRedirection::create(m_new_fd, m_old_fd, Rewiring::Close::None)); return create(move(command)); } @@ -1156,7 +1179,7 @@ void Glob::dump(int level) const RefPtr Glob::run(RefPtr) { - return create(m_text); + return create(m_text, position()); } void Glob::highlight_in_editor(Line::Editor& editor, Shell&, HighlightMetadata metadata) diff --git a/Shell/AST.h b/Shell/AST.h index d22f103593..21eff815a3 100644 --- a/Shell/AST.h +++ b/Shell/AST.h @@ -225,6 +225,7 @@ struct Command { mutable RefPtr pipeline; Vector next_chain; + Optional position; }; struct HitTestResult { @@ -258,8 +259,8 @@ public: { } - CommandValue(Vector argv) - : m_command({ move(argv), {}, true, false, true, false, nullptr, {} }) + CommandValue(Vector argv, Position position) + : m_command({ move(argv), {}, true, false, true, false, nullptr, {}, move(position) }) { } @@ -347,13 +348,15 @@ public: virtual Vector resolve_as_list(RefPtr) override; virtual ~GlobValue(); virtual bool is_glob() const override { return true; } - GlobValue(String glob) + GlobValue(String glob, Position position) : m_glob(move(glob)) + , m_generation_position(move(position)) { } private: String m_glob; + Position m_generation_position; }; class SimpleVariableValue final : public Value { -- cgit v1.2.3