Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate PkgPrivateMetadata to XProcessing #3822

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,17 @@ void generate() throws IOException {
TypeSpec.Builder entryPointInterfaceBuilder =
JavaPoetExtKt.addOriginatingElement(
TypeSpec.interfaceBuilder(metadata.generatedClassName().simpleName()),
metadata.getXTypeElement(env))
metadata.getTypeElement())
.addAnnotation(Processors.getOriginatingElementAnnotation(metadata.getTypeElement()))
.addModifiers(Modifier.PUBLIC)
.addSuperinterface(metadata.baseClassName())
.addAnnotation(metadata.getAnnotation());

Processors.addGeneratedAnnotation(entryPointInterfaceBuilder, env, getClass());

if (metadata.getOptionalInstallInAnnotation(env).isPresent()) {
if (metadata.getOptionalInstallInAnnotation().isPresent()) {
entryPointInterfaceBuilder.addAnnotation(
XAnnotations.getAnnotationSpec(metadata.getOptionalInstallInAnnotation(env).get()));
XAnnotations.getAnnotationSpec(metadata.getOptionalInstallInAnnotation().get()));
}

env.getFiler()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,110 +16,87 @@

package dagger.hilt.processor.internal.aggregateddeps;

import static androidx.room.compiler.processing.compat.XConverters.toJavac;
import static androidx.room.compiler.processing.compat.XConverters.toXProcessing;
import static com.google.auto.common.Visibility.effectiveVisibilityOfElement;


import androidx.room.compiler.processing.XAnnotation;
import androidx.room.compiler.processing.XProcessingEnv;
import androidx.room.compiler.processing.XTypeElement;
import com.google.auto.common.MoreElements;
import com.google.auto.common.Visibility;
import com.google.auto.value.AutoValue;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.TypeName;
import dagger.hilt.processor.internal.ClassNames;
import dagger.hilt.processor.internal.Processors;
import dagger.hilt.processor.internal.kotlin.KotlinMetadataUtils;
import dagger.internal.codegen.xprocessing.XElements;
import dagger.internal.codegen.xprocessing.XTypeElements;
import java.util.Optional;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;

