Search in sources :

Example 36 with Types

use of javax.lang.model.util.Types in project CoreData by FangCloud-Android.

the class ReplaceInternalMethod method bind.

private void bind(MethodSpec.Builder builder) {
    Types typeUtils = processingEnv.getTypeUtils();
    TypeName typeEntity = ClassName.get(entityDetail.getEntityElement().asType());
    ParameterizedTypeName typeListEntity = ParameterizedTypeName.get(ClassName.get(ArrayList.class), typeEntity);
    builder.addStatement("$T $N = new $T()", typeListEntity, entityDetail.getEntityElement().getSimpleName() + "List", typeListEntity);
    List<Element> relationElements = entityDetail.getRelationElements();
    for (Element relationElement : relationElements) {
        Element typeRelationElement = typeUtils.asElement(relationElement.asType());
        TypeName typeRelation = ClassName.get(relationElement.asType());
        ParameterizedTypeName typeListRelation = ParameterizedTypeName.get(ClassName.get(ArrayList.class), typeRelation);
        builder.addStatement("$T $N = new $T()", typeListRelation, typeRelationElement.getSimpleName() + "List", typeListRelation);
    }
    builder.addCode("for ($T item : collection) {\n  ", typeEntity);
    builder.addStatement("$N.add($N)", entityDetail.getEntityElement().getSimpleName() + "List", "item");
    for (Element relationElement : relationElements) {
        Element typeRelationElement = typeUtils.asElement(relationElement.asType());
        TypeName typeRelation = ClassName.get(relationElement.asType());
        relationElement.getSimpleName();
        String methodGet = Utils.methodGet(relationElement, "item");
        builder.addCode("if($N != null){\n  ", methodGet);
        builder.addStatement("$N.add($N)", typeRelationElement.getSimpleName() + "List", methodGet);
        builder.addCode("}\n");
    }
    builder.addCode("}\n");
    builder.addStatement("executeInsert($N, db)", entityDetail.getEntityElement().getSimpleName() + "List");
    for (Element relationElement : relationElements) {
        Element typeRelationElement = typeUtils.asElement(relationElement.asType());
        ClassName classNameRelation = ClassName.bestGuess(relationElement.asType().toString());
        String relationDaoName = Utils.relationDaoName(classNameRelation);
        builder.addStatement("$N.replace($N, db)", relationDaoName, typeRelationElement.getSimpleName() + "List");
    }
}
Also used : Types(javax.lang.model.util.Types) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName) TypeName(com.squareup.javapoet.TypeName) Element(javax.lang.model.element.Element) TypeElement(javax.lang.model.element.TypeElement) ArrayList(java.util.ArrayList) ClassName(com.squareup.javapoet.ClassName) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName)

Example 37 with Types

use of javax.lang.model.util.Types in project checker-framework by typetools.

the class KeyForPropagator method propagate.

/**
 * Propagate annotations from the type arguments of one type to another. Which type is the source
 * and destination of the annotations depends on the direction parameter. Only @KeyFor annotations
 * are propagated and only if the type to which it would be propagated contains an @UnknownKeyFor
 * or contains no key for annotations of any kind. If any of the type arguments are wildcards than
 * they are ignored.
 *
 * <p>Note the primary annotations of subtype/supertype are not used.
 *
 * <p>Simple Example:
 *
 * <pre>{@code
 * typeOf(subtype) = ArrayList<@KeyFor("a") String>
 * typeOf(supertype) = List<@UnknownKeyFor String>
 * direction = TO_SUPERTYPE
 * }</pre>
 *
 * The type of supertype after propagate would be: {@code List<@KeyFor("a") String>}
 *
 * <p>A more complex example would be:
 *
 * <pre>{@code
 * typeOf(subtype) = HashMap<@UnknownKeyFor String, @KeyFor("b") List<@KeyFor("c") String>>
 * typeOf(supertype) = Map<@KeyFor("a") String, @KeyFor("b") List<@KeyFor("c") String>>
 * direction = TO_SUBTYPE
 * }</pre>
 *
 * The type of subtype after propagate would be: {@code HashMap<@KeyFor("a") String, @KeyFor("b")
 * List<@KeyFor("c") String>>}
 */
