Skip to content

Commit

Permalink
Migrate HiltCompilerOptions, BadInputException, and ViewGenerator to …
Browse files Browse the repository at this point in the history
…XProcessing

RELNOTES=n/a
PiperOrigin-RevId: 525431490
  • Loading branch information
kuanyingchou authored and Dagger Team committed Apr 19, 2023
1 parent 4ee57b2 commit 180c6b2
Show file tree
Hide file tree
Showing 10 changed files with 33 additions and 183 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public void processEach(XTypeElement annotation, XElement element) throws Except
new InjectorEntryPointGenerator(processingEnv(), metadata).generate();
switch (metadata.androidType()) {
case APPLICATION:
GradleProjectType projectType = getGradleProjectType(getProcessingEnv());
GradleProjectType projectType = getGradleProjectType(processingEnv());
if (projectType != GradleProjectType.UNSET) {
ProcessorErrors.checkState(
projectType == GradleProjectType.APP,
Expand All @@ -73,7 +73,7 @@ public void processEach(XTypeElement annotation, XElement element) throws Except
// in the same build unit. Thus, we only generate the application here if we're using the
// aggregating root processor. If we're using the Hilt Gradle plugin's aggregating task, we
// need to generate the application within ComponentTreeDepsProcessor instead.
if (useAggregatingRootProcessor(getProcessingEnv())) {
if (useAggregatingRootProcessor(processingEnv())) {
// While we could always generate the application in ComponentTreeDepsProcessor, even if
// we're using the aggregating root processor, it can lead to extraneous errors when
// things fail before ComponentTreeDepsProcessor runs so we generate it here to avoid that
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package dagger.hilt.android.processor.internal.androidentrypoint;

import static androidx.room.compiler.processing.XTypeKt.isInt;
import static androidx.room.compiler.processing.compat.XConverters.toJavac;
import static dagger.internal.codegen.xprocessing.XTypes.isDeclared;
import static dagger.internal.codegen.xprocessing.XTypes.isPrimitive;

Expand All @@ -28,7 +27,6 @@
import androidx.room.compiler.processing.XProcessingEnv;
import androidx.room.compiler.processing.XType;
import androidx.room.compiler.processing.XTypeParameterElement;
import com.google.auto.common.Visibility;
import com.squareup.javapoet.AnnotationSpec;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.JavaFile;
Expand Down Expand Up @@ -91,10 +89,9 @@ public void generate() {
}

private boolean isConstructorVisibleToGeneratedClass(XConstructorElement constructor) {
Visibility visibility = Visibility.ofElement(toJavac(constructor));
if (visibility == Visibility.DEFAULT && !isInOurPackage(constructor)) {
if (Processors.hasJavaPackagePrivateVisibility(constructor) && !isInOurPackage(constructor)) {
return false;
} else if (visibility == Visibility.PRIVATE) {
} else if (constructor.isPrivate()) {
return false;
}

Expand Down
12 changes: 3 additions & 9 deletions java/dagger/hilt/processor/internal/BadInputException.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,37 +16,31 @@

package dagger.hilt.processor.internal;

import static androidx.room.compiler.processing.compat.XConverters.toJavac;

import androidx.room.compiler.processing.XElement;
import com.google.common.collect.ImmutableList;
import javax.lang.model.element.Element;

/**
* Exception to throw when input code has caused an error.
* Includes elements to point to for the cause of the error
*/
public final class BadInputException extends RuntimeException {
private final ImmutableList<Element> badElements;
private final ImmutableList<XElement> badElements;

public BadInputException(String message) {
this(message, ImmutableList.of());
}

public BadInputException(String message, XElement badElement) {
this(message, toJavac(badElement));
}

public BadInputException(String message, Element badElement) {
this(message, ImmutableList.of(badElement));
}

public BadInputException(String message, Iterable<? extends Element> badElements) {
public BadInputException(String message, Iterable<? extends XElement> badElements) {
super(message);
this.badElements = ImmutableList.copyOf(badElements);
}

public ImmutableList<Element> getBadElements() {
public ImmutableList<XElement> getBadElements() {
return badElements;
}
}
28 changes: 6 additions & 22 deletions java/dagger/hilt/processor/internal/HiltCompilerOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package dagger.hilt.processor.internal;

import static androidx.room.compiler.processing.compat.XConverters.getProcessingEnv;
import static androidx.room.compiler.processing.compat.XConverters.toJavac;
import static com.google.common.base.Ascii.toUpperCase;

import androidx.room.compiler.processing.XProcessingEnv;
Expand All @@ -30,8 +29,6 @@
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic.Kind;

/** Hilt annotation processor options. */
Expand Down Expand Up @@ -64,13 +61,13 @@ public static boolean isAndroidSuperClassValidationDisabled(XTypeElement element
* HiltAndroidApp} or {@code HiltAndroidTest} usages in the same compilation unit.
*/
public static boolean isCrossCompilationRootValidationDisabled(
ImmutableSet<TypeElement> rootElements, ProcessingEnvironment env) {
ImmutableSet<XTypeElement> rootElements, XProcessingEnv env) {
EnumOption<BooleanValue> option = DISABLE_CROSS_COMPILATION_ROOT_VALIDATION;
return option.get(env) == BooleanValue.TRUE;
}

/** Returns {@code true} if the check for {@link dagger.hilt.InstallIn} is disabled. */
public static boolean isModuleInstallInCheckDisabled(ProcessingEnvironment env) {
public static boolean isModuleInstallInCheckDisabled(XProcessingEnv env) {
return DISABLE_MODULES_HAVE_INSTALL_IN_CHECK.get(env) == BooleanValue.TRUE;
}

Expand All @@ -82,34 +79,25 @@ public static boolean isModuleInstallInCheckDisabled(ProcessingEnvironment env)
* dagger.hilt.android.testing.BindValue} or a test {@link dagger.Module}) cannot use the shared
* component. In these cases, a component will be generated for the test.
*/
public static boolean isSharedTestComponentsEnabled(ProcessingEnvironment env) {
public static boolean isSharedTestComponentsEnabled(XProcessingEnv env) {
return SHARE_TEST_COMPONENTS.get(env) == BooleanValue.TRUE;
}

/**
* Returns {@code true} if the aggregating processor is enabled (default is {@code true}).
*
* <p>Note:This is for internal use only!
*/
public static boolean useAggregatingRootProcessor(ProcessingEnvironment env) {
return USE_AGGREGATING_ROOT_PROCESSOR.get(env) == BooleanValue.TRUE;
}

/**
* Returns {@code true} if the aggregating processor is enabled (default is {@code true}).
*
* <p>Note:This is for internal use only!
*/
public static boolean useAggregatingRootProcessor(XProcessingEnv env) {
return useAggregatingRootProcessor(toJavac(env));
return USE_AGGREGATING_ROOT_PROCESSOR.get(env) == BooleanValue.TRUE;
}

/**
* Returns project type or null if Hilt Gradle Plugin is not applied.
*
* <p>Note:This is for internal use only!
*/
public static GradleProjectType getGradleProjectType(ProcessingEnvironment env) {
public static GradleProjectType getGradleProjectType(XProcessingEnv env) {
return GRADLE_PROJECT_TYPE.get(env);
}

Expand Down Expand Up @@ -186,11 +174,7 @@ String getQualifiedName() {
return "dagger.hilt." + name;
}

E get(XProcessingEnv processingEnv) {
return get(toJavac(processingEnv));
}

E get(ProcessingEnvironment env) {
E get(XProcessingEnv env) {
String value = env.getOptions().get(getQualifiedName());
if (value == null) {
return defaultValue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import javax.lang.model.element.Element;
import javax.tools.Diagnostic.Kind;

/** Utility class to handle keeping track of errors during processing. */
Expand Down Expand Up @@ -67,8 +66,8 @@ void recordError(Throwable t) {
if (badInput.getBadElements().isEmpty()) {
hiltErrors.add(HiltError.of(badInput.getMessage()));
}
for (Element element : badInput.getBadElements()) {
hiltErrors.add(HiltError.of(badInput.getMessage(), toXProcessing(element, processingEnv)));
for (XElement element : badInput.getBadElements()) {
hiltErrors.add(HiltError.of(badInput.getMessage(), element));
}
} else if (t instanceof ErrorTypeException) {
ErrorTypeException badInput = (ErrorTypeException) t;
Expand Down
142 changes: 5 additions & 137 deletions java/dagger/hilt/processor/internal/ProcessorErrors.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,13 @@

package dagger.hilt.processor.internal;

import static androidx.room.compiler.processing.compat.XConverters.toJavac;
import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList;

import androidx.room.compiler.processing.XElement;
import androidx.room.compiler.processing.compat.XConverters;
import com.google.auto.common.MoreTypes;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.errorprone.annotations.FormatMethod;
import com.google.errorprone.annotations.FormatString;
import java.util.Collection;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;

/** Static helper methods for throwing errors during code generation. */
public final class ProcessorErrors {
Expand Down Expand Up @@ -90,28 +80,11 @@ public static void checkState(
public static void checkState(
boolean expression, XElement badElement, @Nullable Object errorMessage) {
Preconditions.checkNotNull(badElement);
checkState(expression, toJavac(badElement), errorMessage);
}

/**
* Ensures the truth of an expression involving the state of the calling instance, but not
* involving any parameters to the calling method.
*
* @param expression a boolean expression
* @param badElement the element that was at fault
* @param errorMessage the exception message to use if the check fails; will be converted to a
* string using {@link String#valueOf(Object)}
* @throws BadInputException if {@code expression} is false
*/
public static void checkState(
boolean expression, Element badElement, @Nullable Object errorMessage) {
Preconditions.checkNotNull(badElement);
if (!expression) {
throw new BadInputException(String.valueOf(errorMessage), badElement);
}
}

// TODO(kuanyingchou): Remove this method once all usages are migrated to XProcessing.
/**
* Ensures the truth of an expression involving the state of the calling instance, but not
* involving any parameters to the calling method.
Expand All @@ -134,7 +107,7 @@ public static void checkState(
@FormatMethod
public static void checkState(
boolean expression,
Element badElement,
XElement badElement,
@Nullable @FormatString String errorMessageTemplate,
@Nullable Object... errorMessageArgs) {
Preconditions.checkNotNull(badElement);
Expand All @@ -144,86 +117,6 @@ public static void checkState(
}
}

/**
* Ensures the truth of an expression involving the state of the calling instance, but not
* involving any parameters to the calling method.
*
* <p>e.g. checkState(foo.isABar(), "Failed because of %s is not a bar", foo);
*
* @param expression a boolean expression
* @param badElement the element that was at fault
* @param errorMessageTemplate a template for the exception message should the check fail. The
* message is formed by replacing each {@code %s} placeholder in the template with an
* argument. These are matched by position - the first {@code %s} gets {@code
* errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted message in
* square braces. Unmatched placeholders will be left as-is.
* @param errorMessageArgs the arguments to be substituted into the message template. Arguments
* are converted to strings using {@link String#valueOf(Object)}.
* @throws BadInputException if {@code expression} is false
* @throws NullPointerException if the check fails and either {@code errorMessageTemplate} or
* {@code errorMessageArgs} is null (don't let this happen)
*/
@FormatMethod
public static void checkState(
boolean expression,
XElement badElement,
@Nullable @FormatString String errorMessageTemplate,
@Nullable Object... errorMessageArgs) {
checkState(expression, toJavac(badElement), errorMessageTemplate, errorMessageArgs);
}

/**
* Ensures the truth of an expression involving the state of the calling instance, but not
* involving any parameters to the calling method.
*
* @param expression a boolean expression
* @param badElements the element that were at fault
* @param errorMessage the exception message to use if the check fails; will be converted to a
* string using {@link String#valueOf(Object)}
* @throws BadInputException if {@code expression} is false
*/
public static void checkState(
boolean expression,
Collection<? extends Element> badElements,
@Nullable Object errorMessage) {
Preconditions.checkNotNull(badElements);
if (!expression) {
Preconditions.checkState(!badElements.isEmpty());
throw new BadInputException(String.valueOf(errorMessage), badElements);
}
}

/**
* Ensures the truth of an expression involving the state of the calling instance, but not
* involving any parameters to the calling method.
*
* @param expression a boolean expression
* @param badElements the elements that were at fault
* @param errorMessageTemplate a template for the exception message should the check fail. The
* message is formed by replacing each {@code %s} placeholder in the template with an
* argument. These are matched by position - the first {@code %s} gets {@code
* errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted message in
* square braces. Unmatched placeholders will be left as-is.
* @param errorMessageArgs the arguments to be substituted into the message template. Arguments
* are converted to strings using {@link String#valueOf(Object)}.
* @throws BadInputException if {@code expression} is false
* @throws NullPointerException if the check fails and either {@code errorMessageTemplate} or
* {@code errorMessageArgs} is null (don't let this happen)
*/
@FormatMethod
public static void checkState(
boolean expression,
Collection<? extends Element> badElements,
@Nullable @FormatString String errorMessageTemplate,
@Nullable Object... errorMessageArgs) {
Preconditions.checkNotNull(badElements);
if (!expression) {
Preconditions.checkState(!badElements.isEmpty());
throw new BadInputException(
String.format(errorMessageTemplate, errorMessageArgs), badElements);
}
}

/**
* Ensures the truth of an expression involving the state of the calling instance, but not
* involving any parameters to the calling method.
Expand All @@ -250,35 +143,10 @@ public static void checkStateX(
@Nullable @FormatString String errorMessageTemplate,
@Nullable Object... errorMessageArgs) {
Preconditions.checkNotNull(badElements);
checkState(
expression,
badElements.stream().map(XConverters::toJavac).collect(toImmutableList()),
errorMessageTemplate,
errorMessageArgs);
}

/**
* Ensures that the given element is not an error kind and does not inherit from an error kind.
*
* @param element the element to check
* @throws ErrorTypeException if {@code element} inherits from an error kind.
*/
public static void checkNotErrorKind(TypeElement element) {
TypeMirror currType = element.asType();
ImmutableList.Builder<String> typeHierarchy = ImmutableList.builder();
while (currType.getKind() != TypeKind.NONE) {
typeHierarchy.add(currType.toString());
if (currType.getKind() == TypeKind.ERROR) {
throw new ErrorTypeException(
String.format(
"%s, type hierarchy contains error kind, %s."
+ "\n\tThe partially resolved hierarchy is:\n\t\t%s",
element,
currType,
typeHierarchy.build().stream().collect(Collectors.joining(" -> "))),
element);
}
currType = MoreTypes.asTypeElement(currType).getSuperclass();
if (!expression) {
Preconditions.checkState(!badElements.isEmpty());
throw new BadInputException(
String.format(errorMessageTemplate, errorMessageArgs), badElements);
}
}

Expand Down
Loading

0 comments on commit 180c6b2

Please sign in to comment.