use of javax.lang.model.util.Types in project checker-framework by typetools.
the class AnnotatedTypes method fixUpRawTypes.
/**
* Some times we create type arguments for types that were raw. When we do an asSuper we lose
* these arguments. If in the converted type (i.e. the subtype as super) is missing type arguments
* AND those type arguments should come from the original subtype's type arguments then we copy
* the original type arguments to the converted type. e.g. We have a type W, that "wasRaw" {@code
* ArrayList<? extends Object>} When W is converted to type A, List, using asSuper it no longer
* has its type argument. But since the type argument to List should be the same as that to
* ArrayList we copy over the type argument of W to A. A becomes {@code List<? extends Object>}
*
* @param originalSubtype the subtype before being converted by asSuper
* @param asSuperType he subtype after being converted by asSuper
* @param supertype the supertype for which asSuperType should have the same underlying type
* @param types the types utility
*/
private static void fixUpRawTypes(final AnnotatedTypeMirror originalSubtype, final AnnotatedTypeMirror asSuperType, final AnnotatedTypeMirror supertype, final Types types) {
if (asSuperType == null || asSuperType.getKind() != TypeKind.DECLARED || originalSubtype.getKind() != TypeKind.DECLARED) {
return;
}
final AnnotatedDeclaredType declaredAsSuper = (AnnotatedDeclaredType) asSuperType;
final AnnotatedDeclaredType declaredSubtype = (AnnotatedDeclaredType) originalSubtype;
if (!declaredAsSuper.isUnderlyingTypeRaw() || !declaredAsSuper.getTypeArguments().isEmpty() || declaredSubtype.getTypeArguments().isEmpty()) {
return;
}
Set<Pair<Integer, Integer>> typeArgMap = TypeArgumentMapper.mapTypeArgumentIndices((TypeElement) declaredSubtype.getUnderlyingType().asElement(), (TypeElement) declaredAsSuper.getUnderlyingType().asElement(), types);
if (typeArgMap.size() != declaredSubtype.getTypeArguments().size()) {
return;
}
List<Pair<Integer, Integer>> orderedByDestination = new ArrayList<>(typeArgMap);
orderedByDestination.sort(Comparator.comparingInt(o -> o.second));
if (typeArgMap.size() == ((AnnotatedDeclaredType) supertype).getTypeArguments().size()) {
List<? extends AnnotatedTypeMirror> subTypeArgs = declaredSubtype.getTypeArguments();
List<AnnotatedTypeMirror> newTypeArgs = CollectionsPlume.mapList(mapping -> subTypeArgs.get(mapping.first).deepCopy(), orderedByDestination);
declaredAsSuper.setTypeArguments(newTypeArgs);
} else {
declaredAsSuper.setTypeArguments(Collections.emptyList());
}
}
use of javax.lang.model.util.Types in project dubbo by alibaba.
the class MapTypeDefinitionBuilder method accept.
@Override
public boolean accept(ProcessingEnvironment processingEnv, DeclaredType type) {
Elements elements = processingEnv.getElementUtils();
TypeElement mapTypeElement = elements.getTypeElement(Map.class.getTypeName());
TypeMirror mapType = mapTypeElement.asType();
Types types = processingEnv.getTypeUtils();
TypeMirror erasedType = types.erasure(type);
return types.isAssignable(erasedType, mapType);
}
use of javax.lang.model.util.Types in project auto by google.
the class MoreElements method getAllMethods.
private static ImmutableSet<ExecutableElement> getAllMethods(TypeElement type, Overrides overrides) {
SetMultimap<String, ExecutableElement> methodMap = LinkedHashMultimap.create();
getAllMethods(type, methodMap);
// Find methods that are overridden. We do this using `Elements.overrides`, which means
// that it is inherently a quadratic operation, since we have to compare every method against
// every other method. We reduce the performance impact by (a) grouping methods by name, since
// a method cannot override another method with a different name, and (b) making sure that
// methods in ancestor types precede those in descendant types, which means we only have to
// check a method against the ones that follow it in that order.
Set<ExecutableElement> overridden = new LinkedHashSet<ExecutableElement>();
for (Collection<ExecutableElement> methods : methodMap.asMap().values()) {
List<ExecutableElement> methodList = ImmutableList.copyOf(methods);
for (int i = 0; i < methodList.size(); i++) {
ExecutableElement methodI = methodList.get(i);
for (int j = i + 1; j < methodList.size(); j++) {
ExecutableElement methodJ = methodList.get(j);
if (overrides.overrides(methodJ, methodI, type)) {
overridden.add(methodI);
break;
}
}
}
}
return methodMap.values().stream().filter(m -> !overridden.contains(m)).collect(toImmutableSet());
}
use of javax.lang.model.util.Types in project auto by google.
the class AutoValueishProcessor method process.
@Override
public final boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (annotationType == null) {
// This should not happen. If the annotation type is not found, how did the processor get
// triggered?
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Did not process @" + annotationClassName + " because the annotation class was not found");
return false;
}
List<TypeElement> deferredTypes = deferredTypeNames.stream().map(name -> elementUtils().getTypeElement(name)).collect(toList());
if (roundEnv.processingOver()) {
// was in deferredTypes.
for (TypeElement type : deferredTypes) {
errorReporter.reportError(type, "[%sUndefined] Did not generate @%s class for %s because it references" + " undefined types", simpleAnnotationName, simpleAnnotationName, type.getQualifiedName());
}
return false;
}
Collection<? extends Element> annotatedElements = roundEnv.getElementsAnnotatedWith(annotationType);
List<TypeElement> types = new ImmutableList.Builder<TypeElement>().addAll(deferredTypes).addAll(ElementFilter.typesIn(annotatedElements)).build();
deferredTypeNames.clear();
for (TypeElement type : types) {
try {
validateType(type);
processType(type);
} catch (AbortProcessingException e) {
// We abandoned this type; continue with the next.
} catch (MissingTypeException e) {
// We abandoned this type, but only because we needed another type that it references and
// that other type was missing. It is possible that the missing type will be generated by
// further annotation processing, so we will try again on the next round (perhaps failing
// again and adding it back to the list).
addDeferredType(type);
} catch (RuntimeException e) {
String trace = Throwables.getStackTraceAsString(e);
errorReporter.reportError(type, "[%sException] @%s processor threw an exception: %s", simpleAnnotationName, simpleAnnotationName, trace);
throw e;
}
}
// never claim annotation, because who knows what other processors want?
return false;
}
use of javax.lang.model.util.Types in project auto by google.
the class BuilderMethodClassifierForAutoBuilder method rewriteParameterTypes.
// Rewrites the parameter types of the executable so they use the type variables of the builder
// where appropriate.
//
// Suppose we have something like this:
//
// static <E> Set<E> singletonSet(E elem) {...}
//
// @AutoBuilder(callMethod = "singletonSet")
// interface SingletonSetBuilder<E> {
// SingletonSetBuilder<E> setElem(E elem);
// Set<E> build();
// }
//
// We want to check that the type of the setter `setElem` matches the type of the
// parameter it is setting. But in fact it doesn't: the type of the setter is
// E-of-SingletonSetBuilder while the type of the parameter is E-of-singletonSet. So we
// need to rewrite any type variables mentioned in parameters so that they use the corresponding
// types from the builder. We want to return a map where "elem" is mapped to
// E-of-SingletonSetBuilder, even though the `elem` that we get from the parameters of
// singletonSet is going to be E-of-singletonSet. And we also want that to work if the parameter
// is something more complicated, like List<? extends E>.
//
// For the corresponding situation with AutoValue, we have a way of dodging the problem somewhat.
// For an @AutoValue class Foo<E> with a builder Builder<E>, we can craft a DeclaredType
// Foo<E> where the E comes from Builder<E>, and we can use Types.asMemberOf to determine the
// return types of methods (which are what we want to rewrite in that case). But that doesn't
// work here because singletonSet is static and Types.asMemberOf would have no effect on it.
//
// So instead we take the type of each parameter and feed it through a TypeVisitor that rewrites
// type variables, rewriting from E-of-singletonSet to E-of-SingletonSetBuilder. Then we can use
// Types.isSameType or Types.isAssignable and it will work as we expect.
//
// In principle a similar situation arises with the return type Set<E> of singletonSet versus
// the return type Set<E> of SingletonSetBuilder.build(). But in fact we only use
// MoreTypes.equivalence to compare those, and that returns true for distinct type variables if
// they have the same name and bounds.
private static ImmutableMap<String, TypeMirror> rewriteParameterTypes(ExecutableElement executable, TypeElement builderType, ErrorReporter errorReporter, Types typeUtils) {
ImmutableList<TypeParameterElement> executableTypeParams = executableTypeParams(executable);
List<? extends TypeParameterElement> builderTypeParams = builderType.getTypeParameters();
if (!BuilderSpec.sameTypeParameters(executableTypeParams, builderTypeParams)) {
errorReporter.abortWithError(builderType, "[AutoBuilderTypeParams] Builder type parameters %s must match type parameters %s of %s", TypeEncoder.typeParametersString(builderTypeParams), TypeEncoder.typeParametersString(executableTypeParams), AutoBuilderProcessor.executableString(executable));
}
if (executableTypeParams.isEmpty()) {
// variables to substitute.
return executable.getParameters().stream().collect(toImmutableMap(v -> v.getSimpleName().toString(), Element::asType));
}
Map<Equivalence.Wrapper<TypeVariable>, TypeMirror> typeVariables = new LinkedHashMap<>();
for (int i = 0; i < executableTypeParams.size(); i++) {
TypeVariable from = MoreTypes.asTypeVariable(executableTypeParams.get(i).asType());
TypeVariable to = MoreTypes.asTypeVariable(builderTypeParams.get(i).asType());
typeVariables.put(MoreTypes.equivalence().wrap(from), to);
}
Function<TypeVariable, TypeMirror> substitute = v -> typeVariables.get(MoreTypes.equivalence().wrap(v));
return executable.getParameters().stream().collect(toImmutableMap(v -> v.getSimpleName().toString(), v -> TypeVariables.substituteTypeVariables(v.asType(), substitute, typeUtils)));
}
Aggregations