use of javax.lang.model.element.Element in project epoxy by airbnb.
the class ProcessorUtils method isSubtypeOfType.
static boolean isSubtypeOfType(TypeMirror typeMirror, String otherType) {
if (otherType.equals(typeMirror.toString())) {
return true;
}
if (typeMirror.getKind() != TypeKind.DECLARED) {
return false;
}
DeclaredType declaredType = (DeclaredType) typeMirror;
List<? extends TypeMirror> typeArguments = declaredType.getTypeArguments();
if (typeArguments.size() > 0) {
StringBuilder typeString = new StringBuilder(declaredType.asElement().toString());
typeString.append('<');
for (int i = 0; i < typeArguments.size(); i++) {
if (i > 0) {
typeString.append(',');
}
typeString.append('?');
}
typeString.append('>');
if (typeString.toString().equals(otherType)) {
return true;
}
}
Element element = declaredType.asElement();
if (!(element instanceof TypeElement)) {
return false;
}
TypeElement typeElement = (TypeElement) element;
TypeMirror superType = typeElement.getSuperclass();
if (isSubtypeOfType(superType, otherType)) {
return true;
}
for (TypeMirror interfaceType : typeElement.getInterfaces()) {
if (isSubtypeOfType(interfaceType, otherType)) {
return true;
}
}
return false;
}
use of javax.lang.model.element.Element in project epoxy by airbnb.
the class ResourceProcessor method processorResources.
void processorResources(RoundEnvironment env) {
resources.clear();
if (trees == null) {
return;
}
RClassScanner scanner = new RClassScanner();
for (Class<? extends Annotation> annotation : EpoxyProcessor.getSupportedAnnotations()) {
for (Element element : env.getElementsAnnotatedWith(annotation)) {
JCTree tree = (JCTree) trees.getTree(element, getMirror(element, annotation));
if (tree != null) {
// tree can be null if the references are compiled types and not source
tree.accept(scanner);
}
}
}
for (String rClass : scanner.getRClasses()) {
parseRClass(rClass, resources);
}
}
use of javax.lang.model.element.Element in project epoxy by airbnb.
the class ConfigManager method processConfigurations.
List<Exception> processConfigurations(RoundEnvironment roundEnv) {
configurationMap.clear();
Set<? extends Element> annotatedElements = roundEnv.getElementsAnnotatedWith(PackageEpoxyConfig.class);
List<Exception> errors = new ArrayList<>();
for (Element element : annotatedElements) {
String packageName = elementUtils.getPackageOf(element).getQualifiedName().toString();
if (configurationMap.containsKey(packageName)) {
errors.add(buildEpoxyException("Only one Epoxy configuration annotation is allowed per package (%s)", packageName));
}
PackageEpoxyConfig annotation = element.getAnnotation(PackageEpoxyConfig.class);
configurationMap.put(packageName, PackageConfigSettings.create(annotation));
}
return errors;
}
use of javax.lang.model.element.Element in project ARouter by alibaba.
the class AutowiredProcessor method generateHelper.
private void generateHelper() throws IOException, IllegalAccessException {
TypeElement type_ISyringe = elements.getTypeElement(ISYRINGE);
TypeMirror iProvider = elements.getTypeElement(Consts.IPROVIDER).asType();
TypeMirror activityTm = elements.getTypeElement(Consts.ACTIVITY).asType();
TypeMirror fragmentTm = elements.getTypeElement(Consts.FRAGMENT).asType();
TypeMirror fragmentTmV4 = elements.getTypeElement(Consts.FRAGMENT_V4).asType();
// Build input param name.
ParameterSpec objectParamSpec = ParameterSpec.builder(TypeName.OBJECT, "target").build();
if (MapUtils.isNotEmpty(parentAndChild)) {
for (Map.Entry<TypeElement, List<Element>> entry : parentAndChild.entrySet()) {
// Build method : 'inject'
MethodSpec.Builder injectMethodBuilder = MethodSpec.methodBuilder(METHOD_INJECT).addAnnotation(Override.class).addModifiers(PUBLIC).addParameter(objectParamSpec);
TypeElement parent = entry.getKey();
List<Element> childs = entry.getValue();
String qualifiedName = parent.getQualifiedName().toString();
String packageName = qualifiedName.substring(0, qualifiedName.lastIndexOf("."));
String fileName = parent.getSimpleName() + NAME_OF_AUTOWIRED;
logger.info(">>> Start process " + childs.size() + " field in " + parent.getSimpleName() + " ... <<<");
injectMethodBuilder.addStatement("$T substitute = ($T)target", ClassName.get(parent), ClassName.get(parent));
// Generate method body, start inject.
for (Element element : childs) {
Autowired fieldConfig = element.getAnnotation(Autowired.class);
String fieldName = element.getSimpleName().toString();
if (types.isSubtype(element.asType(), iProvider)) {
// It's provider
if ("".equals(fieldConfig.name())) {
// User has not set service path, then use byType.
// Getter
injectMethodBuilder.addStatement("substitute." + fieldName + " = $T.getInstance().navigation($T.class)", ARouterClass, ClassName.get(element.asType()));
} else {
// use byName
// Getter
injectMethodBuilder.addStatement("substitute." + fieldName + " = ($T)$T.getInstance().build($S).navigation();", ClassName.get(element.asType()), ARouterClass, fieldConfig.name());
}
// Validater
if (fieldConfig.required()) {
injectMethodBuilder.beginControlFlow("if (substitute." + fieldName + " == null)");
injectMethodBuilder.addStatement("throw new RuntimeException(\"The field '" + fieldName + "' is null, in class '\" + $T.class.getName() + \"!\")", ClassName.get(parent));
injectMethodBuilder.endControlFlow();
}
} else {
// It's normal intent value
String statment = "substitute." + fieldName + " = substitute.";
boolean isActivity = false;
if (types.isSubtype(parent.asType(), activityTm)) {
// Activity, then use getIntent()
isActivity = true;
statment += "getIntent().";
} else if (types.isSubtype(parent.asType(), fragmentTm) || types.isSubtype(parent.asType(), fragmentTmV4)) {
// Fragment, then use getArguments()
statment += "getArguments().";
} else {
throw new IllegalAccessException("The field [" + fieldName + "] need autowired from intent, its parent must be activity or fragment!");
}
statment = buildStatement(statment, typeUtils.typeExchange(element), isActivity);
if (statment.startsWith("$T.")) {
// Not mortals
injectMethodBuilder.addStatement("substitute." + fieldName + " = " + statment, JsonClass, (StringUtils.isEmpty(fieldConfig.name()) ? fieldName : fieldConfig.name()), ClassName.get(element.asType()));
} else {
injectMethodBuilder.addStatement(statment, StringUtils.isEmpty(fieldConfig.name()) ? fieldName : fieldConfig.name());
}
// Validater
if (fieldConfig.required() && !element.asType().getKind().isPrimitive()) {
// Primitive wont be check.
injectMethodBuilder.beginControlFlow("if (substitute." + fieldName + " == null)");
injectMethodBuilder.addStatement("throw new RuntimeException(\"The field '" + fieldName + "' is null, in class '\" + $T.class.getName() + \"!\")", ClassName.get(parent));
injectMethodBuilder.endControlFlow();
}
}
}
// Generate autowired helper
JavaFile.builder(packageName, TypeSpec.classBuilder(fileName).addJavadoc(WARNING_TIPS).addSuperinterface(ClassName.get(type_ISyringe)).addModifiers(PUBLIC).addMethod(injectMethodBuilder.build()).build()).build().writeTo(mFiler);
logger.info(">>> " + parent.getSimpleName() + " has been processed, " + fileName + " has been generated. <<<");
}
logger.info(">>> Autowired processor stop. <<<");
}
}
use of javax.lang.model.element.Element in project ARouter by alibaba.
the class RouteProcessor method parseRoutes.
private void parseRoutes(Set<? extends Element> routeElements) throws IOException {
if (CollectionUtils.isNotEmpty(routeElements)) {
// Perpare the type an so on.
logger.info(">>> Found routes, size is " + routeElements.size() + " <<<");
rootMap.clear();
TypeMirror type_Activity = elements.getTypeElement(ACTIVITY).asType();
TypeMirror type_Service = elements.getTypeElement(SERVICE).asType();
TypeElement type_Parcelable = elements.getTypeElement(PARCELABLE);
// Interface of ARouter
TypeElement type_IRouteGroup = elements.getTypeElement(IROUTE_GROUP);
TypeElement type_IProviderGroup = elements.getTypeElement(IPROVIDER_GROUP);
ClassName routeMetaCn = ClassName.get(RouteMeta.class);
ClassName routeTypeCn = ClassName.get(RouteType.class);
/*
Build input type, format as :
```Map<String, Class<? extends IRouteGroup>>```
*/
ParameterizedTypeName inputMapTypeOfRoot = ParameterizedTypeName.get(ClassName.get(Map.class), ClassName.get(String.class), ParameterizedTypeName.get(ClassName.get(Class.class), WildcardTypeName.subtypeOf(ClassName.get(type_IRouteGroup))));
/*
```Map<String, RouteMeta>```
*/
ParameterizedTypeName inputMapTypeOfGroup = ParameterizedTypeName.get(ClassName.get(Map.class), ClassName.get(String.class), ClassName.get(RouteMeta.class));
/*
Build input param name.
*/
ParameterSpec rootParamSpec = ParameterSpec.builder(inputMapTypeOfRoot, "routes").build();
ParameterSpec groupParamSpec = ParameterSpec.builder(inputMapTypeOfGroup, "atlas").build();
// Ps. its param type same as groupParamSpec!
ParameterSpec providerParamSpec = ParameterSpec.builder(inputMapTypeOfGroup, "providers").build();
/*
Build method : 'loadInto'
*/
MethodSpec.Builder loadIntoMethodOfRootBuilder = MethodSpec.methodBuilder(METHOD_LOAD_INTO).addAnnotation(Override.class).addModifiers(PUBLIC).addParameter(rootParamSpec);
// Follow a sequence, find out metas of group first, generate java file, then statistics them as root.
for (Element element : routeElements) {
TypeMirror tm = element.asType();
Route route = element.getAnnotation(Route.class);
RouteMeta routeMete = null;
if (types.isSubtype(tm, type_Activity)) {
// Activity
logger.info(">>> Found activity route: " + tm.toString() + " <<<");
// Get all fields annotation by @Autowired
Map<String, Integer> paramsType = new HashMap<>();
for (Element field : element.getEnclosedElements()) {
if (field.getKind().isField() && field.getAnnotation(Autowired.class) != null && !types.isSubtype(field.asType(), iProvider)) {
// It must be field, then it has annotation, but it not be provider.
Autowired paramConfig = field.getAnnotation(Autowired.class);
paramsType.put(StringUtils.isEmpty(paramConfig.name()) ? field.getSimpleName().toString() : paramConfig.name(), typeUtils.typeExchange(field));
}
}
routeMete = new RouteMeta(route, element, RouteType.ACTIVITY, paramsType);
} else if (types.isSubtype(tm, iProvider)) {
// IProvider
logger.info(">>> Found provider route: " + tm.toString() + " <<<");
routeMete = new RouteMeta(route, element, RouteType.PROVIDER, null);
} else if (types.isSubtype(tm, type_Service)) {
// Service
logger.info(">>> Found service route: " + tm.toString() + " <<<");
routeMete = new RouteMeta(route, element, RouteType.parse(SERVICE), null);
}
categories(routeMete);
// if (StringUtils.isEmpty(moduleName)) { // Hasn't generate the module name.
// moduleName = ModuleUtils.generateModuleName(element, logger);
// }
}
MethodSpec.Builder loadIntoMethodOfProviderBuilder = MethodSpec.methodBuilder(METHOD_LOAD_INTO).addAnnotation(Override.class).addModifiers(PUBLIC).addParameter(providerParamSpec);
// Start generate java source, structure is divided into upper and lower levels, used for demand initialization.
for (Map.Entry<String, Set<RouteMeta>> entry : groupMap.entrySet()) {
String groupName = entry.getKey();
MethodSpec.Builder loadIntoMethodOfGroupBuilder = MethodSpec.methodBuilder(METHOD_LOAD_INTO).addAnnotation(Override.class).addModifiers(PUBLIC).addParameter(groupParamSpec);
// Build group method body
Set<RouteMeta> groupData = entry.getValue();
for (RouteMeta routeMeta : groupData) {
switch(routeMeta.getType()) {
case // Need cache provider's super class
PROVIDER:
List<? extends TypeMirror> interfaces = ((TypeElement) routeMeta.getRawType()).getInterfaces();
for (TypeMirror tm : interfaces) {
if (types.isSubtype(tm, iProvider)) {
// This interface extend the IProvider, so it can be used for mark provider
loadIntoMethodOfProviderBuilder.addStatement("providers.put($S, $T.build($T." + routeMeta.getType() + ", $T.class, $S, $S, null, " + routeMeta.getPriority() + ", " + routeMeta.getExtra() + "))", // Spite unuseless name
tm.toString().substring(tm.toString().lastIndexOf(".") + 1), routeMetaCn, routeTypeCn, ClassName.get((TypeElement) routeMeta.getRawType()), routeMeta.getPath(), routeMeta.getGroup());
}
}
break;
default:
break;
}
// Make map body for paramsType
StringBuilder mapBodyBuilder = new StringBuilder();
Map<String, Integer> paramsType = routeMeta.getParamsType();
if (MapUtils.isNotEmpty(paramsType)) {
for (Map.Entry<String, Integer> types : paramsType.entrySet()) {
mapBodyBuilder.append("put(\"").append(types.getKey()).append("\", ").append(types.getValue()).append("); ");
}
}
String mapBody = mapBodyBuilder.toString();
loadIntoMethodOfGroupBuilder.addStatement("atlas.put($S, $T.build($T." + routeMeta.getType() + ", $T.class, $S, $S, " + (StringUtils.isEmpty(mapBody) ? null : ("new java.util.HashMap<String, Integer>(){{" + mapBodyBuilder.toString() + "}}")) + ", " + routeMeta.getPriority() + ", " + routeMeta.getExtra() + "))", routeMeta.getPath(), routeMetaCn, routeTypeCn, ClassName.get((TypeElement) routeMeta.getRawType()), routeMeta.getPath().toLowerCase(), routeMeta.getGroup().toLowerCase());
}
// Generate groups
String groupFileName = NAME_OF_GROUP + groupName;
JavaFile.builder(PACKAGE_OF_GENERATE_FILE, TypeSpec.classBuilder(groupFileName).addJavadoc(WARNING_TIPS).addSuperinterface(ClassName.get(type_IRouteGroup)).addModifiers(PUBLIC).addMethod(loadIntoMethodOfGroupBuilder.build()).build()).build().writeTo(mFiler);
logger.info(">>> Generated group: " + groupName + "<<<");
rootMap.put(groupName, groupFileName);
}
if (MapUtils.isNotEmpty(rootMap)) {
// Generate root meta by group name, it must be generated before root, then I can findout the class of group.
for (Map.Entry<String, String> entry : rootMap.entrySet()) {
loadIntoMethodOfRootBuilder.addStatement("routes.put($S, $T.class)", entry.getKey(), ClassName.get(PACKAGE_OF_GENERATE_FILE, entry.getValue()));
}
}
// Wirte provider into disk
String providerMapFileName = NAME_OF_PROVIDER + SEPARATOR + moduleName;
JavaFile.builder(PACKAGE_OF_GENERATE_FILE, TypeSpec.classBuilder(providerMapFileName).addJavadoc(WARNING_TIPS).addSuperinterface(ClassName.get(type_IProviderGroup)).addModifiers(PUBLIC).addMethod(loadIntoMethodOfProviderBuilder.build()).build()).build().writeTo(mFiler);
logger.info(">>> Generated provider map, name is " + providerMapFileName + " <<<");
// Write root meta into disk.
String rootFileName = NAME_OF_ROOT + SEPARATOR + moduleName;
JavaFile.builder(PACKAGE_OF_GENERATE_FILE, TypeSpec.classBuilder(rootFileName).addJavadoc(WARNING_TIPS).addSuperinterface(ClassName.get(elements.getTypeElement(ITROUTE_ROOT))).addModifiers(PUBLIC).addMethod(loadIntoMethodOfRootBuilder.build()).build()).build().writeTo(mFiler);
logger.info(">>> Generated root, name is " + rootFileName + " <<<");
}
}
Aggregations