Search in sources :

Example 46 with TypeParameterElement

use of javax.lang.model.element.TypeParameterElement in project checker-framework by typetools.

the class QualifierDefaults method getWildcardBoundType.

/**
 * @return the BoundType of annotatedWildcard. If it is unbounded, use the type parameter to
 *     which its an argument.
 */
public static BoundType getWildcardBoundType(final AnnotatedWildcardType annotatedWildcard, final AnnotatedTypeFactory typeFactory) {
    final WildcardType wildcard = (WildcardType) annotatedWildcard.getUnderlyingType();
    final BoundType boundType;
    if (wildcard.isUnbound() && wildcard.bound != null) {
        boundType = getTypeVarBoundType((TypeParameterElement) wildcard.bound.asElement(), typeFactory);
    } else {
        // note: isSuperBound will be true for unbounded and lowers, but the unbounded case is
        // already handled
        boundType = wildcard.isSuperBound() ? BoundType.LOWER : BoundType.UPPER;
    }
    return boundType;
}
Also used : AnnotatedWildcardType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType) WildcardType(com.sun.tools.javac.code.Type.WildcardType) TypeParameterElement(javax.lang.model.element.TypeParameterElement)

Example 47 with TypeParameterElement

use of javax.lang.model.element.TypeParameterElement in project lombok by rzwitserloot.

the class HandleDelegate method checkConflictOfTypeVarNames.

/**
 * There's a rare but problematic case if a delegate method has its own type variables, and the delegated type does too, and the method uses both.
 * If for example the delegated type has {@code <E>}, and the method has {@code <T>}, but in our class we have a {@code <T>} at the class level, then we have two different
 * type variables both named {@code T}. We detect this situation and error out asking the programmer to rename their type variable.
 *
 * @throws CantMakeDelegates If there's a conflict. Conflict list is in ex.conflicted.
 */
public void checkConflictOfTypeVarNames(MethodSig sig, JavacNode annotation) throws CantMakeDelegates {
    if (sig.elem.getTypeParameters().isEmpty())
        return;
    Set<String> usedInOurType = new HashSet<String>();
    JavacNode enclosingType = annotation;
    while (enclosingType != null) {
        if (enclosingType.getKind() == Kind.TYPE) {
            List<JCTypeParameter> typarams = ((JCClassDecl) enclosingType.get()).typarams;
            if (typarams != null)
                for (JCTypeParameter param : typarams) {
                    if (param.name != null)
                        usedInOurType.add(param.name.toString());
                }
        }
        enclosingType = enclosingType.up();
    }
    Set<String> usedInMethodSig = new HashSet<String>();
    for (TypeParameterElement param : sig.elem.getTypeParameters()) {
        usedInMethodSig.add(param.getSimpleName().toString());
    }
    usedInMethodSig.retainAll(usedInOurType);
    if (usedInMethodSig.isEmpty())
        return;
    // We might be delegating a List<T>, and we are making method <T> toArray(). A conflict is possible.
    // But only if the toArray method also uses type vars from its class, otherwise we're only shadowing,
    // which is okay as we'll add a @SuppressWarnings.
    FindTypeVarScanner scanner = new FindTypeVarScanner();
    sig.elem.asType().accept(scanner, null);
    Set<String> names = new HashSet<String>(scanner.getTypeVariables());
    names.removeAll(usedInMethodSig);
    if (!names.isEmpty()) {
        // We have a confirmed conflict. We could dig deeper as this may still be a false alarm, but its already an exceedingly rare case.
        CantMakeDelegates cmd = new CantMakeDelegates();
        cmd.conflicted = usedInMethodSig;
        throw cmd;
    }
}
Also used : JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) JCClassDecl(com.sun.tools.javac.tree.JCTree.JCClassDecl) FindTypeVarScanner(lombok.javac.FindTypeVarScanner) JavacNode(lombok.javac.JavacNode) HashSet(java.util.HashSet) TypeParameterElement(javax.lang.model.element.TypeParameterElement)

Example 48 with TypeParameterElement

use of javax.lang.model.element.TypeParameterElement in project revapi by revapi.

the class FormalTypeParametersChanged method doVisit.

