Skip to content

Commit

Permalink
Migrate MapKeyProcessingStep to XProcessing.
Browse files Browse the repository at this point in the history
RELNOTES=N/A
PiperOrigin-RevId: 405919555
  • Loading branch information
bcorso authored and Dagger Team committed Oct 27, 2021
1 parent f3aa581 commit 288ba4c
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 63 deletions.
24 changes: 6 additions & 18 deletions java/dagger/internal/codegen/MapKeyProcessingStep.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,48 +17,39 @@
package dagger.internal.codegen;

import static dagger.internal.codegen.binding.MapKeys.getUnwrappedMapKeyType;
import static javax.lang.model.element.ElementKind.ANNOTATION_TYPE;
import static dagger.internal.codegen.xprocessing.XTypes.isDeclared;

import androidx.room.compiler.processing.XAnnotationKt;
import androidx.room.compiler.processing.XMessager;
import androidx.room.compiler.processing.XType;
import androidx.room.compiler.processing.XTypeElement;
import androidx.room.compiler.processing.compat.XConverters;
import com.google.auto.common.MoreTypes;
import com.google.common.collect.ImmutableSet;
import com.squareup.javapoet.ClassName;
import dagger.MapKey;
import dagger.internal.codegen.javapoet.TypeNames;
import dagger.internal.codegen.langmodel.DaggerTypes;
import dagger.internal.codegen.validation.MapKeyValidator;
import dagger.internal.codegen.validation.TypeCheckingProcessingStep;
import dagger.internal.codegen.validation.ValidationReport;
import dagger.internal.codegen.writing.AnnotationCreatorGenerator;
import dagger.internal.codegen.writing.UnwrappedMapKeyGenerator;
import javax.inject.Inject;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;

