Skip to content

Commit 0f699a7

Browse files
committed
added artefact filtering in variant generation
1 parent e3c4c7e commit 0f699a7

10 files changed

Lines changed: 110 additions & 22 deletions

File tree

src/main/java/de/variantsync/evolution/variability/SPLCommit.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public class SPLCommit extends Commit {
3535

3636
/**
3737
* Constructor for commits that should only contain information about the commit id.
38+
* TODO: Document params.
3839
*
3940
* @param commitId The id of the commit
4041
*/

src/main/java/de/variantsync/evolution/variability/pc/Artefact.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package de.variantsync.evolution.variability.pc;
22

33
import de.variantsync.evolution.feature.Variant;
4-
import de.variantsync.evolution.util.io.CaseSensitivePath;
54
import de.variantsync.evolution.util.functional.Result;
5+
import de.variantsync.evolution.util.io.CaseSensitivePath;
66
import de.variantsync.evolution.variability.pc.groundtruth.GroundTruth;
7+
import de.variantsync.evolution.variability.pc.options.VariantGenerationOptions;
78
import de.variantsync.evolution.variability.pc.visitor.ArtefactVisitor;
89
import de.variantsync.evolution.variability.pc.visitor.ArtefactVisitorFocus;
910
import de.variantsync.evolution.variability.pc.visitor.common.FilePCQuery;

src/main/java/de/variantsync/evolution/variability/pc/LineBasedAnnotation.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package de.variantsync.evolution.variability.pc;
22

33
import de.variantsync.evolution.feature.Variant;
4-
import de.variantsync.evolution.util.io.CaseSensitivePath;
54
import de.variantsync.evolution.util.functional.Result;
5+
import de.variantsync.evolution.util.io.CaseSensitivePath;
66
import de.variantsync.evolution.variability.pc.groundtruth.AnnotationGroundTruth;
77
import de.variantsync.evolution.variability.pc.groundtruth.BlockMatching;
88
import de.variantsync.evolution.variability.pc.groundtruth.GroundTruth;
9+
import de.variantsync.evolution.variability.pc.options.VariantGenerationOptions;
910
import de.variantsync.evolution.variability.pc.visitor.LineBasedAnnotationVisitorFocus;
1011
import org.prop4j.Node;
1112

src/main/java/de/variantsync/evolution/variability/pc/SourceCodeFile.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@
22

33
import de.variantsync.evolution.feature.Variant;
44
import de.variantsync.evolution.io.TextIO;
5-
import de.variantsync.evolution.util.io.CaseSensitivePath;
65
import de.variantsync.evolution.util.Logger;
7-
import de.variantsync.evolution.util.io.PathUtils;
86
import de.variantsync.evolution.util.fide.bugfix.FixTrueFalse;
97
import de.variantsync.evolution.util.functional.Functional;
108
import de.variantsync.evolution.util.functional.Result;
119
import de.variantsync.evolution.util.functional.Traversable;
10+
import de.variantsync.evolution.util.io.CaseSensitivePath;
11+
import de.variantsync.evolution.util.io.PathUtils;
1212
import de.variantsync.evolution.variability.pc.groundtruth.AnnotationGroundTruth;
1313
import de.variantsync.evolution.variability.pc.groundtruth.BlockMatching;
1414
import de.variantsync.evolution.variability.pc.groundtruth.GroundTruth;
15+
import de.variantsync.evolution.variability.pc.options.VariantGenerationOptions;
1516
import de.variantsync.evolution.variability.pc.visitor.SourceCodeFileVisitorFocus;
1617
import org.prop4j.Node;
1718

src/main/java/de/variantsync/evolution/variability/pc/SyntheticArtefactTreeNode.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package de.variantsync.evolution.variability.pc;
22

33
import de.variantsync.evolution.feature.Variant;
4-
import de.variantsync.evolution.util.io.CaseSensitivePath;
54
import de.variantsync.evolution.util.Logger;
65
import de.variantsync.evolution.util.fide.bugfix.FixTrueFalse;
76
import de.variantsync.evolution.util.functional.Functional;
87
import de.variantsync.evolution.util.functional.Result;
8+
import de.variantsync.evolution.util.io.CaseSensitivePath;
99
import de.variantsync.evolution.variability.pc.groundtruth.GroundTruth;
10+
import de.variantsync.evolution.variability.pc.options.VariantGenerationOptions;
1011
import de.variantsync.evolution.variability.pc.visitor.ArtefactVisitorFocus;
1112
import de.variantsync.evolution.variability.pc.visitor.SyntheticArtefactTreeNodeVisitorFocus;
1213

@@ -59,6 +60,12 @@ public Result<GroundTruth, Exception> generateVariant(final Variant variant, fin
5960
}
6061
} else {
6162
for (final Child subtree : subtrees) {
63+
if (subtree instanceof SourceCodeFile sourceCodeFile) {
64+
if (!strategy.filter().shouldKeep(sourceCodeFile)) {
65+
continue;
66+
}
67+
}
68+
6269
if (variant.isImplementing(subtree.getPresenceCondition())) {
6370
final Result<GroundTruth, Exception> result = subtree
6471
.generateVariant(variant, sourceDir, targetDir, strategy);

src/main/java/de/variantsync/evolution/variability/pc/VariantGenerationOptions.java

Lines changed: 0 additions & 7 deletions
This file was deleted.
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package de.variantsync.evolution.variability.pc.options;
2+
3+
import de.variantsync.evolution.variability.pc.Artefact;
4+
5+
import java.util.Arrays;
6+
import java.util.Collection;
7+
8+
/**
9+
* Predicate to filter artefacts upon certain operations.
10+
* @param <A> The type of artefact that should be filtered.
11+
*/
12+
@FunctionalInterface
13+
public interface ArtefactFilter<A extends Artefact> {
14+
/**
15+
* Determines whether a given artefact should be considered in or dropped from subsequent computations.
16+
* @param a The artefact that should be filtered.
17+
* @return True iff the given artefact should be kept and used in further computations.
18+
*/
19+
boolean shouldKeep(final A a);
20+
21+
/**
22+
* @return A filter that accepts all artifacts. Formally, its value is `a -> true`.
23+
*/
24+
static <A extends Artefact> ArtefactFilter<A> KeepAll() {
25+
return a -> true;
26+
}
27+
28+
/**
29+
* Folds all given filters into a single filter.
30+
* The returned filter will run all filters in the order they are returned by the given collection.
31+
* The returned filter returns false and stops computation as soon as one of the given filters
32+
* rejects the input artefact to test.
33+
* @param filters A collection of filters to collapse.
34+
* @param <A> The type of artefacts to filter.
35+
* @return A single filter that returns true for a given artifact iff all of the given filters return true for it.
36+
* Formally, if `f` is the output filter `f.shouldKeep(a) iff (forall fi in filters: fi.shouldKeep(a))`.
37+
*/
38+
static <A extends Artefact> ArtefactFilter<A> Fold(final Collection<ArtefactFilter<A>> filters) {
39+
return a -> {
40+
for (final ArtefactFilter<A> filter : filters) {
41+
if (!filter.shouldKeep(a)) {
42+
return false;
43+
}
44+
}
45+
46+
return true;
47+
};
48+
}
49+
50+
/**
51+
* @see #Fold(Collection)
52+
*/
53+
@SafeVarargs
54+
static <A extends Artefact> ArtefactFilter<A> Fold(final ArtefactFilter<A>... filters) {
55+
return Fold(Arrays.asList(filters));
56+
}
57+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package de.variantsync.evolution.variability.pc.options;
2+
3+
import de.variantsync.evolution.variability.pc.SourceCodeFile;
4+
5+
public record VariantGenerationOptions(
6+
boolean exitOnError,
7+
boolean ignoreNonExistentSPLFiles,
8+
ArtefactFilter<SourceCodeFile> filter
9+
)
10+
{
11+
public static VariantGenerationOptions ExitOnError(final ArtefactFilter<SourceCodeFile> filter) {
12+
return new VariantGenerationOptions(true, false, filter);
13+
}
14+
15+
public static VariantGenerationOptions IgnoreErrors(final ArtefactFilter<SourceCodeFile> filter) {
16+
return new VariantGenerationOptions(false, true, filter);
17+
}
18+
19+
public static VariantGenerationOptions ExitOnErrorButAllowNonExistentFiles(final ArtefactFilter<SourceCodeFile> filter) {
20+
return new VariantGenerationOptions(true, true, filter);
21+
}
22+
}

src/main/java/de/variantsync/evolution/variants/blueprints/VariantsRevisionFromVariabilityBlueprint.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
package de.variantsync.evolution.variants.blueprints;
22

3-
import de.variantsync.evolution.feature.sampling.Sample;
43
import de.variantsync.evolution.feature.Variant;
4+
import de.variantsync.evolution.feature.sampling.Sample;
55
import de.variantsync.evolution.repository.AbstractSPLRepository;
66
import de.variantsync.evolution.repository.AbstractVariantsRepository;
77
import de.variantsync.evolution.repository.Branch;
8-
import de.variantsync.evolution.util.io.CaseSensitivePath;
98
import de.variantsync.evolution.util.Logger;
109
import de.variantsync.evolution.util.functional.Lazy;
1110
import de.variantsync.evolution.util.functional.Result;
11+
import de.variantsync.evolution.util.io.CaseSensitivePath;
1212
import de.variantsync.evolution.variability.SPLCommit;
1313
import de.variantsync.evolution.variability.pc.Artefact;
14-
import de.variantsync.evolution.variability.pc.VariantGenerationOptions;
1514
import de.variantsync.evolution.variability.pc.groundtruth.GroundTruth;
15+
import de.variantsync.evolution.variability.pc.options.ArtefactFilter;
16+
import de.variantsync.evolution.variability.pc.options.VariantGenerationOptions;
1617
import de.variantsync.evolution.variants.VariantCommit;
1718
import de.variantsync.evolution.variants.VariantsRevision;
1819
import de.variantsync.evolution.variants.sampling.SamplingStrategy;
@@ -86,7 +87,7 @@ public Lazy<VariantsRevision.Branches> generateArtefactsFor(final VariantsRevisi
8687
variant,
8788
new CaseSensitivePath(splRepo.getPath()),
8889
new CaseSensitivePath(variantsRepo.getPath()),
89-
VariantGenerationOptions.ExitOnErrorButAllowNonExistentFiles);
90+
VariantGenerationOptions.ExitOnErrorButAllowNonExistentFiles(ArtefactFilter.KeepAll()));
9091
Logger.log(result.map(u -> "Generating variant " + variant + " was successful!"));
9192

9293
// Commit the generated variant with the corresponding spl commit has as message.

src/test/java/de/variantsync/evolution/VariantGenerationTest.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,26 @@
22

33
import de.ovgu.featureide.fm.core.analysis.cnf.formula.FeatureModelFormula;
44
import de.ovgu.featureide.fm.core.base.IFeatureModel;
5-
import de.variantsync.evolution.feature.sampling.Sampler;
65
import de.variantsync.evolution.feature.Variant;
6+
import de.variantsync.evolution.feature.config.FeatureIDEConfiguration;
77
import de.variantsync.evolution.feature.config.IConfiguration;
8+
import de.variantsync.evolution.feature.config.SayYesToAllConfiguration;
89
import de.variantsync.evolution.feature.sampling.FeatureIDESampler;
10+
import de.variantsync.evolution.feature.sampling.Sampler;
911
import de.variantsync.evolution.io.ResourceLoader;
1012
import de.variantsync.evolution.io.Resources;
1113
import de.variantsync.evolution.io.TextIO;
1214
import de.variantsync.evolution.io.kernelhaven.KernelHavenSPLPCIO;
1315
import de.variantsync.evolution.sat.SAT;
14-
import de.variantsync.evolution.util.io.CaseSensitivePath;
1516
import de.variantsync.evolution.util.Logger;
16-
import de.variantsync.evolution.util.io.PathUtils;
1717
import de.variantsync.evolution.util.fide.FeatureModelUtils;
1818
import de.variantsync.evolution.util.fide.bugfix.FixTrueFalse;
1919
import de.variantsync.evolution.util.functional.Result;
20-
import de.variantsync.evolution.feature.config.FeatureIDEConfiguration;
21-
import de.variantsync.evolution.feature.config.SayYesToAllConfiguration;
20+
import de.variantsync.evolution.util.io.CaseSensitivePath;
21+
import de.variantsync.evolution.util.io.PathUtils;
2222
import de.variantsync.evolution.variability.pc.*;
23+
import de.variantsync.evolution.variability.pc.options.ArtefactFilter;
24+
import de.variantsync.evolution.variability.pc.options.VariantGenerationOptions;
2325
import org.junit.BeforeClass;
2426
import org.junit.Test;
2527
import org.prop4j.And;
@@ -69,7 +71,9 @@ public boolean generate(final List<Variant> variantsToTest, final boolean writeC
6971

7072
for (final Variant v : variantsToTest) {
7173
traceToTest
72-
.generateVariant(v, splDir, variantsDir.resolve(v.getName()), VariantGenerationOptions.ExitOnErrorButAllowNonExistentFiles)
74+
.generateVariant(v, splDir,
75+
variantsDir.resolve(v.getName()),
76+
VariantGenerationOptions.ExitOnErrorButAllowNonExistentFiles(ArtefactFilter.KeepAll()))
7377
// Write ground truth
7478
.bind(groundTruth -> Result.Try(() -> Resources.Instance().write(
7579
Artefact.class,

0 commit comments

Comments
 (0)