我有简单的注释处理器。
@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();
}
}
}
但这不起作用!在另一个项目中,我正在构建项目并查看信息消息:但未生成类。如果我在主方法的主类中运行生成代码一切正常!我做错了吗?