Skip to content

Commit 8387aac

Browse files
committed
Eliminate runtime reflection in Operators. Perform reflection in OperatorsTest instead.
1 parent 0ff8092 commit 8387aac

2 files changed

Lines changed: 110 additions & 21 deletions

File tree

src/main/java/org/scijava/parsington/Operators.java

Lines changed: 63 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,8 @@
3333
import static org.scijava.parsington.Operator.Associativity.LEFT;
3434
import static org.scijava.parsington.Operator.Associativity.RIGHT;
3535

36-
import java.lang.reflect.Field;
37-
import java.lang.reflect.Modifier;
3836
import java.util.ArrayList;
37+
import java.util.Arrays;
3938
import java.util.List;
4039

4140
import org.scijava.parsington.Operator.Associativity;
@@ -172,6 +171,67 @@ public final class Operators {
172171
public static final Operator UNSIGNED_RIGHT_SHIFT_ASSIGN = op(">>>=", 2,
173172
RIGHT, 0);
174173

174+
private static final List<Operator> operatorList = new ArrayList<>(
175+
Arrays.asList(
176+
DOT,
177+
PARENS,
178+
BRACKETS,
179+
BRACES,
180+
TRANSPOSE,
181+
DOT_TRANSPOSE,
182+
POW,
183+
DOT_POW,
184+
POST_INC,
185+
POST_DEC,
186+
PRE_INC,
187+
PRE_DEC,
188+
POS,
189+
NEG,
190+
COMPLEMENT,
191+
NOT,
192+
MUL,
193+
DIV,
194+
MOD,
195+
RIGHT_DIV,
196+
DOT_MUL,
197+
DOT_DIV,
198+
DOT_RIGHT_DIV,
199+
ADD,
200+
SUB,
201+
LEFT_SHIFT,
202+
RIGHT_SHIFT,
203+
UNSIGNED_RIGHT_SHIFT,
204+
LESS_THAN,
205+
GREATER_THAN,
206+
LESS_THAN_OR_EQUAL,
207+
GREATER_THAN_OR_EQUAL,
208+
INSTANCEOF,
209+
EQUAL,
210+
NOT_EQUAL,
211+
BITWISE_AND,
212+
BITWISE_OR,
213+
LOGICAL_AND,
214+
LOGICAL_OR,
215+
QUESTION,
216+
COLON,
217+
ASSIGN,
218+
POW_ASSIGN,
219+
DOT_POW_ASSIGN,
220+
MUL_ASSIGN,
221+
DIV_ASSIGN,
222+
MOD_ASSIGN,
223+
RIGHT_DIV_ASSIGN,
224+
DOT_DIV_ASSIGN,
225+
DOT_RIGHT_DIV_ASSIGN,
226+
ADD_ASSIGN,
227+
SUB_ASSIGN,
228+
AND_ASSIGN,
229+
OR_ASSIGN,
230+
LEFT_SHIFT_ASSIGN,
231+
RIGHT_SHIFT_ASSIGN,
232+
UNSIGNED_RIGHT_SHIFT_ASSIGN));
233+
234+
175235
private Operators() {
176236
// NB: Prevent instantiation of utility class.
177237
}
@@ -183,19 +243,7 @@ private Operators() {
183243
* {@link Operators} class, in declaration order.
184244
*/
185245
public static List<Operator> standardList() {
186-
// Build the standard list from all available Operator constants.
187-
final ArrayList<Operator> ops = new ArrayList<>();
188-
for (final Field f : Operators.class.getFields()) {
189-
if (!isOperator(f)) continue;
190-
try {
191-
ops.add((Operator) f.get(null));
192-
}
193-
catch (final IllegalAccessException exc) {
194-
// This should never happen.
195-
throw new IllegalStateException(exc);
196-
}
197-
}
198-
return ops;
246+
return new ArrayList<>(operatorList);
199247
}
200248

201249
// -- Helper methods --
@@ -212,10 +260,4 @@ private static Group group(final String leftSymbol,
212260
return new Group(leftSymbol, rightSymbol, precedence);
213261
}
214262

215-
private static boolean isOperator(final Field f) {
216-
final int mods = f.getModifiers();
217-
return Modifier.isStatic(mods) && Modifier.isFinal(mods) &&
218-
Operator.class.isAssignableFrom(f.getType());
219-
}
220-
221263
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package org.scijava.parsington;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import java.lang.reflect.Field;
6+
import java.lang.reflect.Modifier;
7+
import java.util.ArrayList;
8+
import java.util.Collections;
9+
import java.util.List;
10+
11+
import static org.junit.jupiter.api.Assertions.assertEquals;
12+
13+
public class OperatorsTest extends AbstractTest {
14+
15+
@Test
16+
public void testStandardList() {
17+
// ensure the Operators static list matches a list generated by reflection on the Operators class
18+
List<Operator> fromStatic = Operators.standardList();
19+
List<Operator> fromReflection = standardList();
20+
Collections.sort(fromStatic);
21+
Collections.sort(fromReflection);
22+
23+
assertEquals(fromStatic, fromReflection);
24+
}
25+
26+
public List<Operator> standardList() {
27+
// Build the standard list from all available Operator constants.
28+
final ArrayList<Operator> ops = new ArrayList<>();
29+
for (final Field f : Operators.class.getFields()) {
30+
if (!isOperator(f)) continue;
31+
try {
32+
ops.add((Operator) f.get(null));
33+
} catch (final IllegalAccessException exc) {
34+
// This should never happen.
35+
throw new IllegalStateException(exc);
36+
}
37+
}
38+
return ops;
39+
}
40+
41+
private boolean isOperator(final Field f) {
42+
final int mods = f.getModifiers();
43+
return Modifier.isStatic(mods) && Modifier.isFinal(mods) &&
44+
Operator.class.isAssignableFrom(f.getType());
45+
}
46+
47+
}

0 commit comments

Comments
 (0)