JMethod constructorMethod = valueClass.method(interfaceMethod.mods().getValue() & ~JMod.ABSTRACT | JMod.STATIC, types._void, interfaceMethod.name());
constructorMethod.annotate(Nonnull.class);
for (JTypeVar visitorTypeParameter: visitorInterface.getValueTypeParameters()) {
Types.generifyWithBoundsFrom(constructorMethod, visitorTypeParameter.name(), visitorTypeParameter);
}
AbstractJClass usedValueClassType = valueClass.narrow(constructorMethod.typeParams());
constructorMethod.type(usedValueClassType);
for (JVar param: interfaceMethod.params()) {
AbstractJType paramType = visitorInterface.substituteSpecialType(param.type(), usedValueClassType, usedValueClassType, types._RuntimeException);
JVar constructorMethodParam = constructorMethod.param(param.mods().getValue(), paramType, param.name());
if (param.type().isReference())
constructorMethodParam.annotate(isNullable(param) ? Nullable.class : Nonnull.class);
}
JVar param = interfaceMethod.listVarParam();
if (param != null) {
AbstractJType paramType = visitorInterface.substituteSpecialType(param.type().elementType(), usedValueClassType, usedValueClassType, types._RuntimeException);
JVar constructorMethodParam = constructorMethod.varParam(param.mods().getValue(), paramType, param.name());
if (param.type().isReference())
constructorMethodParam.annotate(isNullable(param) ? Nullable.class : Nonnull.class);
}
AbstractJClass usedCaseClassType = caseClasses.get(interfaceMethod.name()).narrow(constructorMethod.typeParams());
if (!interfaceMethod.params().isEmpty() || interfaceMethod.hasVarArgs()) {
boolean hasNullChecks = false;
for (JVar param1: interfaceMethod.params()) {
if (param1.type().isReference() && !isNullable(param1)) {
JConditional nullCheck = constructorMethod.body()._if(JExpr.ref(param1.name()).eq(JExpr._null()));
JInvocation nullPointerExceptionConstruction = JExpr._new(types._NullPointerException);
nullPointerExceptionConstruction.arg(JExpr.lit("Argument shouldn't be null: '" + param1.name() + "' argument in static method invocation: '" + constructorMethod.name() + "' in class " + valueClass.fullName()));
nullCheck._then()._throw(nullPointerExceptionConstruction);
hasNullChecks = true;
}
}
JVar param1 = interfaceMethod.listVarParam();
if (param1 != null) {
if (param1.type().isReference() && !isNullable(param1)) {
JConditional nullCheck = constructorMethod.body()._if(JExpr.ref(param1.name()).eq(JExpr._null()));
JInvocation nullPointerExceptionConstruction = JExpr._new(types._NullPointerException);
nullPointerExceptionConstruction.arg(JExpr.lit("Argument shouldn't be null: '" + param1.name() + "' argument in static method invocation: '" + constructorMethod.name() + "' in class " + valueClass.fullName()));
nullCheck._then()._throw(nullPointerExceptionConstruction);
hasNullChecks = true;
}
}
if (hasNullChecks) {
JAnnotationUse annotation = constructorMethod.annotate(SuppressWarnings.class);
annotation.paramArray("value", "null");
}
JInvocation caseClassConstructorInvocation = JExpr._new(usedCaseClassType);
for (JVar param2: interfaceMethod.params()) {
caseClassConstructorInvocation.arg(JExpr.ref(param2.name()));
}
JVar param2 = interfaceMethod.listVarParam();
if (param2 != null) {
caseClassConstructorInvocation.arg(JExpr.ref(param2.name()));
}
JInvocation constructorInvocation = JExpr._new(usedValueClassType);
constructorInvocation.arg(caseClassConstructorInvocation);
constructorMethod.body()._return(constructorInvocation);
} else {
JInvocation caseClassConstructorInvocation = JExpr._new(usedCaseClassType.erasure());
JInvocation initializer = JExpr._new(usedValueClassType.erasure());
initializer.arg(caseClassConstructorInvocation);
JFieldVar singletonInstanceField = valueClass.field(JMod.PRIVATE | JMod.STATIC | JMod.FINAL,
usedValueClassType.erasure(),
interfaceMethod.name().toUpperCase(),