private void doVisit(@Nullable JavaModelElement oldElement, @Nullable JavaModelElement newElement) {
    if (!isBothAccessible(oldElement, newElement)) {
        return;
    }
    assert oldElement != null;
    assert newElement != null;
    Parameterizable oldEl = (Parameterizable) oldElement.getDeclaringElement();
    Parameterizable newEl = (Parameterizable) newElement.getDeclaringElement();
    List<? extends TypeParameterElement> oldPars = oldEl.getTypeParameters();
    List<? extends TypeParameterElement> newPars = newEl.getTypeParameters();
    if (oldPars.size() == 0 && oldPars.size() == newPars.size()) {
        return;
    }
    List<TypeParameterElement> added = new ArrayList<>();
    List<TypeParameterElement> removed = new ArrayList<>();
    Map<TypeParameterElement, TypeParameterElement> changed = new LinkedHashMap<>();
    Iterator<? extends TypeParameterElement> oldIt = oldPars.iterator();
    Iterator<? extends TypeParameterElement> newIt = newPars.iterator();
    while (oldIt.hasNext() && newIt.hasNext()) {
        TypeParameterElement oldT = oldIt.next();
        TypeParameterElement newT = newIt.next();
        String oldS = Util.toUniqueString(oldT.asType());
        String newS = Util.toUniqueString(newT.asType());
        if (!oldS.equals(newS)) {
            changed.put(oldT, newT);
        }
    }
    while (oldIt.hasNext()) {
        removed.add(oldIt.next());
    }
    while (newIt.hasNext()) {
        added.add(newIt.next());
    }
    if (!added.isEmpty() || !removed.isEmpty() || !changed.isEmpty()) {
        pushActive(oldElement, newElement, added, removed, changed);
    }
}
Also used : ArrayList(java.util.ArrayList) Parameterizable(javax.lang.model.element.Parameterizable) TypeParameterElement(javax.lang.model.element.TypeParameterElement) LinkedHashMap(java.util.LinkedHashMap)

Example 49 with TypeParameterElement

use of javax.lang.model.element.TypeParameterElement in project revapi by revapi.

the class FormalTypeParametersChanged method doEnd.

@Nullable
@Override
protected List<Difference> doEnd() {
    ActiveElements<JavaModelElement> els = popIfActive();
    if (els == null) {
        return null;
    }
    @SuppressWarnings("unchecked") List<TypeParameterElement> added = (List<TypeParameterElement>) els.context[0];
    @SuppressWarnings("unchecked") List<TypeParameterElement> removed = (List<TypeParameterElement>) els.context[1];
    @SuppressWarnings("unchecked") Map<TypeParameterElement, TypeParameterElement> changed = (Map<TypeParameterElement, TypeParameterElement>) els.context[2];
    Parameterizable oldT = (Parameterizable) els.oldElement.getDeclaringElement();
    List<Difference> diffs = new ArrayList<>();
    if (oldT.getTypeParameters().isEmpty()) {
        diffs.add(createDifference(Code.GENERICS_ELEMENT_NOW_PARAMETERIZED, Code.attachmentsFor(els.oldElement, els.newElement)));
    }
    for (TypeParameterElement e : added) {
        diffs.add(createDifferenceWithExplicitParams(Code.GENERICS_FORMAL_TYPE_PARAMETER_ADDED, Code.attachmentsFor(els.oldElement, els.newElement), Util.toHumanReadableString(e)));
    }
    for (TypeParameterElement e : removed) {
        diffs.add(createDifferenceWithExplicitParams(Code.GENERICS_FORMAL_TYPE_PARAMETER_REMOVED, Code.attachmentsFor(els.oldElement, els.newElement), Util.toHumanReadableString(e)));
    }
    for (Map.Entry<TypeParameterElement, TypeParameterElement> e : changed.entrySet()) {
        String oldP = Util.toHumanReadableString(e.getKey());
        String newP = Util.toHumanReadableString(e.getValue());
        diffs.add(createDifferenceWithExplicitParams(Code.GENERICS_FORMAL_TYPE_PARAMETER_CHANGED, Code.attachmentsFor(els.oldElement, els.newElement, "oldTypeParameter", oldP, "newTypeParameter", newP), oldP, newP));
    }
    return diffs;
}
Also used : JavaModelElement(org.revapi.java.spi.JavaModelElement) ArrayList(java.util.ArrayList) Difference(org.revapi.Difference) TypeParameterElement(javax.lang.model.element.TypeParameterElement) Parameterizable(javax.lang.model.element.Parameterizable) ArrayList(java.util.ArrayList) List(java.util.List) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) Nullable(javax.annotation.Nullable)

Example 50 with TypeParameterElement

use of javax.lang.model.element.TypeParameterElement in project Rocket by mozilla-tw.

the class RequestOptionsGenerator method generateStaticMethodEquivalentForExtensionMethod.

