private void processRound(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { loop: for (TypeElement annotation : annotations) { for (Element element : roundEnv.getElementsAnnotatedWith(annotation)) { switch (element.getAnnotation(RuntimeExtension.class).value()) { case FRAMEWORK: entry = "Fragment-Host: system.bundle; extension:=framework"; break loop; case BOOTCLASSPATH: entry = "Fragment-Host: system.bundle; extension:=bootclasspath"; break loop; } } } try { generateFile(); } catch (IOException e) { messager.printMessage(Kind.ERROR, "IOException while generating file with contracts! " + e.getMessage()); e.printStackTrace(); } }
private void processRound(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { loop: for (TypeElement annotation : annotations) { for (Element element : roundEnv.getElementsAnnotatedWith(annotation)) { if (element.getAnnotation(Activator.class).extension()) { extensionActivator = element.asType().toString(); } else { activator = element.asType().toString(); } if (activator != null && extensionActivator != null) { break loop; } } } try { generateFile(); } catch (IOException e) { messager.printMessage(Kind.ERROR, "IOException while generating file with contracts! " + e.getMessage()); e.printStackTrace(); } }
@Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { for (Element element : roundEnv.getElementsAnnotatedWith(ParameterNames.class)) { ParameterNames names = element.getAnnotation(ParameterNames.class); if (names == null) { continue; } List<String> expected = Arrays.asList(names.value()); List<String> actual = ((ExecutableElement) element) .getParameters() .stream() .map(p -> p.getSimpleName().toString()) .collect(toCollection(ArrayList::new)); if (!expected.equals(actual)) { String message = String.format( "bad parameter names for %s#%s; expected: %s, was: %s", element, element, expected, actual); messager.printMessage(Kind.ERROR, message); } } return false; }
private void flush(RoundEnvironment roundEnv) { if (!originatingElements.isEmpty()) { try (OutputStream os = processingEnv.getFiler().createResource( StandardLocation.CLASS_OUTPUT, "", "META-INF/.bytecodePatched", originatingElements.toArray(new Element[originatingElements.size()])).openOutputStream()) { BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os, "UTF-8")); for (Map.Entry<String, String> exEntry : superclasses.entrySet()) { String api = exEntry.getKey(); String sup = exEntry.getValue(); bw.append("extend.").append(api).append("=").append(sup); bw.newLine(); } bw.flush(); } catch (IOException x) { processingEnv.getMessager().printMessage(Kind.ERROR, x.getMessage()); } } }
private TypeElement getImplFor() { implForElement = processingEnv.getElementUtils().getTypeElement(IMPL_FOR_NAME); if (implForElement == null) { if (!reported) { processingEnv.getMessager().printMessage(Kind.ERROR, "Cannot find @ImplementationFor annotation"); reported = true; } return null; } for (Element e : implForElement.getEnclosedElements()) { if (e.getKind() == ElementKind.METHOD && e.getSimpleName().contentEquals("value")) { valueElement = e; break; } } return implForElement; }
private boolean parseBeanMethod(ExecutableElement beanMethod, String[] beanNames, Messager messager) { boolean valid = true; if (beanNames.length == 0) { valid = false; messager.printMessage(Kind.ERROR, "All @Bean annotations must define at least one name for a bean.", beanMethod); } if (beanMethod.getReturnType().getKind() != TypeKind.DECLARED) { valid = false; messager.printMessage(Kind.ERROR, "@Bean methods must return an Object", beanMethod); } if (!beanMethod.getModifiers().contains(Modifier.PUBLIC)) { valid = false; messager.printMessage(Kind.ERROR, "@Bean methods must be marked public", beanMethod); } List<Modifier> illegalModifiers = getIllegalModifiers(beanMethod.getModifiers(), DISALLOWED_ON_METHOD); if (illegalModifiers.size() != 0) { valid = false; messager.printMessage(Kind.ERROR, "Illegal modifiers found on spring @Bean method: " + illegalModifiers.stream().map(m -> m.name()).collect(Collectors.joining(", ")), beanMethod); } return valid; }
public final M parse(RoundEnvironment env, Element element) { this.roundEnv = env; M model = null; try { AnnotationMirror mirror = null; if (getAnnotationType() != null) { mirror = Utils.findAnnotationMirror(processingEnv, element.getAnnotationMirrors(), getAnnotationType()); } if (!context.getTruffleTypes().verify(context, element, mirror)) { return null; } model = parse(element, mirror); if (model == null) { return null; } model.emitMessages((TypeElement) element, log); return filterErrorElements(model); } catch (CompileErrorException e) { log.message(Kind.WARNING, element, null, null, "The truffle processor could not parse class due to error: %s", e.getMessage()); return null; } finally { this.roundEnv = null; } }
public TruffleTypes(ProcessorContext context) { node = getRequired(context, Node.class); nodeArray = context.getEnvironment().getTypeUtils().getArrayType(node); unexpectedValueException = getRequired(context, UnexpectedResultException.class); frame = getRequired(context, VirtualFrame.class); childAnnotation = getRequired(context, Child.class); childrenAnnotation = getRequired(context, Children.class); compilerDirectives = getRequired(context, CompilerDirectives.class); compilerAsserts = getRequired(context, CompilerAsserts.class); assumption = getRequired(context, Assumption.class); invalidAssumption = getRequired(context, InvalidAssumptionException.class); nodeInfoAnnotation = getRequired(context, NodeInfo.class); nodeInfoKind = getRequired(context, NodeInfo.Kind.class); slowPath = getRequired(context, SlowPath.class); truffleOptions = getRequired(context, TruffleOptions.class); }
private void checkInputType(TypeElement nodeClass, TypeMirror returnType, Element element, AnnotationMirror annotation) { InputType inputType = getInputType(returnType, element, annotation); if (inputType != InputType.Value) { boolean allowed = false; InputType[] allowedTypes = nodeClass.getAnnotation(NodeInfo.class).allowedUsageTypes(); for (InputType allowedType : allowedTypes) { if (inputType == allowedType) { allowed = true; break; } } if (!allowed) { env.getMessager().printMessage(Kind.ERROR, String.format("@NodeIntrinsic returns input type %s, but only %s is allowed.", inputType, Arrays.toString(allowedTypes)), element, annotation); } } }
private void printMessage(Kind kind, Element element, String message, Object[] args) { if (args.length > 0) { message = String.format(message, args); } processingEnv.getMessager().printMessage(kind, message, element); }
void complete() { try { writeFile(); } catch (Exception ex) { StaticEnvironment.processing().getMessager().printMessage( Diagnostic.Kind.MANDATORY_WARNING, "Cannot write service files: " + key + ex.toString()); } }
@Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { for (Element root : roundEnv.getRootElements()) { processingEnv.getMessager().printMessage(Kind.ERROR, "error1", root); processingEnv.getMessager().printMessage(Kind.ERROR, "error2", root); Trees trees = Trees.instance(processingEnv); TreePath path = trees.getPath(root); trees.printMessage(Kind.ERROR, "error3", path.getLeaf(), path.getCompilationUnit()); trees.printMessage(Kind.ERROR, "error4", path.getLeaf(), path.getCompilationUnit()); } return true; }
@Override public void report(Diagnostic<? extends JavaFileObject> message) { if (partialReparseErrors != null) { if (this.jfo != null && this.jfo == message.getSource()) { partialReparseErrors.add(message); if (message.getKind() == Kind.ERROR) { partialReparseRealErrors = true; } } } else { Diagnostics errors = getErrors(message.getSource()); errors.add((int) message.getPosition(), message); } }
private void warnUndocumented(int i, Element e, String key) { AnnotationMirror mirror = null; AnnotationValue value = null; if (e != null) { for (AnnotationMirror _mirror : e.getAnnotationMirrors()) { if (_mirror.getAnnotationType().toString().equals(NbBundle.Messages.class.getCanonicalName())) { mirror = _mirror; for (Map.Entry<? extends ExecutableElement,? extends AnnotationValue> entry : mirror.getElementValues().entrySet()) { if (entry.getKey().getSimpleName().contentEquals("value")) { // SimpleAnnotationValueVisitor6 unusable here since we need to determine the AnnotationValue in scope when visitString is called: Object v = entry.getValue().getValue(); if (v instanceof String) { if (((String) v).startsWith(key + "=")) { value = entry.getValue(); } } else { for (AnnotationValue subentry : NbCollections.checkedListByCopy((List<?>) v, AnnotationValue.class, true)) { v = subentry.getValue(); if (v instanceof String) { if (((String) v).startsWith(key + "=")) { value = subentry; break; } } } } break; } } break; } } } processingEnv.getMessager().printMessage(Kind.WARNING, "Undocumented format parameter {" + i + "}", e, mirror, value); }
@Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { if (!roundEnv.processingOver()) { for (Element e : roundEnv.getElementsAnnotatedWith(RandomlyFails.class)) { Element typeEl = e.getKind() == ElementKind.METHOD ? e.getEnclosingElement() : e; TypeMirror nbTestCaseType = processingEnv.getElementUtils(). getTypeElement(NbTestCase.class.getName()).asType(); if (!processingEnv.getTypeUtils().isAssignable(typeEl.asType(), nbTestCaseType)) { processingEnv.getMessager().printMessage(Kind.ERROR, "@RandomlyFails must be used on NbTestCase subclasses", e); } } return true; } return false; }
private boolean verifyTriggerAnnotations(ExecutableElement method) { List<AnnotationMirror> patternAnnotations = new ArrayList<AnnotationMirror>(); AnnotationMirror am = findAnnotation(method.getAnnotationMirrors(), "org.netbeans.spi.java.hints.TriggerPattern"); if (am != null) { patternAnnotations.add(am); } am = findAnnotation(method.getAnnotationMirrors(), "org.netbeans.spi.java.hints.TriggerPatterns"); if (am != null) { patternAnnotations.addAll(Arrays.asList(getAttributeValue(am, "value", AnnotationMirror[].class))); } for (AnnotationMirror patternDescription : patternAnnotations) { String pattern = getAttributeValue(patternDescription, "value", String.class); if (pattern == null) continue; Set<String> variables = new HashSet<String>(); Matcher m = VARIABLE_PATTERN.matcher(pattern); while (m.find()) { variables.add(m.group(0)); } for (AnnotationMirror constraint : getAttributeValue(patternDescription, "constraints", AnnotationMirror[].class)) { String variable = getAttributeValue(constraint, "variable", String.class); String type = getAttributeValue(constraint, "type", String.class); if (variable == null || type == null) continue; if (!variables.contains(variable)) { processingEnv.getMessager().printMessage(Kind.WARNING, "Variable " + variable + " not used in the pattern", method, constraint, getAttributeValueDescription(constraint, "variable")); } } } return false; }
public Void visitString(String s, Void p) { if ("displayName".equals(attrName) || "description".equals(attrName) || "tooltip".equals(attrName)) { try { annotationFolder.bundlevalue(attrName, s); } catch (LayerGenerationException ex) { processingEnv.getMessager().printMessage(Kind.ERROR, ex.getLocalizedMessage(), errElement, errAnnotationMirror, errAnnotationValue); } } else { annotationFolder.stringvalue(attrName, s); } return null; }
/** * Register a service. * If the class does not have an appropriate signature, an error will be printed and the registration skipped. * @param clazz the service implementation type (an error will be reported if not a {@link TypeElement}) * @param annotation the (top-level) annotation registering the service, for diagnostic purposes * @param type the type to which the implementation must be assignable * @param path a path under which to register, or "" if inapplicable * @param position a position at which to register, or {@link Integer#MAX_VALUE} to skip * @param supersedes possibly empty list of implementation to supersede * @since 8.8 */ protected final void register( Element el, Class<? extends Annotation> annotation, TypeMirror type, String path, int position, String... supersedes ) { if (el.getKind() != ElementKind.CLASS) { processingEnv.getMessager().printMessage(Kind.ERROR, annotation.getName() + " is not applicable to a " + el.getKind(), el); return; } if (el.getEnclosingElement().getKind() == ElementKind.CLASS && !el.getModifiers().contains(Modifier.STATIC)) { processingEnv.getMessager().printMessage(Kind.ERROR, "Inner class needs to be static to be annotated with @ServiceProvider", el); return; } TypeElement clazz = (TypeElement) el; String impl = processingEnv.getElementUtils().getBinaryName(clazz).toString(); String xface = processingEnv.getElementUtils().getBinaryName((TypeElement) processingEnv.getTypeUtils().asElement(type)).toString(); if (!processingEnv.getTypeUtils().isAssignable(clazz.asType(), type)) { AnnotationMirror ann = findAnnotationMirror(clazz, annotation); processingEnv.getMessager().printMessage(Kind.ERROR, impl + " is not assignable to " + xface, clazz, ann, findAnnotationValue(ann, "service")); return; } String rsrc = (path.length() > 0 ? "META-INF/namedservices/" + path + "/" : "META-INF/services/") + xface; Boolean verify = verifiedClasses.get(clazz); if (verify == null) { verify = verifyServiceProviderSignature(clazz, annotation); verifiedClasses.put(clazz, verify); } if (!verify) { return; } registerImpl(clazz, impl, rsrc, position, supersedes); }
private boolean verifyServiceProviderSignature(TypeElement clazz, Class<? extends Annotation> annotation) { AnnotationMirror ann = findAnnotationMirror(clazz, annotation); if (!clazz.getModifiers().contains(Modifier.PUBLIC)) { processingEnv.getMessager().printMessage(Kind.ERROR, clazz + " must be public", clazz, ann); return false; } if (clazz.getModifiers().contains(Modifier.ABSTRACT)) { processingEnv.getMessager().printMessage(Kind.ERROR, clazz + " must not be abstract", clazz, ann); return false; } if (clazz.getEnclosingElement().getKind() != ElementKind.PACKAGE && !clazz.getModifiers().contains(Modifier.STATIC)) { processingEnv.getMessager().printMessage(Kind.ERROR, clazz + " must be static", clazz, ann); return false; } { boolean hasDefaultCtor = false; for (ExecutableElement constructor : ElementFilter.constructorsIn(clazz.getEnclosedElements())) { if (constructor.getModifiers().contains(Modifier.PUBLIC) && constructor.getParameters().isEmpty()) { hasDefaultCtor = true; break; } } if (!hasDefaultCtor) { processingEnv.getMessager().printMessage(Kind.ERROR, clazz + " must have a public no-argument constructor", clazz, ann); return false; } } return true; }
public static void main(String[] args) throws Exception { try { fm.setLocation(SOURCE_PATH, Arrays.asList(new File(System.getProperty("test.src"), "tests"))); for (JavaFileObject jfo : fm.list(SOURCE_PATH, "", Collections.singleton(JavaFileObject.Kind.SOURCE), true)) { new ResolveHarness(jfo).check(); } if (nerrors > 0) { throw new AssertionError("Errors were found"); } } finally { fm.close(); } }
private void error(Element element, String message, Object... args) { if (args.length > 0) { message = String.format(message, args); } this.messager.printMessage(Kind.ERROR, message, element); }
/** * Read a TypeElement to get application structure. * * @param te definition type element. * @param messager presents error messages for the compiler to pass to the user. * @return the {@link DefinitionModel} parsed from a properly annotated {@link TypeElement} */ public DefinitionModel extractDefinition(TypeElement te, Messager messager) { Verified verified = te.getAnnotation(Verified.class); DefinitionModel model = new DefinitionModel(te, verified == null ? false : verified.root()); errorIfInvalidClass(te, messager); model.addDependencyNames(getImportsTypes(te)); String[] configurationBeanNames = AnnotationValueExtractor .getAnnotationValue(te, CONFIGURATION_TYPE, DEFAULT_ANNOTATION_VALUE); String[] componentBeanNames = AnnotationValueExtractor .getAnnotationValue(te, COMPONENT_TYPE, DEFAULT_ANNOTATION_VALUE); if (configurationBeanNames != null) { for (Element enclosed : te.getEnclosedElements()) { handleEnclosedElements(messager, model, enclosed); } } else { if (componentBeanNames != null) { addModelsFromComponent(te, model, componentBeanNames, messager); } else { messager.printMessage(Kind.ERROR, "@Verified annotation must only be used on @Configuration or @Component classes", te); } } for (String expectedBean : verified.expectedBeans()) { model.addDefinition(new ExpectedModel(expectedBean, te)); } return model; }
/** * This method is called on {@link ExecutableElement}. * Bean methods on an @Configuration bean, or Constructors on @Component classes. * This method parses the @Qualifier, or @Value annotations if a @Verified=root, and reads the types of each parameter. * That data is used to build a list of {@link InstanceDependencyModel}'s which are part of an {@link InstanceModel}. * All parameters must have an @Qualifier or @Value, and the annotations can not be mixed, errors will result otherwise. * * @param messager APT messager that will receive error messages. * @param model the DefinitionModel being parse, which may be a @Configuration or @Component annotated entity. * @param execelement the bean method if an @Configuration, or the constructor if an @Component. * @return the dependencies of the to be constructed {@link InstanceModel} */ private List<InstanceDependencyModel> execElementDependency(Messager messager, DefinitionModel model, ExecutableElement execelement) { List<InstanceDependencyModel> dependencies = new ArrayList<>(); boolean hasValues = false; boolean hasQualifiers = false; for (VariableElement varelement : execelement.getParameters()) { String[] qualifierNames = AnnotationValueExtractor .getAnnotationValue(varelement, QUALIFIER_TYPE, DEFAULT_ANNOTATION_VALUE); String[] valueNames = AnnotationValueExtractor .getAnnotationValue(varelement, VALUE_TYPE, DEFAULT_ANNOTATION_VALUE); if (qualifierNames == null && valueNames == null) { messager.printMessage(Kind.ERROR, "All parameters must have an @Qualifier or a @Value annotation", varelement); } if (qualifierNames != null) { dependencies.add(new InstanceDependencyModel(qualifierNames[0], varelement.asType().toString())); hasQualifiers = true; } if (valueNames != null) { //ignore values as they will be used to build beans and pass the data on, and //are not beans themselves... and cannot be intermingled with @Qualifiers. hasValues = true; } } if (hasValues && hasQualifiers) { messager.printMessage(Kind.ERROR, "No method may define both @Qualifier or a @Value annotations," + " keep property values in there own beans", execelement); } if (hasValues && !model.isRootNode()) { messager.printMessage(Kind.ERROR, "Only @Verified(root=true) nodes may use @Value annotations to create beans," + " decouples spring graph from environment", execelement); } return dependencies; }
/** * Builds an instance model by finding the autowired constructor of an @Component model as well as * * @param te the TypeElement corresponding to the @Component class. * @param dm the definitionModel built from the @Component. * @param names the list if names in an @Component annotation. Users must explicitly define one. * @param messager errors are added to this APT messager. */ private void addModelsFromComponent(TypeElement te, DefinitionModel dm, String[] names, Messager messager) { List<InstanceDependencyModel> dependencies = new ArrayList<>(); ExecutableElement chosenConstructor = findAutowiredConstructor(extractConstructorsFromComponent(te)); if (chosenConstructor == null) { messager.printMessage(Kind.ERROR, "No single default constructor or single @Autowired constructor", te); } else { dependencies = execElementDependency(messager, dm, chosenConstructor); //dm.getExpectedDefinitions() } te.getEnclosedElements().stream() .filter(el -> el instanceof VariableElement) .map(el -> (VariableElement) el) .filter(ve -> !staticPrivateFinalLiteralField.test(ve) && !privateFinalField.test(ve)) .forEach(ve -> messager .printMessage(Kind.ERROR, "@Component classes my only have static final constant fields or final private fields", ve)); InstanceModel model = new InstanceModel(names[0], dm.getIdentity(), chosenConstructor, te.getQualifiedName().toString(), dependencies, new ArrayList<>()); dm.addDefinition(model); for (InstanceDependencyModel dep : dependencies) { ExpectedModel expectedModel = new ExpectedModel(dep.getIdentity()); expectedModel.addDefinitionReferenceToType(model.getIdentity(), dep.getType()); dm.addDefinition(expectedModel); } }
private void errorIfInvalidClass(TypeElement te, Messager messager) { if (te.getEnclosingElement().getKind() != ElementKind.PACKAGE) { messager.printMessage(Kind.ERROR, "The class must be a top level class, not an internal class", te); } if (AnnotationValueExtractor.getAnnotationValue(te, COMPONENTSCAN_TYPE, "basePackages") != null || AnnotationValueExtractor.getAnnotationValue(te, COMPONENTSCANS_TYPE, "basePackages") != null) { messager.printMessage(Kind.ERROR, "You may not use @ComponentScan(s) on @Verified classes", te); } }
/** * Gives user feedback as info/warnings/errors during compilation (works in m2e with takari-lifecycle). * * @param messager APT round handler for user messages */ public void outputErrors(Messager messager) { Iterable<ErrorModel> errors = checkAndStoreValid(); for (ErrorModel error : errors) { for (AbstractModel model : error.getInvolved()) { if (model.getSourceElement().isPresent()) { messager.printMessage(Kind.ERROR, error.getMessageOn(model, k -> getMessageFormats().getMessage(k)), getCorrespondingElement(elementUtils, model.getSourceElement().get())); } } } }
@Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { if (roundEnv.processingOver()) { processingEnv.getMessager().printMessage(Kind.ERROR, "Stop!"); } return false; }
@Override public void print(Kind kind, Element e, String msg) { switch (kind) { case ERROR: printError(e, msg); return; case WARNING: case MANDATORY_WARNING: printWarning(e, msg); return; default: printWarning(e, msg); return; } }
public VerboseCandidateSubdiagProcessor(boolean mostSpecific, Phase phase, boolean success) { super(Kind.OTHER, "compiler.misc.applicable.method.found", "compiler.misc.applicable.method.found.1", "compiler.misc.not.applicable.method.found"); this.mostSpecific = mostSpecific; this.phase = phase; this.success = success; }
@Override public Void visitDocComment(DocCommentTree tree, Void ignore) { super.visitDocComment(tree, ignore); for (TagStackItem tsi: tagStack) { warnIfEmpty(tsi, null); if (tsi.tree.getKind() == DocTree.Kind.START_ELEMENT && tsi.tag.endKind == HtmlTag.EndKind.REQUIRED) { StartElementTree t = (StartElementTree) tsi.tree; env.messages.error(HTML, t, "dc.tag.not.closed", t.getName()); } } return null; }
@Override public void print(Kind kind, String msg) { switch (kind) { case ERROR: printError(msg); return; case WARNING: case MANDATORY_WARNING: printWarning(msg); return; default: printNotice(msg); return; } }
public void report(Diagnostic<? extends JavaFileObject> diagnostic) { if (diagnostic.getKind() == Diagnostic.Kind.ERROR) { errorFound = true; } else if (statProcessor.matches(diagnostic)) { statProcessor.process(diagnostic); } }
@Override public Void visitLiteral(LiteralTree tree, Void ignore) { markEnclosingTag(Flag.HAS_INLINE_TAG); if (tree.getKind() == DocTree.Kind.CODE) { for (TagStackItem tsi: tagStack) { if (tsi.tag == HtmlTag.CODE) { env.messages.warning(HTML, tree, "dc.tag.code.within.code"); break; } } } return super.visitLiteral(tree, ignore); }
private Diagnostic<JavaFileObject> createDiagnostic( final Diagnostic.Kind kind, final String code, final Object... args) { return new Diagnostic<JavaFileObject>() { public String getCode() { return code; } public long getColumnNumber() { return Diagnostic.NOPOS; } public long getEndPosition() { return Diagnostic.NOPOS; } public Kind getKind() { return kind; } public long getLineNumber() { return Diagnostic.NOPOS; } public String getMessage(Locale locale) { if (code.length() == 0) return (String) args[0]; return getText(code, args); // FIXME locale } public long getPosition() { return Diagnostic.NOPOS; } public JavaFileObject getSource() { return null; } public long getStartPosition() { return Diagnostic.NOPOS; } }; }
private void processAnnotated(Element element) { Qualify.Extend extend = element.getAnnotation(Qualify.Extend.class); if (extend != null) { if (mixinMetamodel != null) print(Kind.ERROR, "multiple mixin definitions", element); TypeElement mixin = qualifyExtendValue(extend); if (!mixin.equals(typeElementFor(Object.class))) { mixinMetamodel = ClassName.bestGuess(getQualifierName(getFlatName(mixin))); } mixinProperty = extend.name().isEmpty() ? name : extend.name(); } getProviders().forEach(extension -> extension.processAnnotated(element, metadata())); }
@Override public void finished(TaskEvent taskEvent) { if (taskEvent.getKind().equals(TaskEvent.Kind.ANALYZE)) { CompilationUnitTree compilationUnit = taskEvent.getCompilationUnit(); visitor.scan(compilationUnit, null); } }
public boolean verify(ProcessorContext context, Element element, AnnotationMirror mirror) { if (errors.isEmpty()) { return true; } for (String error : errors) { context.getLog().message(Kind.ERROR, element, mirror, null, error); } return false; }
private boolean verifyAnnotation(TypeMirror serviceInterface, TypeElement serviceProvider) { if (!processingEnv.getTypeUtils().isSubtype(serviceProvider.asType(), serviceInterface)) { String msg = String.format("Service provider class %s doesn't implement service interface %s", serviceProvider.getSimpleName(), serviceInterface); processingEnv.getMessager().printMessage(Kind.ERROR, msg, serviceProvider); return false; } return true; }