refactor(patch): initialize DiffHunk with all the information accessible immediately

This commit is contained in:
Aleksey Kulikov 2022-04-22 13:14:57 +03:00
parent 28f08e308a
commit 77a34c3335
4 changed files with 167 additions and 149 deletions

View file

@ -4,7 +4,6 @@ import 'package:ffi/ffi.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/diff.dart' as bindings;
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/bindings/patch.dart' as patch_bindings;
import 'package:libgit2dart/src/util.dart';
class Diff {
@ -602,112 +601,3 @@ final _statsFinalizer = Finalizer<Pointer<git_diff_stats>>(
(pointer) => bindings.statsFree(pointer),
);
// coverage:ignore-end
class DiffHunk {
/// Initializes a new instance of [DiffHunk] class from provided
/// pointers to patch object and diff hunk object in memory and number of
/// lines in hunk.
const DiffHunk(
this._patchPointer,
this._diffHunkPointer,
this.linesCount,
this.index,
);
/// Pointer to memory address for allocated diff hunk object.
final Pointer<git_diff_hunk> _diffHunkPointer;
/// Pointer to memory address for allocated patch object.
final Pointer<git_patch> _patchPointer;
/// Number of total lines in this hunk.
final int linesCount;
/// Index of this hunk in the patch.
final int index;
/// Starting line number in 'old file'.
int get oldStart => _diffHunkPointer.ref.old_start;
/// Number of lines in 'old file'.
int get oldLines => _diffHunkPointer.ref.old_lines;
/// Starting line number in 'new file'.
int get newStart => _diffHunkPointer.ref.new_start;
/// Number of lines in 'new file'.
int get newLines => _diffHunkPointer.ref.new_lines;
/// Header of a hunk.
String get header {
final list = <int>[];
for (var i = 0; i < _diffHunkPointer.ref.header_len; i++) {
list.add(_diffHunkPointer.ref.header[i]);
}
return String.fromCharCodes(list);
}
/// List of lines in a hunk of a patch.
List<DiffLine> get lines {
final lines = <DiffLine>[];
for (var i = 0; i < linesCount; i++) {
lines.add(
DiffLine(
patch_bindings.lines(
patchPointer: _patchPointer,
hunkIndex: index,
lineOfHunk: i,
),
),
);
}
return lines;
}
@override
String toString() {
return 'DiffHunk{linesCount: $linesCount, index: $index, '
'oldStart: $oldStart, oldLines: $oldLines, newStart: $newStart, '
'newLines: $newLines, header: $header}';
}
}
class DiffLine {
/// Initializes a new instance of [DiffLine] class from provided
/// pointer to diff line object in memory.
const DiffLine(this._diffLinePointer);
/// Pointer to memory address for allocated diff line object.
final Pointer<git_diff_line> _diffLinePointer;
/// Type of the line.
GitDiffLine get origin {
return GitDiffLine.values.singleWhere(
(e) => _diffLinePointer.ref.origin == e.value,
);
}
/// Line number in old file or -1 for added line.
int get oldLineNumber => _diffLinePointer.ref.old_lineno;
/// Line number in new file or -1 for deleted line.
int get newLineNumber => _diffLinePointer.ref.new_lineno;
/// Number of newline characters in content.
int get numLines => _diffLinePointer.ref.num_lines;
/// Offset in the original file to the content.
int get contentOffset => _diffLinePointer.ref.content_offset;
/// Content of the diff line.
String get content => _diffLinePointer.ref.content
.cast<Utf8>()
.toDartString(length: _diffLinePointer.ref.content_len);
@override
String toString() {
return 'DiffLine{oldLineNumber: $oldLineNumber, '
'newLineNumber: $newLineNumber, numLines: $numLines, '
'contentOffset: $contentOffset, content: $content}';
}
}

View file

@ -1,5 +1,6 @@
import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/bindings/patch.dart' as bindings;
@ -197,14 +198,49 @@ class Patch {
final length = bindings.numHunks(_patchPointer);
final hunks = <DiffHunk>[];
for (var i = 0; i < length; i++) {
final hunk = bindings.hunk(patchPointer: _patchPointer, hunkIndex: i);
for (var index = 0; index < length; index++) {
final hunk = bindings.hunk(patchPointer: _patchPointer, hunkIndex: index);
final hunkPointer = hunk['hunk']! as Pointer<git_diff_hunk>;
final linesCount = hunk['linesN']! as int;
final lines = <DiffLine>[];
for (var i = 0; i < linesCount; i++) {
final linePointer = bindings.lines(
patchPointer: _patchPointer,
hunkIndex: index,
lineOfHunk: i,
);
lines.add(
DiffLine._(
origin: GitDiffLine.values.singleWhere(
(e) => linePointer.ref.origin == e.value,
),
oldLineNumber: linePointer.ref.old_lineno,
newLineNumber: linePointer.ref.new_lineno,
numLines: linePointer.ref.num_lines,
contentOffset: linePointer.ref.content_offset,
content: linePointer.ref.content
.cast<Utf8>()
.toDartString(length: linePointer.ref.content_len),
),
);
}
final intHeader = <int>[];
for (var i = 0; i < hunkPointer.ref.header_len; i++) {
intHeader.add(hunkPointer.ref.header[i]);
}
hunks.add(
DiffHunk(
_patchPointer,
hunk['hunk']! as Pointer<git_diff_hunk>,
hunk['linesN']! as int,
i,
DiffHunk._(
linesCount: linesCount,
index: index,
oldStart: hunkPointer.ref.old_start,
oldLines: hunkPointer.ref.old_lines,
newStart: hunkPointer.ref.new_start,
newLines: hunkPointer.ref.new_lines,
header: String.fromCharCodes(intHeader),
lines: lines,
),
);
}
@ -251,3 +287,83 @@ class PatchStats {
'deletions: $deletions}';
}
}
class DiffHunk {
const DiffHunk._({
required this.linesCount,
required this.index,
required this.oldStart,
required this.oldLines,
required this.newStart,
required this.newLines,
required this.header,
required this.lines,
});
/// Number of total lines in this hunk.
final int linesCount;
/// Index of this hunk in the patch.
final int index;
/// Starting line number in 'old file'.
final int oldStart;
/// Number of lines in 'old file'.
final int oldLines;
/// Starting line number in 'new file'.
final int newStart;
/// Number of lines in 'new file'.
final int newLines;
/// Header of a hunk.
final String header;
/// List of lines in a hunk of a patch.
final List<DiffLine> lines;
@override
String toString() {
return 'DiffHunk{linesCount: $linesCount, index: $index, '
'oldStart: $oldStart, oldLines: $oldLines, newStart: $newStart, '
'newLines: $newLines, header: $header}';
}
}
class DiffLine {
const DiffLine._({
required this.origin,
required this.oldLineNumber,
required this.newLineNumber,
required this.numLines,
required this.contentOffset,
required this.content,
});
/// Type of the line.
final GitDiffLine origin;
/// Line number in old file or -1 for added line.
final int oldLineNumber;
/// Line number in new file or -1 for deleted line.
final int newLineNumber;
/// Number of newline characters in content.
final int numLines;
/// Offset in the original file to the content.
final int contentOffset;
/// Content of the diff line.
final String content;
@override
String toString() {
return 'DiffLine{oldLineNumber: $oldLineNumber, '
'newLineNumber: $newLineNumber, numLines: $numLines, '
'contentOffset: $contentOffset, content: $content}';
}
}