package com.ccccc.annotationcompile;
import com.ccccc.zpannotations.Constants;
import com.ccccc.zpannotations.ZpBindView;
import com.ccccc.zpannotations.eventbus.AnnotationScanResultBean;
import com.ccccc.zpannotations.eventbus.BindMethod;
import com.google.auto.service.AutoService;
import com.google.gson.Gson;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeMirror;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
@AutoService(Processor.class)
public class ZpAnnotationCompile extends AbstractProcessor {
String TAG = "ZpAnnotationCompile";
//3.定义一个用来生成APT目录下面的文件的对象
Filer filer;
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
print("init");
filer = processingEnv.getFiler();
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
@Override
public Set<String> getSupportedAnnotationTypes() {
Set<String> types = new HashSet<>();
types.add(ZpBindView.class.getCanonicalName());
types.add(BindMethod.class.getCanonicalName());
// types.add(Override.class.getCanonicalName());
return types;
}
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
print("process");
Set<? extends Element> elementsAnnotatedWith = roundEnvironment.getElementsAnnotatedWith(ZpBindView.class);
Set<? extends Element> bindMethodSet = roundEnvironment.getElementsAnnotatedWith(BindMethod.class);
parserBindMethod(bindMethodSet);
// TypeElement//类
// ExecutableElement//方法
// VariableElement//属性
// 开始对elementsAnnotatedWith进行分类
Map<String, List<VariableElement>> map = new HashMap<>();
for (Element ele : elementsAnnotatedWith) {
VariableElement variableElement = (VariableElement) ele;
String activityName = variableElement.getEnclosingElement().getSimpleName().toString();
Class aClass = variableElement.getEnclosingElement().getClass();
print("activityName=" + activityName);
print("aClass=" + aClass);
List<VariableElement> variableElements = map.get(activityName);
if (variableElements == null) {
variableElements = new ArrayList<>();
map.put(activityName, variableElements);
}
variableElements.add(variableElement);
}
if (map.size() > 0) {
Writer writer = null;
Iterator<String> iterator = map.keySet().iterator();
while (iterator.hasNext()) {
String activityName = iterator.next();
List<VariableElement> variableElements = map.get(activityName);
//得到包名
TypeElement enclosingElement = (TypeElement) variableElements.get(0).getEnclosingElement();
String packageName = processingEnv.getElementUtils().getPackageOf(enclosingElement).toString();
try {
JavaFileObject sourceFile = filer.createSourceFile(packageName + "." + activityName + Constants.BIND_VIEW_LAST_NAME);
writer = sourceFile.openWriter();
// package com.example.dn_butterknife;
writer.write("package " + packageName + ";\n");
// import com.example.dn_butterknife.IBinder;
writer.write("import com.ccccc.zpannotations.IBinder;\n");
// public class MainActivity_ViewBinding implements IBinder<
// com.example.dn_butterknife.MainActivity>{
writer.write("public class " + activityName + Constants.BIND_VIEW_LAST_NAME + " implements IBinder<" +
packageName + "." + activityName + ">{\n");
// public void bind(com.example.dn_butterknife.MainActivity target) {
writer.write(" @Override\n" +
" public void bind(" + packageName + "." + activityName + " target){\n");
//target.tvText=(android.widget.TextView)target.findViewById(2131165325);
for (VariableElement variableElement : variableElements) {
//得到名字
String variableName = variableElement.getSimpleName().toString();
//得到ID
int id = variableElement.getAnnotation(ZpBindView.class).value();
//得到类型
TypeMirror typeMirror = variableElement.asType();
writer.write(" target." + variableName + "=(" + typeMirror + ")target.findViewById(" + id + ");\n");
}
writer.write(" }\n}");
} catch (Exception e) {
e.printStackTrace();
} finally {
if (writer != null) {
try {
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
return false;
}
private void parserBindMethod(Set<? extends Element> bindMethodSet) {
Map<String, List<AnnotationScanResultBean>> map = new HashMap<>();
Writer writer = null;
String tempPackageName = "";
for (Element ele : bindMethodSet) {
String activityName = ele.getEnclosingElement().getSimpleName().toString();
List<AnnotationScanResultBean> methodElements = map.get(activityName);
if (methodElements == null) {
methodElements = new ArrayList<>();
map.put(activityName, methodElements);
}
AnnotationScanResultBean bean = new AnnotationScanResultBean();
String packageName = processingEnv.getElementUtils().getPackageOf(ele).toString();
tempPackageName = packageName;
String methodName = ele.getSimpleName().toString();
bean.setPackageName(packageName);
bean.setActivityName(activityName);
bean.setMethodName(methodName);
BindMethod annotation = ele.getAnnotation(BindMethod.class);
bean.setBindMethodEventKey(annotation.eventKey());
bean.setBindMethodthreadMode(annotation.threadMode());
methodElements.add(bean);
// print("parserBindMethod ele methoName= " + ele.getSimpleName());
// print("parserBindMethod ele = " + ele.getEnclosingElement().getSimpleName().toString());
// print("parserBindMethod ele1 = " + ele.getAnnotation(BindMethod.class));
// print("parserBindMethod ele2 = " + ele.getAnnotation(BindMethod.class).eventKey());
// print("parserBindMethod ele3 = " + ele.getAnnotation(BindMethod.class).threadMode());
// print("parserBindMethod ele4 = " + ele.getClass().getName());
//
// String packageName = processingEnv.getElementUtils().getPackageOf(ele).toString();
// print("parse