public void propagate(final AnnotatedDeclaredType subtype, final AnnotatedDeclaredType supertype, PropagationDirection direction, final AnnotatedTypeFactory typeFactory) {
    final TypeElement subtypeElement = (TypeElement) subtype.getUnderlyingType().asElement();
    final TypeElement supertypeElement = (TypeElement) supertype.getUnderlyingType().asElement();
    final Types types = typeFactory.getProcessingEnv().getTypeUtils();
    // Note: The right hand side of this or expression will cover raw types
    if (subtype.getTypeArguments().isEmpty()) {
        return;
    }
    // In either case, there is no reason to propagate
    if (supertype.getTypeArguments().isEmpty()) {
        return;
    }
    Set<Pair<Integer, Integer>> typeParamMappings = TypeArgumentMapper.mapTypeArgumentIndices(subtypeElement, supertypeElement, types);
    final List<AnnotatedTypeMirror> subtypeArgs = subtype.getTypeArguments();
    final List<AnnotatedTypeMirror> supertypeArgs = supertype.getTypeArguments();
    for (final Pair<Integer, Integer> path : typeParamMappings) {
        final AnnotatedTypeMirror subtypeArg = subtypeArgs.get(path.first);
        final AnnotatedTypeMirror supertypeArg = supertypeArgs.get(path.second);
        if (subtypeArg.getKind() == TypeKind.WILDCARD || supertypeArg.getKind() == TypeKind.WILDCARD) {
            continue;
        }
        switch(direction) {
            case TO_SUBTYPE:
                replacer.visit(supertypeArg, subtypeArg);
                break;
            case TO_SUPERTYPE:
                replacer.visit(subtypeArg, supertypeArg);
                break;
            case BOTH:
                // note if they both have an annotation nothing will happen
                replacer.visit(subtypeArg, supertypeArg);
                replacer.visit(supertypeArg, subtypeArg);
                break;
        }
    }
}
Also used : Types(javax.lang.model.util.Types) TypeElement(javax.lang.model.element.TypeElement) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) Pair(org.checkerframework.javacutil.Pair)

Example 38 with Types

use of javax.lang.model.util.Types in project checker-framework by typetools.

the class AnnotatedTypes method annotatedGLB.

/**
 * Returns the "annotated greatest lower bound" of {@code type1} and {@code type2}.
 *
 * <p>Suppose that there is an expression e with annotated type T. The underlying type of T must
 * be the same as javac's type for e. (This is a requirement of the Checker Framework.) As a
 * corollary, when computing a glb of atype1 and atype2, it is required that
 * underlyingType(cfGLB(atype1, atype2) == glb(javacGLB(underlyingType(atype1),
 * underlyingType(atype2)). Because of this requirement, the return value of this method (the
 * "annotated GLB") may not be a subtype of one of the types.
 *
 * <p>The "annotated greatest lower bound" is defined as follows:
 *
 * <ol>
 *   <li>If the underlying type of {@code type1} and {@code type2} are the same, then return a
 *       copy of {@code type1} whose primary annotations are the greatest lower bound of the
 *       primary annotations on {@code type1} and {@code type2}.
 *   <li>If the underlying type of {@code type1} is a subtype of the underlying type of {@code
 *       type2}, then return a copy of {@code type1} whose primary annotations are the greatest
 *       lower bound of the primary annotations on {@code type1} and {@code type2}.
 *   <li>If the underlying type of {@code type1} is a supertype of the underlying type of {@code
 *       type2}, then return a copy of {@code type2} whose primary annotations are the greatest
 *       lower bound of the primary annotations on {@code type1} and {@code type2}.
 *   <li>If the underlying type of {@code type1} and {@code type2} are not in a subtyping
 *       relationship, then return an annotated intersection type whose bounds are {@code type1}
 *       and {@code type2}.
 * </ol>
 *
 * @param atypeFactory the AnnotatedTypeFactory
 * @param type1 annotated type
 * @param type2 annotated type
 * @return the annotated glb of type1 and type2
 */
