/** * The type parameters to place on the builder, with the "extends ..." bounds. */ String alligatorWithBounds() { List<TypeParameterElement> allParameters = allParameters(); if (allParameters.isEmpty()) { return ""; } StringBuilder alligator = new StringBuilder("<"); String separator = ""; for (TypeParameterElement param : allParameters) { alligator.append(separator); separator = ", "; alligator.append(param.toString()); for (TypeMirror bound : param.getBounds()) { alligator.append(" extends ").append(bound); } } return alligator.append(">").toString(); }
private Map<TypeParameterElement, TypeMirror> getChildInstanceOfClassFromGeneric(final TypeElement typeElement, final Class<?> aClass) { Map<TypeParameterElement, TypeMirror> result = new HashMap<>(); for (TypeParameterElement element : typeElement.getTypeParameters()) { List<? extends TypeMirror> bounds = element.getBounds(); for (TypeMirror bound : bounds) { if (bound instanceof DeclaredType && ((DeclaredType) bound).asElement() instanceof TypeElement) { Collection<TypeMirror> viewsType = getViewsType((TypeElement) ((DeclaredType) bound).asElement()); boolean isViewType = false; for (TypeMirror viewType : viewsType) { if (((DeclaredType) viewType).asElement().toString().equals(aClass.getCanonicalName())) { isViewType = true; } } if (isViewType) { result.put(element, bound); break; } } } } return result; }
TypevarContext(TypeElement element, String renderedTypeString) { List<? extends TypeParameterElement> typeParameters = element.getTypeParameters(); if (!typeParameters.isEmpty()) { this.arguments = SourceTypes.extract(renderedTypeString).getValue(); this.parameters = Lists.newArrayList(); for (TypeParameterElement p : typeParameters) { parameters.add(p.getSimpleName().toString()); } // we allow having no arguments in a string as raw type/unspecified argument scenario Verify.verify(arguments.isEmpty() || (parameters.size() == arguments.size()), parameters + " =/> " + arguments); } else { this.parameters = Collections.emptyList(); this.arguments = Collections.emptyList(); } }
private TypeExtractor processTypeParameters(ExecutableElement method, EncodedElement.Builder builder) { boolean isStatic = method.getModifiers().contains(Modifier.STATIC); TypeExtractor typesReader = isStatic ? new TypeExtractor(types, method) : this.typesReader; for (TypeParameterElement p : method.getTypeParameters()) { String name = p.getSimpleName().toString(); ImmutableList<Defined> bounds = typesReader.getDefined(p.getBounds()); if (!isStatic) { typesReader = typesReader.withParameter(name, bounds); } builder.addTypeParams(new EncodedElement.TypeParam.Builder() .name(name) .addAllBounds(bounds) .build()); } builder.typeParameters(typesReader.parameters); return typesReader; }
/** * Makes a list of trees representing the given type parameter elements. */ private static List<TypeParameterTree> makeTypeParamsCopy( List<? extends TypeParameterElement> typeParams, TreeMaker maker) { if (typeParams.isEmpty()) { return Collections.emptyList(); } int size = typeParams.size(); if (size == 1) { return Collections.singletonList(makeCopy(typeParams.get(0), maker)); } List<TypeParameterTree> result = new ArrayList(size); for (TypeParameterElement typeParam : typeParams) { result.add(makeCopy(typeParam, maker)); } return result; }
@Override void initialize(final Element element, CompilationController info) { final String labelText; if(element.getKind() == ElementKind.TYPE_PARAMETER) { labelText = UIUtilities.createHeader((TypeParameterElement) element, info.getElements().isDeprecated(element), false, false, true); } else { labelText = UIUtilities.createHeader((VariableElement) element, info.getElements().isDeprecated(element), false, false, true); } final Icon labelIcon = ElementIcons.getElementIcon(element.getKind(), element.getModifiers()); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { Dimension preferredSize = label.getPreferredSize(); label.setText(labelText); label.setIcon(labelIcon); label.setPreferredSize(preferredSize); label.setMinimumSize(preferredSize); } }); }
private boolean deepSearchTypes(DeclaredType currentElement, TypeMirror orig, TypeMirror something, Map<TypeMirror, TypeParameterElement> mappings) { Types types = workingCopy.getTypes(); List<? extends TypeMirror> directSupertypes = types.directSupertypes(currentElement); for (TypeMirror superType : directSupertypes) { DeclaredType type = (DeclaredType) superType; List<? extends TypeMirror> typeArguments = type.getTypeArguments(); for (int i = 0; i < typeArguments.size(); i++) { TypeMirror typeArgument = typeArguments.get(i); if (something.equals(typeArgument)) { TypeElement asElement = (TypeElement) type.asElement(); mappings.put(orig, asElement.getTypeParameters().get(i)); if (types.erasure(targetType.asType()).equals(types.erasure(superType))) { return true; } if(deepSearchTypes(type, orig, typeArgument, mappings)) { break; } } } if (types.erasure(targetType.asType()).equals(types.erasure(superType))) { mappings.remove(orig); return true; } } return false; }
public Boolean visitType(TypeElement arg0, Void arg1) { for (TypeParameterElement e : arg0.getTypeParameters()) { if (stop) { return false; } for (TypeMirror b : e.getBounds()) { if (stop) { return false; } if (b.accept(this, arg1)) { return true; } } } TypeMirror superclass = arg0.getSuperclass(); if (superclass.getKind() == TypeKind.DECLARED) { if (!((DeclaredType) superclass).asElement().getKind().isInterface()) { return false; } } return superclass.accept(this, arg1); }
private void completeTypeVarName(Element forElement, String prefix, int substitutionOffset) { if (prefix.length() > 0) { if (prefix.charAt(0) == '<') { prefix = prefix.substring(1, prefix.length()); } else { // not type param return; } } List<? extends TypeParameterElement> tparams = (forElement.getKind().isClass() || forElement.getKind().isInterface()) ? ((TypeElement) forElement).getTypeParameters() : ((ExecutableElement) forElement).getTypeParameters(); for (TypeParameterElement typeVariable : tparams) { String name = typeVariable.getSimpleName().toString(); if (name.startsWith(prefix)) { items.add(JavadocCompletionItem.createNameItem( '<' + name + '>', substitutionOffset)); } } }
private void dumpTypeArguments(List<? extends TypeParameterElement> list) { if (list.isEmpty()) { return ; } boolean addSpace = false; result.append("<"); for (TypeParameterElement e : list) { if (addSpace) { result.append(", "); } result.append(getTypeName(info, e.asType(), true)); addSpace = true; } result.append(">"); }
public String generateComment(TypeElement clazz, CompilationInfo javac) { StringBuilder builder = new StringBuilder( // "/**\n" + // NOI18N "\n" // NOI18N ); if (clazz.getNestingKind() == NestingKind.TOP_LEVEL) { builder.append("@author ").append(author).append("\n"); // NOI18N } if (SourceVersion.RELEASE_5.compareTo(srcVersion) <= 0) { for (TypeParameterElement param : clazz.getTypeParameters()) { builder.append("@param <").append(param.getSimpleName().toString()).append("> \n"); // NOI18N } } if (SourceVersion.RELEASE_5.compareTo(srcVersion) <= 0 && JavadocUtilities.isDeprecated(javac, clazz)) { builder.append("@deprecated\n"); // NOI18N } // builder.append("*/\n"); // NOI18N return builder.toString(); }
public static Spec parse(Element element, ProcessingEnvironment processingEnv) { Messager messager = processingEnv.getMessager(); if (element.getKind() != ElementKind.INTERFACE) { messager.printMessage( Diagnostic.Kind.ERROR, "@DataEnum can only be used on interfaces.", element); return null; } TypeElement dataEnum = (TypeElement) element; List<TypeVariableName> typeVariableNames = new ArrayList<>(); for (TypeParameterElement typeParameterElement : dataEnum.getTypeParameters()) { typeVariableNames.add(TypeVariableName.get(typeParameterElement)); } List<Value> values = ValuesParser.parse(dataEnum, processingEnv); if (values == null) { return null; } ClassName enumInterface = ClassName.get(dataEnum); return new Spec(enumInterface, typeVariableNames, values); }
private void printFormalTypeParameters(Parameterizable e, boolean pad) { List<? extends TypeParameterElement> typeParams = e.getTypeParameters(); if (typeParams.size() > 0) { writer.print("<"); boolean first = true; for(TypeParameterElement tpe: typeParams) { if (!first) writer.print(", "); printAnnotationsInline(tpe); writer.print(tpe.toString()); first = false; } writer.print(">"); if (pad) writer.print(" "); } }
void writeType(TypeElement e) { if (!acceptType.test(task.getElements().getBinaryName(e).toString())) return ; try { analyzeElement(e); writeTypes(e.getInterfaces()); out.write(e.getNestingKind().toString()); out.write(e.getQualifiedName().toString()); write(e.getSuperclass()); for (TypeParameterElement param : e.getTypeParameters()) { visit(param, null); } List<Element> defs = new ArrayList<>(e.getEnclosedElements()); //XXX: forcing ordering for members - not completely correct! Collections.sort(defs, (e1, e2) -> e1.toString().compareTo(e2.toString())); for (Element def : defs) { visit(def, null); } out.write("\n"); } catch (IOException ex) { ex.printStackTrace(); } }
@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; }
/** * Make a TypeVariableName for the given TypeMirror. This form is used internally to avoid * infinite recursion in cases like {@code Enum<E extends Enum<E>>}. When we encounter such a * thing, we will make a TypeVariableName without bounds and add that to the {@code typeVariables} * map before looking up the bounds. Then if we encounter this TypeVariable again while * constructing the bounds, we can just return it from the map. And, the code that put the entry * in {@code variables} will make sure that the bounds are filled in before returning. */ static com.wrmsr.wava.java.poet.TypeVariableName get( TypeVariable mirror, Map<TypeParameterElement, com.wrmsr.wava.java.poet.TypeVariableName> typeVariables) { TypeParameterElement element = (TypeParameterElement) mirror.asElement(); com.wrmsr.wava.java.poet.TypeVariableName typeVariableName = typeVariables.get(element); if (typeVariableName == null) { // Since the bounds field is public, we need to make it an unmodifiableList. But we control // the List that that wraps, which means we can change it before returning. List<TypeName> bounds = new ArrayList<>(); List<TypeName> visibleBounds = Collections.unmodifiableList(bounds); typeVariableName = new com.wrmsr.wava.java.poet.TypeVariableName(element.getSimpleName().toString(), visibleBounds); typeVariables.put(element, typeVariableName); for (TypeMirror typeMirror : element.getBounds()) { bounds.add(TypeName.get(typeMirror, typeVariables)); } bounds.remove(OBJECT); } return typeVariableName; }
static TypeName get( javax.lang.model.type.WildcardType mirror, Map<TypeParameterElement, TypeVariableName> typeVariables) { TypeMirror extendsBound = mirror.getExtendsBound(); if (extendsBound == null) { TypeMirror superBound = mirror.getSuperBound(); if (superBound == null) { return subtypeOf(Object.class); } else { return supertypeOf(TypeName.get(superBound, typeVariables)); } } else { return subtypeOf(TypeName.get(extendsBound, typeVariables)); } }
@Test public void getTypeVariableTypeMirror() { List<? extends TypeParameterElement> typeVariables = getElement(Parameterized.class).getTypeParameters(); // Members of converted types use ClassName and not Class<?>. ClassName number = ClassName.get(Number.class); ClassName runnable = ClassName.get(Runnable.class); ClassName serializable = ClassName.get(Serializable.class); assertThat(TypeName.get(typeVariables.get(0).asType())) .isEqualTo(TypeVariableName.get("Simple")); assertThat(TypeName.get(typeVariables.get(1).asType())) .isEqualTo(TypeVariableName.get("ExtendsClass", number)); assertThat(TypeName.get(typeVariables.get(2).asType())) .isEqualTo(TypeVariableName.get("ExtendsInterface", runnable)); assertThat(TypeName.get(typeVariables.get(3).asType())) .isEqualTo(TypeVariableName.get("ExtendsTypeVariable", TypeVariableName.get("Simple"))); assertThat(TypeName.get(typeVariables.get(4).asType())) .isEqualTo(TypeVariableName.get("Intersection", number, runnable)); assertThat(TypeName.get(typeVariables.get(5).asType())) .isEqualTo(TypeVariableName.get("IntersectionOfInterfaces", runnable, serializable)); assertThat(((TypeVariableName) TypeName.get(typeVariables.get(4).asType())).bounds) .containsExactly(number, runnable); }
@Override public Void visitTypeVariable(AnnotatedTypeVariable type, GlacierAnnotatedTypeFactory p) { TypeParameterElement tpelt = (TypeParameterElement) type.getUnderlyingType().asElement(); if (!visited.containsKey(tpelt)) { visited.put(tpelt, type); if (type.getAnnotations().isEmpty() && type.getUpperBound().getAnnotations().isEmpty() && tpelt.getEnclosingElement().getKind() != ElementKind.TYPE_PARAMETER) { ElementAnnotationApplier.apply(type, tpelt, p); } super.visitTypeVariable(type, p); visited.remove(tpelt); } return null; }
public RuntimePermissionsElement(TypeElement element, TypeResolver resolver) { mTypeResolver = resolver; mTypeName = TypeName.get(element.asType()); typeVariables = new ArrayList<>(); List<? extends TypeParameterElement> typeParameters = element.getTypeParameters(); for (TypeParameterElement element1 : typeParameters) { typeVariables.add(TypeVariableName.get(element1)); } String claseName = element.getQualifiedName().toString(); packageName = ProcessorUtil.getPackageName(claseName); className = ProcessorUtil.getClassName(claseName); classType = checkActivity(element, resolver); generatedClassName = element.getSimpleName().toString() + ConstantsProvider.GEN_CLASS_SUFFIX; needsPermissionsMethods = findMethods(element, NeedsPermission.class); validateNeedsMethods(); showsRationaleMethods = findMethods(element, OnShowRationale.class); validateRationaleMethods(); deniedPermissionMethods = findMethods(element, OnPermissionDenied.class); validateDeniedMethods(); neverAskMethods = findMethods(element, OnNeverAskAgain.class); validateNeverAskMethods(); }
private int getFactoryProxyIndex(TypeName gtname) throws AnnotationProcessingException { int ret = -1; boolean found = false; if (gtname instanceof TypeVariableName) { for (TypeParameterElement tpe : m_elem.getTypeParameters()) { ++ret; if (tpe.toString().equals(gtname.toString())) { found = true; break; } } if (!found) { throw new AnnotationProcessingException(null, "%s type is not found during factory proxy query.", gtname.toString()); } } else { throw new AnnotationProcessingException(null, "%s type is not generic type for factory proxy query.", gtname.toString()); } return ret; }
/** * Make a TypeVariableName for the given TypeMirror. This form is used internally to avoid * infinite recursion in cases like {@code Enum<E extends Enum<E>>}. When we encounter such a * thing, we will make a TypeVariableName without bounds and add that to the {@code typeVariables} * map before looking up the bounds. Then if we encounter this TypeVariable again while * constructing the bounds, we can just return it from the map. And, the code that put the entry * in {@code variables} will make sure that the bounds are filled in before returning. */ static TypeVariableName get( TypeVariable mirror, Map<TypeParameterElement, TypeVariableName> typeVariables) { TypeParameterElement element = (TypeParameterElement) mirror.asElement(); TypeVariableName typeVariableName = typeVariables.get(element); if (typeVariableName == null) { // Since the bounds field is public, we need to make it an unmodifiableList. But we control // the List that that wraps, which means we can change it before returning. List<TypeName> bounds = new ArrayList<>(); List<TypeName> visibleBounds = Collections.unmodifiableList(bounds); typeVariableName = new TypeVariableName(element.getSimpleName().toString(), visibleBounds); typeVariables.put(element, typeVariableName); for (TypeMirror typeMirror : element.getBounds()) { bounds.add(TypeName.get(typeMirror, typeVariables)); } bounds.remove(OBJECT); } return typeVariableName; }
@Override public void addTo(SourceBuilder source) { if (!typeParameters.isEmpty()) { String prefix = "<"; for (Object typeParameter : typeParameters) { source.add("%s%s", prefix, typeParameter); if (typeParameter instanceof TypeParameterElement) { TypeParameterElement element = (TypeParameterElement) typeParameter; if (!extendsObject(element)) { String separator = " extends "; for (TypeMirror bound : element.getBounds()) { source.add("%s%s", separator, bound); separator = " & "; } } } prefix = ", "; } source.add(">"); } }
@Override public TypeKey visitTypeVariable(TypeVariable t, Set<TypeParameterElement> visited) { TypeParameterElement element = (TypeParameterElement) t.asElement(); if (visited.contains(element)) { // This avoids infinite recursion with adapted types like <T extends Comparable<T>>. // It should probably check that T is bound correctly, but this is unlikely to be an issue // in the wild. return AnyKey.get(t.toString()); } visited.add(element); ImmutableList.Builder<TypeKey> builder = ImmutableList.builder(); for (TypeMirror bound : element.getBounds()) { TypeKey boundKey = bound.accept(this, visited); if (!boundKey.equals(OBJECT)) { builder.add(boundKey); } } ImmutableList<TypeKey> bounds = builder.build(); if (bounds.size() == 0) { return AnyKey.get(t.toString()); } else { return BoundedKey.get(t.toString(), bounds); } }
private String getViewClassFromGeneric(TypeElement typeElement) { TypeMirror superclass = typeElement.asType(); Map<String, String> parentTypes = Collections.emptyMap(); if (!typeElement.getTypeParameters().isEmpty()) { MvpCompiler.getMessager().printMessage(Diagnostic.Kind.WARNING, "Your " + typeElement.getSimpleName() + " is typed. @InjectViewState may generate wrong code. Your can set view/view state class manually."); } while (superclass.getKind() != TypeKind.NONE) { TypeElement superclassElement = (TypeElement) ((DeclaredType) superclass).asElement(); final List<? extends TypeMirror> typeArguments = ((DeclaredType) superclass).getTypeArguments(); final List<? extends TypeParameterElement> typeParameters = superclassElement.getTypeParameters(); if (typeArguments.size() > typeParameters.size()) { throw new IllegalArgumentException("Code generation for interface " + typeElement.getSimpleName() + " failed. Simplify your generics. (" + typeArguments + " vs " + typeParameters + ")"); } Map<String, String> types = new HashMap<>(); for (int i = 0; i < typeArguments.size(); i++) { types.put(typeParameters.get(i).toString(), fillGenerics(parentTypes, typeArguments.get(i))); } if (superclassElement.toString().equals(MVP_PRESENTER_CLASS)) { // MvpPresenter is typed only on View class return fillGenerics(parentTypes, typeArguments); } parentTypes = types; superclass = superclassElement.getSuperclass(); } return ""; }
private List<Method> iterateInterfaces(int level, TypeElement parentElement, String parentDefaultStrategy, Map<String, String> parentTypes, List<Method> rootMethods, List<Method> superinterfacesMethods) { for (TypeMirror typeMirror : parentElement.getInterfaces()) { final TypeElement anInterface = (TypeElement) ((DeclaredType) typeMirror).asElement(); final List<? extends TypeMirror> typeArguments = ((DeclaredType) typeMirror).getTypeArguments(); final List<? extends TypeParameterElement> typeParameters = anInterface.getTypeParameters(); if (typeArguments.size() > typeParameters.size()) { throw new IllegalArgumentException("Code generation for interface " + anInterface.getSimpleName() + " failed. Simplify your generics."); } Map<String, String> types = new HashMap<>(); for (int i = 0; i < typeArguments.size(); i++) { types.put(typeParameters.get(i).toString(), typeArguments.get(i).toString()); } Map<String, String> totalInterfaceTypes = new HashMap<>(typeParameters.size()); for (int i = 0; i < typeArguments.size(); i++) { totalInterfaceTypes.put(typeParameters.get(i).toString(), fillGenerics(parentTypes, typeArguments.get(i))); } for (int i = typeArguments.size(); i < typeParameters.size(); i++) { if (typeParameters.get(i).getBounds().size() != 1) { throw new IllegalArgumentException("Code generation for interface " + anInterface.getSimpleName() + " failed. Simplify your generics."); } totalInterfaceTypes.put(typeParameters.get(i).toString(), typeParameters.get(i).getBounds().get(0).toString()); } String defaultStrategy = parentDefaultStrategy != null ? parentDefaultStrategy : getStateStrategyType(anInterface); getMethods(totalInterfaceTypes, anInterface, defaultStrategy, rootMethods, superinterfacesMethods); iterateInterfaces(level + 1, anInterface, defaultStrategy, types, rootMethods, superinterfacesMethods); } return superinterfacesMethods; }
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; }
@Override public List<? extends TypeParameterElement> getTypeParameters() { List<? extends TypeParameterElement> tps = typeParameters; if (tps == null) { tps = delegate.getTypeParameters(); typeParameters = tps; } return tps; }
private static String[] collectVars(List<? extends TypeParameterElement> typeParameters) { String[] vars = new String[typeParameters.size()]; int c = 0; for (TypeParameterElement p : typeParameters) { vars[c++] = p.getSimpleName().toString(); } return vars; }
private Type.Parameters initParameters(Parameterizable context) { Type.Parameters parameters = factory.parameters(); for (TypeParameterElement p : context.getTypeParameters()) { String name = p.getSimpleName().toString(); // <T extends Cls<T>>: when parsing bounds for T, T should be already defined for recursion Type.Parameters parameterForRecursion = parameters.recursive(name); List<Type.Defined> bounds = getBounds(parameterForRecursion, p); parameters = parameters.introduce(name, bounds); } return parameters; }
private List<Type.Defined> getBounds(Type.Parameters parameters, TypeParameterElement p) { List<Type.Defined> bounds = new ArrayList<>(); for (TypeMirror b : p.getBounds()) { bounds.add((Type.Defined) b.accept(converter, parameters)); } return bounds; }
private List<String> getTypeParameterNames(Parameterizable element) { List<String> names = new ArrayList<>(); for (TypeParameterElement p : element.getTypeParameters()) { names.add(p.getSimpleName().toString()); } return names; }