1/*
2 * Copyright (c) 2011, 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
24import java.io.*;
25import java.util.*;
26import javax.annotation.processing.*;
27import javax.lang.model.element.*;
28import javax.lang.model.type.*;
29import javax.lang.model.util.*;
30import javax.tools.*;
31
32public class Generator extends JavacTestingAbstractProcessor {
33
34    @Override
35    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
36        for (TypeElement te: ElementFilter.typesIn(roundEnv.getRootElements())) {
37            System.err.println(te);
38            generateIfMissing(te.getSuperclass());
39            generateIfMissing(te.getInterfaces());
40        }
41        return true;
42    }
43
44    void generateIfMissing(List<? extends TypeMirror> ts) {
45        for (TypeMirror t: ts)
46            generateIfMissing(t);
47    }
48
49    void generateIfMissing(TypeMirror t) {
50        if (t == null)
51            return;
52        if (t.getKind() == TypeKind.ERROR) {
53            Element e = ((ErrorType) t).asElement();
54            if (e == null)
55                return;
56            if (e.asType().getKind() == TypeKind.ERROR)
57                createFile((TypeElement) e);
58        }
59    }
60
61    void createFile(TypeElement e) {
62        try {
63            JavaFileObject fo = filer.createSourceFile(e.getSimpleName());
64            Writer out = fo.openWriter();
65            try {
66                switch (e.getKind()) {
67                    case CLASS:
68                        out.write("import java.util.*;\n");
69                        out.write("class " + signature(e) + " {\n");
70                        out.write("    public void run() {\n");
71                        out.write("        Class<?> c = getClass();\n");
72                        out.write("        System.out.println(\"class: \" + c);\n");
73                        out.write("        System.out.println(\"superclass: \" + c.getSuperclass());\n");
74                        out.write("        System.out.println(\"generic superclass: \" +c.getGenericSuperclass());\n");
75                        out.write("        System.out.println(\"interfaces: \" + Arrays.asList(c.getInterfaces()));\n");
76                        out.write("        System.out.println(\"generic interfaces: \" + Arrays.asList(c.getGenericInterfaces()));\n");
77                        out.write("    }\n");
78                        out.write("}\n");
79                        break;
80                    case INTERFACE:
81                        out.write("interface " + signature(e) + " {\n");
82                        out.write("    void run();\n");
83                        out.write("}\n");
84                        break;
85                }
86            } finally {
87                out.close();
88            }
89        } catch (IOException ex) {
90            messager.printMessage(Diagnostic.Kind.ERROR, "problem writing file: " + ex);
91        }
92    }
93
94    String signature(TypeElement e) {
95        System.err.println("signature: " + e + " " + e.getTypeParameters());
96        StringBuilder sb = new StringBuilder();
97        sb.append(e.getSimpleName());
98        if (!e.getTypeParameters().isEmpty()) {
99            sb.append("<");
100            String sep = "";
101            for (TypeParameterElement t : e.getTypeParameters()) {
102                sb.append(sep);
103                sb.append(t);
104                sep = ",";
105            }
106            sb.append(">");
107        }
108        return sb.toString();
109    }
110}
111
112