Skip to content

Commit bb317a5

Browse files
gselzerctrueden
authored andcommitted
Remove typesMatch() from OpMatcher
typesMatch() shouldn't really pertain to the OpMatcher. It might instead belong in OpCandidate, or in RuntimeSafeMatchingRoutine... TBD.
1 parent f6dba31 commit bb317a5

3 files changed

Lines changed: 8 additions & 193 deletions

File tree

scijava/scijava-ops-api/src/main/java/org/scijava/ops/api/features/OpMatcher.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,4 @@
4242
public interface OpMatcher {
4343

4444
OpCandidate match(MatchingConditions conditions, OpEnvironment env);
45-
46-
boolean typesMatch(OpCandidate candidate);
4745
}

scijava/scijava-ops-engine/src/main/java/org/scijava/ops/engine/impl/ManualOpCandidate.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@ public ManualOpCandidate(OpEnvironment env, OpRef ref, OpInfo info,
1818
OpMatcher matcher)
1919
{
2020
super(env, ref, info, generateTypeVarAssigns(ref, info));
21-
if (!matcher.typesMatch(this)) throw new IllegalArgumentException(
22-
"OpInfo " + info +
23-
" cannot satisfy the requirements contained within OpRef " + ref);
2421
}
2522

2623
private static Map<TypeVariable<?>, Type> generateTypeVarAssigns(OpRef ref,

scijava/scijava-ops-engine/src/main/java/org/scijava/ops/engine/matcher/impl/DefaultOpMatcher.java

Lines changed: 8 additions & 188 deletions
Original file line numberDiff line numberDiff line change
@@ -29,29 +29,19 @@
2929

3030
package org.scijava.ops.engine.matcher.impl;
3131

32-
import java.lang.reflect.ParameterizedType;
33-
import java.lang.reflect.Type;
34-
import java.lang.reflect.TypeVariable;
3532
import java.util.ArrayList;
36-
import java.util.Arrays;
3733
import java.util.Collection;
3834
import java.util.Collections;
39-
import java.util.HashMap;
4035
import java.util.List;
4136

4237
import org.scijava.ops.api.OpCandidate;
43-
import org.scijava.ops.api.OpCandidate.StatusCode;
4438
import org.scijava.ops.api.OpEnvironment;
4539
import org.scijava.ops.api.OpRef;
46-
import org.scijava.ops.api.OpUtils;
4740
import org.scijava.ops.api.features.MatchingConditions;
4841
import org.scijava.ops.api.features.MatchingRoutine;
4942
import org.scijava.ops.api.features.OpMatcher;
5043
import org.scijava.ops.api.features.OpMatchingException;
5144
import org.scijava.service.AbstractService;
52-
import org.scijava.struct.Member;
53-
import org.scijava.types.Types;
54-
import org.scijava.types.Types.TypeVarInfo;
5545

5646
/**
5747
* Default implementation of {@link OpMatcher}. Used for finding Ops which match
@@ -68,121 +58,6 @@ public DefaultOpMatcher(Collection<? extends MatchingRoutine> matchers) {
6858
Collections.sort(this.matchers, Collections.reverseOrder());
6959
}
7060

71-
private OpMatchingException agglomeratedException(
72-
List<OpMatchingException> list)
73-
{
74-
OpMatchingException agglomerated = new OpMatchingException(
75-
"No MatchingRoutine was able to produce a match!");
76-
for (int i = 0; i < list.size(); i++) {
77-
agglomerated.addSuppressed(list.get(i));
78-
}
79-
return agglomerated;
80-
}
81-
82-
// -- Helper methods --
83-
84-
/**
85-
* Performs several checks, whether the specified candidate:</br>
86-
* </br>
87-
* * {@link #isValid(OpCandidate)}</br>
88-
* * {@link #outputsMatch(OpCandidate, HashMap)}</br>
89-
* * has a matching number of args</br>
90-
* * {@link #missArgs(OpCandidate, Type[])}</br>
91-
* </br>
92-
* then returns the candidates which fulfill this criteria.
93-
*
94-
* @param candidates
95-
* the candidates to check
96-
* @return candidates passing checks
97-
*/
98-
private List<OpCandidate> checkCandidates(final List<OpCandidate> candidates) {
99-
final ArrayList<OpCandidate> validCandidates = new ArrayList<>();
100-
for (final OpCandidate candidate : candidates) {
101-
if (!isValid(candidate))
102-
continue;
103-
final Type[] args = candidate.paddedArgs();
104-
if (args == null)
105-
continue;
106-
if (missArgs(candidate, args))
107-
continue;
108-
validCandidates.add(candidate);
109-
}
110-
return validCandidates;
111-
}
112-
113-
/**
114-
* Checks whether the output types of the candidate are applicable to the
115-
* input types of the {@link OpRef}. Sets candidate status code if there are
116-
* too many, to few, or not matching types.
117-
*
118-
* @param candidate
119-
* the candidate to check inputs for
120-
* @param typeBounds
121-
* possibly predetermined type bounds for type variables
122-
* @return whether the input types match
123-
*/
124-
private boolean inputsMatch(final OpCandidate candidate, HashMap<TypeVariable<?>, TypeVarInfo> typeBounds) {
125-
if (checkCandidates(Collections.singletonList(candidate)).isEmpty())
126-
return false;
127-
final Type[] refArgTypes = candidate.paddedArgs();
128-
final Type refType = candidate.getRef().getType();
129-
final Type infoType = candidate.opInfo().opType();
130-
Type[] candidateArgTypes = OpUtils.inputTypes(candidate);
131-
Type implementedInfoType = Types.getExactSuperType(infoType, Types.raw(
132-
refType));
133-
if (!(implementedInfoType instanceof ParameterizedType)) {
134-
throw new UnsupportedOperationException(
135-
"Op type is not a ParameterizedType; we don't know how to deal with these yet.");
136-
}
137-
Type[] implTypeParams = ((ParameterizedType) implementedInfoType)
138-
.getActualTypeArguments();
139-
candidateArgTypes = candidate.opInfo().struct().members().stream()//
140-
.map(member -> member.isInput() ? member.getType() : null) //
141-
.toArray(Type[]::new);
142-
for (int i = 0; i < implTypeParams.length; i++) {
143-
if (candidateArgTypes[i] == null) implTypeParams[i] = null;
144-
}
145-
candidateArgTypes = Arrays.stream(implTypeParams) //
146-
.filter(t -> t != null).toArray(Type[]::new);
147-
148-
if (refArgTypes == null)
149-
return true; // no constraints on output types
150-
151-
if (candidateArgTypes.length < refArgTypes.length) {
152-
candidate.setStatus(StatusCode.TOO_FEW_ARGS);
153-
return false;
154-
} else if (candidateArgTypes.length > refArgTypes.length) {
155-
candidate.setStatus(StatusCode.TOO_MANY_ARGS);
156-
return false;
157-
}
158-
159-
int conflictingIndex = Types.isApplicable(refArgTypes, candidateArgTypes, typeBounds);
160-
if (conflictingIndex != -1) {
161-
final Type to = refArgTypes[conflictingIndex];
162-
final Type from = candidateArgTypes[conflictingIndex];
163-
candidate.setStatus(StatusCode.ARG_TYPES_DO_NOT_MATCH, //
164-
"request=" + to.getTypeName() + ", actual=" + from.getTypeName());
165-
return false;
166-
}
167-
return true;
168-
}
169-
170-
/**
171-
* Determines if the specified candidate is valid and sets status code if
172-
* not.
173-
*
174-
* @param candidate
175-
* the candidate to check
176-
* @return whether the candidate is valid
177-
*/
178-
private boolean isValid(final OpCandidate candidate) {
179-
if (candidate.opInfo().isValid()) {
180-
return true;
181-
}
182-
candidate.setStatus(StatusCode.INVALID_STRUCT);
183-
return false;
184-
}
185-
18661
@Override
18762
public OpCandidate match(MatchingConditions conditions, OpEnvironment env) {
18863
List<OpMatchingException> exceptions = new ArrayList<>(matchers.size());
@@ -200,69 +75,14 @@ public OpCandidate match(MatchingConditions conditions, OpEnvironment env) {
20075
throw agglomeratedException(exceptions);
20176
}
20277

203-
/**
204-
* Determines if the candidate has some arguments missing.
205-
* <p>
206-
* Helper method of {@link #filterMatches(List)}.
207-
* </p>
208-
*/
209-
private boolean missArgs(final OpCandidate candidate, final Type[] paddedArgs) {
210-
int i = 0;
211-
for (final Member<?> member : OpUtils.inputs(candidate)) {
212-
if (paddedArgs[i++] == null && member.isRequired()) {
213-
candidate.setStatus(StatusCode.REQUIRED_ARG_IS_NULL, null, member);
214-
return true;
215-
}
216-
}
217-
return false;
218-
}
219-
220-
/**
221-
* Checks whether the output type of the candidate matches the output type
222-
* of the {@link OpRef}. Sets candidate status code if they are not matching.
223-
*
224-
* @param candidate
225-
* the candidate to check output for
226-
* @param typeBounds
227-
* possibly predetermined type bounds for type variables
228-
* @return whether the output types match
229-
*/
230-
private boolean outputsMatch(final OpCandidate candidate, HashMap<TypeVariable<?>, TypeVarInfo> typeBounds) {
231-
final Type refOutType = candidate.getRef().getOutType();
232-
if (refOutType == null)
233-
return true; // no constraints on output types
234-
235-
if(candidate.opInfo().output().isInput()) return true;
236-
final Type candidateOutType = OpUtils.outputType(candidate);
237-
final int conflictingIndex = MatchingUtils.checkGenericOutputsAssignability(new Type[] { candidateOutType },
238-
new Type[] { refOutType }, typeBounds);
239-
if (conflictingIndex != -1) {
240-
candidate.setStatus(StatusCode.OUTPUT_TYPES_DO_NOT_MATCH, //
241-
"request=" + refOutType.getTypeName() + ", actual=" + candidateOutType.getTypeName());
242-
return false;
243-
}
244-
return true;
245-
}
246-
247-
/**
248-
* Checks whether the arg types of the candidate satisfy the padded arg
249-
* types of the candidate. Sets candidate status code if there are too many,
250-
* to few,not matching arg types or if a match was found.
251-
*
252-
* @param candidate
253-
* the candidate to check args for
254-
* @return whether the arg types are satisfied
255-
*/
256-
@Override
257-
public boolean typesMatch(final OpCandidate candidate) {
258-
HashMap<TypeVariable<?>, TypeVarInfo> typeBounds = new HashMap<>();
259-
if (!inputsMatch(candidate, typeBounds)) {
260-
return false;
261-
}
262-
if (!outputsMatch(candidate, typeBounds)) {
263-
return false;
78+
private OpMatchingException agglomeratedException(
79+
List<OpMatchingException> list)
80+
{
81+
OpMatchingException agglomerated = new OpMatchingException(
82+
"No MatchingRoutine was able to produce a match!");
83+
for (int i = 0; i < list.size(); i++) {
84+
agglomerated.addSuppressed(list.get(i));
26485
}
265-
candidate.setStatus(StatusCode.MATCH);
266-
return true;
86+
return agglomerated;
26787
}
26888
}

0 commit comments

Comments
 (0)