275 } |
275 } |
276 |
276 |
277 void validateMethodInvocation(Method method, int options) |
277 void validateMethodInvocation(Method method, int options) |
278 throws InvalidTypeException, |
278 throws InvalidTypeException, |
279 InvocationException { |
279 InvocationException { |
280 |
|
281 /* |
280 /* |
282 * Method must be in this object's class, a superclass, or |
281 * Method must be in this object's class, a superclass, or |
283 * implemented interface |
282 * implemented interface |
284 */ |
283 */ |
285 ReferenceTypeImpl declType = (ReferenceTypeImpl)method.declaringType(); |
284 ReferenceTypeImpl declType = (ReferenceTypeImpl)method.declaringType(); |
286 if (!declType.isAssignableFrom(this)) { |
285 if (!declType.isAssignableFrom(this)) { |
287 throw new IllegalArgumentException("Invalid method"); |
286 throw new IllegalArgumentException("Invalid method"); |
288 } |
287 } |
289 |
288 |
|
289 if (declType instanceof ClassTypeImpl) { |
|
290 validateClassMethodInvocation(method, options); |
|
291 } else if (declType instanceof InterfaceTypeImpl) { |
|
292 validateIfaceMethodInvocation(method, options); |
|
293 } else { |
|
294 throw new InvalidTypeException(); |
|
295 } |
|
296 } |
|
297 |
|
298 void validateClassMethodInvocation(Method method, int options) |
|
299 throws InvalidTypeException, |
|
300 InvocationException { |
|
301 |
290 ClassTypeImpl clazz = invokableReferenceType(method); |
302 ClassTypeImpl clazz = invokableReferenceType(method); |
291 |
303 |
292 /* |
304 /* |
293 * Method must be a non-constructor |
305 * Method must be a non-constructor |
294 */ |
306 */ |
298 |
310 |
299 /* |
311 /* |
300 * For nonvirtual invokes, method must have a body |
312 * For nonvirtual invokes, method must have a body |
301 */ |
313 */ |
302 if ((options & INVOKE_NONVIRTUAL) != 0) { |
314 if ((options & INVOKE_NONVIRTUAL) != 0) { |
303 if (method.declaringType() instanceof InterfaceType) { |
315 if (method.isAbstract()) { |
304 throw new IllegalArgumentException("Interface method"); |
|
305 } else if (method.isAbstract()) { |
|
306 throw new IllegalArgumentException("Abstract method"); |
316 throw new IllegalArgumentException("Abstract method"); |
307 } |
317 } |
308 } |
318 } |
309 |
319 |
310 /* |
320 /* |
322 * Since we are looking for a method with a real body, we |
332 * Since we are looking for a method with a real body, we |
323 * don't need to bother with interfaces/abstract methods. |
333 * don't need to bother with interfaces/abstract methods. |
324 */ |
334 */ |
325 Method invoker = clazz.concreteMethodByName(method.name(), |
335 Method invoker = clazz.concreteMethodByName(method.name(), |
326 method.signature()); |
336 method.signature()); |
327 // isAssignableFrom check above guarantees non-null |
337 // invoker is supposed to be non-null under normal circumstances |
328 invokedClass = (ClassTypeImpl)invoker.declaringType(); |
338 invokedClass = (ClassTypeImpl)invoker.declaringType(); |
329 } |
339 } |
330 /* The above code is left over from previous versions. |
340 /* The above code is left over from previous versions. |
331 * We haven't had time to divine the intent. jjh, 7/31/2003 |
341 * We haven't had time to divine the intent. jjh, 7/31/2003 |
332 */ |
342 */ |
|
343 } |
|
344 |
|
345 void validateIfaceMethodInvocation(Method method, int options) |
|
346 throws InvalidTypeException, |
|
347 InvocationException { |
|
348 /* |
|
349 * Only default methods allowed for nonvirtual invokes |
|
350 */ |
|
351 if (!method.isDefault()) { |
|
352 throw new IllegalArgumentException("Not a default method"); |
|
353 } |
333 } |
354 } |
334 |
355 |
335 PacketStream sendInvokeCommand(final ThreadReferenceImpl thread, |
356 PacketStream sendInvokeCommand(final ThreadReferenceImpl thread, |
336 final ClassTypeImpl refType, |
357 final ClassTypeImpl refType, |
337 final MethodImpl method, |
358 final MethodImpl method, |
368 |
389 |
369 MethodImpl method = (MethodImpl)methodIntf; |
390 MethodImpl method = (MethodImpl)methodIntf; |
370 ThreadReferenceImpl thread = (ThreadReferenceImpl)threadIntf; |
391 ThreadReferenceImpl thread = (ThreadReferenceImpl)threadIntf; |
371 |
392 |
372 if (method.isStatic()) { |
393 if (method.isStatic()) { |
373 if (referenceType() instanceof ClassType) { |
394 if (referenceType() instanceof InterfaceType) { |
|
395 InterfaceType type = (InterfaceType)referenceType(); |
|
396 return type.invokeMethod(thread, method, origArguments, options); |
|
397 } else if (referenceType() instanceof ClassType) { |
374 ClassType type = (ClassType)referenceType(); |
398 ClassType type = (ClassType)referenceType(); |
375 return type.invokeMethod(thread, method, origArguments, options); |
399 return type.invokeMethod(thread, method, origArguments, options); |
376 } else { |
400 } else { |
377 throw new IllegalArgumentException("Invalid type for static method invocation"); |
401 throw new IllegalArgumentException("Invalid type for static method invocation"); |
378 } |
402 } |