1 /*
2  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /*
25  * @test
26  * @bug 6406164
27  * @summary Test that ElementFilter iterable methods behave properly.
28  * @author  Joseph D. Darcy
29  * @library /tools/javac/lib
30  * @build JavacTestingAbstractProcessor
31  * @compile TestIterables.java
32  * @compile -processor TestIterables -proc:only Foo1.java
33  * @compile Foo1.java
34  * @compile -processor TestIterables Foo1 TestIterables.java
35  */
36 
37 import java.util.Set;
38 import java.util.HashSet;
39 import java.util.Arrays;
40 import java.util.Iterator;
41 import javax.annotation.processing.*;
42 import javax.lang.model.SourceVersion;
43 import static javax.lang.model.SourceVersion.*;
44 import javax.lang.model.element.*;
45 import javax.lang.model.util.*;
46 import static javax.tools.Diagnostic.Kind.*;
47 
48 import static javax.lang.model.util.ElementFilter.*;
49 
50 /**
51  * Verify that the {@code ElementFilter} methods taking iterables
52  * behave correctly by comparing ExpectedElementCounts with actual
53  * results.
54  */
55 @SupportedAnnotationTypes("ExpectedElementCounts")
56 @ExpectedElementCounts(methods=2)
57 public class TestIterables extends JavacTestingAbstractProcessor {
process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv)58     public boolean process(Set<? extends TypeElement> annotations,
59                            RoundEnvironment roundEnv) {
60         if (!roundEnv.processingOver()) {
61             boolean error = false;
62             int topLevelCount = 0;
63 
64             for (TypeElement type : typesIn(roundEnv.getRootElements())) {
65                 topLevelCount++;
66                 ExpectedElementCounts elementCounts = type.getAnnotation(ExpectedElementCounts.class);
67                 if (elementCounts == null)
68                     throw new RuntimeException("Missing ExpectedElementCounts annotation!");
69 
70                 Iterable<? extends Element> irritable = type.getEnclosedElements();
71 
72                 int constructorCount = getCount(constructorsIn(irritable));
73                 int fieldCount       = getCount(fieldsIn(irritable));
74                 int methodCount      = getCount(methodsIn(irritable));
75                 int typeCount        = getCount(typesIn(irritable));
76 
77                 System.out.println("\nType: " + type.getQualifiedName());
78                 System.out.format("Element      Actual\tExpected%n");
79                 System.out.format("constructors %d\t\t%d%n", constructorCount, elementCounts.constructors());
80                 System.out.format("fields       %d\t\t%d%n", fieldCount,       elementCounts.fields());
81                 System.out.format("methods      %d\t\t%d%n", methodCount,      elementCounts.methods());
82                 System.out.format("types        %d\t\t%d%n", typeCount,        elementCounts.types());
83 
84                 if ((constructorCount != elementCounts.constructors()) ||
85                     (fieldCount       != elementCounts.fields()) ||
86                     (methodCount      != elementCounts.methods()) ||
87                     (typeCount        != elementCounts.types()) )
88                     error = true;
89             }
90 
91             if (topLevelCount == 0)
92                 error = true;
93 
94             if (error)
95                 throw new RuntimeException("A count mismatch has occured.");
96         }
97 
98         return true;
99     }
100 
getCount(Iterable<? extends Element> iter)101     private int getCount(Iterable<? extends Element> iter) {
102         int count1 = 0;
103         int count2 = 0;
104 
105         Iterator<? extends Element> iterator = iter.iterator();
106         while (iterator.hasNext() ) {
107             count1++;
108             iterator.next();
109         }
110 
111         iterator = iter.iterator();
112         while (iterator.hasNext() ) {
113             count2++;
114             iterator.next();
115         }
116 
117         if (count1 != count2)
118             throw new RuntimeException("Inconsistent counts from iterator.");
119 
120         return count1;
121     }
122 }
123