/**
* The annotation processor responsible for validating the mapKey annotation and auto-generate
* implementation of annotations marked with {@link MapKey @MapKey} where necessary.
*/
final class MapKeyProcessingStep extends TypeCheckingProcessingStep<XTypeElement> {
private final XMessager messager;
private final DaggerTypes types;
private final MapKeyValidator mapKeyValidator;
private final AnnotationCreatorGenerator annotationCreatorGenerator;
private final UnwrappedMapKeyGenerator unwrappedMapKeyGenerator;

@Inject
MapKeyProcessingStep(
XMessager messager,
DaggerTypes types,
MapKeyValidator mapKeyValidator,
AnnotationCreatorGenerator annotationCreatorGenerator,
UnwrappedMapKeyGenerator unwrappedMapKeyGenerator) {
this.messager = messager;
this.types = types;
this.mapKeyValidator = mapKeyValidator;
this.annotationCreatorGenerator = annotationCreatorGenerator;
this.unwrappedMapKeyGenerator = unwrappedMapKeyGenerator;
Expand All @@ -75,18 +66,15 @@ protected void process(XTypeElement mapAnnotation, ImmutableSet<ClassName> annot
mapKeyReport.printMessagesTo(messager);

if (mapKeyReport.isClean()) {
if (!XAnnotationKt.get(
mapAnnotation.getAnnotation(TypeNames.MAP_KEY), "unwrapValue", Boolean.class)) {
if (!mapAnnotation.getAnnotation(TypeNames.MAP_KEY).getAsBoolean("unwrapValue")) {
annotationCreatorGenerator.generate(mapAnnotation, messager);
} else if (unwrappedValueKind(XConverters.toJavac(mapAnnotation)).equals(ANNOTATION_TYPE)) {
} else if (isAnnotationType(getUnwrappedMapKeyType(mapAnnotation.getType()))) {
unwrappedMapKeyGenerator.generate(mapAnnotation, messager);
}
}
}

private ElementKind unwrappedValueKind(TypeElement mapKeyAnnotationType) {
DeclaredType unwrappedMapKeyType =
getUnwrappedMapKeyType(MoreTypes.asDeclared(mapKeyAnnotationType.asType()), types);
return unwrappedMapKeyType.asElement().getKind();
private boolean isAnnotationType(XType type) {
return isDeclared(type) && type.getTypeElement().isAnnotationClass();
}
}
3 changes: 2 additions & 1 deletion java/dagger/internal/codegen/binding/KeyFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package dagger.internal.codegen.binding;

import static androidx.room.compiler.processing.compat.XConverters.toJavac;
import static androidx.room.compiler.processing.compat.XConverters.toXProcessing;
import static com.google.auto.common.MoreTypes.asExecutable;
import static com.google.auto.common.MoreTypes.isType;
import static com.google.common.base.Preconditions.checkArgument;
Expand Down Expand Up @@ -237,7 +238,7 @@ private TypeMirror bindingMethodKeyType(
case SET:
return setOf(returnType);
case MAP:
TypeMirror mapKeyType = mapKeyType(getMapKey(method).get(), types);
TypeMirror mapKeyType = mapKeyType(toXProcessing(getMapKey(method).get(), processingEnv));
return frameworkClassName.isPresent()
? mapOfFrameworkType(mapKeyType, frameworkClassName.get(), returnType)
: mapOf(mapKeyType, returnType);
Expand Down
64 changes: 25 additions & 39 deletions java/dagger/internal/codegen/binding/MapKeys.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,26 @@

package dagger.internal.codegen.binding;

import static androidx.room.compiler.processing.XTypeKt.isArray;
import static androidx.room.compiler.processing.compat.XConverters.toJavac;
import static androidx.room.compiler.processing.compat.XConverters.toXProcessing;
import static com.google.auto.common.AnnotationMirrors.getAnnotatedAnnotations;
import static com.google.auto.common.AnnotationMirrors.getAnnotationValuesWithDefaults;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.Iterables.getOnlyElement;
import static com.squareup.javapoet.MethodSpec.methodBuilder;
import static dagger.internal.codegen.base.MapKeyAccessibility.isMapKeyPubliclyAccessible;
import static dagger.internal.codegen.binding.SourceFiles.elementBasedClassName;
import static dagger.internal.codegen.xprocessing.XTypes.isDeclared;
import static dagger.internal.codegen.xprocessing.XTypes.isPrimitive;
import static javax.lang.model.element.Modifier.PUBLIC;
import static javax.lang.model.element.Modifier.STATIC;
import static javax.lang.model.util.ElementFilter.methodsIn;

import androidx.room.compiler.processing.XAnnotation;
import androidx.room.compiler.processing.XElement;
import androidx.room.compiler.processing.XMethodElement;
import androidx.room.compiler.processing.XProcessingEnv;
import androidx.room.compiler.processing.XType;
import com.google.auto.common.MoreElements;
import com.google.auto.common.MoreTypes;
import com.google.common.collect.ImmutableSet;
Expand All @@ -47,14 +54,8 @@
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.PrimitiveType;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.SimpleTypeVisitor8;

/** Methods for extracting {@link MapKey} annotations and key code blocks from binding elements. */
public final class MapKeys {
Expand Down Expand Up @@ -98,10 +99,10 @@ static Optional<? extends AnnotationValue> unwrapValue(AnnotationMirror mapKey)
: Optional.empty();
}

static TypeMirror mapKeyType(AnnotationMirror mapKeyAnnotation, DaggerTypes types) {
return unwrapValue(mapKeyAnnotation).isPresent()
? getUnwrappedMapKeyType(mapKeyAnnotation.getAnnotationType(), types)
: mapKeyAnnotation.getAnnotationType();
static TypeMirror mapKeyType(XAnnotation mapKeyAnnotation) {
return unwrapValue(toJavac(mapKeyAnnotation)).isPresent()
? toJavac(getUnwrappedMapKeyType(mapKeyAnnotation.getType()))
: toJavac(mapKeyAnnotation.getType());
}

/**
Expand All @@ -112,36 +113,21 @@ static TypeMirror mapKeyType(AnnotationMirror mapKeyAnnotation, DaggerTypes type
* has more than one member, or if its single member is an array
* @throws NoSuchElementException if the annotation has no members
*/
public static DeclaredType getUnwrappedMapKeyType(
final DeclaredType mapKeyAnnotationType, final DaggerTypes types) {
public static XType getUnwrappedMapKeyType(XType mapKeyAnnotationType) {
checkArgument(
MoreTypes.asTypeElement(mapKeyAnnotationType).getKind() == ElementKind.ANNOTATION_TYPE,
isDeclared(mapKeyAnnotationType)
&& mapKeyAnnotationType.getTypeElement().isAnnotationClass(),
"%s is not an annotation type",
mapKeyAnnotationType);

final ExecutableElement onlyElement =
getOnlyElement(methodsIn(mapKeyAnnotationType.asElement().getEnclosedElements()));

SimpleTypeVisitor8<DeclaredType, Void> keyTypeElementVisitor =
new SimpleTypeVisitor8<DeclaredType, Void>() {

@Override
public DeclaredType visitArray(ArrayType t, Void p) {
throw new IllegalArgumentException(
mapKeyAnnotationType + "." + onlyElement.getSimpleName() + " cannot be an array");
}

@Override
public DeclaredType visitPrimitive(PrimitiveType t, Void p) {
return MoreTypes.asDeclared(types.boxedClass(t).asType());
}

@Override
public DeclaredType visitDeclared(DeclaredType t, Void p) {
return t;
}
};
return keyTypeElementVisitor.visit(onlyElement.getReturnType());
XMethodElement annotationValueMethod =
getOnlyElement(mapKeyAnnotationType.getTypeElement().getDeclaredMethods());
XType annotationValueType = annotationValueMethod.getReturnType();
if (isArray(annotationValueType)) {
throw new IllegalArgumentException(
mapKeyAnnotationType + "." + annotationValueMethod.getName() + " cannot be an array");
}
return isPrimitive(annotationValueType) ? annotationValueType.boxed() : annotationValueType;
}

/**
Expand Down Expand Up @@ -214,15 +200,15 @@ public static ClassName mapKeyProxyClassName(ContributionBinding binding) {
* accessible.
*/
public static Optional<MethodSpec> mapKeyFactoryMethod(
ContributionBinding binding, DaggerTypes types, DaggerElements elements) {
ContributionBinding binding, XProcessingEnv processingEnv, DaggerElements elements) {
return binding
.mapKeyAnnotation()
.filter(mapKey -> !isMapKeyPubliclyAccessible(mapKey))
.map(
mapKey ->
methodBuilder("create")
.addModifiers(PUBLIC, STATIC)
.returns(TypeName.get(mapKeyType(mapKey, types)))
.returns(TypeName.get(mapKeyType(toXProcessing(mapKey, processingEnv))))
.addStatement("return $L", directMapKeyExpression(mapKey, elements))
.build());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@
import static javax.lang.model.element.Modifier.PUBLIC;

import androidx.room.compiler.processing.XFiler;
import androidx.room.compiler.processing.XProcessingEnv;
import com.google.common.collect.ImmutableList;
import com.squareup.javapoet.TypeSpec;
import dagger.internal.codegen.base.SourceFileGenerator;
import dagger.internal.codegen.binding.ContributionBinding;
import dagger.internal.codegen.binding.MapKeys;
import dagger.internal.codegen.langmodel.DaggerElements;
import dagger.internal.codegen.langmodel.DaggerTypes;
import javax.inject.Inject;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
Expand All @@ -40,14 +40,17 @@
*/
public final class InaccessibleMapKeyProxyGenerator
extends SourceFileGenerator<ContributionBinding> {
private final DaggerTypes types;
private final XProcessingEnv processingEnv;
private final DaggerElements elements;

@Inject
InaccessibleMapKeyProxyGenerator(
XFiler filer, DaggerTypes types, DaggerElements elements, SourceVersion sourceVersion) {
XProcessingEnv processingEnv,
XFiler filer,
DaggerElements elements,
SourceVersion sourceVersion) {
super(filer, elements, sourceVersion);
this.types = types;
this.processingEnv = processingEnv;
this.elements = elements;
}

Expand All @@ -59,7 +62,7 @@ public Element originatingElement(ContributionBinding binding) {

@Override
public ImmutableList<TypeSpec.Builder> topLevelTypes(ContributionBinding binding) {
return MapKeys.mapKeyFactoryMethod(binding, types, elements)
return MapKeys.mapKeyFactoryMethod(binding, processingEnv, elements)
.map(
method ->
classBuilder(MapKeys.mapKeyProxyClassName(binding))
Expand Down

0 comments on commit 288ba4c

Please sign in to comment.