Skip to content

Commit

Permalink
fix: support creation of partial shadow classes (#2040)
Browse files Browse the repository at this point in the history
  • Loading branch information
tdurieux authored and monperrus committed Jun 9, 2018
1 parent 45a309a commit 439d0c4
Show file tree
Hide file tree
Showing 3 changed files with 227 additions and 110 deletions.
10 changes: 10 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,16 @@
<artifactId>querydsl-core</artifactId>
<version>3.6.9</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
</exclusion>
<exclusion>
<groupId>com.mysema.commons</groupId>
<artifactId>mysema-commons-lang</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

Expand Down
261 changes: 178 additions & 83 deletions src/main/java/spoon/support/visitor/java/JavaReflectionVisitorImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import spoon.SpoonException;
import spoon.reflect.path.CtRole;
import spoon.reflect.reference.CtTypeReference;
import spoon.support.visitor.java.reflect.RtMethod;
import spoon.support.visitor.java.reflect.RtParameter;

Expand Down Expand Up @@ -46,38 +45,70 @@ public <T> void visitClass(Class<T> clazz) {
if (clazz.getPackage() != null) {
clazz.getPackage();
}
for (TypeVariable<Class<T>> generic : clazz.getTypeParameters()) {
visitTypeParameter(generic);
try {
for (TypeVariable<Class<T>> generic : clazz.getTypeParameters()) {
visitTypeParameter(generic);
}
} catch (NoClassDefFoundError ignore) {
// partial classpath
}
if (clazz.getGenericSuperclass() != null && clazz.getGenericSuperclass() != Object.class) {
visitTypeReference(CtRole.SUPER_TYPE, clazz.getGenericSuperclass());
try {
if (clazz.getGenericSuperclass() != null && clazz.getGenericSuperclass() != Object.class) {
visitTypeReference(CtRole.SUPER_TYPE, clazz.getGenericSuperclass());
}
} catch (NoClassDefFoundError ignore) {
// partial classpath
}
for (Type anInterface : clazz.getGenericInterfaces()) {
visitTypeReference(CtRole.INTERFACE, anInterface);
try {
for (Type anInterface : clazz.getGenericInterfaces()) {
visitTypeReference(CtRole.INTERFACE, anInterface);
}
} catch (NoClassDefFoundError ignore) {
// partial classpath
}
for (Annotation annotation : clazz.getDeclaredAnnotations()) {
visitAnnotation(annotation);
try {
for (Annotation annotation : clazz.getDeclaredAnnotations()) {
visitAnnotation(annotation);
}
} catch (NoClassDefFoundError ignore) {
// partial classpath
}
for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
if (constructor.isSynthetic()) {
continue;
try {
for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
if (constructor.isSynthetic()) {
continue;
}
visitConstructor(constructor);
}
visitConstructor(constructor);
} catch (NoClassDefFoundError ignore) {
// partial classpath
}
for (RtMethod method : getDeclaredMethods(clazz)) {
if (method.getMethod().isSynthetic()) {
continue;
try {
for (RtMethod method : getDeclaredMethods(clazz)) {
if (method.getMethod().isSynthetic()) {
continue;
}
visitMethod(method);
}
visitMethod(method);
} catch (NoClassDefFoundError ignore) {
// partial classpath
}
for (Field field : clazz.getDeclaredFields()) {
if (field.isSynthetic()) {
continue;
try {
for (Field field : clazz.getDeclaredFields()) {
if (field.isSynthetic()) {
continue;
}
visitField(field);
}
visitField(field);
} catch (NoClassDefFoundError ignore) {
// partial classpath
}
for (Class<?> aClass : clazz.getDeclaredClasses()) {
visitType(aClass);
try {
for (Class<?> aClass : clazz.getDeclaredClasses()) {
visitType(aClass);
}
} catch (NoClassDefFoundError ignore) {
// partial classpath
}
}

Expand All @@ -99,29 +130,54 @@ public <T> void visitInterface(Class<T> clazz) {
if (clazz.getPackage() != null) {
clazz.getPackage();
}
for (Type anInterface : clazz.getGenericInterfaces()) {
visitTypeReference(CtRole.INTERFACE, anInterface);
try {
for (Type anInterface : clazz.getGenericInterfaces()) {
visitTypeReference(CtRole.INTERFACE, anInterface);
}
} catch (NoClassDefFoundError ignore) {
// partial classpath
}
for (Annotation annotation : clazz.getDeclaredAnnotations()) {
visitAnnotation(annotation);

try {
for (Annotation annotation : clazz.getDeclaredAnnotations()) {
visitAnnotation(annotation);
}
} catch (NoClassDefFoundError ignore) {
// partial classpath
}
for (RtMethod method : getDeclaredMethods(clazz)) {
if (method.getMethod().isSynthetic()) {
continue;
try {
for (RtMethod method : getDeclaredMethods(clazz)) {
if (method.getMethod().isSynthetic()) {
continue;
}
visitMethod(method);
}
visitMethod(method);
} catch (NoClassDefFoundError ignore) {
// partial classpath
}
for (Field field : clazz.getDeclaredFields()) {
if (field.isSynthetic()) {
continue;
try {
for (Field field : clazz.getDeclaredFields()) {
if (field.isSynthetic()) {
continue;
}
visitField(field);
}
visitField(field);
} catch (NoClassDefFoundError ignore) {
// partial classpath
}
for (Class<?> aClass : clazz.getDeclaredClasses()) {
visitType(aClass);
try {
for (Class<?> aClass : clazz.getDeclaredClasses()) {
visitType(aClass);
}
} catch (NoClassDefFoundError ignore) {
// partial classpath
}
for (TypeVariable<Class<T>> generic : clazz.getTypeParameters()) {
visitTypeParameter(generic);
try {
for (TypeVariable<Class<T>> generic : clazz.getTypeParameters()) {
visitTypeParameter(generic);
}
} catch (NoClassDefFoundError ignore) {
// partial classpath
}
}

Expand All @@ -131,46 +187,70 @@ public <T> void visitEnum(Class<T> clazz) {
if (clazz.getPackage() != null) {
clazz.getPackage();
}
for (Type anInterface : clazz.getGenericInterfaces()) {
visitTypeReference(CtRole.INTERFACE, anInterface);
}
for (Annotation annotation : clazz.getDeclaredAnnotations()) {
visitAnnotation(annotation);
try {
for (Type anInterface : clazz.getGenericInterfaces()) {
visitTypeReference(CtRole.INTERFACE, anInterface);
}
} catch (NoClassDefFoundError ignore) {
// partial classpath
}
for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
if (Modifier.isPrivate(constructor.getModifiers())) {
Class<?>[] paramTypes = constructor.getParameterTypes();
if (paramTypes.length == 2 && paramTypes[0] == String.class && paramTypes[1] == int.class) {
//ignore implicit enum constructor
try {
for (Annotation annotation : clazz.getDeclaredAnnotations()) {
visitAnnotation(annotation);
}
} catch (NoClassDefFoundError ignore) {
// partial classpath
}
try {
for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
if (Modifier.isPrivate(constructor.getModifiers())) {
Class<?>[] paramTypes = constructor.getParameterTypes();
if (paramTypes.length == 2 && paramTypes[0] == String.class && paramTypes[1] == int.class) {
//ignore implicit enum constructor
continue;
}
}
if (constructor.isSynthetic()) {
continue;
}
visitConstructor(constructor);
}
if (constructor.isSynthetic()) {
continue;
}
visitConstructor(constructor);
} catch (NoClassDefFoundError ignore) {
// partial classpath
}
for (RtMethod method : getDeclaredMethods(clazz)) {
if (("valueOf".equals(method.getName()) && method.getParameterTypes().length == 1 && String.class.equals(method.getParameterTypes()[0])) || "values".equals(method.getName())) {
continue;
}
if (method.getMethod().isSynthetic()) {
continue;
try {
for (RtMethod method : getDeclaredMethods(clazz)) {
if (("valueOf".equals(method.getName()) && method.getParameterTypes().length == 1 && String.class.equals(method.getParameterTypes()[0])) || "values".equals(method.getName())) {
continue;
}
if (method.getMethod().isSynthetic()) {
continue;
}
visitMethod(method);
}
visitMethod(method);
} catch (NoClassDefFoundError ignore) {
// partial classpath
}
for (Field field : clazz.getDeclaredFields()) {
if (field.isSynthetic()) {
continue;
}
if (field.isEnumConstant()) {
visitEnumValue(field);
} else {
visitField(field);
try {
for (Field field : clazz.getDeclaredFields()) {
if (field.isSynthetic()) {
continue;
}
if (field.isEnumConstant()) {
visitEnumValue(field);
} else {
visitField(field);
}
}
} catch (NoClassDefFoundError ignore) {
// partial classpath
}
for (Class<?> aClass : clazz.getDeclaredClasses()) {
visitType(aClass);
try {
for (Class<?> aClass : clazz.getDeclaredClasses()) {
visitType(aClass);
}
} catch (NoClassDefFoundError ignore) {
// partial classpath
}
}

Expand All @@ -180,23 +260,39 @@ public <T extends Annotation> void visitAnnotationClass(Class<T> clazz) {
if (clazz.getPackage() != null) {
clazz.getPackage();
}
for (Annotation annotation : clazz.getDeclaredAnnotations()) {
visitAnnotation(annotation);
try {
for (Annotation annotation : clazz.getDeclaredAnnotations()) {
visitAnnotation(annotation);
}
} catch (NoClassDefFoundError ignore) {
// partial classpath
}
for (RtMethod method : getDeclaredMethods(clazz)) {
if (method.getMethod().isSynthetic()) {
continue;
try {
for (RtMethod method : getDeclaredMethods(clazz)) {
if (method.getMethod().isSynthetic()) {
continue;
}
visitMethod(method);
}
visitMethod(method);
} catch (NoClassDefFoundError ignore) {
// partial classpath
}
for (Field field : clazz.getDeclaredFields()) {
if (field.isSynthetic()) {
continue;
try {
for (Field field : clazz.getDeclaredFields()) {
if (field.isSynthetic()) {
continue;
}
visitField(field);
}
visitField(field);
} catch (NoClassDefFoundError ignore) {
// partial classpath
}
for (Class<?> aClass : clazz.getDeclaredClasses()) {
visitType(aClass);
try {
for (Class<?> aClass : clazz.getDeclaredClasses()) {
visitType(aClass);
}
} catch (NoClassDefFoundError ignore) {
// partial classpath
}
}

Expand Down Expand Up @@ -322,7 +418,6 @@ public <T extends GenericDeclaration> void visitTypeParameterReference(CtRole ro

@Override
public final void visitTypeReference(CtRole role, Type type) {
CtTypeReference<?> ctTypeReference;
if (type instanceof TypeVariable) {
this.visitTypeParameterReference(role, (TypeVariable<?>) type);
return;
Expand Down
Loading

0 comments on commit 439d0c4

Please sign in to comment.