public static AnnotatedTypeMirror annotatedGLB(AnnotatedTypeFactory atypeFactory, AnnotatedTypeMirror type1, AnnotatedTypeMirror type2) {
    TypeMirror glbJava = TypesUtils.greatestLowerBound(type1.getUnderlyingType(), type2.getUnderlyingType(), atypeFactory.getProcessingEnv());
    Types types = atypeFactory.types;
    if (types.isSubtype(type1.getUnderlyingType(), type2.getUnderlyingType())) {
        return glbSubtype(atypeFactory.getQualifierHierarchy(), type1, type2);
    } else if (types.isSubtype(type2.getUnderlyingType(), type1.getUnderlyingType())) {
        return glbSubtype(atypeFactory.getQualifierHierarchy(), type2, type1);
    }
    if (types.isSameType(type1.getUnderlyingType(), glbJava)) {
        return glbSubtype(atypeFactory.getQualifierHierarchy(), type1, type2);
    } else if (types.isSameType(type2.getUnderlyingType(), glbJava)) {
        return glbSubtype(atypeFactory.getQualifierHierarchy(), type2, type1);
    }
    if (glbJava.getKind() != TypeKind.INTERSECTION) {
        // If one type isn't a subtype of the other, then GLB must be an intersection.
        throw new BugInCF("AnnotatedTypes#annotatedGLB: expected intersection, got [%s] %s. " + "type1: %s, type2: %s", glbJava.getKind(), glbJava, type1, type2);
    }
    QualifierHierarchy qualifierHierarchy = atypeFactory.getQualifierHierarchy();
    Set<AnnotationMirror> set1 = AnnotatedTypes.findEffectiveLowerBoundAnnotations(qualifierHierarchy, type1);
    Set<AnnotationMirror> set2 = AnnotatedTypes.findEffectiveLowerBoundAnnotations(qualifierHierarchy, type2);
    Set<? extends AnnotationMirror> glbAnno = qualifierHierarchy.greatestLowerBounds(set1, set2);
    AnnotatedIntersectionType glb = (AnnotatedIntersectionType) AnnotatedTypeMirror.createType(glbJava, atypeFactory, false);
    List<AnnotatedTypeMirror> newBounds = new ArrayList<>(2);
    for (AnnotatedTypeMirror bound : glb.getBounds()) {
        if (types.isSameType(bound.getUnderlyingType(), type1.getUnderlyingType())) {
            newBounds.add(type1.deepCopy());
        } else if (types.isSameType(bound.getUnderlyingType(), type2.getUnderlyingType())) {
            newBounds.add(type2.deepCopy());
        } else if (type1.getKind() == TypeKind.INTERSECTION) {
            AnnotatedIntersectionType intertype1 = (AnnotatedIntersectionType) type1;
            for (AnnotatedTypeMirror otherBound : intertype1.getBounds()) {
                if (types.isSameType(bound.getUnderlyingType(), otherBound.getUnderlyingType())) {
                    newBounds.add(otherBound.deepCopy());
                }
            }
        } else if (type2.getKind() == TypeKind.INTERSECTION) {
            AnnotatedIntersectionType intertype2 = (AnnotatedIntersectionType) type2;
            for (AnnotatedTypeMirror otherBound : intertype2.getBounds()) {
                if (types.isSameType(bound.getUnderlyingType(), otherBound.getUnderlyingType())) {
                    newBounds.add(otherBound.deepCopy());
                }
            }
        } else {
            throw new BugInCF("Neither %s nor %s is one of the intersection bounds in %s. Bound: %s", type1, type2, bound, glb);
        }
    }
    glb.setBounds(newBounds);
    glb.addAnnotations(glbAnno);
    return glb;
}
Also used : Types(javax.lang.model.util.Types) AnnotationMirror(javax.lang.model.element.AnnotationMirror) AnnotatedIntersectionType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedIntersectionType) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) QualifierHierarchy(org.checkerframework.framework.type.QualifierHierarchy) ArrayList(java.util.ArrayList) BugInCF(org.checkerframework.javacutil.BugInCF) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 39 with Types

use of javax.lang.model.util.Types in project react4j by react4j.

