use of com.squareup.javapoet.MethodSpec in project pixel-dungeon-remix by NYRDS.
the class PdAnnotationProcessor method process.
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
Map<Element, Set<Element>> fieldsByClass = new HashMap<>();
Map<Element, String> defaultValues = new HashMap<>();
// for each javax.lang.model.element.Element annotated with the CustomAnnotation
for (Element element : roundEnvironment.getElementsAnnotatedWith(Packable.class)) {
Element parent = element.getEnclosingElement();
String defaultValue = element.getAnnotation(Packable.class).defaultValue();
if (!defaultValue.isEmpty()) {
defaultValues.put(element, defaultValue);
}
if (fieldsByClass.get(parent) == null) {
fieldsByClass.put(parent, new HashSet<Element>());
}
fieldsByClass.get(parent).add(element);
}
TypeSpec BundleHelper = TypeSpec.classBuilder("BundleHelper").addModifiers(Modifier.PUBLIC, Modifier.FINAL).build();
MethodSpec pack = MethodSpec.methodBuilder("Pack").addModifiers(Modifier.PUBLIC, Modifier.STATIC).returns(void.class).addParameter(ClassName.get("com.watabou.utils", "Bundlable"), "arg").addParameter(ClassName.get("com.watabou.utils", "Bundle"), "bundle").beginControlFlow("try").build();
MethodSpec unpack = MethodSpec.methodBuilder("UnPack").addModifiers(Modifier.PUBLIC, Modifier.STATIC).returns(void.class).addParameter(ClassName.get("com.watabou.utils", "Bundlable"), "arg").addParameter(ClassName.get("com.watabou.utils", "Bundle"), "bundle").beginControlFlow("try").build();
for (Element clazz : fieldsByClass.keySet()) {
CodeBlock packerBlock = CodeBlock.builder().beginControlFlow("if(arg instanceof $T)", TypeName.get(clazz.asType())).build();
CodeBlock unpackerBlock = CodeBlock.builder().beginControlFlow("if(arg instanceof $T)", TypeName.get(clazz.asType())).build();
for (Element field : fieldsByClass.get(clazz)) {
String fieldName = field.getSimpleName().toString();
packerBlock = packerBlock.toBuilder().addStatement("$T $L = $T.class.getDeclaredField($S)", Field.class, fieldName, TypeName.get(clazz.asType()), fieldName).addStatement("$L.setAccessible(true)", fieldName).addStatement("bundle.put($S,($T)$L.get(arg))", fieldName, TypeName.get(field.asType()), fieldName).build();
unpackerBlock = unpackerBlock.toBuilder().addStatement("$T $L = $T.class.getDeclaredField($S)", Field.class, fieldName, TypeName.get(clazz.asType()), fieldName).addStatement("$L.setAccessible(true)", fieldName).build();
String fieldType = TypeName.get(field.asType()).toString();
String defaultValue = defaultValues.get(field);
if (fieldType.equals("int")) {
if (defaultValue == null || defaultValue.isEmpty()) {
defaultValue = "0";
}
unpackerBlock = unpackerBlock.toBuilder().addStatement("$L.setInt(arg,bundle.optInt($S,$L))", fieldName, fieldName, defaultValue).build();
continue;
}
if (fieldType.equals("boolean")) {
if (defaultValue == null || defaultValue.isEmpty()) {
defaultValue = "false";
}
unpackerBlock = unpackerBlock.toBuilder().addStatement("$L.setBoolean(arg,bundle.optBoolean($S,$L))", fieldName, fieldName, defaultValue).build();
continue;
}
if (fieldType.equals("float")) {
if (defaultValue == null || defaultValue.isEmpty()) {
defaultValue = "0.0f";
}
unpackerBlock = unpackerBlock.toBuilder().addStatement("$L.setFloat(arg,bundle.optFloat($S,$L))", fieldName, fieldName, defaultValue).build();
continue;
}
if (fieldType.equals("java.lang.String")) {
if (defaultValue == null || defaultValue.isEmpty()) {
defaultValue = "Unknown";
}
unpackerBlock = unpackerBlock.toBuilder().addStatement("$L.set(arg,bundle.optString($S,$S))", fieldName, fieldName, defaultValue).build();
continue;
}
Set<Class<?>> fieldInterfaces = new HashSet<>();
Collections.addAll(fieldInterfaces, field.getClass().getInterfaces());
Set<String> fieldInterfaceNames = new HashSet<>();
for (Class<?> clazzz : fieldInterfaces) {
fieldInterfaceNames.add(clazzz.getSimpleName());
}
/*
if(fieldType.equals("Collection")) {
unpackerBlock = unpackerBlock.toBuilder()
.addStatement("$L.set(arg,bundle.getCollection($S,$S))", fieldName,fieldName,fieldType+".class")
.build();
continue;
}
*/
if (fieldType.equals("Bundlable")) {
unpackerBlock = unpackerBlock.toBuilder().addStatement("($S)$L.set(arg,bundle.get($S))", fieldType + ".class", fieldName, fieldName).build();
continue;
}
}
packerBlock = packerBlock.toBuilder().endControlFlow().build();
unpackerBlock = unpackerBlock.toBuilder().endControlFlow().build();
pack = pack.toBuilder().addCode(packerBlock).build();
unpack = unpack.toBuilder().addCode(unpackerBlock).build();
}
pack = pack.toBuilder().nextControlFlow("catch ($T e)", NoSuchFieldException.class).addStatement("throw new $T(e)", ClassName.get("com.nyrds.android.util", "TrackedRuntimeException")).nextControlFlow("catch ($T e)", IllegalAccessException.class).addStatement("throw new $T(e)", ClassName.get("com.nyrds.android.util", "TrackedRuntimeException")).endControlFlow().build();
unpack = unpack.toBuilder().nextControlFlow("catch ($T e)", NoSuchFieldException.class).addStatement("throw new $T(e)", ClassName.get("com.nyrds.android.util", "TrackedRuntimeException")).nextControlFlow("catch ($T e)", IllegalAccessException.class).addStatement("throw new $T(e)", ClassName.get("com.nyrds.android.util", "TrackedRuntimeException")).endControlFlow().build();
BundleHelper = BundleHelper.toBuilder().addMethod(pack).addMethod(unpack).build();
JavaFile javaFile = JavaFile.builder("com.nyrds.generated", BundleHelper).build();
try {
// write the file
JavaFileObject source = processingEnv.getFiler().createSourceFile("com.nyrds.generated.BundleHelper");
Writer writer = source.openWriter();
javaFile.writeTo(writer);
writer.flush();
writer.close();
} catch (IOException e) {
// Note: calling e.printStackTrace() will print IO errors
// that occur from the file already existing after its first run, this is normal
}
return true;
}
use of com.squareup.javapoet.MethodSpec in project arez by arez.
the class ActionDescriptor method buildAction.
/**
* Generate the action wrapper.
*/
@Nonnull
private MethodSpec buildAction() throws ArezProcessorException {
final MethodSpec.Builder builder = MethodSpec.methodBuilder(_action.getSimpleName().toString());
ProcessorUtil.copyAccessModifiers(_action, builder);
ProcessorUtil.copyExceptions(_actionType, builder);
ProcessorUtil.copyTypeParameters(_actionType, builder);
ProcessorUtil.copyDocumentedAnnotations(_action, builder);
builder.addAnnotation(Override.class);
final TypeMirror returnType = _actionType.getReturnType();
builder.returns(TypeName.get(returnType));
final boolean isProcedure = returnType.getKind() == TypeKind.VOID;
final List<? extends TypeMirror> thrownTypes = _action.getThrownTypes();
final boolean isSafe = thrownTypes.isEmpty();
final StringBuilder statement = new StringBuilder();
final ArrayList<Object> parameterNames = new ArrayList<>();
if (!isProcedure) {
statement.append("return ");
}
statement.append("$N().");
parameterNames.add(_componentDescriptor.getContextMethodName());
if (isProcedure && isSafe) {
statement.append("safeAction");
} else if (isProcedure) {
statement.append("action");
} else if (isSafe) {
statement.append("safeAction");
} else {
statement.append("action");
}
statement.append("(");
statement.append("$T.areNamesEnabled() ? $N() + $S : null");
parameterNames.add(GeneratorUtil.AREZ_CLASSNAME);
parameterNames.add(_componentDescriptor.getComponentNameMethodName());
parameterNames.add("." + getName());
statement.append(", ");
statement.append(_mutation);
statement.append(", () -> super.");
statement.append(_action.getSimpleName());
statement.append("(");
boolean firstParam = true;
final List<? extends VariableElement> parameters = _action.getParameters();
final int paramCount = parameters.size();
for (int i = 0; i < paramCount; i++) {
final VariableElement element = parameters.get(i);
final TypeName parameterType = TypeName.get(_actionType.getParameterTypes().get(i));
final ParameterSpec.Builder param = ParameterSpec.builder(parameterType, element.getSimpleName().toString(), Modifier.FINAL);
ProcessorUtil.copyDocumentedAnnotations(element, param);
builder.addParameter(param.build());
parameterNames.add(element.getSimpleName().toString());
if (!firstParam) {
statement.append(",");
}
firstParam = false;
statement.append("$N");
}
statement.append(")");
if (_reportParameters) {
for (final VariableElement parameter : parameters) {
parameterNames.add(parameter.getSimpleName().toString());
statement.append(", $N");
}
}
statement.append(" )");
GeneratorUtil.generateNotDisposedInvariant(_componentDescriptor, builder);
GeneratorUtil.generateTryBlock(builder, thrownTypes, b -> b.addStatement(statement.toString(), parameterNames.toArray()));
return builder.build();
}
use of com.squareup.javapoet.MethodSpec in project arez by arez.
the class ComponentDescriptor method buildType.
/**
* Build the enhanced class for the component.
*/
@Nonnull
TypeSpec buildType(@Nonnull final Types typeUtils) throws ArezProcessorException {
final TypeSpec.Builder builder = TypeSpec.classBuilder(getArezClassName()).superclass(TypeName.get(getElement().asType())).addTypeVariables(ProcessorUtil.getTypeArgumentsAsNames(asDeclaredType())).addModifiers(Modifier.FINAL);
builder.addAnnotation(AnnotationSpec.builder(Generated.class).addMember("value", "$S", ArezProcessor.class.getName()).build());
if (!_roComputeds.isEmpty()) {
builder.addAnnotation(AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "$S", "unchecked").build());
}
final boolean publicType = ProcessorUtil.getConstructors(getElement()).stream().anyMatch(c -> c.getModifiers().contains(Modifier.PUBLIC)) && getElement().getModifiers().contains(Modifier.PUBLIC);
if (publicType) {
builder.addModifiers(Modifier.PUBLIC);
}
if (null != _scopeAnnotation) {
final DeclaredType annotationType = _scopeAnnotation.getAnnotationType();
final TypeElement typeElement = (TypeElement) annotationType.asElement();
builder.addAnnotation(ClassName.get(typeElement));
}
builder.addSuperinterface(GeneratorUtil.DISPOSABLE_CLASSNAME);
builder.addSuperinterface(ParameterizedTypeName.get(GeneratorUtil.IDENTIFIABLE_CLASSNAME, getIdType().box()));
builder.addSuperinterface(GeneratorUtil.COMPONENT_OBSERVABLE_CLASSNAME);
buildFields(builder);
buildConstructors(builder, typeUtils);
builder.addMethod(buildContextRefMethod());
if (null != _componentRef) {
builder.addMethod(buildComponentRefMethod());
}
if (null == _componentId) {
builder.addMethod(buildComponentIdMethod());
}
builder.addMethod(buildArezIdMethod());
builder.addMethod(buildComponentNameMethod());
final MethodSpec method = buildComponentTypeNameMethod();
if (null != method) {
builder.addMethod(method);
}
if (!getCascadeOnDisposeDependencies().isEmpty()) {
builder.addMethod(buildCascadeOnDisposeDepsMethod());
}
if (!getSetNullOnDisposeDependencies().isEmpty()) {
builder.addMethod(buildSetNullOnDisposeDepsMethod());
}
builder.addMethod(buildInternalObserve());
builder.addMethod(buildObserve());
builder.addMethod(buildIsDisposed());
builder.addMethod(buildDispose());
_roObservables.forEach(e -> e.buildMethods(builder));
_roAutoruns.forEach(e -> e.buildMethods(builder));
_roActions.forEach(e -> e.buildMethods(builder));
_roComputeds.forEach(e -> e.buildMethods(builder));
_roMemoizes.forEach(e -> e.buildMethods(builder));
_roTrackeds.forEach(e -> e.buildMethods(builder));
builder.addMethod(buildHashcodeMethod());
builder.addMethod(buildEqualsMethod());
if (_generateToString) {
builder.addMethod(buildToStringMethod());
}
return builder.build();
}
use of com.squareup.javapoet.MethodSpec in project arez by arez.
the class ComponentDescriptor method buildSetNullOnDisposeDepsMethod.
@Nonnull
private MethodSpec buildSetNullOnDisposeDepsMethod() throws ArezProcessorException {
final MethodSpec.Builder builder = MethodSpec.methodBuilder(GeneratorUtil.SET_NULL_ON_DISPOSE_METHOD_NAME);
builder.addModifiers(Modifier.PRIVATE, Modifier.FINAL);
final AtomicInteger count = new AtomicInteger(1);
getSetNullOnDisposeDependencies().forEach(d -> {
final String varName = "dependency" + count.get();
count.incrementAndGet();
builder.addStatement("final $T $N = $N()", d.getMethod().getReturnType(), varName, d.getMethod().getSimpleName().toString());
final CodeBlock.Builder codeBlock = CodeBlock.builder();
codeBlock.beginControlFlow("if ( !$T.observe( $N ) ) ", GeneratorUtil.COMPONENT_OBSERVABLE_CLASSNAME, varName);
codeBlock.addStatement("$N( null )", d.getObservable().getSetter().getSimpleName().toString());
codeBlock.endControlFlow("");
builder.addCode(codeBlock.build());
});
return builder.build();
}
use of com.squareup.javapoet.MethodSpec in project arez by arez.
the class ComponentDescriptor method buildHashcodeMethod.
@Nonnull
private MethodSpec buildHashcodeMethod() throws ArezProcessorException {
final String idMethod = getIdMethodName();
final MethodSpec.Builder method = MethodSpec.methodBuilder("hashCode").addModifiers(Modifier.PUBLIC, Modifier.FINAL).addAnnotation(Override.class).returns(TypeName.INT);
final TypeKind kind = null != _componentId ? _componentId.getReturnType().getKind() : TypeKind.LONG;
if (_requireEquals) {
if (kind == TypeKind.DECLARED || kind == TypeKind.TYPEVAR) {
method.addStatement("return null != $N() ? $N().hashCode() : $T.identityHashCode( this )", idMethod, idMethod, System.class);
} else if (kind == TypeKind.BYTE) {
method.addStatement("return $T.hashCode( $N() )", Byte.class, idMethod);
} else if (kind == TypeKind.CHAR) {
method.addStatement("return $T.hashCode( $N() )", Character.class, idMethod);
} else if (kind == TypeKind.SHORT) {
method.addStatement("return $T.hashCode( $N() )", Short.class, idMethod);
} else if (kind == TypeKind.INT) {
method.addStatement("return $T.hashCode( $N() )", Integer.class, idMethod);
} else if (kind == TypeKind.LONG) {
method.addStatement("return $T.hashCode( $N() )", Long.class, idMethod);
} else if (kind == TypeKind.FLOAT) {
method.addStatement("return $T.hashCode( $N() )", Float.class, idMethod);
} else if (kind == TypeKind.DOUBLE) {
method.addStatement("return $T.hashCode( $N() )", Double.class, idMethod);
} else {
// So very unlikely but will cover it for completeness
assert kind == TypeKind.BOOLEAN;
method.addStatement("return $T.hashCode( $N() )", Boolean.class, idMethod);
}
} else {
final CodeBlock.Builder guardBlock = CodeBlock.builder();
guardBlock.beginControlFlow("if ( $T.areNativeComponentsEnabled() )", GeneratorUtil.AREZ_CLASSNAME);
if (kind == TypeKind.DECLARED || kind == TypeKind.TYPEVAR) {
guardBlock.addStatement("return null != $N() ? $N().hashCode() : $T.identityHashCode( this )", idMethod, idMethod, System.class);
} else if (kind == TypeKind.BYTE) {
guardBlock.addStatement("return $T.hashCode( $N() )", Byte.class, idMethod);
} else if (kind == TypeKind.CHAR) {
guardBlock.addStatement("return $T.hashCode( $N() )", Character.class, idMethod);
} else if (kind == TypeKind.SHORT) {
guardBlock.addStatement("return $T.hashCode( $N() )", Short.class, idMethod);
} else if (kind == TypeKind.INT) {
guardBlock.addStatement("return $T.hashCode( $N() )", Integer.class, idMethod);
} else if (kind == TypeKind.LONG) {
guardBlock.addStatement("return $T.hashCode( $N() )", Long.class, idMethod);
} else if (kind == TypeKind.FLOAT) {
guardBlock.addStatement("return $T.hashCode( $N() )", Float.class, idMethod);
} else if (kind == TypeKind.DOUBLE) {
guardBlock.addStatement("return $T.hashCode( $N() )", Double.class, idMethod);
} else {
// So very unlikely but will cover it for completeness
assert kind == TypeKind.BOOLEAN;
guardBlock.addStatement("return $T.hashCode( $N() )", Boolean.class, idMethod);
}
guardBlock.nextControlFlow("else");
guardBlock.addStatement("return super.hashCode()");
guardBlock.endControlFlow();
method.addCode(guardBlock.build());
}
return method.build();
}
Aggregations