use of butterknife.BindViews in project butterknife by JakeWharton.
the class ButterKnifeProcessor method findAndParseTargets.
private Map<TypeElement, BindingSet> findAndParseTargets(RoundEnvironment env) {
Map<TypeElement, BindingSet.Builder> builderMap = new LinkedHashMap<>();
Set<TypeElement> erasedTargetNames = new LinkedHashSet<>();
scanForRClasses(env);
// Process each @BindAnim element.
for (Element element : env.getElementsAnnotatedWith(BindAnim.class)) {
if (!SuperficialValidation.validateElement(element))
continue;
try {
parseResourceAnimation(element, builderMap, erasedTargetNames);
} catch (Exception e) {
logParsingError(element, BindAnim.class, e);
}
}
// Process each @BindArray element.
for (Element element : env.getElementsAnnotatedWith(BindArray.class)) {
if (!SuperficialValidation.validateElement(element))
continue;
try {
parseResourceArray(element, builderMap, erasedTargetNames);
} catch (Exception e) {
logParsingError(element, BindArray.class, e);
}
}
// Process each @BindBitmap element.
for (Element element : env.getElementsAnnotatedWith(BindBitmap.class)) {
if (!SuperficialValidation.validateElement(element))
continue;
try {
parseResourceBitmap(element, builderMap, erasedTargetNames);
} catch (Exception e) {
logParsingError(element, BindBitmap.class, e);
}
}
// Process each @BindBool element.
for (Element element : env.getElementsAnnotatedWith(BindBool.class)) {
if (!SuperficialValidation.validateElement(element))
continue;
try {
parseResourceBool(element, builderMap, erasedTargetNames);
} catch (Exception e) {
logParsingError(element, BindBool.class, e);
}
}
// Process each @BindColor element.
for (Element element : env.getElementsAnnotatedWith(BindColor.class)) {
if (!SuperficialValidation.validateElement(element))
continue;
try {
parseResourceColor(element, builderMap, erasedTargetNames);
} catch (Exception e) {
logParsingError(element, BindColor.class, e);
}
}
// Process each @BindDimen element.
for (Element element : env.getElementsAnnotatedWith(BindDimen.class)) {
if (!SuperficialValidation.validateElement(element))
continue;
try {
parseResourceDimen(element, builderMap, erasedTargetNames);
} catch (Exception e) {
logParsingError(element, BindDimen.class, e);
}
}
// Process each @BindDrawable element.
for (Element element : env.getElementsAnnotatedWith(BindDrawable.class)) {
if (!SuperficialValidation.validateElement(element))
continue;
try {
parseResourceDrawable(element, builderMap, erasedTargetNames);
} catch (Exception e) {
logParsingError(element, BindDrawable.class, e);
}
}
// Process each @BindFloat element.
for (Element element : env.getElementsAnnotatedWith(BindFloat.class)) {
if (!SuperficialValidation.validateElement(element))
continue;
try {
parseResourceFloat(element, builderMap, erasedTargetNames);
} catch (Exception e) {
logParsingError(element, BindFloat.class, e);
}
}
// Process each @BindFont element.
for (Element element : env.getElementsAnnotatedWith(BindFont.class)) {
if (!SuperficialValidation.validateElement(element))
continue;
try {
parseResourceFont(element, builderMap, erasedTargetNames);
} catch (Exception e) {
logParsingError(element, BindFont.class, e);
}
}
// Process each @BindInt element.
for (Element element : env.getElementsAnnotatedWith(BindInt.class)) {
if (!SuperficialValidation.validateElement(element))
continue;
try {
parseResourceInt(element, builderMap, erasedTargetNames);
} catch (Exception e) {
logParsingError(element, BindInt.class, e);
}
}
// Process each @BindString element.
for (Element element : env.getElementsAnnotatedWith(BindString.class)) {
if (!SuperficialValidation.validateElement(element))
continue;
try {
parseResourceString(element, builderMap, erasedTargetNames);
} catch (Exception e) {
logParsingError(element, BindString.class, e);
}
}
// Process each @BindView element.
for (Element element : env.getElementsAnnotatedWith(BindView.class)) {
// so that an unresolved View type can be generated by later processing rounds
try {
parseBindView(element, builderMap, erasedTargetNames);
} catch (Exception e) {
logParsingError(element, BindView.class, e);
}
}
// Process each @BindViews element.
for (Element element : env.getElementsAnnotatedWith(BindViews.class)) {
// so that an unresolved View type can be generated by later processing rounds
try {
parseBindViews(element, builderMap, erasedTargetNames);
} catch (Exception e) {
logParsingError(element, BindViews.class, e);
}
}
// Process each annotation that corresponds to a listener.
for (Class<? extends Annotation> listener : LISTENERS) {
findAndParseListener(env, listener, builderMap, erasedTargetNames);
}
// Associate superclass binders with their subclass binders. This is a queue-based tree walk
// which starts at the roots (superclasses) and walks to the leafs (subclasses).
Deque<Map.Entry<TypeElement, BindingSet.Builder>> entries = new ArrayDeque<>(builderMap.entrySet());
Map<TypeElement, BindingSet> bindingMap = new LinkedHashMap<>();
while (!entries.isEmpty()) {
Map.Entry<TypeElement, BindingSet.Builder> entry = entries.removeFirst();
TypeElement type = entry.getKey();
BindingSet.Builder builder = entry.getValue();
TypeElement parentType = findParentType(type, erasedTargetNames);
if (parentType == null) {
bindingMap.put(type, builder.build());
} else {
BindingSet parentBinding = bindingMap.get(parentType);
if (parentBinding != null) {
builder.setParent(parentBinding);
bindingMap.put(type, builder.build());
} else {
// Has a superclass binding but we haven't built it yet. Re-enqueue for later.
entries.addLast(entry);
}
}
}
return bindingMap;
}
use of butterknife.BindViews in project AndroidLife by CaMnter.
the class ButterKnifeProcessor method findAndParseTargets.
/**
* 1.扫描 R class,并解析
* 2.SuperficialValidation.validateElement(...) google auto 验证 javax Element
* 3.处理 @BindArray
* 4.处理 @BindBitmap
* 5.处理 @BindBool
* 6.处理 @BindColor
* 7.处理 @BindDimen
* 8.处理 @BindDrawable
* 9.处理 @BindFloat
* 10.处理 @BindInt
* 11.处理 @BindString
* 12.处理 @BindView
* 13.处理 @BindViews
* 14.处理事件( @OnCheckedChanged, @OnClick, @OnEditorAction, @OnFocusChange, @OnItemClick 等)
* 15.BindingSet.Builder Map 缓存生成 BindingSet Map 缓存
*
* @param env RoundEnvironment
* @return Map
*/
private Map<TypeElement, BindingSet> findAndParseTargets(RoundEnvironment env) {
Map<TypeElement, BindingSet.Builder> builderMap = new LinkedHashMap<>();
Set<TypeElement> erasedTargetNames = new LinkedHashSet<>();
// TODO Mark 1
scanForRClasses(env);
// Process each @BindArray element.
for (Element element : env.getElementsAnnotatedWith(BindArray.class)) {
if (!SuperficialValidation.validateElement(element))
continue;
try {
parseResourceArray(element, builderMap, erasedTargetNames);
} catch (Exception e) {
logParsingError(element, BindArray.class, e);
}
}
// Process each @BindBitmap element.
for (Element element : env.getElementsAnnotatedWith(BindBitmap.class)) {
if (!SuperficialValidation.validateElement(element))
continue;
try {
parseResourceBitmap(element, builderMap, erasedTargetNames);
} catch (Exception e) {
logParsingError(element, BindBitmap.class, e);
}
}
// Process each @BindBool element.
for (Element element : env.getElementsAnnotatedWith(BindBool.class)) {
if (!SuperficialValidation.validateElement(element))
continue;
try {
parseResourceBool(element, builderMap, erasedTargetNames);
} catch (Exception e) {
logParsingError(element, BindBool.class, e);
}
}
// Process each @BindColor element.
for (Element element : env.getElementsAnnotatedWith(BindColor.class)) {
if (!SuperficialValidation.validateElement(element))
continue;
try {
parseResourceColor(element, builderMap, erasedTargetNames);
} catch (Exception e) {
logParsingError(element, BindColor.class, e);
}
}
// Process each @BindDimen element.
for (Element element : env.getElementsAnnotatedWith(BindDimen.class)) {
if (!SuperficialValidation.validateElement(element))
continue;
try {
parseResourceDimen(element, builderMap, erasedTargetNames);
} catch (Exception e) {
logParsingError(element, BindDimen.class, e);
}
}
// Process each @BindDrawable element.
for (Element element : env.getElementsAnnotatedWith(BindDrawable.class)) {
if (!SuperficialValidation.validateElement(element))
continue;
try {
parseResourceDrawable(element, builderMap, erasedTargetNames);
} catch (Exception e) {
logParsingError(element, BindDrawable.class, e);
}
}
// Process each @BindFloat element.
for (Element element : env.getElementsAnnotatedWith(BindFloat.class)) {
if (!SuperficialValidation.validateElement(element))
continue;
try {
parseResourceFloat(element, builderMap, erasedTargetNames);
} catch (Exception e) {
logParsingError(element, BindFloat.class, e);
}
}
// Process each @BindInt element.
for (Element element : env.getElementsAnnotatedWith(BindInt.class)) {
if (!SuperficialValidation.validateElement(element))
continue;
try {
parseResourceInt(element, builderMap, erasedTargetNames);
} catch (Exception e) {
logParsingError(element, BindInt.class, e);
}
}
// Process each @BindString element.
for (Element element : env.getElementsAnnotatedWith(BindString.class)) {
if (!SuperficialValidation.validateElement(element))
continue;
try {
parseResourceString(element, builderMap, erasedTargetNames);
} catch (Exception e) {
logParsingError(element, BindString.class, e);
}
}
// Process each @BindView element.
for (Element element : env.getElementsAnnotatedWith(BindView.class)) {
// so that an unresolved View type can be generated by later processing rounds
try {
parseBindView(element, builderMap, erasedTargetNames);
} catch (Exception e) {
logParsingError(element, BindView.class, e);
}
}
// Process each @BindViews element.
for (Element element : env.getElementsAnnotatedWith(BindViews.class)) {
// so that an unresolved View type can be generated by later processing rounds
try {
parseBindViews(element, builderMap, erasedTargetNames);
} catch (Exception e) {
logParsingError(element, BindViews.class, e);
}
}
// Process each annotation that corresponds to a listener.
for (Class<? extends Annotation> listener : LISTENERS) {
findAndParseListener(env, listener, builderMap, erasedTargetNames);
}
/*
* TODO Mark 2
*
* 1.遍历 BindingSet.Builder Map 缓存
* 2.拿到每个 .java 元素 和其对应的 BindingSet.Builder 缓存
* 3.寻找 .java 元素的父类型元素
* - 不存在的话,就直接构建
* - 存在的话,查看父类型的 Builder 缓存。有的话,设置 Parent,开始构建。没有的话,放入 BindingSet.Builder 缓存 的末尾
* 4.构建后的数据,会生成 BindingSet Map 缓存
*/
// Associate superclass binders with their subclass binders. This is a queue-based tree walk
// which starts at the roots (superclasses) and walks to the leafs (subclasses).
Deque<Map.Entry<TypeElement, BindingSet.Builder>> entries = new ArrayDeque<>(builderMap.entrySet());
Map<TypeElement, BindingSet> bindingMap = new LinkedHashMap<>();
while (!entries.isEmpty()) {
Map.Entry<TypeElement, BindingSet.Builder> entry = entries.removeFirst();
TypeElement type = entry.getKey();
BindingSet.Builder builder = entry.getValue();
TypeElement parentType = findParentType(type, erasedTargetNames);
if (parentType == null) {
bindingMap.put(type, builder.build());
} else {
BindingSet parentBinding = bindingMap.get(parentType);
if (parentBinding != null) {
builder.setParent(parentBinding);
bindingMap.put(type, builder.build());
} else {
// Has a superclass binding but we haven't built it yet. Re-enqueue for later.
entries.addLast(entry);
}
}
}
return bindingMap;
}
use of butterknife.BindViews in project AndroidLife by CaMnter.
the class ButterKnifeProcessor method parseBindViews.
/**
* 解析 BindViews
*
* 1.拿到 BindArray 注解元素 的 .java 类元素
* 2.检查注解使用错误,或者注解所在的环境问题( 比如 private or static,所在的 .java 是 private 等 )
* - 有错误就 return
* 3.获取元素的类型
* 4.校验是否是 Array 或者 List,不是则报错返回
* 5.校验元素类型( 不是 View 的子类,并且不是接口类型 ),报错返回
* 6.获取该 .java 元素对应的 BindingSet.Builder,没有则创建
* 7.注解中抽出一组 Id,校验是否有重复 id
* 8.包装成 FieldCollectionViewBinding 添加到 BindingSet.Builder
* 9.记录 .java 元素 为要删除的目录
*
* @param element BindBitmap 注解元素
* @param builderMap BindingSet.Builder 缓存 Map
* @param erasedTargetNames 要删除元素的目录,存在的是 .java 的元素
*/
private void parseBindViews(Element element, Map<TypeElement, BindingSet.Builder> builderMap, Set<TypeElement> erasedTargetNames) {
TypeElement enclosingElement = (TypeElement) element.getEnclosingElement();
// Start by verifying common generated code restrictions.
boolean hasError = isInaccessibleViaGeneratedCode(BindViews.class, "fields", element) || isBindingInWrongPackage(BindViews.class, element);
// Verify that the type is a List or an array.
TypeMirror elementType = element.asType();
String erasedType = doubleErasure(elementType);
TypeMirror viewType = null;
FieldCollectionViewBinding.Kind kind = null;
if (elementType.getKind() == TypeKind.ARRAY) {
ArrayType arrayType = (ArrayType) elementType;
viewType = arrayType.getComponentType();
kind = FieldCollectionViewBinding.Kind.ARRAY;
} else if (LIST_TYPE.equals(erasedType)) {
DeclaredType declaredType = (DeclaredType) elementType;
List<? extends TypeMirror> typeArguments = declaredType.getTypeArguments();
if (typeArguments.size() != 1) {
error(element, "@%s List must have a generic component. (%s.%s)", BindViews.class.getSimpleName(), enclosingElement.getQualifiedName(), element.getSimpleName());
hasError = true;
} else {
viewType = typeArguments.get(0);
}
kind = FieldCollectionViewBinding.Kind.LIST;
} else {
error(element, "@%s must be a List or array. (%s.%s)", BindViews.class.getSimpleName(), enclosingElement.getQualifiedName(), element.getSimpleName());
hasError = true;
}
if (viewType != null && viewType.getKind() == TypeKind.TYPEVAR) {
TypeVariable typeVariable = (TypeVariable) viewType;
viewType = typeVariable.getUpperBound();
}
// Verify that the target type extends from View.
if (viewType != null && !isSubtypeOfType(viewType, VIEW_TYPE) && !isInterface(viewType)) {
if (viewType.getKind() == TypeKind.ERROR) {
note(element, "@%s List or array with unresolved type (%s) " + "must elsewhere be generated as a View or interface. (%s.%s)", BindViews.class.getSimpleName(), viewType, enclosingElement.getQualifiedName(), element.getSimpleName());
} else {
error(element, "@%s List or array type must extend from View or be an interface. (%s.%s)", BindViews.class.getSimpleName(), enclosingElement.getQualifiedName(), element.getSimpleName());
hasError = true;
}
}
// Assemble information on the field.
String name = element.getSimpleName().toString();
int[] ids = element.getAnnotation(BindViews.class).value();
if (ids.length == 0) {
error(element, "@%s must specify at least one ID. (%s.%s)", BindViews.class.getSimpleName(), enclosingElement.getQualifiedName(), element.getSimpleName());
hasError = true;
}
Integer duplicateId = findDuplicate(ids);
if (duplicateId != null) {
error(element, "@%s annotation contains duplicate ID %d. (%s.%s)", BindViews.class.getSimpleName(), duplicateId, enclosingElement.getQualifiedName(), element.getSimpleName());
hasError = true;
}
if (hasError) {
return;
}
// Always false as hasError would have been true.
assert viewType != null;
TypeName type = TypeName.get(viewType);
boolean required = isFieldRequired(element);
List<Id> idVars = new ArrayList<>();
for (int id : ids) {
QualifiedId qualifiedId = elementToQualifiedId(element, id);
idVars.add(getId(qualifiedId));
}
BindingSet.Builder builder = getOrCreateBindingBuilder(builderMap, enclosingElement);
builder.addFieldCollection(new FieldCollectionViewBinding(name, type, kind, idVars, required));
erasedTargetNames.add(enclosingElement);
}
Aggregations