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");
}
}
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;
}
}
}
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;
}
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);
}
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));
}
Aggregations