Skip to content

Commit 018d03e

Browse files
authored
Merge pull request #242 from scijava/scijava-ops-engine/add-reduced-info-tree-generator
Add ReducedInfoTreeGenerator
2 parents a991acf + 4ece27d commit 018d03e

File tree

5 files changed

+87
-0
lines changed

5 files changed

+87
-0
lines changed

scijava-ops-engine/src/main/java/module-info.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
provides org.scijava.ops.engine.InfoTreeGenerator with
7373
org.scijava.ops.engine.matcher.adapt.AdaptationInfoTreeGenerator,
7474
org.scijava.ops.engine.impl.DefaultInfoTreeGenerator,
75+
org.scijava.ops.engine.matcher.reduce.ReducedInfoTreeGenerator,
7576
org.scijava.ops.engine.matcher.convert.ConvertedInfoTreeGenerator;
7677

7778
provides org.scijava.ops.api.OpEnvironment with
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
2+
package org.scijava.ops.engine.matcher.reduce;
3+
4+
import org.scijava.ops.api.InfoTree;
5+
import org.scijava.ops.api.OpEnvironment;
6+
import org.scijava.ops.api.OpInfo;
7+
import org.scijava.ops.engine.InfoTreeGenerator;
8+
9+
import java.util.Collection;
10+
import java.util.Map;
11+
12+
/**
13+
* An {@link org.scijava.ops.engine.InfoTreeGenerator} that is used to generate
14+
* {@link org.scijava.ops.api.InfoTree}s for {@link ReducedOpInfo}s.
15+
*
16+
* @author Gabriel Selzer
17+
*/
18+
public class ReducedInfoTreeGenerator implements InfoTreeGenerator {
19+
20+
@Override
21+
public InfoTree generate(OpEnvironment env, String signature,
22+
Map<String, OpInfo> idMap, Collection<InfoTreeGenerator> generators)
23+
{
24+
// Chop off the prefix on all ReducedOpInfos
25+
var reductionPrefix = ReducedOpInfo.IMPL_DECLARATION //
26+
+ ReducedOpInfo.PARAMS_REDUCED;
27+
var prefixless = signature.substring(reductionPrefix.length());
28+
// Find the number of parameters reduced
29+
var numString = prefixless.substring(0, //
30+
prefixless.indexOf(ReducedOpInfo.ORIGINAL_INFO));
31+
var idx = Integer.parseInt(numString) - 1;
32+
33+
// Create an InfoTree from the original Info
34+
var substring = signature.substring( //
35+
signature.indexOf(ReducedOpInfo.ORIGINAL_INFO) //
36+
+ ReducedOpInfo.ORIGINAL_INFO.length());
37+
var original = InfoTreeGenerator.generateDependencyTree(env, substring,
38+
idMap, generators);
39+
// Reduce the original info, and build a new InfoTree from the proper
40+
// ReducedInfo
41+
var reductions = new ReducedOpInfoGenerator().generateInfosFrom(
42+
original.info());
43+
return new InfoTree(reductions.get(idx), original.dependencies());
44+
}
45+
46+
@Override
47+
public boolean canGenerate(String signature) {
48+
return signature.startsWith(ReducedOpInfo.IMPL_DECLARATION);
49+
}
50+
}

scijava-ops-engine/src/main/resources/META-INF/services/org.scijava.ops.engine.InfoTreeGenerator

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
# Instead, modify and re-run <basedir>/bin/generate-meta-inf.sh from the top-level
33
org.scijava.ops.engine.matcher.adapt.AdaptationInfoTreeGenerator
44
org.scijava.ops.engine.impl.DefaultInfoTreeGenerator
5+
org.scijava.ops.engine.matcher.reduce.ReducedInfoTreeGenerator
56
org.scijava.ops.engine.matcher.convert.ConvertedInfoTreeGenerator

scijava-ops-engine/src/test/java/org/scijava/ops/engine/impl/ProvenanceTest.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import java.util.Arrays;
5555
import java.util.Iterator;
5656
import java.util.List;
57+
import java.util.function.BiFunction;
5758
import java.util.function.Function;
5859

5960
public class ProvenanceTest extends AbstractTestEnvironment implements
@@ -117,6 +118,11 @@ public Thing apply(Double[] doubles) {
117118
}
118119
}
119120

121+
@OpMethod(names = "test.create.thing", type = BiFunction.class)
122+
public static Thing createThingWithNullable(Double d1, @Nullable Double d2) {
123+
return new Thing(d2 == null ? d1 : d1 + d2);
124+
}
125+
120126
static class Thing {
121127

122128
private Double d;
@@ -518,6 +524,34 @@ public void testAdaptationWithDependencies() {
518524
Assertions.assertEquals(1, ops.history().executionsUpon(actual).size());
519525
}
520526

527+
@Test
528+
public void testReducedOpRecovery() {
529+
// Get the Op
530+
Function<Double, Thing> f = ops //
531+
.op("test.create.thing") //
532+
.inType(Double.class) //
533+
.outType(Thing.class) //
534+
.function();
535+
// Assert only one execution
536+
Thing actual = f.apply(4.0);
537+
Thing expected = new Thing(4.0);
538+
Assertions.assertEquals(expected.d, actual.d);
539+
Assertions.assertEquals(1, ops.history().executionsUpon(actual).size());
540+
// Get the signature from the Op
541+
String signature = Ops.signature(f);
542+
// Generate the Op from the signature and the Op type
543+
Nil<Function<Thing, Thing>> special = new Nil<>() {};
544+
Function<Thing, Thing> fromString = ops //
545+
.opFromSignature(signature, special);
546+
// Assert Op similarity
547+
Assertions.assertTrue(wrappedOpEquality(f, fromString));
548+
// Assert only one execution
549+
actual = f.apply(4.0);
550+
Assertions.assertEquals(expected.d, actual.d);
551+
Assertions.assertEquals(1, ops.history().executionsUpon(actual).size());
552+
553+
}
554+
521555
// -- Helper Methods -- //
522556

523557
/**

scijava-ops-engine/templates/main/java/module-info.vm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ module org.scijava.ops.engine {
4444
provides org.scijava.ops.engine.InfoTreeGenerator with
4545
org.scijava.ops.engine.matcher.adapt.AdaptationInfoTreeGenerator,
4646
org.scijava.ops.engine.impl.DefaultInfoTreeGenerator,
47+
org.scijava.ops.engine.matcher.reduce.ReducedInfoTreeGenerator,
4748
org.scijava.ops.engine.matcher.convert.ConvertedInfoTreeGenerator;
4849

4950
provides org.scijava.ops.api.OpEnvironment with

0 commit comments

Comments
 (0)