private MethodAndStaticVar generateStaticMethodEquivalentForExtensionMethod(ExecutableElement instanceMethod) {
    boolean skipStaticMethod = skipStaticMethod(instanceMethod);
    if (skipStaticMethod) {
        return new MethodAndStaticVar();
    }
    String staticMethodName = getStaticMethodName(instanceMethod);
    String instanceMethodName = instanceMethod.getSimpleName().toString();
    if (Strings.isNullOrEmpty(staticMethodName)) {
        if (instanceMethodName.startsWith("dont")) {
            staticMethodName = "no" + instanceMethodName.replace("dont", "");
        } else {
            staticMethodName = instanceMethodName + "Of";
        }
    }
    boolean memoize = memoizeStaticMethodFromAnnotation(instanceMethod);
    MethodSpec.Builder methodSpecBuilder = MethodSpec.methodBuilder(staticMethodName).addModifiers(Modifier.PUBLIC, Modifier.STATIC).addJavadoc(processorUtil.generateSeeMethodJavadoc(instanceMethod)).returns(glideOptionsName);
    List<? extends VariableElement> parameters = instanceMethod.getParameters();
    // but should not itself require a RequestOptions object to be passed in.
    if (parameters.isEmpty()) {
        throw new IllegalArgumentException("Expected non-empty parameters for: " + instanceMethod);
    }
    // Remove is not supported.
    parameters = parameters.subList(1, parameters.size());
    String createNewOptionAndCall = "new $T().$L(";
    if (!parameters.isEmpty()) {
        for (VariableElement parameter : parameters) {
            methodSpecBuilder.addParameter(getParameterSpec(parameter));
            createNewOptionAndCall += parameter.getSimpleName().toString();
            // use the Application Context to avoid memory leaks.
            if (memoize && isAndroidContext(parameter)) {
                createNewOptionAndCall += ".getApplicationContext()";
            }
            createNewOptionAndCall += ", ";
        }
        createNewOptionAndCall = createNewOptionAndCall.substring(0, createNewOptionAndCall.length() - 2);
    }
    createNewOptionAndCall += ")";
    FieldSpec requiredStaticField = null;
    if (memoize) {
        // if (GlideOptions.<methodName> == null) {
        // GlideOptions.<methodName> = new GlideOptions().<methodName>().autoClone()
        // }
        // Mix in an incrementing unique id to handle method overloading.
        String staticVariableName = staticMethodName + nextStaticFieldUniqueId++;
        requiredStaticField = FieldSpec.builder(glideOptionsName, staticVariableName).addModifiers(Modifier.PRIVATE, Modifier.STATIC).build();
        methodSpecBuilder.beginControlFlow("if ($T.$N == null)", glideOptionsName, staticVariableName).addStatement("$T.$N =\n" + createNewOptionAndCall + ".$N", glideOptionsName, staticVariableName, glideOptionsName, instanceMethodName, "autoClone()").endControlFlow().addStatement("return $T.$N", glideOptionsName, staticVariableName);
    } else {
        // return new GlideOptions().<methodName>()
        methodSpecBuilder.addStatement("return " + createNewOptionAndCall, glideOptionsName, instanceMethodName);
    }
    List<? extends TypeParameterElement> typeParameters = instanceMethod.getTypeParameters();
    for (TypeParameterElement typeParameterElement : typeParameters) {
        methodSpecBuilder.addTypeVariable(TypeVariableName.get(typeParameterElement.getSimpleName().toString()));
    }
    methodSpecBuilder.addAnnotation(AnnotationSpec.builder(CHECK_RESULT_CLASS_NAME).build());
    return new MethodAndStaticVar(methodSpecBuilder.build(), requiredStaticField);
}
Also used : MethodSpec(com.squareup.javapoet.MethodSpec) VariableElement(javax.lang.model.element.VariableElement) FieldSpec(com.squareup.javapoet.FieldSpec) TypeParameterElement(javax.lang.model.element.TypeParameterElement)

Aggregations

TypeParameterElement (javax.lang.model.element.TypeParameterElement)66 TypeElement (javax.lang.model.element.TypeElement)30 TypeMirror (javax.lang.model.type.TypeMirror)26 Test (org.junit.Test)18 ExecutableElement (javax.lang.model.element.ExecutableElement)13 TypeVariable (javax.lang.model.type.TypeVariable)13 Element (javax.lang.model.element.Element)10 VariableElement (javax.lang.model.element.VariableElement)9 ArrayList (java.util.ArrayList)7 LinkedHashMap (java.util.LinkedHashMap)7 List (java.util.List)7 DeclaredType (javax.lang.model.type.DeclaredType)7 MethodSpec (com.squareup.javapoet.MethodSpec)6 Map (java.util.Map)6 FieldSpec (com.squareup.javapoet.FieldSpec)5 HashSet (java.util.HashSet)4 Modifier (javax.lang.model.element.Modifier)4 ArrayType (javax.lang.model.type.ArrayType)4 Types (javax.lang.model.util.Types)4 MoreElements (com.google.auto.common.MoreElements)3