HHH-14724 Fix generation of problematic metamodel classes which use TYPE_USE annotations
This commit is contained in:
parent
1411e7bad3
commit
96c96c67ea
|
@ -30,7 +30,7 @@ dependencies {
|
|||
|
||||
testCompile libraries.junit
|
||||
testCompile libraries.jpa
|
||||
testCompile libraries.validation
|
||||
testCompile libraries.validation
|
||||
testCompile project( ':hibernate-core' )
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.jpamodelgen.util;
|
||||
|
||||
import java.util.List;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.TypeParameterElement;
|
||||
import javax.lang.model.type.ArrayType;
|
||||
import javax.lang.model.type.DeclaredType;
|
||||
import javax.lang.model.type.ExecutableType;
|
||||
import javax.lang.model.type.IntersectionType;
|
||||
import javax.lang.model.type.NoType;
|
||||
import javax.lang.model.type.NullType;
|
||||
import javax.lang.model.type.PrimitiveType;
|
||||
import javax.lang.model.type.TypeKind;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.lang.model.type.TypeVariable;
|
||||
import javax.lang.model.type.UnionType;
|
||||
import javax.lang.model.type.WildcardType;
|
||||
import javax.lang.model.util.SimpleTypeVisitor8;
|
||||
|
||||
/**
|
||||
* @author Christian Beikov
|
||||
*/
|
||||
public final class TypeRenderingVisitor extends SimpleTypeVisitor8<Object, Object> {
|
||||
|
||||
private final StringBuilder sb = new StringBuilder();
|
||||
|
||||
private TypeRenderingVisitor() {
|
||||
}
|
||||
|
||||
public static String toString(TypeMirror typeMirror) {
|
||||
if ( typeMirror instanceof TypeVariable ) {
|
||||
// Top level type variables don't need to render the upper bound as `T extends Type`
|
||||
final Element typeVariableElement = ( (TypeVariable) typeMirror ).asElement();
|
||||
if ( typeVariableElement instanceof TypeParameterElement ) {
|
||||
final TypeParameterElement typeParameter = (TypeParameterElement) typeVariableElement;
|
||||
if ( typeParameter.getEnclosingElement().getKind() == ElementKind.METHOD ) {
|
||||
// But for method level type variable we return the upper bound
|
||||
// because the type variable has no meaning except for that method
|
||||
typeMirror = ( (TypeVariable) typeMirror ).getUpperBound();
|
||||
}
|
||||
else {
|
||||
return typeParameter.toString();
|
||||
}
|
||||
}
|
||||
else {
|
||||
typeMirror = typeVariableElement.asType();
|
||||
}
|
||||
}
|
||||
else if ( typeMirror instanceof IntersectionType ) {
|
||||
// For top level type only the first type is relevant
|
||||
typeMirror = ( (IntersectionType) typeMirror ).getBounds().get( 0 );
|
||||
}
|
||||
final TypeRenderingVisitor typeRenderingVisitor = new TypeRenderingVisitor();
|
||||
typeMirror.accept( typeRenderingVisitor, null );
|
||||
return typeRenderingVisitor.sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitPrimitive(PrimitiveType t, Object o) {
|
||||
final String primitiveTypeName = getPrimitiveTypeName( t.getKind() );
|
||||
if ( primitiveTypeName != null ) {
|
||||
sb.append( primitiveTypeName );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String getPrimitiveTypeName(TypeKind kind) {
|
||||
switch ( kind ) {
|
||||
case INT:
|
||||
return "int";
|
||||
case BOOLEAN:
|
||||
return "boolean";
|
||||
case BYTE:
|
||||
return "byte";
|
||||
case CHAR:
|
||||
return "char";
|
||||
case DOUBLE:
|
||||
return "double";
|
||||
case FLOAT:
|
||||
return "float";
|
||||
case LONG:
|
||||
return "long";
|
||||
case SHORT:
|
||||
return "short";
|
||||
case VOID:
|
||||
return "void";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitNull(NullType t, Object o) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitArray(ArrayType t, Object o) {
|
||||
t.getComponentType().accept( this, null );
|
||||
sb.append( "[]" );
|
||||
return t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitDeclared(DeclaredType t, Object o) {
|
||||
sb.append( t.asElement().toString() );
|
||||
List<? extends TypeMirror> typeArguments = t.getTypeArguments();
|
||||
if ( !typeArguments.isEmpty() ) {
|
||||
sb.append( '<' );
|
||||
typeArguments.get( 0 ).accept( this, null );
|
||||
for ( int i = 1; i < typeArguments.size(); i++ ) {
|
||||
sb.append( ", " );
|
||||
typeArguments.get( i ).accept( this, null );
|
||||
}
|
||||
sb.append( '>' );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitTypeVariable(TypeVariable t, Object o) {
|
||||
final Element typeVariableElement = t.asElement();
|
||||
if ( typeVariableElement instanceof TypeParameterElement ) {
|
||||
final TypeParameterElement typeParameter = (TypeParameterElement) typeVariableElement;
|
||||
sb.append( typeParameter );
|
||||
if ( !"java.lang.Object".equals( t.getUpperBound().toString() ) ) {
|
||||
sb.append( " extends " );
|
||||
t.getUpperBound().accept( this, null );
|
||||
}
|
||||
}
|
||||
else {
|
||||
typeVariableElement.asType().accept( this, null );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitWildcard(WildcardType t, Object o) {
|
||||
sb.append( '?' );
|
||||
if ( t.getExtendsBound() != null ) {
|
||||
sb.append( " extends " );
|
||||
t.getExtendsBound().accept( this, null );
|
||||
}
|
||||
if ( t.getSuperBound() != null ) {
|
||||
sb.append( " super " );
|
||||
t.getSuperBound().accept( this, null );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitUnion(UnionType t, Object o) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitIntersection(IntersectionType t, Object o) {
|
||||
final List<? extends TypeMirror> bounds = t.getBounds();
|
||||
bounds.get( 0 ).accept( this, null );
|
||||
for ( int i = 0; i < bounds.size(); i++ ) {
|
||||
sb.append( " & " );
|
||||
bounds.get( i ).accept( this, null );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitExecutable(ExecutableType t, Object o) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitNoType(NoType t, Object o) {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -74,7 +74,7 @@ public final class TypeUtils {
|
|||
if ( type.getKind().isPrimitive() ) {
|
||||
return PRIMITIVE_WRAPPERS.get( type.getKind() );
|
||||
}
|
||||
return type.toString();
|
||||
return TypeRenderingVisitor.toString( type );
|
||||
}
|
||||
|
||||
public static String toArrayTypeString(ArrayType type, Context context) {
|
||||
|
|
Loading…
Reference in New Issue