Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 415470
Collapse All | Expand All

(-)a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JSR308SpecSnippetTests.java (-1 / +144 lines)
Lines 16-21 Link Here
16
 *                          Bug 415543 - [1.8][compiler] Incorrect bound index in RuntimeInvisibleTypeAnnotations attribute
16
 *                          Bug 415543 - [1.8][compiler] Incorrect bound index in RuntimeInvisibleTypeAnnotations attribute
17
 *                          Bug 415397 - [1.8][compiler] Type Annotations on wildcard type argument dropped
17
 *                          Bug 415397 - [1.8][compiler] Type Annotations on wildcard type argument dropped
18
 *                          Bug 415399 - [1.8][compiler] Type annotations on constructor results dropped by the code generator
18
 *                          Bug 415399 - [1.8][compiler] Type annotations on constructor results dropped by the code generator
19
 *                          Bug 415470 - [1.8][compiler] Type annotations on class declaration go vanishing
19
 *******************************************************************************/
20
 *******************************************************************************/
20
package org.eclipse.jdt.core.tests.compiler.regression;
21
package org.eclipse.jdt.core.tests.compiler.regression;
21
22
Lines 1424-1430 public class JSR308SpecSnippetTests extends AbstractRegressionTest { Link Here
1424
		"The annotation @MAnno is disallowed for this location\n" + 
1425
		"The annotation @MAnno is disallowed for this location\n" + 
1425
		"----------\n");
1426
		"----------\n");
1426
	}
1427
	}
