# HG changeset patch # User Christian Humer # Date 1361793718 -3600 # Node ID e25ad0220267add014b89176505a35d35d84577e # Parent 85891f9c21970613efdc55a4d1062bbc13346076 Codewriter now supports writing generic type hierarchies and wildcards. Added a method to resolve a common base type out of multiple types. diff -r 85891f9c2197 -r e25ad0220267 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Utils.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Utils.java Mon Feb 25 12:43:18 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Utils.java Mon Feb 25 13:01:58 2013 +0100 @@ -47,6 +47,14 @@ } } + public static TypeMirror boxType(ProcessorContext context, TypeMirror primitiveType) { + TypeMirror boxedType = primitiveType; + if (boxedType.getKind().isPrimitive()) { + boxedType = context.getEnvironment().getTypeUtils().boxedClass((PrimitiveType) boxedType).asType(); + } + return boxedType; + } + public static List collectAnnotations(ProcessorContext context, AnnotationMirror markerAnnotation, String elementName, Element element, Class annotationClass) { List result = Utils.getAnnotationValueList(markerAnnotation, elementName); @@ -61,6 +69,42 @@ return result; } + public static TypeMirror getCommonSuperType(ProcessorContext context, TypeMirror[] types) { + if (types.length == 0) { + return context.getType(Object.class); + } + TypeMirror prev = types[0]; + for (int i = 1; i < types.length; i++) { + prev = getCommonSuperType(context, prev, types[i]); + } + return prev; + } + + public static TypeMirror getCommonSuperType(ProcessorContext context, TypeMirror type1, TypeMirror type2) { + if (typeEquals(type1, type2)) { + return type1; + } + TypeElement element1 = fromTypeMirror(type1); + TypeElement element2 = fromTypeMirror(type2); + if (element1 == null || element2 == null) { + return context.getType(Object.class); + } + + List element1Types = getDirectSuperTypes(element1); + element1Types.add(0, element1); + List element2Types = getDirectSuperTypes(element2); + element2Types.add(0, element2); + + for (TypeElement superType1 : element1Types) { + for (TypeElement superType2 : element2Types) { + if (typeEquals(superType1.asType(), superType2.asType())) { + return superType2.asType(); + } + } + } + return context.getType(Object.class); + } + public static String getReadableSignature(ExecutableElement method) { // TODO toString does not guarantee a good signature return method.toString(); @@ -146,31 +190,43 @@ case LONG: return "long"; case DECLARED: - return getGenericName(fromTypeMirror(mirror)); + return getDeclaredName((DeclaredType) mirror); case ARRAY: return getSimpleName(((ArrayType) mirror).getComponentType()) + "[]"; case VOID: return "void"; + case WILDCARD: + return getWildcardName((WildcardType) mirror); case TYPEVAR: - return ((TypeParameterElement) ((TypeVariable) mirror).asElement()).getSimpleName().toString(); + return "?"; default: throw new RuntimeException("Unknown type specified " + mirror.getKind() + " mirror: " + mirror); } } - private static String getGenericName(TypeElement element) { - String simpleName = element.getSimpleName().toString(); + private static String getWildcardName(WildcardType type) { + StringBuilder b = new StringBuilder(); + if (type.getExtendsBound() != null) { + b.append("? extends ").append(getSimpleName(type.getExtendsBound())); + } else if (type.getSuperBound() != null) { + b.append("? super ").append(getSimpleName(type.getExtendsBound())); + } + return b.toString(); + } - if (element.getTypeParameters().size() == 0) { + private static String getDeclaredName(DeclaredType element) { + String simpleName = element.asElement().getSimpleName().toString(); + + if (element.getTypeArguments().size() == 0) { return simpleName; } StringBuilder b = new StringBuilder(simpleName); b.append("<"); - if (element.getTypeParameters().size() > 0) { - for (int i = 0; i < element.getTypeParameters().size(); i++) { - b.append("?"); - if (i < element.getTypeParameters().size() - 1) { + if (element.getTypeArguments().size() > 0) { + for (int i = 0; i < element.getTypeArguments().size(); i++) { + b.append(getSimpleName(element.getTypeArguments().get(i))); + if (i < element.getTypeArguments().size() - 1) { b.append(", "); } } @@ -282,6 +338,19 @@ return null; } + public static List getDirectSuperTypes(TypeElement element) { + List types = new ArrayList<>(); + if (element.getSuperclass() != null) { + TypeElement superElement = fromTypeMirror(element.getSuperclass()); + if (superElement != null) { + types.add(superElement); + types.addAll(getDirectSuperTypes(superElement)); + } + } + + return types; + } + public static List getSuperTypes(TypeElement element) { List types = new ArrayList<>(); List superTypes = null; @@ -468,8 +537,10 @@ for (int i = 0; i < params.length; i++) { TypeMirror param1 = params[i]; TypeMirror param2 = method.getParameters().get(i).asType(); - if (!getQualifiedName(param1).equals(getQualifiedName(param2))) { - continue method; + if (param1.getKind() != TypeKind.TYPEVAR && param2.getKind() != TypeKind.TYPEVAR) { + if (!getQualifiedName(param1).equals(getQualifiedName(param2))) { + continue method; + } } } return method;