Skip to content

Commit 7f9e357

Browse files
committed
minor refactor
1 parent b8ff812 commit 7f9e357

File tree

1 file changed

+58
-70
lines changed

1 file changed

+58
-70
lines changed

src/main/java/org/codehaus/groovy/vmplugin/v8/Selector.java

Lines changed: 58 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -124,22 +124,18 @@ public abstract class Selector {
124124
private static final CallType[] CALL_TYPE_VALUES = CallType.values();
125125

126126
/**
127-
* Returns the Selector
127+
* Returns a Selector or throws a GroovyBugError.
128128
*/
129129
public static Selector getSelector(CacheableCallSite callSite, Class<?> sender, String methodName, int callID, boolean safeNavigation, boolean thisCall, boolean spreadCall, Object[] arguments) {
130130
CallType callType = CALL_TYPE_VALUES[callID];
131131
return switch (callType) {
132-
case INIT ->
133-
new InitSelector(callSite, sender, methodName, callType, safeNavigation, thisCall, spreadCall, arguments);
134-
case METHOD ->
135-
new MethodSelector(callSite, sender, methodName, callType, safeNavigation, thisCall, spreadCall, arguments);
136-
case GET ->
137-
new PropertySelector(callSite, sender, methodName, callType, safeNavigation, thisCall, spreadCall, arguments);
138-
case SET -> throw new GroovyBugError("your call tried to do a property set, which is not supported.");
139-
case CAST -> new CastSelector(callSite, arguments);
140-
case INTERFACE ->
141-
new InterfaceSelector(callSite, sender, methodName, callType, safeNavigation, thisCall, spreadCall, arguments);
142-
default -> throw new GroovyBugError("unexpected call type");
132+
case INIT -> new InitSelector(callSite, sender, methodName, callType, safeNavigation, thisCall, spreadCall, arguments);
133+
case METHOD -> new MethodSelector(callSite, sender, methodName, callType, safeNavigation, thisCall, spreadCall, arguments);
134+
case GET -> new PropertySelector(callSite, sender, methodName, callType, safeNavigation, thisCall, spreadCall, arguments);
135+
case SET -> throw new GroovyBugError("your call tried to do a property set, which is not supported.");
136+
case CAST -> new CastSelector(callSite, sender, methodName, arguments);
137+
case INTERFACE -> new InterfaceSelector(callSite, sender, methodName, callType, safeNavigation, thisCall, spreadCall, arguments);
138+
default -> throw new GroovyBugError("unexpected call type");
143139
};
144140
}
145141

@@ -164,35 +160,37 @@ public Object getCorrectedReceiver() {
164160
private static class CastSelector extends MethodSelector {
165161
private final Class<?> staticSourceType, staticTargetType;
166162

167-
public CastSelector(CacheableCallSite callSite, Object[] arguments) {
168-
super(callSite, Selector.class, "", CallType.CAST, Boolean.FALSE, Boolean.FALSE, Boolean.FALSE, arguments);
163+
CastSelector(final CacheableCallSite callSite, final Class<?> sender, final String spec, final Object[] args) {
164+
super(callSite, sender, spec, CallType.CAST, Boolean.FALSE, Boolean.FALSE, Boolean.FALSE, args);
169165
this.staticSourceType = callSite.type().parameterType(0);
170166
this.staticTargetType = callSite.type().returnType();
171167
}
172168

173169
@Override
174170
public void setCallSiteTarget() {
175-
// target types String, Enum and Class are handled by the compiler
171+
// NOTE: target types String, Class, and Enum are handled by the compiler
176172

177-
handleBoolean();
178-
handleNullWithoutBoolean();
173+
if (handle == null) handleBoolean();
174+
if (handle == null) handleNullWithoutBoolean();
179175

180-
// !! from here on args[0] is always not null !!
181-
handleInstanceCase();
176+
// NOTE: !! from here on if handle is null, args[0] is always not null !!
182177

183-
// targetType is abstract Collection fitting for HashSet or ArrayList
184-
// and object is Collection or array
185-
handleCollections();
186-
handleSAM();
178+
if (handle == null) handleIsAnInstance();
179+
if (handle == null) handleCollections();
180+
if (handle == null) handleSAM();
187181

188182
// will handle :
189183
// * collection case where argument is an array
190184
// * array transformation (staticTargetType.isArray())
191185
// * constructor invocation
192-
// * final GroovyCastException
193-
castToTypeFallBack();
186+
// * throw GroovyCastException
187+
if (handle == null) {
188+
handle = MethodHandles.insertArguments(DTT_CAST_TO_TYPE, 1, staticTargetType);
189+
}
194190

195-
if (!handle.type().equals(callSite.type())) castAndSetGuards();
191+
if (!handle.type().equals(callSite.type())) {
192+
castAndSetGuards();
193+
}
196194
}
197195

198196
private void castAndSetGuards() {
@@ -202,62 +200,34 @@ private void castAndSetGuards() {
202200
}
203201

204202
private void handleNullWithoutBoolean() {
205-
if (handle != null || args[0] != null) return;
206-
207-
if (staticTargetType.isPrimitive()) {
208-
handle = MethodHandles.insertArguments(GROOVY_CAST_EXCEPTION, 1, staticTargetType);
209-
// need to call here because we used the static target type
210-
// it won't be done otherwise because handle.type() == callSite.type()
211-
castAndSetGuards();
212-
} else {
213-
handle = MethodHandles.identity(staticSourceType);
203+
if (args[0] == null) {
204+
if (staticTargetType.isPrimitive()) {
205+
handle = MethodHandles.insertArguments(GROOVY_CAST_EXCEPTION, 1, staticTargetType);
206+
// need to call here because we used the static target type
207+
// it won't be done otherwise because handle.type() == callSite.type()
208+
castAndSetGuards();
209+
} else {
210+
handle = MethodHandles.identity(staticSourceType);
211+
}
214212
}
215213
}
216214

217-
private void handleInstanceCase() {
218-
if (handle != null) return;
219-
215+
private void handleIsAnInstance() {
220216
if (staticTargetType.isAssignableFrom(args[0].getClass())) {
221217
handle = MethodHandles.identity(staticSourceType);
222218
}
223219
}
224220

225-
private static boolean isAbstractClassOf(Class<?> toTest, Class<?> givenOnCallSite) {
226-
if (!toTest.isAssignableFrom(givenOnCallSite)) return false;
227-
if (givenOnCallSite.isInterface()) return true;
228-
return Modifier.isAbstract(givenOnCallSite.getModifiers());
229-
}
230-
231-
private void handleCollections() {
232-
if (handle != null) return;
233-
234-
if (!(args[0] instanceof Collection)) return;
235-
if (isAbstractClassOf(HashSet.class, staticTargetType)) {
236-
handle = HASHSET_CONSTRUCTOR;
237-
} else if (isAbstractClassOf(ArrayList.class, staticTargetType)) {
238-
handle = ARRAYLIST_CONSTRUCTOR;
239-
}
240-
}
241-
242221
private void handleSAM() {
243-
if (handle != null) return;
244-
245-
if (!(args[0] instanceof Closure)) return;
246-
Method m = CachedSAMClass.getSAMMethod(staticTargetType);
247-
if (m == null) return;
248-
//TODO: optimize: add guard based on type Closure
249-
handle = MethodHandles.insertArguments(SAM_CONVERSION, 1, m, staticTargetType);
250-
}
251-
252-
private void castToTypeFallBack() {
253-
if (handle != null) return;
254-
255-
// generic fallback to castToType
256-
handle = MethodHandles.insertArguments(DTT_CAST_TO_TYPE, 1, staticTargetType);
222+
if (args[0] instanceof Closure) {
223+
Method m = CachedSAMClass.getSAMMethod(staticTargetType);
224+
if (m == null) return;
225+
// TODO: optimize: add guard based on type Closure
226+
handle = MethodHandles.insertArguments(SAM_CONVERSION, 1, m, staticTargetType);
227+
}
257228
}
258229

259230
private void handleBoolean() {
260-
if (handle != null) return;
261231
boolean primitive = (staticTargetType == boolean.class);
262232
if (!primitive && staticTargetType != Boolean.class) return;
263233
// boolean->boolean, Boolean->boolean, boolean->Boolean are handled by the compiler
@@ -278,6 +248,24 @@ private void handleBoolean() {
278248

279249
handle = MethodHandles.guardWithTest(ifNull, thenZero, elseCallAsBoolean);
280250
}
251+
252+
/**
253+
* Sets handle if object is Collection and target type is an abstract
254+
* type fitting for HashSet or ArrayList.
255+
*/
256+
private void handleCollections() {
257+
if (args[0] instanceof Collection) {
258+
if (isAbstractClassOf(HashSet.class, staticTargetType)) {
259+
handle = HASHSET_CONSTRUCTOR;
260+
} else if (isAbstractClassOf(ArrayList.class, staticTargetType)) {
261+
handle = ARRAYLIST_CONSTRUCTOR;
262+
}
263+
}
264+
}
265+
266+
private static boolean isAbstractClassOf(final Class<?> type, final Class<?> callSiteType) {
267+
return (callSiteType.isInterface() || Modifier.isAbstract(callSiteType.getModifiers())) && type.isAssignableFrom(callSiteType);
268+
}
281269
}
282270

283271
private static class PropertySelector extends MethodSelector {

0 commit comments

Comments
 (0)