Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,12 @@ public static CommitDiffResult createCommitDiff(
final CanonicalTreeParser currentTreeParser = new CanonicalTreeParser();
final CanonicalTreeParser prevTreeParser = new CanonicalTreeParser();
try (ObjectReader reader = repository.getGitRepo().getRepository().newObjectReader()) {
try {
currentTreeParser.reset(reader, childCommit.getTree());
if (parentCommit != null) {
prevTreeParser.reset(reader, parentCommit.getTree());
}
} catch (IOException e) {
return CommitDiffResult.Failure(DiffError.JGIT_ERROR, e.toString());
currentTreeParser.reset(reader, childCommit.getTree());
if (parentCommit != null) {
prevTreeParser.reset(reader, parentCommit.getTree());
}
} catch (IOException e) {
return CommitDiffResult.Failure(DiffError.JGIT_ERROR, e.toString());
}

final AbstractTreeIterator parentTreeIterator;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public VariationDiffAdapter(Projection<L> node) {
super(node);
}

@Override
protected VariationTreeAdapter<L> newInstance(VariationNode<?, L> node) {
return new VariationDiffAdapter<>(Cast.unchecked(node));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.variantsync.diffdetective.variation.Label;
import org.variantsync.diffdetective.variation.tree.VariationNode;
Expand All @@ -24,15 +26,17 @@
public class VariationTreeAdapter<L extends Label> extends AbstractTree {
private String cachedLabel;
private VariationNode<?, L> backingNode;
private LinkedHashMap<String, Object> metadata;

public VariationTreeAdapter(VariationNode<?, L> node) {
this.backingNode = node;
this.metadata = new LinkedHashMap<>();

if (backingNode.isConditionalAnnotation()) {
cachedLabel = backingNode.getFormula().toString();
} else {
cachedLabel = backingNode.getLabel().getLines().stream().collect(Collectors.joining("\n"));
}
cachedLabel =
Stream.concat(
backingNode.getLabel().getLines().stream(),
backingNode.getLabel().getTrailingLines().stream()
).collect(Collectors.joining("\n"));

var children = new ArrayList<Tree>(node.getChildren().size());
for (var child : node.getChildren()) {
Expand All @@ -41,7 +45,7 @@ public VariationTreeAdapter(VariationNode<?, L> node) {
setChildren(children);
}

protected VariationTreeAdapter newInstance(VariationNode<?, L> node) {
protected VariationTreeAdapter<L> newInstance(VariationNode<?, L> node) {
return new VariationTreeAdapter<>(node);
}

Expand All @@ -65,12 +69,12 @@ public int getLength() {

@Override
public Iterator<Entry<String, Object>> getMetadata() {
throw new UnsupportedOperationException();
return metadata.entrySet().iterator();
}

@Override
public Object getMetadata(String arg0) {
throw new UnsupportedOperationException();
public Object getMetadata(String key) {
return metadata.get(key);
}

/**
Expand All @@ -97,8 +101,8 @@ public void setLength(int length) {
}

@Override
public Object setMetadata(String name, Object value) {
throw new UnsupportedOperationException();
public Object setMetadata(String key, Object value) {
return metadata.put(key, value);
}

@Override
Expand Down
12 changes: 9 additions & 3 deletions src/main/java/org/variantsync/diffdetective/util/Assert.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public static void assertFalse(boolean condition, String errorMessage) {
}

/** Throws {@link AssertionError} with {@code errorMessage} as error message. */
public static void fail(String errorMessage) {
public static <T> T fail(String errorMessage) {
Comment thread
pmbittner marked this conversation as resolved.
throw new AssertionError(errorMessage);
}

Expand All @@ -105,12 +105,18 @@ public static void assertNull(Object o) {
}

public static <T> void assertEquals(T expected, T actual) {
assertEquals(expected, actual, null);
}

public static <T> void assertEquals(T expected, T actual, String message) {
String prefix = message == null ? "" : message + ": ";

if (expected == null) {
if (actual != null) {
fail("expected is null but actual is not!");
fail(prefix + "expected is null but actually it is " + actual);
}
} else {
assertTrue(expected.equals(actual), expected + " != " + actual);
assertTrue(expected.equals(actual), prefix + expected + " != " + actual);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

import org.variantsync.diffdetective.diff.text.DiffLineNumber;
import org.variantsync.diffdetective.util.Assert;
import org.variantsync.diffdetective.util.StringUtils;
import org.variantsync.diffdetective.variation.diff.Time;
import org.variantsync.diffdetective.variation.diff.VariationDiff; // For Javadoc

/**
Expand Down Expand Up @@ -82,6 +84,66 @@ public List<String> getTrailingLines() {
return getDiffTrailingLines().stream().map(Line::content).toList();
}

/**
* Returns a deep copy where the line numbers at {@code time} are set to
* {@link DiffLineNumber#InvalidLineNumber}.
*/
@Override
public DiffLinesLabel withoutTimeDependentState(Time time) {
return new DiffLinesLabel(
mapWithoutTimeDependentState(getDiffLines(), time),
mapWithoutTimeDependentState(getDiffTrailingLines(), time)
);
}

private List<Line> mapWithoutTimeDependentState(List<Line> lines, Time time) {
return lines
.stream()
.map(line -> new Line(
line.content(),
line.lineNumber().withLineNumberAtTime(DiffLineNumber.InvalidLineNumber, time)
))
.toList();
}

/**
* Returns a deep copy where the line numbers at {@code time} are copied from
* {@code otherLabel}. The number of lines and their content must be identical in {@code this}
* and {@code otherLabel}.
*
* @see withoutTimeDependentState
*/
@Override
public DiffLinesLabel withTimeDependentStateFrom(Label otherLabel, Time time) {
DiffLinesLabel other = (DiffLinesLabel) otherLabel;

return new DiffLinesLabel(
zipWithTimeDependentStateFrom(this.getDiffLines(), other.getDiffLines(), time),
zipWithTimeDependentStateFrom(this.getDiffTrailingLines(), other.getDiffTrailingLines(), time)
);
}

private static List<Line> zipWithTimeDependentStateFrom(List<Line> linesA, List<Line> linesB, Time time) {
List<Line> result = new ArrayList<>(linesA.size());

Iterator<Line> itA = linesA.iterator();
Iterator<Line> itB = linesA.iterator();
while (itA.hasNext() && itB.hasNext()) {
Line lineA = itA.next();
Line lineB = itB.next();

Assert.assertEquals(lineA.content(), lineB.content(), "Mismatching line contents in a call to `withTimeDependentStateFrom` detected");
result.add(new Line(
lineA.content(),
lineB.lineNumber().withLineNumberAtTime(lineB.lineNumber().atTime(time), time)
));
}

Assert.assertFalse(itA.hasNext() || itB.hasNext(), "Mismatching line counts in a call to `withTimeDependentStateFrom` detected");

return result;
}

@Override
public String toString() {
return lines
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/org/variantsync/diffdetective/variation/Label.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import java.util.List;

import org.variantsync.diffdetective.util.Assert;
import org.variantsync.diffdetective.variation.diff.Time;
import org.variantsync.diffdetective.variation.diff.VariationDiff; // For Javadoc
import org.variantsync.diffdetective.variation.tree.VariationTree; // For Javadoc

Expand All @@ -19,6 +21,29 @@ public interface Label {
* For example, {@code #endif}s are stored as trailing lines.
*/
List<String> getTrailingLines();

/**
* Returns a deep copy where the state that is only valid at {@code time} is set to its default
* value. Note that not all implementations need to have time dependent state.
*
* @see withTimeDependentStateFrom
*/
default Label withoutTimeDependentState(Time time) {
return this.clone();
}

/**
* Returns a deep copy where the state that is only valid at {@code time} is copied from
* {@code other}. All time independent state must be equal in {@code this} and {@code other}.
* Note that not all implementations need to have time dependent state.
*
* @see withoutTimeDependentState
*/
default Label withTimeDependentStateFrom(Label other, Time time) {
Assert.assertEquals(this, other);
return this.clone();
}

/**
* Creates a deep copy of this label.
*/
Expand Down
Loading