2

我有简单的注释处理器。

@SupportedSourceVersion(SourceVersion.RELEASE_7)
@AutoService(Processor.class)

    public class FirstProcessor extends AbstractProcessor {

        private Messager messager;

        private EnumGenerator enumGenerator;
        private Elements elementUtils;

        @Override
        public synchronized void init(ProcessingEnvironment processingEnv) {
            super.init(processingEnv);
            messager = processingEnv.getMessager();
            elementUtils = processingEnv.getElementUtils();
            enumGenerator = new EnumGenerator(messager);
        }

        @Override
        public Set<String> getSupportedAnnotationTypes() {
            Set<String> set = new HashSet<>();
            Collections.addAll(set, SuperPower.class.getCanonicalName(), Service.class.getCanonicalName());
            return set;
        }

        @Override
        public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
            messager.printMessage(Diagnostic.Kind.NOTE, "start generate...");

            for (Element elem: roundEnv.getElementsAnnotatedWith(SuperPower.class)) {
                SuperPower superPower = elem.getAnnotation(SuperPower.class);
                String message = String.format("SuperPower found in %s, with name %s, with power %d, with lvl %s", elem.getSimpleName(),
                        superPower.name(), superPower.power(), superPower.value());

                messager.printMessage(Diagnostic.Kind.NOTE, message);
            }

            Map<String, String> foundedServices = new HashMap<>();

            for (Element elem: roundEnv.getElementsAnnotatedWith(Service.class)) {
                Service service = elem.getAnnotation(Service.class);

                messager.printMessage(Diagnostic.Kind.NOTE, "found new annotation for class: " + elem.getSimpleName());

                PackageElement packageElement = elementUtils.getPackageOf(elem);
                String packageString = packageElement.getQualifiedName().toString();
                foundedServices.put(elem.getSimpleName().toString(), packageString);
            }

            if (foundedServices.size() != 0)
            generateEnum(foundedServices);

            return false;
        }

        private void generateEnum(Map<String, String> foundedServices) {
            enumGenerator.generateEnum(foundedServices);
        }
    }

他调用generateEnum:

public class EnumGenerator {

    private final Messager messager;

    private static final String ENUM_PATH = ".enum";

    protected static final String ENUM_CLASS_NAME = "ServiceTypeEnum";
    protected static final String ENUM_SUFFIX = "_ENUM";
    protected static final String CLASS_SUFFIX = ".class";
    protected static final String CLASS_REFERNECE_FIELD_NAME = "mClass";
    protected static final String CONSTRUCTOR_PARAM_NAME = "clazz";

    public EnumGenerator(Messager messager) {
        this.messager = messager;
    }

    protected void generateEnum(Map<String, String> foundedServices) {
        File path = new File(Path.ROOT + ENUM_PATH);

        //class modifiers and name
        TypeSpec.Builder servicesEnumBuilder = TypeSpec.enumBuilder(ENUM_CLASS_NAME)
                .addModifiers(Modifier.PUBLIC);

        //add ENUMS values: name(service.class)
        messager.printMessage(Diagnostic.Kind.NOTE, "size of map: " + foundedServices.size());
        for (Map.Entry<String, String> entry : foundedServices.entrySet()) {
            servicesEnumBuilder.addEnumConstant(
                    entry.getKey().toUpperCase() + ENUM_SUFFIX,
                    TypeSpec.anonymousClassBuilder("$T", ClassName.get(entry.getValue(), entry.getKey())).build());
        }

        //add FIELD: private final Class<?> mClass
        TypeName wildcard = WildcardTypeName.subtypeOf(Object.class);
        servicesEnumBuilder.addField(
                ParameterizedTypeName.get(ClassName.get(Class.class), wildcard),
                CLASS_REFERNECE_FIELD_NAME,
                Modifier.PRIVATE, Modifier.FINAL);

        //add method (constructor) ServiceType(final Class<?> clazz) {this.mClass = clazz;}
        servicesEnumBuilder.addMethod(
                MethodSpec.constructorBuilder()
                        .addParameter(
                                ParameterizedTypeName.get(ClassName.get(Class.class), wildcard),
                                CONSTRUCTOR_PARAM_NAME,
                                Modifier.FINAL)
                        .addStatement("this.$S = $S", CLASS_REFERNECE_FIELD_NAME, CONSTRUCTOR_PARAM_NAME)
                        .build());

        TypeSpec enumWithServices = servicesEnumBuilder.build();

        messager.printMessage(Diagnostic.Kind.NOTE, "generate to: " + path.getPath());
        JavaFile enumFile = JavaFile.builder(ENUM_PATH, enumWithServices).build();

        try {
            enumFile.writeTo(path);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

但这不起作用!在另一个项目中,我正在构建项目并查看信息消息:在此处输入图像描述但未生成类。如果我在主方法的主类中运行生成代码一切正常!我做错了吗?

4

0 回答 0