|
30 | 30 | import javax.lang.model.util.Elements;
|
31 | 31 | import javax.lang.model.util.SimpleTypeVisitor8;
|
32 | 32 | import javax.tools.Diagnostic;
|
| 33 | +import java.util.Collection; |
33 | 34 | import java.util.HashMap;
|
34 | 35 | import java.util.HashSet;
|
35 | 36 | import java.util.List;
|
36 | 37 | import java.util.Map;
|
| 38 | +import java.util.Objects; |
37 | 39 | import java.util.Set;
|
| 40 | +import java.util.stream.Stream; |
38 | 41 |
|
39 | 42 | import static java.beans.Introspector.decapitalize;
|
| 43 | +import static java.util.stream.Stream.concat; |
40 | 44 | import static org.hibernate.internal.util.StringHelper.split;
|
41 | 45 | import static org.hibernate.processor.util.AccessTypeInformation.DEFAULT_ACCESS_TYPE;
|
42 | 46 | import static org.hibernate.processor.util.Constants.ACCESS;
|
@@ -779,4 +783,41 @@ public static boolean isPrimitive(String paramType) {
|
779 | 783 |
|
780 | 784 | public static final Set<String> PRIMITIVE_TYPES =
|
781 | 785 | Set.of("boolean", "char", "long", "int", "short", "byte", "double", "float");
|
| 786 | + |
| 787 | + public static TypeMirror resolveTypeMirror(TypeElement typeElement, Element element, String name) { |
| 788 | + final var mirrorMap = resolveTypeParameters( typeElement.asType(), element, Map.of(), new HashSet<>() ); |
| 789 | + return mirrorMap == null ? null : mirrorMap.get( name ); |
| 790 | + } |
| 791 | + |
| 792 | + private static Map<String, TypeMirror> resolveTypeParameters(TypeMirror type, Element element, Map<String, TypeMirror> parametersMap, Collection<Element> visited) { |
| 793 | + if ( !(type instanceof DeclaredType declaredType |
| 794 | + && declaredType.asElement() instanceof TypeElement typeElement) ) { |
| 795 | + return null; |
| 796 | + } |
| 797 | + if ( !visited.add( typeElement ) ) { |
| 798 | + return null; |
| 799 | + } |
| 800 | + final var generic = typeElement.getTypeParameters(); |
| 801 | + final var map = new HashMap<String, TypeMirror>(); |
| 802 | + var typeArguments = declaredType.getTypeArguments(); |
| 803 | + if ( !(typeArguments.isEmpty() || generic.size() == typeArguments.size()) ) { |
| 804 | + return null; |
| 805 | + } |
| 806 | + for ( var n = 0; n < generic.size(); ++n ) { |
| 807 | + final var mirror = typeArguments.isEmpty() |
| 808 | + ? generic.get( 0 ).getBounds().get( 0 ) |
| 809 | + : typeArguments.get( n ); |
| 810 | + final var value = mirror.toString(); |
| 811 | + map.put( generic.get( n ).toString(), parametersMap.getOrDefault( value, mirror ) ); |
| 812 | + } |
| 813 | + if ( typeElement.equals( element ) ) { |
| 814 | + return map; |
| 815 | + } |
| 816 | + return concat( |
| 817 | + Stream.of( typeElement.getSuperclass() ), |
| 818 | + typeElement.getInterfaces().stream() |
| 819 | + ).map( tm -> resolveTypeParameters( tm, element, map, visited ) ) |
| 820 | + .filter( Objects::nonNull ) |
| 821 | + .findFirst().orElse( null ); |
| 822 | + } |
782 | 823 | }
|
0 commit comments