Refine search
public JMethod overrideAnnotatedMethod(ExecutableElement executableElement, GeneratedClassHolder holder) { TypeMirror annotatedClass = holder.getAnnotatedElement().asType(); DeclaredType baseClass = (DeclaredType) executableElement.getEnclosingElement().asType(); Map<String, List<AbstractJClass>> methodTypes = new LinkedHashMap<>(); for (TypeParameterElement typeParameter : executableElement.getTypeParameters()) { List<? extends TypeMirror> bounds = typeParameter.getBounds(); String methodName = executableElement.getSimpleName().toString(); AbstractJClass returnType = typeMirrorToJClass(executableElement.getReturnType(), actualTypes); int modifier = elementVisibilityModifierToJMod(executableElement);
inheritedAnnotations.addAll(type.getAnnotationMirrors()); if (type.getKind() == TypeKind.TYPEVAR) { TypeVariable typeVar = (TypeVariable) type; inheritedAnnotations.addAll(typeVar.getUpperBound().getAnnotationMirrors()); if (typeVar.asElement().getKind() == TYPE_PARAMETER) { Element genericElt = ((TypeParameterElement) typeVar.asElement()).getGenericElement(); if (genericElt.getKind().isClass() || genericElt.getKind().isInterface()) { ((TypeElement) genericElt) .getTypeParameters().stream() .filter( typeParam -> typeParam.getSimpleName().equals(typeVar.asElement().getSimpleName())) .findFirst() .ifPresent(decl -> inheritedAnnotations.addAll(decl.getAnnotationMirrors()));
checkNotNull(method, "method == null"); Element enclosingClass = method.getEnclosingElement(); if (enclosingClass.getModifiers().contains(Modifier.FINAL)) { throw new IllegalArgumentException("Cannot override method on final class " + enclosingClass); Set<Modifier> modifiers = method.getModifiers(); if (modifiers.contains(Modifier.PRIVATE) || modifiers.contains(Modifier.FINAL) String methodName = method.getSimpleName().toString(); MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(methodName); for (TypeParameterElement typeParameterElement : method.getTypeParameters()) { TypeVariable var = (TypeVariable) typeParameterElement.asType(); methodBuilder.addTypeVariable(TypeVariableName.get(var));
public void generify(IJGenerifiable generifiable, TypeElement fromTypeParameters) { for (TypeParameterElement param : fromTypeParameters.getTypeParameters()) { List<AbstractJClass> bounds = typeBoundsToJClass(param.getBounds()); addTypeBounds(generifiable, bounds, param.getSimpleName().toString()); } }
/** Returns type variable equivalent to {@code element}. */ public static TypeVariableName get(TypeParameterElement element) { String name = element.getSimpleName().toString(); List<? extends TypeMirror> boundsMirrors = element.getBounds(); List<TypeName> boundsTypeNames = new ArrayList<>(); for (TypeMirror typeMirror : boundsMirrors) { boundsTypeNames.add(TypeName.get(typeMirror)); } return TypeVariableName.of(name, boundsTypeNames); }
JDefinedClass newClass = codeModel._class(modifiers, element.getQualifiedName().toString(), classType); newClass.hide(); Annotator classAnnotator = new Annotator(newClass, environment); classAnnotator.annotate(element.getAnnotationMirrors()); for (TypeParameterElement parameter: element.getTypeParameters()) { JTypeVar typeVariable = newClass.generify(parameter.getSimpleName().toString()); environment.put(typeVariable.name(), typeVariable); for (TypeMirror type: parameter.getBounds()) { typeVariable.bound((AbstractJClass)toJType(type, environment)); TypeMirror superclass = element.getSuperclass(); if (superclass != null && superclass.getKind() != TypeKind.NONE) { newClass._extends((AbstractJClass)toJType(superclass, environment)); for (Element enclosedElement: element.getEnclosedElements()) { if (enclosedElement.getKind().equals(ElementKind.METHOD)) { ExecutableElement executable = (ExecutableElement)enclosedElement; JMethod method = newClass.method(toJMod(executable.getModifiers()), codeModel.VOID, executable.getSimpleName().toString()); TypeEnvironment methodEnvironment = environment.enclosed(); Annotator methodAnnotator = new Annotator(method, environment); methodAnnotator.annotate(executable.getAnnotationMirrors()); for (TypeParameterElement parameter: executable.getTypeParameters()) { JTypeVar typeVariable = method.generify(parameter.getSimpleName().toString()); methodEnvironment.put(typeVariable.name(), typeVariable); for (TypeMirror type: parameter.getBounds()) { typeVariable.bound((AbstractJClass)toJType(type, methodEnvironment));
DeriveResult<AlgebraicDataType> parseAlgebraicDataType(final TypeElement adtTypeElement, DeriveConfig deriveConfig) { asDeclaredType.visit(adtTypeElement.asType()) .filter(t -> (t.asElement().getEnclosingElement().getKind() == ElementKind.PACKAGE) || t.asElement().getModifiers().contains(Modifier.STATIC) || (t.asElement().getKind() == ElementKind.ENUM) || (t.asElement().getKind() == ElementKind.INTERFACE)), error(message("Invalid annotated class (only static classes are supported)", onElement(adtTypeElement))), traverseOptional(declaredType.getTypeArguments(), ta -> asTypeVariable.visit(ta).filter( tv -> types.isSameType(elements.getTypeElement("java.lang.Object").asType(), tv.getUpperBound()))), error(message("Please use only type variable without bounds as type parameter", onElement(adtTypeElement))), findOnlyOne(adtAcceptMethod.getTypeParameters()).filter(t -> findOnlyOne(t.getBounds()) .filter(b -> types.isSameType(deriveUtils.object().classModel().asType(), b)) .isPresent()).map(TypeParameterElement::asType).flatMap(asTypeVariable::visit).filter( tv -> types.isSameType(tv, adtAcceptMethod.getReturnType())), error(message( "Method must have one, and only one, type variable (without bounds) that should also be the method "
private ValueVisitorInterfaceModel buildVisitorInterface(TypeElement visitorElement, GenerateValueClassForVisitor dataVisitor) throws SourceException, CodeGenerationException { try { JDefinedClass visitorInterfaceModel = createJDefinedClass(visitorElement); for (Element element: visitorElement.getEnclosedElements()) { if (element.getKind().equals(ElementKind.METHOD)) { ExecutableElement executable = (ExecutableElement)element; JMethod method = visitorInterfaceModel.method(toJMod(executable.getModifiers()), toJType(executable.getReturnType()), executable.getSimpleName().toString()); for (TypeParameterElement parameter: executable.getTypeParameters()) { JTypeVar typeVariable = method.generify(parameter.getSimpleName().toString()); for (TypeMirror type: parameter.getBounds()) { typeVariable.bound((AbstractJClass)toJType(type)); } } for (TypeMirror type: executable.getThrownTypes()) { AbstractJClass throwable = (AbstractJClass)toJType(type); method._throws(throwable); } for (VariableElement variable: executable.getParameters()) { JVar param = method.param(toJMod(variable.getModifiers()), toJType(variable.asType()), variable.getSimpleName().toString()); for (AnnotationMirror annotation: variable.getAnnotationMirrors()) { param.annotate((AbstractJClass)toJType(annotation.getAnnotationType())); } } } } return new ValueVisitorInterfaceModel(visitorInterfaceModel, dataVisitor); } catch (JClassAlreadyExistsException ex) { throw new CodeGenerationException(ex); } }
while (typeElement != null && typeElement.asType().getKind() != TypeKind.NONE) { for (TypeParameterElement typeParameter : typeElement.getTypeParameters()) { List<? extends TypeMirror> bounds = typeParameter.getBounds(); ClassNode typeParam = getClass(bound.toString()); TypeMirror type = typeElement.getSuperclass(); if (type.getKind() != TypeKind.DECLARED) { break; if ((element.getKind() == ElementKind.CLASS || element.getKind() == ElementKind.ENUM) && (element instanceof TypeElement)) {
private MethodSignature getSignature(TypeElement classElement, ExecutableElement element, String[] typeParameters, Types types) { String name = element.getSimpleName().toString(); String[] parameters = new String[element.getParameters().size()]; VariableElement var = element.getParameters().get(i); TypeMirror type = var.asType(); String typeString = null; if (type.getKind() == TypeKind.TYPEVAR) { List<? extends TypeParameterElement> declaredTypeParameters = element.getTypeParameters(); if (declaredTypeParameters.isEmpty()) { declaredTypeParameters = classElement.getTypeParameters(); if (typeParam.getSimpleName().toString().equals(type.toString())) { break; typeString = types.erasure(type).toString();
static MethodSpec.Builder overriding(ExecutableElement method) { String methodName = method.getSimpleName().toString(); MethodSpec.Builder builder = MethodSpec.methodBuilder(methodName) .addAnnotation(Override.class); Set<Modifier> modifiers = method.getModifiers(); modifiers = new LinkedHashSet<>(modifiers); modifiers.remove(Modifier.ABSTRACT); Modifier defaultModifier = null; // Modifier.DEFAULT doesn't exist until Java 8. try { defaultModifier = Modifier.valueOf("DEFAULT"); } catch (IllegalArgumentException e) { // Ignored. } modifiers.remove(defaultModifier); builder = builder.addModifiers(modifiers); for (TypeParameterElement typeParameterElement : method.getTypeParameters()) { TypeVariable var = (TypeVariable) typeParameterElement.asType(); builder = builder.addTypeVariable(TypeVariableName.get(var)); } builder = builder.returns(TypeName.get(method.getReturnType())) .addParameters(getParameters(method)) .varargs(method.isVarArgs()); for (TypeMirror thrownType : method.getThrownTypes()) { builder = builder.addException(TypeName.get(thrownType)); } return builder; }
return handle.typeMirrors == null ? handle : (TypeMirrorHandle<T>)handle.typeMirrors.get(0); map.put(tm, new TypeMirrorHandle(null, null, null)); TypeKind kind = tm.getKind(); ElementHandle<? extends Element> element = null; List<TypeMirrorHandle<? extends TypeMirror>> typeMirrors = null; TypeElement te = (TypeElement)dt.asElement(); element = ElementHandle.create(te); Element encl = te.getEnclosingElement(); genericOuter = (encl.getKind().isClass() || encl.getKind().isInterface()) && !((TypeElement)encl).getTypeParameters().isEmpty() && !te.getModifiers().contains(Modifier.STATIC); if (te.getTypeParameters().isEmpty() && !genericOuter) break; if (targ.getKind() == TypeKind.TYPEVAR) { TypeParameterElement tpe = (TypeParameterElement)((TypeVariable)targ).asElement(); if (tpe.getGenericElement() == dt.asElement()) break; throw new IllegalArgumentException("Currently unsupported TypeKind: " + tm.getKind());
return new JsonRecursiveObject(declaredType.asElement().getSimpleName().toString()); return new JsonArray(new JsonPrimitive(Object.class.getName())); } else { TypeParameterElement elem = ((TypeElement) declaredType.asElement()).getTypeParameters().get(0); return new JsonArray(acceptOrRecurse(o, elem.asType())); if (element.getKind() == ElementKind.ENUM) { List<String> enumConstants = new ArrayList<String>(); for (Element e : element.getEnclosedElements()) { if (e.getKind() == ElementKind.ENUM_CONSTANT) { enumConstants.add(e.toString());
private Map<String, String> computeFormalParameters(TypeElement classElement) { Map<String, String> formalMap = new TreeMap<>(); TypeMirror superclass = classElement.getSuperclass(); while (superclass != null) { TypeElement superclassElement = (TypeElement) processingEnv.getTypeUtils().asElement(superclass); if (superclassElement == null) { break; } List<? extends TypeParameterElement> superClassTypeParameters = superclassElement.getTypeParameters(); for (TypeParameterElement typeParameter : superClassTypeParameters) { String simpleName = typeParameter.getSimpleName().toString(); if (formalMap.containsKey(simpleName)) { continue; } TypeMirror typeMirror = processingEnv.getTypeUtils().asMemberOf((DeclaredType) classElement.asType(), typeParameter); formalMap.put(simpleName, typeMirror.toString()); logDebug(String.format("Add formal parameter: %s → %s", simpleName, typeMirror)); } superclass = superclassElement.getSuperclass(); } return formalMap; }
@Override public Boolean visitTypeVariable(TypeVariable a, EqualVisitorParam p) { if (p.type.getKind().equals(TYPEVAR)) { TypeVariable b = (TypeVariable) p.type; TypeParameterElement aElement = (TypeParameterElement) a.asElement(); TypeParameterElement bElement = (TypeParameterElement) b.asElement(); Set<ComparedElements> newVisiting = visitingSetPlus(p.visiting, aElement, bElement); if (newVisiting.equals(p.visiting)) { // We're already visiting this pair of elements. // This can happen with our friend Eclipse when looking at <T extends Comparable<T>>. // It incorrectly reports the upper bound of T as T itself. return true; } // We use aElement.getBounds() instead of a.getUpperBound() to avoid having to deal with // the different way intersection types (like <T extends Number & Comparable<T>>) are // represented before and after Java 8. We do have an issue that this code may consider // that <T extends Foo & Bar> is different from <T extends Bar & Foo>, but it's very // hard to avoid that, and not likely to be much of a problem in practice. return equalLists(aElement.getBounds(), bElement.getBounds(), newVisiting) && equal(a.getLowerBound(), b.getLowerBound(), newVisiting) && a.asElement().getSimpleName().equals(b.asElement().getSimpleName()); } return false; }
/** * Returns true if the given type parameter has an upper bound of type {@link Object}. * * @param typeParamEl the type parameter * @return true if the given type parameter has an upper bound of type {@link Object} */ public boolean isUpperBoundToObject(TypeParameterElement typeParamEl) { TypeMirror typeParam = typeParamEl.asType(); if (typeParam.getKind() != TypeKind.TYPEVAR) { throw new RuntimeException(String.format("Unexpected kind of type parameter for %s: %s", typeParamEl.getSimpleName(), typeParam.getKind())); } TypeVariable tv = (TypeVariable) typeParam; TypeElement objectElem = elements.getTypeElement(Object.class.getName()); return types.isSameType(objectElem.asType(), tv.getUpperBound()); }
/** * Returns true if the given typeElement is a subtype of the given type parameter's upper bound. * * @param typeElement the type element * @param typeParamEl the type parameter element * @return true if the given typeElement is a subtype of the given type parameter's upper bound */ public boolean matchesUpperBound(TypeElement typeElement, TypeParameterElement typeParamEl) { TypeMirror typeParam = typeParamEl.asType(); if (typeParam.getKind() != TypeKind.TYPEVAR) { throw new RuntimeException(String.format("Unexpected kind of type parameter for %s: %s", typeParamEl.getSimpleName(), typeParam.getKind())); } TypeVariable tv = (TypeVariable) typeParam; return types.isSubtype(typeElement.asType(), tv.getUpperBound()); }
@Test public void testGenericMirror_withSelfReference() { Consumer<DeclaredType> test = foobar -> { // FooBar<E extends FooBar<E>> TypeElement foobarElement = maybeAsTypeElement(foobar).get(); assertThat(foobarElement.getSimpleName().toString()).isEqualTo("FooBar"); assertThat(foobar.getTypeArguments()).hasSize(1); assertThat(SourceBuilder.forTesting().add("%s", foobar).toString()) .isEqualTo("FooBar<E>"); // E extends FooBar<E> TypeParameterElement typeParameter = foobarElement.getTypeParameters().get(0); assertThat(typeParameter.getSimpleName().toString()).isEqualTo("E"); assertThat(typeParameter.getBounds()).hasSize(1); // FooBar<E> DeclaredType bound = maybeDeclared(typeParameter.getBounds().get(0)).get(); assertThat(bound.asElement().getSimpleName().toString()).isEqualTo("FooBar"); assertThat(bound.getTypeArguments()).hasSize(1); // E TypeVariable typeArgument = maybeVariable(bound.getTypeArguments().get(0)).get(); assertThat(typeArgument.asElement()).isEqualTo(typeParameter); }; DeclaredType realFoobar = (DeclaredType) model .newType("package org.example; interface FooBar<E extends FooBar<E>> { }").asType(); GenericElement.Builder fakeFoobarBuilder = new GenericElement.Builder(FOO_BAR_NAME); fakeFoobarBuilder.getTypeParameter("E").addBound(fakeFoobarBuilder.asType()); GenericMirror fakeFoobar = fakeFoobarBuilder.build().asType(); test.accept(realFoobar); test.accept(fakeFoobar); } }
private MutableType handleGenerics(MutableType simpleType, Element element) { if (element.getKind().equals(ElementKind.CLASS) || element.getKind().equals(ElementKind.INTERFACE)) { TypeElement typeElement = (TypeElement)element; if (typeElement.getTypeParameters() != null && typeElement.getTypeParameters().size() > 0) { TypeParameter[] typeParameters = new TypeParameter[typeElement.getTypeParameters().size()]; for (int i = 0; i < typeElement.getTypeParameters().size(); i++) { TypeParameterElement typeParameterElement = typeElement.getTypeParameters().get(i); Type[] boundTypes = new Type[typeParameterElement.getBounds().size()]; for (int j = 0; j < typeParameterElement.getBounds().size(); j++) { TypeMirror typeMirror = typeParameterElement.getBounds().get(j); TypeVariable typeVariable = (TypeVariable)typeParameterElement.asType(); typeMirror = typeVariable.getUpperBound(); Element boundElement = types.asElement(typeMirror); boundTypes[j] = toType(boundElement); } if (typeParameterElement.asType().getKind().equals(TypeKind.TYPEVAR)) { TypeVariable typeVariable = (TypeVariable)typeParameterElement.asType(); typeParameters[i] = TypeParameterBuilder.get(typeVariable.toString(), boundTypes); } else { typeParameters[i] = TypeParameterBuilder.get(boundTypes); } } return TypedClassBuilder.get(simpleType, typeParameters); } } return simpleType; }
/** * Return the type of a type parameter element of a given type element when that type parameter * element is parameterized by a sub type, directly or indirectly. When the type parameter cannot * be resolved, null is returned. * * @param typeUtils the type utils * @param subType the sub type for which the type parameter is parameterized * @param typeParam the type parameter to resolve * @return the type parameterizing the type parameter */ public static TypeMirror resolveTypeParameter(Types typeUtils, DeclaredType subType, TypeParameterElement typeParam) { TypeMirror erased = typeUtils.erasure(typeParam.getGenericElement().asType()); TypeMirror erasedSubType = typeUtils.erasure(subType); if (typeUtils.isSameType(erased, erasedSubType)) { return typeParam.asType(); } else if (typeUtils.isSubtype(erasedSubType, erased)) { for (TypeMirror superType : typeUtils.directSupertypes(subType)) { TypeMirror resolved = resolveTypeParameter(typeUtils, (DeclaredType) superType, typeParam); if (resolved != null) { if (resolved.getKind() == TypeKind.TYPEVAR) { return typeUtils.asMemberOf(subType, ((TypeVariable) resolved).asElement()); } else { return resolved; } } } } return null; }