1 /*******************************************************************************
2 * Copyright (c) 2000, 2017 IBM Corporation and others.
3 *
4 * This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License 2.0
6 * which accompanies this distribution, and is available at
7 * https://www.eclipse.org/legal/epl-2.0/
8 *
9 * SPDX-License-Identifier: EPL-2.0
10 *
11 * Contributors:
12 * IBM Corporation - initial API and implementation
13 *******************************************************************************/
14 package org.eclipse.jdt.core.tests.model;
15
16 import java.io.IOException;
17
18 import org.eclipse.core.resources.IFolder;
19 import org.eclipse.core.runtime.CoreException;
20 import org.eclipse.core.runtime.IPath;
21 import org.eclipse.core.runtime.IProgressMonitor;
22 import org.eclipse.core.runtime.Path;
23 import org.eclipse.jdt.core.*;
24 import org.eclipse.jdt.core.search.IJavaSearchConstants;
25 import org.eclipse.jdt.core.search.IJavaSearchScope;
26 import org.eclipse.jdt.core.search.SearchEngine;
27 import org.eclipse.jdt.internal.core.ClasspathEntry;
28
29 import junit.framework.Test;
30
31 public class ClassFileTests extends ModifyingResourceTests {
32
33 IPackageFragmentRoot jarRoot;
34 ICompilationUnit workingCopy;
35 IOrdinaryClassFile classFile;
36
ClassFileTests(String name)37 public ClassFileTests(String name) {
38 super(name);
39 }
40
41 // Use this static initializer to specify subset for tests
42 // All specified tests which do not belong to the class are skipped...
43 static {
44 // TESTS_PREFIX = "testGetCategories";
45 // TESTS_NAMES = new String[] { "testBug372687"};
46 // TESTS_NUMBERS = new int[] { 13 };
47 // TESTS_RANGE = new int[] { 16, -1 };
48 }
suite()49 public static Test suite() {
50 return buildModelTestSuite(ClassFileTests.class);
51 }
52
53 @Override
setUpSuite()54 public void setUpSuite() throws Exception {
55 super.setUpSuite();
56 IJavaProject javaProject = createJavaProject("P", new String[0], new String[] {"JCL15_LIB", "/P/lib"}, "", JavaCore.VERSION_1_5);
57 String[] pathAndContents = new String[] {
58 "nongeneric/A.java",
59 "package nongeneric;\n" +
60 "public class A {\n" +
61 "}",
62 "generic/X.java",
63 "package generic;\n" +
64 "public class X<T> {\n" +
65 " <U extends Exception> X<T> foo(X<T> x) throws RuntimeException, U {\n" +
66 " return null;\n" +
67 " }\n" +
68 " <K, V extends T> V foo(K key, V value) throws Exception {\n" +
69 " return value;\n" +
70 " }\n" +
71 "}",
72 "generic/Y.java",
73 "package generic;\n" +
74 "public class Y<K, L> {\n" +
75 "}",
76 "generic/Z.java",
77 "package generic;\n" +
78 "public class Z<T extends Object & I<? super T>> {\n" +
79 "}",
80 "generic/I.java",
81 "package generic;\n" +
82 "public interface I<T> {\n" +
83 "}",
84 "generic/W.java",
85 "package generic;\n" +
86 "public class W<T extends X<T> , U extends T> {\n" +
87 "}",
88 "generic/V.java",
89 "package generic;\n" +
90 "public class V extends X<Thread> implements I<String> {\n" +
91 "}",
92 "generic/GenericField.java",
93 "package generic;\n" +
94 "import java.util.Collection;\n" +
95 "public class GenericField {\n" +
96 " protected Collection<String> myField;\n" +
97 "}",
98 "annotated/X.java",
99 "package annotated;\n" +
100 "@MyOtherAnnot\n" +
101 "public class X {\n" +
102 " @MyOtherAnnot\n" +
103 " Object field;\n" +
104 " @MyOtherAnnot\n" +
105 " void method() {}\n" +
106 " @MyAnnot(_int=1)\n" +
107 " void foo01() {}\n" +
108 " @MyAnnot(_byte=(byte)2)\n" +
109 " void foo02() {}\n" +
110 " @MyAnnot(_short=(short)3)\n" +
111 " void foo03() {}\n" +
112 " @MyAnnot(_char='a')\n" +
113 " void foo04() {}\n" +
114 " @MyAnnot(_float=1.2f)\n" +
115 " void foo05() {}\n" +
116 " @MyAnnot(_double=3.4)\n" +
117 " void foo06() {}\n" +
118 " @MyAnnot(_boolean=true)\n" +
119 " void foo07() {}\n" +
120 " @MyAnnot(_long=123456789L)\n" +
121 " void foo08() {}\n" +
122 " @MyAnnot(_string=\"abc\")\n" +
123 " void foo09() {}\n" +
124 " @MyAnnot(_annot=@MyOtherAnnot)\n" +
125 " void foo10() {}\n" +
126 " @MyAnnot(_class=String.class)\n" +
127 " void foo11() {}\n" +
128 " @MyAnnot(_enum=MyEnum.SECOND)\n" +
129 " void foo12() {}\n" +
130 " @MyAnnot(_array={1, 2, 3})\n" +
131 " void foo13() {}\n" +
132 " @MyAnnot(_neg_int = -2)\n" +
133 " void foo14() {}\n" +
134 " @MyAnnot(_neg_float=-2.0f)\n" +
135 " void foo15() {}\n" +
136 " @MyAnnot(_neg_double=-2.0)\n" +
137 " void foo16() {}\n" +
138 " @MyAnnot(_neg_long=-2L)\n" +
139 " void foo17() {}\n" +
140 "}\n" +
141 "@interface MyAnnot {\n" +
142 " int _int() default 0;\n" +
143 " byte _byte() default 0;\n" +
144 " short _short() default 0;\n" +
145 " char _char() default ' ';\n" +
146 " float _float() default 0.0f;\n" +
147 " double _double() default 0.0;\n" +
148 " boolean _boolean() default false;\n" +
149 " long _long() default 0L;\n" +
150 " String _string() default \" \";\n" +
151 " MyOtherAnnot _annot() default @MyOtherAnnot;\n" +
152 " Class _class() default Object.class;\n" +
153 " MyEnum _enum() default MyEnum.FIRST;\n" +
154 " int[] _array() default {};\n" +
155 " int _neg_int() default -1;\n" +
156 " float _neg_float() default -1.0f;\n" +
157 " double _neg_double() default -1.0;\n" +
158 " long _neg_long() default -1L;\n" +
159 "}\n" +
160 "@interface MyOtherAnnot {\n" +
161 "}\n" +
162 "enum MyEnum {\n" +
163 " FIRST, SECOND;\n" +
164 "}",
165 "annotated/Y.java",
166 "package annotated;\n" +
167 "import java.lang.annotation.*;\n" +
168 "import static java.lang.annotation.ElementType.*;\n" +
169 "import static java.lang.annotation.RetentionPolicy.*;\n" +
170 "@Deprecated\n" +
171 "@Documented\n" +
172 "@Inherited\n" +
173 "@Retention(SOURCE)\n" +
174 "@Target({PACKAGE, TYPE, ANNOTATION_TYPE, METHOD, CONSTRUCTOR, FIELD, LOCAL_VARIABLE, PARAMETER})\n" +
175 "public @interface Y {\n" +
176 "}",
177 "varargs/X.java",
178 "package varargs;\n" +
179 "public class X {\n" +
180 " void foo(String s, Object ... others) {\n" +
181 " }\n" +
182 "}",
183 "workingcopy/X.java",
184 "package workingcopy;\n" +
185 "public class X {\n" +
186 " void foo() {\n" +
187 " System.out.println();\n" +
188 " }\n" +
189 "}",
190 "workingcopy/Y.java",
191 "package workingcopy;\n" +
192 "public class Y<W> {\n" +
193 " <T> T foo(T t, String... args) {\n" +
194 " return t;\n" +
195 " }\n" +
196 "}",
197 "annotated/MyAnnotation.java",
198 "package annotated;\n" +
199 "import java.lang.annotation.Retention;\n" +
200 "import java.lang.annotation.RetentionPolicy;\n" +
201 "@Retention(value = RetentionPolicy.RUNTIME)\n" +
202 "public @interface MyAnnotation {}",
203 "annotated/MyAnnotation2.java",
204 "package annotated;\n" +
205 "import java.lang.annotation.Retention;\n" +
206 "import java.lang.annotation.RetentionPolicy;\n" +
207 "@Retention(value = RetentionPolicy.SOURCE)\n" +
208 "public @interface MyAnnotation2 {}",
209 "annotated/MyAnnotation3.java",
210 "package annotated;\n" +
211 "import java.lang.annotation.Retention;\n" +
212 "import java.lang.annotation.RetentionPolicy;\n" +
213 "@Retention(value = RetentionPolicy.CLASS)\n" +
214 "public @interface MyAnnotation3 {}",
215 "test342757/X.java",
216 "package test342757;\n" +
217 "public class X {\n" +
218 " class B {\n" +
219 " public B(@Deprecated @Annot String s) {}\n" +
220 " public void foo(@Deprecated @Annot int j) {}\n" +
221 " }\n" +
222 "}",
223 "test342757/Annot.java",
224 "package test342757;\n" +
225 "import java.lang.annotation.Retention;\n" +
226 "import static java.lang.annotation.RetentionPolicy.*;\n" +
227 "@Retention(CLASS)\n" +
228 "@interface Annot {}",
229 };
230 addLibrary(javaProject, "lib.jar", "libsrc.zip", pathAndContents, JavaCore.VERSION_1_5);
231 this.jarRoot = javaProject.getPackageFragmentRoot(getFile("/P/lib.jar"));
232 }
233
234 @Override
tearDownSuite()235 public void tearDownSuite() throws Exception {
236 super.tearDownSuite();
237 deleteProject("P");
238 }
239
240 @Override
tearDown()241 protected void tearDown() throws Exception {
242 if (this.workingCopy != null)
243 this.workingCopy.discardWorkingCopy();
244 if (this.classFile != null) {
245 removeLibrary(getJavaProject("P"), "lib2.jar", "src2.zip");
246 this.classFile = null;
247 }
248 super.tearDown();
249 }
250
createClassFile(String contents)251 private IOrdinaryClassFile createClassFile(String contents) throws CoreException, IOException {
252 IJavaProject project = getJavaProject("P");
253 addLibrary(project, "lib2.jar", "src2.zip", new String[] {"p/X.java", contents}, "1.5");
254 this.classFile = project.getPackageFragmentRoot(getFile("/P/lib2.jar")).getPackageFragment("p").getOrdinaryClassFile("X.class");
255 return this.classFile;
256 }
257
258 /*
259 * Ensures that the annotations of a binary type are correct
260 */
testAnnotations01()261 public void testAnnotations01() throws JavaModelException {
262 IType type = this.jarRoot.getPackageFragment("annotated").getOrdinaryClassFile("X.class").getType();
263 assertAnnotationsEqual(
264 "@annotated.MyOtherAnnot\n",
265 type.getAnnotations());
266 }
267
268 /*
269 * Ensures that the annotations of a binary method are correct
270 */
testAnnotations02()271 public void testAnnotations02() throws JavaModelException {
272 IType type = this.jarRoot.getPackageFragment("annotated").getOrdinaryClassFile("X.class").getType();
273 IMethod method = type.getMethod("method", new String[0]);
274 assertAnnotationsEqual(
275 "@annotated.MyOtherAnnot\n",
276 method.getAnnotations());
277 }
278
279 /*
280 * Ensures that the annotations of a binary field are correct
281 */
testAnnotations03()282 public void testAnnotations03() throws JavaModelException {
283 IType type = this.jarRoot.getPackageFragment("annotated").getOrdinaryClassFile("X.class").getType();
284 IField field = type.getField("field");
285 assertAnnotationsEqual(
286 "@annotated.MyOtherAnnot\n",
287 field.getAnnotations());
288 }
289
290 /*
291 * Ensures that an annotation with an int value is correct
292 */
testAnnotations04()293 public void testAnnotations04() throws JavaModelException {
294 IType type = this.jarRoot.getPackageFragment("annotated").getOrdinaryClassFile("X.class").getType();
295 IMethod method = type.getMethod("foo01", new String[0]);
296 assertAnnotationsEqual(
297 "@annotated.MyAnnot(_int=(int)1)\n",
298 method.getAnnotations());
299 }
300
301 /*
302 * Ensures that an annotation with a byte value is correct
303 */
testAnnotations05()304 public void testAnnotations05() throws JavaModelException {
305 IType type = this.jarRoot.getPackageFragment("annotated").getOrdinaryClassFile("X.class").getType();
306 IMethod method = type.getMethod("foo02", new String[0]);
307 assertAnnotationsEqual(
308 "@annotated.MyAnnot(_byte=(byte)2)\n",
309 method.getAnnotations());
310 }
311
312 /*
313 * Ensures that an annotation with a short value is correct
314 */
testAnnotations06()315 public void testAnnotations06() throws JavaModelException {
316 IType type = this.jarRoot.getPackageFragment("annotated").getOrdinaryClassFile("X.class").getType();
317 IMethod method = type.getMethod("foo03", new String[0]);
318 assertAnnotationsEqual(
319 "@annotated.MyAnnot(_short=(short)3)\n",
320 method.getAnnotations());
321 }
322
323 /*
324 * Ensures that an annotation with a char value is correct
325 */
testAnnotations07()326 public void testAnnotations07() throws JavaModelException {
327 IType type = this.jarRoot.getPackageFragment("annotated").getOrdinaryClassFile("X.class").getType();
328 IMethod method = type.getMethod("foo04", new String[0]);
329 assertAnnotationsEqual(
330 "@annotated.MyAnnot(_char='a')\n",
331 method.getAnnotations());
332 }
333
334 /*
335 * Ensures that an annotation with a float value is correct
336 */
testAnnotations08()337 public void testAnnotations08() throws JavaModelException {
338 IType type = this.jarRoot.getPackageFragment("annotated").getOrdinaryClassFile("X.class").getType();
339 IMethod method = type.getMethod("foo05", new String[0]);
340 assertAnnotationsEqual(
341 "@annotated.MyAnnot(_float=1.2f)\n",
342 method.getAnnotations());
343 }
344
345 /*
346 * Ensures that an annotation with a double value is correct
347 */
testAnnotations09()348 public void testAnnotations09() throws JavaModelException {
349 IType type = this.jarRoot.getPackageFragment("annotated").getOrdinaryClassFile("X.class").getType();
350 IMethod method = type.getMethod("foo06", new String[0]);
351 assertAnnotationsEqual(
352 "@annotated.MyAnnot(_double=(double)3.4)\n",
353 method.getAnnotations());
354 }
355
356 /*
357 * Ensures that an annotation with a boolean value is correct
358 */
testAnnotations10()359 public void testAnnotations10() throws JavaModelException {
360 IType type = this.jarRoot.getPackageFragment("annotated").getOrdinaryClassFile("X.class").getType();
361 IMethod method = type.getMethod("foo07", new String[0]);
362 assertAnnotationsEqual(
363 "@annotated.MyAnnot(_boolean=true)\n",
364 method.getAnnotations());
365 }
366
367 /*
368 * Ensures that an annotation with a long value is correct
369 */
testAnnotations11()370 public void testAnnotations11() throws JavaModelException {
371 IType type = this.jarRoot.getPackageFragment("annotated").getOrdinaryClassFile("X.class").getType();
372 IMethod method = type.getMethod("foo08", new String[0]);
373 assertAnnotationsEqual(
374 "@annotated.MyAnnot(_long=123456789L)\n",
375 method.getAnnotations());
376 }
377
378 /*
379 * Ensures that an annotation with a String value is correct
380 */
testAnnotations12()381 public void testAnnotations12() throws JavaModelException {
382 IType type = this.jarRoot.getPackageFragment("annotated").getOrdinaryClassFile("X.class").getType();
383 IMethod method = type.getMethod("foo09", new String[0]);
384 assertAnnotationsEqual(
385 "@annotated.MyAnnot(_string=\"abc\")\n",
386 method.getAnnotations());
387 }
388
389 /*
390 * Ensures that an annotation with an annotation value is correct
391 */
testAnnotations13()392 public void testAnnotations13() throws JavaModelException {
393 IType type = this.jarRoot.getPackageFragment("annotated").getOrdinaryClassFile("X.class").getType();
394 IMethod method = type.getMethod("foo10", new String[0]);
395 assertAnnotationsEqual(
396 "@annotated.MyAnnot(_annot=@annotated.MyOtherAnnot)\n",
397 method.getAnnotations());
398 }
399
400 /*
401 * Ensures that an annotation with a Class value is correct
402 */
testAnnotations14()403 public void testAnnotations14() throws JavaModelException {
404 IType type = this.jarRoot.getPackageFragment("annotated").getOrdinaryClassFile("X.class").getType();
405 IMethod method = type.getMethod("foo11", new String[0]);
406 assertAnnotationsEqual(
407 "@annotated.MyAnnot(_class=java.lang.String.class)\n",
408 method.getAnnotations());
409 }
410
411 /*
412 * Ensures that an annotation with an enumeration value is correct
413 */
testAnnotations15()414 public void testAnnotations15() throws JavaModelException {
415 IType type = this.jarRoot.getPackageFragment("annotated").getOrdinaryClassFile("X.class").getType();
416 IMethod method = type.getMethod("foo12", new String[0]);
417 assertAnnotationsEqual(
418 "@annotated.MyAnnot(_enum=annotated.MyEnum.SECOND)\n",
419 method.getAnnotations());
420 }
421
422 /*
423 * Ensures that an annotation with an array value is correct
424 */
testAnnotations16()425 public void testAnnotations16() throws JavaModelException {
426 IType type = this.jarRoot.getPackageFragment("annotated").getOrdinaryClassFile("X.class").getType();
427 IMethod method = type.getMethod("foo13", new String[0]);
428 assertAnnotationsEqual(
429 "@annotated.MyAnnot(_array={(int)1, (int)2, (int)3})\n",
430 method.getAnnotations());
431 }
432
433 /*
434 * Ensures that the standard annotations of a binary type are correct
435 * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=248309 )
436 */
testAnnotations17()437 public void testAnnotations17() throws JavaModelException {
438 IType type = this.jarRoot.getPackageFragment("annotated").getOrdinaryClassFile("Y.class").getType();
439 assertAnnotationsEqual(
440 "@java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.LOCAL_VARIABLE, java.lang.annotation.ElementType.ANNOTATION_TYPE, java.lang.annotation.ElementType.PACKAGE})\n" +
441 "@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE)\n" +
442 "@java.lang.Deprecated\n" +
443 "@java.lang.annotation.Documented\n" +
444 "@java.lang.annotation.Inherited\n",
445 type.getAnnotations());
446 }
447
448 /*
449 * Ensures that the annotation of a binary type exists
450 */
testAnnotations18()451 public void testAnnotations18() throws JavaModelException {
452 IAnnotation annotation = this.jarRoot.getPackageFragment("annotated").getOrdinaryClassFile("X.class").getType().getAnnotation("annotated.MyOtherAnnot");
453 assertTrue("Annotation should exist", annotation.exists());
454 }
455
456 /*
457 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=286407
458 */
testAnnotations19()459 public void testAnnotations19() throws JavaModelException {
460 IPackageFragment packageFragment = this.jarRoot.getPackageFragment("annotated");
461 IOrdinaryClassFile classFile2 = packageFragment.getOrdinaryClassFile("MyAnnotation.class");
462 IType type = classFile2.getType();
463 assertAnnotationsEqual(
464 "@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)\n",
465 type.getAnnotations());
466 }
467 /*
468 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=286407
469 */
testAnnotations20()470 public void testAnnotations20() throws JavaModelException {
471 IPackageFragment packageFragment = this.jarRoot.getPackageFragment("annotated");
472 IOrdinaryClassFile classFile2 = packageFragment.getOrdinaryClassFile("MyAnnotation2.class");
473 IType type = classFile2.getType();
474 assertAnnotationsEqual(
475 "@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE)\n",
476 type.getAnnotations());
477 }
478 /*
479 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=286407
480 */
testAnnotations21()481 public void testAnnotations21() throws JavaModelException {
482 IPackageFragment packageFragment = this.jarRoot.getPackageFragment("annotated");
483 IOrdinaryClassFile classFile2 = packageFragment.getOrdinaryClassFile("MyAnnotation3.class");
484 IType type = classFile2.getType();
485 assertAnnotationsEqual(
486 "@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS)\n",
487 type.getAnnotations());
488 }
489
490 /*
491 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=248312
492 * Ensures that an annotation with a negative int value is correct
493 */
testAnnotations22()494 public void testAnnotations22() throws JavaModelException {
495 IType type = this.jarRoot.getPackageFragment("annotated").getOrdinaryClassFile("X.class").getType();
496 IMethod method = type.getMethod("foo14", new String[0]);
497 assertAnnotationsEqual(
498 "@annotated.MyAnnot(_neg_int=(int)-2)\n",
499 method.getAnnotations());
500 }
501
502 /*
503 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=248312
504 * Ensures that an annotation with a negative float value is correct
505 */
testAnnotations23()506 public void testAnnotations23() throws JavaModelException {
507 IType type = this.jarRoot.getPackageFragment("annotated").getOrdinaryClassFile("X.class").getType();
508 IMethod method = type.getMethod("foo15", new String[0]);
509 assertAnnotationsEqual(
510 "@annotated.MyAnnot(_neg_float=-2.0f)\n",
511 method.getAnnotations());
512 }
513
514 /*
515 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=248312
516 * Ensures that an annotation with a negative double value is correct
517 */
testAnnotations24()518 public void testAnnotations24() throws JavaModelException {
519 IType type = this.jarRoot.getPackageFragment("annotated").getOrdinaryClassFile("X.class").getType();
520 IMethod method = type.getMethod("foo16", new String[0]);
521 assertAnnotationsEqual(
522 "@annotated.MyAnnot(_neg_double=(double)-2.0)\n",
523 method.getAnnotations());
524 }
525
526 /*
527 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=248312
528 * Ensures that an annotation with a negative long value is correct
529 */
testAnnotations25()530 public void testAnnotations25() throws JavaModelException {
531 IType type = this.jarRoot.getPackageFragment("annotated").getOrdinaryClassFile("X.class").getType();
532 IMethod method = type.getMethod("foo17", new String[0]);
533 assertAnnotationsEqual(
534 "@annotated.MyAnnot(_neg_long=-2L)\n",
535 method.getAnnotations());
536 }
537
538 /*
539 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=342757
540 */
testAnnotations26()541 public void testAnnotations26() throws JavaModelException {
542 IType type = this.jarRoot.getPackageFragment("test342757").getOrdinaryClassFile("X$B.class").getType();
543 IMethod[] methods = type.getMethods();
544 String expected =
545 "@test342757.Annot\n" +
546 "@java.lang.Deprecated\n" +
547 "@test342757.Annot\n" +
548 "@java.lang.Deprecated\n";
549 StringBuffer buffer = new StringBuffer();
550 for (int i = 0, max = methods.length; i < max; i++) {
551 ILocalVariable[] parameters = methods[i].getParameters();
552 for (int j = 0, max2 = parameters.length; j < max2; j++) {
553 IAnnotation[] annotations = parameters[j].getAnnotations();
554 for (int n = 0; n < annotations.length; n++) {
555 IAnnotation annotation = annotations[n];
556 appendAnnotation(buffer, annotation);
557 buffer.append("\n");
558 }
559 }
560 }
561 String actual = buffer.toString();
562 if (!expected.equals(actual)) {
563 System.out.println(displayString(actual, 2) + this.endChar);
564 }
565 assertEquals("Unexpected annotations", expected, actual);
566 }
567
568 /*
569 * Ensures that no exception is thrown for a .class file name with a dot
570 * (regression test for bug 114140 assertion failed when opening a class file not not the classpath)
571 */
testDotName()572 public void testDotName() throws JavaModelException {
573 IType type = getClassFile("/P/X.Y.class").getType();
574 assertEquals("X.Y", type.getElementName());
575 }
576
577 /*
578 * Ensure that the exception types of a binary method are correct.
579 */
testExceptionTypes1()580 public void testExceptionTypes1() throws JavaModelException {
581 IType type = this.jarRoot.getPackageFragment("generic").getOrdinaryClassFile("X.class").getType();
582 IMethod method = type.getMethod("foo", new String[] {"TK;", "TV;"});
583 assertStringsEqual(
584 "Unexpected return type",
585 "Ljava.lang.Exception;\n",
586 method.getExceptionTypes());
587 }
588
589 /*
590 * Ensure that the exception types of a binary method is correct.
591 */
testExceptionTypes2()592 public void testExceptionTypes2() throws JavaModelException {
593 IType type = this.jarRoot.getPackageFragment("generic").getOrdinaryClassFile("X.class").getType();
594 IMethod method = type.getMethod("foo", new String[] {"Lgeneric.X<TT;>;"});
595 assertStringsEqual(
596 "Unexpected return type",
597 "Ljava.lang.RuntimeException;\n" +
598 "TU;\n",
599 method.getExceptionTypes());
600 }
601
602 /*
603 * Ensure that the categories for a class are correct.
604 */
testGetCategories01()605 public void testGetCategories01() throws CoreException, IOException {
606 createClassFile(
607 "package p;\n" +
608 "/**\n" +
609 " * @category test\n" +
610 " */\n" +
611 "public class X {\n" +
612 "}"
613 );
614 String[] categories = this.classFile.getType().getCategories();
615 assertStringsEqual(
616 "Unexpected categories",
617 "test\n",
618 categories);
619 }
testGetCategories02()620 public void testGetCategories02() throws CoreException, IOException {
621 createClassFile(
622 "package p;\n" +
623 "/**\n" +
624 " * @category test1 test2 test3 test4 test5 test6 test7 test8 test9 test10\n" +
625 " */\n" +
626 "public class X {\n" +
627 "}"
628 );
629 String[] categories = this.classFile.getType().getCategories();
630 assertStringsEqual(
631 "Unexpected categories",
632 "test1\ntest2\ntest3\ntest4\ntest5\ntest6\ntest7\ntest8\ntest9\ntest10\n",
633 categories);
634 }
635
636 /*
637 * Ensure that the categories for a field are correct.
638 */
testGetCategories03()639 public void testGetCategories03() throws CoreException, IOException {
640 createClassFile(
641 "package p;\n" +
642 "public class X {\n" +
643 " /**\n" +
644 " * @category test\n" +
645 " */\n" +
646 " int field;\n" +
647 "}"
648 );
649 String[] categories = this.classFile.getType().getField("field").getCategories();
650 assertStringsEqual(
651 "Unexpected categories",
652 "test\n",
653 categories);
654 }
testGetCategories04()655 public void testGetCategories04() throws CoreException, IOException {
656 createClassFile(
657 "package p;\n" +
658 "public class X {\n" +
659 " /**\n" +
660 " * @category test1 test2\n" +
661 " */\n" +
662 " int field;\n" +
663 "}"
664 );
665 String[] categories = this.classFile.getType().getField("field").getCategories();
666 assertStringsEqual(
667 "Unexpected categories",
668 "test1\ntest2\n",
669 categories);
670 }
671
672 /*
673 * Ensure that the categories for a method are correct.
674 */
testGetCategories05()675 public void testGetCategories05() throws CoreException, IOException {
676 createClassFile(
677 "package p;\n" +
678 "public class X {\n" +
679 " /**\n" +
680 " * @category test\n" +
681 " */\n" +
682 " void foo() {}\n" +
683 "}"
684 );
685 String[] categories = this.classFile.getType().getMethod("foo", new String[0]).getCategories();
686 assertStringsEqual(
687 "Unexpected categories",
688 "test\n",
689 categories);
690 }
testGetCategories06()691 public void testGetCategories06() throws CoreException, IOException {
692 createClassFile(
693 "package p;\n" +
694 "public class X {\n" +
695 " /**\n" +
696 " * @category test1 test2 test3 test4 test5\n" +
697 " */\n" +
698 " void foo() {}\n" +
699 "}"
700 );
701 String[] categories = this.classFile.getType().getMethod("foo", new String[0]).getCategories();
702 assertStringsEqual(
703 "Unexpected categories",
704 "test1\ntest2\ntest3\ntest4\ntest5\n",
705 categories);
706 }
707 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=125676
testGetCategories07()708 public void testGetCategories07() throws CoreException, IOException {
709 createClassFile(
710 "package p;\n" +
711 "public class X {\n" +
712 " /**\n" +
713 " * @category " +
714 " * test\n" +
715 " */\n" +
716 " void foo() {}\n" +
717 "}"
718 );
719 String[] categories = this.classFile.getType().getMethod("foo", new String[0]).getCategories();
720 assertStringsEqual(
721 "Unexpected categories",
722 "",
723 categories);
724 }
testGetCategories08()725 public void testGetCategories08() throws CoreException, IOException {
726 createClassFile(
727 "package p;\n" +
728 "public class X {\n" +
729 " /**\n" +
730 " * @category" +
731 " * test\n" +
732 " */\n" +
733 " void foo() {}\n" +
734 "}"
735 );
736 String[] categories = this.classFile.getType().getMethod("foo", new String[0]).getCategories();
737 assertStringsEqual(
738 "Unexpected categories",
739 "",
740 categories);
741 }
testGetCategories09()742 public void testGetCategories09() throws CoreException, IOException {
743 createClassFile(
744 "package p;\n" +
745 "public class X {\n" +
746 " /**\n" +
747 " * @category test1" +
748 " * test2\n" +
749 " */\n" +
750 " void foo() {}\n" +
751 "}"
752 );
753 String[] categories = this.classFile.getType().getMethod("foo", new String[0]).getCategories();
754 assertStringsEqual(
755 "Unexpected categories",
756 "test1\n",
757 categories);
758 }
759
760 /*
761 * Ensure that the categories for a member that has no categories when another member defines some are correct.
762 */
testGetCategories10()763 public void testGetCategories10() throws CoreException, IOException {
764 createClassFile(
765 "package p;\n" +
766 "public class X {\n" +
767 " int field1;\n" +
768 " /**\n" +
769 " * @category test\n" +
770 " */\n" +
771 " int field2;\n" +
772 "}"
773 );
774 String[] categories = this.classFile.getType().getField("field1").getCategories();
775 assertStringsEqual(
776 "Unexpected categories",
777 "",
778 categories);
779 }
780
781 /*
782 * Ensures that the children of a type for a given category are correct.
783 */
testGetChildrenForCategory01()784 public void testGetChildrenForCategory01() throws CoreException, IOException {
785 createClassFile(
786 "package p;\n" +
787 "public class X {\n" +
788 " /**\n" +
789 " * @category test\n" +
790 " */\n" +
791 " int field;\n" +
792 " /**\n" +
793 " * @category test\n" +
794 " */\n" +
795 " void foo1() {}\n" +
796 " /**\n" +
797 " * @category test\n" +
798 " */\n" +
799 " void foo2() {}\n" +
800 " /**\n" +
801 " * @category other\n" +
802 " */\n" +
803 " void foo3() {}\n" +
804 "}"
805 );
806 IJavaElement[] children = this.classFile.getType().getChildrenForCategory("test");
807 assertElementsEqual(
808 "Unexpected children",
809 "field [in X [in X.class [in p [in lib2.jar [in P]]]]]\n" +
810 "foo1() [in X [in X.class [in p [in lib2.jar [in P]]]]]\n" +
811 "foo2() [in X [in X.class [in p [in lib2.jar [in P]]]]]",
812 children);
813 }
testGetChildrenForCategory02()814 public void testGetChildrenForCategory02() throws CoreException, IOException {
815 createClassFile(
816 "package p;\n" +
817 "public class X {\n" +
818 " /**\n" +
819 " * @category fields test all\n" +
820 " */\n" +
821 " int field;\n" +
822 " /**\n" +
823 " * @category methods test all\n" +
824 " */\n" +
825 " void foo1() {}\n" +
826 " /**\n" +
827 " * @category methods test all\n" +
828 " */\n" +
829 " void foo2() {}\n" +
830 " /**\n" +
831 " * @category methods other all\n" +
832 " */\n" +
833 " void foo3() {}\n" +
834 "}"
835 );
836 IJavaElement[] tests = this.classFile.getType().getChildrenForCategory("test");
837 assertElementsEqual(
838 "Unexpected children",
839 "field [in X [in X.class [in p [in lib2.jar [in P]]]]]\n" +
840 "foo1() [in X [in X.class [in p [in lib2.jar [in P]]]]]\n" +
841 "foo2() [in X [in X.class [in p [in lib2.jar [in P]]]]]",
842 tests);
843 IJavaElement[] methods = this.classFile.getType().getChildrenForCategory("methods");
844 assertElementsEqual(
845 "Unexpected children",
846 "foo1() [in X [in X.class [in p [in lib2.jar [in P]]]]]\n" +
847 "foo2() [in X [in X.class [in p [in lib2.jar [in P]]]]]\n" +
848 "foo3() [in X [in X.class [in p [in lib2.jar [in P]]]]]",
849 methods);
850 IJavaElement[] others = this.classFile.getType().getChildrenForCategory("other");
851 assertElementsEqual(
852 "Unexpected children",
853 "foo3() [in X [in X.class [in p [in lib2.jar [in P]]]]]",
854 others);
855 IJavaElement[] all = this.classFile.getType().getChildrenForCategory("all");
856 assertElementsEqual(
857 "Unexpected children",
858 "field [in X [in X.class [in p [in lib2.jar [in P]]]]]\n" +
859 "foo1() [in X [in X.class [in p [in lib2.jar [in P]]]]]\n" +
860 "foo2() [in X [in X.class [in p [in lib2.jar [in P]]]]]\n" +
861 "foo3() [in X [in X.class [in p [in lib2.jar [in P]]]]]",
862 all);
863 }
864
865 /*
866 * Ensures that the default value for an annotation method is correct.
867 */
testDefaultValue1()868 public void testDefaultValue1() throws JavaModelException {
869 IType type = this.jarRoot.getPackageFragment("annotated").getOrdinaryClassFile("MyAnnot.class").getType();
870 IMethod method = type.getMethod("_int", new String[0]);
871 assertMemberValuePairEquals(
872 "_int=(int)0",
873 method.getDefaultValue());
874 }
875
876 /*
877 * Ensures that the default value for an annotation method is correct.
878 */
testDefaultValue2()879 public void testDefaultValue2() throws JavaModelException {
880 IType type = this.jarRoot.getPackageFragment("annotated").getOrdinaryClassFile("MyAnnot.class").getType();
881 IMethod method = type.getMethod("_annot", new String[0]);
882 assertMemberValuePairEquals(
883 "_annot=@annotated.MyOtherAnnot",
884 method.getDefaultValue());
885 }
886
887 /*
888 * Ensures that the default value for an annotation method is correct.
889 */
testDefaultValue3()890 public void testDefaultValue3() throws JavaModelException {
891 IType type = this.jarRoot.getPackageFragment("annotated").getOrdinaryClassFile("MyAnnot.class").getType();
892 IMethod method = type.getMethod("_array", new String[0]);
893 assertMemberValuePairEquals(
894 "_array=[unknown]{}",
895 method.getDefaultValue());
896 }
897
898
899 /*
900 * Ensures that the default value for an regular method is correct.
901 */
testDefaultValue4()902 public void testDefaultValue4() throws JavaModelException {
903 IType type = getPackageFragmentRoot("P", getExternalJCLPathString(JavaCore.VERSION_1_5)).getPackageFragment("java.lang").getOrdinaryClassFile("Object.class").getType();
904 IMethod method = type.getMethod("toString", new String[0]);
905 assertMemberValuePairEquals(
906 "<null>",
907 method.getDefaultValue());
908 }
909
910 /*
911 * Ensures that getFullyQualifiedName() behaves correctly for a top level binary type
912 */
testGetFullyQualifiedName1()913 public void testGetFullyQualifiedName1() {
914 IType type = getClassFile("/P/lib/p/X.class").getType();
915 assertEquals("p.X", type.getFullyQualifiedName());
916 }
917
918 /*
919 * Ensures that getFullyQualifiedName() behaves correctly for a top level binary type
920 */
testGetFullyQualifiedName2()921 public void testGetFullyQualifiedName2() {
922 IType type = getClassFile("/P/lib/X.class").getType();
923 assertEquals("X", type.getFullyQualifiedName());
924 }
925
926 /*
927 * Ensures that getFullyQualifiedName() behaves correctly for a member type
928 */
testGetFullyQualifiedName3()929 public void testGetFullyQualifiedName3() {
930 IType type = getClassFile("/P/lib/p/X$Member.class").getType();
931 assertEquals("p.X$Member", type.getFullyQualifiedName());
932 }
933
934 /*
935 * Ensures that getFullyQualifiedName() behaves correctly for a local type
936 */
testGetFullyQualifiedName4()937 public void testGetFullyQualifiedName4() {
938 IType type = getClassFile("/P/lib/p/X$Local.class").getType();
939 assertEquals("p.X$Local", type.getFullyQualifiedName());
940 }
941
942 /*
943 * Ensures that getFullyQualifiedName('.') behaves correctly for a top level binary type
944 */
testGetFullyQualifiedName5()945 public void testGetFullyQualifiedName5() {
946 IType type = getClassFile("/P/lib/p/X.class").getType();
947 assertEquals("p.X", type.getFullyQualifiedName('.'));
948 }
949
950 /*
951 * Ensures that getFullyQualifiedName('.') behaves correctly for a top level binary type
952 */
testGetFullyQualifiedName6()953 public void testGetFullyQualifiedName6() {
954 IType type = getClassFile("/P/lib/X.class").getType();
955 assertEquals("X", type.getFullyQualifiedName('.'));
956 }
957
958 /*
959 * Ensures that getFullyQualifiedName() behaves correctly for a member type
960 */
testGetFullyQualifiedName7()961 public void testGetFullyQualifiedName7() {
962 IType type = getClassFile("/P/lib/p/X$Member.class").getType();
963 assertEquals("p.X.Member", type.getFullyQualifiedName('.'));
964 }
965
966 /*
967 * Ensures that getFullyQualifiedName() behaves correctly for a local type
968 */
testGetFullyQualifiedName8()969 public void testGetFullyQualifiedName8() {
970 IType type = getClassFile("/P/lib/p/X$Local.class").getType();
971 assertEquals("p.X.Local", type.getFullyQualifiedName('.'));
972 }
973
974 /*
975 * Ensures that the resource of a .class file in an external folder is null
976 */
testGetResource()977 public void testGetResource() throws Exception {
978 try {
979 createExternalFolder("externalLib/p");
980 createExternalFile("externalLib/p/X.class", "");
981 createJavaProject("P1", new String[0], new String[] {getExternalResourcePath("externalLib")}, "");
982 IOrdinaryClassFile classFile1 = getClassFile("P1", getExternalResourcePath("externalLib"), "p", "X.class");
983 assertResourceEquals(
984 "Unexpected resource",
985 "<null>",
986 classFile1.getResource());
987 } finally {
988 deleteExternalResource("externalLib");
989 deleteProject("P1");
990 }
991 }
992
993 /*
994 * Ensures that IType#getSuperclassTypeSignature() is correct for a binary type.
995 * (regression test for bug 78520 [model] IType#getSuperInterfaceTypeSignatures() doesn't include type arguments)
996 */
testGetSuperclassTypeSignature()997 public void testGetSuperclassTypeSignature() throws JavaModelException {
998 IType type = this.jarRoot.getPackageFragment("generic").getOrdinaryClassFile("V.class").getType();
999 assertEquals(
1000 "Unexpected signature",
1001 "Lgeneric.X<Ljava.lang.Thread;>;",
1002 type.getSuperclassTypeSignature());
1003 }
1004
1005 /*
1006 * Ensures that IType#getSuperInterfaceTypeSignatures() is correct for a binary type.
1007 * (regression test for bug 78520 [model] IType#getSuperInterfaceTypeSignatures() doesn't include type arguments)
1008 */
testGetSuperInterfaceTypeSignatures()1009 public void testGetSuperInterfaceTypeSignatures() throws JavaModelException {
1010 IType type = this.jarRoot.getPackageFragment("generic").getOrdinaryClassFile("V.class").getType();
1011 assertStringsEqual(
1012 "Unexpected signatures",
1013 "Lgeneric.I<Ljava.lang.String;>;\n",
1014 type.getSuperInterfaceTypeSignatures());
1015 }
1016
1017 /*
1018 * Ensures that if a root folder (that has a jar like name) is opened, and then a Jar package fragment root created on this root folder,
1019 * then attempting to open a class file in this folder doesn't throw a ClassCastException
1020 * (regression test for bug 204652 "Open Type": ClassCastException in conjunction with a class folder)
1021 */
testJarLikeRootFolder()1022 public void testJarLikeRootFolder() throws CoreException {
1023 try {
1024 IJavaProject p = createJavaProject("P1", new String[0], new String[] {"/P1/classFolder.jar"}, "");
1025 IFolder folder = createFolder("/P1/classFolder.jar/p");
1026 createFile("/P1/classFolder.jar/X.class", "p");
1027
1028 // populate cache with a valid package fragment root and a valid package fragment
1029 IPackageFragment validPkg = p.getPackageFragmentRoot(folder.getParent()).getPackageFragment("p");
1030 validPkg.open(null);
1031
1032 // create an invalid package fragment root and an invalid package fragment
1033 IPackageFragment invalidPkg = p.getPackageFragmentRoot("/P1/classFolder.jar").getPackageFragment("p");
1034
1035 // ensure that the class file cannot be opened with a valid exception
1036 IOrdinaryClassFile openable = invalidPkg.getOrdinaryClassFile("X.class");
1037 JavaModelException expected = null;
1038 try {
1039 openable.open(null);
1040 } catch (JavaModelException e) {
1041 expected = e;
1042 }
1043 assertExceptionEquals("Unexpected exception", new Path("/P1/classFolder.jar").toOSString() + " does not exist", expected);
1044 } finally {
1045 deleteProject("P1");
1046 }
1047 }
1048
1049 /*
1050 * Ensures that the parameter names of a binary method with source attached are correct.
1051 */
testParameterNames01()1052 public void testParameterNames01() throws CoreException {
1053 IMethod method = this.jarRoot.getPackageFragment("generic").getOrdinaryClassFile("X.class").getType().getMethod("foo", new String[] {"TK;", "TV;"});
1054 String[] parameterNames = method.getParameterNames();
1055 assertStringsEqual(
1056 "Unexpected parameter names",
1057 "key\n" +
1058 "value\n",
1059 parameterNames);
1060 }
1061
1062 /*
1063 * Ensures that the parameter names of a binary method without source attached are correct.
1064 */
testParameterNames02()1065 public void testParameterNames02() throws CoreException {
1066 IPath sourceAttachmentPath = this.jarRoot.getSourceAttachmentPath();
1067 try {
1068 attachSource(this.jarRoot, null, null);
1069 IMethod method = this.jarRoot.getPackageFragment("generic").getOrdinaryClassFile("X.class").getType().getMethod("foo", new String[] {"TK;", "TV;"});
1070 String[] parameterNames = method.getParameterNames();
1071 assertStringsEqual(
1072 "Unexpected parameter names",
1073 "key\n" +
1074 "value\n",
1075 parameterNames);
1076 } finally {
1077 attachSource(this.jarRoot, sourceAttachmentPath.toString(), null);
1078 }
1079 }
1080
1081 /**
1082 * Ensure that the type parameter signatures of a binary type are correct.
1083 */
testParameterTypeSignatures1()1084 public void testParameterTypeSignatures1() throws JavaModelException {
1085 IType type = this.jarRoot.getPackageFragment("generic").getOrdinaryClassFile("X.class").getType();
1086 assertStringsEqual(
1087 "Unexpected type parameters",
1088 "T:Ljava.lang.Object;\n",
1089 type.getTypeParameterSignatures());
1090 }
1091
1092 /**
1093 * Ensure that the type parameter signatures of a binary type are correct.
1094 */
testParameterTypeSignatures2()1095 public void testParameterTypeSignatures2() throws JavaModelException {
1096 IType type = this.jarRoot.getPackageFragment("nongeneric").getOrdinaryClassFile("A.class").getType();
1097 assertStringsEqual(
1098 "Unexpected type parameters",
1099 "",
1100 type.getTypeParameterSignatures());
1101 }
1102
1103 /**
1104 * Ensure that the type parameter signatures of a binary type are correct.
1105 */
testParameterTypeSignatures3()1106 public void testParameterTypeSignatures3() throws JavaModelException {
1107 IType type = this.jarRoot.getPackageFragment("generic").getOrdinaryClassFile("Y.class").getType();
1108 assertStringsEqual(
1109 "Unexpected type parameters",
1110 "K:Ljava.lang.Object;\n" +
1111 "L:Ljava.lang.Object;\n",
1112 type.getTypeParameterSignatures());
1113 }
1114
1115 /**
1116 * Ensure that the type parameter signatures of a binary type are correct.
1117 */
testParameterTypeSignatures4()1118 public void testParameterTypeSignatures4() throws JavaModelException {
1119 IType type = this.jarRoot.getPackageFragment("generic").getOrdinaryClassFile("Z.class").getType();
1120 assertStringsEqual(
1121 "Unexpected type parameters",
1122 "T:Ljava.lang.Object;:Lgeneric.I<-TT;>;\n",
1123 type.getTypeParameterSignatures());
1124 }
1125
1126 /**
1127 * Ensure that the type parameter signatures of a binary type are correct.
1128 */
testParameterTypeSignatures5()1129 public void testParameterTypeSignatures5() throws JavaModelException {
1130 IType type = this.jarRoot.getPackageFragment("generic").getOrdinaryClassFile("W.class").getType();
1131 assertStringsEqual(
1132 "Unexpected type parameters",
1133 "T:Lgeneric.X<TT;>;\n" +
1134 "U:TT;\n",
1135 type.getTypeParameterSignatures());
1136 }
1137
1138 /**
1139 * Ensure that the type parameter signatures of a binary method are correct.
1140 * @deprecated
1141 */
testParameterTypeSignatures6()1142 public void testParameterTypeSignatures6() throws JavaModelException {
1143 IType type = this.jarRoot.getPackageFragment("generic").getOrdinaryClassFile("X.class").getType();
1144 IMethod method = type.getMethod("foo", new String[] {"TK;", "TV;"});
1145 assertStringsEqual(
1146 "Unexpected type parameters",
1147 "K:Ljava.lang.Object;\n" +
1148 "V:TT;\n",
1149 method.getTypeParameterSignatures());
1150 }
1151
1152 /*
1153 * Ensures that the raw parameter names of a binary method with source attached are correct.
1154 */
testRawParameterNames01()1155 public void testRawParameterNames01() throws CoreException {
1156 IMethod method = this.jarRoot.getPackageFragment("generic").getOrdinaryClassFile("X.class").getType().getMethod("foo", new String[] {"TK;", "TV;"});
1157 String[] parameterNames = method.getRawParameterNames();
1158 assertStringsEqual(
1159 "Unexpected parameter names",
1160 "arg0\n" +
1161 "arg1\n",
1162 parameterNames);
1163 }
1164
1165 /*
1166 * Ensures that the raw parameter names of a binary method without source attached are correct.
1167 */
testRawParameterNames02()1168 public void testRawParameterNames02() throws CoreException {
1169 IPath sourceAttachmentPath = this.jarRoot.getSourceAttachmentPath();
1170 try {
1171 attachSource(this.jarRoot, null, null);
1172 IMethod method = this.jarRoot.getPackageFragment("generic").getOrdinaryClassFile("X.class").getType().getMethod("foo", new String[] {"TK;", "TV;"});
1173 String[] parameterNames = method.getParameterNames();
1174 assertStringsEqual(
1175 "Unexpected parameter names",
1176 "key\n" +
1177 "value\n",
1178 parameterNames);
1179 } finally {
1180 attachSource(this.jarRoot, sourceAttachmentPath.toString(), null);
1181 }
1182 }
1183
1184 /*
1185 * Ensure that the return type of a binary method is correct.
1186 */
testReturnType1()1187 public void testReturnType1() throws JavaModelException {
1188 IType type = this.jarRoot.getPackageFragment("generic").getOrdinaryClassFile("X.class").getType();
1189 IMethod method = type.getMethod("foo", new String[] {"TK;", "TV;"});
1190 assertEquals(
1191 "Unexpected return type",
1192 "TV;",
1193 method.getReturnType());
1194 }
1195
1196 /*
1197 * Ensure that the return type of a binary method is correct.
1198 */
testReturnType2()1199 public void testReturnType2() throws JavaModelException {
1200 IType type = this.jarRoot.getPackageFragment("generic").getOrdinaryClassFile("X.class").getType();
1201 IMethod method = type.getMethod("foo", new String[] {"Lgeneric.X<TT;>;"});
1202 assertEquals(
1203 "Unexpected return type",
1204 "Lgeneric.X<TT;>;",
1205 method.getReturnType());
1206 }
1207
1208 /*
1209 * Ensures that asking for the source range of a IOrdinaryClassFile in a non-Java project throws a JavaModelException
1210 * (regression test for bug 132494 JavaModelException opening up class file in non java project)
1211 */
testSourceRange1()1212 public void testSourceRange1() throws CoreException { // was testSourceRangeNonJavaProject()
1213 try {
1214 createProject("Simple");
1215 createFile("/Simple/X.class", "");
1216 IOrdinaryClassFile classX = getClassFile("/Simple/X.class");
1217 JavaModelException exception = null;
1218 try {
1219 classX.getSourceRange();
1220 } catch (JavaModelException e) {
1221 exception = e;
1222 }
1223 assertExceptionEquals("Unexpected exception", "Simple does not exist", exception);
1224 } finally {
1225 deleteProject("Simple");
1226 }
1227 }
1228
1229 /*
1230 * Ensures that asking for the source range of a IOrdinaryClassFile not on the classpath of a Java project doesn't throw a JavaModelException
1231 * (regression test for bug 138507 exception in .class file editor for classes imported via plug-in import)
1232 */
testSourceRange2()1233 public void testSourceRange2() throws CoreException { // was testSourceRangeNotOnClasspath()
1234 try {
1235 createJavaProject("P2", new String[] {"src"}, "bin");
1236 createFile("/P2/bin/X.class", "");
1237 IOrdinaryClassFile classX = getClassFile("/P2/bin/X.class");
1238 assertNull("Unxepected source range", classX.getSourceRange());
1239 } finally {
1240 deleteProject("P2");
1241 }
1242 }
1243
1244 /*
1245 * Ensures that asking for the source range of a IOrdinaryClassFile in proj==src case without the corresponding .java file doesn't throw a JavaModelException
1246 * (regression test for bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=221904 )
1247 */
testSourceRange3()1248 public void testSourceRange3() throws CoreException {
1249 try {
1250 createJavaProject("P2", new String[] {""}, "");
1251 createFile("/P2/X.class", "");
1252 IOrdinaryClassFile classX = getClassFile("/P2/X.class");
1253 assertNull("Unxepected source range", classX.getSourceRange());
1254 } finally {
1255 deleteProject("P2");
1256 }
1257 }
1258
1259 /*
1260 * Ensure that opening a binary type parameter when its parent has not been open yet
1261 * doesn't throw a JavaModelException
1262 * (regression test for bug 101228 JME on code assist)
1263 */
testTypeParameter()1264 public void testTypeParameter() throws CoreException {
1265 IOrdinaryClassFile clazz = this.jarRoot.getPackageFragment("generic").getOrdinaryClassFile("X.class");
1266 ITypeParameter typeParameter = clazz.getType().getTypeParameter("T");
1267 clazz.close();
1268 assertStringsEqual(
1269 "Unexpected bounds",
1270 "java.lang.Object\n",
1271 typeParameter.getBounds());
1272 }
1273
1274 /*
1275 * Ensure that a method with varargs has the AccVarargs flag set.
1276 */
testVarargs()1277 public void testVarargs() throws JavaModelException {
1278 IType type = this.jarRoot.getPackageFragment("varargs").getOrdinaryClassFile("X.class").getType();
1279 IMethod method = type.getMethod("foo", new String[]{"Ljava.lang.String;", "[Ljava.lang.Object;"});
1280 assertTrue("Should have the AccVarargs flag set", Flags.isVarargs(method.getFlags()));
1281 }
1282
1283 /*
1284 * Ensures that a class file can be turned into a working copy and that its children are correct.
1285 */
testWorkingCopy01()1286 public void testWorkingCopy01() throws CoreException {
1287 IOrdinaryClassFile clazz = this.jarRoot.getPackageFragment("workingcopy").getOrdinaryClassFile("X.class");
1288 this.workingCopy = clazz.getWorkingCopy(null/*primary owner*/, (IProgressMonitor) null/*no progress*/);
1289 assertElementDescendants(
1290 "Unexpected children",
1291 "[Working copy] X.class\n" +
1292 " package workingcopy\n" +
1293 " class X\n" +
1294 " void foo()",
1295 this.workingCopy);
1296 }
1297
1298 /*
1299 * Ensures that a class file without source attached can be turned into a working copy and that its children are correct.
1300 */
testWorkingCopy02()1301 public void testWorkingCopy02() throws CoreException {
1302 IPath sourceAttachmentPath = this.jarRoot.getSourceAttachmentPath();
1303 try {
1304 attachSource(this.jarRoot, null, null);
1305 IOrdinaryClassFile clazz = this.jarRoot.getPackageFragment("workingcopy").getOrdinaryClassFile("X.class");
1306 assertNull("Should not have source attached", clazz.getSource());
1307 this.workingCopy = clazz.getWorkingCopy(null/*primary owner*/, (IProgressMonitor) null/*no progress*/);
1308 assertElementDescendants(
1309 "Unexpected children",
1310 "[Working copy] X.class\n" +
1311 " package workingcopy\n" +
1312 " class X\n" +
1313 " X()\n" +
1314 " void foo()",
1315 this.workingCopy);
1316 } finally {
1317 attachSource(this.jarRoot, sourceAttachmentPath.toString(), null);
1318 }
1319 }
1320
1321 /*
1322 * Ensures that a class file can be turned into a working copy, modified and that its children are correct.
1323 */
testWorkingCopy03()1324 public void testWorkingCopy03() throws CoreException {
1325 IOrdinaryClassFile clazz = this.jarRoot.getPackageFragment("workingcopy").getOrdinaryClassFile("X.class");
1326 this.workingCopy = clazz.getWorkingCopy(null/*primary owner*/, (IProgressMonitor) null/*no progress*/);
1327 this.workingCopy.getBuffer().setContents(
1328 "package workingcopy;\n" +
1329 "public class X {\n" +
1330 " void bar() {\n" +
1331 " }\n" +
1332 "}"
1333 );
1334 this.workingCopy.reconcile(ICompilationUnit.NO_AST, false/*don't force problems*/, null/*primary owner*/, null/*no progress*/);
1335 assertElementDescendants(
1336 "Unexpected children",
1337 "[Working copy] X.class\n" +
1338 " package workingcopy\n" +
1339 " class X\n" +
1340 " void bar()",
1341 this.workingCopy);
1342 }
1343
1344 /*
1345 * Ensures that a class file working copy cannot be commited
1346 */
testWorkingCopy04()1347 public void testWorkingCopy04() throws CoreException {
1348 IOrdinaryClassFile clazz = this.jarRoot.getPackageFragment("workingcopy").getOrdinaryClassFile("X.class");
1349 this.workingCopy = clazz.getWorkingCopy(null/*primary owner*/, (IProgressMonitor) null/*no progress*/);
1350 this.workingCopy.getBuffer().setContents(
1351 "package workingcopy;\n" +
1352 "public class X {\n" +
1353 " void bar() {\n" +
1354 " }\n" +
1355 "}"
1356 );
1357 JavaModelException exception = null;
1358 try {
1359 this.workingCopy.commitWorkingCopy(false/*don't force*/, null);
1360 } catch (JavaModelException e) {
1361 exception = e;
1362 }
1363 assertEquals(
1364 "Unxepected JavaModelException",
1365 "Java Model Exception: Java Model Status [Operation not supported for specified element type(s):[Working copy] X.class [in workingcopy [in lib.jar [in P]]]]",
1366 exception.toString());
1367 }
1368
1369 /*
1370 * Ensures that a type can be created in class file working copy.
1371 */
testWorkingCopy05()1372 public void testWorkingCopy05() throws CoreException {
1373 IOrdinaryClassFile clazz = this.jarRoot.getPackageFragment("workingcopy").getOrdinaryClassFile("X.class");
1374 this.workingCopy = clazz.getWorkingCopy(null/*primary owner*/, (IProgressMonitor) null/*no progress*/);
1375 this.workingCopy.createType(
1376 "class Y {\n" +
1377 "}",
1378 null,
1379 false/*don't force*/,
1380 null);
1381 assertElementDescendants(
1382 "Unexpected children",
1383 "[Working copy] X.class\n" +
1384 " package workingcopy\n" +
1385 " class X\n" +
1386 " void foo()\n" +
1387 " class Y",
1388 this.workingCopy);
1389 }
1390
1391 /*
1392 * Ensures that the primary compilation unit of class file working copy is correct.
1393 */
testWorkingCopy06()1394 public void testWorkingCopy06() throws CoreException {
1395 IOrdinaryClassFile clazz = this.jarRoot.getPackageFragment("workingcopy").getOrdinaryClassFile("X.class");
1396 WorkingCopyOwner owner = new WorkingCopyOwner() {};
1397 this.workingCopy = clazz.getWorkingCopy(owner, null/*no progress*/);
1398 ICompilationUnit primary = this.workingCopy.getPrimary();
1399 assertEquals("Unexpected owner of primary working copy", null, primary.getOwner());
1400 }
1401
1402 /*
1403 * Ensures that a class file working copy can be restored from the original source.
1404 */
testWorkingCopy07()1405 public void testWorkingCopy07() throws CoreException {
1406 IOrdinaryClassFile clazz = this.jarRoot.getPackageFragment("workingcopy").getOrdinaryClassFile("X.class");
1407 WorkingCopyOwner owner = new WorkingCopyOwner() {};
1408 this.workingCopy = clazz.getWorkingCopy(owner, null/*no progress*/);
1409 this.workingCopy.getBuffer().setContents(
1410 "package workingcopy;\n" +
1411 "public class X {\n" +
1412 " void bar() {\n" +
1413 " }\n" +
1414 "}"
1415 );
1416 this.workingCopy.reconcile(ICompilationUnit.NO_AST, false/*don't force problems*/, null/*primary owner*/, null/*no progress*/);
1417 this.workingCopy.restore();
1418 assertElementDescendants(
1419 "Unexpected children",
1420 "[Working copy] X.class\n" +
1421 " package workingcopy\n" +
1422 " class X\n" +
1423 " void foo()",
1424 this.workingCopy);
1425 }
1426
1427 /*
1428 * Ensures that a class file working copy can be reconciled against.
1429 */
testWorkingCopy08()1430 public void testWorkingCopy08() throws CoreException {
1431 IOrdinaryClassFile clazz = this.jarRoot.getPackageFragment("workingcopy").getOrdinaryClassFile("X.class");
1432 ProblemRequestor problemRequestor = new ProblemRequestor();
1433 WorkingCopyOwner owner = newWorkingCopyOwner(problemRequestor);
1434 this.workingCopy = clazz.getWorkingCopy(owner, null/*no progress*/);
1435 this.workingCopy.getBuffer().setContents(
1436 "package workingcopy;\n" +
1437 "public class X {\n" +
1438 " public void bar() {\n" +
1439 " }\n" +
1440 "}"
1441 );
1442 this.workingCopy.makeConsistent(null);
1443
1444 ICompilationUnit cu = getCompilationUnit("/P/Y.java");
1445 ICompilationUnit copy = null;
1446 try {
1447 copy = cu.getWorkingCopy(owner, null/*no progress*/);
1448 copy.getBuffer().setContents(
1449 "public class Y {\n" +
1450 " void foo(workingcopy.X x) {\n" +
1451 " x.bar();\n" +
1452 " }\n" +
1453 "}"
1454 );
1455 problemRequestor.problems = new StringBuffer();
1456 problemRequestor.problemCount = 0;
1457 copy.reconcile(ICompilationUnit.NO_AST, false/*don't force problems*/, owner, null/*no progress*/);
1458 assertProblems(
1459 "Unexpected problems",
1460 "----------\n" +
1461 "----------\n",
1462 problemRequestor);
1463 } finally {
1464 if (copy != null)
1465 copy.discardWorkingCopy();
1466 }
1467 }
1468
1469 /*
1470 * Ensures that types in a class file are hidden when reconciling against if the class file working copy is empty.
1471 */
testWorkingCopy09()1472 public void testWorkingCopy09() throws CoreException {
1473 IOrdinaryClassFile clazz = this.jarRoot.getPackageFragment("workingcopy").getOrdinaryClassFile("X.class");
1474 ProblemRequestor problemRequestor = new ProblemRequestor();
1475 WorkingCopyOwner owner = newWorkingCopyOwner(problemRequestor);
1476 this.workingCopy = clazz.getWorkingCopy(owner, null/*no progress*/);
1477 this.workingCopy.getBuffer().setContents( "");
1478 this.workingCopy.makeConsistent(null);
1479
1480 ICompilationUnit cu = getCompilationUnit("/P/Y.java");
1481 ICompilationUnit copy = null;
1482 try {
1483 copy = cu.getWorkingCopy(owner, /*problemRequestor, */null/*no prpgress*/);
1484 copy.getBuffer().setContents(
1485 "public class Y {\n" +
1486 " workingcopy.X x;\n" +
1487 "}"
1488 );
1489 problemRequestor.problems = new StringBuffer();
1490 problemRequestor.problemCount = 0;
1491 copy.reconcile(ICompilationUnit.NO_AST, false/*don't force problems*/, owner, null/*no progress*/);
1492 assertProblems(
1493 "Unexpected problems",
1494 "----------\n" +
1495 "1. ERROR in /P/Y.java\n" +
1496 "workingcopy.X cannot be resolved to a type\n" +
1497 "----------\n",
1498 problemRequestor);
1499 } finally {
1500 if (copy != null)
1501 copy.discardWorkingCopy();
1502 }
1503 }
1504
1505 /*
1506 * Ensures that a 1.5 class file without source attached can be turned into a working copy and that its source is correct.
1507 */
testWorkingCopy10()1508 public void testWorkingCopy10() throws CoreException {
1509 IPath sourceAttachmentPath = this.jarRoot.getSourceAttachmentPath();
1510 try {
1511 attachSource(this.jarRoot, null, null);
1512 IOrdinaryClassFile clazz = this.jarRoot.getPackageFragment("workingcopy").getOrdinaryClassFile("Y.class");
1513 assertNull("Should not have source attached", clazz.getSource());
1514 this.workingCopy = clazz.getWorkingCopy(null/*primary owner*/, (IProgressMonitor) null/*no progress*/);
1515 assertSourceEquals(
1516 "Unexpected source",
1517 "package workingcopy;\n" +
1518 "public class Y<W> {\n" +
1519 " \n" +
1520 " public Y() {\n" +
1521 " }\n" +
1522 " \n" +
1523 " <T> T foo(T t, java.lang.String... args) {\n" +
1524 " return null;\n" +
1525 " }\n" +
1526 "}",
1527 this.workingCopy.getSource());
1528 } finally {
1529 attachSource(this.jarRoot, sourceAttachmentPath.toString(), null);
1530 }
1531 }
1532
1533 /*
1534 * Ensures that types in a class file are not found by a search if the class file working copy is empty.
1535 */
testWorkingCopy11()1536 public void testWorkingCopy11() throws CoreException {
1537 IPackageFragment pkg = this.jarRoot.getPackageFragment("workingcopy");
1538 IOrdinaryClassFile clazz = pkg.getOrdinaryClassFile("X.class");
1539 this.workingCopy = clazz.getWorkingCopy(null/*primary owner*/, (IProgressMonitor) null/*no progress*/);
1540 this.workingCopy.getBuffer().setContents( "");
1541 this.workingCopy.makeConsistent(null);
1542
1543 IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[] {pkg});
1544 AbstractJavaSearchTests.JavaSearchResultCollector requestor = new AbstractJavaSearchTests.JavaSearchResultCollector();
1545 search("*", IJavaSearchConstants.TYPE, IJavaSearchConstants.DECLARATIONS, scope, requestor);
1546 assertSearchResults(
1547 "lib.jar workingcopy.Y",
1548 requestor);
1549 }
1550 /*
1551 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=150244
1552 */
testGetBytes()1553 public void testGetBytes() throws CoreException {
1554 IPackageFragment pkg = this.jarRoot.getPackageFragment("workingcopy");
1555 IOrdinaryClassFile clazz = pkg.getOrdinaryClassFile("X.class");
1556 byte[] bytes = clazz.getBytes();
1557 assertNotNull("No bytes", bytes);
1558 int length = bytes.length;
1559 assertTrue("wrong size", length > 5);
1560 // sanity check: first four bytes are 0xCAFEBABE
1561 assertEquals("Wrong value", 0xCA, bytes[0] & 0xFF);
1562 assertEquals("Wrong value", 0xFE, bytes[1] & 0xFF);
1563 assertEquals("Wrong value", 0xBA, bytes[2] & 0xFF);
1564 assertEquals("Wrong value", 0xBE, bytes[3] & 0xFF);
1565 }
1566 /*
1567 * Ensures that the annotations of a binary field are correct
1568 */
testGenericFieldGetTypeSignature()1569 public void testGenericFieldGetTypeSignature() throws JavaModelException {
1570 IType type = this.jarRoot.getPackageFragment("generic").getOrdinaryClassFile("GenericField.class").getType();
1571 IField field = type.getField("myField");
1572 assertEquals(
1573 "Wrong type signature",
1574 "Ljava.util.Collection<Ljava.lang.String;>;",
1575 field.getTypeSignature());
1576 }
1577
testBug246594()1578 public void testBug246594() throws JavaModelException {
1579 IType type = this.jarRoot.getPackageFragment("generic").getOrdinaryClassFile(
1580 "Z.class").getType();
1581 ITypeParameter typeParam = type.getTypeParameter("T");
1582 assertNotNull(typeParam);
1583 assertStringsEqual("Type parameter bounds signatures",
1584 "Ljava.lang.Object;\n" +
1585 "Lgeneric.I<-TT;>;\n",
1586 typeParam.getBoundsSignatures());
1587 }
1588
testBug246594a()1589 public void testBug246594a() throws JavaModelException {
1590 IType type = this.jarRoot.getPackageFragment("generic").getOrdinaryClassFile(
1591 "X.class").getType();
1592 IMethod method = type.getMethod("foo", new String[] { "TK;", "TV;" });
1593 ITypeParameter typeParam = method.getTypeParameter("V");
1594 assertStringsEqual("Type parameter bounds signatures",
1595 "TT;\n", typeParam.getBoundsSignatures());
1596 }
1597 //https://bugs.eclipse.org/bugs/show_bug.cgi?id=316937
testBug316937()1598 public void testBug316937() throws Exception {
1599 try {
1600 IJavaProject project = getJavaProject("P");
1601 String[] pathAndContents = new String[] {
1602 "bug316937/Foo.java",
1603 "package bug316937;\n" + "public class Foo {\n"
1604 + " class Bar {\n"
1605 + " public Bar(int a, int b) {}\n" + " }\n"
1606 + "}\n" };
1607 addLibrary(project, "lib316937.jar", "src316937.zip",
1608 pathAndContents, JavaCore.VERSION_1_5);
1609 IPackageFragmentRoot packageFragRoot = project
1610 .getPackageFragmentRoot(getFile("/P/lib316937.jar"));
1611
1612 IType type = packageFragRoot.getPackageFragment("bug316937")
1613 .getOrdinaryClassFile("Foo.class").getType();
1614 IType subType = type.getType("Bar");
1615 IMethod[] methods = subType.getMethods();
1616 assertEquals("Constructros", 1, methods.length);
1617 IMethod method = methods[0];
1618 String[] paramNames = method.getParameterNames();
1619 assertStringsEqual("Type parameter names", "a\n" + "b\n",
1620 paramNames);
1621
1622 // Remove the source attachment
1623 IClasspathEntry[] rawClasspath = project.getRawClasspath();
1624 for (int index = 0; index < rawClasspath.length; index++) {
1625 IClasspathEntry entry = rawClasspath[index];
1626 if (entry.getPath().toString().endsWith("lib316937.jar")) {
1627 ((ClasspathEntry) entry).sourceAttachmentPath = null;
1628 }
1629 }
1630 project.setRawClasspath(rawClasspath, null);
1631
1632 packageFragRoot = project
1633 .getPackageFragmentRoot(getFile("/P/lib316937.jar"));
1634 type = packageFragRoot.getPackageFragment("bug316937")
1635 .getOrdinaryClassFile("Foo.class").getType();
1636 subType = type.getType("Bar");
1637 methods = subType.getMethods();
1638 assertEquals("Constructros", 1, methods.length);
1639 method = methods[0];
1640 paramNames = method.getParameterNames();
1641 assertStringsEqual("Type parameter names", "a\n" + "b\n",
1642 paramNames);
1643 } finally {
1644 removeLibrary(getJavaProject("P"), "lib316937.jar", "src316937.zip");
1645 }
1646 }
1647 /*
1648 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=372687
1649 * Ensures that if more than one thread try to open a class file at the same time, the children are correct.
1650 */
testBug372687()1651 public void testBug372687() throws CoreException {
1652 String expected = "X.class\n" +
1653 " class X\n" +
1654 " X()\n" +
1655 " void foo()";
1656 class GetClassThread extends Thread {
1657 public String childString;
1658 @Override
1659 public void run(){
1660 IOrdinaryClassFile clazz = ClassFileTests.this.jarRoot.getPackageFragment("workingcopy").getOrdinaryClassFile("X.class");
1661 try {
1662 this.childString = expandAll(clazz);
1663 } catch (CoreException e) {
1664 e.printStackTrace();
1665 }
1666 }
1667 }
1668 for (int i = 0; i < 10; i++) {
1669 GetClassThread th1 = new GetClassThread();
1670 GetClassThread th2 = new GetClassThread();
1671 GetClassThread th3 = new GetClassThread();
1672 th1.start();
1673 th2.start();
1674 th3.start();
1675 try {
1676 th1.join();
1677 th2.join();
1678 th3.join();
1679 } catch (InterruptedException e) {
1680 // ignore
1681 }
1682 assertEquals("Unexpected children", expected, th1.childString);
1683 assertEquals("Unexpected children", expected, th2.childString);
1684 assertEquals("Unexpected children", expected, th3.childString);
1685 IOrdinaryClassFile clazz = ClassFileTests.this.jarRoot.getPackageFragment("workingcopy").getOrdinaryClassFile("X.class");
1686 clazz.close();
1687 }
1688 }
1689
1690 }
1691