summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorAli Mohammad Pur <ali.mpfard@gmail.com>2023-02-18 10:15:08 +0330
committerAli Mohammad Pur <Ali.mpfard@gmail.com>2023-02-28 15:52:24 +0330
commitbeeb58bd93b13acffd54e568f5d001c068ee00e3 (patch)
tree1444fca3fa61786f5f6948afaea8bc8659825146 /Userland
parent79e402748023d99f58610c550236951d8ef3cb2b (diff)
downloadserenity-beeb58bd93b13acffd54e568f5d001c068ee00e3.zip
Shell+LibCodeComprehension: Start replacing {Deprecated => }String
This starts by switching all AST members to Strings, and dealing with the fallout.
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibCodeComprehension/Shell/ShellComprehensionEngine.cpp10
-rw-r--r--Userland/Shell/AST.cpp423
-rw-r--r--Userland/Shell/AST.h190
-rw-r--r--Userland/Shell/Builtin.cpp57
-rw-r--r--Userland/Shell/Formatter.cpp4
-rw-r--r--Userland/Shell/Formatter.h1
-rw-r--r--Userland/Shell/ImmediateFunctions.cpp132
-rw-r--r--Userland/Shell/Parser.cpp219
-rw-r--r--Userland/Shell/Parser.h4
-rw-r--r--Userland/Shell/PosixParser.cpp98
-rw-r--r--Userland/Shell/Shell.cpp59
-rw-r--r--Userland/Shell/main.cpp9
12 files changed, 625 insertions, 581 deletions
diff --git a/Userland/Libraries/LibCodeComprehension/Shell/ShellComprehensionEngine.cpp b/Userland/Libraries/LibCodeComprehension/Shell/ShellComprehensionEngine.cpp
index 504343f001..7b4e20b320 100644
--- a/Userland/Libraries/LibCodeComprehension/Shell/ShellComprehensionEngine.cpp
+++ b/Userland/Libraries/LibCodeComprehension/Shell/ShellComprehensionEngine.cpp
@@ -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;
diff --git a/Userland/Shell/AST.cpp b/Userland/Shell/AST.cpp
index 838b5e01f7..a407bb1b6c 100644
--- a/Userland/Shell/AST.cpp
+++ b/Userland/Shell/AST.cpp
@@ -6,10 +6,10 @@
#include "AST.h"
#include "Shell.h"
-#include <AK/DeprecatedString.h>
#include <AK/MemoryStream.h>
#include <AK/ScopeGuard.h>
#include <AK/ScopedValueRollback.h>
+#include <AK/String.h>
#include <AK/StringBuilder.h>
#include <AK/URL.h>
#include <LibCore/DeprecatedFile.h>
@@ -108,7 +108,7 @@ namespace Shell::AST {
static inline void print_indented(StringView str, int indent)
{
- dbgln("{}{}", DeprecatedString::repeated(' ', indent * 2), str);
+ dbgln("{: >{}}", str, str.length() + indent * 2);
}
static inline Optional<Position> merge_positions(Optional<Position> const& left, Optional<Position> const& right)
@@ -154,7 +154,7 @@ static inline Vector<Command> join_commands(Vector<Command> left, Vector<Command
return commands;
}
-static DeprecatedString resolve_slices(RefPtr<Shell> shell, DeprecatedString&& input_value, NonnullRefPtrVector<Slice> slices)
+static String resolve_slices(RefPtr<Shell> shell, String&& input_value, NonnullRefPtrVector<Slice> slices)
{
if (slices.is_empty())
return move(input_value);
@@ -169,13 +169,13 @@ static DeprecatedString resolve_slices(RefPtr<Shell> shell, DeprecatedString&& i
return move(input_value);
}
- auto index_values = value->resolve_as_list(shell);
+ auto index_values = value->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors();
Vector<size_t> indices;
indices.ensure_capacity(index_values.size());
size_t i = 0;
for (auto& value : index_values) {
- auto maybe_index = value.to_int();
+ auto maybe_index = value.bytes_as_string_view().to_int();
if (!maybe_index.has_value()) {
shell->raise_error(Shell::ShellError::InvalidSliceContentsError, DeprecatedString::formatted("Invalid value in slice index {}: {} (expected a number)", i, value), slice.position());
return move(input_value);
@@ -185,10 +185,10 @@ static DeprecatedString resolve_slices(RefPtr<Shell> shell, DeprecatedString&& i
auto index = maybe_index.value();
auto original_index = index;
if (index < 0)
- index += input_value.length();
+ index += input_value.bytes_as_string_view().length();
- if (index < 0 || (size_t)index >= input_value.length()) {
- shell->raise_error(Shell::ShellError::InvalidSliceContentsError, DeprecatedString::formatted("Slice index {} (evaluated as {}) out of value bounds [0-{})", index, original_index, input_value.length()), slice.position());
+ if (index < 0 || (size_t)index >= input_value.bytes_as_string_view().length()) {
+ shell->raise_error(Shell::ShellError::InvalidSliceContentsError, DeprecatedString::formatted("Slice index {} (evaluated as {}) out of value bounds [0-{})", index, original_index, input_value.bytes_as_string_view().length()), slice.position());
return move(input_value);
}
indices.unchecked_append(index);
@@ -196,15 +196,15 @@ static DeprecatedString resolve_slices(RefPtr<Shell> shell, DeprecatedString&& i
StringBuilder builder { indices.size() };
for (auto& index : indices)
- builder.append(input_value[index]);
+ builder.append(input_value.bytes_as_string_view()[index]);
- input_value = builder.to_deprecated_string();
+ input_value = builder.to_string().release_value_but_fixme_should_propagate_errors();
}
return move(input_value);
}
-static Vector<DeprecatedString> resolve_slices(RefPtr<Shell> shell, Vector<DeprecatedString>&& values, NonnullRefPtrVector<Slice> slices)
+static Vector<String> resolve_slices(RefPtr<Shell> shell, Vector<String>&& values, NonnullRefPtrVector<Slice> slices)
{
if (slices.is_empty())
return move(values);
@@ -219,13 +219,13 @@ static Vector<DeprecatedString> resolve_slices(RefPtr<Shell> shell, Vector<Depre
return move(values);
}
- auto index_values = value->resolve_as_list(shell);
+ auto index_values = value->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors();
Vector<size_t> indices;
indices.ensure_capacity(index_values.size());
size_t i = 0;
for (auto& value : index_values) {
- auto maybe_index = value.to_int();
+ auto maybe_index = value.bytes_as_string_view().to_int();
if (!maybe_index.has_value()) {
shell->raise_error(Shell::ShellError::InvalidSliceContentsError, DeprecatedString::formatted("Invalid value in slice index {}: {} (expected a number)", i, value), slice.position());
return move(values);
@@ -244,7 +244,7 @@ static Vector<DeprecatedString> resolve_slices(RefPtr<Shell> shell, Vector<Depre
indices.unchecked_append(index);
}
- Vector<DeprecatedString> result;
+ Vector<String> result;
result.ensure_capacity(indices.size());
for (auto& index : indices)
result.unchecked_append(values[index]);
@@ -276,7 +276,7 @@ bool Node::is_syntax_error() const
void Node::for_each_entry(RefPtr<Shell> shell, Function<IterationDecision(NonnullRefPtr<Value>)> callback)
{
- auto value = run(shell)->resolve_without_cast(shell);
+ auto value = run(shell)->resolve_without_cast(shell).release_value_but_fixme_should_propagate_errors();
if (shell && shell->has_any_error())
return;
@@ -286,7 +286,7 @@ void Node::for_each_entry(RefPtr<Shell> shell, Function<IterationDecision(Nonnul
}
if (value->is_list_without_resolution()) {
- auto list = value->resolve_without_cast(shell);
+ auto list = value->resolve_without_cast(shell).release_value_but_fixme_should_propagate_errors();
for (auto& element : static_cast<ListValue*>(list.ptr())->values()) {
if (callback(element) == IterationDecision::Break)
break;
@@ -294,7 +294,7 @@ void Node::for_each_entry(RefPtr<Shell> shell, Function<IterationDecision(Nonnul
return;
}
- auto list = value->resolve_as_list(shell);
+ auto list = value->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors();
for (auto& element : list) {
if (callback(make_ref_counted<StringValue>(move(element))) == IterationDecision::Break)
break;
@@ -310,13 +310,13 @@ Vector<Command> Node::to_lazy_evaluated_commands(RefPtr<Shell> shell)
};
}
- return run(shell)->resolve_as_commands(shell);
+ return run(shell)->resolve_as_commands(shell).release_value_but_fixme_should_propagate_errors();
}
void Node::dump(int level) const
{
print_indented(DeprecatedString::formatted("{} at {}:{} (from {}.{} to {}.{})",
- class_name().characters(),
+ class_name(),
m_position.start_offset,
m_position.end_offset,
m_position.start_line.line_number,
@@ -380,7 +380,7 @@ Vector<Line::CompletionSuggestion> Node::complete_for_editor(Shell& shell, size_
if (!program_name_node)
return {};
- DeprecatedString program_name;
+ String program_name;
if (program_name_node->is_bareword())
program_name = static_cast<BarewordLiteral const*>(program_name_node.ptr())->text();
else
@@ -475,15 +475,17 @@ RefPtr<Value> ListConcatenate::run(RefPtr<Shell> shell)
if (shell && shell->has_any_error())
break;
if (!result) {
- result = make_ref_counted<ListValue>({ element->run(shell)->resolve_without_cast(shell) });
+ result = make_ref_counted<ListValue>({ element->run(shell)->resolve_without_cast(shell).release_value_but_fixme_should_propagate_errors() });
continue;
}
- auto element_value = element->run(shell)->resolve_without_cast(shell);
+ auto element_value = element->run(shell)->resolve_without_cast(shell).release_value_but_fixme_should_propagate_errors();
if (shell && shell->has_any_error())
break;
if (result->is_command() || element_value->is_command()) {
- auto joined_commands = join_commands(result->resolve_as_commands(shell), element_value->resolve_as_commands(shell));
+ auto joined_commands = join_commands(
+ result->resolve_as_commands(shell).release_value_but_fixme_should_propagate_errors(),
+ element_value->resolve_as_commands(shell).release_value_but_fixme_should_propagate_errors());
if (joined_commands.size() == 1) {
auto& command = joined_commands[0];
@@ -498,7 +500,7 @@ RefPtr<Value> ListConcatenate::run(RefPtr<Shell> shell)
if (result->is_list_without_resolution()) {
values.extend(static_cast<ListValue*>(result.ptr())->values());
} else {
- for (auto& result : result->resolve_as_list(shell))
+ for (auto& result : result->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors())
values.append(make_ref_counted<StringValue>(result));
}
@@ -644,29 +646,29 @@ void BarewordLiteral::highlight_in_editor(Line::Editor& editor, Shell& shell, Hi
}
if (m_text.starts_with('-')) {
- if (m_text == "--") {
+ if (m_text == "--"sv) {
editor.stylize({ m_position.start_offset, m_position.end_offset }, { Line::Style::Foreground(Line::Style::XtermColor::Green) });
return;
}
- if (m_text == "-")
+ if (m_text == "-"sv)
return;
- if (m_text.starts_with("--"sv)) {
- auto index = m_text.find('=').value_or(m_text.length() - 1) + 1;
+ if (m_text.starts_with_bytes("--"sv)) {
+ auto index = m_text.find_byte_offset('=').value_or(m_text.bytes_as_string_view().length() - 1) + 1;
editor.stylize({ m_position.start_offset, m_position.start_offset + index }, { Line::Style::Foreground(Line::Style::XtermColor::Cyan) });
} else {
editor.stylize({ m_position.start_offset, m_position.end_offset }, { Line::Style::Foreground(Line::Style::XtermColor::Cyan) });
}
}
if (Core::DeprecatedFile::exists(m_text)) {
- auto realpath = shell.resolve_path(m_text);
+ auto realpath = shell.resolve_path(m_text.bytes_as_string_view());
auto url = URL::create_with_file_scheme(realpath);
url.set_host(shell.hostname);
editor.stylize({ m_position.start_offset, m_position.end_offset }, { Line::Style::Hyperlink(url.to_deprecated_string()) });
}
}
-BarewordLiteral::BarewordLiteral(Position position, DeprecatedString text)
+BarewordLiteral::BarewordLiteral(Position position, String text)
: Node(move(position))
, m_text(move(text))
{
@@ -738,14 +740,14 @@ RefPtr<Value> CastToCommand::run(RefPtr<Shell> shell)
if (m_inner->is_command())
return m_inner->run(shell);
- auto value = m_inner->run(shell)->resolve_without_cast(shell);
+ auto value = m_inner->run(shell)->resolve_without_cast(shell).release_value_but_fixme_should_propagate_errors();
if (shell && shell->has_any_error())
return make_ref_counted<ListValue>({});
if (value->is_command())
return value;
- auto argv = value->resolve_as_list(shell);
+ auto argv = value->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors();
return make_ref_counted<CommandValue>(move(argv), position());
}
@@ -773,7 +775,7 @@ Vector<Line::CompletionSuggestion> CastToCommand::complete_for_editor(Shell& she
auto corrected_offset = offset - matching_node->position().start_offset;
auto* node = static_cast<BarewordLiteral const*>(matching_node.ptr());
- if (corrected_offset > node->text().length())
+ if (corrected_offset > node->text().bytes_as_string_view().length())
return {};
return shell.complete_program_name(node->text(), corrected_offset);
@@ -806,14 +808,14 @@ RefPtr<Value> CastToList::run(RefPtr<Shell> shell)
if (!m_inner)
return make_ref_counted<ListValue>({});
- auto inner_value = m_inner->run(shell)->resolve_without_cast(shell);
+ auto inner_value = m_inner->run(shell)->resolve_without_cast(shell).release_value_but_fixme_should_propagate_errors();
if (shell && shell->has_any_error())
return make_ref_counted<ListValue>({});
if (inner_value->is_command() || inner_value->is_list())
return inner_value;
- auto values = inner_value->resolve_as_list(shell);
+ auto values = inner_value->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors();
NonnullRefPtrVector<Value> cast_values;
for (auto& value : values)
cast_values.append(make_ref_counted<StringValue>(value));
@@ -921,7 +923,7 @@ void Comment::highlight_in_editor(Line::Editor& editor, Shell&, HighlightMetadat
editor.stylize({ m_position.start_offset, m_position.end_offset }, { Line::Style::Foreground(150, 150, 150) }); // Light gray
}
-Comment::Comment(Position position, DeprecatedString text)
+Comment::Comment(Position position, String text)
: Node(move(position))
, m_text(move(text))
{
@@ -962,11 +964,11 @@ void DoubleQuotedString::dump(int level) const
RefPtr<Value> DoubleQuotedString::run(RefPtr<Shell> shell)
{
StringBuilder builder;
- auto values = m_inner->run(shell)->resolve_as_list(shell);
+ auto values = m_inner->run(shell)->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors();
builder.join(""sv, values);
- return make_ref_counted<StringValue>(builder.to_deprecated_string());
+ return make_ref_counted<StringValue>(builder.to_string().release_value_but_fixme_should_propagate_errors());
}
void DoubleQuotedString::highlight_in_editor(Line::Editor& editor, Shell& shell, HighlightMetadata metadata)
@@ -1005,20 +1007,20 @@ void DynamicEvaluate::dump(int level) const
RefPtr<Value> DynamicEvaluate::run(RefPtr<Shell> shell)
{
- auto result = m_inner->run(shell)->resolve_without_cast(shell);
+ auto result = m_inner->run(shell)->resolve_without_cast(shell).release_value_but_fixme_should_propagate_errors();
if (shell && shell->has_any_error())
return make_ref_counted<ListValue>({});
// Dynamic Evaluation behaves differently between strings and lists.
// Strings are treated as variables, and Lists are treated as commands.
if (result->is_string()) {
- auto name_part = result->resolve_as_list(shell);
+ auto name_part = result->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors();
VERIFY(name_part.size() == 1);
return make_ref_counted<SimpleVariableValue>(name_part[0]);
}
// If it's anything else, we're just gonna cast it to a list.
- auto list = result->resolve_as_list(shell);
+ auto list = result->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors();
return make_ref_counted<CommandValue>(move(list), position());
}
@@ -1094,9 +1096,9 @@ RefPtr<Value> FunctionDeclaration::run(RefPtr<Shell> shell)
{
Vector<DeprecatedString> args;
for (auto& arg : m_arguments)
- args.append(arg.name);
+ args.append(arg.name.to_deprecated_string());
- shell->define_function(m_name.name, move(args), m_block);
+ shell->define_function(m_name.name.to_deprecated_string(), move(args), m_block);
return make_ref_counted<ListValue>({});
}
@@ -1136,12 +1138,12 @@ Vector<Line::CompletionSuggestion> FunctionDeclaration::complete_for_editor(Shel
auto corrected_offset = offset - matching_node->position().start_offset - 1; // Skip the first '$'
auto* node = static_cast<SimpleVariable const*>(matching_node.ptr());
- auto name = node->name().substring_view(0, corrected_offset);
+ auto name = node->name().bytes_as_string_view().substring_view(0, corrected_offset);
Vector<Line::CompletionSuggestion> results;
for (auto& arg : m_arguments) {
- if (arg.name.starts_with(name))
- results.append(arg.name);
+ if (arg.name.starts_with_bytes(name))
+ results.append(arg.name.to_deprecated_string());
}
results.extend(matching_node->complete_for_editor(shell, offset, hit_test_result));
@@ -1219,7 +1221,7 @@ RefPtr<Value> ForLoop::run(RefPtr<Shell> shell)
};
if (m_iterated_expression) {
- auto variable_name = m_variable.has_value() ? m_variable->name : "it";
+ auto variable_name = m_variable.has_value() ? m_variable->name : String::from_utf8_short_string("it"sv);
Optional<StringView> index_name = m_index_variable.has_value() ? Optional<StringView>(m_index_variable->name) : Optional<StringView>();
size_t i = 0;
m_iterated_expression->for_each_entry(shell, [&](auto value) {
@@ -1238,10 +1240,10 @@ RefPtr<Value> ForLoop::run(RefPtr<Shell> shell)
{
auto frame = shell->push_frame(DeprecatedString::formatted("for ({})", this));
- shell->set_local_variable(variable_name, value, true);
+ shell->set_local_variable(variable_name.bytes_as_string_view(), value, true);
if (index_name.has_value())
- shell->set_local_variable(index_name.value(), make_ref_counted<AST::StringValue>(DeprecatedString::number(i)), true);
+ shell->set_local_variable(index_name.value(), make_ref_counted<AST::StringValue>(String::number(i).release_value_but_fixme_should_propagate_errors()), true);
++i;
@@ -1349,7 +1351,7 @@ void Glob::highlight_in_editor(Line::Editor& editor, Shell&, HighlightMetadata m
editor.stylize({ m_position.start_offset, m_position.end_offset }, move(style));
}
-Glob::Glob(Position position, DeprecatedString text)
+Glob::Glob(Position position, String text)
: Node(move(position))
, m_text(move(text))
{
@@ -1396,19 +1398,19 @@ RefPtr<Value> Heredoc::run(RefPtr<Shell> shell)
if (!value)
return value;
- auto list = value->resolve_as_list(shell);
+ auto list = value->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors();
// The list better have one entry, otherwise we've put the wrong kind of node inside this heredoc
VERIFY(list.size() == 1);
- auto lines = list.first().split_view('\n');
+ auto lines = list.first().bytes_as_string_view().split_view('\n');
// Now just trim each line and put them back in a string
- StringBuilder builder { list.first().length() };
+ StringBuilder builder { list.first().bytes_as_string_view().length() };
for (auto& line : lines) {
builder.append(line.trim_whitespace(TrimMode::Left));
builder.append('\n');
}
- return make_ref_counted<StringValue>(builder.to_deprecated_string());
+ return make_ref_counted<StringValue>(builder.to_string().release_value_but_fixme_should_propagate_errors());
}();
if (evaluates_to_string())
@@ -1434,11 +1436,12 @@ RefPtr<Value> Heredoc::run(RefPtr<Shell> shell)
return nullptr;
}
- auto text = value->resolve_as_string(shell);
+ auto text = value->resolve_as_string(shell).release_value_but_fixme_should_propagate_errors();
+ auto bytes = text.bytes();
- auto written = fwrite(text.characters(), 1, text.length(), file);
+ auto written = fwrite(bytes.data(), 1, bytes.size(), file);
fflush(file);
- if (written != text.length()) {
+ if (written != bytes.size()) {
if (shell)
shell->raise_error(Shell::ShellError::WriteFailure, "heredoc"sv, position());
}
@@ -1472,7 +1475,7 @@ HitTestResult Heredoc::hit_test_position(size_t offset) const
return m_contents->hit_test_position(offset);
}
-Heredoc::Heredoc(Position position, DeprecatedString end, bool allow_interpolation, bool deindent, Optional<int> target_fd)
+Heredoc::Heredoc(Position position, String end, bool allow_interpolation, bool deindent, Optional<int> target_fd)
: Node(move(position))
, m_end(move(end))
, m_allows_interpolation(allow_interpolation)
@@ -1653,7 +1656,7 @@ void Execute::for_each_entry(RefPtr<Shell> shell, Function<IterationDecision(Non
if (m_command->would_execute())
return m_command->for_each_entry(shell, move(callback));
- auto unexpanded_commands = m_command->run(shell)->resolve_as_commands(shell);
+ auto unexpanded_commands = m_command->run(shell)->resolve_as_commands(shell).release_value_but_fixme_should_propagate_errors();
if (shell && shell->has_any_error())
return;
@@ -1708,7 +1711,7 @@ void Execute::for_each_entry(RefPtr<Shell> shell, Function<IterationDecision(Non
stream.discard(ifs.length()).release_value_but_fixme_should_propagate_errors();
if (shell->options.inline_exec_keep_empty_segments)
- if (callback(make_ref_counted<StringValue>("")) == IterationDecision::Break) {
+ if (callback(make_ref_counted<StringValue>(String {})) == IterationDecision::Break) {
loop.quit(Break);
notifier->set_enabled(false);
return Break;
@@ -1723,8 +1726,8 @@ void Execute::for_each_entry(RefPtr<Shell> shell, Function<IterationDecision(Non
auto entry = entry_result.release_value();
stream.read_entire_buffer(entry).release_value_but_fixme_should_propagate_errors();
- auto str = StringView(entry.data(), entry.size() - ifs.length());
- if (callback(make_ref_counted<StringValue>(str)) == IterationDecision::Break) {
+ auto str = String::from_utf8(StringView(entry.data(), entry.size() - ifs.length())).release_value_but_fixme_should_propagate_errors();
+ if (callback(make_ref_counted<StringValue>(move(str))) == IterationDecision::Break) {
loop.quit(Break);
notifier->set_enabled(false);
return Break;
@@ -1812,7 +1815,7 @@ void Execute::for_each_entry(RefPtr<Shell> shell, Function<IterationDecision(Non
}
auto entry = entry_result.release_value();
stream.read_entire_buffer(entry).release_value_but_fixme_should_propagate_errors();
- callback(make_ref_counted<StringValue>(DeprecatedString::copy(entry)));
+ callback(make_ref_counted<StringValue>(String::from_utf8(entry).release_value_but_fixme_should_propagate_errors()));
}
}
@@ -1872,7 +1875,7 @@ Vector<Line::CompletionSuggestion> Execute::complete_for_editor(Shell& shell, si
auto corrected_offset = offset - matching_node->position().start_offset;
auto* node = static_cast<BarewordLiteral const*>(matching_node.ptr());
- if (corrected_offset > node->text().length())
+ if (corrected_offset > node->text().bytes_as_string_view().length())
return {};
return shell.complete_program_name(node->text(), corrected_offset);
@@ -1910,7 +1913,7 @@ void IfCond::dump(int level) const
RefPtr<Value> IfCond::run(RefPtr<Shell> shell)
{
- auto cond = m_condition->run(shell)->resolve_without_cast(shell);
+ auto cond = m_condition->run(shell)->resolve_without_cast(shell).release_value_but_fixme_should_propagate_errors();
if (shell && shell->has_any_error())
return make_ref_counted<ListValue>({});
@@ -2051,7 +2054,7 @@ Vector<Line::CompletionSuggestion> ImmediateExpression::complete_for_editor(Shel
auto corrected_offset = offset - m_function.position.start_offset;
- if (corrected_offset > m_function.name.length())
+ if (corrected_offset > m_function.name.bytes_as_string_view().length())
return {};
return shell.complete_immediate_function_name(m_function.name, corrected_offset);
@@ -2160,9 +2163,9 @@ Join::~Join()
void MatchExpr::dump(int level) const
{
Node::dump(level);
- print_indented(DeprecatedString::formatted("(expression: {})", m_expr_name.characters()), level + 1);
+ print_indented(DeprecatedString::formatted("(expression: {})", m_expr_name), level + 1);
m_matched_expr->dump(level + 2);
- print_indented(DeprecatedString::formatted("(named: {})", m_expr_name.characters()), level + 1);
+ print_indented(DeprecatedString::formatted("(named: {})", m_expr_name), level + 1);
print_indented("(entries)"sv, level + 1);
for (auto& entry : m_entries) {
StringBuilder builder;
@@ -2201,11 +2204,11 @@ void MatchExpr::dump(int level) const
RefPtr<Value> MatchExpr::run(RefPtr<Shell> shell)
{
- auto value = m_matched_expr->run(shell)->resolve_without_cast(shell);
+ auto value = m_matched_expr->run(shell)->resolve_without_cast(shell).release_value_but_fixme_should_propagate_errors();
if (shell && shell->has_any_error())
return make_ref_counted<ListValue>({});
- auto list = value->resolve_as_list(shell);
+ auto list = value->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors();
auto list_matches = [&](auto&& pattern, auto& spans) {
if constexpr (IsSame<RemoveCVReference<decltype(pattern)>, Regex<ECMA262>>) {
@@ -2219,7 +2222,7 @@ RefPtr<Value> MatchExpr::run(RefPtr<Shell> shell)
spans.ensure_capacity(match.n_capture_groups);
for (size_t i = 0; i < match.n_capture_groups; ++i) {
auto& capture = match.capture_group_matches[0][i];
- spans.append(capture.view.to_deprecated_string());
+ spans.append(capture.view.to_string().release_value_but_fixme_should_propagate_errors());
}
return true;
} else {
@@ -2228,10 +2231,10 @@ RefPtr<Value> MatchExpr::run(RefPtr<Shell> shell)
for (size_t i = 0; i < pattern.size(); ++i) {
Vector<AK::MaskSpan> mask_spans;
- if (!list[i].matches(pattern[i], mask_spans))
+ if (!list[i].bytes_as_string_view().matches(pattern[i], mask_spans))
return false;
for (auto& span : mask_spans)
- spans.append(list[i].substring(span.start, span.length));
+ spans.append(list[i].substring_from_byte_offset(span.start, span.length).release_value_but_fixme_should_propagate_errors());
}
return true;
@@ -2242,7 +2245,7 @@ RefPtr<Value> MatchExpr::run(RefPtr<Shell> shell)
if constexpr (IsSame<RemoveCVReference<decltype(option)>, Regex<ECMA262>>) {
return option;
} else {
- Vector<DeprecatedString> pattern;
+ Vector<String> pattern;
if (option.is_glob()) {
pattern.append(static_cast<const Glob*>(&option)->text());
} else if (option.is_bareword()) {
@@ -2253,8 +2256,8 @@ RefPtr<Value> MatchExpr::run(RefPtr<Shell> shell)
return pattern;
option.for_each_entry(shell, [&](auto&& value) {
- pattern.extend(value->resolve_as_list(nullptr)); // Note: 'nullptr' incurs special behavior,
- // asking the node for a 'raw' value.
+ pattern.extend(value->resolve_as_list(nullptr).release_value_but_fixme_should_propagate_errors()); // Note: 'nullptr' incurs special behavior,
+ // asking the node for a 'raw' value.
return IterationDecision::Continue;
});
}
@@ -2265,19 +2268,19 @@ RefPtr<Value> MatchExpr::run(RefPtr<Shell> shell)
auto frame = shell->push_frame(DeprecatedString::formatted("match ({})", this));
if (!m_expr_name.is_empty())
- shell->set_local_variable(m_expr_name, value, true);
+ shell->set_local_variable(m_expr_name.to_deprecated_string(), value, true);
for (auto& entry : m_entries) {
auto result = entry.options.visit([&](auto& options) -> Variant<IterationDecision, RefPtr<Value>> {
for (auto& option : options) {
- Vector<DeprecatedString> spans;
+ Vector<String> spans;
if (list_matches(resolve_pattern(option), spans)) {
if (entry.body) {
if (entry.match_names.has_value()) {
size_t i = 0;
for (auto& name : entry.match_names.value()) {
if (spans.size() > i)
- shell->set_local_variable(name, make_ref_counted<AST::StringValue>(spans[i]), true);
+ shell->set_local_variable(name.to_deprecated_string(), make_ref_counted<AST::StringValue>(spans[i]), true);
++i;
}
}
@@ -2346,7 +2349,7 @@ HitTestResult MatchExpr::hit_test_position(size_t offset) const
return {};
}
-MatchExpr::MatchExpr(Position position, NonnullRefPtr<Node> expr, DeprecatedString name, Optional<Position> as_position, Vector<MatchEntry> entries)
+MatchExpr::MatchExpr(Position position, NonnullRefPtr<Node> expr, String name, Optional<Position> as_position, Vector<MatchEntry> entries)
: Node(move(position))
, m_matched_expr(move(expr))
, m_expr_name(move(name))
@@ -2537,14 +2540,14 @@ void PathRedirectionNode::highlight_in_editor(Line::Editor& editor, Shell& shell
metadata.is_first_in_list = false;
m_path->highlight_in_editor(editor, shell, metadata);
if (m_path->is_bareword()) {
- auto path_text = m_path->run(nullptr)->resolve_as_list(nullptr);
+ auto path_text = m_path->run(nullptr)->resolve_as_list(nullptr).release_value_but_fixme_should_propagate_errors();
VERIFY(path_text.size() == 1);
// Apply a URL to the path.
auto& position = m_path->position();
auto& path = path_text[0];
if (!path.starts_with('/'))
- path = DeprecatedString::formatted("{}/{}", shell.cwd, path);
- auto url = URL::create_with_file_scheme(path);
+ path = String::formatted("{}/{}", shell.cwd, path).release_value_but_fixme_should_propagate_errors();
+ auto url = URL::create_with_file_scheme(path.to_deprecated_string());
url.set_host(shell.hostname);
editor.stylize({ position.start_offset, position.end_offset }, { Line::Style::Hyperlink(url.to_deprecated_string()) });
}
@@ -2567,7 +2570,7 @@ Vector<Line::CompletionSuggestion> PathRedirectionNode::complete_for_editor(Shel
auto corrected_offset = offset - matching_node->position().start_offset;
auto* node = static_cast<BarewordLiteral const*>(matching_node.ptr());
- if (corrected_offset > node->text().length())
+ if (corrected_offset > node->text().bytes_as_string_view().length())
return {};
return shell.complete_path(""sv, node->text(), corrected_offset, Shell::ExecutableOnly::No, nullptr, nullptr);
@@ -2592,8 +2595,8 @@ RefPtr<Value> Range::run(RefPtr<Shell> shell)
NonnullRefPtrVector<Value> values;
if (start->is_string() && end->is_string()) {
- auto start_str = start->resolve_as_list(shell)[0];
- auto end_str = end->resolve_as_list(shell)[0];
+ auto start_str = start->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors()[0];
+ auto end_str = end->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors()[0];
Utf8View start_view { start_str }, end_view { end_str };
if (start_view.validate() && end_view.validate()) {
@@ -2606,24 +2609,24 @@ RefPtr<Value> Range::run(RefPtr<Shell> shell)
for (u32 code_point = start_code_point; code_point != end_code_point; code_point += step) {
builder.clear();
builder.append_code_point(code_point);
- values.append(make_ref_counted<StringValue>(builder.to_deprecated_string()));
+ values.append(make_ref_counted<StringValue>(builder.to_string().release_value_but_fixme_should_propagate_errors()));
}
// Append the ending code point too, most shells treat this as inclusive.
builder.clear();
builder.append_code_point(end_code_point);
- values.append(make_ref_counted<StringValue>(builder.to_deprecated_string()));
+ values.append(make_ref_counted<StringValue>(builder.to_string().release_value_but_fixme_should_propagate_errors()));
} else {
// Could be two numbers?
- auto start_int = start_str.to_int();
- auto end_int = end_str.to_int();
+ auto start_int = start_str.bytes_as_string_view().to_int();
+ auto end_int = end_str.bytes_as_string_view().to_int();
if (start_int.has_value() && end_int.has_value()) {
auto start = start_int.value();
auto end = end_int.value();
auto step = start > end ? -1 : 1;
for (int value = start; value != end; value += step)
- values.append(make_ref_counted<StringValue>(DeprecatedString::number(value)));
+ values.append(make_ref_counted<StringValue>(String::number(value).release_value_but_fixme_should_propagate_errors()));
// Append the range end too, most shells treat this as inclusive.
- values.append(make_ref_counted<StringValue>(DeprecatedString::number(end)));
+ values.append(make_ref_counted<StringValue>(String::number(end).release_value_but_fixme_should_propagate_errors()));
} else {
goto yield_start_end;
}
@@ -2708,14 +2711,14 @@ void ReadRedirection::dump(int level) const
RefPtr<Value> ReadRedirection::run(RefPtr<Shell> shell)
{
Command command;
- auto path_segments = m_path->run(shell)->resolve_as_list(shell);
+ auto path_segments = m_path->run(shell)->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors();
if (shell && shell->has_any_error())
return make_ref_counted<ListValue>({});
StringBuilder builder;
builder.join(' ', path_segments);
- command.redirections.append(PathRedirection::create(builder.to_deprecated_string(), m_fd, PathRedirection::Read));
+ command.redirections.append(PathRedirection::create(builder.to_string().release_value_but_fixme_should_propagate_errors(), m_fd, PathRedirection::Read));
return make_ref_counted<CommandValue>(move(command));
}
@@ -2738,14 +2741,14 @@ void ReadWriteRedirection::dump(int level) const
RefPtr<Value> ReadWriteRedirection::run(RefPtr<Shell> shell)
{
Command command;
- auto path_segments = m_path->run(shell)->resolve_as_list(shell);
+ auto path_segments = m_path->run(shell)->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors();
if (shell && shell->has_any_error())
return make_ref_counted<ListValue>({});
StringBuilder builder;
builder.join(' ', path_segments);
- command.redirections.append(PathRedirection::create(builder.to_deprecated_string(), m_fd, PathRedirection::ReadWrite));
+ command.redirections.append(PathRedirection::create(builder.to_string().release_value_but_fixme_should_propagate_errors(), m_fd, PathRedirection::ReadWrite));
return make_ref_counted<CommandValue>(move(command));
}
@@ -2933,7 +2936,7 @@ RefPtr<Value> SimpleVariable::run(RefPtr<Shell>)
{
NonnullRefPtr<Value> value = make_ref_counted<SimpleVariableValue>(m_name);
if (m_slice)
- value = value->with_slices(*m_slice);
+ value = value->with_slices(*m_slice).release_value_but_fixme_should_propagate_errors();
return value;
}
@@ -2969,13 +2972,13 @@ Vector<Line::CompletionSuggestion> SimpleVariable::complete_for_editor(Shell& sh
auto corrected_offset = offset - matching_node->position().start_offset - 1;
- if (corrected_offset > m_name.length() + 1)
+ if (corrected_offset > m_name.bytes_as_string_view().length() + 1)
return {};
return shell.complete_variable(m_name, corrected_offset);
}
-SimpleVariable::SimpleVariable(Position position, DeprecatedString name)
+SimpleVariable::SimpleVariable(Position position, String name)
: VariableNode(move(position))
, m_name(move(name))
{
@@ -2989,7 +2992,7 @@ void SpecialVariable::dump(int level) const
{
Node::dump(level);
print_indented("(Name)"sv, level + 1);
- print_indented(DeprecatedString { &m_name, 1 }, level + 1);
+ print_indented(StringView { &m_name, 1 }, level + 1);
print_indented("(Slice)"sv, level + 1);
if (m_slice)
m_slice->dump(level + 2);
@@ -3001,7 +3004,7 @@ RefPtr<Value> SpecialVariable::run(RefPtr<Shell>)
{
NonnullRefPtr<Value> value = make_ref_counted<SpecialVariableValue>(m_name);
if (m_slice)
- value = value->with_slices(*m_slice);
+ value = value->with_slices(*m_slice).release_value_but_fixme_should_propagate_errors();
return value;
}
@@ -3044,19 +3047,19 @@ void Juxtaposition::dump(int level) const
RefPtr<Value> Juxtaposition::run(RefPtr<Shell> shell)
{
- auto left_value = m_left->run(shell)->resolve_without_cast(shell);
+ auto left_value = m_left->run(shell)->resolve_without_cast(shell).release_value_but_fixme_should_propagate_errors();
if (shell && shell->has_any_error())
return make_ref_counted<ListValue>({});
- auto right_value = m_right->run(shell)->resolve_without_cast(shell);
+ auto right_value = m_right->run(shell)->resolve_without_cast(shell).release_value_but_fixme_should_propagate_errors();
if (shell && shell->has_any_error())
return make_ref_counted<ListValue>({});
- auto left = left_value->resolve_as_list(shell);
- auto right = right_value->resolve_as_list(shell);
+ auto left = left_value->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors();
+ auto right = right_value->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors();
if (m_mode == Mode::StringExpand) {
- Vector<DeprecatedString> result;
+ Vector<String> result;
result.ensure_capacity(left.size() + right.size());
for (auto& left_item : left)
@@ -3064,7 +3067,7 @@ RefPtr<Value> Juxtaposition::run(RefPtr<Shell> shell)
if (!result.is_empty() && !right.is_empty()) {
auto& last = result.last();
- last = DeprecatedString::formatted("{}{}", last, right.first());
+ last = String::formatted("{}{}", last, right.first()).release_value_but_fixme_should_propagate_errors();
right.take_first();
}
for (auto& right_item : right)
@@ -3082,14 +3085,14 @@ RefPtr<Value> Juxtaposition::run(RefPtr<Shell> shell)
builder.append(left[0]);
builder.append(right[0]);
- return make_ref_counted<StringValue>(builder.to_deprecated_string());
+ return make_ref_counted<StringValue>(builder.to_string().release_value_but_fixme_should_propagate_errors());
}
// Otherwise, treat them as lists and create a list product (or just append).
if (left.is_empty() || right.is_empty())
return make_ref_counted<ListValue>({});
- Vector<DeprecatedString> result;
+ Vector<String> result;
result.ensure_capacity(left.size() * right.size());
StringBuilder builder;
@@ -3097,7 +3100,7 @@ RefPtr<Value> Juxtaposition::run(RefPtr<Shell> shell)
for (auto& right_element : right) {
builder.append(left_element);
builder.append(right_element);
- result.append(builder.to_deprecated_string());
+ result.append(builder.to_string().release_value_but_fixme_should_propagate_errors());
builder.clear();
}
}
@@ -3113,8 +3116,8 @@ void Juxtaposition::highlight_in_editor(Line::Editor& editor, Shell& shell, High
// since that resolution is a pure operation, we can just go ahead
// and do it to get the value :)
if (m_right->is_bareword() && m_left->is_tilde()) {
- auto tilde_value = m_left->run(shell)->resolve_as_list(shell)[0];
- auto bareword_value = m_right->run(shell)->resolve_as_list(shell)[0];
+ auto tilde_value = m_left->run(shell)->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors()[0];
+ auto bareword_value = m_right->run(shell)->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors()[0];
StringBuilder path_builder;
path_builder.append(tilde_value);
@@ -3143,14 +3146,14 @@ Vector<Line::CompletionSuggestion> Juxtaposition::complete_for_editor(Shell& she
// '~/foo/bar' is special, we have to actually resolve the tilde
// then complete the bareword with that path prefix.
- auto left_values = m_left->run(shell)->resolve_as_list(shell);
+ auto left_values = m_left->run(shell)->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors();
if (left_values.is_empty())
return m_right->complete_for_editor(shell, offset, hit_test_result);
auto& left_value = left_values.first();
- auto right_values = m_right->run(shell)->resolve_as_list(shell);
+ auto right_values = m_right->run(shell)->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors();
StringView right_value {};
auto corrected_offset = offset - matching_node->position().start_offset;
@@ -3221,7 +3224,7 @@ void StringLiteral::highlight_in_editor(Line::Editor& editor, Shell&, HighlightM
editor.stylize({ m_position.start_offset, m_position.end_offset }, move(style));
}
-StringLiteral::StringLiteral(Position position, DeprecatedString text, EnclosureType enclosure_type)
+StringLiteral::StringLiteral(Position position, String text, EnclosureType enclosure_type)
: Node(move(position))
, m_text(move(text))
, m_enclosure_type(enclosure_type)
@@ -3241,11 +3244,11 @@ void StringPartCompose::dump(int level) const
RefPtr<Value> StringPartCompose::run(RefPtr<Shell> shell)
{
- auto left = m_left->run(shell)->resolve_as_list(shell);
+ auto left = m_left->run(shell)->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors();
if (shell && shell->has_any_error())
return make_ref_counted<ListValue>({});
- auto right = m_right->run(shell)->resolve_as_list(shell);
+ auto right = m_right->run(shell)->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors();
if (shell && shell->has_any_error())
return make_ref_counted<ListValue>({});
@@ -3253,7 +3256,7 @@ RefPtr<Value> StringPartCompose::run(RefPtr<Shell> shell)
builder.join(' ', left);
builder.join(' ', right);
- return make_ref_counted<StringValue>(builder.to_deprecated_string());
+ return make_ref_counted<StringValue>(builder.to_string().release_value_but_fixme_should_propagate_errors());
}
void StringPartCompose::highlight_in_editor(Line::Editor& editor, Shell& shell, HighlightMetadata metadata)
@@ -3296,8 +3299,8 @@ void SyntaxError::dump(int level) const
RefPtr<Value> SyntaxError::run(RefPtr<Shell> shell)
{
- shell->raise_error(Shell::ShellError::EvaluatedSyntaxError, m_syntax_error_text, position());
- return make_ref_counted<StringValue>("");
+ shell->raise_error(Shell::ShellError::EvaluatedSyntaxError, m_syntax_error_text.to_deprecated_string(), position());
+ return make_ref_counted<StringValue>(String {});
}
void SyntaxError::highlight_in_editor(Line::Editor& editor, Shell&, HighlightMetadata)
@@ -3305,7 +3308,7 @@ void SyntaxError::highlight_in_editor(Line::Editor& editor, Shell&, HighlightMet
editor.stylize({ m_position.start_offset, m_position.end_offset }, { Line::Style::Foreground(Line::Style::XtermColor::Red), Line::Style::Bold });
}
-SyntaxError::SyntaxError(Position position, DeprecatedString error, bool is_continuable)
+SyntaxError::SyntaxError(Position position, String error, bool is_continuable)
: Node(move(position))
, m_syntax_error_text(move(error))
, m_is_continuable(is_continuable)
@@ -3375,21 +3378,21 @@ Vector<Line::CompletionSuggestion> Tilde::complete_for_editor(Shell& shell, size
auto corrected_offset = offset - matching_node->position().start_offset - 1;
- if (corrected_offset > m_username.length() + 1)
+ if (corrected_offset > m_username.bytes_as_string_view().length() + 1)
return {};
return shell.complete_user(m_username, corrected_offset);
}
-DeprecatedString Tilde::text() const
+String Tilde::text() const
{
StringBuilder builder;
builder.append('~');
builder.append(m_username);
- return builder.to_deprecated_string();
+ return builder.to_string().release_value_but_fixme_should_propagate_errors();
}
-Tilde::Tilde(Position position, DeprecatedString username)
+Tilde::Tilde(Position position, String username)
: Node(move(position))
, m_username(move(username))
{
@@ -3409,14 +3412,14 @@ void WriteAppendRedirection::dump(int level) const
RefPtr<Value> WriteAppendRedirection::run(RefPtr<Shell> shell)
{
Command command;
- auto path_segments = m_path->run(shell)->resolve_as_list(shell);
+ auto path_segments = m_path->run(shell)->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors();
if (shell && shell->has_any_error())
return make_ref_counted<ListValue>({});
StringBuilder builder;
builder.join(' ', path_segments);
- command.redirections.append(PathRedirection::create(builder.to_deprecated_string(), m_fd, PathRedirection::WriteAppend));
+ command.redirections.append(PathRedirection::create(builder.to_string().release_value_but_fixme_should_propagate_errors(), m_fd, PathRedirection::WriteAppend));
return make_ref_counted<CommandValue>(move(command));
}
@@ -3439,14 +3442,14 @@ void WriteRedirection::dump(int level) const
RefPtr<Value> WriteRedirection::run(RefPtr<Shell> shell)
{
Command command;
- auto path_segments = m_path->run(shell)->resolve_as_list(shell);
+ auto path_segments = m_path->run(shell)->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors();
if (shell && shell->has_any_error())
return make_ref_counted<ListValue>({});
StringBuilder builder;
builder.join(' ', path_segments);
- command.redirections.append(PathRedirection::create(builder.to_deprecated_string(), m_fd, PathRedirection::Write));
+ command.redirections.append(PathRedirection::create(builder.to_string().release_value_but_fixme_should_propagate_errors(), m_fd, PathRedirection::Write));
return make_ref_counted<CommandValue>(move(command));
}
@@ -3472,7 +3475,7 @@ void VariableDeclarations::dump(int level) const
RefPtr<Value> VariableDeclarations::run(RefPtr<Shell> shell)
{
for (auto& var : m_variables) {
- auto name_value = var.name->run(shell)->resolve_as_list(shell);
+ auto name_value = var.name->run(shell)->resolve_as_list(shell).release_value_but_fixme_should_propagate_errors();
if (shell && shell->has_any_error())
break;
@@ -3481,9 +3484,9 @@ RefPtr<Value> VariableDeclarations::run(RefPtr<Shell> shell)
auto value = var.value->run(shell);
if (shell && shell->has_any_error())
break;
- value = value->resolve_without_cast(shell);
+ value = value->resolve_without_cast(shell).release_value_but_fixme_should_propagate_errors();
- shell->set_local_variable(name, value.release_nonnull());
+ shell->set_local_variable(name.to_deprecated_string(), value.release_nonnull());
}
return make_ref_counted<ListValue>({});
@@ -3535,21 +3538,21 @@ Value::~Value()
{
}
-DeprecatedString Value::resolve_as_string(RefPtr<Shell> shell)
+ErrorOr<String> Value::resolve_as_string(RefPtr<Shell> shell)
{
if (shell)
shell->raise_error(Shell::ShellError::EvaluatedSyntaxError, "Conversion to string not allowed");
- return {};
+ return String {};
}
-Vector<AST::Command> Value::resolve_as_commands(RefPtr<Shell> shell)
+ErrorOr<Vector<AST::Command>> Value::resolve_as_commands(RefPtr<Shell> shell)
{
Command command;
- command.argv = resolve_as_list(shell);
- return { command };
+ command.argv = TRY(resolve_as_list(shell));
+ return Vector { move(command) };
}
-ListValue::ListValue(Vector<DeprecatedString> values)
+ListValue::ListValue(Vector<String> values)
{
if (values.is_empty())
return;
@@ -3558,16 +3561,16 @@ ListValue::ListValue(Vector<DeprecatedString> values)
m_contained_values.append(adopt_ref(*new StringValue(move(str))));
}
-NonnullRefPtr<Value> Value::with_slices(NonnullRefPtr<Slice> slice) const&
+ErrorOr<NonnullRefPtr<Value>> Value::with_slices(NonnullRefPtr<Slice> slice) const&
{
- auto value = clone();
+ auto value = TRY(clone());
value->m_slices.append(move(slice));
return value;
}
-NonnullRefPtr<Value> Value::with_slices(NonnullRefPtrVector<Slice> slices) const&
+ErrorOr<NonnullRefPtr<Value>> Value::with_slices(NonnullRefPtrVector<Slice> slices) const&
{
- auto value = clone();
+ auto value = TRY(clone());
value->m_slices.extend(move(slices));
return value;
}
@@ -3576,24 +3579,24 @@ ListValue::~ListValue()
{
}
-Vector<DeprecatedString> ListValue::resolve_as_list(RefPtr<Shell> shell)
+ErrorOr<Vector<String>> ListValue::resolve_as_list(RefPtr<Shell> shell)
{
- Vector<DeprecatedString> values;
+ Vector<String> values;
for (auto& value : m_contained_values)
- values.extend(value.resolve_as_list(shell));
+ values.extend(TRY(value.resolve_as_list(shell)));
return resolve_slices(shell, move(values), m_slices);
}
-NonnullRefPtr<Value> ListValue::resolve_without_cast(RefPtr<Shell> shell)
+ErrorOr<NonnullRefPtr<Value>> ListValue::resolve_without_cast(RefPtr<Shell> shell)
{
NonnullRefPtrVector<Value> values;
for (auto& value : m_contained_values)
- values.append(value.resolve_without_cast(shell));
+ values.append(TRY(value.resolve_without_cast(shell)));
NonnullRefPtr<Value> value = make_ref_counted<ListValue>(move(values));
if (!m_slices.is_empty())
- value = value->with_slices(m_slices);
+ value = TRY(value->with_slices(m_slices));
return value;
}
@@ -3605,25 +3608,25 @@ CommandSequenceValue::~CommandSequenceValue()
{
}
-Vector<DeprecatedString> CommandSequenceValue::resolve_as_list(RefPtr<Shell> shell)
+ErrorOr<Vector<String>> CommandSequenceValue::resolve_as_list(RefPtr<Shell> shell)
{
shell->raise_error(Shell::ShellError::EvaluatedSyntaxError, "Unexpected cast of a command sequence to a list");
- return {};
+ return Vector<String> {};
}
-Vector<Command> CommandSequenceValue::resolve_as_commands(RefPtr<Shell>)
+ErrorOr<Vector<Command>> CommandSequenceValue::resolve_as_commands(RefPtr<Shell>)
{
return m_contained_values;
}
-Vector<DeprecatedString> CommandValue::resolve_as_list(RefPtr<Shell>)
+ErrorOr<Vector<String>> CommandValue::resolve_as_list(RefPtr<Shell>)
{
return m_command.argv;
}
-Vector<Command> CommandValue::resolve_as_commands(RefPtr<Shell>)
+ErrorOr<Vector<Command>> CommandValue::resolve_as_commands(RefPtr<Shell>)
{
- return { m_command };
+ return Vector { m_command };
}
JobValue::~JobValue()
@@ -3634,31 +3637,31 @@ StringValue::~StringValue()
{
}
-DeprecatedString StringValue::resolve_as_string(RefPtr<Shell> shell)
+ErrorOr<String> StringValue::resolve_as_string(RefPtr<Shell> shell)
{
- if (m_split.is_null())
+ if (m_split.is_empty())
return m_string;
return Value::resolve_as_string(shell);
}
-Vector<DeprecatedString> StringValue::resolve_as_list(RefPtr<Shell> shell)
+ErrorOr<Vector<String>> StringValue::resolve_as_list(RefPtr<Shell> shell)
{
if (is_list()) {
auto parts = StringView(m_string).split_view(m_split, m_keep_empty ? SplitBehavior::KeepEmpty : SplitBehavior::Nothing);
- Vector<DeprecatedString> result;
+ Vector<String> result;
result.ensure_capacity(parts.size());
for (auto& part : parts)
- result.append(part);
+ result.append(TRY(String::from_utf8(part)));
return resolve_slices(shell, move(result), m_slices);
}
- return { resolve_slices(shell, DeprecatedString { m_string }, m_slices) };
+ return Vector<String> { resolve_slices(shell, Vector { m_string }, m_slices) };
}
-NonnullRefPtr<Value> StringValue::resolve_without_cast(RefPtr<Shell> shell)
+ErrorOr<NonnullRefPtr<Value>> StringValue::resolve_without_cast(RefPtr<Shell> shell)
{
if (is_list())
- return make_ref_counted<AST::ListValue>(resolve_as_list(shell)); // No need to reapply the slices.
+ return try_make_ref_counted<AST::ListValue>(TRY(resolve_as_list(shell))); // No need to reapply the slices.
return *this;
}
@@ -3666,49 +3669,59 @@ NonnullRefPtr<Value> StringValue::resolve_without_cast(RefPtr<Shell> shell)
GlobValue::~GlobValue()
{
}
-Vector<DeprecatedString> GlobValue::resolve_as_list(RefPtr<Shell> shell)
+
+ErrorOr<Vector<String>> GlobValue::resolve_as_list(RefPtr<Shell> shell)
{
if (!shell)
- return { resolve_slices(shell, DeprecatedString { m_glob }, m_slices) };
+ return resolve_slices(shell, Vector { m_glob }, m_slices);
auto results = shell->expand_globs(m_glob, shell->cwd);
if (results.is_empty())
shell->raise_error(Shell::ShellError::InvalidGlobError, "Glob did not match anything!", m_generation_position);
- return resolve_slices(shell, move(results), m_slices);
+
+ Vector<String> strings;
+ TRY(strings.try_ensure_capacity(results.size()));
+ for (auto& entry : results) {
+ TRY(strings.try_append(TRY(String::from_utf8(entry))));
+ }
+
+ return resolve_slices(shell, move(strings), m_slices);
}
SimpleVariableValue::~SimpleVariableValue()
{
}
-DeprecatedString SimpleVariableValue::resolve_as_string(RefPtr<Shell> shell)
+ErrorOr<String> SimpleVariableValue::resolve_as_string(RefPtr<Shell> shell)
{
if (!shell)
- return resolve_slices(shell, DeprecatedString {}, m_slices);
+ return resolve_slices(shell, String {}, m_slices);
- if (auto value = resolve_without_cast(shell); value != this)
+ if (auto value = TRY(resolve_without_cast(shell)); value != this)
return value->resolve_as_string(shell);
- char* env_value = getenv(m_name.characters());
- return resolve_slices(shell, env_value, m_slices);
+ auto name = m_name.to_deprecated_string();
+ char* env_value = getenv(name.characters());
+ return resolve_slices(shell, TRY(String::from_utf8(StringView { env_value, strlen(env_value) })), m_slices);
}
-Vector<DeprecatedString> SimpleVariableValue::resolve_as_list(RefPtr<Shell> shell)
+ErrorOr<Vector<String>> SimpleVariableValue::resolve_as_list(RefPtr<Shell> shell)
{
if (!shell)
- return resolve_slices(shell, Vector<DeprecatedString> {}, m_slices);
+ return resolve_slices(shell, Vector<String> {}, m_slices);
- if (auto value = resolve_without_cast(shell); value != this)
+ if (auto value = TRY(resolve_without_cast(shell)); value != this)
return value->resolve_as_list(shell);
- char* env_value = getenv(m_name.characters());
+ auto name = m_name.to_deprecated_string();
+ char* env_value = getenv(name.characters());
if (env_value == nullptr)
- return { resolve_slices(shell, "", m_slices) };
+ return { resolve_slices(shell, Vector { String {} }, m_slices) };
- return { resolve_slices(shell, DeprecatedString { env_value }, m_slices) };
+ return { resolve_slices(shell, Vector { TRY(String::from_utf8(StringView { env_value, strlen(env_value) })) }, m_slices) };
}
-NonnullRefPtr<Value> SimpleVariableValue::resolve_without_cast(RefPtr<Shell> shell)
+ErrorOr<NonnullRefPtr<Value>> SimpleVariableValue::resolve_without_cast(RefPtr<Shell> shell)
{
VERIFY(shell);
@@ -3716,7 +3729,7 @@ NonnullRefPtr<Value> SimpleVariableValue::resolve_without_cast(RefPtr<Shell> she
auto result = value.release_nonnull();
// If a slice is applied, add it.
if (!m_slices.is_empty())
- result = result->with_slices(m_slices);
+ result = TRY(result->with_slices(m_slices));
return const_cast<Value&>(*result);
}
@@ -3728,76 +3741,76 @@ SpecialVariableValue::~SpecialVariableValue()
{
}
-DeprecatedString SpecialVariableValue::resolve_as_string(RefPtr<Shell> shell)
+ErrorOr<String> SpecialVariableValue::resolve_as_string(RefPtr<Shell> shell)
{
if (!shell)
- return {};
+ return String {};
- auto result = resolve_as_list(shell);
+ auto result = TRY(resolve_as_list(shell));
if (result.size() == 1)
return result[0];
if (result.is_empty())
- return {};
+ return String {};
return Value::resolve_as_string(shell);
}
-Vector<DeprecatedString> SpecialVariableValue::resolve_as_list(RefPtr<Shell> shell)
+ErrorOr<Vector<String>> SpecialVariableValue::resolve_as_list(RefPtr<Shell> shell)
{
if (!shell)
- return {};
+ return Vector<String> {};
switch (m_name) {
case '?':
- return { resolve_slices(shell, DeprecatedString::number(shell->last_return_code.value_or(0)), m_slices) };
+ return { resolve_slices(shell, Vector { TRY(String::number(shell->last_return_code.value_or(0))) }, m_slices) };
case '$':
- return { resolve_slices(shell, DeprecatedString::number(getpid()), m_slices) };
+ return { resolve_slices(shell, Vector { TRY(String::number(getpid())) }, m_slices) };
case '*':
if (auto argv = shell->lookup_local_variable("ARGV"sv))
- return resolve_slices(shell, const_cast<Value&>(*argv).resolve_as_list(shell), m_slices);
- return resolve_slices(shell, Vector<DeprecatedString> {}, m_slices);
+ return resolve_slices(shell, TRY(const_cast<Value&>(*argv).resolve_as_list(shell)), m_slices);
+ return resolve_slices(shell, Vector<String> {}, m_slices);
case '#':
if (auto argv = shell->lookup_local_variable("ARGV"sv)) {
if (argv->is_list()) {
auto list_argv = static_cast<AST::ListValue const*>(argv.ptr());
- return { resolve_slices(shell, DeprecatedString::number(list_argv->values().size()), m_slices) };
+ return { resolve_slices(shell, Vector { TRY(String::number(list_argv->values().size())) }, m_slices) };
}
- return { resolve_slices(shell, "1", m_slices) };
+ return { resolve_slices(shell, Vector { String::from_utf8_short_string("1"sv) }, m_slices) };
}
- return { resolve_slices(shell, "0", m_slices) };
+ return { resolve_slices(shell, Vector { String::from_utf8_short_string("0"sv) }, m_slices) };
default:
- return { resolve_slices(shell, "", m_slices) };
+ return { resolve_slices(shell, Vector { String::from_utf8_short_string(""sv) }, m_slices) };
}
}
-NonnullRefPtr<Value> SpecialVariableValue::resolve_without_cast(RefPtr<Shell> shell)
+ErrorOr<NonnullRefPtr<Value>> SpecialVariableValue::resolve_without_cast(RefPtr<Shell> shell)
{
if (!shell)
return *this;
- return make_ref_counted<ListValue>(resolve_as_list(shell));
+ return try_make_ref_counted<ListValue>(TRY(resolve_as_list(shell)));
}
TildeValue::~TildeValue()
{
}
-DeprecatedString TildeValue::resolve_as_string(RefPtr<Shell> shell)
+ErrorOr<String> TildeValue::resolve_as_string(RefPtr<Shell> shell)
{
- return resolve_as_list(shell).first();
+ return TRY(resolve_as_list(shell)).first();
}
-Vector<DeprecatedString> TildeValue::resolve_as_list(RefPtr<Shell> shell)
+ErrorOr<Vector<String>> TildeValue::resolve_as_list(RefPtr<Shell> shell)
{
StringBuilder builder;
builder.append('~');
builder.append(m_username);
if (!shell)
- return { resolve_slices(shell, builder.to_deprecated_string(), m_slices) };
+ return { resolve_slices(shell, Vector { TRY(builder.to_string()) }, m_slices) };
- return { resolve_slices(shell, shell->expand_tilde(builder.to_deprecated_string()), m_slices) };
+ return { resolve_slices(shell, Vector { TRY(String::from_utf8(shell->expand_tilde(builder.to_deprecated_string()))) }, m_slices) };
}
ErrorOr<NonnullRefPtr<Rewiring>> CloseRedirection::apply() const
@@ -3811,7 +3824,7 @@ CloseRedirection::~CloseRedirection()
ErrorOr<NonnullRefPtr<Rewiring>> PathRedirection::apply() const
{
- auto check_fd_and_return = [my_fd = this->fd](int fd, DeprecatedString const& path) -> ErrorOr<NonnullRefPtr<Rewiring>> {
+ auto check_fd_and_return = [my_fd = this->fd](int fd, String const& path) -> ErrorOr<NonnullRefPtr<Rewiring>> {
if (fd < 0) {
auto error = Error::from_errno(errno);
dbgln("open() failed for '{}' with {}", path, error);
@@ -3819,18 +3832,20 @@ ErrorOr<NonnullRefPtr<Rewiring>> PathRedirection::apply() const
}
return adopt_nonnull_ref_or_enomem(new (nothrow) Rewiring(fd, my_fd, Rewiring::Close::Old));
};
+
+ auto path_string = path.to_deprecated_string();
switch (direction) {
case AST::PathRedirection::WriteAppend:
- return check_fd_and_return(open(path.characters(), O_WRONLY | O_CREAT | O_APPEND, 0666), path);
+ return check_fd_and_return(open(path_string.characters(), O_WRONLY | O_CREAT | O_APPEND, 0666), path);
case AST::PathRedirection::Write:
- return check_fd_and_return(open(path.characters(), O_WRONLY | O_CREAT | O_TRUNC, 0666), path);
+ return check_fd_and_return(open(path_string.characters(), O_WRONLY | O_CREAT | O_TRUNC, 0666), path);
case AST::PathRedirection::Read:
- return check_fd_and_return(open(path.characters(), O_RDONLY), path);
+ return check_fd_and_return(open(path_string.characters(), O_RDONLY), path);
case AST::PathRedirection::ReadWrite:
- return check_fd_and_return(open(path.characters(), O_RDWR | O_CREAT, 0666), path);
+ return check_fd_and_return(open(path_string.characters(), O_RDWR | O_CREAT, 0666), path);
}
VERIFY_NOT_REACHED();
diff --git a/Userland/Shell/AST.h b/Userland/Shell/AST.h
index 4d68c7848a..dd766d73da 100644
--- a/Userland/Shell/AST.h
+++ b/Userland/Shell/AST.h
@@ -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 {
diff --git a/Userland/Shell/Builtin.cpp b/Userland/Shell/Builtin.cpp
index a4e78b8604..0e51867ecd 100644
--- a/Userland/Shell/Builtin.cpp
+++ b/Userland/Shell/Builtin.cpp
@@ -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;
},
});
diff --git a/Userland/Shell/Formatter.cpp b/Userland/Shell/Formatter.cpp
index 9f7aea7820..3c1ac9aad3 100644
--- a/Userland/Shell/Formatter.cpp
+++ b/Userland/Shell/Formatter.cpp
@@ -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 '\\':
diff --git a/Userland/Shell/Formatter.h b/Userland/Shell/Formatter.h
index ac58e54ec2..00e29bf889 100644
--- a/Userland/Shell/Formatter.h
+++ b/Userland/Shell/Formatter.h
@@ -6,6 +6,7 @@
#pragma once
+#include "AST.h"
#include "NodeVisitor.h"
#include <AK/DeprecatedString.h>
#include <AK/Forward.h>
diff --git a/Userland/Shell/ImmediateFunctions.cpp b/Userland/Shell/ImmediateFunctions.cpp
index 647bafb80d..7a0d1e2f31 100644
--- a/Userland/Shell/ImmediateFunctions.cpp
+++ b/Userland/Shell/ImmediateFunctions.cpp
@@ -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(
diff --git a/Userland/Shell/Parser.cpp b/Userland/Shell/Parser.cpp
index 43ec26b497..ec9ec35f99 100644
--- a/Userland/Shell/Parser.cpp
+++ b/Userland/Shell/Parser.cpp
@@ -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)));
diff --git a/Userland/Shell/Parser.h b/Userland/Shell/Parser.h
index 91da805da4..802489d9b0 100644
--- a/Userland/Shell/Parser.h
+++ b/Userland/Shell/Parser.h
@@ -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 };
diff --git a/Userland/Shell/PosixParser.cpp b/Userland/Shell/PosixParser.cpp
index 427971c74e..fea91a5b95 100644
--- a/Userland/Shell/PosixParser.cpp
+++ b/Userland/Shell/PosixParser.cpp
@@ -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)
diff --git a/Userland/Shell/Shell.cpp b/Userland/Shell/Shell.cpp
index ef1e94ac93..5d288a34be 100644
--- a/Userland/Shell/Shell.cpp
+++ b/Userland/Shell/Shell.cpp
@@ -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())
diff --git a/Userland/Shell/main.cpp b/Userland/Shell/main.cpp
index 043e43c0e9..1ed6c8803e 100644
--- a/Userland/Shell/main.cpp
+++ b/Userland/Shell/main.cpp
@@ -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);