377 private static final byte METHOD_FORMAL_PARAMETER = 0x16;
378 private static final byte THROWS = 0x17;
379 // Type Annotations inside method bodies
380 private static final byte LOCAL_VARIABLE = (byte)0x40;
381 private static final byte RESOURCE_VARIABLE = (byte)0x41;
382 private static final byte EXCEPTION_PARAMETER = (byte)0x42;
383 private static final byte INSTANCEOF = (byte)0x43;
384 private static final byte NEW = (byte)0x44;
385 private static final byte CONSTRUCTOR_REFERENCE = (byte)0x45;
386 private static final byte METHOD_REFERENCE = (byte)0x46;
387 private static final byte CAST = (byte)0x47;
388 private static final byte CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = (byte)0x48;
389 private static final byte METHOD_INVOCATION_TYPE_ARGUMENT = (byte)0x49;
390 private static final byte CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = (byte)0x4A;
391 private static final byte METHOD_REFERENCE_TYPE_ARGUMENT = (byte)0x4B;
392
393 private static TypeAnnotation parseTypeAnnotation(ByteBuffer buf,
394 ConstantPool cp,
395 AnnotatedElement baseDecl,
396 Class<?> container) {
397 TypeAnnotationTargetInfo ti = parseTargetInfo(buf);
398 LocationInfo locationInfo = LocationInfo.parseLocationInfo(buf);
399 Annotation a = AnnotationParser.parseAnnotation(buf, cp, container, false);
400 if (ti == null) // Inside a method for example
401 return null;
402 return new TypeAnnotation(ti, locationInfo, a, baseDecl);
403 }
404
405 private static TypeAnnotationTargetInfo parseTargetInfo(ByteBuffer buf) {
406 byte posCode = buf.get();
407 switch(posCode) {
408 case CLASS_TYPE_PARAMETER:
409 case METHOD_TYPE_PARAMETER: {
410 byte index = buf.get();
411 TypeAnnotationTargetInfo res;
412 if (posCode == CLASS_TYPE_PARAMETER)
413 res = new TypeAnnotationTargetInfo(TypeAnnotationTarget.CLASS_TYPE_PARAMETER,
414 index);
415 else
416 res = new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_TYPE_PARAMETER,
417 index);
418 return res;
419 } // unreachable break;
420 case CLASS_EXTENDS: {
421 short index = buf.getShort();
422 if (index == -1) {
423 return new TypeAnnotationTargetInfo(TypeAnnotationTarget.CLASS_EXTENDS);
424 } else if (index >= 0) {
425 TypeAnnotationTargetInfo res = new TypeAnnotationTargetInfo(TypeAnnotationTarget.CLASS_IMPLEMENTS,
426 index);
427 return res;
428 }} break;
429 case CLASS_TYPE_PARAMETER_BOUND:
430 return parse2ByteTarget(TypeAnnotationTarget.CLASS_TYPE_PARAMETER_BOUND, buf);
431 case METHOD_TYPE_PARAMETER_BOUND:
432 return parse2ByteTarget(TypeAnnotationTarget.METHOD_TYPE_PARAMETER_BOUND, buf);
433 case FIELD:
434 return new TypeAnnotationTargetInfo(TypeAnnotationTarget.FIELD);
435 case METHOD_RETURN:
436 return new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_RETURN);
437 case METHOD_RECEIVER:
438 return new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_RECEIVER);
439 case METHOD_FORMAL_PARAMETER: {
440 byte index = buf.get();
441 return new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_FORMAL_PARAMETER,
442 index);
443 } //unreachable break;
444 case THROWS:
445 return parseShortTarget(TypeAnnotationTarget.THROWS, buf);
446
447 /*
448 * The ones below are inside method bodies, we don't care about them for core reflection
449 * other than adjusting for them in the byte stream.
450 */
451 case LOCAL_VARIABLE:
452 case RESOURCE_VARIABLE:
453 short length = buf.getShort();
454 for (int i = 0; i < length; ++i) {
455 short offset = buf.getShort();
456 short varLength = buf.getShort();
457 short index = buf.getShort();
458 }
459 return null;
460 case EXCEPTION_PARAMETER: {
469 }
470 return null;
471 case CAST:
472 case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
473 case METHOD_INVOCATION_TYPE_ARGUMENT:
474 case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
475 case METHOD_REFERENCE_TYPE_ARGUMENT: {
476 short offset = buf.getShort();
477 byte index = buf.get();
478 }
479 return null;
480
481 default:
482 // will throw error below
483 break;
484 }
485 throw new AnnotationFormatError("Could not parse bytes for type annotations");
486 }
487
488 private static TypeAnnotationTargetInfo parseShortTarget(TypeAnnotationTarget target, ByteBuffer buf) {
489 short index = buf.getShort();
490 return new TypeAnnotationTargetInfo(target, index);
491 }
492 private static TypeAnnotationTargetInfo parse2ByteTarget(TypeAnnotationTarget target, ByteBuffer buf) {
493 byte count = buf.get();
494 byte secondaryIndex = buf.get();
495 return new TypeAnnotationTargetInfo(target,
496 count,
497 secondaryIndex);
498 }
499 }
|
377 private static final byte METHOD_FORMAL_PARAMETER = 0x16;
378 private static final byte THROWS = 0x17;
379 // Type Annotations inside method bodies
380 private static final byte LOCAL_VARIABLE = (byte)0x40;
381 private static final byte RESOURCE_VARIABLE = (byte)0x41;
382 private static final byte EXCEPTION_PARAMETER = (byte)0x42;
383 private static final byte INSTANCEOF = (byte)0x43;
384 private static final byte NEW = (byte)0x44;
385 private static final byte CONSTRUCTOR_REFERENCE = (byte)0x45;
386 private static final byte METHOD_REFERENCE = (byte)0x46;
387 private static final byte CAST = (byte)0x47;
388 private static final byte CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = (byte)0x48;
389 private static final byte METHOD_INVOCATION_TYPE_ARGUMENT = (byte)0x49;
390 private static final byte CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = (byte)0x4A;
391 private static final byte METHOD_REFERENCE_TYPE_ARGUMENT = (byte)0x4B;
392
393 private static TypeAnnotation parseTypeAnnotation(ByteBuffer buf,
394 ConstantPool cp,
395 AnnotatedElement baseDecl,
396 Class<?> container) {
397 try {
398 TypeAnnotationTargetInfo ti = parseTargetInfo(buf);
399 LocationInfo locationInfo = LocationInfo.parseLocationInfo(buf);
400 Annotation a = AnnotationParser.parseAnnotation(buf, cp, container, false);
401 if (ti == null) // Inside a method for example
402 return null;
403 return new TypeAnnotation(ti, locationInfo, a, baseDecl);
404 } catch (IllegalArgumentException | // Bad type in const pool at specified index
405 BufferUnderflowException e) {
406 throw new AnnotationFormatError(e);
407 }
408 }
409
410 private static TypeAnnotationTargetInfo parseTargetInfo(ByteBuffer buf) {
411 int posCode = buf.get() & 0xFF;
412 switch(posCode) {
413 case CLASS_TYPE_PARAMETER:
414 case METHOD_TYPE_PARAMETER: {
415 int index = buf.get() & 0xFF;
416 TypeAnnotationTargetInfo res;
417 if (posCode == CLASS_TYPE_PARAMETER)
418 res = new TypeAnnotationTargetInfo(TypeAnnotationTarget.CLASS_TYPE_PARAMETER,
419 index);
420 else
421 res = new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_TYPE_PARAMETER,
422 index);
423 return res;
424 } // unreachable break;
425 case CLASS_EXTENDS: {
426 short index = buf.getShort(); //needs to be signed
427 if (index == -1) {
428 return new TypeAnnotationTargetInfo(TypeAnnotationTarget.CLASS_EXTENDS);
429 } else if (index >= 0) {
430 TypeAnnotationTargetInfo res = new TypeAnnotationTargetInfo(TypeAnnotationTarget.CLASS_IMPLEMENTS,
431 index);
432 return res;
433 }} break;
434 case CLASS_TYPE_PARAMETER_BOUND:
435 return parse2ByteTarget(TypeAnnotationTarget.CLASS_TYPE_PARAMETER_BOUND, buf);
436 case METHOD_TYPE_PARAMETER_BOUND:
437 return parse2ByteTarget(TypeAnnotationTarget.METHOD_TYPE_PARAMETER_BOUND, buf);
438 case FIELD:
439 return new TypeAnnotationTargetInfo(TypeAnnotationTarget.FIELD);
440 case METHOD_RETURN:
441 return new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_RETURN);
442 case METHOD_RECEIVER:
443 return new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_RECEIVER);
444 case METHOD_FORMAL_PARAMETER: {
445 int index = buf.get() & 0xFF;
446 return new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_FORMAL_PARAMETER,
447 index);
448 } //unreachable break;
449 case THROWS:
450 return parseShortTarget(TypeAnnotationTarget.THROWS, buf);
451
452 /*
453 * The ones below are inside method bodies, we don't care about them for core reflection
454 * other than adjusting for them in the byte stream.
455 */
456 case LOCAL_VARIABLE:
457 case RESOURCE_VARIABLE:
458 short length = buf.getShort();
459 for (int i = 0; i < length; ++i) {
460 short offset = buf.getShort();
461 short varLength = buf.getShort();
462 short index = buf.getShort();
463 }
464 return null;
465 case EXCEPTION_PARAMETER: {
474 }
475 return null;
476 case CAST:
477 case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
478 case METHOD_INVOCATION_TYPE_ARGUMENT:
479 case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
480 case METHOD_REFERENCE_TYPE_ARGUMENT: {
481 short offset = buf.getShort();
482 byte index = buf.get();
483 }
484 return null;
485
486 default:
487 // will throw error below
488 break;
489 }
490 throw new AnnotationFormatError("Could not parse bytes for type annotations");
491 }
492
493 private static TypeAnnotationTargetInfo parseShortTarget(TypeAnnotationTarget target, ByteBuffer buf) {
494 int index = buf.getShort() & 0xFFFF;
495 return new TypeAnnotationTargetInfo(target, index);
496 }
497 private static TypeAnnotationTargetInfo parse2ByteTarget(TypeAnnotationTarget target, ByteBuffer buf) {
498 int count = buf.get() & 0xFF;
499 int secondaryIndex = buf.get() & 0xFF;
500 return new TypeAnnotationTargetInfo(target,
501 count,
502 secondaryIndex);
503 }
504 }
|