diff --git a/bin/tests/scenarios/jdime_matching_issue/base.java b/bin/tests/scenarios/jdime_matching_issue/base.java new file mode 100644 index 0000000..b563b52 --- /dev/null +++ b/bin/tests/scenarios/jdime_matching_issue/base.java @@ -0,0 +1,21 @@ +package de.fosd.jdime.artifact; + +import java.security.MessageDigest; + +public abstract class Artifact> implements Comparable, StatisticsInterface { + public boolean hasChanges(Revision revision) { + if (this.revision.equals(revision)) { + return false; + } + + if (!hasMatching(revision)) { + return true; + } + + T match = getMatching(revision).getMatchingArtifact(this); + + return getTreeSize() != match.getTreeSize() || Artifacts.bfsStream(self()).anyMatch(a -> { + return !a.hasMatching(revision) || !a.getMatching(revision).getMatchingArtifact(a).hashId().equals(a.hashId()); + }); + } +} diff --git a/bin/tests/scenarios/jdime_matching_issue/left.java b/bin/tests/scenarios/jdime_matching_issue/left.java new file mode 100644 index 0000000..5ffe591 --- /dev/null +++ b/bin/tests/scenarios/jdime_matching_issue/left.java @@ -0,0 +1,22 @@ +package de.fosd.jdime.artifact; + +import java.security.MessageDigest; + +public abstract class Artifact> implements Comparable, StatisticsInterface { + public boolean hasChanges(Revision revision) { + + if (this.revision.equals(revision)) { + return false; + } + + if (!hasMatching(revision)) { + return true; + } + + T match = getMatching(revision).getMatchingArtifact(this); + + return getTreeSize() != match.getTreeSize() || Artifacts.bfsStream(self()).anyMatch(a -> { + return !a.hasMatching(revision) || !a.getMatching(revision).getMatchingArtifact(a).hashId().equals(a.hashId()); + }); + } +} diff --git a/bin/tests/scenarios/jdime_matching_issue/merge.java b/bin/tests/scenarios/jdime_matching_issue/merge.java new file mode 100644 index 0000000..fca08b5 --- /dev/null +++ b/bin/tests/scenarios/jdime_matching_issue/merge.java @@ -0,0 +1 @@ + package de . fosd . jdime . artifact ; import java . security . MessageDigest ; public abstract class Artifact < T extends Artifact < T > > implements Comparable < T > , StatisticsInterface { public boolean hasChanges ( Revision revision ) { if ( this . revision . equals ( revision ) ) { return false ; } if ( ! hasMatching ( revision ) ) { return true ; } T match = getMatching ( revision ) . getMatchingArtifact ( this ) ; return getTreeSize ( ) != match . getTreeSize ( ) || ! getTreeHash ( ) . equals ( match . getTreeHash ( ) ) ; } } \ No newline at end of file diff --git a/bin/tests/scenarios/jdime_matching_issue/right.java b/bin/tests/scenarios/jdime_matching_issue/right.java new file mode 100644 index 0000000..1cb1895 --- /dev/null +++ b/bin/tests/scenarios/jdime_matching_issue/right.java @@ -0,0 +1,20 @@ +package de.fosd.jdime.artifact; + +import java.security.MessageDigest; + +public abstract class Artifact> implements Comparable, StatisticsInterface { + public boolean hasChanges(Revision revision) { + + if (this.revision.equals(revision)) { + return false; + } + + if (!hasMatching(revision)) { + return true; + } + + T match = getMatching(revision).getMatchingArtifact(this); + + return getTreeSize() != match.getTreeSize() || !getTreeHash().equals(match.getTreeHash()); + } +} diff --git a/matching/src/ordered_tree_matching.rs b/matching/src/ordered_tree_matching.rs index 9ee4ce3..1be6153 100644 --- a/matching/src/ordered_tree_matching.rs +++ b/matching/src/ordered_tree_matching.rs @@ -38,6 +38,14 @@ pub fn ordered_tree_matching<'a>( ) => { let root_matching: usize = (kind_left == kind_right).into(); + // Node kinds do not match, so we return a matching with a score of 0 + if root_matching == 0 { + return Matchings::from_single( + UnorderedPair(left, right), + MatchingEntry::new(0, false), + ); + } + let m = children_left.len(); let n = children_right.len();