the class React4jProcessor method determineOnInputChangeMethods.

private void determineOnInputChangeMethods(@Nonnull final ViewDescriptor descriptor) {
    final List<ExecutableElement> methods = getMethods(descriptor.getElement()).stream().filter(m -> AnnotationsUtil.hasAnnotationOfType(m, Constants.ON_INPUT_CHANGE_CLASSNAME)).collect(Collectors.toList());
    final ArrayList<OnInputChangeDescriptor> onInputChangeDescriptors = new ArrayList<>();
    for (final ExecutableElement method : methods) {
        final VariableElement phase = (VariableElement) AnnotationsUtil.getAnnotationValue(method, Constants.ON_INPUT_CHANGE_CLASSNAME, "phase").getValue();
        final boolean preUpdate = phase.getSimpleName().toString().equals("PRE");
        final List<? extends VariableElement> parameters = method.getParameters();
        final ExecutableType methodType = resolveMethodType(descriptor, method);
        final List<? extends TypeMirror> parameterTypes = methodType.getParameterTypes();
        MemberChecks.mustBeSubclassCallable(descriptor.getElement(), Constants.VIEW_CLASSNAME, Constants.ON_INPUT_CHANGE_CLASSNAME, method);
        MemberChecks.mustNotThrowAnyExceptions(Constants.ON_INPUT_CHANGE_CLASSNAME, method);
        MemberChecks.mustNotReturnAnyValue(Constants.ON_INPUT_CHANGE_CLASSNAME, method);
        final int parameterCount = parameters.size();
        if (0 == parameterCount) {
            throw new ProcessorException("@OnInputChange target must have at least 1 parameter.", method);
        }
        final List<InputDescriptor> inputDescriptors = new ArrayList<>(parameterCount);
        for (int i = 0; i < parameterCount; i++) {
            final VariableElement parameter = parameters.get(i);
            final String name = deriveOnInputChangeName(parameter);
            final InputDescriptor input = descriptor.findInputNamed(name);
            if (null == input) {
                throw new ProcessorException("@OnInputChange target has a parameter named '" + parameter.getSimpleName() + "' and the parameter is associated with a " + "@Input named '" + name + "' but there is no corresponding @Input " + "annotated method.", parameter);
            }
            final Types typeUtils = processingEnv.getTypeUtils();
            if (!typeUtils.isAssignable(parameterTypes.get(i), input.getMethodType().getReturnType())) {
                throw new ProcessorException("@OnInputChange target has a parameter named '" + parameter.getSimpleName() + "' and the parameter type is not " + "assignable to the return type of the associated @Input annotated method.", method);
            }
            final boolean mismatchedNullability = (AnnotationsUtil.hasNonnullAnnotation(parameter) && AnnotationsUtil.hasNullableAnnotation(input.getMethod())) || (AnnotationsUtil.hasNullableAnnotation(parameter) && input.isNonNull());
            if (mismatchedNullability) {
                throw new ProcessorException("@OnInputChange target has a parameter named '" + parameter.getSimpleName() + "' that has a nullability annotation " + "incompatible with the associated @Input method named " + method.getSimpleName(), method);
            }
            if (input.isImmutable()) {
                throw new ProcessorException("@OnInputChange target has a parameter named '" + parameter.getSimpleName() + "' that is associated with a @Input " + "annotated method and the input is specified as immutable.", method);
            }
            inputDescriptors.add(input);
        }
        onInputChangeDescriptors.add(new OnInputChangeDescriptor(method, inputDescriptors, preUpdate));
    }
    descriptor.setOnInputChangeDescriptors(onInputChangeDescriptors);
}
Also used : Arrays(java.util.Arrays) SupportedOptions(javax.annotation.processing.SupportedOptions) Modifier(javax.lang.model.element.Modifier) VariableElement(javax.lang.model.element.VariableElement) DeferredElementSet(org.realityforge.proton.DeferredElementSet) HashMap(java.util.HashMap) TypeElement(javax.lang.model.element.TypeElement) SupportedAnnotationTypes(javax.annotation.processing.SupportedAnnotationTypes) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) ElementsUtil(org.realityforge.proton.ElementsUtil) SupportedSourceVersion(javax.annotation.processing.SupportedSourceVersion) Matcher(java.util.regex.Matcher) Diagnostic(javax.tools.Diagnostic) Map(java.util.Map) DeclaredType(javax.lang.model.type.DeclaredType) ProcessorException(org.realityforge.proton.ProcessorException) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) ArrayType(javax.lang.model.type.ArrayType) ElementKind(javax.lang.model.element.ElementKind) ExecutableType(javax.lang.model.type.ExecutableType) Collection(java.util.Collection) ExecutableElement(javax.lang.model.element.ExecutableElement) Set(java.util.Set) IOException(java.io.IOException) Element(javax.lang.model.element.Element) Types(javax.lang.model.util.Types) AnnotationsUtil(org.realityforge.proton.AnnotationsUtil) Collectors(java.util.stream.Collectors) AnnotationMirror(javax.lang.model.element.AnnotationMirror) TypeParameterElement(javax.lang.model.element.TypeParameterElement) TypeKind(javax.lang.model.type.TypeKind) AbstractStandardProcessor(org.realityforge.proton.AbstractStandardProcessor) SourceVersion(javax.lang.model.SourceVersion) List(java.util.List) TypeMirror(javax.lang.model.type.TypeMirror) MemberChecks(org.realityforge.proton.MemberChecks) RoundEnvironment(javax.annotation.processing.RoundEnvironment) TypeName(com.squareup.javapoet.TypeName) TypeVariable(javax.lang.model.type.TypeVariable) AnnotationValue(javax.lang.model.element.AnnotationValue) Pattern(java.util.regex.Pattern) Collections(java.util.Collections) ExecutableType(javax.lang.model.type.ExecutableType) SupportedAnnotationTypes(javax.annotation.processing.SupportedAnnotationTypes) Types(javax.lang.model.util.Types) ProcessorException(org.realityforge.proton.ProcessorException) ExecutableElement(javax.lang.model.element.ExecutableElement) ArrayList(java.util.ArrayList) VariableElement(javax.lang.model.element.VariableElement)

