1 /* |
|
2 * Copyright (c) 2004, 2006, 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. Oracle designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Oracle in the LICENSE file that accompanied this code. |
|
10 * |
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 * version 2 for more details (a copy is included in the LICENSE file that |
|
15 * accompanied this code). |
|
16 * |
|
17 * You should have received a copy of the GNU General Public License version |
|
18 * 2 along with this work; if not, write to the Free Software Foundation, |
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 * |
|
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 * or visit www.oracle.com if you need additional information or have any |
|
23 * questions. |
|
24 */ |
|
25 |
|
26 package com.sun.tools.apt.comp; |
|
27 |
|
28 import com.sun.mirror.declaration.*; |
|
29 import static com.sun.mirror.declaration.Modifier.*; |
|
30 import com.sun.mirror.type.*; |
|
31 import com.sun.mirror.apt.*; |
|
32 |
|
33 import java.util.*; |
|
34 import com.sun.mirror.util.*; |
|
35 |
|
36 /** |
|
37 * Class used to implement "-print" option. |
|
38 */ |
|
39 @SuppressWarnings("deprecation") |
|
40 public class PrintAP implements AnnotationProcessor { |
|
41 |
|
42 |
|
43 static class PrintingVisitors { |
|
44 int indentation = 0; // Indentation level; |
|
45 AnnotationProcessorEnvironment env; |
|
46 Messager out; |
|
47 Declaration java_lang_Object; |
|
48 Declaration java_lang_annotation_Annotation; |
|
49 |
|
50 static Set<Modifier> EMPTY_ELIDES = Collections.emptySet(); |
|
51 static Set<Modifier> INTERFACE_ELIDES = EnumSet.of(ABSTRACT); |
|
52 static Set<Modifier> ENUM_ELIDES = EnumSet.of(FINAL, ABSTRACT); |
|
53 static Set<Modifier> INTERFACE_MEMBER_ELIDES = EnumSet.of(ABSTRACT, PUBLIC, STATIC, FINAL); |
|
54 |
|
55 PrintingVisitors(AnnotationProcessorEnvironment env) { |
|
56 this.env = env; |
|
57 this.out = env.getMessager(); |
|
58 this.java_lang_Object = env.getTypeDeclaration("java.lang.Object"); |
|
59 this.java_lang_annotation_Annotation = env.getTypeDeclaration("java.lang.annotation.Annotation"); |
|
60 } |
|
61 |
|
62 |
|
63 static String [] spaces = { |
|
64 "", |
|
65 " ", |
|
66 " ", |
|
67 " ", |
|
68 " ", |
|
69 " ", |
|
70 " ", |
|
71 " ", |
|
72 " ", |
|
73 " ", |
|
74 " " |
|
75 }; |
|
76 |
|
77 |
|
78 String indent(){ |
|
79 int indentation = this.indentation; |
|
80 if (indentation < 0) |
|
81 return ""; |
|
82 else if (indentation <= 10) |
|
83 return spaces[indentation]; |
|
84 else { |
|
85 StringBuilder sb = new StringBuilder(); |
|
86 while (indentation > 10) { |
|
87 sb.append(spaces[indentation]); |
|
88 indentation -= 10; |
|
89 } |
|
90 sb.append(spaces[indentation]); |
|
91 return sb.toString(); |
|
92 } |
|
93 } |
|
94 |
|
95 |
|
96 class PrePrinting extends SimpleDeclarationVisitor { |
|
97 Map<EnumDeclaration, Integer> enumCardinality = new HashMap<EnumDeclaration, Integer>(); |
|
98 Map<EnumDeclaration, Integer> enumConstVisited = new HashMap<EnumDeclaration, Integer>(); |
|
99 |
|
100 PrePrinting(){} |
|
101 |
|
102 public void visitClassDeclaration(ClassDeclaration d) { |
|
103 System.out.println(); |
|
104 printDocComment(d); |
|
105 printModifiers(d, EMPTY_ELIDES); |
|
106 System.out.print("class " + d.getSimpleName()); |
|
107 printFormalTypeParameters(d); |
|
108 |
|
109 // Elide "extends Object" |
|
110 ClassType Super = d.getSuperclass(); |
|
111 if (Super != null && !java_lang_Object.equals(Super.getDeclaration()) ) |
|
112 System.out.print(" extends " + Super.toString()); |
|
113 |
|
114 printInterfaces(d); |
|
115 |
|
116 System.out.println(" {"); |
|
117 |
|
118 PrintingVisitors.this.indentation++; |
|
119 } |
|
120 |
|
121 public void visitEnumDeclaration(EnumDeclaration d) { |
|
122 enumCardinality.put(d, d.getEnumConstants().size()); |
|
123 enumConstVisited.put(d, 1); |
|
124 |
|
125 System.out.println(); |
|
126 printDocComment(d); |
|
127 printModifiers(d, ENUM_ELIDES); |
|
128 |
|
129 System.out.print("enum " + d.getSimpleName()); |
|
130 printFormalTypeParameters(d); |
|
131 printInterfaces(d); |
|
132 |
|
133 System.out.println(" {"); |
|
134 |
|
135 PrintingVisitors.this.indentation++; |
|
136 } |
|
137 |
|
138 |
|
139 public void visitInterfaceDeclaration(InterfaceDeclaration d) { |
|
140 System.out.println(); |
|
141 printDocComment(d); |
|
142 printModifiers(d, INTERFACE_ELIDES); |
|
143 System.out.print("interface " + d.getSimpleName()); |
|
144 |
|
145 printFormalTypeParameters(d); |
|
146 printInterfaces(d); |
|
147 |
|
148 System.out.println(" {"); |
|
149 |
|
150 PrintingVisitors.this.indentation++; |
|
151 } |
|
152 |
|
153 public void visitAnnotationTypeDeclaration(AnnotationTypeDeclaration d) { |
|
154 System.out.println(); |
|
155 printDocComment(d); |
|
156 printModifiers(d, INTERFACE_ELIDES); |
|
157 System.out.print("@interface " + d.getSimpleName()); |
|
158 printFormalTypeParameters(d); |
|
159 |
|
160 printInterfaces(d); |
|
161 |
|
162 System.out.println(" {"); |
|
163 |
|
164 PrintingVisitors.this.indentation++; |
|
165 } |
|
166 |
|
167 public void visitFieldDeclaration(FieldDeclaration d) { |
|
168 System.out.println(); |
|
169 printDocComment(d); |
|
170 printModifiers(d, |
|
171 (d.getDeclaringType() instanceof InterfaceDeclaration)? |
|
172 INTERFACE_MEMBER_ELIDES : EMPTY_ELIDES); |
|
173 System.out.print(d.getType().toString() + " " + |
|
174 d.getSimpleName() ); |
|
175 String constantExpr = d.getConstantExpression(); |
|
176 if (constantExpr != null) { |
|
177 System.out.print(" = " + constantExpr); |
|
178 } |
|
179 System.out.println(";" ); |
|
180 } |
|
181 |
|
182 public void visitEnumConstantDeclaration(EnumConstantDeclaration d) { |
|
183 EnumDeclaration ed = d.getDeclaringType(); |
|
184 int enumCard = enumCardinality.get(ed); |
|
185 int enumVisit = enumConstVisited.get(ed); |
|
186 |
|
187 System.out.println(); |
|
188 printDocComment(d); |
|
189 System.out.print(PrintingVisitors.this.indent()); |
|
190 System.out.print(d.getSimpleName() ); |
|
191 System.out.println((enumVisit < enumCard )? ",":";" ); |
|
192 |
|
193 enumConstVisited.put(ed, enumVisit+1); |
|
194 } |
|
195 |
|
196 public void visitMethodDeclaration(MethodDeclaration d) { |
|
197 System.out.println(); |
|
198 printDocComment(d); |
|
199 printModifiers(d, |
|
200 (d.getDeclaringType() instanceof InterfaceDeclaration)? |
|
201 INTERFACE_MEMBER_ELIDES : EMPTY_ELIDES); |
|
202 printFormalTypeParameters(d); |
|
203 System.out.print(d.getReturnType().toString() + " "); |
|
204 System.out.print(d.getSimpleName() + "("); |
|
205 printParameters(d); |
|
206 System.out.print(")"); |
|
207 printThrows(d); |
|
208 System.out.println(";"); |
|
209 } |
|
210 |
|
211 public void visitConstructorDeclaration(ConstructorDeclaration d) { |
|
212 System.out.println(); |
|
213 printDocComment(d); |
|
214 printModifiers(d, EMPTY_ELIDES); |
|
215 printFormalTypeParameters(d); |
|
216 System.out.print(d.getSimpleName() + "("); |
|
217 printParameters(d); |
|
218 System.out.print(")"); |
|
219 printThrows(d); |
|
220 System.out.println(";"); |
|
221 } |
|
222 |
|
223 |
|
224 } |
|
225 |
|
226 class PostPrinting extends SimpleDeclarationVisitor { |
|
227 PostPrinting(){} |
|
228 |
|
229 public void visitTypeDeclaration(TypeDeclaration d) { |
|
230 PrintingVisitors.this.indentation--; |
|
231 |
|
232 System.out.print(PrintingVisitors.this.indent()); |
|
233 System.out.println("}"); |
|
234 } |
|
235 } |
|
236 |
|
237 private void printAnnotations(Collection<AnnotationMirror> annots) { |
|
238 |
|
239 for(AnnotationMirror annot: annots) { |
|
240 System.out.print(this.indent()); |
|
241 System.out.print(annot.toString()); |
|
242 System.out.println(); |
|
243 } |
|
244 } |
|
245 |
|
246 private void printAnnotationsInline(Collection<AnnotationMirror> annots) { |
|
247 |
|
248 for(AnnotationMirror annot: annots) { |
|
249 System.out.print(annot); |
|
250 System.out.print(" "); |
|
251 } |
|
252 } |
|
253 |
|
254 |
|
255 private void printParameters(ExecutableDeclaration ex) { |
|
256 |
|
257 Collection<ParameterDeclaration> parameters = ex.getParameters(); |
|
258 int size = parameters.size(); |
|
259 |
|
260 switch (size) { |
|
261 case 0: |
|
262 break; |
|
263 |
|
264 case 1: |
|
265 for(ParameterDeclaration parameter: parameters) { |
|
266 printModifiers(parameter, EMPTY_ELIDES); |
|
267 |
|
268 if (ex.isVarArgs() ) { |
|
269 System.out.print(((ArrayType)parameter.getType()).getComponentType() ); |
|
270 System.out.print("..."); |
|
271 } else |
|
272 System.out.print(parameter.getType()); |
|
273 System.out.print(" " + parameter.getSimpleName()); |
|
274 } |
|
275 break; |
|
276 |
|
277 default: |
|
278 { |
|
279 int i = 1; |
|
280 for(ParameterDeclaration parameter: parameters) { |
|
281 if (i == 2) |
|
282 PrintingVisitors.this.indentation++; |
|
283 |
|
284 if (i > 1) |
|
285 System.out.print(PrintingVisitors.this.indent()); |
|
286 |
|
287 printModifiers(parameter, EMPTY_ELIDES); |
|
288 |
|
289 if (i == size && ex.isVarArgs() ) { |
|
290 System.out.print(((ArrayType)parameter.getType()).getComponentType() ); |
|
291 System.out.print("..."); |
|
292 } else |
|
293 System.out.print(parameter.getType()); |
|
294 System.out.print(" " + parameter.getSimpleName()); |
|
295 |
|
296 if (i < size) |
|
297 System.out.println(","); |
|
298 |
|
299 i++; |
|
300 } |
|
301 |
|
302 if (parameters.size() >= 2) |
|
303 PrintingVisitors.this.indentation--; |
|
304 } |
|
305 break; |
|
306 } |
|
307 } |
|
308 |
|
309 private void printDocComment(Declaration d) { |
|
310 String docComment = d.getDocComment(); |
|
311 |
|
312 if (docComment != null) { |
|
313 // Break comment into lines |
|
314 java.util.StringTokenizer st = new StringTokenizer(docComment, |
|
315 "\n\r"); |
|
316 System.out.print(PrintingVisitors.this.indent()); |
|
317 System.out.println("/**"); |
|
318 |
|
319 while(st.hasMoreTokens()) { |
|
320 System.out.print(PrintingVisitors.this.indent()); |
|
321 System.out.print(" *"); |
|
322 System.out.println(st.nextToken()); |
|
323 } |
|
324 |
|
325 System.out.print(PrintingVisitors.this.indent()); |
|
326 System.out.println(" */"); |
|
327 } |
|
328 } |
|
329 |
|
330 private void printModifiers(Declaration d, Collection<Modifier> elides) { |
|
331 printAnnotations(d.getAnnotationMirrors()); |
|
332 |
|
333 System.out.print(PrintingVisitors.this.indent()); |
|
334 |
|
335 for(Modifier m: adjustModifiers(d.getModifiers(), elides) ){ |
|
336 System.out.print(m.toString() + " "); |
|
337 } |
|
338 } |
|
339 |
|
340 private void printModifiers(ParameterDeclaration d, Collection<Modifier> elides) { |
|
341 printAnnotationsInline(d.getAnnotationMirrors()); |
|
342 |
|
343 for(Modifier m: adjustModifiers(d.getModifiers(), elides) ) { |
|
344 System.out.print(m.toString() + " "); |
|
345 } |
|
346 } |
|
347 |
|
348 private Collection<Modifier> adjustModifiers(Collection<Modifier> mods, |
|
349 Collection<Modifier> elides) { |
|
350 if (elides.isEmpty()) |
|
351 return mods; |
|
352 else { |
|
353 Collection<Modifier> newMods = new LinkedHashSet<Modifier>(); |
|
354 newMods.addAll(mods); |
|
355 newMods.removeAll(elides); |
|
356 return newMods; |
|
357 } |
|
358 } |
|
359 |
|
360 private void printFormalTypeParameters(ExecutableDeclaration e) { |
|
361 printFormalTypeParameterSet(e.getFormalTypeParameters(), true); |
|
362 } |
|
363 |
|
364 private void printFormalTypeParameters(TypeDeclaration d) { |
|
365 printFormalTypeParameterSet(d.getFormalTypeParameters(), false); |
|
366 } |
|
367 |
|
368 private void printFormalTypeParameterSet(Collection<TypeParameterDeclaration> typeParams, boolean pad) { |
|
369 if (typeParams.size() != 0) { |
|
370 System.out.print("<"); |
|
371 |
|
372 boolean first = true; |
|
373 for(TypeParameterDeclaration tpd: typeParams) { |
|
374 if (!first) |
|
375 System.out.print(", "); |
|
376 System.out.print(tpd.toString()); |
|
377 } |
|
378 |
|
379 System.out.print(">"); |
|
380 if (pad) |
|
381 System.out.print(" "); |
|
382 |
|
383 } |
|
384 } |
|
385 |
|
386 private void printInterfaceSet(Collection<InterfaceType> interfaces, |
|
387 boolean classNotInterface) { |
|
388 if (interfaces.size() != 0) { |
|
389 System.out.print((classNotInterface?" implements" : " extends")); |
|
390 |
|
391 boolean first = true; |
|
392 for(InterfaceType interType: interfaces) { |
|
393 if (!first) |
|
394 System.out.print(","); |
|
395 System.out.print(" "); |
|
396 System.out.print(interType.toString()); |
|
397 first = false; |
|
398 } |
|
399 } |
|
400 } |
|
401 |
|
402 private void printInterfaces(TypeDeclaration d) { |
|
403 printInterfaceSet(d.getSuperinterfaces(), d instanceof ClassDeclaration); |
|
404 } |
|
405 |
|
406 private void printInterfaces(AnnotationTypeDeclaration d) { |
|
407 Collection<InterfaceType> interfaces = new HashSet<InterfaceType>(d.getSuperinterfaces()); |
|
408 |
|
409 for(InterfaceType interType: interfaces) { |
|
410 if (java_lang_annotation_Annotation.equals(interType.getDeclaration()) ) |
|
411 interfaces.remove(interType); |
|
412 } |
|
413 |
|
414 printInterfaceSet(interfaces, d instanceof ClassDeclaration); |
|
415 } |
|
416 |
|
417 private void printThrows(ExecutableDeclaration d) { |
|
418 Collection<ReferenceType> thrownTypes = d.getThrownTypes(); |
|
419 final int size = thrownTypes.size(); |
|
420 if (size != 0) { |
|
421 System.out.print(" throws"); |
|
422 |
|
423 int i = 1; |
|
424 for(ReferenceType thrownType: thrownTypes) { |
|
425 if (i == 1) { |
|
426 System.out.print(" "); |
|
427 } |
|
428 |
|
429 if (i == 2) |
|
430 PrintingVisitors.this.indentation++; |
|
431 |
|
432 if (i >= 2) |
|
433 System.out.print(PrintingVisitors.this.indent()); |
|
434 |
|
435 System.out.print(thrownType.toString()); |
|
436 |
|
437 |
|
438 if (i != size) { |
|
439 System.out.println(", "); |
|
440 } |
|
441 i++; |
|
442 } |
|
443 |
|
444 if (size >= 2) |
|
445 PrintingVisitors.this.indentation--; |
|
446 } |
|
447 } |
|
448 |
|
449 DeclarationVisitor getPrintingVisitor() { |
|
450 return DeclarationVisitors.getSourceOrderDeclarationScanner(new PrePrinting(), |
|
451 new PostPrinting()); |
|
452 } |
|
453 } |
|
454 |
|
455 AnnotationProcessorEnvironment env; |
|
456 PrintAP(AnnotationProcessorEnvironment env) { |
|
457 this.env = env; |
|
458 } |
|
459 |
|
460 |
|
461 public void process() { |
|
462 Collection<TypeDeclaration> typedecls = env.getSpecifiedTypeDeclarations(); |
|
463 |
|
464 for (TypeDeclaration td: typedecls) |
|
465 td.accept((new PrintingVisitors(env)).getPrintingVisitor()); |
|
466 } |
|
467 } |
|