mcimadamore@1114: /* ksrini@2227: * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. mcimadamore@1114: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. mcimadamore@1114: * mcimadamore@1114: * This code is free software; you can redistribute it and/or modify it mcimadamore@1114: * under the terms of the GNU General Public License version 2 only, as mcimadamore@1114: * published by the Free Software Foundation. mcimadamore@1114: * mcimadamore@1114: * This code is distributed in the hope that it will be useful, but WITHOUT mcimadamore@1114: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or mcimadamore@1114: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License mcimadamore@1114: * version 2 for more details (a copy is included in the LICENSE file that mcimadamore@1114: * accompanied this code). mcimadamore@1114: * mcimadamore@1114: * You should have received a copy of the GNU General Public License version mcimadamore@1114: * 2 along with this work; if not, write to the Free Software Foundation, mcimadamore@1114: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. mcimadamore@1114: * mcimadamore@1114: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA mcimadamore@1114: * or visit www.oracle.com if you need additional information or have any mcimadamore@1114: * questions. mcimadamore@1114: */ mcimadamore@1114: mcimadamore@1114: /* mcimadamore@1114: * @test mcimadamore@1114: * @bug 7098660 mcimadamore@1114: * @summary Write better overload resolution/inference tests darcy@1466: * @library /tools/javac/lib mcimadamore@1114: * @build JavacTestingAbstractProcessor ResolveHarness mcimadamore@1114: * @run main ResolveHarness mcimadamore@1114: */ mcimadamore@1114: mcimadamore@1114: import com.sun.source.util.JavacTask; mcimadamore@1114: import com.sun.tools.javac.api.ClientCodeWrapper.DiagnosticSourceUnwrapper; mcimadamore@1875: import com.sun.tools.javac.code.Flags; mcimadamore@1875: import com.sun.tools.javac.code.Symbol; mcimadamore@1114: import com.sun.tools.javac.code.Type.MethodType; mcimadamore@1114: import com.sun.tools.javac.util.JCDiagnostic; mcimadamore@1114: mcimadamore@1114: import java.io.File; mcimadamore@1114: import java.util.Set; mcimadamore@1114: import java.util.Arrays; mcimadamore@1114: import java.util.ArrayList; mcimadamore@1114: import java.util.Collections; mcimadamore@1114: import java.util.HashMap; mcimadamore@1114: import java.util.HashSet; mcimadamore@1114: import java.util.List; mcimadamore@1779: import java.util.Locale; mcimadamore@1114: import java.util.Map; mcimadamore@1114: mcimadamore@1114: import javax.annotation.processing.AbstractProcessor; mcimadamore@1114: import javax.annotation.processing.RoundEnvironment; mcimadamore@1114: import javax.annotation.processing.SupportedAnnotationTypes; mcimadamore@1114: import javax.lang.model.element.Element; mcimadamore@1114: import javax.lang.model.element.TypeElement; mcimadamore@1114: import javax.tools.Diagnostic; mcimadamore@1114: import javax.tools.Diagnostic.Kind; mcimadamore@1114: import javax.tools.DiagnosticListener; mcimadamore@1114: import javax.tools.JavaCompiler; mcimadamore@1114: import javax.tools.JavaFileObject; mcimadamore@1114: import javax.tools.StandardJavaFileManager; mcimadamore@1114: import javax.tools.ToolProvider; mcimadamore@1114: mcimadamore@1114: import static javax.tools.StandardLocation.*; mcimadamore@1114: mcimadamore@1114: public class ResolveHarness implements javax.tools.DiagnosticListener { mcimadamore@1114: mcimadamore@1114: static int nerrors = 0; mcimadamore@1114: mcimadamore@1114: static final JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); mcimadamore@1114: static final StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); mcimadamore@1114: mcimadamore@1114: public static void main(String[] args) throws Exception { mcimadamore@1114: fm.setLocation(SOURCE_PATH, mcimadamore@1114: Arrays.asList(new File(System.getProperty("test.src"), "tests"))); mcimadamore@1114: for (JavaFileObject jfo : fm.list(SOURCE_PATH, "", Collections.singleton(JavaFileObject.Kind.SOURCE), true)) { mcimadamore@1114: new ResolveHarness(jfo).check(); mcimadamore@1114: } mcimadamore@1114: if (nerrors > 0) { mcimadamore@1114: throw new AssertionError("Errors were found"); mcimadamore@1114: } mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: mcimadamore@1114: JavaFileObject jfo; mcimadamore@1114: DiagnosticProcessor[] diagProcessors; mcimadamore@1114: Map candidatesMap = new HashMap(); mcimadamore@1114: Set declaredKeys = new HashSet<>(); mcimadamore@1114: List> diags = new ArrayList<>(); mcimadamore@1114: List seenCandidates = new ArrayList<>(); mcimadamore@1779: Map predefTranslationMap = new HashMap<>(); mcimadamore@1114: mcimadamore@1114: protected ResolveHarness(JavaFileObject jfo) { mcimadamore@1114: this.jfo = jfo; mcimadamore@1114: this.diagProcessors = new DiagnosticProcessor[] { mcimadamore@1114: new VerboseResolutionNoteProcessor(), mcimadamore@1114: new VerboseDeferredInferenceNoteProcessor(), mcimadamore@1114: new ErrorProcessor() mcimadamore@1114: }; mcimadamore@1779: predefTranslationMap.put("+", "_plus"); mcimadamore@1779: predefTranslationMap.put("-", "_minus"); mcimadamore@1779: predefTranslationMap.put("~", "_not"); mcimadamore@1779: predefTranslationMap.put("++", "_plusplus"); mcimadamore@1779: predefTranslationMap.put("--", "_minusminus"); mcimadamore@1779: predefTranslationMap.put("!", "_bang"); mcimadamore@1779: predefTranslationMap.put("*", "_mul"); mcimadamore@1779: predefTranslationMap.put("/", "_div"); mcimadamore@1779: predefTranslationMap.put("%", "_mod"); mcimadamore@1779: predefTranslationMap.put("&", "_and"); mcimadamore@1779: predefTranslationMap.put("|", "_or"); mcimadamore@1779: predefTranslationMap.put("^", "_xor"); mcimadamore@1779: predefTranslationMap.put("<<", "_lshift"); mcimadamore@1779: predefTranslationMap.put(">>", "_rshift"); mcimadamore@1779: predefTranslationMap.put("<<<", "_lshiftshift"); mcimadamore@1779: predefTranslationMap.put(">>>", "_rshiftshift"); mcimadamore@1779: predefTranslationMap.put("<", "_lt"); mcimadamore@1779: predefTranslationMap.put(">", "_gt"); mcimadamore@1779: predefTranslationMap.put("<=", "_lteq"); mcimadamore@1779: predefTranslationMap.put(">=", "_gteq"); mcimadamore@1779: predefTranslationMap.put("==", "_eq"); mcimadamore@1779: predefTranslationMap.put("!=", "_neq"); mcimadamore@1779: predefTranslationMap.put("&&", "_andand"); mcimadamore@1779: predefTranslationMap.put("||", "_oror"); mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: protected void check() throws Exception { mcimadamore@1114: String[] options = { mcimadamore@1114: "-XDshouldStopPolicy=ATTR", mcimadamore@1779: "-XDverboseResolution=success,failure,applicable,inapplicable,deferred-inference,predef" mcimadamore@1114: }; mcimadamore@1114: mcimadamore@1114: AbstractProcessor[] processors = { new ResolveCandidateFinder(), null }; mcimadamore@1114: mcimadamore@1114: @SuppressWarnings("unchecked") mcimadamore@1114: DiagnosticListener[] diagListeners = mcimadamore@1114: new DiagnosticListener[] { new DiagnosticHandler(false), new DiagnosticHandler(true) }; mcimadamore@1114: mcimadamore@1114: for (int i = 0 ; i < options.length ; i ++) { mcimadamore@1114: JavacTask ct = (JavacTask)comp.getTask(null, fm, diagListeners[i], mcimadamore@1114: Arrays.asList(options[i]), null, Arrays.asList(jfo)); mcimadamore@1114: if (processors[i] != null) { mcimadamore@1114: ct.setProcessors(Collections.singleton(processors[i])); mcimadamore@1114: } mcimadamore@1114: ct.analyze(); mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: //check diags mcimadamore@1114: for (Diagnostic diag : diags) { mcimadamore@1114: for (DiagnosticProcessor proc : diagProcessors) { mcimadamore@1114: if (proc.matches(diag)) { mcimadamore@1114: proc.process(diag); mcimadamore@1114: break; mcimadamore@1114: } mcimadamore@1114: } mcimadamore@1114: } mcimadamore@1114: //check all candidates have been used up mcimadamore@1114: for (Map.Entry entry : candidatesMap.entrySet()) { mcimadamore@1114: if (!seenCandidates.contains(entry.getKey())) { mcimadamore@1875: error("Redundant @Candidate annotation on method " + entry.getKey().elem + " sig = " + entry.getKey().elem.asType()); mcimadamore@1114: } mcimadamore@1114: } mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: public void report(Diagnostic diagnostic) { mcimadamore@1114: diags.add(diagnostic); mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: Candidate getCandidateAtPos(Element methodSym, long line, long col) { mcimadamore@1114: Candidate c = candidatesMap.get(new ElementKey(methodSym)); mcimadamore@1114: if (c != null) { mcimadamore@1114: Pos pos = c.pos(); mcimadamore@1114: if (!pos.userDefined() || mcimadamore@1114: (pos.line() == line && pos.col() == col)) { mcimadamore@1114: seenCandidates.add(new ElementKey(methodSym)); mcimadamore@1114: return c; mcimadamore@1114: } mcimadamore@1114: } else { mcimadamore@1114: error("Missing @Candidate annotation on method " + methodSym); mcimadamore@1114: } mcimadamore@1114: return null; mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: void checkSig(Candidate c, Element methodSym, MethodType mtype) { mcimadamore@1114: if (c.sig().length() > 0 && !c.sig().equals(mtype.toString())) { mcimadamore@1114: error("Inferred type mismatch for method: " + methodSym); mcimadamore@1114: } mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: protected void error(String msg) { mcimadamore@1114: nerrors++; mcimadamore@1114: System.err.printf("Error occurred while checking file: %s\nreason: %s\n", jfo.getName(), msg); mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: /** mcimadamore@1114: * Base class for diagnostic processor. It provides methods for matching and mcimadamore@1114: * processing a given diagnostic object (overridden by subclasses). mcimadamore@1114: */ mcimadamore@1114: abstract class DiagnosticProcessor { mcimadamore@1114: mcimadamore@1114: List codes; mcimadamore@1114: Diagnostic.Kind kind; mcimadamore@1114: mcimadamore@1114: public DiagnosticProcessor(Kind kind, String... codes) { mcimadamore@1114: this.codes = Arrays.asList(codes); mcimadamore@1114: this.kind = kind; mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: abstract void process(Diagnostic diagnostic); mcimadamore@1114: mcimadamore@1114: boolean matches(Diagnostic diagnostic) { mcimadamore@1114: return (codes.isEmpty() || codes.contains(diagnostic.getCode())) && mcimadamore@1114: diagnostic.getKind() == kind; mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: JCDiagnostic asJCDiagnostic(Diagnostic diagnostic) { mcimadamore@1114: if (diagnostic instanceof JCDiagnostic) { mcimadamore@1114: return (JCDiagnostic)diagnostic; mcimadamore@1114: } else if (diagnostic instanceof DiagnosticSourceUnwrapper) { mcimadamore@1114: return ((DiagnosticSourceUnwrapper)diagnostic).d; mcimadamore@1114: } else { mcimadamore@1114: throw new AssertionError("Cannot convert diagnostic to JCDiagnostic: " + diagnostic.getClass().getName()); mcimadamore@1114: } mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: List subDiagnostics(Diagnostic diagnostic) { mcimadamore@1114: JCDiagnostic diag = asJCDiagnostic(diagnostic); mcimadamore@1114: if (diag instanceof JCDiagnostic.MultilineDiagnostic) { mcimadamore@1114: return ((JCDiagnostic.MultilineDiagnostic)diag).getSubdiagnostics(); mcimadamore@1114: } else { mcimadamore@1114: throw new AssertionError("Cannot extract subdiagnostics: " + diag.getClass().getName()); mcimadamore@1114: } mcimadamore@1114: } mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: /** mcimadamore@1114: * Processor for verbose resolution notes generated by javac. The processor mcimadamore@1114: * checks that the diagnostic is associated with a method declared by mcimadamore@1114: * a class annotated with the special @TraceResolve marker annotation. If mcimadamore@1114: * that's the case, all subdiagnostics (one for each resolution candidate) mcimadamore@1114: * are checked against the corresponding @Candidate annotations, using mcimadamore@1114: * a VerboseCandidateSubdiagProcessor. mcimadamore@1114: */ mcimadamore@1114: class VerboseResolutionNoteProcessor extends DiagnosticProcessor { mcimadamore@1114: mcimadamore@1114: VerboseResolutionNoteProcessor() { mcimadamore@1114: super(Kind.NOTE, mcimadamore@1114: "compiler.note.verbose.resolve.multi", mcimadamore@1114: "compiler.note.verbose.resolve.multi.1"); mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: @Override mcimadamore@1114: void process(Diagnostic diagnostic) { mcimadamore@1114: Element siteSym = getSiteSym(diagnostic); mcimadamore@1779: if (siteSym.getSimpleName().length() != 0 && mcimadamore@1875: ((Symbol)siteSym).outermostClass().getAnnotation(TraceResolve.class) == null) { mcimadamore@1114: return; mcimadamore@1114: } mcimadamore@1114: int candidateIdx = 0; mcimadamore@1114: for (JCDiagnostic d : subDiagnostics(diagnostic)) { mcimadamore@1114: boolean isMostSpecific = candidateIdx++ == mostSpecific(diagnostic); mcimadamore@1114: VerboseCandidateSubdiagProcessor subProc = mcimadamore@1114: new VerboseCandidateSubdiagProcessor(isMostSpecific, phase(diagnostic), success(diagnostic)); mcimadamore@1114: if (subProc.matches(d)) { mcimadamore@1114: subProc.process(d); mcimadamore@1114: } else { mcimadamore@1114: throw new AssertionError("Bad subdiagnostic: " + d.getCode()); mcimadamore@1114: } mcimadamore@1114: } mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: Element getSiteSym(Diagnostic diagnostic) { mcimadamore@1114: return (Element)asJCDiagnostic(diagnostic).getArgs()[1]; mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: int mostSpecific(Diagnostic diagnostic) { mcimadamore@1114: return success(diagnostic) ? mcimadamore@1114: (Integer)asJCDiagnostic(diagnostic).getArgs()[2] : -1; mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: boolean success(Diagnostic diagnostic) { mcimadamore@1114: return diagnostic.getCode().equals("compiler.note.verbose.resolve.multi"); mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: Phase phase(Diagnostic diagnostic) { mcimadamore@1114: return Phase.fromString(asJCDiagnostic(diagnostic).getArgs()[3].toString()); mcimadamore@1114: } mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: /** mcimadamore@1114: * Processor for verbose resolution subdiagnostic notes generated by javac. mcimadamore@1114: * The processor checks that the details of the overload candidate mcimadamore@1114: * match against the info contained in the corresponding @Candidate mcimadamore@1114: * annotation (if any). mcimadamore@1114: */ mcimadamore@1114: class VerboseCandidateSubdiagProcessor extends DiagnosticProcessor { mcimadamore@1114: mcimadamore@1114: boolean mostSpecific; mcimadamore@1114: Phase phase; mcimadamore@1114: boolean success; mcimadamore@1114: mcimadamore@1114: public VerboseCandidateSubdiagProcessor(boolean mostSpecific, Phase phase, boolean success) { mcimadamore@1114: super(Kind.OTHER, mcimadamore@1114: "compiler.misc.applicable.method.found", mcimadamore@1114: "compiler.misc.applicable.method.found.1", mcimadamore@1114: "compiler.misc.not.applicable.method.found"); mcimadamore@1114: this.mostSpecific = mostSpecific; mcimadamore@1114: this.phase = phase; mcimadamore@1114: this.success = success; mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: @Override mcimadamore@1114: void process(Diagnostic diagnostic) { mcimadamore@1875: Symbol methodSym = (Symbol)methodSym(diagnostic); mcimadamore@1875: if ((methodSym.flags() & Flags.GENERATEDCONSTR) != 0) { mcimadamore@1875: //skip resolution of default constructor (put there by javac) mcimadamore@1875: return; mcimadamore@1875: } mcimadamore@1114: Candidate c = getCandidateAtPos(methodSym, mcimadamore@1114: asJCDiagnostic(diagnostic).getLineNumber(), mcimadamore@1114: asJCDiagnostic(diagnostic).getColumnNumber()); mcimadamore@1114: if (c == null) { mcimadamore@1114: return; //nothing to check mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: if (c.applicable().length == 0 && c.mostSpecific()) { mcimadamore@1114: error("Inapplicable method cannot be most specific " + methodSym); mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: if (isApplicable(diagnostic) != Arrays.asList(c.applicable()).contains(phase)) { mcimadamore@1114: error("Invalid candidate's applicability " + methodSym); mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: if (success) { mcimadamore@1114: for (Phase p : c.applicable()) { mcimadamore@1114: if (phase.ordinal() < p.ordinal()) { mcimadamore@1114: error("Invalid phase " + p + " on method " + methodSym); mcimadamore@1114: } mcimadamore@1114: } mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: if (Arrays.asList(c.applicable()).contains(phase)) { //applicable mcimadamore@1114: if (c.mostSpecific() != mostSpecific) { mcimadamore@1779: error("Invalid most specific value for method " + methodSym + " " + new ElementKey(methodSym).key); mcimadamore@1114: } mcimadamore@1114: MethodType mtype = getSig(diagnostic); mcimadamore@1114: if (mtype != null) { mcimadamore@1114: checkSig(c, methodSym, mtype); mcimadamore@1114: } mcimadamore@1114: } mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: boolean isApplicable(Diagnostic diagnostic) { mcimadamore@1114: return !diagnostic.getCode().equals("compiler.misc.not.applicable.method.found"); mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: Element methodSym(Diagnostic diagnostic) { mcimadamore@1114: return (Element)asJCDiagnostic(diagnostic).getArgs()[1]; mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: MethodType getSig(Diagnostic diagnostic) { mcimadamore@1114: JCDiagnostic details = (JCDiagnostic)asJCDiagnostic(diagnostic).getArgs()[2]; mcimadamore@1114: if (details == null) { mcimadamore@1114: return null; mcimadamore@1114: } else if (details instanceof JCDiagnostic) { mcimadamore@1114: return details.getCode().equals("compiler.misc.full.inst.sig") ? mcimadamore@1114: (MethodType)details.getArgs()[0] : null; mcimadamore@1114: } else { mcimadamore@1114: throw new AssertionError("Bad diagnostic arg: " + details); mcimadamore@1114: } mcimadamore@1114: } mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: /** mcimadamore@1114: * Processor for verbose deferred inference notes generated by javac. The mcimadamore@1114: * processor checks that the inferred signature for a given generic method mcimadamore@1114: * call corresponds to the one (if any) declared in the @Candidate annotation. mcimadamore@1114: */ mcimadamore@1114: class VerboseDeferredInferenceNoteProcessor extends DiagnosticProcessor { mcimadamore@1114: mcimadamore@1114: public VerboseDeferredInferenceNoteProcessor() { mcimadamore@1114: super(Kind.NOTE, "compiler.note.deferred.method.inst"); mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: @Override mcimadamore@1114: void process(Diagnostic diagnostic) { mcimadamore@1114: Element methodSym = methodSym(diagnostic); mcimadamore@1114: Candidate c = getCandidateAtPos(methodSym, mcimadamore@1114: asJCDiagnostic(diagnostic).getLineNumber(), mcimadamore@1114: asJCDiagnostic(diagnostic).getColumnNumber()); mcimadamore@1114: MethodType sig = sig(diagnostic); mcimadamore@1114: if (c != null && sig != null) { mcimadamore@1114: checkSig(c, methodSym, sig); mcimadamore@1114: } mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: Element methodSym(Diagnostic diagnostic) { mcimadamore@1114: return (Element)asJCDiagnostic(diagnostic).getArgs()[0]; mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: MethodType sig(Diagnostic diagnostic) { mcimadamore@1114: return (MethodType)asJCDiagnostic(diagnostic).getArgs()[1]; mcimadamore@1114: } mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: /** mcimadamore@1114: * Processor for all error diagnostics; if the error key is not declared in mcimadamore@1114: * the test file header, the processor reports an error. mcimadamore@1114: */ mcimadamore@1114: class ErrorProcessor extends DiagnosticProcessor { mcimadamore@1114: mcimadamore@1114: public ErrorProcessor() { mcimadamore@1114: super(Diagnostic.Kind.ERROR); mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: @Override mcimadamore@1114: void process(Diagnostic diagnostic) { mcimadamore@1114: if (!declaredKeys.contains(diagnostic.getCode())) { mcimadamore@1114: error("Unexpected compilation error key '" + diagnostic.getCode() + "'"); mcimadamore@1114: } mcimadamore@1114: } mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: @SupportedAnnotationTypes({"Candidate","TraceResolve"}) mcimadamore@1114: class ResolveCandidateFinder extends JavacTestingAbstractProcessor { mcimadamore@1114: mcimadamore@1114: @Override mcimadamore@1114: public boolean process(Set annotations, RoundEnvironment roundEnv) { mcimadamore@1114: if (roundEnv.processingOver()) mcimadamore@1114: return true; mcimadamore@1114: mcimadamore@1114: TypeElement traceResolveAnno = elements.getTypeElement("TraceResolve"); mcimadamore@1114: TypeElement candidateAnno = elements.getTypeElement("Candidate"); mcimadamore@1114: mcimadamore@1114: if (!annotations.contains(traceResolveAnno)) { mcimadamore@1114: error("no @TraceResolve annotation found in test class"); mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: if (!annotations.contains(candidateAnno)) { mcimadamore@1114: error("no @candidate annotation found in test class"); mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: for (Element elem: roundEnv.getElementsAnnotatedWith(traceResolveAnno)) { mcimadamore@1114: TraceResolve traceResolve = elem.getAnnotation(TraceResolve.class); mcimadamore@1114: declaredKeys.addAll(Arrays.asList(traceResolve.keys())); mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: for (Element elem: roundEnv.getElementsAnnotatedWith(candidateAnno)) { mcimadamore@1114: candidatesMap.put(new ElementKey(elem), elem.getAnnotation(Candidate.class)); mcimadamore@1114: } mcimadamore@1114: return true; mcimadamore@1114: } mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: class ElementKey { mcimadamore@1114: mcimadamore@1114: String key; mcimadamore@1114: Element elem; mcimadamore@1114: mcimadamore@1114: public ElementKey(Element elem) { mcimadamore@1114: this.elem = elem; mcimadamore@1114: this.key = computeKey(elem); mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: @Override mcimadamore@1114: public boolean equals(Object obj) { mcimadamore@1114: if (obj instanceof ElementKey) { mcimadamore@1114: ElementKey other = (ElementKey)obj; mcimadamore@1114: return other.key.equals(key); mcimadamore@1114: } mcimadamore@1114: return false; mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: @Override mcimadamore@1114: public int hashCode() { mcimadamore@1114: return key.hashCode(); mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: String computeKey(Element e) { mcimadamore@1875: String simpleName = e.getSimpleName().toString(); mcimadamore@1875: String opName = predefTranslationMap.get(simpleName); mcimadamore@1875: String name = opName != null ? opName : simpleName; mcimadamore@1875: return name + e.asType(); mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: @Override mcimadamore@1114: public String toString() { mcimadamore@1114: return "Key{"+key+"}"; mcimadamore@1114: } mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: class DiagnosticHandler implements DiagnosticListener { mcimadamore@1114: mcimadamore@1114: boolean shouldRecordDiags; mcimadamore@1114: mcimadamore@1114: DiagnosticHandler(boolean shouldRecordDiags) { mcimadamore@1114: this.shouldRecordDiags = shouldRecordDiags; mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: public void report(Diagnostic diagnostic) { mcimadamore@1114: if (shouldRecordDiags) mcimadamore@1114: diags.add(diagnostic); mcimadamore@1114: } mcimadamore@1114: mcimadamore@1114: } mcimadamore@1114: }