/** PkgPrivateModuleMetadata contains a set of utilities for processing package private modules. */
@AutoValue
public abstract class PkgPrivateMetadata {
/** Returns the public Hilt wrapped type or the type itself if it is already public. */
public static TypeElement publicModule(TypeElement element, Elements elements) {
return publicDep(element, elements, ClassNames.MODULE);
public static XTypeElement publicModule(XTypeElement element, XProcessingEnv env) {
return publicDep(element, env, ClassNames.MODULE);
}

/** Returns the public Hilt wrapped type or the type itself if it is already public. */
public static TypeElement publicEarlyEntryPoint(TypeElement element, Elements elements) {
return publicDep(element, elements, ClassNames.EARLY_ENTRY_POINT);
public static XTypeElement publicEarlyEntryPoint(XTypeElement element, XProcessingEnv env) {
return publicDep(element, env, ClassNames.EARLY_ENTRY_POINT);
}

/** Returns the public Hilt wrapped type or the type itself if it is already public. */
public static TypeElement publicEntryPoint(TypeElement element, Elements elements) {
return publicDep(element, elements, ClassNames.ENTRY_POINT);
public static XTypeElement publicEntryPoint(XTypeElement element, XProcessingEnv env) {
return publicDep(element, env, ClassNames.ENTRY_POINT);
}

private static TypeElement publicDep(
TypeElement element, Elements elements, ClassName annotation) {
return of(elements, element, annotation)
private static XTypeElement publicDep(
XTypeElement element, XProcessingEnv env, ClassName annotation) {
return of(element, annotation)
.map(PkgPrivateMetadata::generatedClassName)
.map(ClassName::canonicalName)
.map(elements::getTypeElement)
.map(env::requireTypeElement)
.orElse(element);
}

private static final String PREFIX = "HiltWrapper_";

/** Returns the base class name of the elemenet. */
TypeName baseClassName() {
return TypeName.get(getTypeElement().asType());
return getTypeElement().getClassName();
}

/** Returns TypeElement for the module element the metadata object represents */
abstract TypeElement getTypeElement();

/** Returns TypeElement for the module element the metadata object represents */
public XTypeElement getXTypeElement(XProcessingEnv env) {
return toXProcessing(getTypeElement(), env);
}
abstract XTypeElement getTypeElement();

/**
* Returns an optional @InstallIn AnnotationMirror for the module element the metadata object
* represents
*/
abstract Optional<AnnotationMirror> getOptionalInstallInAnnotationMirror();

/**
* Returns an optional @InstallIn XAnnotation for the module element the metadata object
* represents
*/
public Optional<XAnnotation> getOptionalInstallInAnnotation(XProcessingEnv env) {
return getOptionalInstallInAnnotationMirror()
.map(annotationMirror -> toXProcessing(annotationMirror, env));
}
abstract Optional<XAnnotation> getOptionalInstallInAnnotation();

/** Return the Type of this package private element. */
abstract ClassName getAnnotation();

/** Returns the expected genenerated classname for the element the metadata object represents */
/** Returns the expected generated classname for the element the metadata object represents */
final ClassName generatedClassName() {
return Processors.prepend(
Processors.getEnclosedClassName(ClassName.get(getTypeElement())), PREFIX);
Processors.getEnclosedClassName(getTypeElement().getClassName()), PREFIX);
}

// TODO(kuanyingchou): Remove this method once all usages are migrated to XProcessing.
/**
* Returns an Optional PkgPrivateMetadata requiring Hilt processing, otherwise returns an empty
* Optional.
*/
static Optional<PkgPrivateMetadata> of(
Elements elements, TypeElement element, ClassName annotation) {
static Optional<PkgPrivateMetadata> of(XTypeElement element, ClassName annotation) {
// If this is a public element no wrapping is needed
if (effectiveVisibilityOfElement(element) == Visibility.PUBLIC
&& !KotlinMetadataUtils.getMetadataUtil().isVisibilityInternal(element)) {
if (XTypeElements.isEffectivelyPublic(element) && !element.isInternal()) {
return Optional.empty();
}

Optional<AnnotationMirror> installIn;
if (Processors.hasAnnotation(element, ClassNames.INSTALL_IN)) {
installIn = Optional.of(Processors.getAnnotationMirror(element, ClassNames.INSTALL_IN));
} else if (Processors.hasAnnotation(element, ClassNames.TEST_INSTALL_IN)) {
installIn = Optional.of(Processors.getAnnotationMirror(element, ClassNames.TEST_INSTALL_IN));
Optional<XAnnotation> installIn;
if (element.hasAnnotation(ClassNames.INSTALL_IN)) {
installIn = Optional.of(element.getAnnotation(ClassNames.INSTALL_IN));
} else if (element.hasAnnotation(ClassNames.TEST_INSTALL_IN)) {
installIn = Optional.of(element.getAnnotation(ClassNames.TEST_INSTALL_IN));
} else {
throw new IllegalStateException(
"Expected element to be annotated with @InstallIn: " + element);
Expand All @@ -132,16 +109,11 @@ static Optional<PkgPrivateMetadata> of(
// error more confusing for users since they probably aren't aware of the wrapper. When
// skipped, if the root is in a different package, the error will instead just be on the
// generated Hilt component.
if (Processors.requiresModuleInstance(elements, MoreElements.asType(element))) {
if (Processors.requiresModuleInstance(element)) {
return Optional.empty();
}
}
return Optional.of(
new AutoValue_PkgPrivateMetadata(MoreElements.asType(element), installIn, annotation));
}

static Optional<PkgPrivateMetadata> of(
XProcessingEnv env, XTypeElement element, ClassName annotation) {
return of(toJavac(env).getElementUtils(), toJavac(element), annotation);
new AutoValue_PkgPrivateMetadata(XElements.asTypeElement(element), installIn, annotation));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
* Copyright (C) 2019 The Dagger Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package dagger.hilt.processor.internal.aggregateddeps;

import static com.google.auto.common.Visibility.effectiveVisibilityOfElement;

import com.google.auto.common.MoreElements;
import com.google.auto.common.Visibility;
import com.google.auto.value.AutoValue;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.TypeName;
import dagger.hilt.processor.internal.ClassNames;
import dagger.hilt.processor.internal.Processors;
import dagger.hilt.processor.internal.kotlin.KotlinMetadataUtils;
import java.util.Optional;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;

/** PkgPrivateModuleMetadata contains a set of utilities for processing package private modules. */
@AutoValue
public abstract class PkgPrivateMetadataLegacy {
/** Returns the public Hilt wrapped type or the type itself if it is already public. */
public static TypeElement publicEntryPoint(TypeElement element, Elements elements) {
return publicDep(element, elements, ClassNames.ENTRY_POINT);
}

private static TypeElement publicDep(
TypeElement element, Elements elements, ClassName annotation) {
return of(elements, element, annotation)
.map(PkgPrivateMetadataLegacy::generatedClassName)
.map(ClassName::canonicalName)
.map(elements::getTypeElement)
.orElse(element);
}

private static final String PREFIX = "HiltWrapper_";

/** Returns the base class name of the elemenet. */
TypeName baseClassName() {
return TypeName.get(getTypeElement().asType());
}

/** Returns TypeElement for the module element the metadata object represents */
abstract TypeElement getTypeElement();

/**
* Returns an optional @InstallIn AnnotationMirror for the module element the metadata object
* represents
*/
abstract Optional<AnnotationMirror> getOptionalInstallInAnnotationMirror();

/** Return the Type of this package private element. */
abstract ClassName getAnnotation();

/** Returns the expected genenerated classname for the element the metadata object represents */
final ClassName generatedClassName() {
return Processors.prepend(
Processors.getEnclosedClassName(ClassName.get(getTypeElement())), PREFIX);
}

/**
* Returns an Optional PkgPrivateMetadataLegacy requiring Hilt processing, otherwise returns an
* empty Optional.
*/
static Optional<PkgPrivateMetadataLegacy> of(
Elements elements, TypeElement element, ClassName annotation) {
// If this is a public element no wrapping is needed
if (effectiveVisibilityOfElement(element) == Visibility.PUBLIC
&& !KotlinMetadataUtils.getMetadataUtil().isVisibilityInternal(element)) {
return Optional.empty();
}

Optional<AnnotationMirror> installIn;
if (Processors.hasAnnotation(element, ClassNames.INSTALL_IN)) {
installIn = Optional.of(Processors.getAnnotationMirror(element, ClassNames.INSTALL_IN));
} else if (Processors.hasAnnotation(element, ClassNames.TEST_INSTALL_IN)) {
installIn = Optional.of(Processors.getAnnotationMirror(element, ClassNames.TEST_INSTALL_IN));
} else {
throw new IllegalStateException(
"Expected element to be annotated with @InstallIn: " + element);
}

if (annotation.equals(ClassNames.MODULE)
) {
// Skip modules that require a module instance. Otherwise Dagger validation will (correctly)
// fail on the wrapper saying a public module can't include a private one, which makes the
// error more confusing for users since they probably aren't aware of the wrapper. When
// skipped, if the root is in a different package, the error will instead just be on the
// generated Hilt component.
if (Processors.requiresModuleInstance(elements, MoreElements.asType(element))) {
return Optional.empty();
}
}
return Optional.of(
new AutoValue_PkgPrivateMetadataLegacy(
MoreElements.asType(element), installIn, annotation));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,12 @@ void generate() throws IOException {
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
// generated @InstallIn is exactly the same as the module being processed
.addAnnotation(
XAnnotations.getAnnotationSpec(metadata.getOptionalInstallInAnnotation(env).get()))
XAnnotations.getAnnotationSpec(metadata.getOptionalInstallInAnnotation().get()))
.addAnnotation(
AnnotationSpec.builder(metadata.getAnnotation())
.addMember("includes", "$T.class", metadata.getXTypeElement(env).getClassName())
.addMember("includes", "$T.class", metadata.getTypeElement().getClassName())
.build());
JavaPoetExtKt.addOriginatingElement(builder, metadata.getXTypeElement(env));
JavaPoetExtKt.addOriginatingElement(builder, metadata.getTypeElement());

Processors.addGeneratedAnnotation(builder, env, getClass());

Expand Down