Example 40 with Types

use of javax.lang.model.util.Types in project checker-framework by typetools.

the class InitializationAnnotatedTypeFactory method isInitializedForFrame.

/**
 * Return true if the type is initialized with respect to the given frame -- that is, all of the
 * fields of the frame are initialized.
 *
 * @param type the type whose initialization type qualifiers to check
 * @param frame a class in {@code type}'s class hierarchy
 * @return true if the type is initialized for the given frame
 */
public boolean isInitializedForFrame(AnnotatedTypeMirror type, TypeMirror frame) {
    AnnotationMirror initializationAnno = type.getEffectiveAnnotationInHierarchy(UNKNOWN_INITIALIZATION);
    TypeMirror typeFrame = getTypeFrameFromAnnotation(initializationAnno);
    Types types = processingEnv.getTypeUtils();
    return types.isSubtype(typeFrame, types.erasure(frame));
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) Types(javax.lang.model.util.Types) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror)

Aggregations

Types (javax.lang.model.util.Types)113 TypeMirror (javax.lang.model.type.TypeMirror)77 TypeElement (javax.lang.model.element.TypeElement)52 Elements (javax.lang.model.util.Elements)48 ExecutableElement (javax.lang.model.element.ExecutableElement)34 Element (javax.lang.model.element.Element)30 SupportedAnnotationTypes (javax.annotation.processing.SupportedAnnotationTypes)27 DeclaredType (javax.lang.model.type.DeclaredType)26 ArrayList (java.util.ArrayList)25 Map (java.util.Map)24 VariableElement (javax.lang.model.element.VariableElement)24 List (java.util.List)21 AnnotationMirror (javax.lang.model.element.AnnotationMirror)20 TypeKind (javax.lang.model.type.TypeKind)18 Set (java.util.Set)16 Collection (java.util.Collection)15 HashMap (java.util.HashMap)13 ElementKind (javax.lang.model.element.ElementKind)13 Modifier (javax.lang.model.element.Modifier)13 IOException (java.io.IOException)12