aboutsummaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
authorBrad Corso <bcorso@google.com>2021-04-26 17:08:32 -0700
committerDagger Team <dagger-dev+copybara@google.com>2021-04-26 17:10:21 -0700
commitbfdb10962bbd1cdf3c695f3d9fa8b87f8984a21d (patch)
tree3a2e28433dd6ef34814c76fa0d3faa6428f7c7db /java
parentf90a69f4065f05a18fc6ea8fcefe13eba310662d (diff)
downloaddagger2-bfdb10962bbd1cdf3c695f3d9fa8b87f8984a21d.tar.gz
Add flag to disable cross-compilation root validation.
Fixes #2577 RELNOTES=Fixes #2577: Add flag to disable cross-compilation root validation. PiperOrigin-RevId: 370573954
Diffstat (limited to 'java')
-rw-r--r--java/dagger/hilt/android/processor/internal/androidentrypoint/AndroidEntryPointMetadata.java4
-rw-r--r--java/dagger/hilt/processor/internal/BUILD5
-rw-r--r--java/dagger/hilt/processor/internal/HiltCompilerOptions.java74
-rw-r--r--java/dagger/hilt/processor/internal/aggregateddeps/AggregatedDepsProcessor.java4
-rw-r--r--java/dagger/hilt/processor/internal/root/RootMetadata.java4
-rw-r--r--java/dagger/hilt/processor/internal/root/RootProcessor.java55
6 files changed, 96 insertions, 50 deletions
diff --git a/java/dagger/hilt/android/processor/internal/androidentrypoint/AndroidEntryPointMetadata.java b/java/dagger/hilt/android/processor/internal/androidentrypoint/AndroidEntryPointMetadata.java
index cdec4269a..c94f6a977 100644
--- a/java/dagger/hilt/android/processor/internal/androidentrypoint/AndroidEntryPointMetadata.java
+++ b/java/dagger/hilt/android/processor/internal/androidentrypoint/AndroidEntryPointMetadata.java
@@ -16,7 +16,7 @@
package dagger.hilt.android.processor.internal.androidentrypoint;
-import static dagger.hilt.processor.internal.HiltCompilerOptions.BooleanOption.DISABLE_ANDROID_SUPERCLASS_VALIDATION;
+import static dagger.hilt.processor.internal.HiltCompilerOptions.isAndroidSuperclassValidationDisabled;
import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet;
import com.google.auto.common.MoreElements;
@@ -245,7 +245,7 @@ public abstract class AndroidEntryPointMetadata {
final TypeElement baseElement;
final ClassName generatedClassName;
boolean requiresBytecodeInjection =
- DISABLE_ANDROID_SUPERCLASS_VALIDATION.get(env)
+ isAndroidSuperclassValidationDisabled(androidEntryPointElement, env)
&& MoreTypes.isTypeOf(Void.class, androidEntryPointClassValue.asType());
if (requiresBytecodeInjection) {
baseElement = MoreElements.asType(env.getTypeUtils().asElement(androidEntryPointElement.getSuperclass()));
diff --git a/java/dagger/hilt/processor/internal/BUILD b/java/dagger/hilt/processor/internal/BUILD
index 93dba0fb7..978655dea 100644
--- a/java/dagger/hilt/processor/internal/BUILD
+++ b/java/dagger/hilt/processor/internal/BUILD
@@ -154,6 +154,11 @@ java_library(
java_library(
name = "compiler_options",
srcs = ["HiltCompilerOptions.java"],
+ deps = [
+ ":processor_errors",
+ "//java/dagger/internal/guava:collect",
+ "@google_bazel_common//third_party/java/javapoet",
+ ],
)
filegroup(
diff --git a/java/dagger/hilt/processor/internal/HiltCompilerOptions.java b/java/dagger/hilt/processor/internal/HiltCompilerOptions.java
index 7cf82ee3f..0d248239b 100644
--- a/java/dagger/hilt/processor/internal/HiltCompilerOptions.java
+++ b/java/dagger/hilt/processor/internal/HiltCompilerOptions.java
@@ -16,36 +16,74 @@
package dagger.hilt.processor.internal;
+import com.google.common.collect.ImmutableSet;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.TypeElement;
/** Hilt annotation processor options. */
// TODO(danysantiago): Consider consolidating with Dagger compiler options logic.
public final class HiltCompilerOptions {
+ /**
+ * Returns {@code true} if the superclass validation is disabled for
+ * {@link dagger.hilt.android.AndroidEntryPoint}-annotated classes.
+ *
+ * This flag is for internal use only! The superclass validation checks that the super class is a
+ * generated {@code Hilt_} class. This flag is disabled by the Hilt Gradle plugin to enable
+ * bytecode transformation to change the superclass.
+ */
+ public static boolean isAndroidSuperclassValidationDisabled(
+ TypeElement element, ProcessingEnvironment env) {
+ BooleanOption option = BooleanOption.DISABLE_ANDROID_SUPERCLASS_VALIDATION;
+ return option.get(env);
+ }
+
+ /**
+ * Returns {@code true} if cross-compilation root validation is disabled.
+ *
+ * <p>This flag should rarely be needed, but may be used for legacy/migration purposes if
+ * tests require the use of {@link dagger.hilt.android.HiltAndroidApp} rather than
+ * {@link dagger.hilt.android.testing.HiltAndroidTest}.
+ *
+ * <p>Note that Hilt still does validation within a single compilation unit. In particular,
+ * a compilation unit that contains a {@code HiltAndroidApp} usage cannot have other
+ * {@code HiltAndroidApp} or {@code HiltAndroidTest} usages in the same compilation unit.
+ */
+ public static boolean isCrossCompilationRootValidationDisabled(
+ ImmutableSet<TypeElement> rootElements, ProcessingEnvironment env) {
+ BooleanOption option = BooleanOption.DISABLE_CROSS_COMPILATION_ROOT_VALIDATION;
+ return option.get(env);
+ }
+
+ /** Returns {@code true} if the check for {@link dagger.hilt.InstallIn} is disabled. */
+ public static boolean isModuleInstallInCheckDisabled(ProcessingEnvironment env) {
+ return BooleanOption.DISABLE_MODULES_HAVE_INSTALL_IN_CHECK.get(env);
+ }
+
+ /**
+ * Returns {@code true} of unit tests should try to share generated components, rather than using
+ * separate generated components per Hilt test root.
+ *
+ * <p>Tests that provide their own test bindings (e.g. using {@link
+ * 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) {
+ return BooleanOption.SHARE_TEST_COMPONENTS.get(env);
+ }
+
/** Processor options which can have true or false values. */
- public enum BooleanOption {
- /**
- * Flag that disables validating the superclass of @AndroidEntryPoint are Hilt_ generated,
- * classes. This flag is to be used internally by the Gradle plugin, enabling the bytecode
- * transformation to change the superclass.
- */
+ private enum BooleanOption {
DISABLE_ANDROID_SUPERCLASS_VALIDATION(
"android.internal.disableAndroidSuperclassValidation", false),
- /** Flag that disables check on modules to be annotated with @InstallIn. */
+ DISABLE_CROSS_COMPILATION_ROOT_VALIDATION("disableCrossCompilationRootValidation", false),
+
DISABLE_MODULES_HAVE_INSTALL_IN_CHECK("disableModulesHaveInstallInCheck", false),
- /**
- * Flag that enables unit tests to share a single generated Component, rather than using a
- * separate generated Component per Hilt test root.
- *
- * <p>Tests that provide their own test bindings (e.g. using {@link
- * 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.
- */
SHARE_TEST_COMPONENTS("shareTestComponents", false);
private final String name;
@@ -56,7 +94,7 @@ public final class HiltCompilerOptions {
this.defaultValue = defaultValue;
}
- public boolean get(ProcessingEnvironment env) {
+ boolean get(ProcessingEnvironment env) {
String value = env.getOptions().get(getQualifiedName());
if (value == null) {
return defaultValue;
@@ -65,7 +103,7 @@ public final class HiltCompilerOptions {
return Boolean.parseBoolean(value);
}
- public String getQualifiedName() {
+ String getQualifiedName() {
return "dagger.hilt." + name;
}
}
@@ -75,6 +113,4 @@ public final class HiltCompilerOptions {
.map(BooleanOption::getQualifiedName)
.collect(Collectors.toSet());
}
-
- private HiltCompilerOptions() {}
}
diff --git a/java/dagger/hilt/processor/internal/aggregateddeps/AggregatedDepsProcessor.java b/java/dagger/hilt/processor/internal/aggregateddeps/AggregatedDepsProcessor.java
index c45b373cb..151401e60 100644
--- a/java/dagger/hilt/processor/internal/aggregateddeps/AggregatedDepsProcessor.java
+++ b/java/dagger/hilt/processor/internal/aggregateddeps/AggregatedDepsProcessor.java
@@ -20,7 +20,7 @@ import static com.google.auto.common.AnnotationMirrors.getAnnotationValue;
import static com.google.auto.common.MoreElements.asType;
import static com.google.auto.common.MoreElements.getPackage;
import static com.google.common.collect.Iterables.getOnlyElement;
-import static dagger.hilt.processor.internal.HiltCompilerOptions.BooleanOption.DISABLE_MODULES_HAVE_INSTALL_IN_CHECK;
+import static dagger.hilt.processor.internal.HiltCompilerOptions.isModuleInstallInCheckDisabled;
import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList;
import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet;
import static javax.lang.model.element.ElementKind.CLASS;
@@ -398,7 +398,7 @@ public final class AggregatedDepsProcessor extends BaseProcessor {
}
private boolean installInCheckDisabled(Element element) {
- return DISABLE_MODULES_HAVE_INSTALL_IN_CHECK.get(getProcessingEnv())
+ return isModuleInstallInCheckDisabled(getProcessingEnv())
|| Processors.hasAnnotation(element, ClassNames.DISABLE_INSTALL_IN_CHECK);
}
diff --git a/java/dagger/hilt/processor/internal/root/RootMetadata.java b/java/dagger/hilt/processor/internal/root/RootMetadata.java
index 1a115034f..b39b590ef 100644
--- a/java/dagger/hilt/processor/internal/root/RootMetadata.java
+++ b/java/dagger/hilt/processor/internal/root/RootMetadata.java
@@ -18,7 +18,7 @@ package dagger.hilt.processor.internal.root;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Suppliers.memoize;
-import static dagger.hilt.processor.internal.HiltCompilerOptions.BooleanOption.SHARE_TEST_COMPONENTS;
+import static dagger.hilt.processor.internal.HiltCompilerOptions.isSharedTestComponentsEnabled;
import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet;
import static javax.lang.model.element.Modifier.ABSTRACT;
import static javax.lang.model.element.Modifier.PRIVATE;
@@ -133,7 +133,7 @@ public final class RootMetadata {
// TODO(groakley): Allow more tests to share modules, e.g. tests that uninstall the same module.
// In that case, this might instead return which shared dep grouping should be used.
public boolean canShareTestComponents() {
- return SHARE_TEST_COMPONENTS.get(env)
+ return isSharedTestComponentsEnabled(env)
&& root.isTestRoot()
&& !deps.includesTestDeps(root.classname());
}
diff --git a/java/dagger/hilt/processor/internal/root/RootProcessor.java b/java/dagger/hilt/processor/internal/root/RootProcessor.java
index 3ef896364..1ee4446d4 100644
--- a/java/dagger/hilt/processor/internal/root/RootProcessor.java
+++ b/java/dagger/hilt/processor/internal/root/RootProcessor.java
@@ -17,7 +17,8 @@
package dagger.hilt.processor.internal.root;
import static com.google.common.base.Preconditions.checkState;
-import static dagger.hilt.processor.internal.HiltCompilerOptions.BooleanOption.SHARE_TEST_COMPONENTS;
+import static dagger.hilt.processor.internal.HiltCompilerOptions.isCrossCompilationRootValidationDisabled;
+import static dagger.hilt.processor.internal.HiltCompilerOptions.isSharedTestComponentsEnabled;
import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList;
import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet;
import static java.util.Comparator.comparing;
@@ -136,7 +137,7 @@ public final class RootProcessor extends BaseProcessor {
boolean isTestEnv = rootsToProcess.stream().anyMatch(Root::isTestRoot);
ComponentNames componentNames =
- isTestEnv && SHARE_TEST_COMPONENTS.get(getProcessingEnv())
+ isTestEnv && isSharedTestComponentsEnabled(getProcessingEnv())
? ComponentNames.withRenamingIntoPackage(
ClassNames.DEFAULT_ROOT.packageName(),
rootsToProcess.stream().map(Root::element).collect(toImmutableList()))
@@ -202,23 +203,6 @@ public final class RootProcessor extends BaseProcessor {
.sorted(QUALIFIED_NAME_COMPARATOR)
.collect(toImmutableSet());
- ImmutableSet<TypeElement> processedTestRootElements =
- allRoots.stream()
- .filter(Root::isTestRoot)
- .filter(root -> !rootsToProcess.contains(root))
- .map(Root::element)
- .sorted(QUALIFIED_NAME_COMPARATOR)
- .collect(toImmutableSet());
-
- // TODO(b/185742783): Add an explanation or link to docs to explain why we're forbidding this.
- ProcessorErrors.checkState(
- processedTestRootElements.isEmpty(),
- "Cannot process new roots when there are test roots from a previous compilation unit:"
- + "\n\tTest roots from previous compilation unit: %s"
- + "\n\tAll roots from this compilation unit: %s",
- processedTestRootElements,
- rootElementsToProcess);
-
ImmutableSet<TypeElement> appRootElementsToProcess =
rootsToProcess.stream()
.filter(root -> !root.isTestRoot())
@@ -226,6 +210,7 @@ public final class RootProcessor extends BaseProcessor {
.sorted(QUALIFIED_NAME_COMPARATOR)
.collect(toImmutableSet());
+ // Perform validation between roots in this compilation unit.
if (!appRootElementsToProcess.isEmpty()) {
ImmutableSet<TypeElement> testRootElementsToProcess =
rootsToProcess.stream()
@@ -242,6 +227,31 @@ public final class RootProcessor extends BaseProcessor {
appRootElementsToProcess,
testRootElementsToProcess);
+ ProcessorErrors.checkState(
+ appRootElementsToProcess.size() == 1,
+ "Cannot process multiple app roots in the same compilation unit: %s",
+ appRootElementsToProcess);
+ }
+
+ // Perform validation across roots previous compilation units.
+ if (!isCrossCompilationRootValidationDisabled(rootElementsToProcess, getProcessingEnv())) {
+ ImmutableSet<TypeElement> processedTestRootElements =
+ allRoots.stream()
+ .filter(Root::isTestRoot)
+ .filter(root -> !rootsToProcess.contains(root))
+ .map(Root::element)
+ .sorted(QUALIFIED_NAME_COMPARATOR)
+ .collect(toImmutableSet());
+
+ // TODO(b/185742783): Add an explanation or link to docs to explain why we're forbidding this.
+ ProcessorErrors.checkState(
+ processedTestRootElements.isEmpty(),
+ "Cannot process new roots when there are test roots from a previous compilation unit:"
+ + "\n\tTest roots from previous compilation unit: %s"
+ + "\n\tAll roots from this compilation unit: %s",
+ processedTestRootElements,
+ rootElementsToProcess);
+
ImmutableSet<TypeElement> processedAppRootElements =
allRoots.stream()
.filter(root -> !root.isTestRoot())
@@ -251,18 +261,13 @@ public final class RootProcessor extends BaseProcessor {
.collect(toImmutableSet());
ProcessorErrors.checkState(
- processedAppRootElements.isEmpty(),
+ processedAppRootElements.isEmpty() || appRootElementsToProcess.isEmpty(),
"Cannot process app roots in this compilation unit since there are app roots in a "
+ "previous compilation unit:"
+ "\n\tApp roots in previous compilation unit: %s"
+ "\n\tApp roots in this compilation unit: %s",
processedAppRootElements,
appRootElementsToProcess);
-
- ProcessorErrors.checkState(
- appRootElementsToProcess.size() == 1,
- "Cannot process multiple app roots in the same compilation unit: %s",
- appRootElementsToProcess);
}
}