public void buildClass(BuilderASTTransformation transform, ClassNode buildee, AnnotationNode anno) { List<String> excludes = new ArrayList<String>(); List<String> includes = new ArrayList<String>(); includes.add(Undefined.STRING); if (!getIncludeExclude(transform, anno, buildee, excludes, includes)) return; if (includes.size() == 1 && Undefined.isUndefined(includes.get(0))) includes = null; ClassNode builder = createBuilder(anno, buildee); createBuilderFactoryMethod(anno, buildee, builder); // List<FieldNode> fields = getFields(transform, anno, buildee); boolean allNames = transform.memberHasValue(anno, "allNames", true); boolean allProperties = !transform.memberHasValue(anno, "allProperties", false); List<PropertyInfo> props = getPropertyInfos(transform, anno, buildee, excludes, includes, allNames, allProperties); for (PropertyInfo pi : props) { ClassNode correctedType = getCorrectedType(buildee, pi.getType(), builder); String fieldName = pi.getName(); builder.addField(createFieldCopy(buildee, fieldName, correctedType)); builder.addMethod(createBuilderMethodForProp(builder, new PropertyInfo(fieldName, correctedType), getPrefix(anno))); } builder.addMethod(createBuildMethod(anno, buildee, props)); }
protected List<PropertyInfo> getPropertyInfoFromClassNode(BuilderASTTransformation transform, AnnotationNode anno, ClassNode cNode, List<String> includes, List<String> excludes, boolean allNames, boolean allProperties) { List<PropertyInfo> props = new ArrayList<PropertyInfo>(); List<String> seen = new ArrayList<String>(); for (PropertyNode pNode : BeanUtils.getAllProperties(cNode, false, false, allProperties)) { if (shouldSkip(pNode.getName(), excludes, includes, allNames)) continue; props.add(new PropertyInfo(pNode.getName(), pNode.getType())); seen.add(pNode.getName()); } for (FieldNode fNode : getFields(transform, anno, cNode)) { if (seen.contains(fNode.getName()) || shouldSkip(fNode.getName(), excludes, includes, allNames)) continue; props.add(new PropertyInfo(fNode.getName(), fNode.getType())); } return props; }
public void buildMethod(BuilderASTTransformation transform, MethodNode mNode, AnnotationNode anno) { if (transform.getMemberValue(anno, "includes") != null || transform.getMemberValue(anno, "excludes") != null) { transform.addError("Error during " + BuilderASTTransformation.MY_TYPE_NAME + " processing: includes/excludes only allowed on classes", anno); } ClassNode buildee = mNode.getDeclaringClass(); ClassNode builder = createBuilder(anno, buildee); createBuilderFactoryMethod(anno, buildee, builder); for (Parameter parameter : mNode.getParameters()) { builder.addField(createFieldCopy(buildee, parameter)); builder.addMethod(createBuilderMethodForProp(builder, new PropertyInfo(parameter.getName(), parameter.getType()), getPrefix(anno))); } builder.addMethod(createBuildMethodForMethod(anno, buildee, mNode, mNode.getParameters())); }
protected static List<PropertyInfo> getPropertyInfoFromBeanInfo(ClassNode cNode, List<String> includes, List<String> excludes, boolean allNames) { final List<PropertyInfo> result = new ArrayList<PropertyInfo>(); try { BeanInfo beanInfo = Introspector.getBeanInfo(cNode.getTypeClass()); for (PropertyDescriptor descriptor : beanInfo.getPropertyDescriptors()) { if (shouldSkipUndefinedAware(descriptor.getName(), excludes, includes, allNames)) continue; // skip hidden and read-only props if (descriptor.isHidden() || descriptor.getWriteMethod() == null) continue; result.add(new PropertyInfo(descriptor.getName(), ClassHelper.make(descriptor.getPropertyType()))); } } catch (IntrospectionException ignore) { } return result; }
private static Expression initializeInstance(ClassNode buildee, List<PropertyInfo> props, BlockStatement body) { Expression instance = varX("_the" + buildee.getNameWithoutPackage(), buildee); body.addStatement(declS(instance, ctorX(buildee))); for (PropertyInfo pi : props) { body.addStatement(stmt(assignX(propX(instance, pi.getName()), varX(pi.getName(), pi.getType())))); } return instance; } }
protected void checkKnownProperty(BuilderASTTransformation transform, AnnotationNode anno, String name, List<PropertyInfo> properties) { for (PropertyInfo prop: properties) { if (name.equals(prop.getName())) { return; } } transform.addError("Error during " + MY_TYPE_NAME + " processing: tried to include unknown property '" + name + "'", anno); }
private MethodNode createBuilderMethodForField(ClassNode builderClass, PropertyInfo prop, String prefix) { String propName = prop.getName().equals("class") ? "clazz" : prop.getName(); String setterName = getSetterName(prefix, prop.getName()); return new MethodNode(setterName, ACC_PUBLIC, newClass(builderClass), params(param(newClass(prop.getType()), propName)), NO_EXCEPTIONS, block( stmt(assignX(propX(varX("this"), constX(propName)), varX(propName))), returnS(varX("this", newClass(builderClass))) )); }
protected static List<PropertyInfo> getPropertyInfoFromClassNode(ClassNode cNode, List<String> includes, List<String> excludes, boolean allNames) { List<PropertyInfo> props = new ArrayList<PropertyInfo>(); for (FieldNode fNode : getInstancePropertyFields(cNode)) { if (shouldSkip(fNode.getName(), excludes, includes, allNames)) continue; props.add(new PropertyInfo(fNode.getName(), fNode.getType())); } return props; }
private MethodNode createBuilderMethodForProp(ClassNode builder, PropertyInfo pinfo, String prefix) { ClassNode fieldType = pinfo.getType(); String fieldName = pinfo.getName(); String setterName = getSetterName(prefix, fieldName); return new MethodNode(setterName, ACC_PUBLIC, newClass(builder), params(param(fieldType, fieldName)), NO_EXCEPTIONS, block( stmt(assignX(propX(varX("this"), constX(fieldName)), varX(fieldName, fieldType))), returnS(varX("this", builder)) )); }
private static Expression initializeInstance(ClassNode sourceClass, List<PropertyInfo> props, BlockStatement body) { Expression instance = varX("_the" + sourceClass.getNameWithoutPackage(), sourceClass); body.addStatement(declS(instance, ctorX(sourceClass))); for (PropertyInfo prop : props) { body.addStatement(stmt(assignX(propX(instance, prop.getName()), varX(prop.getName().equals("class") ? "clazz" : prop.getName(), newClass(prop.getType()))))); } return instance; }