mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 13:48:12 +00:00
LibDiff: Make Diff::from_text fallible
This commit is contained in:
parent
23df5748f6
commit
ee92378b80
5 changed files with 22 additions and 17 deletions
|
@ -55,7 +55,7 @@ void SemanticSyntaxHighlighter::rehighlight(Palette const& palette)
|
||||||
|
|
||||||
// FIXME: Computing the diff on the entire document's tokens is quite inefficient.
|
// FIXME: Computing the diff on the entire document's tokens is quite inefficient.
|
||||||
// An improvement over this could be only including the tokens that are in edited text ranges in the diff.
|
// An improvement over this could be only including the tokens that are in edited text ranges in the diff.
|
||||||
auto diff_hunks = Diff::from_text(previous.view(), current.view());
|
auto diff_hunks = Diff::from_text(previous.view(), current.view()).release_value_but_fixme_should_propagate_errors();
|
||||||
for (auto& token : current_tokens) {
|
for (auto& token : current_tokens) {
|
||||||
new_tokens_info.append(CodeComprehension::TokenInfo { CodeComprehension::TokenInfo::SemanticType::Unknown,
|
new_tokens_info.append(CodeComprehension::TokenInfo { CodeComprehension::TokenInfo::SemanticType::Unknown,
|
||||||
token.start().line, token.start().column, token.end().line, token.end().column });
|
token.start().line, token.start().column, token.end().line, token.end().column });
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
namespace Diff {
|
namespace Diff {
|
||||||
|
|
||||||
Vector<Hunk> from_text(StringView old_text, StringView new_text)
|
ErrorOr<Vector<Hunk>> from_text(StringView old_text, StringView new_text)
|
||||||
{
|
{
|
||||||
auto old_lines = old_text.lines();
|
auto old_lines = old_text.lines();
|
||||||
auto new_lines = new_text.lines();
|
auto new_lines = new_text.lines();
|
||||||
|
@ -33,7 +33,7 @@ Vector<Hunk> from_text(StringView old_text, StringView new_text)
|
||||||
};
|
};
|
||||||
|
|
||||||
auto dp_matrix = Vector<Cell>();
|
auto dp_matrix = Vector<Cell>();
|
||||||
dp_matrix.resize((old_lines.size() + 1) * (new_lines.size() + 1));
|
TRY(dp_matrix.try_resize((old_lines.size() + 1) * (new_lines.size() + 1)));
|
||||||
|
|
||||||
auto dp = [&dp_matrix, width = old_lines.size() + 1](size_t i, size_t j) -> Cell& {
|
auto dp = [&dp_matrix, width = old_lines.size() + 1](size_t i, size_t j) -> Cell& {
|
||||||
return dp_matrix[i + width * j];
|
return dp_matrix[i + width * j];
|
||||||
|
@ -66,27 +66,31 @@ Vector<Hunk> from_text(StringView old_text, StringView new_text)
|
||||||
Hunk cur_hunk;
|
Hunk cur_hunk;
|
||||||
bool in_hunk = false;
|
bool in_hunk = false;
|
||||||
|
|
||||||
auto update_hunk = [&](size_t i, size_t j, Direction direction) {
|
auto update_hunk = [&](size_t i, size_t j, Direction direction) -> ErrorOr<void> {
|
||||||
if (!in_hunk) {
|
if (!in_hunk) {
|
||||||
in_hunk = true;
|
in_hunk = true;
|
||||||
cur_hunk = { i, j, {}, {} };
|
cur_hunk = { i, j, {}, {} };
|
||||||
}
|
}
|
||||||
if (direction == Direction::Down) {
|
if (direction == Direction::Down) {
|
||||||
cur_hunk.added_lines.append(new_lines[j]);
|
TRY(cur_hunk.added_lines.try_append(new_lines[j]));
|
||||||
} else if (direction == Direction::Right) {
|
} else if (direction == Direction::Right) {
|
||||||
cur_hunk.removed_lines.append(old_lines[i]);
|
TRY(cur_hunk.removed_lines.try_append(old_lines[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
};
|
};
|
||||||
|
|
||||||
auto flush_hunk = [&]() {
|
auto flush_hunk = [&]() -> ErrorOr<void> {
|
||||||
if (in_hunk) {
|
if (in_hunk) {
|
||||||
if (cur_hunk.added_lines.size() > 0)
|
if (cur_hunk.added_lines.size() > 0)
|
||||||
cur_hunk.target_start_line++;
|
cur_hunk.target_start_line++;
|
||||||
if (cur_hunk.removed_lines.size() > 0)
|
if (cur_hunk.removed_lines.size() > 0)
|
||||||
cur_hunk.original_start_line++;
|
cur_hunk.original_start_line++;
|
||||||
hunks.append(cur_hunk);
|
TRY(hunks.try_append(cur_hunk));
|
||||||
in_hunk = false;
|
in_hunk = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
@ -95,28 +99,28 @@ Vector<Hunk> from_text(StringView old_text, StringView new_text)
|
||||||
while (i < old_lines.size() && j < new_lines.size()) {
|
while (i < old_lines.size() && j < new_lines.size()) {
|
||||||
auto& cell = dp(i, j);
|
auto& cell = dp(i, j);
|
||||||
if (cell.direction == Direction::Down) {
|
if (cell.direction == Direction::Down) {
|
||||||
update_hunk(i, j, cell.direction);
|
TRY(update_hunk(i, j, cell.direction));
|
||||||
++j;
|
++j;
|
||||||
} else if (cell.direction == Direction::Right) {
|
} else if (cell.direction == Direction::Right) {
|
||||||
update_hunk(i, j, cell.direction);
|
TRY(update_hunk(i, j, cell.direction));
|
||||||
++i;
|
++i;
|
||||||
} else {
|
} else {
|
||||||
++i;
|
++i;
|
||||||
++j;
|
++j;
|
||||||
flush_hunk();
|
TRY(flush_hunk());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (i < old_lines.size()) {
|
while (i < old_lines.size()) {
|
||||||
update_hunk(i, new_lines.is_empty() ? 0 : new_lines.size() - 1, Direction::Right); // Remove a line
|
TRY(update_hunk(i, new_lines.is_empty() ? 0 : new_lines.size() - 1, Direction::Right)); // Remove a line
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
while (j < new_lines.size()) {
|
while (j < new_lines.size()) {
|
||||||
update_hunk(old_lines.is_empty() ? 0 : old_lines.size() - 1, j, Direction::Down); // Add a line
|
TRY(update_hunk(old_lines.is_empty() ? 0 : old_lines.size() - 1, j, Direction::Down)); // Add a line
|
||||||
++j;
|
++j;
|
||||||
}
|
}
|
||||||
|
|
||||||
flush_hunk();
|
TRY(flush_hunk());
|
||||||
|
|
||||||
return hunks;
|
return hunks;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Hunks.h"
|
#include "Hunks.h"
|
||||||
|
#include <AK/Error.h>
|
||||||
|
|
||||||
namespace Diff {
|
namespace Diff {
|
||||||
|
|
||||||
Vector<Hunk> from_text(StringView old_text, StringView new_text);
|
ErrorOr<Vector<Hunk>> from_text(StringView old_text, StringView new_text);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
|
|
||||||
auto const color_output = TRY(Core::System::isatty(STDOUT_FILENO)) ? Diff::ColorOutput::Yes : Diff::ColorOutput::No;
|
auto const color_output = TRY(Core::System::isatty(STDOUT_FILENO)) ? Diff::ColorOutput::Yes : Diff::ColorOutput::No;
|
||||||
|
|
||||||
auto hunks = Diff::from_text(TRY(file1->read_until_eof()), TRY(file2->read_until_eof()));
|
auto hunks = TRY(Diff::from_text(TRY(file1->read_until_eof()), TRY(file2->read_until_eof())));
|
||||||
for (auto const& hunk : hunks)
|
for (auto const& hunk : hunks)
|
||||||
TRY(Diff::write_normal(hunk, *out, color_output));
|
TRY(Diff::write_normal(hunk, *out, color_output));
|
||||||
|
|
||||||
|
|
|
@ -254,7 +254,7 @@ static ErrorOr<TestResult> run_test(HeadlessWebContentView& view, StringView inp
|
||||||
else
|
else
|
||||||
outln("\nTest failed: {}", input_path);
|
outln("\nTest failed: {}", input_path);
|
||||||
|
|
||||||
auto hunks = Diff::from_text(expectation, actual);
|
auto hunks = TRY(Diff::from_text(expectation, actual));
|
||||||
auto out = TRY(Core::File::standard_output());
|
auto out = TRY(Core::File::standard_output());
|
||||||
for (auto const& hunk : hunks) {
|
for (auto const& hunk : hunks) {
|
||||||
TRY(out->write_formatted("Hunk: "));
|
TRY(out->write_formatted("Hunk: "));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue