TestMissingElement.java revision 1520:71f35e4b93a5
1/*
2 * Copyright (c) 2011, 2013, 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/*
26 * @test
27 * @bug 6639645 7026414 7025809
28 * @summary Modeling type implementing missing interfaces
29 * @library /tools/javac/lib
30 * @build JavacTestingAbstractProcessor TestMissingElement
31 * @compile/fail/ref=TestMissingElement.ref -proc:only -XprintRounds -XDrawDiagnostics -processor TestMissingElement InvalidSource.java
32 */
33
34import java.util.*;
35import javax.annotation.processing.*;
36import javax.lang.model.element.*;
37import javax.lang.model.type.*;
38import javax.lang.model.util.*;
39import static javax.tools.Diagnostic.Kind.*;
40
41public class TestMissingElement extends JavacTestingAbstractProcessor {
42    @Override
43    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
44        for (TypeElement te: ElementFilter.typesIn(roundEnv.getRootElements())) {
45            if (isSimpleName(te, "InvalidSource")) {
46                for (Element c: te.getEnclosedElements()) {
47                    for (AnnotationMirror am: c.getAnnotationMirrors()) {
48                        Element ate = am.getAnnotationType().asElement();
49                        if (isSimpleName(ate, "ExpectInterfaces")) {
50                            checkInterfaces((TypeElement) c, getValue(am));
51                        } else if (isSimpleName(ate, "ExpectSupertype")) {
52                            checkSupertype((TypeElement) c, getValue(am));
53                        }
54                    }
55                }
56            }
57        }
58        return true;
59    }
60
61    private boolean isSimpleName(Element e, String name) {
62        return e.getSimpleName().contentEquals(name);
63    }
64
65    private String getValue(AnnotationMirror am) {
66        Map<? extends ExecutableElement, ? extends AnnotationValue> map = am.getElementValues();
67        if (map.size() != 1) throw new IllegalArgumentException();
68        AnnotationValue v = map.values().iterator().next();
69        return (String) v.getValue();
70    }
71
72    private void checkInterfaces(TypeElement te, String expect) {
73        System.err.println("check interfaces: " + te + " -- " + expect);
74        String found = asString(te.getInterfaces(), ", ");
75        checkEqual("interfaces", te, found, expect);
76    }
77
78    private void checkSupertype(TypeElement te, String expect) {
79        System.err.println("check supertype: " + te + " -- " + expect);
80        String found = asString(te.getSuperclass());
81        checkEqual("supertype", te, found, expect);
82    }
83
84    private void checkEqual(String label, TypeElement te, String found, String expect) {
85        if (found.equals(expect)) {
86//            messager.printMessage(NOTE, "expected " + label + " found: " + expect, te);
87        } else {
88            System.err.println("unexpected " + label + ": " + te + "\n"
89                    + " found: " + found + "\n"
90                    + "expect: " + expect);
91            messager.printMessage(ERROR, "unexpected " + label + " found: " + found + "; expected: " + expect, te);
92        }
93    }
94
95    private String asString(List<? extends TypeMirror> ts, String sep) {
96        StringBuilder sb = new StringBuilder();
97        for (TypeMirror t: ts) {
98            if (sb.length() != 0) sb.append(sep);
99            sb.append(asString(t));
100        }
101        return sb.toString();
102    }
103
104    private String asString(TypeMirror t) {
105        if (t == null)
106            return "[typ:null]";
107        return t.accept(new SimpleTypeVisitor<String, Void>() {
108            @Override
109            public String defaultAction(TypeMirror t, Void ignore) {
110                return "[typ:" + t.toString() + "]";
111            }
112
113            @Override
114            public String visitDeclared(DeclaredType t, Void ignore) {
115                checkEqual(t.asElement(), types.asElement(t));
116                String s = asString(t.asElement());
117                List<? extends TypeMirror> args = t.getTypeArguments();
118                if (!args.isEmpty())
119                    s += "<" + asString(args, ",") + ">";
120                return s;
121            }
122
123            @Override
124            public String visitTypeVariable(TypeVariable t, Void ignore) {
125                return "tvar " + t;
126            }
127
128            @Override
129            public String visitError(ErrorType t, Void ignore) {
130                return "!:" + visitDeclared(t, ignore);
131            }
132        }, null);
133    }
134
135    private String asString(Element e) {
136        if (e == null)
137            return "[elt:null]";
138        return e.accept(new SimpleElementVisitor<String, Void>() {
139            @Override
140            public String defaultAction(Element e, Void ignore) {
141                return "[elt:" + e.getKind() + " " + e.toString() + "]";
142            }
143            @Override
144            public String visitPackage(PackageElement e, Void ignore) {
145                return "pkg " + e.getQualifiedName();
146            }
147            @Override
148            public String visitType(TypeElement e, Void ignore) {
149                StringBuilder sb = new StringBuilder();
150                if (e.getEnclosedElements().isEmpty())
151                    sb.append("empty ");
152                ElementKind ek = e.getKind();
153                switch (ek) {
154                    case CLASS:
155                        sb.append("clss");
156                        break;
157                    case INTERFACE:
158                        sb.append("intf");
159                        break;
160                    default:
161                        sb.append(ek);
162                        break;
163                }
164                sb.append(" ");
165                Element encl = e.getEnclosingElement();
166                if (!isUnnamedPackage(encl) && encl.asType().getKind() != TypeKind.NONE) {
167                    sb.append("(");
168                    sb.append(asString(encl));
169                    sb.append(")");
170                    sb.append(".");
171                }
172                sb.append(e.getSimpleName());
173                if (e.asType().getKind() == TypeKind.ERROR) sb.append("!");
174                return sb.toString();
175            }
176        }, null);
177    }
178
179    boolean isUnnamedPackage(Element e) {
180        return (e != null && e.getKind() == ElementKind.PACKAGE
181                && ((PackageElement) e).isUnnamed());
182    }
183
184    void checkEqual(Element e1, Element e2) {
185        if (e1 != e2) {
186            throw new AssertionError("elements not equal as expected: "
187                + e1 + ", " + e2);
188        }
189    }
190}
191
192
193
194