1427
	public void test030() throws Exception { // WILL FAIL WHEN https://bugs.eclipse.org/bugs/show_bug.cgi?id=415470 IS FIXED.
1428
	public void test030() throws Exception {
1428
		this.runConformTest(
1429
		this.runConformTest(
1429
			new String[] {
1430
			new String[] {
1430
				"X.java",
1431
				"X.java",
Lines 1436-1441 public class JSR308SpecSnippetTests extends AbstractRegressionTest { Link Here
1436
				"}\n",
1437
				"}\n",
1437
		},
1438
		},
1438
		"");
1439
		"");
1440
		// javac b100 produces:
1441
		//		  RuntimeInvisibleAnnotations:
1442
		//			    0: #11() LAnnotation;
1443
		//			    1: #12() LTypeAnnotation;
1439
		String expectedOutput =
1444
		String expectedOutput =
1440
				"// Compiled from X.java (version 1.8 : 52.0, super bit)\n" + 
1445
				"// Compiled from X.java (version 1.8 : 52.0, super bit)\n" + 
1441
				"class X {\n" + 
1446
				"class X {\n" + 
Lines 1457-1462 public class JSR308SpecSnippetTests extends AbstractRegressionTest { Link Here
1457
				"    constant #15 utf8: \"X.java\"\n" + 
1462
				"    constant #15 utf8: \"X.java\"\n" + 
1458
				"    constant #16 utf8: \"RuntimeInvisibleAnnotations\"\n" + 
1463
				"    constant #16 utf8: \"RuntimeInvisibleAnnotations\"\n" + 
1459
				"    constant #17 utf8: \"LAnnotation;\"\n" + 
1464
				"    constant #17 utf8: \"LAnnotation;\"\n" + 
1465
				"    constant #18 utf8: \"LTypeAnnotation;\"\n" + 
1460
				"  \n" + 
1466
				"  \n" + 
1461
				"  // Method descriptor #6 ()V\n" + 
1467
				"  // Method descriptor #6 ()V\n" + 
1462
				"  // Stack: 1, Locals: 1\n" + 
1468
				"  // Stack: 1, Locals: 1\n" + 
Lines 1472-1477 public class JSR308SpecSnippetTests extends AbstractRegressionTest { Link Here
1472
				"  RuntimeInvisibleAnnotations: \n" + 
1478
				"  RuntimeInvisibleAnnotations: \n" + 
1473
				"    #17 @Annotation(\n" + 
1479
				"    #17 @Annotation(\n" + 
1474
				"    )\n" + 
1480
				"    )\n" + 
1481
				"    #18 @TypeAnnotation(\n" + 
1482
				"    )\n" + 
1483
				"}";
1484
		checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
1485
	}
1486
1487
	public void test030a() throws Exception {
1488
		this.runConformTest(
1489
			new String[] {
1490
				"X.java",
1491
				"import java.lang.annotation.*;\n" +
1492
				"import static java.lang.annotation.ElementType.*; \n" +
1493
				"@Retention(RetentionPolicy.RUNTIME)\n" +
1494
				"@Target({TYPE_USE}) @interface TypeAnnotation { }\n" +
1495
				"@Retention(RetentionPolicy.RUNTIME)\n" +
1496
				"@Target({TYPE}) @interface Annotation { }\n" +
1497
				"@Annotation @TypeAnnotation class X {\n" +
1498
				"}\n",
1499
		},
1500
		"");
1501
		String expectedOutput =
1502
				"// Compiled from X.java (version 1.8 : 52.0, super bit)\n" + 
1503
				"class X {\n" + 
1504
				"  Constant pool:\n" + 
1505
				"    constant #1 class: #2 X\n" + 
1506
				"    constant #2 utf8: \"X\"\n" + 
1507
				"    constant #3 class: #4 java/lang/Object\n" + 
1508
				"    constant #4 utf8: \"java/lang/Object\"\n" + 
1509
				"    constant #5 utf8: \"<init>\"\n" + 
1510
				"    constant #6 utf8: \"()V\"\n" + 
1511
				"    constant #7 utf8: \"Code\"\n" + 
1512
				"    constant #8 method_ref: #3.#9 java/lang/Object.<init> ()V\n" + 
1513
				"    constant #9 name_and_type: #5.#6 <init> ()V\n" + 
1514
				"    constant #10 utf8: \"LineNumberTable\"\n" + 
1515
				"    constant #11 utf8: \"LocalVariableTable\"\n" + 
1516
				"    constant #12 utf8: \"this\"\n" + 
1517
				"    constant #13 utf8: \"LX;\"\n" + 
1518
				"    constant #14 utf8: \"SourceFile\"\n" + 
1519
				"    constant #15 utf8: \"X.java\"\n" + 
1520
				"    constant #16 utf8: \"RuntimeVisibleAnnotations\"\n" + 
1521
				"    constant #17 utf8: \"LAnnotation;\"\n" + 
1522
				"    constant #18 utf8: \"LTypeAnnotation;\"\n" + 
1523
				"  \n" + 
1524
				"  // Method descriptor #6 ()V\n" + 
1525
				"  // Stack: 1, Locals: 1\n" + 
1526
				"  X();\n" + 
1527
				"    0  aload_0 [this]\n" + 
1528
				"    1  invokespecial java.lang.Object() [8]\n" + 
1529
				"    4  return\n" + 
1530
				"      Line numbers:\n" + 
1531
				"        [pc: 0, line: 7]\n" + 
1532
				"      Local variable table:\n" + 
1533
				"        [pc: 0, pc: 5] local: this index: 0 type: X\n" + 
1534
				"\n" + 
1535
				"  RuntimeVisibleAnnotations: \n" + 
1536
				"    #17 @Annotation(\n" + 
1537
				"    )\n" + 
1538
				"    #18 @TypeAnnotation(\n" + 
1539
				"    )\n" + 
1540
				"}";
1541
		checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
1542
	}
1543
1544
	public void test030b() throws Exception {
1545
		this.runNegativeTest(
1546
			new String[] {
1547
				"X.java",
1548
				"import java.lang.annotation.*;\n" +
1549
				"import static java.lang.annotation.ElementType.*; \n" +
1550
				"@Retention(RetentionPolicy.RUNTIME)\n" +
1551
				// Only TYPE_USE annotations get this special treatment
1552
				"@Target({TYPE_PARAMETER}) @interface TypeAnnotation { }\n" +
1553
				"@Retention(RetentionPolicy.RUNTIME)\n" +
1554
				"@Target({TYPE}) @interface Annotation { }\n" +
1555
				"@Annotation @TypeAnnotation class X {\n" +
1556
				"}\n",
1557
		},
1558
		"----------\n" + 
1559
		"1. ERROR in X.java (at line 7)\n" + 
1560
		"	@Annotation @TypeAnnotation class X {\n" + 
1561
		"	            ^^^^^^^^^^^^^^^\n" + 
1562
		"The annotation @TypeAnnotation is disallowed for this location\n" + 
1563
		"----------\n");
1564
	}
1565
	public void test030c() throws Exception {
1566
		this.runConformTest(
1567
			new String[] {
1568
				"X.java",
1569
				"import java.lang.annotation.*;\n" +
1570
				"import static java.lang.annotation.ElementType.*; \n" +
1571
				"@Retention(RetentionPolicy.RUNTIME)\n" +
1572
				"@Target({TYPE_USE,TYPE_PARAMETER}) @interface TypeAnnotation { }\n" +
1573
				"@Retention(RetentionPolicy.RUNTIME)\n" +
1574
				"@Target({TYPE}) @interface Annotation { }\n" +
1575
				"@Annotation @TypeAnnotation class X {\n" +
1576
				"}\n",
1577
		},
1578
		"");
1579
		String expectedOutput =
1580
				"// Compiled from X.java (version 1.8 : 52.0, super bit)\n" + 
1581
				"class X {\n" + 
1582
				"  Constant pool:\n" + 
1583
				"    constant #1 class: #2 X\n" + 
1584
				"    constant #2 utf8: \"X\"\n" + 
1585
				"    constant #3 class: #4 java/lang/Object\n" + 
1586
				"    constant #4 utf8: \"java/lang/Object\"\n" + 
1587
				"    constant #5 utf8: \"<init>\"\n" + 
1588
				"    constant #6 utf8: \"()V\"\n" + 
1589
				"    constant #7 utf8: \"Code\"\n" + 
1590
				"    constant #8 method_ref: #3.#9 java/lang/Object.<init> ()V\n" + 
1591
				"    constant #9 name_and_type: #5.#6 <init> ()V\n" + 
1592
				"    constant #10 utf8: \"LineNumberTable\"\n" + 
1593
				"    constant #11 utf8: \"LocalVariableTable\"\n" + 
1594
				"    constant #12 utf8: \"this\"\n" + 
1595
				"    constant #13 utf8: \"LX;\"\n" + 
1596
				"    constant #14 utf8: \"SourceFile\"\n" + 
1597
				"    constant #15 utf8: \"X.java\"\n" + 
1598
				"    constant #16 utf8: \"RuntimeVisibleAnnotations\"\n" + 
1599
				"    constant #17 utf8: \"LAnnotation;\"\n" + 
1600
				"    constant #18 utf8: \"LTypeAnnotation;\"\n" + 
1601
				"  \n" + 
1602
				"  // Method descriptor #6 ()V\n" + 
1603
				"  // Stack: 1, Locals: 1\n" + 
1604
				"  X();\n" + 
1605
				"    0  aload_0 [this]\n" + 
1606
				"    1  invokespecial java.lang.Object() [8]\n" + 
1607
				"    4  return\n" + 
1608
				"      Line numbers:\n" + 
1609
				"        [pc: 0, line: 7]\n" + 
1610
				"      Local variable table:\n" + 
1611
				"        [pc: 0, pc: 5] local: this index: 0 type: X\n" + 
1612
				"\n" + 
1613
				"  RuntimeVisibleAnnotations: \n" + 
1614
				"    #17 @Annotation(\n" + 
1615
				"    )\n" + 
1616
				"    #18 @TypeAnnotation(\n" + 
1617
				"    )\n" + 
1475
				"}";
1618
				"}";
1476
		checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
1619
		checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
1477
	}
1620
	}
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java (-9 / +17 lines)
Lines 19-24 Link Here
19
 *                          Bug 409246 - [1.8][compiler] Type annotations on catch parameters not handled properly
19
 *                          Bug 409246 - [1.8][compiler] Type annotations on catch parameters not handled properly
20
 *                          Bug 415541 - [1.8][compiler] Type annotations in the body of static initializer get dropped
20
 *                          Bug 415541 - [1.8][compiler] Type annotations in the body of static initializer get dropped
21
 *                          Bug 415399 - [1.8][compiler] Type annotations on constructor results dropped by the code generator
21
 *                          Bug 415399 - [1.8][compiler] Type annotations on constructor results dropped by the code generator
22
 *                          Bug 415470 - [1.8][compiler] Type annotations on class declaration go vanishing
22
 *******************************************************************************/
23
 *******************************************************************************/
23
package org.eclipse.jdt.internal.compiler;
24
package org.eclipse.jdt.internal.compiler;
24
25
Lines 354-360 public class ClassFile implements TypeConstants, TypeIds { Link Here
354
			if (typeDeclaration != null) {
355
			if (typeDeclaration != null) {
355
				final Annotation[] annotations = typeDeclaration.annotations;
356
				final Annotation[] annotations = typeDeclaration.annotations;
356
				if (annotations != null) {
357
				if (annotations != null) {
357
					attributesNumber += generateRuntimeAnnotations(annotations);
358
					attributesNumber += generateRuntimeAnnotations(annotations, true);
358
				}
359
				}
359
			}
360
			}
360
		}
361
		}
Lines 450-456 public class ClassFile implements TypeConstants, TypeIds { Link Here
450
			if (fieldDeclaration != null) {
451
			if (fieldDeclaration != null) {
451
				Annotation[] annotations = fieldDeclaration.annotations;
452
				Annotation[] annotations = fieldDeclaration.annotations;
452
				if (annotations != null) {
453
				if (annotations != null) {
453
					attributesNumber += generateRuntimeAnnotations(annotations);
454
					attributesNumber += generateRuntimeAnnotations(annotations, false);
454
				}
455
				}
455
456
456
				if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) {
457
				if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) {
Lines 3180-3186 public class ClassFile implements TypeConstants, TypeIds { Link Here
3180
			if (methodDeclaration != null) {
3181
			if (methodDeclaration != null) {
3181
				Annotation[] annotations = methodDeclaration.annotations;
3182
				Annotation[] annotations = methodDeclaration.annotations;
3182
				if (annotations != null) {
3183
				if (annotations != null) {
3183
					attributesNumber += generateRuntimeAnnotations(annotations);
3184
					attributesNumber += generateRuntimeAnnotations(annotations, false);
3184
				}
3185
				}
3185
				if ((methodBinding.tagBits & TagBits.HasParameterAnnotations) != 0) {
3186
				if ((methodBinding.tagBits & TagBits.HasParameterAnnotations) != 0) {
3186
					Argument[] arguments = methodDeclaration.arguments;
3187
					Argument[] arguments = methodDeclaration.arguments;
Lines 3384-3392 public class ClassFile implements TypeConstants, TypeIds { Link Here
3384
3385
3385
	/**
3386
	/**
3386
	 * @param annotations
3387
	 * @param annotations
3388
	 * @param includeTypeUseAnnotations Used to support JSR308 Section 2.3 special allowance for TYPE_USE annotation used on a type declaration
3387
	 * @return the number of attributes created while dumping the annotations in the .class file
3389
	 * @return the number of attributes created while dumping the annotations in the .class file
3388
	 */
3390
	 */
3389
	private int generateRuntimeAnnotations(final Annotation[] annotations) {
3391
	private int generateRuntimeAnnotations(final Annotation[] annotations, final boolean includeTypeUseAnnotations) {
3390
		int attributesNumber = 0;
3392
		int attributesNumber = 0;
3391
		final int length = annotations.length;
3393
		final int length = annotations.length;
3392
		int visibleAnnotationsCounter = 0;
3394
		int visibleAnnotationsCounter = 0;
Lines 3394-3402 public class ClassFile implements TypeConstants, TypeIds { Link Here
3394
3396
3395
		for (int i = 0; i < length; i++) {
3397
		for (int i = 0; i < length; i++) {
3396
			Annotation annotation = annotations[i];
3398
			Annotation annotation = annotations[i];
3397
			if (annotation.isRuntimeInvisible()) {
3399
			if (annotation.isRuntimeInvisible() || (includeTypeUseAnnotations && annotation.isRuntimeTypeInvisible())) {
3398
				invisibleAnnotationsCounter++;
3400
				invisibleAnnotationsCounter++;
3399
			} else if (annotation.isRuntimeVisible()) {
3401
			} else if (annotation.isRuntimeVisible() || (includeTypeUseAnnotations && annotation.isRuntimeTypeVisible())) {
3400
				visibleAnnotationsCounter++;
3402
				visibleAnnotationsCounter++;
3401
			}
3403
			}
3402
		}
3404
		}
Lines 3422-3428 public class ClassFile implements TypeConstants, TypeIds { Link Here
3422
			loop: for (int i = 0; i < length; i++) {
3424
			loop: for (int i = 0; i < length; i++) {
3423
				if (invisibleAnnotationsCounter == 0) break loop;
3425
				if (invisibleAnnotationsCounter == 0) break loop;
3424
				Annotation annotation = annotations[i];
3426
				Annotation annotation = annotations[i];
3425
				if (annotation.isRuntimeInvisible()) {
3427
				if (annotation.isRuntimeInvisible() || 
3428
						// No need to explicitly check it is type_use and not type_parameter, 
3429
						// that will already have been checked
3430
						(includeTypeUseAnnotations && annotation.isRuntimeTypeInvisible())) {
3426
					int currentAnnotationOffset = this.contentsOffset;
3431
					int currentAnnotationOffset = this.contentsOffset;
3427
					generateAnnotation(annotation, currentAnnotationOffset);
3432
					generateAnnotation(annotation, currentAnnotationOffset);
3428
					invisibleAnnotationsCounter--;
3433
					invisibleAnnotationsCounter--;
Lines 3469-3475 public class ClassFile implements TypeConstants, TypeIds { Link Here
3469
			loop: for (int i = 0; i < length; i++) {
3474
			loop: for (int i = 0; i < length; i++) {
3470
				if (visibleAnnotationsCounter == 0) break loop;
3475
				if (visibleAnnotationsCounter == 0) break loop;
3471
				Annotation annotation = annotations[i];
3476
				Annotation annotation = annotations[i];
3472
				if (annotation.isRuntimeVisible()) {
3477
				if (annotation.isRuntimeVisible() || 
3478
					// No need to explicitly check it is type_use and not type_parameter, 
3479
					// that will already have been checked
3480
					(includeTypeUseAnnotations && annotation.isRuntimeTypeVisible())) {
3473
					visibleAnnotationsCounter--;
3481
					visibleAnnotationsCounter--;
3474
					int currentAnnotationOffset = this.contentsOffset;
3482
					int currentAnnotationOffset = this.contentsOffset;
3475
					generateAnnotation(annotation, currentAnnotationOffset);
3483
					generateAnnotation(annotation, currentAnnotationOffset);
Lines 3495-3500 public class ClassFile implements TypeConstants, TypeIds { Link Here
3495
		}
3503
		}
3496
		return attributesNumber;
3504
		return attributesNumber;
3497
	}
3505
	}
3506
	
3498
	private int generateRuntimeAnnotationsForParameters(Argument[] arguments) {
3507
	private int generateRuntimeAnnotationsForParameters(Argument[] arguments) {
3499
		final int argumentsLength = arguments.length;
3508
		final int argumentsLength = arguments.length;
3500
		final int VISIBLE_INDEX = 0;
3509
		final int VISIBLE_INDEX = 0;
3501
- 

Return to bug 415470