mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-25 17:10:23 +00:00
Shell+LibCodeComprehension: Start replacing {Deprecated => }String
This starts by switching all AST members to Strings, and dealing with the fallout.
This commit is contained in:
parent
79e4027480
commit
beeb58bd93
Notes:
sideshowbarker
2024-07-17 05:13:53 +09:00
Author: https://github.com/alimpfard Commit: https://github.com/SerenityOS/serenity/commit/beeb58bd93 Pull-request: https://github.com/SerenityOS/serenity/pull/17538 Reviewed-by: https://github.com/ADKaster
12 changed files with 625 additions and 581 deletions
|
@ -78,7 +78,7 @@ Vector<DeprecatedString> const& ShellComprehensionEngine::DocumentData::sourced_
|
|||
auto& filename = entries[1];
|
||||
if (filename->would_execute())
|
||||
return;
|
||||
auto name_list = const_cast<::Shell::AST::Node*>(filename.ptr())->run(nullptr)->resolve_as_list(nullptr);
|
||||
auto name_list = const_cast<::Shell::AST::Node*>(filename.ptr())->run(nullptr)->resolve_as_list(nullptr).release_value_but_fixme_should_propagate_errors();
|
||||
StringBuilder builder;
|
||||
builder.join(' ', name_list);
|
||||
sourced_files.set(builder.to_deprecated_string());
|
||||
|
@ -107,7 +107,7 @@ NonnullRefPtr<::Shell::AST::Node> ShellComprehensionEngine::DocumentData::parse(
|
|||
if (auto node = parser.parse())
|
||||
return node.release_nonnull();
|
||||
|
||||
return ::Shell::AST::make_ref_counted<::Shell::AST::SyntaxError>(::Shell::AST::Position {}, "Unable to parse file");
|
||||
return ::Shell::AST::make_ref_counted<::Shell::AST::SyntaxError>(::Shell::AST::Position {}, String::from_utf8("Unable to parse file"sv).release_value_but_fixme_should_propagate_errors());
|
||||
}
|
||||
|
||||
size_t ShellComprehensionEngine::resolve(ShellComprehensionEngine::DocumentData const& document, const GUI::TextPosition& position)
|
||||
|
@ -184,7 +184,7 @@ Optional<CodeComprehension::ProjectLocation> ShellComprehensionEngine::find_decl
|
|||
auto& declarations = all_declarations();
|
||||
for (auto& entry : declarations) {
|
||||
for (auto& declaration : entry.value) {
|
||||
if (declaration.name == name)
|
||||
if (declaration.name.view() == name)
|
||||
return declaration.position;
|
||||
}
|
||||
}
|
||||
|
@ -209,7 +209,7 @@ void ShellComprehensionEngine::update_declared_symbols(DocumentData const& docum
|
|||
|
||||
DeprecatedString name;
|
||||
if (literal->is_bareword())
|
||||
name = static_ptr_cast<::Shell::AST::BarewordLiteral const>(literal)->text();
|
||||
name = static_ptr_cast<::Shell::AST::BarewordLiteral const>(literal)->text().to_deprecated_string();
|
||||
|
||||
if (!name.is_empty()) {
|
||||
dbgln("Found variable {}", name);
|
||||
|
@ -222,7 +222,7 @@ void ShellComprehensionEngine::update_declared_symbols(DocumentData const& docum
|
|||
void visit(::Shell::AST::FunctionDeclaration const* node) override
|
||||
{
|
||||
dbgln("Found function {}", node->name().name);
|
||||
declarations.append({ node->name().name, { filename, node->position().start_line.line_number, node->position().start_line.line_column }, CodeComprehension::DeclarationType::Function, {} });
|
||||
declarations.append({ node->name().name.to_deprecated_string(), { filename, node->position().start_line.line_number, node->position().start_line.line_column }, CodeComprehension::DeclarationType::Function, {} });
|
||||
}
|
||||
|
||||
DeprecatedString const& filename;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -9,11 +9,11 @@
|
|||
#include "Forward.h"
|
||||
#include "Job.h"
|
||||
#include "NodeVisitor.h"
|
||||
#include <AK/DeprecatedString.h>
|
||||
#include <AK/Format.h>
|
||||
#include <AK/NonnullRefPtr.h>
|
||||
#include <AK/RefCounted.h>
|
||||
#include <AK/RefPtr.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/Types.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibLine/Editor.h>
|
||||
|
@ -60,7 +60,7 @@ struct Position {
|
|||
};
|
||||
|
||||
struct NameWithPosition {
|
||||
DeprecatedString name;
|
||||
String name;
|
||||
Position position;
|
||||
};
|
||||
|
||||
|
@ -117,7 +117,7 @@ private:
|
|||
};
|
||||
|
||||
struct PathRedirection : public Redirection {
|
||||
DeprecatedString path;
|
||||
String path;
|
||||
int fd { -1 };
|
||||
enum {
|
||||
Read,
|
||||
|
@ -126,7 +126,7 @@ struct PathRedirection : public Redirection {
|
|||
ReadWrite,
|
||||
} direction { Read };
|
||||
|
||||
static NonnullRefPtr<PathRedirection> create(DeprecatedString path, int fd, decltype(direction) direction)
|
||||
static NonnullRefPtr<PathRedirection> create(String path, int fd, decltype(direction) direction)
|
||||
{
|
||||
return adopt_ref(*new PathRedirection(move(path), fd, direction));
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ struct PathRedirection : public Redirection {
|
|||
virtual ~PathRedirection();
|
||||
|
||||
private:
|
||||
PathRedirection(DeprecatedString path, int fd, decltype(direction) direction)
|
||||
PathRedirection(String path, int fd, decltype(direction) direction)
|
||||
: path(move(path))
|
||||
, fd(fd)
|
||||
, direction(direction)
|
||||
|
@ -207,7 +207,7 @@ struct NodeWithAction {
|
|||
};
|
||||
|
||||
struct Command {
|
||||
Vector<DeprecatedString> argv;
|
||||
Vector<String> argv;
|
||||
NonnullRefPtrVector<Redirection> redirections;
|
||||
bool should_wait { true };
|
||||
bool is_pipe_source { false };
|
||||
|
@ -227,13 +227,13 @@ struct HitTestResult {
|
|||
|
||||
class Value : public RefCounted<Value> {
|
||||
public:
|
||||
virtual Vector<DeprecatedString> resolve_as_list(RefPtr<Shell>) = 0;
|
||||
virtual DeprecatedString resolve_as_string(RefPtr<Shell> shell);
|
||||
virtual Vector<Command> resolve_as_commands(RefPtr<Shell>);
|
||||
virtual NonnullRefPtr<Value> resolve_without_cast(RefPtr<Shell>) { return *this; }
|
||||
virtual NonnullRefPtr<Value> clone() const = 0;
|
||||
virtual NonnullRefPtr<Value> with_slices(NonnullRefPtr<Slice> slice) const&;
|
||||
virtual NonnullRefPtr<Value> with_slices(NonnullRefPtrVector<Slice> slices) const&;
|
||||
virtual ErrorOr<Vector<String>> resolve_as_list(RefPtr<Shell>) = 0;
|
||||
virtual ErrorOr<String> resolve_as_string(RefPtr<Shell> shell);
|
||||
virtual ErrorOr<Vector<Command>> resolve_as_commands(RefPtr<Shell>);
|
||||
virtual ErrorOr<NonnullRefPtr<Value>> resolve_without_cast(RefPtr<Shell>) { return *this; }
|
||||
virtual ErrorOr<NonnullRefPtr<Value>> clone() const = 0;
|
||||
virtual ErrorOr<NonnullRefPtr<Value>> with_slices(NonnullRefPtr<Slice> slice) const&;
|
||||
virtual ErrorOr<NonnullRefPtr<Value>> with_slices(NonnullRefPtrVector<Slice> slices) const&;
|
||||
virtual ~Value();
|
||||
virtual bool is_command() const { return false; }
|
||||
virtual bool is_glob() const { return false; }
|
||||
|
@ -253,9 +253,9 @@ protected:
|
|||
|
||||
class CommandValue final : public Value {
|
||||
public:
|
||||
virtual Vector<DeprecatedString> resolve_as_list(RefPtr<Shell>) override;
|
||||
virtual Vector<Command> resolve_as_commands(RefPtr<Shell>) override;
|
||||
virtual NonnullRefPtr<Value> clone() const override { return make_ref_counted<CommandValue>(m_command)->set_slices(m_slices); }
|
||||
virtual ErrorOr<Vector<String>> resolve_as_list(RefPtr<Shell>) override;
|
||||
virtual ErrorOr<Vector<Command>> resolve_as_commands(RefPtr<Shell>) override;
|
||||
virtual ErrorOr<NonnullRefPtr<Value>> clone() const override { return TRY(try_make_ref_counted<CommandValue>(m_command))->set_slices(m_slices); }
|
||||
virtual ~CommandValue();
|
||||
virtual bool is_command() const override { return true; }
|
||||
CommandValue(Command command)
|
||||
|
@ -263,7 +263,7 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
CommandValue(Vector<DeprecatedString> argv, Position position)
|
||||
CommandValue(Vector<String> argv, Position position)
|
||||
: m_command({ move(argv), {}, true, false, true, false, nullptr, {}, move(position) })
|
||||
{
|
||||
}
|
||||
|
@ -274,9 +274,9 @@ private:
|
|||
|
||||
class CommandSequenceValue final : public Value {
|
||||
public:
|
||||
virtual Vector<DeprecatedString> resolve_as_list(RefPtr<Shell>) override;
|
||||
virtual Vector<Command> resolve_as_commands(RefPtr<Shell>) override;
|
||||
virtual NonnullRefPtr<Value> clone() const override { return make_ref_counted<CommandSequenceValue>(m_contained_values)->set_slices(m_slices); }
|
||||
virtual ErrorOr<Vector<String>> resolve_as_list(RefPtr<Shell>) override;
|
||||
virtual ErrorOr<Vector<Command>> resolve_as_commands(RefPtr<Shell>) override;
|
||||
virtual ErrorOr<NonnullRefPtr<Value>> clone() const override { return TRY(try_make_ref_counted<CommandSequenceValue>(m_contained_values))->set_slices(m_slices); }
|
||||
virtual ~CommandSequenceValue();
|
||||
virtual bool is_command() const override { return true; }
|
||||
CommandSequenceValue(Vector<Command> commands)
|
||||
|
@ -290,10 +290,10 @@ private:
|
|||
|
||||
class JobValue final : public Value {
|
||||
public:
|
||||
virtual Vector<DeprecatedString> resolve_as_list(RefPtr<Shell>) override { VERIFY_NOT_REACHED(); }
|
||||
virtual DeprecatedString resolve_as_string(RefPtr<Shell>) override { return DeprecatedString::formatted("%{}", m_job->job_id()); }
|
||||
virtual Vector<Command> resolve_as_commands(RefPtr<Shell>) override { VERIFY_NOT_REACHED(); }
|
||||
virtual NonnullRefPtr<Value> clone() const override { return make_ref_counted<JobValue>(m_job)->set_slices(m_slices); }
|
||||
virtual ErrorOr<Vector<String>> resolve_as_list(RefPtr<Shell>) override { VERIFY_NOT_REACHED(); }
|
||||
virtual ErrorOr<String> resolve_as_string(RefPtr<Shell>) override { return String::formatted("%{}", m_job->job_id()); }
|
||||
virtual ErrorOr<Vector<Command>> resolve_as_commands(RefPtr<Shell>) override { VERIFY_NOT_REACHED(); }
|
||||
virtual ErrorOr<NonnullRefPtr<Value>> clone() const override { return TRY(try_make_ref_counted<JobValue>(m_job))->set_slices(m_slices); }
|
||||
virtual ~JobValue();
|
||||
virtual bool is_job() const override { return true; }
|
||||
JobValue(RefPtr<Job> job)
|
||||
|
@ -309,13 +309,13 @@ private:
|
|||
|
||||
class ListValue final : public Value {
|
||||
public:
|
||||
virtual Vector<DeprecatedString> resolve_as_list(RefPtr<Shell>) override;
|
||||
virtual NonnullRefPtr<Value> resolve_without_cast(RefPtr<Shell>) override;
|
||||
virtual NonnullRefPtr<Value> clone() const override { return make_ref_counted<ListValue>(m_contained_values)->set_slices(m_slices); }
|
||||
virtual ErrorOr<Vector<String>> resolve_as_list(RefPtr<Shell>) override;
|
||||
virtual ErrorOr<NonnullRefPtr<Value>> resolve_without_cast(RefPtr<Shell>) override;
|
||||
virtual ErrorOr<NonnullRefPtr<Value>> clone() const override { return TRY(try_make_ref_counted<ListValue>(m_contained_values))->set_slices(m_slices); }
|
||||
virtual ~ListValue();
|
||||
virtual bool is_list() const override { return true; }
|
||||
virtual bool is_list_without_resolution() const override { return true; }
|
||||
ListValue(Vector<DeprecatedString> values);
|
||||
ListValue(Vector<String> values);
|
||||
ListValue(NonnullRefPtrVector<Value> values)
|
||||
: m_contained_values(move(values))
|
||||
{
|
||||
|
@ -330,14 +330,14 @@ private:
|
|||
|
||||
class StringValue final : public Value {
|
||||
public:
|
||||
virtual Vector<DeprecatedString> resolve_as_list(RefPtr<Shell>) override;
|
||||
virtual DeprecatedString resolve_as_string(RefPtr<Shell> shell) override;
|
||||
virtual NonnullRefPtr<Value> clone() const override { return make_ref_counted<StringValue>(m_string, m_split, m_keep_empty)->set_slices(m_slices); }
|
||||
virtual ErrorOr<Vector<String>> resolve_as_list(RefPtr<Shell>) override;
|
||||
virtual ErrorOr<String> resolve_as_string(RefPtr<Shell> shell) override;
|
||||
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); }
|
||||
virtual ~StringValue();
|
||||
virtual bool is_string() const override { return m_split.is_null(); }
|
||||
virtual bool is_list() const override { return !m_split.is_null(); }
|
||||
NonnullRefPtr<Value> resolve_without_cast(RefPtr<Shell>) override;
|
||||
StringValue(DeprecatedString string, DeprecatedString split_by = {}, bool keep_empty = false)
|
||||
virtual bool is_string() const override { return m_split.is_empty(); }
|
||||
virtual bool is_list() const override { return !m_split.is_empty(); }
|
||||
ErrorOr<NonnullRefPtr<Value>> resolve_without_cast(RefPtr<Shell>) override;
|
||||
StringValue(String string, String split_by = {}, bool keep_empty = false)
|
||||
: m_string(move(string))
|
||||
, m_split(move(split_by))
|
||||
, m_keep_empty(keep_empty)
|
||||
|
@ -345,50 +345,50 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
DeprecatedString m_string;
|
||||
DeprecatedString m_split;
|
||||
String m_string;
|
||||
String m_split;
|
||||
bool m_keep_empty { false };
|
||||
};
|
||||
|
||||
class GlobValue final : public Value {
|
||||
public:
|
||||
virtual Vector<DeprecatedString> resolve_as_list(RefPtr<Shell>) override;
|
||||
virtual NonnullRefPtr<Value> clone() const override { return make_ref_counted<GlobValue>(m_glob, m_generation_position)->set_slices(m_slices); }
|
||||
virtual ErrorOr<Vector<String>> resolve_as_list(RefPtr<Shell>) override;
|
||||
virtual ErrorOr<NonnullRefPtr<Value>> clone() const override { return TRY(try_make_ref_counted<GlobValue>(m_glob, m_generation_position))->set_slices(m_slices); }
|
||||
virtual ~GlobValue();
|
||||
virtual bool is_glob() const override { return true; }
|
||||
GlobValue(DeprecatedString glob, Position position)
|
||||
GlobValue(String glob, Position position)
|
||||
: m_glob(move(glob))
|
||||
, m_generation_position(move(position))
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
DeprecatedString m_glob;
|
||||
String m_glob;
|
||||
Position m_generation_position;
|
||||
};
|
||||
|
||||
class SimpleVariableValue final : public Value {
|
||||
public:
|
||||
virtual Vector<DeprecatedString> resolve_as_list(RefPtr<Shell>) override;
|
||||
virtual DeprecatedString resolve_as_string(RefPtr<Shell>) override;
|
||||
virtual NonnullRefPtr<Value> resolve_without_cast(RefPtr<Shell>) override;
|
||||
virtual NonnullRefPtr<Value> clone() const override { return make_ref_counted<SimpleVariableValue>(m_name)->set_slices(m_slices); }
|
||||
virtual ErrorOr<Vector<String>> resolve_as_list(RefPtr<Shell>) override;
|
||||
virtual ErrorOr<String> resolve_as_string(RefPtr<Shell>) override;
|
||||
virtual ErrorOr<NonnullRefPtr<Value>> resolve_without_cast(RefPtr<Shell>) override;
|
||||
virtual ErrorOr<NonnullRefPtr<Value>> clone() const override { return TRY(try_make_ref_counted<SimpleVariableValue>(m_name))->set_slices(m_slices); }
|
||||
virtual ~SimpleVariableValue();
|
||||
SimpleVariableValue(DeprecatedString name)
|
||||
SimpleVariableValue(String name)
|
||||
: m_name(move(name))
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
DeprecatedString m_name;
|
||||
String m_name;
|
||||
};
|
||||
|
||||
class SpecialVariableValue final : public Value {
|
||||
public:
|
||||
virtual Vector<DeprecatedString> resolve_as_list(RefPtr<Shell>) override;
|
||||
virtual DeprecatedString resolve_as_string(RefPtr<Shell>) override;
|
||||
virtual NonnullRefPtr<Value> resolve_without_cast(RefPtr<Shell>) override;
|
||||
virtual NonnullRefPtr<Value> clone() const override { return make_ref_counted<SpecialVariableValue>(m_name)->set_slices(m_slices); }
|
||||
virtual ErrorOr<Vector<String>> resolve_as_list(RefPtr<Shell>) override;
|
||||
virtual ErrorOr<String> resolve_as_string(RefPtr<Shell>) override;
|
||||
virtual ErrorOr<NonnullRefPtr<Value>> resolve_without_cast(RefPtr<Shell>) override;
|
||||
virtual ErrorOr<NonnullRefPtr<Value>> clone() const override { return TRY(try_make_ref_counted<SpecialVariableValue>(m_name))->set_slices(m_slices); }
|
||||
virtual ~SpecialVariableValue();
|
||||
SpecialVariableValue(char name)
|
||||
: m_name(name)
|
||||
|
@ -401,18 +401,18 @@ private:
|
|||
|
||||
class TildeValue final : public Value {
|
||||
public:
|
||||
virtual Vector<DeprecatedString> resolve_as_list(RefPtr<Shell>) override;
|
||||
virtual DeprecatedString resolve_as_string(RefPtr<Shell>) override;
|
||||
virtual NonnullRefPtr<Value> clone() const override { return make_ref_counted<TildeValue>(m_username)->set_slices(m_slices); }
|
||||
virtual ErrorOr<Vector<String>> resolve_as_list(RefPtr<Shell>) override;
|
||||
virtual ErrorOr<String> resolve_as_string(RefPtr<Shell>) override;
|
||||
virtual ErrorOr<NonnullRefPtr<Value>> clone() const override { return TRY(try_make_ref_counted<TildeValue>(m_username))->set_slices(m_slices); }
|
||||
virtual ~TildeValue();
|
||||
virtual bool is_string() const override { return true; }
|
||||
TildeValue(DeprecatedString name)
|
||||
TildeValue(String name)
|
||||
: m_username(move(name))
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
DeprecatedString m_username;
|
||||
String m_username;
|
||||
};
|
||||
|
||||
class Node : public RefCounted<Node> {
|
||||
|
@ -432,7 +432,7 @@ public:
|
|||
return { this, nullptr, nullptr };
|
||||
return { nullptr, nullptr, nullptr };
|
||||
}
|
||||
virtual DeprecatedString class_name() const { return "Node"; }
|
||||
virtual StringView class_name() const { return "Node"sv; }
|
||||
Node(Position);
|
||||
virtual ~Node() = default;
|
||||
|
||||
|
@ -519,14 +519,14 @@ protected:
|
|||
RefPtr<SyntaxError> m_syntax_error_node;
|
||||
};
|
||||
|
||||
#define NODE(name) \
|
||||
virtual DeprecatedString class_name() const override \
|
||||
{ \
|
||||
return #name; \
|
||||
} \
|
||||
virtual Kind kind() const override \
|
||||
{ \
|
||||
return Kind::name; \
|
||||
#define NODE(name) \
|
||||
virtual StringView class_name() const override \
|
||||
{ \
|
||||
return #name##sv; \
|
||||
} \
|
||||
virtual Kind kind() const override \
|
||||
{ \
|
||||
return Kind::name; \
|
||||
}
|
||||
|
||||
class PathRedirectionNode : public Node {
|
||||
|
@ -610,11 +610,11 @@ private:
|
|||
|
||||
class BarewordLiteral final : public Node {
|
||||
public:
|
||||
BarewordLiteral(Position, DeprecatedString);
|
||||
BarewordLiteral(Position, String);
|
||||
virtual ~BarewordLiteral() = default;
|
||||
virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
|
||||
|
||||
DeprecatedString const& text() const { return m_text; }
|
||||
String const& text() const { return m_text; }
|
||||
|
||||
private:
|
||||
NODE(BarewordLiteral);
|
||||
|
@ -624,7 +624,7 @@ private:
|
|||
virtual bool is_bareword() const override { return true; }
|
||||
virtual RefPtr<Node const> leftmost_trivial_literal() const override { return this; }
|
||||
|
||||
DeprecatedString m_text;
|
||||
String m_text;
|
||||
};
|
||||
|
||||
class BraceExpansion final : public Node {
|
||||
|
@ -727,11 +727,11 @@ private:
|
|||
|
||||
class Comment : public Node {
|
||||
public:
|
||||
Comment(Position, DeprecatedString);
|
||||
Comment(Position, String);
|
||||
virtual ~Comment();
|
||||
virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
|
||||
|
||||
DeprecatedString const& text() const { return m_text; }
|
||||
String const& text() const { return m_text; }
|
||||
|
||||
private:
|
||||
NODE(Comment);
|
||||
|
@ -739,7 +739,7 @@ private:
|
|||
virtual RefPtr<Value> run(RefPtr<Shell>) override;
|
||||
virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
|
||||
|
||||
DeprecatedString m_text;
|
||||
String m_text;
|
||||
};
|
||||
|
||||
class ContinuationControl final : public Node {
|
||||
|
@ -890,11 +890,11 @@ private:
|
|||
|
||||
class Glob final : public Node {
|
||||
public:
|
||||
Glob(Position, DeprecatedString);
|
||||
Glob(Position, String);
|
||||
virtual ~Glob();
|
||||
virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
|
||||
|
||||
DeprecatedString const& text() const { return m_text; }
|
||||
String const& text() const { return m_text; }
|
||||
|
||||
private:
|
||||
NODE(Glob);
|
||||
|
@ -904,7 +904,7 @@ private:
|
|||
virtual bool is_glob() const override { return true; }
|
||||
virtual bool is_list() const override { return true; }
|
||||
|
||||
DeprecatedString m_text;
|
||||
String m_text;
|
||||
};
|
||||
|
||||
struct HistorySelector {
|
||||
|
@ -923,7 +923,7 @@ struct HistorySelector {
|
|||
EventKind kind { IndexFromStart };
|
||||
size_t index { 0 };
|
||||
Position text_position;
|
||||
DeprecatedString text;
|
||||
String text;
|
||||
} event;
|
||||
|
||||
struct WordSelector {
|
||||
|
@ -1025,7 +1025,7 @@ public:
|
|||
|
||||
NonnullRefPtrVector<Node> const& arguments() const { return m_arguments; }
|
||||
auto const& function() const { return m_function; }
|
||||
DeprecatedString const& function_name() const { return m_function.name; }
|
||||
String const& function_name() const { return m_function.name; }
|
||||
Position const& function_position() const { return m_function.position; }
|
||||
bool has_closing_brace() const { return m_closing_brace_position.has_value(); }
|
||||
|
||||
|
@ -1067,7 +1067,7 @@ private:
|
|||
|
||||
struct MatchEntry {
|
||||
Variant<NonnullRefPtrVector<Node>, Vector<Regex<ECMA262>>> options;
|
||||
Optional<Vector<DeprecatedString>> match_names;
|
||||
Optional<Vector<String>> match_names;
|
||||
Optional<Position> match_as_position;
|
||||
Vector<Position> pipe_positions;
|
||||
RefPtr<Node> body;
|
||||
|
@ -1075,12 +1075,12 @@ struct MatchEntry {
|
|||
|
||||
class MatchExpr final : public Node {
|
||||
public:
|
||||
MatchExpr(Position, NonnullRefPtr<Node> expr, DeprecatedString name, Optional<Position> as_position, Vector<MatchEntry> entries);
|
||||
MatchExpr(Position, NonnullRefPtr<Node> expr, String name, Optional<Position> as_position, Vector<MatchEntry> entries);
|
||||
virtual ~MatchExpr();
|
||||
virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
|
||||
|
||||
NonnullRefPtr<Node> const& matched_expr() const { return m_matched_expr; }
|
||||
DeprecatedString const& expr_name() const { return m_expr_name; }
|
||||
String const& expr_name() const { return m_expr_name; }
|
||||
Vector<MatchEntry> const& entries() const { return m_entries; }
|
||||
Optional<Position> const& as_position() const { return m_as_position; }
|
||||
|
||||
|
@ -1094,7 +1094,7 @@ private:
|
|||
virtual bool should_override_execution_in_current_process() const override { return true; }
|
||||
|
||||
NonnullRefPtr<Node> m_matched_expr;
|
||||
DeprecatedString m_expr_name;
|
||||
String m_expr_name;
|
||||
Optional<Position> m_as_position;
|
||||
Vector<MatchEntry> m_entries;
|
||||
};
|
||||
|
@ -1273,11 +1273,11 @@ protected:
|
|||
|
||||
class SimpleVariable final : public VariableNode {
|
||||
public:
|
||||
SimpleVariable(Position, DeprecatedString);
|
||||
SimpleVariable(Position, String);
|
||||
virtual ~SimpleVariable();
|
||||
|
||||
virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
|
||||
DeprecatedString const& name() const { return m_name; }
|
||||
String const& name() const { return m_name; }
|
||||
|
||||
private:
|
||||
NODE(SimpleVariable);
|
||||
|
@ -1288,7 +1288,7 @@ private:
|
|||
virtual HitTestResult hit_test_position(size_t) const override;
|
||||
virtual bool is_simple_variable() const override { return true; }
|
||||
|
||||
DeprecatedString m_name;
|
||||
String m_name;
|
||||
};
|
||||
|
||||
class SpecialVariable final : public VariableNode {
|
||||
|
@ -1338,11 +1338,11 @@ private:
|
|||
|
||||
class Heredoc final : public Node {
|
||||
public:
|
||||
Heredoc(Position, DeprecatedString end, bool allow_interpolation, bool deindent, Optional<int> target_fd = {});
|
||||
Heredoc(Position, String end, bool allow_interpolation, bool deindent, Optional<int> target_fd = {});
|
||||
virtual ~Heredoc();
|
||||
virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
|
||||
|
||||
DeprecatedString const& end() const { return m_end; }
|
||||
String const& end() const { return m_end; }
|
||||
bool allow_interpolation() const { return m_allows_interpolation; }
|
||||
bool deindent() const { return m_deindent; }
|
||||
Optional<int> target_fd() const { return m_target_fd; }
|
||||
|
@ -1365,7 +1365,7 @@ private:
|
|||
virtual HitTestResult hit_test_position(size_t) const override;
|
||||
virtual RefPtr<Node const> leftmost_trivial_literal() const override { return this; };
|
||||
|
||||
DeprecatedString m_end;
|
||||
String m_end;
|
||||
bool m_allows_interpolation { false };
|
||||
bool m_deindent { false };
|
||||
Optional<int> m_target_fd;
|
||||
|
@ -1380,11 +1380,11 @@ public:
|
|||
DoubleQuotes,
|
||||
};
|
||||
|
||||
StringLiteral(Position, DeprecatedString, EnclosureType);
|
||||
StringLiteral(Position, String, EnclosureType);
|
||||
virtual ~StringLiteral();
|
||||
virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
|
||||
|
||||
DeprecatedString const& text() const { return m_text; }
|
||||
String const& text() const { return m_text; }
|
||||
EnclosureType enclosure_type() const { return m_enclosure_type; }
|
||||
|
||||
private:
|
||||
|
@ -1394,7 +1394,7 @@ private:
|
|||
virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
|
||||
virtual RefPtr<Node const> leftmost_trivial_literal() const override { return this; };
|
||||
|
||||
DeprecatedString m_text;
|
||||
String m_text;
|
||||
EnclosureType m_enclosure_type;
|
||||
};
|
||||
|
||||
|
@ -1420,11 +1420,11 @@ private:
|
|||
|
||||
class SyntaxError final : public Node {
|
||||
public:
|
||||
SyntaxError(Position, DeprecatedString, bool is_continuable = false);
|
||||
SyntaxError(Position, String, bool is_continuable = false);
|
||||
virtual ~SyntaxError();
|
||||
virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
|
||||
|
||||
DeprecatedString const& error_text() const { return m_syntax_error_text; }
|
||||
String const& error_text() const { return m_syntax_error_text; }
|
||||
bool is_continuable() const { return m_is_continuable; }
|
||||
|
||||
virtual void clear_syntax_error() override
|
||||
|
@ -1449,7 +1449,7 @@ private:
|
|||
virtual HitTestResult hit_test_position(size_t) const override { return { nullptr, nullptr, nullptr }; }
|
||||
virtual SyntaxError& syntax_error_node() override;
|
||||
|
||||
DeprecatedString m_syntax_error_text;
|
||||
String m_syntax_error_text;
|
||||
bool m_is_continuable { false };
|
||||
bool m_is_cleared { false };
|
||||
};
|
||||
|
@ -1473,11 +1473,11 @@ private:
|
|||
|
||||
class Tilde final : public Node {
|
||||
public:
|
||||
Tilde(Position, DeprecatedString);
|
||||
Tilde(Position, String);
|
||||
virtual ~Tilde();
|
||||
virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
|
||||
|
||||
DeprecatedString text() const;
|
||||
String text() const;
|
||||
|
||||
private:
|
||||
NODE(Tilde);
|
||||
|
@ -1488,7 +1488,7 @@ private:
|
|||
virtual HitTestResult hit_test_position(size_t) const override;
|
||||
virtual bool is_tilde() const override { return true; }
|
||||
|
||||
DeprecatedString m_username;
|
||||
String m_username;
|
||||
};
|
||||
|
||||
class VariableDeclarations final : public Node {
|
||||
|
|
|
@ -554,7 +554,7 @@ int Shell::builtin_export(int argc, char const** argv)
|
|||
if (parts.size() == 1) {
|
||||
auto value = lookup_local_variable(parts[0]);
|
||||
if (value) {
|
||||
auto values = const_cast<AST::Value&>(*value).resolve_as_list(*this);
|
||||
auto values = const_cast<AST::Value&>(*value).resolve_as_list(*this).release_value_but_fixme_should_propagate_errors();
|
||||
StringBuilder builder;
|
||||
builder.join(' ', values);
|
||||
parts.append(builder.to_deprecated_string());
|
||||
|
@ -963,7 +963,7 @@ int Shell::builtin_shift(int argc, char const** argv)
|
|||
int Shell::builtin_source(int argc, char const** argv)
|
||||
{
|
||||
char const* file_to_source = nullptr;
|
||||
Vector<DeprecatedString> args;
|
||||
Vector<StringView> args;
|
||||
|
||||
Core::ArgsParser parser;
|
||||
parser.add_positional_argument(file_to_source, "File to read commands from", "path");
|
||||
|
@ -978,8 +978,14 @@ int Shell::builtin_source(int argc, char const** argv)
|
|||
set_local_variable("ARGV", const_cast<AST::Value&>(*previous_argv));
|
||||
} };
|
||||
|
||||
if (!args.is_empty())
|
||||
set_local_variable("ARGV", AST::make_ref_counted<AST::ListValue>(move(args)));
|
||||
if (!args.is_empty()) {
|
||||
Vector<String> arguments;
|
||||
arguments.ensure_capacity(args.size());
|
||||
for (auto& arg : args)
|
||||
arguments.append(String::from_utf8(arg).release_value_but_fixme_should_propagate_errors());
|
||||
|
||||
set_local_variable("ARGV", AST::make_ref_counted<AST::ListValue>(move(arguments)));
|
||||
}
|
||||
|
||||
if (!run_file(file_to_source, true))
|
||||
return 126;
|
||||
|
@ -989,14 +995,14 @@ int Shell::builtin_source(int argc, char const** argv)
|
|||
|
||||
int Shell::builtin_time(int argc, char const** argv)
|
||||
{
|
||||
AST::Command command;
|
||||
Vector<StringView> args;
|
||||
|
||||
int number_of_iterations = 1;
|
||||
|
||||
Core::ArgsParser parser;
|
||||
parser.add_option(number_of_iterations, "Number of iterations", "iterations", 'n', "iterations");
|
||||
parser.set_stop_on_first_non_option(true);
|
||||
parser.add_positional_argument(command.argv, "Command to execute with arguments", "command", Core::ArgsParser::Required::Yes);
|
||||
parser.add_positional_argument(args, "Command to execute with arguments", "command", Core::ArgsParser::Required::Yes);
|
||||
|
||||
if (!parser.parse(argc, const_cast<char**>(argv), Core::ArgsParser::FailureBehavior::PrintUsage))
|
||||
return 1;
|
||||
|
@ -1004,6 +1010,11 @@ int Shell::builtin_time(int argc, char const** argv)
|
|||
if (number_of_iterations < 1)
|
||||
return 1;
|
||||
|
||||
AST::Command command;
|
||||
command.argv.ensure_capacity(args.size());
|
||||
for (auto& arg : args)
|
||||
command.argv.append(String::from_utf8(arg).release_value_but_fixme_should_propagate_errors());
|
||||
|
||||
auto commands = expand_aliases({ move(command) });
|
||||
|
||||
AK::Statistics iteration_times;
|
||||
|
@ -1163,7 +1174,7 @@ int Shell::builtin_not(int argc, char const** argv)
|
|||
|
||||
AST::Command command;
|
||||
for (size_t i = 1; i < (size_t)argc; ++i)
|
||||
command.argv.append(argv[i]);
|
||||
command.argv.append(String::from_utf8(StringView { argv[i], strlen(argv[i]) }).release_value_but_fixme_should_propagate_errors());
|
||||
|
||||
auto commands = expand_aliases({ move(command) });
|
||||
int exit_code = 1;
|
||||
|
@ -1182,24 +1193,24 @@ int Shell::builtin_not(int argc, char const** argv)
|
|||
int Shell::builtin_kill(int argc, char const** argv)
|
||||
{
|
||||
// Simply translate the arguments and pass them to `kill'
|
||||
Vector<DeprecatedString> replaced_values;
|
||||
Vector<String> replaced_values;
|
||||
auto kill_path = Core::DeprecatedFile::resolve_executable_from_environment("kill"sv);
|
||||
if (!kill_path.has_value()) {
|
||||
warnln("kill: `kill' not found in PATH");
|
||||
return 126;
|
||||
}
|
||||
replaced_values.append(kill_path.release_value());
|
||||
replaced_values.append(String::from_deprecated_string(kill_path.release_value()).release_value_but_fixme_should_propagate_errors());
|
||||
for (auto i = 1; i < argc; ++i) {
|
||||
if (auto job_id = resolve_job_spec({ argv[i], strlen(argv[1]) }); job_id.has_value()) {
|
||||
auto job = find_job(job_id.value());
|
||||
if (job) {
|
||||
replaced_values.append(DeprecatedString::number(job->pid()));
|
||||
replaced_values.append(String::number(job->pid()).release_value_but_fixme_should_propagate_errors());
|
||||
} else {
|
||||
warnln("kill: Job with pid {} not found", job_id.value());
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
replaced_values.append(argv[i]);
|
||||
replaced_values.append(String::from_deprecated_string(argv[i]).release_value_but_fixme_should_propagate_errors());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1230,9 +1241,13 @@ bool Shell::run_builtin(const AST::Command& command, NonnullRefPtrVector<AST::Re
|
|||
if (!has_builtin(command.argv.first()))
|
||||
return false;
|
||||
|
||||
// FIXME: Make all the functions above take the more idiomatic (Main::Arguments) parameters, and remove this gross conversion.
|
||||
Vector<char const*> argv;
|
||||
for (auto& arg : command.argv)
|
||||
argv.append(arg.characters());
|
||||
Vector<DeprecatedString> args;
|
||||
for (auto& arg : command.argv) {
|
||||
args.append(arg.to_deprecated_string());
|
||||
argv.append(args.last().characters());
|
||||
}
|
||||
|
||||
argv.append(nullptr);
|
||||
|
||||
|
@ -1302,19 +1317,19 @@ int Shell::builtin_argsparser_parse(int argc, char const** argv)
|
|||
auto try_convert = [](StringView value, Type type) -> Optional<RefPtr<AST::Value>> {
|
||||
switch (type) {
|
||||
case Type::Bool:
|
||||
return AST::make_ref_counted<AST::StringValue>("true");
|
||||
return AST::make_ref_counted<AST::StringValue>(String::from_utf8("true"sv).release_value_but_fixme_should_propagate_errors());
|
||||
case Type::String:
|
||||
return AST::make_ref_counted<AST::StringValue>(value);
|
||||
return AST::make_ref_counted<AST::StringValue>(String::from_utf8(value).release_value_but_fixme_should_propagate_errors());
|
||||
case Type::I32:
|
||||
if (auto number = value.to_int(); number.has_value())
|
||||
return AST::make_ref_counted<AST::StringValue>(DeprecatedString::number(*number));
|
||||
return AST::make_ref_counted<AST::StringValue>(String::number(*number).release_value_but_fixme_should_propagate_errors());
|
||||
|
||||
warnln("Invalid value for type i32: {}", value);
|
||||
return {};
|
||||
case Type::U32:
|
||||
case Type::Size:
|
||||
if (auto number = value.to_uint(); number.has_value())
|
||||
return AST::make_ref_counted<AST::StringValue>(DeprecatedString::number(*number));
|
||||
return AST::make_ref_counted<AST::StringValue>(String::number(*number).release_value_but_fixme_should_propagate_errors());
|
||||
|
||||
warnln("Invalid value for type u32|size: {}", value);
|
||||
return {};
|
||||
|
@ -1327,7 +1342,7 @@ int Shell::builtin_argsparser_parse(int argc, char const** argv)
|
|||
return {};
|
||||
}
|
||||
|
||||
return AST::make_ref_counted<AST::StringValue>(DeprecatedString::number(number));
|
||||
return AST::make_ref_counted<AST::StringValue>(String::number(number).release_value_but_fixme_should_propagate_errors());
|
||||
}
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
|
@ -1337,8 +1352,8 @@ int Shell::builtin_argsparser_parse(int argc, char const** argv)
|
|||
auto enlist = [&](auto name, auto value) -> NonnullRefPtr<AST::Value> {
|
||||
auto variable = lookup_local_variable(name);
|
||||
if (variable) {
|
||||
auto list = const_cast<AST::Value&>(*variable).resolve_as_list(*this);
|
||||
auto new_value = value->resolve_as_string(*this);
|
||||
auto list = const_cast<AST::Value&>(*variable).resolve_as_list(*this).release_value_but_fixme_should_propagate_errors();
|
||||
auto new_value = value->resolve_as_string(*this).release_value_but_fixme_should_propagate_errors();
|
||||
list.append(move(new_value));
|
||||
return make_ref_counted<AST::ListValue>(move(list));
|
||||
}
|
||||
|
@ -1482,7 +1497,7 @@ int Shell::builtin_argsparser_parse(int argc, char const** argv)
|
|||
}
|
||||
|
||||
if (type == Type::Bool)
|
||||
set_local_variable(current_variable, make_ref_counted<AST::StringValue>("false"), true);
|
||||
set_local_variable(current_variable, make_ref_counted<AST::StringValue>(String::from_utf8("false"sv).release_value_but_fixme_should_propagate_errors()), true);
|
||||
return true;
|
||||
},
|
||||
});
|
||||
|
|
|
@ -598,7 +598,7 @@ void Formatter::visit(const AST::MatchExpr* node)
|
|||
if (!first)
|
||||
current_builder().append(" | "sv);
|
||||
first = false;
|
||||
auto node = make_ref_counted<AST::BarewordLiteral>(AST::Position {}, option.pattern_value);
|
||||
auto node = make_ref_counted<AST::BarewordLiteral>(AST::Position {}, String::from_utf8(option.pattern_value).release_value_but_fixme_should_propagate_errors());
|
||||
node->visit(*this);
|
||||
}
|
||||
});
|
||||
|
@ -791,7 +791,7 @@ void Formatter::visit(const AST::StringLiteral* node)
|
|||
current_builder().append("'"sv);
|
||||
|
||||
if (m_options.in_double_quotes && !m_options.in_heredoc) {
|
||||
for (auto ch : node->text()) {
|
||||
for (auto ch : node->text().bytes_as_string_view()) {
|
||||
switch (ch) {
|
||||
case '"':
|
||||
case '\\':
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "AST.h"
|
||||
#include "NodeVisitor.h"
|
||||
#include <AK/DeprecatedString.h>
|
||||
#include <AK/Forward.h>
|
||||
|
|
|
@ -59,7 +59,7 @@ RefPtr<AST::Node> Shell::immediate_length_impl(AST::ImmediateExpression& invokin
|
|||
if (expr_node->is_list())
|
||||
mode = List;
|
||||
else if (expr_node->is_simple_variable()) // "Look inside" variables
|
||||
mode = const_cast<AST::Node*>(expr_node)->run(this)->resolve_without_cast(this)->is_list_without_resolution() ? List : String;
|
||||
mode = const_cast<AST::Node*>(expr_node)->run(this)->resolve_without_cast(this).release_value_but_fixme_should_propagate_errors()->is_list_without_resolution() ? List : String;
|
||||
else if (is<AST::ImmediateExpression>(expr_node))
|
||||
mode = List;
|
||||
else
|
||||
|
@ -67,7 +67,7 @@ RefPtr<AST::Node> Shell::immediate_length_impl(AST::ImmediateExpression& invokin
|
|||
}
|
||||
|
||||
auto value_with_number = [&](auto number) -> NonnullRefPtr<AST::Node> {
|
||||
return AST::make_ref_counted<AST::BarewordLiteral>(invoking_node.position(), DeprecatedString::number(number));
|
||||
return AST::make_ref_counted<AST::BarewordLiteral>(invoking_node.position(), String::number(number).release_value_but_fixme_should_propagate_errors());
|
||||
};
|
||||
|
||||
auto do_across = [&](StringView mode_name, auto& values) {
|
||||
|
@ -80,9 +80,9 @@ RefPtr<AST::Node> Shell::immediate_length_impl(AST::ImmediateExpression& invokin
|
|||
// ImmediateExpression(length <mode_name> <entry>)
|
||||
resulting_nodes.unchecked_append(AST::make_ref_counted<AST::ImmediateExpression>(
|
||||
expr_node->position(),
|
||||
AST::NameWithPosition { "length", invoking_node.function_position() },
|
||||
AST::NameWithPosition { String::from_utf8("length"sv).release_value_but_fixme_should_propagate_errors(), invoking_node.function_position() },
|
||||
NonnullRefPtrVector<AST::Node> { Vector<NonnullRefPtr<AST::Node>> {
|
||||
static_cast<NonnullRefPtr<AST::Node>>(AST::make_ref_counted<AST::BarewordLiteral>(expr_node->position(), mode_name)),
|
||||
static_cast<NonnullRefPtr<AST::Node>>(AST::make_ref_counted<AST::BarewordLiteral>(expr_node->position(), String::from_utf8(mode_name).release_value_but_fixme_should_propagate_errors())),
|
||||
AST::make_ref_counted<AST::SyntheticNode>(expr_node->position(), NonnullRefPtr<AST::Value>(entry)),
|
||||
} },
|
||||
expr_node->position()));
|
||||
|
@ -100,7 +100,7 @@ RefPtr<AST::Node> Shell::immediate_length_impl(AST::ImmediateExpression& invokin
|
|||
if (!value)
|
||||
return value_with_number(0);
|
||||
|
||||
value = value->resolve_without_cast(this);
|
||||
value = value->resolve_without_cast(this).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
if (auto list = dynamic_cast<AST::ListValue*>(value.ptr())) {
|
||||
if (across)
|
||||
|
@ -109,7 +109,7 @@ RefPtr<AST::Node> Shell::immediate_length_impl(AST::ImmediateExpression& invokin
|
|||
return value_with_number(list->values().size());
|
||||
}
|
||||
|
||||
auto list = value->resolve_as_list(this);
|
||||
auto list = value->resolve_as_list(this).release_value_but_fixme_should_propagate_errors();
|
||||
if (!across)
|
||||
return value_with_number(list.size());
|
||||
|
||||
|
@ -145,7 +145,7 @@ RefPtr<AST::Node> Shell::immediate_length_impl(AST::ImmediateExpression& invokin
|
|||
if (!value)
|
||||
return value_with_number(0);
|
||||
|
||||
value = value->resolve_without_cast(*this);
|
||||
value = value->resolve_without_cast(*this).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
if (auto list = dynamic_cast<AST::ListValue*>(value.ptr())) {
|
||||
if (!across)
|
||||
|
@ -165,7 +165,7 @@ RefPtr<AST::Node> Shell::immediate_length_impl(AST::ImmediateExpression& invokin
|
|||
}
|
||||
|
||||
// Evaluate the nodes and substitute with the lengths.
|
||||
auto list = value->resolve_as_list(this);
|
||||
auto list = value->resolve_as_list(this).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
if (!expr_node->is_list()) {
|
||||
if (list.size() == 1) {
|
||||
|
@ -173,7 +173,7 @@ RefPtr<AST::Node> Shell::immediate_length_impl(AST::ImmediateExpression& invokin
|
|||
goto raise_no_list_allowed;
|
||||
|
||||
// This is the normal case, the expression is a normal non-list expression.
|
||||
return value_with_number(list.first().length());
|
||||
return value_with_number(list.first().bytes_as_string_view().length());
|
||||
}
|
||||
|
||||
// This can be hit by asking for the length of a command list (e.g. `(>/dev/null)`)
|
||||
|
@ -208,7 +208,7 @@ RefPtr<AST::Node> Shell::immediate_regex_replace(AST::ImmediateExpression& invok
|
|||
|
||||
auto pattern = const_cast<AST::Node&>(arguments[0]).run(this);
|
||||
auto replacement = const_cast<AST::Node&>(arguments[1]).run(this);
|
||||
auto value = const_cast<AST::Node&>(arguments[2]).run(this)->resolve_without_cast(this);
|
||||
auto value = const_cast<AST::Node&>(arguments[2]).run(this)->resolve_without_cast(this).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
if (!pattern->is_string()) {
|
||||
raise_error(ShellError::EvaluatedSyntaxError, "Expected the regex_replace pattern to be a string", arguments[0].position());
|
||||
|
@ -225,10 +225,13 @@ RefPtr<AST::Node> Shell::immediate_regex_replace(AST::ImmediateExpression& invok
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
Regex<PosixExtendedParser> re { pattern->resolve_as_list(this).first() };
|
||||
auto result = re.replace(value->resolve_as_list(this)[0], replacement->resolve_as_list(this)[0], PosixFlags::Global | PosixFlags::Multiline | PosixFlags::Unicode);
|
||||
Regex<PosixExtendedParser> re { pattern->resolve_as_list(this).release_value_but_fixme_should_propagate_errors().first().to_deprecated_string() };
|
||||
auto result = re.replace(
|
||||
value->resolve_as_list(this).release_value_but_fixme_should_propagate_errors()[0],
|
||||
replacement->resolve_as_list(this).release_value_but_fixme_should_propagate_errors()[0],
|
||||
PosixFlags::Global | PosixFlags::Multiline | PosixFlags::Unicode);
|
||||
|
||||
return AST::make_ref_counted<AST::StringLiteral>(invoking_node.position(), move(result), AST::StringLiteral::EnclosureType::None);
|
||||
return AST::make_ref_counted<AST::StringLiteral>(invoking_node.position(), String::from_utf8(result).release_value_but_fixme_should_propagate_errors(), AST::StringLiteral::EnclosureType::None);
|
||||
}
|
||||
|
||||
RefPtr<AST::Node> Shell::immediate_remove_suffix(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
||||
|
@ -239,24 +242,25 @@ RefPtr<AST::Node> Shell::immediate_remove_suffix(AST::ImmediateExpression& invok
|
|||
}
|
||||
|
||||
auto suffix = const_cast<AST::Node&>(arguments[0]).run(this);
|
||||
auto value = const_cast<AST::Node&>(arguments[1]).run(this)->resolve_without_cast(this);
|
||||
auto value = const_cast<AST::Node&>(arguments[1]).run(this)->resolve_without_cast(this).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
if (!suffix->is_string()) {
|
||||
raise_error(ShellError::EvaluatedSyntaxError, "Expected the remove_suffix suffix string to be a string", arguments[0].position());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto suffix_str = suffix->resolve_as_list(this)[0];
|
||||
auto values = value->resolve_as_list(this);
|
||||
auto suffix_str = suffix->resolve_as_list(this).release_value_but_fixme_should_propagate_errors()[0];
|
||||
auto values = value->resolve_as_list(this).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
Vector<NonnullRefPtr<AST::Node>> nodes;
|
||||
|
||||
for (auto& value_str : values) {
|
||||
StringView removed { value_str };
|
||||
String removed = String::from_utf8(value_str).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
if (value_str.ends_with(suffix_str))
|
||||
removed = removed.substring_view(0, value_str.length() - suffix_str.length());
|
||||
nodes.append(AST::make_ref_counted<AST::StringLiteral>(invoking_node.position(), removed, AST::StringLiteral::EnclosureType::None));
|
||||
if (value_str.bytes_as_string_view().ends_with(suffix_str))
|
||||
removed = removed.substring_from_byte_offset(0, value_str.bytes_as_string_view().length() - suffix_str.bytes_as_string_view().length()).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
nodes.append(AST::make_ref_counted<AST::StringLiteral>(invoking_node.position(), move(removed), AST::StringLiteral::EnclosureType::None));
|
||||
}
|
||||
|
||||
return AST::make_ref_counted<AST::ListConcatenate>(invoking_node.position(), move(nodes));
|
||||
|
@ -270,24 +274,24 @@ RefPtr<AST::Node> Shell::immediate_remove_prefix(AST::ImmediateExpression& invok
|
|||
}
|
||||
|
||||
auto prefix = const_cast<AST::Node&>(arguments[0]).run(this);
|
||||
auto value = const_cast<AST::Node&>(arguments[1]).run(this)->resolve_without_cast(this);
|
||||
auto value = const_cast<AST::Node&>(arguments[1]).run(this)->resolve_without_cast(this).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
if (!prefix->is_string()) {
|
||||
raise_error(ShellError::EvaluatedSyntaxError, "Expected the remove_prefix prefix string to be a string", arguments[0].position());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto prefix_str = prefix->resolve_as_list(this)[0];
|
||||
auto values = value->resolve_as_list(this);
|
||||
auto prefix_str = prefix->resolve_as_list(this).release_value_but_fixme_should_propagate_errors()[0];
|
||||
auto values = value->resolve_as_list(this).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
Vector<NonnullRefPtr<AST::Node>> nodes;
|
||||
|
||||
for (auto& value_str : values) {
|
||||
StringView removed { value_str };
|
||||
String removed = String::from_utf8(value_str).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
if (value_str.starts_with(prefix_str))
|
||||
removed = removed.substring_view(prefix_str.length());
|
||||
nodes.append(AST::make_ref_counted<AST::StringLiteral>(invoking_node.position(), removed, AST::StringLiteral::EnclosureType::None));
|
||||
if (value_str.bytes_as_string_view().starts_with(prefix_str))
|
||||
removed = removed.substring_from_byte_offset(prefix_str.bytes_as_string_view().length()).release_value_but_fixme_should_propagate_errors();
|
||||
nodes.append(AST::make_ref_counted<AST::StringLiteral>(invoking_node.position(), move(removed), AST::StringLiteral::EnclosureType::None));
|
||||
}
|
||||
|
||||
return AST::make_ref_counted<AST::ListConcatenate>(invoking_node.position(), move(nodes));
|
||||
|
@ -301,14 +305,14 @@ RefPtr<AST::Node> Shell::immediate_split(AST::ImmediateExpression& invoking_node
|
|||
}
|
||||
|
||||
auto delimiter = const_cast<AST::Node&>(arguments[0]).run(this);
|
||||
auto value = const_cast<AST::Node&>(arguments[1]).run(this)->resolve_without_cast(this);
|
||||
auto value = const_cast<AST::Node&>(arguments[1]).run(this)->resolve_without_cast(this).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
if (!delimiter->is_string()) {
|
||||
raise_error(ShellError::EvaluatedSyntaxError, "Expected the split delimiter string to be a string", arguments[0].position());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto delimiter_str = delimiter->resolve_as_list(this)[0];
|
||||
auto delimiter_str = delimiter->resolve_as_list(this).release_value_but_fixme_should_propagate_errors()[0];
|
||||
|
||||
auto transform = [&](auto const& values) {
|
||||
// Translate to a list of applications of `split <delimiter>`
|
||||
|
@ -334,25 +338,25 @@ RefPtr<AST::Node> Shell::immediate_split(AST::ImmediateExpression& invoking_node
|
|||
}
|
||||
|
||||
// Otherwise, just resolve to a list and transform that.
|
||||
auto list = value->resolve_as_list(this);
|
||||
auto list = value->resolve_as_list(this).release_value_but_fixme_should_propagate_errors();
|
||||
if (!value->is_list()) {
|
||||
if (list.is_empty())
|
||||
return AST::make_ref_counted<AST::ListConcatenate>(invoking_node.position(), NonnullRefPtrVector<AST::Node> {});
|
||||
|
||||
auto& value = list.first();
|
||||
Vector<DeprecatedString> split_strings;
|
||||
Vector<String> split_strings;
|
||||
if (delimiter_str.is_empty()) {
|
||||
StringBuilder builder;
|
||||
for (auto code_point : Utf8View { value }) {
|
||||
builder.append_code_point(code_point);
|
||||
split_strings.append(builder.to_deprecated_string());
|
||||
split_strings.append(builder.to_string().release_value_but_fixme_should_propagate_errors());
|
||||
builder.clear();
|
||||
}
|
||||
} else {
|
||||
auto split = StringView { value }.split_view(delimiter_str, options.inline_exec_keep_empty_segments ? SplitBehavior::KeepEmpty : SplitBehavior::Nothing);
|
||||
split_strings.ensure_capacity(split.size());
|
||||
for (auto& entry : split)
|
||||
split_strings.append(entry);
|
||||
split_strings.append(String::from_utf8(entry).release_value_but_fixme_should_propagate_errors());
|
||||
}
|
||||
return AST::make_ref_counted<AST::SyntheticNode>(invoking_node.position(), AST::make_ref_counted<AST::ListValue>(move(split_strings)));
|
||||
}
|
||||
|
@ -368,12 +372,12 @@ RefPtr<AST::Node> Shell::immediate_concat_lists(AST::ImmediateExpression& invoki
|
|||
if (auto* list = dynamic_cast<const AST::ListConcatenate*>(&argument)) {
|
||||
result.extend(list->list());
|
||||
} else {
|
||||
auto list_of_values = const_cast<AST::Node&>(argument).run(this)->resolve_without_cast(this);
|
||||
auto list_of_values = const_cast<AST::Node&>(argument).run(this)->resolve_without_cast(this).release_value_but_fixme_should_propagate_errors();
|
||||
if (auto* list = dynamic_cast<AST::ListValue*>(list_of_values.ptr())) {
|
||||
for (auto& entry : static_cast<Vector<NonnullRefPtr<AST::Value>>&>(list->values()))
|
||||
result.append(AST::make_ref_counted<AST::SyntheticNode>(argument.position(), entry));
|
||||
} else {
|
||||
auto values = list_of_values->resolve_as_list(this);
|
||||
auto values = list_of_values->resolve_as_list(this).release_value_but_fixme_should_propagate_errors();
|
||||
for (auto& entry : values)
|
||||
result.append(AST::make_ref_counted<AST::StringLiteral>(argument.position(), entry, AST::StringLiteral::EnclosureType::None));
|
||||
}
|
||||
|
@ -391,7 +395,7 @@ RefPtr<AST::Node> Shell::immediate_filter_glob(AST::ImmediateExpression& invokin
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
auto glob_list = const_cast<AST::Node&>(arguments[0]).run(*this)->resolve_as_list(*this);
|
||||
auto glob_list = const_cast<AST::Node&>(arguments[0]).run(*this)->resolve_as_list(*this).release_value_but_fixme_should_propagate_errors();
|
||||
if (glob_list.size() != 1) {
|
||||
raise_error(ShellError::EvaluatedSyntaxError, "Expected the <glob> argument to filter_glob to be a single string", arguments[0].position());
|
||||
return nullptr;
|
||||
|
@ -402,18 +406,18 @@ RefPtr<AST::Node> Shell::immediate_filter_glob(AST::ImmediateExpression& invokin
|
|||
NonnullRefPtrVector<AST::Node> result;
|
||||
|
||||
const_cast<AST::Node&>(list_node).for_each_entry(*this, [&](NonnullRefPtr<AST::Value> entry) {
|
||||
auto value = entry->resolve_as_list(*this);
|
||||
auto value = entry->resolve_as_list(*this).release_value_but_fixme_should_propagate_errors();
|
||||
if (value.size() == 0)
|
||||
return IterationDecision::Continue;
|
||||
if (value.size() == 1) {
|
||||
if (!value.first().matches(glob))
|
||||
if (!value.first().bytes_as_string_view().matches(glob))
|
||||
return IterationDecision::Continue;
|
||||
result.append(AST::make_ref_counted<AST::StringLiteral>(arguments[1].position(), value.first(), AST::StringLiteral::EnclosureType::None));
|
||||
return IterationDecision::Continue;
|
||||
}
|
||||
|
||||
for (auto& entry : value) {
|
||||
if (entry.matches(glob)) {
|
||||
if (entry.bytes_as_string_view().matches(glob)) {
|
||||
NonnullRefPtrVector<AST::Node> nodes;
|
||||
for (auto& string : value)
|
||||
nodes.append(AST::make_ref_counted<AST::StringLiteral>(arguments[1].position(), string, AST::StringLiteral::EnclosureType::None));
|
||||
|
@ -440,17 +444,17 @@ RefPtr<AST::Node> Shell::immediate_join(AST::ImmediateExpression& invoking_node,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
auto value = const_cast<AST::Node&>(arguments[1]).run(this)->resolve_without_cast(this);
|
||||
auto value = const_cast<AST::Node&>(arguments[1]).run(this)->resolve_without_cast(this).release_value_but_fixme_should_propagate_errors();
|
||||
if (!value->is_list()) {
|
||||
raise_error(ShellError::EvaluatedSyntaxError, "Expected the joined list to be a list", arguments[1].position());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto delimiter_str = delimiter->resolve_as_list(this)[0];
|
||||
auto delimiter_str = delimiter->resolve_as_list(this).release_value_but_fixme_should_propagate_errors()[0];
|
||||
StringBuilder builder;
|
||||
builder.join(delimiter_str, value->resolve_as_list(*this));
|
||||
builder.join(delimiter_str, value->resolve_as_list(*this).release_value_but_fixme_should_propagate_errors());
|
||||
|
||||
return AST::make_ref_counted<AST::StringLiteral>(invoking_node.position(), builder.to_deprecated_string(), AST::StringLiteral::EnclosureType::None);
|
||||
return AST::make_ref_counted<AST::StringLiteral>(invoking_node.position(), builder.to_string().release_value_but_fixme_should_propagate_errors(), AST::StringLiteral::EnclosureType::None);
|
||||
}
|
||||
|
||||
RefPtr<AST::Node> Shell::immediate_value_or_default(AST::ImmediateExpression& invoking_node, NonnullRefPtrVector<AST::Node> const& arguments)
|
||||
|
@ -460,7 +464,7 @@ RefPtr<AST::Node> Shell::immediate_value_or_default(AST::ImmediateExpression& in
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
auto name = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this);
|
||||
auto name = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this).release_value_but_fixme_should_propagate_errors();
|
||||
if (!local_variable_or(name, ""sv).is_empty())
|
||||
return make_ref_counted<AST::SimpleVariable>(invoking_node.position(), name);
|
||||
|
||||
|
@ -474,12 +478,12 @@ RefPtr<AST::Node> Shell::immediate_assign_default(AST::ImmediateExpression& invo
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
auto name = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this);
|
||||
auto name = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this).release_value_but_fixme_should_propagate_errors();
|
||||
if (!local_variable_or(name, ""sv).is_empty())
|
||||
return make_ref_counted<AST::SimpleVariable>(invoking_node.position(), name);
|
||||
|
||||
auto value = const_cast<AST::Node&>(arguments.last()).run(*this)->resolve_without_cast(*this);
|
||||
set_local_variable(name, value);
|
||||
auto value = const_cast<AST::Node&>(arguments.last()).run(*this)->resolve_without_cast(*this).release_value_but_fixme_should_propagate_errors();
|
||||
set_local_variable(name.to_deprecated_string(), value);
|
||||
|
||||
return make_ref_counted<AST::SyntheticNode>(invoking_node.position(), value);
|
||||
}
|
||||
|
@ -491,15 +495,15 @@ RefPtr<AST::Node> Shell::immediate_error_if_empty(AST::ImmediateExpression& invo
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
auto name = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this);
|
||||
auto name = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this).release_value_but_fixme_should_propagate_errors();
|
||||
if (!local_variable_or(name, ""sv).is_empty())
|
||||
return make_ref_counted<AST::SimpleVariable>(invoking_node.position(), name);
|
||||
|
||||
auto error_value = const_cast<AST::Node&>(arguments.last()).run(*this)->resolve_as_string(*this);
|
||||
auto error_value = const_cast<AST::Node&>(arguments.last()).run(*this)->resolve_as_string(*this).release_value_but_fixme_should_propagate_errors();
|
||||
if (error_value.is_empty())
|
||||
error_value = DeprecatedString::formatted("Expected {} to be non-empty", name);
|
||||
error_value = String::formatted("Expected {} to be non-empty", name).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
raise_error(ShellError::EvaluatedSyntaxError, error_value, invoking_node.position());
|
||||
raise_error(ShellError::EvaluatedSyntaxError, error_value.bytes_as_string_view(), invoking_node.position());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -510,8 +514,8 @@ RefPtr<AST::Node> Shell::immediate_null_or_alternative(AST::ImmediateExpression&
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
auto value = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_without_cast(*this);
|
||||
if ((value->is_string() && value->resolve_as_string(*this).is_empty()) || (value->is_list() && value->resolve_as_list(*this).is_empty()))
|
||||
auto value = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_without_cast(*this).release_value_but_fixme_should_propagate_errors();
|
||||
if ((value->is_string() && value->resolve_as_string(*this).release_value_but_fixme_should_propagate_errors().is_empty()) || (value->is_list() && value->resolve_as_list(*this).release_value_but_fixme_should_propagate_errors().is_empty()))
|
||||
return make_ref_counted<AST::SyntheticNode>(invoking_node.position(), value);
|
||||
|
||||
return arguments.last();
|
||||
|
@ -524,7 +528,7 @@ RefPtr<AST::Node> Shell::immediate_defined_value_or_default(AST::ImmediateExpres
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
auto name = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this);
|
||||
auto name = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this).release_value_but_fixme_should_propagate_errors();
|
||||
if (!find_frame_containing_local_variable(name))
|
||||
return arguments.last();
|
||||
|
||||
|
@ -538,12 +542,12 @@ RefPtr<AST::Node> Shell::immediate_assign_defined_default(AST::ImmediateExpressi
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
auto name = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this);
|
||||
auto name = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this).release_value_but_fixme_should_propagate_errors();
|
||||
if (find_frame_containing_local_variable(name))
|
||||
return make_ref_counted<AST::SimpleVariable>(invoking_node.position(), name);
|
||||
|
||||
auto value = const_cast<AST::Node&>(arguments.last()).run(*this)->resolve_without_cast(*this);
|
||||
set_local_variable(name, value);
|
||||
auto value = const_cast<AST::Node&>(arguments.last()).run(*this)->resolve_without_cast(*this).release_value_but_fixme_should_propagate_errors();
|
||||
set_local_variable(name.to_deprecated_string(), value);
|
||||
|
||||
return make_ref_counted<AST::SyntheticNode>(invoking_node.position(), value);
|
||||
}
|
||||
|
@ -555,15 +559,15 @@ RefPtr<AST::Node> Shell::immediate_error_if_unset(AST::ImmediateExpression& invo
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
auto name = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this);
|
||||
auto name = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this).release_value_but_fixme_should_propagate_errors();
|
||||
if (find_frame_containing_local_variable(name))
|
||||
return make_ref_counted<AST::SimpleVariable>(invoking_node.position(), name);
|
||||
|
||||
auto error_value = const_cast<AST::Node&>(arguments.last()).run(*this)->resolve_as_string(*this);
|
||||
auto error_value = const_cast<AST::Node&>(arguments.last()).run(*this)->resolve_as_string(*this).release_value_but_fixme_should_propagate_errors();
|
||||
if (error_value.is_empty())
|
||||
error_value = DeprecatedString::formatted("Expected {} to be set", name);
|
||||
error_value = String::formatted("Expected {} to be set", name).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
raise_error(ShellError::EvaluatedSyntaxError, error_value, invoking_node.position());
|
||||
raise_error(ShellError::EvaluatedSyntaxError, error_value.bytes_as_string_view(), invoking_node.position());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -574,7 +578,7 @@ RefPtr<AST::Node> Shell::immediate_null_if_unset_or_alternative(AST::ImmediateEx
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
auto name = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this);
|
||||
auto name = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this).release_value_but_fixme_should_propagate_errors();
|
||||
if (!find_frame_containing_local_variable(name))
|
||||
return arguments.last();
|
||||
|
||||
|
@ -588,7 +592,7 @@ RefPtr<AST::Node> Shell::immediate_reexpand(AST::ImmediateExpression& invoking_n
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
auto value = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this);
|
||||
auto value = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this).release_value_but_fixme_should_propagate_errors();
|
||||
return parse(value, m_is_interactive, false);
|
||||
}
|
||||
|
||||
|
@ -599,7 +603,7 @@ RefPtr<AST::Node> Shell::immediate_length_of_variable(AST::ImmediateExpression&
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
auto name = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this);
|
||||
auto name = const_cast<AST::Node&>(arguments.first()).run(*this)->resolve_as_string(*this).release_value_but_fixme_should_propagate_errors();
|
||||
auto variable = make_ref_counted<AST::SimpleVariable>(invoking_node.position(), name);
|
||||
|
||||
return immediate_length_impl(
|
||||
|
|
|
@ -132,7 +132,7 @@ RefPtr<AST::Node> Parser::parse()
|
|||
auto error_start = push_start();
|
||||
while (!at_end())
|
||||
consume();
|
||||
auto syntax_error_node = create<AST::SyntaxError>("Unexpected tokens past the end");
|
||||
auto syntax_error_node = create<AST::SyntaxError>(String::from_utf8("Unexpected tokens past the end"sv).release_value_but_fixme_should_propagate_errors());
|
||||
if (!toplevel)
|
||||
toplevel = move(syntax_error_node);
|
||||
else if (!toplevel->is_syntax_error())
|
||||
|
@ -217,7 +217,7 @@ Parser::SequenceParseResult Parser::parse_sequence()
|
|||
error_builder.appendff(", {} (at {}:{})", entry.end, entry.node->position().start_line.line_column, entry.node->position().start_line.line_number);
|
||||
first = false;
|
||||
}
|
||||
left.append(create<AST::SyntaxError>(error_builder.to_deprecated_string(), true));
|
||||
left.append(create<AST::SyntaxError>(error_builder.to_string().release_value_but_fixme_should_propagate_errors(), true));
|
||||
// Just read the rest of the newlines
|
||||
goto discard_terminators;
|
||||
}
|
||||
|
@ -314,7 +314,7 @@ RefPtr<AST::Node> Parser::parse_variable_decls()
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
auto name_expr = create<AST::BarewordLiteral>(move(var_name));
|
||||
auto name_expr = create<AST::BarewordLiteral>(String::from_utf8(var_name).release_value_but_fixme_should_propagate_errors());
|
||||
|
||||
auto start = push_start();
|
||||
auto expression = parse_expression();
|
||||
|
@ -326,14 +326,14 @@ RefPtr<AST::Node> Parser::parse_variable_decls()
|
|||
if (!command)
|
||||
restore_to(*start);
|
||||
else if (!expect(')'))
|
||||
command->set_is_syntax_error(*create<AST::SyntaxError>("Expected a terminating close paren", true));
|
||||
command->set_is_syntax_error(*create<AST::SyntaxError>(String::from_utf8("Expected a terminating close paren"sv).release_value_but_fixme_should_propagate_errors(), true));
|
||||
expression = command;
|
||||
}
|
||||
}
|
||||
if (!expression) {
|
||||
if (is_whitespace(peek())) {
|
||||
auto string_start = push_start();
|
||||
expression = create<AST::StringLiteral>("", AST::StringLiteral::EnclosureType::None);
|
||||
expression = create<AST::StringLiteral>(String {}, AST::StringLiteral::EnclosureType::None);
|
||||
} else {
|
||||
restore_to(pos_before_name.offset, pos_before_name.line);
|
||||
return nullptr;
|
||||
|
@ -391,7 +391,7 @@ RefPtr<AST::Node> Parser::parse_function_decl()
|
|||
// FIXME: Should this be a syntax error, or just return?
|
||||
return restore();
|
||||
}
|
||||
arguments.append({ arg_name, { name_offset, m_offset, start_line, line() } });
|
||||
arguments.append({ String::from_utf8(arg_name).release_value_but_fixme_should_propagate_errors(), { name_offset, m_offset, start_line, line() } });
|
||||
}
|
||||
|
||||
consume_while(is_any_of("\n\t "sv));
|
||||
|
@ -400,12 +400,12 @@ RefPtr<AST::Node> Parser::parse_function_decl()
|
|||
RefPtr<AST::Node> syntax_error;
|
||||
{
|
||||
auto obrace_error_start = push_start();
|
||||
syntax_error = create<AST::SyntaxError>("Expected an open brace '{' to start a function body", true);
|
||||
syntax_error = create<AST::SyntaxError>(String::from_utf8("Expected an open brace '{' to start a function body"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
}
|
||||
if (!expect('{')) {
|
||||
return create<AST::FunctionDeclaration>(
|
||||
AST::NameWithPosition {
|
||||
move(function_name),
|
||||
String::from_utf8(function_name).release_value_but_fixme_should_propagate_errors(),
|
||||
{ pos_before_name.offset, pos_after_name.offset, pos_before_name.line, pos_after_name.line } },
|
||||
move(arguments),
|
||||
move(syntax_error));
|
||||
|
@ -419,7 +419,7 @@ RefPtr<AST::Node> Parser::parse_function_decl()
|
|||
RefPtr<AST::SyntaxError> syntax_error;
|
||||
{
|
||||
auto cbrace_error_start = push_start();
|
||||
syntax_error = create<AST::SyntaxError>("Expected a close brace '}' to end a function body", true);
|
||||
syntax_error = create<AST::SyntaxError>(String::from_utf8("Expected a close brace '}' to end a function body"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
}
|
||||
if (!expect('}')) {
|
||||
if (body)
|
||||
|
@ -429,7 +429,7 @@ RefPtr<AST::Node> Parser::parse_function_decl()
|
|||
|
||||
return create<AST::FunctionDeclaration>(
|
||||
AST::NameWithPosition {
|
||||
move(function_name),
|
||||
String::from_utf8(function_name).release_value_but_fixme_should_propagate_errors(),
|
||||
{ pos_before_name.offset, pos_after_name.offset, pos_before_name.line, pos_after_name.line } },
|
||||
move(arguments),
|
||||
move(body));
|
||||
|
@ -438,7 +438,7 @@ RefPtr<AST::Node> Parser::parse_function_decl()
|
|||
|
||||
return create<AST::FunctionDeclaration>(
|
||||
AST::NameWithPosition {
|
||||
move(function_name),
|
||||
String::from_utf8(function_name).release_value_but_fixme_should_propagate_errors(),
|
||||
{ pos_before_name.offset, pos_after_name.offset, pos_before_name.line, pos_after_name.line } },
|
||||
move(arguments),
|
||||
move(body));
|
||||
|
@ -460,7 +460,7 @@ RefPtr<AST::Node> Parser::parse_or_logical_sequence()
|
|||
|
||||
auto right_and_sequence = parse_and_logical_sequence();
|
||||
if (!right_and_sequence)
|
||||
right_and_sequence = create<AST::SyntaxError>("Expected an expression after '||'", true);
|
||||
right_and_sequence = create<AST::SyntaxError>(String::from_utf8("Expected an expression after '||'"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
|
||||
return create<AST::Or>(
|
||||
and_sequence.release_nonnull(),
|
||||
|
@ -484,7 +484,7 @@ RefPtr<AST::Node> Parser::parse_and_logical_sequence()
|
|||
|
||||
auto right_and_sequence = parse_and_logical_sequence();
|
||||
if (!right_and_sequence)
|
||||
right_and_sequence = create<AST::SyntaxError>("Expected an expression after '&&'", true);
|
||||
right_and_sequence = create<AST::SyntaxError>(String::from_utf8("Expected an expression after '&&'"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
|
||||
return create<AST::And>(
|
||||
pipe_sequence.release_nonnull(),
|
||||
|
@ -642,7 +642,7 @@ RefPtr<AST::Node> Parser::parse_for_loop()
|
|||
|
||||
auto offset_after_variable = current_position();
|
||||
index_variable_name = AST::NameWithPosition {
|
||||
variable,
|
||||
String::from_utf8(variable).release_value_but_fixme_should_propagate_errors(),
|
||||
{ offset_before_variable.offset, offset_after_variable.offset, offset_before_variable.line, offset_after_variable.line },
|
||||
};
|
||||
|
||||
|
@ -660,13 +660,13 @@ RefPtr<AST::Node> Parser::parse_for_loop()
|
|||
auto variable_name_end_offset = current_position();
|
||||
if (!name.is_empty()) {
|
||||
variable_name = AST::NameWithPosition {
|
||||
name,
|
||||
String::from_utf8(name).release_value_but_fixme_should_propagate_errors(),
|
||||
{ variable_name_start_offset.offset, variable_name_end_offset.offset, variable_name_start_offset.line, variable_name_end_offset.line }
|
||||
};
|
||||
consume_while(is_whitespace);
|
||||
auto in_error_start = push_start();
|
||||
if (!expect("in"sv)) {
|
||||
auto syntax_error = create<AST::SyntaxError>("Expected 'in' after a variable name in a 'for' loop", true);
|
||||
auto syntax_error = create<AST::SyntaxError>(String::from_utf8("Expected 'in' after a variable name in a 'for' loop"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
return create<AST::ForLoop>(move(variable_name), move(index_variable_name), move(syntax_error), nullptr); // ForLoop Var Iterated Block
|
||||
}
|
||||
in_start_position = AST::Position { in_error_start->offset, m_offset, in_error_start->line, line() };
|
||||
|
@ -678,14 +678,14 @@ RefPtr<AST::Node> Parser::parse_for_loop()
|
|||
auto iter_error_start = push_start();
|
||||
iterated_expression = parse_expression();
|
||||
if (!iterated_expression)
|
||||
iterated_expression = create<AST::SyntaxError>("Expected an expression in 'for' loop", true);
|
||||
iterated_expression = create<AST::SyntaxError>(String::from_utf8("Expected an expression in 'for' loop"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
}
|
||||
|
||||
consume_while(is_any_of(" \t\n"sv));
|
||||
{
|
||||
auto obrace_error_start = push_start();
|
||||
if (!expect('{')) {
|
||||
auto syntax_error = create<AST::SyntaxError>("Expected an open brace '{' to start a 'for' loop body", true);
|
||||
auto syntax_error = create<AST::SyntaxError>(String::from_utf8("Expected an open brace '{' to start a 'for' loop body"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
return create<AST::ForLoop>(move(variable_name), move(index_variable_name), move(iterated_expression), move(syntax_error), move(in_start_position), move(index_start_position)); // ForLoop Var Iterated Block
|
||||
}
|
||||
}
|
||||
|
@ -697,7 +697,7 @@ RefPtr<AST::Node> Parser::parse_for_loop()
|
|||
auto cbrace_error_start = push_start();
|
||||
if (!expect('}')) {
|
||||
auto error_start = push_start();
|
||||
auto syntax_error = create<AST::SyntaxError>("Expected a close brace '}' to end a 'for' loop body", true);
|
||||
auto syntax_error = create<AST::SyntaxError>(String::from_utf8("Expected a close brace '}' to end a 'for' loop body"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
if (body)
|
||||
body->set_is_syntax_error(*syntax_error);
|
||||
else
|
||||
|
@ -722,7 +722,7 @@ RefPtr<AST::Node> Parser::parse_loop_loop()
|
|||
{
|
||||
auto obrace_error_start = push_start();
|
||||
if (!expect('{')) {
|
||||
auto syntax_error = create<AST::SyntaxError>("Expected an open brace '{' to start a 'loop' loop body", true);
|
||||
auto syntax_error = create<AST::SyntaxError>(String::from_utf8("Expected an open brace '{' to start a 'loop' loop body"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
return create<AST::ForLoop>(AST::NameWithPosition {}, AST::NameWithPosition {}, nullptr, move(syntax_error)); // ForLoop null null Block
|
||||
}
|
||||
}
|
||||
|
@ -734,7 +734,7 @@ RefPtr<AST::Node> Parser::parse_loop_loop()
|
|||
auto cbrace_error_start = push_start();
|
||||
if (!expect('}')) {
|
||||
auto error_start = push_start();
|
||||
auto syntax_error = create<AST::SyntaxError>("Expected a close brace '}' to end a 'loop' loop body", true);
|
||||
auto syntax_error = create<AST::SyntaxError>(String::from_utf8("Expected a close brace '}' to end a 'loop' loop body"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
if (body)
|
||||
body->set_is_syntax_error(*syntax_error);
|
||||
else
|
||||
|
@ -761,7 +761,7 @@ RefPtr<AST::Node> Parser::parse_if_expr()
|
|||
auto cond_error_start = push_start();
|
||||
condition = parse_or_logical_sequence();
|
||||
if (!condition)
|
||||
condition = create<AST::SyntaxError>("Expected a logical sequence after 'if'", true);
|
||||
condition = create<AST::SyntaxError>(String::from_utf8("Expected a logical sequence after 'if'"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
}
|
||||
|
||||
auto parse_braced_toplevel = [&]() -> RefPtr<AST::Node> {
|
||||
|
@ -769,7 +769,7 @@ RefPtr<AST::Node> Parser::parse_if_expr()
|
|||
{
|
||||
auto obrace_error_start = push_start();
|
||||
if (!expect('{')) {
|
||||
body = create<AST::SyntaxError>("Expected an open brace '{' to start an 'if' true branch", true);
|
||||
body = create<AST::SyntaxError>(String::from_utf8("Expected an open brace '{' to start an 'if' true branch"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -780,7 +780,7 @@ RefPtr<AST::Node> Parser::parse_if_expr()
|
|||
auto cbrace_error_start = push_start();
|
||||
if (!expect('}')) {
|
||||
auto error_start = push_start();
|
||||
RefPtr<AST::SyntaxError> syntax_error = create<AST::SyntaxError>("Expected a close brace '}' to end an 'if' true branch", true);
|
||||
RefPtr<AST::SyntaxError> syntax_error = create<AST::SyntaxError>(String::from_utf8("Expected a close brace '}' to end an 'if' true branch"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
if (body)
|
||||
body->set_is_syntax_error(*syntax_error);
|
||||
else
|
||||
|
@ -832,7 +832,7 @@ RefPtr<AST::Node> Parser::parse_subshell()
|
|||
auto cbrace_error_start = push_start();
|
||||
if (!expect('}')) {
|
||||
auto error_start = push_start();
|
||||
RefPtr<AST::SyntaxError> syntax_error = create<AST::SyntaxError>("Expected a close brace '}' to end a subshell", true);
|
||||
RefPtr<AST::SyntaxError> syntax_error = create<AST::SyntaxError>(String::from_utf8("Expected a close brace '}' to end a subshell"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
if (body)
|
||||
body->set_is_syntax_error(*syntax_error);
|
||||
else
|
||||
|
@ -857,13 +857,13 @@ RefPtr<AST::Node> Parser::parse_match_expr()
|
|||
auto match_expression = parse_expression();
|
||||
if (!match_expression) {
|
||||
return create<AST::MatchExpr>(
|
||||
create<AST::SyntaxError>("Expected an expression after 'match'", true),
|
||||
DeprecatedString {}, Optional<AST::Position> {}, Vector<AST::MatchEntry> {});
|
||||
create<AST::SyntaxError>(String::from_utf8("Expected an expression after 'match'"sv).release_value_but_fixme_should_propagate_errors(), true),
|
||||
String {}, Optional<AST::Position> {}, Vector<AST::MatchEntry> {});
|
||||
}
|
||||
|
||||
consume_while(is_any_of(" \t\n"sv));
|
||||
|
||||
DeprecatedString match_name;
|
||||
String match_name;
|
||||
Optional<AST::Position> as_position;
|
||||
auto as_start = m_offset;
|
||||
auto as_line = line();
|
||||
|
@ -873,17 +873,17 @@ RefPtr<AST::Node> Parser::parse_match_expr()
|
|||
if (consume_while(is_any_of(" \t\n"sv)).is_empty()) {
|
||||
auto node = create<AST::MatchExpr>(
|
||||
match_expression.release_nonnull(),
|
||||
DeprecatedString {}, move(as_position), Vector<AST::MatchEntry> {});
|
||||
node->set_is_syntax_error(create<AST::SyntaxError>("Expected whitespace after 'as' in 'match'", true));
|
||||
String {}, move(as_position), Vector<AST::MatchEntry> {});
|
||||
node->set_is_syntax_error(create<AST::SyntaxError>(String::from_utf8("Expected whitespace after 'as' in 'match'"sv).release_value_but_fixme_should_propagate_errors(), true));
|
||||
return node;
|
||||
}
|
||||
|
||||
match_name = consume_while(is_word_character);
|
||||
match_name = String::from_utf8(consume_while(is_word_character)).release_value_but_fixme_should_propagate_errors();
|
||||
if (match_name.is_empty()) {
|
||||
auto node = create<AST::MatchExpr>(
|
||||
match_expression.release_nonnull(),
|
||||
DeprecatedString {}, move(as_position), Vector<AST::MatchEntry> {});
|
||||
node->set_is_syntax_error(create<AST::SyntaxError>("Expected an identifier after 'as' in 'match'", true));
|
||||
String {}, move(as_position), Vector<AST::MatchEntry> {});
|
||||
node->set_is_syntax_error(create<AST::SyntaxError>(String::from_utf8("Expected an identifier after 'as' in 'match'"sv).release_value_but_fixme_should_propagate_errors(), true));
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
@ -894,7 +894,7 @@ RefPtr<AST::Node> Parser::parse_match_expr()
|
|||
auto node = create<AST::MatchExpr>(
|
||||
match_expression.release_nonnull(),
|
||||
move(match_name), move(as_position), Vector<AST::MatchEntry> {});
|
||||
node->set_is_syntax_error(create<AST::SyntaxError>("Expected an open brace '{' to start a 'match' entry list", true));
|
||||
node->set_is_syntax_error(create<AST::SyntaxError>(String::from_utf8("Expected an open brace '{' to start a 'match' entry list"sv).release_value_but_fixme_should_propagate_errors(), true));
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -916,7 +916,7 @@ RefPtr<AST::Node> Parser::parse_match_expr()
|
|||
auto node = create<AST::MatchExpr>(
|
||||
match_expression.release_nonnull(),
|
||||
move(match_name), move(as_position), move(entries));
|
||||
node->set_is_syntax_error(create<AST::SyntaxError>("Expected a close brace '}' to end a 'match' entry list", true));
|
||||
node->set_is_syntax_error(create<AST::SyntaxError>(String::from_utf8("Expected a close brace '}' to end a 'match' entry list"sv).release_value_but_fixme_should_propagate_errors(), true));
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -930,7 +930,7 @@ AST::MatchEntry Parser::parse_match_entry()
|
|||
NonnullRefPtrVector<AST::Node> patterns;
|
||||
Vector<Regex<ECMA262>> regexps;
|
||||
Vector<AST::Position> pipe_positions;
|
||||
Optional<Vector<DeprecatedString>> match_names;
|
||||
Optional<Vector<String>> match_names;
|
||||
Optional<AST::Position> match_as_position;
|
||||
enum {
|
||||
Regex,
|
||||
|
@ -942,14 +942,14 @@ AST::MatchEntry Parser::parse_match_entry()
|
|||
auto regex_pattern = parse_regex_pattern();
|
||||
if (regex_pattern.has_value()) {
|
||||
if (auto error = regex_pattern.value().parser_result.error; error != regex::Error::NoError)
|
||||
return { NonnullRefPtrVector<AST::Node> {}, {}, {}, {}, create<AST::SyntaxError>(regex::get_error_string(error), false) };
|
||||
return { NonnullRefPtrVector<AST::Node> {}, {}, {}, {}, create<AST::SyntaxError>(String::from_utf8(regex::get_error_string(error)).release_value_but_fixme_should_propagate_errors(), false) };
|
||||
|
||||
pattern_kind = Regex;
|
||||
regexps.append(regex_pattern.release_value());
|
||||
} else {
|
||||
auto glob_pattern = parse_match_pattern();
|
||||
if (!glob_pattern)
|
||||
return { NonnullRefPtrVector<AST::Node> {}, {}, {}, {}, create<AST::SyntaxError>("Expected a pattern in 'match' body", true) };
|
||||
return { NonnullRefPtrVector<AST::Node> {}, {}, {}, {}, create<AST::SyntaxError>(String::from_utf8("Expected a pattern in 'match' body"sv).release_value_but_fixme_should_propagate_errors(), true) };
|
||||
|
||||
pattern_kind = Glob;
|
||||
patterns.append(glob_pattern.release_nonnull());
|
||||
|
@ -967,7 +967,7 @@ AST::MatchEntry Parser::parse_match_entry()
|
|||
case Regex: {
|
||||
auto pattern = parse_regex_pattern();
|
||||
if (!pattern.has_value()) {
|
||||
error = create<AST::SyntaxError>("Expected a regex pattern to follow '|' in 'match' body", true);
|
||||
error = create<AST::SyntaxError>(String::from_utf8("Expected a regex pattern to follow '|' in 'match' body"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
break;
|
||||
}
|
||||
regexps.append(pattern.release_value());
|
||||
|
@ -976,7 +976,7 @@ AST::MatchEntry Parser::parse_match_entry()
|
|||
case Glob: {
|
||||
auto pattern = parse_match_pattern();
|
||||
if (!pattern) {
|
||||
error = create<AST::SyntaxError>("Expected a pattern to follow '|' in 'match' body", true);
|
||||
error = create<AST::SyntaxError>(String::from_utf8("Expected a pattern to follow '|' in 'match' body"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
break;
|
||||
}
|
||||
patterns.append(pattern.release_nonnull());
|
||||
|
@ -999,42 +999,42 @@ AST::MatchEntry Parser::parse_match_entry()
|
|||
consume_while(is_any_of(" \t\n"sv));
|
||||
if (!expect('(')) {
|
||||
if (!error)
|
||||
error = create<AST::SyntaxError>("Expected an explicit list of identifiers after a pattern 'as'");
|
||||
error = create<AST::SyntaxError>(String::from_utf8("Expected an explicit list of identifiers after a pattern 'as'"sv).release_value_but_fixme_should_propagate_errors());
|
||||
} else {
|
||||
match_names = Vector<DeprecatedString>();
|
||||
match_names = Vector<String>();
|
||||
for (;;) {
|
||||
consume_while(is_whitespace);
|
||||
auto name = consume_while(is_word_character);
|
||||
if (name.is_empty())
|
||||
break;
|
||||
match_names.value().append(move(name));
|
||||
match_names->append(String::from_utf8(name).release_value_but_fixme_should_propagate_errors());
|
||||
}
|
||||
|
||||
if (!expect(')')) {
|
||||
if (!error)
|
||||
error = create<AST::SyntaxError>("Expected a close paren ')' to end the identifier list of pattern 'as'", true);
|
||||
error = create<AST::SyntaxError>(String::from_utf8("Expected a close paren ')' to end the identifier list of pattern 'as'"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
}
|
||||
}
|
||||
consume_while(is_any_of(" \t\n"sv));
|
||||
}
|
||||
|
||||
if (pattern_kind == Regex) {
|
||||
Vector<DeprecatedString> names;
|
||||
Vector<String> names;
|
||||
for (auto& regex : regexps) {
|
||||
if (names.is_empty()) {
|
||||
for (auto& name : regex.parser_result.capture_groups)
|
||||
names.append(name);
|
||||
names.append(String::from_utf8(name).release_value_but_fixme_should_propagate_errors());
|
||||
} else {
|
||||
size_t index = 0;
|
||||
for (auto& name : regex.parser_result.capture_groups) {
|
||||
if (names.size() <= index) {
|
||||
names.append(name);
|
||||
names.append(String::from_utf8(name).release_value_but_fixme_should_propagate_errors());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (names[index] != name) {
|
||||
if (names[index] != name.view()) {
|
||||
if (!error)
|
||||
error = create<AST::SyntaxError>("Alternative regex patterns must have the same capture groups", false);
|
||||
error = create<AST::SyntaxError>(String::from_utf8("Alternative regex patterns must have the same capture groups"sv).release_value_but_fixme_should_propagate_errors(), false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1045,14 +1045,14 @@ AST::MatchEntry Parser::parse_match_entry()
|
|||
|
||||
if (!expect('{')) {
|
||||
if (!error)
|
||||
error = create<AST::SyntaxError>("Expected an open brace '{' to start a match entry body", true);
|
||||
error = create<AST::SyntaxError>(String::from_utf8("Expected an open brace '{' to start a match entry body"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
}
|
||||
|
||||
auto body = parse_toplevel();
|
||||
|
||||
if (!expect('}')) {
|
||||
if (!error)
|
||||
error = create<AST::SyntaxError>("Expected a close brace '}' to end a match entry body", true);
|
||||
error = create<AST::SyntaxError>(String::from_utf8("Expected a close brace '}' to end a match entry body"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
}
|
||||
|
||||
if (body && error)
|
||||
|
@ -1131,7 +1131,7 @@ RefPtr<AST::Node> Parser::parse_redirection()
|
|||
// Eat a character and hope the problem goes away
|
||||
consume();
|
||||
}
|
||||
path = create<AST::SyntaxError>("Expected a path after redirection", true);
|
||||
path = create<AST::SyntaxError>(String::from_utf8("Expected a path after redirection"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
}
|
||||
return create<AST::WriteAppendRedirection>(pipe_fd, path.release_nonnull()); // Redirection WriteAppend
|
||||
}
|
||||
|
@ -1154,7 +1154,7 @@ RefPtr<AST::Node> Parser::parse_redirection()
|
|||
}
|
||||
auto redir = create<AST::Fd2FdRedirection>(pipe_fd, dest_pipe_fd); // Redirection Fd2Fd
|
||||
if (dest_pipe_fd == -1)
|
||||
redir->set_is_syntax_error(*create<AST::SyntaxError>("Expected a file descriptor"));
|
||||
redir->set_is_syntax_error(*create<AST::SyntaxError>(String::from_utf8("Expected a file descriptor"sv).release_value_but_fixme_should_propagate_errors()));
|
||||
return redir;
|
||||
}
|
||||
consume_while(is_whitespace);
|
||||
|
@ -1165,7 +1165,7 @@ RefPtr<AST::Node> Parser::parse_redirection()
|
|||
// Eat a character and hope the problem goes away
|
||||
consume();
|
||||
}
|
||||
path = create<AST::SyntaxError>("Expected a path after redirection", true);
|
||||
path = create<AST::SyntaxError>(String::from_utf8("Expected a path after redirection"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
}
|
||||
return create<AST::WriteRedirection>(pipe_fd, path.release_nonnull()); // Redirection Write
|
||||
}
|
||||
|
@ -1189,7 +1189,7 @@ RefPtr<AST::Node> Parser::parse_redirection()
|
|||
// Eat a character and hope the problem goes away
|
||||
consume();
|
||||
}
|
||||
path = create<AST::SyntaxError>("Expected a path after redirection", true);
|
||||
path = create<AST::SyntaxError>(String::from_utf8("Expected a path after redirection"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
}
|
||||
if (mode == Read)
|
||||
return create<AST::ReadRedirection>(pipe_fd, path.release_nonnull()); // Redirection Read
|
||||
|
@ -1226,7 +1226,7 @@ RefPtr<AST::Node> Parser::parse_expression()
|
|||
{
|
||||
auto rule_start = push_start();
|
||||
if (m_rule_start_offsets.size() > max_allowed_nested_rule_depth)
|
||||
return create<AST::SyntaxError>(DeprecatedString::formatted("Expression nested too deep (max allowed is {})", max_allowed_nested_rule_depth));
|
||||
return create<AST::SyntaxError>(String::formatted("Expression nested too deep (max allowed is {})", max_allowed_nested_rule_depth).release_value_but_fixme_should_propagate_errors());
|
||||
|
||||
auto starting_char = peek();
|
||||
|
||||
|
@ -1362,10 +1362,10 @@ RefPtr<AST::Node> Parser::parse_string()
|
|||
consume();
|
||||
auto inner = parse_string_inner(StringEndCondition::DoubleQuote);
|
||||
if (!inner)
|
||||
inner = create<AST::SyntaxError>("Unexpected EOF in string", true);
|
||||
inner = create<AST::SyntaxError>(String::from_utf8("Unexpected EOF in string"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
if (!expect('"')) {
|
||||
inner = create<AST::DoubleQuotedString>(move(inner));
|
||||
inner->set_is_syntax_error(*create<AST::SyntaxError>("Expected a terminating double quote", true));
|
||||
inner->set_is_syntax_error(*create<AST::SyntaxError>(String::from_utf8("Expected a terminating double quote"sv).release_value_but_fixme_should_propagate_errors(), true));
|
||||
return inner;
|
||||
}
|
||||
return create<AST::DoubleQuotedString>(move(inner)); // Double Quoted String
|
||||
|
@ -1377,9 +1377,9 @@ RefPtr<AST::Node> Parser::parse_string()
|
|||
bool is_error = false;
|
||||
if (!expect('\''))
|
||||
is_error = true;
|
||||
auto result = create<AST::StringLiteral>(move(text), AST::StringLiteral::EnclosureType::SingleQuotes); // String Literal
|
||||
auto result = create<AST::StringLiteral>(String::from_utf8(text).release_value_but_fixme_should_propagate_errors(), AST::StringLiteral::EnclosureType::SingleQuotes); // String Literal
|
||||
if (is_error)
|
||||
result->set_is_syntax_error(*create<AST::SyntaxError>("Expected a terminating single quote", true));
|
||||
result->set_is_syntax_error(*create<AST::SyntaxError>(String::from_utf8("Expected a terminating single quote"sv).release_value_but_fixme_should_propagate_errors(), true));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1459,7 +1459,7 @@ RefPtr<AST::Node> Parser::parse_string_inner(StringEndCondition condition)
|
|||
continue;
|
||||
}
|
||||
if (peek() == '$') {
|
||||
auto string_literal = create<AST::StringLiteral>(builder.to_deprecated_string(), AST::StringLiteral::EnclosureType::DoubleQuotes); // String Literal
|
||||
auto string_literal = create<AST::StringLiteral>(builder.to_string().release_value_but_fixme_should_propagate_errors(), AST::StringLiteral::EnclosureType::DoubleQuotes); // String Literal
|
||||
auto read_concat = [&](auto&& node) {
|
||||
auto inner = create<AST::StringPartCompose>(
|
||||
move(string_literal),
|
||||
|
@ -1485,7 +1485,7 @@ RefPtr<AST::Node> Parser::parse_string_inner(StringEndCondition condition)
|
|||
builder.append(consume());
|
||||
}
|
||||
|
||||
return create<AST::StringLiteral>(builder.to_deprecated_string(), AST::StringLiteral::EnclosureType::DoubleQuotes); // String Literal
|
||||
return create<AST::StringLiteral>(builder.to_string().release_value_but_fixme_should_propagate_errors(), AST::StringLiteral::EnclosureType::DoubleQuotes); // String Literal
|
||||
}
|
||||
|
||||
RefPtr<AST::Node> Parser::parse_variable()
|
||||
|
@ -1530,7 +1530,7 @@ RefPtr<AST::Node> Parser::parse_variable_ref()
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
return create<AST::SimpleVariable>(move(name)); // Variable Simple
|
||||
return create<AST::SimpleVariable>(String::from_utf8(name).release_value_but_fixme_should_propagate_errors()); // Variable Simple
|
||||
}
|
||||
|
||||
RefPtr<AST::Slice> Parser::parse_slice()
|
||||
|
@ -1548,7 +1548,7 @@ RefPtr<AST::Slice> Parser::parse_slice()
|
|||
RefPtr<AST::SyntaxError> error;
|
||||
|
||||
if (peek() != ']')
|
||||
error = create<AST::SyntaxError>("Expected a close bracket ']' to end a variable slice");
|
||||
error = create<AST::SyntaxError>(String::from_utf8("Expected a close bracket ']' to end a variable slice"sv).release_value_but_fixme_should_propagate_errors());
|
||||
else
|
||||
consume();
|
||||
|
||||
|
@ -1556,7 +1556,7 @@ RefPtr<AST::Slice> Parser::parse_slice()
|
|||
if (error)
|
||||
spec = move(error);
|
||||
else
|
||||
spec = create<AST::SyntaxError>("Expected either a range, or a comma-seprated list of selectors");
|
||||
spec = create<AST::SyntaxError>(String::from_utf8("Expected either a range, or a comma-seprated list of selectors"sv).release_value_but_fixme_should_propagate_errors());
|
||||
}
|
||||
|
||||
auto node = create<AST::Slice>(spec.release_nonnull());
|
||||
|
@ -1579,16 +1579,16 @@ RefPtr<AST::Node> Parser::parse_evaluate()
|
|||
consume();
|
||||
auto inner = parse_pipe_sequence();
|
||||
if (!inner)
|
||||
inner = create<AST::SyntaxError>("Unexpected EOF in list", true);
|
||||
inner = create<AST::SyntaxError>(String::from_utf8("Unexpected EOF in list"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
if (!expect(')'))
|
||||
inner->set_is_syntax_error(*create<AST::SyntaxError>("Expected a terminating close paren", true));
|
||||
inner->set_is_syntax_error(*create<AST::SyntaxError>(String::from_utf8("Expected a terminating close paren"sv).release_value_but_fixme_should_propagate_errors(), true));
|
||||
|
||||
return create<AST::Execute>(inner.release_nonnull(), true);
|
||||
}
|
||||
auto inner = parse_expression();
|
||||
|
||||
if (!inner) {
|
||||
inner = create<AST::SyntaxError>("Expected a command", true);
|
||||
inner = create<AST::SyntaxError>(String::from_utf8("Expected a command"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
} else {
|
||||
if (inner->is_list()) {
|
||||
auto execute_inner = create<AST::Execute>(inner.release_nonnull(), true);
|
||||
|
@ -1659,14 +1659,14 @@ RefPtr<AST::Node> Parser::parse_immediate_expression()
|
|||
};
|
||||
|
||||
auto node = create<AST::ImmediateExpression>(
|
||||
AST::NameWithPosition { function_name, move(function_position) },
|
||||
AST::NameWithPosition { String::from_utf8(function_name).release_value_but_fixme_should_propagate_errors(), move(function_position) },
|
||||
move(arguments),
|
||||
ending_brace_position);
|
||||
|
||||
if (!ending_brace_position.has_value())
|
||||
node->set_is_syntax_error(create<AST::SyntaxError>("Expected a closing brace '}' to end an immediate expression", true));
|
||||
node->set_is_syntax_error(create<AST::SyntaxError>(String::from_utf8("Expected a closing brace '}' to end an immediate expression"sv).release_value_but_fixme_should_propagate_errors(), true));
|
||||
else if (node->function_name().is_empty())
|
||||
node->set_is_syntax_error(create<AST::SyntaxError>("Expected an immediate function name"));
|
||||
node->set_is_syntax_error(create<AST::SyntaxError>(String::from_utf8("Expected an immediate function name"sv).release_value_but_fixme_should_propagate_errors()));
|
||||
|
||||
return node;
|
||||
}
|
||||
|
@ -1711,7 +1711,7 @@ RefPtr<AST::Node> Parser::parse_history_designator()
|
|||
consume();
|
||||
selector.event.kind = AST::HistorySelector::EventKind::IndexFromEnd;
|
||||
selector.event.index = 0;
|
||||
selector.event.text = "!";
|
||||
selector.event.text = String::from_utf8_short_string("!"sv);
|
||||
break;
|
||||
case '?':
|
||||
consume();
|
||||
|
@ -1728,22 +1728,23 @@ RefPtr<AST::Node> Parser::parse_history_designator()
|
|||
|
||||
selector.event.text = static_ptr_cast<AST::BarewordLiteral>(bareword)->text();
|
||||
selector.event.text_position = bareword->position();
|
||||
auto it = selector.event.text.begin();
|
||||
auto selector_bytes = selector.event.text.bytes();
|
||||
auto it = selector_bytes.begin();
|
||||
bool is_negative = false;
|
||||
if (*it == '-') {
|
||||
++it;
|
||||
is_negative = true;
|
||||
}
|
||||
if (it != selector.event.text.end() && all_of(it, selector.event.text.end(), is_digit)) {
|
||||
if (it != selector_bytes.end() && all_of(it, selector_bytes.end(), is_digit)) {
|
||||
if (is_negative)
|
||||
selector.event.kind = AST::HistorySelector::EventKind::IndexFromEnd;
|
||||
else
|
||||
selector.event.kind = AST::HistorySelector::EventKind::IndexFromStart;
|
||||
auto number = abs(selector.event.text.to_int().value_or(0));
|
||||
auto number = abs(selector.event.text.bytes_as_string_view().to_int().value_or(0));
|
||||
if (number != 0)
|
||||
selector.event.index = number - 1;
|
||||
else
|
||||
syntax_error = create<AST::SyntaxError>("History entry index value invalid or out of range");
|
||||
syntax_error = create<AST::SyntaxError>(String::from_utf8("History entry index value invalid or out of range"sv).release_value_but_fixme_should_propagate_errors());
|
||||
}
|
||||
if (":^$*"sv.contains(peek())) {
|
||||
is_word_selector = true;
|
||||
|
@ -1803,7 +1804,7 @@ RefPtr<AST::Node> Parser::parse_history_designator()
|
|||
auto first_char = peek();
|
||||
if (!(is_digit(first_char) || "^$-*"sv.contains(first_char))) {
|
||||
if (!syntax_error)
|
||||
syntax_error = create<AST::SyntaxError>("Expected a word selector after ':' in a history event designator", true);
|
||||
syntax_error = create<AST::SyntaxError>(String::from_utf8("Expected a word selector after ':' in a history event designator"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
} else if (first_char == '*') {
|
||||
consume();
|
||||
selector.word_selector_range.start = make_word_selector(AST::HistorySelector::WordSelectorKind::Index, 1);
|
||||
|
@ -1853,7 +1854,7 @@ RefPtr<AST::Node> Parser::parse_comment()
|
|||
|
||||
consume();
|
||||
auto text = consume_while(is_not('\n'));
|
||||
return create<AST::Comment>(move(text)); // Comment
|
||||
return create<AST::Comment>(String::from_utf8(text).release_value_but_fixme_should_propagate_errors()); // Comment
|
||||
}
|
||||
|
||||
RefPtr<AST::Node> Parser::parse_bareword()
|
||||
|
@ -1895,18 +1896,18 @@ RefPtr<AST::Node> Parser::parse_bareword()
|
|||
|
||||
auto current_end = m_offset;
|
||||
auto current_line = line();
|
||||
auto string = builder.to_deprecated_string();
|
||||
auto string = builder.to_string().release_value_but_fixme_should_propagate_errors();
|
||||
if (string.starts_with('~')) {
|
||||
DeprecatedString username;
|
||||
String username;
|
||||
RefPtr<AST::Node> tilde, text;
|
||||
|
||||
auto first_slash_index = string.find('/');
|
||||
auto first_slash_index = string.find_byte_offset('/');
|
||||
if (first_slash_index.has_value()) {
|
||||
username = string.substring_view(1, first_slash_index.value() - 1);
|
||||
string = string.substring_view(first_slash_index.value(), string.length() - first_slash_index.value());
|
||||
username = string.substring_from_byte_offset(1, *first_slash_index).release_value_but_fixme_should_propagate_errors();
|
||||
string = string.substring_from_byte_offset(*first_slash_index + 1).release_value_but_fixme_should_propagate_errors();
|
||||
} else {
|
||||
username = string.substring_view(1, string.length() - 1);
|
||||
string = "";
|
||||
username = string.substring_from_byte_offset(1).release_value_but_fixme_should_propagate_errors();
|
||||
string = {};
|
||||
}
|
||||
|
||||
// Synthesize a Tilde Node with the correct positioning information.
|
||||
|
@ -1914,7 +1915,7 @@ RefPtr<AST::Node> Parser::parse_bareword()
|
|||
restore_to(rule_start->offset, rule_start->line);
|
||||
auto ch = consume();
|
||||
VERIFY(ch == '~');
|
||||
auto username_length = username.length();
|
||||
auto username_length = username.bytes_as_string_view().length();
|
||||
tilde = create<AST::Tilde>(move(username));
|
||||
// Consume the username (if any)
|
||||
for (size_t i = 0; i < username_length; ++i)
|
||||
|
@ -1934,9 +1935,9 @@ RefPtr<AST::Node> Parser::parse_bareword()
|
|||
return create<AST::Juxtaposition>(tilde.release_nonnull(), text.release_nonnull()); // Juxtaposition Variable Bareword
|
||||
}
|
||||
|
||||
if (string.starts_with("\\~"sv)) {
|
||||
if (string.starts_with_bytes("\\~"sv)) {
|
||||
// Un-escape the tilde, but only at the start (where it would be an expansion)
|
||||
string = string.substring(1, string.length() - 1);
|
||||
string = string.substring_from_byte_offset(1).release_value_but_fixme_should_propagate_errors();
|
||||
}
|
||||
|
||||
return create<AST::BarewordLiteral>(move(string)); // Bareword Literal
|
||||
|
@ -1963,7 +1964,7 @@ RefPtr<AST::Node> Parser::parse_glob()
|
|||
} else {
|
||||
// FIXME: Allow composition of tilde+bareword with globs: '~/foo/bar/baz*'
|
||||
restore_to(saved_offset.offset, saved_offset.line);
|
||||
bareword_part->set_is_syntax_error(*create<AST::SyntaxError>(DeprecatedString::formatted("Unexpected {} inside a glob", bareword_part->class_name())));
|
||||
bareword_part->set_is_syntax_error(*create<AST::SyntaxError>(String::formatted("Unexpected {} inside a glob", bareword_part->class_name()).release_value_but_fixme_should_propagate_errors()));
|
||||
return bareword_part;
|
||||
}
|
||||
textbuilder.append(text);
|
||||
|
@ -1984,11 +1985,11 @@ RefPtr<AST::Node> Parser::parse_glob()
|
|||
textbuilder.append('~');
|
||||
textbuilder.append(bareword->text());
|
||||
} else {
|
||||
return create<AST::SyntaxError>(DeprecatedString::formatted("Invalid node '{}' in glob position, escape shell special characters", glob_after->class_name()));
|
||||
return create<AST::SyntaxError>(String::formatted("Invalid node '{}' in glob position, escape shell special characters", glob_after->class_name()).release_value_but_fixme_should_propagate_errors());
|
||||
}
|
||||
}
|
||||
|
||||
return create<AST::Glob>(textbuilder.to_deprecated_string()); // Glob
|
||||
return create<AST::Glob>(textbuilder.to_string().release_value_but_fixme_should_propagate_errors()); // Glob
|
||||
}
|
||||
|
||||
return bareword_part;
|
||||
|
@ -2003,7 +2004,7 @@ RefPtr<AST::Node> Parser::parse_brace_expansion()
|
|||
|
||||
if (auto spec = parse_brace_expansion_spec()) {
|
||||
if (!expect('}'))
|
||||
spec->set_is_syntax_error(create<AST::SyntaxError>("Expected a close brace '}' to end a brace expansion", true));
|
||||
spec->set_is_syntax_error(create<AST::SyntaxError>(String::from_utf8("Expected a close brace '}' to end a brace expansion"sv).release_value_but_fixme_should_propagate_errors(), true));
|
||||
|
||||
return spec;
|
||||
}
|
||||
|
@ -2024,19 +2025,19 @@ RefPtr<AST::Node> Parser::parse_brace_expansion_spec()
|
|||
|
||||
if (next_is(","sv)) {
|
||||
// Note that we don't consume the ',' here.
|
||||
subexpressions.append(create<AST::StringLiteral>("", AST::StringLiteral::EnclosureType::None));
|
||||
subexpressions.append(create<AST::StringLiteral>(String {}, AST::StringLiteral::EnclosureType::None));
|
||||
} else {
|
||||
auto start_expr = parse_expression();
|
||||
if (start_expr) {
|
||||
if (expect(".."sv)) {
|
||||
if (auto end_expr = parse_expression()) {
|
||||
if (end_expr->position().start_offset != start_expr->position().end_offset + 2)
|
||||
end_expr->set_is_syntax_error(create<AST::SyntaxError>("Expected no whitespace between '..' and the following expression in brace expansion"));
|
||||
end_expr->set_is_syntax_error(create<AST::SyntaxError>(String::from_utf8("Expected no whitespace between '..' and the following expression in brace expansion"sv).release_value_but_fixme_should_propagate_errors()));
|
||||
|
||||
return create<AST::Range>(start_expr.release_nonnull(), end_expr.release_nonnull());
|
||||
}
|
||||
|
||||
return create<AST::Range>(start_expr.release_nonnull(), create<AST::SyntaxError>("Expected an expression to end range brace expansion with", true));
|
||||
return create<AST::Range>(start_expr.release_nonnull(), create<AST::SyntaxError>(String::from_utf8("Expected an expression to end range brace expansion with"sv).release_value_but_fixme_should_propagate_errors(), true));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2049,7 +2050,7 @@ RefPtr<AST::Node> Parser::parse_brace_expansion_spec()
|
|||
if (expr) {
|
||||
subexpressions.append(expr.release_nonnull());
|
||||
} else {
|
||||
subexpressions.append(create<AST::StringLiteral>("", AST::StringLiteral::EnclosureType::None));
|
||||
subexpressions.append(create<AST::StringLiteral>(String {}, AST::StringLiteral::EnclosureType::None));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2071,7 +2072,7 @@ RefPtr<AST::Node> Parser::parse_heredoc_initiation_record()
|
|||
consume();
|
||||
|
||||
HeredocInitiationRecord record;
|
||||
record.end = "<error>";
|
||||
record.end = String::from_utf8("<error>"sv).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
RefPtr<AST::SyntaxError> syntax_error_node;
|
||||
|
||||
|
@ -2093,7 +2094,7 @@ RefPtr<AST::Node> Parser::parse_heredoc_initiation_record()
|
|||
// StringLiteral | bareword
|
||||
if (auto bareword = parse_bareword()) {
|
||||
if (!bareword->is_bareword()) {
|
||||
syntax_error_node = create<AST::SyntaxError>(DeprecatedString::formatted("Expected a bareword or a quoted string, not {}", bareword->class_name()));
|
||||
syntax_error_node = create<AST::SyntaxError>(String::formatted("Expected a bareword or a quoted string, not {}", bareword->class_name()).release_value_but_fixme_should_propagate_errors());
|
||||
} else {
|
||||
if (bareword->is_syntax_error())
|
||||
syntax_error_node = bareword->syntax_error_node();
|
||||
|
@ -2109,19 +2110,19 @@ RefPtr<AST::Node> Parser::parse_heredoc_initiation_record()
|
|||
if (!expect('\''))
|
||||
is_error = true;
|
||||
if (is_error)
|
||||
syntax_error_node = create<AST::SyntaxError>("Expected a terminating single quote", true);
|
||||
syntax_error_node = create<AST::SyntaxError>(String::from_utf8("Expected a terminating single quote"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
|
||||
record.end = text;
|
||||
record.end = String::from_utf8(text).release_value_but_fixme_should_propagate_errors();
|
||||
record.interpolate = false;
|
||||
} else {
|
||||
syntax_error_node = create<AST::SyntaxError>("Expected a bareword or a single-quoted string literal for heredoc end key", true);
|
||||
syntax_error_node = create<AST::SyntaxError>(String::from_utf8("Expected a bareword or a single-quoted string literal for heredoc end key"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
}
|
||||
|
||||
auto node = create<AST::Heredoc>(record.end, record.interpolate, record.deindent);
|
||||
if (syntax_error_node)
|
||||
node->set_is_syntax_error(*syntax_error_node);
|
||||
else
|
||||
node->set_is_syntax_error(*create<AST::SyntaxError>(DeprecatedString::formatted("Expected heredoc contents for heredoc with end key '{}'", node->end()), true));
|
||||
node->set_is_syntax_error(*create<AST::SyntaxError>(String::formatted("Expected heredoc contents for heredoc with end key '{}'", node->end()).release_value_but_fixme_should_propagate_errors(), true));
|
||||
|
||||
record.node = node;
|
||||
m_heredoc_initiations.append(move(record));
|
||||
|
@ -2137,7 +2138,7 @@ bool Parser::parse_heredoc_entries()
|
|||
for (auto& record : heredocs) {
|
||||
auto rule_start = push_start();
|
||||
if (m_rule_start_offsets.size() > max_allowed_nested_rule_depth) {
|
||||
record.node->set_is_syntax_error(*create<AST::SyntaxError>(DeprecatedString::formatted("Expression nested too deep (max allowed is {})", max_allowed_nested_rule_depth)));
|
||||
record.node->set_is_syntax_error(*create<AST::SyntaxError>(String::formatted("Expression nested too deep (max allowed is {})", max_allowed_nested_rule_depth).release_value_but_fixme_should_propagate_errors()));
|
||||
continue;
|
||||
}
|
||||
bool found_key = false;
|
||||
|
@ -2162,9 +2163,11 @@ bool Parser::parse_heredoc_entries()
|
|||
if (!last_line_offset.has_value())
|
||||
last_line_offset = current_position();
|
||||
// Now just wrap it in a StringLiteral and set it as the node's contents
|
||||
auto node = create<AST::StringLiteral>(m_input.substring_view(rule_start->offset, last_line_offset->offset - rule_start->offset), AST::StringLiteral::EnclosureType::None);
|
||||
auto node = create<AST::StringLiteral>(
|
||||
String::from_utf8(m_input.substring_view(rule_start->offset, last_line_offset->offset - rule_start->offset)).release_value_but_fixme_should_propagate_errors(),
|
||||
AST::StringLiteral::EnclosureType::None);
|
||||
if (!found_key)
|
||||
node->set_is_syntax_error(*create<AST::SyntaxError>(DeprecatedString::formatted("Expected to find the heredoc key '{}', but found Eof", record.end), true));
|
||||
node->set_is_syntax_error(*create<AST::SyntaxError>(String::formatted("Expected to find the heredoc key '{}', but found Eof", record.end).release_value_but_fixme_should_propagate_errors(), true));
|
||||
record.node->set_contents(move(node));
|
||||
} else {
|
||||
// Interpolation is allowed, so we're going to read doublequoted string innards
|
||||
|
@ -2211,11 +2214,11 @@ bool Parser::parse_heredoc_entries()
|
|||
}
|
||||
|
||||
if (!expr && found_key) {
|
||||
expr = create<AST::StringLiteral>("", AST::StringLiteral::EnclosureType::None);
|
||||
expr = create<AST::StringLiteral>(String {}, AST::StringLiteral::EnclosureType::None);
|
||||
} else if (!expr) {
|
||||
expr = create<AST::SyntaxError>(DeprecatedString::formatted("Expected to find a valid string inside a heredoc (with end key '{}')", record.end), true);
|
||||
expr = create<AST::SyntaxError>(String::formatted("Expected to find a valid string inside a heredoc (with end key '{}')", record.end).release_value_but_fixme_should_propagate_errors(), true);
|
||||
} else if (!found_key) {
|
||||
expr->set_is_syntax_error(*create<AST::SyntaxError>(DeprecatedString::formatted("Expected to find the heredoc key '{}'", record.end), true));
|
||||
expr->set_is_syntax_error(*create<AST::SyntaxError>(String::formatted("Expected to find the heredoc key '{}'", record.end).release_value_but_fixme_should_propagate_errors(), true));
|
||||
}
|
||||
|
||||
record.node->set_contents(create<AST::DoubleQuotedString>(move(expr)));
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
#pragma once
|
||||
|
||||
#include "AST.h"
|
||||
#include <AK/DeprecatedString.h>
|
||||
#include <AK/Function.h>
|
||||
#include <AK/RefPtr.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <AK/Vector.h>
|
||||
|
||||
|
@ -53,7 +53,7 @@ private:
|
|||
};
|
||||
|
||||
struct HeredocInitiationRecord {
|
||||
DeprecatedString end;
|
||||
String end;
|
||||
RefPtr<AST::Heredoc> node;
|
||||
bool interpolate { false };
|
||||
bool deindent { false };
|
||||
|
|
|
@ -149,7 +149,7 @@ void Parser::handle_heredoc_contents()
|
|||
Parser parser { token.value, m_in_interactive_mode, Reduction::HeredocContents };
|
||||
contents = parser.parse_word();
|
||||
} else {
|
||||
contents = make_ref_counted<AST::StringLiteral>(token.position.value_or(empty_position()), token.value, AST::StringLiteral::EnclosureType::None);
|
||||
contents = make_ref_counted<AST::StringLiteral>(token.position.value_or(empty_position()), String::from_utf8(token.value).release_value_but_fixme_should_propagate_errors(), AST::StringLiteral::EnclosureType::None);
|
||||
}
|
||||
|
||||
if (contents)
|
||||
|
@ -643,7 +643,7 @@ RefPtr<AST::Node> Parser::parse_complete_command()
|
|||
auto position = peek().position;
|
||||
auto syntax_error = make_ref_counted<AST::SyntaxError>(
|
||||
position.value_or(empty_position()),
|
||||
"Extra tokens after complete command"sv);
|
||||
String::from_utf8("Extra tokens after complete command"sv).release_value_but_fixme_should_propagate_errors());
|
||||
|
||||
if (list)
|
||||
list->set_is_syntax_error(*syntax_error);
|
||||
|
@ -837,7 +837,7 @@ RefPtr<AST::Node> Parser::parse_function_definition()
|
|||
|
||||
return make_ref_counted<AST::FunctionDeclaration>(
|
||||
name.position.value_or(empty_position()).with_end(peek().position.value_or(empty_position())),
|
||||
AST::NameWithPosition { name.value, name.position.value_or(empty_position()) },
|
||||
AST::NameWithPosition { String::from_utf8(name.value).release_value_but_fixme_should_propagate_errors(), name.position.value_or(empty_position()) },
|
||||
Vector<AST::NameWithPosition> {},
|
||||
body.release_nonnull());
|
||||
}
|
||||
|
@ -921,13 +921,13 @@ RefPtr<AST::Node> Parser::parse_while_clause()
|
|||
if (!condition)
|
||||
condition = make_ref_counted<AST::SyntaxError>(
|
||||
peek().position.value_or(empty_position()),
|
||||
"Expected condition after 'while'"sv);
|
||||
String::from_utf8("Expected condition after 'while'"sv).release_value_but_fixme_should_propagate_errors());
|
||||
|
||||
auto do_group = parse_do_group();
|
||||
if (!do_group)
|
||||
do_group = make_ref_counted<AST::SyntaxError>(
|
||||
peek().position.value_or(empty_position()),
|
||||
"Expected 'do' after 'while'"sv);
|
||||
String::from_utf8("Expected 'do' after 'while'"sv).release_value_but_fixme_should_propagate_errors());
|
||||
|
||||
// while foo; bar -> loop { if foo { bar } else { break } }
|
||||
return make_ref_counted<AST::ForLoop>(
|
||||
|
@ -955,13 +955,13 @@ RefPtr<AST::Node> Parser::parse_until_clause()
|
|||
if (!condition)
|
||||
condition = make_ref_counted<AST::SyntaxError>(
|
||||
peek().position.value_or(empty_position()),
|
||||
"Expected condition after 'until'"sv);
|
||||
String::from_utf8("Expected condition after 'until'"sv).release_value_but_fixme_should_propagate_errors());
|
||||
|
||||
auto do_group = parse_do_group();
|
||||
if (!do_group)
|
||||
do_group = make_ref_counted<AST::SyntaxError>(
|
||||
peek().position.value_or(empty_position()),
|
||||
"Expected 'do' after 'until'"sv);
|
||||
String::from_utf8("Expected 'do' after 'until'"sv).release_value_but_fixme_should_propagate_errors());
|
||||
|
||||
// until foo; bar -> loop { if foo { break } else { bar } }
|
||||
return make_ref_counted<AST::ForLoop>(
|
||||
|
@ -992,7 +992,7 @@ RefPtr<AST::Node> Parser::parse_brace_group()
|
|||
if (peek().type != Token::Type::CloseBrace) {
|
||||
error = make_ref_counted<AST::SyntaxError>(
|
||||
peek().position.value_or(empty_position()),
|
||||
DeprecatedString::formatted("Expected '}}', not {}", peek().type_name()));
|
||||
String::formatted("Expected '}}', not {}", peek().type_name()).release_value_but_fixme_should_propagate_errors());
|
||||
} else {
|
||||
consume();
|
||||
}
|
||||
|
@ -1020,12 +1020,12 @@ RefPtr<AST::Node> Parser::parse_case_clause()
|
|||
if (!expr)
|
||||
expr = make_ref_counted<AST::SyntaxError>(
|
||||
peek().position.value_or(empty_position()),
|
||||
DeprecatedString::formatted("Expected a word, not {}", peek().type_name()));
|
||||
String::formatted("Expected a word, not {}", peek().type_name()).release_value_but_fixme_should_propagate_errors());
|
||||
|
||||
if (peek().type != Token::Type::In) {
|
||||
syntax_error = make_ref_counted<AST::SyntaxError>(
|
||||
peek().position.value_or(empty_position()),
|
||||
DeprecatedString::formatted("Expected 'in', not {}", peek().type_name()));
|
||||
String::formatted("Expected 'in', not {}", peek().type_name()).release_value_but_fixme_should_propagate_errors());
|
||||
} else {
|
||||
skip();
|
||||
}
|
||||
|
@ -1059,7 +1059,7 @@ RefPtr<AST::Node> Parser::parse_case_clause()
|
|||
if (!syntax_error)
|
||||
syntax_error = make_ref_counted<AST::SyntaxError>(
|
||||
peek().position.value_or(empty_position()),
|
||||
DeprecatedString::formatted("Expected ')', not {}", peek().type_name()));
|
||||
String::formatted("Expected ')', not {}", peek().type_name()).release_value_but_fixme_should_propagate_errors());
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1074,7 +1074,7 @@ RefPtr<AST::Node> Parser::parse_case_clause()
|
|||
if (!syntax_error)
|
||||
syntax_error = make_ref_counted<AST::SyntaxError>(
|
||||
peek().position.value_or(empty_position()),
|
||||
DeprecatedString::formatted("Expected ';;', not {}", peek().type_name()));
|
||||
String::formatted("Expected ';;', not {}", peek().type_name()).release_value_but_fixme_should_propagate_errors());
|
||||
}
|
||||
|
||||
if (syntax_error) {
|
||||
|
@ -1097,7 +1097,7 @@ RefPtr<AST::Node> Parser::parse_case_clause()
|
|||
if (peek().type != Token::Type::Esac) {
|
||||
syntax_error = make_ref_counted<AST::SyntaxError>(
|
||||
peek().position.value_or(empty_position()),
|
||||
DeprecatedString::formatted("Expected 'esac', not {}", peek().type_name()));
|
||||
String::formatted("Expected 'esac', not {}", peek().type_name()).release_value_but_fixme_should_propagate_errors());
|
||||
} else {
|
||||
skip();
|
||||
}
|
||||
|
@ -1105,7 +1105,7 @@ RefPtr<AST::Node> Parser::parse_case_clause()
|
|||
auto node = make_ref_counted<AST::MatchExpr>(
|
||||
start_position.with_end(peek().position.value_or(empty_position())),
|
||||
expr.release_nonnull(),
|
||||
DeprecatedString {},
|
||||
String {},
|
||||
Optional<AST::Position> {},
|
||||
move(entries));
|
||||
|
||||
|
@ -1132,7 +1132,7 @@ Parser::CaseItemsResult Parser::parse_case_list()
|
|||
if (!node)
|
||||
node = make_ref_counted<AST::SyntaxError>(
|
||||
peek().position.value_or(empty_position()),
|
||||
DeprecatedString::formatted("Expected a word, not {}", peek().type_name()));
|
||||
String::formatted("Expected a word, not {}", peek().type_name()).release_value_but_fixme_should_propagate_errors());
|
||||
|
||||
nodes.append(node.release_nonnull());
|
||||
|
||||
|
@ -1147,7 +1147,7 @@ Parser::CaseItemsResult Parser::parse_case_list()
|
|||
if (nodes.is_empty())
|
||||
nodes.append(make_ref_counted<AST::SyntaxError>(
|
||||
peek().position.value_or(empty_position()),
|
||||
DeprecatedString::formatted("Expected a word, not {}", peek().type_name())));
|
||||
String::formatted("Expected a word, not {}", peek().type_name()).release_value_but_fixme_should_propagate_errors()));
|
||||
|
||||
return { move(pipes), move(nodes) };
|
||||
}
|
||||
|
@ -1162,20 +1162,20 @@ RefPtr<AST::Node> Parser::parse_if_clause()
|
|||
skip();
|
||||
auto main_condition = parse_compound_list();
|
||||
if (!main_condition)
|
||||
main_condition = make_ref_counted<AST::SyntaxError>(empty_position(), "Expected compound list after 'if'");
|
||||
main_condition = make_ref_counted<AST::SyntaxError>(empty_position(), String::from_utf8("Expected compound list after 'if'"sv).release_value_but_fixme_should_propagate_errors());
|
||||
|
||||
RefPtr<AST::SyntaxError> syntax_error;
|
||||
if (peek().type != Token::Type::Then) {
|
||||
syntax_error = make_ref_counted<AST::SyntaxError>(
|
||||
peek().position.value_or(empty_position()),
|
||||
DeprecatedString::formatted("Expected 'then', not {}", peek().type_name()));
|
||||
String::formatted("Expected 'then', not {}", peek().type_name()).release_value_but_fixme_should_propagate_errors());
|
||||
} else {
|
||||
skip();
|
||||
}
|
||||
|
||||
auto main_consequence = parse_compound_list();
|
||||
if (!main_consequence)
|
||||
main_consequence = make_ref_counted<AST::SyntaxError>(empty_position(), "Expected compound list after 'then'");
|
||||
main_consequence = make_ref_counted<AST::SyntaxError>(empty_position(), String::from_utf8("Expected compound list after 'then'"sv).release_value_but_fixme_should_propagate_errors());
|
||||
|
||||
auto node = make_ref_counted<AST::IfCond>(start_position, Optional<AST::Position>(), main_condition.release_nonnull(), main_consequence.release_nonnull(), nullptr);
|
||||
auto active_node = node;
|
||||
|
@ -1184,20 +1184,20 @@ RefPtr<AST::Node> Parser::parse_if_clause()
|
|||
skip();
|
||||
auto condition = parse_compound_list();
|
||||
if (!condition)
|
||||
condition = make_ref_counted<AST::SyntaxError>(empty_position(), "Expected compound list after 'elif'");
|
||||
condition = make_ref_counted<AST::SyntaxError>(empty_position(), String::from_utf8("Expected compound list after 'elif'"sv).release_value_but_fixme_should_propagate_errors());
|
||||
|
||||
if (peek().type != Token::Type::Then) {
|
||||
if (!syntax_error)
|
||||
syntax_error = make_ref_counted<AST::SyntaxError>(
|
||||
peek().position.value_or(empty_position()),
|
||||
DeprecatedString::formatted("Expected 'then', not {}", peek().type_name()));
|
||||
String::formatted("Expected 'then', not {}", peek().type_name()).release_value_but_fixme_should_propagate_errors());
|
||||
} else {
|
||||
skip();
|
||||
}
|
||||
|
||||
auto consequence = parse_compound_list();
|
||||
if (!consequence)
|
||||
consequence = make_ref_counted<AST::SyntaxError>(empty_position(), "Expected compound list after 'then'");
|
||||
consequence = make_ref_counted<AST::SyntaxError>(empty_position(), String::from_utf8("Expected compound list after 'then'"sv).release_value_but_fixme_should_propagate_errors());
|
||||
|
||||
auto new_node = make_ref_counted<AST::IfCond>(start_position, Optional<AST::Position>(), condition.release_nonnull(), consequence.release_nonnull(), nullptr);
|
||||
|
||||
|
@ -1211,7 +1211,7 @@ RefPtr<AST::Node> Parser::parse_if_clause()
|
|||
skip();
|
||||
active_node->false_branch() = parse_compound_list();
|
||||
if (!active_node->false_branch())
|
||||
active_node->false_branch() = make_ref_counted<AST::SyntaxError>(empty_position(), "Expected compound list after 'else'");
|
||||
active_node->false_branch() = make_ref_counted<AST::SyntaxError>(empty_position(), String::from_utf8("Expected compound list after 'else'"sv).release_value_but_fixme_should_propagate_errors());
|
||||
break;
|
||||
case Token::Type::Fi:
|
||||
needs_fi = false;
|
||||
|
@ -1220,7 +1220,7 @@ RefPtr<AST::Node> Parser::parse_if_clause()
|
|||
if (!syntax_error)
|
||||
syntax_error = make_ref_counted<AST::SyntaxError>(
|
||||
peek().position.value_or(empty_position()),
|
||||
DeprecatedString::formatted("Expected 'else' or 'fi', not {}", peek().type_name()));
|
||||
String::formatted("Expected 'else' or 'fi', not {}", peek().type_name()).release_value_but_fixme_should_propagate_errors());
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1229,7 +1229,7 @@ RefPtr<AST::Node> Parser::parse_if_clause()
|
|||
if (!syntax_error)
|
||||
syntax_error = make_ref_counted<AST::SyntaxError>(
|
||||
peek().position.value_or(empty_position()),
|
||||
DeprecatedString::formatted("Expected 'fi', not {}", peek().type_name()));
|
||||
String::formatted("Expected 'fi', not {}", peek().type_name()).release_value_but_fixme_should_propagate_errors());
|
||||
} else {
|
||||
skip();
|
||||
}
|
||||
|
@ -1252,10 +1252,10 @@ RefPtr<AST::Node> Parser::parse_subshell()
|
|||
|
||||
auto list = parse_compound_list();
|
||||
if (!list)
|
||||
error = make_ref_counted<AST::SyntaxError>(peek().position.value_or(empty_position()), "Expected compound list after ("sv);
|
||||
error = make_ref_counted<AST::SyntaxError>(peek().position.value_or(empty_position()), String::from_utf8("Expected compound list after ("sv).release_value_but_fixme_should_propagate_errors());
|
||||
|
||||
if (peek().type != Token::Type::CloseParen)
|
||||
error = make_ref_counted<AST::SyntaxError>(peek().position.value_or(empty_position()), "Expected ) after compound list"sv);
|
||||
error = make_ref_counted<AST::SyntaxError>(peek().position.value_or(empty_position()), String::from_utf8("Expected ) after compound list"sv).release_value_but_fixme_should_propagate_errors());
|
||||
else
|
||||
skip();
|
||||
|
||||
|
@ -1369,7 +1369,7 @@ RefPtr<AST::Node> Parser::parse_for_clause()
|
|||
auto body = parse_do_group();
|
||||
return AST::make_ref_counted<AST::ForLoop>(
|
||||
start_position.with_end(peek().position.value_or(empty_position())),
|
||||
AST::NameWithPosition { move(name), name_position.value_or(empty_position()) },
|
||||
AST::NameWithPosition { String::from_deprecated_string(name).release_value_but_fixme_should_propagate_errors(), name_position.value_or(empty_position()) },
|
||||
Optional<AST::NameWithPosition> {},
|
||||
move(iterated_expression),
|
||||
move(body),
|
||||
|
@ -1414,13 +1414,13 @@ RefPtr<AST::Node> Parser::parse_word()
|
|||
auto user = lexer.consume_while(is_ascii_alphanumeric);
|
||||
string = lexer.remaining();
|
||||
|
||||
word = make_ref_counted<AST::Tilde>(token.position.value_or(empty_position()), user);
|
||||
word = make_ref_counted<AST::Tilde>(token.position.value_or(empty_position()), String::from_utf8(user).release_value_but_fixme_should_propagate_errors());
|
||||
}
|
||||
|
||||
if (string.is_empty())
|
||||
return;
|
||||
|
||||
auto node = make_ref_counted<AST::BarewordLiteral>(token.position.value_or(empty_position()), string);
|
||||
auto node = make_ref_counted<AST::BarewordLiteral>(token.position.value_or(empty_position()), String::from_utf8(string).release_value_but_fixme_should_propagate_errors());
|
||||
|
||||
if (word) {
|
||||
word = make_ref_counted<AST::Juxtaposition>(
|
||||
|
@ -1437,7 +1437,7 @@ RefPtr<AST::Node> Parser::parse_word()
|
|||
if (string.is_empty())
|
||||
return;
|
||||
|
||||
auto node = make_ref_counted<AST::StringLiteral>(token.position.value_or(empty_position()), string, AST::StringLiteral::EnclosureType::SingleQuotes);
|
||||
auto node = make_ref_counted<AST::StringLiteral>(token.position.value_or(empty_position()), String::from_utf8(string).release_value_but_fixme_should_propagate_errors(), AST::StringLiteral::EnclosureType::SingleQuotes);
|
||||
|
||||
if (word) {
|
||||
word = make_ref_counted<AST::Juxtaposition>(
|
||||
|
@ -1454,7 +1454,7 @@ RefPtr<AST::Node> Parser::parse_word()
|
|||
if (string.is_empty())
|
||||
return;
|
||||
|
||||
auto node = make_ref_counted<AST::StringLiteral>(token.position.value_or(empty_position()), string, AST::StringLiteral::EnclosureType::DoubleQuotes);
|
||||
auto node = make_ref_counted<AST::StringLiteral>(token.position.value_or(empty_position()), String::from_utf8(string).release_value_but_fixme_should_propagate_errors(), AST::StringLiteral::EnclosureType::DoubleQuotes);
|
||||
|
||||
if (word) {
|
||||
word = make_ref_counted<AST::Juxtaposition>(
|
||||
|
@ -1512,12 +1512,12 @@ RefPtr<AST::Node> Parser::parse_word()
|
|||
case ResolvedParameterExpansion::Op::GetVariable:
|
||||
node = make_ref_counted<AST::SimpleVariable>(
|
||||
token.position.value_or(empty_position()),
|
||||
x.parameter);
|
||||
String::from_deprecated_string(x.parameter).release_value_but_fixme_should_propagate_errors());
|
||||
break;
|
||||
case ResolvedParameterExpansion::Op::GetLastBackgroundPid:
|
||||
node = make_ref_counted<AST::SyntaxError>(
|
||||
token.position.value_or(empty_position()),
|
||||
"$! not implemented");
|
||||
String::from_utf8("$! not implemented"sv).release_value_but_fixme_should_propagate_errors());
|
||||
break;
|
||||
case ResolvedParameterExpansion::Op::GetPositionalParameterList:
|
||||
node = make_ref_counted<AST::SpecialVariable>(
|
||||
|
@ -1527,7 +1527,7 @@ RefPtr<AST::Node> Parser::parse_word()
|
|||
case ResolvedParameterExpansion::Op::GetCurrentOptionFlags:
|
||||
node = make_ref_counted<AST::SyntaxError>(
|
||||
token.position.value_or(empty_position()),
|
||||
"The current option flags are not available in parameter expansions");
|
||||
String::from_utf8("The current option flags are not available in parameter expansions"sv).release_value_but_fixme_should_propagate_errors());
|
||||
break;
|
||||
case ResolvedParameterExpansion::Op::GetPositionalParameterCount:
|
||||
node = make_ref_counted<AST::SpecialVariable>(
|
||||
|
@ -1542,7 +1542,7 @@ RefPtr<AST::Node> Parser::parse_word()
|
|||
case ResolvedParameterExpansion::Op::GetPositionalParameterListAsString:
|
||||
node = make_ref_counted<AST::SyntaxError>(
|
||||
token.position.value_or(empty_position()),
|
||||
"$* not implemented");
|
||||
String::from_utf8("$* not implemented"sv).release_value_but_fixme_should_propagate_errors());
|
||||
break;
|
||||
case ResolvedParameterExpansion::Op::GetShellProcessId:
|
||||
node = make_ref_counted<AST::SpecialVariable>(
|
||||
|
@ -1555,7 +1555,7 @@ RefPtr<AST::Node> Parser::parse_word()
|
|||
NonnullRefPtrVector<AST::Node> arguments;
|
||||
arguments.append(make_ref_counted<AST::BarewordLiteral>(
|
||||
token.position.value_or(empty_position()),
|
||||
x.parameter));
|
||||
String::from_deprecated_string(x.parameter).release_value_but_fixme_should_propagate_errors()));
|
||||
|
||||
if (!x.argument.is_empty()) {
|
||||
// dbgln("Will parse {}", x.argument);
|
||||
|
@ -1565,7 +1565,7 @@ RefPtr<AST::Node> Parser::parse_word()
|
|||
node = make_ref_counted<AST::ImmediateExpression>(
|
||||
token.position.value_or(empty_position()),
|
||||
AST::NameWithPosition {
|
||||
immediate_function_name,
|
||||
String::from_deprecated_string(immediate_function_name).release_value_but_fixme_should_propagate_errors(),
|
||||
token.position.value_or(empty_position()),
|
||||
},
|
||||
move(arguments),
|
||||
|
@ -1576,7 +1576,7 @@ RefPtr<AST::Node> Parser::parse_word()
|
|||
node = make_ref_counted<AST::ImmediateExpression>(
|
||||
token.position.value_or(empty_position()),
|
||||
AST::NameWithPosition {
|
||||
"reexpand",
|
||||
String::from_utf8("reexpand"sv).release_value_but_fixme_should_propagate_errors(),
|
||||
token.position.value_or(empty_position()),
|
||||
},
|
||||
Vector { node.release_nonnull() },
|
||||
|
@ -1732,7 +1732,7 @@ RefPtr<AST::Node> Parser::parse_do_group()
|
|||
if (peek().type != Token::Type::Do) {
|
||||
return make_ref_counted<AST::SyntaxError>(
|
||||
peek().position.value_or(empty_position()),
|
||||
DeprecatedString::formatted("Expected 'do', not {}", peek().type_name()));
|
||||
String::formatted("Expected 'do', not {}", peek().type_name()).release_value_but_fixme_should_propagate_errors());
|
||||
}
|
||||
|
||||
consume();
|
||||
|
@ -1743,7 +1743,7 @@ RefPtr<AST::Node> Parser::parse_do_group()
|
|||
if (peek().type != Token::Type::Done) {
|
||||
error = make_ref_counted<AST::SyntaxError>(
|
||||
peek().position.value_or(empty_position()),
|
||||
DeprecatedString::formatted("Expected 'done', not {}", peek().type_name()));
|
||||
String::formatted("Expected 'done', not {}", peek().type_name()).release_value_but_fixme_should_propagate_errors());
|
||||
} else {
|
||||
consume();
|
||||
}
|
||||
|
@ -1779,17 +1779,17 @@ RefPtr<AST::Node> Parser::parse_simple_command()
|
|||
nodes.append(
|
||||
make_ref_counted<AST::BarewordLiteral>(
|
||||
peek().position.value_or(empty_position()),
|
||||
consume().value));
|
||||
String::from_deprecated_string(consume().value).release_value_but_fixme_should_propagate_errors()));
|
||||
} else {
|
||||
// env (assignments) (command)
|
||||
nodes.append(make_ref_counted<AST::BarewordLiteral>(
|
||||
empty_position(),
|
||||
"env"));
|
||||
String::from_utf8_short_string("env"sv)));
|
||||
|
||||
nodes.append(
|
||||
make_ref_counted<AST::BarewordLiteral>(
|
||||
peek().position.value_or(empty_position()),
|
||||
consume().value));
|
||||
String::from_deprecated_string(consume().value).release_value_but_fixme_should_propagate_errors()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1804,10 +1804,10 @@ RefPtr<AST::Node> Parser::parse_simple_command()
|
|||
auto parts = definition.split_limit('=', 2, SplitBehavior::KeepEmpty);
|
||||
auto name = make_ref_counted<AST::BarewordLiteral>(
|
||||
empty_position(),
|
||||
parts[0]);
|
||||
String::from_deprecated_string(parts[0]).release_value_but_fixme_should_propagate_errors());
|
||||
auto value = make_ref_counted<AST::BarewordLiteral>(
|
||||
empty_position(),
|
||||
parts.size() > 1 ? parts[1] : "");
|
||||
String::from_deprecated_string(parts.size() > 1 ? parts[1] : "").release_value_but_fixme_should_propagate_errors());
|
||||
|
||||
variables.append({ move(name), move(value) });
|
||||
}
|
||||
|
@ -1885,7 +1885,7 @@ RefPtr<AST::Node> Parser::parse_io_here(AST::Position start_position, Optional<i
|
|||
|
||||
auto end_keyword = consume();
|
||||
if (!is_one_of(end_keyword.type, Token::Type::Word, Token::Type::Token))
|
||||
return make_ref_counted<AST::SyntaxError>(io_operator_token.position.value_or(start_position), "Expected a heredoc keyword", true);
|
||||
return make_ref_counted<AST::SyntaxError>(io_operator_token.position.value_or(start_position), String::from_utf8("Expected a heredoc keyword"sv).release_value_but_fixme_should_propagate_errors(), true);
|
||||
|
||||
auto [end_keyword_text, allow_interpolation] = Lexer::process_heredoc_key(end_keyword);
|
||||
RefPtr<AST::SyntaxError> error;
|
||||
|
@ -1893,7 +1893,7 @@ RefPtr<AST::Node> Parser::parse_io_here(AST::Position start_position, Optional<i
|
|||
auto position = start_position.with_end(peek().position.value_or(empty_position()));
|
||||
auto result = make_ref_counted<AST::Heredoc>(
|
||||
position,
|
||||
end_keyword_text,
|
||||
String::from_deprecated_string(end_keyword_text).release_value_but_fixme_should_propagate_errors(),
|
||||
allow_interpolation,
|
||||
io_operator == Token::Type::DoubleLessDash,
|
||||
Optional<int> { redirection_fd });
|
||||
|
@ -1954,7 +1954,7 @@ RefPtr<AST::Node> Parser::parse_io_file(AST::Position start_position, Optional<i
|
|||
auto is_less = io_operator == Token::Type::LessAnd;
|
||||
auto source_fd = fd.value_or(is_less ? 0 : 1);
|
||||
if (word->is_bareword()) {
|
||||
auto maybe_target_fd = static_ptr_cast<AST::BarewordLiteral>(word)->text().to_int(AK::TrimWhitespace::No);
|
||||
auto maybe_target_fd = static_ptr_cast<AST::BarewordLiteral>(word)->text().bytes_as_string_view().to_int();
|
||||
if (maybe_target_fd.has_value()) {
|
||||
auto target_fd = maybe_target_fd.release_value();
|
||||
if (is_less)
|
||||
|
|
|
@ -309,7 +309,7 @@ Vector<AST::Command> Shell::expand_aliases(Vector<AST::Command> initial_commands
|
|||
subcommand_nonnull,
|
||||
adopt_ref(*new AST::CommandLiteral(subcommand_nonnull->position(), command))));
|
||||
auto res = substitute->run(*this);
|
||||
for (auto& subst_command : res->resolve_as_commands(*this)) {
|
||||
for (auto& subst_command : res->resolve_as_commands(*this).release_value_but_fixme_should_propagate_errors()) {
|
||||
if (!subst_command.argv.is_empty() && subst_command.argv.first() == argv0) // Disallow an alias resolving to itself.
|
||||
commands.append(subst_command);
|
||||
else
|
||||
|
@ -364,7 +364,7 @@ RefPtr<AST::Value const> Shell::lookup_local_variable(StringView name) const
|
|||
RefPtr<AST::Value const> Shell::get_argument(size_t index) const
|
||||
{
|
||||
if (index == 0)
|
||||
return adopt_ref(*new AST::StringValue(current_script));
|
||||
return adopt_ref(*new AST::StringValue(String::from_deprecated_string(current_script).release_value_but_fixme_should_propagate_errors()));
|
||||
|
||||
--index;
|
||||
if (auto argv = lookup_local_variable("ARGV"sv)) {
|
||||
|
@ -390,7 +390,7 @@ DeprecatedString Shell::local_variable_or(StringView name, DeprecatedString cons
|
|||
auto value = lookup_local_variable(name);
|
||||
if (value) {
|
||||
StringBuilder builder;
|
||||
builder.join(' ', const_cast<AST::Value&>(*value).resolve_as_list(const_cast<Shell&>(*this)));
|
||||
builder.join(' ', const_cast<AST::Value&>(*value).resolve_as_list(const_cast<Shell&>(*this)).release_value_but_fixme_should_propagate_errors());
|
||||
return builder.to_deprecated_string();
|
||||
}
|
||||
return replacement;
|
||||
|
@ -594,7 +594,7 @@ int Shell::run_command(StringView cmd, Optional<SourcePosition> source_position_
|
|||
if (command->is_syntax_error()) {
|
||||
auto& error_node = command->syntax_error_node();
|
||||
auto& position = error_node.position();
|
||||
raise_error(ShellError::EvaluatedSyntaxError, error_node.error_text(), position);
|
||||
raise_error(ShellError::EvaluatedSyntaxError, error_node.error_text().bytes_as_string_view(), position);
|
||||
}
|
||||
|
||||
if (!has_error(ShellError::None)) {
|
||||
|
@ -673,7 +673,7 @@ ErrorOr<RefPtr<Job>> Shell::run_command(const AST::Command& command)
|
|||
auto apply_rewirings = [&]() -> ErrorOr<void> {
|
||||
for (auto& rewiring : rewirings) {
|
||||
|
||||
dbgln_if(SH_DEBUG, "in {}<{}>, dup2({}, {})", command.argv.is_empty() ? "(<Empty>)" : command.argv[0].characters(), getpid(), rewiring.old_fd, rewiring.new_fd);
|
||||
dbgln_if(SH_DEBUG, "in {}<{}>, dup2({}, {})", command.argv.is_empty() ? "(<Empty>)"sv : command.argv[0], getpid(), rewiring.old_fd, rewiring.new_fd);
|
||||
int rc = dup2(rewiring.old_fd, rewiring.new_fd);
|
||||
if (rc < 0)
|
||||
return Error::from_syscall("dup2"sv, rc);
|
||||
|
@ -734,11 +734,13 @@ ErrorOr<RefPtr<Job>> Shell::run_command(const AST::Command& command)
|
|||
}
|
||||
|
||||
Vector<char const*> argv;
|
||||
Vector<DeprecatedString> copy_argv = command.argv;
|
||||
Vector<DeprecatedString> copy_argv;
|
||||
argv.ensure_capacity(command.argv.size() + 1);
|
||||
|
||||
for (auto& arg : copy_argv)
|
||||
argv.append(arg.characters());
|
||||
for (auto& arg : command.argv) {
|
||||
copy_argv.append(arg.to_deprecated_string());
|
||||
argv.append(copy_argv.last().characters());
|
||||
}
|
||||
|
||||
argv.append(nullptr);
|
||||
|
||||
|
@ -1068,7 +1070,7 @@ bool Shell::is_allowed_to_modify_termios(const AST::Command& command) const
|
|||
if (!value)
|
||||
return false;
|
||||
|
||||
return const_cast<AST::Value&>(*value).resolve_as_list(const_cast<Shell&>(*this)).contains_slow(command.argv[0]);
|
||||
return const_cast<AST::Value&>(*value).resolve_as_list(const_cast<Shell&>(*this)).release_value_but_fixme_should_propagate_errors().contains_slow(command.argv[0]);
|
||||
}
|
||||
|
||||
void Shell::restore_ios()
|
||||
|
@ -1665,29 +1667,27 @@ ErrorOr<Vector<Line::CompletionSuggestion>> Shell::complete_via_program_itself(s
|
|||
if (command_node->would_execute())
|
||||
return Error::from_string_literal("Refusing to complete nodes that would execute");
|
||||
|
||||
DeprecatedString program_name_storage;
|
||||
String program_name_storage;
|
||||
if (known_program_name.is_null()) {
|
||||
auto node = command_node->leftmost_trivial_literal();
|
||||
if (!node)
|
||||
return Error::from_string_literal("Cannot complete");
|
||||
|
||||
program_name_storage = const_cast<AST::Node&>(*node).run(*this)->resolve_as_string(*this);
|
||||
program_name_storage = const_cast<AST::Node&>(*node).run(*this)->resolve_as_string(*this).release_value_but_fixme_should_propagate_errors();
|
||||
known_program_name = program_name_storage;
|
||||
}
|
||||
|
||||
auto program_name = known_program_name;
|
||||
|
||||
AST::Command completion_command;
|
||||
completion_command.argv.append(program_name);
|
||||
completion_command.argv.append(program_name_storage);
|
||||
completion_command = expand_aliases({ completion_command }).last();
|
||||
|
||||
auto completion_utility_name = DeprecatedString::formatted("_complete_{}", completion_command.argv[0]);
|
||||
auto completion_utility_name = String::formatted("_complete_{}", completion_command.argv[0]).release_value_but_fixme_should_propagate_errors();
|
||||
if (binary_search(cached_path.span(), completion_utility_name, nullptr, RunnablePathComparator {}) != nullptr)
|
||||
completion_command.argv[0] = completion_utility_name;
|
||||
else if (!options.invoke_program_for_autocomplete)
|
||||
return Error::from_string_literal("Refusing to use the program itself as completion source");
|
||||
|
||||
completion_command.argv.extend({ "--complete", "--" });
|
||||
completion_command.argv.extend({ String::from_utf8("--complete"sv).release_value_but_fixme_should_propagate_errors(), String::from_utf8_short_string("--"sv) });
|
||||
|
||||
struct Visitor : public AST::NodeVisitor {
|
||||
Visitor(Shell& shell, AST::Position position)
|
||||
|
@ -1699,12 +1699,12 @@ ErrorOr<Vector<Line::CompletionSuggestion>> Shell::complete_via_program_itself(s
|
|||
|
||||
Shell& shell;
|
||||
AST::Position completion_position;
|
||||
Vector<Vector<DeprecatedString>> lists;
|
||||
Vector<Vector<String>> lists;
|
||||
bool fail { false };
|
||||
|
||||
void push_list() { lists.empend(); }
|
||||
Vector<DeprecatedString> pop_list() { return lists.take_last(); }
|
||||
Vector<DeprecatedString>& list() { return lists.last(); }
|
||||
Vector<String> pop_list() { return lists.take_last(); }
|
||||
Vector<String>& list() { return lists.last(); }
|
||||
|
||||
bool should_include(AST::Node const* node) const { return node->position().end_offset <= completion_position.end_offset; }
|
||||
|
||||
|
@ -1717,7 +1717,7 @@ ErrorOr<Vector<Line::CompletionSuggestion>> Shell::complete_via_program_itself(s
|
|||
virtual void visit(AST::BraceExpansion const* node) override
|
||||
{
|
||||
if (should_include(node))
|
||||
list().extend(static_cast<AST::Node*>(const_cast<AST::BraceExpansion*>(node))->run(shell)->resolve_as_list(shell));
|
||||
list().extend(static_cast<AST::Node*>(const_cast<AST::BraceExpansion*>(node))->run(shell)->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors());
|
||||
}
|
||||
|
||||
virtual void visit(AST::CommandLiteral const* node) override
|
||||
|
@ -1742,7 +1742,7 @@ ErrorOr<Vector<Line::CompletionSuggestion>> Shell::complete_via_program_itself(s
|
|||
auto list = pop_list();
|
||||
StringBuilder builder;
|
||||
builder.join(""sv, list);
|
||||
this->list().append(builder.to_deprecated_string());
|
||||
this->list().append(builder.to_string().release_value_but_fixme_should_propagate_errors());
|
||||
}
|
||||
|
||||
virtual void visit(AST::Glob const* node) override
|
||||
|
@ -1761,7 +1761,7 @@ ErrorOr<Vector<Line::CompletionSuggestion>> Shell::complete_via_program_itself(s
|
|||
auto list = pop_list();
|
||||
StringBuilder builder;
|
||||
builder.join(""sv, list);
|
||||
this->list().append(builder.to_deprecated_string());
|
||||
this->list().append(builder.to_string().release_value_but_fixme_should_propagate_errors());
|
||||
}
|
||||
|
||||
virtual void visit(AST::ImmediateExpression const* node) override
|
||||
|
@ -1783,13 +1783,13 @@ ErrorOr<Vector<Line::CompletionSuggestion>> Shell::complete_via_program_itself(s
|
|||
virtual void visit(AST::SimpleVariable const* node) override
|
||||
{
|
||||
if (should_include(node))
|
||||
list().extend(static_cast<AST::Node*>(const_cast<AST::SimpleVariable*>(node))->run(shell)->resolve_as_list(shell));
|
||||
list().extend(static_cast<AST::Node*>(const_cast<AST::SimpleVariable*>(node))->run(shell)->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors());
|
||||
}
|
||||
|
||||
virtual void visit(AST::SpecialVariable const* node) override
|
||||
{
|
||||
if (should_include(node))
|
||||
list().extend(static_cast<AST::Node*>(const_cast<AST::SpecialVariable*>(node))->run(shell)->resolve_as_list(shell));
|
||||
list().extend(static_cast<AST::Node*>(const_cast<AST::SpecialVariable*>(node))->run(shell)->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors());
|
||||
}
|
||||
|
||||
virtual void visit(AST::Juxtaposition const* node) override
|
||||
|
@ -1810,7 +1810,7 @@ ErrorOr<Vector<Line::CompletionSuggestion>> Shell::complete_via_program_itself(s
|
|||
for (auto& right_entry : right) {
|
||||
builder.append(left_entry);
|
||||
builder.append(right_entry);
|
||||
list().append(builder.to_deprecated_string());
|
||||
list().append(builder.to_string().release_value_but_fixme_should_propagate_errors());
|
||||
builder.clear();
|
||||
}
|
||||
}
|
||||
|
@ -1825,7 +1825,7 @@ ErrorOr<Vector<Line::CompletionSuggestion>> Shell::complete_via_program_itself(s
|
|||
virtual void visit(AST::Tilde const* node) override
|
||||
{
|
||||
if (should_include(node))
|
||||
list().extend(static_cast<AST::Node*>(const_cast<AST::Tilde*>(node))->run(shell)->resolve_as_list(shell));
|
||||
list().extend(static_cast<AST::Node*>(const_cast<AST::Tilde*>(node))->run(shell)->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors());
|
||||
}
|
||||
|
||||
virtual void visit(AST::PathRedirectionNode const*) override { }
|
||||
|
@ -1844,9 +1844,10 @@ ErrorOr<Vector<Line::CompletionSuggestion>> Shell::complete_via_program_itself(s
|
|||
|
||||
completion_command.argv.extend(visitor.list());
|
||||
|
||||
auto devnull = String::from_utf8("/dev/null"sv).release_value_but_fixme_should_propagate_errors();
|
||||
completion_command.should_wait = true;
|
||||
completion_command.redirections.append(AST::PathRedirection::create("/dev/null", STDERR_FILENO, AST::PathRedirection::Write));
|
||||
completion_command.redirections.append(AST::PathRedirection::create("/dev/null", STDIN_FILENO, AST::PathRedirection::Read));
|
||||
completion_command.redirections.append(AST::PathRedirection::create(devnull, STDERR_FILENO, AST::PathRedirection::Write));
|
||||
completion_command.redirections.append(AST::PathRedirection::create(devnull, STDIN_FILENO, AST::PathRedirection::Read));
|
||||
|
||||
auto execute_node = make_ref_counted<AST::Execute>(
|
||||
AST::Position {},
|
||||
|
@ -1869,7 +1870,7 @@ ErrorOr<Vector<Line::CompletionSuggestion>> Shell::complete_via_program_itself(s
|
|||
{
|
||||
TemporaryChange change(m_is_interactive, false);
|
||||
execute_node->for_each_entry(*this, [&](NonnullRefPtr<AST::Value> entry) -> IterationDecision {
|
||||
auto result = entry->resolve_as_string(*this);
|
||||
auto result = entry->resolve_as_string(*this).release_value_but_fixme_should_propagate_errors();
|
||||
JsonParser parser(result);
|
||||
auto parsed_result = parser.parse();
|
||||
if (parsed_result.is_error())
|
||||
|
|
|
@ -165,7 +165,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
|
||||
StringView command_to_run = {};
|
||||
StringView file_to_read_from = {};
|
||||
Vector<DeprecatedString> script_args;
|
||||
Vector<StringView> script_args;
|
||||
bool skip_rc_files = false;
|
||||
char const* format = nullptr;
|
||||
bool should_format_live = false;
|
||||
|
@ -236,7 +236,12 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
shell->cache_path();
|
||||
}
|
||||
|
||||
shell->set_local_variable("ARGV", adopt_ref(*new Shell::AST::ListValue(move(script_args))));
|
||||
Vector<String> args_to_pass;
|
||||
TRY(args_to_pass.try_ensure_capacity(script_args.size()));
|
||||
for (auto& arg : script_args)
|
||||
TRY(args_to_pass.try_append(TRY(String::from_utf8(arg))));
|
||||
|
||||
shell->set_local_variable("ARGV", adopt_ref(*new Shell::AST::ListValue(move(args_to_pass))));
|
||||
|
||||
if (!command_to_run.is_empty()) {
|
||||
auto result = shell->run_command(command_to_run);
|
||||
|
|
Loading…
Reference in a new issue