TestMissingElement.java revision 3294:9adfb22ff08f
133965Sjdp/*
233965Sjdp * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
3218822Sdim * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4130561Sobrien *
533965Sjdp * This code is free software; you can redistribute it and/or modify it
633965Sjdp * under the terms of the GNU General Public License version 2 only, as
733965Sjdp * published by the Free Software Foundation.
833965Sjdp *
933965Sjdp * This code is distributed in the hope that it will be useful, but WITHOUT
1033965Sjdp * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1133965Sjdp * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1233965Sjdp * version 2 for more details (a copy is included in the LICENSE file that
1333965Sjdp * accompanied this code).
1433965Sjdp *
1533965Sjdp * You should have received a copy of the GNU General Public License version
1633965Sjdp * 2 along with this work; if not, write to the Free Software Foundation,
1733965Sjdp * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1838889Sjdp *
1938889Sjdp * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20218822Sdim * or visit www.oracle.com if you need additional information or have any
2133965Sjdp * questions.
2233965Sjdp */
2333965Sjdp
2433965Sjdp/*
25218822Sdim * @test
26218822Sdim * @bug 6639645 7026414 7025809
2760484Sobrien * @summary Modeling type implementing missing interfaces
2860484Sobrien * @library /tools/javac/lib
2960484Sobrien * @modules jdk.compiler/com.sun.tools.javac.processing
3060484Sobrien *          jdk.compiler/com.sun.tools.javac.util
3160484Sobrien * @build JavacTestingAbstractProcessor TestMissingElement
32130561Sobrien * @compile/fail/ref=TestMissingElement.ref -XDaccessInternalAPI -proc:only -XprintRounds -XDrawDiagnostics -processor TestMissingElement InvalidSource.java
3360484Sobrien */
3460484Sobrien
3560484Sobrienimport java.io.PrintWriter;
3660484Sobrienimport java.util.*;
3760484Sobrienimport javax.annotation.processing.*;
3860484Sobrienimport javax.lang.model.element.*;
3960484Sobrienimport javax.lang.model.type.*;
4060484Sobrienimport javax.lang.model.util.*;
4133965Sjdpimport static javax.tools.Diagnostic.Kind.*;
4260484Sobrien
4360484Sobrienimport com.sun.tools.javac.processing.JavacProcessingEnvironment;
4433965Sjdpimport com.sun.tools.javac.util.Log;
4533965Sjdp
4633965Sjdppublic class TestMissingElement extends JavacTestingAbstractProcessor {
4738889Sjdp    private PrintWriter out;
4833965Sjdp
4933965Sjdp    @Override
5033965Sjdp    public void init(ProcessingEnvironment env) {
5133965Sjdp        super.init(env);
5233965Sjdp        out = ((JavacProcessingEnvironment) env).getContext().get(Log.outKey);
5333965Sjdp    }
5433965Sjdp
5533965Sjdp    @Override
5633965Sjdp    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
5760484Sobrien        for (TypeElement te: ElementFilter.typesIn(roundEnv.getRootElements())) {
5860484Sobrien            if (isSimpleName(te, "InvalidSource")) {
5960484Sobrien                for (Element c: te.getEnclosedElements()) {
6033965Sjdp                    for (AnnotationMirror am: c.getAnnotationMirrors()) {
6133965Sjdp                        Element ate = am.getAnnotationType().asElement();
6233965Sjdp                        if (isSimpleName(ate, "ExpectInterfaces")) {
6333965Sjdp                            checkInterfaces((TypeElement) c, getValue(am));
6460484Sobrien                        } else if (isSimpleName(ate, "ExpectSupertype")) {
6560484Sobrien                            checkSupertype((TypeElement) c, getValue(am));
6633965Sjdp                        }
6760484Sobrien                    }
6860484Sobrien                }
6960484Sobrien            }
7060484Sobrien        }
7133965Sjdp        return true;
7260484Sobrien    }
7360484Sobrien
7433965Sjdp    private boolean isSimpleName(Element e, String name) {
7533965Sjdp        return e.getSimpleName().contentEquals(name);
7633965Sjdp    }
7760484Sobrien
7833965Sjdp    private String getValue(AnnotationMirror am) {
7933965Sjdp        Map<? extends ExecutableElement, ? extends AnnotationValue> map = am.getElementValues();
8033965Sjdp        if (map.size() != 1) throw new IllegalArgumentException();
8133965Sjdp        AnnotationValue v = map.values().iterator().next();
8238889Sjdp        return (String) v.getValue();
8338889Sjdp    }
8433965Sjdp
8533965Sjdp    private void checkInterfaces(TypeElement te, String expect) {
8633965Sjdp        out.println("check interfaces: " + te + " -- " + expect);
8733965Sjdp        String found = asString(te.getInterfaces(), ", ");
8860484Sobrien        checkEqual("interfaces", te, found, expect);
8960484Sobrien    }
9060484Sobrien
9160484Sobrien    private void checkSupertype(TypeElement te, String expect) {
9260484Sobrien        out.println("check supertype: " + te + " -- " + expect);
9360484Sobrien        String found = asString(te.getSuperclass());
9460484Sobrien        checkEqual("supertype", te, found, expect);
9560484Sobrien    }
9633965Sjdp
9733965Sjdp    private void checkEqual(String label, TypeElement te, String found, String expect) {
9860484Sobrien        if (found.equals(expect)) {
9960484Sobrien//            messager.printMessage(NOTE, "expected " + label + " found: " + expect, te);
10060484Sobrien        } else {
10160484Sobrien            out.println("unexpected " + label + ": " + te + "\n"
10260484Sobrien                    + " found: " + found + "\n"
10360484Sobrien                    + "expect: " + expect);
10460484Sobrien            messager.printMessage(ERROR, "unexpected " + label + " found: " + found + "; expected: " + expect, te);
10560484Sobrien        }
10660484Sobrien    }
10760484Sobrien
10860484Sobrien    private String asString(List<? extends TypeMirror> ts, String sep) {
10933965Sjdp        StringBuilder sb = new StringBuilder();
11060484Sobrien        for (TypeMirror t: ts) {
11160484Sobrien            if (sb.length() != 0) sb.append(sep);
112218822Sdim            sb.append(asString(t));
113218822Sdim        }
114218822Sdim        return sb.toString();
115218822Sdim    }
116218822Sdim
117218822Sdim    private String asString(TypeMirror t) {
118218822Sdim        if (t == null)
11960484Sobrien            return "[typ:null]";
12033965Sjdp        return t.accept(new SimpleTypeVisitor<String, Void>() {
12160484Sobrien            @Override
12238889Sjdp            public String defaultAction(TypeMirror t, Void ignore) {
12338889Sjdp                return "[typ:" + t.toString() + "]";
12460484Sobrien            }
12533965Sjdp
12660484Sobrien            @Override
12760484Sobrien            public String visitDeclared(DeclaredType t, Void ignore) {
12833965Sjdp                checkEqual(t.asElement(), types.asElement(t));
12933965Sjdp                String s = asString(t.asElement());
13033965Sjdp                List<? extends TypeMirror> args = t.getTypeArguments();
13160484Sobrien                if (!args.isEmpty())
13260484Sobrien                    s += "<" + asString(args, ",") + ">";
13360484Sobrien                return s;
13460484Sobrien            }
13533965Sjdp
13660484Sobrien            @Override
13760484Sobrien            public String visitTypeVariable(TypeVariable t, Void ignore) {
13833965Sjdp                return "tvar " + t;
13960484Sobrien            }
14060484Sobrien
14160484Sobrien            @Override
14260484Sobrien            public String visitError(ErrorType t, Void ignore) {
14360484Sobrien                return "!:" + visitDeclared(t, ignore);
14460484Sobrien            }
14560484Sobrien        }, null);
14660484Sobrien    }
14760484Sobrien
14860484Sobrien    private String asString(Element e) {
14933965Sjdp        if (e == null)
15033965Sjdp            return "[elt:null]";
15138889Sjdp        return e.accept(new SimpleElementVisitor<String, Void>() {
15238889Sjdp            @Override
15360484Sobrien            public String defaultAction(Element e, Void ignore) {
15460484Sobrien                return "[elt:" + e.getKind() + " " + e.toString() + "]";
15533965Sjdp            }
15660484Sobrien            @Override
15760484Sobrien            public String visitPackage(PackageElement e, Void ignore) {
15860484Sobrien                return "pkg " + e.getQualifiedName();
15960484Sobrien            }
16060484Sobrien            @Override
16133965Sjdp            public String visitType(TypeElement e, Void ignore) {
16260484Sobrien                StringBuilder sb = new StringBuilder();
16360484Sobrien                if (e.getEnclosedElements().isEmpty())
164218822Sdim                    sb.append("empty ");
165218822Sdim                ElementKind ek = e.getKind();
166218822Sdim                switch (ek) {
16738889Sjdp                    case CLASS:
16838889Sjdp                        sb.append("clss");
16960484Sobrien                        break;
17038889Sjdp                    case INTERFACE:
17138889Sjdp                        sb.append("intf");
17238889Sjdp                        break;
17338889Sjdp                    default:
174218822Sdim                        sb.append(ek);
17538889Sjdp                        break;
17638889Sjdp                }
17760484Sobrien                sb.append(" ");
17838889Sjdp                Element encl = e.getEnclosingElement();
17938889Sjdp                if (!isUnnamedPackage(encl) && encl.asType().getKind() != TypeKind.NONE) {
18038889Sjdp                    sb.append("(");
18160484Sobrien                    sb.append(asString(encl));
18260484Sobrien                    sb.append(")");
18338889Sjdp                    sb.append(".");
18438889Sjdp                }
18533965Sjdp                sb.append(e.getSimpleName());
18660484Sobrien                if (e.asType().getKind() == TypeKind.ERROR) sb.append("!");
18760484Sobrien                return sb.toString();
18860484Sobrien            }
18960484Sobrien        }, null);
19060484Sobrien    }
19160484Sobrien
19260484Sobrien    boolean isUnnamedPackage(Element e) {
19360484Sobrien        return (e != null && e.getKind() == ElementKind.PACKAGE
19460484Sobrien                && ((PackageElement) e).isUnnamed());
19560484Sobrien    }
19660484Sobrien
19760484Sobrien    void checkEqual(Element e1, Element e2) {
19860484Sobrien        if (e1 != e2) {
19960484Sobrien            throw new AssertionError("elements not equal as expected: "
20060484Sobrien                + e1 + ", " + e2);
20160484Sobrien        }
20260484Sobrien    }
20360484Sobrien}
20460484Sobrien
20560484Sobrien
20660484Sobrien
20760484Sobrien