Skip to content

Commit

Permalink
#418 abstract json with generics and inheritance
Browse files Browse the repository at this point in the history
  • Loading branch information
elucash committed Aug 17, 2016
1 parent 5aad9bc commit ab28b83
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 16 deletions.
@@ -0,0 +1,8 @@
package nonimmutables.recurs;

import org.immutables.value.Value;

@Value.Immutable
public interface AbstractMySomethingContent extends MyContent {

}
18 changes: 18 additions & 0 deletions value-fixture/src/nonimmutables/recurs/AbstractSomething.java
@@ -0,0 +1,18 @@
package nonimmutables.recurs;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.immutables.value.Value.Immutable;

@JsonSerialize
@Immutable
public interface AbstractSomething extends IHaveGetContentAndWithId<MySomethingContent, Something> {

// this override is not needed with 2.2, hooray! \o/
// @Override
// MySomethingContent getContent();

// without this override it generates the withId method that returns T instead of Something for
// the Json class ;(
// @Override
// Something withId(int id);
}
@@ -0,0 +1,6 @@
package nonimmutables.recurs;

public interface IHaveGetContentAndWithId<T extends MyContent, A extends MyBase> extends MyBase, IHaveWithIdMethod<A> {

T getContent();
}
7 changes: 7 additions & 0 deletions value-fixture/src/nonimmutables/recurs/IHaveWithIdMethod.java
@@ -0,0 +1,7 @@
package nonimmutables.recurs;

public interface IHaveWithIdMethod<T extends MyBase> {

T withId(int id); // I that having getId in MyBase will generate this but I need an interface to
// use commonly on multiple class that inherit from MyBase
}
6 changes: 6 additions & 0 deletions value-fixture/src/nonimmutables/recurs/MyBase.java
@@ -0,0 +1,6 @@
package nonimmutables.recurs;

public interface MyBase {

int getId();
}
3 changes: 3 additions & 0 deletions value-fixture/src/nonimmutables/recurs/MyContent.java
@@ -0,0 +1,3 @@
package nonimmutables.recurs;
public interface MyContent {}

4 changes: 4 additions & 0 deletions value-fixture/src/nonimmutables/recurs/package-info.java
@@ -0,0 +1,4 @@
@org.immutables.value.Value.Style(
typeAbstract = "Abstract*",
typeImmutable = "*")
package nonimmutables.recurs;
Expand Up @@ -402,31 +402,39 @@ private AttributeNames deriveNames(String accessorName) {
}

private TypeMirror resolveReturnType(ExecutableElement method) {
method = CachingElements.getDelegate(method);
TypeMirror returnType = method.getReturnType();

TypeElement typeElement = getTypeElement();
if (isEclipseImplementation) {
return returnType;
return method.getReturnType();
}
return resolveReturnType(processing, method, typeElement);
}

static TypeMirror resolveReturnType(
ProcessingEnvironment processing,
ExecutableElement method,
TypeElement typeElement) {
method = CachingElements.getDelegate(method);
TypeMirror returnType = method.getReturnType();

// We do not support parametrized accessor methods,
// but we do support inheriting parametrized accessors, which
// we supposedly parametrized with actual type parameters as
// our target class could not define formal type parameters also.
if (returnType.getKind() == TypeKind.TYPEVAR) {
return asInheritedMemberReturnType(method);
return asInheritedMemberReturnType(processing, typeElement, method);
} else if (returnType.getKind() == TypeKind.DECLARED
|| returnType.getKind() == TypeKind.ERROR) {
if (!((DeclaredType) returnType).getTypeArguments().isEmpty()) {
return asInheritedMemberReturnType(method);
return asInheritedMemberReturnType(processing, typeElement, method);
}
}
return returnType;
}

private TypeMirror asInheritedMemberReturnType(ExecutableElement method) {
TypeElement typeElement = getTypeElement();

static TypeMirror asInheritedMemberReturnType(
ProcessingEnvironment processing,
TypeElement typeElement,
ExecutableElement method) {
ExecutableType asMethodOfType =
(ExecutableType) processing.getTypeUtils()
.asMemberOf((DeclaredType) typeElement.asType(), method);
Expand Down Expand Up @@ -460,7 +468,7 @@ private Reporter report(Element type) {
return Reporter.from(protoclass.processing()).withElement(type);
}

private static boolean isEclipseImplementation(Element element) {
static boolean isEclipseImplementation(Element element) {
return CachingElements.getDelegate(element).getClass().getCanonicalName().startsWith(ORG_ECLIPSE);
}
}
Expand Up @@ -1263,7 +1263,19 @@ public Set<String> getNonAttributeAbstractMethodSignatures() {
|| m.getSimpleName().contentEquals(AccessorAttributesCollector.TO_STRING_METHOD)) {

if (m.getModifiers().contains(Modifier.ABSTRACT)) {
signatures.add(toSignature(m));
TypeMirror returnType = m.getReturnType();
String r = returnType.toString();
if (!AccessorAttributesCollector.isEclipseImplementation(m)) {
returnType = AccessorAttributesCollector.asInheritedMemberReturnType(
constitution.protoclass().processing(),
CachingElements.getDelegate((TypeElement) element), m);

System.out.println("!!! YYY " + returnType);
}
if (!returnType.toString().equals(r)) {
System.out.println("!!! MMMM " + m + " : " + returnType);
}
signatures.add(toSignature(m, returnType));
}
}
}
Expand Down Expand Up @@ -1338,7 +1350,7 @@ public class BoundElement {
this.name = method.getSimpleName();
this.type = method.getReturnType().getKind().isPrimitive()
? wrapType(method.getReturnType().toString())
: appendReturnType(method, new StringBuilder(), declaringType);
: appendReturnType(method, new StringBuilder(), declaringType, method.getReturnType());
this.parameters = appendParameters(method, new StringBuilder(), declaringType, true, true);
this.arguments = appendParameters(method, new StringBuilder(), declaringType, false, false);
}
Expand All @@ -1361,11 +1373,11 @@ public List<ValueAttribute> getBuilderParameters() {
return params;
}

private String toSignature(ExecutableElement m) {
private String toSignature(ExecutableElement m, TypeMirror returnType) {
DeclaringType declaringType = inferDeclaringType(m);
StringBuilder signature = new StringBuilder();
appendAccessModifier(m, signature);
appendReturnType(m, signature, declaringType);
appendReturnType(m, signature, declaringType, returnType);
signature.append(" ").append(m.getSimpleName());
appendParameters(m, signature, declaringType, true, false);
return signature.toString();
Expand All @@ -1381,8 +1393,12 @@ private CharSequence appendAccessModifier(ExecutableElement m, StringBuilder sig
return signature;
}

private CharSequence appendReturnType(ExecutableElement m, StringBuilder signature, DeclaringType declaringType) {
return signature.append(printType(m, m.getReturnType(), declaringType));
private CharSequence appendReturnType(
ExecutableElement m,
StringBuilder signature,
DeclaringType declaringType,
TypeMirror returnType) {
return signature.append(printType(m, returnType, declaringType));
}

private CharSequence appendParameters(
Expand Down

0 comments on commit ab28b83

Please sign in to comment.