diff options
author | Sadaf Ebrahimi <sadafebrahimi@google.com> | 2024-03-05 22:32:05 +0000 |
---|---|---|
committer | Sadaf Ebrahimi <sadafebrahimi@google.com> | 2024-04-10 16:26:18 +0000 |
commit | 6e122a5665bfe6169574f578311d44f81d3882d3 (patch) | |
tree | 8c39faf93432b4da3e7ef07f5643befaa87ec726 | |
parent | 7a2c823d73c7cf0fff8a3f1e622aae46c546fa03 (diff) | |
parent | 0786d0af598028098849cb88a16b72549f238dcc (diff) | |
download | dagger2-main.tar.gz |
This project was upgraded with external_updater.
Usage: tools/external_updater/updater.sh update dagger2
For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md
Test: TreeHugger
Change-Id: I6a876e5d65cdd1d83ad3db931a09c349bdfa17cd
803 files changed, 15640 insertions, 7190 deletions
diff --git a/.github/actions/artifact-android-local-tests/action.yml b/.github/actions/artifact-android-local-tests/action.yml index 54109851f..c4b24eb48 100644 --- a/.github/actions/artifact-android-local-tests/action.yml +++ b/.github/actions/artifact-android-local-tests/action.yml @@ -5,6 +5,18 @@ inputs: agp: description: 'The version of AGP to test with.' required: true + type: choice + options: + - '7.0.0' + - '7.1.2' + - '8.1.0' + jdk: + description: 'The version of JDK to test with.' + required: true + type: choice + options: + - '11' + - '17' runs: using: "composite" @@ -25,11 +37,11 @@ runs: with: name: local-snapshot path: ~/.m2/repository/com/google/dagger - - name: 'Install Java ${{ env.USE_JAVA_VERSION }}' + - name: 'Install Java ${{ inputs.jdk }}' uses: actions/setup-java@v3 with: distribution: '${{ env.USE_JAVA_DISTRIBUTION }}' - java-version: '${{ env.USE_JAVA_VERSION }}' + java-version: '${{ inputs.jdk }}' - name: 'Gradle Android local tests (AGP ${{ inputs.agp }})' run: ./util/run-local-gradle-android-tests.sh "${{ inputs.agp }}" shell: bash diff --git a/.github/actions/cleanup-caches/action.yml b/.github/actions/cleanup-caches/action.yml new file mode 100644 index 000000000..294d62451 --- /dev/null +++ b/.github/actions/cleanup-caches/action.yml @@ -0,0 +1,13 @@ +name: 'Clean up caches' +description: 'Cleans up GitHub Action caches.' + +runs: + using: "composite" + steps: + - name: 'Check out repository' + uses: actions/checkout@v3 + - name: 'Cleanup caches' + run: python ./util/cleanup-github-caches.py + shell: bash + env: + GITHUB_TOKEN: ${{ github.token }} diff --git a/.github/actions/prechecks/action.yml b/.github/actions/prechecks/action.yml index 3ff6ec0da..09dc5d9cd 100644 --- a/.github/actions/prechecks/action.yml +++ b/.github/actions/prechecks/action.yml @@ -20,3 +20,10 @@ runs: shell: bash env: GH_TOKEN: ${{ github.token }} + - name: 'Check out repository' + uses: actions/checkout@v3 + - name: 'Cleanup caches' + run: python ./util/cleanup-github-caches.py + shell: bash + env: + GITHUB_TOKEN: ${{ github.token }} diff --git a/.github/actions/test-gradle-plugin/action.yml b/.github/actions/test-gradle-plugin/action.yml index 55232789b..bd5747294 100644 --- a/.github/actions/test-gradle-plugin/action.yml +++ b/.github/actions/test-gradle-plugin/action.yml @@ -4,11 +4,11 @@ description: 'Tests the Hilt Gradle plugin.' runs: using: "composite" steps: - - name: 'Install Java ${{ env.USE_JAVA_VERSION }}' + - name: 'Install Java ${{ env.USE_JAVA_VERSION_FOR_PLUGIN }}' uses: actions/setup-java@v3 with: distribution: '${{ env.USE_JAVA_DISTRIBUTION }}' - java-version: '${{ env.USE_JAVA_VERSION }}' + java-version: '${{ env.USE_JAVA_VERSION_FOR_PLUGIN }}' - name: 'Check out repository' uses: actions/checkout@v3 - name: 'Cache local Maven repository' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f4650e7ab..d50fcec92 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,9 +11,11 @@ on: env: USE_JAVA_DISTRIBUTION: 'zulu' USE_JAVA_VERSION: '11' - # Our Bazel builds currently rely on 5.3.2. The version is set via + # This is required by AGP 8.3+. + USE_JAVA_VERSION_FOR_PLUGIN: '17' + # Our Bazel builds currently rely on 6.4.0. The version is set via # baselisk by USE_BAZEL_VERSION: https://github.com/bazelbuild/bazelisk. - USE_BAZEL_VERSION: '5.3.2' + USE_BAZEL_VERSION: '6.4.0' # The default Maven 3.9.0 has a regression so we manually install 3.8.7. # https://issues.apache.org/jira/browse/MNG-7679 USE_MAVEN_VERSION: '3.8.7' @@ -35,7 +37,9 @@ jobs: bazel-test: name: 'Bazel tests' needs: validate-latest-dagger-version - runs-on: ubuntu-latest + runs-on: + group: large-runner + labels: ubuntu-22.04-16core steps: - uses: actions/checkout@v3 - uses: ./.github/actions/bazel-test @@ -59,24 +63,19 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - agp: ['7.0.0', '7.1.2'] + include: + - agp: '7.0.0' + jdk: '11' + - agp: '7.1.2' + jdk: '11' + - agp: '8.1.0' + jdk: '17' steps: - uses: actions/checkout@v3 - uses: ./.github/actions/artifact-android-local-tests with: agp: '${{ matrix.agp }}' - artifact-android-emulator-tests: - name: 'Artifact Android emulator tests (API 30)' - needs: bazel-build - # It's recommended to run emulator tests on macOS - # See https://github.com/marketplace/actions/android-emulator-runner - runs-on: macos-latest - steps: - - uses: actions/checkout@v3 - - uses: ./.github/actions/artifact-android-emulator-tests - timeout-minutes: 30 # TODO(b/287486065) investigate whether there is performance regression - with: - api-level: '30' + jdk: '${{ matrix.jdk }}' artifact-android-emulator-legacy-api-tests: name: 'Artifact Android emulator tests (API ${{ matrix.api-level }})' # We only run this on master push (essentially a postsubmit) since these @@ -88,11 +87,11 @@ jobs: runs-on: macos-latest strategy: matrix: # Run on 16 (PreL), 21 (L), and 26 (O). - api-level: [16, 21, 26] + api-level: [16, 21, 26, 30] steps: - uses: actions/checkout@v3 - uses: ./.github/actions/artifact-android-emulator-tests - timeout-minutes: 25 + timeout-minutes: 35 with: api-level: '${{ matrix.api-level }}' publish-snapshot: @@ -174,3 +173,12 @@ jobs: - uses: ./.github/actions/build-gradle-plugin with: agp: '+' + cleanup-caches: + name: 'Clean up GitHub Action caches' + # TODO(bcorso): Consider also waiting on artifact-android-emulator-tests + # and artifact-android-emulator-legacy-api-tests after checking flakiness. + needs: [bazel-test, artifact-java-local-tests, artifact-android-local-tests, test-gradle-plugin] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: ./.github/actions/cleanup-caches diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fd371b190..b16c0d58c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,9 +10,11 @@ on: env: USE_JAVA_DISTRIBUTION: 'zulu' USE_JAVA_VERSION: '11' - # Our Bazel builds currently rely on 5.3.2. The version is set via + # This is required by AGP 8.3+. + USE_JAVA_VERSION_FOR_PLUGIN: '17' + # Our Bazel builds currently rely on 6.4.0. The version is set via # baselisk by USE_BAZEL_VERSION: https://github.com/bazelbuild/bazelisk. - USE_BAZEL_VERSION: '5.3.2' + USE_BAZEL_VERSION: '6.4.0' DAGGER_RELEASE_VERSION: "${{ github.event.inputs.dagger_release_version }}" # The default Maven 3.9.0 has a regression so we manually install 3.8.7. # https://issues.apache.org/jira/browse/MNG-7679 @@ -37,7 +39,9 @@ jobs: bazel-test: name: 'Bazel tests' needs: validate-latest-dagger-version - runs-on: ubuntu-latest + runs-on: + group: large-runner + labels: ubuntu-22.04-16core steps: - uses: actions/checkout@v3 - uses: ./.github/actions/bazel-test @@ -61,12 +65,19 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - agp: ['7.0.0', '7.1.2'] + include: + - agp: '7.0.0' + jdk: '11' + - agp: '7.1.2' + jdk: '11' + - agp: '8.1.0' + jdk: '17' steps: - uses: actions/checkout@v3 - uses: ./.github/actions/artifact-android-local-tests with: agp: '${{ matrix.agp }}' + jdk: '${{ matrix.jdk }}' publish-artifacts: name: 'Publish Artifact' needs: [bazel-test, artifact-java-local-tests, artifact-android-local-tests, test-gradle-plugin] @@ -76,17 +76,6 @@ android_library( ) jarjar_library( - name = "shaded_android_processor", - jars = [ - "//java/dagger/android/processor", - "//third_party/java/auto:common", - ], - rules = [ - "rule com.google.auto.common.** dagger.android.shaded.auto.common.@1", - ], -) - -jarjar_library( name = "shaded_grpc_server_processor", jars = [ "//java/dagger/grpc/server/processor", @@ -1,23 +1,20 @@ # This project was upgraded with external_updater. -# Usage: tools/external_updater/updater.sh update dagger2 -# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md +# Usage: tools/external_updater/updater.sh update external/dagger2 +# For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md name: "dagger2" description: "A fast dependency injector for Android and Java." third_party { - url { - type: HOMEPAGE - value: "https://dagger.dev" - } - url { - type: GIT - value: "https://github.com/google/dagger" - } - version: "dagger-2.47" license_type: NOTICE last_upgrade_date { - year: 2023 - month: 8 - day: 2 + year: 2024 + month: 3 + day: 5 + } + homepage: "https://dagger.dev" + identifier { + type: "Git" + value: "https://github.com/google/dagger" + version: "dagger-2.51" } } @@ -38,8 +38,8 @@ release. load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") -DAGGER_TAG = "2.46.1" -DAGGER_SHA = "bbd75275faa3186ebaa08e6779dc5410741a940146d43ef532306eb2682c13f7" +DAGGER_TAG = "2.50" +DAGGER_SHA = "764993ba2465551c181b84b47e467f86fb367d8c0cd50154bd5519a4afb57753" http_archive( name = "dagger", strip_prefix = "dagger-dagger-%s" % DAGGER_TAG, @@ -26,33 +26,19 @@ local_repository( ) ############################# -# Load Bazel-Common repository -############################# - -http_archive( - name = "google_bazel_common", - sha256 = "60a9aebe25f476646f61c041d1679a9b21076deffbd51526838c7f24d6468ac0", - strip_prefix = "bazel-common-227a23a508a2fab0fa67ffe2d9332ae536a40edc", - urls = ["https://github.com/google/bazel-common/archive/227a23a508a2fab0fa67ffe2d9332ae536a40edc.zip"], -) - -load("@google_bazel_common//:workspace_defs.bzl", "google_common_workspace_rules") - -google_common_workspace_rules() - -############################# # Load Bazel Skylib rules ############################# -BAZEL_SKYLIB_VERSION = "1.2.1" +BAZEL_SKYLIB_VERSION = "1.5.0" -BAZEL_SKYLIB_SHA = "f7be3474d42aae265405a592bb7da8e171919d74c16f082a5457840f06054728" +BAZEL_SKYLIB_SHA = "cd55a062e763b9349921f0f5db8c3933288dc8ba4f76dd9416aac68acee3cb94" http_archive( name = "bazel_skylib", sha256 = BAZEL_SKYLIB_SHA, urls = [ - "https://github.com/bazelbuild/bazel-skylib/releases/download/{version}/bazel-skylib-{version}.tar.gz".format(version = BAZEL_SKYLIB_VERSION), + "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/%s/bazel-skylib-%s.tar.gz" % (BAZEL_SKYLIB_VERSION, BAZEL_SKYLIB_VERSION), + "https://github.com/bazelbuild/bazel-skylib/releases/download/%s/bazel-skylib-%s.tar.gz" % (BAZEL_SKYLIB_VERSION, BAZEL_SKYLIB_VERSION), ], ) @@ -60,6 +46,42 @@ load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") bazel_skylib_workspace() +#################################################### +# Load Protobuf repository (needed by bazel-common) +#################################################### + +http_archive( + name = "rules_proto", + # output from `sha256sum` on the downloaded tar.gz file + sha256 = "66bfdf8782796239d3875d37e7de19b1d94301e8972b3cbd2446b332429b4df1", + strip_prefix = "rules_proto-4.0.0", + urls = [ + "https://mirror.bazel.build/github.com/bazelbuild/rules_proto/archive/refs/tags/4.0.0.tar.gz", + "https://github.com/bazelbuild/rules_proto/archive/refs/tags/4.0.0.tar.gz", + ], +) + +load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains") + +rules_proto_dependencies() + +rules_proto_toolchains() + +############################# +# Load Bazel-Common repository +############################# + +http_archive( + name = "google_bazel_common", + sha256 = "82a49fb27c01ad184db948747733159022f9464fc2e62da996fa700594d9ea42", + strip_prefix = "bazel-common-2a6b6406e12208e02b2060df0631fb30919080f3", + urls = ["https://github.com/google/bazel-common/archive/2a6b6406e12208e02b2060df0631fb30919080f3.zip"], +) + +load("@google_bazel_common//:workspace_defs.bzl", "google_common_workspace_rules") + +google_common_workspace_rules() + ############################# # Load Protobuf dependencies ############################# @@ -107,9 +129,9 @@ robolectric_repositories() # Load Kotlin repository ############################# -RULES_KOTLIN_TAG = "v1.8-RC-1" +RULES_KOTLIN_TAG = "v1.8" -RULES_KOTLIN_SHA = "1779628569eb3b0fe97a3fb5c3ed8090e6503e425600b401c7b1afb6b23a3098" +RULES_KOTLIN_SHA = "01293740a16e474669aba5b5a1fe3d368de5832442f164e4fbfc566815a8bc3a" http_archive( name = "io_bazel_rules_kotlin", @@ -119,10 +141,10 @@ http_archive( load("@io_bazel_rules_kotlin//kotlin:repositories.bzl", "kotlin_repositories", "kotlinc_version") -KOTLIN_VERSION = "1.8.0" +KOTLIN_VERSION = "1.9.20" # Get from https://github.com/JetBrains/kotlin/releases/ -KOTLINC_RELEASE_SHA = "0bb9419fac9832a56a3a19cad282f8f2d6f1237d2d467dc8dfe9bd4a2a43c42e" +KOTLINC_RELEASE_SHA = "15a8a2825b74ccf6c44e04e97672db802d2df75ce2fbb63ef0539bf3ae5006f0" kotlin_repositories( compiler_release = kotlinc_version( @@ -139,9 +161,9 @@ kt_register_toolchains() # Load Maven dependencies ############################# -RULES_JVM_EXTERNAL_TAG = "4.2" +RULES_JVM_EXTERNAL_TAG = "4.5" -RULES_JVM_EXTERNAL_SHA = "cd1a77b7b02e8e008439ca76fd34f5b07aecb8c752961f9640dea15e9e5ba1ca" +RULES_JVM_EXTERNAL_SHA = "b17d7388feb9bfa7f2fa09031b32707df529f26c91ab9e5d909eb1676badd9a6" http_archive( name = "rules_jvm_external", @@ -159,7 +181,7 @@ AUTO_COMMON_VERSION = "1.2.1" # NOTE(bcorso): Even though we set the version here, our Guava version in # processor code will use whatever version is built into JavaBuilder, which is # tied to the version of Bazel we're using. -GUAVA_VERSION = "27.1" +GUAVA_VERSION = "33.0.0" GRPC_VERSION = "1.2.0" @@ -171,11 +193,12 @@ CHECKER_FRAMEWORK_VERSION = "2.5.3" ERROR_PRONE_VERSION = "2.14.0" -KSP_VERSION = KOTLIN_VERSION + "-1.0.9" +KSP_VERSION = KOTLIN_VERSION + "-1.0.14" maven_install( artifacts = [ "androidx.annotation:annotation:1.1.0", + "androidx.annotation:annotation-experimental:1.3.1", "androidx.appcompat:appcompat:1.3.1", "androidx.activity:activity:1.5.1", "androidx.fragment:fragment:1.5.1", @@ -220,7 +243,7 @@ maven_install( "com.google.guava:guava-beta-checker:1.0", "com.google.protobuf:protobuf-java:3.7.0", "com.google.testing.compile:compile-testing:0.18", - "com.google.truth:truth:1.1", + "com.google.truth:truth:1.4.0", "com.squareup:javapoet:1.13.0", "com.squareup:kotlinpoet:1.11.0", "io.github.java-diff-utils:java-diff-utils:4.11", @@ -246,6 +269,7 @@ maven_install( "org.jetbrains.kotlin:kotlin-daemon-embeddable:%s" % KOTLIN_VERSION, "org.jetbrains.kotlin:kotlin-stdlib:%s" % KOTLIN_VERSION, "org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.6.2", + "org.jspecify:jspecify:0.3.0", "org.mockito:mockito-core:2.28.2", "org.objenesis:objenesis:1.0", "org.robolectric:robolectric:4.4", diff --git a/examples/bazel/WORKSPACE b/examples/bazel/WORKSPACE index 3291f3a69..3ad378c7e 100644 --- a/examples/bazel/WORKSPACE +++ b/examples/bazel/WORKSPACE @@ -42,9 +42,7 @@ load( android_sdk_repository( name = "androidsdk", api_level = 32, - # Need to upgrade Bazel before upgrading tools - # https://github.com/bazelbuild/bazel/issues/13989 - build_tools_version = "30.0.3", + build_tools_version = "32.0.0", ) ############################# diff --git a/java/dagger/BUILD b/java/dagger/BUILD index 4675e3054..918340825 100644 --- a/java/dagger/BUILD +++ b/java/dagger/BUILD @@ -22,8 +22,7 @@ load( "JAVA_RELEASE_MIN", "POM_VERSION", ) -load("//tools:maven.bzl", "pom_file") -load("@google_bazel_common//tools/javadoc:javadoc.bzl", "javadoc_library") +load("//tools:maven.bzl", "gen_maven_artifact") package(default_visibility = ["//:src"]) @@ -38,22 +37,21 @@ java_library( ], ) -pom_file( - name = "pom", - artifact_id = "dagger", +gen_maven_artifact( + name = "artifact", + artifact_coordinates = "com.google.dagger:dagger:" + POM_VERSION, artifact_name = "Dagger", - targets = [":core"], + artifact_target = ":core", + artifact_target_maven_deps = [ + "javax.inject:javax.inject", + ], + javadoc_root_packages = ["dagger"], + javadoc_srcs = [":javadoc-srcs"], + proguard_specs = [":proguard.pro"], + r8_specs = [":r8.pro"], ) filegroup( name = "javadoc-srcs", srcs = glob(["**/*"]), ) - -javadoc_library( - name = "core-javadoc", - srcs = [":javadoc-srcs"], - exclude_packages = ["dagger.internal"], - root_packages = ["dagger"], - deps = ["//third_party/java/jsr330_inject"], -) diff --git a/java/dagger/android/BUILD b/java/dagger/android/BUILD index ef41dde4a..686e6aef5 100644 --- a/java/dagger/android/BUILD +++ b/java/dagger/android/BUILD @@ -17,14 +17,14 @@ load( "//:build_defs.bzl", - "DOCLINT_HTML_AND_SYNTAX", - "DOCLINT_REFERENCES", - "JAVA_RELEASE_MIN", "POM_VERSION", ) load("//tools:dejetify.bzl", "dejetified_library") -load("//tools:maven.bzl", "pom_file") -load("@google_bazel_common//tools/javadoc:javadoc.bzl", "javadoc_library") +load( + "//tools:maven.bzl", + "gen_maven_artifact", + "pom_file", +) package(default_visibility = ["//:src"]) @@ -43,8 +43,6 @@ filegroup( android_library( name = "android", srcs = SRCS, - javacopts = JAVA_RELEASE_MIN + DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES, - manifest = "AndroidManifest.xml", plugins = [ "//java/dagger/android/internal/proguard:plugin", ], @@ -60,17 +58,28 @@ android_library( ], ) -pom_file( - name = "pom", - artifact_id = "dagger-android", +gen_maven_artifact( + name = "artifact", + artifact_coordinates = "com.google.dagger:dagger-android:" + POM_VERSION, artifact_name = "Dagger Android", + artifact_target = ":android", + artifact_target_maven_deps = [ + "androidx.annotation:annotation", + "com.google.dagger:dagger", + "com.google.dagger:dagger-lint-aar", + ], + javadoc_android_api_level = 32, + javadoc_root_packages = [ + "dagger.android", + ], + javadoc_srcs = [":android-srcs"], + manifest = "AndroidManifest.xml", packaging = "aar", - targets = [":android"], ) dejetified_library( name = "dejetified-android", - input = ":android.aar", + input = ":artifact.aar", output = "android-legacy.aar", ) @@ -92,12 +101,3 @@ pom_file( packaging = "aar", targets = [":legacy-deps"], ) - -javadoc_library( - name = "android-javadoc", - srcs = [":android-srcs"], - android_api_level = 30, - exclude_packages = ["dagger.android.internal"], - root_packages = ["dagger.android"], - deps = [":android"], -) diff --git a/java/dagger/android/internal/proguard/BUILD b/java/dagger/android/internal/proguard/BUILD index 5a85279fb..7cb2cbc5d 100644 --- a/java/dagger/android/internal/proguard/BUILD +++ b/java/dagger/android/internal/proguard/BUILD @@ -22,10 +22,19 @@ package(default_visibility = ["//:src"]) java_library( name = "proguard-processor", - srcs = ["ProguardProcessor.java"], + srcs = [ + "KspProguardProcessor.java", + "ProguardProcessingStep.java", + "ProguardProcessor.java", + ], javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES, deps = [ + "//java/dagger/android/processor:base_processing_step", + "//java/dagger/internal/codegen/xprocessing", "//third_party/java/auto:service", + "//third_party/java/guava/collect", + "//third_party/java/javapoet", + "@maven//:com_google_devtools_ksp_symbol_processing_api", ], ) diff --git a/java/dagger/android/internal/proguard/KspProguardProcessor.java b/java/dagger/android/internal/proguard/KspProguardProcessor.java new file mode 100644 index 000000000..e2d4c4c3b --- /dev/null +++ b/java/dagger/android/internal/proguard/KspProguardProcessor.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2024 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.android.internal.proguard; + +import androidx.room.compiler.processing.XProcessingEnv; +import androidx.room.compiler.processing.XProcessingEnvConfig; +import androidx.room.compiler.processing.XProcessingStep; +import androidx.room.compiler.processing.ksp.KspBasicAnnotationProcessor; +import com.google.auto.service.AutoService; +import com.google.common.collect.ImmutableList; +import com.google.devtools.ksp.processing.SymbolProcessor; +import com.google.devtools.ksp.processing.SymbolProcessorEnvironment; +import com.google.devtools.ksp.processing.SymbolProcessorProvider; + +/** + * An annotation processor to generate dagger-android's specific proguard needs. This is only + * intended to run over the dagger-android project itself, as the alternative is to create an + * intermediary java_library for proguard rules to be consumed by the project. + * + * <p>Basic structure looks like this: + * + * <pre><code> + * resources/META-INF/com.android.tools/proguard/dagger-android.pro + * resources/META-INF/com.android.tools/r8/dagger-android.pro + * resources/META-INF/proguard/dagger-android.pro + * </code></pre> + */ +public final class KspProguardProcessor extends KspBasicAnnotationProcessor { + private static final XProcessingEnvConfig PROCESSING_ENV_CONFIG = + new XProcessingEnvConfig.Builder().build(); + private XProcessingEnv env; + + private KspProguardProcessor(SymbolProcessorEnvironment symbolProcessorEnvironment) { + super(symbolProcessorEnvironment, PROCESSING_ENV_CONFIG); + } + + @Override + public void initialize(XProcessingEnv env) { + this.env = env; + } + + @Override + public Iterable<XProcessingStep> processingSteps() { + return ImmutableList.of(new ProguardProcessingStep(env)); + } + + /** Provides the {@link KspProguardProcessor}. */ + @AutoService(SymbolProcessorProvider.class) + public static final class Provider implements SymbolProcessorProvider { + @Override + public SymbolProcessor create(SymbolProcessorEnvironment symbolProcessorEnvironment) { + return new KspProguardProcessor(symbolProcessorEnvironment); + } + } +} diff --git a/java/dagger/android/internal/proguard/ProguardProcessingStep.java b/java/dagger/android/internal/proguard/ProguardProcessingStep.java new file mode 100644 index 000000000..c4cc0612d --- /dev/null +++ b/java/dagger/android/internal/proguard/ProguardProcessingStep.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2024 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.android.internal.proguard; + +import static java.nio.charset.StandardCharsets.UTF_8; + +import androidx.room.compiler.processing.XElement; +import androidx.room.compiler.processing.XFiler; +import androidx.room.compiler.processing.XProcessingEnv; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.squareup.javapoet.ClassName; +import dagger.android.processor.BaseProcessingStep; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.nio.file.Path; + +/** + * A annotation processing step to generate dagger-android's specific proguard needs. This is only + * intended to run over the dagger-android project itself, as the alternative is to create an + * intermediary java_library for proguard rules to be consumed by the project. + * + * <p>Basic structure looks like this: + * + * <pre><code> + * resources/META-INF/com.android.tools/proguard/dagger-android.pro + * resources/META-INF/com.android.tools/r8/dagger-android.pro + * resources/META-INF/proguard/dagger-android.pro + * </code></pre> + */ +public final class ProguardProcessingStep extends BaseProcessingStep { + private final XProcessingEnv processingEnv; + + ProguardProcessingStep(XProcessingEnv processingEnv) { + this.processingEnv = processingEnv; + } + + static final ClassName GENERATE_RULES_ANNOTATION_NAME = + ClassName.get("dagger.android.internal", "GenerateAndroidInjectionProguardRules"); + + @Override + public ImmutableSet<ClassName> annotationClassNames() { + return ImmutableSet.of(GENERATE_RULES_ANNOTATION_NAME); + } + + @Override + public void process(XElement element, ImmutableSet<ClassName> annotationNames) { + XFiler filer = processingEnv.getFiler(); + + String errorProneRule = "-dontwarn com.google.errorprone.annotations.**\n"; + String androidInjectionKeysRule = + "-identifiernamestring class dagger.android.internal.AndroidInjectionKeys {\n" + + " java.lang.String of(java.lang.String);\n" + + "}\n"; + + writeFile(filer, "com.android.tools/proguard", errorProneRule); + writeFile(filer, "com.android.tools/r8", errorProneRule + androidInjectionKeysRule); + writeFile(filer, "proguard", errorProneRule); + } + + private void writeFile(XFiler filer, String intermediatePath, String contents) { + try (OutputStream outputStream = + filer.writeResource( + Path.of("META-INF/" + intermediatePath + "/dagger-android.pro"), + ImmutableList.<XElement>of(), + XFiler.Mode.Isolating); + BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, UTF_8))) { + writer.write(contents); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } +} diff --git a/java/dagger/android/internal/proguard/ProguardProcessor.java b/java/dagger/android/internal/proguard/ProguardProcessor.java index 49274e94f..8677bf179 100644 --- a/java/dagger/android/internal/proguard/ProguardProcessor.java +++ b/java/dagger/android/internal/proguard/ProguardProcessor.java @@ -16,19 +16,13 @@ package dagger.android.internal.proguard; -import static javax.tools.StandardLocation.CLASS_OUTPUT; - +import androidx.room.compiler.processing.XProcessingEnv; +import androidx.room.compiler.processing.XProcessingStep; +import androidx.room.compiler.processing.javac.JavacBasicAnnotationProcessor; import com.google.auto.service.AutoService; -import java.io.IOException; -import java.io.Writer; -import java.util.Set; -import javax.annotation.processing.AbstractProcessor; -import javax.annotation.processing.Filer; +import com.google.common.collect.ImmutableList; import javax.annotation.processing.Processor; -import javax.annotation.processing.RoundEnvironment; -import javax.annotation.processing.SupportedAnnotationTypes; import javax.lang.model.SourceVersion; -import javax.lang.model.element.TypeElement; /** * An {@linkplain Processor annotation processor} to generate dagger-android's specific proguard @@ -44,46 +38,17 @@ import javax.lang.model.element.TypeElement; * </code></pre> */ @AutoService(Processor.class) -@SupportedAnnotationTypes(ProguardProcessor.GENERATE_RULES_ANNOTATION_NAME) -public final class ProguardProcessor extends AbstractProcessor { - - static final String GENERATE_RULES_ANNOTATION_NAME = - "dagger.android.internal.GenerateAndroidInjectionProguardRules"; +public final class ProguardProcessor extends JavacBasicAnnotationProcessor { + private XProcessingEnv env; @Override - public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { - roundEnv - .getElementsAnnotatedWith( - processingEnv.getElementUtils().getTypeElement(GENERATE_RULES_ANNOTATION_NAME)) - .forEach(element -> generate()); - - return false; - } - - private void generate() { - Filer filer = processingEnv.getFiler(); - - String errorProneRule = "-dontwarn com.google.errorprone.annotations.**\n"; - String androidInjectionKeysRule = - "-identifiernamestring class dagger.android.internal.AndroidInjectionKeys {\n" - + " java.lang.String of(java.lang.String);\n" - + "}\n"; - - writeFile(filer, "com.android.tools/proguard", errorProneRule); - writeFile(filer, "com.android.tools/r8", errorProneRule + androidInjectionKeysRule); - writeFile(filer, "proguard", errorProneRule); + public void initialize(XProcessingEnv env) { + this.env = env; } - private static void writeFile(Filer filer, String intermediatePath, String contents) { - try (Writer writer = - filer - .createResource( - CLASS_OUTPUT, "", "META-INF/" + intermediatePath + "/dagger-android.pro") - .openWriter()) { - writer.write(contents); - } catch (IOException e) { - throw new IllegalStateException(e); - } + @Override + public Iterable<XProcessingStep> processingSteps() { + return ImmutableList.of(new ProguardProcessingStep(env)); } @Override diff --git a/java/dagger/android/processor/AndroidInjectorDescriptor.java b/java/dagger/android/processor/AndroidInjectorDescriptor.java index 12f2edf24..758d895aa 100644 --- a/java/dagger/android/processor/AndroidInjectorDescriptor.java +++ b/java/dagger/android/processor/AndroidInjectorDescriptor.java @@ -16,29 +16,23 @@ package dagger.android.processor; -import static com.google.auto.common.AnnotationMirrors.getAnnotationValue; -import static dagger.android.processor.MoreDaggerElements.getAnnotatedAnnotations; -import static java.util.stream.Collectors.toList; -import static javax.lang.model.element.Modifier.ABSTRACT; - -import com.google.auto.common.MoreElements; -import com.google.auto.common.MoreTypes; +import androidx.room.compiler.processing.JavaPoetExtKt; +import androidx.room.compiler.processing.XAnnotation; +import androidx.room.compiler.processing.XAnnotationValue; +import androidx.room.compiler.processing.XElement; +import androidx.room.compiler.processing.XExecutableElement; +import androidx.room.compiler.processing.XMessager; +import androidx.room.compiler.processing.XMethodElement; +import androidx.room.compiler.processing.XType; +import androidx.room.compiler.processing.XTypeElement; import com.google.auto.value.AutoValue; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; import com.squareup.javapoet.AnnotationSpec; import com.squareup.javapoet.ClassName; -import com.squareup.javapoet.TypeName; -import java.util.List; +import dagger.internal.codegen.xprocessing.XElements; import java.util.Optional; -import javax.annotation.processing.Messager; -import javax.lang.model.element.AnnotationMirror; -import javax.lang.model.element.AnnotationValue; -import javax.lang.model.element.Element; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.TypeElement; -import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.SimpleAnnotationValueVisitor8; import javax.tools.Diagnostic.Kind; /** @@ -60,7 +54,7 @@ abstract class AndroidInjectorDescriptor { abstract ClassName enclosingModule(); /** The method annotated with {@code ContributesAndroidInjector}. */ - abstract ExecutableElement method(); + abstract XExecutableElement method(); @AutoValue.Builder abstract static class Builder { @@ -72,15 +66,15 @@ abstract class AndroidInjectorDescriptor { abstract Builder enclosingModule(ClassName enclosingModule); - abstract Builder method(ExecutableElement method); + abstract Builder method(XExecutableElement method); abstract AndroidInjectorDescriptor build(); } static final class Validator { - private final Messager messager; + private final XMessager messager; - Validator(Messager messager) { + Validator(XMessager messager) { this.messager = messager; } @@ -88,10 +82,10 @@ abstract class AndroidInjectorDescriptor { * Validates a {@code ContributesAndroidInjector} method, returning an {@link * AndroidInjectorDescriptor} if it is valid, or {@link Optional#empty()} otherwise. */ - Optional<AndroidInjectorDescriptor> createIfValid(ExecutableElement method) { + Optional<AndroidInjectorDescriptor> createIfValid(XMethodElement method) { ErrorReporter reporter = new ErrorReporter(method, messager); - if (!method.getModifiers().contains(ABSTRACT)) { + if (!method.isAbstract()) { reporter.reportError("@ContributesAndroidInjector methods must be abstract"); } @@ -101,41 +95,40 @@ abstract class AndroidInjectorDescriptor { AndroidInjectorDescriptor.Builder builder = new AutoValue_AndroidInjectorDescriptor.Builder().method(method); - TypeElement enclosingElement = MoreElements.asType(method.getEnclosingElement()); - if (!MoreDaggerElements.isAnnotationPresent(enclosingElement, TypeNames.MODULE)) { + XTypeElement enclosingElement = XElements.asTypeElement(method.getEnclosingElement()); + if (!enclosingElement.hasAnnotation(TypeNames.MODULE)) { reporter.reportError("@ContributesAndroidInjector methods must be in a @Module"); } - builder.enclosingModule(ClassName.get(enclosingElement)); + builder.enclosingModule(enclosingElement.getClassName()); - TypeMirror injectedType = method.getReturnType(); - if (MoreTypes.asDeclared(injectedType).getTypeArguments().isEmpty()) { - builder.injectedType(ClassName.get(MoreTypes.asTypeElement(injectedType))); + XType injectedType = method.getReturnType(); + if (injectedType.getTypeArguments().isEmpty()) { + builder.injectedType(injectedType.getTypeElement().getClassName()); } else { reporter.reportError( "@ContributesAndroidInjector methods cannot return parameterized types"); } - AnnotationMirror annotation = - MoreDaggerElements.getAnnotationMirror(method, TypeNames.CONTRIBUTES_ANDROID_INJECTOR) - .get(); - for (TypeMirror module : - getAnnotationValue(annotation, "modules").accept(new AllTypesVisitor(), null)) { - if (MoreDaggerElements.isAnnotationPresent(MoreTypes.asElement(module), TypeNames.MODULE)) { - builder.modulesBuilder().add((ClassName) TypeName.get(module)); + XAnnotation annotation = method.getAnnotation(TypeNames.CONTRIBUTES_ANDROID_INJECTOR); + for (XType module : getTypeList(annotation.getAnnotationValue("modules"))) { + if (module.getTypeElement().hasAnnotation(TypeNames.MODULE)) { + builder.modulesBuilder().add((ClassName) module.getTypeName()); } else { reporter.reportError(String.format("%s is not a @Module", module), annotation); } } - for (AnnotationMirror scope : Sets.union( - getAnnotatedAnnotations(method, TypeNames.SCOPE), - getAnnotatedAnnotations(method, TypeNames.SCOPE_JAVAX))) { - builder.scopesBuilder().add(AnnotationSpec.get(scope)); + for (XAnnotation scope : + Sets.union( + method.getAnnotationsAnnotatedWith(TypeNames.SCOPE), + method.getAnnotationsAnnotatedWith(TypeNames.SCOPE_JAVAX))) { + builder.scopesBuilder().add(JavaPoetExtKt.toAnnotationSpec(scope)); } - for (AnnotationMirror qualifier : Sets.union( - getAnnotatedAnnotations(method, TypeNames.QUALIFIER), - getAnnotatedAnnotations(method, TypeNames.QUALIFIER_JAVAX))) { + for (XAnnotation qualifier : + Sets.union( + method.getAnnotationsAnnotatedWith(TypeNames.QUALIFIER), + method.getAnnotationsAnnotatedWith(TypeNames.QUALIFIER_JAVAX))) { reporter.reportError( "@ContributesAndroidInjector methods cannot have qualifiers", qualifier); } @@ -143,13 +136,23 @@ abstract class AndroidInjectorDescriptor { return reporter.hasError ? Optional.empty() : Optional.of(builder.build()); } + private static ImmutableList<XType> getTypeList(XAnnotationValue annotationValue) { + if (annotationValue.hasTypeListValue()) { + return ImmutableList.copyOf(annotationValue.asTypeList()); + } + if (annotationValue.hasTypeValue()) { + return ImmutableList.of(annotationValue.asType()); + } + throw new IllegalArgumentException("Does not have type list"); + } + // TODO(ronshapiro): use ValidationReport once it is moved out of the compiler private static class ErrorReporter { - private final Element subject; - private final Messager messager; + private final XElement subject; + private final XMessager messager; private boolean hasError; - ErrorReporter(Element subject, Messager messager) { + ErrorReporter(XElement subject, XMessager messager) { this.subject = subject; this.messager = messager; } @@ -159,29 +162,10 @@ abstract class AndroidInjectorDescriptor { messager.printMessage(Kind.ERROR, error, subject); } - void reportError(String error, AnnotationMirror annotation) { + void reportError(String error, XAnnotation annotation) { hasError = true; messager.printMessage(Kind.ERROR, error, subject, annotation); } } } - - private static final class AllTypesVisitor - extends SimpleAnnotationValueVisitor8<ImmutableSet<TypeMirror>, Void> { - @Override - public ImmutableSet<TypeMirror> visitArray(List<? extends AnnotationValue> values, Void aVoid) { - return ImmutableSet.copyOf( - values.stream().flatMap(v -> v.accept(this, null).stream()).collect(toList())); - } - - @Override - public ImmutableSet<TypeMirror> visitType(TypeMirror a, Void aVoid) { - return ImmutableSet.of(a); - } - - @Override - protected ImmutableSet<TypeMirror> defaultAction(Object o, Void aVoid) { - throw new AssertionError(o); - } - } } diff --git a/java/dagger/android/processor/AndroidMapKeyProcessingStep.java b/java/dagger/android/processor/AndroidMapKeyProcessingStep.java new file mode 100644 index 000000000..8a7e83c77 --- /dev/null +++ b/java/dagger/android/processor/AndroidMapKeyProcessingStep.java @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2017 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.android.processor; + +import static com.google.common.collect.Iterables.getOnlyElement; +import static dagger.android.processor.AndroidMapKeys.injectedTypeFromMapKey; +import static dagger.internal.codegen.xprocessing.XTypes.toStableString; + +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 androidx.room.compiler.processing.XTypeElement; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; +import com.squareup.javapoet.ClassName; +import dagger.internal.codegen.xprocessing.XElements; +import dagger.internal.codegen.xprocessing.XTypes; +import javax.tools.Diagnostic.Kind; + +/** Validates the correctness of {@link dagger.MapKey}s used with {@code dagger.android}. */ +final class AndroidMapKeyProcessingStep extends BaseProcessingStep { + private final XProcessingEnv processingEnv; + + AndroidMapKeyProcessingStep(XProcessingEnv processingEnv) { + this.processingEnv = processingEnv; + } + + @Override + public ImmutableSet<ClassName> annotationClassNames() { + return ImmutableSet.of(TypeNames.ANDROID_INJECTION_KEY, TypeNames.CLASS_KEY); + } + + @Override + public void process(XElement element, ImmutableSet<ClassName> annotationNames) { + for (ClassName annotationName : annotationNames) { + validateMethod(annotationName, XElements.asMethod(element)); + } + } + + private void validateMethod(ClassName annotation, XMethodElement method) { + if (!Sets.union( + method.getAnnotationsAnnotatedWith(TypeNames.QUALIFIER), + method.getAnnotationsAnnotatedWith(TypeNames.QUALIFIER_JAVAX)) + .isEmpty()) { + return; + } + + XType returnType = method.getReturnType(); + if (!factoryElement().getType().getRawType().isAssignableFrom(returnType.getRawType())) { + // if returnType is not related to AndroidInjector.Factory, ignore the method + return; + } + + if (!Sets.union( + method.getAnnotationsAnnotatedWith(TypeNames.SCOPE), + method.getAnnotationsAnnotatedWith(TypeNames.SCOPE_JAVAX)) + .isEmpty()) { + XAnnotation suppressedWarnings = method.getAnnotation(ClassName.get(SuppressWarnings.class)); + if (suppressedWarnings == null + || !ImmutableSet.copyOf(suppressedWarnings.getAsStringList("value")) + .contains("dagger.android.ScopedInjectorFactory")) { + XAnnotation mapKeyAnnotation = + getOnlyElement(method.getAnnotationsAnnotatedWith(TypeNames.MAP_KEY)); + XTypeElement mapKeyValueElement = + processingEnv.requireTypeElement(injectedTypeFromMapKey(mapKeyAnnotation).get()); + processingEnv + .getMessager() + .printMessage( + Kind.ERROR, + String.format( + "%s bindings should not be scoped. Scoping this method may leak instances of" + + " %s.", + TypeNames.ANDROID_INJECTOR_FACTORY.canonicalName(), + mapKeyValueElement.getQualifiedName()), + method); + } + } + + validateReturnType(method); + + // @Binds methods should only have one parameter, but we can't guarantee the order of Processors + // in javac, so do a basic check for valid form + if (method.hasAnnotation(TypeNames.BINDS) && method.getParameters().size() == 1) { + validateMapKeyMatchesBindsParameter(annotation, method); + } + } + + /** Report an error if the method's return type is not {@code AndroidInjector.Factory<?>}. */ + private void validateReturnType(XMethodElement method) { + XType returnType = method.getReturnType(); + XType requiredReturnType = injectorFactoryOf(processingEnv.getWildcardType(null, null)); + + // TODO(b/311460276) use XType.isSameType when the bug is fixed. + if (!returnType.getTypeName().equals(requiredReturnType.getTypeName())) { + processingEnv + .getMessager() + .printMessage( + Kind.ERROR, + String.format( + "%s should bind %s, not %s. See https://dagger.dev/android", + method, toStableString(requiredReturnType), toStableString(returnType)), + method); + } + } + + /** + * A valid @Binds method could bind an {@code AndroidInjector.Factory} for one type, while giving + * it a map key of a different type. The return type and parameter type would pass typical @Binds + * validation, but the map lookup in {@code DispatchingAndroidInjector} would retrieve the wrong + * injector factory. + * + * <pre>{@code + * {@literal @Binds} + * {@literal @IntoMap} + * {@literal @ClassKey(GreenActivity.class)} + * abstract AndroidInjector.Factory<?> bindBlueActivity( + * BlueActivityComponent.Builder builder); + * }</pre> + */ + private void validateMapKeyMatchesBindsParameter( + ClassName annotationName, XMethodElement method) { + XType parameterType = getOnlyElement(method.getParameters()).getType(); + XAnnotation annotation = method.getAnnotation(annotationName); + XType mapKeyType = + processingEnv.requireTypeElement(injectedTypeFromMapKey(annotation).get()).getType(); + if (!XTypes.isAssignableTo(parameterType, injectorFactoryOf(mapKeyType))) { + processingEnv + .getMessager() + .printMessage( + Kind.ERROR, + String.format( + "%s does not implement AndroidInjector<%s>", + toStableString(parameterType), toStableString(mapKeyType)), + method, + annotation); + } + } + + /** Returns a {@link XType} for {@code AndroidInjector.Factory<implementationType>}. */ + private XType injectorFactoryOf(XType implementationType) { + return processingEnv.getDeclaredType(factoryElement(), implementationType); + } + + private XTypeElement factoryElement() { + return processingEnv.requireTypeElement(TypeNames.ANDROID_INJECTOR_FACTORY.canonicalName()); + } +} diff --git a/java/dagger/android/processor/AndroidMapKeyValidator.java b/java/dagger/android/processor/AndroidMapKeyValidator.java deleted file mode 100644 index 8d674666b..000000000 --- a/java/dagger/android/processor/AndroidMapKeyValidator.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (C) 2017 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.android.processor; - -import static com.google.auto.common.AnnotationMirrors.getAnnotatedAnnotations; -import static com.google.common.collect.Iterables.getOnlyElement; -import static dagger.android.processor.AndroidMapKeys.injectedTypeFromMapKey; -import static dagger.android.processor.MoreDaggerElements.getAnnotatedAnnotations; - -import com.google.auto.common.BasicAnnotationProcessor.Step; -import com.google.auto.common.MoreElements; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.ImmutableSetMultimap; -import com.google.common.collect.Sets; -import com.squareup.javapoet.ClassName; -import dagger.MapKey; -import javax.annotation.processing.Messager; -import javax.lang.model.element.AnnotationMirror; -import javax.lang.model.element.Element; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.TypeElement; -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.Elements; -import javax.lang.model.util.Types; -import javax.tools.Diagnostic.Kind; - -/** Validates the correctness of {@link dagger.MapKey}s used with {@code dagger.android}. */ -final class AndroidMapKeyValidator implements Step { - private static final ImmutableMap<String, ClassName> SUPPORTED_ANNOTATIONS = - ImmutableMap.of( - TypeNames.ANDROID_INJECTION_KEY.toString(), TypeNames.ANDROID_INJECTION_KEY, - TypeNames.CLASS_KEY.toString(), TypeNames.CLASS_KEY); - - private final Elements elements; - private final Types types; - private final Messager messager; - - AndroidMapKeyValidator(Elements elements, Types types, Messager messager) { - this.elements = elements; - this.types = types; - this.messager = messager; - } - - @Override - public ImmutableSet<String> annotations() { - return SUPPORTED_ANNOTATIONS.keySet(); - } - - @Override - public ImmutableSet<Element> process(ImmutableSetMultimap<String, Element> elementsByAnnotation) { - ImmutableSet.Builder<Element> deferredElements = ImmutableSet.builder(); - elementsByAnnotation - .entries() - .forEach( - entry -> { - try { - validateMethod(entry.getKey(), MoreElements.asExecutable(entry.getValue())); - } catch (TypeNotPresentException e) { - deferredElements.add(entry.getValue()); - } - }); - return deferredElements.build(); - } - - private void validateMethod(String annotation, ExecutableElement method) { - if (!Sets.union(getAnnotatedAnnotations(method, TypeNames.QUALIFIER), - getAnnotatedAnnotations(method, TypeNames.QUALIFIER_JAVAX)).isEmpty()) { - return; - } - - TypeMirror returnType = method.getReturnType(); - if (!types.isAssignable(types.erasure(returnType), factoryElement().asType())) { - // if returnType is not related to AndroidInjector.Factory, ignore the method - return; - } - - if (!Sets.union(getAnnotatedAnnotations(method, TypeNames.SCOPE), - getAnnotatedAnnotations(method, TypeNames.SCOPE_JAVAX)).isEmpty()) { - SuppressWarnings suppressedWarnings = method.getAnnotation(SuppressWarnings.class); - if (suppressedWarnings == null - || !ImmutableSet.copyOf(suppressedWarnings.value()) - .contains("dagger.android.ScopedInjectorFactory")) { - AnnotationMirror mapKeyAnnotation = - getOnlyElement(getAnnotatedAnnotations(method, MapKey.class)); - TypeElement mapKeyValueElement = - elements.getTypeElement(injectedTypeFromMapKey(mapKeyAnnotation).get()); - messager.printMessage( - Kind.ERROR, - String.format( - "%s bindings should not be scoped. Scoping this method may leak instances of %s.", - TypeNames.ANDROID_INJECTOR_FACTORY.canonicalName(), - mapKeyValueElement.getQualifiedName()), - method); - } - } - - validateReturnType(method); - - // @Binds methods should only have one parameter, but we can't guarantee the order of Processors - // in javac, so do a basic check for valid form - if (MoreDaggerElements.isAnnotationPresent(method, TypeNames.BINDS) - && method.getParameters().size() == 1) { - validateMapKeyMatchesBindsParameter(annotation, method); - } - } - - /** Report an error if the method's return type is not {@code AndroidInjector.Factory<?>}. */ - private void validateReturnType(ExecutableElement method) { - TypeMirror returnType = method.getReturnType(); - DeclaredType requiredReturnType = injectorFactoryOf(types.getWildcardType(null, null)); - - if (!types.isSameType(returnType, requiredReturnType)) { - messager.printMessage( - Kind.ERROR, - String.format( - "%s should bind %s, not %s. See https://dagger.dev/android", - method, requiredReturnType, returnType), - method); - } - } - - /** - * A valid @Binds method could bind an {@code AndroidInjector.Factory} for one type, while giving - * it a map key of a different type. The return type and parameter type would pass typical @Binds - * validation, but the map lookup in {@code DispatchingAndroidInjector} would retrieve the wrong - * injector factory. - * - * <pre>{@code - * {@literal @Binds} - * {@literal @IntoMap} - * {@literal @ClassKey(GreenActivity.class)} - * abstract AndroidInjector.Factory<?> bindBlueActivity( - * BlueActivityComponent.Builder builder); - * }</pre> - */ - private void validateMapKeyMatchesBindsParameter(String annotation, ExecutableElement method) { - TypeMirror parameterType = getOnlyElement(method.getParameters()).asType(); - AnnotationMirror annotationMirror = - MoreDaggerElements.getAnnotationMirror(method, SUPPORTED_ANNOTATIONS.get(annotation)).get(); - TypeMirror mapKeyType = - elements.getTypeElement(injectedTypeFromMapKey(annotationMirror).get()).asType(); - if (!types.isAssignable(parameterType, injectorFactoryOf(mapKeyType))) { - messager.printMessage( - Kind.ERROR, - String.format("%s does not implement AndroidInjector<%s>", parameterType, mapKeyType), - method, - annotationMirror); - } - } - - /** Returns a {@link DeclaredType} for {@code AndroidInjector.Factory<implementationType>}. */ - private DeclaredType injectorFactoryOf(TypeMirror implementationType) { - return types.getDeclaredType(factoryElement(), implementationType); - } - - private TypeElement factoryElement() { - return elements.getTypeElement(TypeNames.ANDROID_INJECTOR_FACTORY.canonicalName()); - } -} diff --git a/java/dagger/android/processor/AndroidMapKeys.java b/java/dagger/android/processor/AndroidMapKeys.java index 28da2715a..e3d890e29 100644 --- a/java/dagger/android/processor/AndroidMapKeys.java +++ b/java/dagger/android/processor/AndroidMapKeys.java @@ -16,13 +16,9 @@ package dagger.android.processor; -import static com.google.auto.common.AnnotationMirrors.getAnnotationValue; - -import com.google.auto.common.MoreTypes; +import androidx.room.compiler.processing.XAnnotation; +import androidx.room.compiler.processing.XAnnotationValue; import java.util.Optional; -import javax.lang.model.element.AnnotationMirror; -import javax.lang.model.element.TypeElement; -import javax.lang.model.type.TypeMirror; final class AndroidMapKeys { /** @@ -30,13 +26,12 @@ final class AndroidMapKeys { * it's {@link dagger.multibindings.ClassKey}, returns the fully-qualified class name of the * annotation value. Otherwise returns {@link Optional#empty()}. */ - static Optional<String> injectedTypeFromMapKey(AnnotationMirror mapKey) { - Object mapKeyClass = getAnnotationValue(mapKey, "value").getValue(); - if (mapKeyClass instanceof String) { - return Optional.of((String) mapKeyClass); - } else if (mapKeyClass instanceof TypeMirror) { - TypeElement type = MoreTypes.asTypeElement((TypeMirror) mapKeyClass); - return Optional.of(type.getQualifiedName().toString()); + static Optional<String> injectedTypeFromMapKey(XAnnotation mapKey) { + XAnnotationValue mapKeyClass = mapKey.getAnnotationValue("value"); + if (mapKeyClass.hasStringValue()) { + return Optional.of(mapKeyClass.asString()); + } else if (mapKeyClass.hasTypeValue()) { + return Optional.of(mapKeyClass.asType().getTypeElement().getQualifiedName()); } else { return Optional.empty(); } diff --git a/java/dagger/android/processor/AndroidProcessor.java b/java/dagger/android/processor/AndroidProcessor.java index 2a8ab345b..beb8d0de7 100644 --- a/java/dagger/android/processor/AndroidProcessor.java +++ b/java/dagger/android/processor/AndroidProcessor.java @@ -16,21 +16,15 @@ package dagger.android.processor; -import static javax.tools.Diagnostic.Kind.ERROR; import static net.ltgt.gradle.incap.IncrementalAnnotationProcessorType.ISOLATING; -import com.google.auto.common.BasicAnnotationProcessor; +import androidx.room.compiler.processing.XProcessingEnv; +import androidx.room.compiler.processing.XProcessingStep; +import androidx.room.compiler.processing.javac.JavacBasicAnnotationProcessor; import com.google.auto.service.AutoService; -import com.google.common.base.Ascii; -import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; -import java.util.Set; -import javax.annotation.processing.Filer; -import javax.annotation.processing.Messager; import javax.annotation.processing.Processor; import javax.lang.model.SourceVersion; -import javax.lang.model.util.Elements; -import javax.lang.model.util.Types; import net.ltgt.gradle.incap.IncrementalAnnotationProcessor; /** @@ -49,51 +43,22 @@ import net.ltgt.gradle.incap.IncrementalAnnotationProcessor; */ @IncrementalAnnotationProcessor(ISOLATING) @AutoService(Processor.class) -public final class AndroidProcessor extends BasicAnnotationProcessor { - private static final String FLAG_EXPERIMENTAL_USE_STRING_KEYS = - "dagger.android.experimentalUseStringKeys"; +public final class AndroidProcessor extends JavacBasicAnnotationProcessor { + private final DelegateAndroidProcessor delegate = new DelegateAndroidProcessor(); @Override - protected Iterable<? extends Step> steps() { - Filer filer = processingEnv.getFiler(); - Messager messager = processingEnv.getMessager(); - Elements elements = processingEnv.getElementUtils(); - Types types = processingEnv.getTypeUtils(); - - return ImmutableList.of( - new AndroidMapKeyValidator(elements, types, messager), - new ContributesAndroidInjectorGenerator( - new AndroidInjectorDescriptor.Validator(messager), - useStringKeys(), - filer, - elements, - processingEnv.getSourceVersion())); + public void initialize(XProcessingEnv env) { + delegate.initialize(env); } - private boolean useStringKeys() { - if (!processingEnv.getOptions().containsKey(FLAG_EXPERIMENTAL_USE_STRING_KEYS)) { - return false; - } - String flagValue = processingEnv.getOptions().get(FLAG_EXPERIMENTAL_USE_STRING_KEYS); - if (flagValue == null || Ascii.equalsIgnoreCase(flagValue, "true")) { - return true; - } else if (Ascii.equalsIgnoreCase(flagValue, "false")) { - return false; - } else { - processingEnv - .getMessager() - .printMessage( - ERROR, - String.format( - "Unknown flag value: %s. %s must be set to either 'true' or 'false'.", - flagValue, FLAG_EXPERIMENTAL_USE_STRING_KEYS)); - return false; - } + @Override + public Iterable<XProcessingStep> processingSteps() { + return delegate.processingSteps(); } @Override - public Set<String> getSupportedOptions() { - return ImmutableSet.of(FLAG_EXPERIMENTAL_USE_STRING_KEYS); + public final ImmutableSet<String> getSupportedOptions() { + return ImmutableSet.of(DelegateAndroidProcessor.FLAG_EXPERIMENTAL_USE_STRING_KEYS); } @Override diff --git a/java/dagger/android/processor/BUILD b/java/dagger/android/processor/BUILD index d545ef8ef..f70c09102 100644 --- a/java/dagger/android/processor/BUILD +++ b/java/dagger/android/processor/BUILD @@ -22,8 +22,7 @@ load( "DOCLINT_REFERENCES", "POM_VERSION", ) -load("//tools:maven.bzl", "pom_file") -load("@google_bazel_common//tools/javadoc:javadoc.bzl", "javadoc_library") +load("//tools:maven.bzl", "gen_maven_artifact") package(default_visibility = ["//:src"]) @@ -33,29 +32,65 @@ filegroup( ) java_library( + name = "base_processing_step", + srcs = ["BaseProcessingStep.java"], + deps = [ + "//java/dagger/internal/codegen/extension", + "//java/dagger/internal/codegen/xprocessing", + "//third_party/java/guava/base", + "//third_party/java/guava/collect", + "//third_party/java/javapoet", + ], +) + +java_library( name = "processor", - srcs = [":srcs"], + srcs = glob( + ["*.java"], + exclude = ["BaseProcessingStep.java"], + ), javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES, tags = ["maven_coordinates=com.google.dagger:dagger-android-processor:" + POM_VERSION], deps = [ + ":base_processing_step", "//java/dagger:core", - "//java/dagger/internal/codegen/extension", + "//java/dagger/internal/codegen/xprocessing", "//java/dagger/spi", - "//third_party/java/auto:common", "//third_party/java/auto:service", "//third_party/java/auto:value", "//third_party/java/guava/base", "//third_party/java/guava/collect", "//third_party/java/incap", "//third_party/java/javapoet", + "@maven//:com_google_devtools_ksp_symbol_processing_api", ], ) -pom_file( - name = "pom", - artifact_id = "dagger-android-processor", +gen_maven_artifact( + name = "artifact", + artifact_coordinates = "com.google.dagger:dagger-android-processor:" + POM_VERSION, artifact_name = "Dagger Android Processor", - targets = [":processor"], + artifact_target = ":processor", + artifact_target_libs = [ + "//java/dagger/internal/codegen/xprocessing", + "//java/dagger/android/processor:base_processing_step", + ], + artifact_target_maven_deps = [ + "com.google.dagger:dagger", + "com.google.devtools.ksp:symbol-processing-api", + "com.google.guava:guava", + "com.squareup:javapoet", + "com.google.code.findbugs:jsr305", + "com.google.dagger:dagger-spi", + "com.google.guava:failureaccess", + "com.squareup:kotlinpoet", + "net.ltgt.gradle.incap:incap", + "org.jetbrains.kotlin:kotlin-stdlib", + ], + javadoc_root_packages = [ + "dagger.android.processor", + ], + javadoc_srcs = [":srcs"], ) java_plugin( @@ -64,10 +99,3 @@ java_plugin( processor_class = "dagger.android.processor.AndroidProcessor", deps = [":processor"], ) - -javadoc_library( - name = "processor-javadoc", - srcs = [":srcs"], - root_packages = ["dagger.android.processor"], - deps = [":processor"], -) diff --git a/java/dagger/android/processor/BaseProcessingStep.java b/java/dagger/android/processor/BaseProcessingStep.java new file mode 100644 index 000000000..100ded0a0 --- /dev/null +++ b/java/dagger/android/processor/BaseProcessingStep.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2023 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.android.processor; + +import static com.google.common.base.Preconditions.checkState; +import static com.google.common.collect.Sets.difference; +import static dagger.internal.codegen.extension.DaggerStreams.toImmutableMap; +import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; + +import androidx.room.compiler.processing.XElement; +import androidx.room.compiler.processing.XProcessingEnv; +import androidx.room.compiler.processing.XProcessingStep; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSetMultimap; +import com.google.common.collect.Maps; +import com.squareup.javapoet.ClassName; +import java.util.Map; +import java.util.Set; + +/** + * A {@link XProcessingStep} that processes one element at a time and defers any for which {@link + * TypeNotPresentException} is thrown. + */ +public abstract class BaseProcessingStep implements XProcessingStep { + @Override + public final ImmutableSet<String> annotations() { + return annotationClassNames().stream().map(ClassName::canonicalName).collect(toImmutableSet()); + } + + // Subclass must ensure all annotated targets are of valid type. + @Override + public ImmutableSet<XElement> process( + XProcessingEnv env, Map<String, ? extends Set<? extends XElement>> elementsByAnnotation) { + ImmutableSet.Builder<XElement> deferredElements = ImmutableSet.builder(); + inverse(elementsByAnnotation) + .forEach( + (element, annotations) -> { + try { + process(element, annotations); + } catch (TypeNotPresentException e) { + deferredElements.add(element); + } + }); + return deferredElements.build(); + } + + /** + * Processes one element. If this method throws {@link TypeNotPresentException}, the element will + * be deferred until the next round of processing. + * + * @param annotations the subset of {@link XProcessingStep#annotations()} that annotate {@code + * element} + */ + protected abstract void process(XElement element, ImmutableSet<ClassName> annotations); + + private ImmutableMap<XElement, ImmutableSet<ClassName>> inverse( + Map<String, ? extends Set<? extends XElement>> elementsByAnnotation) { + ImmutableMap<String, ClassName> annotationClassNames = + annotationClassNames().stream() + .collect(toImmutableMap(ClassName::canonicalName, className -> className)); + checkState( + annotationClassNames.keySet().containsAll(elementsByAnnotation.keySet()), + "Unexpected annotations for %s: %s", + this.getClass().getCanonicalName(), + difference(elementsByAnnotation.keySet(), annotationClassNames.keySet())); + + ImmutableSetMultimap.Builder<XElement, ClassName> builder = ImmutableSetMultimap.builder(); + elementsByAnnotation.forEach( + (annotationName, elementSet) -> + elementSet.forEach( + element -> builder.put(element, annotationClassNames.get(annotationName)))); + + return ImmutableMap.copyOf(Maps.transformValues(builder.build().asMap(), ImmutableSet::copyOf)); + } + + /** Returns the set of annotations processed by this processing step. */ + protected abstract Set<ClassName> annotationClassNames(); +} diff --git a/java/dagger/android/processor/ContributesAndroidInjectorGenerator.java b/java/dagger/android/processor/ContributesAndroidInjectorProcessingStep.java index f3f4d18ab..9e9ed2b20 100644 --- a/java/dagger/android/processor/ContributesAndroidInjectorGenerator.java +++ b/java/dagger/android/processor/ContributesAndroidInjectorProcessingStep.java @@ -16,23 +16,27 @@ package dagger.android.processor; -import static com.google.auto.common.GeneratedAnnotationSpecs.generatedAnnotationSpec; +import static androidx.room.compiler.processing.JavaPoetExtKt.addOriginatingElement; import static com.google.common.base.CaseFormat.LOWER_CAMEL; import static com.google.common.base.CaseFormat.UPPER_CAMEL; import static com.squareup.javapoet.MethodSpec.constructorBuilder; import static com.squareup.javapoet.MethodSpec.methodBuilder; import static com.squareup.javapoet.TypeSpec.classBuilder; import static com.squareup.javapoet.TypeSpec.interfaceBuilder; +import static dagger.android.processor.DelegateAndroidProcessor.FLAG_EXPERIMENTAL_USE_STRING_KEYS; import static javax.lang.model.element.Modifier.ABSTRACT; import static javax.lang.model.element.Modifier.PRIVATE; 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 static javax.tools.Diagnostic.Kind.ERROR; -import com.google.auto.common.BasicAnnotationProcessor.Step; +import androidx.room.compiler.processing.XElement; +import androidx.room.compiler.processing.XFiler; +import androidx.room.compiler.processing.XProcessingEnv; +import androidx.room.compiler.processing.XTypeElement; +import com.google.common.base.Ascii; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.ImmutableSetMultimap; import com.squareup.javapoet.AnnotationSpec; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.JavaFile; @@ -41,52 +45,26 @@ import com.squareup.javapoet.ParameterizedTypeName; import com.squareup.javapoet.TypeName; import com.squareup.javapoet.TypeSpec; import com.squareup.javapoet.WildcardTypeName; -import dagger.android.processor.AndroidInjectorDescriptor.Validator; -import java.io.IOException; -import javax.annotation.processing.Filer; -import javax.lang.model.SourceVersion; -import javax.lang.model.element.Element; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.util.Elements; +import dagger.internal.codegen.xprocessing.XElements; /** Generates the implementation specified in {@code ContributesAndroidInjector}. */ -final class ContributesAndroidInjectorGenerator implements Step { - +final class ContributesAndroidInjectorProcessingStep extends BaseProcessingStep { private final AndroidInjectorDescriptor.Validator validator; - private final Filer filer; - private final Elements elements; - private final boolean useStringKeys; - private final SourceVersion sourceVersion; - - ContributesAndroidInjectorGenerator( - Validator validator, - boolean useStringKeys, - Filer filer, - Elements elements, - SourceVersion sourceVersion) { - this.validator = validator; - this.useStringKeys = useStringKeys; - this.filer = filer; - this.elements = elements; - this.sourceVersion = sourceVersion; + private final XProcessingEnv processingEnv; + + ContributesAndroidInjectorProcessingStep(XProcessingEnv processingEnv) { + this.processingEnv = processingEnv; + this.validator = new AndroidInjectorDescriptor.Validator(processingEnv.getMessager()); } @Override - public ImmutableSet<String> annotations() { - return ImmutableSet.of(TypeNames.CONTRIBUTES_ANDROID_INJECTOR.toString()); + public ImmutableSet<ClassName> annotationClassNames() { + return ImmutableSet.of(TypeNames.CONTRIBUTES_ANDROID_INJECTOR); } @Override - public ImmutableSet<Element> process(ImmutableSetMultimap<String, Element> elementsByAnnotation) { - ImmutableSet.Builder<Element> deferredElements = ImmutableSet.builder(); - for (ExecutableElement method : methodsIn(elementsByAnnotation.values())) { - try { - validator.createIfValid(method).ifPresent(this::generate); - } catch (TypeNotPresentException e) { - deferredElements.add(method); - } - } - return deferredElements.build(); + public void process(XElement element, ImmutableSet<ClassName> annotationNames) { + validator.createIfValid(XElements.asMethod(element)).ifPresent(this::generate); } private void generate(AndroidInjectorDescriptor descriptor) { @@ -97,7 +75,7 @@ final class ContributesAndroidInjectorGenerator implements Step { .peerClass( Joiner.on('_').join(descriptor.enclosingModule().simpleNames()) + "_" - + LOWER_CAMEL.to(UPPER_CAMEL, descriptor.method().getSimpleName().toString())); + + LOWER_CAMEL.to(UPPER_CAMEL, XElements.getSimpleName(descriptor.method()))); String baseName = descriptor.injectedType().simpleName(); ClassName subcomponentName = moduleName.nestedClass(baseName + "Subcomponent"); @@ -105,7 +83,6 @@ final class ContributesAndroidInjectorGenerator implements Step { TypeSpec.Builder module = classBuilder(moduleName) - .addOriginatingElement(descriptor.method()) .addAnnotation( AnnotationSpec.builder(TypeNames.MODULE) .addMember("subcomponents", "$T.class", subcomponentName) @@ -114,16 +91,45 @@ final class ContributesAndroidInjectorGenerator implements Step { .addMethod(bindAndroidInjectorFactory(descriptor, subcomponentFactoryName)) .addType(subcomponent(descriptor, subcomponentName, subcomponentFactoryName)) .addMethod(constructorBuilder().addModifiers(PRIVATE).build()); - generatedAnnotationSpec(elements, sourceVersion, AndroidProcessor.class) - .ifPresent(module::addAnnotation); - - try { - JavaFile.builder(moduleName.packageName(), module.build()) - .skipJavaLangImports(true) - .build() - .writeTo(filer); - } catch (IOException e) { - throw new AssertionError(e); + + addOriginatingElement(module, descriptor.method()); + + XTypeElement generatedAnnotation = processingEnv.findGeneratedAnnotation(); + if (generatedAnnotation != null) { + module.addAnnotation( + AnnotationSpec.builder(generatedAnnotation.getClassName()) + .addMember( + "value", "$S", ClassName.get("dagger.android.processor", "AndroidProcessor")) + .build()); + } + + processingEnv + .getFiler() + .write( + JavaFile.builder(moduleName.packageName(), module.build()) + .skipJavaLangImports(true) + .build(), + XFiler.Mode.Isolating); + } + + private static boolean useStringKeys(XProcessingEnv processingEnv) { + if (!processingEnv.getOptions().containsKey(FLAG_EXPERIMENTAL_USE_STRING_KEYS)) { + return false; + } + String flagValue = processingEnv.getOptions().get(FLAG_EXPERIMENTAL_USE_STRING_KEYS); + if (flagValue == null || Ascii.equalsIgnoreCase(flagValue, "true")) { + return true; + } else if (Ascii.equalsIgnoreCase(flagValue, "false")) { + return false; + } else { + processingEnv + .getMessager() + .printMessage( + ERROR, + String.format( + "Unknown flag value: %s. %s must be set to either 'true' or 'false'.", + flagValue, FLAG_EXPERIMENTAL_USE_STRING_KEYS)); + return false; } } @@ -142,7 +148,7 @@ final class ContributesAndroidInjectorGenerator implements Step { } private AnnotationSpec androidInjectorMapKey(AndroidInjectorDescriptor descriptor) { - if (useStringKeys) { + if (useStringKeys(processingEnv)) { return AnnotationSpec.builder(TypeNames.ANDROID_INJECTION_KEY) .addMember("value", "$S", descriptor.injectedType().toString()) .build(); diff --git a/java/dagger/android/processor/DelegateAndroidProcessor.java b/java/dagger/android/processor/DelegateAndroidProcessor.java new file mode 100644 index 000000000..7c141f041 --- /dev/null +++ b/java/dagger/android/processor/DelegateAndroidProcessor.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2023 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.android.processor; + +import androidx.room.compiler.processing.XProcessingEnv; +import androidx.room.compiler.processing.XProcessingEnvConfig; +import androidx.room.compiler.processing.XProcessingStep; +import com.google.common.collect.ImmutableList; +import dagger.BindsInstance; +import dagger.Component; +import javax.inject.Singleton; + +/** An implementation of Dagger Android processor that is shared between Javac and KSP. */ +final class DelegateAndroidProcessor { + static final XProcessingEnvConfig PROCESSING_ENV_CONFIG = + new XProcessingEnvConfig.Builder().build(); + static final String FLAG_EXPERIMENTAL_USE_STRING_KEYS = + "dagger.android.experimentalUseStringKeys"; + + private XProcessingEnv env; + + public void initialize(XProcessingEnv env) { + this.env = env; + } + + public ImmutableList<XProcessingStep> processingSteps() { + return ImmutableList.of( + new AndroidMapKeyProcessingStep(env), new ContributesAndroidInjectorProcessingStep(env)); + } + + @Singleton + @Component + interface Injector { + void inject(DelegateAndroidProcessor delegateAndroidProcessor); + + @Component.Factory + interface Factory { + Injector create(@BindsInstance XProcessingEnv env); + } + } +} diff --git a/java/dagger/android/processor/DuplicateAndroidInjectorsChecker.java b/java/dagger/android/processor/DuplicateAndroidInjectorsChecker.java index bcc8e5a1e..22270381c 100644 --- a/java/dagger/android/processor/DuplicateAndroidInjectorsChecker.java +++ b/java/dagger/android/processor/DuplicateAndroidInjectorsChecker.java @@ -16,34 +16,34 @@ package dagger.android.processor; -import static com.google.auto.common.AnnotationMirrors.getAnnotatedAnnotations; import static com.google.common.collect.Iterables.getOnlyElement; import static dagger.android.processor.AndroidMapKeys.injectedTypeFromMapKey; import static java.util.stream.Collectors.collectingAndThen; import static java.util.stream.Collectors.toList; import static javax.tools.Diagnostic.Kind.ERROR; -import com.google.auto.common.MoreTypes; +import androidx.room.compiler.processing.XAnnotation; +import androidx.room.compiler.processing.XType; import com.google.auto.service.AutoService; import com.google.common.collect.ImmutableListMultimap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; import com.google.common.collect.Multimaps; -import dagger.MapKey; -import dagger.model.Binding; -import dagger.model.BindingGraph; -import dagger.model.BindingKind; -import dagger.model.Key; -import dagger.spi.BindingGraphPlugin; -import dagger.spi.DiagnosticReporter; +import dagger.internal.codegen.xprocessing.DaggerElements; +import dagger.internal.codegen.xprocessing.XElements; +import dagger.internal.codegen.xprocessing.XTypes; +import dagger.spi.model.Binding; +import dagger.spi.model.BindingGraph; +import dagger.spi.model.BindingGraphPlugin; +import dagger.spi.model.BindingKind; +import dagger.spi.model.DaggerProcessingEnv; +import dagger.spi.model.DiagnosticReporter; +import dagger.spi.model.Key; import java.util.Formatter; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Stream; -import javax.lang.model.element.AnnotationMirror; -import javax.lang.model.type.TypeKind; -import javax.lang.model.type.TypeMirror; /** * Validates that the two maps that {@code DispatchingAndroidInjector} injects have logically @@ -53,6 +53,13 @@ import javax.lang.model.type.TypeMirror; */ @AutoService(BindingGraphPlugin.class) public final class DuplicateAndroidInjectorsChecker implements BindingGraphPlugin { + private DaggerProcessingEnv processingEnv; + + @Override + public void init(DaggerProcessingEnv processingEnv, Map<String, String> options) { + this.processingEnv = processingEnv; + } + @Override public void visitGraph(BindingGraph graph, DiagnosticReporter diagnosticReporter) { for (Binding binding : graph.bindings()) { @@ -64,7 +71,10 @@ public final class DuplicateAndroidInjectorsChecker implements BindingGraphPlugi private boolean isDispatchingAndroidInjector(Binding binding) { Key key = binding.key(); - return MoreDaggerTypes.isTypeOf(TypeNames.DISPATCHING_ANDROID_INJECTOR, key.type()) + + return XTypes.isTypeOf( + DaggerElements.toXProcessing(key.type(), processingEnv), + TypeNames.DISPATCHING_ANDROID_INJECTOR) && !key.qualifier().isPresent(); } @@ -79,7 +89,7 @@ public final class DuplicateAndroidInjectorsChecker implements BindingGraphPlugi ImmutableListMultimap.Builder<String, Binding> mapKeyIndex = ImmutableListMultimap.builder(); for (Binding injectorFactory : injectorFactories) { - AnnotationMirror mapKey = mapKey(injectorFactory).get(); + XAnnotation mapKey = mapKey(injectorFactory).get(); Optional<String> injectedType = injectedTypeFromMapKey(mapKey); if (injectedType.isPresent()) { mapKeyIndex.put(injectedType.get(), injectorFactory); @@ -113,21 +123,26 @@ public final class DuplicateAndroidInjectorsChecker implements BindingGraphPlugi .filter(requestedBinding -> requestedBinding.kind().equals(BindingKind.MULTIBOUND_MAP)) .filter( requestedBinding -> { - TypeMirror valueType = - MoreTypes.asDeclared(requestedBinding.key().type()).getTypeArguments().get(1); - if (!MoreDaggerTypes.isTypeOf(TypeNames.PROVIDER, valueType) - || !valueType.getKind().equals(TypeKind.DECLARED)) { + XType valueType = + DaggerElements.toXProcessing(requestedBinding.key().type(), processingEnv) + .getTypeArguments() + .get(1); + if (!XTypes.isTypeOf(valueType, TypeNames.PROVIDER) + || !XTypes.isDeclared(valueType)) { return false; } - TypeMirror providedType = MoreTypes.asDeclared(valueType).getTypeArguments().get(0); - return MoreDaggerTypes.isTypeOf(TypeNames.ANDROID_INJECTOR_FACTORY, providedType); + XType providedType = valueType.getTypeArguments().get(0); + return XTypes.isTypeOf(providedType, TypeNames.ANDROID_INJECTOR_FACTORY); }); } - private Optional<AnnotationMirror> mapKey(Binding binding) { + private Optional<XAnnotation> mapKey(Binding binding) { return binding .bindingElement() - .map(bindingElement -> getAnnotatedAnnotations(bindingElement, MapKey.class)) + .map( + bindingElement -> + XElements.getAnnotatedAnnotations( + DaggerElements.toXProcessing(bindingElement, processingEnv), TypeNames.MAP_KEY)) .flatMap( annotations -> annotations.isEmpty() diff --git a/java/dagger/hilt/processor/internal/definecomponent/KspDefineComponentValidationProcessor.java b/java/dagger/android/processor/KspAndroidProcessor.java index d46921ec2..7fe4f52d8 100644 --- a/java/dagger/hilt/processor/internal/definecomponent/KspDefineComponentValidationProcessor.java +++ b/java/dagger/android/processor/KspAndroidProcessor.java @@ -14,36 +14,40 @@ * limitations under the License. */ -package dagger.hilt.processor.internal.definecomponent; +package dagger.android.processor; +import androidx.room.compiler.processing.XProcessingEnv; +import androidx.room.compiler.processing.XProcessingStep; +import androidx.room.compiler.processing.ksp.KspBasicAnnotationProcessor; import com.google.auto.service.AutoService; import com.google.devtools.ksp.processing.SymbolProcessor; import com.google.devtools.ksp.processing.SymbolProcessorEnvironment; import com.google.devtools.ksp.processing.SymbolProcessorProvider; -import dagger.hilt.processor.internal.BaseProcessingStep; -import dagger.hilt.processor.internal.KspBaseProcessingStepProcessor; -/** - * A processor for {@link dagger.hilt.DefineComponent} and {@link - * dagger.hilt.DefineComponent.Builder}. - */ -public final class KspDefineComponentValidationProcessor extends KspBaseProcessingStepProcessor { - public KspDefineComponentValidationProcessor( - SymbolProcessorEnvironment symbolProcessorEnvironment) { - super(symbolProcessorEnvironment); +/** Ksp Processor for verifying usage of {@code dagger.android} code. */ +final class KspAndroidProcessor extends KspBasicAnnotationProcessor { + private final DelegateAndroidProcessor delegate = new DelegateAndroidProcessor(); + + private KspAndroidProcessor(SymbolProcessorEnvironment symbolProcessorEnvironment) { + super(symbolProcessorEnvironment, DelegateAndroidProcessor.PROCESSING_ENV_CONFIG); + } + + @Override + public void initialize(XProcessingEnv env) { + delegate.initialize(env); } @Override - protected BaseProcessingStep processingStep() { - return new DefineComponentValidationProcessingStep(getXProcessingEnv()); + public Iterable<XProcessingStep> processingSteps() { + return delegate.processingSteps(); } - /** Provides the {@link KspDefineComponentValidationProcessor}. */ + /** Provides the {@link KspAndroidProcessor}. */ @AutoService(SymbolProcessorProvider.class) public static final class Provider implements SymbolProcessorProvider { @Override public SymbolProcessor create(SymbolProcessorEnvironment symbolProcessorEnvironment) { - return new KspDefineComponentValidationProcessor(symbolProcessorEnvironment); + return new KspAndroidProcessor(symbolProcessorEnvironment); } } } diff --git a/java/dagger/android/processor/MoreDaggerElements.java b/java/dagger/android/processor/MoreDaggerElements.java deleted file mode 100644 index 572caa31a..000000000 --- a/java/dagger/android/processor/MoreDaggerElements.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2021 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.android.processor; - -import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; - -import com.google.auto.common.MoreElements; -import com.google.common.collect.ImmutableSet; -import com.squareup.javapoet.ClassName; -import java.util.Optional; -import javax.lang.model.element.AnnotationMirror; -import javax.lang.model.element.Element; -import javax.lang.model.element.TypeElement; - -// TODO(bcorso): Dedupe with dagger/internal/codegen/langmodel/DaggerElements.java? -// TODO(bcorso): Contribute upstream to auto common? -/** Similar to auto common, but uses {@link ClassName} rather than {@link Class}. */ -final class MoreDaggerElements { - /** - * Returns {@code true} iff the given element has an {@link AnnotationMirror} whose {@linkplain - * AnnotationMirror#getAnnotationType() annotation type} has the same canonical name as that of - * {@code annotationClass}. This method is a safer alternative to calling {@link - * Element#getAnnotation} and checking for {@code null} as it avoids any interaction with - * annotation proxies. - */ - public static boolean isAnnotationPresent(Element element, ClassName annotationName) { - return getAnnotationMirror(element, annotationName).isPresent(); - } - - /** - * Returns an {@link AnnotationMirror} for the annotation of type {@code annotationClass} on - * {@code element}, or {@link Optional#empty()} if no such annotation exists. This method is a - * safer alternative to calling {@link Element#getAnnotation} as it avoids any interaction with - * annotation proxies. - */ - public static Optional<AnnotationMirror> getAnnotationMirror( - Element element, ClassName annotationName) { - String annotationClassName = annotationName.canonicalName(); - for (AnnotationMirror annotationMirror : element.getAnnotationMirrors()) { - TypeElement annotationTypeElement = - MoreElements.asType(annotationMirror.getAnnotationType().asElement()); - if (annotationTypeElement.getQualifiedName().contentEquals(annotationClassName)) { - return Optional.of(annotationMirror); - } - } - return Optional.empty(); - } - - public static ImmutableSet<AnnotationMirror> getAnnotatedAnnotations( - Element element, ClassName annotationName) { - return element.getAnnotationMirrors().stream() - .filter(input -> isAnnotationPresent(input.getAnnotationType().asElement(), annotationName)) - .collect(toImmutableSet()); - } - - private MoreDaggerElements() {} -} diff --git a/java/dagger/android/processor/MoreDaggerTypes.java b/java/dagger/android/processor/MoreDaggerTypes.java deleted file mode 100644 index 4bde405e1..000000000 --- a/java/dagger/android/processor/MoreDaggerTypes.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2021 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.android.processor; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.auto.common.MoreElements; -import com.squareup.javapoet.ArrayTypeName; -import com.squareup.javapoet.ClassName; -import com.squareup.javapoet.TypeName; -import javax.lang.model.element.TypeElement; -import javax.lang.model.type.ArrayType; -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.ErrorType; -import javax.lang.model.type.NoType; -import javax.lang.model.type.PrimitiveType; -import javax.lang.model.type.TypeKind; -import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.SimpleTypeVisitor8; - -// TODO(bcorso): Dedupe with dagger/internal/codegen/langmodel/DaggerTypes.java? -// TODO(bcorso): Contribute upstream to auto common? -/** Similar to auto common, but uses {@link ClassName} rather than {@link Class}. */ -final class MoreDaggerTypes { - - /** - * Returns true if the raw type underlying the given {@link TypeMirror} represents the same raw - * type as the given {@link Class} and throws an IllegalArgumentException if the {@link - * TypeMirror} does not represent a type that can be referenced by a {@link Class} - */ - public static boolean isTypeOf(final TypeName typeName, TypeMirror type) { - checkNotNull(typeName); - return type.accept(new IsTypeOf(typeName), null); - } - - private static final class IsTypeOf extends SimpleTypeVisitor8<Boolean, Void> { - private final TypeName typeName; - - IsTypeOf(TypeName typeName) { - this.typeName = typeName; - } - - @Override - protected Boolean defaultAction(TypeMirror type, Void ignored) { - throw new IllegalArgumentException(type + " cannot be represented as a Class<?>."); - } - - @Override - public Boolean visitNoType(NoType noType, Void p) { - if (noType.getKind().equals(TypeKind.VOID)) { - return typeName.equals(TypeName.VOID); - } - throw new IllegalArgumentException(noType + " cannot be represented as a Class<?>."); - } - - @Override - public Boolean visitError(ErrorType errorType, Void p) { - return false; - } - - @Override - public Boolean visitPrimitive(PrimitiveType type, Void p) { - switch (type.getKind()) { - case BOOLEAN: - return typeName.equals(TypeName.BOOLEAN); - case BYTE: - return typeName.equals(TypeName.BYTE); - case CHAR: - return typeName.equals(TypeName.CHAR); - case DOUBLE: - return typeName.equals(TypeName.DOUBLE); - case FLOAT: - return typeName.equals(TypeName.FLOAT); - case INT: - return typeName.equals(TypeName.INT); - case LONG: - return typeName.equals(TypeName.LONG); - case SHORT: - return typeName.equals(TypeName.SHORT); - default: - throw new IllegalArgumentException(type + " cannot be represented as a Class<?>."); - } - } - - @Override - public Boolean visitArray(ArrayType array, Void p) { - return (typeName instanceof ArrayTypeName) - && isTypeOf(((ArrayTypeName) typeName).componentType, array.getComponentType()); - } - - @Override - public Boolean visitDeclared(DeclaredType type, Void ignored) { - TypeElement typeElement = MoreElements.asType(type.asElement()); - return (typeName instanceof ClassName) - && typeElement.getQualifiedName().contentEquals(((ClassName) typeName).canonicalName()); - } - } - - private MoreDaggerTypes() {} -} diff --git a/java/dagger/android/support/BUILD b/java/dagger/android/support/BUILD index 2fc9e2eb7..2f4c407b8 100644 --- a/java/dagger/android/support/BUILD +++ b/java/dagger/android/support/BUILD @@ -17,12 +17,14 @@ load( "//:build_defs.bzl", - "JAVA_RELEASE_MIN", "POM_VERSION", ) load("//tools:dejetify.bzl", "dejetified_library") -load("//tools:maven.bzl", "pom_file") -load("@google_bazel_common//tools/javadoc:javadoc.bzl", "javadoc_library") +load( + "//tools:maven.bzl", + "gen_maven_artifact", + "pom_file", +) package(default_visibility = ["//:src"]) @@ -34,8 +36,6 @@ filegroup( android_library( name = "support", srcs = glob(["*.java"]), - javacopts = JAVA_RELEASE_MIN, - manifest = "AndroidManifest.xml", tags = ["maven_coordinates=com.google.dagger:dagger-android-support:" + POM_VERSION], deps = [ "//:dagger_with_compiler", @@ -51,17 +51,34 @@ android_library( ], ) -pom_file( - name = "pom", - artifact_id = "dagger-android-support", +gen_maven_artifact( + name = "artifact", + artifact_coordinates = "com.google.dagger:dagger-android-support:" + POM_VERSION, artifact_name = "Dagger Android Support", + artifact_target = ":support", + artifact_target_maven_deps = [ + "androidx.activity:activity", + "androidx.annotation:annotation", + "androidx.appcompat:appcompat", + "androidx.fragment:fragment", + "androidx.lifecycle:lifecycle-common", + "androidx.lifecycle:lifecycle-viewmodel", + "androidx.lifecycle:lifecycle-viewmodel-savedstate", + "com.google.dagger:dagger", + "com.google.dagger:dagger-android", + ], + javadoc_android_api_level = 32, + javadoc_root_packages = [ + "dagger.android.support", + ], + javadoc_srcs = [":support-srcs"], + manifest = "AndroidManifest.xml", packaging = "aar", - targets = [":support"], ) dejetified_library( name = "dejetified-support", - input = ":support.aar", + input = ":artifact.aar", output = "support-legacy.aar", ) @@ -85,11 +102,3 @@ pom_file( packaging = "aar", targets = [":legacy-deps"], ) - -javadoc_library( - name = "support-javadoc", - srcs = [":support-srcs"], - android_api_level = 32, - root_packages = ["dagger.android.support"], - deps = [":support"], -) diff --git a/java/dagger/hilt/android/BUILD b/java/dagger/hilt/android/BUILD index ca950a3ee..b30f6625d 100644 --- a/java/dagger/hilt/android/BUILD +++ b/java/dagger/hilt/android/BUILD @@ -15,8 +15,8 @@ # Description: # A library based on Hilt that provides standard components and automated injection for Android. load("//:build_defs.bzl", "POM_VERSION") -load("//tools:maven.bzl", "gen_maven_artifact") load("//tools:bazel_compat.bzl", "compat_kt_android_library") +load("//tools:maven.bzl", "gen_maven_artifact") package(default_visibility = ["//:src"]) @@ -39,6 +39,7 @@ android_library( "//java/dagger/hilt/android/internal/managers:component_supplier", "//java/dagger/hilt/android/internal/modules", "//java/dagger/hilt/android/lifecycle:hilt_view_model", + "//java/dagger/hilt/android/lifecycle:hilt_view_model_extensions", "//java/dagger/hilt/codegen:originating_element", "//java/dagger/hilt/internal:component_entry_point", "//java/dagger/hilt/internal:component_manager", @@ -146,6 +147,14 @@ android_library( ], ) +android_library( + name = "unstable_api", + srcs = ["UnstableApi.java"], + deps = [ + "@maven//:androidx_annotation_annotation_experimental", + ], +) + java_library( name = "package_info", srcs = ["package-info.java"], @@ -163,6 +172,7 @@ android_library( ":entry_point_accessors", ":hilt_android_app", ":package_info", + ":unstable_api", "//java/dagger/hilt:artifact-core-lib", "//java/dagger/hilt/android/migration:custom_inject", "//java/dagger/hilt/android/migration:optional_inject", @@ -180,6 +190,7 @@ gen_maven_artifact( "//java/dagger/hilt/android:activity_retained_lifecycle", "//java/dagger/hilt/android:android_entry_point", "//java/dagger/hilt/android:hilt_android_app", + "//java/dagger/hilt/android:unstable_api", "//java/dagger/hilt/android:early_entry_point", "//java/dagger/hilt/android:package_info", "//java/dagger/hilt/android:view_model_lifecycle", @@ -193,10 +204,13 @@ gen_maven_artifact( "//java/dagger/hilt/android/internal/lifecycle", "//java/dagger/hilt/android/internal/managers", "//java/dagger/hilt/android/internal/managers:component_supplier", + "//java/dagger/hilt/android/internal/managers:saved_state_handle_holder", "//java/dagger/hilt/android/internal/migration:has_custom_inject", "//java/dagger/hilt/android/internal/migration:injected_by_hilt", "//java/dagger/hilt/android/internal/modules", + "//java/dagger/hilt/android/lifecycle:activity_retained_saved_state", "//java/dagger/hilt/android/lifecycle:hilt_view_model", + "//java/dagger/hilt/android/lifecycle:hilt_view_model_extensions", "//java/dagger/hilt/android/lifecycle:package_info", "//java/dagger/hilt/android/lifecycle:retained_lifecycle", "//java/dagger/hilt/android/migration:custom_inject", @@ -216,6 +230,7 @@ gen_maven_artifact( artifact_target_maven_deps = [ "androidx.activity:activity", "androidx.annotation:annotation", + "androidx.annotation:annotation-experimental", "androidx.fragment:fragment", "androidx.lifecycle:lifecycle-common", "androidx.lifecycle:lifecycle-viewmodel", @@ -244,10 +259,9 @@ gen_maven_artifact( ], manifest = "AndroidManifest.xml", packaging = "aar", - proguard_specs = [ + proguard_and_r8_specs = [ "//java/dagger/hilt:proguard-rules.pro", - ":proguard-rules.pro", - "//java/dagger/hilt/android/lifecycle:proguard-rules.pro", + "//java/dagger/hilt/android:proguard-rules.pro", "//java/dagger/hilt/internal:proguard-rules.pro", ], ) diff --git a/java/dagger/hilt/android/UnstableApi.java b/java/dagger/hilt/android/UnstableApi.java new file mode 100644 index 000000000..dd328ecb3 --- /dev/null +++ b/java/dagger/hilt/android/UnstableApi.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2023 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.android; + +import androidx.annotation.RequiresOptIn; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** Mark unstable Api usage. */ +@Retention(RetentionPolicy.CLASS) +@Target({ElementType.METHOD, ElementType.TYPE, ElementType.ANNOTATION_TYPE}) +@RequiresOptIn(level = RequiresOptIn.Level.ERROR) +public @interface UnstableApi {} diff --git a/java/dagger/hilt/android/internal/BUILD b/java/dagger/hilt/android/internal/BUILD index ae8a06692..4a231a85e 100644 --- a/java/dagger/hilt/android/internal/BUILD +++ b/java/dagger/hilt/android/internal/BUILD @@ -21,6 +21,7 @@ android_library( name = "internal", srcs = [ "Contexts.java", + "OnReceiveBytecodeInjectionMarker.java", "ThreadUtil.java", ], ) diff --git a/java/dagger/hilt/android/internal/OnReceiveBytecodeInjectionMarker.java b/java/dagger/hilt/android/internal/OnReceiveBytecodeInjectionMarker.java new file mode 100644 index 000000000..ed5abbe4a --- /dev/null +++ b/java/dagger/hilt/android/internal/OnReceiveBytecodeInjectionMarker.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2023 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.android.internal; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * The marker annotation used to denote that we need to inject super.onReceive() call + * to the @AndroidEntryPoint-annotated BroadcastReceiver's onReceive() method. + */ +@Retention(RetentionPolicy.CLASS) +@Target(ElementType.TYPE) +public @interface OnReceiveBytecodeInjectionMarker { } + diff --git a/java/dagger/hilt/android/internal/builders/ActivityRetainedComponentBuilder.java b/java/dagger/hilt/android/internal/builders/ActivityRetainedComponentBuilder.java index 110b3fef1..ff5998c01 100644 --- a/java/dagger/hilt/android/internal/builders/ActivityRetainedComponentBuilder.java +++ b/java/dagger/hilt/android/internal/builders/ActivityRetainedComponentBuilder.java @@ -16,11 +16,17 @@ package dagger.hilt.android.internal.builders; +import dagger.BindsInstance; import dagger.hilt.DefineComponent; import dagger.hilt.android.components.ActivityRetainedComponent; +import dagger.hilt.android.internal.managers.SavedStateHandleHolder; /** Interface for creating a {@link ActivityRetainedComponent}. */ @DefineComponent.Builder public interface ActivityRetainedComponentBuilder { + + ActivityRetainedComponentBuilder savedStateHandleHolder( + @BindsInstance SavedStateHandleHolder savedStateHandleHolder); + ActivityRetainedComponent build(); } diff --git a/java/dagger/hilt/android/internal/builders/BUILD b/java/dagger/hilt/android/internal/builders/BUILD index 598503eff..7f26e1dce 100644 --- a/java/dagger/hilt/android/internal/builders/BUILD +++ b/java/dagger/hilt/android/internal/builders/BUILD @@ -25,6 +25,7 @@ android_library( "//java/dagger/hilt:define_component", "//java/dagger/hilt/android:view_model_lifecycle", "//java/dagger/hilt/android/components", + "//java/dagger/hilt/android/internal/managers:saved_state_handle_holder", "@maven//:androidx_activity_activity", "@maven//:androidx_fragment_fragment", "@maven//:androidx_lifecycle_lifecycle_common", diff --git a/java/dagger/hilt/android/internal/lifecycle/BUILD b/java/dagger/hilt/android/internal/lifecycle/BUILD index f7314d279..7afd1dd9d 100644 --- a/java/dagger/hilt/android/internal/lifecycle/BUILD +++ b/java/dagger/hilt/android/internal/lifecycle/BUILD @@ -38,6 +38,7 @@ android_library( "@maven//:androidx_lifecycle_lifecycle_viewmodel", "@maven//:androidx_lifecycle_lifecycle_viewmodel_savedstate", "@maven//:androidx_savedstate_savedstate", + "@maven//:org_jetbrains_kotlin_kotlin_stdlib", ], ) diff --git a/java/dagger/hilt/android/internal/lifecycle/DefaultViewModelFactories.java b/java/dagger/hilt/android/internal/lifecycle/DefaultViewModelFactories.java index 78b8eb16b..67e68e71a 100644 --- a/java/dagger/hilt/android/internal/lifecycle/DefaultViewModelFactories.java +++ b/java/dagger/hilt/android/internal/lifecycle/DefaultViewModelFactories.java @@ -29,7 +29,7 @@ import dagger.hilt.android.components.ActivityComponent; import dagger.hilt.android.components.FragmentComponent; import dagger.hilt.android.internal.builders.ViewModelComponentBuilder; import dagger.multibindings.Multibinds; -import java.util.Set; +import java.util.Map; import javax.inject.Inject; /** @@ -69,12 +69,12 @@ public final class DefaultViewModelFactories { /** Internal factory for the Hilt ViewModel Factory. */ public static final class InternalFactoryFactory { - private final Set<String> keySet; + private final Map<Class<?>, Boolean> keySet; private final ViewModelComponentBuilder viewModelComponentBuilder; @Inject InternalFactoryFactory( - @HiltViewModelMap.KeySet Set<String> keySet, + @HiltViewModelMap.KeySet Map<Class<?>, Boolean> keySet, ViewModelComponentBuilder viewModelComponentBuilder) { this.keySet = keySet; this.viewModelComponentBuilder = viewModelComponentBuilder; @@ -103,7 +103,7 @@ public final class DefaultViewModelFactories { interface ActivityModule { @Multibinds @HiltViewModelMap.KeySet - abstract Set<String> viewModelKeys(); + abstract Map<Class<?>, Boolean> viewModelKeys(); } /** The activity entry point to retrieve the factory. */ diff --git a/java/dagger/hilt/android/internal/lifecycle/HiltViewModelAssistedMap.java b/java/dagger/hilt/android/internal/lifecycle/HiltViewModelAssistedMap.java new file mode 100644 index 000000000..69bb2b118 --- /dev/null +++ b/java/dagger/hilt/android/internal/lifecycle/HiltViewModelAssistedMap.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2023 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.android.internal.lifecycle; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import javax.inject.Qualifier; + +/** + * Internal qualifier for the multibinding map of assisted factories for @AssistedInject-annotated + * ViewModels used by the {@link dagger.hilt.android.lifecycle.HiltViewModelFactory}. + */ +@Qualifier +@Retention(RetentionPolicy.CLASS) +@Target({ElementType.METHOD, ElementType.PARAMETER}) +public @interface HiltViewModelAssistedMap {} diff --git a/java/dagger/hilt/android/internal/lifecycle/HiltViewModelFactory.java b/java/dagger/hilt/android/internal/lifecycle/HiltViewModelFactory.java index 52f31b920..6819c24bd 100644 --- a/java/dagger/hilt/android/internal/lifecycle/HiltViewModelFactory.java +++ b/java/dagger/hilt/android/internal/lifecycle/HiltViewModelFactory.java @@ -16,12 +16,12 @@ package dagger.hilt.android.internal.lifecycle; +import static androidx.lifecycle.SavedStateHandleSupport.createSavedStateHandle; + import android.app.Activity; import android.os.Bundle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.lifecycle.AbstractSavedStateViewModelFactory; -import androidx.lifecycle.SavedStateHandle; import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.viewmodel.CreationExtras; @@ -35,8 +35,8 @@ import dagger.hilt.android.components.ViewModelComponent; import dagger.hilt.android.internal.builders.ViewModelComponentBuilder; import dagger.multibindings.Multibinds; import java.util.Map; -import java.util.Set; import javax.inject.Provider; +import kotlin.jvm.functions.Function1; /** * View Model Provider Factory for the Hilt Extension. @@ -54,54 +54,110 @@ public final class HiltViewModelFactory implements ViewModelProvider.Factory { @InstallIn(ViewModelComponent.class) public interface ViewModelFactoriesEntryPoint { @HiltViewModelMap - Map<String, Provider<ViewModel>> getHiltViewModelMap(); + Map<Class<?>, Provider<ViewModel>> getHiltViewModelMap(); + + // From ViewModel class names to user defined @AssistedFactory-annotated implementations. + @HiltViewModelAssistedMap + Map<Class<?>, Object> getHiltViewModelAssistedMap(); } + /** Creation extra key for the callbacks that create @AssistedInject-annotated ViewModels. */ + public static final CreationExtras.Key<Function1<Object, ViewModel>> CREATION_CALLBACK_KEY = + new CreationExtras.Key<Function1<Object, ViewModel>>() {}; + /** Hilt module for providing the empty multi-binding map of ViewModels. */ @Module @InstallIn(ViewModelComponent.class) interface ViewModelModule { @Multibinds @HiltViewModelMap - Map<String, ViewModel> hiltViewModelMap(); + Map<Class<?>, ViewModel> hiltViewModelMap(); + + @Multibinds + @HiltViewModelAssistedMap + Map<Class<?>, Object> hiltViewModelAssistedMap(); } - private final Set<String> hiltViewModelKeys; + private final Map<Class<?>, Boolean> hiltViewModelKeys; private final ViewModelProvider.Factory delegateFactory; - private final AbstractSavedStateViewModelFactory hiltViewModelFactory; + private final ViewModelProvider.Factory hiltViewModelFactory; public HiltViewModelFactory( - @NonNull Set<String> hiltViewModelKeys, + @NonNull Map<Class<?>, Boolean> hiltViewModelKeys, @NonNull ViewModelProvider.Factory delegateFactory, @NonNull ViewModelComponentBuilder viewModelComponentBuilder) { this.hiltViewModelKeys = hiltViewModelKeys; this.delegateFactory = delegateFactory; this.hiltViewModelFactory = - new AbstractSavedStateViewModelFactory() { + new ViewModelProvider.Factory() { @NonNull @Override - @SuppressWarnings("unchecked") - protected <T extends ViewModel> T create( - @NonNull String key, @NonNull Class<T> modelClass, @NonNull SavedStateHandle handle) { + public <T extends ViewModel> T create( + @NonNull Class<T> modelClass, @NonNull CreationExtras extras) { RetainedLifecycleImpl lifecycle = new RetainedLifecycleImpl(); - ViewModelComponent component = viewModelComponentBuilder - .savedStateHandle(handle) - .viewModelLifecycle(lifecycle) - .build(); + ViewModelComponent component = + viewModelComponentBuilder + .savedStateHandle(createSavedStateHandle(extras)) + .viewModelLifecycle(lifecycle) + .build(); + T viewModel = createViewModel(component, modelClass, extras); + viewModel.addCloseable(lifecycle::dispatchOnCleared); + return viewModel; + } + + private <T extends ViewModel> T createViewModel( + @NonNull ViewModelComponent component, + @NonNull Class<T> modelClass, + @NonNull CreationExtras extras) { Provider<? extends ViewModel> provider = EntryPoints.get(component, ViewModelFactoriesEntryPoint.class) .getHiltViewModelMap() - .get(modelClass.getName()); - if (provider == null) { - throw new IllegalStateException( - "Expected the @HiltViewModel-annotated class '" - + modelClass.getName() - + "' to be available in the multi-binding of " - + "@HiltViewModelMap but none was found."); + .get(modelClass); + Function1<Object, ViewModel> creationCallback = extras.get(CREATION_CALLBACK_KEY); + Object assistedFactory = + EntryPoints.get(component, ViewModelFactoriesEntryPoint.class) + .getHiltViewModelAssistedMap() + .get(modelClass); + + if (assistedFactory == null) { + if (creationCallback == null) { + if (provider == null) { + throw new IllegalStateException( + "Expected the @HiltViewModel-annotated class " + + modelClass.getName() + + " to be available in the multi-binding of " + + "@HiltViewModelMap" + + " but none was found."); + } else { + return (T) provider.get(); + } + } else { + // Provider could be null or non-null. + throw new IllegalStateException( + "Found creation callback but class " + + modelClass.getName() + + " does not have an assisted factory specified in @HiltViewModel."); + } + } else { + if (provider == null) { + if (creationCallback == null) { + throw new IllegalStateException( + "Found @HiltViewModel-annotated class " + + modelClass.getName() + + " using @AssistedInject but no creation callback" + + " was provided in CreationExtras."); + } else { + return (T) creationCallback.invoke(assistedFactory); + } + } else { + // Creation callback could be null or non-null. + throw new AssertionError( + "Found the @HiltViewModel-annotated class " + + modelClass.getName() + + " in both the multi-bindings of " + + "@HiltViewModelMap and @HiltViewModelAssistedMap."); + } } - ViewModel viewModel = provider.get(); - viewModel.addCloseable(lifecycle::dispatchOnCleared); - return (T) viewModel; } }; } @@ -110,7 +166,7 @@ public final class HiltViewModelFactory implements ViewModelProvider.Factory { @Override public <T extends ViewModel> T create( @NonNull Class<T> modelClass, @NonNull CreationExtras extras) { - if (hiltViewModelKeys.contains(modelClass.getName())) { + if (hiltViewModelKeys.containsKey(modelClass)) { return hiltViewModelFactory.create(modelClass, extras); } else { return delegateFactory.create(modelClass, extras); @@ -120,7 +176,7 @@ public final class HiltViewModelFactory implements ViewModelProvider.Factory { @NonNull @Override public <T extends ViewModel> T create(@NonNull Class<T> modelClass) { - if (hiltViewModelKeys.contains(modelClass.getName())) { + if (hiltViewModelKeys.containsKey(modelClass)) { return hiltViewModelFactory.create(modelClass); } else { return delegateFactory.create(modelClass); @@ -131,7 +187,8 @@ public final class HiltViewModelFactory implements ViewModelProvider.Factory { @InstallIn(ActivityComponent.class) interface ActivityCreatorEntryPoint { @HiltViewModelMap.KeySet - Set<String> getViewModelKeys(); + Map<Class<?>, Boolean> getViewModelKeys(); + ViewModelComponentBuilder getViewModelComponentBuilder(); } diff --git a/java/dagger/hilt/android/internal/managers/ActivityComponentManager.java b/java/dagger/hilt/android/internal/managers/ActivityComponentManager.java index 50e4ce11d..3fa4910d0 100644 --- a/java/dagger/hilt/android/internal/managers/ActivityComponentManager.java +++ b/java/dagger/hilt/android/internal/managers/ActivityComponentManager.java @@ -70,6 +70,12 @@ public class ActivityComponentManager implements GeneratedComponentManager<Objec return component; } + public final SavedStateHandleHolder getSavedStateHandleHolder() { + // This will only be used on base activity that extends ComponentActivity. + return ((ActivityRetainedComponentManager) activityRetainedComponentManager) + .getSavedStateHandleHolder(); + } + protected Object createComponent() { if (!(activity.getApplication() instanceof GeneratedComponentManager)) { throw new IllegalStateException( diff --git a/java/dagger/hilt/android/internal/managers/ActivityRetainedComponentManager.java b/java/dagger/hilt/android/internal/managers/ActivityRetainedComponentManager.java index df63bd3d1..dc3539c34 100644 --- a/java/dagger/hilt/android/internal/managers/ActivityRetainedComponentManager.java +++ b/java/dagger/hilt/android/internal/managers/ActivityRetainedComponentManager.java @@ -23,6 +23,7 @@ import androidx.annotation.Nullable; import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelStoreOwner; +import androidx.lifecycle.viewmodel.CreationExtras; import dagger.Module; import dagger.Provides; import dagger.hilt.EntryPoint; @@ -57,15 +58,22 @@ final class ActivityRetainedComponentManager static final class ActivityRetainedComponentViewModel extends ViewModel { private final ActivityRetainedComponent component; + private final SavedStateHandleHolder savedStateHandleHolder; - ActivityRetainedComponentViewModel(ActivityRetainedComponent component) { + ActivityRetainedComponentViewModel( + ActivityRetainedComponent component, SavedStateHandleHolder savedStateHandleHolder) { this.component = component; + this.savedStateHandleHolder = savedStateHandleHolder; } ActivityRetainedComponent getComponent() { return component; } + SavedStateHandleHolder getSavedStateHandleHolder() { + return savedStateHandleHolder; + } + @Override protected void onCleared() { super.onCleared(); @@ -95,13 +103,17 @@ final class ActivityRetainedComponentManager @NonNull @Override @SuppressWarnings("unchecked") - public <T extends ViewModel> T create(@NonNull Class<T> aClass) { + public <T extends ViewModel> T create( + @NonNull Class<T> aClass, CreationExtras creationExtras) { + SavedStateHandleHolder savedStateHandleHolder = + new SavedStateHandleHolder(creationExtras); ActivityRetainedComponent component = EntryPointAccessors.fromApplication( - context, ActivityRetainedComponentBuilderEntryPoint.class) + context, ActivityRetainedComponentBuilderEntryPoint.class) .retainedComponentBuilder() + .savedStateHandleHolder(savedStateHandleHolder) .build(); - return (T) new ActivityRetainedComponentViewModel(component); + return (T) new ActivityRetainedComponentViewModel(component, savedStateHandleHolder); } }); } @@ -118,6 +130,12 @@ final class ActivityRetainedComponentManager return component; } + public SavedStateHandleHolder getSavedStateHandleHolder() { + return getViewModelProvider(viewModelStoreOwner, context) + .get(ActivityRetainedComponentViewModel.class) + .getSavedStateHandleHolder(); + } + private ActivityRetainedComponent createComponent() { return getViewModelProvider(viewModelStoreOwner, context) .get(ActivityRetainedComponentViewModel.class) diff --git a/java/dagger/hilt/android/internal/managers/BUILD b/java/dagger/hilt/android/internal/managers/BUILD index e553c6e8c..950b51129 100644 --- a/java/dagger/hilt/android/internal/managers/BUILD +++ b/java/dagger/hilt/android/internal/managers/BUILD @@ -30,25 +30,46 @@ android_library( "ApplicationComponentManager.java", "BroadcastReceiverComponentManager.java", "FragmentComponentManager.java", + "SavedStateHandleModule.java", "ServiceComponentManager.java", "ViewComponentManager.java", ], + exports = [":saved_state_handle_holder"], deps = [ ":component_supplier", + ":saved_state_handle_holder", "//:dagger_with_compiler", "//java/dagger/hilt:entry_point", "//java/dagger/hilt:install_in", "//java/dagger/hilt/android:activity_retained_lifecycle", "//java/dagger/hilt/android:entry_point_accessors", + "//java/dagger/hilt/android:unstable_api", "//java/dagger/hilt/android/components", "//java/dagger/hilt/android/internal", "//java/dagger/hilt/android/internal/builders", "//java/dagger/hilt/android/internal/lifecycle", + "//java/dagger/hilt/android/lifecycle:activity_retained_saved_state", "//java/dagger/hilt/android/scopes", "//java/dagger/hilt/internal:component_manager", "//java/dagger/hilt/internal:preconditions", "@maven//:androidx_activity_activity", "@maven//:androidx_annotation_annotation", + "@maven//:androidx_annotation_annotation_experimental", + "@maven//:androidx_fragment_fragment", + "@maven//:androidx_lifecycle_lifecycle_common", + "@maven//:androidx_lifecycle_lifecycle_viewmodel", + "@maven//:androidx_lifecycle_lifecycle_viewmodel_savedstate", + ], +) + +android_library( + name = "saved_state_handle_holder", + srcs = ["SavedStateHandleHolder.java"], + deps = [ + "//java/dagger/hilt/android/internal", + "//java/dagger/hilt/internal:preconditions", + "@maven//:androidx_activity_activity", + "@maven//:androidx_annotation_annotation", "@maven//:androidx_fragment_fragment", "@maven//:androidx_lifecycle_lifecycle_common", "@maven//:androidx_lifecycle_lifecycle_viewmodel", diff --git a/java/dagger/hilt/android/internal/managers/SavedStateHandleHolder.java b/java/dagger/hilt/android/internal/managers/SavedStateHandleHolder.java new file mode 100644 index 000000000..835015900 --- /dev/null +++ b/java/dagger/hilt/android/internal/managers/SavedStateHandleHolder.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2023 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.android.internal.managers; + +import static dagger.hilt.internal.Preconditions.checkNotNull; +import static dagger.hilt.internal.Preconditions.checkState; + +import android.os.Bundle; +import androidx.annotation.Nullable; +import androidx.lifecycle.SavedStateHandle; +import androidx.lifecycle.SavedStateHandleSupport; +import androidx.lifecycle.viewmodel.CreationExtras; +import androidx.lifecycle.viewmodel.MutableCreationExtras; +import dagger.hilt.android.internal.ThreadUtil; + +/** Implementation for SavedStateHandleHolder. */ +public final class SavedStateHandleHolder { + private CreationExtras extras; + private SavedStateHandle handle; + private final boolean nonComponentActivity; + + SavedStateHandleHolder(@Nullable CreationExtras extras) { + nonComponentActivity = (extras == null); + this.extras = extras; + } + + SavedStateHandle getSavedStateHandle() { + ThreadUtil.ensureMainThread(); + checkState( + !nonComponentActivity, + "Activity that does not extend ComponentActivity cannot use SavedStateHandle"); + if (handle != null) { + return handle; + } + checkNotNull( + extras, + "The first access to SavedStateHandle should happen between super.onCreate() and" + + " super.onDestroy()"); + // Clean up default args, since those are unused and we don't want to duplicate those for each + // SavedStateHandle + MutableCreationExtras mutableExtras = new MutableCreationExtras(extras); + mutableExtras.set(SavedStateHandleSupport.DEFAULT_ARGS_KEY, Bundle.EMPTY); + extras = mutableExtras; + handle = SavedStateHandleSupport.createSavedStateHandle(extras); + + extras = null; + return handle; + } + + public void clear() { + extras = null; + } + + public void setExtras(CreationExtras extras) { + if (handle != null) { + // If handle is already created, we don't need to store CreationExtras. + return; + } + this.extras = extras; + } + + public boolean isInvalid() { + return handle == null && extras == null; + } +} diff --git a/java/dagger/hilt/android/internal/managers/SavedStateHandleModule.java b/java/dagger/hilt/android/internal/managers/SavedStateHandleModule.java new file mode 100644 index 000000000..18ca508bc --- /dev/null +++ b/java/dagger/hilt/android/internal/managers/SavedStateHandleModule.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2023 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.android.internal.managers; + +import androidx.annotation.OptIn; +import androidx.lifecycle.SavedStateHandle; +import dagger.Module; +import dagger.Provides; +import dagger.hilt.InstallIn; +import dagger.hilt.android.UnstableApi; +import dagger.hilt.android.components.ActivityRetainedComponent; +import dagger.hilt.android.lifecycle.ActivityRetainedSavedState; +import dagger.hilt.android.scopes.ActivityRetainedScoped; + +/** Module providing SavedStateHandle from ActivityRetainedComponent. */ +@Module +@InstallIn(ActivityRetainedComponent.class) +abstract class SavedStateHandleModule { + @OptIn(markerClass = UnstableApi.class) + @ActivityRetainedSavedState + @ActivityRetainedScoped + @Provides + static SavedStateHandle provideSavedStateHandle(SavedStateHandleHolder savedStateHandleHolder) { + return savedStateHandleHolder.getSavedStateHandle(); + } +} diff --git a/java/dagger/hilt/android/lifecycle/ActivityRetainedSavedState.java b/java/dagger/hilt/android/lifecycle/ActivityRetainedSavedState.java new file mode 100644 index 000000000..629843538 --- /dev/null +++ b/java/dagger/hilt/android/lifecycle/ActivityRetainedSavedState.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2023 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.android.lifecycle; + +import dagger.hilt.android.UnstableApi; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import javax.inject.Qualifier; + +/** Qualifies a binding that belongs to ActivityRetainedComponent. */ +@Qualifier +@Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD}) +@UnstableApi +@Retention(RetentionPolicy.CLASS) +public @interface ActivityRetainedSavedState {} diff --git a/java/dagger/hilt/android/lifecycle/BUILD b/java/dagger/hilt/android/lifecycle/BUILD index 456dbe76a..26394f0f8 100644 --- a/java/dagger/hilt/android/lifecycle/BUILD +++ b/java/dagger/hilt/android/lifecycle/BUILD @@ -15,6 +15,8 @@ # Description: # Hilt ViewModel integration. +load("//tools:bazel_compat.bzl", "compat_kt_android_library") + package(default_visibility = ["//:src"]) java_library( @@ -31,7 +33,6 @@ android_library( exported_plugins = [ "//java/dagger/hilt/android/processor/internal/viewmodel:processor", ], - proguard_specs = ["proguard-rules.pro"], exports = [ "//:dagger_with_compiler", "//java/dagger/hilt:install_in", @@ -54,6 +55,26 @@ android_library( ], ) +android_library( + name = "activity_retained_saved_state", + srcs = ["ActivityRetainedSavedState.java"], + deps = [ + "//java/dagger/hilt/android:unstable_api", + "//third_party/java/jsr330_inject", + ], +) + +compat_kt_android_library( + name = "hilt_view_model_extensions", + srcs = ["HiltViewModelExtensions.kt"], + deps = [ + ":package_info", + "//java/dagger/hilt/android/internal/lifecycle", + "@maven//:androidx_annotation_annotation", + "@maven//:androidx_lifecycle_lifecycle_viewmodel", + ], +) + filegroup( name = "srcs_filegroup", srcs = glob(["*"]), diff --git a/java/dagger/hilt/android/lifecycle/HiltViewModel.java b/java/dagger/hilt/android/lifecycle/HiltViewModel.java index 198ec8abe..a5e486f21 100644 --- a/java/dagger/hilt/android/lifecycle/HiltViewModel.java +++ b/java/dagger/hilt/android/lifecycle/HiltViewModel.java @@ -53,7 +53,46 @@ import java.lang.annotation.Target; * } * </pre> * - * <p>Exactly one constructor in the {@code ViewModel} must be annotated with {@code Inject}. + * <p>{@code ViewModel}s annotated with {@link HiltViewModel} can also be used with assisted + * injection: + * + * <pre> + * @HiltViewModel(assistedFactory = DonutViewModel.Factory.class) + * public class DonutViewModel extends ViewModel { + * @AssistedInject + * public DonutViewModel( + * SavedStateHandle handle, + * RecipeRepository repository, + * $#64;Assisted int donutId + * ) { + * // ... + * } + * + * @AssistedFactory + * public interface Factory { + * DonutViewModel create(int donutId); + * } + * } + * </pre> + * + * <pre> + * @AndroidEntryPoint + * public class CookingActivity extends AppCompatActivity { + * public void onCreate(Bundle savedInstanceState) { + * DonutViewModel vm = new ViewModelProvider( + * getViewModelStore(), + * getDefaultViewModelProviderFactory(), + * HiltViewModelExtensions.withCreationCallback( + * getDefaultViewModelCreationExtras(), + * (DonutViewModel.Factory factory) -> factory.create(1) + * ) + * ).get(DonutViewModel.class); + * } + * } + * </pre> + * + * <p>Exactly one constructor in the {@code ViewModel} must be annotated with {@code Inject} or + * {@code AssistedInject}. * * <p>Only dependencies available in the {@link dagger.hilt.android.components.ViewModelComponent} * can be injected into the {@code ViewModel}. @@ -65,4 +104,11 @@ import java.lang.annotation.Target; @Target(ElementType.TYPE) @Retention(RetentionPolicy.CLASS) @GeneratesRootInput -public @interface HiltViewModel {} +public @interface HiltViewModel { + /** + * Returns a factory class that can be used to create this ViewModel with assisted injection. The + * default value `Object.class` denotes that no factory is specified and the ViewModel is not + * assisted injected. + */ + Class<?> assistedFactory() default Object.class; +} diff --git a/java/dagger/hilt/android/lifecycle/HiltViewModelExtensions.kt b/java/dagger/hilt/android/lifecycle/HiltViewModelExtensions.kt new file mode 100644 index 000000000..f212c58ba --- /dev/null +++ b/java/dagger/hilt/android/lifecycle/HiltViewModelExtensions.kt @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2023 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. + */ + +@file:JvmName("HiltViewModelExtensions") + +package dagger.hilt.android.lifecycle + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewmodel.CreationExtras +import androidx.lifecycle.viewmodel.MutableCreationExtras +import dagger.hilt.android.internal.lifecycle.HiltViewModelFactory + +/** + * Returns a new {@code CreationExtras} with the original entries plus the passed in creation + * callback. The callback is used by Hilt to create {@link AssistedInject}-annotated {@link + * HiltViewModel}s. + * + * @param callback A creation callback that takes an assisted factory and returns a {@code + * ViewModel}. + */ +fun <VMF> CreationExtras.withCreationCallback(callback: (VMF) -> ViewModel): CreationExtras = + MutableCreationExtras(this).addCreationCallback(callback) + +/** + * Returns the {@code MutableCreationExtras} with the passed in creation callback added. The + * callback is used by Hilt to create {@link AssistedInject}-annotated {@link HiltViewModel}s. + * + * @param callback A creation callback that takes an assisted factory and returns a {@code + * ViewModel}. + */ +@Suppress("UNCHECKED_CAST") +fun <VMF> MutableCreationExtras.addCreationCallback(callback: (VMF) -> ViewModel): CreationExtras = + this.apply { + this[HiltViewModelFactory.CREATION_CALLBACK_KEY] = { factory -> callback(factory as VMF) } + } diff --git a/java/dagger/hilt/android/lifecycle/proguard-rules.pro b/java/dagger/hilt/android/lifecycle/proguard-rules.pro deleted file mode 100644 index 6c647f105..000000000 --- a/java/dagger/hilt/android/lifecycle/proguard-rules.pro +++ /dev/null @@ -1,2 +0,0 @@ -# Keep class names of Hilt injected ViewModels since their name are used as a multibinding map key. --keepnames @dagger.hilt.android.lifecycle.HiltViewModel class * extends androidx.lifecycle.ViewModel
\ No newline at end of file diff --git a/java/dagger/hilt/android/plugin/agp-wrapper-7-0/build.gradle b/java/dagger/hilt/android/plugin/agp-wrapper-7-0/build.gradle index 3c0349565..5509261c5 100644 --- a/java/dagger/hilt/android/plugin/agp-wrapper-7-0/build.gradle +++ b/java/dagger/hilt/android/plugin/agp-wrapper-7-0/build.gradle @@ -2,8 +2,10 @@ plugins { id 'org.jetbrains.kotlin.jvm' } -kotlin { - jvmToolchain(11) +compileKotlin { + kotlinOptions { + jvmTarget = 11 + } } dependencies { diff --git a/java/dagger/hilt/android/plugin/agp-wrapper-7-1/build.gradle b/java/dagger/hilt/android/plugin/agp-wrapper-7-1/build.gradle index 5bc8d3d1c..982949a49 100644 --- a/java/dagger/hilt/android/plugin/agp-wrapper-7-1/build.gradle +++ b/java/dagger/hilt/android/plugin/agp-wrapper-7-1/build.gradle @@ -2,8 +2,10 @@ plugins { id 'org.jetbrains.kotlin.jvm' } -kotlin { - jvmToolchain(11) +compileKotlin { + kotlinOptions { + jvmTarget = 11 + } } dependencies { diff --git a/java/dagger/hilt/android/plugin/agp-wrapper-7-2/build.gradle b/java/dagger/hilt/android/plugin/agp-wrapper-7-2/build.gradle index a41330196..e0331c2a8 100644 --- a/java/dagger/hilt/android/plugin/agp-wrapper-7-2/build.gradle +++ b/java/dagger/hilt/android/plugin/agp-wrapper-7-2/build.gradle @@ -2,8 +2,10 @@ plugins { id 'org.jetbrains.kotlin.jvm' } -kotlin { - jvmToolchain(11) +compileKotlin { + kotlinOptions { + jvmTarget = 11 + } } dependencies { diff --git a/java/dagger/hilt/android/plugin/agp-wrapper-impl/build.gradle b/java/dagger/hilt/android/plugin/agp-wrapper-impl/build.gradle index 3ad558a8a..f270efb9f 100644 --- a/java/dagger/hilt/android/plugin/agp-wrapper-impl/build.gradle +++ b/java/dagger/hilt/android/plugin/agp-wrapper-impl/build.gradle @@ -2,8 +2,10 @@ plugins { id 'org.jetbrains.kotlin.jvm' } -kotlin { - jvmToolchain(11) +compileKotlin { + kotlinOptions { + jvmTarget = 11 + } } dependencies { diff --git a/java/dagger/hilt/android/plugin/agp-wrapper/build.gradle b/java/dagger/hilt/android/plugin/agp-wrapper/build.gradle index 71ea72424..d8238e8f1 100644 --- a/java/dagger/hilt/android/plugin/agp-wrapper/build.gradle +++ b/java/dagger/hilt/android/plugin/agp-wrapper/build.gradle @@ -2,8 +2,10 @@ plugins { id 'org.jetbrains.kotlin.jvm' } -kotlin { - jvmToolchain(11) +compileKotlin { + kotlinOptions { + jvmTarget = 11 + } } dependencies { diff --git a/java/dagger/hilt/android/plugin/agp-wrapper/src/main/kotlin/dagger/hilt/android/plugin/util/ComponentCompat.kt b/java/dagger/hilt/android/plugin/agp-wrapper/src/main/kotlin/dagger/hilt/android/plugin/util/ComponentCompat.kt index acc59e79d..1f0d589a2 100644 --- a/java/dagger/hilt/android/plugin/agp-wrapper/src/main/kotlin/dagger/hilt/android/plugin/util/ComponentCompat.kt +++ b/java/dagger/hilt/android/plugin/agp-wrapper/src/main/kotlin/dagger/hilt/android/plugin/util/ComponentCompat.kt @@ -20,6 +20,8 @@ import com.android.build.api.instrumentation.AsmClassVisitorFactory import com.android.build.api.instrumentation.FramesComputationMode import com.android.build.api.instrumentation.InstrumentationParameters import com.android.build.api.instrumentation.InstrumentationScope +import java.io.File +import org.gradle.api.Project /** * Compatibility version of [com.android.build.api.variant.Component] diff --git a/java/dagger/hilt/android/plugin/build.gradle b/java/dagger/hilt/android/plugin/build.gradle index 869d88516..685ea7e37 100644 --- a/java/dagger/hilt/android/plugin/build.gradle +++ b/java/dagger/hilt/android/plugin/build.gradle @@ -1,8 +1,8 @@ buildscript { ext { - kotlin_version = "1.8.20" + kotlin_version = "1.9.20" agp_version = System.getenv('AGP_VERSION') ?: "7.2.0" - ksp_version = "$kotlin_version-1.0.11" + ksp_version = "$kotlin_version-1.0.14" pluginArtifactId = 'hilt-android-gradle-plugin' pluginId = 'com.google.dagger.hilt.android' } @@ -24,7 +24,12 @@ allprojects { mavenCentral() } } + +// Avoids conflict with BUILD file +project.buildDir = 'buildOut' + subprojects { + project.buildDir = 'buildOut' afterEvaluate { dependencies { // This is needed to align older versions of kotlin-stdlib. diff --git a/java/dagger/hilt/android/plugin/main/build.gradle b/java/dagger/hilt/android/plugin/main/build.gradle index 96a28b937..035ecea22 100644 --- a/java/dagger/hilt/android/plugin/main/build.gradle +++ b/java/dagger/hilt/android/plugin/main/build.gradle @@ -65,16 +65,16 @@ dependencies { compileOnly "com.android.tools.build:gradle:$agp_version" compileOnly "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" compileOnly "com.google.devtools.ksp:symbol-processing-gradle-plugin:$ksp_version" - implementation 'org.ow2.asm:asm:9.0' + implementation 'org.ow2.asm:asm:9.6' implementation "com.squareup:javapoet:1.13.0" testImplementation gradleTestKit() testImplementation 'junit:junit:4.12' testImplementation 'com.google.truth:truth:1.0.1' testImplementation 'org.javassist:javassist:3.26.0-GA' - testPluginCompile 'com.android.tools.build:gradle:7.1.2' - testPluginCompile 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.0' - testPluginCompile 'com.google.devtools.ksp:symbol-processing-gradle-plugin:1.8.0-1.0.9' + testPluginCompile "com.android.tools.build:gradle:$agp_version" + testPluginCompile "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + testPluginCompile "com.google.devtools.ksp:symbol-processing-gradle-plugin:$ksp_version" } // Configure the generating task of plugin-under-test-metadata.properties to @@ -85,14 +85,11 @@ tasks.withType(PluginUnderTestMetadata.class).named("pluginUnderTestMetadata").c it.pluginClasspath.from(configurations.testPluginCompile) } -kotlin { - jvmToolchain(11) -} - compileKotlin { kotlinOptions { allWarningsAsErrors = true freeCompilerArgs += [ "-opt-in=kotlin.ExperimentalStdlibApi" ] + jvmTarget = 11 } } diff --git a/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/AndroidEntryPointClassVisitor.kt b/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/AndroidEntryPointClassVisitor.kt index da5fb3c3c..16e4af9c0 100644 --- a/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/AndroidEntryPointClassVisitor.kt +++ b/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/AndroidEntryPointClassVisitor.kt @@ -36,15 +36,10 @@ import org.objectweb.asm.Opcodes class AndroidEntryPointClassVisitor( private val apiVersion: Int, nextClassVisitor: ClassVisitor, - private val additionalClasses: File + private val classContext: ClassContext ) : ClassVisitor(apiVersion, nextClassVisitor) { - interface AndroidEntryPointParams : InstrumentationParameters { - @get:Internal - val additionalClassesDir: Property<File> - } - - abstract class Factory : AsmClassVisitorFactory<AndroidEntryPointParams> { + abstract class Factory : AsmClassVisitorFactory<InstrumentationParameters.None> { override fun createClassVisitor( classContext: ClassContext, nextClassVisitor: ClassVisitor @@ -52,7 +47,7 @@ class AndroidEntryPointClassVisitor( return AndroidEntryPointClassVisitor( apiVersion = instrumentationContext.apiVersion.get(), nextClassVisitor = nextClassVisitor, - additionalClasses = parameters.get().additionalClassesDir.get() + classContext = classContext ) } @@ -198,34 +193,21 @@ class AndroidEntryPointClassVisitor( } /** - * Check if Hilt generated class is a BroadcastReceiver with the marker field which means + * Check if Hilt generated class is a BroadcastReceiver with the marker annotation which means * a super.onReceive invocation has to be inserted in the implementation. */ - private fun hasOnReceiveBytecodeInjectionMarker() = - findAdditionalClassFile(newSuperclassName).inputStream().use { - var hasMarker = false - ClassReader(it).accept( - object : ClassVisitor(apiVersion) { - override fun visitField( - access: Int, - name: String, - descriptor: String, - signature: String?, - value: Any? - ): FieldVisitor? { - if (name == "onReceiveBytecodeInjectionMarker") { - hasMarker = true - } - return null - } - }, - ClassReader.SKIP_CODE or ClassReader.SKIP_DEBUG or ClassReader.SKIP_FRAMES - ) - return@use hasMarker - } + private fun hasOnReceiveBytecodeInjectionMarker(): Boolean { + val newSuperclassFQName = newSuperclassName.toFQName() + return classContext.loadClassData(newSuperclassFQName) + ?.classAnnotations?.contains(ON_RECEIVE_MARKER_ANNOTATION) + ?: error("Cannot load class $newSuperclassFQName!") + } - private fun findAdditionalClassFile(className: String) = - File(additionalClasses, "$className.class") + /** + * Return a fully qualified name from an internal name. + * See https://asm.ow2.io/javadoc/org/objectweb/asm/Type.html#getInternalName() + */ + private fun String.toFQName() = this.replace('/', '.') companion object { val ANDROID_ENTRY_POINT_ANNOTATIONS = setOf( @@ -235,5 +217,6 @@ class AndroidEntryPointClassVisitor( const val ON_RECEIVE_METHOD_NAME = "onReceive" const val ON_RECEIVE_METHOD_DESCRIPTOR = "(Landroid/content/Context;Landroid/content/Intent;)V" + const val ON_RECEIVE_MARKER_ANNOTATION = "dagger.hilt.android.internal.OnReceiveBytecodeInjectionMarker" } } diff --git a/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/HiltGradlePlugin.kt b/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/HiltGradlePlugin.kt index 4e2b8788a..7b03e434a 100644 --- a/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/HiltGradlePlugin.kt +++ b/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/HiltGradlePlugin.kt @@ -38,7 +38,6 @@ import dagger.hilt.android.plugin.util.getKaptConfigName import dagger.hilt.android.plugin.util.getKspConfigName import dagger.hilt.android.plugin.util.isKspTask import dagger.hilt.processor.internal.optionvalues.GradleProjectType -import java.io.File import javax.inject.Inject import org.gradle.api.JavaVersion import org.gradle.api.Plugin @@ -246,12 +245,9 @@ class HiltGradlePlugin @Inject constructor( fun registerTransform(androidComponent: ComponentCompat) { androidComponent.transformClassesWith( classVisitorFactoryImplClass = AndroidEntryPointClassVisitor.Factory::class.java, - scope = InstrumentationScope.PROJECT - ) { params -> - val classesDir = - File(project.buildDir, "intermediates/javac/${androidComponent.name}/classes") - params.additionalClassesDir.set(classesDir) - } + scope = InstrumentationScope.PROJECT, + instrumentationParamsConfig = {} + ) androidComponent.setAsmFramesComputationMode( FramesComputationMode.COMPUTE_FRAMES_FOR_INSTRUMENTED_METHODS ) diff --git a/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/util/CopyTransform.kt b/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/util/CopyTransform.kt index 7c8326b0f..f7c33dca4 100644 --- a/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/util/CopyTransform.kt +++ b/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/util/CopyTransform.kt @@ -16,7 +16,6 @@ package dagger.hilt.android.plugin.util -import org.gradle.api.artifacts.transform.CacheableTransform import org.gradle.api.artifacts.transform.InputArtifact import org.gradle.api.artifacts.transform.TransformAction import org.gradle.api.artifacts.transform.TransformOutputs @@ -24,12 +23,13 @@ import org.gradle.api.artifacts.transform.TransformParameters import org.gradle.api.file.FileSystemLocation import org.gradle.api.provider.Provider import org.gradle.api.tasks.Classpath +import org.gradle.work.DisableCachingByDefault /** * A transform that registers the input file (usually a jar or a class) as an output and thus * changing from one artifact type to another. */ -@CacheableTransform +@DisableCachingByDefault(because = "Copying files does not benefit from caching") abstract class CopyTransform : TransformAction<TransformParameters.None> { @get:Classpath @get:InputArtifact diff --git a/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/util/Tasks.kt b/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/util/Tasks.kt index 2c803b71a..a91ce35c6 100644 --- a/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/util/Tasks.kt +++ b/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/util/Tasks.kt @@ -38,8 +38,20 @@ internal fun addKaptTaskProcessorOptions( component: ComponentCompat, produceArgProvider: (Task) -> CommandLineArgumentProvider ) = project.plugins.withId("kotlin-kapt") { + checkClass("org.jetbrains.kotlin.gradle.internal.KaptTask") { + """ + The KAPT plugin was detected to be applied but its task class could not be found. + + This is an indicator that the Hilt Gradle Plugin is using a different class loader because + it was declared at the root while KAPT was declared in a sub-project. To fix this, declare + both plugins in the same scope, i.e. either at the root (without applying them) or at the + sub-projects. + """.trimIndent() + } project.tasks.withType(KaptTask::class.java) { task -> - if (task.name == "kapt${component.name.capitalize()}Kotlin") { + if (task.name == "kapt${component.name.capitalize()}Kotlin" || + // Task names in shared/src/AndroidMain in KMP projects has a platform suffix. + task.name == "kapt${component.name.capitalize()}KotlinAndroid") { val argProvider = produceArgProvider.invoke(task) // TODO: Update once KT-58009 is fixed. try { @@ -60,16 +72,39 @@ internal fun addKspTaskProcessorOptions( component: ComponentCompat, produceArgProvider: (Task) -> CommandLineArgumentProvider ) = project.plugins.withId("com.google.devtools.ksp") { + checkClass("com.google.devtools.ksp.gradle.KspTaskJvm") { + """ + The KSP plugin was detected to be applied but its task class could not be found. + + This is an indicator that the Hilt Gradle Plugin is using a different class loader because + it was declared at the root while KSP was declared in a sub-project. To fix this, declare + both plugins in the same scope, i.e. either at the root (without applying them) or at the + sub-projects. + + See https://github.com/google/dagger/issues/3965 for more details. + """.trimIndent() + } project.tasks.withType(KspTaskJvm::class.java) { task -> - if (task.name == "ksp${component.name.capitalize()}Kotlin") { + if (task.name == "ksp${component.name.capitalize()}Kotlin" || + // Task names in shared/src/AndroidMain in KMP projects has a platform suffix. + task.name == "ksp${component.name.capitalize()}KotlinAndroid") { task.commandLineArgumentProviders.add(produceArgProvider.invoke(task)) } } } +private inline fun checkClass(fqn: String, msg: () -> String) { + try { + Class.forName(fqn) + } catch (ex: ClassNotFoundException) { + throw IllegalStateException(msg.invoke(), ex) + } +} + internal fun Task.isKspTask(): Boolean = try { val kspTaskClass = Class.forName("com.google.devtools.ksp.gradle.KspTask") kspTaskClass.isAssignableFrom(this::class.java) } catch (ex: ClassNotFoundException) { false -}
\ No newline at end of file +} + diff --git a/java/dagger/hilt/android/plugin/main/src/test/data/android-libraryA/build.gradle b/java/dagger/hilt/android/plugin/main/src/test/data/android-libraryA/build.gradle index e0ec23097..9e8a097b2 100644 --- a/java/dagger/hilt/android/plugin/main/src/test/data/android-libraryA/build.gradle +++ b/java/dagger/hilt/android/plugin/main/src/test/data/android-libraryA/build.gradle @@ -4,12 +4,12 @@ plugins { } android { - compileSdkVersion 32 - buildToolsVersion "32.0.0" + compileSdkVersion 33 + buildToolsVersion "33.0.0" defaultConfig { minSdkVersion 21 - targetSdkVersion 32 + targetSdkVersion 33 versionCode 1 versionName "1.0" } diff --git a/java/dagger/hilt/android/plugin/main/src/test/data/android-libraryC/build.gradle b/java/dagger/hilt/android/plugin/main/src/test/data/android-libraryC/build.gradle index 68c6a97f3..450f128aa 100644 --- a/java/dagger/hilt/android/plugin/main/src/test/data/android-libraryC/build.gradle +++ b/java/dagger/hilt/android/plugin/main/src/test/data/android-libraryC/build.gradle @@ -4,12 +4,12 @@ plugins { } android { - compileSdkVersion 32 - buildToolsVersion "32.0.0" + compileSdkVersion 33 + buildToolsVersion "33.0.0" defaultConfig { minSdkVersion 21 - targetSdkVersion 32 + targetSdkVersion 33 versionCode 1 versionName "1.0" } diff --git a/java/dagger/hilt/android/plugin/main/src/test/data/flavored-project/app/build.gradle b/java/dagger/hilt/android/plugin/main/src/test/data/flavored-project/app/build.gradle index 23cd028b9..954e209d9 100644 --- a/java/dagger/hilt/android/plugin/main/src/test/data/flavored-project/app/build.gradle +++ b/java/dagger/hilt/android/plugin/main/src/test/data/flavored-project/app/build.gradle @@ -20,8 +20,8 @@ plugins { } android { - compileSdkVersion 32 - buildToolsVersion "32.0.0" + compileSdkVersion 33 + buildToolsVersion "33.0.0" flavorDimensions 'api', 'version' productFlavors { @@ -46,7 +46,7 @@ android { defaultConfig { applicationId "simple.app" minSdkVersion 21 - targetSdkVersion 32 + targetSdkVersion 33 } compileOptions { diff --git a/java/dagger/hilt/android/plugin/main/src/test/data/flavored-project/feature/build.gradle b/java/dagger/hilt/android/plugin/main/src/test/data/flavored-project/feature/build.gradle index 8e3495156..068d402fa 100644 --- a/java/dagger/hilt/android/plugin/main/src/test/data/flavored-project/feature/build.gradle +++ b/java/dagger/hilt/android/plugin/main/src/test/data/flavored-project/feature/build.gradle @@ -20,8 +20,8 @@ plugins { } android { - compileSdkVersion 32 - buildToolsVersion "32.0.0" + compileSdkVersion 33 + buildToolsVersion "33.0.0" flavorDimensions 'api', 'version' productFlavors { @@ -45,7 +45,7 @@ android { defaultConfig { minSdkVersion 16 - targetSdkVersion 32 + targetSdkVersion 33 } compileOptions { diff --git a/java/dagger/hilt/android/plugin/main/src/test/data/simple-project-for-agp-test/app/build.gradle b/java/dagger/hilt/android/plugin/main/src/test/data/simple-project-for-agp-test/app/build.gradle index 2173a8280..506d40a81 100644 --- a/java/dagger/hilt/android/plugin/main/src/test/data/simple-project-for-agp-test/app/build.gradle +++ b/java/dagger/hilt/android/plugin/main/src/test/data/simple-project-for-agp-test/app/build.gradle @@ -20,13 +20,13 @@ plugins { } android { - compileSdkVersion 32 - buildToolsVersion "32.0.0" + compileSdkVersion 33 + namespace "simple.app" defaultConfig { applicationId "simple.app" minSdkVersion 21 - targetSdkVersion 32 + targetSdkVersion 33 } compileOptions { diff --git a/java/dagger/hilt/android/plugin/main/src/test/data/simple-project-for-agp-test/app/src/main/AndroidManifest.xml b/java/dagger/hilt/android/plugin/main/src/test/data/simple-project-for-agp-test/app/src/main/AndroidManifest.xml index da45ecc46..ce521fba8 100644 --- a/java/dagger/hilt/android/plugin/main/src/test/data/simple-project-for-agp-test/app/src/main/AndroidManifest.xml +++ b/java/dagger/hilt/android/plugin/main/src/test/data/simple-project-for-agp-test/app/src/main/AndroidManifest.xml @@ -16,5 +16,7 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="simple.app"> <application android:name=".SimpleApp" android:label="Flavored App"> + <receiver android:name=".SimpleReceiver" android:exported="false"> + </receiver> </application> </manifest>
\ No newline at end of file diff --git a/java/dagger/hilt/android/plugin/main/src/test/data/simple-project-for-agp-test/app/src/main/java/simple/app/SimpleReceiver.java b/java/dagger/hilt/android/plugin/main/src/test/data/simple-project-for-agp-test/app/src/main/java/simple/app/SimpleReceiver.java new file mode 100644 index 000000000..ce483add8 --- /dev/null +++ b/java/dagger/hilt/android/plugin/main/src/test/data/simple-project-for-agp-test/app/src/main/java/simple/app/SimpleReceiver.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2023 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 simple.app; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import dagger.hilt.android.AndroidEntryPoint; + +@AndroidEntryPoint +class SimpleReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) {} +} diff --git a/java/dagger/hilt/android/plugin/main/src/test/data/simple-project-for-agp-test/feature/build.gradle b/java/dagger/hilt/android/plugin/main/src/test/data/simple-project-for-agp-test/feature/build.gradle index e19f1d571..57f7a742b 100644 --- a/java/dagger/hilt/android/plugin/main/src/test/data/simple-project-for-agp-test/feature/build.gradle +++ b/java/dagger/hilt/android/plugin/main/src/test/data/simple-project-for-agp-test/feature/build.gradle @@ -20,12 +20,12 @@ plugins { } android { - compileSdkVersion 32 - buildToolsVersion "32.0.0" + compileSdkVersion 33 + namespace "simple.library" defaultConfig { minSdkVersion 16 - targetSdkVersion 32 + targetSdkVersion 33 } compileOptions { diff --git a/java/dagger/hilt/android/plugin/main/src/test/kotlin/AGPCompatibilityTest.kt b/java/dagger/hilt/android/plugin/main/src/test/kotlin/AGPCompatibilityTest.kt index d5bc48802..f488fb332 100644 --- a/java/dagger/hilt/android/plugin/main/src/test/kotlin/AGPCompatibilityTest.kt +++ b/java/dagger/hilt/android/plugin/main/src/test/kotlin/AGPCompatibilityTest.kt @@ -26,11 +26,13 @@ import org.junit.rules.TemporaryFolder import org.junit.runner.RunWith import org.junit.runners.Parameterized -const val TASK = ":app:hiltJavaCompileDebug" +// `hiltJavaCompileDebug` gets to run as well as `transformDebugClassesWithAsm` depends on it. +const val TASK = ":app:transformDebugClassesWithAsm" @RunWith(Parameterized::class) class AGPCompatibilityTest( - private val agpVersion: String + private val agpVersion: String, + private val gradleVersion: String ) { @get:Rule val testProjectDir = TemporaryFolder() @@ -75,18 +77,21 @@ class AGPCompatibilityTest( GradleRunner.create() .withProjectDir(testProjectDir.root) .withArguments(*args) + .withGradleVersion(gradleVersion) .forwardOutput() return gradleRunner.build() } companion object { @JvmStatic - @Parameterized.Parameters(name = "agpVersion = {0}") + @Parameterized.Parameters(name = "agpVersion = {0}, gradleVersion = {1}") fun parameters() = listOf( - arrayOf("7.2.0"), - arrayOf("7.1.0"), - arrayOf("7.0.0"), + // AGP 8.3 requires Gradle 8.4 and JDK 17. + arrayOf("8.3.0-alpha11", "8.4"), + arrayOf("7.2.0", "7.4.2"), + arrayOf("7.1.0", "7.4.2"), + arrayOf("7.0.0", "7.4.2"), ) } } diff --git a/java/dagger/hilt/android/plugin/main/src/test/kotlin/BuildCacheTest.kt b/java/dagger/hilt/android/plugin/main/src/test/kotlin/BuildCacheTest.kt index 4c34dd621..c5a67afbb 100644 --- a/java/dagger/hilt/android/plugin/main/src/test/kotlin/BuildCacheTest.kt +++ b/java/dagger/hilt/android/plugin/main/src/test/kotlin/BuildCacheTest.kt @@ -82,8 +82,6 @@ class BuildCacheTest(private val enableAggregatingTask: Boolean) { val secondResult = secondGradleRunner.build() val cacheableTasks: List<String> = mutableListOf<String>().apply { - add(":checkDebugAarMetadata") - add(":checkDebugDuplicateClasses") add(":compileDebugJavaWithJavac") add(":compressDebugAssets") add(":desugarDebugFileDependencies") @@ -105,9 +103,6 @@ class BuildCacheTest(private val enableAggregatingTask: Boolean) { add(":mergeProjectDexDebug") add(":processDebugManifestForPackage") add(":transformDebugClassesWithAsm") - add(":validateSigningDebug") - add(":writeDebugAppMetadata") - add(":writeDebugSigningConfigVersions") } val tasksFromCache = diff --git a/java/dagger/hilt/android/plugin/main/src/test/kotlin/GradleTestRunner.kt b/java/dagger/hilt/android/plugin/main/src/test/kotlin/GradleTestRunner.kt index fb47bdb13..221dfcfd4 100644 --- a/java/dagger/hilt/android/plugin/main/src/test/kotlin/GradleTestRunner.kt +++ b/java/dagger/hilt/android/plugin/main/src/test/kotlin/GradleTestRunner.kt @@ -156,13 +156,13 @@ class GradleTestRunner(val tempFolder: TemporaryFolder) { } android { - compileSdkVersion 32 - buildToolsVersion "32.0.0" + compileSdkVersion 33 + buildToolsVersion "33.0.0" defaultConfig { ${ if (isAppProject) "applicationId \"plugin.test\"" else "" } minSdkVersion 21 - targetSdkVersion 32 + targetSdkVersion 33 } compileOptions { @@ -189,7 +189,8 @@ class GradleTestRunner(val tempFolder: TemporaryFolder) { ${hiltOptions.joinToString(separator = "\n")} } ${additionalClosures.joinToString(separator = "\n")} - """.trimIndent() + """ + .trimIndent() ) } } @@ -198,9 +199,14 @@ class GradleTestRunner(val tempFolder: TemporaryFolder) { gradlePropertiesFile?.delete() gradlePropertiesFile = tempFolder.newFile("gradle.properties").apply { - writeText(""" + writeText( + """ android.useAndroidX=true - """.trimIndent()) + // TODO(b/296583777): See if there's a better way to fix the OOM error. + org.gradle.jvmargs=-XX:MaxMetaspaceSize=1g + """ + .trimIndent() + ) } } @@ -218,7 +224,8 @@ class GradleTestRunner(val tempFolder: TemporaryFolder) { ${activities.joinToString(separator = "\n")} </application> </manifest> - """.trimIndent() + """ + .trimIndent() ) } } diff --git a/java/dagger/hilt/android/plugin/main/src/test/kotlin/IncrementalProcessorTest.kt b/java/dagger/hilt/android/plugin/main/src/test/kotlin/IncrementalProcessorTest.kt index 1e8490f1b..4fb25a0b3 100644 --- a/java/dagger/hilt/android/plugin/main/src/test/kotlin/IncrementalProcessorTest.kt +++ b/java/dagger/hilt/android/plugin/main/src/test/kotlin/IncrementalProcessorTest.kt @@ -34,11 +34,9 @@ import org.junit.runners.Parameterized @RunWith(Parameterized::class) class IncrementalProcessorTest(private val incapMode: String) { - @get:Rule - val testProjectDir = TemporaryFolder() + @get:Rule val testProjectDir = TemporaryFolder() - @get:Rule - val expect: Expect = Expect.create() + @get:Rule val expect: Expect = Expect.create() // Original source files private lateinit var srcApp: File @@ -108,16 +106,18 @@ class IncrementalProcessorTest(private val incapMode: String) { private lateinit var unchangedFiles: Set<File> private lateinit var deletedFiles: Set<File> - private val compileTaskName = if (incapMode == ISOLATING_MODE) { - ":hiltJavaCompileDebug" - } else { - ":compileDebugJavaWithJavac" - } - private val testCompileTaskName = if (incapMode == ISOLATING_MODE) { - ":hiltJavaCompileDebugUnitTest" - } else { - ":compileDebugUnitTestJavaWithJavac" - } + private val compileTaskName = + if (incapMode == ISOLATING_MODE) { + ":hiltJavaCompileDebug" + } else { + ":compileDebugJavaWithJavac" + } + private val testCompileTaskName = + if (incapMode == ISOLATING_MODE) { + ":hiltJavaCompileDebugUnitTest" + } else { + ":compileDebugUnitTestJavaWithJavac" + } private val aggregatingTaskName = ":hiltAggregateDepsDebug" private val testAggregatingTaskName = ":hiltAggregateDepsDebugUnitTest" @@ -128,8 +128,9 @@ class IncrementalProcessorTest(private val incapMode: String) { File("src/test/data/simple-project").copyRecursively(projectRoot) // set up build file - File(projectRoot, "build.gradle").writeText( - """ + File(projectRoot, "build.gradle") + .writeText( + """ buildscript { repositories { google() @@ -146,13 +147,13 @@ class IncrementalProcessorTest(private val incapMode: String) { } android { - compileSdkVersion 32 - buildToolsVersion "32.0.0" + compileSdkVersion 33 + buildToolsVersion "33.0.0" defaultConfig { applicationId "hilt.simple" minSdkVersion 21 - targetSdkVersion 32 + targetSdkVersion 33 javaCompileOptions { annotationProcessorOptions { arguments += ["dagger.hilt.shareTestComponents" : "true"] @@ -190,32 +191,36 @@ class IncrementalProcessorTest(private val incapMode: String) { hilt { enableAggregatingTask = ${if (incapMode == ISOLATING_MODE) "true" else "false"} } - """.trimIndent() - ) + """ + .trimIndent() + ) // Compute directory paths val defaultGenSrcDir = "build/generated/ap_generated_sources/debug/out/" - fun getComponentTreeDepsGenSrcDir(variant: String) = if (incapMode == ISOLATING_MODE) { - "build/generated/hilt/component_trees/$variant/" - } else { - "build/generated/ap_generated_sources/$variant/out/" - } + fun getComponentTreeDepsGenSrcDir(variant: String) = + if (incapMode == ISOLATING_MODE) { + "build/generated/hilt/component_trees/$variant/" + } else { + "build/generated/ap_generated_sources/$variant/out/" + } val componentTreeDepsGenSrcDir = getComponentTreeDepsGenSrcDir("debug") val testComponentTreeDepsGenSrcDir = getComponentTreeDepsGenSrcDir("debugUnitTest") - fun getRootGenSrcDir(variant: String) = if (incapMode == ISOLATING_MODE) { - "build/generated/hilt/component_sources/$variant/" - } else { - "build/generated/ap_generated_sources/$variant/out/" - } + fun getRootGenSrcDir(variant: String) = + if (incapMode == ISOLATING_MODE) { + "build/generated/hilt/component_sources/$variant/" + } else { + "build/generated/ap_generated_sources/$variant/out/" + } val rootGenSrcDir = getRootGenSrcDir("debug") val testRootGenSrcDir = getRootGenSrcDir("debugUnitTest") val defaultClassesDir = "build/intermediates/javac/debug/classes" val testDefaultClassesDir = "build/intermediates/javac/debugUnitTest/classes" - fun getRootClassesDir(variant: String) = if (incapMode == ISOLATING_MODE) { - "build/intermediates/hilt/component_classes/$variant/" - } else { - "build/intermediates/javac/$variant/classes" - } + fun getRootClassesDir(variant: String) = + if (incapMode == ISOLATING_MODE) { + "build/intermediates/hilt/component_classes/$variant/" + } else { + "build/intermediates/javac/$variant/classes" + } val rootClassesDir = getRootClassesDir("debug") val testRootClassesDir = getRootClassesDir("debugUnitTest") @@ -236,59 +241,64 @@ class IncrementalProcessorTest(private val incapMode: String) { File(projectRoot, "$defaultGenSrcDir/simple/Activity1_GeneratedInjector.java") genActivityInjector2 = File(projectRoot, "$defaultGenSrcDir/simple/Activity2_GeneratedInjector.java") - genAppInjectorDeps = File( - projectRoot, - "$defaultGenSrcDir/hilt_aggregated_deps/_simple_SimpleApp_GeneratedInjector.java" - ) - genActivityInjectorDeps1 = File( - projectRoot, - "$defaultGenSrcDir/hilt_aggregated_deps/_simple_Activity1_GeneratedInjector.java" - ) - genActivityInjectorDeps2 = File( - projectRoot, - "$defaultGenSrcDir/hilt_aggregated_deps/_simple_Activity2_GeneratedInjector.java" - ) - genModuleDeps1 = File( - projectRoot, - "$defaultGenSrcDir/hilt_aggregated_deps/_simple_Module1.java" - ) + genAppInjectorDeps = + File( + projectRoot, + "$defaultGenSrcDir/hilt_aggregated_deps/_simple_SimpleApp_GeneratedInjector.java" + ) + genActivityInjectorDeps1 = + File( + projectRoot, + "$defaultGenSrcDir/hilt_aggregated_deps/_simple_Activity1_GeneratedInjector.java" + ) + genActivityInjectorDeps2 = + File( + projectRoot, + "$defaultGenSrcDir/hilt_aggregated_deps/_simple_Activity2_GeneratedInjector.java" + ) + genModuleDeps1 = + File(projectRoot, "$defaultGenSrcDir/hilt_aggregated_deps/_simple_Module1.java") genModuleDeps2 = File(projectRoot, "$defaultGenSrcDir/hilt_aggregated_deps/_simple_Module2.java") genComponentTreeDeps = File(projectRoot, "$componentTreeDepsGenSrcDir/simple/SimpleApp_ComponentTreeDeps.java") genHiltComponents = File(projectRoot, "$rootGenSrcDir/simple/SimpleApp_HiltComponents.java") - genDaggerHiltApplicationComponent = File( - projectRoot, - "$rootGenSrcDir/simple/DaggerSimpleApp_HiltComponents_SingletonC.java" - ) - genTest1ComponentTreeDeps = File( - projectRoot, - testComponentTreeDepsGenSrcDir + - "/dagger/hilt/android/internal/testing/root/Test1_ComponentTreeDeps.java" - ) - genTest2ComponentTreeDeps = File( - projectRoot, - testComponentTreeDepsGenSrcDir + - "/dagger/hilt/android/internal/testing/root/Test2_ComponentTreeDeps.java" - ) - genTest1HiltComponents = File( - projectRoot, - "$testRootGenSrcDir/dagger/hilt/android/internal/testing/root/Test1_HiltComponents.java" - ) - genTest2HiltComponents = File( - projectRoot, - "$testRootGenSrcDir/dagger/hilt/android/internal/testing/root/Test2_HiltComponents.java" - ) - genTest1DaggerHiltApplicationComponent = File( - projectRoot, - testRootGenSrcDir + - "/dagger/hilt/android/internal/testing/root/DaggerTest1_HiltComponents_SingletonC.java" - ) - genTest2DaggerHiltApplicationComponent = File( - projectRoot, - testRootGenSrcDir + - "/dagger/hilt/android/internal/testing/root/DaggerTest2_HiltComponents_SingletonC.java" - ) + genDaggerHiltApplicationComponent = + File(projectRoot, "$rootGenSrcDir/simple/DaggerSimpleApp_HiltComponents_SingletonC.java") + genTest1ComponentTreeDeps = + File( + projectRoot, + testComponentTreeDepsGenSrcDir + + "/dagger/hilt/android/internal/testing/root/Test1_ComponentTreeDeps.java" + ) + genTest2ComponentTreeDeps = + File( + projectRoot, + testComponentTreeDepsGenSrcDir + + "/dagger/hilt/android/internal/testing/root/Test2_ComponentTreeDeps.java" + ) + genTest1HiltComponents = + File( + projectRoot, + "$testRootGenSrcDir/dagger/hilt/android/internal/testing/root/Test1_HiltComponents.java" + ) + genTest2HiltComponents = + File( + projectRoot, + "$testRootGenSrcDir/dagger/hilt/android/internal/testing/root/Test2_HiltComponents.java" + ) + genTest1DaggerHiltApplicationComponent = + File( + projectRoot, + testRootGenSrcDir + + "/dagger/hilt/android/internal/testing/root/DaggerTest1_HiltComponents_SingletonC.java" + ) + genTest2DaggerHiltApplicationComponent = + File( + projectRoot, + testRootGenSrcDir + + "/dagger/hilt/android/internal/testing/root/DaggerTest2_HiltComponents_SingletonC.java" + ) classSrcApp = File(projectRoot, "$defaultClassesDir/simple/SimpleApp.class") classSrcActivity1 = File(projectRoot, "$defaultClassesDir/simple/Activity1.class") @@ -302,70 +312,69 @@ class IncrementalProcessorTest(private val incapMode: String) { classGenHiltActivity2 = File(projectRoot, "$defaultClassesDir/simple/Hilt_Activity2.class") classGenAppInjector = File(projectRoot, "$defaultClassesDir/simple/SimpleApp_GeneratedInjector.class") - classGenActivityInjector1 = File( - projectRoot, - "$defaultClassesDir/simple/Activity1_GeneratedInjector.class" - ) - classGenActivityInjector2 = File( - projectRoot, - "$defaultClassesDir/simple/Activity2_GeneratedInjector.class" - ) - classGenAppInjectorDeps = File( - projectRoot, - "$defaultClassesDir/hilt_aggregated_deps/_simple_SimpleApp_GeneratedInjector.class" - ) - classGenActivityInjectorDeps1 = File( - projectRoot, - "$defaultClassesDir/hilt_aggregated_deps/_simple_Activity1_GeneratedInjector.class" - ) - classGenActivityInjectorDeps2 = File( - projectRoot, - "$defaultClassesDir/hilt_aggregated_deps/_simple_Activity2_GeneratedInjector.class" - ) + classGenActivityInjector1 = + File(projectRoot, "$defaultClassesDir/simple/Activity1_GeneratedInjector.class") + classGenActivityInjector2 = + File(projectRoot, "$defaultClassesDir/simple/Activity2_GeneratedInjector.class") + classGenAppInjectorDeps = + File( + projectRoot, + "$defaultClassesDir/hilt_aggregated_deps/_simple_SimpleApp_GeneratedInjector.class" + ) + classGenActivityInjectorDeps1 = + File( + projectRoot, + "$defaultClassesDir/hilt_aggregated_deps/_simple_Activity1_GeneratedInjector.class" + ) + classGenActivityInjectorDeps2 = + File( + projectRoot, + "$defaultClassesDir/hilt_aggregated_deps/_simple_Activity2_GeneratedInjector.class" + ) classGenModuleDeps1 = File(projectRoot, "$defaultClassesDir/hilt_aggregated_deps/_simple_Module1.class") classGenModuleDeps2 = File(projectRoot, "$defaultClassesDir/hilt_aggregated_deps/_simple_Module2.class") - classGenComponentTreeDeps = File( - projectRoot, - "$rootClassesDir/simple/SimpleApp_ComponentTreeDeps.class" - ) - classGenHiltComponents = File( - projectRoot, - "$rootClassesDir/simple/SimpleApp_HiltComponents.class" - ) - classGenDaggerHiltApplicationComponent = File( - projectRoot, - "$rootClassesDir/simple/DaggerSimpleApp_HiltComponents_SingletonC.class" - ) - classGenTest1ComponentTreeDeps = File( - projectRoot, - testRootClassesDir + - "/dagger/hilt/android/internal/testing/root/Test1_ComponentTreeDeps.class" - ) - classGenTest2ComponentTreeDeps = File( - projectRoot, - testRootClassesDir + - "/dagger/hilt/android/internal/testing/root/Test2_ComponentTreeDeps.class" - ) - classGenTest1HiltComponents = File( - projectRoot, - "$testRootClassesDir/dagger/hilt/android/internal/testing/root/Test1_HiltComponents.class" - ) - classGenTest2HiltComponents = File( - projectRoot, - "$testRootClassesDir/dagger/hilt/android/internal/testing/root/Test2_HiltComponents.class" - ) - classGenTest1DaggerHiltApplicationComponent = File( - projectRoot, - testRootClassesDir + - "/dagger/hilt/android/internal/testing/root/DaggerTest1_HiltComponents_SingletonC.class" - ) - classGenTest2DaggerHiltApplicationComponent = File( - projectRoot, - testRootClassesDir + - "/dagger/hilt/android/internal/testing/root/DaggerTest2_HiltComponents_SingletonC.class" - ) + classGenComponentTreeDeps = + File(projectRoot, "$rootClassesDir/simple/SimpleApp_ComponentTreeDeps.class") + classGenHiltComponents = + File(projectRoot, "$rootClassesDir/simple/SimpleApp_HiltComponents.class") + classGenDaggerHiltApplicationComponent = + File(projectRoot, "$rootClassesDir/simple/DaggerSimpleApp_HiltComponents_SingletonC.class") + classGenTest1ComponentTreeDeps = + File( + projectRoot, + testRootClassesDir + + "/dagger/hilt/android/internal/testing/root/Test1_ComponentTreeDeps.class" + ) + classGenTest2ComponentTreeDeps = + File( + projectRoot, + testRootClassesDir + + "/dagger/hilt/android/internal/testing/root/Test2_ComponentTreeDeps.class" + ) + classGenTest1HiltComponents = + File( + projectRoot, + "$testRootClassesDir/dagger/hilt/android/internal/testing/root/Test1_HiltComponents.class" + ) + classGenTest2HiltComponents = + File( + projectRoot, + "$testRootClassesDir/dagger/hilt/android/internal/testing/root/Test2_HiltComponents.class" + ) + classGenTest1DaggerHiltApplicationComponent = + File( + projectRoot, + testRootClassesDir + + "/dagger/hilt/android/internal/testing/root/DaggerTest1_HiltComponents_SingletonC.class" + ) + classGenTest2DaggerHiltApplicationComponent = + File( + projectRoot, + testRootClassesDir + + "/dagger/hilt/android/internal/testing/root/DaggerTest2_HiltComponents_SingletonC.class" + ) } @Test @@ -428,13 +437,15 @@ class IncrementalProcessorTest(private val incapMode: String) { // Change Activity 1 source searchAndReplace( - srcActivity1, "// Insert-change", + srcActivity1, + "// Insert-change", """ @Override public void onResume() { super.onResume(); } - """.trimIndent() + """ + .trimIndent() ) val result = runIncrementalBuild() @@ -442,66 +453,69 @@ class IncrementalProcessorTest(private val incapMode: String) { // Check annotation processing outputs // * Only activity 1 sources are re-generated, isolation in modules and from other activities - val regeneratedSourceFiles = if (incapMode == ISOLATING_MODE) { - // * Aggregating task did not run, no change in deps - expect.that(result.task(aggregatingTaskName)!!.outcome).isEqualTo(TaskOutcome.UP_TO_DATE) - // * Components are re-generated due to a recompilation of a dep - listOf( - genHiltApp, // Re-gen because components got re-gen - genHiltActivity1, - genActivityInjector1, - genActivityInjectorDeps1, - genHiltComponents, - genDaggerHiltApplicationComponent - ) - } else { - // * Root classes along with components are always re-generated (aggregated processor) - listOf( - genHiltApp, - genHiltActivity1, - genAppInjector, - genActivityInjector1, - genAppInjectorDeps, - genActivityInjectorDeps1, - genComponentTreeDeps, - genHiltComponents, - genDaggerHiltApplicationComponent - ) - } + val regeneratedSourceFiles = + if (incapMode == ISOLATING_MODE) { + // * Aggregating task did not run, no change in deps + expect.that(result.task(aggregatingTaskName)!!.outcome).isEqualTo(TaskOutcome.UP_TO_DATE) + // * Components are re-generated due to a recompilation of a dep + listOf( + genHiltApp, // Re-gen because components got re-gen + genHiltActivity1, + genActivityInjector1, + genActivityInjectorDeps1, + genHiltComponents, + genDaggerHiltApplicationComponent + ) + } else { + // * Root classes along with components are always re-generated (aggregated processor) + listOf( + genHiltApp, + genHiltActivity1, + genAppInjector, + genActivityInjector1, + genAppInjectorDeps, + genActivityInjectorDeps1, + genComponentTreeDeps, + genHiltComponents, + genDaggerHiltApplicationComponent + ) + } assertChangedFiles(FileType.JAVA, regeneratedSourceFiles) val componentTreeDepsIncrementalBuild = genComponentTreeDeps.readText(Charsets.UTF_8) - expect.withMessage("Full build") - .that(componentTreeDepsFullBuild) - .isEqualTo(componentTreeDepsIncrementalBuild) + expect + .withMessage("Full build") + .that(componentTreeDepsFullBuild) + .isEqualTo(componentTreeDepsIncrementalBuild) // Check compilation outputs // * Gen sources from activity 1 are re-compiled - val recompiledClassFiles = if (incapMode == ISOLATING_MODE) { - listOf( - classSrcActivity1, - classGenHiltApp, - classGenHiltActivity1, - classGenActivityInjector1, - classGenActivityInjectorDeps1, - classGenHiltComponents, - classGenDaggerHiltApplicationComponent, - ) - } else { - // * All aggregating processor gen sources are re-compiled - listOf( - classSrcActivity1, - classGenHiltApp, - classGenHiltActivity1, - classGenAppInjector, - classGenActivityInjector1, - classGenAppInjectorDeps, - classGenActivityInjectorDeps1, - classGenHiltComponents, - classGenComponentTreeDeps, - classGenDaggerHiltApplicationComponent - ) - } + val recompiledClassFiles = + if (incapMode == ISOLATING_MODE) { + listOf( + classSrcActivity1, + classGenHiltApp, + classGenHiltActivity1, + classGenActivityInjector1, + classGenActivityInjectorDeps1, + classGenHiltComponents, + classGenDaggerHiltApplicationComponent, + ) + } else { + // * All aggregating processor gen sources are re-compiled + listOf( + classSrcActivity1, + classGenHiltApp, + classGenHiltActivity1, + classGenAppInjector, + classGenActivityInjector1, + classGenAppInjectorDeps, + classGenActivityInjectorDeps1, + classGenHiltComponents, + classGenComponentTreeDeps, + classGenDaggerHiltApplicationComponent + ) + } assertChangedFiles(FileType.CLASS, recompiledClassFiles) } @@ -512,76 +526,82 @@ class IncrementalProcessorTest(private val incapMode: String) { // Change Activity 1 source searchAndReplace( - srcActivity1, "// Insert-change", + srcActivity1, + "// Insert-change", """ private void foo() { } - """.trimIndent() + """ + .trimIndent() ) val result = runIncrementalBuild() - val expectedOutcome = if (incapMode == ISOLATING_MODE) { - // In isolating mode, changes that do not affect ABI will not cause re-compilation. - TaskOutcome.UP_TO_DATE - } else { - TaskOutcome.SUCCESS - } + val expectedOutcome = + if (incapMode == ISOLATING_MODE) { + // In isolating mode, changes that do not affect ABI will not cause re-compilation. + TaskOutcome.UP_TO_DATE + } else { + TaskOutcome.SUCCESS + } expect.that(result.task(compileTaskName)!!.outcome).isEqualTo(expectedOutcome) // Check annotation processing outputs // * Only activity 1 sources are re-generated, isolation in modules and from other activities - val regeneratedSourceFiles = if (incapMode == ISOLATING_MODE) { - // * Aggregating task did not run, no change in deps - expect.that(result.task(aggregatingTaskName)!!.outcome).isEqualTo(TaskOutcome.UP_TO_DATE) - listOf( - genHiltActivity1, - genActivityInjector1, - genActivityInjectorDeps1, - ) - } else { - // * Root classes along with components are always re-generated (aggregated processor) - listOf( - genHiltApp, - genHiltActivity1, - genAppInjector, - genActivityInjector1, - genAppInjectorDeps, - genActivityInjectorDeps1, - genComponentTreeDeps, - genHiltComponents, - genDaggerHiltApplicationComponent - ) - } + val regeneratedSourceFiles = + if (incapMode == ISOLATING_MODE) { + // * Aggregating task did not run, no change in deps + expect.that(result.task(aggregatingTaskName)!!.outcome).isEqualTo(TaskOutcome.UP_TO_DATE) + listOf( + genHiltActivity1, + genActivityInjector1, + genActivityInjectorDeps1, + ) + } else { + // * Root classes along with components are always re-generated (aggregated processor) + listOf( + genHiltApp, + genHiltActivity1, + genAppInjector, + genActivityInjector1, + genAppInjectorDeps, + genActivityInjectorDeps1, + genComponentTreeDeps, + genHiltComponents, + genDaggerHiltApplicationComponent + ) + } assertChangedFiles(FileType.JAVA, regeneratedSourceFiles) val componentTreeDepsIncrementalBuild = genComponentTreeDeps.readText(Charsets.UTF_8) - expect.withMessage("Full build") - .that(componentTreeDepsFullBuild) - .isEqualTo(componentTreeDepsIncrementalBuild) + expect + .withMessage("Full build") + .that(componentTreeDepsFullBuild) + .isEqualTo(componentTreeDepsIncrementalBuild) // Check compilation outputs // * Gen sources from activity 1 are re-compiled - val recompiledClassFiles = if (incapMode == ISOLATING_MODE) { - listOf( - classSrcActivity1, - classGenHiltActivity1, - classGenActivityInjector1, - classGenActivityInjectorDeps1 - ) - } else { - // * All aggregating processor gen sources are re-compiled - listOf( - classSrcActivity1, - classGenHiltApp, - classGenHiltActivity1, - classGenAppInjector, - classGenActivityInjector1, - classGenAppInjectorDeps, - classGenActivityInjectorDeps1, - classGenComponentTreeDeps, - classGenHiltComponents, - classGenDaggerHiltApplicationComponent - ) - } + val recompiledClassFiles = + if (incapMode == ISOLATING_MODE) { + listOf( + classSrcActivity1, + classGenHiltActivity1, + classGenActivityInjector1, + classGenActivityInjectorDeps1 + ) + } else { + // * All aggregating processor gen sources are re-compiled + listOf( + classSrcActivity1, + classGenHiltApp, + classGenHiltActivity1, + classGenAppInjector, + classGenActivityInjector1, + classGenAppInjectorDeps, + classGenActivityInjectorDeps1, + classGenComponentTreeDeps, + classGenHiltComponents, + classGenDaggerHiltApplicationComponent + ) + } assertChangedFiles(FileType.CLASS, recompiledClassFiles) } @@ -592,13 +612,15 @@ class IncrementalProcessorTest(private val incapMode: String) { // Change Module 1 source searchAndReplace( - srcModule1, "// Insert-change", + srcModule1, + "// Insert-change", """ @Provides static double provideDouble() { return 10.10; } - """.trimIndent() + """ + .trimIndent() ) val result = runIncrementalBuild() @@ -606,58 +628,61 @@ class IncrementalProcessorTest(private val incapMode: String) { // Check annotation processing outputs // * Only module 1 sources are re-generated, isolation from other modules - val regeneratedSourceFiles = if (incapMode == ISOLATING_MODE) { - // * Aggregating task did not run, no change in deps - expect.that(result.task(aggregatingTaskName)!!.outcome).isEqualTo(TaskOutcome.UP_TO_DATE) - // * Components are re-generated due to a recompilation of a dep - listOf( - genHiltApp, // Re-generated because components got re-generated - genModuleDeps1, - genHiltComponents, - genDaggerHiltApplicationComponent - ) - } else { - // * Root classes along with components are always re-generated (aggregated processor) - listOf( - genHiltApp, - genAppInjector, - genAppInjectorDeps, - genModuleDeps1, - genComponentTreeDeps, - genHiltComponents, - genDaggerHiltApplicationComponent - ) - } + val regeneratedSourceFiles = + if (incapMode == ISOLATING_MODE) { + // * Aggregating task did not run, no change in deps + expect.that(result.task(aggregatingTaskName)!!.outcome).isEqualTo(TaskOutcome.UP_TO_DATE) + // * Components are re-generated due to a recompilation of a dep + listOf( + genHiltApp, // Re-generated because components got re-generated + genModuleDeps1, + genHiltComponents, + genDaggerHiltApplicationComponent + ) + } else { + // * Root classes along with components are always re-generated (aggregated processor) + listOf( + genHiltApp, + genAppInjector, + genAppInjectorDeps, + genModuleDeps1, + genComponentTreeDeps, + genHiltComponents, + genDaggerHiltApplicationComponent + ) + } assertChangedFiles(FileType.JAVA, regeneratedSourceFiles) val componentTreeDepsIncrementalBuild = genComponentTreeDeps.readText(Charsets.UTF_8) - expect.withMessage("Full build") - .that(componentTreeDepsFullBuild) - .isEqualTo(componentTreeDepsIncrementalBuild) + expect + .withMessage("Full build") + .that(componentTreeDepsFullBuild) + .isEqualTo(componentTreeDepsIncrementalBuild) // Check compilation outputs // * Gen sources from module 1 are re-compiled - val recompiledClassFiles = if (incapMode == ISOLATING_MODE) { - listOf( - classSrcModule1, - classGenHiltApp, - classGenModuleDeps1, - classGenHiltComponents, - classGenDaggerHiltApplicationComponent - ) - } else { - // * All aggregating processor gen sources are re-compiled - listOf( - classSrcModule1, - classGenHiltApp, - classGenAppInjector, - classGenAppInjectorDeps, - classGenModuleDeps1, - classGenComponentTreeDeps, - classGenHiltComponents, - classGenDaggerHiltApplicationComponent - ) - } + val recompiledClassFiles = + if (incapMode == ISOLATING_MODE) { + listOf( + classSrcModule1, + classGenHiltApp, + classGenModuleDeps1, + classGenHiltComponents, + classGenDaggerHiltApplicationComponent + ) + } else { + // * All aggregating processor gen sources are re-compiled + listOf( + classSrcModule1, + classGenHiltApp, + classGenAppInjector, + classGenAppInjectorDeps, + classGenModuleDeps1, + classGenComponentTreeDeps, + classGenHiltComponents, + classGenDaggerHiltApplicationComponent + ) + } assertChangedFiles(FileType.CLASS, recompiledClassFiles) } @@ -668,13 +693,15 @@ class IncrementalProcessorTest(private val incapMode: String) { // Change Application source searchAndReplace( - srcApp, "// Insert-change", + srcApp, + "// Insert-change", """ @Override public void onCreate() { super.onCreate(); } - """.trimIndent() + """ + .trimIndent() ) val result = runIncrementalBuild() @@ -682,57 +709,60 @@ class IncrementalProcessorTest(private val incapMode: String) { // Check annotation processing outputs // * No modules or activities (or any other non-root) classes should be generated - val regeneratedSourceFiles = if (incapMode == ISOLATING_MODE) { - // * Aggregating task did not run, no change in deps - expect.that(result.task(aggregatingTaskName)!!.outcome).isEqualTo(TaskOutcome.UP_TO_DATE) - // * Components are re-generated due to a recompilation of a dep - listOf( - genHiltApp, // Re-generated because components got re-generated - genAppInjector, - genAppInjectorDeps, - genHiltComponents, - genDaggerHiltApplicationComponent - ) - } else { - // * Root classes along with components are always re-generated (aggregated processor) - listOf( - genHiltApp, - genAppInjector, - genAppInjectorDeps, - genComponentTreeDeps, - genHiltComponents, - genDaggerHiltApplicationComponent - ) - } + val regeneratedSourceFiles = + if (incapMode == ISOLATING_MODE) { + // * Aggregating task did not run, no change in deps + expect.that(result.task(aggregatingTaskName)!!.outcome).isEqualTo(TaskOutcome.UP_TO_DATE) + // * Components are re-generated due to a recompilation of a dep + listOf( + genHiltApp, // Re-generated because components got re-generated + genAppInjector, + genAppInjectorDeps, + genHiltComponents, + genDaggerHiltApplicationComponent + ) + } else { + // * Root classes along with components are always re-generated (aggregated processor) + listOf( + genHiltApp, + genAppInjector, + genAppInjectorDeps, + genComponentTreeDeps, + genHiltComponents, + genDaggerHiltApplicationComponent + ) + } assertChangedFiles(FileType.JAVA, regeneratedSourceFiles) val componentTreeDepsIncrementalBuild = genComponentTreeDeps.readText(Charsets.UTF_8) - expect.withMessage("Full build") - .that(componentTreeDepsFullBuild) - .isEqualTo(componentTreeDepsIncrementalBuild) + expect + .withMessage("Full build") + .that(componentTreeDepsFullBuild) + .isEqualTo(componentTreeDepsIncrementalBuild) // Check compilation outputs - val recompiledClassFiles = if (incapMode == ISOLATING_MODE) { - listOf( - classSrcApp, - classGenHiltApp, - classGenAppInjector, - classGenAppInjectorDeps, - classGenHiltComponents, - classGenDaggerHiltApplicationComponent - ) - } else { - // * All aggregating processor gen sources are re-compiled - listOf( - classSrcApp, - classGenHiltApp, - classGenAppInjector, - classGenAppInjectorDeps, - classGenComponentTreeDeps, - classGenHiltComponents, - classGenDaggerHiltApplicationComponent - ) - } + val recompiledClassFiles = + if (incapMode == ISOLATING_MODE) { + listOf( + classSrcApp, + classGenHiltApp, + classGenAppInjector, + classGenAppInjectorDeps, + classGenHiltComponents, + classGenDaggerHiltApplicationComponent + ) + } else { + // * All aggregating processor gen sources are re-compiled + listOf( + classSrcApp, + classGenHiltApp, + classGenAppInjector, + classGenAppInjectorDeps, + classGenComponentTreeDeps, + classGenHiltComponents, + classGenDaggerHiltApplicationComponent + ) + } assertChangedFiles(FileType.CLASS, recompiledClassFiles) } @@ -749,33 +779,28 @@ class IncrementalProcessorTest(private val incapMode: String) { // * All related gen classes from activity 2 should be deleted // * Unrelated activities and modules are in isolation and should be unchanged // * Root classes along with components are always re-generated (aggregated processor) - assertDeletedFiles( - listOf( - genHiltActivity2, - genActivityInjector2, - genActivityInjectorDeps2 - ) - ) - val regeneratedSourceFiles = if (incapMode == ISOLATING_MODE) { - // * Aggregating task ran due to a change in dep - expect.that(result.task(aggregatingTaskName)!!.outcome).isEqualTo(TaskOutcome.SUCCESS) - // * Components are re-generated since there was a change in dep - listOf( - genHiltApp, // Re-generated because components got re-generated - genComponentTreeDeps, - genHiltComponents, - genDaggerHiltApplicationComponent - ) - } else { - listOf( - genHiltApp, - genAppInjector, - genAppInjectorDeps, - genComponentTreeDeps, - genHiltComponents, - genDaggerHiltApplicationComponent - ) - } + assertDeletedFiles(listOf(genHiltActivity2, genActivityInjector2, genActivityInjectorDeps2)) + val regeneratedSourceFiles = + if (incapMode == ISOLATING_MODE) { + // * Aggregating task ran due to a change in dep + expect.that(result.task(aggregatingTaskName)!!.outcome).isEqualTo(TaskOutcome.SUCCESS) + // * Components are re-generated since there was a change in dep + listOf( + genHiltApp, // Re-generated because components got re-generated + genComponentTreeDeps, + genHiltComponents, + genDaggerHiltApplicationComponent + ) + } else { + listOf( + genHiltApp, + genAppInjector, + genAppInjectorDeps, + genComponentTreeDeps, + genHiltComponents, + genDaggerHiltApplicationComponent + ) + } assertChangedFiles(FileType.JAVA, regeneratedSourceFiles) // Check compilation outputs @@ -789,23 +814,24 @@ class IncrementalProcessorTest(private val incapMode: String) { classGenActivityInjectorDeps2 ) ) - val recompiledClassFiles = if (incapMode == ISOLATING_MODE) { - listOf( - classGenHiltApp, - classGenComponentTreeDeps, - classGenHiltComponents, - classGenDaggerHiltApplicationComponent - ) - } else { - listOf( - classGenHiltApp, - classGenAppInjector, - classGenAppInjectorDeps, - classGenComponentTreeDeps, - classGenHiltComponents, - classGenDaggerHiltApplicationComponent - ) - } + val recompiledClassFiles = + if (incapMode == ISOLATING_MODE) { + listOf( + classGenHiltApp, + classGenComponentTreeDeps, + classGenHiltComponents, + classGenDaggerHiltApplicationComponent + ) + } else { + listOf( + classGenHiltApp, + classGenAppInjector, + classGenAppInjectorDeps, + classGenComponentTreeDeps, + classGenHiltComponents, + classGenDaggerHiltApplicationComponent + ) + } assertChangedFiles(FileType.CLASS, recompiledClassFiles) } @@ -822,58 +848,53 @@ class IncrementalProcessorTest(private val incapMode: String) { // * All related gen classes from module 2 should be deleted // * Unrelated activities and modules are in isolation and should be unchanged - assertDeletedFiles( - listOf(genModuleDeps2) - ) - val regeneratedSourceFiles = if (incapMode == ISOLATING_MODE) { - // * Aggregating task ran due to a change in dep - expect.that(result.task(aggregatingTaskName)!!.outcome).isEqualTo(TaskOutcome.SUCCESS) - // * Components are re-generated since there was a change in dep - listOf( - genHiltApp, // Re-generated because components got re-generated - genComponentTreeDeps, - genHiltComponents, - genDaggerHiltApplicationComponent - ) - } else { - // * Root classes along with components are always re-generated (aggregated processor) - listOf( - genHiltApp, - genAppInjector, - genAppInjectorDeps, - genComponentTreeDeps, - genHiltComponents, - genDaggerHiltApplicationComponent - ) - } + assertDeletedFiles(listOf(genModuleDeps2)) + val regeneratedSourceFiles = + if (incapMode == ISOLATING_MODE) { + // * Aggregating task ran due to a change in dep + expect.that(result.task(aggregatingTaskName)!!.outcome).isEqualTo(TaskOutcome.SUCCESS) + // * Components are re-generated since there was a change in dep + listOf( + genHiltApp, // Re-generated because components got re-generated + genComponentTreeDeps, + genHiltComponents, + genDaggerHiltApplicationComponent + ) + } else { + // * Root classes along with components are always re-generated (aggregated processor) + listOf( + genHiltApp, + genAppInjector, + genAppInjectorDeps, + genComponentTreeDeps, + genHiltComponents, + genDaggerHiltApplicationComponent + ) + } assertChangedFiles(FileType.JAVA, regeneratedSourceFiles) // Check compilation outputs // * All compiled classes from module 2 should be deleted // * Unrelated activities and modules are in isolation and should be unchanged - assertDeletedFiles( - listOf( - classSrcModule2, - classGenModuleDeps2 - ) - ) - val recompiledClassFiles = if (incapMode == ISOLATING_MODE) { - listOf( - classGenHiltApp, - classGenComponentTreeDeps, - classGenHiltComponents, - classGenDaggerHiltApplicationComponent - ) - } else { - listOf( - classGenHiltApp, - classGenAppInjector, - classGenAppInjectorDeps, - classGenComponentTreeDeps, - classGenHiltComponents, - classGenDaggerHiltApplicationComponent - ) - } + assertDeletedFiles(listOf(classSrcModule2, classGenModuleDeps2)) + val recompiledClassFiles = + if (incapMode == ISOLATING_MODE) { + listOf( + classGenHiltApp, + classGenComponentTreeDeps, + classGenHiltComponents, + classGenDaggerHiltApplicationComponent + ) + } else { + listOf( + classGenHiltApp, + classGenAppInjector, + classGenAppInjectorDeps, + classGenComponentTreeDeps, + classGenHiltComponents, + classGenDaggerHiltApplicationComponent + ) + } assertChangedFiles(FileType.CLASS, recompiledClassFiles) } @@ -887,48 +908,52 @@ class IncrementalProcessorTest(private val incapMode: String) { package simple; public class Foo { } - """.trimIndent() + """ + .trimIndent() ) val result = runIncrementalBuild() - val expectedOutcome = if (incapMode == ISOLATING_MODE) { - // In isolating mode, component compile task does not re-compile. - TaskOutcome.UP_TO_DATE - } else { - TaskOutcome.SUCCESS - } + val expectedOutcome = + if (incapMode == ISOLATING_MODE) { + // In isolating mode, component compile task does not re-compile. + TaskOutcome.UP_TO_DATE + } else { + TaskOutcome.SUCCESS + } expect.that(result.task(compileTaskName)!!.outcome).isEqualTo(expectedOutcome) - val regeneratedSourceFiles = if (incapMode == ISOLATING_MODE) { - // * Aggregating task did not run, no change in deps - expect.that(result.task(aggregatingTaskName)!!.outcome).isEqualTo(TaskOutcome.UP_TO_DATE) - // * Non-DI related source causes no files to be generated - emptyList() - } else { - // * Root classes are always re-generated (aggregated processor) - listOf( - genHiltApp, - genAppInjector, - genAppInjectorDeps, - genComponentTreeDeps, - genHiltComponents, - genDaggerHiltApplicationComponent - ) - } + val regeneratedSourceFiles = + if (incapMode == ISOLATING_MODE) { + // * Aggregating task did not run, no change in deps + expect.that(result.task(aggregatingTaskName)!!.outcome).isEqualTo(TaskOutcome.UP_TO_DATE) + // * Non-DI related source causes no files to be generated + emptyList() + } else { + // * Root classes are always re-generated (aggregated processor) + listOf( + genHiltApp, + genAppInjector, + genAppInjectorDeps, + genComponentTreeDeps, + genHiltComponents, + genDaggerHiltApplicationComponent + ) + } assertChangedFiles(FileType.JAVA, regeneratedSourceFiles) - val recompiledClassFiles = if (incapMode == ISOLATING_MODE) { - emptyList() - } else { - listOf( - classGenHiltApp, - classGenAppInjector, - classGenAppInjectorDeps, - classGenComponentTreeDeps, - classGenHiltComponents, - classGenDaggerHiltApplicationComponent - ) - } + val recompiledClassFiles = + if (incapMode == ISOLATING_MODE) { + emptyList() + } else { + listOf( + classGenHiltApp, + classGenAppInjector, + classGenAppInjectorDeps, + classGenComponentTreeDeps, + classGenHiltComponents, + classGenDaggerHiltApplicationComponent + ) + } assertChangedFiles(FileType.CLASS, recompiledClassFiles) } @@ -970,11 +995,13 @@ class IncrementalProcessorTest(private val incapMode: String) { // Change Test 1 source searchAndReplace( - srcTest1, "// Insert-change", + srcTest1, + "// Insert-change", """ @Test public void newTest() { } - """.trimIndent() + """ + .trimIndent() ) val result = runIncrementalTestBuild() @@ -983,49 +1010,53 @@ class IncrementalProcessorTest(private val incapMode: String) { // Check annotation processing outputs // * Unrelated test components should be unchanged - val regeneratedSourceFiles = if (incapMode == ISOLATING_MODE) { - listOf( - genTest1HiltComponents, - genTest1DaggerHiltApplicationComponent, - ) - } else { - listOf( - genTest1ComponentTreeDeps, - genTest2ComponentTreeDeps, - genTest1HiltComponents, - genTest2HiltComponents, - genTest1DaggerHiltApplicationComponent, - genTest2DaggerHiltApplicationComponent, - ) - } + val regeneratedSourceFiles = + if (incapMode == ISOLATING_MODE) { + listOf( + genTest1HiltComponents, + genTest1DaggerHiltApplicationComponent, + ) + } else { + listOf( + genTest1ComponentTreeDeps, + genTest2ComponentTreeDeps, + genTest1HiltComponents, + genTest2HiltComponents, + genTest1DaggerHiltApplicationComponent, + genTest2DaggerHiltApplicationComponent, + ) + } assertChangedFiles(FileType.JAVA, regeneratedSourceFiles) val test1ComponentTreeDepsIncrementalBuild = genTest1ComponentTreeDeps.readText(Charsets.UTF_8) val test2ComponentTreeDepsIncrementalBuild = genTest2ComponentTreeDeps.readText(Charsets.UTF_8) - expect.withMessage("Full build") - .that(test1ComponentTreeDepsFullBuild) - .isEqualTo(test1ComponentTreeDepsIncrementalBuild) - expect.withMessage("Full build") - .that(test2ComponentTreeDepsFullBuild) - .isEqualTo(test2ComponentTreeDepsIncrementalBuild) - - val recompiledClassFiles = if (incapMode == ISOLATING_MODE) { - listOf( - classSrcTest1, - classGenTest1HiltComponents, - classGenTest1DaggerHiltApplicationComponent, - ) - } else { - listOf( - classSrcTest1, - classGenTest1ComponentTreeDeps, - classGenTest2ComponentTreeDeps, - classGenTest1HiltComponents, - classGenTest2HiltComponents, - classGenTest1DaggerHiltApplicationComponent, - classGenTest2DaggerHiltApplicationComponent, - ) - } + expect + .withMessage("Full build") + .that(test1ComponentTreeDepsFullBuild) + .isEqualTo(test1ComponentTreeDepsIncrementalBuild) + expect + .withMessage("Full build") + .that(test2ComponentTreeDepsFullBuild) + .isEqualTo(test2ComponentTreeDepsIncrementalBuild) + + val recompiledClassFiles = + if (incapMode == ISOLATING_MODE) { + listOf( + classSrcTest1, + classGenTest1HiltComponents, + classGenTest1DaggerHiltApplicationComponent, + ) + } else { + listOf( + classSrcTest1, + classGenTest1ComponentTreeDeps, + classGenTest2ComponentTreeDeps, + classGenTest1HiltComponents, + classGenTest2HiltComponents, + classGenTest1DaggerHiltApplicationComponent, + classGenTest2DaggerHiltApplicationComponent, + ) + } assertChangedFiles(FileType.CLASS, recompiledClassFiles) } @@ -1037,60 +1068,67 @@ class IncrementalProcessorTest(private val incapMode: String) { // Change Test 1 source searchAndReplace( - srcTest1, "// Insert-change", + srcTest1, + "// Insert-change", """ private void newMethod() { } - """.trimIndent() + """ + .trimIndent() ) val result = runIncrementalTestBuild() - val expectedOutcome = if (incapMode == ISOLATING_MODE) { - // In isolating mode, changes that do not affect ABI will not cause re-compilation. - TaskOutcome.UP_TO_DATE - } else { - TaskOutcome.SUCCESS - } + val expectedOutcome = + if (incapMode == ISOLATING_MODE) { + // In isolating mode, changes that do not affect ABI will not cause re-compilation. + TaskOutcome.UP_TO_DATE + } else { + TaskOutcome.SUCCESS + } expect.that(result.task(testCompileTaskName)!!.outcome).isEqualTo(expectedOutcome) // Check annotation processing outputs // * Unrelated test components should be unchanged - val regeneratedSourceFiles = if (incapMode == ISOLATING_MODE) { - emptyList() - } else { - listOf( - genTest1ComponentTreeDeps, - genTest2ComponentTreeDeps, - genTest1HiltComponents, - genTest2HiltComponents, - genTest1DaggerHiltApplicationComponent, - genTest2DaggerHiltApplicationComponent, - ) - } + val regeneratedSourceFiles = + if (incapMode == ISOLATING_MODE) { + emptyList() + } else { + listOf( + genTest1ComponentTreeDeps, + genTest2ComponentTreeDeps, + genTest1HiltComponents, + genTest2HiltComponents, + genTest1DaggerHiltApplicationComponent, + genTest2DaggerHiltApplicationComponent, + ) + } assertChangedFiles(FileType.JAVA, regeneratedSourceFiles) val test1ComponentTreeDepsIncrementalBuild = genTest1ComponentTreeDeps.readText(Charsets.UTF_8) val test2ComponentTreeDepsIncrementalBuild = genTest2ComponentTreeDeps.readText(Charsets.UTF_8) - expect.withMessage("Full build") - .that(test1ComponentTreeDepsFullBuild) - .isEqualTo(test1ComponentTreeDepsIncrementalBuild) - expect.withMessage("Full build") - .that(test2ComponentTreeDepsFullBuild) - .isEqualTo(test2ComponentTreeDepsIncrementalBuild) - - val recompiledClassFiles = if (incapMode == ISOLATING_MODE) { - listOf(classSrcTest1) - } else { - listOf( - classSrcTest1, - classGenTest1ComponentTreeDeps, - classGenTest2ComponentTreeDeps, - classGenTest1HiltComponents, - classGenTest2HiltComponents, - classGenTest1DaggerHiltApplicationComponent, - classGenTest2DaggerHiltApplicationComponent, - ) - } + expect + .withMessage("Full build") + .that(test1ComponentTreeDepsFullBuild) + .isEqualTo(test1ComponentTreeDepsIncrementalBuild) + expect + .withMessage("Full build") + .that(test2ComponentTreeDepsFullBuild) + .isEqualTo(test2ComponentTreeDepsIncrementalBuild) + + val recompiledClassFiles = + if (incapMode == ISOLATING_MODE) { + listOf(classSrcTest1) + } else { + listOf( + classSrcTest1, + classGenTest1ComponentTreeDeps, + classGenTest2ComponentTreeDeps, + classGenTest1HiltComponents, + classGenTest2HiltComponents, + classGenTest1DaggerHiltApplicationComponent, + classGenTest2DaggerHiltApplicationComponent, + ) + } assertChangedFiles(FileType.CLASS, recompiledClassFiles) } @@ -1129,83 +1167,93 @@ class IncrementalProcessorTest(private val incapMode: String) { } private fun recordTimestamps() { - val files = listOf( - genHiltApp, - genHiltActivity1, - genHiltActivity2, - genAppInjector, - genActivityInjector1, - genActivityInjector2, - genAppInjectorDeps, - genActivityInjectorDeps1, - genActivityInjectorDeps2, - genModuleDeps1, - genModuleDeps2, - genComponentTreeDeps, - genHiltComponents, - genDaggerHiltApplicationComponent, - genTest1ComponentTreeDeps, - genTest2ComponentTreeDeps, - genTest1HiltComponents, - genTest2HiltComponents, - genTest1DaggerHiltApplicationComponent, - genTest2DaggerHiltApplicationComponent, - classSrcApp, - classSrcActivity1, - classSrcActivity2, - classSrcModule1, - classSrcModule2, - classSrcTest1, - classSrcTest2, - classGenHiltApp, - classGenHiltActivity1, - classGenHiltActivity2, - classGenAppInjector, - classGenActivityInjector1, - classGenActivityInjector2, - classGenAppInjectorDeps, - classGenActivityInjectorDeps1, - classGenActivityInjectorDeps2, - classGenModuleDeps1, - classGenModuleDeps2, - classGenComponentTreeDeps, - classGenHiltComponents, - classGenDaggerHiltApplicationComponent, - classGenTest1ComponentTreeDeps, - classGenTest2ComponentTreeDeps, - classGenTest1HiltComponents, - classGenTest2HiltComponents, - classGenTest1DaggerHiltApplicationComponent, - classGenTest2DaggerHiltApplicationComponent, - ) + val files = + listOf( + genHiltApp, + genHiltActivity1, + genHiltActivity2, + genAppInjector, + genActivityInjector1, + genActivityInjector2, + genAppInjectorDeps, + genActivityInjectorDeps1, + genActivityInjectorDeps2, + genModuleDeps1, + genModuleDeps2, + genComponentTreeDeps, + genHiltComponents, + genDaggerHiltApplicationComponent, + genTest1ComponentTreeDeps, + genTest2ComponentTreeDeps, + genTest1HiltComponents, + genTest2HiltComponents, + genTest1DaggerHiltApplicationComponent, + genTest2DaggerHiltApplicationComponent, + classSrcApp, + classSrcActivity1, + classSrcActivity2, + classSrcModule1, + classSrcModule2, + classSrcTest1, + classSrcTest2, + classGenHiltApp, + classGenHiltActivity1, + classGenHiltActivity2, + classGenAppInjector, + classGenActivityInjector1, + classGenActivityInjector2, + classGenAppInjectorDeps, + classGenActivityInjectorDeps1, + classGenActivityInjectorDeps2, + classGenModuleDeps1, + classGenModuleDeps2, + classGenComponentTreeDeps, + classGenHiltComponents, + classGenDaggerHiltApplicationComponent, + classGenTest1ComponentTreeDeps, + classGenTest2ComponentTreeDeps, + classGenTest1HiltComponents, + classGenTest2HiltComponents, + classGenTest1DaggerHiltApplicationComponent, + classGenTest2DaggerHiltApplicationComponent, + ) - fileToTimestampMap = mutableMapOf<File, Long>().apply { - for (file in files) { - this[file] = file.lastModified() + fileToTimestampMap = + mutableMapOf<File, Long>().apply { + for (file in files) { + this[file] = file.lastModified() + } } - } } private fun recordFileChanges() { - changedFiles = fileToTimestampMap.filter { (file, previousTimestamp) -> - file.exists() && file.lastModified() != previousTimestamp - }.keys + changedFiles = + fileToTimestampMap + .filter { (file, previousTimestamp) -> + file.exists() && file.lastModified() != previousTimestamp + } + .keys - unchangedFiles = fileToTimestampMap.filter { (file, previousTimestamp) -> - file.exists() && file.lastModified() == previousTimestamp - }.keys + unchangedFiles = + fileToTimestampMap + .filter { (file, previousTimestamp) -> + file.exists() && file.lastModified() == previousTimestamp + } + .keys deletedFiles = fileToTimestampMap.filter { (file, _) -> !file.exists() }.keys } private fun assertFilesExist(files: Collection<File>) { - expect.withMessage("Existing files") + expect + .withMessage("Existing files") .that(files.filter { it.exists() }) .containsExactlyElementsIn(files) } private fun assertChangedFiles(type: FileType, files: Collection<File>) { - expect.withMessage("Changed files") + expect + .withMessage("Changed files") .that(changedFiles.filter { it.name.endsWith(type.extension) }) .containsExactlyElementsIn(files) } @@ -1227,10 +1275,7 @@ class IncrementalProcessorTest(private val incapMode: String) { @JvmStatic @Parameterized.Parameters(name = "{0}") - fun parameters() = listOf( - ISOLATING_MODE, - AGGREGATING_MODE - ) + fun parameters() = listOf(ISOLATING_MODE, AGGREGATING_MODE) private const val ISOLATING_MODE = "isolating" private const val AGGREGATING_MODE = "aggregating" diff --git a/java/dagger/hilt/android/plugin/settings.gradle b/java/dagger/hilt/android/plugin/settings.gradle index 55724bf48..778bf22e4 100644 --- a/java/dagger/hilt/android/plugin/settings.gradle +++ b/java/dagger/hilt/android/plugin/settings.gradle @@ -21,3 +21,4 @@ include ':agp-wrapper-impl' include ':agp-wrapper-7-0' include ':agp-wrapper-7-1' include ':agp-wrapper-7-2' + diff --git a/java/dagger/hilt/android/processor/BUILD b/java/dagger/hilt/android/processor/BUILD index 6f45216f1..bf5a6c3b5 100644 --- a/java/dagger/hilt/android/processor/BUILD +++ b/java/dagger/hilt/android/processor/BUILD @@ -52,6 +52,7 @@ gen_maven_artifact( "//java/dagger/hilt/processor/internal:component_names", "//java/dagger/hilt/processor/internal:components", "//java/dagger/hilt/processor/internal:hilt_processing_env_configs", + "//java/dagger/hilt/processor/internal:method_signature", "//java/dagger/hilt/processor/internal:processor_errors", "//java/dagger/hilt/processor/internal:processors", "//java/dagger/hilt/processor/internal/aggregateddeps:component_dependencies", diff --git a/java/dagger/hilt/android/processor/internal/AndroidClassNames.java b/java/dagger/hilt/android/processor/internal/AndroidClassNames.java index 2d954481a..e37c6b7bd 100644 --- a/java/dagger/hilt/android/processor/internal/AndroidClassNames.java +++ b/java/dagger/hilt/android/processor/internal/AndroidClassNames.java @@ -99,6 +99,10 @@ public final class AndroidClassNames { get("dagger.hilt.android.internal.managers", "ServiceComponentManager"); public static final ClassName VIEW_COMPONENT_MANAGER = get("dagger.hilt.android.internal.managers", "ViewComponentManager"); + public static final ClassName SAVED_STATE_HANDLE_ENTRY_POINTS = + get("dagger.hilt.android.internal.managers", "SavedStateHandleEntryPoints"); + public static final ClassName SAVED_STATE_HANDLE_HOLDER = + get("dagger.hilt.android.internal.managers", "SavedStateHandleHolder"); public static final ClassName HAS_CUSTOM_INJECT = get("dagger.hilt.android.internal.migration", "HasCustomInject"); @@ -114,6 +118,10 @@ public final class AndroidClassNames { get("dagger.hilt.android.lifecycle", "HiltViewModel"); public static final ClassName HILT_VIEW_MODEL_MAP_QUALIFIER = get("dagger.hilt.android.internal.lifecycle", "HiltViewModelMap"); + + public static final ClassName HILT_VIEW_MODEL_ASSISTED_FACTORY_MAP_QUALIFIER = + get("dagger.hilt.android.internal.lifecycle", "HiltViewModelAssistedMap"); + public static final ClassName HILT_VIEW_MODEL_KEYS_QUALIFIER = get("dagger.hilt.android.internal.lifecycle", "HiltViewModelMap", "KeySet"); public static final ClassName VIEW_MODEL = get("androidx.lifecycle", "ViewModel"); @@ -121,9 +129,13 @@ public final class AndroidClassNames { get("androidx.lifecycle", "ViewModelProvider", "Factory"); public static final ClassName SAVED_STATE_HANDLE = get("androidx.lifecycle", "SavedStateHandle"); - + public static final ClassName DEFAULT_LIFECYCLE_OBSERVER = + get("androidx.lifecycle", "DefaultLifecycleObserver"); + public static final ClassName LIFECYCLE_OWNER = get("androidx.lifecycle", "LifecycleOwner"); public static final ClassName ON_CONTEXT_AVAILABLE_LISTENER = get("androidx.activity.contextaware", "OnContextAvailableListener"); + public static final ClassName UI_THREAD = get("androidx.annotation", "UiThread"); + public static final ClassName INJECT_VIA_ON_CONTEXT_AVAILABLE_LISTENER = get("dagger.hilt.android", "InjectViaOnContextAvailableListener"); diff --git a/java/dagger/hilt/android/processor/internal/androidentrypoint/ActivityGenerator.java b/java/dagger/hilt/android/processor/internal/androidentrypoint/ActivityGenerator.java index 49f439ec9..e1bf74f50 100644 --- a/java/dagger/hilt/android/processor/internal/androidentrypoint/ActivityGenerator.java +++ b/java/dagger/hilt/android/processor/internal/androidentrypoint/ActivityGenerator.java @@ -16,22 +16,58 @@ package dagger.hilt.android.processor.internal.androidentrypoint; +import static com.google.common.base.Preconditions.checkState; +import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; +import static kotlin.streams.jdk8.StreamsKt.asStream; + import androidx.room.compiler.processing.JavaPoetExtKt; +import androidx.room.compiler.processing.XAnnotated; +import androidx.room.compiler.processing.XExecutableParameterElement; import androidx.room.compiler.processing.XFiler; +import androidx.room.compiler.processing.XMethodElement; import androidx.room.compiler.processing.XProcessingEnv; import androidx.room.compiler.processing.XTypeParameterElement; +import com.google.common.base.CaseFormat; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.CodeBlock; +import com.squareup.javapoet.FieldSpec; import com.squareup.javapoet.JavaFile; import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.ParameterSpec; +import com.squareup.javapoet.TypeName; import com.squareup.javapoet.TypeSpec; import dagger.hilt.android.processor.internal.AndroidClassNames; +import dagger.hilt.processor.internal.ClassNames; +import dagger.hilt.processor.internal.MethodSignature; import dagger.hilt.processor.internal.Processors; +import dagger.internal.codegen.xprocessing.XElements; import java.io.IOException; import javax.lang.model.element.Modifier; +import javax.tools.Diagnostic; /** Generates an Hilt Activity class for the @AndroidEntryPoint annotated class. */ public final class ActivityGenerator { + private enum ActivityMethod { + ON_CREATE(AndroidClassNames.BUNDLE), + ON_STOP(), + ON_DESTROY(); + + @SuppressWarnings("ImmutableEnumChecker") + private final MethodSignature signature; + + ActivityMethod(TypeName... parameterTypes) { + String methodName = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, name()); + this.signature = MethodSignature.of(methodName, parameterTypes); + } + } + + private static final FieldSpec SAVED_STATE_HANDLE_HOLDER_FIELD = + FieldSpec.builder(AndroidClassNames.SAVED_STATE_HANDLE_HOLDER, "savedStateHandleHolder") + .addModifiers(Modifier.PRIVATE) + .build(); + private final XProcessingEnv env; private final AndroidEntryPointMetadata metadata; private final ClassName generatedClassName; @@ -61,6 +97,13 @@ public final class ActivityGenerator { CodeBlock.builder().addStatement("_initHiltInternal()").build(), builder); builder.addMethod(init()); + if (!metadata.overridesAndroidEntryPointClass()) { + builder + .addField(SAVED_STATE_HANDLE_HOLDER_FIELD) + .addMethod(initSavedStateHandleHolderMethod()) + .addMethod(onCreateComponentActivity()) + .addMethod(onDestroyComponentActivity()); + } metadata.baseElement().getTypeParameters().stream() .map(XTypeParameterElement::getTypeVariableName) @@ -133,4 +176,119 @@ public final class ActivityGenerator { AndroidClassNames.DEFAULT_VIEW_MODEL_FACTORIES) .build(); } + + // @Override + // public void onCreate(Bundle bundle) { + // super.onCreate(savedInstanceState); + // initSavedStateHandleHolder(); + // } + // + private MethodSpec onCreateComponentActivity() { + XMethodElement nearestOverrideMethod = + requireNearestOverrideMethod(ActivityMethod.ON_CREATE, metadata); + if (nearestOverrideMethod.isFinal()) { + env.getMessager() + .printMessage( + Diagnostic.Kind.ERROR, + "Do not mark onCreate as final in base Activity class, as Hilt needs to override it" + + " to inject SavedStateHandle.", + nearestOverrideMethod); + } + ParameterSpec.Builder parameterBuilder = + ParameterSpec.builder(AndroidClassNames.BUNDLE, "savedInstanceState"); + MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder("onCreate"); + // If the sub class is overriding onCreate with @Nullable parameter, then this generated + // method will also prefix the parameter with @Nullable. + if (isNullable(nearestOverrideMethod.getParameters().get(0))) { + parameterBuilder.addAnnotation(AndroidClassNames.NULLABLE); + } + if (nearestOverrideMethod.hasAnnotation(AndroidClassNames.UI_THREAD)) { + methodBuilder.addAnnotation(AndroidClassNames.UI_THREAD); + } + return methodBuilder + .addAnnotation(AndroidClassNames.CALL_SUPER) + .addAnnotation(Override.class) + .addModifiers(XElements.getModifiers(nearestOverrideMethod)) + .addParameter(parameterBuilder.build()) + .addStatement("super.onCreate(savedInstanceState)") + .addStatement("initSavedStateHandleHolder()") + .build(); + } + + // private void initSavedStateHandleHolder() { + // savedStateHandleHolder = componentManager().getSavedStateHandleHolder(); + // if (savedStateHandleHolder.isInvalid()) { + // savedStateHandleHolder.setExtras(getDefaultViewModelCreationExtras()); + // } + // } + private static MethodSpec initSavedStateHandleHolderMethod() { + return MethodSpec.methodBuilder("initSavedStateHandleHolder") + .addModifiers(Modifier.PRIVATE) + .beginControlFlow( + "if (getApplication() instanceof $T)", ClassNames.GENERATED_COMPONENT_MANAGER) + .addStatement( + "$N = componentManager().getSavedStateHandleHolder()", SAVED_STATE_HANDLE_HOLDER_FIELD) + .beginControlFlow("if ($N.isInvalid())", SAVED_STATE_HANDLE_HOLDER_FIELD) + .addStatement( + "$N.setExtras(getDefaultViewModelCreationExtras())", SAVED_STATE_HANDLE_HOLDER_FIELD) + .endControlFlow() + .endControlFlow() + .build(); + } + + private static boolean isNullable(XExecutableParameterElement element) { + return hasNullableAnnotation(element) || hasNullableAnnotation(element.getType()); + } + + private static boolean hasNullableAnnotation(XAnnotated element) { + return element.getAllAnnotations().stream() + .anyMatch(annotation -> annotation.getClassName().simpleName().equals("Nullable")); + } + + // @Override + // public void onDestroy() { + // super.onDestroy(); + // if (savedStateHandleHolder != null) { + // savedStateHandleHolder.clear(); + // } + // } + private MethodSpec onDestroyComponentActivity() { + XMethodElement nearestOverrideMethod = + requireNearestOverrideMethod(ActivityMethod.ON_DESTROY, metadata); + if (nearestOverrideMethod.isFinal()) { + env.getMessager() + .printMessage( + Diagnostic.Kind.ERROR, + "Do not mark onDestroy as final in base Activity class, as Hilt needs to override it" + + " to clean up SavedStateHandle.", + nearestOverrideMethod); + } + return MethodSpec.methodBuilder("onDestroy") + .addAnnotation(Override.class) + .addModifiers(XElements.getModifiers(nearestOverrideMethod)) + .addStatement("super.onDestroy()") + .beginControlFlow("if ($N != null)", SAVED_STATE_HANDLE_HOLDER_FIELD) + .addStatement("$N.clear()", SAVED_STATE_HANDLE_HOLDER_FIELD) + .endControlFlow() + .build(); + } + + private static XMethodElement requireNearestOverrideMethod( + ActivityMethod activityMethod, AndroidEntryPointMetadata metadata) { + XMethodElement methodOnAndroidEntryPointElement = + metadata.element().getDeclaredMethods().stream() + .filter(method -> MethodSignature.of(method).equals(activityMethod.signature)) + .findFirst() + .orElse(null); + if (methodOnAndroidEntryPointElement != null) { + return methodOnAndroidEntryPointElement; + } + + ImmutableList<XMethodElement> methodOnBaseElement = + asStream(metadata.baseElement().getAllMethods()) + .filter(method -> MethodSignature.of(method).equals(activityMethod.signature)) + .collect(toImmutableList()); + checkState(methodOnBaseElement.size() >= 1); + return Iterables.getLast(methodOnBaseElement); + } } diff --git a/java/dagger/hilt/android/processor/internal/androidentrypoint/AndroidEntryPointMetadata.java b/java/dagger/hilt/android/processor/internal/androidentrypoint/AndroidEntryPointMetadata.java index 6f925dace..71ad88eee 100644 --- a/java/dagger/hilt/android/processor/internal/androidentrypoint/AndroidEntryPointMetadata.java +++ b/java/dagger/hilt/android/processor/internal/androidentrypoint/AndroidEntryPointMetadata.java @@ -23,7 +23,6 @@ import static com.google.common.collect.Iterables.getOnlyElement; import static dagger.hilt.processor.internal.HiltCompilerOptions.isAndroidSuperClassValidationDisabled; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; import static dagger.internal.codegen.xprocessing.XElements.asTypeElement; -import static dagger.internal.codegen.xprocessing.XTypeElements.isKotlinSource; import static dagger.internal.codegen.xprocessing.XTypes.isDeclared; import androidx.room.compiler.processing.XAnnotation; @@ -159,7 +158,7 @@ public abstract class AndroidEntryPointMetadata { public Modifier[] generatedClassModifiers() { // Note XElement#isPublic() refers to the jvm visibility. Since "internal" visibility is // represented as public in the jvm, we have to check XElement#isInternal() explicitly. - return isKotlinSource(element()) && element().isPublic() && !element().isInternal() + return element().isFromKotlin() && element().isPublic() && !element().isInternal() ? new Modifier[] {Modifier.ABSTRACT, Modifier.PUBLIC} : new Modifier[] {Modifier.ABSTRACT}; } diff --git a/java/dagger/hilt/android/processor/internal/androidentrypoint/BUILD b/java/dagger/hilt/android/processor/internal/androidentrypoint/BUILD index 96beff3fd..327412b52 100644 --- a/java/dagger/hilt/android/processor/internal/androidentrypoint/BUILD +++ b/java/dagger/hilt/android/processor/internal/androidentrypoint/BUILD @@ -71,11 +71,11 @@ java_library( "//java/dagger/hilt/android/processor/internal:android_classnames", "//java/dagger/hilt/processor/internal:classnames", "//java/dagger/hilt/processor/internal:component_names", + "//java/dagger/hilt/processor/internal:method_signature", "//java/dagger/hilt/processor/internal:processor_errors", "//java/dagger/hilt/processor/internal:processors", "//java/dagger/internal/codegen/extension", "//java/dagger/internal/codegen/xprocessing", - "//third_party/java/auto:common", "//third_party/java/guava/base", "//third_party/java/guava/collect", "//third_party/java/javapoet", diff --git a/java/dagger/hilt/android/processor/internal/androidentrypoint/BroadcastReceiverGenerator.java b/java/dagger/hilt/android/processor/internal/androidentrypoint/BroadcastReceiverGenerator.java index 156842bbd..78a7976d1 100644 --- a/java/dagger/hilt/android/processor/internal/androidentrypoint/BroadcastReceiverGenerator.java +++ b/java/dagger/hilt/android/processor/internal/androidentrypoint/BroadcastReceiverGenerator.java @@ -30,13 +30,12 @@ import androidx.room.compiler.processing.XTypeElement; import androidx.room.compiler.processing.XTypeParameterElement; import com.google.common.collect.ImmutableSet; import com.squareup.javapoet.ClassName; -import com.squareup.javapoet.FieldSpec; import com.squareup.javapoet.JavaFile; import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.ParameterSpec; -import com.squareup.javapoet.TypeName; import com.squareup.javapoet.TypeSpec; import dagger.hilt.android.processor.internal.AndroidClassNames; +import dagger.hilt.processor.internal.ClassNames; import dagger.hilt.processor.internal.Processors; import dagger.internal.codegen.xprocessing.XExecutableTypes; import java.io.IOException; @@ -69,6 +68,13 @@ public final class BroadcastReceiverGenerator { .addModifiers(metadata.generatedClassModifiers()) .addMethod(onReceiveMethod()); + // Add an annotation used as a marker to let the bytecode injector know this receiver + // will need to be injected with a super.onReceive call. This is only necessary if no concrete + // onReceive call is implemented in any of the super classes. + if (metadata.requiresBytecodeInjection() && !isOnReceiveImplemented(metadata.baseElement())) { + builder.addAnnotation(ClassNames.ON_RECEIVE_BYTECODE_INJECTION_MARKER); + } + JavaPoetExtKt.addOriginatingElement(builder, metadata.element()); Generators.addGeneratedBaseClassJavadoc(builder, AndroidClassNames.ANDROID_ENTRY_POINT); Processors.addGeneratedAnnotation(builder, env, getClass()); @@ -82,20 +88,6 @@ public final class BroadcastReceiverGenerator { Generators.copyLintAnnotations(metadata.element(), builder); Generators.copySuppressAnnotations(metadata.element(), builder); - // Add an unused field used as a marker to let the bytecode injector know this receiver will - // need to be injected with a super.onReceive call. This is only necessary if no concrete - // onReceive call is implemented in any of the super classes. - if (metadata.requiresBytecodeInjection() && !isOnReceiveImplemented(metadata.baseElement())) { - builder.addField( - FieldSpec.builder( - TypeName.BOOLEAN, - "onReceiveBytecodeInjectionMarker", - Modifier.PRIVATE, - Modifier.FINAL) - .initializer("false") - .build()); - } - env.getFiler() .write( JavaFile.builder(generatedClassName.packageName(), builder.build()).build(), diff --git a/java/dagger/hilt/android/processor/internal/bindvalue/BindValueMetadata.java b/java/dagger/hilt/android/processor/internal/bindvalue/BindValueMetadata.java index 00a64028a..b59760960 100644 --- a/java/dagger/hilt/android/processor/internal/bindvalue/BindValueMetadata.java +++ b/java/dagger/hilt/android/processor/internal/bindvalue/BindValueMetadata.java @@ -33,8 +33,6 @@ import com.squareup.javapoet.ClassName; import dagger.hilt.processor.internal.ClassNames; import dagger.hilt.processor.internal.ProcessorErrors; import dagger.hilt.processor.internal.Processors; -import dagger.hilt.processor.internal.kotlin.KotlinMetadataUtil; -import dagger.hilt.processor.internal.kotlin.KotlinMetadataUtils; import dagger.internal.codegen.xprocessing.XAnnotations; import dagger.internal.codegen.xprocessing.XElements; import java.util.Collection; @@ -111,12 +109,7 @@ abstract class BindValueMetadata { XElements.toStableString(element)); XFieldElement field = asField(element); - - KotlinMetadataUtil metadataUtil = KotlinMetadataUtils.getMetadataUtil(); - Optional<XMethodElement> propertyGetter = - metadataUtil.hasMetadata(field) - ? metadataUtil.getPropertyGetter(field) - : Optional.empty(); + Optional<XMethodElement> propertyGetter = Optional.ofNullable(field.getGetter()); if (propertyGetter.isPresent()) { ProcessorErrors.checkState( !propertyGetter.get().isPrivate(), diff --git a/java/dagger/hilt/android/processor/internal/viewmodel/BUILD b/java/dagger/hilt/android/processor/internal/viewmodel/BUILD index f3686a1c8..90760ea31 100644 --- a/java/dagger/hilt/android/processor/internal/viewmodel/BUILD +++ b/java/dagger/hilt/android/processor/internal/viewmodel/BUILD @@ -38,6 +38,7 @@ kt_jvm_library( "//java/dagger/hilt/android/processor/internal:android_classnames", "//java/dagger/hilt/processor/internal:base_processor", "//java/dagger/hilt/processor/internal:classnames", + "//java/dagger/hilt/processor/internal:compiler_options", "//java/dagger/hilt/processor/internal:processor_errors", "//java/dagger/hilt/processor/internal:processors", "//java/dagger/internal/codegen/xprocessing", @@ -63,6 +64,7 @@ kt_jvm_library( "//:spi", "//java/dagger/hilt/android/processor/internal:android_classnames", "//java/dagger/hilt/processor/internal:dagger_models", + "//java/dagger/internal/codegen/xprocessing", "//third_party/java/auto:service", "//third_party/java/guava/graph", "//third_party/java/javapoet", diff --git a/java/dagger/hilt/android/processor/internal/viewmodel/ViewModelMetadata.kt b/java/dagger/hilt/android/processor/internal/viewmodel/ViewModelMetadata.kt index 49b35a7d9..920410a0b 100644 --- a/java/dagger/hilt/android/processor/internal/viewmodel/ViewModelMetadata.kt +++ b/java/dagger/hilt/android/processor/internal/viewmodel/ViewModelMetadata.kt @@ -16,83 +16,181 @@ package dagger.hilt.android.processor.internal.viewmodel +import androidx.room.compiler.codegen.XTypeName +import androidx.room.compiler.codegen.toJavaPoet import androidx.room.compiler.processing.ExperimentalProcessingApi +import androidx.room.compiler.processing.XMethodElement import androidx.room.compiler.processing.XProcessingEnv import androidx.room.compiler.processing.XTypeElement import com.squareup.javapoet.ClassName import dagger.hilt.android.processor.internal.AndroidClassNames import dagger.hilt.processor.internal.ClassNames +import dagger.hilt.processor.internal.HiltCompilerOptions import dagger.hilt.processor.internal.ProcessorErrors import dagger.hilt.processor.internal.Processors import dagger.internal.codegen.xprocessing.XAnnotations +import dagger.internal.codegen.xprocessing.XElements +import dagger.internal.codegen.xprocessing.XTypeElements import dagger.internal.codegen.xprocessing.XTypes /** Data class that represents a Hilt injected ViewModel */ @OptIn(ExperimentalProcessingApi::class) -internal class ViewModelMetadata private constructor(val typeElement: XTypeElement) { - val className = typeElement.className +internal class ViewModelMetadata +private constructor(val viewModelElement: XTypeElement, val assistedFactory: XTypeElement) { + val className = viewModelElement.asClassName().toJavaPoet() + + val assistedFactoryClassName: ClassName = assistedFactory.asClassName().toJavaPoet() val modulesClassName = ClassName.get( - typeElement.packageName, + viewModelElement.packageName, "${className.simpleNames().joinToString("_")}_HiltModules" ) companion object { + + private const val ASSISTED_FACTORY_VALUE = "assistedFactory" + + fun getAssistedFactoryMethods(factory: XTypeElement?): List<XMethodElement> { + return XTypeElements.getAllNonPrivateInstanceMethods(factory) + .filter { it.isAbstract() } + .filter { !it.isJavaDefault() } + } + internal fun create( processingEnv: XProcessingEnv, - typeElement: XTypeElement, + viewModelElement: XTypeElement, ): ViewModelMetadata? { ProcessorErrors.checkState( - XTypes.isSubtype(typeElement.type, processingEnv.requireType(AndroidClassNames.VIEW_MODEL)), - typeElement, + XTypes.isSubtype( + viewModelElement.type, + processingEnv.requireType(AndroidClassNames.VIEW_MODEL) + ), + viewModelElement, "@HiltViewModel is only supported on types that subclass %s.", AndroidClassNames.VIEW_MODEL ) - typeElement - .getConstructors() - .filter { constructor -> - ProcessorErrors.checkState( - !constructor.hasAnnotation(ClassNames.ASSISTED_INJECT), - constructor, - "ViewModel constructor should be annotated with @Inject instead of @AssistedInject." - ) - constructor.hasAnnotation(ClassNames.INJECT) - } - .let { injectConstructors -> - ProcessorErrors.checkState( - injectConstructors.size == 1, - typeElement, - "@HiltViewModel annotated class should contain exactly one @Inject " + - "annotated constructor." - ) - - injectConstructors.forEach { injectConstructor -> + val isAssistedInjectFeatureEnabled = + HiltCompilerOptions.isAssistedInjectViewModelsEnabled(viewModelElement) + + val assistedFactoryType = + viewModelElement + .requireAnnotation(AndroidClassNames.HILT_VIEW_MODEL) + .getAsType(ASSISTED_FACTORY_VALUE) + val assistedFactory = assistedFactoryType.typeElement!! + + if (assistedFactoryType.asTypeName() != XTypeName.ANY_OBJECT) { + ProcessorErrors.checkState( + isAssistedInjectFeatureEnabled, + viewModelElement, + "Specified assisted factory %s for %s in @HiltViewModel but compiler option 'enableAssistedInjectViewModels' was not enabled.", + assistedFactoryType.asTypeName().toJavaPoet(), + XElements.toStableString(viewModelElement), + ) + + ProcessorErrors.checkState( + assistedFactory.hasAnnotation(ClassNames.ASSISTED_FACTORY), + viewModelElement, + "Class %s is not annotated with @AssistedFactory.", + assistedFactoryType.asTypeName().toJavaPoet() + ) + + val assistedFactoryMethod = getAssistedFactoryMethods(assistedFactory).singleOrNull() + + ProcessorErrors.checkState( + assistedFactoryMethod != null, + assistedFactory, + "Cannot find assisted factory method in %s.", + XElements.toStableString(assistedFactory) + ) + + val assistedFactoryMethodType = assistedFactoryMethod!!.asMemberOf(assistedFactoryType) + + ProcessorErrors.checkState( + assistedFactoryMethodType.returnType.asTypeName() == viewModelElement.asClassName(), + assistedFactoryMethod, + "Class %s must have a factory method that returns a %s. Found %s.", + XElements.toStableString(assistedFactory), + XElements.toStableString(viewModelElement), + XTypes.toStableString(assistedFactoryMethodType.returnType) + ) + } + + val injectConstructors = + viewModelElement.getConstructors().filter { constructor -> + if (isAssistedInjectFeatureEnabled) { + constructor.hasAnnotation(ClassNames.INJECT) || + constructor.hasAnnotation(ClassNames.ASSISTED_INJECT) + } else { ProcessorErrors.checkState( - !injectConstructor.isPrivate(), - injectConstructor, - "@Inject annotated constructors must not be private." + !constructor.hasAnnotation(ClassNames.ASSISTED_INJECT), + constructor, + "ViewModel constructor should be annotated with @Inject instead of @AssistedInject." ) + constructor.hasAnnotation(ClassNames.INJECT) } } + val injectAnnotationsMessage = + if (isAssistedInjectFeatureEnabled) { + "@Inject or @AssistedInject" + } else { + "@Inject" + } + + ProcessorErrors.checkState( + injectConstructors.size == 1, + viewModelElement, + "@HiltViewModel annotated class should contain exactly one %s annotated constructor.", + injectAnnotationsMessage + ) + + val injectConstructor = injectConstructors.single() + + ProcessorErrors.checkState( + !injectConstructor.isPrivate(), + injectConstructor, + "%s annotated constructors must not be private.", + injectAnnotationsMessage + ) + + if (injectConstructor.hasAnnotation(ClassNames.ASSISTED_INJECT)) { + // If "enableAssistedInjectViewModels" is not enabled we'll get error: + // "ViewModel constructor should be annotated with @Inject instead of @AssistedInject." + + ProcessorErrors.checkState( + assistedFactoryType.asTypeName() != XTypeName.ANY_OBJECT, + viewModelElement, + "%s must have a valid assisted factory specified in @HiltViewModel when used with assisted injection. Found %s.", + XElements.toStableString(viewModelElement), + XTypes.toStableString(assistedFactoryType) + ) + } else { + ProcessorErrors.checkState( + assistedFactoryType.asTypeName() == XTypeName.ANY_OBJECT, + injectConstructor, + "Found assisted factory %s in @HiltViewModel but the constructor was annotated with @Inject instead of @AssistedInject.", + XTypes.toStableString(assistedFactoryType), + ) + } + ProcessorErrors.checkState( - !typeElement.isNested() || typeElement.isStatic(), - typeElement, + !viewModelElement.isNested() || viewModelElement.isStatic(), + viewModelElement, "@HiltViewModel may only be used on inner classes if they are static." ) - Processors.getScopeAnnotations(typeElement).let { scopeAnnotations -> + Processors.getScopeAnnotations(viewModelElement).let { scopeAnnotations -> ProcessorErrors.checkState( scopeAnnotations.isEmpty(), - typeElement, + viewModelElement, "@HiltViewModel classes should not be scoped. Found: %s", scopeAnnotations.joinToString { XAnnotations.toStableString(it) } ) } - return ViewModelMetadata(typeElement) + return ViewModelMetadata(viewModelElement, assistedFactory) } } } diff --git a/java/dagger/hilt/android/processor/internal/viewmodel/ViewModelModuleGenerator.kt b/java/dagger/hilt/android/processor/internal/viewmodel/ViewModelModuleGenerator.kt index 29f8c3ce5..6a156fa79 100644 --- a/java/dagger/hilt/android/processor/internal/viewmodel/ViewModelModuleGenerator.kt +++ b/java/dagger/hilt/android/processor/internal/viewmodel/ViewModelModuleGenerator.kt @@ -16,6 +16,7 @@ package dagger.hilt.android.processor.internal.viewmodel +import androidx.room.compiler.codegen.XTypeName import androidx.room.compiler.processing.ExperimentalProcessingApi import androidx.room.compiler.processing.XProcessingEnv import androidx.room.compiler.processing.addOriginatingElement @@ -23,6 +24,7 @@ import com.squareup.javapoet.AnnotationSpec import com.squareup.javapoet.ClassName import com.squareup.javapoet.JavaFile import com.squareup.javapoet.MethodSpec +import com.squareup.javapoet.TypeName import com.squareup.javapoet.TypeSpec import dagger.hilt.android.processor.internal.AndroidClassNames import dagger.hilt.processor.internal.ClassNames @@ -40,18 +42,20 @@ import javax.lang.model.element.Modifier * public static abstract class BindsModule { * @Binds * @IntoMap - * @StringKey("pkg.$") + * @LazyClassKey(pkg.$) * @HiltViewModelMap * public abstract ViewModel bind($ vm) * } * @Module * @InstallIn(ActivityRetainedComponent.class) * public static final class KeyModule { + * private static String className = "pkg.$"; * @Provides - * @IntoSet + * @IntoMap * @HiltViewModelMap.KeySet - * public static String provide() { - * return "pkg.$"; + * @LazyClassKey(pkg.$) + * public static boolean provide() { + * return true; * } * } * } @@ -60,20 +64,20 @@ import javax.lang.model.element.Modifier @OptIn(ExperimentalProcessingApi::class) internal class ViewModelModuleGenerator( private val processingEnv: XProcessingEnv, - private val injectedViewModel: ViewModelMetadata + private val viewModelMetadata: ViewModelMetadata, ) { fun generate() { val modulesTypeSpec = - TypeSpec.classBuilder(injectedViewModel.modulesClassName) + TypeSpec.classBuilder(viewModelMetadata.modulesClassName) .apply { - addOriginatingElement(injectedViewModel.typeElement) + addOriginatingElement(viewModelMetadata.viewModelElement) Processors.addGeneratedAnnotation(this, processingEnv, ViewModelProcessor::class.java) addAnnotation( AnnotationSpec.builder(ClassNames.ORIGINATING_ELEMENT) .addMember( "topLevelClass", "$T.class", - injectedViewModel.className.topLevelClassName() + viewModelMetadata.className.topLevelClassName(), ) .build() ) @@ -85,18 +89,24 @@ internal class ViewModelModuleGenerator( .build() processingEnv.filer.write( - JavaFile.builder(injectedViewModel.modulesClassName.packageName(), modulesTypeSpec).build() + JavaFile.builder(viewModelMetadata.modulesClassName.packageName(), modulesTypeSpec).build() ) } private fun getBindsModuleTypeSpec() = createModuleTypeSpec( className = "BindsModule", - component = AndroidClassNames.VIEW_MODEL_COMPONENT + component = AndroidClassNames.VIEW_MODEL_COMPONENT, ) .addModifiers(Modifier.ABSTRACT) .addMethod(MethodSpec.constructorBuilder().addModifiers(Modifier.PRIVATE).build()) - .addMethod(getViewModelBindsMethod()) + .addMethod( + if (viewModelMetadata.assistedFactory.asClassName() != XTypeName.ANY_OBJECT) { + getAssistedViewModelBindsMethod() + } else { + getViewModelBindsMethod() + } + ) .build() private fun getViewModelBindsMethod() = @@ -104,20 +114,20 @@ internal class ViewModelModuleGenerator( .addAnnotation(ClassNames.BINDS) .addAnnotation(ClassNames.INTO_MAP) .addAnnotation( - AnnotationSpec.builder(ClassNames.STRING_KEY) - .addMember("value", S, injectedViewModel.className.reflectionName()) + AnnotationSpec.builder(ClassNames.LAZY_CLASS_KEY) + .addMember("value", "$T.class", viewModelMetadata.className) .build() ) .addAnnotation(AndroidClassNames.HILT_VIEW_MODEL_MAP_QUALIFIER) .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) .returns(AndroidClassNames.VIEW_MODEL) - .addParameter(injectedViewModel.className, "vm") + .addParameter(viewModelMetadata.className, "vm") .build() private fun getKeyModuleTypeSpec() = createModuleTypeSpec( className = "KeyModule", - component = AndroidClassNames.ACTIVITY_RETAINED_COMPONENT + component = AndroidClassNames.ACTIVITY_RETAINED_COMPONENT, ) .addModifiers(Modifier.FINAL) .addMethod(MethodSpec.constructorBuilder().addModifiers(Modifier.PRIVATE).build()) @@ -127,16 +137,49 @@ internal class ViewModelModuleGenerator( private fun getViewModelKeyProvidesMethod() = MethodSpec.methodBuilder("provide") .addAnnotation(ClassNames.PROVIDES) - .addAnnotation(ClassNames.INTO_SET) + .addAnnotation(ClassNames.INTO_MAP) + .addAnnotation( + AnnotationSpec.builder(ClassNames.LAZY_CLASS_KEY) + .addMember("value", "$T.class", viewModelMetadata.className) + .build() + ) .addAnnotation(AndroidClassNames.HILT_VIEW_MODEL_KEYS_QUALIFIER) .addModifiers(Modifier.PUBLIC, Modifier.STATIC) - .returns(String::class.java) - .addStatement("return $S", injectedViewModel.className.reflectionName()) + .returns(Boolean::class.java) + .addStatement("return true") + .build() + + /** + * Should generate: + * ``` + * @Binds + * @IntoMap + * @LazyClassKey(pkg.FooViewModel.class) + * @HiltViewModelAssistedMap + * public abstract Object bind(FooViewModelAssistedFactory factory); + * ``` + * + * So that we have a HiltViewModelAssistedMap that maps from fully qualified ViewModel names to + * its assisted factory instance. + */ + private fun getAssistedViewModelBindsMethod() = + MethodSpec.methodBuilder("bind") + .addAnnotation(ClassNames.BINDS) + .addAnnotation(ClassNames.INTO_MAP) + .addAnnotation( + AnnotationSpec.builder(ClassNames.LAZY_CLASS_KEY) + .addMember("value", "$T.class", viewModelMetadata.className) + .build() + ) + .addAnnotation(AndroidClassNames.HILT_VIEW_MODEL_ASSISTED_FACTORY_MAP_QUALIFIER) + .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) + .addParameter(viewModelMetadata.assistedFactoryClassName, "factory") + .returns(TypeName.OBJECT) .build() private fun createModuleTypeSpec(className: String, component: ClassName) = TypeSpec.classBuilder(className) - .addOriginatingElement(injectedViewModel.typeElement) + .addOriginatingElement(viewModelMetadata.viewModelElement) .addAnnotation(ClassNames.MODULE) .addAnnotation( AnnotationSpec.builder(ClassNames.INSTALL_IN) diff --git a/java/dagger/hilt/android/processor/internal/viewmodel/ViewModelProcessingStep.kt b/java/dagger/hilt/android/processor/internal/viewmodel/ViewModelProcessingStep.kt index 69f7ac284..55cb289fc 100644 --- a/java/dagger/hilt/android/processor/internal/viewmodel/ViewModelProcessingStep.kt +++ b/java/dagger/hilt/android/processor/internal/viewmodel/ViewModelProcessingStep.kt @@ -28,16 +28,13 @@ import dagger.internal.codegen.xprocessing.XElements @OptIn(ExperimentalProcessingApi::class) /** Annotation processor for @ViewModelInject. */ class ViewModelProcessingStep(env: XProcessingEnv) : BaseProcessingStep(env) { + override fun annotationClassNames() = ImmutableSet.of(AndroidClassNames.HILT_VIEW_MODEL) override fun processEach(annotation: ClassName, element: XElement) { val typeElement = XElements.asTypeElement(element) - ViewModelMetadata.create( - processingEnv(), - typeElement, - ) - ?.let { viewModelMetadata -> - ViewModelModuleGenerator(processingEnv(), viewModelMetadata).generate() - } + ViewModelMetadata.create(processingEnv(), typeElement)?.let { viewModelMetadata -> + ViewModelModuleGenerator(processingEnv(), viewModelMetadata).generate() + } } } diff --git a/java/dagger/hilt/android/processor/internal/viewmodel/ViewModelValidationPlugin.kt b/java/dagger/hilt/android/processor/internal/viewmodel/ViewModelValidationPlugin.kt index d5c3666b3..69094c9a5 100644 --- a/java/dagger/hilt/android/processor/internal/viewmodel/ViewModelValidationPlugin.kt +++ b/java/dagger/hilt/android/processor/internal/viewmodel/ViewModelValidationPlugin.kt @@ -14,27 +14,45 @@ * limitations under the License. */ +@file:OptIn(ExperimentalProcessingApi::class) + package dagger.hilt.android.processor.internal.viewmodel +import androidx.room.compiler.processing.ExperimentalProcessingApi +import androidx.room.compiler.processing.XMethodElement +import androidx.room.compiler.processing.XProcessingEnv +import androidx.room.compiler.processing.XProcessingEnv.Companion.create +import androidx.room.compiler.processing.XType +import androidx.room.compiler.processing.XTypeElement +import androidx.room.compiler.processing.compat.XConverters.toXProcessing import com.google.auto.service.AutoService import com.google.common.graph.EndpointPair import com.google.common.graph.ImmutableNetwork import dagger.hilt.android.processor.internal.AndroidClassNames -import dagger.hilt.processor.internal.asElement import dagger.hilt.processor.internal.getQualifiedName import dagger.hilt.processor.internal.hasAnnotation +import dagger.internal.codegen.xprocessing.XTypeElements import dagger.spi.model.Binding import dagger.spi.model.BindingGraph import dagger.spi.model.BindingGraph.Edge import dagger.spi.model.BindingGraph.Node import dagger.spi.model.BindingGraphPlugin import dagger.spi.model.BindingKind +import dagger.spi.model.DaggerProcessingEnv +import dagger.spi.model.DaggerType import dagger.spi.model.DiagnosticReporter import javax.tools.Diagnostic.Kind /** Plugin to validate users do not inject @HiltViewModel classes. */ @AutoService(BindingGraphPlugin::class) class ViewModelValidationPlugin : BindingGraphPlugin { + + private lateinit var env: XProcessingEnv + + override fun init(processingEnv: DaggerProcessingEnv, options: MutableMap<String, String>) { + env = processingEnv.toXProcessingEnv() + } + override fun visitGraph(bindingGraph: BindingGraph, diagnosticReporter: DiagnosticReporter) { if (bindingGraph.rootComponentNode().isSubcomponent()) { // This check does not work with partial graphs since it needs to take into account the source @@ -47,10 +65,10 @@ class ViewModelValidationPlugin : BindingGraphPlugin { val pair: EndpointPair<Node> = network.incidentNodes(edge) val target: Node = pair.target() val source: Node = pair.source() - if ( - target is Binding && - isHiltViewModelBinding(target) && !isInternalHiltViewModelUsage(source) - ) { + if (target !is Binding) { + return@forEach + } + if (isHiltViewModelBinding(target) && !isInternalHiltViewModelUsage(source)) { diagnosticReporter.reportDependency( Kind.ERROR, edge, @@ -59,6 +77,17 @@ class ViewModelValidationPlugin : BindingGraphPlugin { "(e.g. ViewModelProvider) instead." + "\nInjected ViewModel: ${target.key().type()}\n" ) + } else if ( + isViewModelAssistedFactory(target) && !isInternalViewModelAssistedFactoryUsage(source) + ) { + diagnosticReporter.reportDependency( + Kind.ERROR, + edge, + "\nInjection of an assisted factory for Hilt ViewModel is prohibited since it " + + "can not be used to create a ViewModel instance correctly.\nAccess the ViewModel via " + + "the Android APIs (e.g. ViewModelProvider) instead." + + "\nInjected factory: ${target.key().type()}\n" + ) } } } @@ -67,7 +96,7 @@ class ViewModelValidationPlugin : BindingGraphPlugin { // Make sure this is from an @Inject constructor rather than an overridden binding like an // @Provides and that the class is annotated with @HiltViewModel. return target.kind() == BindingKind.INJECTION && - target.key().type().asElement().hasAnnotation(AndroidClassNames.HILT_VIEW_MODEL) + target.key().type().hasAnnotation(AndroidClassNames.HILT_VIEW_MODEL) } private fun isInternalHiltViewModelUsage(source: Node): Boolean { @@ -86,4 +115,58 @@ class ViewModelValidationPlugin : BindingGraphPlugin { AndroidClassNames.HILT_VIEW_MODEL_MAP_QUALIFIER.canonicalName() && source.key().multibindingContributionIdentifier().isPresent() } + + private fun isViewModelAssistedFactory(target: Binding): Boolean { + if (target.kind() != BindingKind.ASSISTED_FACTORY) return false + val factoryType = target.key().type() + return getAssistedInjectTypeElement(factoryType.toXType(env)) + .hasAnnotation(AndroidClassNames.HILT_VIEW_MODEL) + } + + private fun getAssistedInjectTypeElement(factoryType: XType): XTypeElement = + // The factory method and the type element for its return type cannot be + // null as the BindingGraph won't be created if the + // @AssistedFactory-annotated class is invalid. + getAssistedFactoryMethods(factoryType.typeElement) + .single() + .asMemberOf(factoryType) + .returnType + .typeElement!! + + private fun getAssistedFactoryMethods(factory: XTypeElement?): List<XMethodElement> { + return XTypeElements.getAllNonPrivateInstanceMethods(factory) + .filter { it.isAbstract() } + .filter { !it.isJavaDefault() } + } + + private fun isInternalViewModelAssistedFactoryUsage(source: Node): Boolean { + // We expect the only usage of the assisted factory for a Hilt ViewModel is in the + // code we generate: + // @Binds + // @IntoMap + // @StringKey(...) + // @HiltViewModelAssistedMap + // public abstract Object bind(FooFactory factory); + return source is Binding && + source.key().qualifier().isPresent() && + source.key().qualifier().get().getQualifiedName() == + AndroidClassNames.HILT_VIEW_MODEL_ASSISTED_FACTORY_MAP_QUALIFIER.canonicalName() && + source.key().multibindingContributionIdentifier().isPresent() + } +} + +private fun DaggerType.toXType(processingEnv: XProcessingEnv): XType { + return when (backend()) { + DaggerProcessingEnv.Backend.JAVAC -> javac().toXProcessing(processingEnv) + DaggerProcessingEnv.Backend.KSP -> ksp().toXProcessing(processingEnv) + else -> error("Backend ${ backend() } not supported yet.") + } +} + +private fun DaggerProcessingEnv.toXProcessingEnv(): XProcessingEnv { + return when (backend()) { + DaggerProcessingEnv.Backend.JAVAC -> create(javac()) + DaggerProcessingEnv.Backend.KSP -> create(ksp(), resolver()) + else -> error("Backend ${ backend() } not supported yet.") + } } diff --git a/java/dagger/hilt/android/testing/BUILD b/java/dagger/hilt/android/testing/BUILD index 6c3c6e564..ee3d78ab1 100644 --- a/java/dagger/hilt/android/testing/BUILD +++ b/java/dagger/hilt/android/testing/BUILD @@ -168,6 +168,15 @@ android_library( ], ) +android_library( + name = "skip_test_injection", + testonly = 1, + srcs = ["SkipTestInjection.java"], + deps = [ + ":package_info", + ], +) + java_library( name = "package_info", srcs = ["package-info.java"], @@ -220,6 +229,7 @@ gen_maven_artifact( artifact_target_maven_deps = [ "androidx.activity:activity", "androidx.annotation:annotation", + "androidx.annotation:annotation-experimental", "androidx.fragment:fragment", "androidx.lifecycle:lifecycle-common", "androidx.lifecycle:lifecycle-viewmodel", diff --git a/java/dagger/hilt/android/testing/SkipTestInjection.java b/java/dagger/hilt/android/testing/SkipTestInjection.java new file mode 100644 index 000000000..f8e015ba0 --- /dev/null +++ b/java/dagger/hilt/android/testing/SkipTestInjection.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2024 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.android.testing; + +import static java.lang.annotation.RetentionPolicy.CLASS; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Annotation used for skipping test injection in a Hilt Android Test. This may be useful if + * building separate custom test infrastructure to inject the test class from another Hilt + * component. This may be used on either the test class or an annotation that annotates + * the test class. + */ +@Retention(CLASS) +@Target({ElementType.TYPE}) +public @interface SkipTestInjection {} diff --git a/java/dagger/hilt/android/testing/compile/HiltCompilerTests.java b/java/dagger/hilt/android/testing/compile/HiltCompilerTests.java index 8f2abd39d..89bf67882 100644 --- a/java/dagger/hilt/android/testing/compile/HiltCompilerTests.java +++ b/java/dagger/hilt/android/testing/compile/HiltCompilerTests.java @@ -117,7 +117,7 @@ public final class HiltCompilerTests { .collect(toMap((Processor e) -> e.getClass(), (Processor e) -> e)); // Adds extra processors, and allows overriding any processors of the same class. - extraProcessors.stream().forEach(processor -> processors.put(processor.getClass(), processor)); + extraProcessors.forEach(processor -> processors.put(processor.getClass(), processor)); return CompilerTests.compiler().withProcessors(processors.values()); } @@ -191,9 +191,9 @@ public final class HiltCompilerTests { private static ImmutableList<SymbolProcessorProvider> kspDefaultProcessors() { // TODO(bcorso): Add the rest of the KSP processors here. return ImmutableList.of( - new KspAndroidEntryPointProcessor.Provider(), - new KspAliasOfProcessor.Provider(), new KspAggregatedDepsProcessor.Provider(), + new KspAliasOfProcessor.Provider(), + new KspAndroidEntryPointProcessor.Provider(), new KspComponentProcessor.Provider(), new KspComponentTreeDepsProcessor.Provider(), new KspCustomTestApplicationProcessor.Provider(), @@ -279,16 +279,14 @@ public final class HiltCompilerTests { "-P", "plugin:org.jetbrains.kotlin.kapt3:correctErrorTypes=true"), /* config= */ HiltProcessingEnvConfigs.CONFIGS, /* javacProcessors= */ ImmutableList.<Processor>builder() - .addAll(defaultProcessors()) - .addAll(additionalJavacProcessors()) + .addAll(mergeProcessors(defaultProcessors(), additionalJavacProcessors())) .addAll( processingSteps().stream() .map(HiltCompilerProcessors.JavacProcessor::new) .collect(toImmutableList())) .build(), /* symbolProcessorProviders= */ ImmutableList.<SymbolProcessorProvider>builder() - .addAll(kspDefaultProcessors()) - .addAll(additionalKspProcessors()) + .addAll(mergeProcessors(kspDefaultProcessors(), additionalKspProcessors())) .addAll( processingSteps().stream() .map(HiltCompilerProcessors.KspProcessor.Provider::new) @@ -300,6 +298,15 @@ public final class HiltCompilerTests { }); } + private static <T> ImmutableList<T> mergeProcessors( + Collection<T> defaultProcessors, Collection<T> extraProcessors) { + Map<Class<?>, T> processors = + defaultProcessors.stream().collect(toMap((T e) -> e.getClass(), (T e) -> e)); + // Adds extra processors, and allows overriding any processors of the same class. + extraProcessors.forEach(processor -> processors.put(processor.getClass(), processor)); + return ImmutableList.copyOf(processors.values()); + } + /** Used to build a {@link HiltCompiler}. */ @AutoValue.Builder public abstract static class Builder { diff --git a/java/dagger/hilt/migration/BUILD b/java/dagger/hilt/migration/BUILD index 446e7a2ea..27f472a18 100644 --- a/java/dagger/hilt/migration/BUILD +++ b/java/dagger/hilt/migration/BUILD @@ -18,9 +18,7 @@ package(default_visibility = ["//:src"]) java_library( name = "alias_of", - srcs = [ - "AliasOf.java", - ], + srcs = ["AliasOf.java"], exported_plugins = [ "//java/dagger/hilt/processor/internal/aliasof:processor", ], diff --git a/java/dagger/hilt/processor/BUILD b/java/dagger/hilt/processor/BUILD index ba7c9eee4..ecbc29495 100644 --- a/java/dagger/hilt/processor/BUILD +++ b/java/dagger/hilt/processor/BUILD @@ -74,6 +74,7 @@ gen_maven_artifact( "//java/dagger/hilt/processor/internal:component_names", "//java/dagger/hilt/processor/internal:components", "//java/dagger/hilt/processor/internal:hilt_processing_env_configs", + "//java/dagger/hilt/processor/internal:method_signature", "//java/dagger/hilt/processor/internal:processor_errors", "//java/dagger/hilt/processor/internal:processors", "//java/dagger/hilt/processor/internal/aggregateddeps:component_dependencies", diff --git a/java/dagger/hilt/processor/internal/BUILD b/java/dagger/hilt/processor/internal/BUILD index a2746baf6..8828227aa 100644 --- a/java/dagger/hilt/processor/internal/BUILD +++ b/java/dagger/hilt/processor/internal/BUILD @@ -57,9 +57,7 @@ java_library( "ProcessorErrors.java", ], deps = [ - "//java/dagger/internal/codegen/extension", "//java/dagger/internal/codegen/xprocessing", - "//third_party/java/auto:common", "//third_party/java/error_prone:annotations", "//third_party/java/guava/base", "//third_party/java/guava/collect", @@ -87,6 +85,20 @@ java_library( ) java_library( + name = "method_signature", + srcs = [ + "MethodSignature.java", + ], + deps = [ + "//java/dagger/internal/codegen/extension", + "//java/dagger/internal/codegen/xprocessing", + "//third_party/java/auto:value", + "//third_party/java/guava/collect", + "//third_party/java/javapoet", + ], +) + +java_library( name = "classnames", srcs = [ "ClassNames.java", diff --git a/java/dagger/hilt/processor/internal/ClassNames.java b/java/dagger/hilt/processor/internal/ClassNames.java index ec2e73ed4..00de786f0 100644 --- a/java/dagger/hilt/processor/internal/ClassNames.java +++ b/java/dagger/hilt/processor/internal/ClassNames.java @@ -72,7 +72,11 @@ public final class ClassNames { public static final ClassName DEFINE_COMPONENT_CLASSES = get("dagger.hilt.internal.definecomponent", "DefineComponentClasses"); + public static final ClassName IDENTIFIER_NAME_STRING = + get("dagger.internal", "IdentifierNameString"); + public static final ClassName ASSISTED_INJECT = get("dagger.assisted", "AssistedInject"); + public static final ClassName ASSISTED_FACTORY = get("dagger.assisted", "AssistedFactory"); public static final ClassName BINDS = get("dagger", "Binds"); public static final ClassName BINDS_OPTIONAL_OF = @@ -85,6 +89,7 @@ public final class ClassNames { public static final ClassName INTO_SET = get("dagger.multibindings", "IntoSet"); public static final ClassName ELEMENTS_INTO_SET = get("dagger.multibindings", "ElementsIntoSet"); public static final ClassName STRING_KEY = get("dagger.multibindings", "StringKey"); + public static final ClassName LAZY_CLASS_KEY = get("dagger.multibindings", "LazyClassKey"); public static final ClassName PROVIDES = get("dagger", "Provides"); public static final ClassName COMPONENT = get("dagger", "Component"); @@ -169,6 +174,8 @@ public final class ClassNames { get("dagger.hilt.android.internal.testing", "TestInstanceHolder"); public static final ClassName HILT_ANDROID_TEST = get("dagger.hilt.android.testing", "HiltAndroidTest"); + public static final ClassName SKIP_TEST_INJECTION = + get("dagger.hilt.android.testing", "SkipTestInjection"); public static final ClassName CUSTOM_TEST_APPLICATION = get("dagger.hilt.android.testing", "CustomTestApplication"); public static final ClassName ON_COMPONENT_READY_RUNNER = @@ -214,6 +221,9 @@ public final class ClassNames { public static final ClassName SUPPRESS_WARNINGS = get("java.lang", "SuppressWarnings"); public static final ClassName KOTLIN_SUPPRESS = get("kotlin", "Suppress"); + public static final ClassName ON_RECEIVE_BYTECODE_INJECTION_MARKER = + get("dagger.hilt.android.internal", "OnReceiveBytecodeInjectionMarker"); + // Kotlin-specific class names public static final ClassName KOTLIN_METADATA = get("kotlin", "Metadata"); diff --git a/java/dagger/hilt/processor/internal/DaggerModels.kt b/java/dagger/hilt/processor/internal/DaggerModels.kt index 7d64d2396..9fe0cf4f7 100644 --- a/java/dagger/hilt/processor/internal/DaggerModels.kt +++ b/java/dagger/hilt/processor/internal/DaggerModels.kt @@ -18,47 +18,37 @@ package dagger.hilt.processor.internal import com.google.auto.common.MoreTypes import com.google.devtools.ksp.symbol.KSAnnotated +import com.google.devtools.ksp.symbol.KSDeclaration import com.squareup.javapoet.ClassName import dagger.spi.model.DaggerAnnotation import dagger.spi.model.DaggerElement import dagger.spi.model.DaggerProcessingEnv +import dagger.spi.model.DaggerProcessingEnv.Backend.JAVAC +import dagger.spi.model.DaggerProcessingEnv.Backend.KSP import dagger.spi.model.DaggerType -fun DaggerType.asElement(): DaggerElement = +fun DaggerType.hasAnnotation(className: ClassName): Boolean = when (checkNotNull(backend())) { - DaggerProcessingEnv.Backend.JAVAC -> { - val javaType = checkNotNull(java()) - DaggerElement.fromJavac(MoreTypes.asElement(javaType)) - } - DaggerProcessingEnv.Backend.KSP -> { - val kspType = checkNotNull(ksp()) - DaggerElement.fromKsp(kspType.declaration) - } + JAVAC -> Processors.hasAnnotation(MoreTypes.asTypeElement(javac()), className) + KSP -> ksp().declaration.hasAnnotation(className.canonicalName()) + } + +fun KSDeclaration.hasAnnotation(annotationName: String): Boolean = + annotations.any { + it.annotationType.resolve().declaration.qualifiedName?.asString().equals(annotationName) } fun DaggerElement.hasAnnotation(className: ClassName) = when (checkNotNull(backend())) { - DaggerProcessingEnv.Backend.JAVAC -> { - val javaElement = checkNotNull(java()) - Processors.hasAnnotation(javaElement, className) - } - DaggerProcessingEnv.Backend.KSP -> { - val kspAnnotated = checkNotNull(ksp()) - kspAnnotated.hasAnnotation(className) - } + JAVAC -> Processors.hasAnnotation(javac(), className) + KSP -> ksp().hasAnnotation(className) } fun DaggerAnnotation.getQualifiedName() = when (checkNotNull(backend())) { - DaggerProcessingEnv.Backend.JAVAC -> { - val javaAnnotation = checkNotNull(java()) - MoreTypes.asTypeElement(javaAnnotation.annotationType).qualifiedName.toString() - } - DaggerProcessingEnv.Backend.KSP -> { - val kspAnnotation = checkNotNull(ksp()) - kspAnnotation.annotationType.resolve().declaration.qualifiedName!!.asString() - } + JAVAC -> MoreTypes.asTypeElement(javac().annotationType).qualifiedName.toString() + KSP -> ksp().annotationType.resolve().declaration.qualifiedName!!.asString() } private fun KSAnnotated.hasAnnotation(className: ClassName) = diff --git a/java/dagger/hilt/processor/internal/HiltCompilerOptions.java b/java/dagger/hilt/processor/internal/HiltCompilerOptions.java index cdb2d6c98..90575599b 100644 --- a/java/dagger/hilt/processor/internal/HiltCompilerOptions.java +++ b/java/dagger/hilt/processor/internal/HiltCompilerOptions.java @@ -21,6 +21,7 @@ import static com.google.common.base.Ascii.toUpperCase; import androidx.room.compiler.processing.XProcessingEnv; import androidx.room.compiler.processing.XTypeElement; +import androidx.room.compiler.processing.compat.XConverters; import com.google.common.collect.ImmutableSet; import dagger.hilt.processor.internal.optionvalues.BooleanValue; import dagger.hilt.processor.internal.optionvalues.GradleProjectType; @@ -101,6 +102,13 @@ public final class HiltCompilerOptions { return GRADLE_PROJECT_TYPE.get(env); } + public static boolean isAssistedInjectViewModelsEnabled(XTypeElement viewModelElement) { + boolean enabled = + ENABLE_ASSISTED_INJECT_VIEWMODELS.get(XConverters.getProcessingEnv(viewModelElement)) + == BooleanValue.TRUE; + return enabled; + } + /** Do not use! This is for internal use only. */ private static final EnumOption<BooleanValue> DISABLE_ANDROID_SUPERCLASS_VALIDATION = new EnumOption<>("android.internal.disableAndroidSuperclassValidation", BooleanValue.FALSE); @@ -124,6 +132,9 @@ public final class HiltCompilerOptions { private static final EnumOption<GradleProjectType> GRADLE_PROJECT_TYPE = new EnumOption<>("android.internal.projectType", GradleProjectType.UNSET); + private static final EnumOption<BooleanValue> ENABLE_ASSISTED_INJECT_VIEWMODELS = + new EnumOption<>( + "enableAssistedInjectViewModels", BooleanValue.TRUE ); private static final ImmutableSet<String> DEPRECATED_OPTIONS = ImmutableSet.of("dagger.hilt.android.useFragmentGetContextFix"); diff --git a/java/dagger/hilt/processor/internal/MethodSignature.java b/java/dagger/hilt/processor/internal/MethodSignature.java new file mode 100644 index 000000000..7fffef2bb --- /dev/null +++ b/java/dagger/hilt/processor/internal/MethodSignature.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2023 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; + +import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; +import static java.util.stream.Collectors.joining; + +import androidx.room.compiler.processing.XExecutableElement; +import androidx.room.compiler.processing.XMethodElement; +import androidx.room.compiler.processing.XMethodType; +import androidx.room.compiler.processing.XType; +import com.google.auto.value.AutoValue; +import com.google.common.collect.ImmutableList; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.TypeName; +import dagger.internal.codegen.xprocessing.XElements; + +/** Represents the method signature needed to uniquely identify a method. */ +@AutoValue +public abstract class MethodSignature { + MethodSignature() {} + + abstract String name(); + + abstract ImmutableList<TypeName> parameters(); + + /** Creates a {@link MethodSignature} from a method name and parameter {@link TypeNames} */ + public static MethodSignature of(String methodName, TypeName... typeNames) { + return new AutoValue_MethodSignature(methodName, ImmutableList.copyOf(typeNames)); + } + + /** Creates a {@link MethodSignature} from a {@link MethodSpec} */ + public static MethodSignature of(MethodSpec method) { + return new AutoValue_MethodSignature( + method.name, method.parameters.stream().map(p -> p.type).collect(toImmutableList())); + } + + /** Creates a {@link MethodSignature} from an {@link XExecutableElement} */ + public static MethodSignature of(XExecutableElement executableElement) { + return new AutoValue_MethodSignature( + XElements.getSimpleName(executableElement), + executableElement.getParameters().stream() + .map(p -> p.getType().getTypeName()) + .collect(toImmutableList())); + } + + /** + * Creates a {@link MethodSignature} from an {@link XMethodElement}. + * + * <p>This version will resolve type parameters as declared by {@code enclosing}. + */ + static MethodSignature ofDeclaredType(XMethodElement method, XType enclosing) { + XMethodType executableType = method.asMemberOf(enclosing); + return new AutoValue_MethodSignature( + XElements.getSimpleName(method), + executableType.getParameterTypes().stream() + .map(XType::getTypeName) + .collect(toImmutableList())); + } + + /** Returns a string in the format: METHOD_NAME(PARAM_TYPE1,PARAM_TYEP2,...) */ + @Override + public final String toString() { + return String.format( + "%s(%s)", name(), parameters().stream().map(Object::toString).collect(joining(","))); + } +} diff --git a/java/dagger/hilt/processor/internal/kotlin/KotlinMetadataUtil.java b/java/dagger/hilt/processor/internal/kotlin/KotlinMetadataUtil.java index 771a4b8a5..915a47de7 100644 --- a/java/dagger/hilt/processor/internal/kotlin/KotlinMetadataUtil.java +++ b/java/dagger/hilt/processor/internal/kotlin/KotlinMetadataUtil.java @@ -34,7 +34,6 @@ import com.squareup.javapoet.ClassName; import dagger.hilt.processor.internal.ClassNames; import dagger.internal.codegen.xprocessing.XAnnotations; import dagger.internal.codegen.xprocessing.XElements; -import java.util.Optional; import javax.inject.Inject; /** Utility class for interacting with Kotlin Metadata. */ @@ -133,10 +132,6 @@ public final class KotlinMetadataUtil { : ImmutableList.of(); } - public Optional<XMethodElement> getPropertyGetter(XFieldElement fieldElement) { - return metadataFactory.create(fieldElement).getPropertyGetter(fieldElement); - } - public boolean containsConstructorWithDefaultParam(XTypeElement typeElement) { return hasMetadata(typeElement) && metadataFactory.create(typeElement).containsConstructorWithDefaultParam(); diff --git a/java/dagger/hilt/processor/internal/root/RootGenerator.java b/java/dagger/hilt/processor/internal/root/RootGenerator.java index 2868f7c8f..f43327200 100644 --- a/java/dagger/hilt/processor/internal/root/RootGenerator.java +++ b/java/dagger/hilt/processor/internal/root/RootGenerator.java @@ -23,9 +23,7 @@ import static javax.lang.model.element.Modifier.PUBLIC; import static javax.lang.model.element.Modifier.STATIC; import androidx.room.compiler.processing.JavaPoetExtKt; -import androidx.room.compiler.processing.XFiler.Mode; import androidx.room.compiler.processing.XProcessingEnv; -import androidx.room.compiler.processing.XProcessingEnv.Backend; import androidx.room.compiler.processing.XTypeElement; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -132,12 +130,7 @@ final class RootGenerator { JavaFile componentsWrapperJavaFile = JavaFile.builder(componentsWrapperClassName.packageName(), componentsWrapper.build()) .build(); - // TODO(danysantiago): Support formatting in KSP: b/288572563 - if (env.getBackend() == Backend.KSP) { - env.getFiler().write(componentsWrapperJavaFile, Mode.Isolating); - } else { - RootFileFormatter.write(componentsWrapperJavaFile, env); - } + RootFileFormatter.write(componentsWrapperJavaFile, env); } private static ComponentTree filterDescriptors(ComponentTree componentTree) { diff --git a/java/dagger/hilt/processor/internal/root/RootMetadata.java b/java/dagger/hilt/processor/internal/root/RootMetadata.java index 8166d668e..55f6e9c4e 100644 --- a/java/dagger/hilt/processor/internal/root/RootMetadata.java +++ b/java/dagger/hilt/processor/internal/root/RootMetadata.java @@ -21,7 +21,6 @@ import static com.google.common.base.Suppliers.memoize; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; import androidx.room.compiler.processing.XConstructorElement; -import androidx.room.compiler.processing.XMethodElement; import androidx.room.compiler.processing.XProcessingEnv; import androidx.room.compiler.processing.XTypeElement; import com.google.common.base.Supplier; @@ -40,6 +39,7 @@ import javax.tools.Diagnostic; /** Contains metadata about the given hilt root. */ public final class RootMetadata { + private static final ClassName APPLICATION_CONTEXT_MODULE = ClassName.get("dagger.hilt.android.internal.modules", "ApplicationContextModule"); @@ -195,33 +195,10 @@ public final class RootMetadata { } private static boolean daggerCanConstruct(XTypeElement type) { - if (type.isKotlinObject()) { - // Treat Kotlin object modules as if Dagger can construct them (it technically can't, but it - // doesn't need to as it can use them since all their provision methods are static). + if (!Processors.requiresModuleInstance(type)) { return true; } - - return !isInnerClass(type) - && !hasNonDaggerAbstractMethod(type) - && (hasOnlyStaticProvides(type) || hasVisibleEmptyConstructor(type)); - } - - private static boolean isInnerClass(XTypeElement type) { - return type.isNested() && !type.isStatic(); - } - - private static boolean hasNonDaggerAbstractMethod(XTypeElement type) { - // TODO(erichang): Actually this isn't really supported b/28989613 - return type.getDeclaredMethods().stream() - .filter(XMethodElement::isAbstract) - .anyMatch(method -> !Processors.hasDaggerAbstractMethodAnnotation(method)); - } - - private static boolean hasOnlyStaticProvides(XTypeElement type) { - // TODO(erichang): Check for @Produces too when we have a producers story - return type.getDeclaredMethods().stream() - .filter(method -> method.hasAnnotation(ClassNames.PROVIDES)) - .allMatch(XMethodElement::isStatic); + return hasVisibleEmptyConstructor(type) && (!type.isNested() || type.isStatic()); } private static boolean hasVisibleEmptyConstructor(XTypeElement type) { diff --git a/java/dagger/hilt/processor/internal/root/RootProcessingStep.java b/java/dagger/hilt/processor/internal/root/RootProcessingStep.java index f281995d9..d6de432bc 100644 --- a/java/dagger/hilt/processor/internal/root/RootProcessingStep.java +++ b/java/dagger/hilt/processor/internal/root/RootProcessingStep.java @@ -57,6 +57,9 @@ import java.util.Set; public final class RootProcessingStep extends BaseProcessingStep { private boolean processed; + // TODO(b/297889547) do not run preProcess and postProcess if supported annotation isn't present + // in the environment. + private boolean hasElementsToProcess = false; private GeneratesRootInputs generatesRootInputs; public RootProcessingStep(XProcessingEnv env) { @@ -75,13 +78,16 @@ public final class RootProcessingStep extends BaseProcessingStep { @Override public void processEach(ClassName annotation, XElement element) throws Exception { + hasElementsToProcess = true; XTypeElement rootElement = XElements.asTypeElement(element); // TODO(bcorso): Move this logic into a separate isolating processor to avoid regenerating it // for unrelated changes in Gradle. RootType rootType = RootType.of(rootElement); if (rootType.isTestRoot()) { - new TestInjectorGenerator(processingEnv(), TestRootMetadata.of(processingEnv(), rootElement)) - .generate(); + TestRootMetadata testRootMetadata = TestRootMetadata.of(processingEnv(), rootElement); + if (testRootMetadata.skipTestInjectionAnnotation().isEmpty()) { + new TestInjectorGenerator(processingEnv(), testRootMetadata).generate(); + } } XTypeElement originatingRootElement = @@ -93,6 +99,9 @@ public final class RootProcessingStep extends BaseProcessingStep { @Override protected void postProcess(XProcessingEnv env, XRoundEnv roundEnv) throws Exception { + if (!hasElementsToProcess) { + return; + } if (!useAggregatingRootProcessor(processingEnv())) { return; } diff --git a/java/dagger/hilt/processor/internal/root/TestComponentDataGenerator.java b/java/dagger/hilt/processor/internal/root/TestComponentDataGenerator.java index 689dae7dc..bacb75b87 100644 --- a/java/dagger/hilt/processor/internal/root/TestComponentDataGenerator.java +++ b/java/dagger/hilt/processor/internal/root/TestComponentDataGenerator.java @@ -25,6 +25,7 @@ import static javax.lang.model.element.Modifier.PUBLIC; import static javax.lang.model.element.Modifier.STATIC; import androidx.room.compiler.processing.JavaPoetExtKt; +import androidx.room.compiler.processing.XAnnotation; import androidx.room.compiler.processing.XConstructorElement; import androidx.room.compiler.processing.XFiler.Mode; import androidx.room.compiler.processing.XProcessingEnv; @@ -41,6 +42,7 @@ import dagger.hilt.processor.internal.ComponentNames; import dagger.hilt.processor.internal.Processors; import java.io.IOException; import java.util.List; +import java.util.Optional; /** Generates an implementation of {@link dagger.hilt.android.internal.TestComponentData}. */ public final class TestComponentDataGenerator { @@ -222,6 +224,13 @@ public final class TestComponentDataGenerator { } private CodeBlock callInjectTest(XTypeElement testElement) { + Optional<XAnnotation> skipTestInjection = + rootMetadata.testRootMetadata().skipTestInjectionAnnotation(); + if (skipTestInjection.isPresent()) { + return CodeBlock.of( + "throw new IllegalStateException(\"Cannot inject test when using @$L\")", + skipTestInjection.get().getName()); + } return CodeBlock.of( "(($T) (($T) $T.getApplication($T.getApplicationContext()))" + ".generatedComponent()).injectTest(testInstance)", diff --git a/java/dagger/hilt/processor/internal/root/TestRootMetadata.java b/java/dagger/hilt/processor/internal/root/TestRootMetadata.java index 5dc6feeaa..b0523034f 100644 --- a/java/dagger/hilt/processor/internal/root/TestRootMetadata.java +++ b/java/dagger/hilt/processor/internal/root/TestRootMetadata.java @@ -16,6 +16,7 @@ package dagger.hilt.processor.internal.root; +import androidx.room.compiler.processing.XAnnotation; import androidx.room.compiler.processing.XElement; import androidx.room.compiler.processing.XProcessingEnv; import androidx.room.compiler.processing.XTypeElement; @@ -25,6 +26,8 @@ import dagger.hilt.processor.internal.ClassNames; import dagger.hilt.processor.internal.ProcessorErrors; import dagger.hilt.processor.internal.Processors; import dagger.internal.codegen.xprocessing.XElements; +import java.util.Optional; +import java.util.Set; import javax.lang.model.element.TypeElement; /** Metadata class for {@code InternalTestRoot} annotated classes. */ @@ -57,6 +60,28 @@ abstract class TestRootMetadata { return Processors.append(Processors.getEnclosedClassName(testName()), "_GeneratedInjector"); } + /** + * Returns either the SkipTestInjection annotation or the first annotation that was annotated + * with SkipTestInjection, if present. + */ + Optional<XAnnotation> skipTestInjectionAnnotation() { + XAnnotation skipTestAnnotation = testElement().getAnnotation(ClassNames.SKIP_TEST_INJECTION); + if (skipTestAnnotation != null) { + return Optional.of(skipTestAnnotation); + } + + Set<XAnnotation> annotatedAnnotations = testElement().getAnnotationsAnnotatedWith( + ClassNames.SKIP_TEST_INJECTION); + if (!annotatedAnnotations.isEmpty()) { + // Just return the first annotation that skips test injection if there are multiple since + // at this point it doesn't really matter and the specific annotation is only really useful + // for communicating back to the user. + return Optional.of(annotatedAnnotations.iterator().next()); + } + + return Optional.empty(); + } + static TestRootMetadata of(XProcessingEnv env, XElement element) { XTypeElement testElement = XElements.asTypeElement(element); diff --git a/java/dagger/internal/AbstractMapFactory.java b/java/dagger/internal/AbstractMapFactory.java index 1cf83fa1d..22512e9d3 100644 --- a/java/dagger/internal/AbstractMapFactory.java +++ b/java/dagger/internal/AbstractMapFactory.java @@ -22,7 +22,6 @@ import static java.util.Collections.unmodifiableMap; import java.util.LinkedHashMap; import java.util.Map; -import javax.inject.Provider; /** * An {@code abstract} {@link Factory} implementation used to implement {@link Map} bindings. diff --git a/java/dagger/internal/DelegateFactory.java b/java/dagger/internal/DelegateFactory.java index 3b4a30f23..bc5cd9a29 100644 --- a/java/dagger/internal/DelegateFactory.java +++ b/java/dagger/internal/DelegateFactory.java @@ -17,12 +17,11 @@ package dagger.internal; import static dagger.internal.Preconditions.checkNotNull; - -import javax.inject.Provider; +import static dagger.internal.Providers.asDaggerProvider; /** * A DelegateFactory that is used to stitch Provider/Lazy indirection based dependency cycles. - * + * * @since 2.0.1 */ public final class DelegateFactory<T> implements Factory<T> { @@ -44,18 +43,43 @@ public final class DelegateFactory<T> implements Factory<T> { } /** + * Legacy javax version of the method to support libraries compiled with an older version of + * Dagger. Do not use directly. + */ + @Deprecated + public void setDelegatedProvider(javax.inject.Provider<T> delegate) { + setDelegatedProvider(asDaggerProvider(delegate)); + } + + /** * Sets {@code delegateFactory}'s delegate provider to {@code delegate}. * * <p>{@code delegateFactory} must be an instance of {@link DelegateFactory}, otherwise this * method will throw a {@link ClassCastException}. */ public static <T> void setDelegate(Provider<T> delegateFactory, Provider<T> delegate) { - checkNotNull(delegate); DelegateFactory<T> asDelegateFactory = (DelegateFactory<T>) delegateFactory; - if (asDelegateFactory.delegate != null) { + setDelegateInternal(asDelegateFactory, delegate); + } + + /** + * Legacy javax version of the method to support libraries compiled with an older version of + * Dagger. Do not use directly. + */ + @Deprecated + public static <T> void setDelegate( + javax.inject.Provider<T> delegateFactory, javax.inject.Provider<T> delegate) { + DelegateFactory<T> asDelegateFactory = (DelegateFactory<T>) delegateFactory; + setDelegateInternal(asDelegateFactory, asDaggerProvider(delegate)); + } + + private static <T> void setDelegateInternal( + DelegateFactory<T> delegateFactory, Provider<T> delegate) { + checkNotNull(delegate); + if (delegateFactory.delegate != null) { throw new IllegalStateException(); } - asDelegateFactory.delegate = delegate; + delegateFactory.delegate = delegate; } /** @@ -67,4 +91,3 @@ public final class DelegateFactory<T> implements Factory<T> { return checkNotNull(delegate); } } - diff --git a/java/dagger/internal/DoubleCheck.java b/java/dagger/internal/DoubleCheck.java index af7d7f69a..6af866175 100644 --- a/java/dagger/internal/DoubleCheck.java +++ b/java/dagger/internal/DoubleCheck.java @@ -17,9 +17,9 @@ package dagger.internal; import static dagger.internal.Preconditions.checkNotNull; +import static dagger.internal.Providers.asDaggerProvider; import dagger.Lazy; -import javax.inject.Provider; /** * A {@link Lazy} and {@link Provider} implementation that memoizes the value returned from a @@ -73,7 +73,8 @@ public final class DoubleCheck<T> implements Provider<T>, Lazy<T> { /** Returns a {@link Provider} that caches the value from the given delegate provider. */ // This method is declared this way instead of "<T> Provider<T> provider(Provider<T> delegate)" // to work around an Eclipse type inference bug: https://github.com/google/dagger/issues/949. - public static <P extends Provider<T>, T> Provider<T> provider(P delegate) { + public static <P extends dagger.internal.Provider<T>, T> dagger.internal.Provider<T> provider( + P delegate) { checkNotNull(delegate); if (delegate instanceof DoubleCheck) { /* This should be a rare case, but if we have a scoped @Binds that delegates to a scoped @@ -83,6 +84,16 @@ public final class DoubleCheck<T> implements Provider<T>, Lazy<T> { return new DoubleCheck<T>(delegate); } + /** + * Legacy javax version of the method to support libraries compiled with an older version of + * Dagger. Do not use directly. + */ + @Deprecated + public static <P extends javax.inject.Provider<T>, T> javax.inject.Provider<T> provider( + P delegate) { + return provider(asDaggerProvider(delegate)); + } + /** Returns a {@link Lazy} that caches the value from the given provider. */ // This method is declared this way instead of "<T> Lazy<T> lazy(Provider<T> delegate)" // to work around an Eclipse type inference bug: https://github.com/google/dagger/issues/949. @@ -99,4 +110,12 @@ public final class DoubleCheck<T> implements Provider<T>, Lazy<T> { } return new DoubleCheck<T>(checkNotNull(provider)); } + + /** + * Legacy javax version of the method to support libraries compiled with an older version of + * Dagger. Do not use directly. + */ + public static <P extends javax.inject.Provider<T>, T> Lazy<T> lazy(P provider) { + return lazy(asDaggerProvider(provider)); + } } diff --git a/java/dagger/internal/Factory.java b/java/dagger/internal/Factory.java index 9c03f81aa..73bcfbc13 100644 --- a/java/dagger/internal/Factory.java +++ b/java/dagger/internal/Factory.java @@ -18,7 +18,6 @@ package dagger.internal; import dagger.Provides; import javax.inject.Inject; -import javax.inject.Provider; import javax.inject.Scope; /** diff --git a/java/dagger/internal/IdentifierNameString.java b/java/dagger/internal/IdentifierNameString.java new file mode 100644 index 000000000..95d2bfa6f --- /dev/null +++ b/java/dagger/internal/IdentifierNameString.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2024 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.internal; + +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.CLASS; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Annotates the dagger generated class that requires applying -identifiernamestring rule. + * + * <p>When applied, all the strings fields that corresponds to a class name within the annotated + * class will be obfuscated if its corresponding class is obfuscated. This only works with r8. + * + */ +@Documented +@Retention(CLASS) +@Target(TYPE) +public @interface IdentifierNameString {} diff --git a/java/dagger/internal/KeepFieldType.java b/java/dagger/internal/KeepFieldType.java new file mode 100644 index 000000000..090550210 --- /dev/null +++ b/java/dagger/internal/KeepFieldType.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2024 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.internal; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.RetentionPolicy.CLASS; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Annotates the dagger generated field that requires keeping the field types. + * + * <p>Annotating a field with this annotation, the field type's class name won't be discarded or + * obfuscated when compiles with proguard. Note:This will cause the containing class to be kept, and + * only works with proguard. + */ +@Documented +@Retention(CLASS) +@Target(FIELD) +public @interface KeepFieldType {} diff --git a/java/dagger/internal/LazyClassKeyMap.java b/java/dagger/internal/LazyClassKeyMap.java new file mode 100644 index 000000000..dabf86f91 --- /dev/null +++ b/java/dagger/internal/LazyClassKeyMap.java @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2024 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.internal; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +/** + * A class keyed map that delegates to a string keyed map under the hood. + * + * <p>A {@code LazyClassKeyMap} is created for @LazyClassKey contributed map binding. + */ +public final class LazyClassKeyMap<V> implements Map<Class<?>, V> { + private final Map<String, V> delegate; + + public static <V> Map<Class<?>, V> of(Map<String, V> delegate) { + return new LazyClassKeyMap<>(delegate); + } + + private LazyClassKeyMap(Map<String, V> delegate) { + this.delegate = delegate; + } + + @Override + public V get(Object key) { + if (!(key instanceof Class)) { + throw new IllegalArgumentException("Key must be a class"); + } + return delegate.get(((Class<?>) key).getName()); + } + + @Override + public Set<Class<?>> keySet() { + // This method will load all class keys, therefore no need to use @LazyClassKey annotated + // bindings. + throw new UnsupportedOperationException( + "Maps created with @LazyClassKey do not support usage of keySet(). Consider @ClassKey" + + " instead."); + } + + @Override + public Collection<V> values() { + return delegate.values(); + } + + @Override + public boolean isEmpty() { + return delegate.isEmpty(); + } + + @Override + public boolean containsKey(Object key) { + if (!(key instanceof Class)) { + throw new IllegalArgumentException("Key must be a class"); + } + return delegate.containsKey(((Class<?>) key).getName()); + } + + @Override + public boolean containsValue(Object value) { + return delegate.containsValue(value); + } + + @Override + public int size() { + return delegate.size(); + } + + @Override + public Set<Map.Entry<Class<?>, V>> entrySet() { + // This method will load all class keys, therefore no need to use @LazyClassKey annotated + // bindings. + throw new UnsupportedOperationException( + "Maps created with @LazyClassKey do not support usage of entrySet(). Consider @ClassKey" + + " instead."); + } + + // The dagger map binding should be a immutable map. + @Override + public V remove(Object key) { + throw new UnsupportedOperationException("Dagger map bindings are immutable"); + } + + @Override + public void clear() { + throw new UnsupportedOperationException("Dagger map bindings are immutable"); + } + + @Override + public V put(Class<?> key, V value) { + throw new UnsupportedOperationException("Dagger map bindings are immutable"); + } + + @Override + public void putAll(Map<? extends Class<?>, ? extends V> map) { + throw new UnsupportedOperationException("Dagger map bindings are immutable"); + } + + /** A factory for {@code LazyClassKeyMap}. */ + public static class Factory<V> implements Provider<Map<Class<?>, V>> { + MapFactory<String, V> delegate; + + public static <V> Factory<V> of(MapFactory<String, V> delegate) { + return new Factory<>(delegate); + } + + private Factory(MapFactory<String, V> delegate) { + this.delegate = delegate; + } + + @Override + public Map<Class<?>, V> get() { + return LazyClassKeyMap.of(delegate.get()); + } + } +} diff --git a/java/dagger/internal/MapFactory.java b/java/dagger/internal/MapFactory.java index 39748c9ad..376cfdc1c 100644 --- a/java/dagger/internal/MapFactory.java +++ b/java/dagger/internal/MapFactory.java @@ -17,12 +17,12 @@ package dagger.internal; import static dagger.internal.DaggerCollections.newLinkedHashMapWithExpectedSize; +import static dagger.internal.Providers.asDaggerProvider; import static java.util.Collections.unmodifiableMap; import java.util.Collections; import java.util.Map; import java.util.Map.Entry; -import javax.inject.Provider; /** * A {@link Factory} implementation used to implement {@link Map} bindings. This factory returns a @@ -72,12 +72,30 @@ public final class MapFactory<K, V> extends AbstractMapFactory<K, V, V> { return this; } + /** + * Legacy javax version of the method to support libraries compiled with an older version of + * Dagger. Do not use directly. + */ + @Deprecated + public Builder<K, V> put(K key, javax.inject.Provider<V> providerOfValue) { + return put(key, asDaggerProvider(providerOfValue)); + } + @Override public Builder<K, V> putAll(Provider<Map<K, V>> mapFactory) { super.putAll(mapFactory); return this; } + /** + * Legacy javax version of the method to support libraries compiled with an older version of + * Dagger. Do not use directly. + */ + @Deprecated + public Builder<K, V> putAll(javax.inject.Provider<Map<K, V>> mapFactory) { + return putAll(asDaggerProvider(mapFactory)); + } + /** Returns a new {@link MapProviderFactory}. */ public MapFactory<K, V> build() { return new MapFactory<>(map); diff --git a/java/dagger/internal/MapProviderFactory.java b/java/dagger/internal/MapProviderFactory.java index 1fe478856..8491ffc85 100644 --- a/java/dagger/internal/MapProviderFactory.java +++ b/java/dagger/internal/MapProviderFactory.java @@ -16,9 +16,12 @@ package dagger.internal; +import static dagger.internal.DaggerCollections.newLinkedHashMapWithExpectedSize; +import static dagger.internal.Providers.asDaggerProvider; + import dagger.Lazy; +import java.util.Collections; import java.util.Map; -import javax.inject.Provider; /** * A {@link Factory} implementation used to implement {@link Map} bindings. This factory returns a @@ -57,12 +60,43 @@ public final class MapProviderFactory<K, V> extends AbstractMapFactory<K, V, Pro return this; } + /** + * Legacy javax version of the method to support libraries compiled with an older version of + * Dagger. Do not use directly. + */ + @Deprecated + public Builder<K, V> put(K key, javax.inject.Provider<V> providerOfValue) { + return put(key, asDaggerProvider(providerOfValue)); + } + @Override public Builder<K, V> putAll(Provider<Map<K, Provider<V>>> mapProviderFactory) { super.putAll(mapProviderFactory); return this; } + /** + * Legacy javax version of the method to support libraries compiled with an older version of + * Dagger. Do not use directly. + */ + @Deprecated + public Builder<K, V> putAll( + final javax.inject.Provider<Map<K, javax.inject.Provider<V>>> mapProviderFactory) { + return putAll(new Provider<Map<K, Provider<V>>>() { + @Override public Map<K, Provider<V>> get() { + Map<K, javax.inject.Provider<V>> javaxMap = mapProviderFactory.get(); + if (javaxMap.isEmpty()) { + return Collections.emptyMap(); + } + Map<K, Provider<V>> daggerMap = newLinkedHashMapWithExpectedSize(javaxMap.size()); + for (Map.Entry<K, javax.inject.Provider<V>> e : javaxMap.entrySet()) { + daggerMap.put(e.getKey(), asDaggerProvider(e.getValue())); + } + return Collections.unmodifiableMap(daggerMap); + } + }); + } + /** Returns a new {@link MapProviderFactory}. */ public MapProviderFactory<K, V> build() { return new MapProviderFactory<>(map); diff --git a/java/dagger/internal/Provider.java b/java/dagger/internal/Provider.java new file mode 100644 index 000000000..e38860187 --- /dev/null +++ b/java/dagger/internal/Provider.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2023 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.internal; + +/** + * Internal Provider interface to make support for {@code javax.inject.Provider} and + * {@code jakarta.inject.Provider} easier. Do not use outside of Dagger implementation code. + */ +// TODO(erichang): Make this also extend the Jakarta Provider +public interface Provider<T> extends javax.inject.Provider<T> { +} diff --git a/java/dagger/internal/ProviderOfLazy.java b/java/dagger/internal/ProviderOfLazy.java index 23b6afd75..0430cbd6e 100644 --- a/java/dagger/internal/ProviderOfLazy.java +++ b/java/dagger/internal/ProviderOfLazy.java @@ -17,9 +17,9 @@ package dagger.internal; import static dagger.internal.Preconditions.checkNotNull; +import static dagger.internal.Providers.asDaggerProvider; import dagger.Lazy; -import javax.inject.Provider; /** * A {@link Provider} of {@link Lazy} instances that each delegate to a given {@link Provider}. @@ -51,4 +51,13 @@ public final class ProviderOfLazy<T> implements Provider<Lazy<T>> { public static <T> Provider<Lazy<T>> create(Provider<T> provider) { return new ProviderOfLazy<T>(checkNotNull(provider)); } + + /** + * Legacy javax version of the method to support libraries compiled with an older version of + * Dagger. Do not use directly. + */ + @Deprecated + public static <T> Provider<Lazy<T>> create(javax.inject.Provider<T> provider) { + return create(asDaggerProvider(provider)); + } } diff --git a/java/dagger/internal/Providers.java b/java/dagger/internal/Providers.java new file mode 100644 index 000000000..60ec83fa4 --- /dev/null +++ b/java/dagger/internal/Providers.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2023 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.internal; + +import static dagger.internal.Preconditions.checkNotNull; + +/** Helper class for utility functions dealing with Providers. */ +public final class Providers { + + /** Converts a javax provider to a Dagger internal provider. */ + public static <T> Provider<T> asDaggerProvider(final javax.inject.Provider<T> provider) { + checkNotNull(provider); + return new Provider<T>() { + @Override public T get() { + return provider.get(); + } + }; + } + + private Providers() {} +} diff --git a/java/dagger/internal/SetFactory.java b/java/dagger/internal/SetFactory.java index 349399b3e..f16076708 100644 --- a/java/dagger/internal/SetFactory.java +++ b/java/dagger/internal/SetFactory.java @@ -20,6 +20,7 @@ import static dagger.internal.DaggerCollections.hasDuplicates; import static dagger.internal.DaggerCollections.newHashSetWithExpectedSize; import static dagger.internal.DaggerCollections.presizedList; import static dagger.internal.Preconditions.checkNotNull; +import static dagger.internal.Providers.asDaggerProvider; import static java.util.Collections.emptySet; import static java.util.Collections.unmodifiableSet; @@ -27,7 +28,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; -import javax.inject.Provider; /** * A {@link Factory} implementation used to implement {@link Set} bindings. This factory always @@ -73,6 +73,15 @@ public final class SetFactory<T> implements Factory<Set<T>> { return this; } + /** + * Legacy javax version of the method to support libraries compiled with an older version of + * Dagger. Do not use directly. + */ + @Deprecated + public Builder<T> addProvider(javax.inject.Provider<? extends T> individualProvider) { + return addProvider(asDaggerProvider(individualProvider)); + } + @SuppressWarnings("unchecked") public Builder<T> addCollectionProvider( Provider<? extends Collection<? extends T>> collectionProvider) { @@ -81,6 +90,16 @@ public final class SetFactory<T> implements Factory<Set<T>> { return this; } + /** + * Legacy javax version of the method to support libraries compiled with an older version of + * Dagger. Do not use directly. + */ + @Deprecated + public Builder<T> addCollectionProvider( + javax.inject.Provider<? extends Collection<? extends T>> collectionProvider) { + return addCollectionProvider(asDaggerProvider(collectionProvider)); + } + public SetFactory<T> build() { assert !hasDuplicates(individualProviders) : "Codegen error? Duplicates in the provider list"; diff --git a/java/dagger/internal/SingleCheck.java b/java/dagger/internal/SingleCheck.java index 41280699d..32ba83a6f 100644 --- a/java/dagger/internal/SingleCheck.java +++ b/java/dagger/internal/SingleCheck.java @@ -17,8 +17,7 @@ package dagger.internal; import static dagger.internal.Preconditions.checkNotNull; - -import javax.inject.Provider; +import static dagger.internal.Providers.asDaggerProvider; /** * A {@link Provider} implementation that memoizes the result of another {@link Provider} using @@ -58,7 +57,7 @@ public final class SingleCheck<T> implements Provider<T> { } /** Returns a {@link Provider} that caches the value from the given delegate provider. */ - // This method is declared this way instead of "<T> Provider<T> provider(Provider<T> provider)" + // This method is declared this way instead of "<T> Provider<T> provider(Provider<T> provider)" // to work around an Eclipse type inference bug: https://github.com/google/dagger/issues/949. public static <P extends Provider<T>, T> Provider<T> provider(P provider) { // If a scoped @Binds delegates to a scoped binding, don't cache the value again. @@ -67,4 +66,13 @@ public final class SingleCheck<T> implements Provider<T> { } return new SingleCheck<T>(checkNotNull(provider)); } + + /** + * Legacy javax version of the method to support libraries compiled with an older version of + * Dagger. Do not use directly. + */ + public static <P extends javax.inject.Provider<T>, T> javax.inject.Provider<T> provider( + P delegate) { + return provider(asDaggerProvider(delegate)); + } } diff --git a/java/dagger/internal/codegen/BUILD b/java/dagger/internal/codegen/BUILD index a3868b529..80ca8d7dc 100644 --- a/java/dagger/internal/codegen/BUILD +++ b/java/dagger/internal/codegen/BUILD @@ -43,7 +43,6 @@ java_library( "//java/dagger/internal/codegen/compileroption", "//java/dagger/internal/codegen/componentgenerator", "//java/dagger/internal/codegen/kotlin", - "//java/dagger/internal/codegen/model", "//java/dagger/internal/codegen/processingstep", "//java/dagger/internal/codegen/validation", "//java/dagger/internal/codegen/writing", @@ -89,7 +88,6 @@ gen_maven_artifact( ], artifact_target_maven_deps = [ "com.google.code.findbugs:jsr305", - "com.google.dagger:dagger-producers", "com.google.dagger:dagger-spi", "com.google.dagger:dagger", "com.google.devtools.ksp:symbol-processing-api", diff --git a/java/dagger/internal/codegen/DelegateComponentProcessor.java b/java/dagger/internal/codegen/DelegateComponentProcessor.java index 96d433b40..432daa686 100644 --- a/java/dagger/internal/codegen/DelegateComponentProcessor.java +++ b/java/dagger/internal/codegen/DelegateComponentProcessor.java @@ -32,10 +32,13 @@ import dagger.Provides; import dagger.internal.codegen.base.ClearableCache; import dagger.internal.codegen.base.SourceFileGenerationException; import dagger.internal.codegen.base.SourceFileGenerator; +import dagger.internal.codegen.base.SourceFileHjarGenerator; import dagger.internal.codegen.binding.BindingGraphFactory; +import dagger.internal.codegen.binding.ComponentDescriptor; import dagger.internal.codegen.binding.InjectBindingRegistry; import dagger.internal.codegen.binding.MembersInjectionBinding; import dagger.internal.codegen.binding.ModuleDescriptor; +import dagger.internal.codegen.binding.MonitoringModules; import dagger.internal.codegen.binding.ProductionBinding; import dagger.internal.codegen.binding.ProvisionBinding; import dagger.internal.codegen.bindinggraphvalidation.BindingGraphValidationModule; @@ -53,7 +56,6 @@ import dagger.internal.codegen.validation.InjectBindingRegistryModule; import dagger.internal.codegen.validation.InjectValidator; import dagger.internal.codegen.validation.ValidationBindingGraphPlugins; import dagger.internal.codegen.writing.FactoryGenerator; -import dagger.internal.codegen.writing.HjarSourceFileGenerator; import dagger.internal.codegen.writing.MembersInjectorGenerator; import dagger.internal.codegen.writing.ModuleGenerator; import dagger.internal.codegen.writing.ModuleProxies.ModuleConstructorProxyGenerator; @@ -98,8 +100,9 @@ final class DelegateComponentProcessor { + legacyPlugin.pluginName() + ". Either compile with KAPT or migrate the plugin to implement " + "dagger.spi.model.BindingGraphPlugin.")); - // We've already reported warnings on the invalid legacy plugins above. We can't actually - // process these plugins in KSP, so just skip them to allow processing of the valid plugins. + // Even though we've reported an error, processing will still continue for the remainder of + // the processing round to try to catch other errors. We set the javac plugins to empty to + // skip processing since it would just result in ClassCastExceptions in KSP. legacyPlugins = ImmutableSet.of(); } DaggerDelegateComponentProcessor_Injector.factory() @@ -171,6 +174,14 @@ final class DelegateComponentProcessor { @Binds @IntoSet + ClearableCache componentDescriptorFactory(ComponentDescriptor.Factory cache); + + @Binds + @IntoSet + ClearableCache monitoringModules(MonitoringModules cache); + + @Binds + @IntoSet ClearableCache bindingGraphFactory(BindingGraphFactory cache); @Binds @@ -190,34 +201,44 @@ final class DelegateComponentProcessor { interface SourceFileGeneratorsModule { @Provides static SourceFileGenerator<ProvisionBinding> factoryGenerator( - FactoryGenerator generator, CompilerOptions compilerOptions) { - return hjarWrapper(generator, compilerOptions); + FactoryGenerator generator, + CompilerOptions compilerOptions, + XProcessingEnv processingEnv) { + return hjarWrapper(generator, compilerOptions, processingEnv); } @Provides static SourceFileGenerator<ProductionBinding> producerFactoryGenerator( - ProducerFactoryGenerator generator, CompilerOptions compilerOptions) { - return hjarWrapper(generator, compilerOptions); + ProducerFactoryGenerator generator, + CompilerOptions compilerOptions, + XProcessingEnv processingEnv) { + return hjarWrapper(generator, compilerOptions, processingEnv); } @Provides static SourceFileGenerator<MembersInjectionBinding> membersInjectorGenerator( - MembersInjectorGenerator generator, CompilerOptions compilerOptions) { - return hjarWrapper(generator, compilerOptions); + MembersInjectorGenerator generator, + CompilerOptions compilerOptions, + XProcessingEnv processingEnv) { + return hjarWrapper(generator, compilerOptions, processingEnv); } @Provides @ModuleGenerator static SourceFileGenerator<XTypeElement> moduleConstructorProxyGenerator( - ModuleConstructorProxyGenerator generator, CompilerOptions compilerOptions) { - return hjarWrapper(generator, compilerOptions); + ModuleConstructorProxyGenerator generator, + CompilerOptions compilerOptions, + XProcessingEnv processingEnv) { + return hjarWrapper(generator, compilerOptions, processingEnv); } } private static <T> SourceFileGenerator<T> hjarWrapper( - SourceFileGenerator<T> generator, CompilerOptions compilerOptions) { + SourceFileGenerator<T> generator, + CompilerOptions compilerOptions, + XProcessingEnv processingEnv) { return compilerOptions.headerCompilation() - ? HjarSourceFileGenerator.wrap(generator) + ? SourceFileHjarGenerator.wrap(generator, processingEnv) : generator; } } diff --git a/java/dagger/internal/codegen/base/ElementFormatter.java b/java/dagger/internal/codegen/base/ElementFormatter.java index 16381e32f..8e3edc955 100644 --- a/java/dagger/internal/codegen/base/ElementFormatter.java +++ b/java/dagger/internal/codegen/base/ElementFormatter.java @@ -36,7 +36,8 @@ import javax.inject.Inject; * * <p>Elements directly enclosed by a type are preceded by the enclosing type's qualified name. * - * <p>Parameters are given with their enclosing executable, with other parameters elided. + * <p>If the element is a parameter, the returned string will include the enclosing executable, + * with other parameters elided. */ public final class ElementFormatter extends Formatter<XElement> { @Inject @@ -52,15 +53,29 @@ public final class ElementFormatter extends Formatter<XElement> { * * <p>Elements directly enclosed by a type are preceded by the enclosing type's qualified name. * - * <p>Parameters are given with their enclosing executable, with other parameters elided. + * <p>If the element is a parameter, the returned string will include the enclosing executable, + * with other parameters elided. */ public static String elementToString(XElement element) { + return elementToString(element, /* elideMethodParameterTypes= */ false); + } + + /** + * Returns a useful string form for an element. + * + * <p>Elements directly enclosed by a type are preceded by the enclosing type's qualified name. + * + * <p>Parameters are given with their enclosing executable, with other parameters elided. + */ + public static String elementToString(XElement element, boolean elideMethodParameterTypes) { if (isExecutable(element)) { return enclosingTypeAndMemberName(element) .append( - asExecutable(element).getParameters().stream() - .map(parameter -> XTypes.toStableString(parameter.getType())) - .collect(joining(", ", "(", ")"))) + elideMethodParameterTypes + ? (asExecutable(element).getParameters().isEmpty() ? "()" : "(…)") + : asExecutable(element).getParameters().stream() + .map(parameter -> XTypes.toStableString(parameter.getType())) + .collect(joining(", ", "(", ")"))) .toString(); } else if (isMethodParameter(element)) { XExecutableElement methodOrConstructor = asMethodParameter(element).getEnclosingElement(); diff --git a/java/dagger/internal/codegen/base/FrameworkTypes.java b/java/dagger/internal/codegen/base/FrameworkTypes.java index 59588caf5..e39aeabea 100644 --- a/java/dagger/internal/codegen/base/FrameworkTypes.java +++ b/java/dagger/internal/codegen/base/FrameworkTypes.java @@ -29,6 +29,7 @@ import java.util.Set; * type that the framework itself defines. */ public final class FrameworkTypes { + // TODO(erichang): Add the Jakarta Provider here private static final ImmutableSet<ClassName> PROVISION_TYPES = ImmutableSet.of(TypeNames.PROVIDER, TypeNames.LAZY, TypeNames.MEMBERS_INJECTOR); diff --git a/java/dagger/internal/codegen/base/MapType.java b/java/dagger/internal/codegen/base/MapType.java index 00401ed72..c4ba838e8 100644 --- a/java/dagger/internal/codegen/base/MapType.java +++ b/java/dagger/internal/codegen/base/MapType.java @@ -115,6 +115,13 @@ public abstract class MapType { return isMap(key.type().xprocessing()); } + public static boolean isMapOfProvider(XType keyType) { + if (MapType.isMap(keyType)) { + return MapType.from(keyType).valuesAreTypeOf(TypeNames.PROVIDER); + } + return false; + } + /** * Returns a {@link MapType} for {@code type}. * diff --git a/java/dagger/internal/codegen/base/OptionalType.java b/java/dagger/internal/codegen/base/OptionalType.java index 79b638d4a..5544eaeba 100644 --- a/java/dagger/internal/codegen/base/OptionalType.java +++ b/java/dagger/internal/codegen/base/OptionalType.java @@ -20,6 +20,7 @@ import static com.google.common.base.Preconditions.checkArgument; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableMap; import static dagger.internal.codegen.extension.DaggerStreams.valuesOf; import static dagger.internal.codegen.xprocessing.XTypes.isDeclared; +import static dagger.internal.codegen.xprocessing.XTypes.isTypeOf; import androidx.room.compiler.processing.XType; import androidx.room.compiler.processing.XTypeElement; @@ -155,4 +156,14 @@ public abstract class OptionalType { public static OptionalType from(Key key) { return from(key.type().xprocessing()); } + + public static boolean isOptionalProviderType(XType type) { + if (OptionalType.isOptional(type)) { + OptionalType optionalType = OptionalType.from(type); + if (isTypeOf(optionalType.valueType(), TypeNames.PROVIDER)) { + return true; + } + } + return false; + } } diff --git a/java/dagger/internal/codegen/base/SourceFileGenerator.java b/java/dagger/internal/codegen/base/SourceFileGenerator.java index c43499a50..dfe14b1d5 100644 --- a/java/dagger/internal/codegen/base/SourceFileGenerator.java +++ b/java/dagger/internal/codegen/base/SourceFileGenerator.java @@ -18,6 +18,7 @@ package dagger.internal.codegen.base; import static androidx.room.compiler.processing.JavaPoetExtKt.addOriginatingElement; import static com.google.common.base.Preconditions.checkNotNull; +import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.CAST; import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.KOTLIN_INTERNAL; import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.RAWTYPES; import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.UNCHECKED; @@ -100,13 +101,12 @@ public abstract class SourceFileGenerator<T> { .build()); generatedAnnotation.ifPresent(typeSpecBuilder::addAnnotation); - // TODO(b/134590785): Remove UNCHECKED/RAWTYPES and suppress locally where necessary. // TODO(b/263891456): Remove KOTLIN_INTERNAL and use Object/raw types where necessary. typeSpecBuilder.addAnnotation( AnnotationSpecs.suppressWarnings( ImmutableSet.<Suppression>builder() .addAll(warningSuppressions()) - .add(UNCHECKED, RAWTYPES, KOTLIN_INTERNAL) + .add(UNCHECKED, RAWTYPES, KOTLIN_INTERNAL, CAST) .build())); String packageName = closestEnclosingTypeElement(originatingElement).getPackageName(); diff --git a/java/dagger/internal/codegen/base/SourceFileHjarGenerator.java b/java/dagger/internal/codegen/base/SourceFileHjarGenerator.java new file mode 100644 index 000000000..6857c366f --- /dev/null +++ b/java/dagger/internal/codegen/base/SourceFileHjarGenerator.java @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2017 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.internal.codegen.base; + +import static com.squareup.javapoet.MethodSpec.constructorBuilder; +import static com.squareup.javapoet.MethodSpec.methodBuilder; +import static com.squareup.javapoet.TypeSpec.classBuilder; +import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; +import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; +import static dagger.internal.codegen.langmodel.Accessibility.isElementAccessibleFrom; +import static dagger.internal.codegen.xprocessing.XElements.closestEnclosingTypeElement; +import static javax.lang.model.element.Modifier.PRIVATE; + +import androidx.room.compiler.processing.XConstructorElement; +import androidx.room.compiler.processing.XElement; +import androidx.room.compiler.processing.XExecutableParameterElement; +import androidx.room.compiler.processing.XProcessingEnv; +import androidx.room.compiler.processing.XType; +import androidx.room.compiler.processing.XTypeElement; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.CodeBlock; +import com.squareup.javapoet.FieldSpec; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.TypeName; +import com.squareup.javapoet.TypeSpec; +import dagger.internal.codegen.javapoet.CodeBlocks; +import dagger.internal.codegen.javapoet.TypeNames; +import java.util.Optional; +import javax.lang.model.element.Modifier; + +/** + * A source file generator that only writes the relevant code necessary for Bazel to create a + * correct header (ABI) jar. + */ +public final class SourceFileHjarGenerator<T> extends SourceFileGenerator<T> { + public static <T> SourceFileGenerator<T> wrap( + SourceFileGenerator<T> delegate, XProcessingEnv processingEnv) { + return new SourceFileHjarGenerator<>(delegate, processingEnv); + } + + private final SourceFileGenerator<T> delegate; + private final XProcessingEnv processingEnv; + + private SourceFileHjarGenerator(SourceFileGenerator<T> delegate, XProcessingEnv processingEnv) { + super(delegate); + this.delegate = delegate; + this.processingEnv = processingEnv; + } + + @Override + public XElement originatingElement(T input) { + return delegate.originatingElement(input); + } + + @Override + public ImmutableList<TypeSpec.Builder> topLevelTypes(T input) { + String packageName = closestEnclosingTypeElement(originatingElement(input)).getPackageName(); + return delegate.topLevelTypes(input).stream() + .map(completeType -> skeletonType(packageName, completeType.build())) + .collect(toImmutableList()); + } + + private TypeSpec.Builder skeletonType(String packageName, TypeSpec completeType) { + TypeSpec.Builder skeleton = + classBuilder(completeType.name) + .addSuperinterfaces(completeType.superinterfaces) + .addTypeVariables(completeType.typeVariables) + .addModifiers(completeType.modifiers.toArray(new Modifier[0])) + .addAnnotations(completeType.annotations); + + if (!completeType.superclass.equals(ClassName.OBJECT)) { + skeleton.superclass(completeType.superclass); + } + + completeType.methodSpecs.stream() + .filter(method -> !method.modifiers.contains(PRIVATE) || method.isConstructor()) + .map(completeMethod -> skeletonMethod(packageName, completeType, completeMethod)) + .forEach(skeleton::addMethod); + + completeType.fieldSpecs.stream() + .filter(field -> !field.modifiers.contains(PRIVATE)) + .map(this::skeletonField) + .forEach(skeleton::addField); + + completeType.typeSpecs.stream() + .map(type -> skeletonType(packageName, type).build()) + .forEach(skeleton::addType); + + completeType.alwaysQualifiedNames + .forEach(skeleton::alwaysQualify); + + return skeleton; + } + + private MethodSpec skeletonMethod( + String packageName, TypeSpec completeType, MethodSpec completeMethod) { + MethodSpec.Builder skeleton = + completeMethod.isConstructor() + ? constructorBuilder() + : methodBuilder(completeMethod.name).returns(completeMethod.returnType); + + if (completeMethod.isConstructor()) { + getRequiredSuperCall(packageName, completeType) + .ifPresent(superCall -> skeleton.addStatement("$L", superCall)); + } else if (!completeMethod.returnType.equals(TypeName.VOID)) { + skeleton.addStatement("return $L", getDefaultValueCodeBlock(completeMethod.returnType)); + } + + return skeleton + .addModifiers(completeMethod.modifiers) + .addTypeVariables(completeMethod.typeVariables) + .addParameters(completeMethod.parameters) + .addExceptions(completeMethod.exceptions) + .varargs(completeMethod.varargs) + .addAnnotations(completeMethod.annotations) + .build(); + } + + private Optional<CodeBlock> getRequiredSuperCall(String packageName, TypeSpec completeType) { + if (completeType.superclass.equals(TypeName.OBJECT)) { + return Optional.empty(); + } + + ClassName rawSuperClass = (ClassName) TypeNames.rawTypeName(completeType.superclass); + XTypeElement superTypeElement = + processingEnv.requireTypeElement(rawSuperClass.canonicalName()); + + ImmutableSet<XConstructorElement> accessibleConstructors = + superTypeElement.getConstructors().stream() + .filter( + constructor -> + // isElementAccessibleFrom doesn't take protected into account so check manually + constructor.isProtected() + || isElementAccessibleFrom(constructor, packageName)) + .collect(toImmutableSet()); + + // If there's an accessible default constructor we don't need to call super() manually. + if (accessibleConstructors.isEmpty() + || accessibleConstructors.stream() + .anyMatch(constructor -> constructor.getParameters().isEmpty())) { + return Optional.empty(); + } + + return Optional.of( + CodeBlock.of( + "super($L)", + CodeBlocks.makeParametersCodeBlock( + // We just choose the first constructor (it doesn't really matter since we're just + // trying to ensure the constructor body compiles). + accessibleConstructors.stream().findFirst().get().getParameters().stream() + .map(XExecutableParameterElement::getType) + .map(XType::getTypeName) + .map(SourceFileHjarGenerator::getDefaultValueCodeBlock) + .collect(toImmutableList())))); + } + + /** + * Returns a {@link CodeBlock} containing the default value for the given {@code typeName}. + * + * <p>See https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html. + */ + private static CodeBlock getDefaultValueCodeBlock(TypeName typeName) { + if (typeName.isPrimitive()) { + if (typeName.equals(TypeName.BOOLEAN)) { + return CodeBlock.of("false"); + } else if (typeName.equals(TypeName.CHAR)) { + return CodeBlock.of("'\u0000'"); + } else if (typeName.equals(TypeName.BYTE)) { + return CodeBlock.of("0"); + } else if (typeName.equals(TypeName.SHORT)) { + return CodeBlock.of("0"); + } else if (typeName.equals(TypeName.INT)) { + return CodeBlock.of("0"); + } else if (typeName.equals(TypeName.LONG)) { + return CodeBlock.of("0L"); + } else if (typeName.equals(TypeName.FLOAT)) { + return CodeBlock.of("0.0f"); + } else if (typeName.equals(TypeName.DOUBLE)) { + return CodeBlock.of("0.0d"); + } else { + throw new AssertionError("Unexpected type: " + typeName); + } + } + return CodeBlock.of("null"); + } + + private FieldSpec skeletonField(FieldSpec completeField) { + return FieldSpec.builder( + completeField.type, + completeField.name, + completeField.modifiers.toArray(new Modifier[0])) + .addAnnotations(completeField.annotations) + .build(); + } +} diff --git a/java/dagger/internal/codegen/base/TarjanSCCs.java b/java/dagger/internal/codegen/base/TarjanSCCs.java index ab9a0fdae..b089333b0 100644 --- a/java/dagger/internal/codegen/base/TarjanSCCs.java +++ b/java/dagger/internal/codegen/base/TarjanSCCs.java @@ -20,6 +20,7 @@ import static com.google.common.base.Preconditions.checkState; import static java.lang.Math.min; import com.google.common.collect.ImmutableCollection; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; import com.google.common.collect.Sets; @@ -39,7 +40,7 @@ import java.util.Set; public final class TarjanSCCs { /** Returns the set of strongly connected components in reverse topological order. */ - public static <NodeT> ImmutableSet<ImmutableSet<NodeT>> compute( + public static <NodeT> ImmutableList<ImmutableSet<NodeT>> compute( ImmutableCollection<NodeT> nodes, SuccessorsFunction<NodeT> successorsFunction) { return new TarjanSCC<>(nodes, successorsFunction).compute(); } @@ -62,14 +63,14 @@ public final class TarjanSCCs { this.lowLinks = Maps.newHashMapWithExpectedSize(nodes.size()); } - private ImmutableSet<ImmutableSet<NodeT>> compute() { + private ImmutableList<ImmutableSet<NodeT>> compute() { checkState(indexes.isEmpty(), "TarjanSCC#compute() can only be called once per instance!"); for (NodeT node : nodes) { if (!indexes.containsKey(node)) { stronglyConnect(node); } } - return ImmutableSet.copyOf(stronglyConnectedComponents); + return ImmutableList.copyOf(stronglyConnectedComponents); } private void stronglyConnect(NodeT node) { diff --git a/java/dagger/internal/codegen/binding/AnnotationExpression.java b/java/dagger/internal/codegen/binding/AnnotationExpression.java index 6980c1437..535a7ef57 100644 --- a/java/dagger/internal/codegen/binding/AnnotationExpression.java +++ b/java/dagger/internal/codegen/binding/AnnotationExpression.java @@ -112,7 +112,7 @@ public final class AnnotationExpression { } else if (value.hasAnnotationValue()) { return getAnnotationInstanceExpression(value.asAnnotation()); } else if (value.hasTypeValue()) { - return CodeBlock.of("$T.class", value.asType().getTypeName()); + return CodeBlock.of("$T.class", value.asType().getTypeElement().getClassName()); } else if (value.hasStringValue()) { return CodeBlock.of("$S", value.asString()); } else if (value.hasByteValue()) { diff --git a/java/dagger/internal/codegen/binding/AssistedInjectionAnnotations.java b/java/dagger/internal/codegen/binding/AssistedInjectionAnnotations.java index a8bca0956..50a36b937 100644 --- a/java/dagger/internal/codegen/binding/AssistedInjectionAnnotations.java +++ b/java/dagger/internal/codegen/binding/AssistedInjectionAnnotations.java @@ -22,11 +22,11 @@ import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; import static dagger.internal.codegen.xprocessing.XElements.asConstructor; import static dagger.internal.codegen.xprocessing.XElements.asTypeElement; -import static dagger.internal.codegen.xprocessing.XElements.getSimpleName; import androidx.room.compiler.processing.XConstructorElement; import androidx.room.compiler.processing.XConstructorType; import androidx.room.compiler.processing.XElement; +import androidx.room.compiler.processing.XExecutableParameterElement; import androidx.room.compiler.processing.XHasModifiers; import androidx.room.compiler.processing.XMethodElement; import androidx.room.compiler.processing.XMethodType; @@ -90,14 +90,15 @@ public final class AssistedInjectionAnnotations { } private static ImmutableList<ParameterSpec> assistedParameterSpecs( - List<? extends XVariableElement> paramElements, List<XType> paramTypes) { + List<? extends XExecutableParameterElement> paramElements, List<XType> paramTypes) { ImmutableList.Builder<ParameterSpec> assistedParameterSpecs = ImmutableList.builder(); for (int i = 0; i < paramElements.size(); i++) { - XVariableElement paramElement = paramElements.get(i); + XExecutableParameterElement paramElement = paramElements.get(i); XType paramType = paramTypes.get(i); if (isAssistedParameter(paramElement)) { assistedParameterSpecs.add( - ParameterSpec.builder(paramType.getTypeName(), getSimpleName(paramElement)).build()); + ParameterSpec.builder(paramType.getTypeName(), paramElement.getJvmName()) + .build()); } } return assistedParameterSpecs.build(); @@ -133,7 +134,7 @@ public final class AssistedInjectionAnnotations { .collect(toImmutableSet()); } - public static ImmutableList<XVariableElement> assistedParameters(Binding binding) { + public static ImmutableList<XExecutableParameterElement> assistedParameters(Binding binding) { return binding.kind() == BindingKind.ASSISTED_INJECTION ? asConstructor(binding.bindingElement().get()).getParameters().stream() .filter(AssistedInjectionAnnotations::isAssistedParameter) @@ -184,8 +185,10 @@ public final class AssistedInjectionAnnotations { public abstract ImmutableList<AssistedParameter> assistedFactoryAssistedParameters(); @Memoized - public ImmutableMap<AssistedParameter, XVariableElement> assistedInjectAssistedParametersMap() { - ImmutableMap.Builder<AssistedParameter, XVariableElement> builder = ImmutableMap.builder(); + public ImmutableMap<AssistedParameter, XExecutableParameterElement> + assistedInjectAssistedParametersMap() { + ImmutableMap.Builder<AssistedParameter, XExecutableParameterElement> builder = + ImmutableMap.builder(); for (AssistedParameter assistedParameter : assistedInjectAssistedParameters()) { builder.put(assistedParameter, assistedParameter.element()); } @@ -193,9 +196,10 @@ public final class AssistedInjectionAnnotations { } @Memoized - public ImmutableMap<AssistedParameter, XVariableElement> + public ImmutableMap<AssistedParameter, XExecutableParameterElement> assistedFactoryAssistedParametersMap() { - ImmutableMap.Builder<AssistedParameter, XVariableElement> builder = ImmutableMap.builder(); + ImmutableMap.Builder<AssistedParameter, XExecutableParameterElement> builder = + ImmutableMap.builder(); for (AssistedParameter assistedParameter : assistedFactoryAssistedParameters()) { builder.put(assistedParameter, assistedParameter.element()); } @@ -211,7 +215,8 @@ public final class AssistedInjectionAnnotations { */ @AutoValue public abstract static class AssistedParameter { - public static AssistedParameter create(XVariableElement parameter, XType parameterType) { + public static AssistedParameter create( + XExecutableParameterElement parameter, XType parameterType) { AssistedParameter assistedParameter = new AutoValue_AssistedInjectionAnnotations_AssistedParameter( Optional.ofNullable(parameter.getAnnotation(TypeNames.ASSISTED)) @@ -223,7 +228,7 @@ public final class AssistedInjectionAnnotations { return assistedParameter; } - private XVariableElement parameterElement; + private XExecutableParameterElement parameterElement; private XType parameterType; /** Returns the string qualifier from the {@link Assisted#value()}. */ @@ -237,7 +242,7 @@ public final class AssistedInjectionAnnotations { return parameterType; } - public final XVariableElement element() { + public final XExecutableParameterElement element() { return parameterElement; } @@ -260,7 +265,7 @@ public final class AssistedInjectionAnnotations { ImmutableList.Builder<AssistedParameter> builder = ImmutableList.builder(); for (int i = 0; i < assistedInjectConstructor.getParameters().size(); i++) { - XVariableElement parameter = assistedInjectConstructor.getParameters().get(i); + XExecutableParameterElement parameter = assistedInjectConstructor.getParameters().get(i); XType parameterType = assistedInjectConstructorType.getParameterTypes().get(i); if (parameter.hasAnnotation(TypeNames.ASSISTED)) { builder.add(AssistedParameter.create(parameter, parameterType)); @@ -273,7 +278,7 @@ public final class AssistedInjectionAnnotations { XMethodElement factoryMethod, XMethodType factoryMethodType) { ImmutableList.Builder<AssistedParameter> builder = ImmutableList.builder(); for (int i = 0; i < factoryMethod.getParameters().size(); i++) { - XVariableElement parameter = factoryMethod.getParameters().get(i); + XExecutableParameterElement parameter = factoryMethod.getParameters().get(i); XType parameterType = factoryMethodType.getParameterTypes().get(i); builder.add(AssistedParameter.create(parameter, parameterType)); } diff --git a/java/dagger/internal/codegen/binding/BUILD b/java/dagger/internal/codegen/binding/BUILD index e606eb414..7ba349e5b 100644 --- a/java/dagger/internal/codegen/binding/BUILD +++ b/java/dagger/internal/codegen/binding/BUILD @@ -31,11 +31,8 @@ java_library( "//java/dagger/internal/codegen/extension", "//java/dagger/internal/codegen/javapoet", "//java/dagger/internal/codegen/kotlin", - "//java/dagger/internal/codegen/langmodel", "//java/dagger/internal/codegen/model", "//java/dagger/internal/codegen/xprocessing", - "//java/dagger/producers", - "//third_party/java/auto:common", "//third_party/java/auto:value", "//third_party/java/error_prone:annotations", "//third_party/java/guava/base", diff --git a/java/dagger/internal/codegen/binding/BindingGraph.java b/java/dagger/internal/codegen/binding/BindingGraph.java index 8dfe74f5f..0090b3d2a 100644 --- a/java/dagger/internal/codegen/binding/BindingGraph.java +++ b/java/dagger/internal/codegen/binding/BindingGraph.java @@ -149,7 +149,7 @@ public abstract class BindingGraph { /** Returns the set of strongly connected nodes in this graph in reverse topological order. */ @Memoized - public ImmutableSet<ImmutableSet<Node>> stronglyConnectedNodes() { + public ImmutableList<ImmutableSet<Node>> stronglyConnectedNodes() { return TarjanSCCs.<Node>compute( ImmutableSet.copyOf(network().nodes()), // NetworkBuilder does not have a stable successor order, so we have to roll our own @@ -212,14 +212,7 @@ public abstract class BindingGraph { // particular BindingNode. Map<Key, BindingNode> contributionBindings = new LinkedHashMap<>(); Map<Key, BindingNode> membersInjectionBindings = new LinkedHashMap<>(); - - // Construct the maps of the ContributionBindings and MembersInjectionBindings by iterating - // bindings from this component and then from each successive parent. If a binding exists in - // multple components, this order ensures that the child-most binding is always chosen first. - Stream.iterate(componentNode.componentPath(), ComponentPath::parent) - // Stream.iterate is inifinte stream so we need limit it to the known size of the path. - .limit(componentNode.componentPath().components().size()) - .flatMap(path -> topLevelBindingGraph.bindingsByComponent().get(path).stream()) + topLevelBindingGraph.bindingsByComponent().get(componentNode.componentPath()) .forEach( bindingNode -> { if (bindingNode.delegate() instanceof ContributionBinding) { @@ -233,16 +226,19 @@ public abstract class BindingGraph { BindingGraph bindingGraph = new AutoValue_BindingGraph(componentNode, topLevelBindingGraph); - ImmutableSet<ModuleDescriptor> modules = - ((ComponentNodeImpl) componentNode).componentDescriptor().modules(); + ImmutableSet<XTypeElement> modules = + ((ComponentNodeImpl) componentNode).componentDescriptor().modules().stream() + .map(ModuleDescriptor::moduleElement) + .collect(toImmutableSet()); - ImmutableSet<ModuleDescriptor> inheritedModules = + ImmutableSet<XTypeElement> inheritedModules = parent.isPresent() ? Sets.union(parent.get().ownedModules, parent.get().inheritedModules).immutableCopy() : ImmutableSet.of(); // Set these fields directly on the instance rather than passing these in as input to the // AutoValue to prevent exposing this data outside of the class. + bindingGraph.parent = parent; bindingGraph.inheritedModules = inheritedModules; bindingGraph.ownedModules = Sets.difference(modules, inheritedModules).immutableCopy(); bindingGraph.contributionBindings = ImmutableMap.copyOf(contributionBindings); @@ -257,10 +253,11 @@ public abstract class BindingGraph { return bindingGraph; } + private Optional<BindingGraph> parent; private ImmutableMap<Key, BindingNode> contributionBindings; private ImmutableMap<Key, BindingNode> membersInjectionBindings; - private ImmutableSet<ModuleDescriptor> inheritedModules; - private ImmutableSet<ModuleDescriptor> ownedModules; + private ImmutableSet<XTypeElement> inheritedModules; + private ImmutableSet<XTypeElement> ownedModules; private ImmutableSet<XTypeElement> bindingModules; BindingGraph() {} @@ -287,9 +284,7 @@ public abstract class BindingGraph { */ public final Optional<Binding> localContributionBinding(Key key) { return contributionBindings.containsKey(key) - ? Optional.of(contributionBindings.get(key)) - .filter(bindingNode -> bindingNode.componentPath().equals(componentPath())) - .map(BindingNode::delegate) + ? Optional.of(contributionBindings.get(key).delegate()) : Optional.empty(); } @@ -299,15 +294,18 @@ public abstract class BindingGraph { */ public final Optional<Binding> localMembersInjectionBinding(Key key) { return membersInjectionBindings.containsKey(key) - ? Optional.of(membersInjectionBindings.get(key)) - .filter(bindingNode -> bindingNode.componentPath().equals(componentPath())) - .map(BindingNode::delegate) + ? Optional.of(membersInjectionBindings.get(key).delegate()) : Optional.empty(); } /** Returns the {@link ContributionBinding} for the given {@link Key}. */ public final ContributionBinding contributionBinding(Key key) { - return (ContributionBinding) contributionBindings.get(key).delegate(); + if (contributionBindings.containsKey(key)) { + return (ContributionBinding) contributionBindings.get(key).delegate(); + } else if (parent.isPresent()) { + return parent.get().contributionBinding(key); + } + throw new AssertionError("Contribution binding not found for key: " + key); } /** @@ -315,9 +313,12 @@ public abstract class BindingGraph { * Optional#empty()} if one does not exist. */ public final Optional<MembersInjectionBinding> membersInjectionBinding(Key key) { - return membersInjectionBindings.containsKey(key) - ? Optional.of((MembersInjectionBinding) membersInjectionBindings.get(key).delegate()) - : Optional.empty(); + if (membersInjectionBindings.containsKey(key)) { + return Optional.of((MembersInjectionBinding) membersInjectionBindings.get(key).delegate()); + } else if (parent.isPresent()) { + return parent.get().membersInjectionBinding(key); + } + return Optional.empty(); } /** Returns the {@link XTypeElement} for the component this graph represents. */ @@ -334,9 +335,7 @@ public abstract class BindingGraph { * ancestors. */ public final ImmutableSet<XTypeElement> ownedModuleTypes() { - return ownedModules.stream() - .map(ModuleDescriptor::moduleElement) - .collect(toImmutableSet()); + return ownedModules; } /** @@ -394,7 +393,7 @@ public abstract class BindingGraph { ImmutableSet<XTypeElement> requiredModules = stream(Traverser.forTree(BindingGraph::subgraphs).depthFirstPostOrder(this)) .flatMap(graph -> graph.bindingModules.stream()) - .filter(ownedModuleTypes()::contains) + .filter(ownedModules::contains) .collect(toImmutableSet()); ImmutableSet.Builder<ComponentRequirement> requirements = ImmutableSet.builder(); componentDescriptor().requirements().stream() @@ -433,11 +432,18 @@ public abstract class BindingGraph { return topLevelBindingGraph().bindingsByComponent().get(componentPath()); } - @Memoized + // TODO(bcorso): This method can be costly. Consider removing this method and inlining it into its + // only usage, BindingGraphJsonGenerator. public ImmutableSet<BindingNode> bindingNodes() { - return ImmutableSet.<BindingNode>builder() - .addAll(contributionBindings.values()) - .addAll(membersInjectionBindings.values()) - .build(); + // Construct the set of bindings by iterating bindings from this component and then from each + // successive parent. If a binding exists in multiple components, this order ensures that the + // child-most binding is always chosen first. + Map<Key, BindingNode> bindings = new LinkedHashMap<>(); + Stream.iterate(componentPath(), ComponentPath::parent) + // Stream.iterate() is infinite stream so we need limit it to the known size of the path. + .limit(componentPath().components().size()) + .flatMap(path -> topLevelBindingGraph().bindingsByComponent().get(path).stream()) + .forEach(bindingNode -> bindings.putIfAbsent(bindingNode.key(), bindingNode)); + return ImmutableSet.copyOf(bindings.values()); } } diff --git a/java/dagger/internal/codegen/binding/BindingGraphConverter.java b/java/dagger/internal/codegen/binding/BindingGraphConverter.java index 5928b8fb0..adb4435fd 100644 --- a/java/dagger/internal/codegen/binding/BindingGraphConverter.java +++ b/java/dagger/internal/codegen/binding/BindingGraphConverter.java @@ -19,23 +19,19 @@ package dagger.internal.codegen.binding; import static com.google.common.base.Verify.verify; import static dagger.internal.codegen.binding.BindingRequest.bindingRequest; import static dagger.internal.codegen.extension.DaggerGraphs.unreachableNodes; -import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; import static dagger.internal.codegen.model.BindingKind.SUBCOMPONENT_CREATOR; -import androidx.room.compiler.processing.XMethodElement; import androidx.room.compiler.processing.XType; import androidx.room.compiler.processing.XTypeElement; import com.google.auto.value.AutoValue; import com.google.auto.value.extension.memoized.Memoized; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; -import com.google.common.collect.Iterators; import com.google.common.graph.ImmutableNetwork; import com.google.common.graph.MutableNetwork; -import com.google.common.graph.Network; import com.google.common.graph.NetworkBuilder; import dagger.internal.codegen.binding.BindingGraph.TopLevelBindingGraph; +import dagger.internal.codegen.binding.BindingGraphFactory.LegacyBindingGraph; import dagger.internal.codegen.binding.ComponentDescriptor.ComponentMethodDescriptor; import dagger.internal.codegen.model.BindingGraph.ComponentNode; import dagger.internal.codegen.model.BindingGraph.DependencyEdge; @@ -43,7 +39,6 @@ import dagger.internal.codegen.model.BindingGraph.Edge; import dagger.internal.codegen.model.BindingGraph.MissingBinding; import dagger.internal.codegen.model.BindingGraph.Node; import dagger.internal.codegen.model.ComponentPath; -import dagger.internal.codegen.model.DaggerExecutableElement; import dagger.internal.codegen.model.DaggerTypeElement; import dagger.internal.codegen.model.DependencyRequest; import dagger.internal.codegen.model.Key; @@ -70,7 +65,7 @@ final class BindingGraphConverter { */ BindingGraph convert(LegacyBindingGraph legacyBindingGraph, boolean isFullBindingGraph) { MutableNetwork<Node, Edge> network = asNetwork(legacyBindingGraph); - ComponentNode rootNode = rootComponentNode(network); + ComponentNode rootNode = legacyBindingGraph.componentNode(); // When bindings are copied down into child graphs because they transitively depend on local // multibindings or optional bindings, the parent-owned binding is still there. If that @@ -92,47 +87,19 @@ final class BindingGraphConverter { return converter.network; } - // TODO(dpb): Example of BindingGraph logic applied to derived networks. - private ComponentNode rootComponentNode(Network<Node, Edge> network) { - return (ComponentNode) - Iterables.find( - network.nodes(), - node -> node instanceof ComponentNode && node.componentPath().atRoot()); - } - - /** - * Used as a cache key to make sure resolved bindings are cached per component path. - * This is required so that binding nodes are not reused across different branches of the - * graph since the ResolvedBindings class only contains the component and not the path. - */ - @AutoValue - abstract static class ResolvedBindingsWithPath { - abstract ResolvedBindings resolvedBindings(); - abstract ComponentPath componentPath(); - - static ResolvedBindingsWithPath create( - ResolvedBindings resolvedBindings, ComponentPath componentPath) { - return new AutoValue_BindingGraphConverter_ResolvedBindingsWithPath( - resolvedBindings, componentPath); - } - } - private final class Converter { /** The path from the root graph to the currently visited graph. */ private final Deque<LegacyBindingGraph> bindingGraphPath = new ArrayDeque<>(); - /** The {@link ComponentPath} for each component in {@link #bindingGraphPath}. */ - private final Deque<ComponentPath> componentPaths = new ArrayDeque<>(); - private final MutableNetwork<Node, Edge> network = NetworkBuilder.directed().allowsParallelEdges(true).allowsSelfLoops(true).build(); private final Set<BindingNode> bindings = new HashSet<>(); - private final Map<ResolvedBindingsWithPath, ImmutableSet<BindingNode>> resolvedBindingsMap = + private final Map<ResolvedBindings, ImmutableSet<BindingNode>> resolvedBindingsMap = new HashMap<>(); private void visitRootComponent(LegacyBindingGraph graph) { - visitComponent(graph, null); + visitComponent(graph); } /** @@ -141,34 +108,23 @@ final class BindingGraphConverter { * <p>This implementation does the following: * * <ol> - * <li>If this component is installed in its parent by a subcomponent factory method, calls - * {@link #visitSubcomponentFactoryMethod(ComponentNode, ComponentNode, XMethodElement)}. - * <li>For each entry point in the component, calls {@link #visitEntryPoint(ComponentNode, - * DependencyRequest)}. - * <li>For each child component, calls {@link #visitComponent(LegacyBindingGraph, - * ComponentNode)}, updating the traversal state. + * <li>If this component is installed in its parent by a subcomponent factory method, adds + * an edge between the parent and child components. + * <li>For each entry point, adds an edge between the component and the entry point. + * <li>For each child component, calls {@link #visitComponent(LegacyBindingGraph)}, + * updating the traversal state. * </ol> * * @param graph the currently visited graph */ - private void visitComponent(LegacyBindingGraph graph, ComponentNode parentComponent) { + private void visitComponent(LegacyBindingGraph graph) { bindingGraphPath.addLast(graph); - ComponentPath graphPath = - ComponentPath.create( - bindingGraphPath.stream() - .map(LegacyBindingGraph::componentDescriptor) - .map(ComponentDescriptor::typeElement) - .map(DaggerTypeElement::from) - .collect(toImmutableList())); - componentPaths.addLast(graphPath); - ComponentNode currentComponent = - ComponentNodeImpl.create(componentPath(), graph.componentDescriptor()); - - network.addNode(currentComponent); + + network.addNode(graph.componentNode()); for (ComponentMethodDescriptor entryPointMethod : graph.componentDescriptor().entryPointMethods()) { - visitEntryPoint(currentComponent, entryPointMethod.dependencyRequest().get()); + addDependencyEdges(graph.componentNode(), entryPointMethod.dependencyRequest().get()); } for (ResolvedBindings resolvedBindings : graph.resolvedBindings()) { @@ -180,7 +136,7 @@ final class BindingGraphConverter { } } if (binding.kind().equals(SUBCOMPONENT_CREATOR) - && binding.componentPath().equals(currentComponent.componentPath())) { + && binding.componentPath().equals(graph.componentPath())) { network.addEdge( binding, subcomponentNode(binding.key().type().xprocessing(), graph), @@ -190,51 +146,20 @@ final class BindingGraphConverter { } } - if (bindingGraphPath.size() > 1) { - LegacyBindingGraph parent = Iterators.get(bindingGraphPath.descendingIterator(), 1); - parent + for (LegacyBindingGraph childGraph : graph.subgraphs()) { + visitComponent(childGraph); + graph .componentDescriptor() - .getFactoryMethodForChildComponent(graph.componentDescriptor()) + .getFactoryMethodForChildComponent(childGraph.componentDescriptor()) .ifPresent( childFactoryMethod -> - visitSubcomponentFactoryMethod( - parentComponent, currentComponent, childFactoryMethod.methodElement())); - } - - for (LegacyBindingGraph child : graph.subgraphs()) { - visitComponent(child, currentComponent); + network.addEdge( + graph.componentNode(), + childGraph.componentNode(), + new ChildFactoryMethodEdgeImpl(childFactoryMethod.methodElement()))); } verify(bindingGraphPath.removeLast().equals(graph)); - verify(componentPaths.removeLast().equals(graphPath)); - } - - /** - * Called once for each entry point in a component. - * - * @param componentNode the component that contains the entry point - * @param entryPoint the entry point to visit - */ - private void visitEntryPoint(ComponentNode componentNode, DependencyRequest entryPoint) { - addDependencyEdges(componentNode, entryPoint); - } - - /** - * Called if this component was installed in its parent by a subcomponent factory method. - * - * @param parentComponent the parent graph - * @param currentComponent the currently visited graph - * @param factoryMethod the factory method in the parent component that declares that the - * current component is a child - */ - private void visitSubcomponentFactoryMethod( - ComponentNode parentComponent, - ComponentNode currentComponent, - XMethodElement factoryMethod) { - network.addEdge( - parentComponent, - currentComponent, - new ChildFactoryMethodEdgeImpl(DaggerExecutableElement.from(factoryMethod))); } /** @@ -242,7 +167,7 @@ final class BindingGraphConverter { * component. */ private ComponentPath componentPath() { - return componentPaths.getLast(); + return bindingGraphPath.getLast().componentPath(); } /** @@ -250,9 +175,9 @@ final class BindingGraphConverter { * component. */ private ComponentPath pathFromRootToAncestor(XTypeElement ancestor) { - for (ComponentPath componentPath : componentPaths) { - if (componentPath.currentComponent().xprocessing().equals(ancestor)) { - return componentPath; + for (LegacyBindingGraph graph : bindingGraphPath) { + if (graph.componentDescriptor().typeElement().equals(ancestor)) { + return graph.componentPath(); } } throw new IllegalArgumentException( @@ -325,23 +250,18 @@ final class BindingGraphConverter { } private ImmutableSet<BindingNode> bindingNodes(ResolvedBindings resolvedBindings) { - ResolvedBindingsWithPath resolvedBindingsWithPath = - ResolvedBindingsWithPath.create(resolvedBindings, componentPath()); - return resolvedBindingsMap.computeIfAbsent( - resolvedBindingsWithPath, this::uncachedBindingNodes); + return resolvedBindingsMap.computeIfAbsent(resolvedBindings, this::uncachedBindingNodes); } - private ImmutableSet<BindingNode> uncachedBindingNodes( - ResolvedBindingsWithPath resolvedBindingsWithPath) { + private ImmutableSet<BindingNode> uncachedBindingNodes(ResolvedBindings resolvedBindings) { ImmutableSet.Builder<BindingNode> bindingNodes = ImmutableSet.builder(); - resolvedBindingsWithPath.resolvedBindings() + resolvedBindings .allBindings() .asMap() .forEach( (component, bindings) -> { for (Binding binding : bindings) { - bindingNodes.add( - bindingNode(resolvedBindingsWithPath.resolvedBindings(), binding, component)); + bindingNodes.add(bindingNode(resolvedBindings, binding, component)); } }); return bindingNodes.build(); diff --git a/java/dagger/internal/codegen/binding/BindingGraphFactory.java b/java/dagger/internal/codegen/binding/BindingGraphFactory.java index ba1157d50..503435901 100644 --- a/java/dagger/internal/codegen/binding/BindingGraphFactory.java +++ b/java/dagger/internal/codegen/binding/BindingGraphFactory.java @@ -37,7 +37,6 @@ import androidx.room.compiler.processing.XProcessingEnv; import androidx.room.compiler.processing.XTypeElement; import com.google.common.collect.HashMultimap; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSetMultimap; import com.google.common.collect.Iterables; @@ -51,11 +50,15 @@ import dagger.internal.codegen.base.MapType; import dagger.internal.codegen.base.OptionalType; import dagger.internal.codegen.compileroption.CompilerOptions; import dagger.internal.codegen.javapoet.TypeNames; +import dagger.internal.codegen.model.BindingGraph.ComponentNode; +import dagger.internal.codegen.model.BindingKind; +import dagger.internal.codegen.model.ComponentPath; +import dagger.internal.codegen.model.DaggerTypeElement; import dagger.internal.codegen.model.DependencyRequest; import dagger.internal.codegen.model.Key; +import dagger.internal.codegen.model.RequestKind; import dagger.internal.codegen.model.Scope; import dagger.internal.codegen.xprocessing.XTypeElements; -import dagger.producers.internal.ProductionExecutorModule; import java.util.ArrayDeque; import java.util.Deque; import java.util.HashMap; @@ -182,7 +185,8 @@ public final class BindingGraphFactory implements ClearableCache { ImmutableSet.Builder<SubcomponentDeclaration> subcomponentDeclarations = ImmutableSet.builder(); // Collect transitive module bindings and multibinding declarations. - for (ModuleDescriptor moduleDescriptor : modules(componentDescriptor, parentResolver)) { + ImmutableSet<ModuleDescriptor> modules = modules(componentDescriptor, parentResolver); + for (ModuleDescriptor moduleDescriptor : modules) { explicitBindingsBuilder.addAll(moduleDescriptor.bindings()); multibindingDeclarations.addAll(moduleDescriptor.multibindingDeclarations()); subcomponentDeclarations.addAll(moduleDescriptor.subcomponentDeclarations()); @@ -190,8 +194,14 @@ public final class BindingGraphFactory implements ClearableCache { optionalsBuilder.addAll(moduleDescriptor.optionalDeclarations()); } + DaggerTypeElement component = DaggerTypeElement.from(componentDescriptor.typeElement()); + ComponentPath componentPath = + parentResolver.isPresent() + ? parentResolver.get().componentPath.childPath(component) + : ComponentPath.create(ImmutableList.of(component)); final Resolver requestResolver = new Resolver( + componentPath, parentResolver, componentDescriptor, indexBindingDeclarationsByKey(explicitBindingsBuilder.build()), @@ -214,7 +224,7 @@ public final class BindingGraphFactory implements ClearableCache { if (createFullBindingGraph) { // Resolve the keys for all bindings in all modules, stripping any multibinding contribution // identifier so that the multibinding itself is resolved. - modules(componentDescriptor, parentResolver).stream() + modules.stream() .flatMap(module -> module.allBindingKeys().stream()) .map(Key::withoutMultibindingContributionIdentifier) .forEach(requestResolver::resolve); @@ -236,11 +246,7 @@ public final class BindingGraphFactory implements ClearableCache { } } - return new LegacyBindingGraph( - componentDescriptor, - ImmutableMap.copyOf(requestResolver.getResolvedContributionBindings()), - ImmutableMap.copyOf(requestResolver.getResolvedMembersInjectionBindings()), - ImmutableList.copyOf(subgraphs.build())); + return new LegacyBindingGraph(requestResolver, subgraphs.build()); } /** @@ -254,38 +260,23 @@ public final class BindingGraphFactory implements ClearableCache { return shouldIncludeImplicitProductionModules(componentDescriptor, parentResolver) ? new ImmutableSet.Builder<ModuleDescriptor>() .addAll(componentDescriptor.modules()) - .add(descriptorForMonitoringModule(componentDescriptor.typeElement())) - .add(descriptorForProductionExecutorModule()) + .add( + moduleDescriptorFactory.create( + DaggerSuperficialValidation.requireTypeElement( + processingEnv, + generatedMonitoringModuleName(componentDescriptor.typeElement())))) + .add( + moduleDescriptorFactory.create( + processingEnv.requireTypeElement(TypeNames.PRODUCTION_EXECTUTOR_MODULE))) .build() : componentDescriptor.modules(); } private boolean shouldIncludeImplicitProductionModules( - ComponentDescriptor component, Optional<Resolver> parentResolver) { - return component.isProduction() - && ((!component.isSubcomponent() && component.isRealComponent()) - || (parentResolver.isPresent() - && !parentResolver.get().componentDescriptor.isProduction())); - } - - /** - * Returns a descriptor for a generated module that handles monitoring for production components. - * This module is generated in the {@link - * dagger.internal.codegen.validation.MonitoringModuleProcessingStep}. - * - * @throws TypeNotPresentException if the module has not been generated yet. This will cause the - * processor to retry in a later processing round. - */ - private ModuleDescriptor descriptorForMonitoringModule(XTypeElement componentDefinitionType) { - return moduleDescriptorFactory.create( - DaggerSuperficialValidation.requireTypeElement( - processingEnv, generatedMonitoringModuleName(componentDefinitionType))); - } - - /** Returns a descriptor {@link ProductionExecutorModule}. */ - private ModuleDescriptor descriptorForProductionExecutorModule() { - return moduleDescriptorFactory.create( - processingEnv.findTypeElement(TypeNames.PRODUCTION_EXECTUTOR_MODULE)); + ComponentDescriptor componentDescriptor, Optional<Resolver> parentResolver) { + return componentDescriptor.isProduction() + && componentDescriptor.isRealComponent() + && (parentResolver.isEmpty() || !parentResolver.get().componentDescriptor.isProduction()); } /** Indexes {@code bindingDeclarations} by {@link BindingDeclaration#key()}. */ @@ -299,7 +290,70 @@ public final class BindingGraphFactory implements ClearableCache { keysMatchingRequestCache.clear(); } + /** Represents a fully resolved binding graph. */ + static final class LegacyBindingGraph { + private final Resolver resolver; + private final ImmutableList<LegacyBindingGraph> resolvedSubgraphs; + private final ComponentNode componentNode; + + LegacyBindingGraph(Resolver resolver, ImmutableList<LegacyBindingGraph> resolvedSubgraphs) { + this.resolver = resolver; + this.resolvedSubgraphs = resolvedSubgraphs; + this.componentNode = + ComponentNodeImpl.create(resolver.componentPath, resolver.componentDescriptor); + } + + /** Returns the {@link ComponentNode} associated with this binding graph. */ + ComponentNode componentNode() { + return componentNode; + } + + /** Returns the {@link ComponentPath} associated with this binding graph. */ + ComponentPath componentPath() { + return resolver.componentPath; + } + + /** Returns the {@link ComponentDescriptor} associated with this binding graph. */ + ComponentDescriptor componentDescriptor() { + return resolver.componentDescriptor; + } + + /** + * Returns the {@link ResolvedBindings} in this graph or a parent graph that matches the given + * request. + * + * <p>An exception is thrown if there are no resolved bindings found for the request; however, + * this should never happen since all dependencies should have been resolved at this point. + */ + ResolvedBindings resolvedBindings(BindingRequest request) { + return request.isRequestKind(RequestKind.MEMBERS_INJECTION) + ? resolver.getResolvedMembersInjectionBindings(request.key()) + : resolver.getResolvedContributionBindings(request.key()); + } + + /** + * Returns all {@link ResolvedBindings} for the given request. + * + * <p>Note that this only returns the bindings resolved in this component. Bindings resolved in + * parent components are not included. + */ + Iterable<ResolvedBindings> resolvedBindings() { + // Don't return an immutable collection - this is only ever used for looping over all bindings + // in the graph. Copying is wasteful, especially if is a hashing collection, since the values + // should all, by definition, be distinct. + return Iterables.concat( + resolver.resolvedMembersInjectionBindings.values(), + resolver.resolvedContributionBindings.values()); + } + + /** Returns the resolved subgraphs. */ + ImmutableList<LegacyBindingGraph> subgraphs() { + return resolvedSubgraphs; + } + } + private final class Resolver { + final ComponentPath componentPath; final Optional<Resolver> parentResolver; final ComponentDescriptor componentDescriptor; final ImmutableSetMultimap<Key, ContributionBinding> explicitBindings; @@ -318,6 +372,7 @@ public final class BindingGraphFactory implements ClearableCache { final Queue<ComponentDescriptor> subcomponentsToResolve = new ArrayDeque<>(); Resolver( + ComponentPath componentPath, Optional<Resolver> parentResolver, ComponentDescriptor componentDescriptor, ImmutableSetMultimap<Key, ContributionBinding> explicitBindings, @@ -325,6 +380,7 @@ public final class BindingGraphFactory implements ClearableCache { ImmutableSetMultimap<Key, SubcomponentDeclaration> subcomponentDeclarations, ImmutableSetMultimap<Key, DelegateDeclaration> delegateDeclarations, ImmutableSetMultimap<Key, OptionalBindingDeclaration> optionalBindingDeclarations) { + this.componentPath = componentPath; this.parentResolver = parentResolver; this.componentDescriptor = checkNotNull(componentDescriptor); this.explicitBindings = checkNotNull(explicitBindings); @@ -428,6 +484,7 @@ public final class BindingGraphFactory implements ClearableCache { } return ResolvedBindings.forContributionBindings( + componentPath, requestKey, Multimaps.index(bindings, binding -> getOwningComponent(requestKey, binding)), multibindingDeclarations, @@ -466,8 +523,8 @@ public final class BindingGraphFactory implements ClearableCache { injectBindingRegistry.getOrFindMembersInjectionBinding(requestKey); return binding.isPresent() ? ResolvedBindings.forMembersInjectionBinding( - requestKey, componentDescriptor, binding.get()) - : ResolvedBindings.noBindings(requestKey); + componentPath, requestKey, componentDescriptor, binding.get()) + : ResolvedBindings.noBindings(componentPath, requestKey); } /** @@ -577,8 +634,7 @@ public final class BindingGraphFactory implements ClearableCache { * ResolvedBindings#owningComponent(ContributionBinding)}. */ private XTypeElement getOwningComponent(Key requestKey, ContributionBinding binding) { - if (isResolvedInParent(requestKey, binding) - && !new LocalDependencyChecker().dependsOnLocalBindings(binding)) { + if (isResolvedInParent(requestKey, binding) && !requiresResolution(binding)) { ResolvedBindings parentResolvedBindings = parentResolver.get().resolvedContributionBindings.get(requestKey); return parentResolvedBindings.owningComponent(binding); @@ -799,11 +855,17 @@ public final class BindingGraphFactory implements ClearableCache { /* Resolve in the parent in case there are multibinding contributions or conflicts in some * component between this one and the previously-resolved one. */ parentResolver.get().resolve(key); - if (!new LocalDependencyChecker().dependsOnLocalBindings(key) - && getLocalExplicitBindings(key).isEmpty()) { + ResolvedBindings previouslyResolvedBindings = getPreviouslyResolvedBindings(key).get(); + // TODO(b/305748522): Allow caching for assisted injection bindings. + boolean isAssistedInjectionBinding = + previouslyResolvedBindings.bindings().stream() + .anyMatch(binding -> binding.kind() == BindingKind.ASSISTED_INJECTION); + if (!isAssistedInjectionBinding + && !requiresResolution(key) + && getLocalExplicitBindings(key).isEmpty()) { /* Cache the inherited parent component's bindings in case resolving at the parent found * bindings in some component between this one and the previously-resolved one. */ - resolvedContributionBindings.put(key, getPreviouslyResolvedBindings(key).get()); + resolvedContributionBindings.put(key, previouslyResolvedBindings); return; } } @@ -830,26 +892,29 @@ public final class BindingGraphFactory implements ClearableCache { } } - /** - * Returns all of the {@link ResolvedBindings} for {@link ContributionBinding}s from this and - * all ancestor resolvers, indexed by {@link ResolvedBindings#key()}. - */ - Map<Key, ResolvedBindings> getResolvedContributionBindings() { - Map<Key, ResolvedBindings> bindings = new LinkedHashMap<>(); - parentResolver.ifPresent(parent -> bindings.putAll(parent.getResolvedContributionBindings())); - bindings.putAll(resolvedContributionBindings); - return bindings; + private ResolvedBindings getResolvedContributionBindings(Key key) { + if (resolvedContributionBindings.containsKey(key)) { + return resolvedContributionBindings.get(key); + } + if (parentResolver.isPresent()) { + return parentResolver.get().getResolvedContributionBindings(key); + } + throw new AssertionError("No resolved bindings for key: " + key); } - /** - * Returns all of the {@link ResolvedBindings} for {@link MembersInjectionBinding} from this - * resolvers, indexed by {@link ResolvedBindings#key()}. - */ - ImmutableMap<Key, ResolvedBindings> getResolvedMembersInjectionBindings() { - return ImmutableMap.copyOf(resolvedMembersInjectionBindings); + private ResolvedBindings getResolvedMembersInjectionBindings(Key key) { + return resolvedMembersInjectionBindings.get(key); } - private final class LocalDependencyChecker { + private boolean requiresResolution(Key key) { + return new LegacyRequiresResolutionChecker().requiresResolution(key); + } + + private boolean requiresResolution(Binding binding) { + return new LegacyRequiresResolutionChecker().requiresResolution(binding); + } + + private final class LegacyRequiresResolutionChecker { private final Set<Object> cycleChecker = new HashSet<>(); /** @@ -863,14 +928,14 @@ public final class BindingGraphFactory implements ClearableCache { * * @throws IllegalArgumentException if {@link #getPreviouslyResolvedBindings(Key)} is empty */ - private boolean dependsOnLocalBindings(Key key) { + private boolean requiresResolution(Key key) { // Don't recur infinitely if there are valid cycles in the dependency graph. // http://b/23032377 if (!cycleChecker.add(key)) { return false; } return reentrantComputeIfAbsent( - keyDependsOnLocalBindingsCache, key, this::dependsOnLocalBindingsUncached); + keyDependsOnLocalBindingsCache, key, this::requiresResolutionUncached); } /** @@ -882,75 +947,89 @@ public final class BindingGraphFactory implements ClearableCache { * <p>We don't care about non-reusable scoped dependencies because they will never depend on * multibindings with contributions from subcomponents. */ - private boolean dependsOnLocalBindings(Binding binding) { + private boolean requiresResolution(Binding binding) { if (!cycleChecker.add(binding)) { return false; } return reentrantComputeIfAbsent( - bindingDependsOnLocalBindingsCache, binding, this::dependsOnLocalBindingsUncached); + bindingDependsOnLocalBindingsCache, binding, this::requiresResolutionUncached); } - private boolean dependsOnLocalBindingsUncached(Key key) { + private boolean requiresResolutionUncached(Key key) { checkArgument( getPreviouslyResolvedBindings(key).isPresent(), "no previously resolved bindings in %s for %s", Resolver.this, key); ResolvedBindings previouslyResolvedBindings = getPreviouslyResolvedBindings(key).get(); - if (hasLocalMultibindingContributions(key) - || hasLocalOptionalBindingContribution(previouslyResolvedBindings)) { + if (hasLocalBindings(previouslyResolvedBindings)) { return true; } for (Binding binding : previouslyResolvedBindings.bindings()) { - if (dependsOnLocalBindings(binding)) { + if (requiresResolution(binding)) { return true; } } return false; } - private boolean dependsOnLocalBindingsUncached(Binding binding) { + private boolean requiresResolutionUncached(Binding binding) { if ((!binding.scope().isPresent() || binding.scope().get().isReusable()) // TODO(beder): Figure out what happens with production subcomponents. && !binding.bindingType().equals(BindingType.PRODUCTION)) { for (DependencyRequest dependency : binding.dependencies()) { - if (dependsOnLocalBindings(dependency.key())) { + if (requiresResolution(dependency.key())) { return true; } } } return false; } + } - /** - * Returns {@code true} if there is at least one multibinding contribution declared within - * this component's modules that matches the key. - */ - private boolean hasLocalMultibindingContributions(Key requestKey) { - return keysMatchingRequest(requestKey) - .stream() - .anyMatch(key -> !getLocalExplicitMultibindings(key).isEmpty()); - } + private boolean hasLocalBindings(Binding binding) { + return hasLocalMultibindingContributions(binding.key()) + || hasLocalOptionalBindingContribution( + binding.key(), ImmutableSet.of((ContributionBinding) binding)); + } - /** - * Returns {@code true} if there is a contribution in this component for an {@code - * Optional<Foo>} key that has not been contributed in a parent. - */ - private boolean hasLocalOptionalBindingContribution(ResolvedBindings resolvedBindings) { - if (resolvedBindings - .contributionBindings() - .stream() - .map(ContributionBinding::kind) - .anyMatch(isEqual(OPTIONAL))) { - return !getLocalExplicitBindings(keyFactory.unwrapOptional(resolvedBindings.key()).get()) - .isEmpty(); - } else { - // If a parent contributes a @Provides Optional<Foo> binding and a child has a - // @BindsOptionalOf Foo method, the two should conflict, even if there is no binding for - // Foo on its own - return !getOptionalBindingDeclarations(resolvedBindings.key()).isEmpty(); - } + private boolean hasLocalBindings(ResolvedBindings resolvedBindings) { + return hasLocalMultibindingContributions(resolvedBindings.key()) + || hasLocalOptionalBindingContribution(resolvedBindings); + } + + /** + * Returns {@code true} if there is at least one multibinding contribution declared within + * this component's modules that matches the key. + */ + private boolean hasLocalMultibindingContributions(Key requestKey) { + return keysMatchingRequest(requestKey) + .stream() + .anyMatch(key -> !getLocalExplicitMultibindings(key).isEmpty()); + } + + /** + * Returns {@code true} if there is a contribution in this component for an {@code + * Optional<Foo>} key that has not been contributed in a parent. + */ + private boolean hasLocalOptionalBindingContribution(ResolvedBindings resolvedBindings) { + return hasLocalOptionalBindingContribution( + resolvedBindings.key(), resolvedBindings.contributionBindings()); + } + + private boolean hasLocalOptionalBindingContribution( + Key key, ImmutableSet<ContributionBinding> previousContributionBindings) { + if (previousContributionBindings.stream() + .map(ContributionBinding::kind) + .anyMatch(isEqual(OPTIONAL))) { + return !getLocalExplicitBindings(keyFactory.unwrapOptional(key).get()) + .isEmpty(); + } else { + // If a parent contributes a @Provides Optional<Foo> binding and a child has a + // @BindsOptionalOf Foo method, the two should conflict, even if there is no binding for + // Foo on its own + return !getOptionalBindingDeclarations(key).isEmpty(); } } } diff --git a/java/dagger/internal/codegen/binding/CancellationPolicy.java b/java/dagger/internal/codegen/binding/CancellationPolicy.java new file mode 100644 index 000000000..7be42ffbb --- /dev/null +++ b/java/dagger/internal/codegen/binding/CancellationPolicy.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2023 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.internal.codegen.binding; + +import static com.google.common.base.Preconditions.checkArgument; +import static dagger.internal.codegen.xprocessing.XElements.getSimpleName; + +import androidx.room.compiler.processing.XAnnotation; +import dagger.internal.codegen.javapoet.TypeNames; +import dagger.internal.codegen.xprocessing.XAnnotations; + +/** + * The cancellation policy for a {@link dagger.producers.ProductionComponent}. + * + * <p>@see dagger.producers.CancellationPolicy + */ +public enum CancellationPolicy { + PROPAGATE, + IGNORE; + + static CancellationPolicy from(XAnnotation annotation) { + checkArgument(XAnnotations.getClassName(annotation).equals(TypeNames.CANCELLATION_POLICY)); + return valueOf(getSimpleName(annotation.getAsEnum("fromSubcomponents"))); + } +} diff --git a/java/dagger/internal/codegen/binding/ChildFactoryMethodEdgeImpl.java b/java/dagger/internal/codegen/binding/ChildFactoryMethodEdgeImpl.java index 077f4546a..4b1e15ede 100644 --- a/java/dagger/internal/codegen/binding/ChildFactoryMethodEdgeImpl.java +++ b/java/dagger/internal/codegen/binding/ChildFactoryMethodEdgeImpl.java @@ -18,6 +18,7 @@ package dagger.internal.codegen.binding; import static dagger.internal.codegen.base.ElementFormatter.elementToString; +import androidx.room.compiler.processing.XMethodElement; import dagger.internal.codegen.model.BindingGraph.ChildFactoryMethodEdge; import dagger.internal.codegen.model.DaggerExecutableElement; @@ -26,8 +27,8 @@ public final class ChildFactoryMethodEdgeImpl implements ChildFactoryMethodEdge private final DaggerExecutableElement factoryMethod; - ChildFactoryMethodEdgeImpl(DaggerExecutableElement factoryMethod) { - this.factoryMethod = factoryMethod; + ChildFactoryMethodEdgeImpl(XMethodElement factoryMethod) { + this.factoryMethod = DaggerExecutableElement.from(factoryMethod); } @Override diff --git a/java/dagger/internal/codegen/binding/ComponentCreatorDescriptor.java b/java/dagger/internal/codegen/binding/ComponentCreatorDescriptor.java index 0bc22099a..254ca7ea5 100644 --- a/java/dagger/internal/codegen/binding/ComponentCreatorDescriptor.java +++ b/java/dagger/internal/codegen/binding/ComponentCreatorDescriptor.java @@ -41,6 +41,7 @@ import dagger.internal.codegen.base.ComponentCreatorAnnotation; import dagger.internal.codegen.base.ComponentCreatorKind; import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.DependencyRequest; +import dagger.internal.codegen.xprocessing.XElements; import java.util.List; /** @@ -161,7 +162,12 @@ public abstract class ComponentCreatorDescriptor { for (XMethodElement method : getAllUnimplementedMethods(creator)) { XMethodType resolvedMethodType = method.asMemberOf(creator.getType()); if (isSubtype(componentType, resolvedMethodType.getReturnType())) { - verify(factoryMethod == null); // validation should have ensured there's only 1. + verify( + factoryMethod == null, + "Expected a single factory method for %s but found multiple: [%s, %s]", + XElements.toStableString(creator), + XElements.toStableString(factoryMethod), + XElements.toStableString(method)); factoryMethod = method; } else { XExecutableParameterElement parameter = getOnlyElement(method.getParameters()); @@ -171,7 +177,10 @@ public abstract class ComponentCreatorDescriptor { method); } } - verify(factoryMethod != null); // validation should have ensured this. + verify( + factoryMethod != null, + "Expected a single factory method for %s but found none.", + XElements.toStableString(creator)); ImmutableSetMultimap.Builder<ComponentRequirement, XExecutableParameterElement> factoryParameters = ImmutableSetMultimap.builder(); diff --git a/java/dagger/internal/codegen/binding/ComponentDescriptor.java b/java/dagger/internal/codegen/binding/ComponentDescriptor.java index a105608b7..b0a0183b9 100644 --- a/java/dagger/internal/codegen/binding/ComponentDescriptor.java +++ b/java/dagger/internal/codegen/binding/ComponentDescriptor.java @@ -21,14 +21,28 @@ import static androidx.room.compiler.processing.XTypeKt.isVoid; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; +import static com.google.common.collect.Iterables.getOnlyElement; +import static dagger.internal.codegen.base.ComponentAnnotation.rootComponentAnnotation; +import static dagger.internal.codegen.base.ComponentAnnotation.subcomponentAnnotation; +import static dagger.internal.codegen.base.ComponentAnnotation.subcomponentAnnotations; +import static dagger.internal.codegen.base.ComponentCreatorAnnotation.creatorAnnotationsFor; +import static dagger.internal.codegen.base.ModuleAnnotation.moduleAnnotation; +import static dagger.internal.codegen.base.Scopes.productionScope; +import static dagger.internal.codegen.base.Util.reentrantComputeIfAbsent; +import static dagger.internal.codegen.binding.ConfigurationAnnotations.enclosedAnnotatedTypes; +import static dagger.internal.codegen.binding.ConfigurationAnnotations.isSubcomponentCreator; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableMap; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; import static dagger.internal.codegen.javapoet.TypeNames.isFutureType; import static dagger.internal.codegen.xprocessing.XElements.getSimpleName; +import static dagger.internal.codegen.xprocessing.XTypeElements.getAllUnimplementedMethods; +import static dagger.internal.codegen.xprocessing.XTypes.isDeclared; -import androidx.room.compiler.processing.XAnnotation; import androidx.room.compiler.processing.XElement; import androidx.room.compiler.processing.XMethodElement; +import androidx.room.compiler.processing.XMethodType; +import androidx.room.compiler.processing.XProcessingEnv; +import androidx.room.compiler.processing.XType; import androidx.room.compiler.processing.XTypeElement; import com.google.auto.value.AutoValue; import com.google.auto.value.extension.memoized.Memoized; @@ -44,16 +58,21 @@ import com.squareup.javapoet.TypeName; import dagger.Component; import dagger.Module; import dagger.Subcomponent; +import dagger.internal.codegen.base.ClearableCache; import dagger.internal.codegen.base.ComponentAnnotation; +import dagger.internal.codegen.base.DaggerSuperficialValidation; +import dagger.internal.codegen.base.ModuleAnnotation; import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.DependencyRequest; import dagger.internal.codegen.model.Scope; -import dagger.internal.codegen.xprocessing.XAnnotations; +import dagger.internal.codegen.xprocessing.XTypeElements; import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.stream.Stream; +import javax.inject.Inject; +import javax.inject.Singleton; /** * A component declaration. @@ -68,52 +87,54 @@ import java.util.stream.Stream; @CheckReturnValue @AutoValue public abstract class ComponentDescriptor { + /** The annotation that specifies that {@link #typeElement()} is a component. */ + public abstract ComponentAnnotation annotation(); + /** - * The cancellation policy for a {@link dagger.producers.ProductionComponent}. - * - * <p>@see dagger.producers.CancellationPolicy + * The element that defines the component. This is the element to which the {@link #annotation()} + * was applied. */ - public enum CancellationPolicy { - PROPAGATE, - IGNORE; + public abstract XTypeElement typeElement(); - private static CancellationPolicy from(XAnnotation annotation) { - checkArgument(XAnnotations.getClassName(annotation).equals(TypeNames.CANCELLATION_POLICY)); - return valueOf(getSimpleName(annotation.getAsEnum("fromSubcomponents"))); - } - } + /** + * The set of component dependencies listed in {@link Component#dependencies} or {@link + * dagger.producers.ProductionComponent#dependencies()}. + */ + public abstract ImmutableSet<ComponentRequirement> dependencies(); - /** Creates a {@link ComponentDescriptor}. */ - static ComponentDescriptor create( - ComponentAnnotation componentAnnotation, - XTypeElement component, - ImmutableSet<ComponentRequirement> componentDependencies, - ImmutableSet<ModuleDescriptor> transitiveModules, - ImmutableMap<XMethodElement, ComponentRequirement> dependenciesByDependencyMethod, - ImmutableSet<Scope> scopes, - ImmutableSet<ComponentDescriptor> subcomponentsFromModules, - ImmutableBiMap<ComponentMethodDescriptor, ComponentDescriptor> subcomponentsByFactoryMethod, - ImmutableBiMap<ComponentMethodDescriptor, ComponentDescriptor> subcomponentsByBuilderMethod, - ImmutableSet<ComponentMethodDescriptor> componentMethods, - Optional<ComponentCreatorDescriptor> creator) { - ComponentDescriptor descriptor = - new AutoValue_ComponentDescriptor( - componentAnnotation, - component, - componentDependencies, - transitiveModules, - dependenciesByDependencyMethod, - scopes, - subcomponentsFromModules, - subcomponentsByFactoryMethod, - subcomponentsByBuilderMethod, - componentMethods, - creator); - return descriptor; - } + /** + * The {@link ModuleDescriptor modules} declared in {@link Component#modules()} and reachable by + * traversing {@link Module#includes()}. + */ + public abstract ImmutableSet<ModuleDescriptor> modules(); - /** The annotation that specifies that {@link #typeElement()} is a component. */ - public abstract ComponentAnnotation annotation(); + /** The scopes of the component. */ + public abstract ImmutableSet<Scope> scopes(); + + /** + * All {@linkplain Subcomponent direct child} components that are declared by a {@linkplain + * Module#subcomponents() module's subcomponents}. + */ + abstract ImmutableSet<ComponentDescriptor> childComponentsDeclaredByModules(); + + /** + * All {@linkplain Subcomponent direct child} components that are declared by a subcomponent + * factory method. + */ + public abstract ImmutableBiMap<ComponentMethodDescriptor, ComponentDescriptor> + childComponentsDeclaredByFactoryMethods(); + + /** + * All {@linkplain Subcomponent direct child} components that are declared by a subcomponent + * builder method. + */ + abstract ImmutableMap<ComponentMethodDescriptor, ComponentDescriptor> + childComponentsDeclaredByBuilderEntryPoints(); + + public abstract ImmutableSet<ComponentMethodDescriptor> componentMethods(); + + /** Returns a descriptor for the creator type for this component type, if the user defined one. */ + public abstract Optional<ComponentCreatorDescriptor> creatorDescriptor(); /** Returns {@code true} if this is a subcomponent. */ public final boolean isSubcomponent() { @@ -136,18 +157,6 @@ public abstract class ComponentDescriptor { return annotation().isRealComponent(); } - /** - * The element that defines the component. This is the element to which the {@link #annotation()} - * was applied. - */ - public abstract XTypeElement typeElement(); - - /** - * The set of component dependencies listed in {@link Component#dependencies} or {@link - * dagger.producers.ProductionComponent#dependencies()}. - */ - public abstract ImmutableSet<ComponentRequirement> dependencies(); - /** The non-abstract {@link #modules()} and the {@link #dependencies()}. */ public final ImmutableSet<ComponentRequirement> dependenciesAndConcreteModules() { return Stream.concat( @@ -158,12 +167,6 @@ public abstract class ComponentDescriptor { .collect(toImmutableSet()); } - /** - * The {@link ModuleDescriptor modules} declared in {@link Component#modules()} and reachable by - * traversing {@link Module#includes()}. - */ - public abstract ImmutableSet<ModuleDescriptor> modules(); - /** The types of the {@link #modules()}. */ public final ImmutableSet<XTypeElement> moduleTypes() { return modules().stream().map(ModuleDescriptor::moduleElement).collect(toImmutableSet()); @@ -198,13 +201,21 @@ public abstract class ComponentDescriptor { } /** - * This component's {@linkplain #dependencies() dependencies} keyed by each provision or - * production method defined by that dependency. Note that the dependencies' types are not simply - * the enclosing type of the method; a method may be declared by a supertype of the actual - * dependency. + * Returns this component's dependencies keyed by its provision/production method. + * + * <p>Note that the dependencies' types are not simply the enclosing type of the method; a method + * may be declared by a supertype of the actual dependency. */ - public abstract ImmutableMap<XMethodElement, ComponentRequirement> - dependenciesByDependencyMethod(); + @Memoized + public ImmutableMap<XMethodElement, ComponentRequirement> dependenciesByDependencyMethod() { + ImmutableMap.Builder<XMethodElement, ComponentRequirement> builder = ImmutableMap.builder(); + for (ComponentRequirement componentDependency : dependencies()) { + XTypeElements.getAllMethods(componentDependency.typeElement()).stream() + .filter(ComponentDescriptor::isComponentContributionMethod) + .forEach(method -> builder.put(method, componentDependency)); + } + return builder.buildOrThrow(); + } /** The {@linkplain #dependencies() component dependency} that defines a method. */ public final ComponentRequirement getDependencyThatDefinesMethod(XElement method) { @@ -216,9 +227,6 @@ public abstract class ComponentDescriptor { return dependenciesByDependencyMethod().get(method); } - /** The scopes of the component. */ - public abstract ImmutableSet<Scope> scopes(); - /** * All {@link Subcomponent}s which are direct children of this component. This includes * subcomponents installed from {@link Module#subcomponents()} as well as subcomponent {@linkplain @@ -233,19 +241,6 @@ public abstract class ComponentDescriptor { .build(); } - /** - * All {@linkplain Subcomponent direct child} components that are declared by a {@linkplain - * Module#subcomponents() module's subcomponents}. - */ - abstract ImmutableSet<ComponentDescriptor> childComponentsDeclaredByModules(); - - /** - * All {@linkplain Subcomponent direct child} components that are declared by a subcomponent - * factory method. - */ - public abstract ImmutableBiMap<ComponentMethodDescriptor, ComponentDescriptor> - childComponentsDeclaredByFactoryMethods(); - /** Returns a map of {@link #childComponents()} indexed by {@link #typeElement()}. */ @Memoized public ImmutableMap<XTypeElement, ComponentDescriptor> childComponentsByElement() { @@ -259,13 +254,6 @@ public abstract class ComponentDescriptor { childComponentsDeclaredByFactoryMethods().inverse().get(childComponent)); } - /** - * All {@linkplain Subcomponent direct child} components that are declared by a subcomponent - * builder method. - */ - abstract ImmutableBiMap<ComponentMethodDescriptor, ComponentDescriptor> - childComponentsDeclaredByBuilderEntryPoints(); - private final Supplier<ImmutableMap<XTypeElement, ComponentDescriptor>> childComponentsByBuilderType = Suppliers.memoize( @@ -285,8 +273,6 @@ public abstract class ComponentDescriptor { builderType.getQualifiedName()); } - public abstract ImmutableSet<ComponentMethodDescriptor> componentMethods(); - /** Returns the first component method associated with this binding request, if one exists. */ public Optional<ComponentMethodDescriptor> firstMatchingComponentMethod(BindingRequest request) { return Optional.ofNullable(firstMatchingComponentMethods().get(request)); @@ -308,11 +294,6 @@ public abstract class ComponentDescriptor { .collect(toImmutableSet()); } - // TODO(gak): Consider making this non-optional and revising the - // interaction between the spec & generation - /** Returns a descriptor for the creator type for this component type, if the user defined one. */ - public abstract Optional<ComponentCreatorDescriptor> creatorDescriptor(); - /** * Returns {@code true} for components that have a creator, either because the user {@linkplain * #creatorDescriptor() specified one} or because it's a top-level component with an implicit @@ -408,4 +389,204 @@ public abstract class ComponentDescriptor { static boolean isComponentProductionMethod(XMethodElement method) { return isComponentContributionMethod(method) && isFutureType(method.getReturnType()); } + + /** A factory for creating a {@link ComponentDescriptor}. */ + @Singleton + public static final class Factory implements ClearableCache { + private final XProcessingEnv processingEnv; + private final DependencyRequestFactory dependencyRequestFactory; + private final ModuleDescriptor.Factory moduleDescriptorFactory; + private final InjectionAnnotations injectionAnnotations; + private final DaggerSuperficialValidation superficialValidation; + private final Map<XTypeElement, ComponentDescriptor> cache = new HashMap<>(); + + @Inject + Factory( + XProcessingEnv processingEnv, + DependencyRequestFactory dependencyRequestFactory, + ModuleDescriptor.Factory moduleDescriptorFactory, + InjectionAnnotations injectionAnnotations, + DaggerSuperficialValidation superficialValidation) { + this.processingEnv = processingEnv; + this.dependencyRequestFactory = dependencyRequestFactory; + this.moduleDescriptorFactory = moduleDescriptorFactory; + this.injectionAnnotations = injectionAnnotations; + this.superficialValidation = superficialValidation; + } + + /** Returns a descriptor for a root component type. */ + public ComponentDescriptor rootComponentDescriptor(XTypeElement typeElement) { + Optional<ComponentAnnotation> annotation = + rootComponentAnnotation(typeElement, superficialValidation); + checkArgument(annotation.isPresent(), "%s must have a component annotation", typeElement); + return create(typeElement, annotation.get()); + } + + /** Returns a descriptor for a subcomponent type. */ + public ComponentDescriptor subcomponentDescriptor(XTypeElement typeElement) { + Optional<ComponentAnnotation> annotation = + subcomponentAnnotation(typeElement, superficialValidation); + checkArgument(annotation.isPresent(), "%s must have a subcomponent annotation", typeElement); + return create(typeElement, annotation.get()); + } + + /** + * Returns a descriptor for a fictional component based on a module type in order to validate + * its bindings. + */ + public ComponentDescriptor moduleComponentDescriptor(XTypeElement typeElement) { + Optional<ModuleAnnotation> annotation = moduleAnnotation(typeElement, superficialValidation); + checkArgument(annotation.isPresent(), "%s must have a module annotation", typeElement); + return create(typeElement, ComponentAnnotation.fromModuleAnnotation(annotation.get())); + } + + private ComponentDescriptor create( + XTypeElement typeElement, ComponentAnnotation componentAnnotation) { + return reentrantComputeIfAbsent( + cache, typeElement, unused -> createUncached(typeElement, componentAnnotation)); + } + + private ComponentDescriptor createUncached( + XTypeElement typeElement, ComponentAnnotation componentAnnotation) { + ImmutableSet<ComponentRequirement> componentDependencies = + componentAnnotation.dependencyTypes().stream() + .map(ComponentRequirement::forDependency) + .collect(toImmutableSet()); + + // Start with the component's modules. For fictional components built from a module, start + // with that module. + ImmutableSet<XTypeElement> modules = + componentAnnotation.isRealComponent() + ? componentAnnotation.modules() + : ImmutableSet.of(typeElement); + + ImmutableSet<ModuleDescriptor> transitiveModules = + moduleDescriptorFactory.transitiveModules(modules); + + ImmutableSet.Builder<ComponentMethodDescriptor> componentMethodsBuilder = + ImmutableSet.builder(); + ImmutableBiMap.Builder<ComponentMethodDescriptor, ComponentDescriptor> + subcomponentsByFactoryMethod = ImmutableBiMap.builder(); + ImmutableMap.Builder<ComponentMethodDescriptor, ComponentDescriptor> + subcomponentsByBuilderMethod = ImmutableBiMap.builder(); + if (componentAnnotation.isRealComponent()) { + for (XMethodElement componentMethod : getAllUnimplementedMethods(typeElement)) { + ComponentMethodDescriptor componentMethodDescriptor = + getDescriptorForComponentMethod(componentAnnotation, typeElement, componentMethod); + componentMethodsBuilder.add(componentMethodDescriptor); + componentMethodDescriptor + .subcomponent() + .ifPresent( + subcomponent -> { + // If the dependency request is present, that means the method returns the + // subcomponent factory. + if (componentMethodDescriptor.dependencyRequest().isPresent()) { + subcomponentsByBuilderMethod.put(componentMethodDescriptor, subcomponent); + } else { + subcomponentsByFactoryMethod.put(componentMethodDescriptor, subcomponent); + } + }); + } + } + + // Validation should have ensured that this set will have at most one element. + ImmutableSet<XTypeElement> enclosedCreators = + enclosedAnnotatedTypes(typeElement, creatorAnnotationsFor(componentAnnotation)); + Optional<ComponentCreatorDescriptor> creatorDescriptor = + enclosedCreators.isEmpty() + ? Optional.empty() + : Optional.of( + ComponentCreatorDescriptor.create( + getOnlyElement(enclosedCreators), dependencyRequestFactory)); + + ImmutableSet<Scope> scopes = injectionAnnotations.getScopes(typeElement); + if (componentAnnotation.isProduction()) { + scopes = + ImmutableSet.<Scope>builder() + .addAll(scopes).add(productionScope(processingEnv)) + .build(); + } + + ImmutableSet<ComponentDescriptor> subcomponentsFromModules = + transitiveModules.stream() + .flatMap(transitiveModule -> transitiveModule.subcomponentDeclarations().stream()) + .map(SubcomponentDeclaration::subcomponentType) + .map(this::subcomponentDescriptor) + .collect(toImmutableSet()); + + return new AutoValue_ComponentDescriptor( + componentAnnotation, + typeElement, + componentDependencies, + transitiveModules, + scopes, + subcomponentsFromModules, + subcomponentsByFactoryMethod.buildOrThrow(), + subcomponentsByBuilderMethod.buildOrThrow(), + componentMethodsBuilder.build(), + creatorDescriptor); + } + + private ComponentMethodDescriptor getDescriptorForComponentMethod( + ComponentAnnotation componentAnnotation, + XTypeElement componentElement, + XMethodElement componentMethod) { + ComponentMethodDescriptor.Builder descriptor = + ComponentMethodDescriptor.builder(componentMethod); + + XMethodType resolvedComponentMethod = componentMethod.asMemberOf(componentElement.getType()); + XType returnType = resolvedComponentMethod.getReturnType(); + if (isDeclared(returnType) + && !injectionAnnotations.getQualifier(componentMethod).isPresent()) { + XTypeElement returnTypeElement = returnType.getTypeElement(); + if (returnTypeElement.hasAnyAnnotation(subcomponentAnnotations())) { + // It's a subcomponent factory method. There is no dependency request, and there could be + // any number of parameters. Just return the descriptor. + return descriptor.subcomponent(subcomponentDescriptor(returnTypeElement)).build(); + } + if (isSubcomponentCreator(returnTypeElement)) { + descriptor.subcomponent( + subcomponentDescriptor(returnTypeElement.getEnclosingTypeElement())); + } + } + + switch (componentMethod.getParameters().size()) { + case 0: + checkArgument( + !isVoid(returnType), "component method cannot be void: %s", componentMethod); + descriptor.dependencyRequest( + componentAnnotation.isProduction() + ? dependencyRequestFactory.forComponentProductionMethod( + componentMethod, resolvedComponentMethod) + : dependencyRequestFactory.forComponentProvisionMethod( + componentMethod, resolvedComponentMethod)); + break; + + case 1: + checkArgument( + isVoid(returnType) + // TODO(bcorso): Replace this with isSameType()? + || returnType + .getTypeName() + .equals(resolvedComponentMethod.getParameterTypes().get(0).getTypeName()), + "members injection method must return void or parameter type: %s", + componentMethod); + descriptor.dependencyRequest( + dependencyRequestFactory.forComponentMembersInjectionMethod( + componentMethod, resolvedComponentMethod)); + break; + + default: + throw new IllegalArgumentException( + "component method has too many parameters: " + componentMethod); + } + + return descriptor.build(); + } + + @Override + public void clearCache() { + cache.clear(); + } + } } diff --git a/java/dagger/internal/codegen/binding/ComponentDescriptorFactory.java b/java/dagger/internal/codegen/binding/ComponentDescriptorFactory.java deleted file mode 100644 index 1d0945078..000000000 --- a/java/dagger/internal/codegen/binding/ComponentDescriptorFactory.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (C) 2014 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.internal.codegen.binding; - -import static androidx.room.compiler.processing.XTypeKt.isVoid; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.collect.Iterables.getOnlyElement; -import static dagger.internal.codegen.base.ComponentAnnotation.rootComponentAnnotation; -import static dagger.internal.codegen.base.ComponentAnnotation.subcomponentAnnotation; -import static dagger.internal.codegen.base.ComponentAnnotation.subcomponentAnnotations; -import static dagger.internal.codegen.base.ComponentCreatorAnnotation.creatorAnnotationsFor; -import static dagger.internal.codegen.base.ModuleAnnotation.moduleAnnotation; -import static dagger.internal.codegen.base.Scopes.productionScope; -import static dagger.internal.codegen.binding.ConfigurationAnnotations.enclosedAnnotatedTypes; -import static dagger.internal.codegen.binding.ConfigurationAnnotations.isSubcomponentCreator; -import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; -import static dagger.internal.codegen.xprocessing.XTypeElements.getAllUnimplementedMethods; -import static dagger.internal.codegen.xprocessing.XTypes.isDeclared; - -import androidx.room.compiler.processing.XMethodElement; -import androidx.room.compiler.processing.XMethodType; -import androidx.room.compiler.processing.XProcessingEnv; -import androidx.room.compiler.processing.XType; -import androidx.room.compiler.processing.XTypeElement; -import com.google.common.collect.ImmutableBiMap; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import dagger.internal.codegen.base.ComponentAnnotation; -import dagger.internal.codegen.base.DaggerSuperficialValidation; -import dagger.internal.codegen.base.ModuleAnnotation; -import dagger.internal.codegen.binding.ComponentDescriptor.ComponentMethodDescriptor; -import dagger.internal.codegen.model.Scope; -import dagger.internal.codegen.xprocessing.XTypeElements; -import java.util.Optional; -import javax.inject.Inject; - -/** A factory for {@link ComponentDescriptor}s. */ -public final class ComponentDescriptorFactory { - private final XProcessingEnv processingEnv; - private final DependencyRequestFactory dependencyRequestFactory; - private final ModuleDescriptor.Factory moduleDescriptorFactory; - private final InjectionAnnotations injectionAnnotations; - private final DaggerSuperficialValidation superficialValidation; - - @Inject - ComponentDescriptorFactory( - XProcessingEnv processingEnv, - DependencyRequestFactory dependencyRequestFactory, - ModuleDescriptor.Factory moduleDescriptorFactory, - InjectionAnnotations injectionAnnotations, - DaggerSuperficialValidation superficialValidation) { - this.processingEnv = processingEnv; - this.dependencyRequestFactory = dependencyRequestFactory; - this.moduleDescriptorFactory = moduleDescriptorFactory; - this.injectionAnnotations = injectionAnnotations; - this.superficialValidation = superficialValidation; - } - - /** Returns a descriptor for a root component type. */ - public ComponentDescriptor rootComponentDescriptor(XTypeElement typeElement) { - Optional<ComponentAnnotation> annotation = - rootComponentAnnotation(typeElement, superficialValidation); - checkArgument(annotation.isPresent(), "%s must have a component annotation", typeElement); - return create(typeElement, annotation.get()); - } - - /** Returns a descriptor for a subcomponent type. */ - public ComponentDescriptor subcomponentDescriptor(XTypeElement typeElement) { - Optional<ComponentAnnotation> annotation = - subcomponentAnnotation(typeElement, superficialValidation); - checkArgument(annotation.isPresent(), "%s must have a subcomponent annotation", typeElement); - return create(typeElement, annotation.get()); - } - - /** - * Returns a descriptor for a fictional component based on a module type in order to validate its - * bindings. - */ - public ComponentDescriptor moduleComponentDescriptor(XTypeElement typeElement) { - Optional<ModuleAnnotation> annotation = moduleAnnotation(typeElement, superficialValidation); - checkArgument(annotation.isPresent(), "%s must have a module annotation", typeElement); - return create(typeElement, ComponentAnnotation.fromModuleAnnotation(annotation.get())); - } - - private ComponentDescriptor create( - XTypeElement typeElement, ComponentAnnotation componentAnnotation) { - ImmutableSet<ComponentRequirement> componentDependencies = - componentAnnotation.dependencyTypes().stream() - .map(ComponentRequirement::forDependency) - .collect(toImmutableSet()); - - ImmutableMap.Builder<XMethodElement, ComponentRequirement> dependenciesByDependencyMethod = - ImmutableMap.builder(); - for (ComponentRequirement componentDependency : componentDependencies) { - XTypeElements.getAllMethods(componentDependency.typeElement()).stream() - .filter(ComponentDescriptor::isComponentContributionMethod) - .forEach(method -> dependenciesByDependencyMethod.put(method, componentDependency)); - } - - // Start with the component's modules. For fictional components built from a module, start with - // that module. - ImmutableSet<XTypeElement> modules = - componentAnnotation.isRealComponent() - ? componentAnnotation.modules() - : ImmutableSet.of(typeElement); - - ImmutableSet<ModuleDescriptor> transitiveModules = - moduleDescriptorFactory.transitiveModules(modules); - - ImmutableSet<ComponentDescriptor> subcomponentsFromModules = - transitiveModules.stream() - .flatMap(transitiveModule -> transitiveModule.subcomponentDeclarations().stream()) - .map(SubcomponentDeclaration::subcomponentType) - .map(this::subcomponentDescriptor) - .collect(toImmutableSet()); - - ImmutableSet.Builder<ComponentMethodDescriptor> componentMethodsBuilder = - ImmutableSet.builder(); - ImmutableBiMap.Builder<ComponentMethodDescriptor, ComponentDescriptor> - subcomponentsByFactoryMethod = ImmutableBiMap.builder(); - ImmutableBiMap.Builder<ComponentMethodDescriptor, ComponentDescriptor> - subcomponentsByBuilderMethod = ImmutableBiMap.builder(); - if (componentAnnotation.isRealComponent()) { - for (XMethodElement componentMethod : getAllUnimplementedMethods(typeElement)) { - ComponentMethodDescriptor componentMethodDescriptor = - getDescriptorForComponentMethod(componentAnnotation, typeElement, componentMethod); - componentMethodsBuilder.add(componentMethodDescriptor); - componentMethodDescriptor - .subcomponent() - .ifPresent( - subcomponent -> { - // If the dependency request is present, that means the method returns the - // subcomponent factory. - if (componentMethodDescriptor.dependencyRequest().isPresent()) { - subcomponentsByBuilderMethod.put(componentMethodDescriptor, subcomponent); - } else { - subcomponentsByFactoryMethod.put(componentMethodDescriptor, subcomponent); - } - }); - } - } - - // Validation should have ensured that this set will have at most one element. - ImmutableSet<XTypeElement> enclosedCreators = - enclosedAnnotatedTypes(typeElement, creatorAnnotationsFor(componentAnnotation)); - Optional<ComponentCreatorDescriptor> creatorDescriptor = - enclosedCreators.isEmpty() - ? Optional.empty() - : Optional.of( - ComponentCreatorDescriptor.create( - getOnlyElement(enclosedCreators), dependencyRequestFactory)); - - ImmutableSet<Scope> scopes = injectionAnnotations.getScopes(typeElement); - if (componentAnnotation.isProduction()) { - scopes = - ImmutableSet.<Scope>builder().addAll(scopes).add(productionScope(processingEnv)).build(); - } - - return ComponentDescriptor.create( - componentAnnotation, - typeElement, - componentDependencies, - transitiveModules, - dependenciesByDependencyMethod.build(), - scopes, - subcomponentsFromModules, - subcomponentsByFactoryMethod.build(), - subcomponentsByBuilderMethod.build(), - componentMethodsBuilder.build(), - creatorDescriptor); - } - - private ComponentMethodDescriptor getDescriptorForComponentMethod( - ComponentAnnotation componentAnnotation, - XTypeElement componentElement, - XMethodElement componentMethod) { - ComponentMethodDescriptor.Builder descriptor = - ComponentMethodDescriptor.builder(componentMethod); - - XMethodType resolvedComponentMethod = componentMethod.asMemberOf(componentElement.getType()); - XType returnType = resolvedComponentMethod.getReturnType(); - if (isDeclared(returnType) && !injectionAnnotations.getQualifier(componentMethod).isPresent()) { - XTypeElement returnTypeElement = returnType.getTypeElement(); - if (returnTypeElement.hasAnyAnnotation(subcomponentAnnotations())) { - // It's a subcomponent factory method. There is no dependency request, and there could be - // any number of parameters. Just return the descriptor. - return descriptor.subcomponent(subcomponentDescriptor(returnTypeElement)).build(); - } - if (isSubcomponentCreator(returnTypeElement)) { - descriptor.subcomponent( - subcomponentDescriptor(returnTypeElement.getEnclosingTypeElement())); - } - } - - switch (componentMethod.getParameters().size()) { - case 0: - checkArgument(!isVoid(returnType), "component method cannot be void: %s", componentMethod); - descriptor.dependencyRequest( - componentAnnotation.isProduction() - ? dependencyRequestFactory.forComponentProductionMethod( - componentMethod, resolvedComponentMethod) - : dependencyRequestFactory.forComponentProvisionMethod( - componentMethod, resolvedComponentMethod)); - break; - - case 1: - checkArgument( - isVoid(returnType) - // TODO(bcorso): Replace this with isSameType()? - || returnType - .getTypeName() - .equals(resolvedComponentMethod.getParameterTypes().get(0).getTypeName()), - "members injection method must return void or parameter type: %s", - componentMethod); - descriptor.dependencyRequest( - dependencyRequestFactory.forComponentMembersInjectionMethod( - componentMethod, resolvedComponentMethod)); - break; - - default: - throw new IllegalArgumentException( - "component method has too many parameters: " + componentMethod); - } - - return descriptor.build(); - } -} diff --git a/java/dagger/internal/codegen/binding/ComponentRequirement.java b/java/dagger/internal/codegen/binding/ComponentRequirement.java index df105773e..1779ec1d6 100644 --- a/java/dagger/internal/codegen/binding/ComponentRequirement.java +++ b/java/dagger/internal/codegen/binding/ComponentRequirement.java @@ -145,7 +145,7 @@ public abstract class ComponentRequirement { * <p>Alternatively, if the module is a Kotlin Object then the binding methods are considered * {@code static}, requiring no module instance. */ - private boolean requiresModuleInstance() { + public boolean requiresModuleInstance() { if (typeElement().isKotlinObject() || typeElement().isCompanionObject()) { return false; } diff --git a/java/dagger/internal/codegen/binding/DependencyRequestFormatter.java b/java/dagger/internal/codegen/binding/DependencyRequestFormatter.java index 80591b121..853ee994b 100644 --- a/java/dagger/internal/codegen/binding/DependencyRequestFormatter.java +++ b/java/dagger/internal/codegen/binding/DependencyRequestFormatter.java @@ -25,12 +25,10 @@ import static dagger.internal.codegen.base.RequestKinds.requestType; import androidx.room.compiler.processing.XElement; import androidx.room.compiler.processing.XProcessingEnv; import com.google.errorprone.annotations.CanIgnoreReturnValue; -import dagger.Provides; import dagger.internal.codegen.base.Formatter; import dagger.internal.codegen.model.DaggerAnnotation; import dagger.internal.codegen.model.DependencyRequest; import dagger.internal.codegen.xprocessing.XTypes; -import dagger.producers.Produces; import java.util.Optional; import javax.inject.Inject; @@ -43,8 +41,7 @@ import javax.inject.Inject; * <dd>{@code @Qualifier SomeType is provided at\n ComponentType.method()} * <dt>For component injection methods * <dd>{@code SomeType is injected at\n ComponentType.method(foo)} - * <dt>For parameters to {@link Provides @Provides}, {@link Produces @Produces}, or {@link - * Inject @Inject} methods: + * <dt>For parameters to {@code @Provides}, {@code @Produces}, or {@code @Inject} methods: * <dd>{@code @Qualified ResolvedType is injected at\n EnclosingType.method([…, ]param[, …])} * <dt>For parameters to {@link Inject @Inject} constructors: * <dd>{@code @Qualified ResolvedType is injected at\n EnclosingType([…, ]param[, …])} diff --git a/java/dagger/internal/codegen/binding/FrameworkField.java b/java/dagger/internal/codegen/binding/FrameworkField.java index b1d1cf91b..a9f3bbfbd 100644 --- a/java/dagger/internal/codegen/binding/FrameworkField.java +++ b/java/dagger/internal/codegen/binding/FrameworkField.java @@ -24,12 +24,14 @@ import static dagger.internal.codegen.model.BindingKind.MEMBERS_INJECTOR; import static dagger.internal.codegen.xprocessing.XElements.getSimpleName; import androidx.room.compiler.processing.XElement; -import androidx.room.compiler.processing.XType; import com.google.auto.value.AutoValue; import com.google.common.base.CaseFormat; +import com.google.common.base.Preconditions; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.ParameterizedTypeName; import com.squareup.javapoet.TypeName; +import dagger.internal.codegen.base.MapType; +import dagger.internal.codegen.javapoet.TypeNames; import java.util.Optional; /** @@ -49,16 +51,17 @@ public abstract class FrameworkField { /** * Creates a framework field. * - * @param frameworkClassName the name of the framework class (e.g., {@link javax.inject.Provider}) - * @param valueTypeName the name of the type parameter of the framework class (e.g., {@code Foo} - * for {@code Provider<Foo>} - * @param fieldName the name of the field + * @param fieldType the type of the framework field (e.g., {@code Provider<Foo>}). + * @param fieldName the base name of the field. The name of the raw type of the field will be + * added as a suffix */ - public static FrameworkField create( - ClassName frameworkClassName, TypeName valueTypeName, String fieldName) { - String suffix = frameworkClassName.simpleName(); + public static FrameworkField create(TypeName fieldType, String fieldName) { + Preconditions.checkState( + fieldType instanceof ClassName || fieldType instanceof ParameterizedTypeName, + "Can only create a field with a class name or parameterized type name"); + String suffix = ((ClassName) TypeNames.rawTypeName(fieldType)).simpleName(); return new AutoValue_FrameworkField( - ParameterizedTypeName.get(frameworkClassName, valueTypeName), + fieldType, fieldName.endsWith(suffix) ? fieldName : fieldName + suffix); } @@ -71,15 +74,26 @@ public abstract class FrameworkField { public static FrameworkField forBinding( ContributionBinding binding, Optional<ClassName> frameworkClassName) { return create( - frameworkClassName.orElse(binding.frameworkType().frameworkClassName()), - fieldValueType(binding).getTypeName(), + fieldType(binding, frameworkClassName.orElse(binding.frameworkType().frameworkClassName())), frameworkFieldName(binding)); } - private static XType fieldValueType(ContributionBinding binding) { - return binding.contributionType().isMultibinding() - ? binding.contributedType() - : binding.key().type().xprocessing(); + private static TypeName fieldType(ContributionBinding binding, ClassName frameworkClassName) { + if (binding.contributionType().isMultibinding()) { + return ParameterizedTypeName.get(frameworkClassName, binding.contributedType().getTypeName()); + } + + // If the binding key type is a Map<K, Provider<V>>, we need to change field type to a raw + // type. This is because it actually needs to be changed to Map<K, dagger.internal.Provider<V>>, + // but that gets into assignment issues when the field is passed to methods that expect + // Map<K, javax.inject.Provider<V>>. We could add casts everywhere, but it is easier to just + // make the field itself a raw type. + if (MapType.isMapOfProvider(binding.contributedType())) { + return frameworkClassName; + } + + return ParameterizedTypeName.get( + frameworkClassName, binding.key().type().xprocessing().getTypeName()); } private static String frameworkFieldName(ContributionBinding binding) { @@ -104,7 +118,7 @@ public abstract class FrameworkField { } } - public abstract ParameterizedTypeName type(); + public abstract TypeName type(); public abstract String name(); } diff --git a/java/dagger/internal/codegen/binding/FrameworkType.java b/java/dagger/internal/codegen/binding/FrameworkType.java index ce3b149bc..c99594892 100644 --- a/java/dagger/internal/codegen/binding/FrameworkType.java +++ b/java/dagger/internal/codegen/binding/FrameworkType.java @@ -96,7 +96,8 @@ public enum FrameworkType { case PROVIDER_OF_LAZY: return Expression.create( - from.type().rewrapType(TypeNames.LAZY).wrapType(TypeNames.PROVIDER), codeBlock); + from.type().rewrapType(TypeNames.LAZY).wrapType(TypeNames.DAGGER_PROVIDER), + codeBlock); case FUTURE: return Expression.create(from.type().rewrapType(TypeNames.LISTENABLE_FUTURE), codeBlock); @@ -178,7 +179,7 @@ public enum FrameworkType { public ClassName frameworkClassName() { switch (this) { case PROVIDER: - return TypeNames.PROVIDER; + return TypeNames.DAGGER_PROVIDER; case PRODUCER_NODE: // TODO(cgdecker): Replace this with new class for representing internal producer nodes. // Currently the new class is CancellableProducer, but it may be changed to ProducerNode and diff --git a/java/dagger/internal/codegen/binding/FrameworkTypeMapper.java b/java/dagger/internal/codegen/binding/FrameworkTypeMapper.java index 0e17d9687..bd439bf93 100644 --- a/java/dagger/internal/codegen/binding/FrameworkTypeMapper.java +++ b/java/dagger/internal/codegen/binding/FrameworkTypeMapper.java @@ -19,12 +19,10 @@ package dagger.internal.codegen.binding; import static dagger.internal.codegen.binding.BindingType.PRODUCTION; import dagger.internal.codegen.model.RequestKind; -import dagger.producers.Producer; -import javax.inject.Provider; /** * A mapper for associating a {@link RequestKind} to a {@link FrameworkType}, dependent on the type - * of code to be generated (e.g., for {@link Provider} or {@link Producer}). + * of code to be generated (e.g., for {@code Provider} or {@code Producer}). */ public enum FrameworkTypeMapper { FOR_PROVIDER() { diff --git a/java/dagger/internal/codegen/binding/InjectionAnnotations.java b/java/dagger/internal/codegen/binding/InjectionAnnotations.java index a8adb15dd..d4e1f90b7 100644 --- a/java/dagger/internal/codegen/binding/InjectionAnnotations.java +++ b/java/dagger/internal/codegen/binding/InjectionAnnotations.java @@ -22,12 +22,13 @@ import static androidx.room.compiler.processing.XElementKt.isMethod; import static androidx.room.compiler.processing.XElementKt.isMethodParameter; import static androidx.room.compiler.processing.XElementKt.isTypeElement; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; import static com.google.common.collect.Iterables.getOnlyElement; import static dagger.internal.codegen.binding.SourceFiles.factoryNameForElement; import static dagger.internal.codegen.binding.SourceFiles.memberInjectedFieldSignatureForVariable; import static dagger.internal.codegen.binding.SourceFiles.membersInjectorNameForType; -import static dagger.internal.codegen.extension.DaggerCollectors.onlyElement; import static dagger.internal.codegen.extension.DaggerCollectors.toOptional; +import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; import static dagger.internal.codegen.xprocessing.XElements.asField; import static dagger.internal.codegen.xprocessing.XElements.asMethod; @@ -42,14 +43,17 @@ import androidx.room.compiler.processing.XExecutableElement; import androidx.room.compiler.processing.XFieldElement; import androidx.room.compiler.processing.XProcessingEnv; import androidx.room.compiler.processing.XTypeElement; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.squareup.javapoet.ClassName; import dagger.internal.codegen.base.DaggerSuperficialValidation; +import dagger.internal.codegen.base.ElementFormatter; import dagger.internal.codegen.compileroption.CompilerOptions; import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.kotlin.KotlinMetadataUtil; import dagger.internal.codegen.model.DaggerAnnotation; import dagger.internal.codegen.model.Scope; +import dagger.internal.codegen.xprocessing.XAnnotations; import java.util.Optional; import java.util.stream.Stream; import javax.inject.Inject; @@ -100,18 +104,7 @@ public final class InjectionAnnotations { public ImmutableSet<Scope> getScopes(XElement element) { superficialValidation.validateTypeOf(element); ImmutableSet<Scope> scopes = - getScopesFromScopeMetadata(element) - .orElseGet( - () -> { - // Validate the annotation types before we check for @Scope, otherwise the @Scope - // annotation may appear to be missing (b/213880825). - superficialValidation.validateAnnotationTypesOf(element); - return element.getAllAnnotations().stream() - .filter(InjectionAnnotations::hasScopeAnnotation) - .map(DaggerAnnotation::from) - .map(Scope::scope) - .collect(toImmutableSet()); - }); + getScopesWithMetadata(element).orElseGet(() -> getScopesWithoutMetadata(element)); // Fully validate each scope to ensure its values are also valid. scopes.stream() @@ -120,7 +113,18 @@ public final class InjectionAnnotations { return scopes; } - private Optional<ImmutableSet<Scope>> getScopesFromScopeMetadata(XElement element) { + private ImmutableSet<Scope> getScopesWithoutMetadata(XElement element) { + // Validate the annotation types before we check for @Scope, otherwise the @Scope + // annotation may appear to be missing (b/213880825). + superficialValidation.validateAnnotationTypesOf(element); + return element.getAllAnnotations().stream() + .filter(InjectionAnnotations::hasScopeAnnotation) + .map(DaggerAnnotation::from) + .map(Scope::scope) + .collect(toImmutableSet()); + } + + private Optional<ImmutableSet<Scope>> getScopesWithMetadata(XElement element) { Optional<XAnnotation> scopeMetadata = getScopeMetadata(element); if (!scopeMetadata.isPresent()) { return Optional.empty(); @@ -129,13 +133,20 @@ public final class InjectionAnnotations { if (scopeName.isEmpty()) { return Optional.of(ImmutableSet.of()); } - XAnnotation scopeAnnotation = + ImmutableList<XAnnotation> scopeAnnotations = element.getAllAnnotations().stream() .filter( annotation -> scopeName.contentEquals( annotation.getType().getTypeElement().getQualifiedName())) - .collect(onlyElement()); + .collect(toImmutableList()); + checkState( + scopeAnnotations.size() == 1, + "Expected %s to have a scope annotation for %s but found: %s", + ElementFormatter.elementToString(element), + scopeName, + scopeAnnotations.stream().map(XAnnotations::toStableString).collect(toImmutableList())); + XAnnotation scopeAnnotation = getOnlyElement(scopeAnnotations); // Do superficial validation before we convert to a Scope, otherwise the @Scope annotation may // appear to be missing from the annotation if it's no longer on the classpath. superficialValidation.validateAnnotationTypeOf(element, scopeAnnotation); @@ -170,7 +181,7 @@ public final class InjectionAnnotations { return Optional.empty(); } - /* + /** * Returns the qualifier on the given element if it exists. * * <p>The {@code QualifierMetadata} is used to avoid superficial validation on unnecessary @@ -203,16 +214,8 @@ public final class InjectionAnnotations { public ImmutableSet<XAnnotation> getQualifiers(XElement element) { superficialValidation.validateTypeOf(element); ImmutableSet<XAnnotation> qualifiers = - getQualifiersFromQualifierMetadata(element) - .orElseGet( - () -> { - // Validate the annotation types before we check for @Qualifier, otherwise the - // @Qualifier annotation may appear to be missing (b/213880825). - superficialValidation.validateAnnotationTypesOf(element); - return element.getAllAnnotations().stream() - .filter(InjectionAnnotations::hasQualifierAnnotation) - .collect(toImmutableSet()); - }); + getQualifiersWithMetadata(element) + .orElseGet(() -> getQualifiersWithoutMetadata(element)); if (isField(element)) { XFieldElement field = asField(element); @@ -237,7 +240,16 @@ public final class InjectionAnnotations { return qualifiers; } - private Optional<ImmutableSet<XAnnotation>> getQualifiersFromQualifierMetadata(XElement element) { + private ImmutableSet<XAnnotation> getQualifiersWithoutMetadata(XElement element) { + // Validate the annotation types before we check for @Qualifier, otherwise the + // @Qualifier annotation may appear to be missing (b/213880825). + superficialValidation.validateAnnotationTypesOf(element); + return element.getAllAnnotations().stream() + .filter(InjectionAnnotations::hasQualifierAnnotation) + .collect(toImmutableSet()); + } + + private Optional<ImmutableSet<XAnnotation>> getQualifiersWithMetadata(XElement element) { Optional<XAnnotation> qualifierMetadata = getQualifierMetadata(element); if (!qualifierMetadata.isPresent()) { return Optional.empty(); diff --git a/java/dagger/internal/codegen/binding/InjectionSiteFactory.java b/java/dagger/internal/codegen/binding/InjectionSiteFactory.java index 5ede20042..36e831bfd 100644 --- a/java/dagger/internal/codegen/binding/InjectionSiteFactory.java +++ b/java/dagger/internal/codegen/binding/InjectionSiteFactory.java @@ -68,10 +68,13 @@ final class InjectionSiteFactory { XTypeElement typeElement = currentType.get().getTypeElement(); enclosingTypeElementOrder.put(typeElement, enclosingTypeElementOrder.size()); for (XElement enclosedElement : typeElement.getEnclosedElements()) { - enclosedElementOrder.put(enclosedElement, enclosedElementOrder.size()); injectionSiteVisitor .visit(enclosedElement, currentType.get()) - .ifPresent(injectionSites::add); + .ifPresent( + injectionSite -> { + enclosedElementOrder.put(enclosedElement, enclosedElementOrder.size()); + injectionSites.add(injectionSite); + }); } } return ImmutableSortedSet.copyOf( diff --git a/java/dagger/internal/codegen/binding/LegacyBindingGraph.java b/java/dagger/internal/codegen/binding/LegacyBindingGraph.java deleted file mode 100644 index b38697e8d..000000000 --- a/java/dagger/internal/codegen/binding/LegacyBindingGraph.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2014 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.internal.codegen.binding; - -import androidx.room.compiler.processing.XTypeElement; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Iterables; -import com.google.common.collect.Maps; -import com.google.common.collect.Multimaps; -import dagger.internal.codegen.model.Key; -import dagger.internal.codegen.model.RequestKind; -import java.util.Collection; -import java.util.Map; - -// TODO(bcorso): Remove the LegacyBindingGraph after we've migrated to the new BindingGraph. -/** The canonical representation of a full-resolved graph. */ -final class LegacyBindingGraph { - private final ComponentDescriptor componentDescriptor; - private final ImmutableMap<Key, ResolvedBindings> contributionBindings; - private final ImmutableMap<Key, ResolvedBindings> membersInjectionBindings; - private final ImmutableList<LegacyBindingGraph> subgraphs; - - LegacyBindingGraph( - ComponentDescriptor componentDescriptor, - ImmutableMap<Key, ResolvedBindings> contributionBindings, - ImmutableMap<Key, ResolvedBindings> membersInjectionBindings, - ImmutableList<LegacyBindingGraph> subgraphs) { - this.componentDescriptor = componentDescriptor; - this.contributionBindings = contributionBindings; - this.membersInjectionBindings = membersInjectionBindings; - this.subgraphs = checkForDuplicates(subgraphs); - } - - ComponentDescriptor componentDescriptor() { - return componentDescriptor; - } - - ResolvedBindings resolvedBindings(BindingRequest request) { - return request.isRequestKind(RequestKind.MEMBERS_INJECTION) - ? membersInjectionBindings.get(request.key()) - : contributionBindings.get(request.key()); - } - - Iterable<ResolvedBindings> resolvedBindings() { - // Don't return an immutable collection - this is only ever used for looping over all bindings - // in the graph. Copying is wasteful, especially if is a hashing collection, since the values - // should all, by definition, be distinct. - return Iterables.concat(membersInjectionBindings.values(), contributionBindings.values()); - } - - ImmutableList<LegacyBindingGraph> subgraphs() { - return subgraphs; - } - - private static ImmutableList<LegacyBindingGraph> checkForDuplicates( - ImmutableList<LegacyBindingGraph> graphs) { - Map<XTypeElement, Collection<LegacyBindingGraph>> duplicateGraphs = - Maps.filterValues( - Multimaps.index(graphs, graph -> graph.componentDescriptor().typeElement()).asMap(), - overlapping -> overlapping.size() > 1); - if (!duplicateGraphs.isEmpty()) { - throw new IllegalArgumentException("Expected no duplicates: " + duplicateGraphs); - } - return graphs; - } -} diff --git a/java/dagger/internal/codegen/binding/MapKeys.java b/java/dagger/internal/codegen/binding/MapKeys.java index c156dbb06..61ef9f2b2 100644 --- a/java/dagger/internal/codegen/binding/MapKeys.java +++ b/java/dagger/internal/codegen/binding/MapKeys.java @@ -199,5 +199,26 @@ public final class MapKeys { .build()); } + /** + * Returns if this binding is a map binding and uses @LazyClassKey for contributing class keys. + * + * <p>@LazyClassKey won't co-exist with @ClassKey in the graph, since the same binding type cannot + * use more than one @MapKey annotation type and Dagger validation will fail. + */ + public static boolean useLazyClassKey(Binding binding, BindingGraph graph) { + if (!binding.dependencies().isEmpty()) { + ContributionBinding contributionBinding = + graph.contributionBinding(binding.dependencies().iterator().next().key()); + return contributionBinding.mapKey().isPresent() + && contributionBinding + .mapKey() + .get() + .xprocessing() + .getClassName() + .equals(TypeNames.LAZY_CLASS_KEY); + } + return false; + } + private MapKeys() {} } diff --git a/java/dagger/internal/codegen/binding/MethodSignatureFormatter.java b/java/dagger/internal/codegen/binding/MethodSignatureFormatter.java index e98abcca2..d7fea80b7 100644 --- a/java/dagger/internal/codegen/binding/MethodSignatureFormatter.java +++ b/java/dagger/internal/codegen/binding/MethodSignatureFormatter.java @@ -16,13 +16,14 @@ package dagger.internal.codegen.binding; +import static androidx.room.compiler.processing.compat.XConverters.getProcessingEnv; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkState; import static dagger.internal.codegen.base.DiagnosticFormatting.stripCommonTypePrefixes; +import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; import static dagger.internal.codegen.xprocessing.XElements.closestEnclosingTypeElement; import static dagger.internal.codegen.xprocessing.XElements.getSimpleName; import static dagger.internal.codegen.xprocessing.XTypes.isDeclared; -import static java.util.stream.Collectors.joining; import androidx.room.compiler.processing.XAnnotation; import androidx.room.compiler.processing.XExecutableElement; @@ -33,12 +34,13 @@ import androidx.room.compiler.processing.XMethodType; import androidx.room.compiler.processing.XType; import androidx.room.compiler.processing.XTypeElement; import androidx.room.compiler.processing.XVariableElement; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Streams; import com.squareup.javapoet.ClassName; import dagger.internal.codegen.base.Formatter; import dagger.internal.codegen.xprocessing.XAnnotations; import dagger.internal.codegen.xprocessing.XTypes; import java.util.Iterator; -import java.util.List; import java.util.Optional; import javax.inject.Inject; @@ -46,6 +48,8 @@ import javax.inject.Inject; public final class MethodSignatureFormatter extends Formatter<XExecutableElement> { private static final ClassName JET_BRAINS_NOT_NULL = ClassName.get("org.jetbrains.annotations", "NotNull"); + private static final ClassName JET_BRAINS_NULLABLE = + ClassName.get("org.jetbrains.annotations", "Nullable"); private final InjectionAnnotations injectionAnnotations; @@ -106,15 +110,9 @@ public final class MethodSignatureFormatter extends Formatter<XExecutableElement XTypeElement container, boolean includeReturnType) { StringBuilder builder = new StringBuilder(); - List<XAnnotation> annotations = method.getAllAnnotations(); - if (!annotations.isEmpty()) { - builder.append( - annotations.stream() - // Filter out @NotNull annotations added by KAPT to make error messages consistent - .filter(annotation -> !annotation.getClassName().equals(JET_BRAINS_NOT_NULL)) - .map(MethodSignatureFormatter::formatAnnotation) - .collect(joining(" "))) - .append(" "); + ImmutableList<String> formattedAnnotations = formatedAnnotations(method); + if (!formattedAnnotations.isEmpty()) { + builder.append(String.join(" ", formattedAnnotations)).append(" "); } if (getSimpleName(method).contentEquals("<init>")) { builder.append(container.getQualifiedName()); @@ -154,6 +152,34 @@ public final class MethodSignatureFormatter extends Formatter<XExecutableElement return stripCommonTypePrefixes(XTypes.toStableString(type)); } + private static ImmutableList<String> formatedAnnotations(XExecutableElement executableElement) { + Nullability nullability = Nullability.of(executableElement); + ImmutableList<String> formattedAnnotations = + Streams.concat( + executableElement.getAllAnnotations().stream() + // Filter out @NotNull annotations added by KAPT to make error messages + // consistent + .filter(annotation -> !annotation.getClassName().equals(JET_BRAINS_NOT_NULL)) + .map(MethodSignatureFormatter::formatAnnotation), + nullability.nullableAnnotations().stream() + // Filter out @NotNull annotations added by KAPT to make error messages + // consistent + .filter(annotation -> !annotation.equals(JET_BRAINS_NOT_NULL)) + .map(annotation -> String.format("@%s", annotation.canonicalName()))) + .distinct() + .collect(toImmutableList()); + if (nullability.isKotlinTypeNullable() + && nullability.nullableAnnotations().stream().noneMatch(JET_BRAINS_NULLABLE::equals) + && getProcessingEnv(executableElement).findTypeElement(JET_BRAINS_NULLABLE) != null) { + formattedAnnotations = + ImmutableList.<String>builder() + .addAll(formattedAnnotations) + .add(String.format("@%s", JET_BRAINS_NULLABLE.canonicalName())) + .build(); + } + return formattedAnnotations; + } + private static String formatAnnotation(XAnnotation annotation) { return stripCommonTypePrefixes(XAnnotations.toString(annotation)); } diff --git a/java/dagger/internal/codegen/binding/MonitoringModules.java b/java/dagger/internal/codegen/binding/MonitoringModules.java new file mode 100644 index 000000000..fc6dc021c --- /dev/null +++ b/java/dagger/internal/codegen/binding/MonitoringModules.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2023 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.internal.codegen.binding; + +import com.squareup.javapoet.ClassName; +import dagger.internal.codegen.base.ClearableCache; +import java.util.HashSet; +import java.util.Set; +import javax.inject.Inject; +import javax.inject.Singleton; + +/** Keeps track of modules generated in the current round by {@link MonitoringModuleGenerator}. */ +@Singleton +public final class MonitoringModules implements ClearableCache { + Set<ClassName> cache = new HashSet<>(); + + @Inject + MonitoringModules() {} + + public void add(ClassName module) { + cache.add(module); + } + + public boolean isEmpty() { + return cache.isEmpty(); + } + + @Override + public void clearCache() { + cache.clear(); + } +} diff --git a/java/dagger/internal/codegen/binding/Nullability.java b/java/dagger/internal/codegen/binding/Nullability.java index 190227ba0..4231a8fb0 100644 --- a/java/dagger/internal/codegen/binding/Nullability.java +++ b/java/dagger/internal/codegen/binding/Nullability.java @@ -18,7 +18,7 @@ package dagger.internal.codegen.binding; import static androidx.room.compiler.processing.XElementKt.isMethod; import static androidx.room.compiler.processing.XElementKt.isVariableElement; -import static dagger.internal.codegen.xprocessing.XAnnotations.getClassName; +import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; import static dagger.internal.codegen.xprocessing.XElements.asMethod; import static dagger.internal.codegen.xprocessing.XElements.asVariable; @@ -27,7 +27,10 @@ import androidx.room.compiler.processing.XElement; import androidx.room.compiler.processing.XNullability; import androidx.room.compiler.processing.XType; import com.google.auto.value.AutoValue; -import java.util.Optional; +import com.google.common.collect.ImmutableSet; +import com.squareup.javapoet.ClassName; +import dagger.internal.codegen.xprocessing.XAnnotations; +import java.util.stream.Stream; /** * Contains information about the nullability of an element. @@ -42,16 +45,43 @@ import java.util.Optional; @AutoValue public abstract class Nullability { /** A constant that can represent any non-null element. */ - public static final Nullability NOT_NULLABLE = new AutoValue_Nullability(false, Optional.empty()); + public static final Nullability NOT_NULLABLE = + new AutoValue_Nullability(false, ImmutableSet.of()); public static Nullability of(XElement element) { - Optional<XAnnotation> nullableAnnotation = getNullableAnnotation(element); - boolean isNullable = isKotlinTypeNullable(element) || nullableAnnotation.isPresent(); - return isNullable ? new AutoValue_Nullability(isNullable, nullableAnnotation) : NOT_NULLABLE; + return new AutoValue_Nullability( + /* isKotlinTypeNullable= */ isKotlinTypeNullable(element), + /* nullableAnnotations= */ getNullableAnnotations(element)); } + private static ImmutableSet<ClassName> getNullableAnnotations(XElement element) { + return getNullableAnnotations(element.getAllAnnotations().stream(), ImmutableSet.of()); + } + + private static ImmutableSet<ClassName> getNullableAnnotations( + Stream<XAnnotation> annotations, + ImmutableSet<ClassName> filterSet) { + return annotations + .map(XAnnotations::getClassName) + .filter(annotation -> annotation.simpleName().contentEquals("Nullable")) + .filter(annotation -> !filterSet.contains(annotation)) + .collect(toImmutableSet()); + } + + /** + * Returns {@code true} if the element's type is a Kotlin nullable type, e.g. {@code Foo?}. + * + * <p>Note that this method ignores any {@code @Nullable} type annotations and only looks for + * explicit {@code ?} usages on kotlin types. + */ private static boolean isKotlinTypeNullable(XElement element) { - if (isMethod(element)) { + if (element.getClosestMemberContainer().isFromJava()) { + // Note: Technically, it isn't possible for Java sources to have nullable types like in Kotlin + // sources, but for some reason KSP treats certain types as nullable if they have a + // specific @Nullable (TYPE_USE target) annotation. Thus, to avoid inconsistencies with KAPT, + // just return false if this element is from a java source. + return false; + } else if (isMethod(element)) { return isKotlinTypeNullable(asMethod(element).getReturnType()); } else if (isVariableElement(element)) { return isKotlinTypeNullable(asVariable(element).getType()); @@ -64,16 +94,13 @@ public abstract class Nullability { return type.getNullability() == XNullability.NULLABLE; } - /** Returns the first type that specifies this' nullability, or empty if none. */ - private static Optional<XAnnotation> getNullableAnnotation(XElement element) { - return element.getAllAnnotations().stream() - .filter(annotation -> getClassName(annotation).simpleName().contentEquals("Nullable")) - .findFirst(); - } + public abstract boolean isKotlinTypeNullable(); - public abstract boolean isNullable(); + public abstract ImmutableSet<ClassName> nullableAnnotations(); - public abstract Optional<XAnnotation> nullableAnnotation(); + public final boolean isNullable() { + return isKotlinTypeNullable() || !nullableAnnotations().isEmpty(); + } Nullability() {} } diff --git a/java/dagger/internal/codegen/binding/ResolvedBindings.java b/java/dagger/internal/codegen/binding/ResolvedBindings.java index 8a354429a..406ae41f5 100644 --- a/java/dagger/internal/codegen/binding/ResolvedBindings.java +++ b/java/dagger/internal/codegen/binding/ResolvedBindings.java @@ -27,6 +27,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSetMultimap; import com.google.common.collect.Multimap; +import dagger.internal.codegen.model.ComponentPath; import dagger.internal.codegen.model.Key; /** @@ -40,6 +41,9 @@ import dagger.internal.codegen.model.Key; */ @AutoValue abstract class ResolvedBindings { + /** The component path for the resolved bindings. */ + abstract ComponentPath componentPath(); + /** The binding key for which the {@link #bindings()} have been resolved. */ abstract Key key(); @@ -127,12 +131,14 @@ abstract class ResolvedBindings { /** Creates a {@link ResolvedBindings} for contribution bindings. */ static ResolvedBindings forContributionBindings( + ComponentPath componentPath, Key key, Multimap<XTypeElement, ContributionBinding> contributionBindings, Iterable<MultibindingDeclaration> multibindings, Iterable<SubcomponentDeclaration> subcomponentDeclarations, Iterable<OptionalBindingDeclaration> optionalBindingDeclarations) { return new AutoValue_ResolvedBindings( + componentPath, key, ImmutableSetMultimap.copyOf(contributionBindings), ImmutableMap.of(), @@ -145,10 +151,12 @@ abstract class ResolvedBindings { * Creates a {@link ResolvedBindings} for members injection bindings. */ static ResolvedBindings forMembersInjectionBinding( + ComponentPath componentPath, Key key, ComponentDescriptor owningComponent, MembersInjectionBinding ownedMembersInjectionBinding) { return new AutoValue_ResolvedBindings( + componentPath, key, ImmutableSetMultimap.of(), ImmutableMap.of(owningComponent.typeElement(), ownedMembersInjectionBinding), @@ -160,8 +168,9 @@ abstract class ResolvedBindings { /** * Creates a {@link ResolvedBindings} appropriate for when there are no bindings for the key. */ - static ResolvedBindings noBindings(Key key) { + static ResolvedBindings noBindings(ComponentPath componentPath, Key key) { return new AutoValue_ResolvedBindings( + componentPath, key, ImmutableSetMultimap.of(), ImmutableMap.of(), diff --git a/java/dagger/internal/codegen/binding/SourceFiles.java b/java/dagger/internal/codegen/binding/SourceFiles.java index 19d316f3d..e8a10753d 100644 --- a/java/dagger/internal/codegen/binding/SourceFiles.java +++ b/java/dagger/internal/codegen/binding/SourceFiles.java @@ -95,11 +95,23 @@ public final class SourceFiles { return Maps.toMap( binding.dependencies(), - dependency -> - FrameworkField.create( - frameworkTypeMapper.getFrameworkType(dependency.kind()).frameworkClassName(), - dependency.key().type().xprocessing().getTypeName(), - DependencyVariableNamer.name(dependency))); + dependency -> { + ClassName frameworkClassName = + frameworkTypeMapper.getFrameworkType(dependency.kind()).frameworkClassName(); + // Remap factory fields back to javax.inject.Provider to maintain backwards compatibility + // for now. In a future release, we should change this to Dagger Provider. This will still + // be a breaking change, but keeping compatibility for a while should reduce the + // likelihood of breakages as it would require components built at much older versions + // using factories built at newer versions to break. + if (frameworkClassName.equals(TypeNames.DAGGER_PROVIDER)) { + frameworkClassName = TypeNames.PROVIDER; + } + return FrameworkField.create( + ParameterizedTypeName.get( + frameworkClassName, + dependency.key().type().xprocessing().getTypeName()), + DependencyVariableNamer.name(dependency)); + }); } public CodeBlock frameworkTypeUsageStatement( diff --git a/java/dagger/internal/codegen/bindinggraphvalidation/MissingBindingValidator.java b/java/dagger/internal/codegen/bindinggraphvalidation/MissingBindingValidator.java index 774ee5d94..fd9e42efb 100644 --- a/java/dagger/internal/codegen/bindinggraphvalidation/MissingBindingValidator.java +++ b/java/dagger/internal/codegen/bindinggraphvalidation/MissingBindingValidator.java @@ -20,12 +20,13 @@ import static androidx.room.compiler.processing.compat.XConverters.getProcessing import static com.google.common.base.Verify.verify; import static com.google.common.collect.Iterables.getLast; import static com.google.common.collect.Iterables.getOnlyElement; +import static dagger.internal.codegen.base.ElementFormatter.elementToString; +import static dagger.internal.codegen.base.Formatter.INDENT; import static dagger.internal.codegen.base.Keys.isValidImplicitProvisionKey; import static dagger.internal.codegen.base.Keys.isValidMembersInjectionKey; import static dagger.internal.codegen.base.RequestKinds.canBeSatisfiedByProductionBinding; import static dagger.internal.codegen.binding.DependencyRequestFormatter.DOUBLE_INDENT; import static dagger.internal.codegen.extension.DaggerStreams.instancesOf; -import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; import static dagger.internal.codegen.xprocessing.XTypes.isDeclared; import static dagger.internal.codegen.xprocessing.XTypes.isWildcard; @@ -38,6 +39,7 @@ import com.google.common.collect.Iterators; import com.google.common.collect.Lists; import com.squareup.javapoet.TypeName; import com.squareup.javapoet.WildcardTypeName; +import dagger.internal.codegen.binding.ComponentNodeImpl; import dagger.internal.codegen.binding.DependencyRequestFormatter; import dagger.internal.codegen.binding.InjectBindingRegistry; import dagger.internal.codegen.model.Binding; @@ -47,7 +49,6 @@ import dagger.internal.codegen.model.BindingGraph.DependencyEdge; import dagger.internal.codegen.model.BindingGraph.Edge; import dagger.internal.codegen.model.BindingGraph.MissingBinding; import dagger.internal.codegen.model.BindingGraph.Node; -import dagger.internal.codegen.model.ComponentPath; import dagger.internal.codegen.model.DaggerAnnotation; import dagger.internal.codegen.model.DiagnosticReporter; import dagger.internal.codegen.model.Key; @@ -103,62 +104,20 @@ final class MissingBindingValidator extends ValidationBindingGraphPlugin { prunedGraph .missingBindings() .forEach( - missingBinding -> - reportMissingBinding(missingBinding, prunedGraph, fullGraph, diagnosticReporter)); + missingBinding -> reportMissingBinding(missingBinding, fullGraph, diagnosticReporter)); } private void reportMissingBinding( MissingBinding missingBinding, - BindingGraph prunedGraph, - BindingGraph fullGraph, + BindingGraph graph, DiagnosticReporter diagnosticReporter) { - ImmutableSet<Binding> wildcardAlternatives = - getSimilarTypeBindings(fullGraph, missingBinding.key()); - String wildcardTypeErrorMessage = ""; - if (!wildcardAlternatives.isEmpty()) { - wildcardTypeErrorMessage = - String.format( - "\nFound similar bindings:\n %s", - String.join( - "\n ", - wildcardAlternatives.stream() - .map( - binding -> binding.key().type() + " in [" + binding.componentPath() + "]") - .collect(toImmutableSet()))) - + "\n(In Kotlin source, a type like 'Set<Foo>' may" - + " be translated as 'Set<? extends Foo>'. To avoid this implicit" - + " conversion you can add '@JvmSuppressWildcards' on the associated type" - + " argument, e.g. 'Set<@JvmSuppressWildcards Foo>'.)"; - } - - List<ComponentPath> alternativeComponents = - wildcardAlternatives.isEmpty() - ? fullGraph.bindings(missingBinding.key()).stream() - .map(Binding::componentPath) - .distinct() - .collect(toImmutableList()) - : ImmutableList.of(); - // Print component name for each binding along the dependency path if the missing binding - // exists in a different component than expected - if (alternativeComponents.isEmpty()) { - // TODO(b/266993189): the passed in diagnostic reporter is constructed with full graph, so it - // doesn't print out full dependency path for a binding when invoking reportBinding on it. - // Therefore, we manually constructed the binding dependency path and passed into - // reportComponent. - diagnosticReporter.reportComponent( - ERROR, - fullGraph.componentNode(missingBinding.componentPath()).get(), - missingBindingErrorMessage(missingBinding, fullGraph) - + wildcardTypeErrorMessage - + "\n\nMissing binding usage:" - + diagnosticMessageGeneratorFactory.create(prunedGraph).getMessage(missingBinding)); - } else { - diagnosticReporter.reportComponent( - ERROR, - fullGraph.componentNode(missingBinding.componentPath()).get(), - missingBindingErrorMessage(missingBinding, fullGraph) - + wrongComponentErrorMessage(missingBinding, alternativeComponents, prunedGraph)); - } + diagnosticReporter.reportComponent( + ERROR, + graph.componentNode(missingBinding.componentPath()).get(), + missingBindingErrorMessage(missingBinding, graph) + + missingBindingDependencyTraceMessage(missingBinding, graph) + + alternativeBindingsMessage(missingBinding, graph) + + similarBindingsMessage(missingBinding, graph)); } private static ImmutableSet<Binding> getSimilarTypeBindings( @@ -222,50 +181,24 @@ final class MissingBindingValidator extends ValidationBindingGraphPlugin { return errorMessage.toString(); } - private String wrongComponentErrorMessage( - MissingBinding missingBinding, - List<ComponentPath> alternativeComponentPath, - BindingGraph graph) { + private String missingBindingDependencyTraceMessage( + MissingBinding missingBinding, BindingGraph graph) { ImmutableSet<DependencyEdge> entryPoints = graph.entryPointEdgesDependingOnBinding(missingBinding); DiagnosticMessageGenerator generator = diagnosticMessageGeneratorFactory.create(graph); ImmutableList<DependencyEdge> dependencyTrace = generator.dependencyTrace(missingBinding, entryPoints); StringBuilder message = - graph.isFullBindingGraph() - ? new StringBuilder() - : new StringBuilder(dependencyTrace.size() * 100 /* a guess heuristic */); - // Check in which component the missing binding is requested. This can be different from the - // component the missing binding is in because we'll try to search up the parent components for - // a binding which makes missing bindings end up at the root component. This is different from - // the place we are logically requesting the binding from. Note that this is related to the - // particular dependency trace being shown and so is not necessarily stable. - String missingComponentName = - getComponentFromDependencyEdge(dependencyTrace.get(0), graph, false); - boolean hasSameComponentName = false; - for (ComponentPath component : alternativeComponentPath) { - message.append("\nNote: A binding for ").append(missingBinding.key()).append(" exists in "); - String currentComponentName = component.currentComponent().className().canonicalName(); - if (currentComponentName.contentEquals(missingComponentName)) { - hasSameComponentName = true; - message.append("[").append(component).append("]"); - } else { - message.append(currentComponentName); - } - message.append(":"); - } + new StringBuilder(dependencyTrace.size() * 100 /* a guess heuristic */).append("\n"); for (DependencyEdge edge : dependencyTrace) { String line = dependencyRequestFormatter.format(edge.dependencyRequest()); if (line.isEmpty()) { continue; } - // If we ran into a rare case where the component names collide and we need to show the full - // path, only show the full path for the first dependency request. This is guaranteed to be - // the component in question since the logic for checking for a collision uses the first - // edge in the trace. Do not expand subsequent component paths to reduce spam. - String componentName = - String.format("[%s] ", getComponentFromDependencyEdge(edge, graph, hasSameComponentName)); - hasSameComponentName = false; + // We don't have to check for cases where component names collide since + // 1. We always show the full classname of the component, and + // 2. We always show the full component path at the end of the dependency trace (below). + String componentName = String.format("[%s] ", getComponentFromDependencyEdge(edge, graph)); message.append("\n").append(line.replace(DOUBLE_INDENT, DOUBLE_INDENT + componentName)); } if (!dependencyTrace.isEmpty()) { @@ -277,6 +210,71 @@ final class MissingBindingValidator extends ValidationBindingGraphPlugin { return message.toString(); } + private String alternativeBindingsMessage( + MissingBinding missingBinding, BindingGraph graph) { + ImmutableSet<Binding> alternativeBindings = graph.bindings(missingBinding.key()); + if (alternativeBindings.isEmpty()) { + return ""; + } + StringBuilder message = new StringBuilder(); + message.append("\n\nNote: ") + .append(missingBinding.key()) + .append(" is provided in the following other components:"); + for (Binding alternativeBinding : alternativeBindings) { + // Some alternative bindings appear multiple times because they were re-resolved in multiple + // components (e.g. due to multibinding contributions). To avoid the noise, we only report + // the binding where the module is contributed. + if (alternativeBinding.contributingModule().isPresent() + && !((ComponentNodeImpl) graph.componentNode(alternativeBinding.componentPath()).get()) + .componentDescriptor() + .moduleTypes() + .contains(alternativeBinding.contributingModule().get().xprocessing())) { + continue; + } + message.append("\n").append(INDENT).append(asString(alternativeBinding)); + } + return message.toString(); + } + + private String similarBindingsMessage( + MissingBinding missingBinding, BindingGraph graph) { + ImmutableSet<Binding> similarBindings = + getSimilarTypeBindings(graph, missingBinding.key()); + if (similarBindings.isEmpty()) { + return ""; + } + StringBuilder message = + new StringBuilder( + "\n\nNote: A similar binding is provided in the following other components:"); + for (Binding similarBinding : similarBindings) { + message + .append("\n") + .append(INDENT) + .append(similarBinding.key()) + .append(" is provided at:") + .append("\n") + .append(DOUBLE_INDENT) + .append(asString(similarBinding)); + } + message.append("\n") + .append( + "(For Kotlin sources, you may need to use '@JvmSuppressWildcards' or '@JvmWildcard' if " + + "you need to explicitly control the wildcards at a particular usage site.)"); + return message.toString(); + } + + private String asString(Binding binding) { + return String.format( + "[%s] %s", + binding.componentPath().currentComponent().xprocessing().getQualifiedName(), + binding.bindingElement().isPresent() + ? elementToString( + binding.bindingElement().get().xprocessing(), + /* elideMethodParameterTypes= */ true) + // For synthetic bindings just print the Binding#toString() + : binding); + } + private boolean allIncomingDependenciesCanUseProduction( MissingBinding missingBinding, BindingGraph graph) { return graph.network().inEdges(missingBinding).stream() @@ -305,15 +303,11 @@ final class MissingBindingValidator extends ValidationBindingGraphPlugin { .orElse(false); } - private static String getComponentFromDependencyEdge( - DependencyEdge edge, BindingGraph graph, boolean completePath) { - ComponentPath componentPath = graph.network().incidentNodes(edge).source().componentPath(); - return completePath - ? componentPath.toString() - : componentPath.currentComponent().className().canonicalName(); + private static String getComponentFromDependencyEdge(DependencyEdge edge, BindingGraph graph) { + return source(edge, graph).componentPath().currentComponent().className().canonicalName(); } - private Node source(Edge edge, BindingGraph graph) { + private static Node source(Edge edge, BindingGraph graph) { return graph.network().incidentNodes(edge).source(); } diff --git a/java/dagger/internal/codegen/bindinggraphvalidation/SetMultibindingValidator.java b/java/dagger/internal/codegen/bindinggraphvalidation/SetMultibindingValidator.java index f767da851..30ebf09b2 100644 --- a/java/dagger/internal/codegen/bindinggraphvalidation/SetMultibindingValidator.java +++ b/java/dagger/internal/codegen/bindinggraphvalidation/SetMultibindingValidator.java @@ -30,6 +30,7 @@ import dagger.internal.codegen.model.BindingGraph; import dagger.internal.codegen.model.DiagnosticReporter; import dagger.internal.codegen.model.Key; import dagger.internal.codegen.validation.ValidationBindingGraphPlugin; +import java.util.Optional; import javax.inject.Inject; /** Validates that there are not multiple set binding contributions to the same binding. */ @@ -59,7 +60,8 @@ final class SetMultibindingValidator extends ValidationBindingGraphPlugin { Multimap<Key, Binding> dereferencedBindsTargets = HashMultimap.create(); for (Binding dep : bindingGraph.requestedBindings(binding)) { if (dep.kind().equals(DELEGATE)) { - dereferencedBindsTargets.put(dereferenceDelegateBinding(dep, bindingGraph), dep); + dereferenceDelegateBinding(dep, bindingGraph) + .ifPresent(dereferencedKey -> dereferencedBindsTargets.put(dereferencedKey, dep)); } } @@ -80,13 +82,19 @@ final class SetMultibindingValidator extends ValidationBindingGraphPlugin { }); } - /** Returns the delegate target of a delegate binding (going through other delegates as well). */ - private Key dereferenceDelegateBinding(Binding binding, BindingGraph bindingGraph) { + /** + * Returns the dereferenced key of a delegate binding (going through other delegates as well). + * + * <p>If the binding cannot be dereferenced (because it leads to a missing binding or duplicate + * bindings) then {@link Optional#empty()} is returned. + */ + private Optional<Key> dereferenceDelegateBinding(Binding binding, BindingGraph bindingGraph) { ImmutableSet<Binding> delegateSet = bindingGraph.requestedBindings(binding); - if (delegateSet.isEmpty()) { - // There may not be a delegate if the delegate is missing. In this case, we just take the - // requested key and return that. - return Iterables.getOnlyElement(binding.dependencies()).key(); + if (delegateSet.size() != 1) { + // If there isn't exactly 1 delegate then it means either a MissingBinding or DuplicateBinding + // error will be reported. Just return nothing rather than trying to dereference further, as + // anything we report here will just be noise on top of the other error anyway. + return Optional.empty(); } // If there is a binding, first we check if that is a delegate binding so we can dereference // that binding if needed. @@ -94,6 +102,6 @@ final class SetMultibindingValidator extends ValidationBindingGraphPlugin { if (delegate.kind().equals(DELEGATE)) { return dereferenceDelegateBinding(delegate, bindingGraph); } - return delegate.key(); + return Optional.of(delegate.key()); } } diff --git a/java/dagger/internal/codegen/bootstrap/bootstrap_compiler_deploy.jar b/java/dagger/internal/codegen/bootstrap/bootstrap_compiler_deploy.jar Binary files differindex 69e859d4c..6e4b0a96f 100644 --- a/java/dagger/internal/codegen/bootstrap/bootstrap_compiler_deploy.jar +++ b/java/dagger/internal/codegen/bootstrap/bootstrap_compiler_deploy.jar diff --git a/java/dagger/internal/codegen/compileroption/CompilerOptions.java b/java/dagger/internal/codegen/compileroption/CompilerOptions.java index 42599e03b..73f7736f2 100644 --- a/java/dagger/internal/codegen/compileroption/CompilerOptions.java +++ b/java/dagger/internal/codegen/compileroption/CompilerOptions.java @@ -24,16 +24,6 @@ public abstract class CompilerOptions { public abstract boolean usesProducers(); /** - * Returns true if the experimental Android mode is enabled. - * - * <p><b>Warning: Do Not use! This flag is for internal, experimental use only!</b> - * - * <p>Issues related to this flag will not be supported. This flag could break your build, cause - * memory leaks in your app, or cause other unknown issues at runtime. - */ - public abstract boolean experimentalMergedMode(XTypeElement element); - - /** * Returns true if the fast initialization flag, {@code fastInit}, is enabled. * * <p>If enabled, the generated code will attempt to optimize for fast component initialization. diff --git a/java/dagger/internal/codegen/compileroption/ProcessingEnvironmentCompilerOptions.java b/java/dagger/internal/codegen/compileroption/ProcessingEnvironmentCompilerOptions.java index 356d55bf6..81380055a 100644 --- a/java/dagger/internal/codegen/compileroption/ProcessingEnvironmentCompilerOptions.java +++ b/java/dagger/internal/codegen/compileroption/ProcessingEnvironmentCompilerOptions.java @@ -19,7 +19,6 @@ package dagger.internal.codegen.compileroption; import static com.google.common.base.CaseFormat.LOWER_CAMEL; import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE; import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkState; import static com.google.common.collect.Sets.immutableEnumSet; import static dagger.internal.codegen.compileroption.FeatureStatus.DISABLED; import static dagger.internal.codegen.compileroption.FeatureStatus.ENABLED; @@ -107,37 +106,14 @@ public final class ProcessingEnvironmentCompilerOptions extends CompilerOptions } @Override - public boolean experimentalMergedMode(XTypeElement component) { - boolean isExperimental = experimentalMergedModeInternal(); - if (isExperimental) { - checkState( - !fastInitInternal(component), - "Both fast init and experimental merged mode were turned on, please specify exactly one" - + " compilation mode."); - } - return isExperimental; - } - - @Override public boolean fastInit(XTypeElement component) { - boolean isFastInit = fastInitInternal(component); - if (isFastInit) { - checkState( - !experimentalMergedModeInternal(), - "Both fast init and experimental merged mode were turned on, please specify exactly one" - + " compilation mode."); - } - return isFastInit; + return fastInitInternal(component); } private boolean fastInitInternal(XTypeElement component) { return isEnabled(FAST_INIT); } - private boolean experimentalMergedModeInternal() { - return false; - } - @Override public boolean formatGeneratedSource() { return isEnabled(FORMAT_GENERATED_SOURCE); @@ -268,6 +244,16 @@ public final class ProcessingEnvironmentCompilerOptions extends CompilerOptions noLongerRecognized(FLOATING_BINDS_METHODS); noLongerRecognized(EXPERIMENTAL_AHEAD_OF_TIME_SUBCOMPONENTS); noLongerRecognized(USE_GRADLE_INCREMENTAL_PROCESSING); + if (!isEnabled(IGNORE_PROVISION_KEY_WILDCARDS)) { + if (processingEnv.getBackend() == XProcessingEnv.Backend.KSP) { + processingEnv.getMessager().printMessage( + Diagnostic.Kind.ERROR, + String.format( + "When using KSP, you must also enable the '%s' compiler option (see %s).", + "dagger.ignoreProvisionKeyWildcards", + "https://dagger.dev/dev-guide/compiler-options#ignore-provision-key-wildcards")); + } + } return this; } @@ -359,7 +345,7 @@ public final class ProcessingEnvironmentCompilerOptions extends CompilerOptions GENERATED_CLASS_EXTENDS_COMPONENT, - IGNORE_PROVISION_KEY_WILDCARDS, + IGNORE_PROVISION_KEY_WILDCARDS(ENABLED), VALIDATE_TRANSITIVE_COMPONENT_DEPENDENCIES(ENABLED) ; @@ -418,7 +404,7 @@ public final class ProcessingEnvironmentCompilerOptions extends CompilerOptions * How to report that an explicit binding in a subcomponent conflicts with an {@code @Inject} * constructor used in an ancestor component. */ - EXPLICIT_BINDING_CONFLICTS_WITH_INJECT(WARNING, ERROR, NONE), + EXPLICIT_BINDING_CONFLICTS_WITH_INJECT(ERROR, WARNING, NONE), ; final ValidationType defaultType; diff --git a/java/dagger/internal/codegen/componentgenerator/ComponentGeneratorModule.java b/java/dagger/internal/codegen/componentgenerator/ComponentGeneratorModule.java index 179c411e4..a071eaeb2 100644 --- a/java/dagger/internal/codegen/componentgenerator/ComponentGeneratorModule.java +++ b/java/dagger/internal/codegen/componentgenerator/ComponentGeneratorModule.java @@ -16,9 +16,12 @@ package dagger.internal.codegen.componentgenerator; +import androidx.room.compiler.processing.XProcessingEnv; import dagger.Binds; import dagger.Module; +import dagger.Provides; import dagger.internal.codegen.base.SourceFileGenerator; +import dagger.internal.codegen.base.SourceFileHjarGenerator; import dagger.internal.codegen.binding.BindingGraph; import dagger.internal.codegen.binding.ComponentDescriptor; @@ -29,14 +32,23 @@ public interface ComponentGeneratorModule { @Binds abstract SourceFileGenerator<BindingGraph> componentGenerator(ComponentGenerator generator); - // The HjarSourceFileGenerator wrapper first generates the entire TypeSpec before stripping out + // The SourceFileHjarGenerator wrapper first generates the entire TypeSpec before stripping out // things that aren't needed for the hjar. However, this can be really expensive for the component // because it is usually the most expensive file to generate, and most of its content is not - // needed in the hjar. Thus, instead of wrapping the ComponentGenerator in HjarSourceFileGenerator - // we provide a completely separate processing step, ComponentHjarProcessingStep, and generator, - // ComponentHjarGenerator, for when generating hjars for components, which can avoid generating - // the parts of the component that would have been stripped out by the HjarSourceFileGenerator. - @Binds - abstract SourceFileGenerator<ComponentDescriptor> componentHjarGenerator( - ComponentHjarGenerator hjarGenerator); + // needed in the hjar. Thus, we provide a completely separate processing step, + // ComponentHjarProcessingStep and ComponentHjarGenerator, for when generating hjars for + // components, which can avoid generating the parts of the component that would have been stripped + // out by the HjarSourceFileGenerator anyway. Note that we still wrap ComponentHjarGenerator in + // SourceFileHjarGenerator because it adds in constructor and method bodies that are needed for + // Javac to compile correctly, e.g. super(...) calls in the constructor and return statements in + // methods. + @Provides + static SourceFileGenerator<ComponentDescriptor> componentHjarGenerator( + XProcessingEnv processingEnv, + ComponentHjarGenerator hjarGenerator) { + // Note: technically the ComponentHjarGenerator is already in hjar form, but the + // SourceFileHjarGenerator wrapper adds in proper method bodies, e.g. constructors that require + // super() calls or methods that require return statements. + return SourceFileHjarGenerator.wrap(hjarGenerator, processingEnv); + } } diff --git a/java/dagger/internal/codegen/componentgenerator/ComponentHjarGenerator.java b/java/dagger/internal/codegen/componentgenerator/ComponentHjarGenerator.java index 62f11632e..4214cbc72 100644 --- a/java/dagger/internal/codegen/componentgenerator/ComponentHjarGenerator.java +++ b/java/dagger/internal/codegen/componentgenerator/ComponentHjarGenerator.java @@ -192,7 +192,14 @@ final class ComponentHjarGenerator extends SourceFileGenerator<ComponentDescript && isElementAccessibleFrom( module.moduleElement(), component.typeElement().getClassName().packageName())) - .map(module -> ComponentRequirement.forModule(module.moduleElement().getType()))); + .map(module -> ComponentRequirement.forModule(module.moduleElement().getType())) + // If the user hasn't defined an explicit creator/builder then we need to prune out the + // module requirements that don't require a module instance to match the non-hjar + // implementation. + .filter( + requirement -> + component.creatorDescriptor().isPresent() + || requirement.requiresModuleInstance())); } private boolean hasBindsInstanceMethods(ComponentDescriptor componentDescriptor) { diff --git a/java/dagger/internal/codegen/javac/BUILD b/java/dagger/internal/codegen/javac/BUILD index ad2f91be9..325dc99d0 100644 --- a/java/dagger/internal/codegen/javac/BUILD +++ b/java/dagger/internal/codegen/javac/BUILD @@ -23,24 +23,10 @@ java_library( name = "javac", srcs = glob(["*.java"]), plugins = ["//java/dagger/internal/codegen:component-codegen"], - exports = [ - ":javac-import", - ], deps = [ - ":javac-import", "//java/dagger:core", - "//java/dagger/internal/codegen/binding", "//java/dagger/internal/codegen/compileroption", - "//java/dagger/internal/codegen/langmodel", "//java/dagger/internal/codegen/xprocessing", "//third_party/java/guava/collect", ], ) - -load("@rules_java//java:defs.bzl", "java_import") - -# Replacement for @bazel_tools//third_party/java/jdk/langtools:javac, which seems to have gone away? -java_import( - name = "javac-import", - jars = ["@bazel_tools//third_party/java/jdk/langtools:javac_jar"], -) diff --git a/java/dagger/internal/codegen/javac/JavacPluginCompilerOptions.java b/java/dagger/internal/codegen/javac/JavacPluginCompilerOptions.java index 6e778357d..e7c5a44d2 100644 --- a/java/dagger/internal/codegen/javac/JavacPluginCompilerOptions.java +++ b/java/dagger/internal/codegen/javac/JavacPluginCompilerOptions.java @@ -37,11 +37,6 @@ final class JavacPluginCompilerOptions extends CompilerOptions { } @Override - public boolean experimentalMergedMode(XTypeElement element) { - return false; - } - - @Override public boolean fastInit(XTypeElement element) { return false; } diff --git a/java/dagger/internal/codegen/javac/JavacPluginModule.java b/java/dagger/internal/codegen/javac/JavacPluginModule.java index 519816440..f9e6da9bc 100644 --- a/java/dagger/internal/codegen/javac/JavacPluginModule.java +++ b/java/dagger/internal/codegen/javac/JavacPluginModule.java @@ -24,15 +24,13 @@ import com.sun.tools.javac.util.Context; import dagger.Binds; import dagger.Module; import dagger.Provides; -import dagger.internal.codegen.binding.BindingGraphFactory; -import dagger.internal.codegen.binding.ComponentDescriptorFactory; import dagger.internal.codegen.compileroption.CompilerOptions; import javax.lang.model.util.Elements; // ALLOW_TYPES_ELEMENTS import javax.lang.model.util.Types; // ALLOW_TYPES_ELEMENTS /** - * A module that provides a {@link BindingGraphFactory} and {@link ComponentDescriptorFactory} for - * use in {@code javac} plugins. Requires a binding for the {@code javac} {@link Context}. + * A module that provides a {@link XMessager}, {@link XProcessingEnv}, and {@link CompilerOptions} + * for use in {@code javac} plugins. Requires a binding for the {@code javac} {@link Context}. */ @Module(includes = JavacPluginModule.BindsModule.class) public final class JavacPluginModule { diff --git a/java/dagger/internal/codegen/javapoet/AnnotationSpecs.java b/java/dagger/internal/codegen/javapoet/AnnotationSpecs.java index 4628802a4..50ec8b1c8 100644 --- a/java/dagger/internal/codegen/javapoet/AnnotationSpecs.java +++ b/java/dagger/internal/codegen/javapoet/AnnotationSpecs.java @@ -30,7 +30,8 @@ public final class AnnotationSpecs { RAWTYPES("rawtypes"), UNCHECKED("unchecked"), FUTURE_RETURN_VALUE_IGNORED("FutureReturnValueIgnored"), - KOTLIN_INTERNAL("KotlinInternal", "KotlinInternalInJava") + KOTLIN_INTERNAL("KotlinInternal", "KotlinInternalInJava"), + CAST("cast") ; private final ImmutableList<String> values; diff --git a/java/dagger/internal/codegen/javapoet/CodeBlocks.java b/java/dagger/internal/codegen/javapoet/CodeBlocks.java index 912dc71b8..877a0a540 100644 --- a/java/dagger/internal/codegen/javapoet/CodeBlocks.java +++ b/java/dagger/internal/codegen/javapoet/CodeBlocks.java @@ -18,7 +18,8 @@ package dagger.internal.codegen.javapoet; import static com.squareup.javapoet.MethodSpec.methodBuilder; import static com.squareup.javapoet.TypeSpec.anonymousClassBuilder; -import static dagger.internal.codegen.javapoet.TypeNames.providerOf; +import static dagger.internal.codegen.javapoet.TypeNames.daggerProviderOf; +import static dagger.internal.codegen.javapoet.TypeNames.lazyOf; import static java.util.stream.StreamSupport.stream; import static javax.lang.model.element.Modifier.PUBLIC; @@ -87,7 +88,22 @@ public final class CodeBlocks { return CodeBlock.of( "$L", anonymousClassBuilder("") - .superclass(providerOf(providedType)) + .superclass(daggerProviderOf(providedType)) + .addMethod( + methodBuilder("get") + .addAnnotation(Override.class) + .addModifiers(PUBLIC) + .returns(providedType) + .addCode(body) + .build()) + .build()); + } + + public static CodeBlock anonymousLazy(TypeName providedType, CodeBlock body) { + return CodeBlock.of( + "$L", + anonymousClassBuilder("") + .superclass(lazyOf(providedType)) .addMethod( methodBuilder("get") .addAnnotation(Override.class) diff --git a/java/dagger/internal/codegen/javapoet/TypeNames.java b/java/dagger/internal/codegen/javapoet/TypeNames.java index 105394d42..ea89fc033 100644 --- a/java/dagger/internal/codegen/javapoet/TypeNames.java +++ b/java/dagger/internal/codegen/javapoet/TypeNames.java @@ -53,6 +53,16 @@ public final class TypeNames { public static final ClassName SUBCOMPONENT_FACTORY = SUBCOMPONENT.nestedClass("Factory"); // Dagger Internal classnames + public static final ClassName IDENTIFIER_NAME_STRING = + ClassName.get("dagger.internal", "IdentifierNameString"); + public static final ClassName KEEP_FIELD_TYPE = ClassName.get("dagger.internal", "KeepFieldType"); + public static final ClassName LAZY_CLASS_KEY = + ClassName.get("dagger.multibindings", "LazyClassKey"); + public static final ClassName LAZY_CLASS_KEY_MAP = + ClassName.get("dagger.internal", "LazyClassKeyMap"); + public static final ClassName LAZY_CLASS_KEY_MAP_FACTORY = + ClassName.get("dagger.internal", "LazyClassKeyMap", "Factory"); + public static final ClassName DELEGATE_FACTORY = ClassName.get("dagger.internal", "DelegateFactory"); public static final ClassName DOUBLE_CHECK = ClassName.get("dagger.internal", "DoubleCheck"); @@ -62,6 +72,7 @@ public final class TypeNames { ClassName.get("dagger.internal", "InjectedFieldSignature"); public static final ClassName INSTANCE_FACTORY = ClassName.get("dagger.internal", "InstanceFactory"); + public static final ClassName MAP_BUILDER = ClassName.get("dagger.internal", "MapBuilder"); public static final ClassName MAP_FACTORY = ClassName.get("dagger.internal", "MapFactory"); public static final ClassName MAP_PROVIDER_FACTORY = ClassName.get("dagger.internal", "MapProviderFactory"); @@ -69,6 +80,8 @@ public final class TypeNames { public static final ClassName MEMBERS_INJECTORS = ClassName.get("dagger.internal", "MembersInjectors"); public static final ClassName PROVIDER = ClassName.get("javax.inject", "Provider"); + public static final ClassName DAGGER_PROVIDER = ClassName.get("dagger.internal", "Provider"); + public static final ClassName DAGGER_PROVIDERS = ClassName.get("dagger.internal", "Providers"); public static final ClassName PROVIDER_OF_LAZY = ClassName.get("dagger.internal", "ProviderOfLazy"); public static final ClassName SCOPE_METADATA = ClassName.get("dagger.internal", "ScopeMetadata"); @@ -81,6 +94,8 @@ public final class TypeNames { // Dagger Producers classnames public static final ClassName ABSTRACT_PRODUCER = ClassName.get("dagger.producers.internal", "AbstractProducer"); + public static final ClassName ABSTRACT_PRODUCES_METHOD_PRODUCER = + ClassName.get("dagger.producers.internal", "AbstractProducesMethodProducer"); public static final ClassName CANCELLATION_LISTENER = ClassName.get("dagger.producers.internal", "CancellationListener"); public static final ClassName CANCELLATION_POLICY = @@ -138,6 +153,8 @@ public final class TypeNames { public static final ClassName ERROR = ClassName.get("java.lang", "Error"); public static final ClassName EXCEPTION = ClassName.get("java.lang", "Exception"); public static final ClassName RUNTIME_EXCEPTION = ClassName.get("java.lang", "RuntimeException"); + public static final ClassName STRING = ClassName.get("java.lang", "String"); + public static final ClassName MAP = ClassName.get("java.util", "Map"); public static final ClassName KOTLIN_METADATA = ClassName.get("kotlin", "Metadata"); public static final ClassName IMMUTABLE_MAP = @@ -215,6 +232,10 @@ public final class TypeNames { return ParameterizedTypeName.get(PROVIDER, typeName); } + public static ParameterizedTypeName daggerProviderOf(TypeName typeName) { + return ParameterizedTypeName.get(DAGGER_PROVIDER, typeName); + } + public static ParameterizedTypeName setOf(TypeName elementType) { return ParameterizedTypeName.get(SET, elementType); } diff --git a/java/dagger/internal/codegen/kythe/BUILD b/java/dagger/internal/codegen/kythe/BUILD index 9b2e63b7a..217627d78 100644 --- a/java/dagger/internal/codegen/kythe/BUILD +++ b/java/dagger/internal/codegen/kythe/BUILD @@ -31,13 +31,13 @@ java_library( "//java/dagger/internal/codegen/javac", "//java/dagger/internal/codegen/javapoet", "//java/dagger/internal/codegen/kotlin", - "//java/dagger/internal/codegen/langmodel", "//java/dagger/internal/codegen/model", "//java/dagger/internal/codegen/validation", "//java/dagger/internal/codegen/xprocessing", "//third_party/java/auto:service", "//third_party/java/error_prone:annotations", "//third_party/java/guava/collect", + "//third_party/java/jsr330_inject", ], ) diff --git a/java/dagger/internal/codegen/kythe/DaggerKythePlugin.java b/java/dagger/internal/codegen/kythe/DaggerKythePlugin.java index 3280b4f79..0b8a5024b 100644 --- a/java/dagger/internal/codegen/kythe/DaggerKythePlugin.java +++ b/java/dagger/internal/codegen/kythe/DaggerKythePlugin.java @@ -40,7 +40,7 @@ import dagger.internal.codegen.binding.Binding; import dagger.internal.codegen.binding.BindingDeclaration; import dagger.internal.codegen.binding.BindingGraphFactory; import dagger.internal.codegen.binding.BindingNode; -import dagger.internal.codegen.binding.ComponentDescriptorFactory; +import dagger.internal.codegen.binding.ComponentDescriptor; import dagger.internal.codegen.binding.ModuleDescriptor; import dagger.internal.codegen.javac.JavacPluginModule; import dagger.internal.codegen.javapoet.TypeNames; @@ -64,7 +64,7 @@ public class DaggerKythePlugin extends Plugin.Scanner<Void, Void> { // TODO(ronshapiro): use flogger private static final Logger logger = Logger.getLogger(DaggerKythePlugin.class.getCanonicalName()); private FactEmitter emitter; - @Inject ComponentDescriptorFactory componentDescriptorFactory; + @Inject ComponentDescriptor.Factory componentDescriptorFactory; @Inject BindingGraphFactory bindingGraphFactory; @Inject XProcessingEnv xProcessingEnv; diff --git a/java/dagger/internal/codegen/model/BUILD b/java/dagger/internal/codegen/model/BUILD index e6c944ba0..f497f13c0 100644 --- a/java/dagger/internal/codegen/model/BUILD +++ b/java/dagger/internal/codegen/model/BUILD @@ -27,8 +27,6 @@ java_library( "//java/dagger:core", "//java/dagger/internal/codegen/extension", "//java/dagger/internal/codegen/xprocessing", - "//java/dagger/producers", - "//java/dagger/spi", "//third_party/java/auto:common", "//third_party/java/auto:value", "//third_party/java/guava/base", diff --git a/java/dagger/internal/codegen/model/DaggerAnnotation.java b/java/dagger/internal/codegen/model/DaggerAnnotation.java index 4a598719a..23b18e4c8 100644 --- a/java/dagger/internal/codegen/model/DaggerAnnotation.java +++ b/java/dagger/internal/codegen/model/DaggerAnnotation.java @@ -49,7 +49,7 @@ public abstract class DaggerAnnotation { return equivalenceWrapper().get(); } - public AnnotationMirror java() { + public AnnotationMirror javac() { return toJavac(xprocessing()); } diff --git a/java/dagger/internal/codegen/model/DaggerElement.java b/java/dagger/internal/codegen/model/DaggerElement.java index cf2ac52fb..2de01a18f 100644 --- a/java/dagger/internal/codegen/model/DaggerElement.java +++ b/java/dagger/internal/codegen/model/DaggerElement.java @@ -31,7 +31,7 @@ public abstract class DaggerElement { public abstract XElement xprocessing(); - public Element java() { + public Element javac() { return toJavac(xprocessing()); } diff --git a/java/dagger/internal/codegen/model/DaggerExecutableElement.java b/java/dagger/internal/codegen/model/DaggerExecutableElement.java index 484e446e2..42ce1fc97 100644 --- a/java/dagger/internal/codegen/model/DaggerExecutableElement.java +++ b/java/dagger/internal/codegen/model/DaggerExecutableElement.java @@ -32,7 +32,7 @@ public abstract class DaggerExecutableElement { public abstract XExecutableElement xprocessing(); - public ExecutableElement java() { + public ExecutableElement javac() { return toJavac(xprocessing()); } diff --git a/java/dagger/internal/codegen/model/DaggerProcessingEnv.java b/java/dagger/internal/codegen/model/DaggerProcessingEnv.java index 6645b90be..44308293a 100644 --- a/java/dagger/internal/codegen/model/DaggerProcessingEnv.java +++ b/java/dagger/internal/codegen/model/DaggerProcessingEnv.java @@ -39,7 +39,7 @@ public abstract class DaggerProcessingEnv { return Backend.valueOf(xprocessing().getBackend().name()); } - public ProcessingEnvironment java() { + public ProcessingEnvironment javac() { return toJavac(xprocessing()); } } diff --git a/java/dagger/internal/codegen/model/DaggerType.java b/java/dagger/internal/codegen/model/DaggerType.java index c606f15e0..b6f0beb72 100644 --- a/java/dagger/internal/codegen/model/DaggerType.java +++ b/java/dagger/internal/codegen/model/DaggerType.java @@ -39,7 +39,7 @@ public abstract class DaggerType { return equivalenceWrapper().get(); } - public TypeMirror java() { + public TypeMirror javac() { return toJavac(xprocessing()); } diff --git a/java/dagger/internal/codegen/model/DaggerTypeElement.java b/java/dagger/internal/codegen/model/DaggerTypeElement.java index 77e0c4ffd..1bfab067d 100644 --- a/java/dagger/internal/codegen/model/DaggerTypeElement.java +++ b/java/dagger/internal/codegen/model/DaggerTypeElement.java @@ -32,7 +32,7 @@ public abstract class DaggerTypeElement { public abstract XTypeElement xprocessing(); - public TypeElement java() { + public TypeElement javac() { return toJavac(xprocessing()); } diff --git a/java/dagger/internal/codegen/model/MoreAnnotationMirrors.java b/java/dagger/internal/codegen/model/MoreAnnotationMirrors.java index 9b45b891f..ade1f28e8 100644 --- a/java/dagger/internal/codegen/model/MoreAnnotationMirrors.java +++ b/java/dagger/internal/codegen/model/MoreAnnotationMirrors.java @@ -35,7 +35,7 @@ final class MoreAnnotationMirrors { * defined in the annotation type. */ public static String toStableString(DaggerAnnotation qualifier) { - return stableAnnotationMirrorToString(qualifier.java()); + return stableAnnotationMirrorToString(qualifier.javac()); } /** diff --git a/java/dagger/internal/codegen/model/RequestKind.java b/java/dagger/internal/codegen/model/RequestKind.java index 581a829b3..d21a04a41 100644 --- a/java/dagger/internal/codegen/model/RequestKind.java +++ b/java/dagger/internal/codegen/model/RequestKind.java @@ -19,11 +19,6 @@ package dagger.internal.codegen.model; import static com.google.common.base.CaseFormat.UPPER_CAMEL; import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE; -import dagger.Lazy; -import dagger.producers.Produced; -import dagger.producers.Producer; -import javax.inject.Provider; - /** * Represents the different kinds of {@link javax.lang.model.type.TypeMirror types} that may be * requested as dependencies for the same key. For example, {@code String}, {@code @@ -35,13 +30,13 @@ public enum RequestKind { /** A default request for an instance. E.g.: {@code FooType} */ INSTANCE, - /** A request for a {@link Provider}. E.g.: {@code Provider<FooType>} */ + /** A request for a {@code Provider}. E.g.: {@code Provider<FooType>} */ PROVIDER, - /** A request for a {@link Lazy}. E.g.: {@code Lazy<FooType>} */ + /** A request for a {@code Lazy}. E.g.: {@code Lazy<FooType>} */ LAZY, - /** A request for a {@link Provider} of a {@link Lazy}. E.g.: {@code Provider<Lazy<FooType>>} */ + /** A request for a {@code Provider} of a {@code Lazy}. E.g.: {@code Provider<Lazy<FooType>>}. */ PROVIDER_OF_LAZY, /** @@ -50,10 +45,10 @@ public enum RequestKind { */ MEMBERS_INJECTION, - /** A request for a {@link Producer}. E.g.: {@code Producer<FooType>} */ + /** A request for a {@code Producer}. E.g.: {@code Producer<FooType>} */ PRODUCER, - /** A request for a {@link Produced}. E.g.: {@code Produced<FooType>} */ + /** A request for a {@code Produced}. E.g.: {@code Produced<FooType>} */ PRODUCED, /** diff --git a/java/dagger/internal/codegen/processingstep/AssistedFactoryProcessingStep.java b/java/dagger/internal/codegen/processingstep/AssistedFactoryProcessingStep.java index e95bdf927..ebd5d106d 100644 --- a/java/dagger/internal/codegen/processingstep/AssistedFactoryProcessingStep.java +++ b/java/dagger/internal/codegen/processingstep/AssistedFactoryProcessingStep.java @@ -23,6 +23,7 @@ import static dagger.internal.codegen.binding.SourceFiles.generatedClassNameForB import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; import static dagger.internal.codegen.javapoet.CodeBlocks.toParametersCodeBlock; import static dagger.internal.codegen.javapoet.TypeNames.INSTANCE_FACTORY; +import static dagger.internal.codegen.javapoet.TypeNames.daggerProviderOf; import static dagger.internal.codegen.javapoet.TypeNames.providerOf; import static dagger.internal.codegen.langmodel.Accessibility.accessibleTypeName; import static dagger.internal.codegen.xprocessing.MethodSpecs.overriding; @@ -311,9 +312,13 @@ final class AssistedFactoryProcessingStep extends TypeCheckingProcessingStep<XTy // use the parameter names of the @AssistedFactory method. metadata.assistedInjectAssistedParameters().stream() .map(metadata.assistedFactoryAssistedParametersMap()::get) - .map(param -> CodeBlock.of("$L", getSimpleName(param))) + .map(param -> CodeBlock.of("$L", param.getJvmName())) .collect(toParametersCodeBlock())) .build()) + // In a future release, we should delete this javax method. This will still be a breaking + // change, but keeping compatibility for a while should reduce the likelihood of breakages + // as it would require components built at much older versions using factories built at + // newer versions to break. .addMethod( MethodSpec.methodBuilder("create") .addModifiers(PUBLIC, STATIC) @@ -331,6 +336,27 @@ final class AssistedFactoryProcessingStep extends TypeCheckingProcessingStep<XTy : CodeBlock.of(""), name, delegateFactoryParam) + .build()) + // Normally we would have called this just "create", but because of backwards + // compatibility we can't have two methods with the same name/arguments returning + // different Provider types. + .addMethod( + MethodSpec.methodBuilder("createFactoryProvider") + .addModifiers(PUBLIC, STATIC) + .addParameter(delegateFactoryParam) + .addTypeVariables(typeVariableNames(metadata.assistedInjectElement())) + .returns(daggerProviderOf(factory.getType().getTypeName())) + .addStatement( + "return $T.$Lcreate(new $T($N))", + INSTANCE_FACTORY, + // Java 7 type inference requires the method call provide the exact type here. + isPreJava8SourceVersion(processingEnv) + ? CodeBlock.of( + "<$T>", + accessibleTypeName(metadata.factoryType(), name, processingEnv)) + : CodeBlock.of(""), + name, + delegateFactoryParam) .build()); return ImmutableList.of(builder); } diff --git a/java/dagger/internal/codegen/processingstep/AssistedInjectProcessingStep.java b/java/dagger/internal/codegen/processingstep/AssistedInjectProcessingStep.java index 8d73f4774..cfd0bec6e 100644 --- a/java/dagger/internal/codegen/processingstep/AssistedInjectProcessingStep.java +++ b/java/dagger/internal/codegen/processingstep/AssistedInjectProcessingStep.java @@ -26,6 +26,7 @@ import com.google.common.collect.ImmutableSet; import com.squareup.javapoet.ClassName; import dagger.internal.codegen.binding.AssistedInjectionAnnotations.AssistedParameter; import dagger.internal.codegen.javapoet.TypeNames; +import dagger.internal.codegen.validation.InjectValidator; import dagger.internal.codegen.validation.ValidationReport; import java.util.HashSet; import java.util.Set; @@ -34,10 +35,12 @@ import javax.inject.Inject; /** An annotation processor for {@link dagger.assisted.AssistedInject}-annotated elements. */ final class AssistedInjectProcessingStep extends TypeCheckingProcessingStep<XConstructorElement> { private final XMessager messager; + private final InjectValidator injectValidator; @Inject - AssistedInjectProcessingStep(XMessager messager) { + AssistedInjectProcessingStep(XMessager messager, InjectValidator injectValidator) { this.messager = messager; + this.injectValidator = injectValidator; } @Override @@ -48,7 +51,13 @@ final class AssistedInjectProcessingStep extends TypeCheckingProcessingStep<XCon @Override protected void process( XConstructorElement assistedInjectElement, ImmutableSet<ClassName> annotations) { - new AssistedInjectValidator().validate(assistedInjectElement).printMessagesTo(messager); + // The InjectValidator has already run and reported its errors in InjectProcessingStep, so no + // need to report its errors. However, the AssistedInjectValidator relies on the InjectValidator + // returning a clean report, so we check that first before running AssistedInjectValidator. This + // shouldn't be expensive since InjectValidator caches its results after validating. + if (injectValidator.validate(assistedInjectElement.getEnclosingElement()).isClean()) { + new AssistedInjectValidator().validate(assistedInjectElement).printMessagesTo(messager); + } } private final class AssistedInjectValidator { diff --git a/java/dagger/internal/codegen/processingstep/ComponentHjarProcessingStep.java b/java/dagger/internal/codegen/processingstep/ComponentHjarProcessingStep.java index 7a7e180da..864bd768d 100644 --- a/java/dagger/internal/codegen/processingstep/ComponentHjarProcessingStep.java +++ b/java/dagger/internal/codegen/processingstep/ComponentHjarProcessingStep.java @@ -28,7 +28,6 @@ import com.squareup.javapoet.ClassName; import dagger.internal.codegen.base.SourceFileGenerator; import dagger.internal.codegen.binding.BindingGraph; import dagger.internal.codegen.binding.ComponentDescriptor; -import dagger.internal.codegen.binding.ComponentDescriptorFactory; import dagger.internal.codegen.validation.ComponentCreatorValidator; import dagger.internal.codegen.validation.ComponentValidator; import dagger.internal.codegen.validation.ValidationReport; @@ -52,7 +51,7 @@ final class ComponentHjarProcessingStep extends TypeCheckingProcessingStep<XType private final XMessager messager; private final ComponentValidator componentValidator; private final ComponentCreatorValidator creatorValidator; - private final ComponentDescriptorFactory componentDescriptorFactory; + private final ComponentDescriptor.Factory componentDescriptorFactory; private final SourceFileGenerator<ComponentDescriptor> componentGenerator; @Inject @@ -60,7 +59,7 @@ final class ComponentHjarProcessingStep extends TypeCheckingProcessingStep<XType XMessager messager, ComponentValidator componentValidator, ComponentCreatorValidator creatorValidator, - ComponentDescriptorFactory componentDescriptorFactory, + ComponentDescriptor.Factory componentDescriptorFactory, SourceFileGenerator<ComponentDescriptor> componentGenerator) { this.messager = messager; this.componentValidator = componentValidator; diff --git a/java/dagger/internal/codegen/processingstep/ComponentProcessingStep.java b/java/dagger/internal/codegen/processingstep/ComponentProcessingStep.java index 5b17c0061..168e8946f 100644 --- a/java/dagger/internal/codegen/processingstep/ComponentProcessingStep.java +++ b/java/dagger/internal/codegen/processingstep/ComponentProcessingStep.java @@ -34,7 +34,6 @@ import dagger.internal.codegen.base.SourceFileGenerator; import dagger.internal.codegen.binding.BindingGraph; import dagger.internal.codegen.binding.BindingGraphFactory; import dagger.internal.codegen.binding.ComponentDescriptor; -import dagger.internal.codegen.binding.ComponentDescriptorFactory; import dagger.internal.codegen.validation.BindingGraphValidator; import dagger.internal.codegen.validation.ComponentCreatorValidator; import dagger.internal.codegen.validation.ComponentDescriptorValidator; @@ -52,7 +51,7 @@ final class ComponentProcessingStep extends TypeCheckingProcessingStep<XTypeElem private final ComponentValidator componentValidator; private final ComponentCreatorValidator creatorValidator; private final ComponentDescriptorValidator componentDescriptorValidator; - private final ComponentDescriptorFactory componentDescriptorFactory; + private final ComponentDescriptor.Factory componentDescriptorFactory; private final BindingGraphFactory bindingGraphFactory; private final SourceFileGenerator<BindingGraph> componentGenerator; private final BindingGraphValidator bindingGraphValidator; @@ -63,7 +62,7 @@ final class ComponentProcessingStep extends TypeCheckingProcessingStep<XTypeElem ComponentValidator componentValidator, ComponentCreatorValidator creatorValidator, ComponentDescriptorValidator componentDescriptorValidator, - ComponentDescriptorFactory componentDescriptorFactory, + ComponentDescriptor.Factory componentDescriptorFactory, BindingGraphFactory bindingGraphFactory, SourceFileGenerator<BindingGraph> componentGenerator, BindingGraphValidator bindingGraphValidator) { @@ -132,7 +131,10 @@ final class ComponentProcessingStep extends TypeCheckingProcessingStep<XTypeElem return; } BindingGraph fullBindingGraph = bindingGraphFactory.create(subcomponentDescriptor, true); - boolean isValid = bindingGraphValidator.isValid(fullBindingGraph.topLevelBindingGraph()); + // In this case, we don't actually care about the return value. The important part here is that + // BindingGraphValidator#isValid() runs all of the SPI plugins and reports any errors. + // TODO(bcorso): Add a separate API with no return value for this particular case. + boolean unusedIsValid = bindingGraphValidator.isValid(fullBindingGraph.topLevelBindingGraph()); } private void generateComponent(BindingGraph bindingGraph) { diff --git a/java/dagger/internal/codegen/processingstep/MonitoringModuleGenerator.java b/java/dagger/internal/codegen/processingstep/MonitoringModuleGenerator.java index 00b033d96..3692144cf 100644 --- a/java/dagger/internal/codegen/processingstep/MonitoringModuleGenerator.java +++ b/java/dagger/internal/codegen/processingstep/MonitoringModuleGenerator.java @@ -35,6 +35,7 @@ import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.TypeSpec; import dagger.Module; import dagger.internal.codegen.base.SourceFileGenerator; +import dagger.internal.codegen.binding.MonitoringModules; import dagger.internal.codegen.binding.SourceFiles; import dagger.internal.codegen.javapoet.TypeNames; import dagger.multibindings.Multibinds; @@ -42,10 +43,15 @@ import javax.inject.Inject; /** Generates a monitoring module for use with production components. */ final class MonitoringModuleGenerator extends SourceFileGenerator<XTypeElement> { + private final MonitoringModules monitoringModules; @Inject - MonitoringModuleGenerator(XFiler filer, XProcessingEnv processingEnv) { + MonitoringModuleGenerator( + XFiler filer, + XProcessingEnv processingEnv, + MonitoringModules monitoringModules) { super(filer, processingEnv); + this.monitoringModules = monitoringModules; } @Override @@ -55,6 +61,7 @@ final class MonitoringModuleGenerator extends SourceFileGenerator<XTypeElement> @Override public ImmutableList<TypeSpec.Builder> topLevelTypes(XTypeElement componentElement) { + monitoringModules.add(SourceFiles.generatedMonitoringModuleName(componentElement)); return ImmutableList.of( classBuilder(SourceFiles.generatedMonitoringModuleName(componentElement)) .addAnnotation(Module.class) diff --git a/java/dagger/internal/codegen/processingstep/TypeCheckingProcessingStep.java b/java/dagger/internal/codegen/processingstep/TypeCheckingProcessingStep.java index 5d6a64f3d..7ff47532a 100644 --- a/java/dagger/internal/codegen/processingstep/TypeCheckingProcessingStep.java +++ b/java/dagger/internal/codegen/processingstep/TypeCheckingProcessingStep.java @@ -33,6 +33,7 @@ import com.google.common.collect.ImmutableSetMultimap; import com.google.common.collect.Maps; import com.squareup.javapoet.ClassName; import dagger.internal.codegen.base.DaggerSuperficialValidation.ValidationException; +import dagger.internal.codegen.binding.MonitoringModules; import dagger.internal.codegen.compileroption.CompilerOptions; import dagger.internal.codegen.xprocessing.XElements; import java.util.ArrayList; @@ -51,6 +52,7 @@ abstract class TypeCheckingProcessingStep<E extends XElement> implements XProces @Inject XMessager messager; @Inject CompilerOptions compilerOptions; @Inject SuperficialValidator superficialValidator; + @Inject MonitoringModules monitoringModules; @Override public final ImmutableSet<String> annotations() { @@ -70,6 +72,16 @@ abstract class TypeCheckingProcessingStep<E extends XElement> implements XProces .forEach( (element, annotations) -> { try { + if (this instanceof ComponentProcessingStep && !monitoringModules.isEmpty()) { + // If there were any monitoring modules generated by Dagger in this round then we + // should just defer processing the components until the next round. This is an + // optimization to avoid unnecessary processing of components that will likely + // need to be reprocessed next round anyway due to the missing module. We should + // be guaranteed that there will be a next round since the monitoring modules were + // generated in this round. + deferredElements.add(element); + return; + } // The XBasicAnnotationProcessor only validates the element itself. However, we // validate the enclosing type here to keep the previous behavior of // BasicAnnotationProcessor, since Dagger still relies on this behavior. diff --git a/java/dagger/internal/codegen/validation/BUILD b/java/dagger/internal/codegen/validation/BUILD index cc3670843..a24b7e0bf 100644 --- a/java/dagger/internal/codegen/validation/BUILD +++ b/java/dagger/internal/codegen/validation/BUILD @@ -36,7 +36,6 @@ java_library( "//java/dagger/internal/codegen/model", "//java/dagger/internal/codegen/xprocessing", "//java/dagger/spi", - "//third_party/java/auto:common", "//third_party/java/auto:value", "//third_party/java/checker_framework_annotations", "//third_party/java/error_prone:annotations", diff --git a/java/dagger/internal/codegen/validation/BindingMethodValidator.java b/java/dagger/internal/codegen/validation/BindingMethodValidator.java index 9598a7c35..731050649 100644 --- a/java/dagger/internal/codegen/validation/BindingMethodValidator.java +++ b/java/dagger/internal/codegen/validation/BindingMethodValidator.java @@ -140,6 +140,7 @@ abstract class BindingMethodValidator extends BindingElementValidator<XMethodEle @Override protected final void checkAdditionalProperties() { + checkNotExtensionFunction(); checkEnclosingElement(); checkTypeParameters(); checkNotPrivate(); @@ -152,6 +153,12 @@ abstract class BindingMethodValidator extends BindingElementValidator<XMethodEle /** Checks additional properties of the binding method. */ protected void checkAdditionalMethodProperties() {} + private void checkNotExtensionFunction() { + if (method.isExtensionFunction()) { + report.addError(bindingMethods("can not be an extension function")); + } + } + /** * Adds an error if the method is not declared in a class or interface annotated with one of the * {@link #enclosingElementAnnotations}. diff --git a/java/dagger/internal/codegen/validation/ComponentValidator.java b/java/dagger/internal/codegen/validation/ComponentValidator.java index b5034480c..b3469a14e 100644 --- a/java/dagger/internal/codegen/validation/ComponentValidator.java +++ b/java/dagger/internal/codegen/validation/ComponentValidator.java @@ -168,6 +168,7 @@ public final class ComponentValidator implements ClearableCache { // the remaining checks will likely just output unhelpful noise in such cases. return report.addError(invalidTypeError(), component).build(); } + validateFields(); validateUseOfCancellationPolicy(); validateIsAbstractType(); validateCreators(); @@ -208,6 +209,18 @@ public final class ComponentValidator implements ClearableCache { componentKind().annotation().simpleName()); } + private void validateFields() { + component.getDeclaredMethods().stream() + .filter(method -> method.isKotlinPropertySetter() && method.isAbstract()) + .forEach( + method -> + report.addError( + String.format( + "Cannot use 'abstract var' property in a component declaration to get a" + + " binding. Use 'val' or 'fun' instead: %s", + method.getPropertyName()))); + } + private void validateCreators() { ImmutableSet<XTypeElement> creators = enclosedAnnotatedTypes(component, creatorAnnotationsFor(componentAnnotation())); diff --git a/java/dagger/internal/codegen/validation/DiagnosticMessageGenerator.java b/java/dagger/internal/codegen/validation/DiagnosticMessageGenerator.java index fc83e31f2..24ad67691 100644 --- a/java/dagger/internal/codegen/validation/DiagnosticMessageGenerator.java +++ b/java/dagger/internal/codegen/validation/DiagnosticMessageGenerator.java @@ -164,18 +164,11 @@ public final class DiagnosticMessageGenerator { ImmutableList<DependencyEdge> dependencyTrace, ImmutableSet<DependencyEdge> requests, ImmutableSet<DependencyEdge> entryPoints) { - StringBuilder message = - graph.isFullBindingGraph() - ? new StringBuilder() - : new StringBuilder(dependencyTrace.size() * 100 /* a guess heuristic */); - - // Print the dependency trace unless it's a full binding graph - if (!graph.isFullBindingGraph()) { - dependencyTrace.forEach( - edge -> dependencyRequestFormatter.appendFormatLine(message, edge.dependencyRequest())); - if (!dependencyTrace.isEmpty()) { - appendComponentPathUnlessAtRoot(message, source(getLast(dependencyTrace))); - } + StringBuilder message = new StringBuilder(dependencyTrace.size() * 100 /* a guess heuristic */); + dependencyTrace.forEach( + edge -> dependencyRequestFormatter.appendFormatLine(message, edge.dependencyRequest())); + if (!dependencyTrace.isEmpty()) { + appendComponentPathUnlessAtRoot(message, source(getLast(dependencyTrace))); } message.append(getRequestsNotInTrace(dependencyTrace, requests, entryPoints)); return message.toString(); @@ -190,25 +183,19 @@ public final class DiagnosticMessageGenerator { ImmutableSet<XElement> requestsToPrint = requests.stream() // if printing entry points, skip entry points and the traced request - .filter( - request -> - graph.isFullBindingGraph() - || (!request.isEntryPoint() && !isTracedRequest(dependencyTrace, request))) + .filter(request -> !request.isEntryPoint()) + .filter(request -> !isTracedRequest(dependencyTrace, request)) .map(request -> request.dependencyRequest().requestElement()) .flatMap(presentValues()) .map(DaggerElement::xprocessing) .collect(toImmutableSet()); if (!requestsToPrint.isEmpty()) { - message - .append("\nIt is") - .append(graph.isFullBindingGraph() ? " " : " also ") - .append("requested at:"); + message.append("\nIt is also requested at:"); elementFormatter.formatIndentedList(message, requestsToPrint, 1); } - // Print the remaining entry points, showing which component they're in, unless it's a full - // binding graph - if (!graph.isFullBindingGraph() && entryPoints.size() > 1) { + // Print the remaining entry points, showing which component they're in + if (entryPoints.size() > 1) { message.append("\nThe following other entry points also depend on it:"); entryPointFormatter.formatIndentedList( message, @@ -253,9 +240,14 @@ public final class DiagnosticMessageGenerator { } }; - private static boolean isTracedRequest( + private boolean isTracedRequest( ImmutableList<DependencyEdge> dependencyTrace, DependencyEdge request) { - return !dependencyTrace.isEmpty() && request.equals(dependencyTrace.get(0)); + return !dependencyTrace.isEmpty() + && request.dependencyRequest().equals(dependencyTrace.get(0).dependencyRequest()) + // Comparing the dependency request is not enough since the request is just the key. + // Instead, we check that the target incident node is the same. + && graph.network().incidentNodes(request).target() + .equals(graph.network().incidentNodes(dependencyTrace.get(0)).target()); } /** diff --git a/java/dagger/internal/codegen/validation/InjectBindingRegistryImpl.java b/java/dagger/internal/codegen/validation/InjectBindingRegistryImpl.java index cc2d6e940..16344d3f3 100644 --- a/java/dagger/internal/codegen/validation/InjectBindingRegistryImpl.java +++ b/java/dagger/internal/codegen/validation/InjectBindingRegistryImpl.java @@ -17,6 +17,7 @@ package dagger.internal.codegen.validation; import static androidx.room.compiler.processing.XElementKt.isTypeElement; +import static androidx.room.compiler.processing.compat.XConverters.toKS; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; @@ -27,6 +28,7 @@ import static dagger.internal.codegen.binding.InjectionAnnotations.injectedConst import static dagger.internal.codegen.binding.SourceFiles.generatedClassNameForBinding; import static dagger.internal.codegen.extension.DaggerCollectors.toOptional; import static dagger.internal.codegen.xprocessing.XElements.asTypeElement; +import static dagger.internal.codegen.xprocessing.XElements.closestEnclosingTypeElement; import static dagger.internal.codegen.xprocessing.XTypes.erasedTypeName; import static dagger.internal.codegen.xprocessing.XTypes.isDeclared; import static dagger.internal.codegen.xprocessing.XTypes.nonObjectSuperclass; @@ -41,6 +43,7 @@ import androidx.room.compiler.processing.XType; import androidx.room.compiler.processing.XTypeElement; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import com.google.devtools.ksp.symbol.Origin; import com.google.errorprone.annotations.CanIgnoreReturnValue; import com.squareup.javapoet.ClassName; import dagger.Component; @@ -82,7 +85,7 @@ final class InjectBindingRegistryImpl implements InjectBindingRegistry { private final BindingFactory bindingFactory; private final CompilerOptions compilerOptions; - final class BindingsCollection<B extends Binding> { + private final class BindingsCollection<B extends Binding> { private final ClassName factoryClass; private final Map<Key, B> bindingsByKey = Maps.newLinkedHashMap(); private final Deque<B> bindingsRequiringGeneration = new ArrayDeque<>(); @@ -115,24 +118,40 @@ final class InjectBindingRegistryImpl implements InjectBindingRegistry { } /** Caches the binding and generates it if it needs generation. */ - void tryRegisterBinding(B binding, boolean warnIfNotAlreadyGenerated) { + void tryRegisterBinding(B binding, boolean isCalledFromInjectProcessor) { + if (processingEnv.getBackend() == XProcessingEnv.Backend.KSP) { + Origin origin = + toKS(closestEnclosingTypeElement(binding.bindingElement().get())).getOrigin(); + // If the origin of the element is from a source file in the current compilation unit then + // we're guaranteed that the InjectProcessor should run over the element so only generate + // the Factory/MembersInjector if we're being called from the InjectProcessor. + // + // TODO(bcorso): generally, this isn't something we would need to keep track of manually. + // However, KSP incremental processing has a bug that will overwrite the cache for the + // element if we generate files for it, which can lead to missing generated files from + // other processors. See https://github.com/google/dagger/issues/4063 and + // https://github.com/google/dagger/issues/4054. Remove this once that bug is fixed. + if (!isCalledFromInjectProcessor && (origin == Origin.JAVA || origin == Origin.KOTLIN)) { + return; + } + } tryToCacheBinding(binding); @SuppressWarnings("unchecked") B maybeUnresolved = binding.unresolved().isPresent() ? (B) binding.unresolved().get() : binding; - tryToGenerateBinding(maybeUnresolved, warnIfNotAlreadyGenerated); + tryToGenerateBinding(maybeUnresolved, isCalledFromInjectProcessor); } /** * Tries to generate a binding, not generating if it already is generated. For resolved * bindings, this will try to generate the unresolved version of the binding. */ - void tryToGenerateBinding(B binding, boolean warnIfNotAlreadyGenerated) { + void tryToGenerateBinding(B binding, boolean isCalledFromInjectProcessor) { if (shouldGenerateBinding(binding)) { bindingsRequiringGeneration.offer(binding); if (compilerOptions.warnIfInjectionFactoryNotGeneratedUpstream() - && warnIfNotAlreadyGenerated) { + && !isCalledFromInjectProcessor) { messager.printMessage( Kind.NOTE, String.format( @@ -147,6 +166,22 @@ final class InjectBindingRegistryImpl implements InjectBindingRegistry { /** Returns true if the binding needs to be generated. */ private boolean shouldGenerateBinding(B binding) { + if (binding instanceof MembersInjectionBinding) { + MembersInjectionBinding membersInjectionBinding = (MembersInjectionBinding) binding; + // Empty members injection bindings are special and don't need source files. + if (membersInjectionBinding.injectionSites().isEmpty()) { + return false; + } + // Members injectors for classes with no local injection sites and no @Inject + // constructor are unused. + boolean hasInjectConstructor = + !(injectedConstructors(membersInjectionBinding.membersInjectedType()).isEmpty() + && assistedInjectedConstructors( + membersInjectionBinding.membersInjectedType()).isEmpty()); + if (!membersInjectionBinding.hasLocalInjectionSites() && !hasInjectConstructor) { + return false; + } + } return !binding.unresolved().isPresent() && !materializedBindingKeys.contains(binding.key()) && !bindingsRequiringGeneration.contains(binding) @@ -200,52 +235,20 @@ final class InjectBindingRegistryImpl implements InjectBindingRegistry { membersInjectionBindings.generateBindings(membersInjectorGenerator); } - /** - * Registers the binding for generation and later lookup. If the binding is resolved, we also - * attempt to register an unresolved version of it. - */ - private void registerBinding(ProvisionBinding binding, boolean warnIfNotAlreadyGenerated) { - provisionBindings.tryRegisterBinding(binding, warnIfNotAlreadyGenerated); - } - - /** - * Registers the binding for generation and later lookup. If the binding is resolved, we also - * attempt to register an unresolved version of it. - */ - private void registerBinding(MembersInjectionBinding binding, boolean warnIfNotAlreadyGenerated) { - /* - * We generate MembersInjector classes for types with @Inject constructors only if they have any - * injection sites. - * - * We generate MembersInjector classes for types without @Inject constructors only if they have - * local (non-inherited) injection sites. - * - * Warn only when registering bindings post-hoc for those types. - */ - if (warnIfNotAlreadyGenerated) { - boolean hasInjectConstructor = - !(injectedConstructors(binding.membersInjectedType()).isEmpty() - && assistedInjectedConstructors(binding.membersInjectedType()).isEmpty()); - warnIfNotAlreadyGenerated = - hasInjectConstructor - ? !binding.injectionSites().isEmpty() - : binding.hasLocalInjectionSites(); - } - - membersInjectionBindings.tryRegisterBinding(binding, warnIfNotAlreadyGenerated); - } - @Override public Optional<ProvisionBinding> tryRegisterInjectConstructor( XConstructorElement constructorElement) { - return tryRegisterConstructor(constructorElement, Optional.empty(), false); + return tryRegisterConstructor( + constructorElement, + Optional.empty(), + /* isCalledFromInjectProcessor= */ true); } @CanIgnoreReturnValue private Optional<ProvisionBinding> tryRegisterConstructor( XConstructorElement constructorElement, Optional<XType> resolvedType, - boolean warnIfNotAlreadyGenerated) { + boolean isCalledFromInjectProcessor) { XTypeElement typeElement = constructorElement.getEnclosingElement(); // Validating here shouldn't have a performance penalty because the validator caches its reports @@ -263,9 +266,9 @@ final class InjectBindingRegistryImpl implements InjectBindingRegistry { } ProvisionBinding binding = bindingFactory.injectionBinding(constructorElement, resolvedType); - registerBinding(binding, warnIfNotAlreadyGenerated); + provisionBindings.tryRegisterBinding(binding, isCalledFromInjectProcessor); if (!binding.injectionSites().isEmpty()) { - tryRegisterMembersInjectedType(typeElement, resolvedType, warnIfNotAlreadyGenerated); + tryRegisterMembersInjectedType(typeElement, resolvedType, isCalledFromInjectProcessor); } return Optional.of(binding); } @@ -281,7 +284,9 @@ final class InjectBindingRegistryImpl implements InjectBindingRegistry { fieldElement); } return tryRegisterMembersInjectedType( - asTypeElement(fieldElement.getEnclosingElement()), Optional.empty(), false); + asTypeElement(fieldElement.getEnclosingElement()), + Optional.empty(), + /* isCalledFromInjectProcessor= */ true); } @Override @@ -295,12 +300,16 @@ final class InjectBindingRegistryImpl implements InjectBindingRegistry { methodElement); } return tryRegisterMembersInjectedType( - asTypeElement(methodElement.getEnclosingElement()), Optional.empty(), false); + asTypeElement(methodElement.getEnclosingElement()), + Optional.empty(), + /* isCalledFromInjectProcessor= */ true); } @CanIgnoreReturnValue private Optional<MembersInjectionBinding> tryRegisterMembersInjectedType( - XTypeElement typeElement, Optional<XType> resolvedType, boolean warnIfNotAlreadyGenerated) { + XTypeElement typeElement, + Optional<XType> resolvedType, + boolean isCalledFromInjectProcessor) { // Validating here shouldn't have a performance penalty because the validator caches its reports ValidationReport report = injectValidator.validateForMembersInjection(typeElement); report.printMessagesTo(messager); @@ -316,7 +325,7 @@ final class InjectBindingRegistryImpl implements InjectBindingRegistry { } MembersInjectionBinding binding = bindingFactory.membersInjectionBinding(type, resolvedType); - registerBinding(binding, warnIfNotAlreadyGenerated); + membersInjectionBindings.tryRegisterBinding(binding, isCalledFromInjectProcessor); for (Optional<XType> supertype = nonObjectSuperclass(type); supertype.isPresent(); supertype = nonObjectSuperclass(supertype.get())) { @@ -351,7 +360,12 @@ final class InjectBindingRegistryImpl implements InjectBindingRegistry { assistedInjectedConstructors(element).stream()) // We're guaranteed that there's at most 1 @Inject constructors from above validation. .collect(toOptional()) - .flatMap(constructor -> tryRegisterConstructor(constructor, Optional.of(type), true)); + .flatMap( + constructor -> + tryRegisterConstructor( + constructor, + Optional.of(type), + /* isCalledFromInjectProcessor= */ false)); } @CanIgnoreReturnValue @@ -365,7 +379,9 @@ final class InjectBindingRegistryImpl implements InjectBindingRegistry { return Optional.of(binding); } return tryRegisterMembersInjectedType( - key.type().xprocessing().getTypeElement(), Optional.of(key.type().xprocessing()), true); + key.type().xprocessing().getTypeElement(), + Optional.of(key.type().xprocessing()), + /* isCalledFromInjectProcessor= */ false); } @Override diff --git a/java/dagger/internal/codegen/validation/InjectValidator.java b/java/dagger/internal/codegen/validation/InjectValidator.java index f223f6a9a..ac434d7d6 100644 --- a/java/dagger/internal/codegen/validation/InjectValidator.java +++ b/java/dagger/internal/codegen/validation/InjectValidator.java @@ -64,6 +64,7 @@ import javax.tools.Diagnostic.Kind; */ @Singleton public final class InjectValidator implements ClearableCache { + private final XProcessingEnv processingEnv; private final CompilerOptions compilerOptions; private final DependencyRequestValidator dependencyRequestValidator; @@ -298,6 +299,15 @@ public final class InjectValidator implements ClearableCache { fieldElement); } + if (fieldElement.isProtected() + && fieldElement.getEnclosingElement().isFromKotlin() + ) { + builder.addItem( + "Dagger injector does not have access to kotlin protected fields", + staticMemberDiagnosticKind(), + fieldElement); + } + validateDependencyRequest(builder, fieldElement); return builder.build(); diff --git a/java/dagger/internal/codegen/validation/ModelBindingGraphConverter.java b/java/dagger/internal/codegen/validation/ModelBindingGraphConverter.java index 314ed5fb4..ae53978d5 100644 --- a/java/dagger/internal/codegen/validation/ModelBindingGraphConverter.java +++ b/java/dagger/internal/codegen/validation/ModelBindingGraphConverter.java @@ -134,8 +134,8 @@ public final class ModelBindingGraphConverter { } private static Key toModel(dagger.internal.codegen.model.Key key) { - return Key.builder(key.type().java()) - .qualifier(key.qualifier().map(DaggerAnnotation::java)) + return Key.builder(key.type().javac()) + .qualifier(key.qualifier().map(DaggerAnnotation::javac)) .multibindingContributionIdentifier( key.multibindingContributionIdentifier().isPresent() ? Optional.of(toModel(key.multibindingContributionIdentifier().get())) @@ -159,17 +159,17 @@ public final class ModelBindingGraphConverter { .key(toModel(request.key())) .isNullable(request.isNullable()); - request.requestElement().ifPresent(e -> builder.requestElement(e.java())); + request.requestElement().ifPresent(e -> builder.requestElement(e.javac())); return builder.build(); } private static Scope toModel(dagger.internal.codegen.model.Scope scope) { - return Scope.scope(scope.scopeAnnotation().java()); + return Scope.scope(scope.scopeAnnotation().javac()); } private static ComponentPath toModel(dagger.internal.codegen.model.ComponentPath path) { return ComponentPath.create( - path.components().stream().map(DaggerTypeElement::java).collect(toImmutableList())); + path.components().stream().map(DaggerTypeElement::javac).collect(toImmutableList())); } private static dagger.internal.codegen.model.BindingGraph.ComponentNode toInternal( @@ -232,8 +232,8 @@ public final class ModelBindingGraphConverter { binding.dependencies().stream() .map(ModelBindingGraphConverter::toModel) .collect(toImmutableSet()), - binding.bindingElement().map(DaggerElement::java), - binding.contributingModule().map(DaggerTypeElement::java), + binding.bindingElement().map(DaggerElement::javac), + binding.contributingModule().map(DaggerTypeElement::javac), binding.requiresModuleInstance(), binding.scope().map(ModelBindingGraphConverter::toModel), binding.isNullable(), @@ -291,7 +291,7 @@ public final class ModelBindingGraphConverter { static ChildFactoryMethodEdge create( dagger.internal.codegen.model.BindingGraph.ChildFactoryMethodEdge childFactoryMethodEdge) { return new AutoValue_ModelBindingGraphConverter_ChildFactoryMethodEdgeImpl( - childFactoryMethodEdge.factoryMethod().java(), childFactoryMethodEdge); + childFactoryMethodEdge.factoryMethod().javac(), childFactoryMethodEdge); } abstract dagger.internal.codegen.model.BindingGraph.ChildFactoryMethodEdge delegate(); @@ -310,7 +310,7 @@ public final class ModelBindingGraphConverter { subcomponentCreatorBindingEdge) { return new AutoValue_ModelBindingGraphConverter_SubcomponentCreatorBindingEdgeImpl( subcomponentCreatorBindingEdge.declaringModules().stream() - .map(DaggerTypeElement::java) + .map(DaggerTypeElement::javac) .collect(toImmutableSet()), subcomponentCreatorBindingEdge); } diff --git a/java/dagger/internal/codegen/validation/ModuleValidator.java b/java/dagger/internal/codegen/validation/ModuleValidator.java index a1d9b0d11..38bce2b44 100644 --- a/java/dagger/internal/codegen/validation/ModuleValidator.java +++ b/java/dagger/internal/codegen/validation/ModuleValidator.java @@ -58,7 +58,7 @@ import dagger.internal.codegen.base.ComponentCreatorAnnotation; import dagger.internal.codegen.base.DaggerSuperficialValidation; import dagger.internal.codegen.base.ModuleKind; import dagger.internal.codegen.binding.BindingGraphFactory; -import dagger.internal.codegen.binding.ComponentDescriptorFactory; +import dagger.internal.codegen.binding.ComponentDescriptor; import dagger.internal.codegen.binding.InjectionAnnotations; import dagger.internal.codegen.binding.MethodSignatureFormatter; import dagger.internal.codegen.javapoet.TypeNames; @@ -109,7 +109,7 @@ public final class ModuleValidator { private final AnyBindingMethodValidator anyBindingMethodValidator; private final MethodSignatureFormatter methodSignatureFormatter; - private final ComponentDescriptorFactory componentDescriptorFactory; + private final ComponentDescriptor.Factory componentDescriptorFactory; private final BindingGraphFactory bindingGraphFactory; private final BindingGraphValidator bindingGraphValidator; private final InjectionAnnotations injectionAnnotations; @@ -122,7 +122,7 @@ public final class ModuleValidator { ModuleValidator( AnyBindingMethodValidator anyBindingMethodValidator, MethodSignatureFormatter methodSignatureFormatter, - ComponentDescriptorFactory componentDescriptorFactory, + ComponentDescriptor.Factory componentDescriptorFactory, BindingGraphFactory bindingGraphFactory, BindingGraphValidator bindingGraphValidator, InjectionAnnotations injectionAnnotations, diff --git a/java/dagger/internal/codegen/validation/ProducesMethodValidator.java b/java/dagger/internal/codegen/validation/ProducesMethodValidator.java index cf78b63c4..9b4c16c4e 100644 --- a/java/dagger/internal/codegen/validation/ProducesMethodValidator.java +++ b/java/dagger/internal/codegen/validation/ProducesMethodValidator.java @@ -90,7 +90,7 @@ final class ProducesMethodValidator extends BindingMethodValidator { // TODO(beder): Properly handle nullable with producer methods. private void checkNullable() { Nullability nullability = Nullability.of(method); - if (nullability.nullableAnnotation().isPresent()) { + if (!nullability.nullableAnnotations().isEmpty()) { report.addWarning("@Nullable on @Produces methods does not do anything"); } } diff --git a/java/dagger/internal/codegen/validation/SpiModelBindingGraphConverter.java b/java/dagger/internal/codegen/validation/SpiModelBindingGraphConverter.java index 75d0f7f99..42e1adffb 100644 --- a/java/dagger/internal/codegen/validation/SpiModelBindingGraphConverter.java +++ b/java/dagger/internal/codegen/validation/SpiModelBindingGraphConverter.java @@ -16,9 +16,11 @@ package dagger.internal.codegen.validation; +import static androidx.room.compiler.processing.compat.XConverters.getProcessingEnv; import static androidx.room.compiler.processing.compat.XConverters.toJavac; import static androidx.room.compiler.processing.compat.XConverters.toKS; import static androidx.room.compiler.processing.compat.XConverters.toKSResolver; +import static com.google.common.base.Preconditions.checkState; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableMap; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; @@ -31,6 +33,7 @@ import androidx.room.compiler.processing.XType; import androidx.room.compiler.processing.XTypeElement; import com.google.auto.value.AutoValue; import com.google.auto.value.extension.memoized.Memoized; +import com.google.common.base.Equivalence; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSetMultimap; import com.google.common.graph.EndpointPair; @@ -38,7 +41,16 @@ import com.google.common.graph.ImmutableNetwork; import com.google.common.graph.MutableNetwork; import com.google.common.graph.Network; import com.google.common.graph.NetworkBuilder; +import com.google.devtools.ksp.processing.Resolver; +import com.google.devtools.ksp.processing.SymbolProcessorEnvironment; +import com.google.devtools.ksp.symbol.KSAnnotated; +import com.google.devtools.ksp.symbol.KSAnnotation; +import com.google.devtools.ksp.symbol.KSClassDeclaration; +import com.google.devtools.ksp.symbol.KSFunctionDeclaration; +import com.google.devtools.ksp.symbol.KSType; +import dagger.internal.codegen.xprocessing.XAnnotations; import dagger.internal.codegen.xprocessing.XElements; +import dagger.internal.codegen.xprocessing.XTypes; import dagger.spi.model.Binding; import dagger.spi.model.BindingGraph; import dagger.spi.model.BindingGraph.ChildFactoryMethodEdge; @@ -64,6 +76,12 @@ import dagger.spi.model.Key; import dagger.spi.model.RequestKind; import dagger.spi.model.Scope; import java.util.Optional; +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.type.TypeMirror; import javax.tools.Diagnostic; /** A Utility class for converting to the {@link BindingGraph} used by external plugins. */ @@ -141,19 +159,20 @@ public final class SpiModelBindingGraphConverter { } } - private static Key toSpiModel(dagger.internal.codegen.model.Key key, XProcessingEnv env) { + private static Key toSpiModel(dagger.internal.codegen.model.Key key) { Key.Builder builder = - Key.builder(toSpiModel(key.type().xprocessing(), env)) - .qualifier(key.qualifier().map(qualifier -> toSpiModel(qualifier.xprocessing(), env))); + Key.builder(toSpiModel(key.type().xprocessing())) + .qualifier(key.qualifier().map(qualifier -> toSpiModel(qualifier.xprocessing()))); if (key.multibindingContributionIdentifier().isPresent()) { return builder .multibindingContributionIdentifier( toSpiModel( - key.multibindingContributionIdentifier().get().contributingModule().xprocessing(), - env), + key.multibindingContributionIdentifier() + .get() + .contributingModule() + .xprocessing()), toSpiModel( - key.multibindingContributionIdentifier().get().bindingMethod().xprocessing(), - env)) + key.multibindingContributionIdentifier().get().bindingMethod().xprocessing())) .build(); } return builder.build().withoutMultibindingContributionIdentifier(); @@ -169,98 +188,50 @@ public final class SpiModelBindingGraphConverter { @SuppressWarnings("CheckReturnValue") private static DependencyRequest toSpiModel( - dagger.internal.codegen.model.DependencyRequest request, XProcessingEnv env) { + dagger.internal.codegen.model.DependencyRequest request) { DependencyRequest.Builder builder = DependencyRequest.builder() .kind(toSpiModel(request.kind())) - .key(toSpiModel(request.key(), env)) + .key(toSpiModel(request.key())) .isNullable(request.isNullable()); - request - .requestElement() - .ifPresent(e -> builder.requestElement(toSpiModel(e.xprocessing(), env))); + request.requestElement().ifPresent(e -> builder.requestElement(toSpiModel(e.xprocessing()))); return builder.build(); } - private static Scope toSpiModel(dagger.internal.codegen.model.Scope scope, XProcessingEnv env) { - return Scope.scope(toSpiModel(scope.scopeAnnotation().xprocessing(), env)); + private static Scope toSpiModel(dagger.internal.codegen.model.Scope scope) { + return Scope.scope(toSpiModel(scope.scopeAnnotation().xprocessing())); } - private static ComponentPath toSpiModel( - dagger.internal.codegen.model.ComponentPath path, XProcessingEnv env) { + private static ComponentPath toSpiModel(dagger.internal.codegen.model.ComponentPath path) { return ComponentPath.create( path.components().stream() - .map(component -> toSpiModel(component.xprocessing(), env)) + .map(component -> toSpiModel(component.xprocessing())) .collect(toImmutableList())); } - private static DaggerTypeElement toSpiModel(XTypeElement typeElement, XProcessingEnv env) { - switch (env.getBackend()) { - case JAVAC: - return DaggerTypeElement.fromJavac(toJavac(typeElement)); - case KSP: - return DaggerTypeElement.fromKsp(toKS(typeElement)); - } - throw new IllegalStateException( - String.format("Backend %s is not supported yet.", env.getBackend())); + private static DaggerTypeElement toSpiModel(XTypeElement typeElement) { + return DaggerTypeElementImpl.from(typeElement); } - private static DaggerType toSpiModel(XType type, XProcessingEnv env) { - switch (env.getBackend()) { - case JAVAC: - return DaggerType.fromJavac(toJavac(type)); - case KSP: - return DaggerType.fromKsp(toKS(type)); - } - throw new IllegalStateException( - String.format("Backend %s is not supported yet.", env.getBackend())); + private static DaggerType toSpiModel(XType type) { + return DaggerTypeImpl.from(type); } - static DaggerAnnotation toSpiModel(XAnnotation annotation, XProcessingEnv env) { - DaggerTypeElement typeElement = toSpiModel(annotation.getTypeElement(), env); - - switch (env.getBackend()) { - case JAVAC: - return DaggerAnnotation.fromJavac(typeElement, toJavac(annotation)); - case KSP: - return DaggerAnnotation.fromKsp(typeElement, toKS(annotation)); - } - throw new IllegalStateException( - String.format("Backend %s is not supported yet.", env.getBackend())); + static DaggerAnnotation toSpiModel(XAnnotation annotation) { + return DaggerAnnotationImpl.from(annotation); } - private static DaggerElement toSpiModel(XElement element, XProcessingEnv env) { - switch (env.getBackend()) { - case JAVAC: - return DaggerElement.fromJavac(toJavac(element)); - case KSP: - return DaggerElement.fromKsp(XElements.toKSAnnotated(element)); - } - throw new IllegalStateException( - String.format("Backend %s is not supported yet.", env.getBackend())); + private static DaggerElement toSpiModel(XElement element) { + return DaggerElementImpl.from(element); } - private static DaggerExecutableElement toSpiModel( - XExecutableElement executableElement, XProcessingEnv env) { - switch (env.getBackend()) { - case JAVAC: - return DaggerExecutableElement.fromJava(toJavac(executableElement)); - case KSP: - return DaggerExecutableElement.fromKsp(toKS(executableElement)); - } - throw new IllegalStateException( - String.format("Backend %s is not supported yet.", env.getBackend())); + private static DaggerExecutableElement toSpiModel(XExecutableElement executableElement) { + return DaggerExecutableElementImpl.from(executableElement); } static DaggerProcessingEnv toSpiModel(XProcessingEnv env) { - switch (env.getBackend()) { - case JAVAC: - return DaggerProcessingEnv.fromJavac(toJavac(env)); - case KSP: - return DaggerProcessingEnv.fromKsp(toKS(env), toKSResolver(env)); - } - throw new IllegalStateException( - String.format("Backend %s is not supported yet.", env.getBackend())); + return DaggerProcessingEnvImpl.from(env); } private static dagger.internal.codegen.model.BindingGraph.ComponentNode toInternal( @@ -295,14 +266,14 @@ public final class SpiModelBindingGraphConverter { dagger.internal.codegen.model.BindingGraph.ComponentNode componentNode, XProcessingEnv env) { return new AutoValue_SpiModelBindingGraphConverter_ComponentNodeImpl( - toSpiModel(componentNode.componentPath(), env), + toSpiModel(componentNode.componentPath()), componentNode.isSubcomponent(), componentNode.isRealComponent(), componentNode.entryPoints().stream() - .map(request -> SpiModelBindingGraphConverter.toSpiModel(request, env)) + .map(SpiModelBindingGraphConverter::toSpiModel) .collect(toImmutableSet()), componentNode.scopes().stream() - .map(request -> SpiModelBindingGraphConverter.toSpiModel(request, env)) + .map(SpiModelBindingGraphConverter::toSpiModel) .collect(toImmutableSet()), componentNode); } @@ -319,15 +290,15 @@ public final class SpiModelBindingGraphConverter { abstract static class BindingNodeImpl implements Binding { static Binding create(dagger.internal.codegen.model.Binding binding, XProcessingEnv env) { return new AutoValue_SpiModelBindingGraphConverter_BindingNodeImpl( - toSpiModel(binding.key(), env), - toSpiModel(binding.componentPath(), env), + toSpiModel(binding.key()), + toSpiModel(binding.componentPath()), binding.dependencies().stream() - .map(request -> SpiModelBindingGraphConverter.toSpiModel(request, env)) + .map(SpiModelBindingGraphConverter::toSpiModel) .collect(toImmutableSet()), - binding.bindingElement().map(element -> toSpiModel(element.xprocessing(), env)), - binding.contributingModule().map(module -> toSpiModel(module.xprocessing(), env)), + binding.bindingElement().map(element -> toSpiModel(element.xprocessing())), + binding.contributingModule().map(module -> toSpiModel(module.xprocessing())), binding.requiresModuleInstance(), - binding.scope().map(scope -> SpiModelBindingGraphConverter.toSpiModel(scope, env)), + binding.scope().map(SpiModelBindingGraphConverter::toSpiModel), binding.isNullable(), binding.isProduction(), toSpiModel(binding.kind()), @@ -348,8 +319,8 @@ public final class SpiModelBindingGraphConverter { dagger.internal.codegen.model.BindingGraph.MissingBinding missingBinding, XProcessingEnv env) { return new AutoValue_SpiModelBindingGraphConverter_MissingBindingImpl( - toSpiModel(missingBinding.componentPath(), env), - toSpiModel(missingBinding.key(), env), + toSpiModel(missingBinding.componentPath()), + toSpiModel(missingBinding.key()), missingBinding); } @@ -369,7 +340,7 @@ public final class SpiModelBindingGraphConverter { dagger.internal.codegen.model.BindingGraph.DependencyEdge dependencyEdge, XProcessingEnv env) { return new AutoValue_SpiModelBindingGraphConverter_DependencyEdgeImpl( - toSpiModel(dependencyEdge.dependencyRequest(), env), + toSpiModel(dependencyEdge.dependencyRequest()), dependencyEdge.isEntryPoint(), dependencyEdge); } @@ -388,8 +359,7 @@ public final class SpiModelBindingGraphConverter { dagger.internal.codegen.model.BindingGraph.ChildFactoryMethodEdge childFactoryMethodEdge, XProcessingEnv env) { return new AutoValue_SpiModelBindingGraphConverter_ChildFactoryMethodEdgeImpl( - toSpiModel(childFactoryMethodEdge.factoryMethod().xprocessing(), env), - childFactoryMethodEdge); + toSpiModel(childFactoryMethodEdge.factoryMethod().xprocessing()), childFactoryMethodEdge); } abstract dagger.internal.codegen.model.BindingGraph.ChildFactoryMethodEdge internalDelegate(); @@ -409,7 +379,7 @@ public final class SpiModelBindingGraphConverter { XProcessingEnv env) { return new AutoValue_SpiModelBindingGraphConverter_SubcomponentCreatorBindingEdgeImpl( subcomponentCreatorBindingEdge.declaringModules().stream() - .map(module -> toSpiModel(module.xprocessing(), env)) + .map(module -> toSpiModel(module.xprocessing())) .collect(toImmutableSet()), subcomponentCreatorBindingEdge); } @@ -458,6 +428,225 @@ public final class SpiModelBindingGraphConverter { } } + @AutoValue + abstract static class DaggerElementImpl extends DaggerElement { + public static DaggerElement from(XElement element) { + return new AutoValue_SpiModelBindingGraphConverter_DaggerElementImpl(element); + } + + abstract XElement element(); + + @Override + public Element javac() { + checkIsJavac(backend()); + return toJavac(element()); + } + + @Override + public KSAnnotated ksp() { + checkIsKsp(backend()); + return toKS(element()); + } + + @Override + public DaggerProcessingEnv.Backend backend() { + return getBackend(getProcessingEnv(element())); + } + + @Override + public final String toString() { + return XElements.toStableString(element()); + } + } + + @AutoValue + abstract static class DaggerTypeElementImpl extends DaggerTypeElement { + public static DaggerTypeElement from(XTypeElement element) { + return new AutoValue_SpiModelBindingGraphConverter_DaggerTypeElementImpl(element); + } + + abstract XTypeElement element(); + + @Override + public TypeElement javac() { + checkIsJavac(backend()); + return toJavac(element()); + } + + @Override + public KSClassDeclaration ksp() { + checkIsKsp(backend()); + return toKS(element()); + } + + @Override + public DaggerProcessingEnv.Backend backend() { + return getBackend(getProcessingEnv(element())); + } + + @Override + public final String toString() { + return XElements.toStableString(element()); + } + } + + @AutoValue + abstract static class DaggerTypeImpl extends DaggerType { + public static DaggerType from(XType type) { + return new AutoValue_SpiModelBindingGraphConverter_DaggerTypeImpl( + XTypes.equivalence().wrap(type)); + } + + abstract Equivalence.Wrapper<XType> type(); + + @Override + public TypeMirror javac() { + checkIsJavac(backend()); + return toJavac(type().get()); + } + + @Override + public KSType ksp() { + checkIsKsp(backend()); + return toKS(type().get()); + } + + @Override + public DaggerProcessingEnv.Backend backend() { + return getBackend(getProcessingEnv(type().get())); + } + + @Override + public final String toString() { + return XTypes.toStableString(type().get()); + } + } + + @AutoValue + abstract static class DaggerAnnotationImpl extends DaggerAnnotation { + public static DaggerAnnotation from(XAnnotation annotation) { + return new AutoValue_SpiModelBindingGraphConverter_DaggerAnnotationImpl( + XAnnotations.equivalence().wrap(annotation)); + } + + abstract Equivalence.Wrapper<XAnnotation> annotation(); + + @Override + public DaggerTypeElement annotationTypeElement() { + return DaggerTypeElementImpl.from(annotation().get().getTypeElement()); + } + + @Override + public AnnotationMirror javac() { + checkIsJavac(backend()); + return toJavac(annotation().get()); + } + + @Override + public KSAnnotation ksp() { + checkIsKsp(backend()); + return toKS(annotation().get()); + } + + @Override + public DaggerProcessingEnv.Backend backend() { + return getBackend(getProcessingEnv(annotation().get())); + } + + @Override + public final String toString() { + return XAnnotations.toStableString(annotation().get()); + } + } + + @AutoValue + abstract static class DaggerExecutableElementImpl extends DaggerExecutableElement { + public static DaggerExecutableElement from(XExecutableElement executableElement) { + return new AutoValue_SpiModelBindingGraphConverter_DaggerExecutableElementImpl( + executableElement); + } + + abstract XExecutableElement executableElement(); + + @Override + public ExecutableElement javac() { + checkIsJavac(backend()); + return toJavac(executableElement()); + } + + @Override + public KSFunctionDeclaration ksp() { + checkIsKsp(backend()); + return toKS(executableElement()); + } + + @Override + public DaggerProcessingEnv.Backend backend() { + return getBackend(getProcessingEnv(executableElement())); + } + + @Override + public final String toString() { + return XElements.toStableString(executableElement()); + } + } + + private static class DaggerProcessingEnvImpl extends DaggerProcessingEnv { + private final XProcessingEnv env; + + public static DaggerProcessingEnv from(XProcessingEnv env) { + return new DaggerProcessingEnvImpl(env); + } + + DaggerProcessingEnvImpl(XProcessingEnv env) { + this.env = env; + } + + @Override + public ProcessingEnvironment javac() { + checkIsJavac(backend()); + return toJavac(env); + } + + @Override + public SymbolProcessorEnvironment ksp() { + checkIsKsp(backend()); + return toKS(env); + } + + @Override + public Resolver resolver() { + return toKSResolver(env); + } + + @Override + public DaggerProcessingEnv.Backend backend() { + return getBackend(env); + } + } + + private static void checkIsJavac(DaggerProcessingEnv.Backend backend) { + checkState( + backend == DaggerProcessingEnv.Backend.JAVAC, + "Expected JAVAC backend but was: %s", backend); + } + + private static void checkIsKsp(DaggerProcessingEnv.Backend backend) { + checkState( + backend == DaggerProcessingEnv.Backend.KSP, + "Expected KSP backend but was: %s", backend); + } + + private static DaggerProcessingEnv.Backend getBackend(XProcessingEnv env) { + switch (env.getBackend()) { + case JAVAC: + return DaggerProcessingEnv.Backend.JAVAC; + case KSP: + return DaggerProcessingEnv.Backend.KSP; + } + throw new AssertionError(String.format("Unexpected backend %s", env.getBackend())); + } + private static final class DiagnosticReporterImpl extends DiagnosticReporter { static DiagnosticReporterImpl create( dagger.internal.codegen.model.DiagnosticReporter reporter) { diff --git a/java/dagger/internal/codegen/writing/AssistedInjectionParameters.java b/java/dagger/internal/codegen/writing/AssistedInjectionParameters.java index 42551a003..87ac24ae8 100644 --- a/java/dagger/internal/codegen/writing/AssistedInjectionParameters.java +++ b/java/dagger/internal/codegen/writing/AssistedInjectionParameters.java @@ -23,10 +23,10 @@ import static dagger.internal.codegen.xprocessing.XElements.asTypeElement; import androidx.room.compiler.processing.XConstructorElement; import androidx.room.compiler.processing.XConstructorType; +import androidx.room.compiler.processing.XExecutableParameterElement; import androidx.room.compiler.processing.XMethodType; import androidx.room.compiler.processing.XType; import androidx.room.compiler.processing.XTypeElement; -import androidx.room.compiler.processing.XVariableElement; import com.google.common.collect.ImmutableList; import com.squareup.javapoet.ParameterSpec; import dagger.internal.codegen.binding.AssistedInjectionAnnotations; @@ -79,12 +79,12 @@ final class AssistedInjectionParameters { } private static ImmutableList<ParameterSpec> assistedParameterSpecs( - List<? extends XVariableElement> paramElements, + List<XExecutableParameterElement> paramElements, List<XType> paramTypes, ShardImplementation shardImplementation) { ImmutableList.Builder<ParameterSpec> assistedParameterSpecs = ImmutableList.builder(); for (int i = 0; i < paramElements.size(); i++) { - XVariableElement paramElement = paramElements.get(i); + XExecutableParameterElement paramElement = paramElements.get(i); XType paramType = paramTypes.get(i); if (AssistedInjectionAnnotations.isAssistedParameter(paramElement)) { assistedParameterSpecs.add( diff --git a/java/dagger/internal/codegen/writing/BUILD b/java/dagger/internal/codegen/writing/BUILD index c8f9b61c2..3adeb66cd 100644 --- a/java/dagger/internal/codegen/writing/BUILD +++ b/java/dagger/internal/codegen/writing/BUILD @@ -31,11 +31,9 @@ java_library( "//java/dagger/internal/codegen/compileroption", "//java/dagger/internal/codegen/extension", "//java/dagger/internal/codegen/javapoet", - "//java/dagger/internal/codegen/kotlin", "//java/dagger/internal/codegen/langmodel", "//java/dagger/internal/codegen/model", "//java/dagger/internal/codegen/xprocessing", - "//java/dagger/producers", "//third_party/java/auto:common", "//third_party/java/auto:value", "//third_party/java/error_prone:annotations", diff --git a/java/dagger/internal/codegen/writing/ComponentCreatorImplementationFactory.java b/java/dagger/internal/codegen/writing/ComponentCreatorImplementationFactory.java index 88d4d4123..f74b50a36 100644 --- a/java/dagger/internal/codegen/writing/ComponentCreatorImplementationFactory.java +++ b/java/dagger/internal/codegen/writing/ComponentCreatorImplementationFactory.java @@ -202,6 +202,12 @@ final class ComponentCreatorImplementationFactory { case NEEDED: return Optional.of(normalSetterMethod(requirement)); case UNNEEDED: + // If this is a generated Builder, then remove the setter methods for modules that don't + // require an instance. + if (!componentDescriptor().creatorDescriptor().isPresent() + && !requirement.requiresModuleInstance()) { + return Optional.empty(); + } // TODO(bcorso): Don't generate noop setters for any unneeded requirements. // However, since this is a breaking change we can at least avoid trying // to generate noop setters for impossible cases like when the requirement type diff --git a/java/dagger/internal/codegen/writing/ComponentImplementation.java b/java/dagger/internal/codegen/writing/ComponentImplementation.java index 204d6faec..a41b1c793 100644 --- a/java/dagger/internal/codegen/writing/ComponentImplementation.java +++ b/java/dagger/internal/codegen/writing/ComponentImplementation.java @@ -42,6 +42,7 @@ import static javax.lang.model.element.Modifier.PUBLIC; import static javax.lang.model.element.Modifier.STATIC; import static javax.tools.Diagnostic.Kind.ERROR; +import androidx.room.compiler.processing.XExecutableParameterElement; import androidx.room.compiler.processing.XMessager; import androidx.room.compiler.processing.XMethodElement; import androidx.room.compiler.processing.XProcessingEnv; @@ -72,9 +73,9 @@ import dagger.internal.codegen.binding.Binding; import dagger.internal.codegen.binding.BindingGraph; import dagger.internal.codegen.binding.BindingNode; import dagger.internal.codegen.binding.BindingRequest; +import dagger.internal.codegen.binding.CancellationPolicy; import dagger.internal.codegen.binding.ComponentCreatorDescriptor; import dagger.internal.codegen.binding.ComponentDescriptor; -import dagger.internal.codegen.binding.ComponentDescriptor.CancellationPolicy; import dagger.internal.codegen.binding.ComponentDescriptor.ComponentMethodDescriptor; import dagger.internal.codegen.binding.ComponentRequirement; import dagger.internal.codegen.binding.KeyVariableNamer; @@ -111,16 +112,11 @@ public final class ComponentImplementation { /** Compiler Modes. */ public enum CompilerMode { DEFAULT, - FAST_INIT, - EXPERIMENTAL_MERGED_MODE; + FAST_INIT; public boolean isFastInit() { return this == CompilerMode.FAST_INIT; } - - public boolean isExperimentalMergedMode() { - return this == CompilerMode.EXPERIMENTAL_MERGED_MODE; - } } /** A type of field that this component can contain. */ @@ -311,11 +307,7 @@ public final class ComponentImplementation { this.messager = messager; XTypeElement typeElement = rootComponentImplementation().componentDescriptor().typeElement(); this.compilerMode = - compilerOptions.fastInit(typeElement) - ? CompilerMode.FAST_INIT - : (compilerOptions.experimentalMergedMode(typeElement) - ? CompilerMode.EXPERIMENTAL_MERGED_MODE - : CompilerMode.DEFAULT); + compilerOptions.fastInit(typeElement) ? CompilerMode.FAST_INIT : CompilerMode.DEFAULT; } /** @@ -464,7 +456,7 @@ public final class ComponentImplementation { private final UniqueNameSet assistedParamNames = new UniqueNameSet(); private final List<CodeBlock> initializations = new ArrayList<>(); private final SwitchingProviders switchingProviders; - private final ExperimentalSwitchingProviders experimentalSwitchingProviders; + private final LazyClassKeyProviders lazyClassKeyProviders; private final Map<Key, CodeBlock> cancellations = new LinkedHashMap<>(); private final Map<XVariableElement, String> uniqueAssistedName = new LinkedHashMap<>(); private final List<CodeBlock> componentRequirementInitializations = new ArrayList<>(); @@ -481,9 +473,7 @@ public final class ComponentImplementation { private ShardImplementation(ClassName name) { this.name = name; this.switchingProviders = new SwitchingProviders(this, processingEnv); - this.experimentalSwitchingProviders = - new ExperimentalSwitchingProviders(this, componentRequestRepresentationsProvider); - + this.lazyClassKeyProviders = new LazyClassKeyProviders(this); if (graph.componentDescriptor().isProduction()) { claimMethodName(CANCELLATION_LISTENER_METHOD_NAME); } @@ -517,9 +507,8 @@ public final class ComponentImplementation { return switchingProviders; } - /** Returns the {@link ExperimentalSwitchingProviders} class for this shard. */ - public ExperimentalSwitchingProviders getExperimentalSwitchingProviders() { - return experimentalSwitchingProviders; + public LazyClassKeyProviders getLazyClassKeyProviders() { + return lazyClassKeyProviders; } /** Returns the {@link ComponentImplementation} that owns this shard. */ @@ -665,12 +654,12 @@ public final class ComponentImplementation { return assistedParamNames.getUniqueName(name); } - public String getUniqueFieldNameForAssistedParam(XVariableElement element) { - if (uniqueAssistedName.containsKey(element)) { - return uniqueAssistedName.get(element); + public String getUniqueFieldNameForAssistedParam(XExecutableParameterElement parameter) { + if (uniqueAssistedName.containsKey(parameter)) { + return uniqueAssistedName.get(parameter); } - String name = getUniqueAssistedParamName(getSimpleName(element)); - uniqueAssistedName.put(element, name); + String name = getUniqueAssistedParamName(parameter.getJvmName()); + uniqueAssistedName.put(parameter, name); return name; } diff --git a/java/dagger/internal/codegen/writing/ComponentProvisionRequestRepresentation.java b/java/dagger/internal/codegen/writing/ComponentProvisionRequestRepresentation.java index d7594cbc1..41c3c46de 100644 --- a/java/dagger/internal/codegen/writing/ComponentProvisionRequestRepresentation.java +++ b/java/dagger/internal/codegen/writing/ComponentProvisionRequestRepresentation.java @@ -36,7 +36,6 @@ final class ComponentProvisionRequestRepresentation extends RequestRepresentatio private final BindingGraph bindingGraph; private final ComponentRequirementExpressions componentRequirementExpressions; private final CompilerOptions compilerOptions; - private final boolean isExperimentalMergedMode; @AssistedInject ComponentProvisionRequestRepresentation( @@ -49,16 +48,11 @@ final class ComponentProvisionRequestRepresentation extends RequestRepresentatio this.bindingGraph = bindingGraph; this.componentRequirementExpressions = componentRequirementExpressions; this.compilerOptions = compilerOptions; - this.isExperimentalMergedMode = - componentImplementation.compilerMode().isExperimentalMergedMode(); } @Override Expression getDependencyExpression(ClassName requestingClass) { - CodeBlock componentDependency = - isExperimentalMergedMode - ? CodeBlock.of("(($T) dependencies[0])", componentRequirement().type().getTypeName()) - : getComponentRequirementExpression(requestingClass); + CodeBlock componentDependency = getComponentRequirementExpression(requestingClass); CodeBlock invocation = CodeBlock.of( "$L.$L()", componentDependency, asMethod(binding.bindingElement().get()).getJvmName()); diff --git a/java/dagger/internal/codegen/writing/ComponentRequestRepresentations.java b/java/dagger/internal/codegen/writing/ComponentRequestRepresentations.java index 124eba1ff..dd343168a 100644 --- a/java/dagger/internal/codegen/writing/ComponentRequestRepresentations.java +++ b/java/dagger/internal/codegen/writing/ComponentRequestRepresentations.java @@ -19,7 +19,6 @@ package dagger.internal.codegen.writing; import static androidx.room.compiler.processing.XTypeKt.isVoid; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; import static com.google.common.collect.Iterables.getOnlyElement; import static dagger.internal.codegen.base.Util.reentrantComputeIfAbsent; import static dagger.internal.codegen.binding.BindingRequest.bindingRequest; @@ -28,13 +27,17 @@ import static dagger.internal.codegen.langmodel.Accessibility.isRawTypeAccessibl import static dagger.internal.codegen.langmodel.Accessibility.isTypeAccessibleFrom; import static dagger.internal.codegen.xprocessing.MethodSpecs.overriding; import static dagger.internal.codegen.xprocessing.XElements.getSimpleName; +import static dagger.internal.codegen.xprocessing.XProcessingEnvs.isPreJava8SourceVersion; import androidx.room.compiler.processing.XMethodElement; +import androidx.room.compiler.processing.XProcessingEnv; import androidx.room.compiler.processing.XType; import com.google.common.collect.ImmutableList; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.CodeBlock; import com.squareup.javapoet.MethodSpec; +import dagger.internal.codegen.base.MapType; +import dagger.internal.codegen.base.OptionalType; import dagger.internal.codegen.binding.Binding; import dagger.internal.codegen.binding.BindingGraph; import dagger.internal.codegen.binding.BindingRequest; @@ -69,11 +72,8 @@ public final class ComponentRequestRepresentations { membersInjectionBindingRepresentationFactory; private final ProvisionBindingRepresentation.Factory provisionBindingRepresentationFactory; private final ProductionBindingRepresentation.Factory productionBindingRepresentationFactory; - private final ExperimentalSwitchingProviderDependencyRepresentation.Factory - experimentalSwitchingProviderDependencyRepresentationFactory; private final Map<Binding, BindingRepresentation> representations = new HashMap<>(); - private final Map<Binding, ExperimentalSwitchingProviderDependencyRepresentation> - experimentalSwitchingProviderDependencyRepresentations = new HashMap<>(); + private final XProcessingEnv processingEnv; @Inject ComponentRequestRepresentations( @@ -84,8 +84,7 @@ public final class ComponentRequestRepresentations { MembersInjectionBindingRepresentation.Factory membersInjectionBindingRepresentationFactory, ProvisionBindingRepresentation.Factory provisionBindingRepresentationFactory, ProductionBindingRepresentation.Factory productionBindingRepresentationFactory, - ExperimentalSwitchingProviderDependencyRepresentation.Factory - experimentalSwitchingProviderDependencyRepresentationFactory) { + XProcessingEnv processingEnv) { this.parent = parent; this.graph = graph; this.componentImplementation = componentImplementation; @@ -93,9 +92,8 @@ public final class ComponentRequestRepresentations { membersInjectionBindingRepresentationFactory; this.provisionBindingRepresentationFactory = provisionBindingRepresentationFactory; this.productionBindingRepresentationFactory = productionBindingRepresentationFactory; - this.experimentalSwitchingProviderDependencyRepresentationFactory = - experimentalSwitchingProviderDependencyRepresentationFactory; this.componentRequirementExpressions = checkNotNull(componentRequirementExpressions); + this.processingEnv = processingEnv; } /** @@ -241,6 +239,15 @@ public final class ComponentRequestRepresentations { componentMethod.methodElement() .asMemberOf(componentImplementation.graph().componentTypeElement().getType()) .getReturnType(); + + // When compiling with -source 7, javac's type inference isn't strong enough to match things + // like Optional<javax.inject.Provider<T>> to Optional<dagger.internal.Provider<T>>. + if (isPreJava8SourceVersion(processingEnv) + && (MapType.isMapOfProvider(returnType) + || OptionalType.isOptionalProviderType(returnType))) { + return expression.castTo(returnType.getRawType()); + } + return !isVoid(returnType) && !expression.type().isAssignableTo(returnType) ? expression.castTo(returnType) : expression; @@ -278,29 +285,4 @@ public final class ComponentRequestRepresentations { } throw new AssertionError(); } - - /** - * Returns an {@link ExperimentalSwitchingProviderDependencyRepresentation} for the requested - * binding to satisfy dependency requests on it from experimental switching providers. Cannot be - * used for Members Injection requests. - */ - ExperimentalSwitchingProviderDependencyRepresentation - getExperimentalSwitchingProviderDependencyRepresentation(BindingRequest request) { - checkState( - componentImplementation.compilerMode().isExperimentalMergedMode(), - "Compiler mode should be experimentalMergedMode!"); - Optional<Binding> localBinding = graph.localContributionBinding(request.key()); - - if (localBinding.isPresent()) { - return reentrantComputeIfAbsent( - experimentalSwitchingProviderDependencyRepresentations, - localBinding.get(), - binding -> - experimentalSwitchingProviderDependencyRepresentationFactory.create( - (ProvisionBinding) binding)); - } - - checkArgument(parent.isPresent(), "no expression found for %s", request); - return parent.get().getExperimentalSwitchingProviderDependencyRepresentation(request); - } } diff --git a/java/dagger/internal/codegen/writing/DelegateRequestRepresentation.java b/java/dagger/internal/codegen/writing/DelegateRequestRepresentation.java index 673a659fd..82c01cfe2 100644 --- a/java/dagger/internal/codegen/writing/DelegateRequestRepresentation.java +++ b/java/dagger/internal/codegen/writing/DelegateRequestRepresentation.java @@ -36,7 +36,9 @@ import dagger.internal.codegen.binding.BindingGraph; import dagger.internal.codegen.binding.BindsTypeChecker; import dagger.internal.codegen.binding.ContributionBinding; import dagger.internal.codegen.javapoet.Expression; +import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.RequestKind; +import dagger.internal.codegen.xprocessing.XTypes; /** A {@link dagger.internal.codegen.writing.RequestRepresentation} for {@code @Binds} methods. */ final class DelegateRequestRepresentation extends RequestRepresentation { @@ -88,8 +90,14 @@ final class DelegateRequestRepresentation extends RequestRepresentation { ? delegateExpression.castTo(contributedType) : delegateExpression; default: - return castToRawTypeIfNecessary( - delegateExpression, requestType(requestKind, contributedType, processingEnv)); + XType requestedType = requestType(requestKind, contributedType, processingEnv); + if (XTypes.isTypeOf(requestedType, TypeNames.PROVIDER)) { + // Even though the user may have requested a javax Provider, our generated code and + // factories only work in the Dagger Provider type, so swap to that one before doing + // a cast. + requestedType = XTypes.rewrapType(requestedType, TypeNames.DAGGER_PROVIDER); + } + return castToRawTypeIfNecessary(delegateExpression, requestedType); } } diff --git a/java/dagger/internal/codegen/writing/DependencyMethodProviderCreationExpression.java b/java/dagger/internal/codegen/writing/DependencyMethodProviderCreationExpression.java index 49cc024e9..c54b03cc4 100644 --- a/java/dagger/internal/codegen/writing/DependencyMethodProviderCreationExpression.java +++ b/java/dagger/internal/codegen/writing/DependencyMethodProviderCreationExpression.java @@ -24,7 +24,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.squareup.javapoet.MethodSpec.constructorBuilder; import static com.squareup.javapoet.MethodSpec.methodBuilder; import static com.squareup.javapoet.TypeSpec.classBuilder; -import static dagger.internal.codegen.javapoet.TypeNames.providerOf; +import static dagger.internal.codegen.javapoet.TypeNames.daggerProviderOf; import static dagger.internal.codegen.writing.ComponentImplementation.TypeSpecKind.COMPONENT_PROVISION_FACTORY; import static dagger.internal.codegen.xprocessing.XElements.asMethod; import static dagger.internal.codegen.xprocessing.XElements.getSimpleName; @@ -47,7 +47,6 @@ import dagger.internal.codegen.binding.ProvisionBinding; import dagger.internal.codegen.compileroption.CompilerOptions; import dagger.internal.codegen.writing.ComponentImplementation.ShardImplementation; import dagger.internal.codegen.writing.FrameworkFieldInitializer.FrameworkInstanceCreationExpression; -import dagger.internal.codegen.xprocessing.XAnnotations; /** * A {@link javax.inject.Provider} creation expression for a provision method on a component's @@ -106,9 +105,8 @@ final class DependencyMethodProviderCreationExpression binding .nullability() - .nullableAnnotation() - .map(XAnnotations::getClassName) - .ifPresent(getMethod::addAnnotation); + .nullableAnnotations() + .forEach(getMethod::addAnnotation); // We need to use the componentShard here since the generated type is static and shards are // not static classes so it can't be nested inside the shard. @@ -123,7 +121,7 @@ final class DependencyMethodProviderCreationExpression componentShard.addType( COMPONENT_PROVISION_FACTORY, classBuilder(factoryClassName) - .addSuperinterface(providerOf(keyType)) + .addSuperinterface(daggerProviderOf(keyType)) .addModifiers(PRIVATE, STATIC, FINAL) .addField(dependencyClassName, dependency().variableName(), PRIVATE, FINAL) .addMethod( diff --git a/java/dagger/internal/codegen/writing/DerivedFromFrameworkInstanceRequestRepresentation.java b/java/dagger/internal/codegen/writing/DerivedFromFrameworkInstanceRequestRepresentation.java index 4095a600d..f054e6a7e 100644 --- a/java/dagger/internal/codegen/writing/DerivedFromFrameworkInstanceRequestRepresentation.java +++ b/java/dagger/internal/codegen/writing/DerivedFromFrameworkInstanceRequestRepresentation.java @@ -24,11 +24,13 @@ import com.squareup.javapoet.ClassName; import dagger.assisted.Assisted; import dagger.assisted.AssistedFactory; import dagger.assisted.AssistedInject; +import dagger.internal.codegen.base.MapType; import dagger.internal.codegen.binding.BindsTypeChecker; import dagger.internal.codegen.binding.ComponentDescriptor.ComponentMethodDescriptor; import dagger.internal.codegen.binding.ContributionBinding; import dagger.internal.codegen.binding.FrameworkType; import dagger.internal.codegen.javapoet.Expression; +import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.BindingKind; import dagger.internal.codegen.model.RequestKind; @@ -59,30 +61,61 @@ final class DerivedFromFrameworkInstanceRequestRepresentation extends RequestRep @Override Expression getDependencyExpression(ClassName requestingClass) { - Expression expression = - frameworkType.to( - requestKind, - frameworkRequestRepresentation.getDependencyExpression(requestingClass), - processingEnv); - return requiresTypeCast(expression, requestingClass) - ? expression.castTo(binding.contributedType()) - : expression; + return getDependencyExpressionFromFrameworkExpression( + frameworkRequestRepresentation.getDependencyExpression(requestingClass), + requestingClass); } @Override Expression getDependencyExpressionForComponentMethod( ComponentMethodDescriptor componentMethod, ComponentImplementation component) { + return getDependencyExpressionFromFrameworkExpression( + frameworkRequestRepresentation + .getDependencyExpressionForComponentMethod(componentMethod, component), + component.name()); + } + + private Expression getDependencyExpressionFromFrameworkExpression( + Expression frameworkExpression, ClassName requestingClass) { Expression expression = frameworkType.to( requestKind, - frameworkRequestRepresentation.getDependencyExpressionForComponentMethod( - componentMethod, component), + frameworkExpression, processingEnv); - return requiresTypeCast(expression, component.name()) + + // If it is a map type we need to do a raw type cast. This is because a user requested field + // type like dagger.internal.Provider<Map<K, javax.inject.Provider<V>>> isn't always assignable + // from something like dagger.internal.Provider<Map<K, dagger.internal.Provider<V>>> just due + // to variance issues. + if (MapType.isMapOfProvider(binding.contributedType())) { + return castMapOfProvider(expression, binding); + } + + return requiresTypeCast(expression, requestingClass) ? expression.castTo(binding.contributedType()) : expression; } + private Expression castMapOfProvider(Expression expression, ContributionBinding binding) { + switch (requestKind) { + case INSTANCE: + return expression.castTo(binding.contributedType()); + case PROVIDER: + case PROVIDER_OF_LAZY: + return expression.castTo(processingEnv.requireType(TypeNames.DAGGER_PROVIDER).getRawType()); + case LAZY: + return expression.castTo(processingEnv.requireType(TypeNames.LAZY).getRawType()); + case PRODUCER: + case FUTURE: + return expression.castTo(processingEnv.requireType(TypeNames.PRODUCER).getRawType()); + case PRODUCED: + return expression.castTo(processingEnv.requireType(TypeNames.PRODUCED).getRawType()); + + case MEMBERS_INJECTION: // fall through + } + throw new IllegalStateException("Unexpected request kind: " + requestKind); + } + private boolean requiresTypeCast(Expression expression, ClassName requestingClass) { return binding.kind().equals(BindingKind.DELEGATE) && requestKind.equals(RequestKind.INSTANCE) diff --git a/java/dagger/internal/codegen/writing/ExperimentalSwitchingProviderDependencyRepresentation.java b/java/dagger/internal/codegen/writing/ExperimentalSwitchingProviderDependencyRepresentation.java deleted file mode 100644 index 1ebbb240b..000000000 --- a/java/dagger/internal/codegen/writing/ExperimentalSwitchingProviderDependencyRepresentation.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (C) 2021 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.internal.codegen.writing; - -import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; -import static dagger.internal.codegen.langmodel.Accessibility.isRawTypeAccessible; -import static dagger.internal.codegen.langmodel.Accessibility.isTypeAccessibleFrom; -import static dagger.internal.codegen.xprocessing.XTypes.rewrapType; - -import androidx.room.compiler.processing.XProcessingEnv; -import androidx.room.compiler.processing.XType; -import com.squareup.javapoet.CodeBlock; -import dagger.assisted.Assisted; -import dagger.assisted.AssistedFactory; -import dagger.assisted.AssistedInject; -import dagger.internal.codegen.base.ContributionType; -import dagger.internal.codegen.binding.BindsTypeChecker; -import dagger.internal.codegen.binding.FrameworkType; -import dagger.internal.codegen.binding.ProvisionBinding; -import dagger.internal.codegen.javapoet.Expression; -import dagger.internal.codegen.javapoet.TypeNames; -import dagger.internal.codegen.model.BindingKind; -import dagger.internal.codegen.model.DependencyRequest; -import dagger.internal.codegen.model.RequestKind; -import dagger.internal.codegen.writing.ComponentImplementation.ShardImplementation; - -/** - * Returns type casted expressions to satisfy dependency requests from experimental switching - * providers. - */ -final class ExperimentalSwitchingProviderDependencyRepresentation { - private final ProvisionBinding binding; - private final ShardImplementation shardImplementation; - private final BindsTypeChecker bindsTypeChecker; - private final XProcessingEnv processingEnv; - private final XType type; - - @AssistedInject - ExperimentalSwitchingProviderDependencyRepresentation( - @Assisted ProvisionBinding binding, - ComponentImplementation componentImplementation, - BindsTypeChecker bindsTypeChecker, - XProcessingEnv processingEnv) { - this.binding = binding; - this.shardImplementation = componentImplementation.shardImplementation(binding); - this.processingEnv = processingEnv; - this.bindsTypeChecker = bindsTypeChecker; - this.type = - isDelegateSetValuesBinding() - // For convience we allow @Binds @ElementsIntoSet from Collection => Set so that List - // can be contributed without converting to a Set first. Thus, here we rewrap the - // contributed type from Set<T> => Collection<T> to reflect this. - ? rewrapType(binding.contributedType(), TypeNames.COLLECTION) - : binding.contributedType(); - } - - Expression getDependencyExpression(RequestKind requestKind, ProvisionBinding requestingBinding) { - int index = findIndexOfDependency(requestingBinding); - XType frameworkType = - processingEnv.getDeclaredType( - processingEnv.requireTypeElement(FrameworkType.PROVIDER.frameworkClassName())); - Expression expression = - FrameworkType.PROVIDER.to( - requestKind, - Expression.create( - frameworkType, - CodeBlock.of( - "(($T) dependencies[$L])", frameworkType.getRawType().getTypeName(), index)), - processingEnv); - if (usesExplicitTypeCast(expression, requestKind)) { - return expression.castTo(type); - } - if (usesRawTypeCast(requestKind)) { - return expression.castTo(type.getRawType()); - } - return expression; - } - - private int findIndexOfDependency(ProvisionBinding requestingBinding) { - return requestingBinding.dependencies().stream() - .map(DependencyRequest::key) - .collect(toImmutableList()) - .indexOf(binding.key()) - + (requestingBinding.requiresModuleInstance() - && requestingBinding.contributingModule().isPresent() - ? 1 - : 0); - } - - private boolean isDelegateSetValuesBinding() { - return binding.kind().equals(BindingKind.DELEGATE) - && binding.contributionType().equals(ContributionType.SET_VALUES); - } - - private boolean usesExplicitTypeCast(Expression expression, RequestKind requestKind) { - // If the type is accessible, we can directly cast the expression use the type. - return requestKind.equals(RequestKind.INSTANCE) - && !bindsTypeChecker.isAssignable(expression.type(), type, binding.contributionType()) - && isTypeAccessibleFrom(type, shardImplementation.name().packageName()); - } - - private boolean usesRawTypeCast(RequestKind requestKind) { - // If a type has inaccessible type arguments, then cast to raw type. - return requestKind.equals(RequestKind.INSTANCE) - && !isTypeAccessibleFrom(type, shardImplementation.name().packageName()) - && isRawTypeAccessible(type, shardImplementation.name().packageName()); - } - - @AssistedFactory - static interface Factory { - ExperimentalSwitchingProviderDependencyRepresentation create(ProvisionBinding binding); - } -} diff --git a/java/dagger/internal/codegen/writing/ExperimentalSwitchingProviders.java b/java/dagger/internal/codegen/writing/ExperimentalSwitchingProviders.java deleted file mode 100644 index 586b5f53b..000000000 --- a/java/dagger/internal/codegen/writing/ExperimentalSwitchingProviders.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright (C) 2022 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.internal.codegen.writing; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.Iterables.getLast; -import static com.google.common.collect.Iterables.getOnlyElement; -import static com.squareup.javapoet.MethodSpec.methodBuilder; -import static com.squareup.javapoet.TypeSpec.classBuilder; -import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; -import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.UNCHECKED; -import static dagger.internal.codegen.javapoet.AnnotationSpecs.suppressWarnings; -import static dagger.internal.codegen.javapoet.TypeNames.providerOf; -import static javax.lang.model.element.Modifier.FINAL; -import static javax.lang.model.element.Modifier.PRIVATE; -import static javax.lang.model.element.Modifier.PUBLIC; -import static javax.lang.model.element.Modifier.STATIC; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import com.squareup.javapoet.ClassName; -import com.squareup.javapoet.CodeBlock; -import com.squareup.javapoet.MethodSpec; -import com.squareup.javapoet.TypeName; -import com.squareup.javapoet.TypeSpec; -import com.squareup.javapoet.TypeVariableName; -import dagger.internal.codegen.binding.ProvisionBinding; -import dagger.internal.codegen.javapoet.CodeBlocks; -import dagger.internal.codegen.model.Key; -import dagger.internal.codegen.writing.ComponentImplementation.ShardImplementation; -import dagger.internal.codegen.writing.FrameworkFieldInitializer.FrameworkInstanceCreationExpression; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.TreeMap; -import javax.inject.Provider; - -/** - * Keeps track of all provider expression requests for a component. - * - * <p>The provider expression request will be satisfied by a single generated {@code Provider} class - * that can provide instances for all types by switching on an id. - */ -final class ExperimentalSwitchingProviders { - /** - * Each switch size is fixed at 100 cases each and put in its own method. This is to limit the - * size of the methods so that we don't reach the "huge" method size limit for Android that will - * prevent it from being AOT compiled in some versions of Android (b/77652521). This generally - * starts to happen around 1500 cases, but we are choosing 100 to be safe. - */ - // TODO(bcorso): Include a proguard_spec in the Dagger library to prevent inlining these methods? - // TODO(ronshapiro): Consider making this configurable via a flag. - private static final int MAX_CASES_PER_SWITCH = 100; - - private static final long MAX_CASES_PER_CLASS = MAX_CASES_PER_SWITCH * MAX_CASES_PER_SWITCH; - private static final TypeVariableName T = TypeVariableName.get("T"); - - /** - * Maps a {@link Key} to an instance of a {@link SwitchingProviderBuilder}. Each group of {@code - * MAX_CASES_PER_CLASS} keys will share the same instance. - */ - private final Map<Key, SwitchingProviderBuilder> switchingProviderBuilders = - new LinkedHashMap<>(); - - private final ShardImplementation shardImplementation; - private final Provider<ComponentRequestRepresentations> componentRequestRepresentationsProvider; - - ExperimentalSwitchingProviders( - ShardImplementation shardImplementation, - Provider<ComponentRequestRepresentations> componentRequestRepresentationsProvider) { - this.shardImplementation = checkNotNull(shardImplementation); - this.componentRequestRepresentationsProvider = - checkNotNull(componentRequestRepresentationsProvider); - } - - /** Returns the framework instance creation expression for an inner switching provider class. */ - FrameworkInstanceCreationExpression newFrameworkInstanceCreationExpression( - ProvisionBinding binding, RequestRepresentation unscopedInstanceRequestRepresentation) { - return new FrameworkInstanceCreationExpression() { - @Override - public CodeBlock creationExpression() { - return switchingProviderBuilders - .computeIfAbsent(binding.key(), key -> getSwitchingProviderBuilder()) - .getNewInstanceCodeBlock(binding, unscopedInstanceRequestRepresentation); - } - }; - } - - private SwitchingProviderBuilder getSwitchingProviderBuilder() { - if (switchingProviderBuilders.size() % MAX_CASES_PER_CLASS == 0) { - String name = shardImplementation.getUniqueClassName("SwitchingProvider"); - // TODO(wanyingd): move Switching Providers and injection methods to Shard classes to avoid - // exceeding component class constant pool limit. - SwitchingProviderBuilder switchingProviderBuilder = - new SwitchingProviderBuilder(shardImplementation.name().nestedClass(name)); - shardImplementation.addTypeSupplier(switchingProviderBuilder::build); - return switchingProviderBuilder; - } - return getLast(switchingProviderBuilders.values()); - } - - // TODO(bcorso): Consider just merging this class with ExperimentalSwitchingProviders. - private final class SwitchingProviderBuilder { - // Keep the switch cases ordered by switch id. The switch Ids are assigned in pre-order - // traversal, but the switch cases are assigned in post-order traversal of the binding graph. - private final Map<Integer, CodeBlock> switchCases = new TreeMap<>(); - private final Map<Key, Integer> switchIds = new HashMap<>(); - private final ClassName switchingProviderType; - - SwitchingProviderBuilder(ClassName switchingProviderType) { - this.switchingProviderType = checkNotNull(switchingProviderType); - } - - private CodeBlock getNewInstanceCodeBlock( - ProvisionBinding binding, RequestRepresentation unscopedInstanceRequestRepresentation) { - Key key = binding.key(); - if (!switchIds.containsKey(key)) { - int switchId = switchIds.size(); - switchIds.put(key, switchId); - switchCases.put( - switchId, createSwitchCaseCodeBlock(key, unscopedInstanceRequestRepresentation)); - } - - CodeBlock switchingProviderDependencies; - switch (binding.kind()) { - // TODO(wanyingd): there might be a better way to get component requirement information - // without using unscopedInstanceRequestRepresentation. - case COMPONENT_PROVISION: - switchingProviderDependencies = - ((ComponentProvisionRequestRepresentation) unscopedInstanceRequestRepresentation) - .getComponentRequirementExpression(shardImplementation.name()); - break; - case SUBCOMPONENT_CREATOR: - switchingProviderDependencies = - ((SubcomponentCreatorRequestRepresentation) unscopedInstanceRequestRepresentation) - .getDependencyExpressionArguments(); - break; - case MULTIBOUND_SET: - case MULTIBOUND_MAP: - case OPTIONAL: - case INJECTION: - case PROVISION: - case ASSISTED_FACTORY: - // Arguments built in the order of module reference, provision dependencies and members - // injection dependencies - switchingProviderDependencies = - componentRequestRepresentationsProvider.get().getCreateMethodArgumentsCodeBlock( - binding, shardImplementation.name()); - break; - default: - throw new IllegalArgumentException("Unexpected binding kind: " + binding.kind()); - } - - return CodeBlock.of( - "new $T<$L>($L)", - switchingProviderType, - // Add the type parameter explicitly when the binding is scoped because Java can't resolve - // the type when wrapped. For example, the following will error: - // fooProvider = DoubleCheck.provider(new SwitchingProvider<>(1)); - CodeBlock.of("$T", shardImplementation.accessibleTypeName(binding.contributedType())), - switchingProviderDependencies.isEmpty() - ? CodeBlock.of("$L", switchIds.get(key)) - : CodeBlock.of("$L, $L", switchIds.get(key), switchingProviderDependencies)); - } - - private CodeBlock createSwitchCaseCodeBlock( - Key key, RequestRepresentation unscopedInstanceRequestRepresentation) { - // TODO(bcorso): Try to delay calling getDependencyExpression() until we are writing out the - // SwitchingProvider because calling it here makes FrameworkFieldInitializer think there's a - // cycle when initializing ExperimentalSwitchingProviders which adds an unnecessary - // DelegateFactory. - CodeBlock instanceCodeBlock = - unscopedInstanceRequestRepresentation - .getDependencyExpression(switchingProviderType) - .box() - .codeBlock(); - - return CodeBlock.builder() - // TODO(bcorso): Is there something else more useful than the key? - .add("case $L: // $L \n", switchIds.get(key), key) - .addStatement("return ($T) $L", T, instanceCodeBlock) - .build(); - } - - private TypeSpec build() { - TypeSpec.Builder builder = - classBuilder(switchingProviderType) - .addModifiers(PRIVATE, FINAL, STATIC) - .addTypeVariable(T) - .addSuperinterface(providerOf(T)) - .addMethods(getMethods()); - - // The SwitchingProvider constructor lists switch id first and then the dependency array. - MethodSpec.Builder constructor = MethodSpec.constructorBuilder(); - builder.addField(TypeName.INT, "id", PRIVATE, FINAL); - constructor.addParameter(TypeName.INT, "id").addStatement("this.id = id"); - // Pass in provision dependencies and members injection dependencies. - builder.addField(Object[].class, "dependencies", FINAL, PRIVATE); - constructor - .addParameter(Object[].class, "dependencies") - .addStatement("this.dependencies = dependencies") - .varargs(true); - - return builder.addMethod(constructor.build()).build(); - } - - private ImmutableList<MethodSpec> getMethods() { - ImmutableList<CodeBlock> switchCodeBlockPartitions = switchCodeBlockPartitions(); - if (switchCodeBlockPartitions.size() == 1) { - // There are less than MAX_CASES_PER_SWITCH cases, so no need for extra get methods. - return ImmutableList.of( - methodBuilder("get") - .addModifiers(PUBLIC) - .addAnnotation(suppressWarnings(UNCHECKED)) - .addAnnotation(Override.class) - .returns(T) - .addCode(getOnlyElement(switchCodeBlockPartitions)) - .build()); - } - - // This is the main public "get" method that will route to private getter methods. - MethodSpec.Builder routerMethod = - methodBuilder("get") - .addModifiers(PUBLIC) - .addAnnotation(Override.class) - .returns(T) - .beginControlFlow("switch (id / $L)", MAX_CASES_PER_SWITCH); - - ImmutableList.Builder<MethodSpec> getMethods = ImmutableList.builder(); - for (int i = 0; i < switchCodeBlockPartitions.size(); i++) { - MethodSpec method = - methodBuilder("get" + i) - .addModifiers(PRIVATE) - .addAnnotation(suppressWarnings(UNCHECKED)) - .returns(T) - .addCode(switchCodeBlockPartitions.get(i)) - .build(); - getMethods.add(method); - routerMethod.addStatement("case $L: return $N()", i, method); - } - - routerMethod.addStatement("default: throw new $T(id)", AssertionError.class).endControlFlow(); - - return getMethods.add(routerMethod.build()).build(); - } - - private ImmutableList<CodeBlock> switchCodeBlockPartitions() { - return Lists.partition(ImmutableList.copyOf(switchCases.values()), MAX_CASES_PER_SWITCH) - .stream() - .map( - partitionCases -> - CodeBlock.builder() - .beginControlFlow("switch (id)") - .add(CodeBlocks.concat(partitionCases)) - .addStatement("default: throw new $T(id)", AssertionError.class) - .endControlFlow() - .build()) - .collect(toImmutableList()); - } - } -} diff --git a/java/dagger/internal/codegen/writing/FactoryGenerator.java b/java/dagger/internal/codegen/writing/FactoryGenerator.java index 9ec13146d..32195ba6a 100644 --- a/java/dagger/internal/codegen/writing/FactoryGenerator.java +++ b/java/dagger/internal/codegen/writing/FactoryGenerator.java @@ -35,16 +35,15 @@ import static dagger.internal.codegen.javapoet.TypeNames.factoryOf; import static dagger.internal.codegen.model.BindingKind.INJECTION; import static dagger.internal.codegen.model.BindingKind.PROVISION; import static dagger.internal.codegen.writing.GwtCompatibility.gwtIncompatibleAnnotation; -import static dagger.internal.codegen.xprocessing.XElements.getSimpleName; import static javax.lang.model.element.Modifier.FINAL; import static javax.lang.model.element.Modifier.PRIVATE; import static javax.lang.model.element.Modifier.PUBLIC; import static javax.lang.model.element.Modifier.STATIC; import androidx.room.compiler.processing.XElement; +import androidx.room.compiler.processing.XExecutableParameterElement; import androidx.room.compiler.processing.XFiler; import androidx.room.compiler.processing.XProcessingEnv; -import androidx.room.compiler.processing.XVariableElement; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; @@ -71,7 +70,6 @@ import dagger.internal.codegen.model.Key; import dagger.internal.codegen.model.Scope; import dagger.internal.codegen.writing.InjectionMethods.InjectionSiteMethod; import dagger.internal.codegen.writing.InjectionMethods.ProvisionMethod; -import dagger.internal.codegen.xprocessing.XAnnotations; import java.util.List; import java.util.Optional; import java.util.stream.Stream; @@ -236,7 +234,7 @@ public final class FactoryGenerator extends SourceFileGenerator<ProvisionBinding UniqueNameSet uniqueFieldNames = new UniqueNameSet(); ImmutableMap<DependencyRequest, FieldSpec> frameworkFields = frameworkFields(binding); frameworkFields.values().forEach(field -> uniqueFieldNames.claim(field.name)); - ImmutableMap<XVariableElement, ParameterSpec> assistedParameters = + ImmutableMap<XExecutableParameterElement, ParameterSpec> assistedParameters = assistedParameters(binding).stream() .collect( toImmutableMap( @@ -244,13 +242,12 @@ public final class FactoryGenerator extends SourceFileGenerator<ProvisionBinding parameter -> ParameterSpec.builder( parameter.getType().getTypeName(), - uniqueFieldNames.getUniqueName(getSimpleName(parameter))) + uniqueFieldNames.getUniqueName(parameter.getJvmName())) .build())); TypeName providedTypeName = providedTypeName(binding); MethodSpec.Builder getMethod = methodBuilder("get") .addModifiers(PUBLIC) - .returns(providedTypeName) .addParameters(assistedParameters.values()); if (factoryTypeName(binding).isPresent()) { @@ -270,13 +267,14 @@ public final class FactoryGenerator extends SourceFileGenerator<ProvisionBinding if (binding.kind().equals(PROVISION)) { binding .nullability() - .nullableAnnotation() - .map(XAnnotations::getClassName) - .ifPresent(getMethod::addAnnotation); + .nullableAnnotations() + .forEach(getMethod::addAnnotation); + getMethod.returns(providedTypeName); getMethod.addStatement("return $L", invokeNewInstance); } else if (!binding.injectionSites().isEmpty()) { CodeBlock instance = CodeBlock.of("instance"); getMethod + .returns(providedTypeName) .addStatement("$T $L = $L", providedTypeName, instance, invokeNewInstance) .addCode( InjectionSiteMethod.invokeAll( @@ -286,8 +284,11 @@ public final class FactoryGenerator extends SourceFileGenerator<ProvisionBinding binding.key().type().xprocessing(), sourceFiles.frameworkFieldUsages(binding.dependencies(), frameworkFields)::get)) .addStatement("return $L", instance); + } else { - getMethod.addStatement("return $L", invokeNewInstance); + getMethod + .returns(providedTypeName) + .addStatement("return $L", invokeNewInstance); } return getMethod.build(); } diff --git a/java/dagger/internal/codegen/writing/FrameworkFieldInitializer.java b/java/dagger/internal/codegen/writing/FrameworkFieldInitializer.java index 5a981773e..32f0dde04 100644 --- a/java/dagger/internal/codegen/writing/FrameworkFieldInitializer.java +++ b/java/dagger/internal/codegen/writing/FrameworkFieldInitializer.java @@ -142,8 +142,9 @@ class FrameworkFieldInitializer implements FrameworkInstanceSupplier { FrameworkField.forBinding( binding, frameworkInstanceCreationExpression.alternativeFrameworkClass()); - TypeName fieldType = - useRawType ? contributionBindingField.type().rawType : contributionBindingField.type(); + TypeName fieldType = useRawType + ? TypeNames.rawTypeName(contributionBindingField.type()) + : contributionBindingField.type(); if (binding.kind() == BindingKind.ASSISTED_INJECTION) { // An assisted injection factory doesn't extend Provider, so we reference the generated diff --git a/java/dagger/internal/codegen/writing/FrameworkInstanceBindingRepresentation.java b/java/dagger/internal/codegen/writing/FrameworkInstanceBindingRepresentation.java index bb62d52fe..037df56d6 100644 --- a/java/dagger/internal/codegen/writing/FrameworkInstanceBindingRepresentation.java +++ b/java/dagger/internal/codegen/writing/FrameworkInstanceBindingRepresentation.java @@ -47,7 +47,6 @@ final class FrameworkInstanceBindingRepresentation { FrameworkInstanceBindingRepresentation( @Assisted ProvisionBinding binding, BindingGraph graph, - @Assisted FrameworkInstanceSupplier providerField, ComponentImplementation componentImplementation, DelegateRequestRepresentation.Factory delegateRequestRepresentationFactory, DerivedFromFrameworkInstanceRequestRepresentation.Factory @@ -65,7 +64,7 @@ final class FrameworkInstanceBindingRepresentation { this.providerRequestRepresentation = binding.kind().equals(DELEGATE) && !needsCaching(binding, graph) ? delegateRequestRepresentationFactory.create(binding, RequestKind.PROVIDER) - : providerInstanceRequestRepresentationFactory.create(binding, providerField); + : providerInstanceRequestRepresentationFactory.create(binding); this.producerFromProviderRepresentation = producerNodeInstanceRequestRepresentationFactory.create( binding, @@ -108,7 +107,6 @@ final class FrameworkInstanceBindingRepresentation { @AssistedFactory static interface Factory { - FrameworkInstanceBindingRepresentation create( - ProvisionBinding binding, FrameworkInstanceSupplier providerField); + FrameworkInstanceBindingRepresentation create(ProvisionBinding binding); } } diff --git a/java/dagger/internal/codegen/writing/FrameworkInstanceKind.java b/java/dagger/internal/codegen/writing/FrameworkInstanceKind.java index 1353e887f..8e9d4c67d 100644 --- a/java/dagger/internal/codegen/writing/FrameworkInstanceKind.java +++ b/java/dagger/internal/codegen/writing/FrameworkInstanceKind.java @@ -19,21 +19,17 @@ package dagger.internal.codegen.writing; import static dagger.internal.codegen.model.BindingKind.DELEGATE; import dagger.internal.codegen.binding.ContributionBinding; -import dagger.internal.codegen.model.BindingKind; import dagger.internal.codegen.writing.ComponentImplementation.CompilerMode; /** Generation mode for satisfying framework request to Provision Binding. */ enum FrameworkInstanceKind { SWITCHING_PROVIDER, - EXPERIMENTAL_SWITCHING_PROVIDER, STATIC_FACTORY, PROVIDER_FIELD; public static FrameworkInstanceKind from(ContributionBinding binding, CompilerMode compilerMode) { if (usesSwitchingProvider(binding, compilerMode)) { - if (compilerMode.isExperimentalMergedMode()) { - return EXPERIMENTAL_SWITCHING_PROVIDER; - } else if (compilerMode.isFastInit()) { + if (compilerMode.isFastInit()) { return SWITCHING_PROVIDER; } else { throw new IllegalStateException( @@ -48,12 +44,7 @@ enum FrameworkInstanceKind { private static boolean usesSwitchingProvider( ContributionBinding binding, CompilerMode compilerMode) { - if (!compilerMode.isFastInit() && !compilerMode.isExperimentalMergedMode()) { - return false; - } - // TODO(wanyingd): remove this check once we allow inaccessible types in merged mode. - if (compilerMode.isExperimentalMergedMode() - && binding.kind().equals(BindingKind.ASSISTED_FACTORY)) { + if (!compilerMode.isFastInit()) { return false; } switch (binding.kind()) { @@ -100,10 +91,9 @@ enum FrameworkInstanceKind { return true; case PROVISION: return !compilerMode.isFastInit() - && !compilerMode.isExperimentalMergedMode() && !binding.requiresModuleInstance(); case INJECTION: - return !compilerMode.isFastInit() && !compilerMode.isExperimentalMergedMode(); + return !compilerMode.isFastInit(); default: return false; } diff --git a/java/dagger/internal/codegen/writing/HjarSourceFileGenerator.java b/java/dagger/internal/codegen/writing/HjarSourceFileGenerator.java deleted file mode 100644 index 4bafb5aff..000000000 --- a/java/dagger/internal/codegen/writing/HjarSourceFileGenerator.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2017 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.internal.codegen.writing; - -import static com.squareup.javapoet.MethodSpec.constructorBuilder; -import static com.squareup.javapoet.MethodSpec.methodBuilder; -import static com.squareup.javapoet.TypeSpec.classBuilder; -import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; -import static javax.lang.model.element.Modifier.PRIVATE; - -import androidx.room.compiler.processing.XElement; -import com.google.common.collect.ImmutableList; -import com.squareup.javapoet.ClassName; -import com.squareup.javapoet.FieldSpec; -import com.squareup.javapoet.MethodSpec; -import com.squareup.javapoet.TypeSpec; -import dagger.internal.codegen.base.SourceFileGenerator; -import javax.lang.model.element.Modifier; - -/** - * A source file generator that only writes the relevant code necessary for Bazel to create a - * correct header (ABI) jar. - */ -public final class HjarSourceFileGenerator<T> extends SourceFileGenerator<T> { - private final SourceFileGenerator<T> delegate; - - private HjarSourceFileGenerator(SourceFileGenerator<T> delegate) { - super(delegate); - this.delegate = delegate; - } - - public static <T> SourceFileGenerator<T> wrap(SourceFileGenerator<T> delegate) { - return new HjarSourceFileGenerator<>(delegate); - } - - @Override - public XElement originatingElement(T input) { - return delegate.originatingElement(input); - } - - @Override - public ImmutableList<TypeSpec.Builder> topLevelTypes(T input) { - return delegate.topLevelTypes(input).stream() - .map(completeType -> skeletonType(completeType.build())) - .collect(toImmutableList()); - } - - private TypeSpec.Builder skeletonType(TypeSpec completeType) { - TypeSpec.Builder skeleton = - classBuilder(completeType.name) - .addSuperinterfaces(completeType.superinterfaces) - .addTypeVariables(completeType.typeVariables) - .addModifiers(completeType.modifiers.toArray(new Modifier[0])) - .addAnnotations(completeType.annotations); - - if (!completeType.superclass.equals(ClassName.OBJECT)) { - skeleton.superclass(completeType.superclass); - } - - completeType.methodSpecs.stream() - .filter(method -> !method.modifiers.contains(PRIVATE) || method.isConstructor()) - .map(this::skeletonMethod) - .forEach(skeleton::addMethod); - - completeType.fieldSpecs.stream() - .filter(field -> !field.modifiers.contains(PRIVATE)) - .map(this::skeletonField) - .forEach(skeleton::addField); - - completeType.typeSpecs.stream() - .map(type -> skeletonType(type).build()) - .forEach(skeleton::addType); - - return skeleton; - } - - private MethodSpec skeletonMethod(MethodSpec completeMethod) { - MethodSpec.Builder skeleton = - completeMethod.isConstructor() - ? constructorBuilder() - : methodBuilder(completeMethod.name).returns(completeMethod.returnType); - - if (completeMethod.isConstructor()) { - // Code in Turbine must (for technical reasons in javac) have a valid super() call for - // constructors, otherwise javac will bark, and Turbine has no way to avoid this. So we retain - // constructor method bodies if they do exist - skeleton.addCode(completeMethod.code); - } - - return skeleton - .addModifiers(completeMethod.modifiers) - .addTypeVariables(completeMethod.typeVariables) - .addParameters(completeMethod.parameters) - .addExceptions(completeMethod.exceptions) - .varargs(completeMethod.varargs) - .addAnnotations(completeMethod.annotations) - .build(); - } - - private FieldSpec skeletonField(FieldSpec completeField) { - return FieldSpec.builder( - completeField.type, - completeField.name, - completeField.modifiers.toArray(new Modifier[0])) - .addAnnotations(completeField.annotations) - .build(); - } -} diff --git a/java/dagger/internal/codegen/writing/InaccessibleMapKeyProxyGenerator.java b/java/dagger/internal/codegen/writing/InaccessibleMapKeyProxyGenerator.java index e43d8446d..3eaf92db0 100644 --- a/java/dagger/internal/codegen/writing/InaccessibleMapKeyProxyGenerator.java +++ b/java/dagger/internal/codegen/writing/InaccessibleMapKeyProxyGenerator.java @@ -26,10 +26,13 @@ import androidx.room.compiler.processing.XElement; import androidx.room.compiler.processing.XFiler; import androidx.room.compiler.processing.XProcessingEnv; import com.google.common.collect.ImmutableList; +import com.squareup.javapoet.FieldSpec; 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.javapoet.TypeNames; +import dagger.internal.codegen.model.DaggerAnnotation; import javax.inject.Inject; /** @@ -56,11 +59,31 @@ public final class InaccessibleMapKeyProxyGenerator public ImmutableList<TypeSpec.Builder> topLevelTypes(ContributionBinding binding) { return MapKeys.mapKeyFactoryMethod(binding, processingEnv) .map( - method -> - classBuilder(MapKeys.mapKeyProxyClassName(binding)) - .addModifiers(PUBLIC, FINAL) - .addMethod(constructorBuilder().addModifiers(PRIVATE).build()) - .addMethod(method)) + method -> { + TypeSpec.Builder builder = + classBuilder(MapKeys.mapKeyProxyClassName(binding)) + .addModifiers(PUBLIC, FINAL) + .addMethod(constructorBuilder().addModifiers(PRIVATE).build()) + .addMethod(method); + // In proguard, we need to keep the classes referenced by @LazyClassKey, we do that by + // generating a field referencing the type, and then applying @KeepFieldType to the + // field. Here, we generate the field in the proxy class. For classes that are + // accessible from the dagger component, we generate fields in LazyClassKeyProvider. + // Note: the generated field should not be initialized to avoid class loading. + binding + .mapKey() + .map(DaggerAnnotation::xprocessing) + .filter( + mapKey -> + mapKey.getTypeElement().getClassName().equals(TypeNames.LAZY_CLASS_KEY)) + .map( + mapKey -> + FieldSpec.builder(mapKey.getAsType("value").getTypeName(), "className") + .addAnnotation(TypeNames.KEEP_FIELD_TYPE) + .build()) + .ifPresent(builder::addField); + return builder; + }) .map(ImmutableList::of) .orElse(ImmutableList.of()); } diff --git a/java/dagger/internal/codegen/writing/InjectionMethods.java b/java/dagger/internal/codegen/writing/InjectionMethods.java index 75b950aa3..39c03dd7f 100644 --- a/java/dagger/internal/codegen/writing/InjectionMethods.java +++ b/java/dagger/internal/codegen/writing/InjectionMethods.java @@ -18,6 +18,7 @@ package dagger.internal.codegen.writing; import static androidx.room.compiler.processing.XElementKt.isConstructor; import static androidx.room.compiler.processing.XElementKt.isMethod; +import static androidx.room.compiler.processing.XElementKt.isMethodParameter; import static androidx.room.compiler.processing.XTypeKt.isVoid; import static com.google.common.base.CaseFormat.LOWER_CAMEL; import static com.google.common.base.CaseFormat.UPPER_CAMEL; @@ -27,7 +28,6 @@ import static dagger.internal.codegen.binding.AssistedInjectionAnnotations.isAss import static dagger.internal.codegen.binding.SourceFiles.generatedClassNameForBinding; import static dagger.internal.codegen.binding.SourceFiles.memberInjectedFieldSignatureForVariable; import static dagger.internal.codegen.binding.SourceFiles.membersInjectorNameForType; -import static dagger.internal.codegen.binding.SourceFiles.protectAgainstKeywords; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableMap; import static dagger.internal.codegen.javapoet.CodeBlocks.makeParametersCodeBlock; @@ -81,7 +81,6 @@ import dagger.internal.codegen.xprocessing.XAnnotations; import java.util.List; import java.util.Optional; import java.util.function.Function; -import javax.lang.model.SourceVersion; /** Convenience methods for creating and invoking {@link InjectionMethod}s. */ final class InjectionMethods { @@ -145,7 +144,7 @@ final class InjectionMethods { static CodeBlock invoke( ProvisionBinding binding, Function<DependencyRequest, CodeBlock> dependencyUsage, - Function<XVariableElement, String> uniqueAssistedParameterName, + Function<XExecutableParameterElement, String> uniqueAssistedParameterName, ClassName requestingClass, Optional<CodeBlock> moduleReference, CompilerOptions compilerOptions) { @@ -162,7 +161,7 @@ final class InjectionMethods { static ImmutableList<CodeBlock> invokeArguments( ProvisionBinding binding, Function<DependencyRequest, CodeBlock> dependencyUsage, - Function<XVariableElement, String> uniqueAssistedParameterName) { + Function<XExecutableParameterElement, String> uniqueAssistedParameterName) { ImmutableMap<XExecutableParameterElement, DependencyRequest> dependencyRequestMap = binding.provisionDependencies().stream() .collect( @@ -406,10 +405,10 @@ final class InjectionMethods { if (isVoid(method.getReturnType())) { return builder.addStatement("$L", invocation).build(); } else { - Nullability.of(method) - .nullableAnnotation() - .map(XAnnotations::getClassName) - .ifPresent(builder::addAnnotation); + Nullability nullability = Nullability.of(method); + nullability + .nullableAnnotations() + .forEach(builder::addAnnotation); return builder .returns(method.getReturnType().getTypeName()) .addStatement("return $L", invocation) @@ -463,7 +462,11 @@ final class InjectionMethods { return parameters.stream() .map( parameter -> { - String name = parameterNameSet.getUniqueName(validJavaName(getSimpleName(parameter))); + String name = + parameterNameSet.getUniqueName( + isMethodParameter(parameter) + ? asMethodParameter(parameter).getJvmName() + : getSimpleName(parameter)); boolean useObject = !isRawTypePubliclyAccessible(parameter.getType()); return copyParameter(methodBuilder, parameter.getType(), name, useObject); }) @@ -487,19 +490,4 @@ final class InjectionMethods { // If we had to cast the instance add an extra parenthesis incase we're calling a method on it. return useObject ? CodeBlock.of("($L)", instance) : instance; } - - private static String validJavaName(CharSequence name) { - if (SourceVersion.isIdentifier(name)) { - return protectAgainstKeywords(name.toString()); - } - - StringBuilder newName = new StringBuilder(name.length()); - char firstChar = name.charAt(0); - if (!Character.isJavaIdentifierStart(firstChar)) { - newName.append('_'); - } - - name.chars().forEach(c -> newName.append(Character.isJavaIdentifierPart(c) ? c : '_')); - return newName.toString(); - } } diff --git a/java/dagger/internal/codegen/writing/InjectionOrProvisionProviderCreationExpression.java b/java/dagger/internal/codegen/writing/InjectionOrProvisionProviderCreationExpression.java index d32531bef..27e017dba 100644 --- a/java/dagger/internal/codegen/writing/InjectionOrProvisionProviderCreationExpression.java +++ b/java/dagger/internal/codegen/writing/InjectionOrProvisionProviderCreationExpression.java @@ -18,8 +18,15 @@ package dagger.internal.codegen.writing; import static com.google.common.base.Preconditions.checkNotNull; import static dagger.internal.codegen.binding.SourceFiles.generatedClassNameForBinding; +import static dagger.internal.codegen.extension.DaggerCollectors.toOptional; +import static dagger.internal.codegen.model.BindingKind.ASSISTED_FACTORY; import static dagger.internal.codegen.model.BindingKind.INJECTION; +import static dagger.internal.codegen.xprocessing.XElements.getSimpleName; +import androidx.room.compiler.processing.XMethodElement; +import androidx.room.compiler.processing.XProcessingEnv; +import androidx.room.compiler.processing.XTypeElement; +import com.squareup.javapoet.ClassName; import com.squareup.javapoet.CodeBlock; import dagger.assisted.Assisted; import dagger.assisted.AssistedFactory; @@ -29,6 +36,7 @@ import dagger.internal.codegen.javapoet.CodeBlocks; import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.writing.ComponentImplementation.ShardImplementation; import dagger.internal.codegen.writing.FrameworkFieldInitializer.FrameworkInstanceCreationExpression; +import java.util.Optional; import javax.inject.Provider; /** @@ -42,32 +50,64 @@ final class InjectionOrProvisionProviderCreationExpression private final ContributionBinding binding; private final ShardImplementation shardImplementation; private final ComponentRequestRepresentations componentRequestRepresentations; + private final XProcessingEnv processingEnv; @AssistedInject InjectionOrProvisionProviderCreationExpression( @Assisted ContributionBinding binding, ComponentImplementation componentImplementation, - ComponentRequestRepresentations componentRequestRepresentations) { + ComponentRequestRepresentations componentRequestRepresentations, + XProcessingEnv processingEnv) { this.binding = checkNotNull(binding); this.shardImplementation = componentImplementation.shardImplementation(binding); this.componentRequestRepresentations = componentRequestRepresentations; + this.processingEnv = processingEnv; } @Override public CodeBlock creationExpression() { + ClassName factoryImpl = generatedClassNameForBinding(binding); CodeBlock createFactory = CodeBlock.of( - "$T.create($L)", - generatedClassNameForBinding(binding), + "$T.$L($L)", + factoryImpl, + // A different name is used for assisted factories due to backwards compatibility + // issues when migrating from the javax Provider. + binding.kind().equals(ASSISTED_FACTORY) ? "createFactoryProvider" : "create", componentRequestRepresentations.getCreateMethodArgumentsCodeBlock( binding, shardImplementation.name())); + // If this is for an AssistedFactory, then we may need to change the call in case we're building + // against a library built at an older version of Dagger before the changes to make factories + // return a Dagger Provider instead of a javax.inject.Provider. + if (binding.kind().equals(ASSISTED_FACTORY)) { + XTypeElement factoryType = processingEnv.findTypeElement(factoryImpl); + // If we can't find the factory, then assume it is being generated this run, which means + // it should be the newer version and not need wrapping. If it is missing for some other + // reason, then that likely means there will just be some other compilation failure. + if (factoryType != null) { + Optional<XMethodElement> createMethod = factoryType.getDeclaredMethods().stream() + .filter(method -> method.isStatic() + && getSimpleName(method).equals("createFactoryProvider")) + .collect(toOptional()); + // Only convert it if the newer method doesn't exist. + if (createMethod.isEmpty()) { + createFactory = CodeBlock.of( + "$T.asDaggerProvider($T.create($L))", + TypeNames.DAGGER_PROVIDERS, + factoryImpl, + componentRequestRepresentations.getCreateMethodArgumentsCodeBlock( + binding, shardImplementation.name())); + } + } + } + // When scoping a parameterized factory for an @Inject class, Java 7 cannot always infer the // type properly, so cast to a raw framework type before scoping. if (binding.kind().equals(INJECTION) && binding.unresolved().isPresent() && binding.scope().isPresent()) { - return CodeBlocks.cast(createFactory, TypeNames.PROVIDER); + return CodeBlocks.cast(createFactory, TypeNames.DAGGER_PROVIDER); } else { return createFactory; } diff --git a/java/dagger/internal/codegen/writing/LazyClassKeyProviders.java b/java/dagger/internal/codegen/writing/LazyClassKeyProviders.java new file mode 100644 index 000000000..2c2581172 --- /dev/null +++ b/java/dagger/internal/codegen/writing/LazyClassKeyProviders.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2024 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.internal.codegen.writing; + +import static dagger.internal.codegen.base.MapKeyAccessibility.isMapKeyAccessibleFrom; +import static javax.lang.model.element.Modifier.FINAL; +import static javax.lang.model.element.Modifier.PRIVATE; +import static javax.lang.model.element.Modifier.STATIC; + +import androidx.room.compiler.processing.XAnnotation; +import com.google.common.base.Preconditions; +import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.CodeBlock; +import com.squareup.javapoet.FieldSpec; +import com.squareup.javapoet.TypeSpec; +import dagger.internal.codegen.base.UniqueNameSet; +import dagger.internal.codegen.javapoet.TypeNames; +import dagger.internal.codegen.model.Key; +import dagger.internal.codegen.writing.ComponentImplementation.ShardImplementation; +import java.util.HashMap; +import java.util.Map; + +/** Keeps track of all providers for DaggerMap keys. */ +public final class LazyClassKeyProviders { + public static final String MAP_KEY_PROVIDER_NAME = "LazyClassKeyProvider"; + private final ClassName mapKeyProviderType; + private final Map<Key, FieldSpec> entries = new HashMap<>(); + private final Map<Key, FieldSpec> keepClassNamesFields = new HashMap<>(); + private final UniqueNameSet uniqueFieldNames = new UniqueNameSet(); + private final ShardImplementation shardImplementation; + private boolean providerAdded = false; + + LazyClassKeyProviders(ShardImplementation shardImplementation) { + String name = shardImplementation.getUniqueClassName(MAP_KEY_PROVIDER_NAME); + mapKeyProviderType = shardImplementation.name().nestedClass(name); + this.shardImplementation = shardImplementation; + } + + /** Returns a reference to a field in LazyClassKeyProvider that corresponds to this binding. */ + CodeBlock getMapKeyExpression(Key key) { + // This is for avoid generating empty LazyClassKeyProvider in codegen tests + if (!providerAdded) { + shardImplementation.addTypeSupplier(this::build); + providerAdded = true; + } + if (!entries.containsKey(key)) { + addField(key); + } + return CodeBlock.of("$T.$N", mapKeyProviderType, entries.get(key)); + } + + private void addField(Key key) { + Preconditions.checkArgument( + key.multibindingContributionIdentifier().isPresent() + && key.multibindingContributionIdentifier() + .get() + .bindingMethod() + .xprocessing() + .hasAnnotation(TypeNames.LAZY_CLASS_KEY)); + XAnnotation lazyClassKeyAnnotation = + key.multibindingContributionIdentifier() + .get() + .bindingMethod() + .xprocessing() + .getAnnotation(TypeNames.LAZY_CLASS_KEY); + ClassName lazyClassKey = + lazyClassKeyAnnotation.getAsType("value").getTypeElement().getClassName(); + entries.put( + key, + FieldSpec.builder( + TypeNames.STRING, + uniqueFieldNames.getUniqueName(lazyClassKey.canonicalName().replace('.', '_'))) + // TODO(b/217435141): Leave the field as non-final. We will apply @IdentifierNameString + // on the field, which doesn't work well with static final fields. + .addModifiers(STATIC) + .initializer("$S", lazyClassKey.reflectionName()) + .build()); + // To be able to apply -includedescriptorclasses rule to keep the class names referenced by + // LazyClassKey, we need to generate fields that uses those classes as type in + // LazyClassKeyProvider. For types that are not accessible from the generated component, we + // generate fields in the proxy class. + // Note: the generated field should not be initialized to avoid class loading. + if (isMapKeyAccessibleFrom(lazyClassKeyAnnotation, shardImplementation.name().packageName())) { + keepClassNamesFields.put( + key, + FieldSpec.builder( + lazyClassKey, + uniqueFieldNames.getUniqueName(lazyClassKey.canonicalName().replace('.', '_'))) + .addAnnotation(TypeNames.KEEP_FIELD_TYPE) + .build()); + } + } + + private TypeSpec build() { + TypeSpec.Builder builder = + TypeSpec.classBuilder(mapKeyProviderType) + .addAnnotation(TypeNames.IDENTIFIER_NAME_STRING) + .addModifiers(PRIVATE, STATIC, FINAL) + .addFields(entries.values()) + .addFields(keepClassNamesFields.values()); + return builder.build(); + } +} diff --git a/java/dagger/internal/codegen/writing/MapFactoryCreationExpression.java b/java/dagger/internal/codegen/writing/MapFactoryCreationExpression.java index 1f857dbf1..0ea382d1f 100644 --- a/java/dagger/internal/codegen/writing/MapFactoryCreationExpression.java +++ b/java/dagger/internal/codegen/writing/MapFactoryCreationExpression.java @@ -22,14 +22,16 @@ import static dagger.internal.codegen.binding.SourceFiles.mapFactoryClassName; import static dagger.internal.codegen.extension.DaggerCollectors.toOptional; import androidx.room.compiler.processing.XProcessingEnv; -import androidx.room.compiler.processing.XType; +import com.squareup.javapoet.ClassName; import com.squareup.javapoet.CodeBlock; +import com.squareup.javapoet.TypeName; import dagger.assisted.Assisted; import dagger.assisted.AssistedFactory; import dagger.assisted.AssistedInject; import dagger.internal.codegen.base.MapType; import dagger.internal.codegen.binding.BindingGraph; import dagger.internal.codegen.binding.ContributionBinding; +import dagger.internal.codegen.binding.MapKeys; import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.DependencyRequest; import java.util.stream.Stream; @@ -41,6 +43,8 @@ final class MapFactoryCreationExpression extends MultibindingFactoryCreationExpr private final ComponentImplementation componentImplementation; private final BindingGraph graph; private final ContributionBinding binding; + private final boolean useLazyClassKey; + private final LazyClassKeyProviders lazyClassKeyProviders; @AssistedInject MapFactoryCreationExpression( @@ -54,22 +58,31 @@ final class MapFactoryCreationExpression extends MultibindingFactoryCreationExpr this.binding = checkNotNull(binding); this.componentImplementation = componentImplementation; this.graph = graph; + this.useLazyClassKey = MapKeys.useLazyClassKey(binding, graph); + this.lazyClassKeyProviders = + componentImplementation.shardImplementation(binding).getLazyClassKeyProviders(); } @Override public CodeBlock creationExpression() { - CodeBlock.Builder builder = CodeBlock.builder().add("$T.", mapFactoryClassName(binding)); + ClassName mapFactoryClassName = mapFactoryClassName(binding); + CodeBlock.Builder builder = CodeBlock.builder().add("$T.", mapFactoryClassName); + TypeName valueTypeName = TypeName.OBJECT; if (!useRawType()) { MapType mapType = MapType.from(binding.key()); // TODO(ronshapiro): either inline this into mapFactoryClassName, or add a // mapType.unwrappedValueType() method that doesn't require a framework type - XType valueType = + valueTypeName = Stream.of(TypeNames.PROVIDER, TypeNames.PRODUCER, TypeNames.PRODUCED) .filter(mapType::valuesAreTypeOf) .map(mapType::unwrappedValueType) .collect(toOptional()) - .orElseGet(mapType::valueType); - builder.add("<$T, $T>", mapType.keyType().getTypeName(), valueType.getTypeName()); + .orElseGet(mapType::valueType) + .getTypeName(); + builder.add( + "<$T, $T>", + useLazyClassKey ? TypeNames.STRING : mapType.keyType().getTypeName(), + valueTypeName); } builder.add("builder($L)", binding.dependencies().size()); @@ -78,12 +91,20 @@ final class MapFactoryCreationExpression extends MultibindingFactoryCreationExpr ContributionBinding contributionBinding = graph.contributionBinding(dependency.key()); builder.add( ".put($L, $L)", - getMapKeyExpression(contributionBinding, componentImplementation.name(), processingEnv), + useLazyClassKey + ? lazyClassKeyProviders.getMapKeyExpression(dependency.key()) + : getMapKeyExpression( + contributionBinding, componentImplementation.name(), processingEnv), multibindingDependencyExpression(dependency)); } - builder.add(".build()"); - return builder.build(); + return useLazyClassKey + ? CodeBlock.of( + "$T.<$T>of($L)", + TypeNames.LAZY_CLASS_KEY_MAP_FACTORY, + valueTypeName, + builder.add(".build()").build()) + : builder.add(".build()").build(); } @AssistedFactory diff --git a/java/dagger/internal/codegen/writing/MapRequestRepresentation.java b/java/dagger/internal/codegen/writing/MapRequestRepresentation.java index bb49ebe99..f631d34ce 100644 --- a/java/dagger/internal/codegen/writing/MapRequestRepresentation.java +++ b/java/dagger/internal/codegen/writing/MapRequestRepresentation.java @@ -38,6 +38,7 @@ import dagger.internal.MapBuilder; import dagger.internal.codegen.base.MapType; import dagger.internal.codegen.binding.BindingGraph; import dagger.internal.codegen.binding.ContributionBinding; +import dagger.internal.codegen.binding.MapKeys; import dagger.internal.codegen.binding.ProvisionBinding; import dagger.internal.codegen.javapoet.Expression; import dagger.internal.codegen.javapoet.TypeNames; @@ -54,7 +55,8 @@ final class MapRequestRepresentation extends RequestRepresentation { private final ProvisionBinding binding; private final ImmutableMap<DependencyRequest, ContributionBinding> dependencies; private final ComponentRequestRepresentations componentRequestRepresentations; - private final boolean isExperimentalMergedMode; + private final boolean useLazyClassKey; + private final LazyClassKeyProviders lazyClassKeyProviders; @AssistedInject MapRequestRepresentation( @@ -70,12 +72,29 @@ final class MapRequestRepresentation extends RequestRepresentation { this.componentRequestRepresentations = componentRequestRepresentations; this.dependencies = Maps.toMap(binding.dependencies(), dep -> graph.contributionBinding(dep.key())); - this.isExperimentalMergedMode = - componentImplementation.compilerMode().isExperimentalMergedMode(); + this.useLazyClassKey = MapKeys.useLazyClassKey(binding, graph); + this.lazyClassKeyProviders = + componentImplementation.shardImplementation(binding).getLazyClassKeyProviders(); } @Override Expression getDependencyExpression(ClassName requestingClass) { + MapType mapType = MapType.from(binding.key()); + Expression dependencyExpression = getUnderlyingMapExpression(requestingClass); + // LazyClassKey is backed with a string map, therefore needs to be wrapped. + if (useLazyClassKey) { + return Expression.create( + dependencyExpression.type(), + CodeBlock.of( + "$T.<$T>of($L)", + TypeNames.LAZY_CLASS_KEY_MAP, + mapType.valueType().getTypeName(), + dependencyExpression.codeBlock())); + } + return dependencyExpression; + } + + private Expression getUnderlyingMapExpression(ClassName requestingClass) { // TODO(ronshapiro): We should also make an ImmutableMap version of MapFactory boolean isImmutableMapAvailable = isImmutableMapAvailable(); // TODO(ronshapiro, gak): Use Maps.immutableEnumMap() if it's available? @@ -87,9 +106,7 @@ final class MapRequestRepresentation extends RequestRepresentation { .add(maybeTypeParameters(requestingClass)) .add( "of($L)", - dependencies - .keySet() - .stream() + dependencies.keySet().stream() .map(dependency -> keyAndValueExpression(dependency, requestingClass)) .collect(toParametersCodeBlock())) .build()); @@ -104,10 +121,10 @@ final class MapRequestRepresentation extends RequestRepresentation { "singletonMap($L)", keyAndValueExpression(getOnlyElement(dependencies.keySet()), requestingClass))); default: - CodeBlock.Builder instantiation = CodeBlock.builder(); - instantiation - .add("$T.", isImmutableMapAvailable ? ImmutableMap.class : MapBuilder.class) - .add(maybeTypeParameters(requestingClass)); + CodeBlock.Builder instantiation = + CodeBlock.builder() + .add("$T.", isImmutableMapAvailable ? ImmutableMap.class : MapBuilder.class) + .add(maybeTypeParameters(requestingClass)); if (isImmutableMapBuilderWithExpectedSizeAvailable()) { instantiation.add("builderWithExpectedSize($L)", dependencies.size()); } else if (isImmutableMapAvailable) { @@ -135,16 +152,12 @@ final class MapRequestRepresentation extends RequestRepresentation { private CodeBlock keyAndValueExpression(DependencyRequest dependency, ClassName requestingClass) { return CodeBlock.of( "$L, $L", - getMapKeyExpression(dependencies.get(dependency), requestingClass, processingEnv), - isExperimentalMergedMode - ? componentRequestRepresentations - .getExperimentalSwitchingProviderDependencyRepresentation( - bindingRequest(dependency)) - .getDependencyExpression(dependency.kind(), binding) - .codeBlock() - : componentRequestRepresentations - .getDependencyExpression(bindingRequest(dependency), requestingClass) - .codeBlock()); + useLazyClassKey + ? lazyClassKeyProviders.getMapKeyExpression(dependency.key()) + : getMapKeyExpression(dependencies.get(dependency), requestingClass, processingEnv), + componentRequestRepresentations + .getDependencyExpression(bindingRequest(dependency), requestingClass) + .codeBlock()); } private Expression collectionsStaticFactoryInvocation( @@ -163,7 +176,9 @@ final class MapRequestRepresentation extends RequestRepresentation { MapType mapType = MapType.from(binding.key()); return isTypeAccessibleFrom(bindingKeyType, requestingClass.packageName()) ? CodeBlock.of( - "<$T, $T>", mapType.keyType().getTypeName(), mapType.valueType().getTypeName()) + "<$T, $T>", + useLazyClassKey ? TypeNames.STRING : mapType.keyType().getTypeName(), + mapType.valueType().getTypeName()) : CodeBlock.of(""); } diff --git a/java/dagger/internal/codegen/writing/MembersInjectionMethods.java b/java/dagger/internal/codegen/writing/MembersInjectionMethods.java index bac7490b4..a00e3676f 100644 --- a/java/dagger/internal/codegen/writing/MembersInjectionMethods.java +++ b/java/dagger/internal/codegen/writing/MembersInjectionMethods.java @@ -16,15 +16,12 @@ package dagger.internal.codegen.writing; -import static com.google.common.base.Preconditions.checkState; import static com.squareup.javapoet.MethodSpec.methodBuilder; import static dagger.internal.codegen.base.Util.reentrantComputeIfAbsent; -import static dagger.internal.codegen.binding.BindingRequest.bindingRequest; import static dagger.internal.codegen.langmodel.Accessibility.isTypeAccessibleFrom; import static dagger.internal.codegen.writing.ComponentImplementation.MethodSpecKind.MEMBERS_INJECTION_METHOD; import static dagger.internal.codegen.xprocessing.XElements.getSimpleName; import static javax.lang.model.element.Modifier.PRIVATE; -import static javax.lang.model.element.Modifier.STATIC; import androidx.room.compiler.processing.XProcessingEnv; import androidx.room.compiler.processing.XType; @@ -52,7 +49,6 @@ import javax.inject.Inject; @PerComponentImplementation final class MembersInjectionMethods { private final Map<Key, Expression> injectMethodExpressions = new LinkedHashMap<>(); - private final Map<Key, Expression> experimentalInjectMethodExpressions = new LinkedHashMap<>(); private final ComponentImplementation componentImplementation; private final ComponentRequestRepresentations bindingExpressions; private final BindingGraph graph; @@ -81,7 +77,7 @@ final class MembersInjectionMethods { : graph.localContributionBinding(key).get(); Expression expression = reentrantComputeIfAbsent( - injectMethodExpressions, key, k -> injectMethodExpression(binding, false)); + injectMethodExpressions, key, k -> injectMethodExpression(binding)); ShardImplementation shardImplementation = componentImplementation.shardImplementation(binding); return Expression.create( expression.type(), @@ -94,32 +90,11 @@ final class MembersInjectionMethods { instance)); } - /** - * Returns the members injection {@link Expression} for the given {@link Key}, creating it if - * necessary. - */ - Expression getInjectExpressionExperimental( - ProvisionBinding provisionBinding, CodeBlock instance, ClassName requestingClass) { - checkState( - componentImplementation.compilerMode().isExperimentalMergedMode(), - "Compiler mode should be experimentalMergedMode!"); - Expression expression = - reentrantComputeIfAbsent( - experimentalInjectMethodExpressions, - provisionBinding.key(), - k -> injectMethodExpression(provisionBinding, true)); - return Expression.create( - expression.type(), CodeBlock.of("$L($L, dependencies)", expression.codeBlock(), instance)); - } - - private Expression injectMethodExpression(Binding binding, boolean useStaticInjectionMethod) { + private Expression injectMethodExpression(Binding binding) { // TODO(wanyingd): move Switching Providers and injection methods to Shard classes to avoid // exceeding component class constant pool limit. // Add to Component Shard so that is can be accessible from Switching Providers. - ShardImplementation shardImplementation = - useStaticInjectionMethod - ? componentImplementation.getComponentShard() - : componentImplementation.shardImplementation(binding); + ShardImplementation shardImplementation = componentImplementation.shardImplementation(binding); XType keyType = binding.key().type().xprocessing(); XType membersInjectedType = isTypeAccessibleFrom(keyType, shardImplementation.name().packageName()) @@ -132,16 +107,10 @@ final class MembersInjectionMethods { ParameterSpec parameter = ParameterSpec.builder(membersInjectedType.getTypeName(), "instance").build(); MethodSpec.Builder methodBuilder = - useStaticInjectionMethod - ? methodBuilder(methodName) - .addModifiers(PRIVATE, STATIC) - .returns(membersInjectedType.getTypeName()) - .addParameter(parameter) - .addParameter(Object[].class, "dependencies") - : methodBuilder(methodName) - .addModifiers(PRIVATE) - .returns(membersInjectedType.getTypeName()) - .addParameter(parameter); + methodBuilder(methodName) + .addModifiers(PRIVATE) + .returns(membersInjectedType.getTypeName()) + .addParameter(parameter); XTypeElement canIgnoreReturnValue = processingEnv.findTypeElement("com.google.errorprone.annotations.CanIgnoreReturnValue"); if (canIgnoreReturnValue != null) { @@ -155,23 +124,14 @@ final class MembersInjectionMethods { instance, membersInjectedType, request -> - (useStaticInjectionMethod - ? bindingExpressions - .getExperimentalSwitchingProviderDependencyRepresentation( - bindingRequest(request)) - .getDependencyExpression(request.kind(), (ProvisionBinding) binding) - : bindingExpressions.getDependencyArgumentExpression( - request, shardImplementation.name())) + bindingExpressions + .getDependencyArgumentExpression(request, shardImplementation.name()) .codeBlock())); methodBuilder.addStatement("return $L", instance); MethodSpec method = methodBuilder.build(); shardImplementation.addMethod(MEMBERS_INJECTION_METHOD, method); - return Expression.create( - membersInjectedType, - useStaticInjectionMethod - ? CodeBlock.of("$T.$N", shardImplementation.name(), method) - : CodeBlock.of("$N", method)); + return Expression.create(membersInjectedType, CodeBlock.of("$N", method)); } private static ImmutableSet<InjectionSite> injectionSites(Binding binding) { diff --git a/java/dagger/internal/codegen/writing/MembersInjectionRequestRepresentation.java b/java/dagger/internal/codegen/writing/MembersInjectionRequestRepresentation.java index 79b8802b9..f8f31a36e 100644 --- a/java/dagger/internal/codegen/writing/MembersInjectionRequestRepresentation.java +++ b/java/dagger/internal/codegen/writing/MembersInjectionRequestRepresentation.java @@ -17,7 +17,6 @@ package dagger.internal.codegen.writing; import static com.google.common.collect.Iterables.getOnlyElement; -import static dagger.internal.codegen.xprocessing.XElements.getSimpleName; import androidx.room.compiler.processing.XExecutableParameterElement; import androidx.room.compiler.processing.XMethodElement; @@ -56,7 +55,7 @@ final class MembersInjectionRequestRepresentation extends RequestRepresentation XMethodElement methodElement = componentMethod.methodElement(); XExecutableParameterElement parameter = getOnlyElement(methodElement.getParameters()); return membersInjectionMethods.getInjectExpression( - binding.key(), CodeBlock.of("$L", getSimpleName(parameter)), component.name()); + binding.key(), CodeBlock.of("$L", parameter.getJvmName()), component.name()); } // TODO(bcorso): Consider making this a method on all RequestRepresentations. diff --git a/java/dagger/internal/codegen/writing/MembersInjectorGenerator.java b/java/dagger/internal/codegen/writing/MembersInjectorGenerator.java index 82d12ddb5..36a991591 100644 --- a/java/dagger/internal/codegen/writing/MembersInjectorGenerator.java +++ b/java/dagger/internal/codegen/writing/MembersInjectorGenerator.java @@ -20,8 +20,6 @@ import static com.google.common.base.Preconditions.checkState; import static com.squareup.javapoet.MethodSpec.constructorBuilder; import static com.squareup.javapoet.MethodSpec.methodBuilder; import static com.squareup.javapoet.TypeSpec.classBuilder; -import static dagger.internal.codegen.binding.AssistedInjectionAnnotations.assistedInjectedConstructors; -import static dagger.internal.codegen.binding.InjectionAnnotations.injectedConstructors; import static dagger.internal.codegen.binding.SourceFiles.bindingTypeElementTypeVariableNames; import static dagger.internal.codegen.binding.SourceFiles.generateBindingFieldsForDependencies; import static dagger.internal.codegen.binding.SourceFiles.membersInjectorNameForType; @@ -90,19 +88,6 @@ public final class MembersInjectorGenerator extends SourceFileGenerator<MembersI @Override public ImmutableList<TypeSpec.Builder> topLevelTypes(MembersInjectionBinding binding) { - // Empty members injection bindings are special and don't need source files. - if (binding.injectionSites().isEmpty()) { - return ImmutableList.of(); - } - - // Members injectors for classes with no local injection sites and no @Inject - // constructor are unused. - if (!binding.hasLocalInjectionSites() - && injectedConstructors(binding.membersInjectedType()).isEmpty() - && assistedInjectedConstructors(binding.membersInjectedType()).isEmpty()) { - return ImmutableList.of(); - } - // We don't want to write out resolved bindings -- we want to write out the generic version. checkState( @@ -162,7 +147,9 @@ public final class MembersInjectorGenerator extends SourceFileGenerator<MembersI dependency.key().type().xprocessing(), generatedTypeName.packageName()); String fieldName = fieldNames.getUniqueName(bindingField.name()); - TypeName fieldType = useRawFrameworkType ? bindingField.type().rawType : bindingField.type(); + TypeName fieldType = useRawFrameworkType + ? TypeNames.rawTypeName(bindingField.type()) + : bindingField.type(); FieldSpec.Builder fieldBuilder = FieldSpec.builder(fieldType, fieldName, PRIVATE, FINAL); ParameterSpec.Builder parameterBuilder = ParameterSpec.builder(fieldType, fieldName); diff --git a/java/dagger/internal/codegen/writing/OptionalFactories.java b/java/dagger/internal/codegen/writing/OptionalFactories.java index deb9dbfa8..3c327e8bc 100644 --- a/java/dagger/internal/codegen/writing/OptionalFactories.java +++ b/java/dagger/internal/codegen/writing/OptionalFactories.java @@ -28,8 +28,8 @@ import static dagger.internal.codegen.base.RequestKinds.requestTypeName; import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.RAWTYPES; import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.UNCHECKED; import static dagger.internal.codegen.javapoet.TypeNames.abstractProducerOf; +import static dagger.internal.codegen.javapoet.TypeNames.daggerProviderOf; import static dagger.internal.codegen.javapoet.TypeNames.listenableFutureOf; -import static dagger.internal.codegen.javapoet.TypeNames.providerOf; import static dagger.internal.codegen.writing.ComponentImplementation.FieldSpecKind.ABSENT_OPTIONAL_FIELD; import static dagger.internal.codegen.writing.ComponentImplementation.MethodSpecKind.ABSENT_OPTIONAL_METHOD; import static dagger.internal.codegen.writing.ComponentImplementation.TypeSpecKind.PRESENT_FACTORY; @@ -62,15 +62,12 @@ import dagger.internal.codegen.binding.FrameworkType; import dagger.internal.codegen.javapoet.AnnotationSpecs; import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.RequestKind; -import dagger.producers.Producer; -import dagger.producers.internal.Producers; import java.util.Comparator; import java.util.Map; import java.util.Optional; import java.util.TreeMap; import java.util.concurrent.Executor; import javax.inject.Inject; -import javax.inject.Provider; /** The nested class and static methods required by the component to implement optional bindings. */ // TODO(dpb): Name members simply if a component uses only one of Guava or JDK Optional. @@ -150,15 +147,15 @@ final class OptionalFactories { "absent%sProvider", UPPER_UNDERSCORE.to(UPPER_CAMEL, optionalKind.name()))) .addModifiers(PRIVATE, STATIC) .addTypeVariable(typeVariable) - .returns(providerOf(optionalKind.of(typeVariable))) + .returns(daggerProviderOf(optionalKind.of(typeVariable))) .addJavadoc( "Returns a {@link $T} that returns {@code $L}.", - TypeNames.PROVIDER, + TypeNames.DAGGER_PROVIDER, optionalKind.absentValueExpression()) .addCode("$L // safe covariant cast\n", AnnotationSpecs.suppressWarnings(UNCHECKED)) .addStatement( "$1T provider = ($1T) $2N", - providerOf(optionalKind.of(typeVariable)), + daggerProviderOf(optionalKind.of(typeVariable)), perGeneratedFileCache.absentOptionalProviderFields.computeIfAbsent( optionalKind, kind -> { @@ -176,7 +173,7 @@ final class OptionalFactories { */ private FieldSpec absentOptionalProviderField(OptionalKind optionalKind) { return FieldSpec.builder( - TypeNames.PROVIDER, + TypeNames.DAGGER_PROVIDER, String.format("ABSENT_%s_PROVIDER", optionalKind.name()), PRIVATE, STATIC, @@ -185,7 +182,7 @@ final class OptionalFactories { .initializer("$T.create($L)", InstanceFactory.class, optionalKind.absentValueExpression()) .addJavadoc( "A {@link $T} that returns {@code $L}.", - TypeNames.PROVIDER, + TypeNames.DAGGER_PROVIDER, optionalKind.absentValueExpression()) .build(); } @@ -193,7 +190,7 @@ final class OptionalFactories { /** Information about the type of a factory for present bindings. */ @AutoValue abstract static class PresentFactorySpec { - /** Whether the factory is a {@link Provider} or a {@link Producer}. */ + /** Whether the factory is a {@code Provider} or a {@code Producer}. */ abstract FrameworkType frameworkType(); /** What kind of {@code Optional} is returned. */ @@ -302,7 +299,7 @@ final class OptionalFactories { * {@code Producer<Optional<Produced<T>>>}. * </ul> * - * @param delegateFactory an expression for a {@link Provider} or {@link Producer} of the + * @param delegateFactory an expression for a {@code Provider} or {@code Producer} of the * underlying type */ CodeBlock presentOptionalFactory(ContributionBinding binding, CodeBlock delegateFactory) { @@ -415,7 +412,9 @@ final class OptionalFactories { spec.optionalKind(), spec.valueType(), CodeBlock.of( - "$T.createFutureProduced($N.get())", Producers.class, delegateField))) + "$T.createFutureProduced($N.get())", + TypeNames.PRODUCERS, + delegateField))) .build(); default: diff --git a/java/dagger/internal/codegen/writing/OptionalRequestRepresentation.java b/java/dagger/internal/codegen/writing/OptionalRequestRepresentation.java index b77531456..8c9219197 100644 --- a/java/dagger/internal/codegen/writing/OptionalRequestRepresentation.java +++ b/java/dagger/internal/codegen/writing/OptionalRequestRepresentation.java @@ -33,13 +33,13 @@ import dagger.internal.codegen.base.OptionalType.OptionalKind; import dagger.internal.codegen.binding.ProvisionBinding; import dagger.internal.codegen.javapoet.Expression; import dagger.internal.codegen.model.DependencyRequest; +import dagger.internal.codegen.model.RequestKind; /** A binding expression for optional bindings. */ final class OptionalRequestRepresentation extends RequestRepresentation { private final ProvisionBinding binding; private final ComponentRequestRepresentations componentRequestRepresentations; private final XProcessingEnv processingEnv; - private final boolean isExperimentalMergedMode; @AssistedInject OptionalRequestRepresentation( @@ -50,8 +50,6 @@ final class OptionalRequestRepresentation extends RequestRepresentation { this.binding = binding; this.componentRequestRepresentations = componentRequestRepresentations; this.processingEnv = processingEnv; - this.isExperimentalMergedMode = - componentImplementation.compilerMode().isExperimentalMergedMode(); } @Override @@ -78,18 +76,15 @@ final class OptionalRequestRepresentation extends RequestRepresentation { DependencyRequest dependency = getOnlyElement(binding.dependencies()); CodeBlock dependencyExpression = - isExperimentalMergedMode - ? componentRequestRepresentations - .getExperimentalSwitchingProviderDependencyRepresentation( - bindingRequest(dependency)) - .getDependencyExpression(dependency.kind(), binding) - .codeBlock() - : componentRequestRepresentations - .getDependencyExpression(bindingRequest(dependency), requestingClass) - .codeBlock(); + componentRequestRepresentations + .getDependencyExpression(bindingRequest(dependency), requestingClass) + .codeBlock(); - return isTypeAccessibleFrom( - dependency.key().type().xprocessing(), requestingClass.packageName()) + boolean needsObjectExpression = !isTypeAccessibleFrom( + dependency.key().type().xprocessing(), requestingClass.packageName()) + || (isPreJava8SourceVersion(processingEnv) && dependency.kind() == RequestKind.PROVIDER); + + return !needsObjectExpression ? Expression.create( binding.key().type().xprocessing(), optionalKind.presentExpression(dependencyExpression)) diff --git a/java/dagger/internal/codegen/writing/ProducerEntryPointView.java b/java/dagger/internal/codegen/writing/ProducerEntryPointView.java index 648e2537f..34d54584d 100644 --- a/java/dagger/internal/codegen/writing/ProducerEntryPointView.java +++ b/java/dagger/internal/codegen/writing/ProducerEntryPointView.java @@ -31,14 +31,11 @@ import dagger.internal.codegen.javapoet.Expression; import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.RequestKind; import dagger.internal.codegen.writing.ComponentImplementation.ShardImplementation; -import dagger.producers.Producer; -import dagger.producers.internal.CancellationListener; -import dagger.producers.internal.Producers; import java.util.Optional; /** - * A factory of {@linkplain Producers#entryPointViewOf(Producer, CancellationListener) entry point - * views} of {@link Producer}s. + * A factory of {@code Producers#entryPointViewOf(Producer, CancellationListener)} of + * {@code Producer}s. */ final class ProducerEntryPointView { private final ShardImplementation shardImplementation; @@ -50,9 +47,8 @@ final class ProducerEntryPointView { } /** - * Returns an expression for an {@linkplain Producers#entryPointViewOf(Producer, - * CancellationListener) entry point view} of a producer if the component method returns a {@link - * Producer} or {@link com.google.common.util.concurrent.ListenableFuture}. + * Returns an expression for an {@code Producers#entryPointViewOf(Producer, CancellationListener)} + * of a producer if the component method returns a {@code Producer} or {@code ListenableFuture}. * * <p>This is intended to be a replacement implementation for {@link * dagger.internal.codegen.writing.RequestRepresentation#getDependencyExpressionForComponentMethod(ComponentMethodDescriptor, @@ -97,7 +93,7 @@ final class ProducerEntryPointView { CodeBlock.of( "this.$N = $T.entryPointViewOf($L, $L);", field, - Producers.class, + TypeNames.PRODUCERS, producerExpression.getDependencyExpression(shardImplementation.name()).codeBlock(), // Always pass in the componentShard reference here rather than the owning shard for // this key because this needs to be the root CancellationListener. diff --git a/java/dagger/internal/codegen/writing/ProducerFactoryGenerator.java b/java/dagger/internal/codegen/writing/ProducerFactoryGenerator.java index e6c88a9c7..1d8ab02f7 100644 --- a/java/dagger/internal/codegen/writing/ProducerFactoryGenerator.java +++ b/java/dagger/internal/codegen/writing/ProducerFactoryGenerator.java @@ -77,16 +77,13 @@ import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.DependencyRequest; import dagger.internal.codegen.model.Key; import dagger.internal.codegen.model.RequestKind; -import dagger.producers.Producer; -import dagger.producers.internal.AbstractProducesMethodProducer; -import dagger.producers.internal.Producers; import java.util.ArrayList; import java.util.List; import java.util.Map.Entry; import java.util.Optional; import javax.inject.Inject; -/** Generates {@link Producer} implementations from {@link ProductionBinding} instances. */ +/** Generates {@code Producer} implementations from {@link ProductionBinding} instances. */ public final class ProducerFactoryGenerator extends SourceFileGenerator<ProductionBinding> { private final CompilerOptions compilerOptions; private final KeyFactory keyFactory; @@ -163,7 +160,7 @@ public final class ProducerFactoryGenerator extends SourceFileGenerator<Producti addFieldAndConstructorParameter( factoryBuilder, constructorBuilder, fieldName, bindingField.type()); fieldsBuilder.put(dependency, field); - frameworkFieldAssignments.add(fieldAssignment(field, bindingField.type())); + frameworkFieldAssignments.add(fieldAssignment(field, bindingField)); } } ImmutableMap<DependencyRequest, FieldSpec> fields = fieldsBuilder.build(); @@ -219,7 +216,7 @@ public final class ProducerFactoryGenerator extends SourceFileGenerator<Producti factoryBuilder .superclass( ParameterizedTypeName.get( - ClassName.get(AbstractProducesMethodProducer.class), + TypeNames.ABSTRACT_PRODUCES_METHOD_PRODUCER, futureTransform.applyArgType(), providedTypeName)) .addMethod(constructor) @@ -260,11 +257,12 @@ public final class ProducerFactoryGenerator extends SourceFileGenerator<Producti return field; } - private static CodeBlock fieldAssignment(FieldSpec field, ParameterizedTypeName type) { + private static CodeBlock fieldAssignment(FieldSpec field, FrameworkField frameworkField) { CodeBlock.Builder statement = CodeBlock.builder(); - if (type != null && type.rawType.equals(TypeNames.PRODUCER)) { + if (frameworkField.type() != null + && TypeNames.rawTypeName(frameworkField.type()).equals(TypeNames.PRODUCER)) { statement.addStatement( - "this.$1N = $2T.nonCancellationPropagatingViewOf($1N)", field, Producers.class); + "this.$1N = $2T.nonCancellationPropagatingViewOf($1N)", field, TypeNames.PRODUCERS); } else { statement.addStatement("this.$1N = $1N", field); } @@ -275,7 +273,7 @@ public final class ProducerFactoryGenerator extends SourceFileGenerator<Producti MethodSpec.Builder constructorBuilder, FieldSpec field, ParameterizedTypeName type) { if (type != null && type.rawType.equals(TypeNames.PRODUCER)) { constructorBuilder.addStatement( - "this.$1N = $2T.nonCancellationPropagatingViewOf($1N)", field, Producers.class); + "this.$1N = $2T.nonCancellationPropagatingViewOf($1N)", field, TypeNames.PRODUCERS); } else { constructorBuilder.addStatement("this.$1N = $1N", field); } diff --git a/java/dagger/internal/codegen/writing/ProducerFromProviderCreationExpression.java b/java/dagger/internal/codegen/writing/ProducerFromProviderCreationExpression.java index 05dd50b27..9d0895673 100644 --- a/java/dagger/internal/codegen/writing/ProducerFromProviderCreationExpression.java +++ b/java/dagger/internal/codegen/writing/ProducerFromProviderCreationExpression.java @@ -26,10 +26,9 @@ import dagger.internal.codegen.binding.FrameworkType; import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.RequestKind; import dagger.internal.codegen.writing.FrameworkFieldInitializer.FrameworkInstanceCreationExpression; -import dagger.producers.Producer; import java.util.Optional; -/** An {@link Producer} creation expression for provision bindings. */ +/** An {@code Producer} creation expression for provision bindings. */ final class ProducerFromProviderCreationExpression implements FrameworkInstanceCreationExpression { private final RequestRepresentation providerRequestRepresentation; private final ClassName requestingClass; diff --git a/java/dagger/internal/codegen/writing/ProducerNodeInstanceRequestRepresentation.java b/java/dagger/internal/codegen/writing/ProducerNodeInstanceRequestRepresentation.java index 813010cfd..cdcc38933 100644 --- a/java/dagger/internal/codegen/writing/ProducerNodeInstanceRequestRepresentation.java +++ b/java/dagger/internal/codegen/writing/ProducerNodeInstanceRequestRepresentation.java @@ -26,9 +26,9 @@ import dagger.internal.codegen.binding.ComponentDescriptor.ComponentMethodDescri import dagger.internal.codegen.binding.ContributionBinding; import dagger.internal.codegen.binding.FrameworkType; import dagger.internal.codegen.javapoet.Expression; +import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.Key; import dagger.internal.codegen.writing.ComponentImplementation.ShardImplementation; -import dagger.producers.internal.Producers; /** Binding expression for producer node instances. */ final class ProducerNodeInstanceRequestRepresentation @@ -61,7 +61,7 @@ final class ProducerNodeInstanceRequestRepresentation key, CodeBlock.of( "$T.cancel($L, $N);", - Producers.class, + TypeNames.PRODUCERS, result.codeBlock(), ComponentImplementation.MAY_INTERRUPT_IF_RUNNING_PARAM)); return result; diff --git a/java/dagger/internal/codegen/writing/ProviderInstanceRequestRepresentation.java b/java/dagger/internal/codegen/writing/ProviderInstanceRequestRepresentation.java index 9bd8f3d8d..f031a72a6 100644 --- a/java/dagger/internal/codegen/writing/ProviderInstanceRequestRepresentation.java +++ b/java/dagger/internal/codegen/writing/ProviderInstanceRequestRepresentation.java @@ -20,18 +20,29 @@ import androidx.room.compiler.processing.XProcessingEnv; import dagger.assisted.Assisted; import dagger.assisted.AssistedFactory; import dagger.assisted.AssistedInject; -import dagger.internal.codegen.binding.ContributionBinding; import dagger.internal.codegen.binding.FrameworkType; +import dagger.internal.codegen.binding.ProvisionBinding; /** Binding expression for provider instances. */ final class ProviderInstanceRequestRepresentation extends FrameworkInstanceRequestRepresentation { @AssistedInject ProviderInstanceRequestRepresentation( - @Assisted ContributionBinding binding, - @Assisted FrameworkInstanceSupplier frameworkInstanceSupplier, + @Assisted ProvisionBinding binding, + SwitchingProviderInstanceSupplier.Factory switchingProviderInstanceSupplierFactory, + StaticFactoryInstanceSupplier.Factory staticFactoryInstanceSupplierFactory, + ProviderInstanceSupplier.Factory providerInstanceSupplierFactory, + ComponentImplementation componentImplementation, XProcessingEnv processingEnv) { - super(binding, frameworkInstanceSupplier, processingEnv); + super( + binding, + frameworkInstanceSupplier( + binding, + switchingProviderInstanceSupplierFactory, + staticFactoryInstanceSupplierFactory, + providerInstanceSupplierFactory, + componentImplementation), + processingEnv); } @Override @@ -39,9 +50,27 @@ final class ProviderInstanceRequestRepresentation extends FrameworkInstanceReque return FrameworkType.PROVIDER; } + private static FrameworkInstanceSupplier frameworkInstanceSupplier( + ProvisionBinding binding, + SwitchingProviderInstanceSupplier.Factory switchingProviderInstanceSupplierFactory, + StaticFactoryInstanceSupplier.Factory staticFactoryInstanceSupplierFactory, + ProviderInstanceSupplier.Factory providerInstanceSupplierFactory, + ComponentImplementation componentImplementation) { + FrameworkInstanceKind frameworkInstanceKind = + FrameworkInstanceKind.from(binding, componentImplementation.compilerMode()); + switch (frameworkInstanceKind) { + case SWITCHING_PROVIDER: + return switchingProviderInstanceSupplierFactory.create(binding); + case STATIC_FACTORY: + return staticFactoryInstanceSupplierFactory.create(binding); + case PROVIDER_FIELD: + return providerInstanceSupplierFactory.create(binding); + } + throw new AssertionError("Unexpected FrameworkInstanceKind: " + frameworkInstanceKind); + } + @AssistedFactory static interface Factory { - ProviderInstanceRequestRepresentation create( - ContributionBinding binding, FrameworkInstanceSupplier frameworkInstanceSupplier); + ProviderInstanceRequestRepresentation create(ProvisionBinding binding); } } diff --git a/java/dagger/internal/codegen/writing/ProvisionBindingRepresentation.java b/java/dagger/internal/codegen/writing/ProvisionBindingRepresentation.java index 4ae7f3759..0f9b6f3dd 100644 --- a/java/dagger/internal/codegen/writing/ProvisionBindingRepresentation.java +++ b/java/dagger/internal/codegen/writing/ProvisionBindingRepresentation.java @@ -25,7 +25,6 @@ import dagger.assisted.AssistedInject; import dagger.internal.codegen.binding.BindingGraph; import dagger.internal.codegen.binding.BindingRequest; import dagger.internal.codegen.binding.ProvisionBinding; -import dagger.internal.codegen.compileroption.CompilerOptions; import dagger.internal.codegen.model.RequestKind; import dagger.internal.codegen.writing.ComponentImplementation.CompilerMode; @@ -43,34 +42,17 @@ final class ProvisionBindingRepresentation implements BindingRepresentation { @AssistedInject ProvisionBindingRepresentation( @Assisted ProvisionBinding binding, - BindingGraph graph, - ComponentImplementation componentImplementation, DirectInstanceBindingRepresentation.Factory directInstanceBindingRepresentationFactory, FrameworkInstanceBindingRepresentation.Factory frameworkInstanceBindingRepresentationFactory, - SwitchingProviderInstanceSupplier.Factory switchingProviderInstanceSupplierFactory, - ProviderInstanceSupplier.Factory providerInstanceSupplierFactory, - StaticFactoryInstanceSupplier.Factory staticFactoryInstanceSupplierFactory, - CompilerOptions compilerOptions) { + BindingGraph graph, + ComponentImplementation componentImplementation) { this.binding = binding; this.graph = graph; this.compilerMode = componentImplementation.compilerMode(); this.directInstanceBindingRepresentation = directInstanceBindingRepresentationFactory.create(binding); - FrameworkInstanceSupplier frameworkInstanceSupplier = null; - switch (FrameworkInstanceKind.from(binding, compilerMode)) { - case SWITCHING_PROVIDER: - case EXPERIMENTAL_SWITCHING_PROVIDER: - frameworkInstanceSupplier = switchingProviderInstanceSupplierFactory.create(binding); - break; - case STATIC_FACTORY: - frameworkInstanceSupplier = staticFactoryInstanceSupplierFactory.create(binding); - break; - case PROVIDER_FIELD: - frameworkInstanceSupplier = providerInstanceSupplierFactory.create(binding); - break; - } this.frameworkInstanceBindingRepresentation = - frameworkInstanceBindingRepresentationFactory.create(binding, frameworkInstanceSupplier); + frameworkInstanceBindingRepresentationFactory.create(binding); } @Override @@ -81,9 +63,6 @@ final class ProvisionBindingRepresentation implements BindingRepresentation { } private boolean usesDirectInstanceExpression(RequestKind requestKind) { - if (compilerMode.isExperimentalMergedMode()) { - return false; - } if (requestKind != RequestKind.INSTANCE && requestKind != RequestKind.FUTURE) { return false; } diff --git a/java/dagger/internal/codegen/writing/SetRequestRepresentation.java b/java/dagger/internal/codegen/writing/SetRequestRepresentation.java index f5d77ad48..68a340a1b 100644 --- a/java/dagger/internal/codegen/writing/SetRequestRepresentation.java +++ b/java/dagger/internal/codegen/writing/SetRequestRepresentation.java @@ -47,7 +47,6 @@ final class SetRequestRepresentation extends RequestRepresentation { private final BindingGraph graph; private final ComponentRequestRepresentations componentRequestRepresentations; private final XProcessingEnv processingEnv; - private final boolean isExperimentalMergedMode; @AssistedInject SetRequestRepresentation( @@ -60,8 +59,6 @@ final class SetRequestRepresentation extends RequestRepresentation { this.graph = graph; this.componentRequestRepresentations = componentRequestRepresentations; this.processingEnv = processingEnv; - this.isExperimentalMergedMode = - componentImplementation.compilerMode().isExperimentalMergedMode(); } @Override @@ -139,14 +136,7 @@ final class SetRequestRepresentation extends RequestRepresentation { DependencyRequest dependency, ClassName requestingClass) { RequestRepresentation bindingExpression = componentRequestRepresentations.getRequestRepresentation(bindingRequest(dependency)); - CodeBlock expression = - isExperimentalMergedMode - ? componentRequestRepresentations - .getExperimentalSwitchingProviderDependencyRepresentation( - bindingRequest(dependency)) - .getDependencyExpression(dependency.kind(), binding) - .codeBlock() - : bindingExpression.getDependencyExpression(requestingClass).codeBlock(); + CodeBlock expression = bindingExpression.getDependencyExpression(requestingClass).codeBlock(); // TODO(b/211774331): Type casting should be Set after contributions to Set multibinding are // limited to be Set. diff --git a/java/dagger/internal/codegen/writing/SimpleMethodRequestRepresentation.java b/java/dagger/internal/codegen/writing/SimpleMethodRequestRepresentation.java index 4026f1681..79613fd40 100644 --- a/java/dagger/internal/codegen/writing/SimpleMethodRequestRepresentation.java +++ b/java/dagger/internal/codegen/writing/SimpleMethodRequestRepresentation.java @@ -19,7 +19,6 @@ package dagger.internal.codegen.writing; import static androidx.room.compiler.processing.XElementKt.isConstructor; import static androidx.room.compiler.processing.XElementKt.isMethod; import static com.google.common.base.Preconditions.checkArgument; -import static dagger.internal.codegen.binding.BindingRequest.bindingRequest; import static dagger.internal.codegen.javapoet.CodeBlocks.makeParametersCodeBlock; import static dagger.internal.codegen.javapoet.TypeNames.rawTypeName; import static dagger.internal.codegen.langmodel.Accessibility.isTypeAccessibleFrom; @@ -58,7 +57,6 @@ final class SimpleMethodRequestRepresentation extends RequestRepresentation { private final MembersInjectionMethods membersInjectionMethods; private final ComponentRequirementExpressions componentRequirementExpressions; private final ShardImplementation shardImplementation; - private final boolean isExperimentalMergedMode; @AssistedInject SimpleMethodRequestRepresentation( @@ -80,8 +78,6 @@ final class SimpleMethodRequestRepresentation extends RequestRepresentation { this.membersInjectionMethods = membersInjectionMethods; this.componentRequirementExpressions = componentRequirementExpressions; this.shardImplementation = componentImplementation.shardImplementation(binding); - this.isExperimentalMergedMode = - componentImplementation.compilerMode().isExperimentalMergedMode(); } @Override @@ -146,12 +142,8 @@ final class SimpleMethodRequestRepresentation extends RequestRepresentation { } private Expression dependencyArgument(DependencyRequest dependency, ClassName requestingClass) { - return isExperimentalMergedMode - ? componentRequestRepresentations - .getExperimentalSwitchingProviderDependencyRepresentation(bindingRequest(dependency)) - .getDependencyExpression(dependency.kind(), provisionBinding) - : componentRequestRepresentations.getDependencyArgumentExpression( - dependency, requestingClass); + return componentRequestRepresentations.getDependencyArgumentExpression( + dependency, requestingClass); } private Expression injectMembers(CodeBlock instance, ClassName requestingClass) { @@ -167,11 +159,8 @@ final class SimpleMethodRequestRepresentation extends RequestRepresentation { instance = CodeBlock.of("($T) ($T) $L", keyType, rawTypeName(keyType), instance); } } - return isExperimentalMergedMode - ? membersInjectionMethods.getInjectExpressionExperimental( - provisionBinding, instance, requestingClass) - : membersInjectionMethods.getInjectExpression( - provisionBinding.key(), instance, requestingClass); + return membersInjectionMethods.getInjectExpression( + provisionBinding.key(), instance, requestingClass); } private Optional<CodeBlock> moduleReference(ClassName requestingClass) { @@ -180,11 +169,7 @@ final class SimpleMethodRequestRepresentation extends RequestRepresentation { .contributingModule() .map(XTypeElement::getType) .map(ComponentRequirement::forModule) - .map( - module -> - isExperimentalMergedMode - ? CodeBlock.of("(($T) dependencies[0])", module.type().getTypeName()) - : componentRequirementExpressions.getExpression(module, requestingClass)) + .map(module -> componentRequirementExpressions.getExpression(module, requestingClass)) : Optional.empty(); } diff --git a/java/dagger/internal/codegen/writing/StaticMemberSelects.java b/java/dagger/internal/codegen/writing/StaticMemberSelects.java index 3fea6173f..a1ea63c03 100644 --- a/java/dagger/internal/codegen/writing/StaticMemberSelects.java +++ b/java/dagger/internal/codegen/writing/StaticMemberSelects.java @@ -22,11 +22,11 @@ import static dagger.internal.codegen.binding.SourceFiles.bindingTypeElementType import static dagger.internal.codegen.binding.SourceFiles.generatedClassNameForBinding; import static dagger.internal.codegen.binding.SourceFiles.setFactoryClassName; import static dagger.internal.codegen.javapoet.CodeBlocks.toParametersCodeBlock; +import static dagger.internal.codegen.javapoet.TypeNames.DAGGER_PROVIDER; import static dagger.internal.codegen.javapoet.TypeNames.FACTORY; import static dagger.internal.codegen.javapoet.TypeNames.MAP_FACTORY; import static dagger.internal.codegen.javapoet.TypeNames.PRODUCER; import static dagger.internal.codegen.javapoet.TypeNames.PRODUCERS; -import static dagger.internal.codegen.javapoet.TypeNames.PROVIDER; import static dagger.internal.codegen.langmodel.Accessibility.isTypeAccessibleFrom; import static dagger.internal.codegen.xprocessing.XTypes.isDeclared; @@ -52,7 +52,7 @@ final class StaticMemberSelects { ? new ParameterizedStaticMethod( PRODUCERS, typeParameters, CodeBlock.of("emptyMapProducer()"), PRODUCER) : new ParameterizedStaticMethod( - MAP_FACTORY, typeParameters, CodeBlock.of("emptyMapProvider()"), PROVIDER); + MAP_FACTORY, typeParameters, CodeBlock.of("emptyMapProvider()"), DAGGER_PROVIDER); } /** diff --git a/java/dagger/internal/codegen/writing/SubcomponentCreatorRequestRepresentation.java b/java/dagger/internal/codegen/writing/SubcomponentCreatorRequestRepresentation.java index eeadabee9..c71c70af6 100644 --- a/java/dagger/internal/codegen/writing/SubcomponentCreatorRequestRepresentation.java +++ b/java/dagger/internal/codegen/writing/SubcomponentCreatorRequestRepresentation.java @@ -20,29 +20,23 @@ import static dagger.internal.codegen.javapoet.CodeBlocks.toParametersCodeBlock; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.CodeBlock; -import com.squareup.javapoet.FieldSpec; import dagger.assisted.Assisted; import dagger.assisted.AssistedFactory; import dagger.assisted.AssistedInject; import dagger.internal.codegen.binding.ContributionBinding; import dagger.internal.codegen.javapoet.Expression; import dagger.internal.codegen.writing.ComponentImplementation.ShardImplementation; -import java.util.ArrayList; -import java.util.List; /** A binding expression for a subcomponent creator that just invokes the constructor. */ final class SubcomponentCreatorRequestRepresentation extends RequestRepresentation { private final ShardImplementation shardImplementation; private final ContributionBinding binding; - private final boolean isExperimentalMergedMode; @AssistedInject SubcomponentCreatorRequestRepresentation( @Assisted ContributionBinding binding, ComponentImplementation componentImplementation) { this.binding = binding; this.shardImplementation = componentImplementation.shardImplementation(binding); - this.isExperimentalMergedMode = - componentImplementation.compilerMode().isExperimentalMergedMode(); } @Override @@ -51,20 +45,9 @@ final class SubcomponentCreatorRequestRepresentation extends RequestRepresentati binding.key().type().xprocessing(), "new $T($L)", shardImplementation.getSubcomponentCreatorSimpleName(binding.key()), - isExperimentalMergedMode - ? getDependenciesExperimental() - : shardImplementation.componentFieldsByImplementation().values().stream() - .map(field -> CodeBlock.of("$N", field)) - .collect(toParametersCodeBlock())); - } - - private CodeBlock getDependenciesExperimental() { - List<CodeBlock> expressions = new ArrayList<>(); - int index = 0; - for (FieldSpec field : shardImplementation.componentFieldsByImplementation().values()) { - expressions.add(CodeBlock.of("($T) dependencies[$L]", field.type, index++)); - } - return expressions.stream().collect(toParametersCodeBlock()); + shardImplementation.componentFieldsByImplementation().values().stream() + .map(field -> CodeBlock.of("$N", field)) + .collect(toParametersCodeBlock())); } CodeBlock getDependencyExpressionArguments() { diff --git a/java/dagger/internal/codegen/writing/SwitchingProviderInstanceSupplier.java b/java/dagger/internal/codegen/writing/SwitchingProviderInstanceSupplier.java index 7bea206f6..6f8ca7b3f 100644 --- a/java/dagger/internal/codegen/writing/SwitchingProviderInstanceSupplier.java +++ b/java/dagger/internal/codegen/writing/SwitchingProviderInstanceSupplier.java @@ -46,11 +46,9 @@ final class SwitchingProviderInstanceSupplier implements FrameworkInstanceSuppli unscopedDirectInstanceRequestRepresentationFactory) { ShardImplementation shardImplementation = componentImplementation.shardImplementation(binding); FrameworkInstanceCreationExpression frameworkInstanceCreationExpression = - componentImplementation.compilerMode().isExperimentalMergedMode() - ? shardImplementation.getExperimentalSwitchingProviders() - .newFrameworkInstanceCreationExpression( - binding, unscopedDirectInstanceRequestRepresentationFactory.create(binding)) - : shardImplementation.getSwitchingProviders().newFrameworkInstanceCreationExpression( + shardImplementation + .getSwitchingProviders() + .newFrameworkInstanceCreationExpression( binding, unscopedDirectInstanceRequestRepresentationFactory.create(binding)); this.frameworkInstanceSupplier = new FrameworkFieldInitializer( diff --git a/java/dagger/internal/codegen/writing/SwitchingProviders.java b/java/dagger/internal/codegen/writing/SwitchingProviders.java index e6c3bbf52..736f51529 100644 --- a/java/dagger/internal/codegen/writing/SwitchingProviders.java +++ b/java/dagger/internal/codegen/writing/SwitchingProviders.java @@ -24,7 +24,7 @@ import static com.squareup.javapoet.TypeSpec.classBuilder; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.UNCHECKED; import static dagger.internal.codegen.javapoet.AnnotationSpecs.suppressWarnings; -import static dagger.internal.codegen.javapoet.TypeNames.providerOf; +import static dagger.internal.codegen.javapoet.TypeNames.daggerProviderOf; import static javax.lang.model.element.Modifier.FINAL; import static javax.lang.model.element.Modifier.PRIVATE; import static javax.lang.model.element.Modifier.PUBLIC; @@ -172,7 +172,7 @@ final class SwitchingProviders { classBuilder(switchingProviderType) .addModifiers(PRIVATE, FINAL, STATIC) .addTypeVariable(T) - .addSuperinterface(providerOf(T)) + .addSuperinterface(daggerProviderOf(T)) .addMethods(getMethods()); // The SwitchingProvider constructor lists all component parameters first and switch id last. diff --git a/java/dagger/internal/codegen/xprocessing/BUILD b/java/dagger/internal/codegen/xprocessing/BUILD index 262be175a..da465e1d0 100644 --- a/java/dagger/internal/codegen/xprocessing/BUILD +++ b/java/dagger/internal/codegen/xprocessing/BUILD @@ -30,6 +30,7 @@ java_library( deps = [ ":xprocessing-lib", "//java/dagger/internal/codegen/extension", + "//java/dagger/spi", "//third_party/java/auto:common", "//third_party/java/guava/base", "//third_party/java/guava/collect", diff --git a/java/dagger/internal/codegen/xprocessing/DaggerElements.java b/java/dagger/internal/codegen/xprocessing/DaggerElements.java new file mode 100644 index 000000000..84daeb0a9 --- /dev/null +++ b/java/dagger/internal/codegen/xprocessing/DaggerElements.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2023 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.internal.codegen.xprocessing; + +import androidx.room.compiler.processing.XElement; +import androidx.room.compiler.processing.XProcessingEnv; +import androidx.room.compiler.processing.XType; +import androidx.room.compiler.processing.compat.XConverters; +import com.google.devtools.ksp.symbol.KSClassDeclaration; +import com.google.devtools.ksp.symbol.KSFunctionDeclaration; +import com.google.devtools.ksp.symbol.KSPropertyDeclaration; +import com.google.devtools.ksp.symbol.KSValueParameter; +import dagger.spi.model.DaggerElement; +import dagger.spi.model.DaggerProcessingEnv; +import dagger.spi.model.DaggerType; + +/** Convert Dagger model types to XProcessing types. */ +public final class DaggerElements { + public static XElement toXProcessing( + DaggerElement element, DaggerProcessingEnv daggerProcessingEnv) { + XProcessingEnv processingEnv = toXProcessing(daggerProcessingEnv); + switch (element.backend()) { + case JAVAC: + return XConverters.toXProcessing(element.javac(), processingEnv); + case KSP: + if (element.ksp() instanceof KSFunctionDeclaration) { + return XConverters.toXProcessing((KSFunctionDeclaration) element.ksp(), processingEnv); + } else if (element.ksp() instanceof KSClassDeclaration) { + return XConverters.toXProcessing((KSClassDeclaration) element.ksp(), processingEnv); + } else if (element.ksp() instanceof KSValueParameter) { + return XConverters.toXProcessing((KSValueParameter) element.ksp(), processingEnv); + } else if (element.ksp() instanceof KSPropertyDeclaration) { + return XConverters.toXProcessing((KSPropertyDeclaration) element.ksp(), processingEnv); + } + throw new IllegalStateException( + String.format("Unsupported ksp declaration %s.", element.ksp())); + } + throw new IllegalStateException( + String.format("Backend %s not supported yet.", element.backend())); + } + + public static XType toXProcessing(DaggerType type, DaggerProcessingEnv daggerProcessingEnv) { + XProcessingEnv processingEnv = toXProcessing(daggerProcessingEnv); + switch (type.backend()) { + case JAVAC: + return XConverters.toXProcessing(type.javac(), processingEnv); + case KSP: + return XConverters.toXProcessing(type.ksp(), processingEnv); + } + throw new IllegalStateException(String.format("Backend %s not supported yet.", type.backend())); + } + + public static XProcessingEnv toXProcessing(DaggerProcessingEnv processingEnv) { + switch (processingEnv.backend()) { + case JAVAC: + return XProcessingEnv.create(processingEnv.javac()); + case KSP: + return XProcessingEnv.create(processingEnv.ksp(), processingEnv.resolver()); + } + throw new IllegalStateException( + String.format("Backend %s not supported yet.", processingEnv.backend())); + } + + private DaggerElements() {} +} diff --git a/java/dagger/internal/codegen/xprocessing/JavaPoetExt.java b/java/dagger/internal/codegen/xprocessing/JavaPoetExt.java index b28d9c008..bf8e94f2a 100644 --- a/java/dagger/internal/codegen/xprocessing/JavaPoetExt.java +++ b/java/dagger/internal/codegen/xprocessing/JavaPoetExt.java @@ -50,8 +50,7 @@ public final class JavaPoetExt { } public static ParameterSpec toParameterSpec(XExecutableParameterElement param) { - return ParameterSpec.builder(param.getType().getTypeName(), XElements.getSimpleName(param)) - .build(); + return ParameterSpec.builder(param.getType().getTypeName(), param.getJvmName()).build(); } private JavaPoetExt() {} diff --git a/java/dagger/internal/codegen/xprocessing/MethodSpecs.java b/java/dagger/internal/codegen/xprocessing/MethodSpecs.java index fa1f26541..cc8c2f459 100644 --- a/java/dagger/internal/codegen/xprocessing/MethodSpecs.java +++ b/java/dagger/internal/codegen/xprocessing/MethodSpecs.java @@ -16,7 +16,6 @@ package dagger.internal.codegen.xprocessing; -import static dagger.internal.codegen.xprocessing.XElements.getSimpleName; import static javax.lang.model.element.Modifier.PROTECTED; import static javax.lang.model.element.Modifier.PUBLIC; @@ -47,7 +46,7 @@ public final class MethodSpecs { builder.addModifiers(PROTECTED); } for (int i = 0; i < methodType.getParameterTypes().size(); i++) { - String parameterName = getSimpleName(method.getParameters().get(i)); + String parameterName = method.getParameters().get(i).getJvmName(); TypeName parameterType = methodType.getParameterTypes().get(i).getTypeName(); builder.addParameter(ParameterSpec.builder(parameterType, parameterName).build()); } diff --git a/java/dagger/internal/codegen/xprocessing/XElements.java b/java/dagger/internal/codegen/xprocessing/XElements.java index 552be65f9..b63d4d93d 100644 --- a/java/dagger/internal/codegen/xprocessing/XElements.java +++ b/java/dagger/internal/codegen/xprocessing/XElements.java @@ -47,6 +47,7 @@ import androidx.room.compiler.processing.XProcessingEnv; import androidx.room.compiler.processing.XTypeElement; import androidx.room.compiler.processing.XTypeParameterElement; import androidx.room.compiler.processing.XVariableElement; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.devtools.ksp.symbol.KSAnnotated; import com.squareup.javapoet.ClassName; @@ -54,6 +55,7 @@ import java.util.Collection; import java.util.Optional; import javax.annotation.Nullable; import javax.lang.model.element.ElementKind; +import javax.lang.model.element.Modifier; // TODO(bcorso): Consider moving these methods into XProcessing library. /** A utility class for {@link XElement} helper methods. */ @@ -383,5 +385,37 @@ public final class XElements { return element.getClosestMemberContainer().asClassName().getPackageName(); } + public static boolean isFinal(XExecutableElement element) { + if (element.isFinal()) { + return true; + } + if (getProcessingEnv(element).getBackend() == XProcessingEnv.Backend.KSP) { + if (toKS(element).getModifiers().contains(com.google.devtools.ksp.symbol.Modifier.FINAL)) { + return true; + } + } + return false; + } + + public static ImmutableList<Modifier> getModifiers(XExecutableElement element) { + ImmutableList.Builder<Modifier> builder = ImmutableList.builder(); + if (isFinal(element)) { + builder.add(Modifier.FINAL); + } else if (element.isAbstract()) { + builder.add(Modifier.ABSTRACT); + } + if (element.isStatic()) { + builder.add(Modifier.STATIC); + } + if (element.isPublic()) { + builder.add(Modifier.PUBLIC); + } else if (element.isPrivate()) { + builder.add(Modifier.PRIVATE); + } else if (element.isProtected()) { + builder.add(Modifier.PROTECTED); + } + return builder.build(); + } + private XElements() {} } diff --git a/java/dagger/internal/codegen/xprocessing/XMethodElements.java b/java/dagger/internal/codegen/xprocessing/XMethodElements.java index 3066d797e..cbff642c3 100644 --- a/java/dagger/internal/codegen/xprocessing/XMethodElements.java +++ b/java/dagger/internal/codegen/xprocessing/XMethodElements.java @@ -16,11 +16,8 @@ package dagger.internal.codegen.xprocessing; -import static androidx.room.compiler.processing.compat.XConverters.getProcessingEnv; -import static androidx.room.compiler.processing.compat.XConverters.toJavac; import androidx.room.compiler.processing.XMethodElement; -import androidx.room.compiler.processing.XProcessingEnv; import androidx.room.compiler.processing.XTypeElement; // TODO(bcorso): Consider moving these methods into XProcessing library. @@ -40,19 +37,5 @@ public final class XMethodElements { return !method.getExecutableType().getTypeVariableNames().isEmpty(); } - // TODO(b/278628663): Replace with XMethodElement#isDefault. - public static boolean isDefault(XMethodElement method) { - XProcessingEnv processingEnv = getProcessingEnv(method); - switch (processingEnv.getBackend()) { - case JAVAC: - return toJavac(method).isDefault(); - case KSP: - throw new AssertionError( - "XMethodElement#isDefault() is not supported on KSP yet: " - + XElements.toStableString(method)); - } - throw new AssertionError(String.format("Unsupported backend %s", processingEnv.getBackend())); - } - private XMethodElements() {} } diff --git a/java/dagger/internal/codegen/xprocessing/XTypeElements.java b/java/dagger/internal/codegen/xprocessing/XTypeElements.java index 6d9c56486..7330b8f6a 100644 --- a/java/dagger/internal/codegen/xprocessing/XTypeElements.java +++ b/java/dagger/internal/codegen/xprocessing/XTypeElements.java @@ -16,21 +16,16 @@ package dagger.internal.codegen.xprocessing; -import static androidx.room.compiler.processing.compat.XConverters.getProcessingEnv; import static com.google.common.base.Preconditions.checkNotNull; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; import static kotlin.streams.jdk8.StreamsKt.asStream; import androidx.room.compiler.processing.XHasModifiers; import androidx.room.compiler.processing.XMethodElement; -import androidx.room.compiler.processing.XProcessingEnv; import androidx.room.compiler.processing.XTypeElement; import androidx.room.compiler.processing.XTypeParameterElement; -import androidx.room.compiler.processing.compat.XConverters; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; -import com.google.devtools.ksp.symbol.Origin; -import com.squareup.javapoet.ClassName; import com.squareup.javapoet.TypeVariableName; // TODO(bcorso): Consider moving these methods into XProcessing library. @@ -142,20 +137,5 @@ public final class XTypeElements { return visibilities.build(); } - /** Returns true if the source of the given type element is Kotlin. */ - public static boolean isKotlinSource(XTypeElement typeElement) { - XProcessingEnv processingEnv = getProcessingEnv(typeElement); - switch (processingEnv.getBackend()) { - case KSP: - // If this is KSP, then we should be able to check the origin of the declaration. - Origin origin = XConverters.toKS(typeElement).getOrigin(); - return origin == Origin.KOTLIN || origin == Origin.KOTLIN_LIB; - case JAVAC: - // If this is KAPT, then the java stubs should have kotlin metadata. - return typeElement.hasAnnotation(ClassName.get("kotlin", "Metadata")); - } - throw new AssertionError("Unhandled backend kind: " + processingEnv.getBackend()); - } - private XTypeElements() {} } diff --git a/java/dagger/internal/codegen/xprocessing/XTypes.java b/java/dagger/internal/codegen/xprocessing/XTypes.java index 654ce697a..7f4b77aac 100644 --- a/java/dagger/internal/codegen/xprocessing/XTypes.java +++ b/java/dagger/internal/codegen/xprocessing/XTypes.java @@ -388,12 +388,46 @@ public final class XTypes { * {@link Optional} is returned if there is no non-{@link Object} superclass. */ public static Optional<XType> nonObjectSuperclass(XType type) { - return isDeclared(type) - ? type.getSuperTypes().stream() - .filter(supertype -> !supertype.getTypeName().equals(TypeName.OBJECT)) - .filter(supertype -> isDeclared(supertype) && supertype.getTypeElement().isClass()) - .collect(toOptional()) - : Optional.empty(); + if (!isDeclared(type)) { + return Optional.empty(); + } + // We compare elements (rather than TypeName) here because its more efficient on the heap. + XTypeElement objectElement = objectElement(getProcessingEnv(type)); + XTypeElement typeElement = type.getTypeElement(); + if (!typeElement.isClass() || typeElement.equals(objectElement)) { + return Optional.empty(); + } + XType superClass = typeElement.getSuperClass(); + if (!isDeclared(superClass)) { + return Optional.empty(); + } + XTypeElement superClassElement = superClass.getTypeElement(); + if (!superClassElement.isClass() || superClassElement.equals(objectElement)) { + return Optional.empty(); + } + // TODO(b/310954522): XType#getSuperTypes() is less efficient (especially on the heap) as it + // requires creating XType for not just superclass but all super interfaces as well, so we go + // through a bit of effort here to avoid that call unless its absolutely necessary since + // nonObjectSuperclass is called quite a bit via InjectionSiteFactory. However, we should + // eventually optimize this on the XProcessing side instead, e.g. maybe separating + // XType#getSuperClass() into a separate method. + return superClass.getTypeArguments().isEmpty() + ? Optional.of(superClass) + : type.getSuperTypes().stream() + .filter(XTypes::isDeclared) + .filter(supertype -> supertype.getTypeElement().isClass()) + .filter(supertype -> !supertype.getTypeElement().equals(objectElement)) + .collect(toOptional()); + } + + private static XTypeElement objectElement(XProcessingEnv processingEnv) { + switch (processingEnv.getBackend()) { + case JAVAC: + return processingEnv.requireTypeElement(TypeName.OBJECT); + case KSP: + return processingEnv.requireTypeElement("kotlin.Any"); + } + throw new AssertionError("Unexpected backend: " + processingEnv.getBackend()); } /** diff --git a/java/dagger/internal/codegen/xprocessing/xprocessing-testing.jar b/java/dagger/internal/codegen/xprocessing/xprocessing-testing.jar Binary files differindex 7811751e0..4d0d7fd00 100644 --- a/java/dagger/internal/codegen/xprocessing/xprocessing-testing.jar +++ b/java/dagger/internal/codegen/xprocessing/xprocessing-testing.jar diff --git a/java/dagger/internal/codegen/xprocessing/xprocessing.jar b/java/dagger/internal/codegen/xprocessing/xprocessing.jar Binary files differindex 1c41e2053..24590f84d 100644 --- a/java/dagger/internal/codegen/xprocessing/xprocessing.jar +++ b/java/dagger/internal/codegen/xprocessing/xprocessing.jar diff --git a/java/dagger/lint/DaggerKotlinIssueDetector.kt b/java/dagger/lint/DaggerKotlinIssueDetector.kt index 8ca862309..6a4a33ca6 100644 --- a/java/dagger/lint/DaggerKotlinIssueDetector.kt +++ b/java/dagger/lint/DaggerKotlinIssueDetector.kt @@ -204,7 +204,8 @@ class DaggerKotlinIssueDetector : Detector(), SourceCodeScanner { ) { val containingClass = node.containingClass?.toUElement(UClass::class.java) ?: return if (containingClass.isObject()) { - val annotation = node.findAnnotation(JVM_STATIC_ANNOTATION)!! + val annotation = node.findAnnotation(JVM_STATIC_ANNOTATION) + ?: node.javaPsi.modifierList.findAnnotation(JVM_STATIC_ANNOTATION)!! context.report( ISSUE_JVM_STATIC_PROVIDES_IN_OBJECT, context.getLocation(annotation), diff --git a/java/dagger/model/BUILD b/java/dagger/model/BUILD index aaa830601..1a672dc03 100644 --- a/java/dagger/model/BUILD +++ b/java/dagger/model/BUILD @@ -44,7 +44,6 @@ java_library( deps = [ "//java/dagger:core", "//java/dagger/internal/codegen/extension", - "//java/dagger/producers", "//third_party/java/auto:common", "//third_party/java/auto:value", "//third_party/java/error_prone:annotations", diff --git a/java/dagger/model/BindingGraph.java b/java/dagger/model/BindingGraph.java index 1ccba4326..d09bf02c1 100644 --- a/java/dagger/model/BindingGraph.java +++ b/java/dagger/model/BindingGraph.java @@ -43,14 +43,13 @@ import javax.lang.model.element.TypeElement; * <p>A {@link BindingGraph} represents one of the following: * * <ul> - * <li>an entire component hierarchy rooted at a {@link dagger.Component} or {@link - * dagger.producers.ProductionComponent} - * <li>a partial component hierarchy rooted at a {@link dagger.Subcomponent} or {@link - * dagger.producers.ProductionSubcomponent} (only when the value of {@code - * -Adagger.fullBindingGraphValidation} is not {@code NONE}) - * <li>the bindings installed by a {@link Module} or {@link dagger.producers.ProducerModule}, - * including all subcomponents generated by {@link Module#subcomponents()} ()} and {@link - * dagger.producers.ProducerModule#subcomponents()} ()} + * <li>an entire component hierarchy rooted at a {@code Component} or {@code ProductionComponent} + * <li>a partial component hierarchy rooted at a {@code Subcomponent} or + * {@code ProductionSubcomponent} (only when the value of + * {@code -Adagger.fullBindingGraphValidation} is not {@code NONE}) + * <li>the bindings installed by a {@code Module} or {@code ProducerModule}, + * including all subcomponents generated by {@code Module#subcomponents()} and + * {@code ProducerModule#subcomponents()} * </ul> * * In the case of a {@link BindingGraph} representing a module, the root {@link ComponentNode} will diff --git a/java/dagger/model/BindingKind.java b/java/dagger/model/BindingKind.java index 1bfb08098..46d11309a 100644 --- a/java/dagger/model/BindingKind.java +++ b/java/dagger/model/BindingKind.java @@ -34,8 +34,7 @@ public enum BindingKind { ASSISTED_FACTORY, /** - * An implicit binding for a {@link dagger.Component}- or {@link - * dagger.producers.ProductionComponent}-annotated type. + * An implicit binding for a {@code Component}- or {@code ProductionComponent}-annotated type. */ COMPONENT, @@ -65,14 +64,13 @@ public enum BindingKind { /** A binding for a {@link dagger.BindsInstance}-annotated builder method. */ BOUND_INSTANCE, - /** A binding for a {@link dagger.producers.Produces}-annotated method. */ + /** A binding for a {@code Produces}-annotated method. */ PRODUCTION, /** - * A binding for a production method on a production component's {@linkplain - * dagger.producers.ProductionComponent#dependencies()} dependency} that returns a {@link - * com.google.common.util.concurrent.ListenableFuture} or {@link - * com.google.common.util.concurrent.FluentFuture}. Methods on production component dependencies + * A binding for a production method on a production component's + * {@code ProductionComponent#dependencies()} that returns a {@code ListenableFuture} or + * {@code FluentFuture}. Methods on production component dependencies * that don't return a future are considered {@linkplain #COMPONENT_PROVISION component provision * bindings}. */ diff --git a/java/dagger/model/ComponentPath.java b/java/dagger/model/ComponentPath.java index 5a74c7a51..9dfdbf93e 100644 --- a/java/dagger/model/ComponentPath.java +++ b/java/dagger/model/ComponentPath.java @@ -40,8 +40,7 @@ public abstract class ComponentPath { public abstract ImmutableList<TypeElement> components(); /** - * Returns the root {@link dagger.Component}- or {@link - * dagger.producers.ProductionComponent}-annotated type + * Returns the root {@code Component}- or {@code ProductionComponent}-annotated type */ public final TypeElement rootComponent() { return components().get(0); diff --git a/java/dagger/model/RequestKind.java b/java/dagger/model/RequestKind.java index 74a434633..6a19b0a08 100644 --- a/java/dagger/model/RequestKind.java +++ b/java/dagger/model/RequestKind.java @@ -19,11 +19,6 @@ package dagger.model; import static com.google.common.base.CaseFormat.UPPER_CAMEL; import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE; -import dagger.Lazy; -import dagger.producers.Produced; -import dagger.producers.Producer; -import javax.inject.Provider; - /** * Represents the different kinds of {@link javax.lang.model.type.TypeMirror types} that may be * requested as dependencies for the same key. For example, {@code String}, {@code @@ -35,13 +30,13 @@ public enum RequestKind { /** A default request for an instance. E.g.: {@code FooType} */ INSTANCE, - /** A request for a {@link Provider}. E.g.: {@code Provider<FooType>} */ + /** A request for a {@code Provider}. E.g.: {@code Provider<FooType>} */ PROVIDER, - /** A request for a {@link Lazy}. E.g.: {@code Lazy<FooType>} */ + /** A request for a {@code Lazy}. E.g.: {@code Lazy<FooType>} */ LAZY, - /** A request for a {@link Provider} of a {@link Lazy}. E.g.: {@code Provider<Lazy<FooType>>} */ + /** A request for a {@code Provider} of a {@code Lazy}. E.g.: {@code Provider<Lazy<FooType>>} */ PROVIDER_OF_LAZY, /** @@ -50,15 +45,15 @@ public enum RequestKind { */ MEMBERS_INJECTION, - /** A request for a {@link Producer}. E.g.: {@code Producer<FooType>} */ + /** A request for a {@code Producer}. E.g.: {@code Producer<FooType>} */ PRODUCER, - /** A request for a {@link Produced}. E.g.: {@code Produced<FooType>} */ + /** A request for a {@code Produced}. E.g.: {@code Produced<FooType>} */ PRODUCED, /** - * A request for a {@link com.google.common.util.concurrent.ListenableFuture}. E.g.: {@code - * ListenableFuture<FooType>}. These can only be requested by component interfaces. + * A request for a {@code ListenableFuture}. E.g.: {@code ListenableFuture<FooType>}. These can + * only be requested by component interfaces. */ FUTURE, ; diff --git a/java/dagger/model/Scope.java b/java/dagger/model/Scope.java index c7ebfa811..fe64c86d4 100644 --- a/java/dagger/model/Scope.java +++ b/java/dagger/model/Scope.java @@ -26,7 +26,6 @@ import com.google.auto.value.AutoValue; import com.google.common.base.Equivalence; import com.squareup.javapoet.ClassName; import dagger.Reusable; -import dagger.producers.ProductionScope; import javax.inject.Singleton; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.TypeElement; @@ -88,7 +87,7 @@ public abstract class Scope { return isScope(REUSABLE); } - /** Returns {@code true} if this scope is the {@link ProductionScope @ProductionScope} scope. */ + /** Returns {@code true} if this scope is the {@code @ProductionScope} scope. */ public final boolean isProductionScope() { return isScope(PRODUCTION_SCOPE); } diff --git a/java/dagger/multibindings/LazyClassKey.java b/java/dagger/multibindings/LazyClassKey.java new file mode 100644 index 000000000..da46984e3 --- /dev/null +++ b/java/dagger/multibindings/LazyClassKey.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2024 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.multibindings; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import dagger.MapKey; +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * A {@link MapKey} annotation for maps with {@code Class<?>} keys. + * + * <p>The difference from {@link ClassKey} is that dagger generates a string representation for the + * class to use under the hood, which prevents loading unused classes at runtime. + */ +@Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE}) +@Retention(RUNTIME) +@Documented +@MapKey +public @interface LazyClassKey { + Class<?> value(); +} diff --git a/java/dagger/producers/internal/AbstractMapProducer.java b/java/dagger/producers/internal/AbstractMapProducer.java index c60f0cb07..360f1eb8e 100644 --- a/java/dagger/producers/internal/AbstractMapProducer.java +++ b/java/dagger/producers/internal/AbstractMapProducer.java @@ -17,12 +17,13 @@ package dagger.producers.internal; import static com.google.common.base.Preconditions.checkNotNull; +import static dagger.internal.Providers.asDaggerProvider; import static dagger.producers.internal.Producers.producerFromProvider; import com.google.common.collect.ImmutableMap; +import dagger.internal.Provider; import dagger.producers.Producer; import java.util.Map; -import javax.inject.Provider; /** * An {@code abstract} {@link Producer} implementation used to implement {@link Map} bindings. @@ -76,6 +77,15 @@ abstract class AbstractMapProducer<K, V, V2> extends AbstractProducer<Map<K, V2> return this; } + /** + * Legacy javax version of the method to support libraries compiled with an older version of + * Dagger. Do not use directly. + */ + @Deprecated + Builder<K, V, V2> put(K key, javax.inject.Provider<V> providerOfValue) { + return put(key, asDaggerProvider(providerOfValue)); + } + /** Adds contributions from a super-implementation of a component into this builder. */ Builder<K, V, V2> putAll(Producer<Map<K, V2>> mapOfProducers) { if (mapOfProducers instanceof DelegateProducer) { diff --git a/java/dagger/producers/internal/AbstractProducesMethodProducer.java b/java/dagger/producers/internal/AbstractProducesMethodProducer.java index 0cf36ca53..95b8f8340 100644 --- a/java/dagger/producers/internal/AbstractProducesMethodProducer.java +++ b/java/dagger/producers/internal/AbstractProducesMethodProducer.java @@ -17,15 +17,16 @@ package dagger.producers.internal; import static dagger.internal.Preconditions.checkNotNull; +import static dagger.internal.Providers.asDaggerProvider; import com.google.common.util.concurrent.AsyncFunction; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; +import dagger.internal.Provider; import dagger.producers.monitoring.ProducerMonitor; import dagger.producers.monitoring.ProducerToken; import dagger.producers.monitoring.ProductionComponentMonitor; import java.util.concurrent.Executor; -import javax.inject.Provider; import org.checkerframework.checker.nullness.compatqual.NullableDecl; /** @@ -54,6 +55,18 @@ public abstract class AbstractProducesMethodProducer<D, T> extends AbstractProdu this.executorProvider = checkNotNull(executorProvider); } + /** + * Legacy javax version of the method to support libraries compiled with an older version of + * Dagger. Do not use directly. + */ + @Deprecated + protected AbstractProducesMethodProducer( + javax.inject.Provider<ProductionComponentMonitor> monitorProvider, + @NullableDecl ProducerToken token, + javax.inject.Provider<Executor> executorProvider) { + this(asDaggerProvider(monitorProvider), token, asDaggerProvider(executorProvider)); + } + @Override protected final ListenableFuture<T> compute() { monitor = monitorProvider.get().producerMonitorFor(token); diff --git a/java/dagger/producers/internal/DelegateProducer.java b/java/dagger/producers/internal/DelegateProducer.java index 6cc7547c3..de29234ac 100644 --- a/java/dagger/producers/internal/DelegateProducer.java +++ b/java/dagger/producers/internal/DelegateProducer.java @@ -20,8 +20,8 @@ import static dagger.internal.Preconditions.checkNotNull; import com.google.common.util.concurrent.ListenableFuture; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import dagger.producers.Producer; -import javax.inject.Provider; /** * A DelegateProducer that is used to stitch Producer indirection during initialization across diff --git a/java/dagger/producers/internal/MapOfProducedProducer.java b/java/dagger/producers/internal/MapOfProducedProducer.java index bd9f1bfcc..3db774094 100644 --- a/java/dagger/producers/internal/MapOfProducedProducer.java +++ b/java/dagger/producers/internal/MapOfProducedProducer.java @@ -18,6 +18,7 @@ package dagger.producers.internal; import static com.google.common.util.concurrent.Futures.transform; import static com.google.common.util.concurrent.MoreExecutors.directExecutor; +import static dagger.internal.Providers.asDaggerProvider; import com.google.common.base.Function; import com.google.common.collect.ImmutableMap; @@ -25,11 +26,11 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Maps; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; +import dagger.internal.Provider; import dagger.producers.Produced; import dagger.producers.Producer; import java.util.List; import java.util.Map; -import javax.inject.Provider; /** * A {@link Producer} implementation used to implement {@link Map} bindings. This producer returns a @@ -108,6 +109,15 @@ public final class MapOfProducedProducer<K, V> extends AbstractMapProducer<K, V, return this; } + /** + * Legacy javax version of the method to support libraries compiled with an older version of + * Dagger. Do not use directly. + */ + @Deprecated + public Builder<K, V> put(K key, javax.inject.Provider<V> providerOfValue) { + return put(key, asDaggerProvider(providerOfValue)); + } + @Override public Builder<K, V> putAll(Producer<Map<K, Produced<V>>> mapOfProducedProducer) { super.putAll(mapOfProducedProducer); diff --git a/java/dagger/producers/internal/MapOfProducerProducer.java b/java/dagger/producers/internal/MapOfProducerProducer.java index 064cf7499..145ea6db6 100644 --- a/java/dagger/producers/internal/MapOfProducerProducer.java +++ b/java/dagger/producers/internal/MapOfProducerProducer.java @@ -16,6 +16,7 @@ package dagger.producers.internal; +import static dagger.internal.Providers.asDaggerProvider; import static dagger.producers.internal.Producers.entryPointViewOf; import static dagger.producers.internal.Producers.nonCancellationPropagatingViewOf; @@ -24,9 +25,9 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; +import dagger.internal.Provider; import dagger.producers.Producer; import java.util.Map; -import javax.inject.Provider; /** * A {@link Producer} implementation used to implement {@link Map} bindings. This factory returns an @@ -65,6 +66,15 @@ public final class MapOfProducerProducer<K, V> extends AbstractMapProducer<K, V, return this; } + /** + * Legacy javax version of the method to support libraries compiled with an older version of + * Dagger. Do not use directly. + */ + @Deprecated + public Builder<K, V> put(K key, javax.inject.Provider<V> providerOfValue) { + return put(key, asDaggerProvider(providerOfValue)); + } + @Override public Builder<K, V> putAll(Producer<Map<K, Producer<V>>> mapOfProducerProducer) { super.putAll(mapOfProducerProducer); diff --git a/java/dagger/producers/internal/MapProducer.java b/java/dagger/producers/internal/MapProducer.java index 8caeb45cb..c832ef402 100644 --- a/java/dagger/producers/internal/MapProducer.java +++ b/java/dagger/producers/internal/MapProducer.java @@ -17,18 +17,19 @@ package dagger.producers.internal; import static com.google.common.util.concurrent.MoreExecutors.directExecutor; +import static dagger.internal.Providers.asDaggerProvider; import com.google.common.base.Function; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; +import dagger.internal.Provider; import dagger.producers.Producer; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import javax.inject.Provider; /** * A {@link Producer} implementation used to implement {@link Map} bindings. This producer returns a @@ -62,6 +63,15 @@ public final class MapProducer<K, V> extends AbstractMapProducer<K, V, V> { return this; } + /** + * Legacy javax version of the method to support libraries compiled with an older version of + * Dagger. Do not use directly. + */ + @Deprecated + public Builder<K, V> put(K key, javax.inject.Provider<V> providerOfValue) { + return put(key, asDaggerProvider(providerOfValue)); + } + @Override public Builder<K, V> putAll(Producer<Map<K, V>> mapProducer) { super.putAll(mapProducer); diff --git a/java/dagger/producers/internal/Producers.java b/java/dagger/producers/internal/Producers.java index 54e4d5ee3..9385ee326 100644 --- a/java/dagger/producers/internal/Producers.java +++ b/java/dagger/producers/internal/Producers.java @@ -20,6 +20,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.util.concurrent.Futures.catchingAsync; import static com.google.common.util.concurrent.Futures.transform; import static com.google.common.util.concurrent.MoreExecutors.directExecutor; +import static dagger.internal.Providers.asDaggerProvider; import com.google.common.base.Function; import com.google.common.collect.ImmutableMap; @@ -27,12 +28,12 @@ import com.google.common.collect.ImmutableSet; import com.google.common.util.concurrent.AsyncFunction; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; +import dagger.internal.Provider; import dagger.producers.Produced; import dagger.producers.Producer; import java.util.List; import java.util.Map; import java.util.Set; -import javax.inject.Provider; /** * Utility methods for use in generated producer code. @@ -135,6 +136,15 @@ public final class Producers { } /** + * Legacy javax version of the method to support libraries compiled with an older version of + * Dagger. Do not use directly. + */ + @Deprecated + public static <T> Producer<T> producerFromProvider(final javax.inject.Provider<T> provider) { + return producerFromProvider(asDaggerProvider(provider)); + } + + /** * Returns a producer that succeeds with the given value. * * @deprecated Prefer the non-internal version of this method: {@link diff --git a/java/dagger/proguard.pro b/java/dagger/proguard.pro new file mode 100644 index 000000000..1bfc94749 --- /dev/null +++ b/java/dagger/proguard.pro @@ -0,0 +1,3 @@ +-keepclasseswithmembers,includedescriptorclasses class * { + @dagger.internal.KeepFieldType <fields>; +}
\ No newline at end of file diff --git a/java/dagger/r8.pro b/java/dagger/r8.pro new file mode 100644 index 000000000..17e0ffe6d --- /dev/null +++ b/java/dagger/r8.pro @@ -0,0 +1,3 @@ +-identifiernamestring @dagger.internal.IdentifierNameString class ** { + static java.lang.String *; +}
\ No newline at end of file diff --git a/java/dagger/spi/BUILD b/java/dagger/spi/BUILD index 13428c1a4..8084e6396 100644 --- a/java/dagger/spi/BUILD +++ b/java/dagger/spi/BUILD @@ -63,7 +63,6 @@ gen_maven_artifact( ], artifact_target_maven_deps = [ "com.google.code.findbugs:jsr305", - "com.google.dagger:dagger-producers", "com.google.dagger:dagger", "com.google.devtools.ksp:symbol-processing-api", "com.google.guava:failureaccess", diff --git a/java/dagger/spi/model/BUILD b/java/dagger/spi/model/BUILD index e9346ddf6..e5af4e50b 100644 --- a/java/dagger/spi/model/BUILD +++ b/java/dagger/spi/model/BUILD @@ -40,7 +40,6 @@ kt_jvm_library( deps = [ "//java/dagger:core", "//java/dagger/internal/codegen/extension", - "//java/dagger/producers", "//third_party/java/auto:common", "//third_party/java/auto:value", "//third_party/java/error_prone:annotations", @@ -48,7 +47,6 @@ kt_jvm_library( "//third_party/java/guava/collect", "//third_party/java/guava/graph", "//third_party/java/javapoet", - "//third_party/java/jsr305_annotations", "//third_party/java/jsr330_inject", "@maven//:com_google_devtools_ksp_symbol_processing_api", ], diff --git a/java/dagger/spi/model/BindingGraph.java b/java/dagger/spi/model/BindingGraph.java index aab7c2a4b..7f433a1e0 100644 --- a/java/dagger/spi/model/BindingGraph.java +++ b/java/dagger/spi/model/BindingGraph.java @@ -41,14 +41,14 @@ import java.util.stream.Stream; * <p>A {@link BindingGraph} represents one of the following: * * <ul> - * <li>an entire component hierarchy rooted at a {@link dagger.Component} or {@link - * dagger.producers.ProductionComponent} - * <li>a partial component hierarchy rooted at a {@link dagger.Subcomponent} or {@link - * dagger.producers.ProductionSubcomponent} (only when the value of {@code - * -Adagger.fullBindingGraphValidation} is not {@code NONE}) - * <li>the bindings installed by a {@link Module} or {@link dagger.producers.ProducerModule}, - * including all subcomponents generated by {@link Module#subcomponents()} ()} and {@link - * dagger.producers.ProducerModule#subcomponents()} ()} + * <li>an entire component hierarchy rooted at a {@link dagger.Component} or + * {@code ProductionComponent} + * <li>a partial component hierarchy rooted at a {@link dagger.Subcomponent} or + * {@code ProductionSubcomponent} (only when the value of + * {@code -Adagger.fullBindingGraphValidation} is not {@code NONE}) + * <li>the bindings installed by a {@link Module} or {@code ProducerModule}, + * including all subcomponents generated by {@link Module#subcomponents()} ()} and + * {@code ProducerModule#subcomponents()} ()} * </ul> * * In the case of a {@link BindingGraph} representing a module, the root {@link ComponentNode} will diff --git a/java/dagger/spi/model/BindingKind.java b/java/dagger/spi/model/BindingKind.java index b854b5300..eb1e83501 100644 --- a/java/dagger/spi/model/BindingKind.java +++ b/java/dagger/spi/model/BindingKind.java @@ -34,8 +34,8 @@ public enum BindingKind { ASSISTED_FACTORY, /** - * An implicit binding for a {@link dagger.Component}- or {@link - * dagger.producers.ProductionComponent}-annotated type. + * An implicit binding for a {@link dagger.Component}- or {@code ProductionComponent}-annotated + * type. */ COMPONENT, @@ -65,16 +65,14 @@ public enum BindingKind { /** A binding for a {@link dagger.BindsInstance}-annotated builder method. */ BOUND_INSTANCE, - /** A binding for a {@link dagger.producers.Produces}-annotated method. */ + /** A binding for a {@code Produces}-annotated method. */ PRODUCTION, /** - * A binding for a production method on a production component's {@linkplain - * dagger.producers.ProductionComponent#dependencies()} dependency} that returns a {@link - * com.google.common.util.concurrent.ListenableFuture} or {@link - * com.google.common.util.concurrent.FluentFuture}. Methods on production component dependencies - * that don't return a future are considered {@linkplain #COMPONENT_PROVISION component provision - * bindings}. + * A binding for a production method on a production component's + * {@code ProductionComponent#dependencies()} that returns a {@code ListenableFuture} or + * {@code FluentFuture}. Methods on production component dependencies + * that don't return a future are considered component provision bindings. */ COMPONENT_PRODUCTION, diff --git a/java/dagger/spi/model/ComponentPath.java b/java/dagger/spi/model/ComponentPath.java index 63a5f6b90..11c811e26 100644 --- a/java/dagger/spi/model/ComponentPath.java +++ b/java/dagger/spi/model/ComponentPath.java @@ -39,8 +39,7 @@ public abstract class ComponentPath { public abstract ImmutableList<DaggerTypeElement> components(); /** - * Returns the root {@link dagger.Component}- or {@link - * dagger.producers.ProductionComponent}-annotated type + * Returns the root {@code Component}- or {@code ProductionComponent}-annotated type */ public final DaggerTypeElement rootComponent() { return components().get(0); @@ -89,7 +88,7 @@ public abstract class ComponentPath { @Override public final String toString() { - return components().stream().map(DaggerTypeElement::qualifiedName).collect(joining(" → ")); + return components().stream().map(Key::qualifiedName).collect(joining(" → ")); } @Memoized diff --git a/java/dagger/spi/model/DaggerAnnotation.java b/java/dagger/spi/model/DaggerAnnotation.java index 2ec66c010..5b590033f 100644 --- a/java/dagger/spi/model/DaggerAnnotation.java +++ b/java/dagger/spi/model/DaggerAnnotation.java @@ -16,55 +16,29 @@ package dagger.spi.model; -import com.google.auto.common.AnnotationMirrors; -import com.google.auto.value.AutoValue; import com.google.devtools.ksp.symbol.KSAnnotation; -import javax.annotation.Nullable; +import com.google.errorprone.annotations.DoNotMock; import javax.lang.model.element.AnnotationMirror; /** Wrapper type for an annotation. */ -@AutoValue +@DoNotMock("Only use real implementations created by Dagger") public abstract class DaggerAnnotation { - public static DaggerAnnotation fromJavac( - DaggerTypeElement annotationTypeElement, AnnotationMirror annotation) { - return new AutoValue_DaggerAnnotation(annotationTypeElement, annotation, null); - } - - public static DaggerAnnotation fromKsp( - DaggerTypeElement annotationTypeElement, KSAnnotation ksp) { - return new AutoValue_DaggerAnnotation(annotationTypeElement, null, ksp); - } - public abstract DaggerTypeElement annotationTypeElement(); /** - * java representation for the annotation, returns {@code null} if the annotation isn't a java - * element. + * Returns the Javac representation for the annotation. + * + * @throws IllegalStateException if the current backend isn't Javac. */ - @Nullable - public abstract AnnotationMirror java(); + public abstract AnnotationMirror javac(); - /** KSP declaration for the annotation, returns {@code null} not using KSP. */ - @Nullable + /** + * Returns the KSP representation for the annotation. + * + * @throws IllegalStateException if the current backend isn't KSP. + */ public abstract KSAnnotation ksp(); - public DaggerProcessingEnv.Backend backend() { - if (java() != null) { - return DaggerProcessingEnv.Backend.JAVAC; - } else if (ksp() != null) { - return DaggerProcessingEnv.Backend.KSP; - } - throw new AssertionError("Unexpected backend"); - } - - @Override - public final String toString() { - switch (backend()) { - case JAVAC: - return AnnotationMirrors.toString(java()); - case KSP: - return ksp().toString(); - } - throw new IllegalStateException(String.format("Backend %s not supported yet.", backend())); - } + /** Returns the backend used in this compilation. */ + public abstract DaggerProcessingEnv.Backend backend(); } diff --git a/java/dagger/spi/model/DaggerElement.java b/java/dagger/spi/model/DaggerElement.java index 0f6a2cf35..0c0c53ebf 100644 --- a/java/dagger/spi/model/DaggerElement.java +++ b/java/dagger/spi/model/DaggerElement.java @@ -16,49 +16,27 @@ package dagger.spi.model; -import com.google.auto.value.AutoValue; import com.google.devtools.ksp.symbol.KSAnnotated; -import javax.annotation.Nullable; +import com.google.errorprone.annotations.DoNotMock; import javax.lang.model.element.Element; /** Wrapper type for an element. */ -@AutoValue +@DoNotMock("Only use real implementations created by Dagger") public abstract class DaggerElement { - public static DaggerElement fromJavac(Element element) { - return new AutoValue_DaggerElement(element, null); - } - - public static DaggerElement fromKsp(KSAnnotated ksp) { - return new AutoValue_DaggerElement(null, ksp); - } - /** - * Java representation for the element, returns {@code null} not using java annotation processor. + * Returns the Javac representation for the element. + * + * @throws IllegalStateException if the current backend isn't Javac. */ - @Nullable - public abstract Element java(); + public abstract Element javac(); - /** KSP declaration for the element, returns {@code null} not using KSP. */ - @Nullable + /** + * Returns the KSP representation for the element. + * + * @throws IllegalStateException if the current backend isn't KSP. + */ public abstract KSAnnotated ksp(); - public DaggerProcessingEnv.Backend backend() { - if (java() != null) { - return DaggerProcessingEnv.Backend.JAVAC; - } else if (ksp() != null) { - return DaggerProcessingEnv.Backend.KSP; - } - throw new AssertionError("Unexpected backend"); - } - - @Override - public final String toString() { - switch (backend()) { - case JAVAC: - return java().toString(); - case KSP: - return ksp().toString(); - } - throw new IllegalStateException(String.format("Backend %s not supported yet.", backend())); - } + /** Returns the backend used in this compilation. */ + public abstract DaggerProcessingEnv.Backend backend(); } diff --git a/java/dagger/spi/model/DaggerExecutableElement.java b/java/dagger/spi/model/DaggerExecutableElement.java index 7df6a1e38..afbd8e001 100644 --- a/java/dagger/spi/model/DaggerExecutableElement.java +++ b/java/dagger/spi/model/DaggerExecutableElement.java @@ -16,59 +16,27 @@ package dagger.spi.model; -import com.google.auto.value.AutoValue; import com.google.devtools.ksp.symbol.KSFunctionDeclaration; -import javax.annotation.Nullable; +import com.google.errorprone.annotations.DoNotMock; import javax.lang.model.element.ExecutableElement; /** Wrapper type for an executable element. */ -@AutoValue +@DoNotMock("Only use real implementations created by Dagger") public abstract class DaggerExecutableElement { - public static DaggerExecutableElement fromJava(ExecutableElement executableElement) { - return new AutoValue_DaggerExecutableElement(executableElement, null); - } - - public static DaggerExecutableElement fromKsp(KSFunctionDeclaration declaration) { - return new AutoValue_DaggerExecutableElement(null, declaration); - } - /** - * Java representation for the element, returns {@code null} not using java annotation processor. + * Returns the Javac representation for the executable element. + * + * @throws IllegalStateException if the current backend isn't Javac. */ - @Nullable - public abstract ExecutableElement java(); + public abstract ExecutableElement javac(); - /** KSP declaration for the element, returns {@code null} not using KSP. */ - @Nullable + /** + * Returns the KSP representation for the executable element. + * + * @throws IllegalStateException if the current backend isn't KSP. + */ public abstract KSFunctionDeclaration ksp(); - public DaggerProcessingEnv.Backend backend() { - if (java() != null) { - return DaggerProcessingEnv.Backend.JAVAC; - } else if (ksp() != null) { - return DaggerProcessingEnv.Backend.KSP; - } - throw new AssertionError("Unexpected backend"); - } - - @Override - public final String toString() { - switch (backend()) { - case JAVAC: - return java().toString(); - case KSP: - return ksp().toString(); - } - throw new IllegalStateException(String.format("Backend %s not supported yet.", backend())); - } - - String simpleName() { - switch (backend()) { - case JAVAC: - return java().getSimpleName().toString(); - case KSP: - return ksp().getSimpleName().toString(); - } - throw new IllegalStateException(String.format("Backend %s not supported yet.", backend())); - } + /** Returns the backend used in this compilation. */ + public abstract DaggerProcessingEnv.Backend backend(); } diff --git a/java/dagger/spi/model/DaggerProcessingEnv.java b/java/dagger/spi/model/DaggerProcessingEnv.java index 8c652c89d..ab2e33e5f 100644 --- a/java/dagger/spi/model/DaggerProcessingEnv.java +++ b/java/dagger/spi/model/DaggerProcessingEnv.java @@ -16,50 +16,41 @@ package dagger.spi.model; -import com.google.auto.value.AutoValue; import com.google.devtools.ksp.processing.Resolver; import com.google.devtools.ksp.processing.SymbolProcessorEnvironment; -import javax.annotation.Nullable; +import com.google.errorprone.annotations.DoNotMock; import javax.annotation.processing.ProcessingEnvironment; /** Wrapper type for an element. */ -@AutoValue +@DoNotMock("Only use real implementations created by Dagger") public abstract class DaggerProcessingEnv { /** Represents a type of backend used for compilation. */ - public enum Backend { JAVAC, KSP } - - public static boolean isJavac(Backend backend) { - return backend.equals(Backend.JAVAC); - } - - public static DaggerProcessingEnv fromJavac(ProcessingEnvironment env) { - return new AutoValue_DaggerProcessingEnv(env, null, null); - } - - public static DaggerProcessingEnv fromKsp(SymbolProcessorEnvironment env, Resolver resolver) { - return new AutoValue_DaggerProcessingEnv(null, env, resolver); + public enum Backend { + JAVAC, + KSP } /** - * Java representation for the processing environment, returns {@code null} not using java - * annotation processor. + * Returns the Javac representation for the processing environment. + * + * @throws IllegalStateException if the current backend isn't Javac. */ - @Nullable - public abstract ProcessingEnvironment java(); + public abstract ProcessingEnvironment javac(); - @Nullable + /** + * Returns the KSP representation for the processing environment. + * + * @throws IllegalStateException if the current backend isn't KSP. + */ public abstract SymbolProcessorEnvironment ksp(); - @Nullable + /** + * Returns the KSP representation for the resolver. + * + * @throws IllegalStateException if the current backend isn't KSP. + */ public abstract Resolver resolver(); /** Returns the backend used in this compilation. */ - public DaggerProcessingEnv.Backend backend() { - if (java() != null) { - return DaggerProcessingEnv.Backend.JAVAC; - } else if (ksp() != null) { - return DaggerProcessingEnv.Backend.KSP; - } - throw new AssertionError("Unexpected backend"); - } + public abstract DaggerProcessingEnv.Backend backend(); } diff --git a/java/dagger/spi/model/DaggerType.java b/java/dagger/spi/model/DaggerType.java index 249d49492..463350606 100644 --- a/java/dagger/spi/model/DaggerType.java +++ b/java/dagger/spi/model/DaggerType.java @@ -16,47 +16,27 @@ package dagger.spi.model; -import com.google.auto.value.AutoValue; import com.google.devtools.ksp.symbol.KSType; -import javax.annotation.Nullable; +import com.google.errorprone.annotations.DoNotMock; import javax.lang.model.type.TypeMirror; /** Wrapper type for a type. */ -@AutoValue +@DoNotMock("Only use real implementations created by Dagger") public abstract class DaggerType { - public static DaggerType fromJavac(TypeMirror type) { - return new AutoValue_DaggerType(type, null); - } - - public static DaggerType fromKsp(KSType type) { - return new AutoValue_DaggerType(null, type); - } - - /** Java representation for the type, returns {@code null} not using java annotation processor. */ - @Nullable - public abstract TypeMirror java(); - - /** KSP declaration for the type, returns {@code null} not using KSP. */ - @Nullable + /** + * Returns the Javac representation for the type. + * + * @throws IllegalStateException if the current backend isn't Javac. + */ + public abstract TypeMirror javac(); + + /** + * Returns the KSP representation for the type. + * + * @throws IllegalStateException if the current backend isn't KSP. + */ public abstract KSType ksp(); - public DaggerProcessingEnv.Backend backend() { - if (java() != null) { - return DaggerProcessingEnv.Backend.JAVAC; - } else if (ksp() != null) { - return DaggerProcessingEnv.Backend.KSP; - } - throw new AssertionError("Unexpected backend"); - } - - @Override - public final String toString() { - switch (backend()) { - case JAVAC: - return java().toString(); - case KSP: - return ksp().toString(); - } - throw new IllegalStateException(String.format("Backend %s not supported yet.", backend())); - } + /** Returns the backend used in this compilation. */ + public abstract DaggerProcessingEnv.Backend backend(); } diff --git a/java/dagger/spi/model/DaggerTypeElement.java b/java/dagger/spi/model/DaggerTypeElement.java index 2f70a54b8..935770d11 100644 --- a/java/dagger/spi/model/DaggerTypeElement.java +++ b/java/dagger/spi/model/DaggerTypeElement.java @@ -16,78 +16,27 @@ package dagger.spi.model; -import com.google.auto.common.MoreElements; -import com.google.auto.value.AutoValue; import com.google.devtools.ksp.symbol.KSClassDeclaration; -import javax.annotation.Nullable; +import com.google.errorprone.annotations.DoNotMock; import javax.lang.model.element.TypeElement; /** Wrapper type for a type element. */ -@AutoValue +@DoNotMock("Only use real implementations created by Dagger") public abstract class DaggerTypeElement { - public static DaggerTypeElement fromJavac(@Nullable TypeElement element) { - return new AutoValue_DaggerTypeElement(element, null); - } - - public static DaggerTypeElement fromKsp(@Nullable KSClassDeclaration declaration) { - return new AutoValue_DaggerTypeElement(null, declaration); - } - - /** Java representation for the type, returns {@code null} not using java annotation processor. */ - @Nullable - public abstract TypeElement java(); - - /** KSP declaration for the element, returns {@code null} not using KSP. */ - @Nullable + /** + * Returns the Javac representation for the type element. + * + * @throws IllegalStateException if the current backend isn't Javac. + */ + public abstract TypeElement javac(); + + /** + * Returns the KSP representation for the type element. + * + * @throws IllegalStateException if the current backend isn't KSP. + */ public abstract KSClassDeclaration ksp(); - public final boolean hasAnnotation(String annotationName) { - switch (backend()) { - case JAVAC: - return MoreElements.isAnnotationPresent(java(), annotationName); - case KSP: - return KspUtilsKt.hasAnnotation(ksp(), annotationName); - } - throw new IllegalStateException(String.format("Backend %s not supported yet.", backend())); - } - - public String packageName() { - switch (backend()) { - case JAVAC: - return MoreElements.getPackage(java()).getQualifiedName().toString(); - case KSP: - return KspUtilsKt.getNormalizedPackageName(ksp()); - } - throw new IllegalStateException(String.format("Backend %s not supported yet.", backend())); - } - - public String qualifiedName() { - switch (backend()) { - case JAVAC: - return java().getQualifiedName().toString(); - case KSP: - return ksp().getQualifiedName().asString(); - } - throw new IllegalStateException(String.format("Backend %s not supported yet.", backend())); - } - - public DaggerProcessingEnv.Backend backend() { - if (java() != null) { - return DaggerProcessingEnv.Backend.JAVAC; - } else if (ksp() != null) { - return DaggerProcessingEnv.Backend.KSP; - } - throw new AssertionError("Unexpected backend"); - } - - @Override - public final String toString() { - switch (backend()) { - case JAVAC: - return java().toString(); - case KSP: - return ksp().toString(); - } - throw new IllegalStateException(String.format("Backend %s not supported yet.", backend())); - } + /** Returns the backend used in this compilation. */ + public abstract DaggerProcessingEnv.Backend backend(); } diff --git a/java/dagger/spi/model/Key.java b/java/dagger/spi/model/Key.java index d871e6d12..d4478f6a6 100644 --- a/java/dagger/spi/model/Key.java +++ b/java/dagger/spi/model/Key.java @@ -130,7 +130,7 @@ public abstract class Key { private static MultibindingContributionIdentifier create( DaggerTypeElement contributingModule, DaggerExecutableElement bindingMethod) { return new AutoValue_Key_MultibindingContributionIdentifier( - contributingModule.qualifiedName(), bindingMethod.simpleName()); + qualifiedName(contributingModule), simpleName(bindingMethod)); } /** Returns the module containing the multibinding method. */ @@ -150,4 +150,24 @@ public abstract class Key { return String.format("%s#%s", contributingModule(), bindingMethod()); } } + + static String qualifiedName(DaggerTypeElement element) { + switch (element.backend()) { + case JAVAC: + return element.javac().getQualifiedName().toString(); + case KSP: + return element.ksp().getQualifiedName().asString(); + } + throw new IllegalStateException("Unknown backend: " + element.backend()); + } + + private static String simpleName(DaggerExecutableElement element) { + switch (element.backend()) { + case JAVAC: + return element.javac().getSimpleName().toString(); + case KSP: + return element.ksp().getSimpleName().asString(); + } + throw new IllegalStateException("Unknown backend: " + element.backend()); + } } diff --git a/java/dagger/spi/model/MoreAnnotationMirrors.java b/java/dagger/spi/model/MoreAnnotationMirrors.java index 44c0363c9..a5c04c6af 100644 --- a/java/dagger/spi/model/MoreAnnotationMirrors.java +++ b/java/dagger/spi/model/MoreAnnotationMirrors.java @@ -35,7 +35,7 @@ final class MoreAnnotationMirrors { * defined in the annotation type. */ public static String toStableString(DaggerAnnotation qualifier) { - return stableAnnotationMirrorToString(qualifier.java()); + return stableAnnotationMirrorToString(qualifier.javac()); } /** diff --git a/java/dagger/spi/model/RequestKind.java b/java/dagger/spi/model/RequestKind.java index 62f46cd65..bcbe26d4f 100644 --- a/java/dagger/spi/model/RequestKind.java +++ b/java/dagger/spi/model/RequestKind.java @@ -19,11 +19,6 @@ package dagger.spi.model; import static com.google.common.base.CaseFormat.UPPER_CAMEL; import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE; -import dagger.Lazy; -import dagger.producers.Produced; -import dagger.producers.Producer; -import javax.inject.Provider; - /** * Represents the different kinds of {@link javax.lang.model.type.TypeMirror types} that may be * requested as dependencies for the same key. For example, {@code String}, {@code @@ -35,13 +30,13 @@ public enum RequestKind { /** A default request for an instance. E.g.: {@code FooType} */ INSTANCE, - /** A request for a {@link Provider}. E.g.: {@code Provider<FooType>} */ + /** A request for a {@code Provider}. E.g.: {@code Provider<FooType>} */ PROVIDER, - /** A request for a {@link Lazy}. E.g.: {@code Lazy<FooType>} */ + /** A request for a {@code Lazy}. E.g.: {@code Lazy<FooType>} */ LAZY, - /** A request for a {@link Provider} of a {@link Lazy}. E.g.: {@code Provider<Lazy<FooType>>} */ + /** A request for a {@code Provider} of a {@code Lazy}. E.g.: {@code Provider<Lazy<FooType>>}. */ PROVIDER_OF_LAZY, /** @@ -50,15 +45,15 @@ public enum RequestKind { */ MEMBERS_INJECTION, - /** A request for a {@link Producer}. E.g.: {@code Producer<FooType>} */ + /** A request for a {@code Producer}. E.g.: {@code Producer<FooType>} */ PRODUCER, - /** A request for a {@link Produced}. E.g.: {@code Produced<FooType>} */ + /** A request for a {@code Produced}. E.g.: {@code Produced<FooType>} */ PRODUCED, /** - * A request for a {@link com.google.common.util.concurrent.ListenableFuture}. E.g.: {@code - * ListenableFuture<FooType>}. These can only be requested by component interfaces. + * A request for a {@code ListenableFuture}. E.g.: {@code ListenableFuture<FooType>}. These can + * only be requested by component interfaces. */ FUTURE, ; diff --git a/java/dagger/spi/model/Scope.java b/java/dagger/spi/model/Scope.java index d1505b969..2d86101f1 100644 --- a/java/dagger/spi/model/Scope.java +++ b/java/dagger/spi/model/Scope.java @@ -18,6 +18,7 @@ package dagger.spi.model; import static com.google.common.base.Preconditions.checkArgument; +import com.google.auto.common.MoreElements; import com.google.auto.value.AutoValue; /** A representation of a {@link javax.inject.Scope}. */ @@ -42,8 +43,16 @@ public abstract class Scope { * Returns {@code true} if {@code scopeAnnotationType} is a {@link javax.inject.Scope} annotation. */ public static boolean isScope(DaggerTypeElement scopeAnnotationType) { - return scopeAnnotationType.hasAnnotation(SCOPE) - || scopeAnnotationType.hasAnnotation(SCOPE_JAVAX); + switch (scopeAnnotationType.backend()) { + case JAVAC: + return MoreElements.isAnnotationPresent(scopeAnnotationType.javac(), SCOPE) + || MoreElements.isAnnotationPresent(scopeAnnotationType.javac(), SCOPE_JAVAX); + case KSP: + return KspUtilsKt.hasAnnotation(scopeAnnotationType.ksp(), SCOPE) + || KspUtilsKt.hasAnnotation(scopeAnnotationType.ksp(), SCOPE_JAVAX); + } + throw new IllegalStateException( + String.format("Backend %s not supported yet.", scopeAnnotationType.backend())); } private boolean isScope(String annotationName) { @@ -71,8 +80,7 @@ public abstract class Scope { } /** - * Returns {@code true} if this scope is the {@link - * dagger.producers.ProductionScope @ProductionScope} scope. + * Returns {@code true} if this scope is the {@code @ProductionScope} scope. */ public final boolean isProductionScope() { return isScope(PRODUCTION_SCOPE); diff --git a/java/dagger/spi/model/testing/BindingGraphSubject.java b/java/dagger/spi/model/testing/BindingGraphSubject.java index e2067318b..4d53d9367 100644 --- a/java/dagger/spi/model/testing/BindingGraphSubject.java +++ b/java/dagger/spi/model/testing/BindingGraphSubject.java @@ -112,7 +112,7 @@ public final class BindingGraphSubject extends Subject { private static String formattedType(DaggerType type) { switch (type.backend()) { case JAVAC: - return type.java().toString(); + return type.javac().toString(); case KSP: return type.ksp().getDeclaration().getQualifiedName().asString(); } diff --git a/java/dagger/testing/compile/BUILD b/java/dagger/testing/compile/BUILD index 585939867..a0e09a814 100644 --- a/java/dagger/testing/compile/BUILD +++ b/java/dagger/testing/compile/BUILD @@ -26,6 +26,9 @@ java_library( "CompilerProcessors.java", "CompilerTests.java", ], + exports = [ + "//java/dagger/internal/codegen/xprocessing:xprocessing-testing", + ], deps = [ "//java/dagger/internal/codegen:processor", "//java/dagger/internal/codegen/extension", diff --git a/java/dagger/testing/compile/CompilerTests.java b/java/dagger/testing/compile/CompilerTests.java index 55574201e..ac74a618e 100644 --- a/java/dagger/testing/compile/CompilerTests.java +++ b/java/dagger/testing/compile/CompilerTests.java @@ -21,6 +21,7 @@ import static com.google.common.collect.MoreCollectors.onlyElement; import static com.google.common.collect.Streams.stream; import static com.google.testing.compile.Compiler.javac; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; +import static java.util.stream.Collectors.toMap; import androidx.room.compiler.processing.XProcessingEnv; import androidx.room.compiler.processing.XProcessingEnvConfig; @@ -39,6 +40,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.io.Files; +import com.google.devtools.ksp.processing.SymbolProcessorProvider; import com.google.testing.compile.Compiler; import dagger.internal.codegen.ComponentProcessor; import dagger.internal.codegen.KspComponentProcessor; @@ -46,11 +48,13 @@ import dagger.spi.model.BindingGraphPlugin; import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.function.Consumer; +import javax.annotation.processing.Processor; import org.junit.rules.TemporaryFolder; /** A helper class for working with java compiler tests. */ @@ -150,6 +154,8 @@ public final class CompilerTests { // Set default values return builder .processorOptions(DEFAULT_PROCESSOR_OPTIONS) + .additionalJavacProcessors(ImmutableList.of()) + .additionalKspProcessors(ImmutableList.of()) .processingStepSuppliers(ImmutableSet.of()) .bindingGraphPluginSuppliers(ImmutableSet.of()); } @@ -160,6 +166,12 @@ public final class CompilerTests { /** Returns the annotation processor options */ abstract ImmutableMap<String, String> processorOptions(); + /** Returns the extra Javac processors. */ + abstract ImmutableCollection<Processor> additionalJavacProcessors(); + + /** Returns the extra KSP processors. */ + abstract ImmutableCollection<SymbolProcessorProvider> additionalKspProcessors(); + /** Returns the processing steps suppliers. */ abstract ImmutableCollection<Supplier<XProcessingStep>> processingStepSuppliers(); @@ -192,6 +204,16 @@ public final class CompilerTests { return toBuilder().processorOptions(newProcessorOptions).build(); } + /** Returns a new {@link HiltCompiler} instance with the additional Javac processors. */ + public DaggerCompiler withAdditionalJavacProcessors(Processor... processors) { + return toBuilder().additionalJavacProcessors(ImmutableList.copyOf(processors)).build(); + } + + /** Returns a new {@link HiltCompiler} instance with the additional KSP processors. */ + public DaggerCompiler withAdditionalKspProcessors(SymbolProcessorProvider... processors) { + return toBuilder().additionalKspProcessors(ImmutableList.copyOf(processors)).build(); + } + /** Returns a new {@link Compiler} instance with the given processing steps. */ public DaggerCompiler withProcessingSteps(Supplier<XProcessingStep>... suppliers) { return toBuilder().processingStepSuppliers(ImmutableList.copyOf(suppliers)).build(); @@ -210,23 +232,43 @@ public final class CompilerTests { /* kotlincArguments= */ ImmutableList.of( "-P", "plugin:org.jetbrains.kotlin.kapt3:correctErrorTypes=true"), /* config= */ PROCESSING_ENV_CONFIG, - /* javacProcessors= */ ImmutableList.of( - ComponentProcessor.withTestPlugins(bindingGraphPlugins()), - new CompilerProcessors.JavacProcessor(processingSteps())), - /* symbolProcessorProviders= */ ImmutableList.of( - KspComponentProcessor.Provider.withTestPlugins(bindingGraphPlugins()), - new CompilerProcessors.KspProcessor.Provider(processingSteps())), + /* javacProcessors= */ mergeProcessors( + ImmutableList.of( + ComponentProcessor.withTestPlugins(bindingGraphPlugins()), + new CompilerProcessors.JavacProcessor(processingSteps())), + additionalJavacProcessors()), + /* symbolProcessorProviders= */ mergeProcessors( + ImmutableList.of( + KspComponentProcessor.Provider.withTestPlugins(bindingGraphPlugins()), + new CompilerProcessors.KspProcessor.Provider(processingSteps())), + additionalKspProcessors()), result -> { onCompilationResult.accept(result); return null; }); } + private static <T> ImmutableList<T> mergeProcessors( + Collection<T> defaultProcessors, Collection<T> extraProcessors) { + Map<Class<?>, T> processors = + defaultProcessors.stream() + .collect(toMap(Object::getClass, (T e) -> e, (p1, p2) -> p2, HashMap::new)); + // Adds extra processors, and allows overriding any processors of the same class. + extraProcessors.forEach(processor -> processors.put(processor.getClass(), processor)); + return ImmutableList.copyOf(processors.values()); + } + /** Used to build a {@link DaggerCompiler}. */ @AutoValue.Builder public abstract static class Builder { abstract Builder sources(ImmutableCollection<Source> sources); abstract Builder processorOptions(Map<String, String> processorOptions); + + abstract Builder additionalJavacProcessors(ImmutableCollection<Processor> processors); + + abstract Builder additionalKspProcessors( + ImmutableCollection<SymbolProcessorProvider> processors); + abstract Builder processingStepSuppliers( ImmutableCollection<Supplier<XProcessingStep>> processingStepSuppliers); abstract Builder bindingGraphPluginSuppliers( diff --git a/javatests/artifacts/dagger-android-ksp/app/build.gradle b/javatests/artifacts/dagger-android-ksp/app/build.gradle new file mode 100644 index 000000000..434590a47 --- /dev/null +++ b/javatests/artifacts/dagger-android-ksp/app/build.gradle @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2023 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. + */ + +plugins { + id 'com.android.application' + id 'org.jetbrains.kotlin.android' + id 'com.google.devtools.ksp' +} + +android { + namespace 'dagger.android.ksp' + compileSdkVersion 33 + defaultConfig { + applicationId 'dagger.android.ksp' + minSdk 16 + targetSdk 33 + versionCode 1 + versionName "1.0" + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + testOptions { + unitTests.includeAndroidResources = true + } + sourceSets { + String sharedTestDir = 'src/sharedTest/java' + test { + java.srcDirs += sharedTestDir + } + androidTest { + java.srcDirs += sharedTestDir + } + } +} + +dependencies { + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + + testImplementation 'com.google.truth:truth:1.0.1' + testImplementation 'org.robolectric:robolectric:4.11.1' + testImplementation 'androidx.core:core:1.3.2' + testImplementation 'androidx.test.ext:junit:1.1.5' + testImplementation 'androidx.test:runner:1.5.2' + testImplementation 'androidx.test.espresso:espresso-core:3.5.1' + + androidTestImplementation 'com.google.truth:truth:1.0.1' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test:runner:1.5.2' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' + + // Dagger Android dependencies + implementation 'com.google.dagger:dagger:LOCAL-SNAPSHOT' + implementation 'com.google.dagger:dagger-android-support:LOCAL-SNAPSHOT' + implementation 'com.google.dagger:dagger-android:LOCAL-SNAPSHOT' + ksp 'com.google.dagger:dagger-android-processor:LOCAL-SNAPSHOT' + ksp "com.google.dagger:dagger-compiler:LOCAL-SNAPSHOT" +}
\ No newline at end of file diff --git a/javatests/artifacts/dagger-android-ksp/app/src/main/AndroidManifest.xml b/javatests/artifacts/dagger-android-ksp/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000..89b0dbfd9 --- /dev/null +++ b/javatests/artifacts/dagger-android-ksp/app/src/main/AndroidManifest.xml @@ -0,0 +1,30 @@ +<!-- + ~ Copyright (C) 2023 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. + --> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="dagger.android.ksp"> + + <application + android:name=".SimpleApplication" + android:label="@string/appName" + android:theme="@style/Theme.AppCompat.Light"> + <activity android:name=".SimpleActivity" android:exported="true"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest>
\ No newline at end of file diff --git a/javatests/artifacts/dagger-android-ksp/app/src/main/kotlin/dagger/android/ksp/Model .kt b/javatests/artifacts/dagger-android-ksp/app/src/main/kotlin/dagger/android/ksp/Model .kt new file mode 100644 index 000000000..8dd333dd5 --- /dev/null +++ b/javatests/artifacts/dagger-android-ksp/app/src/main/kotlin/dagger/android/ksp/Model .kt @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2023 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.android.ksp + +import javax.inject.Qualifier + +/** Qualifies bindings relating to [android.os.Build.MODEL]. */ +@Qualifier @Retention(AnnotationRetention.RUNTIME) internal annotation class Model diff --git a/javatests/artifacts/dagger-android-ksp/app/src/main/kotlin/dagger/android/ksp/ModelModule.kt b/javatests/artifacts/dagger-android-ksp/app/src/main/kotlin/dagger/android/ksp/ModelModule.kt new file mode 100644 index 000000000..25c0f72ba --- /dev/null +++ b/javatests/artifacts/dagger-android-ksp/app/src/main/kotlin/dagger/android/ksp/ModelModule.kt @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2023 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.android.ksp + +import android.os.Build.MODEL +import dagger.Module +import dagger.Provides + +@Module +object ModelModule { + @Provides @Model fun provideModel(): String = MODEL +} diff --git a/javatests/artifacts/dagger-android-ksp/app/src/main/kotlin/dagger/android/ksp/SimpleActivity.kt b/javatests/artifacts/dagger-android-ksp/app/src/main/kotlin/dagger/android/ksp/SimpleActivity.kt new file mode 100644 index 000000000..5b9b84b03 --- /dev/null +++ b/javatests/artifacts/dagger-android-ksp/app/src/main/kotlin/dagger/android/ksp/SimpleActivity.kt @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2023 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.android.ksp + +import android.os.Bundle +import android.util.Log +import android.widget.TextView +import dagger.Binds +import dagger.Module +import dagger.Subcomponent +import dagger.android.AndroidInjector +import dagger.android.support.DaggerAppCompatActivity +import dagger.multibindings.ClassKey +import dagger.multibindings.IntoMap +import javax.inject.Inject + +/** + * The main activity of the application. + * + * <p>It can be injected with any binding from both {@link SimpleActivityComponent} and {@link + * SimpleApplication.SimpleComponent}. + */ +class SimpleActivity : DaggerAppCompatActivity() { + private val TAG: String = SimpleActivity::class.java.getSimpleName() + + @Inject @UserName lateinit var userName: String + @Inject @Model lateinit var model: String + + override protected fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + Log.i(TAG, "Injected with userName and model: " + userName + ", " + model) + + setContentView(R.layout.activity_main) + + val greeting = findViewById(R.id.greeting) as TextView + val text = getResources().getString(R.string.welcome, userName, model) + greeting.setText(text) + } +} + +@Subcomponent +interface SimpleActivityComponent : AndroidInjector<SimpleActivity> { + + @Subcomponent.Factory interface Factory : AndroidInjector.Factory<SimpleActivity> {} +} + +@Module(subcomponents = [SimpleActivityComponent::class], includes = [UserNameModule::class]) +interface InjectorModule { + @Binds + @IntoMap + @ClassKey(SimpleActivity::class) + fun bind(factory: SimpleActivityComponent.Factory): AndroidInjector.Factory<*> +} + diff --git a/javatests/artifacts/dagger-android-ksp/app/src/main/kotlin/dagger/android/ksp/SimpleApplication.kt b/javatests/artifacts/dagger-android-ksp/app/src/main/kotlin/dagger/android/ksp/SimpleApplication.kt new file mode 100644 index 000000000..37dfd0500 --- /dev/null +++ b/javatests/artifacts/dagger-android-ksp/app/src/main/kotlin/dagger/android/ksp/SimpleApplication.kt @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2023 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.android.ksp + +import android.util.Log +import dagger.Component +import dagger.android.AndroidInjectionModule +import dagger.android.AndroidInjector +import dagger.android.DaggerApplication +import javax.inject.Inject +import javax.inject.Singleton + +/** + * A simple, skeletal application that demonstrates a dependency-injected application using the + * utilities in {@code dagger.android}. + */ +class SimpleApplication : DaggerApplication() { + private val TAG = SimpleApplication::class.java.getSimpleName() + + @Inject @Model lateinit var model: String + + override public fun onCreate() { + super.onCreate() + Log.i(TAG, "Injected with model: " + model) + } + + override protected fun applicationInjector(): AndroidInjector<SimpleApplication> { + return DaggerSimpleComponent.factory().create(this) + } +} + +@Singleton +@Component( + modules = + [AndroidInjectionModule::class, InjectorModule::class, ModelModule::class] +) +interface SimpleComponent : AndroidInjector<SimpleApplication> { + @Component.Factory interface Factory : AndroidInjector.Factory<SimpleApplication> {} +} diff --git a/javatests/artifacts/dagger-android-ksp/app/src/main/kotlin/dagger/android/ksp/UserName.kt b/javatests/artifacts/dagger-android-ksp/app/src/main/kotlin/dagger/android/ksp/UserName.kt new file mode 100644 index 000000000..3388c09c0 --- /dev/null +++ b/javatests/artifacts/dagger-android-ksp/app/src/main/kotlin/dagger/android/ksp/UserName.kt @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2023 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.android.ksp + +import javax.inject.Qualifier + +/** Qualifies bindings relating to the user name. */ +@Qualifier @Retention(AnnotationRetention.RUNTIME) internal annotation class UserName diff --git a/javatests/artifacts/dagger-android-ksp/app/src/main/kotlin/dagger/android/ksp/UserNameModule.kt b/javatests/artifacts/dagger-android-ksp/app/src/main/kotlin/dagger/android/ksp/UserNameModule.kt new file mode 100644 index 000000000..2628398d2 --- /dev/null +++ b/javatests/artifacts/dagger-android-ksp/app/src/main/kotlin/dagger/android/ksp/UserNameModule.kt @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2023 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.android.ksp + +import dagger.Module +import dagger.Provides + +@Module +object UserNameModule { + @UserName @Provides fun provideUserName(): String = "ProdUser" +} diff --git a/javatests/artifacts/dagger-android-ksp/app/src/main/res/layout/activity_main.xml b/javatests/artifacts/dagger-android-ksp/app/src/main/res/layout/activity_main.xml new file mode 100644 index 000000000..4693e5513 --- /dev/null +++ b/javatests/artifacts/dagger-android-ksp/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2023 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. + --> + +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@android:color/background_light"> + + <TextView + android:id="@+id/greeting" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_alignParentTop="true" + android:textColor="@android:color/primary_text_light" + /> +</RelativeLayout>
\ No newline at end of file diff --git a/javatests/artifacts/dagger-android-ksp/app/src/main/res/values/strings.xml b/javatests/artifacts/dagger-android-ksp/app/src/main/res/values/strings.xml new file mode 100644 index 000000000..4bf0e39bf --- /dev/null +++ b/javatests/artifacts/dagger-android-ksp/app/src/main/res/values/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2023 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. + --> + +<resources> + <!--The app name [CHAR_LIMIT=25]--> + <string name="appName">Simple Dagger Android</string> + + <!--The greeting message [CHAR_LIMIT=100]--> + <string name="welcome">Hello, %1$s! You are on build %2$s.</string> +</resources>
\ No newline at end of file diff --git a/javatests/artifacts/dagger-android-ksp/app/src/sharedTest/kotlin/dagger/android/ksp/SimpleActivityTest.kt b/javatests/artifacts/dagger-android-ksp/app/src/sharedTest/kotlin/dagger/android/ksp/SimpleActivityTest.kt new file mode 100644 index 000000000..22a2efb2f --- /dev/null +++ b/javatests/artifacts/dagger-android-ksp/app/src/sharedTest/kotlin/dagger/android/ksp/SimpleActivityTest.kt @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2023 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.android.ksp + +import android.content.Context +import androidx.test.core.app.ActivityScenario +import androidx.test.core.app.ApplicationProvider +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.espresso.matcher.ViewMatchers.withText +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.google.common.truth.Truth.assertThat +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class SimpleActivityTest { + @Test + fun testActivityInject() { + ActivityScenario.launch(SimpleActivity::class.java).onActivity { activity -> + onView(withId(R.id.greeting)) + .check(matches(withText("Hello, ProdUser! You are on build robolectric."))) + } + } + + @Test + fun verifyApplicationInstance() { + assertThat((ApplicationProvider.getApplicationContext() as Context) is SimpleApplication) + .isTrue() + } +} diff --git a/javatests/artifacts/dagger-android-ksp/build.gradle b/javatests/artifacts/dagger-android-ksp/build.gradle new file mode 100644 index 000000000..2aa06052c --- /dev/null +++ b/javatests/artifacts/dagger-android-ksp/build.gradle @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2023 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. + */ + +buildscript { + ext { + agp_version = "8.1.0" + kotlin_version = "1.9.20" + ksp_version = "$kotlin_version-1.0.14" + } + repositories { + google() + mavenCentral() + mavenLocal() + } + dependencies { + classpath "com.android.tools.build:gradle:$agp_version" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath "com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin:$ksp_version" + } +} + +allprojects { + repositories { + google() + mavenCentral() + mavenLocal() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +}
\ No newline at end of file diff --git a/javatests/artifacts/dagger-android-ksp/gradle.properties b/javatests/artifacts/dagger-android-ksp/gradle.properties new file mode 100644 index 000000000..0bdf325d5 --- /dev/null +++ b/javatests/artifacts/dagger-android-ksp/gradle.properties @@ -0,0 +1,4 @@ +android.useAndroidX=true +org.gradle.caching=true +org.gradle.parallel=true +org.gradle.jvmargs=-Xmx2048m
\ No newline at end of file diff --git a/javatests/artifacts/dagger-android-ksp/gradle/wrapper/gradle-wrapper.jar b/javatests/artifacts/dagger-android-ksp/gradle/wrapper/gradle-wrapper.jar Binary files differnew file mode 100644 index 000000000..7f93135c4 --- /dev/null +++ b/javatests/artifacts/dagger-android-ksp/gradle/wrapper/gradle-wrapper.jar diff --git a/javatests/artifacts/dagger-android-ksp/gradle/wrapper/gradle-wrapper.properties b/javatests/artifacts/dagger-android-ksp/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..3fa8f862f --- /dev/null +++ b/javatests/artifacts/dagger-android-ksp/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/javatests/artifacts/dagger-android-ksp/gradlew b/javatests/artifacts/dagger-android-ksp/gradlew new file mode 100755 index 000000000..1aa94a426 --- /dev/null +++ b/javatests/artifacts/dagger-android-ksp/gradlew @@ -0,0 +1,249 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original 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 +# +# https://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. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/javatests/artifacts/dagger-android-ksp/gradlew.bat b/javatests/artifacts/dagger-android-ksp/gradlew.bat new file mode 100644 index 000000000..93e3f59f1 --- /dev/null +++ b/javatests/artifacts/dagger-android-ksp/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/javatests/artifacts/dagger-android-ksp/settings.gradle b/javatests/artifacts/dagger-android-ksp/settings.gradle new file mode 100644 index 000000000..ae4079cc2 --- /dev/null +++ b/javatests/artifacts/dagger-android-ksp/settings.gradle @@ -0,0 +1,9 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * The settings file is used to specify which projects to include in your build. + * For more detailed information on multi-project builds, please refer to https://docs.gradle.org/8.4/userguide/building_swift_projects.html in the Gradle documentation. + */ + +rootProject.name = 'dagger-android-ksp' +include('app') diff --git a/javatests/artifacts/dagger-android/simple/app/build.gradle b/javatests/artifacts/dagger-android/simple/app/build.gradle index be30b3bc1..881a304cb 100644 --- a/javatests/artifacts/dagger-android/simple/app/build.gradle +++ b/javatests/artifacts/dagger-android/simple/app/build.gradle @@ -17,13 +17,13 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 32 - buildToolsVersion "32.0.0" + compileSdkVersion 33 + buildToolsVersion "33.0.0" defaultConfig { applicationId "dagger.android.simple" - minSdkVersion 15 - targetSdkVersion 32 + minSdkVersion 16 + targetSdkVersion 33 versionCode 1 versionName "1.0" } diff --git a/javatests/artifacts/dagger-android/simple/gradle.properties b/javatests/artifacts/dagger-android/simple/gradle.properties index 6cde789f6..0bdf325d5 100644 --- a/javatests/artifacts/dagger-android/simple/gradle.properties +++ b/javatests/artifacts/dagger-android/simple/gradle.properties @@ -1,3 +1,4 @@ android.useAndroidX=true org.gradle.caching=true -org.gradle.parallel=true
\ No newline at end of file +org.gradle.parallel=true +org.gradle.jvmargs=-Xmx2048m
\ No newline at end of file diff --git a/javatests/artifacts/dagger-android/simple/gradle/wrapper/gradle-wrapper.properties b/javatests/artifacts/dagger-android/simple/gradle/wrapper/gradle-wrapper.properties index 00e33edef..98debb84d 100644 --- a/javatests/artifacts/dagger-android/simple/gradle/wrapper/gradle-wrapper.properties +++ b/javatests/artifacts/dagger-android/simple/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/javatests/artifacts/dagger-ksp/build.gradle b/javatests/artifacts/dagger-ksp/build.gradle index 9e92640cf..35aea20f6 100644 --- a/javatests/artifacts/dagger-ksp/build.gradle +++ b/javatests/artifacts/dagger-ksp/build.gradle @@ -17,8 +17,8 @@ buildscript { ext { dagger_version = "LOCAL-SNAPSHOT" - kotlin_version = "1.8.0" - ksp_version = "1.8.0-1.0.9" + kotlin_version = "1.9.20" + ksp_version = "$kotlin_version-1.0.14" junit_version = "4.13" truth_version = "1.0.1" } @@ -27,6 +27,7 @@ buildscript { mavenLocal() } dependencies { + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version") classpath("com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin:$ksp_version") } } diff --git a/javatests/artifacts/dagger-ksp/gradle.properties b/javatests/artifacts/dagger-ksp/gradle.properties index e68633cff..a516e458c 100644 --- a/javatests/artifacts/dagger-ksp/gradle.properties +++ b/javatests/artifacts/dagger-ksp/gradle.properties @@ -1,2 +1,3 @@ org.gradle.caching=true -org.gradle.parallel=true
\ No newline at end of file +org.gradle.parallel=true +org.gradle.jvmargs=-Xmx2048m
\ No newline at end of file diff --git a/javatests/artifacts/dagger-ksp/gradle/wrapper/gradle-wrapper.properties b/javatests/artifacts/dagger-ksp/gradle/wrapper/gradle-wrapper.properties index 0f80bbf51..98debb84d 100644 --- a/javatests/artifacts/dagger-ksp/gradle/wrapper/gradle-wrapper.properties +++ b/javatests/artifacts/dagger-ksp/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/javatests/artifacts/dagger-ksp/transitive-annotation-app/library1/src/main/java/library1/MySubcomponentWithBuilder.java b/javatests/artifacts/dagger-ksp/transitive-annotation-app/library1/src/main/java/library1/MySubcomponentWithBuilder.java index 27045eae8..1aa04f112 100644 --- a/javatests/artifacts/dagger-ksp/transitive-annotation-app/library1/src/main/java/library1/MySubcomponentWithBuilder.java +++ b/javatests/artifacts/dagger-ksp/transitive-annotation-app/library1/src/main/java/library1/MySubcomponentWithBuilder.java @@ -29,9 +29,9 @@ import library2.MyTransitiveType; * the classpath. In most cases, Dagger shouldn't care that the annotation isn't on the classpath */ // TODO(b/219587431): Support @MyTransitiveAnnotation (Requires generating metadata). -@MySubcomponentScope // TODO(b/269172737): Fix issue that requires reordering to build successfully. @MyAnnotation(MyTransitiveType.VALUE) @MyOtherAnnotation(MyTransitiveType.class) +@MySubcomponentScope @Subcomponent(modules = MySubcomponentModule.class) public abstract class MySubcomponentWithBuilder { @MyQualifier diff --git a/javatests/artifacts/dagger-ksp/transitive-annotation-app/library1/src/main/java/library1/MySubcomponentWithFactory.java b/javatests/artifacts/dagger-ksp/transitive-annotation-app/library1/src/main/java/library1/MySubcomponentWithFactory.java index 900519346..baac2975c 100644 --- a/javatests/artifacts/dagger-ksp/transitive-annotation-app/library1/src/main/java/library1/MySubcomponentWithFactory.java +++ b/javatests/artifacts/dagger-ksp/transitive-annotation-app/library1/src/main/java/library1/MySubcomponentWithFactory.java @@ -29,9 +29,9 @@ import library2.MyTransitiveType; * the classpath. In most cases, Dagger shouldn't care that the annotation isn't on the classpath */ // TODO(b/219587431): Support @MyTransitiveAnnotation (Requires generating metadata). -@MySubcomponentScope // TODO(b/269172737): Fix issue that requires reordering to build successfully. @MyAnnotation(MyTransitiveType.VALUE) @MyOtherAnnotation(MyTransitiveType.class) +@MySubcomponentScope @Subcomponent(modules = MySubcomponentModule.class) public abstract class MySubcomponentWithFactory { // TODO(b/219587431): Support @MyTransitiveAnnotation (Requires generating metadata). diff --git a/javatests/artifacts/dagger/build-tests/build.gradle b/javatests/artifacts/dagger/build-tests/build.gradle index 2d2696d9e..7418b9f01 100644 --- a/javatests/artifacts/dagger/build-tests/build.gradle +++ b/javatests/artifacts/dagger/build-tests/build.gradle @@ -23,6 +23,7 @@ plugins { test { systemProperty 'dagger_version', "$dagger_version" systemProperty 'kotlin_version', "$kotlin_version" + systemProperty 'ksp_version', "$ksp_version" } dependencies { diff --git a/javatests/artifacts/dagger/build-tests/src/main/java/buildtests/GradleModule.java b/javatests/artifacts/dagger/build-tests/src/main/java/buildtests/GradleModule.java index d02dd91ea..c4d53d61e 100644 --- a/javatests/artifacts/dagger/build-tests/src/main/java/buildtests/GradleModule.java +++ b/javatests/artifacts/dagger/build-tests/src/main/java/buildtests/GradleModule.java @@ -20,6 +20,7 @@ import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.nio.file.Path; /** Used to create files for a Gradle module in a particular directory. */ public final class GradleModule { @@ -39,6 +40,10 @@ public final class GradleModule { this.moduleSrcDir = new File(moduleDir, "src/main/java/"); } + public Path getDir() { + return moduleDir.toPath(); + } + public GradleModule addBuildFile(String... content) throws IOException { writeFile(createFile(moduleDir, "build.gradle"), content); return this; diff --git a/javatests/artifacts/dagger/build-tests/src/test/java/buildtests/IncrementalProcessingTest.java b/javatests/artifacts/dagger/build-tests/src/test/java/buildtests/IncrementalProcessingTest.java new file mode 100644 index 000000000..bb84b832e --- /dev/null +++ b/javatests/artifacts/dagger/build-tests/src/test/java/buildtests/IncrementalProcessingTest.java @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2023 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 buildtests; + +import static com.google.common.truth.Truth.assertThat; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Set; +import java.util.stream.Collectors; +import org.gradle.testkit.runner.BuildResult; +import org.gradle.testkit.runner.GradleRunner; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +// This is a regression test for https://github.com/google/dagger/issues/4054 +@RunWith(JUnit4.class) +public class IncrementalProcessingTest { + @Rule public TemporaryFolder tmpFolder = new TemporaryFolder(); + + @Test + public void testIncrementalProcessing() throws IOException { + File projectDir = tmpFolder.getRoot(); + GradleModule.create(projectDir) + .addSettingsFile("include 'app'") + .addBuildFile( + "buildscript {", + " ext {", + String.format("dagger_version = \"%s\"", System.getProperty("dagger_version")), + String.format("kotlin_version = \"%s\"", System.getProperty("kotlin_version")), + String.format("ksp_version = \"%s\"", System.getProperty("ksp_version")), + " }", + "}", + "", + "allprojects {", + " repositories {", + " mavenCentral()", + " mavenLocal()", + " }", + "}"); + + GradleModule appModule = + GradleModule.create(projectDir, "app") + .addBuildFile( + "plugins {", + " id 'application'", + " id 'org.jetbrains.kotlin.jvm' version \"$kotlin_version\"", + " id 'com.google.devtools.ksp' version \"$ksp_version\"", + "}", + "dependencies {", + " implementation \"org.jetbrains.kotlin:kotlin-stdlib\"", + " implementation \"com.google.dagger:dagger:$dagger_version\"", + " ksp \"com.google.dagger:dagger-compiler:$dagger_version\"", + "}") + // Note: both A and AFactory need to be in the same source file for this to test the + // regression in https://github.com/google/dagger/issues/4054. + .addSrcFile( + "A.kt", + "package app", + "", + "import dagger.assisted.AssistedFactory", + "import dagger.assisted.AssistedInject", + "", + "class A @AssistedInject constructor()", + "", + "@AssistedFactory", + "interface AFactory {", + " fun create(): A", + "}"); + + // We'll be changing the contents of MyComponent between builds, so store it in a variable. + String myComponentContent = + String.join( + "\n", + "package app", + "", + "import dagger.Component", + "", + "@Component", + "interface MyComponent {", + " fun factory(): AFactory", + "}"); + appModule.addSrcFile("MyComponent.kt", myComponentContent); + + // Build #1 + build(projectDir); + assertThat(getAllKspGeneratedFileNames(appModule.getDir())) + .containsExactly( + "A_Factory.java", + "AFactory_Impl.java", + "DaggerMyComponent.java"); + + // Change method name in MyComponent.kt to trigger incremental processing of only MyComponent. + appModule.addSrcFile("MyComponent.kt", myComponentContent.replace("factory()", "factory2()")); + + // Build #2 + build(projectDir); + assertThat(getAllKspGeneratedFileNames(appModule.getDir())) + .containsExactly( + "A_Factory.java", + "AFactory_Impl.java", + "DaggerMyComponent.java"); + } + + private static BuildResult build(File projectDir) { + return GradleRunner.create() + .withArguments("--stacktrace", "build") + .withProjectDir(projectDir) + .build(); + } + + private static Set<String> getAllKspGeneratedFileNames(Path moduleDir) throws IOException { + return getAllFileNames(moduleDir.resolve("build/generated/ksp/main/java/")); + } + + private static Set<String> getAllFileNames(Path dir) throws IOException { + if (!Files.isDirectory(dir)) { + throw new IllegalArgumentException("Expected directory: " + dir); + } + return Files.walk(dir) + .filter(Files::isRegularFile) + .map(file -> file.getFileName().toString()) + .collect(Collectors.toSet()); + } +} diff --git a/javatests/artifacts/dagger/build.gradle b/javatests/artifacts/dagger/build.gradle index 314ee46ab..499b1ee55 100644 --- a/javatests/artifacts/dagger/build.gradle +++ b/javatests/artifacts/dagger/build.gradle @@ -17,7 +17,8 @@ buildscript { ext { dagger_version = "LOCAL-SNAPSHOT" - kotlin_version = "1.8.0" + kotlin_version = "1.9.20" + ksp_version = "$kotlin_version-1.0.14" junit_version = "4.13" truth_version = "1.0.1" } diff --git a/javatests/artifacts/dagger/gradle.properties b/javatests/artifacts/dagger/gradle.properties index e68633cff..a516e458c 100644 --- a/javatests/artifacts/dagger/gradle.properties +++ b/javatests/artifacts/dagger/gradle.properties @@ -1,2 +1,3 @@ org.gradle.caching=true -org.gradle.parallel=true
\ No newline at end of file +org.gradle.parallel=true +org.gradle.jvmargs=-Xmx2048m
\ No newline at end of file diff --git a/javatests/artifacts/dagger/gradle/wrapper/gradle-wrapper.properties b/javatests/artifacts/dagger/gradle/wrapper/gradle-wrapper.properties index 0f80bbf51..98debb84d 100644 --- a/javatests/artifacts/dagger/gradle/wrapper/gradle-wrapper.properties +++ b/javatests/artifacts/dagger/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/javatests/artifacts/dagger/lazyclasskey/app/build.gradle b/javatests/artifacts/dagger/lazyclasskey/app/build.gradle new file mode 100644 index 000000000..b44309afd --- /dev/null +++ b/javatests/artifacts/dagger/lazyclasskey/app/build.gradle @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2024 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. + */ + +plugins { + id 'com.android.application' +} + +android { + + namespace 'dagger.lazyclasskey' + compileSdkVersion 33 + defaultConfig { + applicationId 'dagger.lazyclasskey' + minSdk 16 + targetSdk 33 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + debug { + minifyEnabled true + shrinkResources true + proguardFiles getDefaultProguardFile( + 'proguard-android-optimize.txt'), + 'proguard-rules.pro' + + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 + } +} + +dependencies { + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.errorprone:error_prone_annotations:2.15.0' + + androidTestImplementation 'androidx.test:core:1.5.0-alpha02' + androidTestImplementation 'androidx.test.ext:junit:1.1.3' + androidTestImplementation "androidx.test:runner:1.5.2" + androidTestImplementation "androidx.test:rules:1.5.0" + androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' + + // Dagger dependencies + implementation "com.google.dagger:dagger:$dagger_version" + annotationProcessor "com.google.dagger:dagger-compiler:$dagger_version" +} diff --git a/javatests/artifacts/dagger/lazyclasskey/app/proguard-rules.pro b/javatests/artifacts/dagger/lazyclasskey/app/proguard-rules.pro new file mode 100644 index 000000000..95980023c --- /dev/null +++ b/javatests/artifacts/dagger/lazyclasskey/app/proguard-rules.pro @@ -0,0 +1,5 @@ + +-dontwarn com.google.errorprone.annotations.MustBeClosed + # TODO(b/324097623) Remove the keep rules once test won't be affected by obfuscation +-keep class kotlin.** +-keep class javax.** { *; } diff --git a/javatests/artifacts/dagger/lazyclasskey/app/src/androidTest/java/dagger/lazyclasskey/FlowerAppTest.java b/javatests/artifacts/dagger/lazyclasskey/app/src/androidTest/java/dagger/lazyclasskey/FlowerAppTest.java new file mode 100644 index 000000000..86e1401bd --- /dev/null +++ b/javatests/artifacts/dagger/lazyclasskey/app/src/androidTest/java/dagger/lazyclasskey/FlowerAppTest.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2024 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.lazyclasskey; + +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.ViewMatchers.withResourceName; +import static androidx.test.espresso.matcher.ViewMatchers.withText; +import static org.hamcrest.Matchers.startsWith; + +import android.content.Intent; +import androidx.test.core.app.ActivityScenario; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class FlowerAppTest { + @Test + public void testFlowerAppWithR8DoesNotCrash() { + Intent mainIntent = + new Intent(ApplicationProvider.getApplicationContext(), FlowerActivity.class); + try (ActivityScenario<FlowerActivity> scenario = ActivityScenario.launch(mainIntent)) { + onView(withResourceName("flower_info")) + .check(matches(withText(startsWith(Lily.class.getSimpleName())))); + } + } +} diff --git a/javatests/artifacts/dagger/lazyclasskey/app/src/main/AndroidManifest.xml b/javatests/artifacts/dagger/lazyclasskey/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000..cec40616b --- /dev/null +++ b/javatests/artifacts/dagger/lazyclasskey/app/src/main/AndroidManifest.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2024 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. + --> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="dagger.lazyclasskey"> + <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="34"/> + <application + android:theme="@style/Theme.AppCompat.Light.NoActionBar" + android:taskAffinity="" + android:label="@string/app_name"> + <activity + android:name=".FlowerActivity" + android:exported="true"> + <intent-filter> + <action android:name="android.intent.action.MAIN"/> + <category android:name="android.intent.category.LAUNCHER"/> + </intent-filter> + </activity> + </application> +</manifest> + diff --git a/java/dagger/spi/model/CompilerEnvironment.java b/javatests/artifacts/dagger/lazyclasskey/app/src/main/java/dagger/lazyclasskey/Flower.java index 28553e4c3..34161a1f9 100644 --- a/java/dagger/spi/model/CompilerEnvironment.java +++ b/javatests/artifacts/dagger/lazyclasskey/app/src/main/java/dagger/lazyclasskey/Flower.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 The Dagger Authors. + * Copyright (C) 2024 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. @@ -14,10 +14,7 @@ * limitations under the License. */ -package dagger.spi.model; +package dagger.lazyclasskey; -/** Types for the compiler in use for annotation processing. */ -public enum CompilerEnvironment { - JAVA, - KSP -} +/** Base class for flowers. */ +interface Flower {} diff --git a/javatests/artifacts/dagger/lazyclasskey/app/src/main/java/dagger/lazyclasskey/FlowerActivity.java b/javatests/artifacts/dagger/lazyclasskey/app/src/main/java/dagger/lazyclasskey/FlowerActivity.java new file mode 100644 index 000000000..005012733 --- /dev/null +++ b/javatests/artifacts/dagger/lazyclasskey/app/src/main/java/dagger/lazyclasskey/FlowerActivity.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2024 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.lazyclasskey; + +import android.os.Bundle; +import android.widget.TextView; +import androidx.activity.ComponentActivity; +import java.util.Locale; +import java.util.Map; + +/** Displays flower price information. */ +public final class FlowerActivity extends ComponentActivity { + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Map<Class<?>, Integer> flowerPrices = DaggerFlowerComponent.create().getFlowerMap(); + setContentView(R.layout.flower_activity); + if (!flowerPrices.containsKey(Rose.class)) { + throw new IllegalStateException("Rose price not found"); + } + if (!flowerPrices.containsKey(Lily.class)) { + throw new IllegalStateException("Lily price not found"); + } + ((TextView) findViewById(R.id.flower_info)) + .setText( + String.format( + Locale.US, + "%s : %d dollar, %s : %d dollar", + Lily.class.getSimpleName(), + flowerPrices.get(Lily.class), + Rose.class.getSimpleName(), + flowerPrices.get(Rose.class))); + } + + class ProguardClassNames { + Rose rose; + Lily lily; + } +} diff --git a/javatests/artifacts/dagger/lazyclasskey/app/src/main/java/dagger/lazyclasskey/FlowerComponent.java b/javatests/artifacts/dagger/lazyclasskey/app/src/main/java/dagger/lazyclasskey/FlowerComponent.java new file mode 100644 index 000000000..1302126ed --- /dev/null +++ b/javatests/artifacts/dagger/lazyclasskey/app/src/main/java/dagger/lazyclasskey/FlowerComponent.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2024 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.lazyclasskey; + +import dagger.Component; +import java.util.Map; + +/** Dagger component for flower bindings. */ +@Component(modules = FlowerModule.class) +public interface FlowerComponent { + Map<Class<?>, Integer> getFlowerMap(); +} diff --git a/javatests/artifacts/dagger/lazyclasskey/app/src/main/java/dagger/lazyclasskey/FlowerModule.java b/javatests/artifacts/dagger/lazyclasskey/app/src/main/java/dagger/lazyclasskey/FlowerModule.java new file mode 100644 index 000000000..4f9b61c0d --- /dev/null +++ b/javatests/artifacts/dagger/lazyclasskey/app/src/main/java/dagger/lazyclasskey/FlowerModule.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2024 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.lazyclasskey; + +import dagger.Module; +import dagger.Provides; +import dagger.multibindings.IntoMap; +import dagger.multibindings.LazyClassKey; + +/** Module for providing flower prices. */ +@Module +abstract class FlowerModule { + @IntoMap + @LazyClassKey(Lily.class) + @Provides + static int lilyPrice() { + return 1; + } + + @IntoMap + @LazyClassKey(Rose.class) + @Provides + static int rosePrice() { + return 2; + } +} diff --git a/javatests/artifacts/dagger/lazyclasskey/app/src/main/java/dagger/lazyclasskey/Lily.java b/javatests/artifacts/dagger/lazyclasskey/app/src/main/java/dagger/lazyclasskey/Lily.java new file mode 100644 index 000000000..c8c21be78 --- /dev/null +++ b/javatests/artifacts/dagger/lazyclasskey/app/src/main/java/dagger/lazyclasskey/Lily.java @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2024 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.lazyclasskey; + +/** Stores info for Lily. */ +final class Lily implements Flower {} diff --git a/javatests/artifacts/dagger/lazyclasskey/app/src/main/java/dagger/lazyclasskey/Rose.java b/javatests/artifacts/dagger/lazyclasskey/app/src/main/java/dagger/lazyclasskey/Rose.java new file mode 100644 index 000000000..abdd87a50 --- /dev/null +++ b/javatests/artifacts/dagger/lazyclasskey/app/src/main/java/dagger/lazyclasskey/Rose.java @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2024 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.lazyclasskey; + +/** Stores information for Rose. */ +final class Rose implements Flower {} diff --git a/javatests/artifacts/dagger/lazyclasskey/app/src/main/res/layout/flower_activity.xml b/javatests/artifacts/dagger/lazyclasskey/app/src/main/res/layout/flower_activity.xml new file mode 100644 index 000000000..400691d74 --- /dev/null +++ b/javatests/artifacts/dagger/lazyclasskey/app/src/main/res/layout/flower_activity.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2024 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. + --> +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + <TextView android:id="@+id/flower_info" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> +</LinearLayout> + diff --git a/javatests/artifacts/dagger/lazyclasskey/app/src/main/res/values/strings.xml b/javatests/artifacts/dagger/lazyclasskey/app/src/main/res/values/strings.xml new file mode 100644 index 000000000..72ad12a27 --- /dev/null +++ b/javatests/artifacts/dagger/lazyclasskey/app/src/main/res/values/strings.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2024 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. + --> +<resources> + <!-- The name of the application [CHAR LIMIT=25] --> + <string name="app_name">Flower Demo</string> +</resources> + diff --git a/javatests/artifacts/dagger/lazyclasskey/build.gradle b/javatests/artifacts/dagger/lazyclasskey/build.gradle new file mode 100644 index 000000000..a0d425259 --- /dev/null +++ b/javatests/artifacts/dagger/lazyclasskey/build.gradle @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2024 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. + */ + +buildscript { + ext { + dagger_version = 'LOCAL-SNAPSHOT' + // AGP is set below 7.2.0 on purpose to be able to obfuscate debug apk. + agp_version = "7.1.2" + kotlin_version = '1.9.20' + } + repositories { + google() + mavenCentral() + mavenLocal() + } + dependencies { + classpath "com.android.tools.build:gradle:$agp_version" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +allprojects { + repositories { + google() + mavenCentral() + mavenLocal() + } +} + +subprojects { + afterEvaluate { + dependencies { + // This is needed to align older versions of kotlin-stdlib. + // The main issue is that in v1.8.0 the jdk7 and jdk8 artifacts were + // merged into kotlin-stdlib, so without this alignment we end up + // getting duplicate classes by pulling in both artifacts. + // See: https://kotlinlang.org/docs/whatsnew18.html#usage-of-the-latest-kotlin-stdlib-version-in-transitive-dependencies + implementation(platform("org.jetbrains.kotlin:kotlin-bom:$kotlin_version")) + } + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/javatests/artifacts/dagger/lazyclasskey/gradle.properties b/javatests/artifacts/dagger/lazyclasskey/gradle.properties new file mode 100644 index 000000000..abca46e4f --- /dev/null +++ b/javatests/artifacts/dagger/lazyclasskey/gradle.properties @@ -0,0 +1,12 @@ +android.useAndroidX=true +android.enableJetifier=true + +# Enable and fail the build if an issue is found that disallows the +# configuration cache. These options along with this app being built in +# presubmit helps us cache changes that would cause config cache to be disabled +# via the HiltGradlePlugin. +org.gradle.unsafe.configuration-cache-problems=fail +org.gradle.unsafe.configuration-cache.max-problems=0 +org.gradle.caching=true +org.gradle.parallel=true +org.gradle.jvmargs=-Xmx2048m diff --git a/javatests/artifacts/dagger/lazyclasskey/gradle/wrapper/gradle-wrapper.jar b/javatests/artifacts/dagger/lazyclasskey/gradle/wrapper/gradle-wrapper.jar Binary files differnew file mode 100644 index 000000000..d64cd4917 --- /dev/null +++ b/javatests/artifacts/dagger/lazyclasskey/gradle/wrapper/gradle-wrapper.jar diff --git a/javatests/artifacts/dagger/lazyclasskey/gradle/wrapper/gradle-wrapper.properties b/javatests/artifacts/dagger/lazyclasskey/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..9623276bc --- /dev/null +++ b/javatests/artifacts/dagger/lazyclasskey/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/javatests/artifacts/dagger/lazyclasskey/gradlew b/javatests/artifacts/dagger/lazyclasskey/gradlew new file mode 100755 index 000000000..1aa94a426 --- /dev/null +++ b/javatests/artifacts/dagger/lazyclasskey/gradlew @@ -0,0 +1,249 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original 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 +# +# https://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. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/javatests/artifacts/dagger/lazyclasskey/gradlew.bat b/javatests/artifacts/dagger/lazyclasskey/gradlew.bat new file mode 100644 index 000000000..93e3f59f1 --- /dev/null +++ b/javatests/artifacts/dagger/lazyclasskey/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/javatests/artifacts/dagger/lazyclasskey/settings.gradle b/javatests/artifacts/dagger/lazyclasskey/settings.gradle new file mode 100644 index 000000000..5bb49fa71 --- /dev/null +++ b/javatests/artifacts/dagger/lazyclasskey/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'lazyclasskey' +include('app') diff --git a/javatests/artifacts/hilt-android/lazyclasskey/app/build.gradle b/javatests/artifacts/hilt-android/lazyclasskey/app/build.gradle new file mode 100644 index 000000000..0f854cb82 --- /dev/null +++ b/javatests/artifacts/hilt-android/lazyclasskey/app/build.gradle @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2024 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. + */ + +plugins { + id 'com.android.application' + id 'com.google.dagger.hilt.android' +} + +android { + + namespace 'hilt.lazyclasskey' + compileSdkVersion 33 + defaultConfig { + applicationId 'hilt.lazyclasskey' + minSdk 16 + targetSdk 33 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + debug { + minifyEnabled true + shrinkResources true + proguardFiles getDefaultProguardFile( + 'proguard-android-optimize.txt'), + 'proguard-rules.pro' + + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 + } +} + +dependencies { + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.errorprone:error_prone_annotations:2.15.0' + + androidTestImplementation 'androidx.test:core:1.5.0-alpha02' + androidTestImplementation 'androidx.test.ext:junit:1.1.3' + androidTestImplementation "androidx.test:runner:1.5.2" + androidTestImplementation "androidx.test:rules:1.5.0" + androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' + + // Hilt dependencies + implementation "com.google.dagger:hilt-android:$hilt_version" + annotationProcessor "com.google.dagger:hilt-compiler:$hilt_version" +}
\ No newline at end of file diff --git a/javatests/artifacts/hilt-android/lazyclasskey/app/proguard-rules.pro b/javatests/artifacts/hilt-android/lazyclasskey/app/proguard-rules.pro new file mode 100644 index 000000000..d389c4339 --- /dev/null +++ b/javatests/artifacts/hilt-android/lazyclasskey/app/proguard-rules.pro @@ -0,0 +1,3 @@ +-dontwarn com.google.errorprone.annotations.MustBeClosed + # TODO(b/324097623) Remove the keep rules once test won't be affected by obfuscation +-keep class kotlin.**
\ No newline at end of file diff --git a/javatests/artifacts/hilt-android/lazyclasskey/app/src/androidTest/java/hilt/lazyclasskey/FlowerAppTest.java b/javatests/artifacts/hilt-android/lazyclasskey/app/src/androidTest/java/hilt/lazyclasskey/FlowerAppTest.java new file mode 100644 index 000000000..a3cf1c349 --- /dev/null +++ b/javatests/artifacts/hilt-android/lazyclasskey/app/src/androidTest/java/hilt/lazyclasskey/FlowerAppTest.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2024 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 hilt.lazyclasskey; + +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.ViewMatchers.withResourceName; +import static androidx.test.espresso.matcher.ViewMatchers.withText; +import static org.hamcrest.Matchers.startsWith; + +import android.content.Intent; +import androidx.test.core.app.ActivityScenario; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class FlowerAppTest { + @Test + public void testFlowerAppWithR8DoesNotCrash() { + Intent mainIntent = + new Intent(ApplicationProvider.getApplicationContext(), FlowerActivity.class); + try (ActivityScenario<FlowerActivity> scenario = ActivityScenario.launch(mainIntent)) { + onView(withResourceName("flower_info")) + .check(matches(withText(startsWith(Lily.class.getSimpleName())))); + } + } +} diff --git a/javatests/artifacts/hilt-android/lazyclasskey/app/src/main/AndroidManifest.xml b/javatests/artifacts/hilt-android/lazyclasskey/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000..9a6ab88d1 --- /dev/null +++ b/javatests/artifacts/hilt-android/lazyclasskey/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2024 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. + --> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="hilt.lazyclasskey"> + <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="34"/> + <application android:name=".FlowerApp" + android:taskAffinity="" + android:theme="@style/Theme.AppCompat.Light.NoActionBar" + android:label="@string/app_name"> + <activity + android:name=".FlowerActivity" + android:exported="true"> + <intent-filter> + <action android:name="android.intent.action.MAIN"/> + <category android:name="android.intent.category.LAUNCHER"/> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/javatests/artifacts/hilt-android/lazyclasskey/app/src/main/java/hilt/lazyclasskey/Flower.java b/javatests/artifacts/hilt-android/lazyclasskey/app/src/main/java/hilt/lazyclasskey/Flower.java new file mode 100644 index 000000000..f7d23fc28 --- /dev/null +++ b/javatests/artifacts/hilt-android/lazyclasskey/app/src/main/java/hilt/lazyclasskey/Flower.java @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2024 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 hilt.lazyclasskey; + +/** Base class for flowers. */ +interface Flower {} diff --git a/javatests/artifacts/hilt-android/lazyclasskey/app/src/main/java/hilt/lazyclasskey/FlowerActivity.java b/javatests/artifacts/hilt-android/lazyclasskey/app/src/main/java/hilt/lazyclasskey/FlowerActivity.java new file mode 100644 index 000000000..b85bde040 --- /dev/null +++ b/javatests/artifacts/hilt-android/lazyclasskey/app/src/main/java/hilt/lazyclasskey/FlowerActivity.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2024 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 hilt.lazyclasskey; + +import android.os.Bundle; +import androidx.appcompat.app.AppCompatActivity; +import android.widget.TextView; +import dagger.hilt.android.AndroidEntryPoint; +import java.util.Locale; +import java.util.Map; +import javax.inject.Inject; + +/** Displays flower price information. */ +@AndroidEntryPoint +public final class FlowerActivity extends AppCompatActivity { + @Inject Map<Class<?>, Integer> flowerPrices; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.flower_activity); + if (!flowerPrices.containsKey(Rose.class)) { + throw new IllegalStateException("Rose price not found"); + } + if (!flowerPrices.containsKey(Lily.class)) { + throw new IllegalStateException("Lily price not found"); + } + ((TextView) findViewById(R.id.flower_info)) + .setText( + String.format( + Locale.US, + "%s : %d dollar, %s : %d dollar", + Lily.class.getSimpleName(), + flowerPrices.get(Lily.class), + Rose.class.getSimpleName(), + flowerPrices.get(Rose.class))); + } +} diff --git a/javatests/artifacts/hilt-android/lazyclasskey/app/src/main/java/hilt/lazyclasskey/FlowerApp.java b/javatests/artifacts/hilt-android/lazyclasskey/app/src/main/java/hilt/lazyclasskey/FlowerApp.java new file mode 100644 index 000000000..337ae8821 --- /dev/null +++ b/javatests/artifacts/hilt-android/lazyclasskey/app/src/main/java/hilt/lazyclasskey/FlowerApp.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2024 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 hilt.lazyclasskey; + +import android.app.Application; +import dagger.hilt.android.HiltAndroidApp; + +/** The main app responsible for providing flower information. */ +@HiltAndroidApp +public class FlowerApp extends Application {} diff --git a/javatests/artifacts/hilt-android/lazyclasskey/app/src/main/java/hilt/lazyclasskey/FlowerModule.java b/javatests/artifacts/hilt-android/lazyclasskey/app/src/main/java/hilt/lazyclasskey/FlowerModule.java new file mode 100644 index 000000000..3e04eac85 --- /dev/null +++ b/javatests/artifacts/hilt-android/lazyclasskey/app/src/main/java/hilt/lazyclasskey/FlowerModule.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2024 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 hilt.lazyclasskey; + +import dagger.Module; +import dagger.Provides; +import dagger.hilt.InstallIn; +import dagger.hilt.components.SingletonComponent; +import dagger.multibindings.IntoMap; +import dagger.multibindings.LazyClassKey; + +/** Module for providing flower prices. */ +@Module +@InstallIn(SingletonComponent.class) +abstract class FlowerModule { + @IntoMap + @LazyClassKey(Lily.class) + @Provides + static int lilyPrice() { + return 1; + } + + @IntoMap + @LazyClassKey(Rose.class) + @Provides + static int rosePrice() { + return 2; + } +} diff --git a/javatests/artifacts/hilt-android/lazyclasskey/app/src/main/java/hilt/lazyclasskey/Lily.java b/javatests/artifacts/hilt-android/lazyclasskey/app/src/main/java/hilt/lazyclasskey/Lily.java new file mode 100644 index 000000000..fc3831a9e --- /dev/null +++ b/javatests/artifacts/hilt-android/lazyclasskey/app/src/main/java/hilt/lazyclasskey/Lily.java @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2024 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 hilt.lazyclasskey; + +/** Stores info for Lily. */ +final class Lily implements Flower {} diff --git a/javatests/artifacts/hilt-android/lazyclasskey/app/src/main/java/hilt/lazyclasskey/Rose.java b/javatests/artifacts/hilt-android/lazyclasskey/app/src/main/java/hilt/lazyclasskey/Rose.java new file mode 100644 index 000000000..695d8fb56 --- /dev/null +++ b/javatests/artifacts/hilt-android/lazyclasskey/app/src/main/java/hilt/lazyclasskey/Rose.java @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2024 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 hilt.lazyclasskey; + +/** Stores information for Rose. */ +final class Rose implements Flower {} diff --git a/javatests/artifacts/hilt-android/lazyclasskey/app/src/main/res/layout/flower_activity.xml b/javatests/artifacts/hilt-android/lazyclasskey/app/src/main/res/layout/flower_activity.xml new file mode 100644 index 000000000..1c6f03f31 --- /dev/null +++ b/javatests/artifacts/hilt-android/lazyclasskey/app/src/main/res/layout/flower_activity.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2024 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. + --> +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + <TextView android:id="@+id/flower_info" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> +</LinearLayout> diff --git a/javatests/artifacts/hilt-android/lazyclasskey/app/src/main/res/values/strings.xml b/javatests/artifacts/hilt-android/lazyclasskey/app/src/main/res/values/strings.xml new file mode 100644 index 000000000..55a2258fc --- /dev/null +++ b/javatests/artifacts/hilt-android/lazyclasskey/app/src/main/res/values/strings.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2024 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. + --> +<resources> + <!-- The name of the application [CHAR LIMIT=25] --> + <string name="app_name">Flower Demo</string> +</resources> diff --git a/javatests/artifacts/hilt-android/lazyclasskey/build.gradle b/javatests/artifacts/hilt-android/lazyclasskey/build.gradle new file mode 100644 index 000000000..14bbfbd37 --- /dev/null +++ b/javatests/artifacts/hilt-android/lazyclasskey/build.gradle @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2024 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. + */ + +buildscript { + ext { + hilt_version = 'LOCAL-SNAPSHOT' + // AGP is set below 7.2.0 on purpose to be able to obfuscate debug apk. + agp_version = "7.1.2" + kotlin_version = '1.9.20' + } + repositories { + google() + mavenCentral() + mavenLocal() + } + dependencies { + classpath "com.android.tools.build:gradle:$agp_version" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version" + } +} + +allprojects { + repositories { + google() + mavenCentral() + mavenLocal() + } +} + +subprojects { + afterEvaluate { + dependencies { + // This is needed to align older versions of kotlin-stdlib. + // The main issue is that in v1.8.0 the jdk7 and jdk8 artifacts were + // merged into kotlin-stdlib, so without this alignment we end up + // getting duplicate classes by pulling in both artifacts. + // See: https://kotlinlang.org/docs/whatsnew18.html#usage-of-the-latest-kotlin-stdlib-version-in-transitive-dependencies + implementation(platform("org.jetbrains.kotlin:kotlin-bom:$kotlin_version")) + } + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/javatests/artifacts/hilt-android/lazyclasskey/gradle.properties b/javatests/artifacts/hilt-android/lazyclasskey/gradle.properties new file mode 100644 index 000000000..abca46e4f --- /dev/null +++ b/javatests/artifacts/hilt-android/lazyclasskey/gradle.properties @@ -0,0 +1,12 @@ +android.useAndroidX=true +android.enableJetifier=true + +# Enable and fail the build if an issue is found that disallows the +# configuration cache. These options along with this app being built in +# presubmit helps us cache changes that would cause config cache to be disabled +# via the HiltGradlePlugin. +org.gradle.unsafe.configuration-cache-problems=fail +org.gradle.unsafe.configuration-cache.max-problems=0 +org.gradle.caching=true +org.gradle.parallel=true +org.gradle.jvmargs=-Xmx2048m diff --git a/javatests/artifacts/hilt-android/lazyclasskey/gradle/wrapper/gradle-wrapper.jar b/javatests/artifacts/hilt-android/lazyclasskey/gradle/wrapper/gradle-wrapper.jar Binary files differnew file mode 100644 index 000000000..7f93135c4 --- /dev/null +++ b/javatests/artifacts/hilt-android/lazyclasskey/gradle/wrapper/gradle-wrapper.jar diff --git a/javatests/artifacts/hilt-android/lazyclasskey/gradle/wrapper/gradle-wrapper.properties b/javatests/artifacts/hilt-android/lazyclasskey/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..9623276bc --- /dev/null +++ b/javatests/artifacts/hilt-android/lazyclasskey/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/javatests/artifacts/hilt-android/lazyclasskey/gradlew b/javatests/artifacts/hilt-android/lazyclasskey/gradlew new file mode 100755 index 000000000..1aa94a426 --- /dev/null +++ b/javatests/artifacts/hilt-android/lazyclasskey/gradlew @@ -0,0 +1,249 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original 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 +# +# https://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. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/javatests/artifacts/hilt-android/lazyclasskey/gradlew.bat b/javatests/artifacts/hilt-android/lazyclasskey/gradlew.bat new file mode 100644 index 000000000..93e3f59f1 --- /dev/null +++ b/javatests/artifacts/hilt-android/lazyclasskey/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/javatests/artifacts/hilt-android/lazyclasskey/settings.gradle b/javatests/artifacts/hilt-android/lazyclasskey/settings.gradle new file mode 100644 index 000000000..5bb49fa71 --- /dev/null +++ b/javatests/artifacts/hilt-android/lazyclasskey/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'lazyclasskey' +include('app') diff --git a/javatests/artifacts/hilt-android/pluginMarker/app/build.gradle b/javatests/artifacts/hilt-android/pluginMarker/app/build.gradle index d07d68c58..e4cde41e7 100644 --- a/javatests/artifacts/hilt-android/pluginMarker/app/build.gradle +++ b/javatests/artifacts/hilt-android/pluginMarker/app/build.gradle @@ -20,13 +20,13 @@ plugins { } android { - compileSdkVersion 32 - buildToolsVersion "32.0.0" + compileSdkVersion 33 + buildToolsVersion "33.0.0" defaultConfig { applicationId "dagger.hilt.android.simple" - minSdkVersion 21 - targetSdkVersion 32 + minSdkVersion 16 + targetSdkVersion 33 } compileOptions { diff --git a/javatests/artifacts/hilt-android/pluginMarker/gradle.properties b/javatests/artifacts/hilt-android/pluginMarker/gradle.properties index 6cde789f6..0bdf325d5 100644 --- a/javatests/artifacts/hilt-android/pluginMarker/gradle.properties +++ b/javatests/artifacts/hilt-android/pluginMarker/gradle.properties @@ -1,3 +1,4 @@ android.useAndroidX=true org.gradle.caching=true -org.gradle.parallel=true
\ No newline at end of file +org.gradle.parallel=true +org.gradle.jvmargs=-Xmx2048m
\ No newline at end of file diff --git a/javatests/artifacts/hilt-android/pluginMarker/gradle/wrapper/gradle-wrapper.properties b/javatests/artifacts/hilt-android/pluginMarker/gradle/wrapper/gradle-wrapper.properties index 0f80bbf51..98debb84d 100644 --- a/javatests/artifacts/hilt-android/pluginMarker/gradle/wrapper/gradle-wrapper.properties +++ b/javatests/artifacts/hilt-android/pluginMarker/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/javatests/artifacts/hilt-android/simple/app-java-only/build.gradle b/javatests/artifacts/hilt-android/simple/app-java-only/build.gradle index 823b2025f..7a156efd5 100644 --- a/javatests/artifacts/hilt-android/simple/app-java-only/build.gradle +++ b/javatests/artifacts/hilt-android/simple/app-java-only/build.gradle @@ -18,13 +18,13 @@ apply plugin: 'com.android.application' apply plugin: 'com.google.dagger.hilt.android' android { - compileSdkVersion 32 - buildToolsVersion "32.0.0" + compileSdkVersion 33 + buildToolsVersion "33.0.0" defaultConfig { applicationId "dagger.hilt.android.simple" - minSdkVersion 15 - targetSdkVersion 32 + minSdkVersion 16 + targetSdkVersion 33 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/javatests/artifacts/hilt-android/simple/app/build.gradle b/javatests/artifacts/hilt-android/simple/app/build.gradle index 48d9b996a..8a196cf70 100644 --- a/javatests/artifacts/hilt-android/simple/app/build.gradle +++ b/javatests/artifacts/hilt-android/simple/app/build.gradle @@ -43,13 +43,13 @@ def getAdditionalTestDirs(String variant) { } android { - compileSdkVersion 32 - buildToolsVersion "32.0.0" + compileSdkVersion 33 + buildToolsVersion "33.0.0" defaultConfig { applicationId "dagger.hilt.android.simple" - minSdkVersion 15 - targetSdkVersion 32 + minSdkVersion 16 + targetSdkVersion 33 versionCode 1 versionName "1.0" testInstrumentationRunner "dagger.hilt.android.simple.SimpleEmulatorTestRunner" diff --git a/javatests/artifacts/hilt-android/simple/build.gradle b/javatests/artifacts/hilt-android/simple/build.gradle index ac3230e96..e0f39a36c 100644 --- a/javatests/artifacts/hilt-android/simple/build.gradle +++ b/javatests/artifacts/hilt-android/simple/build.gradle @@ -17,7 +17,7 @@ buildscript { ext { dagger_version = 'LOCAL-SNAPSHOT' - kotlin_version = '1.8.0' + kotlin_version = '1.9.20' agp_version = System.getenv('AGP_VERSION') ?: "7.1.2" } repositories { diff --git a/javatests/artifacts/hilt-android/simple/deep-android-lib/build.gradle b/javatests/artifacts/hilt-android/simple/deep-android-lib/build.gradle index 41b125d13..ab5424efc 100644 --- a/javatests/artifacts/hilt-android/simple/deep-android-lib/build.gradle +++ b/javatests/artifacts/hilt-android/simple/deep-android-lib/build.gradle @@ -4,12 +4,12 @@ plugins { } android { - compileSdkVersion 32 - buildToolsVersion "32.0.0" + compileSdkVersion 33 + buildToolsVersion "33.0.0" defaultConfig { - minSdkVersion 15 - targetSdkVersion 32 + minSdkVersion 16 + targetSdkVersion 33 versionCode 1 versionName "1.0" } diff --git a/javatests/artifacts/hilt-android/simple/earlyentrypoint/build.gradle b/javatests/artifacts/hilt-android/simple/earlyentrypoint/build.gradle index 4c3d8c823..2a36e6fb2 100644 --- a/javatests/artifacts/hilt-android/simple/earlyentrypoint/build.gradle +++ b/javatests/artifacts/hilt-android/simple/earlyentrypoint/build.gradle @@ -4,12 +4,12 @@ plugins { } android { - compileSdkVersion 32 - buildToolsVersion "32.0.0" + compileSdkVersion 33 + buildToolsVersion "33.0.0" defaultConfig { - minSdkVersion 15 - targetSdkVersion 32 + minSdkVersion 16 + targetSdkVersion 33 versionCode 1 versionName "1.0" } diff --git a/javatests/artifacts/hilt-android/simple/feature/build.gradle b/javatests/artifacts/hilt-android/simple/feature/build.gradle index ab9a3438d..dd33e291d 100644 --- a/javatests/artifacts/hilt-android/simple/feature/build.gradle +++ b/javatests/artifacts/hilt-android/simple/feature/build.gradle @@ -20,12 +20,12 @@ apply plugin: 'kotlin-kapt' apply plugin: 'com.google.dagger.hilt.android' android { - compileSdkVersion 32 - buildToolsVersion "32.0.0" + compileSdkVersion 33 + buildToolsVersion "33.0.0" defaultConfig { - minSdkVersion 15 - targetSdkVersion 32 + minSdkVersion 16 + targetSdkVersion 33 versionCode 1 versionName "1.0" } diff --git a/javatests/artifacts/hilt-android/simple/gradle.properties b/javatests/artifacts/hilt-android/simple/gradle.properties index b88e839aa..1efa70f69 100644 --- a/javatests/artifacts/hilt-android/simple/gradle.properties +++ b/javatests/artifacts/hilt-android/simple/gradle.properties @@ -9,3 +9,4 @@ org.gradle.unsafe.configuration-cache-problems=fail org.gradle.unsafe.configuration-cache.max-problems=0 org.gradle.caching=true org.gradle.parallel=true +org.gradle.jvmargs=-Xmx2048m
\ No newline at end of file diff --git a/javatests/artifacts/hilt-android/simple/gradle/wrapper/gradle-wrapper.properties b/javatests/artifacts/hilt-android/simple/gradle/wrapper/gradle-wrapper.properties index 00e33edef..98debb84d 100644 --- a/javatests/artifacts/hilt-android/simple/gradle/wrapper/gradle-wrapper.properties +++ b/javatests/artifacts/hilt-android/simple/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/javatests/artifacts/hilt-android/simple/uitest/build.gradle b/javatests/artifacts/hilt-android/simple/uitest/build.gradle index 9875b64d4..7c4e0fde2 100644 --- a/javatests/artifacts/hilt-android/simple/uitest/build.gradle +++ b/javatests/artifacts/hilt-android/simple/uitest/build.gradle @@ -18,12 +18,12 @@ apply plugin: 'com.android.test' apply plugin: 'com.google.dagger.hilt.android' android { - compileSdkVersion 32 - buildToolsVersion "32.0.0" + compileSdkVersion 33 + buildToolsVersion "33.0.0" defaultConfig { - minSdkVersion 15 - targetSdkVersion 32 + minSdkVersion 16 + targetSdkVersion 33 testInstrumentationRunner "dagger.hilt.android.simple.uitest.TestRunner" missingDimensionStrategy 'tier', 'free' } diff --git a/javatests/artifacts/hilt-android/simpleKotlin/android-library/build.gradle b/javatests/artifacts/hilt-android/simpleKotlin/android-library/build.gradle index 3c97d6f2a..1e83543c9 100644 --- a/javatests/artifacts/hilt-android/simpleKotlin/android-library/build.gradle +++ b/javatests/artifacts/hilt-android/simpleKotlin/android-library/build.gradle @@ -6,12 +6,12 @@ plugins { } android { - compileSdkVersion 32 - buildToolsVersion "32.0.0" + compileSdkVersion 33 + buildToolsVersion "33.0.0" defaultConfig { - minSdkVersion 15 - targetSdkVersion 32 + minSdkVersion 16 + targetSdkVersion 33 versionCode 1 versionName "1.0" } diff --git a/javatests/artifacts/hilt-android/simpleKotlin/app/build.gradle b/javatests/artifacts/hilt-android/simpleKotlin/app/build.gradle index 0b860afc5..fe4f5b424 100644 --- a/javatests/artifacts/hilt-android/simpleKotlin/app/build.gradle +++ b/javatests/artifacts/hilt-android/simpleKotlin/app/build.gradle @@ -21,13 +21,13 @@ apply plugin: 'kotlin-kapt' apply plugin: 'com.google.devtools.ksp' android { - compileSdkVersion 32 - buildToolsVersion "32.0.0" + compileSdkVersion 33 + buildToolsVersion "33.0.0" defaultConfig { applicationId "dagger.hilt.android.simpleKotlin" - minSdkVersion 15 - targetSdkVersion 32 + minSdkVersion 16 + targetSdkVersion 33 versionCode 1 versionName "1.0" testInstrumentationRunner "dagger.hilt.android.example.gradle.simpleKotlin.TestRunner" diff --git a/javatests/artifacts/hilt-android/simpleKotlin/build.gradle b/javatests/artifacts/hilt-android/simpleKotlin/build.gradle index eee480616..3773deb0d 100644 --- a/javatests/artifacts/hilt-android/simpleKotlin/build.gradle +++ b/javatests/artifacts/hilt-android/simpleKotlin/build.gradle @@ -16,8 +16,8 @@ buildscript { ext { - kotlin_version = '1.8.20' - ksp_version = '1.0.11' + kotlin_version = '1.9.20' + ksp_version = "$kotlin_version-1.0.14" agp_version = System.getenv('AGP_VERSION') ?: "7.1.2" } repositories { @@ -28,7 +28,7 @@ buildscript { dependencies { classpath "com.android.tools.build:gradle:$agp_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath "com.google.devtools.ksp:symbol-processing-gradle-plugin:$kotlin_version-$ksp_version" + classpath "com.google.devtools.ksp:symbol-processing-gradle-plugin:$ksp_version" classpath 'com.google.dagger:hilt-android-gradle-plugin:LOCAL-SNAPSHOT' } } diff --git a/javatests/artifacts/hilt-android/simpleKotlin/deep-android-lib/build.gradle b/javatests/artifacts/hilt-android/simpleKotlin/deep-android-lib/build.gradle index b248a0b80..8973bb9a2 100644 --- a/javatests/artifacts/hilt-android/simpleKotlin/deep-android-lib/build.gradle +++ b/javatests/artifacts/hilt-android/simpleKotlin/deep-android-lib/build.gradle @@ -7,12 +7,12 @@ plugins { } android { - compileSdkVersion 32 - buildToolsVersion "32.0.0" + compileSdkVersion 33 + buildToolsVersion "33.0.0" defaultConfig { - minSdkVersion 15 - targetSdkVersion 32 + minSdkVersion 16 + targetSdkVersion 33 versionCode 1 versionName "1.0" diff --git a/javatests/artifacts/hilt-android/simpleKotlin/gradle.properties b/javatests/artifacts/hilt-android/simpleKotlin/gradle.properties index b88e839aa..1efa70f69 100644 --- a/javatests/artifacts/hilt-android/simpleKotlin/gradle.properties +++ b/javatests/artifacts/hilt-android/simpleKotlin/gradle.properties @@ -9,3 +9,4 @@ org.gradle.unsafe.configuration-cache-problems=fail org.gradle.unsafe.configuration-cache.max-problems=0 org.gradle.caching=true org.gradle.parallel=true +org.gradle.jvmargs=-Xmx2048m
\ No newline at end of file diff --git a/javatests/artifacts/hilt-android/simpleKotlin/gradle/wrapper/gradle-wrapper.properties b/javatests/artifacts/hilt-android/simpleKotlin/gradle/wrapper/gradle-wrapper.properties index 00e33edef..98debb84d 100644 --- a/javatests/artifacts/hilt-android/simpleKotlin/gradle/wrapper/gradle-wrapper.properties +++ b/javatests/artifacts/hilt-android/simpleKotlin/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/javatests/artifacts/hilt-android/viewmodel/app/build.gradle b/javatests/artifacts/hilt-android/viewmodel/app/build.gradle new file mode 100644 index 000000000..a212b3cb0 --- /dev/null +++ b/javatests/artifacts/hilt-android/viewmodel/app/build.gradle @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2023 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. + */ + +plugins { + id 'com.android.application' + id 'com.google.dagger.hilt.android' +} + +android { + + namespace 'dagger.hilt.viewmodel' + compileSdkVersion 33 + defaultConfig { + applicationId 'dagger.hilt.viewmodel' + minSdk 16 + targetSdk 33 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + debug { + minifyEnabled true + shrinkResources true + proguardFiles getDefaultProguardFile( + 'proguard-android-optimize.txt'), + 'proguard-rules.pro' + + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 + } +} + +dependencies { + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.errorprone:error_prone_annotations:2.15.0' + + androidTestImplementation 'androidx.test:core:1.5.0-alpha02' + androidTestImplementation 'androidx.test.ext:junit:1.1.3' + androidTestImplementation "androidx.test:runner:1.5.2" + androidTestImplementation "androidx.test:rules:1.5.0" + androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' + + // Hilt dependencies + implementation "com.google.dagger:hilt-android:$hilt_version" + annotationProcessor "com.google.dagger:hilt-compiler:$hilt_version" +} diff --git a/javatests/artifacts/hilt-android/viewmodel/app/proguard-rules.pro b/javatests/artifacts/hilt-android/viewmodel/app/proguard-rules.pro new file mode 100644 index 000000000..092902889 --- /dev/null +++ b/javatests/artifacts/hilt-android/viewmodel/app/proguard-rules.pro @@ -0,0 +1,2 @@ +-dontwarn com.google.errorprone.annotations.MustBeClosed +-keep class kotlin.** diff --git a/javatests/artifacts/hilt-android/viewmodel/app/src/androidTest/java/dagger/hilt/viewmodel/SimpleApplicationTest.java b/javatests/artifacts/hilt-android/viewmodel/app/src/androidTest/java/dagger/hilt/viewmodel/SimpleApplicationTest.java new file mode 100644 index 000000000..bf4723531 --- /dev/null +++ b/javatests/artifacts/hilt-android/viewmodel/app/src/androidTest/java/dagger/hilt/viewmodel/SimpleApplicationTest.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2023 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.viewmodel; + +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.ViewMatchers.withResourceName; +import static androidx.test.espresso.matcher.ViewMatchers.withText; +import static org.hamcrest.Matchers.startsWith; + +import android.content.Intent; +import androidx.test.core.app.ActivityScenario; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class SimpleApplicationTest { + @Test + public void testHiltViewModelWithR8DoesNotCrash() { + Intent mainIntent = + new Intent(ApplicationProvider.getApplicationContext(), SimpleActivity.class); + try (ActivityScenario<SimpleActivity> scenario = ActivityScenario.launch(mainIntent)) { + onView(withResourceName("greeting")) + .check(matches(withText(startsWith("Hello")))); + } + } +} diff --git a/javatests/artifacts/hilt-android/viewmodel/app/src/main/AndroidManifest.xml b/javatests/artifacts/hilt-android/viewmodel/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000..82afa17d0 --- /dev/null +++ b/javatests/artifacts/hilt-android/viewmodel/app/src/main/AndroidManifest.xml @@ -0,0 +1,29 @@ +<!-- + ~ Copyright (C) 2023 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. + --> +<manifest xmlns:android="http://schemas.android.com/apk/res/android"> + + <application android:name=".SimpleApplication" android:label="@string/appName"> + <activity + android:name=".SimpleActivity" + android:theme="@style/Theme.AppCompat.Light" + android:exported="true"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/javatests/artifacts/hilt-android/viewmodel/app/src/main/java/dagger/hilt/viewmodel/SimpleActivity.java b/javatests/artifacts/hilt-android/viewmodel/app/src/main/java/dagger/hilt/viewmodel/SimpleActivity.java new file mode 100644 index 000000000..ad6e73899 --- /dev/null +++ b/javatests/artifacts/hilt-android/viewmodel/app/src/main/java/dagger/hilt/viewmodel/SimpleActivity.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2023 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.viewmodel; + +import android.os.Bundle; +import android.widget.TextView; +import androidx.annotation.OptIn; +import androidx.appcompat.app.AppCompatActivity; +import androidx.lifecycle.SavedStateHandle; +import androidx.lifecycle.ViewModelProvider; +import dagger.hilt.android.AndroidEntryPoint; +import dagger.hilt.android.UnstableApi; +import dagger.hilt.android.lifecycle.ActivityRetainedSavedState; +import javax.inject.Inject; + +/** The main activity of the application. */ +@OptIn(markerClass = UnstableApi.class) +@AndroidEntryPoint +public class SimpleActivity extends AppCompatActivity { + private static final String TAG = SimpleActivity.class.getSimpleName(); + + @Inject + @ActivityRetainedSavedState + SavedStateHandle savedStateHandle; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + SimpleViewModel viewModel = new ViewModelProvider(this).get(SimpleViewModel.class); + savedStateHandle.set("some_key", "some_content"); + setContentView(R.layout.activity_main); + + ((TextView) findViewById(R.id.greeting)) + .setText(getResources().getString(R.string.welcome, viewModel.userName)); + } +} diff --git a/javatests/artifacts/hilt-android/viewmodel/app/src/main/java/dagger/hilt/viewmodel/SimpleApplication.java b/javatests/artifacts/hilt-android/viewmodel/app/src/main/java/dagger/hilt/viewmodel/SimpleApplication.java new file mode 100644 index 000000000..eed62b175 --- /dev/null +++ b/javatests/artifacts/hilt-android/viewmodel/app/src/main/java/dagger/hilt/viewmodel/SimpleApplication.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2023 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.viewmodel; + +import android.app.Application; +import dagger.hilt.android.HiltAndroidApp; + +/** + * A simple, skeletal application that demonstrates a dependency-injected application using the + * utilities in {@code Hilt} in Android. + */ +@HiltAndroidApp +public class SimpleApplication extends Application {} diff --git a/javatests/artifacts/hilt-android/viewmodel/app/src/main/java/dagger/hilt/viewmodel/SimpleViewModel.java b/javatests/artifacts/hilt-android/viewmodel/app/src/main/java/dagger/hilt/viewmodel/SimpleViewModel.java new file mode 100644 index 000000000..0509d233a --- /dev/null +++ b/javatests/artifacts/hilt-android/viewmodel/app/src/main/java/dagger/hilt/viewmodel/SimpleViewModel.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2023 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.viewmodel; + +import androidx.lifecycle.ViewModel; +import dagger.hilt.android.lifecycle.HiltViewModel; +import javax.inject.Inject; + +/** The view model requires creation by hilt. */ +@HiltViewModel +public final class SimpleViewModel extends ViewModel { + String userName; + + @Inject + SimpleViewModel(@UserName String userName) { + this.userName = userName; + } +} diff --git a/javatests/artifacts/hilt-android/viewmodel/app/src/main/java/dagger/hilt/viewmodel/UserName.java b/javatests/artifacts/hilt-android/viewmodel/app/src/main/java/dagger/hilt/viewmodel/UserName.java new file mode 100644 index 000000000..6bed1cbc6 --- /dev/null +++ b/javatests/artifacts/hilt-android/viewmodel/app/src/main/java/dagger/hilt/viewmodel/UserName.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2023 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.viewmodel; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import javax.inject.Qualifier; + +/** Qualifies bindings relating to the user name. */ +@Qualifier +@Retention(RUNTIME) +@Documented +@interface UserName {} diff --git a/javatests/artifacts/hilt-android/viewmodel/app/src/main/java/dagger/hilt/viewmodel/UserNameModule.java b/javatests/artifacts/hilt-android/viewmodel/app/src/main/java/dagger/hilt/viewmodel/UserNameModule.java new file mode 100644 index 000000000..e1d5bd547 --- /dev/null +++ b/javatests/artifacts/hilt-android/viewmodel/app/src/main/java/dagger/hilt/viewmodel/UserNameModule.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2023 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.viewmodel; + +import dagger.Module; +import dagger.Provides; +import dagger.hilt.InstallIn; +import dagger.hilt.android.components.ViewModelComponent; +import java.util.Random; + +@Module +@InstallIn(ViewModelComponent.class) +final class UserNameModule { + @UserName + @Provides + static String provideUserName() { + return "ProdUser-" + new Random().nextInt(); + } + + private UserNameModule() {} +} diff --git a/javatests/artifacts/hilt-android/viewmodel/app/src/main/res/layout/activity_main.xml b/javatests/artifacts/hilt-android/viewmodel/app/src/main/res/layout/activity_main.xml new file mode 100644 index 000000000..d785a7f27 --- /dev/null +++ b/javatests/artifacts/hilt-android/viewmodel/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2023 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. + --> + +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@android:color/background_light"> + + <TextView + android:id="@+id/greeting" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_alignParentTop="true" + android:textColor="@android:color/primary_text_light" + /> + + <Button + android:id="@+id/goto_feature" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_below="@id/greeting" + android:text="@string/navigateToFeature" + /> +</RelativeLayout> diff --git a/javatests/artifacts/hilt-android/viewmodel/app/src/main/res/values/strings.xml b/javatests/artifacts/hilt-android/viewmodel/app/src/main/res/values/strings.xml new file mode 100644 index 000000000..519ca44a9 --- /dev/null +++ b/javatests/artifacts/hilt-android/viewmodel/app/src/main/res/values/strings.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2023 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. + --> + +<resources> + <!--The app name [CHAR_LIMIT=20]--> + <string name="appName">Simple Hilt Android</string> + + <!--The greeting message [CHAR_LIMIT=100]--> + <string name="welcome">Hello, %1$s!</string> + + <!--The feature button message [CHAR_LIMIT=100]--> + <string name="navigateToFeature">Navigate to a feature!</string> +</resources> diff --git a/javatests/artifacts/hilt-android/viewmodel/build.gradle b/javatests/artifacts/hilt-android/viewmodel/build.gradle new file mode 100644 index 000000000..bbcc108dd --- /dev/null +++ b/javatests/artifacts/hilt-android/viewmodel/build.gradle @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2023 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. + */ + +buildscript { + ext { + hilt_version = 'LOCAL-SNAPSHOT' + // AGP is set below 7.2.0 on purpose to be able to obfuscate debug apk. + agp_version = "7.1.2" + kotlin_version = '1.9.20' + } + repositories { + google() + mavenCentral() + mavenLocal() + } + dependencies { + classpath "com.android.tools.build:gradle:$agp_version" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version" + } +} + +allprojects { + repositories { + google() + mavenCentral() + mavenLocal() + } +} + +subprojects { + afterEvaluate { + dependencies { + // This is needed to align older versions of kotlin-stdlib. + // The main issue is that in v1.8.0 the jdk7 and jdk8 artifacts were + // merged into kotlin-stdlib, so without this alignment we end up + // getting duplicate classes by pulling in both artifacts. + // See: https://kotlinlang.org/docs/whatsnew18.html#usage-of-the-latest-kotlin-stdlib-version-in-transitive-dependencies + implementation(platform("org.jetbrains.kotlin:kotlin-bom:$kotlin_version")) + } + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/javatests/artifacts/hilt-android/viewmodel/gradle.properties b/javatests/artifacts/hilt-android/viewmodel/gradle.properties new file mode 100644 index 000000000..1efa70f69 --- /dev/null +++ b/javatests/artifacts/hilt-android/viewmodel/gradle.properties @@ -0,0 +1,12 @@ +android.useAndroidX=true +android.enableJetifier=true + +# Enable and fail the build if an issue is found that disallows the +# configuration cache. These options along with this app being built in +# presubmit helps us cache changes that would cause config cache to be disabled +# via the HiltGradlePlugin. +org.gradle.unsafe.configuration-cache-problems=fail +org.gradle.unsafe.configuration-cache.max-problems=0 +org.gradle.caching=true +org.gradle.parallel=true +org.gradle.jvmargs=-Xmx2048m
\ No newline at end of file diff --git a/javatests/artifacts/hilt-android/viewmodel/gradle/wrapper/gradle-wrapper.jar b/javatests/artifacts/hilt-android/viewmodel/gradle/wrapper/gradle-wrapper.jar Binary files differnew file mode 100644 index 000000000..7f93135c4 --- /dev/null +++ b/javatests/artifacts/hilt-android/viewmodel/gradle/wrapper/gradle-wrapper.jar diff --git a/javatests/artifacts/hilt-android/viewmodel/gradle/wrapper/gradle-wrapper.properties b/javatests/artifacts/hilt-android/viewmodel/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..9623276bc --- /dev/null +++ b/javatests/artifacts/hilt-android/viewmodel/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/javatests/artifacts/hilt-android/viewmodel/gradlew b/javatests/artifacts/hilt-android/viewmodel/gradlew new file mode 100755 index 000000000..1aa94a426 --- /dev/null +++ b/javatests/artifacts/hilt-android/viewmodel/gradlew @@ -0,0 +1,249 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original 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 +# +# https://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. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/javatests/artifacts/hilt-android/viewmodel/gradlew.bat b/javatests/artifacts/hilt-android/viewmodel/gradlew.bat new file mode 100644 index 000000000..93e3f59f1 --- /dev/null +++ b/javatests/artifacts/hilt-android/viewmodel/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/javatests/artifacts/hilt-android/viewmodel/settings.gradle b/javatests/artifacts/hilt-android/viewmodel/settings.gradle new file mode 100644 index 000000000..5a0650e5e --- /dev/null +++ b/javatests/artifacts/hilt-android/viewmodel/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = "Simple ViewModel" +include ':app'
\ No newline at end of file diff --git a/javatests/dagger/android/processor/AndroidMapKeyValidatorTest.java b/javatests/dagger/android/processor/AndroidMapKeyValidatorTest.java index cfa6e90b5..fc05b6154 100644 --- a/javatests/dagger/android/processor/AndroidMapKeyValidatorTest.java +++ b/javatests/dagger/android/processor/AndroidMapKeyValidatorTest.java @@ -16,22 +16,18 @@ package dagger.android.processor; -import static com.google.testing.compile.CompilationSubject.assertThat; -import static com.google.testing.compile.Compiler.javac; - +import androidx.room.compiler.processing.util.Source; import com.google.common.base.Joiner; -import com.google.testing.compile.Compilation; -import com.google.testing.compile.JavaFileObjects; -import dagger.internal.codegen.ComponentProcessor; -import javax.tools.JavaFileObject; +import dagger.testing.compile.CompilerTests; +import dagger.testing.compile.CompilerTests.DaggerCompiler; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @RunWith(JUnit4.class) public class AndroidMapKeyValidatorTest { - private static final JavaFileObject FOO_ACTIVITY = - JavaFileObjects.forSourceLines( + private static final Source FOO_ACTIVITY = + CompilerTests.javaSource( "test.FooActivity", "package test;", "", @@ -42,8 +38,8 @@ public class AndroidMapKeyValidatorTest { " interface Factory extends AndroidInjector.Factory<FooActivity> {}", " abstract static class Builder extends AndroidInjector.Builder<FooActivity> {}", "}"); - private static final JavaFileObject BAR_ACTIVITY = - JavaFileObjects.forSourceLines( + private static final Source BAR_ACTIVITY = + CompilerTests.javaSource( "test.BarActivity", "package test;", "", @@ -51,8 +47,8 @@ public class AndroidMapKeyValidatorTest { "", "public class BarActivity extends Activity {}"); - private static JavaFileObject moduleWithMethod(String... lines) { - return JavaFileObjects.forSourceLines( + private static Source moduleWithMethod(String... lines) { + return CompilerTests.javaSource( "test.AndroidModule", "package test;", "", @@ -75,56 +71,86 @@ public class AndroidMapKeyValidatorTest { @Test public void rawFactoryType() { - JavaFileObject module = + Source module = moduleWithMethod( "@Binds", "@IntoMap", "@ClassKey(FooActivity.class)", "abstract AndroidInjector.Factory bindRawFactory(FooActivity.Factory factory);"); - Compilation compilation = compile(module, FOO_ACTIVITY); - assertThat(compilation).failed(); - assertThat(compilation) - .hadErrorContaining( - "should bind dagger.android.AndroidInjector.Factory<?>, " - + "not dagger.android.AndroidInjector.Factory"); + compile(module, FOO_ACTIVITY) + .compile( + subject -> { + subject.compilationDidFail(); + subject.hasErrorContaining( + "should bind dagger.android.AndroidInjector.Factory<?>, " + + "not dagger.android.AndroidInjector.Factory"); + }); + } + + @Test + public void wildCardFactoryType() { + Source module = + CompilerTests.kotlinSource( + "AndroidModule.kt", + "package test", + "", + "import dagger.Module", + "import dagger.Binds", + "import dagger.android.AndroidInjector", + "import dagger.multibindings.ClassKey", + "import dagger.multibindings.IntoMap", + "", + "@Module", + "internal abstract class AndroidModule {", + " @Binds", + " @IntoMap", + " @ClassKey(FooActivity::class)", + " abstract fun bindWildcardFactory(factory: FooActivity.Factory):" + + " AndroidInjector.Factory<*>", + "}"); + compile(module, FOO_ACTIVITY).compile(subject -> subject.hasErrorCount(0)); } @Test public void rawBuilderType() { - JavaFileObject module = + Source module = moduleWithMethod( "@Binds", "@IntoMap", "@ClassKey(FooActivity.class)", "abstract AndroidInjector.Builder bindRawBuilder(FooActivity.Builder builder);"); - Compilation compilation = compile(module, FOO_ACTIVITY); - assertThat(compilation).failed(); - assertThat(compilation) - .hadErrorContaining( - "should bind dagger.android.AndroidInjector.Factory<?>, " - + "not dagger.android.AndroidInjector.Builder"); + compile(module, FOO_ACTIVITY) + .compile( + subject -> { + subject.compilationDidFail(); + subject.hasErrorContaining( + "should bind dagger.android.AndroidInjector.Factory<?>, " + + "not dagger.android.AndroidInjector.Builder"); + }); } @Test public void bindsToBuilderNotFactory() { - JavaFileObject module = + Source module = moduleWithMethod( "@Binds", "@IntoMap", "@ClassKey(FooActivity.class)", "abstract AndroidInjector.Builder<?> bindBuilder(", " FooActivity.Builder builder);"); - Compilation compilation = compile(module, FOO_ACTIVITY); - assertThat(compilation).failed(); - assertThat(compilation) - .hadErrorContaining( - "should bind dagger.android.AndroidInjector.Factory<?>, not " - + "dagger.android.AndroidInjector.Builder<?>"); + compile(module, FOO_ACTIVITY) + .compile( + subject -> { + subject.compilationDidFail(); + subject.hasErrorContaining( + "should bind dagger.android.AndroidInjector.Factory<?>, not " + + "dagger.android.AndroidInjector.Builder<?>"); + }); } @Test public void providesToBuilderNotFactory() { - JavaFileObject module = + Source module = moduleWithMethod( "@Provides", "@IntoMap", @@ -132,99 +158,121 @@ public class AndroidMapKeyValidatorTest { "static AndroidInjector.Builder<?> bindBuilder(FooActivity.Builder builder) {", " return builder;", "}"); - Compilation compilation = compile(module, FOO_ACTIVITY); - assertThat(compilation).failed(); - assertThat(compilation) - .hadErrorContaining( - "should bind dagger.android.AndroidInjector.Factory<?>, not " - + "dagger.android.AndroidInjector.Builder<?>"); + compile(module, FOO_ACTIVITY) + .compile( + subject -> { + subject.compilationDidFail(); + subject.hasErrorContaining( + "should bind dagger.android.AndroidInjector.Factory<?>, not " + + "dagger.android.AndroidInjector.Builder<?>"); + }); } @Test public void bindsToConcreteTypeInsteadOfWildcard() { - JavaFileObject module = + Source module = moduleWithMethod( "@Binds", "@IntoMap", "@ClassKey(FooActivity.class)", "abstract AndroidInjector.Builder<FooActivity> bindBuilder(", " FooActivity.Builder builder);"); - Compilation compilation = compile(module, FOO_ACTIVITY); - assertThat(compilation).failed(); - assertThat(compilation) - .hadErrorContaining( - "should bind dagger.android.AndroidInjector.Factory<?>, not " - + "dagger.android.AndroidInjector.Builder<test.FooActivity>"); + compile(module, FOO_ACTIVITY) + .compile( + subject -> { + subject.compilationDidFail(); + subject.hasErrorContaining( + "should bind dagger.android.AndroidInjector.Factory<?>, not " + + "dagger.android.AndroidInjector.Builder<test.FooActivity>"); + }); } @Test public void bindsToBaseTypeInsteadOfWildcard() { - JavaFileObject module = + Source module = moduleWithMethod( "@Binds", "@IntoMap", "@ClassKey(FooActivity.class)", "abstract AndroidInjector.Builder<Activity> bindBuilder(", " FooActivity.Builder builder);"); - Compilation compilation = compile(module, FOO_ACTIVITY); - assertThat(compilation).failed(); - assertThat(compilation) - .hadErrorContaining("@Binds methods' parameter type must be assignable to the return type"); + compile(module, FOO_ACTIVITY) + .compile( + subject -> { + subject.compilationDidFail(); + subject.hasErrorContaining( + "@Binds methods' parameter type must be assignable to the return type"); + }); } @Test public void bindsCorrectType() { - JavaFileObject module = + Source module = moduleWithMethod( "@Binds", "@IntoMap", "@ClassKey(FooActivity.class)", "abstract AndroidInjector.Factory<?> bindCorrectType(FooActivity.Builder builder);"); - Compilation compilation = compile(module, FOO_ACTIVITY); - assertThat(compilation).succeededWithoutWarnings(); + compile(module, FOO_ACTIVITY) + .compile( + subject -> { + subject.hasErrorCount(0); + subject.hasNoWarnings(); + }); } @Test public void bindsCorrectType_AndroidInjectionKey() { - JavaFileObject module = + Source module = moduleWithMethod( "@Binds", "@IntoMap", "@AndroidInjectionKey(\"test.FooActivity\")", "abstract AndroidInjector.Factory<?> bindCorrectType(FooActivity.Builder builder);"); - Compilation compilation = compile(module, FOO_ACTIVITY); - assertThat(compilation).succeededWithoutWarnings(); + compile(module, FOO_ACTIVITY) + .compile( + subject -> { + subject.hasErrorCount(0); + subject.hasNoWarnings(); + }); } @Test public void bindsCorrectType_AndroidInjectionKey_unbounded() { - JavaFileObject module = + Source module = moduleWithMethod( "@Binds", "@IntoMap", "@AndroidInjectionKey(\"test.FooActivity\")", "abstract AndroidInjector.Factory<?> bindCorrectType(FooActivity.Builder builder);"); - Compilation compilation = compile(module, FOO_ACTIVITY); - assertThat(compilation).succeededWithoutWarnings(); + compile(module, FOO_ACTIVITY) + .compile( + subject -> { + subject.hasErrorCount(0); + subject.hasNoWarnings(); + }); } @Test public void bindsWithScope() { - JavaFileObject module = + Source module = moduleWithMethod( "@Binds", "@IntoMap", "@ClassKey(FooActivity.class)", "@Singleton", "abstract AndroidInjector.Factory<?> bindWithScope(FooActivity.Builder builder);"); - Compilation compilation = compile(module, FOO_ACTIVITY); - assertThat(compilation).failed(); - assertThat(compilation).hadErrorContaining("should not be scoped"); + compile(module, FOO_ACTIVITY) + .compile( + subject -> { + subject.compilationDidFail(); + subject.hasErrorContaining("should not be scoped"); + }); } @Test public void bindsWithScope_suppressWarnings() { - JavaFileObject module = + Source module = moduleWithMethod( "@SuppressWarnings(\"dagger.android.ScopedInjectorFactory\")", "@Binds", @@ -232,64 +280,77 @@ public class AndroidMapKeyValidatorTest { "@ClassKey(FooActivity.class)", "@Singleton", "abstract AndroidInjector.Factory<?> bindWithScope(FooActivity.Builder builder);"); - Compilation compilation = compile(module, FOO_ACTIVITY); - assertThat(compilation).succeededWithoutWarnings(); + compile(module, FOO_ACTIVITY) + .compile( + subject -> { + subject.hasErrorCount(0); + subject.hasNoWarnings(); + }); } @Test public void mismatchedMapKey_bindsFactory() { - JavaFileObject module = + Source module = moduleWithMethod( "@Binds", "@IntoMap", "@ClassKey(BarActivity.class)", "abstract AndroidInjector.Factory<?> mismatchedFactory(FooActivity.Factory factory);"); - Compilation compilation = compile(module, FOO_ACTIVITY, BAR_ACTIVITY); - assertThat(compilation).failed(); - assertThat(compilation) - .hadErrorContaining( - "test.FooActivity.Factory does not implement AndroidInjector<test.BarActivity>") - .inFile(module) - .onLine(LINES_BEFORE_METHOD + 3); + compile(module, FOO_ACTIVITY, BAR_ACTIVITY) + .compile( + subject -> { + subject.compilationDidFail(); + subject + .hasErrorContaining( + "test.FooActivity.Factory does not implement" + + " AndroidInjector<test.BarActivity>") + .onLine(LINES_BEFORE_METHOD + 3); + }); } @Test public void mismatchedMapKey_bindsBuilder() { - JavaFileObject module = + Source module = moduleWithMethod( "@Binds", "@IntoMap", "@ClassKey(BarActivity.class)", "abstract AndroidInjector.Factory<?> mismatchedBuilder(FooActivity.Builder builder);"); - Compilation compilation = compile(module, FOO_ACTIVITY, BAR_ACTIVITY); - assertThat(compilation).failed(); - assertThat(compilation) - .hadErrorContaining( - "test.FooActivity.Builder does not implement AndroidInjector<test.BarActivity>") - .inFile(module) - .onLine(LINES_BEFORE_METHOD + 3); + compile(module, FOO_ACTIVITY, BAR_ACTIVITY) + .compile( + subject -> { + subject.compilationDidFail(); + subject + .hasErrorContaining( + "test.FooActivity.Builder does not implement" + + " AndroidInjector<test.BarActivity>") + .onLine(LINES_BEFORE_METHOD + 3); + }); } @Test public void mismatchedMapKey_bindsBuilder_androidInjectionKey() { - JavaFileObject module = + Source module = moduleWithMethod( "@Binds", "@IntoMap", "@AndroidInjectionKey(\"test.BarActivity\")", "abstract AndroidInjector.Factory<?> mismatchedBuilder(FooActivity.Builder builder);"); - Compilation compilation = compile(module, FOO_ACTIVITY, BAR_ACTIVITY); - assertThat(compilation).failed(); - assertThat(compilation) - .hadErrorContaining( - "test.FooActivity.Builder does not implement AndroidInjector<test.BarActivity>") - .inFile(module) - .onLine(LINES_BEFORE_METHOD + 3); + compile(module, FOO_ACTIVITY, BAR_ACTIVITY) + .compile( + subject -> { + subject.compilationDidFail(); + subject + .hasErrorContaining( + "test.FooActivity.Builder does not implement" + + " AndroidInjector<test.BarActivity>") + .onLine(LINES_BEFORE_METHOD + 3); + }); } @Test public void mismatchedMapKey_providesBuilder() { - JavaFileObject module = + Source module = moduleWithMethod( "@Provides", "@IntoMap", @@ -297,13 +358,17 @@ public class AndroidMapKeyValidatorTest { "static AndroidInjector.Factory<?> mismatchedBuilder(FooActivity.Builder builder) {", " return builder;", "}"); - Compilation compilation = compile(module, FOO_ACTIVITY, BAR_ACTIVITY); - assertThat(compilation).succeededWithoutWarnings(); + compile(module, FOO_ACTIVITY, BAR_ACTIVITY) + .compile( + subject -> { + subject.hasErrorCount(0); + subject.hasNoWarnings(); + }); } @Test public void bindsQualifier_ignoresChecks() { - JavaFileObject module = + Source module = moduleWithMethod( "@Binds", "@IntoMap", @@ -312,48 +377,61 @@ public class AndroidMapKeyValidatorTest { // normally this should fail, since it is binding to a Builder not a Factory "abstract AndroidInjector.Builder<?> bindsBuilderWithQualifier(", " FooActivity.Builder builder);"); - Compilation compilation = compile(module, FOO_ACTIVITY); - assertThat(compilation).succeededWithoutWarnings(); + compile(module, FOO_ACTIVITY) + .compile( + subject -> { + subject.hasErrorCount(0); + subject.hasNoWarnings(); + }); } @Test public void bindToPrimitive() { - JavaFileObject module = + Source module = moduleWithMethod( "@Binds", "@IntoMap", "@AndroidInjectionKey(\"test.FooActivity\")", "abstract int bindInt(@Named(\"unused\") int otherInt);"); - Compilation compilation = compile(module, FOO_ACTIVITY); - assertThat(compilation).succeededWithoutWarnings(); + compile(module, FOO_ACTIVITY) + .compile( + subject -> { + subject.hasErrorCount(0); + subject.hasNoWarnings(); + }); } @Test public void bindToNonFrameworkClass() { - JavaFileObject module = + Source module = moduleWithMethod( "@Binds", "@IntoMap", "@AndroidInjectionKey(\"test.FooActivity\")", "abstract Number bindInt(Integer integer);"); - Compilation compilation = compile(module, FOO_ACTIVITY); - assertThat(compilation).succeededWithoutWarnings(); + compile(module, FOO_ACTIVITY) + .compile( + subject -> { + subject.hasErrorCount(0); + subject.hasNoWarnings(); + }); } @Test public void invalidBindsMethod() { - JavaFileObject module = + Source module = moduleWithMethod( "@Binds", "@IntoMap", "@ClassKey(FooActivity.class)", "abstract AndroidInjector.Factory<?> bindCorrectType(", " FooActivity.Builder builder, FooActivity.Builder builder2);"); - Compilation compilation = compile(module, FOO_ACTIVITY); - assertThat(compilation).failed(); + compile(module, FOO_ACTIVITY).compile(subject -> subject.compilationDidFail()); } - private Compilation compile(JavaFileObject... files) { - return javac().withProcessors(new ComponentProcessor(), new AndroidProcessor()).compile(files); + private DaggerCompiler compile(Source... files) { + return CompilerTests.daggerCompiler(files) + .withAdditionalJavacProcessors(new AndroidProcessor()) + .withAdditionalKspProcessors(new KspAndroidProcessor.Provider()); } } diff --git a/javatests/dagger/android/processor/BUILD b/javatests/dagger/android/processor/BUILD index 321293dd7..518234d0a 100644 --- a/javatests/dagger/android/processor/BUILD +++ b/javatests/dagger/android/processor/BUILD @@ -30,6 +30,7 @@ GenJavaTests( "//java/dagger/android", "//java/dagger/android/processor", "//java/dagger/internal/codegen:processor", + "//java/dagger/testing/compile", "//third_party/java/compile_testing", "//third_party/java/guava/base", "//third_party/java/guava/collect", diff --git a/javatests/dagger/android/processor/ContributesAndroidInjectorTest.java b/javatests/dagger/android/processor/ContributesAndroidInjectorTest.java index 1718737cb..70e885fa0 100644 --- a/javatests/dagger/android/processor/ContributesAndroidInjectorTest.java +++ b/javatests/dagger/android/processor/ContributesAndroidInjectorTest.java @@ -16,20 +16,17 @@ package dagger.android.processor; -import static com.google.testing.compile.CompilationSubject.assertThat; -import static com.google.testing.compile.Compiler.javac; - -import com.google.testing.compile.Compilation; -import com.google.testing.compile.JavaFileObjects; -import javax.tools.JavaFileObject; +import androidx.room.compiler.processing.util.Source; +import dagger.testing.compile.CompilerTests; +import dagger.testing.compile.CompilerTests.DaggerCompiler; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @RunWith(JUnit4.class) public final class ContributesAndroidInjectorTest { - private static final JavaFileObject TEST_ACTIVITY = - JavaFileObjects.forSourceLines( + private static final Source TEST_ACTIVITY = + CompilerTests.javaSource( "test.TestActivity", "package test;", "", @@ -39,8 +36,8 @@ public final class ContributesAndroidInjectorTest { @Test public void notAbstract() { - JavaFileObject module = - JavaFileObjects.forSourceLines( + Source module = + CompilerTests.javaSource( "test.TestModule", "package test;", "", @@ -55,26 +52,26 @@ public final class ContributesAndroidInjectorTest { " }", "}"); - Compilation compilation = compile(module, TEST_ACTIVITY); - assertThat(compilation).failed(); - assertThat(compilation) - .hadErrorContaining("must be abstract") - .inFile(module) - .onLineContaining("test()"); + compile(module, TEST_ACTIVITY) + .compile( + subject -> { + subject.compilationDidFail(); + subject.hasErrorContaining("must be abstract").onLineContaining("test()"); + }); } @Test public void hasParameters() { - JavaFileObject otherActivity = - JavaFileObjects.forSourceLines( + Source otherActivity = + CompilerTests.javaSource( "test.OtherActivity", "package test;", "", "import android.app.Activity;", "", "class OtherActivity extends Activity {}"); - JavaFileObject module = - JavaFileObjects.forSourceLines( + Source module = + CompilerTests.javaSource( "test.TestModule", "package test;", "", @@ -90,22 +87,19 @@ public final class ContributesAndroidInjectorTest { " abstract OtherActivity manyParams(OtherActivity two, Object o);", "}"); - Compilation compilation = compile(module, TEST_ACTIVITY, otherActivity); - assertThat(compilation).failed(); - assertThat(compilation) - .hadErrorContaining("cannot have parameters") - .inFile(module) - .onLineContaining("oneParam("); - assertThat(compilation) - .hadErrorContaining("cannot have parameters") - .inFile(module) - .onLineContaining("manyParams("); + compile(module, TEST_ACTIVITY, otherActivity) + .compile( + subject -> { + subject.compilationDidFail(); + subject.hasErrorContaining("cannot have parameters").onLineContaining("oneParam("); + subject.hasErrorContaining("cannot have parameters").onLineContaining("manyParams("); + }); } @Test public void notInAModule() { - JavaFileObject randomFile = - JavaFileObjects.forSourceLines( + Source randomFile = + CompilerTests.javaSource( "test.RandomFile", "package test;", "", @@ -116,26 +110,26 @@ public final class ContributesAndroidInjectorTest { " abstract TestActivity test() {}", "}"); - Compilation compilation = compile(randomFile, TEST_ACTIVITY); - assertThat(compilation).failed(); - assertThat(compilation) - .hadErrorContaining("must be in a @Module") - .inFile(randomFile) - .onLineContaining("test()"); + compile(randomFile, TEST_ACTIVITY) + .compile( + subject -> { + subject.compilationDidFail(); + subject.hasErrorContaining("must be in a @Module").onLineContaining("test()"); + }); } @Test public void parameterizedReturnType() { - JavaFileObject parameterizedActivity = - JavaFileObjects.forSourceLines( + Source parameterizedActivity = + CompilerTests.javaSource( "test.ParameterizedActivity", "package test;", "", "import android.app.Activity;", "", "class ParameterizedActivity<T> extends Activity {}"); - JavaFileObject module = - JavaFileObjects.forSourceLines( + Source module = + CompilerTests.javaSource( "test.TestModule", "package test;", "", @@ -148,18 +142,20 @@ public final class ContributesAndroidInjectorTest { " abstract <T> ParameterizedActivity<T> test();", "}"); - Compilation compilation = compile(module, TEST_ACTIVITY, parameterizedActivity); - assertThat(compilation).failed(); - assertThat(compilation) - .hadErrorContaining("cannot return parameterized types") - .inFile(module) - .onLineContaining("test()"); + compile(module, TEST_ACTIVITY, parameterizedActivity) + .compile( + subject -> { + subject.compilationDidFail(); + subject + .hasErrorContaining("cannot return parameterized types") + .onLineContaining("test()"); + }); } @Test public void moduleIsntModule() { - JavaFileObject module = - JavaFileObjects.forSourceLines( + Source module = + CompilerTests.javaSource( "test.TestModule", "package test;", "", @@ -172,18 +168,20 @@ public final class ContributesAndroidInjectorTest { " abstract TestActivity test();", "}"); - Compilation compilation = compile(module, TEST_ACTIVITY); - assertThat(compilation).failed(); - assertThat(compilation) - .hadErrorContaining("Intent is not a @Module") - .inFile(module) - .onLineContaining("modules = android.content.Intent.class"); + compile(module, TEST_ACTIVITY) + .compile( + subject -> { + subject.compilationDidFail(); + subject + .hasErrorContaining("Intent is not a @Module") + .onLineContaining("modules = android.content.Intent.class"); + }); } @Test public void hasQualifier() { - JavaFileObject module = - JavaFileObjects.forSourceLines( + Source module = + CompilerTests.javaSource( "test.TestModule", "package test;", "", @@ -200,15 +198,19 @@ public final class ContributesAndroidInjectorTest { " abstract TestActivity test();", "}"); - Compilation compilation = compile(module, TEST_ACTIVITY); - assertThat(compilation).failed(); - assertThat(compilation) - .hadErrorContaining("@ContributesAndroidInjector methods cannot have qualifiers") - .inFile(module) - .onLineContaining("@AndroidQualifier"); + compile(module, TEST_ACTIVITY) + .compile( + subject -> { + subject.compilationDidFail(); + subject + .hasErrorContaining("@ContributesAndroidInjector methods cannot have qualifiers") + .onLineContaining("@AndroidQualifier"); + }); } - private static Compilation compile(JavaFileObject... javaFileObjects) { - return javac().withProcessors(new AndroidProcessor()).compile(javaFileObjects); + private static DaggerCompiler compile(Source... sources) { + return CompilerTests.daggerCompiler(sources) + .withAdditionalJavacProcessors(new AndroidProcessor()) + .withAdditionalKspProcessors(new KspAndroidProcessor.Provider()); } } diff --git a/javatests/dagger/android/processor/DuplicateAndroidInjectorsCheckerTest.java b/javatests/dagger/android/processor/DuplicateAndroidInjectorsCheckerTest.java index a84c7eba9..65f8076dc 100644 --- a/javatests/dagger/android/processor/DuplicateAndroidInjectorsCheckerTest.java +++ b/javatests/dagger/android/processor/DuplicateAndroidInjectorsCheckerTest.java @@ -16,13 +16,10 @@ package dagger.android.processor; -import static com.google.testing.compile.CompilationSubject.assertThat; -import static com.google.testing.compile.Compiler.javac; - -import com.google.testing.compile.Compilation; -import com.google.testing.compile.JavaFileObjects; +import androidx.room.compiler.processing.util.Source; import dagger.internal.codegen.ComponentProcessor; -import javax.tools.JavaFileObject; +import dagger.internal.codegen.KspComponentProcessor; +import dagger.testing.compile.CompilerTests; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -31,16 +28,16 @@ import org.junit.runners.JUnit4; public final class DuplicateAndroidInjectorsCheckerTest { @Test public void conflictingMapKeys() { - JavaFileObject activity = - JavaFileObjects.forSourceLines( + Source activity = + CompilerTests.javaSource( "test.TestActivity", "package test;", "", "import android.app.Activity;", "", "public class TestActivity extends Activity {}"); - JavaFileObject injectorFactory = - JavaFileObjects.forSourceLines( + Source injectorFactory = + CompilerTests.javaSource( "test.TestInjectorFactory", "package test;", "", @@ -53,8 +50,8 @@ public final class DuplicateAndroidInjectorsCheckerTest { " @Override", " public AndroidInjector<TestActivity> create(TestActivity instance) { return null; }", "}"); - JavaFileObject module = - JavaFileObjects.forSourceLines( + Source module = + CompilerTests.javaSource( "test.TestModule", "package test;", "", @@ -76,8 +73,8 @@ public final class DuplicateAndroidInjectorsCheckerTest { " @AndroidInjectionKey(\"test.TestActivity\")", " AndroidInjector.Factory<?> stringKey(TestInjectorFactory factory);", "}"); - JavaFileObject component = - JavaFileObjects.forSourceLines( + Source component = + CompilerTests.javaSource( "test.TestComponent", "package test;", "", @@ -90,17 +87,20 @@ public final class DuplicateAndroidInjectorsCheckerTest { " DispatchingAndroidInjector<Activity> dispatchingInjector();", "}"); - Compilation compilation = - javac() - .withProcessors(ComponentProcessor.forTesting(new DuplicateAndroidInjectorsChecker())) - .compile(activity, injectorFactory, module, component); - assertThat(compilation).failed(); - assertThat(compilation) - .hadErrorContaining("Multiple injector factories bound for the same type") - .inFile(component) - .onLineContaining("interface TestComponent"); - assertThat(compilation).hadErrorContaining("classKey(test.TestInjectorFactory)"); - assertThat(compilation).hadErrorContaining("stringKey(test.TestInjectorFactory)"); - assertThat(compilation).hadErrorCount(1); + CompilerTests.daggerCompiler(activity, injectorFactory, module, component) + .withAdditionalJavacProcessors( + ComponentProcessor.withTestPlugins(new DuplicateAndroidInjectorsChecker())) + .withAdditionalKspProcessors( + KspComponentProcessor.Provider.withTestPlugins(new DuplicateAndroidInjectorsChecker())) + .compile( + subject -> { + subject.compilationDidFail(); + subject + .hasErrorContaining("Multiple injector factories bound for the same type") + .onLineContaining("interface TestComponent"); + subject.hasErrorContaining("classKey(test.TestInjectorFactory)"); + subject.hasErrorContaining("stringKey(test.TestInjectorFactory)"); + subject.hasErrorCount(1); + }); } } diff --git a/javatests/dagger/functional/assisted/AssistedFactoryAsQualifiedBindingTest.java b/javatests/dagger/functional/assisted/AssistedFactoryAsQualifiedBindingTest.java index 494372a0e..afb5f7af8 100644 --- a/javatests/dagger/functional/assisted/AssistedFactoryAsQualifiedBindingTest.java +++ b/javatests/dagger/functional/assisted/AssistedFactoryAsQualifiedBindingTest.java @@ -17,7 +17,6 @@ package dagger.functional.assisted; import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth8.assertThat; import static java.lang.annotation.RetentionPolicy.RUNTIME; import dagger.Binds; diff --git a/javatests/dagger/functional/basic/BUILD b/javatests/dagger/functional/basic/BUILD index 18be5e1b2..9ed6fc213 100644 --- a/javatests/dagger/functional/basic/BUILD +++ b/javatests/dagger/functional/basic/BUILD @@ -26,7 +26,9 @@ package(default_visibility = ["//:src"]) GenJavaTests( name = "basic", - srcs = glob(["*.java"]), + srcs = glob( + ["*.java"], + ), gen_library_deps = [ "//javatests/dagger/functional/basic/subpackage", ], diff --git a/javatests/dagger/functional/basic/ComponentNestedTypeTest.java b/javatests/dagger/functional/basic/ComponentNestedTypeTest.java index b9e0cf436..837228f16 100644 --- a/javatests/dagger/functional/basic/ComponentNestedTypeTest.java +++ b/javatests/dagger/functional/basic/ComponentNestedTypeTest.java @@ -54,8 +54,7 @@ public final class ComponentNestedTypeTest { @Test public void typeNameWontClashWithNestedTypeName() { - TestComponent component = - DaggerComponentNestedTypeTest_TestComponent.builder().testModule(new TestModule()).build(); + TestComponent component = DaggerComponentNestedTypeTest_TestComponent.create(); assertThat(component.nestedType()).isNotNull(); } } diff --git a/javatests/dagger/functional/jdk8/OptionalBindingComponentsEmptyTest.java b/javatests/dagger/functional/jdk8/OptionalBindingComponentsEmptyTest.java index 21bdd3c85..8f6319057 100644 --- a/javatests/dagger/functional/jdk8/OptionalBindingComponentsEmptyTest.java +++ b/javatests/dagger/functional/jdk8/OptionalBindingComponentsEmptyTest.java @@ -16,7 +16,7 @@ package dagger.functional.jdk8; -import static com.google.common.truth.Truth8.assertThat; +import static com.google.common.truth.Truth.assertThat; import dagger.functional.jdk8.OptionalBindingComponents.EmptyOptionalBindingComponent; import org.junit.Before; diff --git a/javatests/dagger/functional/jdk8/OptionalBindingComponentsPresentTest.java b/javatests/dagger/functional/jdk8/OptionalBindingComponentsPresentTest.java index 50fbefe4e..0e91dc51b 100644 --- a/javatests/dagger/functional/jdk8/OptionalBindingComponentsPresentTest.java +++ b/javatests/dagger/functional/jdk8/OptionalBindingComponentsPresentTest.java @@ -17,7 +17,6 @@ package dagger.functional.jdk8; import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth8.assertThat; import static dagger.functional.jdk8.OptionalBindingComponents.Value.QUALIFIED_VALUE; import static dagger.functional.jdk8.OptionalBindingComponents.Value.VALUE; diff --git a/javatests/dagger/functional/kotlinsrc/assisted/AssistedFactoryAsQualifiedBindingTest.kt b/javatests/dagger/functional/kotlinsrc/assisted/AssistedFactoryAsQualifiedBindingTest.kt index 8c8dafae3..af891d751 100644 --- a/javatests/dagger/functional/kotlinsrc/assisted/AssistedFactoryAsQualifiedBindingTest.kt +++ b/javatests/dagger/functional/kotlinsrc/assisted/AssistedFactoryAsQualifiedBindingTest.kt @@ -17,7 +17,6 @@ package dagger.functional.kotlinsrc.assisted import com.google.common.truth.Truth.assertThat -import com.google.common.truth.Truth8.assertThat import dagger.Binds import dagger.BindsInstance import dagger.BindsOptionalOf @@ -56,7 +55,7 @@ internal class AssistedFactoryAsQualifiedBindingTest { interface Factory { fun create( @BindsInstance @AsComponentDependency bar: Bar, - @BindsInstance @AsComponentDependency barFactory: BarFactory + @BindsInstance @AsComponentDependency barFactory: BarFactory, ): TestComponent } } @@ -132,7 +131,7 @@ internal class AssistedFactoryAsQualifiedBindingTest { @AsMultibinding val barSet: Set<Bar>, @AsMultibinding val barFactorySet: Set<@JvmSuppressWildcards BarFactory>, val unqualifiedBarSet: Set<Bar>, - val unqualifiedBarFactorySet: Set<@JvmSuppressWildcards BarFactory> + val unqualifiedBarFactorySet: Set<@JvmSuppressWildcards BarFactory>, ) class Bar @AssistedInject constructor() diff --git a/javatests/dagger/functional/kotlinsrc/assisted/AssistedFactoryWithJavaKeyWordNamesTest.kt b/javatests/dagger/functional/kotlinsrc/assisted/AssistedFactoryWithJavaKeyWordNamesTest.kt new file mode 100644 index 000000000..84aaa628b --- /dev/null +++ b/javatests/dagger/functional/kotlinsrc/assisted/AssistedFactoryWithJavaKeyWordNamesTest.kt @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2023 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.functional.kotlinsrc.assisted + +import com.google.common.truth.Truth.assertThat +import dagger.BindsInstance +import dagger.Component +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +// Regression test for https://github.com/google/dagger/issues/3995. +@RunWith(JUnit4::class) +internal class AssistedFactoryWithJavaKeyWordNamesTest { + @Component + interface MyComponent { + fun myAssistedFactory(): MyAssistedFactory + + @Component.Builder + interface Builder { + @BindsInstance fun addInteger(int: Int): Builder + fun build(): MyComponent + } + } + + data class MyAssistedClass @AssistedInject constructor( + val int: Int, + @Assisted val string: String, + @Assisted val long: Long + ) + + @AssistedFactory + interface MyAssistedFactory { + fun create(long: Long, string: String): MyAssistedClass + } + + @Test + fun testParametersWithJavaKeywordNames() { + val int = 1 + val long = 2L + val string = "string" + val myAssistedFactory = + DaggerAssistedFactoryWithJavaKeyWordNamesTest_MyComponent.builder() + .addInteger(int) + .build() + .myAssistedFactory() + .create(long, string) + assertThat(myAssistedFactory.int).isEqualTo(int) + assertThat(myAssistedFactory.long).isEqualTo(long) + assertThat(myAssistedFactory.string).isEqualTo(string) + } +} diff --git a/javatests/dagger/functional/kotlinsrc/assisted/BUILD b/javatests/dagger/functional/kotlinsrc/assisted/BUILD index a90f83c91..57242b385 100644 --- a/javatests/dagger/functional/kotlinsrc/assisted/BUILD +++ b/javatests/dagger/functional/kotlinsrc/assisted/BUILD @@ -132,3 +132,14 @@ GenKtTests( "//third_party/java/junit", ], ) + +GenKtTests( + name = "AssistedFactoryWithJavaKeyWordNamesTest", + srcs = ["AssistedFactoryWithJavaKeyWordNamesTest.kt"], + javacopts = DOCLINT_HTML_AND_SYNTAX, + test_only_deps = [ + "//:dagger_with_compiler", + "//third_party/java/truth", + "//third_party/java/junit", + ], +) diff --git a/javatests/dagger/functional/kotlinsrc/membersinject/MembersInjectTest.kt b/javatests/dagger/functional/kotlinsrc/membersinject/MembersInjectTest.kt index 2fc44258f..e7a751f27 100644 --- a/javatests/dagger/functional/kotlinsrc/membersinject/MembersInjectTest.kt +++ b/javatests/dagger/functional/kotlinsrc/membersinject/MembersInjectTest.kt @@ -23,8 +23,8 @@ import dagger.MembersInjector import dagger.functional.kotlinsrc.membersinject.subpackage.a.AGrandchild import dagger.functional.kotlinsrc.membersinject.subpackage.a.AParent import dagger.functional.kotlinsrc.membersinject.subpackage.b.BChild +import dagger.internal.Provider import javax.inject.Inject -import javax.inject.Provider import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.JUnit4 @@ -85,7 +85,9 @@ class MembersInjectTest { } class A : B() // No injected members + open class B : C() // No injected members + open class C { @Inject lateinit var value: String } diff --git a/javatests/dagger/functional/kotlinsrc/membersinject/MembersInjectionWithJavaKeywordNamesTest.kt b/javatests/dagger/functional/kotlinsrc/membersinject/MembersInjectionWithJavaKeywordNamesTest.kt new file mode 100644 index 000000000..adbfd502c --- /dev/null +++ b/javatests/dagger/functional/kotlinsrc/membersinject/MembersInjectionWithJavaKeywordNamesTest.kt @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2023 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.functional.kotlinsrc.membersinject + +import com.google.common.truth.Truth.assertThat +import dagger.BindsInstance +import dagger.Component +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject +import javax.inject.Inject +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +// Regression test for https://github.com/google/dagger/issues/3995. +@RunWith(JUnit4::class) +internal class MembersInjectionWithJavaKeywordNamesTest { + @Component + interface MyComponent { + fun myClass(): MyClass + + @Component.Builder + interface Builder { + @BindsInstance fun addInteger(int: Int): Builder + @BindsInstance fun addString(string: String): Builder + @BindsInstance fun addLong(long: Long): Builder + fun build(): MyComponent + } + } + + @Suppress("BadInject") + class MyClass @Inject constructor(val int: Int) { + @Inject @JvmField var string: String = "" + + var long: Long? = null + + @Inject fun injectMethod(long: Long) { + this.long = long + } + } + + @Test + fun testParametersWithJavaKeywordNames() { + val int = 1 + val long = 2L + val string = "string" + val myClass = + DaggerMembersInjectionWithJavaKeywordNamesTest_MyComponent.builder() + .addInteger(int) + .addString(string) + .addLong(long) + .build() + .myClass() + assertThat(myClass.int).isEqualTo(int) + assertThat(myClass.long).isEqualTo(long) + assertThat(myClass.string).isEqualTo(string) + } +} diff --git a/javatests/dagger/functional/kotlinsrc/membersinject/MembersInjectionWithTypeAliasSuperclassTest.kt b/javatests/dagger/functional/kotlinsrc/membersinject/MembersInjectionWithTypeAliasSuperclassTest.kt new file mode 100644 index 000000000..e45f63e84 --- /dev/null +++ b/javatests/dagger/functional/kotlinsrc/membersinject/MembersInjectionWithTypeAliasSuperclassTest.kt @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2024 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.functional.kotlinsrc.membersinject + +import com.google.common.truth.Truth.assertThat +import dagger.Component +import javax.inject.Inject +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +/** This is a regression test for https://github.com/google/dagger/issues/4199 */ +@RunWith(JUnit4::class) +class MembersInjectionWithTypeAliasSuperclassTest { + @Test + fun testMembersInjection() { + val myClass = MyClass() + DaggerTestComponent.create().inject(myClass) + assertThat(myClass.foo).isNotNull() + assertThat(myClass.bar).isNotNull() + } +} + +@Component +interface TestComponent { + fun inject(myClass: MyClass) +} + +class MyClass: MyBaseClassAlias() { + @Inject lateinit var foo: Foo +} + +typealias MyBaseClassAlias = MyBaseClass + +abstract class MyBaseClass { + @Inject lateinit var bar: Bar +} + +class Foo @Inject constructor() +class Bar @Inject constructor() diff --git a/javatests/dagger/functional/kotlinsrc/multibindings/ClassKeyWithGenericsTest.kt b/javatests/dagger/functional/kotlinsrc/multibindings/ClassKeyWithGenericsTest.kt new file mode 100644 index 000000000..25d8c5641 --- /dev/null +++ b/javatests/dagger/functional/kotlinsrc/multibindings/ClassKeyWithGenericsTest.kt @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2023 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.functional.kotlinsrc.multibindings + +import com.google.common.truth.Truth.assertThat +import dagger.Component +import dagger.Module +import dagger.Provides +import dagger.multibindings.ClassKey +import dagger.multibindings.IntoMap +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +@RunWith(JUnit4::class) +class ClassKeyWithGenericsTest { + @Component(modules = [TestModule::class]) + interface TestComponent { + val map: Map<Class<*>, String> + } + + @Module + internal object TestModule { + @Provides + @IntoMap + @ClassKey(Thing::class) + fun provideThingValue(): String = "Thing" + + @Provides + @IntoMap + @ClassKey(GenericThing::class) + fun provideAbstractThingValue(): String = "GenericThing" + } + + class Thing + + class GenericThing<T> + + @Test + fun test() { + val map = DaggerClassKeyWithGenericsTest_TestComponent.create().map + assertThat(map) + .containsExactly( + Thing::class.java, "Thing", + GenericThing::class.java, "GenericThing"); + } +} diff --git a/javatests/dagger/functional/kotlinsrc/nullables/BUILD b/javatests/dagger/functional/kotlinsrc/nullables/BUILD index e9db7a7c8..ad9ad77b2 100644 --- a/javatests/dagger/functional/kotlinsrc/nullables/BUILD +++ b/javatests/dagger/functional/kotlinsrc/nullables/BUILD @@ -25,6 +25,18 @@ load("//:test_defs.bzl", "GenKtTests") package(default_visibility = ["//:src"]) GenKtTests( + name = "JspecifyNullableTest", + srcs = ["JspecifyNullableTest.kt"], + javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES, + deps = [ + "//:dagger_with_compiler", + "//third_party/java/jspecify_annotations", + "//third_party/java/junit", + "//third_party/java/truth", + ], +) + +GenKtTests( name = "NullabilityTest", srcs = ["NullabilityTest.kt"], javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES, diff --git a/javatests/dagger/functional/kotlinsrc/nullables/JspecifyNullableTest.kt b/javatests/dagger/functional/kotlinsrc/nullables/JspecifyNullableTest.kt new file mode 100644 index 000000000..9490f6fae --- /dev/null +++ b/javatests/dagger/functional/kotlinsrc/nullables/JspecifyNullableTest.kt @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2023 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.functional.kotlinsrc.nullables + +import com.google.common.truth.Truth.assertThat +import dagger.Component +import dagger.Module +import dagger.Provides +import org.jspecify.annotations.Nullable +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +// This is a regression test for b/290632844. +@RunWith(JUnit4::class) +public final class JspecifyNullableTest { + @Component(modules = [MyIntComponent.MyModule::class]) + interface MyIntComponent { + fun getInt(): Int + + @Module + class MyModule(val intValue: Int) { + // Check that using @Nullable on the type is ignored (matching KAPT). + @Provides fun provideInt(): @Nullable Int = intValue + } + } + + @Component(modules = [MyNullableStringComponent.MyModule::class]) + interface MyNullableStringComponent { + fun getString(): String? + + @Module + class MyModule(val stringValue: String?) { + // Check that using @Nullable on the type is ignored (matching KAPT). + @Provides fun provideString(): @Nullable String? = stringValue + } + } + + @Test + public fun testIntWithValue() { + val component = + DaggerJspecifyNullableTest_MyIntComponent.builder() + .myModule(MyIntComponent.MyModule(15)) + .build() + assertThat(component.getInt()).isEqualTo(15) + } + + @Test + public fun testStringWithValue() { + val component = + DaggerJspecifyNullableTest_MyNullableStringComponent.builder() + .myModule(MyNullableStringComponent.MyModule("TEST_VALUE")) + .build() + assertThat(component.getString()).isEqualTo("TEST_VALUE") + } + + @Test + public fun testStringWithNull() { + val component = + DaggerJspecifyNullableTest_MyNullableStringComponent.builder() + .myModule(MyNullableStringComponent.MyModule(null)) + .build() + assertThat(component.getString()).isNull() + } +} diff --git a/javatests/dagger/functional/membersinject/MembersInjectTest.java b/javatests/dagger/functional/membersinject/MembersInjectTest.java index 06e17f9e6..c6a13dd0d 100644 --- a/javatests/dagger/functional/membersinject/MembersInjectTest.java +++ b/javatests/dagger/functional/membersinject/MembersInjectTest.java @@ -24,8 +24,8 @@ import dagger.MembersInjector; import dagger.functional.membersinject.subpackage.a.AGrandchild; import dagger.functional.membersinject.subpackage.a.AParent; import dagger.functional.membersinject.subpackage.b.BChild; +import dagger.internal.Provider; import javax.inject.Inject; -import javax.inject.Provider; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/javatests/dagger/functional/multibindings/ClassKeyWithGenericsTest.java b/javatests/dagger/functional/multibindings/ClassKeyWithGenericsTest.java new file mode 100644 index 000000000..2cc3ad824 --- /dev/null +++ b/javatests/dagger/functional/multibindings/ClassKeyWithGenericsTest.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2018 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.functional.multibindings; + +import static com.google.common.truth.Truth.assertThat; + +import dagger.Component; +import dagger.Module; +import dagger.Provides; +import dagger.multibindings.ClassKey; +import dagger.multibindings.IntoMap; +import java.util.Map; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +// This is a regression test for https://github.com/google/dagger/issues/4055. +@RunWith(JUnit4.class) +public final class ClassKeyWithGenericsTest { + @Component(modules = TestModule.class) + interface TestComponent { + Map<Class<?>, String> map(); + } + + @Module + interface TestModule { + @Provides + @IntoMap + @ClassKey(Thing.class) + static String provideThingValue() { + return "Thing"; + } + + @Provides + @IntoMap + @ClassKey(GenericThing.class) + static String provideGenericThingValue() { + return "GenericThing"; + } + } + + class Thing {} + + class GenericThing<T> {} + + @Test + public void test() { + Map<Class<?>, String> map = DaggerClassKeyWithGenericsTest_TestComponent.create().map(); + assertThat(map) + .containsExactly( + Thing.class, "Thing", + GenericThing.class, "GenericThing"); + } +} diff --git a/javatests/dagger/functional/nullables/BUILD b/javatests/dagger/functional/nullables/BUILD index 323e6a5df..52fb84393 100644 --- a/javatests/dagger/functional/nullables/BUILD +++ b/javatests/dagger/functional/nullables/BUILD @@ -25,6 +25,18 @@ load("//:test_defs.bzl", "GenJavaTests") package(default_visibility = ["//:src"]) GenJavaTests( + name = "JspecifyNullableTest", + srcs = ["JspecifyNullableTest.java"], + javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES, + deps = [ + "//:dagger_with_compiler", + "//third_party/java/jspecify_annotations", + "//third_party/java/junit", + "//third_party/java/truth", + ], +) + +GenJavaTests( name = "NullabilityTest", srcs = ["NullabilityTest.java"], javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES, diff --git a/javatests/dagger/functional/nullables/JspecifyNullableTest.java b/javatests/dagger/functional/nullables/JspecifyNullableTest.java new file mode 100644 index 000000000..b5d42f3b7 --- /dev/null +++ b/javatests/dagger/functional/nullables/JspecifyNullableTest.java @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2023 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.functional.nullables; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; + +import dagger.Component; +import dagger.Module; +import dagger.Provides; +import javax.inject.Provider; +import org.jspecify.annotations.Nullable; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public final class JspecifyNullableTest { + @Component(modules = MyModule.class, dependencies = ComponentDependency.class) + interface MyComponent { + Integer getInt(); + InnerType getInnerType(); + Provider<Dependency> getDependencyProvider(); + } + + interface Dependency {} + + interface InnerType {} + + @Module + static class MyModule { + private final Integer integer; + private final InnerType innerType; + + MyModule(Integer integer, InnerType innerType) { + this.integer = integer; + this.innerType = innerType; + } + + @Provides + @Nullable Integer provideInt() { + return integer; + } + + @Provides + @Nullable InnerType provideInnerType() { + return innerType; + } + } + + @Component(modules = DependencyModule.class) + interface ComponentDependency { + @Nullable Dependency dependency(); + } + + @Module + static class DependencyModule { + private final Dependency dependency; + + DependencyModule(Dependency dependency) { + this.dependency = dependency; + } + + @Provides + @Nullable Dependency provideDependency() { + return dependency; + } + } + + @Test + public void testWithValue() { + MyComponent component = DaggerJspecifyNullableTest_MyComponent.builder() + .myModule(new MyModule(15, new InnerType() {})) + .componentDependency( + DaggerJspecifyNullableTest_ComponentDependency.builder() + .dependencyModule(new DependencyModule(new Dependency() {})).build()) + .build(); + assertThat(component.getInt()).isEqualTo(15); + assertThat(component.getInnerType()).isNotNull(); + assertThat(component.getDependencyProvider().get()).isNotNull(); + } + + @Test + public void testWithNull() { + MyComponent component = DaggerJspecifyNullableTest_MyComponent.builder() + .myModule(new MyModule(null, null)) + .componentDependency( + DaggerJspecifyNullableTest_ComponentDependency.builder() + .dependencyModule(new DependencyModule(null)).build()) + .build(); + NullPointerException expectedException = + assertThrows(NullPointerException.class, component::getInt); + assertThat(expectedException) + .hasMessageThat() + .contains("Cannot return null from a non-@Nullable @Provides method"); + NullPointerException expectedException2 = + assertThrows(NullPointerException.class, component::getInnerType); + assertThat(expectedException2) + .hasMessageThat() + .contains("Cannot return null from a non-@Nullable @Provides method"); + NullPointerException expectedException3 = + assertThrows(NullPointerException.class, () -> component.getDependencyProvider().get()); + assertThat(expectedException3) + .hasMessageThat() + .contains("Cannot return null from a non-@Nullable @Provides method"); + } +} diff --git a/javatests/dagger/functional/producers/ProducerFactoryTest.java b/javatests/dagger/functional/producers/ProducerFactoryTest.java index 6df526e25..f821ab9c1 100644 --- a/javatests/dagger/functional/producers/ProducerFactoryTest.java +++ b/javatests/dagger/functional/producers/ProducerFactoryTest.java @@ -25,6 +25,7 @@ import static org.mockito.Mockito.when; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.SettableFuture; +import dagger.internal.Provider; import dagger.producers.Producer; import dagger.producers.internal.AbstractProducer; import dagger.producers.internal.CancellableProducer; @@ -33,7 +34,6 @@ import dagger.producers.monitoring.ProducerToken; import dagger.producers.monitoring.ProductionComponentMonitor; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; -import javax.inject.Provider; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -55,7 +55,6 @@ public class ProducerFactoryTest { MockitoAnnotations.initMocks(this); monitor = Mockito.mock(ProducerMonitor.class, Mockito.CALLS_REAL_METHODS); when(componentMonitor.producerMonitorFor(any(ProducerToken.class))).thenReturn(monitor); - // TODO(beder): Use Providers.of when available. executorProvider = new Provider<Executor>() { @Override diff --git a/javatests/dagger/functional/producers/aot/ProducesMethodShadowsInjectConstructorTest.java b/javatests/dagger/functional/producers/aot/ProducesMethodShadowsInjectConstructorTest.java index ef37df216..548ad1dbd 100644 --- a/javatests/dagger/functional/producers/aot/ProducesMethodShadowsInjectConstructorTest.java +++ b/javatests/dagger/functional/producers/aot/ProducesMethodShadowsInjectConstructorTest.java @@ -17,7 +17,6 @@ package dagger.functional.producers.aot; import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth8.assertThat; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; diff --git a/javatests/dagger/hilt/android/AndroidManifest.xml b/javatests/dagger/hilt/android/AndroidManifest.xml index 3c0fa840d..ed24e45cb 100644 --- a/javatests/dagger/hilt/android/AndroidManifest.xml +++ b/javatests/dagger/hilt/android/AndroidManifest.xml @@ -66,10 +66,38 @@ android:exported="false" tools:ignore="MissingClass"/> <activity + android:name=".ViewModelAssistedTest$TestConfigChangeActivity" + android:exported="false" + tools:ignore="MissingClass"/> + <activity + android:name=".ViewModelAssistedTest$TestKeyedViewModelActivity" + android:exported="false" + tools:ignore="MissingClass"/> + <activity + android:name=".ViewModelAssistedTest$TestNoCreationCallbacksActivity" + android:exported="false" + tools:ignore="MissingClass"/> + <activity + android:name=".ViewModelAssistedTest$TestNoFactoryActivity" + android:exported="false" + tools:ignore="MissingClass"/> + <activity + android:name=".ViewModelAssistedTest$TestFragmentArgsActivity" + android:exported="false" + tools:ignore="MissingClass"/> + <activity + android:name=".ViewModelAssistedTest$TestIncompatibleFactoriesActivity" + android:exported="false" + tools:ignore="MissingClass"/> + <activity android:name=".ViewModelSavedStateOwnerTest$TestActivity" android:exported="false" tools:ignore="MissingClass"/> <activity + android:name=".ViewModelSavedStateOwnerTest$ErrorTestActivity" + android:exported="false" + tools:ignore="MissingClass"/> + <activity android:name=".ViewModelWithBaseTest$TestActivity" android:exported="false" tools:ignore="MissingClass"/> diff --git a/javatests/dagger/hilt/android/BUILD b/javatests/dagger/hilt/android/BUILD index 8f927fb98..b3da0d2a6 100644 --- a/javatests/dagger/hilt/android/BUILD +++ b/javatests/dagger/hilt/android/BUILD @@ -543,6 +543,39 @@ android_local_test( ) android_local_test( + name = "ViewModelAssistedTest", + srcs = ["ViewModelAssistedTest.java"], + javacopts = ["-Adagger.hilt.enableAssistedInjectViewModels=true"], + manifest = "AndroidManifest.xml", + manifest_values = { + "minSdkVersion": "14", + }, + deps = [ + "//:android_local_test_exports", + "//:dagger_with_compiler", + "//java/dagger/hilt:install_in", + "//java/dagger/hilt/android:android_entry_point", + "//java/dagger/hilt/android:package_info", + "//java/dagger/hilt/android:view_model_lifecycle", + "//java/dagger/hilt/android/internal/lifecycle", + "//java/dagger/hilt/android/lifecycle:hilt_view_model", + "//java/dagger/hilt/android/lifecycle:hilt_view_model_extensions", + "//java/dagger/hilt/android/scopes", + "//java/dagger/hilt/android/testing:hilt_android_test", + "//third_party/java/jsr330_inject", + "//third_party/java/truth", + "@maven//:androidx_activity_activity", + "@maven//:androidx_fragment_fragment", + "@maven//:androidx_lifecycle_lifecycle_common", + "@maven//:androidx_lifecycle_lifecycle_viewmodel", + "@maven//:androidx_lifecycle_lifecycle_viewmodel_savedstate", + "@maven//:androidx_test_core", + "@maven//:junit_junit", + "@maven//:org_jetbrains_kotlin_kotlin_stdlib", + ], +) + +android_local_test( name = "ViewModelSavedStateOwnerTest", srcs = ["ViewModelSavedStateOwnerTest.java"], manifest = "AndroidManifest.xml", @@ -556,12 +589,15 @@ android_local_test( "//java/dagger/hilt:install_in", "//java/dagger/hilt/android:android_entry_point", "//java/dagger/hilt/android:package_info", + "//java/dagger/hilt/android:unstable_api", + "//java/dagger/hilt/android/lifecycle:activity_retained_saved_state", "//java/dagger/hilt/android/lifecycle:hilt_view_model", "//java/dagger/hilt/android/scopes", "//java/dagger/hilt/android/testing:hilt_android_test", "//third_party/java/jsr330_inject", "//third_party/java/truth", "@maven//:androidx_activity_activity", + "@maven//:androidx_annotation_annotation_experimental", "@maven//:androidx_fragment_fragment", "@maven//:androidx_lifecycle_lifecycle_common", "@maven//:androidx_lifecycle_lifecycle_viewmodel", diff --git a/javatests/dagger/hilt/android/InjectionTest.java b/javatests/dagger/hilt/android/InjectionTest.java index 426fc6d32..37607822b 100644 --- a/javatests/dagger/hilt/android/InjectionTest.java +++ b/javatests/dagger/hilt/android/InjectionTest.java @@ -19,7 +19,6 @@ package dagger.hilt.android; import static androidx.test.core.app.ApplicationProvider.getApplicationContext; import static com.google.common.truth.Truth.assertThat; import static java.lang.annotation.RetentionPolicy.RUNTIME; -import static org.junit.Assert.assertThrows; import static org.junit.Assert.fail; import android.annotation.TargetApi; @@ -439,21 +438,6 @@ public final class InjectionTest { } @Test - @Config(sdk = 19) - public void testViewNoFragmentBindingsWithFragment_fourthConstructor_notPresentOnTwenty() { - TestFragment fragment = setupFragment(TestActivity.class, new TestFragment()); - - assertThrows( - NoSuchMethodError.class, - () -> - new TestView( - fragment.getContext(), - /* attrs= */ null, - /* defStyleAttr= */ 0, - /* defStyleRes= */ 0)); - } - - @Test public void testServiceInjection() throws Exception { TestService testService = Robolectric.setupService(TestService.class); assertThat(testService.appBinding).isEqualTo(APP_BINDING); diff --git a/javatests/dagger/hilt/android/ViewModelAssistedTest.java b/javatests/dagger/hilt/android/ViewModelAssistedTest.java new file mode 100644 index 000000000..e466423aa --- /dev/null +++ b/javatests/dagger/hilt/android/ViewModelAssistedTest.java @@ -0,0 +1,374 @@ +/* + * Copyright (C) 2020 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.android; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; + +import android.os.Build; +import android.os.Bundle; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import androidx.annotation.Nullable; +import androidx.lifecycle.SavedStateHandle; +import androidx.lifecycle.ViewModel; +import androidx.lifecycle.ViewModelProvider; +import androidx.test.core.app.ActivityScenario; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import dagger.assisted.Assisted; +import dagger.assisted.AssistedFactory; +import dagger.assisted.AssistedInject; +import dagger.hilt.android.lifecycle.HiltViewModel; +import dagger.hilt.android.lifecycle.HiltViewModelExtensions; +import dagger.hilt.android.scopes.ViewModelScoped; +import dagger.hilt.android.testing.HiltAndroidRule; +import dagger.hilt.android.testing.HiltAndroidTest; +import dagger.hilt.android.testing.HiltTestApplication; +import javax.inject.Inject; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +@HiltAndroidTest +@RunWith(AndroidJUnit4.class) +// Robolectric requires Java9 to run API 29 and above, so use API 28 instead +@Config(sdk = Build.VERSION_CODES.P, application = HiltTestApplication.class) +public class ViewModelAssistedTest { + + @Rule public final HiltAndroidRule rule = new HiltAndroidRule(this); + + @Test + public void testConfigChange() { + try (ActivityScenario<TestConfigChangeActivity> scenario = + ActivityScenario.launch(TestConfigChangeActivity.class)) { + scenario.onActivity( + activity -> { + assertThat(activity.vm.one.bar).isNotNull(); + assertThat(activity.vm.one.bar).isSameInstanceAs(activity.vm.two.bar); + assertThat(activity.vm.s).isEqualTo("foo"); + }); + scenario.recreate(); + scenario.onActivity( + activity -> { + // Check that we still get the same ViewModel instance after config change and the + // passed assisted arg has no effect anymore. + assertThat(activity.vm.s).isEqualTo("foo"); + }); + } + } + + @Test + public void testKeyedViewModels() { + try (ActivityScenario<TestKeyedViewModelActivity> scenario = + ActivityScenario.launch(TestKeyedViewModelActivity.class)) { + scenario.onActivity( + activity -> { + assertThat(activity.vm1.s).isEqualTo("foo"); + assertThat(activity.vm2.s).isEqualTo("bar"); + }); + } + } + + @Test + public void testNoCreationCallbacks() { + Exception exception = + assertThrows( + IllegalStateException.class, + () -> ActivityScenario.launch(TestNoCreationCallbacksActivity.class).close()); + assertThat(exception) + .hasMessageThat() + .contains( + "Found @HiltViewModel-annotated class" + + " dagger.hilt.android.ViewModelAssistedTest$MyViewModel" + + " using @AssistedInject but no creation callback was provided" + + " in CreationExtras."); + } + + @Test + public void testNoFactory() { + Exception exception = + assertThrows( + RuntimeException.class, + () -> ActivityScenario.launch(TestNoFactoryActivity.class).close()); + assertThat(exception) + .hasMessageThat() + .contains( + "Found creation callback but class" + + " dagger.hilt.android.ViewModelAssistedTest$MyInjectedViewModel does not have an" + + " assisted factory specified in @HiltViewModel."); + } + + @Test + public void testFragmentArgs() { + try (ActivityScenario<TestFragmentArgsActivity> scenario = + ActivityScenario.launch(TestFragmentArgsActivity.class)) { + scenario.onActivity( + activity -> { + TestFragment fragment = + (TestFragment) activity.getSupportFragmentManager().findFragmentByTag("tag"); + assertThat(fragment.vm.handle.<String>get("key")).isEqualTo("foobar"); + }); + } + } + + @Test + public void testIncompatibleFactories() { + Exception exception = + assertThrows( + ClassCastException.class, + () -> ActivityScenario.launch(TestIncompatibleFactoriesActivity.class).close()); + assertThat(exception) + .hasMessageThat() + .contains( + "class dagger.hilt.android.ViewModelAssistedTest_MyViewModel_Factory_Impl cannot be" + + " cast to class" + + " dagger.hilt.android.ViewModelAssistedTest$MyViewModel$AnotherFactory"); + } + + @AndroidEntryPoint(FragmentActivity.class) + public static class TestConfigChangeActivity + extends Hilt_ViewModelAssistedTest_TestConfigChangeActivity { + + MyViewModel vm; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (savedInstanceState == null) { + vm = + new ViewModelProvider( + getViewModelStore(), + getDefaultViewModelProviderFactory(), + HiltViewModelExtensions.withCreationCallback( + getDefaultViewModelCreationExtras(), + (MyViewModel.Factory factory) -> factory.create("foo"))) + .get(MyViewModel.class); + } else { + vm = + new ViewModelProvider( + getViewModelStore(), + getDefaultViewModelProviderFactory(), + HiltViewModelExtensions.withCreationCallback( + getDefaultViewModelCreationExtras(), + (MyViewModel.Factory factory) -> factory.create("bar"))) + .get(MyViewModel.class); + } + } + } + + @AndroidEntryPoint(FragmentActivity.class) + public static class TestKeyedViewModelActivity + extends Hilt_ViewModelAssistedTest_TestKeyedViewModelActivity { + + MyViewModel vm1; + MyViewModel vm2; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + vm1 = + new ViewModelProvider( + getViewModelStore(), + getDefaultViewModelProviderFactory(), + HiltViewModelExtensions.withCreationCallback( + getDefaultViewModelCreationExtras(), + (MyViewModel.Factory factory) -> factory.create("foo"))) + .get("a", MyViewModel.class); + + vm2 = + new ViewModelProvider( + getViewModelStore(), + getDefaultViewModelProviderFactory(), + HiltViewModelExtensions.withCreationCallback( + getDefaultViewModelCreationExtras(), + (MyViewModel.Factory factory) -> factory.create("bar"))) + .get("b", MyViewModel.class); + } + } + + @AndroidEntryPoint(FragmentActivity.class) + public static class TestNoCreationCallbacksActivity + extends Hilt_ViewModelAssistedTest_TestNoCreationCallbacksActivity { + + MyViewModel vm; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + vm = new ViewModelProvider(this).get(MyViewModel.class); + } + } + + @AndroidEntryPoint(FragmentActivity.class) + public static class TestNoFactoryActivity + extends Hilt_ViewModelAssistedTest_TestNoFactoryActivity { + + MyInjectedViewModel vm; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + vm = + new ViewModelProvider( + getViewModelStore(), + getDefaultViewModelProviderFactory(), + HiltViewModelExtensions.withCreationCallback( + getDefaultViewModelCreationExtras(), + (MyViewModel.Factory factory) -> factory.create("bar"))) + .get(MyInjectedViewModel.class); + } + } + + @AndroidEntryPoint(FragmentActivity.class) + public static class TestFragmentArgsActivity + extends Hilt_ViewModelAssistedTest_TestFragmentArgsActivity { + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (savedInstanceState == null) { + Fragment f = + getSupportFragmentManager() + .getFragmentFactory() + .instantiate(TestFragment.class.getClassLoader(), TestFragment.class.getName()); + Bundle b = new Bundle(); + b.putString("key", "foobar"); + f.setArguments(b); + getSupportFragmentManager().beginTransaction().add(0, f, "tag").commitNow(); + } + } + } + + @AndroidEntryPoint(FragmentActivity.class) + public static class TestIncompatibleFactoriesActivity + extends Hilt_ViewModelAssistedTest_TestIncompatibleFactoriesActivity { + + MyViewModel vm; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + vm = + new ViewModelProvider( + getViewModelStore(), + getDefaultViewModelProviderFactory(), + HiltViewModelExtensions.withCreationCallback( + getDefaultViewModelCreationExtras(), + (MyViewModel.AnotherFactory factory) -> factory.create("foo"))) + .get(MyViewModel.class); + } + } + + @AndroidEntryPoint(Fragment.class) + public static class TestFragment extends Hilt_ViewModelAssistedTest_TestFragment { + + MyViewModel vm; + + @Override + public void onCreate(@Nullable Bundle bundle) { + super.onCreate(bundle); + vm = + new ViewModelProvider( + getViewModelStore(), + getDefaultViewModelProviderFactory(), + HiltViewModelExtensions.withCreationCallback( + getDefaultViewModelCreationExtras(), + (MyViewModel.Factory factory) -> factory.create("foo"))) + .get(MyViewModel.class); + } + } + + @HiltViewModel(assistedFactory = MyViewModel.Factory.class) + static class MyViewModel extends ViewModel { + + final DependsOnBarOne one; + final DependsOnBarTwo two; + final SavedStateHandle handle; + final String s; + boolean cleared = false; + + @AssistedInject + MyViewModel( + DependsOnBarOne one, + DependsOnBarTwo two, + ViewModelLifecycle lifecycle, + SavedStateHandle handle, + @Assisted String s) { + this.one = one; + this.two = two; + this.s = s; + this.handle = handle; + lifecycle.addOnClearedListener(() -> cleared = true); + } + + @AssistedFactory + interface Factory { + MyViewModel create(String s); + } + + @AssistedFactory + interface AnotherFactory { + MyViewModel create(String s); + } + } + + @HiltViewModel + static class MyInjectedViewModel extends ViewModel { + + final DependsOnBarOne one; + final DependsOnBarTwo two; + final SavedStateHandle handle; + boolean cleared = false; + + @Inject + MyInjectedViewModel( + DependsOnBarOne one, + DependsOnBarTwo two, + ViewModelLifecycle lifecycle, + SavedStateHandle handle) { + this.one = one; + this.two = two; + this.handle = handle; + lifecycle.addOnClearedListener(() -> cleared = true); + } + } + + @ViewModelScoped + static class Bar { + @Inject + Bar() {} + } + + static class DependsOnBarOne { + final Bar bar; + + @Inject + DependsOnBarOne(Bar bar) { + this.bar = bar; + } + } + + static class DependsOnBarTwo { + final Bar bar; + + @Inject + DependsOnBarTwo(Bar bar) { + this.bar = bar; + } + } +} diff --git a/javatests/dagger/hilt/android/ViewModelSavedStateOwnerTest.java b/javatests/dagger/hilt/android/ViewModelSavedStateOwnerTest.java index eab206efc..3e522b9dd 100644 --- a/javatests/dagger/hilt/android/ViewModelSavedStateOwnerTest.java +++ b/javatests/dagger/hilt/android/ViewModelSavedStateOwnerTest.java @@ -17,12 +17,14 @@ package dagger.hilt.android; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; import android.os.Build; import android.os.Bundle; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.annotation.Nullable; +import androidx.annotation.OptIn; import androidx.lifecycle.SavedStateHandle; import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModelProvider; @@ -31,17 +33,20 @@ import androidx.navigation.NavController; import androidx.navigation.Navigation; import androidx.test.core.app.ActivityScenario; import androidx.test.ext.junit.runners.AndroidJUnit4; +import dagger.hilt.android.lifecycle.ActivityRetainedSavedState; import dagger.hilt.android.lifecycle.HiltViewModel; import dagger.hilt.android.testing.HiltAndroidRule; import dagger.hilt.android.testing.HiltAndroidTest; import dagger.hilt.android.testing.HiltTestApplication; import javax.inject.Inject; +import javax.inject.Provider; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.annotation.Config; /** Test that you can use the Hilt ViewModel factory with other owners. */ +@OptIn(markerClass = UnstableApi.class) @HiltAndroidTest @RunWith(AndroidJUnit4.class) // Robolectric requires Java9 to run API 29 and above, so use API 28 instead @@ -51,6 +56,40 @@ public class ViewModelSavedStateOwnerTest { @Rule public final HiltAndroidRule rule = new HiltAndroidRule(this); @Test + public void activityRetainedComponentSaveState_configurationChange_successfullySavedState() { + try (ActivityScenario<TestActivity> scenario = ActivityScenario.launch(TestActivity.class)) { + scenario.onActivity( + activity -> { + assertThat((String) activity.savedStateHandle.get("argument_key")).isNull(); + activity.savedStateHandle.set("other_key", "activity_other_key"); + }); + scenario.recreate(); + scenario.onActivity( + activity -> { + assertThat((String) activity.savedStateHandle.get("argument_key")).isNull(); + assertThat((String) activity.savedStateHandle.get("other_key")) + .isEqualTo("activity_other_key"); + }); + } + } + + @Test + public void firstTimeAccessToActivityRetainedSaveState_inActivityOnDestroy_fails() { + Exception exception = + assertThrows( + NullPointerException.class, + () -> { + try (ActivityScenario<ErrorTestActivity> scenario = + ActivityScenario.launch(ErrorTestActivity.class)) {} + }); + assertThat(exception) + .hasMessageThat() + .contains( + "The first access to SavedStateHandle should happen between super.onCreate() and" + + " super.onDestroy()"); + } + + @Test public void testViewModelSavedState() { try (ActivityScenario<TestActivity> scenario = ActivityScenario.launch(TestActivity.class)) { scenario.onActivity( @@ -156,13 +195,30 @@ public class ViewModelSavedStateOwnerTest { @AndroidEntryPoint(FragmentActivity.class) public static class TestActivity extends Hilt_ViewModelSavedStateOwnerTest_TestActivity { + @Inject @ActivityRetainedSavedState Provider<SavedStateHandle> provider; + SavedStateHandle savedStateHandle; + @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); + savedStateHandle = provider.get(); setContentView(R.layout.navigation_activity); } } + @AndroidEntryPoint(FragmentActivity.class) + public static class ErrorTestActivity + extends Hilt_ViewModelSavedStateOwnerTest_ErrorTestActivity { + @Inject @ActivityRetainedSavedState Provider<SavedStateHandle> provider; + + @SuppressWarnings("unused") + @Override + protected void onDestroy() { + super.onDestroy(); + SavedStateHandle savedStateHandle = provider.get(); + } + } + @AndroidEntryPoint(Fragment.class) public static class TestFragment extends Hilt_ViewModelSavedStateOwnerTest_TestFragment { @Override diff --git a/javatests/dagger/hilt/android/processor/internal/BUILD b/javatests/dagger/hilt/android/processor/internal/BUILD index 8f2c2d927..ac89e9dea 100644 --- a/javatests/dagger/hilt/android/processor/internal/BUILD +++ b/javatests/dagger/hilt/android/processor/internal/BUILD @@ -29,7 +29,9 @@ compiler_test( ], deps = [ "//java/dagger/hilt/android/testing/compile", - "//third_party/java/compile_testing", + "//java/dagger/internal/codegen/xprocessing", + "//java/dagger/internal/codegen/xprocessing:xprocessing-testing", + "//third_party/java/guava/base", "//third_party/java/junit", "//third_party/java/truth", ], diff --git a/javatests/dagger/hilt/android/processor/internal/GeneratorsTest.java b/javatests/dagger/hilt/android/processor/internal/GeneratorsTest.java index 19f950c98..55e69661e 100644 --- a/javatests/dagger/hilt/android/processor/internal/GeneratorsTest.java +++ b/javatests/dagger/hilt/android/processor/internal/GeneratorsTest.java @@ -16,23 +16,23 @@ package dagger.hilt.android.processor.internal; -import static com.google.testing.compile.CompilationSubject.assertThat; -import static dagger.hilt.android.testing.compile.HiltCompilerTests.compiler; - -import com.google.testing.compile.Compilation; -import com.google.testing.compile.JavaFileObjects; -import javax.tools.JavaFileObject; +import androidx.room.compiler.processing.XProcessingEnv.Backend; +import androidx.room.compiler.processing.util.Source; +import com.google.common.base.Joiner; +import com.google.common.truth.StringSubject; +import dagger.hilt.android.testing.compile.HiltCompilerTests; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @RunWith(JUnit4.class) public final class GeneratorsTest { + private static final Joiner JOINER = Joiner.on("\n"); @Test public void copyConstructorParametersCopiesExternalNullables() { - JavaFileObject baseActivity = - JavaFileObjects.forSourceLines( + Source baseActivity = + HiltCompilerTests.javaSource( "test.BaseActivity", "package test;", "", @@ -44,8 +44,8 @@ public final class GeneratorsTest { " @androidx.annotation.Nullable String androidxNullable,", " @javax.annotation.Nullable String javaxNullable) { }", "}"); - JavaFileObject myActivity = - JavaFileObjects.forSourceLines( + Source myActivity = + HiltCompilerTests.javaSource( "test.MyActivity", "package test;", "", @@ -60,36 +60,36 @@ public final class GeneratorsTest { " super(supportNullable, androidxNullable, javaxNullable);", " }", "}"); - Compilation compilation = compiler().compile(baseActivity, myActivity); - assertThat(compilation).succeeded(); - assertThat(compilation) - .generatedSourceFile("test/Hilt_MyActivity") - .containsElementsIn( - JavaFileObjects.forSourceLines( - "test.Hilt_MyActivity", - "package test;", - "", - "import androidx.annotation.Nullable;", - "", - "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint.ActivityGenerator\")", - "abstract class Hilt_MyActivity extends BaseActivity implements", - " GeneratedComponentManagerHolder {", - " Hilt_MyActivity(", - " @Nullable String supportNullable,", - " @Nullable String androidxNullable,", - " @javax.annotation.Nullable String javaxNullable) {", - " super(supportNullable, androidxNullable, javaxNullable);", - " _initHiltInternal();", - " }", - "}")); + HiltCompilerTests.hiltCompiler(baseActivity, myActivity) + .compile( + subject -> { + subject.hasErrorCount(0); + StringSubject stringSubject = + subject.generatedSourceFileWithPath("test/Hilt_MyActivity.java"); + stringSubject.contains("package test;"); + stringSubject.contains("import androidx.annotation.Nullable;"); + stringSubject.contains( + JOINER.join( + "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint.ActivityGenerator\")", + "abstract class Hilt_MyActivity extends BaseActivity implements " + + "GeneratedComponentManagerHolder {")); + stringSubject.contains( + JOINER.join( + " Hilt_MyActivity(@Nullable String supportNullable," + + " @Nullable String androidxNullable,", + " @javax.annotation.Nullable String javaxNullable) {", + " super(supportNullable, androidxNullable, javaxNullable);", + " _initHiltInternal();", + " }")); + }); } @Test public void copyConstructorParametersConvertsAndroidInternalNullableToExternal() { // Relies on View(Context, AttributeSet), which has android-internal // @android.annotation.Nullable on AttributeSet. - JavaFileObject myView = - JavaFileObjects.forSourceLines( + Source myView = + HiltCompilerTests.javaSource( "test.MyView", "package test;", "", @@ -104,30 +104,43 @@ public final class GeneratorsTest { " super(context, attrs);", " }", "}"); - Compilation compilation = compiler().compile(myView); - assertThat(compilation).succeeded(); - assertThat(compilation) - .generatedSourceFile("test/Hilt_MyView") - .containsElementsIn( - JavaFileObjects.forSourceLines( - "test.Hilt_MyView", - "package test;", - "", - "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint.ViewGenerator\")", - "abstract class Hilt_MyView extends View implements", - "GeneratedComponentManagerHolder {", - " Hilt_MyView(Context context, @Nullable AttributeSet attrs) {", - " super(context, attrs);", - " inject();", - " }", - "}")); + HiltCompilerTests.hiltCompiler(myView) + .compile( + subject -> { + subject.hasErrorCount(0); + StringSubject stringSubject = + subject.generatedSourceFileWithPath("test/Hilt_MyView.java"); + stringSubject.contains("import androidx.annotation.Nullable;"); + stringSubject.contains( + JOINER.join( + "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint.ViewGenerator\")", + "abstract class Hilt_MyView extends View implements" + + " GeneratedComponentManagerHolder {")); + // TODO(kuanyingchou): Remove the condition once + // https://github.com/google/ksp/issues/1459 is fixed + if (HiltCompilerTests.backend(subject) == Backend.KSP) { + stringSubject.contains( + JOINER.join( + " Hilt_MyView(Context p0, @Nullable AttributeSet p1) {", + " super(p0, p1);", + " inject();", + " }")); + } else { + stringSubject.contains( + JOINER.join( + " Hilt_MyView(Context context, @Nullable AttributeSet attrs) {", + " super(context, attrs);", + " inject();", + " }")); + } + }); } // This is a regression test for https://github.com/google/dagger/issues/3296 @Test public void isRestrictedApiConstructorWithPrimitiveParameterTest() { - JavaFileObject baseView = - JavaFileObjects.forSourceLines( + Source baseView = + HiltCompilerTests.javaSource( "test.BaseView", "package test;", "", @@ -140,8 +153,8 @@ public final class GeneratorsTest { " super(context, attrs);", " }", "}"); - JavaFileObject myView = - JavaFileObjects.forSourceLines( + Source myView = + HiltCompilerTests.javaSource( "test.MyView", "package test;", "", @@ -156,15 +169,14 @@ public final class GeneratorsTest { " super(i, j, context, attrs);", " }", "}"); - Compilation compilation = compiler().compile(baseView, myView); - assertThat(compilation).succeeded(); + HiltCompilerTests.hiltCompiler(baseView, myView).compile(subject -> subject.hasErrorCount(0)); } // This is a regression test for https://github.com/google/dagger/issues/3296 @Test public void isRestrictedApiConstructorWithArrayParameterTest() { - JavaFileObject baseView = - JavaFileObjects.forSourceLines( + Source baseView = + HiltCompilerTests.javaSource( "test.BaseView", "package test;", "", @@ -177,8 +189,8 @@ public final class GeneratorsTest { " super(context, attrs);", " }", "}"); - JavaFileObject myView = - JavaFileObjects.forSourceLines( + Source myView = + HiltCompilerTests.javaSource( "test.MyView", "package test;", "", @@ -193,15 +205,14 @@ public final class GeneratorsTest { " super(strs, i, context, attrs);", " }", "}"); - Compilation compilation = compiler().compile(baseView, myView); - assertThat(compilation).succeeded(); + HiltCompilerTests.hiltCompiler(baseView, myView).compile(subject -> subject.hasErrorCount(0)); } // This is a regression test for https://github.com/google/dagger/issues/3296 @Test public void isRestrictedApiConstructorWithTypeParameterTest() { - JavaFileObject baseView = - JavaFileObjects.forSourceLines( + Source baseView = + HiltCompilerTests.javaSource( "test.BaseView", "package test;", "", @@ -214,8 +225,8 @@ public final class GeneratorsTest { " super(context, attrs);", " }", "}"); - JavaFileObject myView = - JavaFileObjects.forSourceLines( + Source myView = + HiltCompilerTests.javaSource( "test.MyView", "package test;", "", @@ -230,14 +241,13 @@ public final class GeneratorsTest { " super(str, i, context, attrs);", " }", "}"); - Compilation compilation = compiler().compile(baseView, myView); - assertThat(compilation).succeeded(); + HiltCompilerTests.hiltCompiler(baseView, myView).compile(subject -> subject.hasErrorCount(0)); } @Test public void copyTargetApiAnnotationActivity() { - JavaFileObject myActivity = - JavaFileObjects.forSourceLines( + Source myActivity = + HiltCompilerTests.javaSource( "test.MyActivity", "package test;", "", @@ -248,26 +258,25 @@ public final class GeneratorsTest { "@TargetApi(24)", "@AndroidEntryPoint(FragmentActivity.class)", "public class MyActivity extends Hilt_MyActivity {}"); - Compilation compilation = compiler().compile(myActivity); - assertThat(compilation).succeeded(); - assertThat(compilation) - .generatedSourceFile("test/Hilt_MyActivity") - .containsElementsIn( - JavaFileObjects.forSourceLines( - "test.Hilt_MyActivity", - " package test;", - "", - "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint.ActivityGenerator\")", - "@TargetApi(24)", - "abstract class Hilt_MyActivity extends FragmentActivity ", - "implements GeneratedComponentManagerHolder {", - "}")); + HiltCompilerTests.hiltCompiler(myActivity) + .compile( + subject -> { + subject.hasErrorCount(0); + StringSubject stringSubject = + subject.generatedSourceFileWithPath("test/Hilt_MyActivity.java"); + stringSubject.contains( + JOINER.join( + "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint.ActivityGenerator\")", + "@TargetApi(24)", + "abstract class Hilt_MyActivity extends FragmentActivity" + + " implements GeneratedComponentManagerHolder {")); + }); } @Test public void copyTargetApiAnnotationOverView() { - JavaFileObject myView = - JavaFileObjects.forSourceLines( + Source myView = + HiltCompilerTests.javaSource( "test.MyView", "package test;", "", @@ -284,27 +293,26 @@ public final class GeneratorsTest { " super(context, attributeSet);", " }", "}"); - Compilation compilation = compiler().compile(myView); - assertThat(compilation).succeeded(); - assertThat(compilation) - .generatedSourceFile("test/Hilt_MyView") - .containsElementsIn( - JavaFileObjects.forSourceLines( - "test.Hilt_MyView", - "", - "package test;", - "", - "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint.ViewGenerator\")", - "@TargetApi(24)", - "abstract class Hilt_MyView extends LinearLayout implements" - + " GeneratedComponentManagerHolder {", - "}")); + HiltCompilerTests.hiltCompiler(myView) + .compile( + subject -> { + subject.hasErrorCount(0); + StringSubject stringSubject = + subject.generatedSourceFileWithPath("test/Hilt_MyView.java"); + stringSubject.contains("package test;"); + stringSubject.contains( + JOINER.join( + "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint.ViewGenerator\")", + "@TargetApi(24)", + "abstract class Hilt_MyView extends LinearLayout implements" + + " GeneratedComponentManagerHolder {")); + }); } @Test public void copyTargetApiAnnotationApplication() { - JavaFileObject myApplication = - JavaFileObjects.forSourceLines( + Source myApplication = + HiltCompilerTests.javaSource( "test.MyApplication", "package test;", "", @@ -315,25 +323,27 @@ public final class GeneratorsTest { "@TargetApi(24)", "@HiltAndroidApp(Application.class)", "public class MyApplication extends Hilt_MyApplication {}"); - Compilation compilation = compiler().compile(myApplication); - assertThat(compilation).succeeded(); - assertThat(compilation) - .generatedSourceFile("test/Hilt_MyApplication") - .containsElementsIn( - JavaFileObjects.forSourceLines( - "test.Hilt_MyApplication", - " package test;", - "", - "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint.ApplicationGenerator\")", - "@TargetApi(24)", - "abstract class Hilt_MyApplication extends Application implements" - + " GeneratedComponentManagerHolder {}")); + HiltCompilerTests.hiltCompiler(myApplication) + .compile( + subject -> { + subject.hasErrorCount(0); + StringSubject stringSubject = + subject.generatedSourceFileWithPath("test/Hilt_MyApplication.java"); + stringSubject.contains("package test;"); + stringSubject.contains( + JOINER.join( + "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint." + + "ApplicationGenerator\")", + "@TargetApi(24)", + "abstract class Hilt_MyApplication extends Application implements" + + " GeneratedComponentManagerHolder {")); + }); } @Test public void copyTargetApiAnnotationFragment() { - JavaFileObject myApplication = - JavaFileObjects.forSourceLines( + Source myApplication = + HiltCompilerTests.javaSource( "test.MyFragment", "package test;", "", @@ -344,25 +354,26 @@ public final class GeneratorsTest { "@TargetApi(24)", "@AndroidEntryPoint(Fragment.class)", "public class MyFragment extends Hilt_MyFragment {}"); - Compilation compilation = compiler().compile(myApplication); - assertThat(compilation).succeeded(); - assertThat(compilation) - .generatedSourceFile("test/Hilt_MyFragment") - .containsElementsIn( - JavaFileObjects.forSourceLines( - "test.Hilt_MyFragment", - "package test;", - "", - "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint.FragmentGenerator\")", - "@TargetApi(24)", - "abstract class Hilt_MyFragment extends Fragment implements" - + " GeneratedComponentManagerHolder {}")); + HiltCompilerTests.hiltCompiler(myApplication) + .compile( + subject -> { + subject.hasErrorCount(0); + StringSubject stringSubject = + subject.generatedSourceFileWithPath("test/Hilt_MyFragment.java"); + stringSubject.contains("package test;"); + stringSubject.contains( + JOINER.join( + "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint.FragmentGenerator\")", + "@TargetApi(24)", + "abstract class Hilt_MyFragment extends Fragment implements" + + " GeneratedComponentManagerHolder {")); + }); } @Test public void copyTargetApiBroadcastRecieverGenerator() { - JavaFileObject myBroadcastReceiver = - JavaFileObjects.forSourceLines( + Source myBroadcastReceiver = + HiltCompilerTests.javaSource( "test.MyBroadcastReceiver", "package test;", "", @@ -373,24 +384,25 @@ public final class GeneratorsTest { "@TargetApi(24)", "@AndroidEntryPoint(BroadcastReceiver.class)", "public class MyBroadcastReceiver extends Hilt_MyBroadcastReceiver {}"); - Compilation compilation = compiler().compile(myBroadcastReceiver); - assertThat(compilation).succeeded(); - assertThat(compilation) - .generatedSourceFile("test/Hilt_MyBroadcastReceiver") - .containsElementsIn( - JavaFileObjects.forSourceLines( - "test.Hilt_MyBroadcastReceiver", - "package test;", - "", - "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint.BroadcastReceiverGenerator\")", - "@TargetApi(24)", - "abstract class Hilt_MyBroadcastReceiver extends BroadcastReceiver {}")); + HiltCompilerTests.hiltCompiler(myBroadcastReceiver) + .compile( + subject -> { + subject.hasErrorCount(0); + StringSubject stringSubject = + subject.generatedSourceFileWithPath("test/Hilt_MyBroadcastReceiver.java"); + stringSubject.contains("package test;"); + stringSubject.contains( + JOINER.join( + "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint.BroadcastReceiverGenerator\")", + "@TargetApi(24)", + "abstract class Hilt_MyBroadcastReceiver extends BroadcastReceiver {")); + }); } @Test public void copyTargetApiServiceGenerator() { - JavaFileObject myService = - JavaFileObjects.forSourceLines( + Source myService = + HiltCompilerTests.javaSource( "test.MyService", "package test;", "", @@ -408,25 +420,26 @@ public final class GeneratorsTest { " return null;", " }", "}"); - Compilation compilation = compiler().compile(myService); - assertThat(compilation).succeeded(); - assertThat(compilation) - .generatedSourceFile("test/Hilt_MyService") - .containsElementsIn( - JavaFileObjects.forSourceLines( - "test.Hilt_MyService", - "package test;", - "", - "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint.ServiceGenerator\")", - "@TargetApi(24)", - "abstract class Hilt_MyService extends Service implements" - + " GeneratedComponentManagerHolder{}")); + HiltCompilerTests.hiltCompiler(myService) + .compile( + subject -> { + subject.hasErrorCount(0); + StringSubject stringSubject = + subject.generatedSourceFileWithPath("test/Hilt_MyService.java"); + stringSubject.contains("package test;"); + stringSubject.contains( + JOINER.join( + "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint.ServiceGenerator\")", + "@TargetApi(24)", + "abstract class Hilt_MyService extends Service implements" + + " GeneratedComponentManagerHolder {")); + }); } @Test public void copySuppressWarningsAnnotationActivity_annotationCopied() { - JavaFileObject myActivity = - JavaFileObjects.forSourceLines( + Source myActivity = + HiltCompilerTests.javaSource( "test.MyActivity", "package test;", "", @@ -437,26 +450,26 @@ public final class GeneratorsTest { "@SuppressWarnings(\"deprecation\")", "@AndroidEntryPoint(FragmentActivity.class)", "public class MyActivity extends Hilt_MyActivity {}"); - Compilation compilation = compiler().compile(myActivity); - assertThat(compilation).succeeded(); - assertThat(compilation) - .generatedSourceFile("test/Hilt_MyActivity") - .containsElementsIn( - JavaFileObjects.forSourceLines( - "test.Hilt_MyActivity", - " package test;", - "", - "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint.ActivityGenerator\")", - "@SuppressWarnings(\"deprecation\")", - "abstract class Hilt_MyActivity extends FragmentActivity ", - "implements GeneratedComponentManagerHolder {", - "}")); + HiltCompilerTests.hiltCompiler(myActivity) + .compile( + subject -> { + subject.hasErrorCount(0); + StringSubject stringSubject = + subject.generatedSourceFileWithPath("test/Hilt_MyActivity.java"); + stringSubject.contains("package test;"); + stringSubject.contains( + JOINER.join( + "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint.ActivityGenerator\")", + "@SuppressWarnings(\"deprecation\")", + "abstract class Hilt_MyActivity extends FragmentActivity " + + "implements GeneratedComponentManagerHolder {")); + }); } @Test public void copySuppressWarningsAnnotation_onView_annotationCopied() { - JavaFileObject myView = - JavaFileObjects.forSourceLines( + Source myView = + HiltCompilerTests.javaSource( "test.MyView", "package test;", "", @@ -473,27 +486,26 @@ public final class GeneratorsTest { " super(context, attributeSet);", " }", "}"); - Compilation compilation = compiler().compile(myView); - assertThat(compilation).succeeded(); - assertThat(compilation) - .generatedSourceFile("test/Hilt_MyView") - .containsElementsIn( - JavaFileObjects.forSourceLines( - "test.Hilt_MyView", - "", - "package test;", - "", - "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint.ViewGenerator\")", - "@SuppressWarnings(\"deprecation\")", - "abstract class Hilt_MyView extends LinearLayout implements" - + " GeneratedComponentManagerHolder {", - "}")); + HiltCompilerTests.hiltCompiler(myView) + .compile( + subject -> { + subject.hasErrorCount(0); + StringSubject stringSubject = + subject.generatedSourceFileWithPath("test/Hilt_MyView.java"); + stringSubject.contains("package test;"); + stringSubject.contains( + JOINER.join( + "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint.ViewGenerator\")", + "@SuppressWarnings(\"deprecation\")", + "abstract class Hilt_MyView extends LinearLayout implements" + + " GeneratedComponentManagerHolder {")); + }); } @Test public void copySuppressWarningsAnnotation_onApplication_annotationCopied() { - JavaFileObject myApplication = - JavaFileObjects.forSourceLines( + Source myApplication = + HiltCompilerTests.javaSource( "test.MyApplication", "package test;", "", @@ -504,25 +516,26 @@ public final class GeneratorsTest { "@SuppressWarnings(\"deprecation\")", "@HiltAndroidApp(Application.class)", "public class MyApplication extends Hilt_MyApplication {}"); - Compilation compilation = compiler().compile(myApplication); - assertThat(compilation).succeeded(); - assertThat(compilation) - .generatedSourceFile("test/Hilt_MyApplication") - .containsElementsIn( - JavaFileObjects.forSourceLines( - "test.Hilt_MyApplication", - " package test;", - "", - "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint.ApplicationGenerator\")", - "@SuppressWarnings(\"deprecation\")", - "abstract class Hilt_MyApplication extends Application implements" - + " GeneratedComponentManagerHolder {}")); + HiltCompilerTests.hiltCompiler(myApplication) + .compile( + subject -> { + subject.hasErrorCount(0); + StringSubject stringSubject = + subject.generatedSourceFileWithPath("test/Hilt_MyApplication.java"); + stringSubject.contains("package test;"); + stringSubject.contains( + JOINER.join( + "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint.ApplicationGenerator\")", + "@SuppressWarnings(\"deprecation\")", + "abstract class Hilt_MyApplication extends Application implements" + + " GeneratedComponentManagerHolder {")); + }); } @Test public void copySuppressWarningsAnnotation_onFragment_annotationCopied() { - JavaFileObject myApplication = - JavaFileObjects.forSourceLines( + Source myApplication = + HiltCompilerTests.javaSource( "test.MyFragment", "package test;", "", @@ -533,25 +546,26 @@ public final class GeneratorsTest { "@SuppressWarnings(\"rawtypes\")", "@AndroidEntryPoint(Fragment.class)", "public class MyFragment extends Hilt_MyFragment {}"); - Compilation compilation = compiler().compile(myApplication); - assertThat(compilation).succeeded(); - assertThat(compilation) - .generatedSourceFile("test/Hilt_MyFragment") - .containsElementsIn( - JavaFileObjects.forSourceLines( - "test.Hilt_MyFragment", - "package test;", - "", - "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint.FragmentGenerator\")", - "@SuppressWarnings(\"rawtypes\")", - "abstract class Hilt_MyFragment extends Fragment implements" - + " GeneratedComponentManagerHolder {}")); + HiltCompilerTests.hiltCompiler(myApplication) + .compile( + subject -> { + subject.hasErrorCount(0); + StringSubject stringSubject = + subject.generatedSourceFileWithPath("test/Hilt_MyFragment.java"); + stringSubject.contains("package test;"); + stringSubject.contains( + JOINER.join( + "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint.FragmentGenerator\")", + "@SuppressWarnings(\"rawtypes\")", + "abstract class Hilt_MyFragment extends Fragment implements" + + " GeneratedComponentManagerHolder {")); + }); } @Test public void copySuppressWarnings_onBroadcastRecieverGenerator_annotationCopied() { - JavaFileObject myBroadcastReceiver = - JavaFileObjects.forSourceLines( + Source myBroadcastReceiver = + HiltCompilerTests.javaSource( "test.MyBroadcastReceiver", "package test;", "", @@ -562,24 +576,26 @@ public final class GeneratorsTest { "@SuppressWarnings(\"deprecation\")", "@AndroidEntryPoint(BroadcastReceiver.class)", "public class MyBroadcastReceiver extends Hilt_MyBroadcastReceiver {}"); - Compilation compilation = compiler().compile(myBroadcastReceiver); - assertThat(compilation).succeeded(); - assertThat(compilation) - .generatedSourceFile("test/Hilt_MyBroadcastReceiver") - .containsElementsIn( - JavaFileObjects.forSourceLines( - "test.Hilt_MyBroadcastReceiver", - "package test;", - "", - "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint.BroadcastReceiverGenerator\")", - "@SuppressWarnings(\"deprecation\")", - "abstract class Hilt_MyBroadcastReceiver extends BroadcastReceiver {}")); + HiltCompilerTests.hiltCompiler(myBroadcastReceiver) + .compile( + subject -> { + subject.hasErrorCount(0); + StringSubject stringSubject = + subject.generatedSourceFileWithPath("test/Hilt_MyBroadcastReceiver.java"); + stringSubject.contains("package test;"); + stringSubject.contains( + JOINER.join( + "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint." + + "BroadcastReceiverGenerator\")", + "@SuppressWarnings(\"deprecation\")", + "abstract class Hilt_MyBroadcastReceiver extends BroadcastReceiver {")); + }); } @Test public void copySuppressWarnings_onServiceGenerator_annotationCopied() { - JavaFileObject myService = - JavaFileObjects.forSourceLines( + Source myService = + HiltCompilerTests.javaSource( "test.MyService", "package test;", "", @@ -597,18 +613,20 @@ public final class GeneratorsTest { " return null;", " }", "}"); - Compilation compilation = compiler().compile(myService); - assertThat(compilation).succeeded(); - assertThat(compilation) - .generatedSourceFile("test/Hilt_MyService") - .containsElementsIn( - JavaFileObjects.forSourceLines( - "test.Hilt_MyService", - "package test;", - "", - "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint.ServiceGenerator\")", - "@SuppressWarnings(\"deprecation\")", - "abstract class Hilt_MyService extends Service implements" - + " GeneratedComponentManagerHolder{}")); + HiltCompilerTests.hiltCompiler(myService) + .compile( + subject -> { + subject.hasErrorCount(0); + StringSubject stringSubject = + subject.generatedSourceFileWithPath("test/Hilt_MyService.java"); + stringSubject.contains("package test;"); + stringSubject.contains( + JOINER.join( + "@Generated(\"dagger.hilt.android.processor.internal.androidentrypoint." + + "ServiceGenerator\")", + "@SuppressWarnings(\"deprecation\")", + "abstract class Hilt_MyService extends Service implements" + + " GeneratedComponentManagerHolder {")); + }); } } diff --git a/javatests/dagger/hilt/android/processor/internal/androidentrypoint/ActivityGeneratorTest.java b/javatests/dagger/hilt/android/processor/internal/androidentrypoint/ActivityGeneratorTest.java index b58c355c8..a056670d7 100644 --- a/javatests/dagger/hilt/android/processor/internal/androidentrypoint/ActivityGeneratorTest.java +++ b/javatests/dagger/hilt/android/processor/internal/androidentrypoint/ActivityGeneratorTest.java @@ -71,4 +71,108 @@ public class ActivityGeneratorTest { HiltCompilerTests.hiltCompiler(baseActivity, myActivity) .compile(subject -> subject.hasErrorCount(0)); } + + @Test + public void baseActivityHasFinalOnDestroy_fails() { + Source myActivity = + HiltCompilerTests.javaSource( + "test.MyActivity", + "package test;", + "", + "import dagger.hilt.android.AndroidEntryPoint;", + "", + "@AndroidEntryPoint(BaseActivity.class)", + "public class MyActivity extends Hilt_MyActivity {}"); + Source baseActivity = + HiltCompilerTests.javaSource( + "test.BaseActivity", + "package test;", + "", + "import androidx.activity.ComponentActivity;", + "", + "public class BaseActivity extends ComponentActivity {", + " @Override public final void onDestroy() {}", + "}"); + HiltCompilerTests.hiltCompiler(myActivity, baseActivity) + .compile( + subject -> { + // TODO(b/319663779) make error count consistent. + // subject.hasErrorCount(1); + subject.hasErrorContaining( + "Do not mark onDestroy as final in base Activity class, as Hilt needs to override" + + " it to clean up SavedStateHandle"); + }); + } + + @Test + public void baseActivityHasFinalOnCreate_fails() { + Source myActivity = + HiltCompilerTests.javaSource( + "test.MyActivity", + "package test;", + "", + "import dagger.hilt.android.AndroidEntryPoint;", + "", + "@AndroidEntryPoint(BaseActivity.class)", + "public class MyActivity extends Hilt_MyActivity {}"); + Source baseActivity = + HiltCompilerTests.javaSource( + "test.BaseActivity", + "package test;", + "", + "import android.os.Bundle;", + "import androidx.activity.ComponentActivity;", + "", + "public class BaseActivity extends ComponentActivity {", + " @Override public final void onCreate(Bundle bundle) {}", + "}"); + HiltCompilerTests.hiltCompiler(myActivity, baseActivity) + .compile( + subject -> { + // TODO(b/319663779) make error count consistent. + // subject.hasErrorCount(1); + subject.hasErrorContaining( + "Do not mark onCreate as final in base Activity class, as Hilt needs to override" + + " it to inject SavedStateHandle"); + }); + } + + @Test + public void secondBaseActivityHasFinalOnCreate_fails() { + Source myActivity = + HiltCompilerTests.javaSource( + "test.MyActivity", + "package test;", + "", + "import dagger.hilt.android.AndroidEntryPoint;", + "", + "@AndroidEntryPoint(BaseActivity.class)", + "public class MyActivity extends Hilt_MyActivity {}"); + Source baseActivity = + HiltCompilerTests.javaSource( + "test.BaseActivity", + "package test;", + "", + "public class BaseActivity extends BaseActivity2 {}"); + Source baseActivity2 = + HiltCompilerTests.javaSource( + "test.BaseActivity2", + "package test;", + "", + "import android.os.Bundle;", + "import androidx.activity.ComponentActivity;", + "", + "public class BaseActivity2 extends ComponentActivity {", + " @Override public final void onCreate(Bundle bundle) {}", + "}"); + HiltCompilerTests.hiltCompiler(myActivity, baseActivity, baseActivity2) + .compile( + subject -> { + // TODO(b/319663779) make error count consistent. + // subject.hasErrorCount(1); + subject.hasErrorContaining( + "Do not mark onCreate as final in base Activity class, as Hilt needs to override" + + " it to inject SavedStateHandle"); + }); + } } diff --git a/javatests/dagger/hilt/android/processor/internal/androidentrypoint/AndroidEntryPointProcessorTest.java b/javatests/dagger/hilt/android/processor/internal/androidentrypoint/AndroidEntryPointProcessorTest.java index f39d8970f..0c11f6eb5 100644 --- a/javatests/dagger/hilt/android/processor/internal/androidentrypoint/AndroidEntryPointProcessorTest.java +++ b/javatests/dagger/hilt/android/processor/internal/androidentrypoint/AndroidEntryPointProcessorTest.java @@ -16,16 +16,12 @@ package dagger.hilt.android.processor.internal.androidentrypoint; -import static com.google.testing.compile.CompilationSubject.assertThat; -import static dagger.hilt.android.testing.compile.HiltCompilerTests.compiler; - import androidx.room.compiler.processing.XProcessingEnv; +import androidx.room.compiler.processing.XProcessingEnv.Backend; import androidx.room.compiler.processing.util.CompilationResultSubject; import androidx.room.compiler.processing.util.Source; -import com.google.testing.compile.Compilation; -import com.google.testing.compile.JavaFileObjects; +import com.google.common.collect.ImmutableMap; import dagger.hilt.android.testing.compile.HiltCompilerTests; -import javax.tools.JavaFileObject; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -106,8 +102,8 @@ public class AndroidEntryPointProcessorTest { @Test public void disableSuperclassValidation_activity() { - JavaFileObject testActivity = - JavaFileObjects.forSourceLines( + Source testActivity = + HiltCompilerTests.javaSource( "test.MyActivity", "package test;", "", @@ -116,17 +112,17 @@ public class AndroidEntryPointProcessorTest { "", "@AndroidEntryPoint", "public class MyActivity extends ComponentActivity { }"); - Compilation compilation = - compiler() - .withOptions("-Adagger.hilt.android.internal.disableAndroidSuperclassValidation=true") - .compile(testActivity); - assertThat(compilation).succeeded(); + HiltCompilerTests.hiltCompiler(testActivity) + .withProcessorOptions( + ImmutableMap.of( + "dagger.hilt.android.internal.disableAndroidSuperclassValidation", "true")) + .compile(subject -> subject.hasErrorCount(0)); } @Test public void disableSuperclassValidation_application() { - JavaFileObject testApplication = - JavaFileObjects.forSourceLines( + Source testApplication = + HiltCompilerTests.javaSource( "test.MyApp", "package test;", "", @@ -135,17 +131,17 @@ public class AndroidEntryPointProcessorTest { "", "@HiltAndroidApp", "public class MyApp extends Application { }"); - Compilation compilation = - compiler() - .withOptions("-Adagger.hilt.android.internal.disableAndroidSuperclassValidation=true") - .compile(testApplication); - assertThat(compilation).succeeded(); + HiltCompilerTests.hiltCompiler(testApplication) + .withProcessorOptions( + ImmutableMap.of( + "dagger.hilt.android.internal.disableAndroidSuperclassValidation", "true")) + .compile(subject -> subject.hasErrorCount(0)); } @Test public void checkBaseActivityExtendsComponentActivity() { - JavaFileObject testActivity = - JavaFileObjects.forSourceLines( + Source testActivity = + HiltCompilerTests.javaSource( "test.MyActivity", "package test;", "", @@ -154,18 +150,18 @@ public class AndroidEntryPointProcessorTest { "", "@AndroidEntryPoint(Activity.class)", "public class MyActivity extends Hilt_MyActivity { }"); - Compilation compilation = compiler().compile(testActivity); - assertThat(compilation).failed(); - assertThat(compilation) - .hadErrorContaining("Activities annotated with @AndroidEntryPoint must be a subclass of " - + "androidx.activity.ComponentActivity. (e.g. FragmentActivity, AppCompatActivity, " - + "etc.)"); + HiltCompilerTests.hiltCompiler(testActivity).compile(subject -> { + subject.compilationDidFail(); + subject.hasErrorContaining( + "Activities annotated with @AndroidEntryPoint must be a subclass of " + + "androidx.activity.ComponentActivity. (e.g. FragmentActivity, AppCompatActivity, " + + "etc.)"); }); } @Test public void checkBaseActivityWithTypeParameters() { - JavaFileObject testActivity = - JavaFileObjects.forSourceLines( + Source testActivity = + HiltCompilerTests.javaSource( "test.BaseActivity", "package test;", "", @@ -174,13 +170,18 @@ public class AndroidEntryPointProcessorTest { "", "@AndroidEntryPoint(ComponentActivity.class)", "public class BaseActivity<T> extends Hilt_BaseActivity {}"); - Compilation compilation = compiler().compile(testActivity); - assertThat(compilation).failed(); - assertThat(compilation).hadErrorCount(2); - assertThat(compilation).hadErrorContaining( - "cannot find symbol\n symbol: class Hilt_BaseActivity"); - assertThat(compilation).hadErrorContaining( - "@AndroidEntryPoint-annotated classes cannot have type parameters."); + HiltCompilerTests.hiltCompiler(testActivity) + .compile( + subject -> { + subject.compilationDidFail(); + if (HiltCompilerTests.backend(subject) == Backend.JAVAC) { + subject.hasErrorCount(2); + } else { + subject.hasErrorCount(1); + } + subject.hasErrorContaining( + "@AndroidEntryPoint-annotated classes cannot have type parameters."); + }); } @Test diff --git a/javatests/dagger/hilt/android/processor/internal/androidentrypoint/BUILD b/javatests/dagger/hilt/android/processor/internal/androidentrypoint/BUILD index 10be14792..8a39641a1 100644 --- a/javatests/dagger/hilt/android/processor/internal/androidentrypoint/BUILD +++ b/javatests/dagger/hilt/android/processor/internal/androidentrypoint/BUILD @@ -49,7 +49,7 @@ compiler_test( "//java/dagger/hilt/android/testing/compile", "//java/dagger/internal/codegen/xprocessing", "//java/dagger/internal/codegen/xprocessing:xprocessing-testing", - "//third_party/java/compile_testing", + "//third_party/java/guava/collect", "//third_party/java/junit", ], ) diff --git a/javatests/dagger/hilt/android/processor/internal/viewmodel/BUILD b/javatests/dagger/hilt/android/processor/internal/viewmodel/BUILD index 79d7cbea8..eb73b3f09 100644 --- a/javatests/dagger/hilt/android/processor/internal/viewmodel/BUILD +++ b/javatests/dagger/hilt/android/processor/internal/viewmodel/BUILD @@ -15,8 +15,8 @@ # Description: # Tests for internal code for implementing Hilt processors. -load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_library") load("//java/dagger/testing/compile:macros.bzl", "kt_compiler_test") +load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_library") package(default_visibility = ["//:src"]) @@ -33,41 +33,47 @@ kt_compiler_test( "//java/dagger/hilt/android/testing/compile", "//java/dagger/internal/codegen/xprocessing", "//java/dagger/internal/codegen/xprocessing:xprocessing-testing", + "//third_party/java/guava/collect", "//third_party/java/junit", ], ) -java_test( - name = "ViewModelGeneratorTest", - runtime_deps = [ - ":ViewModelGeneratorTestLib", - "//java/dagger/hilt/android/lifecycle:hilt_view_model", - "//third_party/java/compile_testing", - "//third_party/java/truth", +kt_compiler_test( + name = "ViewModelValidationPluginTest", + srcs = [ + "ViewModelValidationPluginTest.kt", + ], + compiler_deps = [ "@androidsdk//:platforms/android-32/android.jar", "@maven//:androidx_lifecycle_lifecycle_viewmodel", "@maven//:androidx_lifecycle_lifecycle_viewmodel_savedstate", + "//third_party/java/compile_testing", + "//third_party/java/truth", + "//java/dagger/hilt/android/lifecycle:hilt_view_model", + "//java/dagger/hilt/android:android_entry_point", + "//java/dagger/hilt/android:hilt_android_app", ], -) - -kt_jvm_library( - name = "ViewModelGeneratorTestLib", - srcs = [ - "ViewModelGeneratorTest.kt", - ], + resources = glob(["goldens/*"]), deps = [ ":test_utils", + "//:compiler_internals", "//java/dagger/hilt/android/processor/internal/viewmodel:processor_lib", + "//java/dagger/hilt/android/processor/internal/viewmodel:validation_plugin_lib", + "//java/dagger/hilt/android/testing/compile", + "//java/dagger/internal/codegen/xprocessing", + "//java/dagger/internal/codegen/xprocessing:xprocessing-testing", + "//java/dagger/testing/golden", "//third_party/java/compile_testing", + "//third_party/java/guava/collect", "//third_party/java/junit", "//third_party/java/truth", ], ) kt_compiler_test( - name = "ViewModelValidationPluginTest", + name = "ViewModelValidationPluginWithAssistedInjectTest", srcs = [ - "ViewModelValidationPluginTest.kt", + "ViewModelValidationPluginWithAssistedInjectTest.kt", ], compiler_deps = [ "@androidsdk//:platforms/android-32/android.jar", @@ -79,13 +85,18 @@ kt_compiler_test( "//java/dagger/hilt/android:android_entry_point", "//java/dagger/hilt/android:hilt_android_app", ], + resources = glob(["goldens/*"]), deps = [ ":test_utils", "//:compiler_internals", "//java/dagger/hilt/android/processor/internal/viewmodel:processor_lib", "//java/dagger/hilt/android/processor/internal/viewmodel:validation_plugin_lib", "//java/dagger/hilt/android/testing/compile", + "//java/dagger/internal/codegen/xprocessing", + "//java/dagger/internal/codegen/xprocessing:xprocessing-testing", + "//java/dagger/testing/golden", "//third_party/java/compile_testing", + "//third_party/java/guava/collect", "//third_party/java/junit", "//third_party/java/truth", ], @@ -97,6 +108,6 @@ kt_jvm_library( "TestUtils.kt", ], deps = [ - "//third_party/java/compile_testing", + "//java/dagger/hilt/android/testing/compile", ], ) diff --git a/javatests/dagger/hilt/android/processor/internal/viewmodel/TestUtils.kt b/javatests/dagger/hilt/android/processor/internal/viewmodel/TestUtils.kt index 713cd22b8..d833c32dd 100644 --- a/javatests/dagger/hilt/android/processor/internal/viewmodel/TestUtils.kt +++ b/javatests/dagger/hilt/android/processor/internal/viewmodel/TestUtils.kt @@ -1,15 +1,16 @@ package dagger.hilt.android.processor.internal.viewmodel -import com.google.testing.compile.JavaFileObjects +import dagger.hilt.android.testing.compile.HiltCompilerTests -val GENERATED_TYPE = try { - Class.forName("javax.annotation.processing.Generated") - "javax.annotation.processing.Generated" -} catch (_: ClassNotFoundException) { - "javax.annotation.Generated" -} +val GENERATED_TYPE = + try { + Class.forName("javax.annotation.processing.Generated") + "javax.annotation.processing.Generated" + } catch (_: ClassNotFoundException) { + "javax.annotation.Generated" + } const val GENERATED_ANNOTATION = "@Generated(\"dagger.hilt.android.processor.internal.viewmodel.ViewModelProcessor\")" -fun String.toJFO(qName: String) = JavaFileObjects.forSourceString(qName, this.trimIndent()) +fun String.toJFO(qName: String) = HiltCompilerTests.javaSource(qName, this.trimIndent()) diff --git a/javatests/dagger/hilt/android/processor/internal/viewmodel/ViewModelGeneratorTest.kt b/javatests/dagger/hilt/android/processor/internal/viewmodel/ViewModelGeneratorTest.kt deleted file mode 100644 index c2378e030..000000000 --- a/javatests/dagger/hilt/android/processor/internal/viewmodel/ViewModelGeneratorTest.kt +++ /dev/null @@ -1,449 +0,0 @@ -/* - * Copyright (C) 2020 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.android.processor.internal.viewmodel - -import com.google.testing.compile.CompilationSubject.assertThat -import com.google.testing.compile.Compiler -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.JUnit4 - -@RunWith(JUnit4::class) -class ViewModelGeneratorTest { - - private fun compiler(): Compiler = Compiler.javac().withProcessors(ViewModelProcessor()) - - @Test - fun verifyModule_noArg() { - val myViewModel = """ - package dagger.hilt.android.test; - - import dagger.hilt.android.lifecycle.HiltViewModel; - import androidx.lifecycle.ViewModel; - import javax.inject.Inject; - - @HiltViewModel - class MyViewModel extends ViewModel { - @Inject - MyViewModel() { } - } - """.toJFO("dagger.hilt.android.test.MyViewModel") - - val expected = """ - package dagger.hilt.android.test; - - $GENERATED_ANNOTATION - @OriginatingElement( - topLevelClass = MyViewModel.class - ) - public final class MyViewModel_HiltModules { - private MyViewModel_HiltModules() { - } - - @Module - @InstallIn(ViewModelComponent.class) - public static abstract class BindsModule { - private BindsModule() {} - - @Binds - @IntoMap - @StringKey("dagger.hilt.android.test.MyViewModel") - @HiltViewModelMap - public abstract ViewModel binds(MyViewModel vm); - } - - @Module - @InstallIn(ActivityRetainedComponent.class) - public static final class KeyModule { - private KeyModule() { - } - - @Provides - @IntoSet - @HiltViewModelMap.KeySet - public static String provide() { - return "dagger.hilt.android.test.MyViewModel"; - } - } - } - """.toJFO("dagger.hilt.android.test.MyViewModel_HiltModule") - - val compilation = compiler() - .compile(myViewModel) - assertThat(compilation).apply { - succeeded() - generatedSourceFile("dagger.hilt.android.test.MyViewModel_HiltModules") - .containsElementsIn(expected) - } - } - - @Test - fun verifyModule_savedStateOnlyArg() { - val myViewModel = """ - package dagger.hilt.android.test; - - import dagger.hilt.android.lifecycle.HiltViewModel; - import androidx.lifecycle.ViewModel; - import androidx.lifecycle.SavedStateHandle; - import javax.inject.Inject; - - @HiltViewModel - class MyViewModel extends ViewModel { - @Inject - MyViewModel(SavedStateHandle savedState) { } - } - """.toJFO("dagger.hilt.android.test.MyViewModel") - - val expected = """ - package dagger.hilt.android.test; - - $GENERATED_ANNOTATION - @OriginatingElement( - topLevelClass = MyViewModel.class - ) - public final class MyViewModel_HiltModules { - private MyViewModel_HiltModules() { - } - - @Module - @InstallIn(ViewModelComponent.class) - public static abstract class BindsModule { - private BindsModule() {} - - @Binds - @IntoMap - @StringKey("dagger.hilt.android.test.MyViewModel") - @HiltViewModelMap - public abstract ViewModel binds(MyViewModel vm); - } - - @Module - @InstallIn(ActivityRetainedComponent.class) - public static final class KeyModule { - private KeyModule() { - } - - @Provides - @IntoSet - @HiltViewModelMap.KeySet - public static String provide() { - return "dagger.hilt.android.test.MyViewModel"; - } - } - } - """.toJFO("dagger.hilt.android.test.MyViewModel_HiltModule") - - val compilation = compiler() - .compile(myViewModel) - assertThat(compilation).apply { - succeeded() - generatedSourceFile("dagger.hilt.android.test.MyViewModel_HiltModules") - .containsElementsIn(expected) - } - } - - @Test - fun verifyModule_mixedArgs() { - val foo = """ - package dagger.hilt.android.test; - - public class Foo { } - """.toJFO("dagger.hilt.android.test.Foo") - - val myViewModel = """ - package dagger.hilt.android.test; - - import dagger.hilt.android.lifecycle.HiltViewModel; - import androidx.lifecycle.ViewModel; - import androidx.lifecycle.SavedStateHandle; - import java.lang.String; - import javax.inject.Inject; - - @HiltViewModel - class MyViewModel extends ViewModel { - @Inject - MyViewModel(String s, Foo f, SavedStateHandle savedState, long l) { } - } - """.toJFO("dagger.hilt.android.test.MyViewModel") - - val expected = """ - package dagger.hilt.android.test; - - $GENERATED_ANNOTATION - @OriginatingElement( - topLevelClass = MyViewModel.class - ) - public final class MyViewModel_HiltModules { - private MyViewModel_HiltModules() { - } - - @Module - @InstallIn(ViewModelComponent.class) - public static abstract class BindsModule { - private BindsModule() {} - - @Binds - @IntoMap - @StringKey("dagger.hilt.android.test.MyViewModel") - @HiltViewModelMap - public abstract ViewModel binds(MyViewModel vm); - } - - @Module - @InstallIn(ActivityRetainedComponent.class) - public static final class KeyModule { - private KeyModule() { - } - - @Provides - @IntoSet - @HiltViewModelMap.KeySet - public static String provide() { - return "dagger.hilt.android.test.MyViewModel"; - } - } - } - """.toJFO("dagger.hilt.android.test.MyViewModel_HiltModule") - - val compilation = compiler() - .compile(foo, myViewModel) - assertThat(compilation).apply { - succeeded() - generatedSourceFile("dagger.hilt.android.test.MyViewModel_HiltModules") - .containsElementsIn(expected) - } - } - - @Test - fun verifyModule_mixedAndProviderArgs() { - val foo = """ - package dagger.hilt.android.test; - - public class Foo { } - """.toJFO("dagger.hilt.android.test.Foo") - - val myViewModel = """ - package dagger.hilt.android.test; - - import dagger.hilt.android.lifecycle.HiltViewModel; - import androidx.lifecycle.ViewModel; - import androidx.lifecycle.SavedStateHandle; - import java.lang.String; - import javax.inject.Inject; - import javax.inject.Provider; - - @HiltViewModel - class MyViewModel extends ViewModel { - @Inject - MyViewModel(String s, Provider<Foo> f, SavedStateHandle savedState) { } - } - """.toJFO("dagger.hilt.android.test.MyViewModel") - - val expected = """ - package dagger.hilt.android.test; - - $GENERATED_ANNOTATION - @OriginatingElement( - topLevelClass = MyViewModel.class - ) - public final class MyViewModel_HiltModules { - private MyViewModel_HiltModules() { - } - - @Module - @InstallIn(ViewModelComponent.class) - public static abstract class BindsModule { - private BindsModule() {} - - @Binds - @IntoMap - @StringKey("dagger.hilt.android.test.MyViewModel") - @HiltViewModelMap - public abstract ViewModel binds(MyViewModel vm); - } - - @Module - @InstallIn(ActivityRetainedComponent.class) - public static final class KeyModule { - private KeyModule() { - } - - @Provides - @IntoSet - @HiltViewModelMap.KeySet - public static String provide() { - return "dagger.hilt.android.test.MyViewModel"; - } - } - } - """.toJFO("dagger.hilt.android.test.MyViewModel_HiltModules") - - val compilation = compiler() - .compile(foo, myViewModel) - assertThat(compilation).apply { - succeeded() - generatedSourceFile("dagger.hilt.android.test.MyViewModel_HiltModules") - .containsElementsIn(expected) - } - } - - @Test - fun verifyModule_qualifiedArgs() { - val myQualifier = """ - package dagger.hilt.android.test; - - import javax.inject.Qualifier; - - @Qualifier - public @interface MyQualifier { } - """.toJFO("dagger.hilt.android.test.MyQualifier") - - val myViewModel = """ - package dagger.hilt.android.test; - - import dagger.hilt.android.lifecycle.HiltViewModel; - import androidx.lifecycle.ViewModel; - import androidx.lifecycle.SavedStateHandle; - import java.lang.Long; - import java.lang.String; - import javax.inject.Inject; - import javax.inject.Named; - import javax.inject.Provider; - - @HiltViewModel - class MyViewModel extends ViewModel { - @Inject - MyViewModel(@Named("TheString") String s, @MyQualifier Provider<Long> l, - SavedStateHandle savedState) { - } - } - """.toJFO("dagger.hilt.android.test.MyViewModel") - - val expected = """ - package dagger.hilt.android.test; - - $GENERATED_ANNOTATION - @OriginatingElement( - topLevelClass = MyViewModel.class - ) - public final class MyViewModel_HiltModules { - private MyViewModel_HiltModules() { - } - - @Module - @InstallIn(ViewModelComponent.class) - public static abstract class BindsModule { - private BindsModule() {} - - @Binds - @IntoMap - @StringKey("dagger.hilt.android.test.MyViewModel") - @HiltViewModelMap - public abstract ViewModel binds(MyViewModel vm); - } - - @Module - @InstallIn(ActivityRetainedComponent.class) - public static final class KeyModule { - private KeyModule() { - } - - @Provides - @IntoSet - @HiltViewModelMap.KeySet - public static String provide() { - return "dagger.hilt.android.test.MyViewModel"; - } - } - } - """.toJFO("dagger.hilt.android.test.MyViewModel_HiltModules") - - val compilation = compiler() - .compile(myQualifier, myViewModel) - assertThat(compilation).apply { - succeeded() - generatedSourceFile("dagger.hilt.android.test.MyViewModel_HiltModules") - .containsElementsIn(expected) - } - } - - @Test - fun verifyInnerClass() { - val viewModel = """ - package dagger.hilt.android.test; - - import dagger.hilt.android.lifecycle.HiltViewModel; - import androidx.lifecycle.ViewModel; - import javax.inject.Inject; - - class Outer { - @HiltViewModel - static class InnerViewModel extends ViewModel { - @Inject - InnerViewModel() { } - } - } - """.toJFO("dagger.hilt.android.test.Outer") - - val expectedModule = """ - package dagger.hilt.android.test; - - $GENERATED_ANNOTATION - @OriginatingElement( - topLevelClass = Outer.class - ) - public final class Outer_InnerViewModel_HiltModules { - private Outer_InnerViewModel_HiltModules() { - } - - @Module - @InstallIn(ViewModelComponent.class) - public static abstract class BindsModule { - private BindsModule() {} - - @Binds - @IntoMap - @StringKey("dagger.hilt.android.test.Outer${'$'}InnerViewModel") - @HiltViewModelMap - public abstract ViewModel binds(Outer.InnerViewModel vm); - } - - @Module - @InstallIn(ActivityRetainedComponent.class) - public static final class KeyModule { - private KeyModule() { - } - - @Provides - @IntoSet - @HiltViewModelMap.KeySet - public static String provide() { - return "dagger.hilt.android.test.Outer${'$'}InnerViewModel"; - } - } - } - """.toJFO("dagger.hilt.android.test.Outer_InnerViewModel_HiltModules") - - val compilation = compiler() - .compile(viewModel) - assertThat(compilation).apply { - succeeded() - generatedSourceFile("dagger.hilt.android.test.Outer_InnerViewModel_HiltModules") - .containsElementsIn(expectedModule) - } - } -} diff --git a/javatests/dagger/hilt/android/processor/internal/viewmodel/ViewModelProcessorTest.kt b/javatests/dagger/hilt/android/processor/internal/viewmodel/ViewModelProcessorTest.kt index b35aed247..133770084 100644 --- a/javatests/dagger/hilt/android/processor/internal/viewmodel/ViewModelProcessorTest.kt +++ b/javatests/dagger/hilt/android/processor/internal/viewmodel/ViewModelProcessorTest.kt @@ -18,6 +18,7 @@ package dagger.hilt.android.processor.internal.viewmodel import androidx.room.compiler.processing.ExperimentalProcessingApi import androidx.room.compiler.processing.util.Source +import com.google.common.collect.ImmutableMap import dagger.hilt.android.testing.compile.HiltCompilerTests import org.junit.Test import org.junit.runner.RunWith @@ -84,24 +85,23 @@ class ViewModelProcessorTest { } @Test - fun verifySingleAnnotatedConstructor() { + fun verifyNoAssistedInjectViewModels() { val myViewModel = Source.java( "dagger.hilt.android.test.MyViewModel", """ package dagger.hilt.android.test; + import dagger.assisted.AssistedInject; + import dagger.assisted.Assisted; import androidx.lifecycle.ViewModel; import dagger.hilt.android.lifecycle.HiltViewModel; import javax.inject.Inject; @HiltViewModel class MyViewModel extends ViewModel { - @Inject - MyViewModel() { } - - @Inject - MyViewModel(String s) { } + @AssistedInject + MyViewModel(String s, @Assisted int i) { } } """ .trimIndent() @@ -110,19 +110,68 @@ class ViewModelProcessorTest { HiltCompilerTests.hiltCompiler(myViewModel) .withAdditionalJavacProcessors(ViewModelProcessor()) .withAdditionalKspProcessors(KspViewModelProcessor.Provider()) + .withProcessorOptions(ImmutableMap.of("dagger.hilt.enableAssistedInjectViewModels", "false")) .compile { subject -> subject.compilationDidFail() - subject.hasErrorCount(2) - subject.hasErrorContaining( - "Type dagger.hilt.android.test.MyViewModel may only contain one injected constructor. Found: [@Inject dagger.hilt.android.test.MyViewModel(), @Inject dagger.hilt.android.test.MyViewModel(String)]" - ) + subject.hasErrorCount(1) subject.hasErrorContaining( - "@HiltViewModel annotated class should contain exactly one @Inject annotated constructor." + "ViewModel constructor should be annotated with @Inject instead of @AssistedInject." ) } } @Test + fun verifySingleAnnotatedConstructor() { + val myViewModel = + Source.java( + "dagger.hilt.android.test.MyViewModel", + """ + package dagger.hilt.android.test; + + import androidx.lifecycle.ViewModel; + import dagger.hilt.android.lifecycle.HiltViewModel; + import javax.inject.Inject; + + @HiltViewModel + class MyViewModel extends ViewModel { + @Inject + MyViewModel() { } + + @Inject + MyViewModel(String s) { } + } + """ + .trimIndent() + ) + + listOf(false, true).forEach { enableAssistedInjectViewModels -> + HiltCompilerTests.hiltCompiler(myViewModel) + .withAdditionalJavacProcessors(ViewModelProcessor()) + .withAdditionalKspProcessors(KspViewModelProcessor.Provider()) + .withProcessorOptions( + ImmutableMap.of( + "dagger.hilt.enableAssistedInjectViewModels", + enableAssistedInjectViewModels.toString() + ) + ) + .compile { subject -> + subject.compilationDidFail() + subject.hasErrorCount(2) + subject.hasErrorContaining( + "Type dagger.hilt.android.test.MyViewModel may only contain one injected constructor. Found: [@Inject dagger.hilt.android.test.MyViewModel(), @Inject dagger.hilt.android.test.MyViewModel(String)]" + ) + subject.hasErrorContaining( + if (enableAssistedInjectViewModels) { + "@HiltViewModel annotated class should contain exactly one @Inject or @AssistedInject annotated constructor." + } else { + "@HiltViewModel annotated class should contain exactly one @Inject annotated constructor." + } + ) + } + } + } + + @Test fun verifyNonPrivateConstructor() { val myViewModel = Source.java( @@ -143,15 +192,29 @@ class ViewModelProcessorTest { .trimIndent() ) - HiltCompilerTests.hiltCompiler(myViewModel) - .withAdditionalJavacProcessors(ViewModelProcessor()) - .withAdditionalKspProcessors(KspViewModelProcessor.Provider()) - .compile { subject -> - subject.compilationDidFail() - subject.hasErrorCount(2) - subject.hasErrorContaining("Dagger does not support injection into private constructors") - subject.hasErrorContaining("@Inject annotated constructors must not be private.") - } + listOf(false, true).forEach { enableAssistedInjectViewModels -> + HiltCompilerTests.hiltCompiler(myViewModel) + .withAdditionalJavacProcessors(ViewModelProcessor()) + .withAdditionalKspProcessors(KspViewModelProcessor.Provider()) + .withProcessorOptions( + ImmutableMap.of( + "dagger.hilt.enableAssistedInjectViewModels", + enableAssistedInjectViewModels.toString() + ) + ) + .compile { subject -> + subject.compilationDidFail() + subject.hasErrorCount(2) + subject.hasErrorContaining("Dagger does not support injection into private constructors") + subject.hasErrorContaining( + if (enableAssistedInjectViewModels) { + "@Inject or @AssistedInject annotated constructors must not be private." + } else { + "@Inject annotated constructors must not be private." + } + ) + } + } } @Test @@ -225,4 +288,340 @@ class ViewModelProcessorTest { ) } } + + @Test + fun verifyAssistedFlagIsEnabled() { + val myViewModel = + Source.java( + "dagger.hilt.android.test.MyViewModel", + """ + package dagger.hilt.android.test; + + import dagger.assisted.Assisted; + import dagger.assisted.AssistedInject; + import androidx.lifecycle.ViewModel; + import dagger.hilt.android.lifecycle.HiltViewModel; + + @HiltViewModel(assistedFactory = MyFactory.class) + class MyViewModel extends ViewModel { + @AssistedInject + MyViewModel(String s, @Assisted int i) { } + } + """ + .trimIndent() + ) + val myFactory = + Source.java( + "dagger.hilt.android.test.MyFactory", + """ + package dagger.hilt.android.test; + import dagger.assisted.AssistedFactory; + @AssistedFactory + interface MyFactory { + MyViewModel create(int i); + } + """ + ) + + HiltCompilerTests.hiltCompiler(myViewModel, myFactory) + .withAdditionalJavacProcessors(ViewModelProcessor()) + .withAdditionalKspProcessors(KspViewModelProcessor.Provider()) + .withProcessorOptions(ImmutableMap.of("dagger.hilt.enableAssistedInjectViewModels", "false")) + .compile { subject -> + subject.compilationDidFail() + subject.hasErrorCount(1) + subject.hasErrorContaining( + "Specified assisted factory dagger.hilt.android.test.MyFactory for dagger.hilt.android.test.MyViewModel in @HiltViewModel but compiler option 'enableAssistedInjectViewModels' was not enabled." + ) + } + } + + @Test + fun verifyAssistedFactoryHasMethod() { + val myViewModel = + Source.java( + "dagger.hilt.android.test.MyViewModel", + """ + package dagger.hilt.android.test; + + import dagger.assisted.Assisted; + import dagger.assisted.AssistedInject; + import androidx.lifecycle.ViewModel; + import dagger.hilt.android.lifecycle.HiltViewModel; + + @HiltViewModel(assistedFactory = MyFactory.class) + class MyViewModel extends ViewModel { + @AssistedInject + MyViewModel(String s, @Assisted int i) { } + } + """ + .trimIndent() + ) + val myFactory = + Source.java( + "dagger.hilt.android.test.MyFactory", + """ + package dagger.hilt.android.test; + import dagger.assisted.AssistedFactory; + @AssistedFactory + interface MyFactory {} + """ + ) + + HiltCompilerTests.hiltCompiler(myViewModel, myFactory) + .withAdditionalJavacProcessors(ViewModelProcessor()) + .withAdditionalKspProcessors(KspViewModelProcessor.Provider()) + .withProcessorOptions(ImmutableMap.of("dagger.hilt.enableAssistedInjectViewModels", "true")) + .compile { subject -> + subject.compilationDidFail() + subject.hasErrorCount(2) + subject.hasErrorContaining( + "The @AssistedFactory-annotated type is missing an abstract, non-default method whose return type matches the assisted injection type." + ) + subject.hasErrorContaining( + "Cannot find assisted factory method in dagger.hilt.android.test.MyFactory." + ) + } + } + + @Test + fun verifyAssistedFactoryHasOnlyOneMethod() { + val myViewModel = + Source.java( + "dagger.hilt.android.test.MyViewModel", + """ + package dagger.hilt.android.test; + + import dagger.assisted.Assisted; + import dagger.assisted.AssistedInject; + import androidx.lifecycle.ViewModel; + import dagger.hilt.android.lifecycle.HiltViewModel; + + @HiltViewModel(assistedFactory = MyFactory.class) + class MyViewModel extends ViewModel { + @AssistedInject + MyViewModel(String s, @Assisted int i) { } + } + """ + .trimIndent() + ) + val myFactory = + Source.java( + "dagger.hilt.android.test.MyFactory", + """ + package dagger.hilt.android.test; + import dagger.assisted.AssistedFactory; + @AssistedFactory + interface MyFactory { + MyViewModel create(int i); + String createString(int i); + Integer createInteger(int i); + } + """ + ) + + HiltCompilerTests.hiltCompiler(myViewModel, myFactory) + .withAdditionalJavacProcessors(ViewModelProcessor()) + .withAdditionalKspProcessors(KspViewModelProcessor.Provider()) + .withProcessorOptions(ImmutableMap.of("dagger.hilt.enableAssistedInjectViewModels", "true")) + .compile { subject -> + subject.compilationDidFail() + subject.hasErrorCount(4) + subject.hasErrorContaining( + "The @AssistedFactory-annotated type should contain a single abstract, non-default method but found multiple: [dagger.hilt.android.test.MyFactory.create(int), dagger.hilt.android.test.MyFactory.createString(int), dagger.hilt.android.test.MyFactory.createInteger(int)]" + ) + subject.hasErrorContaining( + "Invalid return type: java.lang.String. An assisted factory's abstract method must return a type with an @AssistedInject-annotated constructor." + ) + subject.hasErrorContaining( + "Invalid return type: java.lang.Integer. An assisted factory's abstract method must return a type with an @AssistedInject-annotated constructor." + ) + subject.hasErrorContaining( + "Cannot find assisted factory method in dagger.hilt.android.test.MyFactory." + ) + } + } + + @Test + fun verifyAssistedFactoryIsAnnotatedWithAssistedFactory() { + val myViewModel = + Source.java( + "dagger.hilt.android.test.MyViewModel", + """ + package dagger.hilt.android.test; + + import dagger.assisted.Assisted; + import dagger.assisted.AssistedInject; + import androidx.lifecycle.ViewModel; + import dagger.hilt.android.lifecycle.HiltViewModel; + + @HiltViewModel(assistedFactory = Integer.class) + class MyViewModel extends ViewModel { + @AssistedInject + MyViewModel(String s, @Assisted int i) { } + } + """ + .trimIndent() + ) + + HiltCompilerTests.hiltCompiler(myViewModel) + .withAdditionalJavacProcessors(ViewModelProcessor()) + .withAdditionalKspProcessors(KspViewModelProcessor.Provider()) + .withProcessorOptions(ImmutableMap.of("dagger.hilt.enableAssistedInjectViewModels", "true")) + .compile { subject -> + subject.compilationDidFail() + subject.hasErrorCount(1) + subject.hasErrorContaining( + "Class java.lang.Integer is not annotated with @AssistedFactory." + ) + } + } + + @Test + fun verifyFactoryMethodHasCorrectReturnType() { + val myViewModel = + Source.java( + "dagger.hilt.android.test.MyViewModel", + """ + package dagger.hilt.android.test; + + import dagger.assisted.Assisted; + import dagger.assisted.AssistedInject; + import androidx.lifecycle.ViewModel; + import dagger.hilt.android.lifecycle.HiltViewModel; + + @HiltViewModel(assistedFactory = MyFactory.class) + class MyViewModel extends ViewModel { + @AssistedInject + MyViewModel(String s, @Assisted int i) { } + } + """ + .trimIndent() + ) + val myFactory = + Source.java( + "dagger.hilt.android.test.MyFactory", + """ + package dagger.hilt.android.test; + import dagger.assisted.AssistedFactory; + @AssistedFactory + interface MyFactory { + String create(int i); + } + """ + ) + + HiltCompilerTests.hiltCompiler(myViewModel, myFactory) + .withAdditionalJavacProcessors(ViewModelProcessor()) + .withAdditionalKspProcessors(KspViewModelProcessor.Provider()) + .withProcessorOptions(ImmutableMap.of("dagger.hilt.enableAssistedInjectViewModels", "true")) + .compile { subject -> + subject.compilationDidFail() + subject.hasErrorCount(2) + subject.hasErrorContaining( + "Invalid return type: java.lang.String. An assisted factory's abstract method must return a type with an @AssistedInject-annotated constructor." + ) + subject.hasErrorContaining( + "Class dagger.hilt.android.test.MyFactory must have a factory method that returns a dagger.hilt.android.test.MyViewModel. Found java.lang.String." + ) + } + } + + @Test + fun verifyAssistedFactoryIsSpecified() { + val myViewModel = + Source.java( + "dagger.hilt.android.test.MyViewModel", + """ + package dagger.hilt.android.test; + + import dagger.assisted.Assisted; + import dagger.assisted.AssistedInject; + import androidx.lifecycle.ViewModel; + import dagger.hilt.android.lifecycle.HiltViewModel; + + @HiltViewModel + class MyViewModel extends ViewModel { + @AssistedInject + MyViewModel(String s, @Assisted int i) { } + } + """ + .trimIndent() + ) + val myFactory = + Source.java( + "dagger.hilt.android.test.MyFactory", + """ + package dagger.hilt.android.test; + import dagger.assisted.AssistedFactory; + @AssistedFactory + interface MyFactory { + MyViewModel create(int i); + } + """ + ) + + HiltCompilerTests.hiltCompiler(myViewModel, myFactory) + .withAdditionalJavacProcessors(ViewModelProcessor()) + .withAdditionalKspProcessors(KspViewModelProcessor.Provider()) + .withProcessorOptions(ImmutableMap.of("dagger.hilt.enableAssistedInjectViewModels", "true")) + .compile { subject -> + subject.compilationDidFail() + subject.hasErrorCount(1) + subject.hasErrorContaining( + "dagger.hilt.android.test.MyViewModel must have a valid assisted factory specified in @HiltViewModel when used with assisted injection. Found java.lang.Object." + ) + } + } + + @Test + fun verifyConstructorHasRightInjectAnnotation() { + val myViewModel = + Source.java( + "dagger.hilt.android.test.MyViewModel", + """ + package dagger.hilt.android.test; + + import dagger.assisted.Assisted; + import dagger.assisted.AssistedInject; + import androidx.lifecycle.ViewModel; + import dagger.hilt.android.lifecycle.HiltViewModel; + import javax.inject.Inject; + + @HiltViewModel(assistedFactory = MyFactory.class) + class MyViewModel extends ViewModel { + @Inject + MyViewModel(String s, int i) { } + } + """ + .trimIndent() + ) + val myFactory = + Source.java( + "dagger.hilt.android.test.MyFactory", + """ + package dagger.hilt.android.test; + import dagger.assisted.AssistedFactory; + @AssistedFactory + interface MyFactory { + MyViewModel create(int i); + } + """ + ) + + HiltCompilerTests.hiltCompiler(myViewModel, myFactory) + .withAdditionalJavacProcessors(ViewModelProcessor()) + .withAdditionalKspProcessors(KspViewModelProcessor.Provider()) + .withProcessorOptions(ImmutableMap.of("dagger.hilt.enableAssistedInjectViewModels", "true")) + .compile { subject -> + subject.compilationDidFail() + subject.hasErrorCount(2) + subject.hasErrorContaining( + "Invalid return type: dagger.hilt.android.test.MyViewModel. An assisted factory's abstract method must return a type with an @AssistedInject-annotated constructor." + ) + subject.hasErrorContaining( + "Found assisted factory dagger.hilt.android.test.MyFactory in @HiltViewModel but the constructor was annotated with @Inject instead of @AssistedInject." + ) + } + } } diff --git a/javatests/dagger/hilt/android/processor/internal/viewmodel/ViewModelValidationPluginTest.kt b/javatests/dagger/hilt/android/processor/internal/viewmodel/ViewModelValidationPluginTest.kt index 89a79bbb5..2bee9d5ec 100644 --- a/javatests/dagger/hilt/android/processor/internal/viewmodel/ViewModelValidationPluginTest.kt +++ b/javatests/dagger/hilt/android/processor/internal/viewmodel/ViewModelValidationPluginTest.kt @@ -16,22 +16,33 @@ package dagger.hilt.android.processor.internal.viewmodel -import com.google.testing.compile.CompilationSubject.assertThat -import com.google.testing.compile.Compiler -import dagger.hilt.android.testing.compile.HiltCompilerTests.compiler +import androidx.room.compiler.processing.ExperimentalProcessingApi +import androidx.room.compiler.processing.util.Source +import com.google.common.collect.ImmutableList +import dagger.hilt.android.testing.compile.HiltCompilerTests import dagger.internal.codegen.ComponentProcessor +import dagger.internal.codegen.KspComponentProcessor import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.JUnit4 +@ExperimentalProcessingApi @RunWith(JUnit4::class) class ViewModelValidationPluginTest { - private fun testCompiler(): Compiler = compiler( - ComponentProcessor.withTestPlugins(ViewModelValidationPlugin()), ViewModelProcessor() - ) + private fun testCompiler(vararg sources: Source): HiltCompilerTests.HiltCompiler = + HiltCompilerTests.hiltCompiler(ImmutableList.copyOf(sources)) + .withAdditionalJavacProcessors( + ComponentProcessor.withTestPlugins(ViewModelValidationPlugin()), + ViewModelProcessor() + ) + .withAdditionalKspProcessors( + KspComponentProcessor.Provider.withTestPlugins(ViewModelValidationPlugin()), + KspViewModelProcessor.Provider() + ) - private val hiltAndroidApp = """ + private val hiltAndroidApp = + """ package test; import android.app.Application; @@ -39,11 +50,13 @@ class ViewModelValidationPluginTest { @HiltAndroidApp(Application.class) public class TestApplication extends Hilt_TestApplication {} - """.toJFO("test.TestApplication") + """ + .toJFO("test.TestApplication") @Test fun injectViewModelIsProhibited() { - val hiltActivity = """ + val hiltActivity = + """ package test; import androidx.fragment.app.FragmentActivity; @@ -54,8 +67,10 @@ class ViewModelValidationPluginTest { public class TestActivity extends Hilt_TestActivity { @Inject Foo foo; } - """.toJFO("test.TestActivity") - val hiltViewModel = """ + """ + .toJFO("test.TestActivity") + val hiltViewModel = + """ package test; import androidx.lifecycle.ViewModel; @@ -66,8 +81,10 @@ class ViewModelValidationPluginTest { class MyViewModel extends ViewModel { @Inject MyViewModel() { } } - """.toJFO("test.MyViewModel") - val foo = """ + """ + .toJFO("test.MyViewModel") + val foo = + """ package test; import javax.inject.Inject; @@ -75,21 +92,20 @@ class ViewModelValidationPluginTest { final class Foo { @Inject Foo(MyViewModel viewModel) {} } - """.toJFO("test.Foo") - - val compilation = testCompiler().compile(foo, hiltViewModel, hiltAndroidApp, hiltActivity) - assertThat(compilation).apply { - failed() - hadErrorCount(1) - hadErrorContainingMatch( - "Injection of an @HiltViewModel class is prohibited" - ) + """ + .toJFO("test.Foo") + + testCompiler(foo, hiltViewModel, hiltAndroidApp, hiltActivity).compile() { subject -> + subject.compilationDidFail() + subject.hasErrorCount(1) + subject.hasErrorContaining("Injection of an @HiltViewModel class is prohibited") } } @Test fun fieldInjectedViewModelIsProhibited() { - val hiltActivity = """ + val hiltActivity = + """ package test; import androidx.fragment.app.FragmentActivity; @@ -100,8 +116,10 @@ class ViewModelValidationPluginTest { public class TestActivity extends Hilt_TestActivity { @Inject MyViewModel viewModel; } - """.toJFO("test.TestActivity") - val hiltViewModel = """ + """ + .toJFO("test.TestActivity") + val hiltViewModel = + """ package test; import androidx.lifecycle.ViewModel; @@ -112,22 +130,21 @@ class ViewModelValidationPluginTest { class MyViewModel extends ViewModel { @Inject MyViewModel() { } } - """.toJFO("test.MyViewModel") - - val compilation = testCompiler().compile(hiltViewModel, hiltAndroidApp, hiltActivity) - assertThat(compilation).apply { - failed() - hadErrorCount(1) - hadErrorContainingMatch( - "Injection of an @HiltViewModel class is prohibited" - ) + """ + .toJFO("test.MyViewModel") + + testCompiler(hiltViewModel, hiltAndroidApp, hiltActivity).compile() { subject -> + subject.compilationDidFail() + subject.hasErrorCount(1) + subject.hasErrorContaining("Injection of an @HiltViewModel class is prohibited") } } @Test fun injectViewModelFromViewModelComponentIsProhibited() { // Use an @HiltViewModel that injects a Foo to get the binding inside the ViewModelComponent - val hiltViewModel = """ + val hiltViewModel = + """ package test; import androidx.lifecycle.ViewModel; @@ -138,9 +155,11 @@ class ViewModelValidationPluginTest { class MyViewModel extends ViewModel { @Inject MyViewModel(Foo foo) { } } - """.toJFO("test.MyViewModel") + """ + .toJFO("test.MyViewModel") - val foo = """ + val foo = + """ package test; import javax.inject.Inject; @@ -149,21 +168,20 @@ class ViewModelValidationPluginTest { final class Foo { @Inject Foo(Provider<MyViewModel> viewModelProvider) {} } - """.toJFO("test.Foo") - - val compilation = testCompiler().compile(foo, hiltViewModel, hiltAndroidApp) - assertThat(compilation).apply { - failed() - hadErrorCount(1) - hadErrorContainingMatch( - "Injection of an @HiltViewModel class is prohibited" - ) + """ + .toJFO("test.Foo") + + testCompiler(foo, hiltViewModel, hiltAndroidApp).compile() { subject -> + subject.compilationDidFail() + subject.hasErrorCount(1) + subject.hasErrorContaining("Injection of an @HiltViewModel class is prohibited") } } @Test fun injectOverriddenViewModelBindingIsAllowed() { - val hiltActivity = """ + val hiltActivity = + """ package test; import androidx.fragment.app.FragmentActivity; @@ -174,8 +192,10 @@ class ViewModelValidationPluginTest { public class TestActivity extends Hilt_TestActivity { @Inject Foo foo; } - """.toJFO("test.TestActivity") - val hiltViewModel = """ + """ + .toJFO("test.TestActivity") + val hiltViewModel = + """ package test; import androidx.lifecycle.ViewModel; @@ -186,8 +206,10 @@ class ViewModelValidationPluginTest { class MyViewModel extends ViewModel { @Inject MyViewModel() { } } - """.toJFO("test.MyViewModel") - val foo = """ + """ + .toJFO("test.MyViewModel") + val foo = + """ package test; import javax.inject.Inject; @@ -195,8 +217,10 @@ class ViewModelValidationPluginTest { final class Foo { @Inject Foo(MyViewModel viewModel) {} } - """.toJFO("test.Foo") - val activityModule = """ + """ + .toJFO("test.Foo") + val activityModule = + """ package test; import dagger.Module; @@ -214,17 +238,19 @@ class ViewModelValidationPluginTest { return null; } } - """.toJFO("test.ActivityModule") + """ + .toJFO("test.ActivityModule") - val compilation = testCompiler().compile( - foo, activityModule, hiltViewModel, hiltAndroidApp, hiltActivity - ) - assertThat(compilation).succeeded() + testCompiler(foo, activityModule, hiltViewModel, hiltAndroidApp, hiltActivity).compile() { + subject -> + subject.hasErrorCount(0) + } } @Test fun injectQualifiedViewModelBindingIsAllowed() { - val hiltActivity = """ + val hiltActivity = + """ package test; import androidx.fragment.app.FragmentActivity; @@ -235,8 +261,10 @@ class ViewModelValidationPluginTest { public class TestActivity extends Hilt_TestActivity { @Inject Foo foo; } - """.toJFO("test.TestActivity") - val hiltViewModel = """ + """ + .toJFO("test.TestActivity") + val hiltViewModel = + """ package test; import androidx.lifecycle.ViewModel; @@ -247,8 +275,10 @@ class ViewModelValidationPluginTest { class MyViewModel extends ViewModel { @Inject MyViewModel() { } } - """.toJFO("test.MyViewModel") - val foo = """ + """ + .toJFO("test.MyViewModel") + val foo = + """ package test; import javax.inject.Inject; @@ -256,8 +286,10 @@ class ViewModelValidationPluginTest { final class Foo { @Inject Foo(@ActivityModule.MyQualifier MyViewModel viewModel) {} } - """.toJFO("test.Foo") - val activityModule = """ + """ + .toJFO("test.Foo") + val activityModule = + """ package test; import dagger.Module; @@ -281,18 +313,20 @@ class ViewModelValidationPluginTest { return null; } } - """.toJFO("test.ActivityModule") + """ + .toJFO("test.ActivityModule") - val compilation = testCompiler().compile( - foo, activityModule, hiltViewModel, hiltAndroidApp, hiltActivity - ) - assertThat(compilation).succeeded() + testCompiler(foo, activityModule, hiltViewModel, hiltAndroidApp, hiltActivity).compile() { + subject -> + subject.hasErrorCount(0) + } } // Regression test for not handling array types properly @Test fun correctlyAllowsOtherBindings() { - val hiltActivity = """ + val hiltActivity = + """ package test; import androidx.fragment.app.FragmentActivity; @@ -303,8 +337,10 @@ class ViewModelValidationPluginTest { public class TestActivity extends Hilt_TestActivity { @Inject Foo foo; } - """.toJFO("test.TestActivity") - val hiltViewModel = """ + """ + .toJFO("test.TestActivity") + val hiltViewModel = + """ package test; import androidx.lifecycle.ViewModel; @@ -315,8 +351,10 @@ class ViewModelValidationPluginTest { class MyViewModel extends ViewModel { @Inject MyViewModel() { } } - """.toJFO("test.MyViewModel") - val foo = """ + """ + .toJFO("test.MyViewModel") + val foo = + """ package test; import javax.inject.Inject; @@ -324,8 +362,10 @@ class ViewModelValidationPluginTest { final class Foo { @Inject Foo(Long[] longArray) {} } - """.toJFO("test.Foo") - val activityModule = """ + """ + .toJFO("test.Foo") + val activityModule = + """ package test; import dagger.Module; @@ -341,11 +381,12 @@ class ViewModelValidationPluginTest { return null; } } - """.toJFO("test.ActivityModule") + """ + .toJFO("test.ActivityModule") - val compilation = testCompiler().compile( - foo, activityModule, hiltViewModel, hiltAndroidApp, hiltActivity - ) - assertThat(compilation).succeeded() + testCompiler(foo, activityModule, hiltViewModel, hiltAndroidApp, hiltActivity).compile() { + subject -> + subject.hasErrorCount(0) + } } } diff --git a/javatests/dagger/hilt/android/processor/internal/viewmodel/ViewModelValidationPluginWithAssistedInjectTest.kt b/javatests/dagger/hilt/android/processor/internal/viewmodel/ViewModelValidationPluginWithAssistedInjectTest.kt new file mode 100644 index 000000000..f8f04fe77 --- /dev/null +++ b/javatests/dagger/hilt/android/processor/internal/viewmodel/ViewModelValidationPluginWithAssistedInjectTest.kt @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2023 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.android.processor.internal.viewmodel + +import androidx.room.compiler.processing.ExperimentalProcessingApi +import androidx.room.compiler.processing.util.Source +import com.google.common.collect.ImmutableList +import com.google.common.collect.ImmutableMap +import dagger.hilt.android.testing.compile.HiltCompilerTests +import dagger.internal.codegen.ComponentProcessor +import dagger.internal.codegen.KspComponentProcessor +import dagger.testing.compile.CompilerTests.* +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +@ExperimentalProcessingApi +@RunWith(JUnit4::class) +class ViewModelValidationPluginWithAssistedInjectTest { + + private fun testCompiler(vararg sources: Source): HiltCompilerTests.HiltCompiler = + HiltCompilerTests.hiltCompiler(ImmutableList.copyOf(sources)) + .withAdditionalJavacProcessors( + ComponentProcessor.withTestPlugins(ViewModelValidationPlugin()), + ViewModelProcessor() + ) + .withAdditionalKspProcessors( + KspComponentProcessor.Provider.withTestPlugins(ViewModelValidationPlugin()), + KspViewModelProcessor.Provider() + ) + .withProcessorOptions(ImmutableMap.of("dagger.hilt.enableAssistedInjectViewModels", "true")) + + private val hiltAndroidApp = + """ + package dagger.hilt.android.test; + + import android.app.Application; + import dagger.hilt.android.HiltAndroidApp; + + @HiltAndroidApp(Application.class) + public class TestApplication extends Hilt_TestApplication {} + """ + .toJFO("dagger.hilt.android.test.TestApplication") + + @Test + fun injectViewModelAssistedFactoryProhibited() { + val hiltActivity = + """ + package dagger.hilt.android.test; + + import androidx.fragment.app.FragmentActivity; + import dagger.hilt.android.AndroidEntryPoint; + import javax.inject.Inject; + + @AndroidEntryPoint(FragmentActivity.class) + public class TestActivity extends Hilt_TestActivity { + @Inject Foo foo; + } + """ + .toJFO("dagger.hilt.android.test.TestActivity") + val hiltViewModel = + """ + package dagger.hilt.android.test; + + import androidx.lifecycle.ViewModel; + import dagger.assisted.Assisted; + import dagger.assisted.AssistedFactory; + import dagger.assisted.AssistedInject; + import dagger.hilt.android.lifecycle.HiltViewModel; + import javax.inject.Inject; + + @HiltViewModel(assistedFactory = MyViewModel.Factory.class) + class MyViewModel extends ViewModel { + @AssistedInject MyViewModel(@Assisted String s) { } + @AssistedFactory interface Factory { + MyViewModel create(String s); + } + } + """ + .toJFO("dagger.hilt.android.test.MyViewModel") + val foo = + """ + package dagger.hilt.android.test; + + import javax.inject.Inject; + + final class Foo { + @Inject Foo(MyViewModel.Factory factory) {} + } + """ + .toJFO("dagger.hilt.android.test.Foo") + + testCompiler(foo, hiltViewModel, hiltAndroidApp, hiltActivity).compile { subject -> + subject.compilationDidFail() + subject.hasErrorCount(1) + subject.hasErrorContaining( + "Injection of an assisted factory for Hilt ViewModel is prohibited since it can not be " + + "used to create a ViewModel instance correctly.\n" + + "Access the ViewModel via the Android APIs (e.g. ViewModelProvider) instead.\n" + + "Injected factory: dagger.hilt.android.test.MyViewModel.Factory" + ) + } + } + + @Test + fun fieldInjectViewModelAssistedFactoryProhibited() { + val hiltActivity = + """ + package dagger.hilt.android.test; + + import androidx.fragment.app.FragmentActivity; + import dagger.hilt.android.AndroidEntryPoint; + import javax.inject.Inject; + + @AndroidEntryPoint(FragmentActivity.class) + public class TestActivity extends Hilt_TestActivity { + @Inject MyViewModel.Factory factory; + } + """ + .toJFO("dagger.hilt.android.test.TestActivity") + val hiltViewModel = + """ + package dagger.hilt.android.test; + + import androidx.lifecycle.ViewModel; + import dagger.assisted.Assisted; + import dagger.assisted.AssistedFactory; + import dagger.assisted.AssistedInject; + import dagger.hilt.android.lifecycle.HiltViewModel; + import javax.inject.Inject; + + @HiltViewModel(assistedFactory = MyViewModel.Factory.class) + class MyViewModel extends ViewModel { + @AssistedInject MyViewModel(@Assisted String s) { } + @AssistedFactory interface Factory { + MyViewModel create(String s); + } + } + """ + .toJFO("dagger.hilt.android.test.MyViewModel") + + testCompiler(hiltViewModel, hiltAndroidApp, hiltActivity).compile { subject -> + subject.compilationDidFail() + subject.hasErrorCount(1) + subject.hasErrorContaining( + "Injection of an assisted factory for Hilt ViewModel is prohibited since it can not be " + + "used to create a ViewModel instance correctly.\n" + + "Access the ViewModel via the Android APIs (e.g. ViewModelProvider) instead.\n" + + "Injected factory: dagger.hilt.android.test.MyViewModel.Factory" + ) + } + } + + @Test + fun injectGenericViewModelAssistedFactoryProhibited() { + val hiltActivity = + """ + package dagger.hilt.android.test; + + import androidx.fragment.app.FragmentActivity; + import dagger.hilt.android.AndroidEntryPoint; + import javax.inject.Inject; + + @AndroidEntryPoint(FragmentActivity.class) + public class TestActivity extends Hilt_TestActivity { + @Inject MyViewModel.Factory factory; + } + """ + .toJFO("dagger.hilt.android.test.TestActivity") + val hiltViewModel = + """ + package dagger.hilt.android.test; + + import androidx.lifecycle.ViewModel; + import dagger.assisted.Assisted; + import dagger.assisted.AssistedFactory; + import dagger.assisted.AssistedInject; + import dagger.hilt.android.lifecycle.HiltViewModel; + import javax.inject.Inject; + + @HiltViewModel(assistedFactory = MyViewModel.Factory.class) + class MyViewModel extends ViewModel { + @AssistedInject MyViewModel(@Assisted String s) { } + interface SingleAssistedFactory<A, T> { + T create(A a); + } + @AssistedFactory interface Factory extends SingleAssistedFactory<String, MyViewModel> {} + } + """ + .toJFO("dagger.hilt.android.test.MyViewModel") + + testCompiler(hiltViewModel, hiltAndroidApp, hiltActivity).compile { subject -> + subject.compilationDidFail() + subject.hasErrorCount(1) + subject.hasErrorContaining( + "Injection of an assisted factory for Hilt ViewModel is prohibited since it can not be " + + "used to create a ViewModel instance correctly.\n" + + "Access the ViewModel via the Android APIs (e.g. ViewModelProvider) instead.\n" + + "Injected factory: dagger.hilt.android.test.MyViewModel.Factory" + ) + } + } +} diff --git a/javatests/dagger/hilt/android/testing/BUILD b/javatests/dagger/hilt/android/testing/BUILD index 7dc1e48cf..973161087 100644 --- a/javatests/dagger/hilt/android/testing/BUILD +++ b/javatests/dagger/hilt/android/testing/BUILD @@ -158,3 +158,37 @@ android_local_test( "//third_party/java/truth", ], ) + +android_local_test( + name = "SkipTestInjectionTest", + srcs = ["SkipTestInjectionTest.java"], + manifest_values = { + "minSdkVersion": "15", + "targetSdkVersion": "27", + }, + deps = [ + "//:android_local_test_exports", + "//:dagger_with_compiler", + "//java/dagger/hilt/android/testing:hilt_android_test", + "//java/dagger/hilt/android/testing:skip_test_injection", + "//third_party/java/jsr330_inject", + "//third_party/java/truth", + ], +) + +android_local_test( + name = "SkipTestInjectionAnnotationTest", + srcs = ["SkipTestInjectionAnnotationTest.java"], + manifest_values = { + "minSdkVersion": "15", + "targetSdkVersion": "27", + }, + deps = [ + "//:android_local_test_exports", + "//:dagger_with_compiler", + "//java/dagger/hilt/android/testing:hilt_android_test", + "//java/dagger/hilt/android/testing:skip_test_injection", + "//third_party/java/jsr330_inject", + "//third_party/java/truth", + ], +) diff --git a/javatests/dagger/hilt/android/testing/SkipTestInjectionAnnotationTest.java b/javatests/dagger/hilt/android/testing/SkipTestInjectionAnnotationTest.java new file mode 100644 index 000000000..60d2bb367 --- /dev/null +++ b/javatests/dagger/hilt/android/testing/SkipTestInjectionAnnotationTest.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2024 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.android.testing; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import javax.inject.Inject; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +@HiltAndroidTest +@SkipTestInjectionAnnotationTest.TestAnnotation +@RunWith(AndroidJUnit4.class) +@Config(application = HiltTestApplication.class) +public final class SkipTestInjectionAnnotationTest { + @Rule public final HiltAndroidRule rule = new HiltAndroidRule(this); + + @SkipTestInjection + @interface TestAnnotation {} + + @Inject String string; // Never provided, shouldn't compile without @SkipTestInjection + + @Test + public void testCannotCallInjectOnTestRule() throws Exception { + IllegalStateException exception = + assertThrows( + IllegalStateException.class, + () -> rule.inject()); + assertThat(exception) + .hasMessageThat() + .isEqualTo("Cannot inject test when using @TestAnnotation"); + } +} diff --git a/javatests/dagger/hilt/android/testing/SkipTestInjectionTest.java b/javatests/dagger/hilt/android/testing/SkipTestInjectionTest.java new file mode 100644 index 000000000..bf4124ce2 --- /dev/null +++ b/javatests/dagger/hilt/android/testing/SkipTestInjectionTest.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2024 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.android.testing; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import javax.inject.Inject; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +@HiltAndroidTest +@SkipTestInjection +@RunWith(AndroidJUnit4.class) +@Config(application = HiltTestApplication.class) +public final class SkipTestInjectionTest { + @Rule public final HiltAndroidRule rule = new HiltAndroidRule(this); + + @Inject String string; // Never provided, shouldn't compile without @SkipTestInjection + + @Test + public void testCannotCallInjectOnTestRule() throws Exception { + IllegalStateException exception = + assertThrows( + IllegalStateException.class, + () -> rule.inject()); + assertThat(exception) + .hasMessageThat() + .isEqualTo("Cannot inject test when using @SkipTestInjection"); + } +} diff --git a/javatests/dagger/hilt/processor/internal/aliasof/AliasOfProcessorTest.java b/javatests/dagger/hilt/processor/internal/aliasof/AliasOfProcessorTest.java index 0654e3425..d326f11ca 100644 --- a/javatests/dagger/hilt/processor/internal/aliasof/AliasOfProcessorTest.java +++ b/javatests/dagger/hilt/processor/internal/aliasof/AliasOfProcessorTest.java @@ -16,15 +16,11 @@ package dagger.hilt.processor.internal.aliasof; -import static com.google.testing.compile.CompilationSubject.assertThat; -import static dagger.hilt.android.testing.compile.HiltCompilerTests.compiler; - import androidx.room.compiler.processing.util.Source; -import com.google.testing.compile.Compilation; -import com.google.testing.compile.JavaFileObjects; import dagger.hilt.android.testing.compile.HiltCompilerTests; -import javax.tools.JavaFileObject; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -33,8 +29,8 @@ import org.junit.runners.JUnit4; public final class AliasOfProcessorTest { @Test public void fails_componentScopedWithAliasScope() { - JavaFileObject scope = - JavaFileObjects.forSourceLines( + Source scope = + HiltCompilerTests.javaSource( "test.AliasScope", "package test;", "", @@ -46,8 +42,8 @@ public final class AliasOfProcessorTest { "@AliasOf(Singleton.class)", "public @interface AliasScope{}"); - JavaFileObject root = - JavaFileObjects.forSourceLines( + Source root = + HiltCompilerTests.javaSource( "test.MyApp", "package test;", "", @@ -57,8 +53,8 @@ public final class AliasOfProcessorTest { "@HiltAndroidApp(Application.class)", "public final class MyApp extends Hilt_MyApp {}"); - JavaFileObject defineComponent = - JavaFileObjects.forSourceLines( + Source defineComponent = + HiltCompilerTests.javaSource( "test.ChildComponent", "package test;", "", @@ -69,17 +65,20 @@ public final class AliasOfProcessorTest { "@AliasScope", "public interface ChildComponent {}"); - Compilation compilation = - compiler() - .withOptions("-Xlint:-processing") // Suppresses unclaimed annotation warning - .compile(root, defineComponent, scope); - - assertThat(compilation).failed(); - assertThat(compilation) - .hadErrorContaining( - "@DefineComponent test.ChildComponent, references invalid scope(s) annotated with" - + " @AliasOf. @DefineComponent scopes cannot be aliases of other scopes:" - + " [@test.AliasScope]"); + HiltCompilerTests.hiltCompiler(root, defineComponent, scope) + .withJavacArguments("-Xlint:-processing") // Suppresses unclaimed annotation warning + .compile( + subject -> + // TODO(user): TAP result inconsistent with local build. + // if (HiltCompilerTests.backend(subject) == Backend.JAVAC) { + // subject.hasErrorCount(2); + // } else { + // subject.hasErrorCount(1); + // } + subject.hasErrorContaining( + "@DefineComponent test.ChildComponent, references invalid scope(s) annotated" + + " with @AliasOf. @DefineComponent scopes cannot be aliases of other scopes:" + + " [@test.AliasScope]")); } @Test @@ -106,10 +105,12 @@ public final class AliasOfProcessorTest { }); } + @Rule public TemporaryFolder tempFolderRule = new TemporaryFolder(); + @Test public void fails_conflictingAliasScope() { - JavaFileObject scope = - JavaFileObjects.forSourceLines( + Source scope = + HiltCompilerTests.javaSource( "test.AliasScope", "package test;", "", @@ -122,8 +123,8 @@ public final class AliasOfProcessorTest { "@AliasOf({Singleton.class, ActivityScoped.class})", "public @interface AliasScope{}"); - JavaFileObject root = - JavaFileObjects.forSourceLines( + Source root = + HiltCompilerTests.javaSource( "test.MyApp", "package test;", "", @@ -133,13 +134,11 @@ public final class AliasOfProcessorTest { "@HiltAndroidApp(Application.class)", "public final class MyApp extends Hilt_MyApp {}"); - Compilation compilation = - compiler() - .withOptions("-Xlint:-processing") // Suppresses unclaimed annotation warning - .compile(root, scope); - - assertThat(compilation).failed(); - assertThat(compilation).hadErrorCount(1); - assertThat(compilation).hadErrorContaining("has conflicting scopes"); + HiltCompilerTests.hiltCompiler(root, scope) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining("has conflicting scopes"); + }); } } diff --git a/javatests/dagger/hilt/processor/internal/aliasof/BUILD b/javatests/dagger/hilt/processor/internal/aliasof/BUILD index bc7874f85..a56e14061 100644 --- a/javatests/dagger/hilt/processor/internal/aliasof/BUILD +++ b/javatests/dagger/hilt/processor/internal/aliasof/BUILD @@ -34,7 +34,6 @@ compiler_test( deps = [ "//java/dagger/hilt/android/testing/compile", "//java/dagger/internal/codegen/xprocessing:xprocessing-testing", - "//third_party/java/compile_testing", "//third_party/java/junit", ], ) diff --git a/javatests/dagger/hilt/processor/internal/root/BUILD b/javatests/dagger/hilt/processor/internal/root/BUILD index 0da11f155..bdc69dc51 100644 --- a/javatests/dagger/hilt/processor/internal/root/BUILD +++ b/javatests/dagger/hilt/processor/internal/root/BUILD @@ -114,8 +114,9 @@ compiler_test( ], deps = [ "//java/dagger/hilt/android/testing/compile", - "//third_party/java/compile_testing", + "//java/dagger/internal/codegen/xprocessing:xprocessing-testing", "//third_party/java/guava/base", + "//third_party/java/guava/collect", "//third_party/java/junit", "//third_party/java/truth", ], diff --git a/javatests/dagger/hilt/processor/internal/root/RootFileFormatterTest.java b/javatests/dagger/hilt/processor/internal/root/RootFileFormatterTest.java index 2a946b748..751f74d0c 100644 --- a/javatests/dagger/hilt/processor/internal/root/RootFileFormatterTest.java +++ b/javatests/dagger/hilt/processor/internal/root/RootFileFormatterTest.java @@ -16,13 +16,11 @@ package dagger.hilt.processor.internal.root; -import static com.google.testing.compile.CompilationSubject.assertThat; -import static dagger.hilt.android.testing.compile.HiltCompilerTests.compiler; - +import androidx.room.compiler.processing.util.Source; import com.google.common.base.Joiner; -import com.google.testing.compile.Compilation; -import com.google.testing.compile.JavaFileObjects; -import javax.tools.JavaFileObject; +import com.google.common.collect.ImmutableMap; +import com.google.common.truth.StringSubject; +import dagger.hilt.android.testing.compile.HiltCompilerTests; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -34,141 +32,138 @@ public final class RootFileFormatterTest { @Test public void testProdComponents() { - Compilation compilation = - compiler() - .compile( - JavaFileObjects.forSourceLines( - "test.TestApplication", - "package test;", - "", - "import android.app.Application;", - "import dagger.hilt.android.HiltAndroidApp;", - "", - "@HiltAndroidApp(Application.class)", - "public class TestApplication extends Hilt_TestApplication {}"), - entryPoint("SingletonComponent", "EntryPoint1"), - entryPoint("SingletonComponent", "EntryPoint2"), - entryPoint("ActivityComponent", "EntryPoint3"), - entryPoint("ActivityComponent", "EntryPoint4")); - assertThat(compilation).succeeded(); - assertThat(compilation) - .generatedSourceFile("test/TestApplication_HiltComponents") - .contentsAsUtf8String() - .contains( - JOINER.join( - " public abstract static class SingletonC implements" - + " HiltWrapper_ActivityRetainedComponentManager" - + "_ActivityRetainedComponentBuilderEntryPoint,", - " ServiceComponentManager.ServiceComponentBuilderEntryPoint,", - " SingletonComponent,", - " GeneratedComponent,", - " EntryPoint1,", - " EntryPoint2,", - " TestApplication_GeneratedInjector {")); - - assertThat(compilation) - .generatedSourceFile("test/TestApplication_HiltComponents") - .contentsAsUtf8String() - .contains( - JOINER.join( - " public abstract static class ActivityC implements ActivityComponent,", - " DefaultViewModelFactories.ActivityEntryPoint,", - " HiltWrapper_HiltViewModelFactory_ActivityCreatorEntryPoint,", - " FragmentComponentManager.FragmentComponentBuilderEntryPoint,", - " ViewComponentManager.ViewComponentBuilderEntryPoint,", - " GeneratedComponent,", - " EntryPoint3,", - " EntryPoint4 {")); + HiltCompilerTests.hiltCompiler( + HiltCompilerTests.javaSource( + "test.TestApplication", + "package test;", + "", + "import android.app.Application;", + "import dagger.hilt.android.HiltAndroidApp;", + "", + "@HiltAndroidApp(Application.class)", + "public class TestApplication extends Hilt_TestApplication {}"), + entryPoint("SingletonComponent", "EntryPoint1"), + entryPoint("SingletonComponent", "EntryPoint2"), + entryPoint("ActivityComponent", "EntryPoint3"), + entryPoint("ActivityComponent", "EntryPoint4")) + .compile( + subject -> { + subject.hasErrorCount(0); + StringSubject stringSubject = + subject.generatedSourceFileWithPath("test/TestApplication_HiltComponents.java"); + stringSubject.contains( + JOINER.join( + " public abstract static class SingletonC implements" + + " HiltWrapper_ActivityRetainedComponentManager" + + "_ActivityRetainedComponentBuilderEntryPoint,", + " ServiceComponentManager.ServiceComponentBuilderEntryPoint,", + " SingletonComponent,", + " GeneratedComponent,", + " EntryPoint1,", + " EntryPoint2,", + " TestApplication_GeneratedInjector {")); + stringSubject.contains( + JOINER.join( + " public abstract static class ActivityC implements ActivityComponent,", + " DefaultViewModelFactories.ActivityEntryPoint,", + " HiltWrapper_HiltViewModelFactory_ActivityCreatorEntryPoint,", + " FragmentComponentManager.FragmentComponentBuilderEntryPoint,", + " ViewComponentManager.ViewComponentBuilderEntryPoint,", + " GeneratedComponent,", + " EntryPoint3,", + " EntryPoint4 {")); + }); } @Test public void testTestComponents() { - Compilation compilation = - compiler() - .withOptions("-Adagger.hilt.shareTestComponents=false") - .compile( - JavaFileObjects.forSourceLines( - "test.MyTest", - "package test;", - "", - "import dagger.hilt.android.testing.HiltAndroidTest;", - "", - "@HiltAndroidTest", - "public class MyTest {}"), - entryPoint("SingletonComponent", "EntryPoint1"), - entryPoint("SingletonComponent", "EntryPoint2"), - entryPoint("ActivityComponent", "EntryPoint3"), - entryPoint("ActivityComponent", "EntryPoint4")); - assertThat(compilation).succeeded(); - assertThat(compilation) - .generatedSourceFile("test/MyTest_HiltComponents") - .contentsAsUtf8String() - .contains( - JOINER.join( - " public abstract static class SingletonC implements" - + " HiltWrapper_ActivityRetainedComponentManager" - + "_ActivityRetainedComponentBuilderEntryPoint,", - " ServiceComponentManager.ServiceComponentBuilderEntryPoint,", - " SingletonComponent,", - " TestSingletonComponent,", - " EntryPoint1,", - " EntryPoint2,", - " MyTest_GeneratedInjector {")); + HiltCompilerTests.hiltCompiler( + HiltCompilerTests.javaSource( + "test.MyTest", + "package test;", + "", + "import dagger.hilt.android.testing.HiltAndroidTest;", + "", + "@HiltAndroidTest", + "public class MyTest {}"), + entryPoint("SingletonComponent", "EntryPoint1"), + entryPoint("SingletonComponent", "EntryPoint2"), + entryPoint("ActivityComponent", "EntryPoint3"), + entryPoint("ActivityComponent", "EntryPoint4")) + .withProcessorOptions( + ImmutableMap.of("dagger.hilt.shareTestComponents", Boolean.toString(false))) + .compile( + subject -> { + subject.hasErrorCount(0); + StringSubject stringSubject = + subject.generatedSourceFileWithPath("test/MyTest_HiltComponents.java"); + stringSubject.contains( + JOINER.join( + " public abstract static class SingletonC implements" + + " HiltWrapper_ActivityRetainedComponentManager" + + "_ActivityRetainedComponentBuilderEntryPoint,", + " ServiceComponentManager.ServiceComponentBuilderEntryPoint,", + " SingletonComponent,", + " TestSingletonComponent,", + " EntryPoint1,", + " EntryPoint2,", + " MyTest_GeneratedInjector {")); - assertThat(compilation) - .generatedSourceFile("test/MyTest_HiltComponents") - .contentsAsUtf8String() - .contains( - JOINER.join( - " public abstract static class ActivityC implements ActivityComponent,", - " DefaultViewModelFactories.ActivityEntryPoint,", - " HiltWrapper_HiltViewModelFactory_ActivityCreatorEntryPoint,", - " FragmentComponentManager.FragmentComponentBuilderEntryPoint,", - " ViewComponentManager.ViewComponentBuilderEntryPoint,", - " GeneratedComponent,", - " EntryPoint3,", - " EntryPoint4 {")); + stringSubject.contains( + JOINER.join( + " public abstract static class ActivityC implements ActivityComponent,", + " DefaultViewModelFactories.ActivityEntryPoint,", + " HiltWrapper_HiltViewModelFactory_ActivityCreatorEntryPoint,", + " FragmentComponentManager.FragmentComponentBuilderEntryPoint,", + " ViewComponentManager.ViewComponentBuilderEntryPoint,", + " GeneratedComponent,", + " EntryPoint3,", + " EntryPoint4 {")); + }); } @Test public void testSharedTestComponents() { - Compilation compilation = - compiler() - .withOptions("-Adagger.hilt.shareTestComponents=true") - .compile( - JavaFileObjects.forSourceLines( - "test.MyTest", - "package test;", - "", - "import dagger.hilt.android.testing.HiltAndroidTest;", - "", - "@HiltAndroidTest", - "public class MyTest {}"), - entryPoint("SingletonComponent", "EntryPoint1")); - assertThat(compilation).succeeded(); - assertThat(compilation) - .generatedSourceFile("dagger/hilt/android/internal/testing/root/Default_HiltComponents") - .contentsAsUtf8String() - .contains( - JOINER.join( - " public abstract static class SingletonC implements" - + " HiltWrapper_ActivityRetainedComponentManager" - + "_ActivityRetainedComponentBuilderEntryPoint,", - " ServiceComponentManager.ServiceComponentBuilderEntryPoint,", - " SingletonComponent,", - " TestSingletonComponent,", - " EntryPoint1,", - " MyTest_GeneratedInjector {")); + HiltCompilerTests.hiltCompiler( + HiltCompilerTests.javaSource( + "test.MyTest", + "package test;", + "", + "import dagger.hilt.android.testing.HiltAndroidTest;", + "", + "@HiltAndroidTest", + "public class MyTest {}"), + entryPoint("SingletonComponent", "EntryPoint1")) + .withProcessorOptions( + ImmutableMap.of("dagger.hilt.shareTestComponents", Boolean.toString(true))) + .compile( + subject -> { + subject.hasErrorCount(0); + StringSubject stringSubject = + subject.generatedSourceFileWithPath( + "dagger/hilt/android/internal/testing/root/Default_HiltComponents.java"); + stringSubject.contains( + JOINER.join( + " public abstract static class SingletonC implements" + + " HiltWrapper_ActivityRetainedComponentManager" + + "_ActivityRetainedComponentBuilderEntryPoint,", + " ServiceComponentManager.ServiceComponentBuilderEntryPoint,", + " SingletonComponent,", + " TestSingletonComponent,", + " EntryPoint1,", + " MyTest_GeneratedInjector {")); + }); } - private static JavaFileObject entryPoint(String component, String name) { - return JavaFileObjects.forSourceLines( + private static Source entryPoint(String component, String name) { + return HiltCompilerTests.javaSource( "test." + name, "package test;", "", "import dagger.hilt.EntryPoint;", "import dagger.hilt.InstallIn;", - component.equals("SingletonComponent") ? "import dagger.hilt.components.SingletonComponent;" + component.equals("SingletonComponent") + ? "import dagger.hilt.components.SingletonComponent;" : "import dagger.hilt.android.components." + component + ";", "", "@EntryPoint", diff --git a/javatests/dagger/internal/DoubleCheckTest.java b/javatests/dagger/internal/DoubleCheckTest.java index e36c1bcee..6bf220d36 100644 --- a/javatests/dagger/internal/DoubleCheckTest.java +++ b/javatests/dagger/internal/DoubleCheckTest.java @@ -32,7 +32,6 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; -import javax.inject.Provider; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/javatests/dagger/internal/MapProviderFactoryTest.java b/javatests/dagger/internal/MapProviderFactoryTest.java index c55bee3ab..e64df8dad 100644 --- a/javatests/dagger/internal/MapProviderFactoryTest.java +++ b/javatests/dagger/internal/MapProviderFactoryTest.java @@ -21,7 +21,6 @@ import static com.google.common.truth.Truth.assertThat; import java.util.LinkedHashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; -import javax.inject.Provider; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; diff --git a/javatests/dagger/internal/SetFactoryTest.java b/javatests/dagger/internal/SetFactoryTest.java index 0032578c6..5e109ddb6 100644 --- a/javatests/dagger/internal/SetFactoryTest.java +++ b/javatests/dagger/internal/SetFactoryTest.java @@ -23,7 +23,6 @@ import java.util.Arrays; import java.util.LinkedHashSet; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; -import javax.inject.Provider; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; diff --git a/javatests/dagger/internal/codegen/AssistedFactoryTest.java b/javatests/dagger/internal/codegen/AssistedFactoryTest.java index 18de701a4..6f38f8f7d 100644 --- a/javatests/dagger/internal/codegen/AssistedFactoryTest.java +++ b/javatests/dagger/internal/codegen/AssistedFactoryTest.java @@ -326,4 +326,110 @@ public class AssistedFactoryTest { subject.generatedSource(goldenFileRule.goldenSource("test/DaggerTestComponent")); }); } + + // This is a regression test for b/305748522 + // The important thing for this test is that we have two assisted factories for the same assisted + // injection class and that they are requested in different components. + @Test + public void testMultipleAssistedFactoryInDifferentComponents() throws Exception { + Source component = + CompilerTests.javaSource( + "test.MyComponent", + "package test;", + "", + "import dagger.Component;", + "", + "@Component", + "interface MyComponent {", + " MyComponentAssistedFactory myComponentAssistedFactory();", + " MySubcomponent mySubcomponent();", + "}"); + Source subcomponent = + CompilerTests.javaSource( + "test.MySubcomponent", + "package test;", + "", + "import dagger.Subcomponent;", + "", + "@Subcomponent", + "interface MySubcomponent {", + " MySubcomponentAssistedFactory mySubcomponentAssistedFactory();", + "}"); + Source assistedClass = + CompilerTests.javaSource( + "test.MyAssistedClass", + "package test;", + "", + "import dagger.assisted.Assisted;", + "import dagger.assisted.AssistedInject;", + "", + "final class MyAssistedClass {", + " private final Foo foo;", + " private final Bar bar;", + "", + " @AssistedInject", + " MyAssistedClass(@Assisted Foo foo, Baz baz, @Assisted Bar bar) {", + " this.foo = foo;", + " this.bar = bar;", + " }", + "}"); + Source componentAssistedFactory = + CompilerTests.javaSource( + "test.MyComponentAssistedFactory", + "package test;", + "", + "import dagger.assisted.AssistedFactory;", + "", + "@AssistedFactory", + "interface MyComponentAssistedFactory {", + " MyAssistedClass create(Bar bar, Foo foo);", + "}"); + Source subcomponentAssistedFactory = + CompilerTests.javaSource( + "test.MySubcomponentAssistedFactory", + "package test;", + "", + "import dagger.assisted.AssistedFactory;", + "", + "@AssistedFactory", + "interface MySubcomponentAssistedFactory {", + " MyAssistedClass create(Bar bar, Foo foo);", + "}"); + Source foo = + CompilerTests.javaSource( + "test.Foo", + "package test;", + "final class Foo {}"); + Source bar = + CompilerTests.javaSource( + "test.Bar", + "package test;", + "final class Bar {}"); + Source baz = + CompilerTests.javaSource( + "test.Baz", + "package test;", + "", + "import javax.inject.Inject;", + "", + "final class Baz {", + " @Inject Baz() {}", + "}"); + + CompilerTests.daggerCompiler( + component, + subcomponent, + assistedClass, + componentAssistedFactory, + subcomponentAssistedFactory, + foo, + bar, + baz) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(0); + subject.generatedSource(goldenFileRule.goldenSource("test/DaggerMyComponent")); + }); + } } diff --git a/javatests/dagger/internal/codegen/AssistedInjectErrorsTest.java b/javatests/dagger/internal/codegen/AssistedInjectErrorsTest.java index 1d3628e46..e8e7fd7e9 100644 --- a/javatests/dagger/internal/codegen/AssistedInjectErrorsTest.java +++ b/javatests/dagger/internal/codegen/AssistedInjectErrorsTest.java @@ -243,4 +243,66 @@ public class AssistedInjectErrorsTest { .withProcessingOptions(compilerMode.processorOptions()) .compile(subject -> subject.hasErrorCount(0)); } + + @Test + public void testMultipleInjectedConstructors() { + Source foo = + CompilerTests.kotlinSource( + "test.Foo.kt", + "package test;", + "", + "import dagger.assisted.Assisted", + "import dagger.assisted.AssistedInject", + "import dagger.assisted.AssistedFactory", + "import javax.inject.Inject", + "", + "class Foo @AssistedInject constructor(@Assisted i: Int) {", + "", + " @Inject", + " constructor(s: String, @Assisted i: Int): this(i) {}", + "}"); + + CompilerTests.daggerCompiler(foo) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(2); + subject.hasErrorContaining( + "Type test.Foo may only contain one injected constructor." + + " Found: [@Inject test.Foo(String, int)," + + " @dagger.assisted.AssistedInject test.Foo(int)]"); + subject.hasErrorContaining( + "@Assisted parameters can only be used within an" + + " @AssistedInject-annotated constructor."); + }); + } + + @Test + public void testMultipleAssistedInjectedConstructors() { + Source foo = + CompilerTests.kotlinSource( + "test.Foo.kt", + "package test;", + "", + "import dagger.assisted.Assisted", + "import dagger.assisted.AssistedInject", + "import dagger.assisted.AssistedFactory", + "", + "class Foo @AssistedInject constructor(@Assisted i: Int) {", + "", + " @AssistedInject", + " constructor(s: String, @Assisted i: Int): this(i) {}", + "}"); + + CompilerTests.daggerCompiler(foo) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining( + "Type test.Foo may only contain one injected constructor." + + " Found: [@dagger.assisted.AssistedInject test.Foo(int)," + + " @dagger.assisted.AssistedInject test.Foo(String, int)]"); + }); + } } diff --git a/javatests/dagger/internal/codegen/BUILD b/javatests/dagger/internal/codegen/BUILD index 5984e5378..b189fe5b3 100644 --- a/javatests/dagger/internal/codegen/BUILD +++ b/javatests/dagger/internal/codegen/BUILD @@ -51,74 +51,137 @@ java_library( srcs = [ "CompilerMode.java", "Compilers.java", + "ComponentCreatorTestHelper.java", + "DaggerModuleMethodSubject.java", + "GeneratingProcessingStep.java", "JavaFileBuilder.java", + "TestUtils.java", ], deps = [ + "//java/dagger:core", "//java/dagger/internal/codegen:package_info", "//java/dagger/internal/codegen:processor", + "//java/dagger/internal/codegen/base", + "//java/dagger/internal/codegen/binding", + "//java/dagger/internal/codegen/xprocessing", "//java/dagger/internal/codegen/xprocessing:xprocessing-testing", + "//java/dagger/producers", "//java/dagger/testing/compile", "//third_party/java/compile_testing", "//third_party/java/guava/base", "//third_party/java/guava/collect", + "//third_party/java/javapoet", + "//third_party/java/truth", "@com_google_auto_value_auto_value//jar", ], ) +# These are tests with over 25 test cases. +LARGE_TESTS = [ + "ComponentCreatorTest.java", + "ComponentProcessorTest.java", + "InjectConstructorFactoryGeneratorTest.java", + "MembersInjectionTest.java", + "MissingBindingValidationTest.java", + "ModuleFactoryGeneratorTest.java", + "ProducerModuleFactoryGeneratorTest.java", + "SubcomponentCreatorValidationTest.java", +] + +# These are tests with over 10 test cases +MEDIUM_TESTS = [ + "BindsMethodValidationTest.java", + "DaggerSuperficialValidationTest.java", + "DelegateRequestRepresentationTest.java", + "DuplicateBindingsValidationTest.java", + "IgnoreProvisionKeyWildcardsTest.java", + "MapMultibindingValidationTest.java", + "MultibindsValidationTest.java", + "ProductionComponentProcessorTest.java", + "ProductionGraphValidationTest.java", + "SubcomponentValidationTest.java", +] + +DEPS = [ + ":compilers", + ":java_lib_no_dagger_compiler", + ":kt_lib_no_dagger_compiler", + "//third_party/java/guava/base", + "//third_party/java/guava/collect", + "//third_party/java/guava/util/concurrent", + "//third_party/java/auto:value", + "@com_google_auto_value_auto_value//jar", + "//third_party/java/auto:common", + "//third_party/java/compile_testing", + "//third_party/java/javapoet", + "//third_party/java/jsr250_annotations", # Include @Generated in generated files. + "//third_party/java/jsr330_inject", + "//third_party/java/junit", + "//third_party/java/mockito", + "//third_party/java/truth", + "//java/dagger:core", + "//java/dagger/internal/codegen:package_info", + "//java/dagger/internal/codegen:processor", + "//java/dagger/internal/codegen/base", + "//java/dagger/internal/codegen/binding", + "//java/dagger/internal/codegen/bindinggraphvalidation", + "//java/dagger/internal/codegen/compileroption", + "//java/dagger/internal/codegen/extension", + "//java/dagger/internal/codegen/javac", + "//java/dagger/internal/codegen/javapoet", + "//java/dagger/internal/codegen/kotlin", + "//java/dagger/internal/codegen/langmodel", + "//java/dagger/internal/codegen/model", + "//java/dagger/internal/codegen/validation", + "//java/dagger/internal/codegen/writing", + "//java/dagger/internal/codegen/xprocessing", + "//java/dagger/internal/codegen/xprocessing:xprocessing-testing", + "//java/dagger/model/testing", + "//java/dagger/producers", + "//java/dagger/spi", + "//java/dagger/spi/model/testing", + "//java/dagger/testing/compile", + "//java/dagger/testing/golden", +] + +GenJavaTests( + name = "large_compiler_tests", + srcs = LARGE_TESTS, + functional = False, + javacopts = DOCLINT_HTML_AND_SYNTAX, + plugins = ["//java/dagger/internal/codegen/bootstrap"], + shard_count = 7, + deps = DEPS, +) + +GenJavaTests( + name = "medium_compiler_tests", + srcs = MEDIUM_TESTS, + functional = False, + javacopts = DOCLINT_HTML_AND_SYNTAX, + plugins = ["//java/dagger/internal/codegen/bootstrap"], + shard_count = 3, + deps = DEPS, +) + GenJavaTests( name = "compiler_tests", srcs = glob( ["*.java"], exclude = [ - "ComponentProcessorTestClasses.java", "CompilerMode.java", "Compilers.java", + "ComponentCreatorTestHelper.java", + "ComponentProcessorTestClasses.java", + "DaggerModuleMethodSubject.java", + "GeneratingProcessingStep.java", "InvalidInjectConstructor.java", "JavaFileBuilder.java", - ], + "TestUtils.java", + ] + LARGE_TESTS + MEDIUM_TESTS, ), functional = False, javacopts = DOCLINT_HTML_AND_SYNTAX, plugins = ["//java/dagger/internal/codegen/bootstrap"], - deps = [ - ":compilers", - ":java_lib_no_dagger_compiler", - ":kt_lib_no_dagger_compiler", - "//java/dagger:core", - "//java/dagger/internal/codegen:package_info", - "//java/dagger/internal/codegen:processor", - "//java/dagger/internal/codegen/base", - "//java/dagger/internal/codegen/binding", - "//java/dagger/internal/codegen/bindinggraphvalidation", - "//java/dagger/internal/codegen/compileroption", - "//java/dagger/internal/codegen/extension", - "//java/dagger/internal/codegen/javac", - "//java/dagger/internal/codegen/javapoet", - "//java/dagger/internal/codegen/kotlin", - "//java/dagger/internal/codegen/langmodel", - "//java/dagger/internal/codegen/model", - "//java/dagger/internal/codegen/validation", - "//java/dagger/internal/codegen/writing", - "//java/dagger/internal/codegen/xprocessing", - "//java/dagger/internal/codegen/xprocessing:xprocessing-testing", - "//java/dagger/model/testing", - "//java/dagger/producers", - "//java/dagger/spi", - "//java/dagger/spi/model/testing", - "//java/dagger/testing/compile", - "//java/dagger/testing/golden", - "//third_party/java/auto:common", - "//third_party/java/auto:value", - "//third_party/java/compile_testing", - "//third_party/java/guava/base", - "//third_party/java/guava/collect", - "//third_party/java/guava/util/concurrent", - "//third_party/java/javapoet", - "//third_party/java/jsr250_annotations", # Include @Generated in generated files. - "//third_party/java/jsr330_inject", - "//third_party/java/junit", - "//third_party/java/mockito", - "//third_party/java/truth", - "@com_google_auto_value_auto_value//jar", - ], + deps = DEPS, ) diff --git a/javatests/dagger/internal/codegen/BindsMethodValidationTest.java b/javatests/dagger/internal/codegen/BindsMethodValidationTest.java index b7c8e1371..cb94f7567 100644 --- a/javatests/dagger/internal/codegen/BindsMethodValidationTest.java +++ b/javatests/dagger/internal/codegen/BindsMethodValidationTest.java @@ -53,6 +53,70 @@ public class BindsMethodValidationTest { } @Test + public void noExtensionForBinds() { + Source module = + CompilerTests.kotlinSource( + "test.TestModule.kt", + "package test", + "", + "import dagger.Binds", + "", + moduleAnnotation, + "interface TestModule {", + " @Binds fun FooImpl.bindObject(): Foo", + "}"); + Source foo = + CompilerTests.javaSource( + "test.Foo", // Prevents formatting onto a single line + "package test;", + "", + "interface Foo {}"); + Source fooImpl = + CompilerTests.javaSource( + "test.FooImpl", // Prevents formatting onto a single line + "package test;", + "", + "class FooImpl implements Foo {", + " @Inject FooImpl() {}", + "}"); + CompilerTests.daggerCompiler(module, foo, fooImpl) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining("@Binds methods can not be an extension function"); + }); + } + + @Test + public void noExtensionForProvides() { + Source module = + CompilerTests.kotlinSource( + "test.TestModule.kt", + "package test", + "", + "import dagger.Provides", + "", + moduleAnnotation, + "object TestModule {", + " @Provides fun Foo.providesString(): String = \"hello\"", + "}"); + Source foo = + CompilerTests.javaSource( + "test.Foo", // Prevents formatting onto a single line + "package test;", + "", + "class Foo {", + " @Inject Foo() {}", + "}"); + CompilerTests.daggerCompiler(module, foo) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining("@Provides methods can not be an extension function"); + }); + } + + @Test public void nonAbstract() { assertThatMethod("@Binds Object concrete(String impl) { return null; }") .hasError("must be abstract"); diff --git a/javatests/dagger/internal/codegen/ComponentProcessorTest.java b/javatests/dagger/internal/codegen/ComponentProcessorTest.java index e7f9b8ed5..90c7b2925 100644 --- a/javatests/dagger/internal/codegen/ComponentProcessorTest.java +++ b/javatests/dagger/internal/codegen/ComponentProcessorTest.java @@ -16,7 +16,12 @@ package dagger.internal.codegen; +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; + +import androidx.room.compiler.processing.util.CompilationResultSubject; import androidx.room.compiler.processing.util.Source; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.squareup.javapoet.AnnotationSpec; import com.squareup.javapoet.MethodSpec; @@ -27,6 +32,7 @@ import dagger.testing.compile.CompilerTests; import dagger.testing.golden.GoldenFileRule; import java.util.Collection; import javax.inject.Inject; +import javax.tools.Diagnostic; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -1380,21 +1386,57 @@ public class ComponentProcessorTest { subject -> { subject.hasErrorCount(0); subject.hasWarningCount(0); - subject.hasNoteContaining( - String.format( - "Generating a MembersInjector for dagger.internal.codegen.%s.", - "ComponentProcessorTestClasses.LocalInjectMemberNoConstructor")); - subject.hasNoteContaining( - String.format( - "Generating a MembersInjector for dagger.internal.codegen.%s.", - "ComponentProcessorTestClasses.LocalInjectMemberWithConstructor")); - subject.hasNoteContaining( - String.format( - "Generating a MembersInjector for dagger.internal.codegen.%s.", - "ComponentProcessorTestClasses.ParentInjectMemberWithConstructor")); + + String generatedFileTemplate = + "dagger/internal/codegen/ComponentProcessorTestClasses_%s_MembersInjector.java"; + String noteTemplate = + "Generating a MembersInjector for " + + "dagger.internal.codegen.ComponentProcessorTestClasses.%s."; + + // Assert that we generate sources and notes for the following classes. + ImmutableList.of( + "LocalInjectMemberNoConstructor", + "LocalInjectMemberWithConstructor", + "ParentInjectMemberWithConstructor") + .forEach( + className -> { + subject.generatedSourceFileWithPath( + String.format(generatedFileTemplate, className)); + subject.hasNoteContaining(String.format(noteTemplate, className)); + }); + + // Assert that we **do not** generate sources and notes for the following classes. + ImmutableList.of( + "ParentInjectMemberNoConstructor", + "NoInjectMemberNoConstructor", + "NoInjectMemberWithConstructor") + .forEach( + className -> { + assertFileNotGenerated( + subject, String.format(generatedFileTemplate, className)); + assertDoesNotHaveNoteContaining( + subject, String.format(noteTemplate, className)); + }); }); } + private void assertFileNotGenerated(CompilationResultSubject subject, String filePath) { + // TODO(b/303653163): replace this with better XProcessing API once we have the ability to get a + // list of all generated sources. + AssertionError error = + assertThrows( + AssertionError.class, + () -> subject.generatedSourceFileWithPath(filePath)); + assertThat(error).hasMessageThat().contains("Didn't generate file"); + } + + private void assertDoesNotHaveNoteContaining(CompilationResultSubject subject, String content) { + assertThat( + subject.getCompilationResult().getDiagnostics().get(Diagnostic.Kind.NOTE).stream() + .filter(diagnostic -> diagnostic.getMsg().contains(content))) + .isEmpty(); + } + @Test public void scopeAnnotationOnInjectConstructorNotValid() { Source aScope = @@ -2045,4 +2087,76 @@ public class ComponentProcessorTest { subject.hasWarningCount(0); }); } + + @Test + public void abstractVarFieldInComponent_failsValidation() { + Source component = + CompilerTests.kotlinSource( + "test.TestComponent.kt", + "package test", + "", + "import dagger.Component", + "", + "@Component(modules = [TestModule::class])", + "interface TestComponent {", + " var foo: String", + "}"); + + Source module = + CompilerTests.javaSource( + "test.TestModule", + "package test;", + "", + "import dagger.Module;", + "import dagger.Provides;", + "", + "@Module", + "abstract class TestModule {", + " @Provides", + " static String provideString() { return \"hello\"; }", + "}"); + + CompilerTests.daggerCompiler(component, module) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining( + "Cannot use 'abstract var' property in a component declaration to get a binding." + + " Use 'val' or 'fun' instead: foo"); + }); + } + + @Test + public void nonAbstractVarFieldInComponent_passesValidation() { + Source component = + CompilerTests.kotlinSource( + "test.TestComponent.kt", + "package test", + "", + "import dagger.Component", + "", + "@Component(modules = [TestModule::class])", + "abstract class TestComponent {", + " var foo: String = \"hello\"", + "}"); + + Source module = + CompilerTests.javaSource( + "test.TestModule", + "package test;", + "", + "import dagger.Module;", + "import dagger.Provides;", + "", + "@Module", + "abstract class TestModule {", + " @Provides", + " static String provideString() { return \"hello\"; }", + "}"); + + CompilerTests.daggerCompiler(component, module) + .withProcessingOptions(compilerMode.processorOptions()) + .compile(subject -> subject.hasErrorCount(0)); + } } diff --git a/javatests/dagger/internal/codegen/DuplicateBindingsValidationTest.java b/javatests/dagger/internal/codegen/DuplicateBindingsValidationTest.java index b45357cd6..c352a2810 100644 --- a/javatests/dagger/internal/codegen/DuplicateBindingsValidationTest.java +++ b/javatests/dagger/internal/codegen/DuplicateBindingsValidationTest.java @@ -1052,9 +1052,8 @@ public class DuplicateBindingsValidationTest { CompilerTests.daggerCompiler(foo, injected1, injected2, provided1, provided2) .compile( subject -> { - subject.hasErrorCount(0); - subject.hasWarningCount(1); - subject.hasWarningContaining( + subject.hasErrorCount(1); + subject.hasErrorContaining( message( "Foo is bound multiple times:", " @Inject Foo(Set<String>) [Injected1]", diff --git a/javatests/dagger/internal/codegen/FrameworkFieldTest.java b/javatests/dagger/internal/codegen/FrameworkFieldTest.java index be495d79b..ba5b88f8c 100644 --- a/javatests/dagger/internal/codegen/FrameworkFieldTest.java +++ b/javatests/dagger/internal/codegen/FrameworkFieldTest.java @@ -24,6 +24,7 @@ import static dagger.internal.codegen.javapoet.TypeNames.providerOf; import com.google.testing.compile.CompilationRule; import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.ParameterizedTypeName; import dagger.internal.codegen.binding.FrameworkField; import javax.inject.Inject; import org.junit.Before; @@ -47,16 +48,20 @@ public class FrameworkFieldTest { } @Test public void frameworkType() { - assertThat(FrameworkField.create(PROVIDER, xTypeName, "test").type()) + assertThat(FrameworkField.create(ParameterizedTypeName.get(PROVIDER, xTypeName), "test").type()) .isEqualTo(providerOf(xTypeName)); - assertThat(FrameworkField.create(MEMBERS_INJECTOR, xTypeName, "test").type()) + assertThat( + FrameworkField.create(ParameterizedTypeName.get(MEMBERS_INJECTOR, xTypeName), "test") + .type()) .isEqualTo(membersInjectorOf(xTypeName)); } @Test public void nameSuffix() { - assertThat(FrameworkField.create(PROVIDER, xTypeName, "foo").name()) + assertThat(FrameworkField.create(ParameterizedTypeName.get(PROVIDER, xTypeName), "foo").name()) .isEqualTo("fooProvider"); - assertThat(FrameworkField.create(PROVIDER, xTypeName, "fooProvider").name()) + assertThat( + FrameworkField.create(ParameterizedTypeName.get(PROVIDER, xTypeName), "fooProvider") + .name()) .isEqualTo("fooProvider"); } diff --git a/javatests/dagger/internal/codegen/GeneratedLines.java b/javatests/dagger/internal/codegen/GeneratedLines.java index 308904a33..d8a038825 100644 --- a/javatests/dagger/internal/codegen/GeneratedLines.java +++ b/javatests/dagger/internal/codegen/GeneratedLines.java @@ -33,7 +33,7 @@ public final class GeneratedLines { private static final String SUPPRESS_WARNINGS_ANNOTATION = "@SuppressWarnings({" - + "\"unchecked\", \"rawtypes\", \"KotlinInternal\", \"KotlinInternalInJava\"" + + "\"unchecked\", \"rawtypes\", \"KotlinInternal\", \"KotlinInternalInJava\", \"cast\"" + "})"; private static final String IMPORT_DAGGER_GENERATED = "import dagger.internal.DaggerGenerated;"; diff --git a/javatests/dagger/internal/codegen/HjarTest.java b/javatests/dagger/internal/codegen/HjarTest.java new file mode 100644 index 000000000..e8f67b725 --- /dev/null +++ b/javatests/dagger/internal/codegen/HjarTest.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2014 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.internal.codegen; + +import androidx.room.compiler.processing.util.Source; +import com.google.common.collect.ImmutableMap; +import dagger.testing.compile.CompilerTests; +import dagger.testing.compile.CompilerTests.DaggerCompiler; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests compilation with the {@code experimental_turbine_hjar} flag enabled. */ +@RunWith(JUnit4.class) +public class HjarTest { + /** Returns a {@link DaggerCompiler} with hjar generation enabled. */ + private static DaggerCompiler daggerCompiler(Source... sources) { + return CompilerTests.daggerCompiler(sources) + .withProcessingOptions(ImmutableMap.of("experimental_turbine_hjar", "")); + } + + @Test + public void componentTest() { + Source component = + CompilerTests.javaSource( + "test.MyComponent", + "package test;", + "", + "import dagger.Component;", + "", + "@Component", + "interface MyComponent {", + " String getString();", + " int getInt();", + " void inject(String str);", + "}"); + daggerCompiler(component).compile(subject -> subject.hasErrorCount(0)); + } + + @Test + public void moduleTest() { + Source module = + CompilerTests.javaSource( + "test.MyModule", + "package test;", + "", + "import dagger.Module;", + "import dagger.Provides;", + "", + "@Module", + "interface MyModule {", + " @Provides static int provideInt() { return 0; }", + " @Provides static String provideString() { return null; }", + " @Provides static String[] provideStringArray() { return null; }", + " @Provides static int[] provideIntArray() { return null; }", + " @Provides static boolean provideBoolean() { return false; }", + "}"); + daggerCompiler(module).compile(subject -> subject.hasErrorCount(0)); + } + + @Test + public void producerModuleTest() { + Source module = + CompilerTests.javaSource( + "test.MyModule", + "package test;", + "", + "import com.google.common.util.concurrent.ListenableFuture;", + "import dagger.producers.ProducerModule;", + "import dagger.producers.Produces;", + "", + "@ProducerModule", + "interface MyModule {", + " @Produces static ListenableFuture<String> produceString() { return null; }", + "}"); + daggerCompiler(module).compile(subject -> subject.hasErrorCount(0)); + } +} diff --git a/javatests/dagger/internal/codegen/IgnoreProvisionKeyWildcardsTest.java b/javatests/dagger/internal/codegen/IgnoreProvisionKeyWildcardsTest.java index 008a0a866..7b1705858 100644 --- a/javatests/dagger/internal/codegen/IgnoreProvisionKeyWildcardsTest.java +++ b/javatests/dagger/internal/codegen/IgnoreProvisionKeyWildcardsTest.java @@ -16,7 +16,6 @@ package dagger.internal.codegen; -import androidx.room.compiler.processing.XProcessingEnv; import androidx.room.compiler.processing.util.CompilationResultSubject; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; @@ -57,7 +56,7 @@ public class IgnoreProvisionKeyWildcardsTest { processingOptions = isIgnoreProvisionKeyWildcardsEnabled ? ImmutableMap.of("dagger.ignoreProvisionKeyWildcards", "enabled") - : ImmutableMap.of(); + : ImmutableMap.of("dagger.ignoreProvisionKeyWildcards", "disabled"); } @Test @@ -219,8 +218,7 @@ public class IgnoreProvisionKeyWildcardsTest { @Test public void testProvidesMultibindsSetContributionsWithDifferentTypeVariances() { compile( - /* javaComponentClass = */ - NEW_LINES.join( + /* javaComponentClass= */ NEW_LINES.join( "@Component(modules = MyModule.class)", "interface MyComponent {", " Set<Foo<? extends Bar>> setExtends();", @@ -231,8 +229,7 @@ public class IgnoreProvisionKeyWildcardsTest { " @Provides @IntoSet static Foo<? extends Bar> setExtends() { return null; }", " @Provides @IntoSet static Foo<Bar> set() { return null; }", "}"), - /* kotlinComponentClass = */ - NEW_LINES.join( + /* kotlinComponentClass= */ NEW_LINES.join( "@Component(modules = [MyModule::class])", "interface MyComponent {", " fun setExtends(): Set<Foo<out Bar>>", @@ -247,14 +244,12 @@ public class IgnoreProvisionKeyWildcardsTest { if (isIgnoreProvisionKeyWildcardsEnabled) { subject.hasErrorCount(1); subject.hasErrorContaining( - String.format( - NEW_LINES_FOR_ERROR_MSG.join( - "Set<Foo<? extends Bar>> has incompatible bindings or declarations:", - " Set bindings and declarations:", - " %1$s Foo<Bar> MyModule.set()", - " %1$s Foo<? extends Bar> MyModule.setExtends()", - " in component: [MyComponent]"), - isKapt(subject) ? "@IntoSet @Provides" : "@Provides @IntoSet")); + NEW_LINES_FOR_ERROR_MSG.join( + "Set<Foo<? extends Bar>> has incompatible bindings or declarations:", + " Set bindings and declarations:", + " @Provides @IntoSet Foo<Bar> MyModule.set()", + " @Provides @IntoSet Foo<? extends Bar> MyModule.setExtends()", + " in component: [MyComponent]")); } else { subject.hasErrorCount(0); } @@ -300,9 +295,8 @@ public class IgnoreProvisionKeyWildcardsTest { "Set<Foo<? extends Bar>> has incompatible bindings or declarations:", " Set bindings and declarations:", " @Multibinds Set<Foo<Bar>> MyModule.mulitbindSet()", - " %s Foo<? extends Bar> %s.setExtends()", + " @Provides @IntoSet Foo<? extends Bar> %s.setExtends()", " in component: [MyComponent]"), - isKapt(subject) ? "@IntoSet @Provides" : "@Provides @IntoSet", sourceKind == SourceKind.KOTLIN ? "MyModule.Companion" : "MyModule")); } else { subject.hasErrorCount(0); @@ -313,8 +307,7 @@ public class IgnoreProvisionKeyWildcardsTest { @Test public void testProvidesIntoSetAndElementsIntoSetContributionsWithDifferentVariances() { compile( - /* javaComponentClass = */ - NEW_LINES.join( + /* javaComponentClass= */ NEW_LINES.join( "@Component(modules = MyModule.class)", "interface MyComponent {", " Set<Foo<? extends Bar>> setExtends();", @@ -328,8 +321,7 @@ public class IgnoreProvisionKeyWildcardsTest { " @ElementsIntoSet", " static Set<Foo<Bar>> set() { return null; }", "}"), - /* kotlinComponentClass = */ - NEW_LINES.join( + /* kotlinComponentClass= */ NEW_LINES.join( "@Component(modules = [MyModule::class])", "interface MyComponent {", " fun setExtends(): Set<Foo<out Bar>>", @@ -344,15 +336,12 @@ public class IgnoreProvisionKeyWildcardsTest { if (isIgnoreProvisionKeyWildcardsEnabled) { subject.hasErrorCount(1); subject.hasErrorContaining( - String.format( - NEW_LINES_FOR_ERROR_MSG.join( - "Set<Foo<? extends Bar>> has incompatible bindings or declarations:", - " Set bindings and declarations:", - " %s Set<Foo<Bar>> MyModule.set()", - " %s Foo<? extends Bar> MyModule.setExtends()", - " in component: [MyComponent]"), - isKapt(subject) ? "@ElementsIntoSet @Provides" : "@Provides @ElementsIntoSet", - isKapt(subject) ? "@IntoSet @Provides" : "@Provides @IntoSet")); + NEW_LINES_FOR_ERROR_MSG.join( + "Set<Foo<? extends Bar>> has incompatible bindings or declarations:", + " Set bindings and declarations:", + " @Provides @ElementsIntoSet Set<Foo<Bar>> MyModule.set()", + " @Provides @IntoSet Foo<? extends Bar> MyModule.setExtends()", + " in component: [MyComponent]")); } else { subject.hasErrorCount(0); } @@ -526,12 +515,8 @@ public class IgnoreProvisionKeyWildcardsTest { " %s Foo<Bar> MyModule.foo()", " %s Foo<? extends Bar> MyModule.fooExtends()", " in component: [MyComponent]"), - isKapt(subject) - ? "@StringKey(\"foo\") @IntoMap @Provides" - : "@Provides @IntoMap @StringKey(\"foo\")", - isKapt(subject) - ? "@StringKey(\"fooExtends\") @IntoMap @Provides" - : "@Provides @IntoMap @StringKey(\"fooExtends\")")); + "@Provides @IntoMap @StringKey(\"foo\")", + "@Provides @IntoMap @StringKey(\"fooExtends\")")); } else { subject.hasErrorCount(0); } @@ -584,6 +569,27 @@ public class IgnoreProvisionKeyWildcardsTest { String javaComponentClass, String kotlinComponentClass, Consumer<CompilationResultSubject> onCompilationResult) { + compileInternal( + javaComponentClass, + kotlinComponentClass, + subject -> { + if (!isIgnoreProvisionKeyWildcardsEnabled) { + if (CompilerTests.backend(subject) == + androidx.room.compiler.processing.XProcessingEnv.Backend.KSP) { + subject.hasErrorCount(1); + subject.hasErrorContaining( + "When using KSP, you must also enable the 'dagger.ignoreProvisionKeyWildcards'"); + return; + } + } + onCompilationResult.accept(subject); + }); + } + + private void compileInternal( + String javaComponentClass, + String kotlinComponentClass, + Consumer<CompilationResultSubject> onCompilationResult) { if (sourceKind == SourceKind.JAVA) { // Compile with Java sources CompilerTests.daggerCompiler( @@ -649,9 +655,4 @@ public class IgnoreProvisionKeyWildcardsTest { .compile(onCompilationResult); } } - - private boolean isKapt(CompilationResultSubject subject) { - return sourceKind == SourceKind.KOTLIN - && CompilerTests.backend(subject) == XProcessingEnv.Backend.JAVAC; - } } diff --git a/javatests/dagger/internal/codegen/LazyClassKeyMapBindingComponentProcessorTest.java b/javatests/dagger/internal/codegen/LazyClassKeyMapBindingComponentProcessorTest.java new file mode 100644 index 000000000..9937d05ed --- /dev/null +++ b/javatests/dagger/internal/codegen/LazyClassKeyMapBindingComponentProcessorTest.java @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2024 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.internal.codegen; + +import static com.google.testing.compile.CompilationSubject.assertThat; + +import androidx.room.compiler.processing.util.Source; +import com.google.testing.compile.Compilation; +import com.google.testing.compile.JavaFileObjects; +import dagger.testing.compile.CompilerTests; +import dagger.testing.golden.GoldenFileRule; +import java.util.Collection; +import javax.tools.JavaFileObject; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +@RunWith(Parameterized.class) +public class LazyClassKeyMapBindingComponentProcessorTest { + @Parameters(name = "{0}") + public static Collection<Object[]> parameters() { + return CompilerMode.TEST_PARAMETERS; + } + + @Rule public GoldenFileRule goldenFileRule = new GoldenFileRule(); + + private final CompilerMode compilerMode; + + public LazyClassKeyMapBindingComponentProcessorTest(CompilerMode compilerMode) { + this.compilerMode = compilerMode; + } + + // Cannot convert to use ksp as this test relies on AutoAnnotationProcessor. + @Test + public void mapBindingsWithInaccessibleKeys() throws Exception { + JavaFileObject mapKeys = + JavaFileObjects.forSourceLines( + "mapkeys.MapKeys", + "package mapkeys;", + "", + "import dagger.MapKey;", + "import dagger.multibindings.LazyClassKey;", + "", + "public class MapKeys {", + " @MapKey(unwrapValue = false)", + " public @interface ComplexKey {", + " Class<?>[] manyClasses();", + " Class<?> oneClass();", + " LazyClassKey annotation();", + " }", + "", + " interface Inaccessible {}", + "}"); + JavaFileObject moduleFile = + JavaFileObjects.forSourceLines( + "mapkeys.MapModule", + "package mapkeys;", + "", + "import dagger.Binds;", + "import dagger.Module;", + "import dagger.Provides;", + "import dagger.multibindings.LazyClassKey;", + "import dagger.multibindings.IntoMap;", + "import java.util.Map;", + "import javax.inject.Provider;", + "", + "@Module", + "public interface MapModule {", + " @Provides @IntoMap @LazyClassKey(MapKeys.Inaccessible.class)", + " static int classKey() { return 1; }", + "", + " @Provides @IntoMap", + " @MapKeys.ComplexKey(", + " manyClasses = {java.lang.Object.class, java.lang.String.class},", + " oneClass = MapKeys.Inaccessible.class,", + " annotation = @LazyClassKey(java.lang.Object.class)", + " )", + " static int complexKeyWithInaccessibleValue() { return 1; }", + "", + " @Provides @IntoMap", + " @MapKeys.ComplexKey(", + " manyClasses = {MapKeys.Inaccessible.class, java.lang.String.class},", + " oneClass = java.lang.String.class,", + " annotation = @LazyClassKey(java.lang.Object.class)", + " )", + " static int complexKeyWithInaccessibleArrayValue() { return 1; }", + "", + " @Provides @IntoMap", + " @MapKeys.ComplexKey(", + " manyClasses = {java.lang.String.class},", + " oneClass = java.lang.String.class,", + " annotation = @LazyClassKey(MapKeys.Inaccessible.class)", + " )", + " static int complexKeyWithInaccessibleAnnotationValue() { return 1; }", + "}"); + JavaFileObject componentFile = + JavaFileObjects.forSourceLines( + "test.TestComponent", + "package test;", + "", + "import dagger.Component;", + "import java.util.Map;", + "import javax.inject.Provider;", + "import mapkeys.MapKeys;", + "import mapkeys.MapModule;", + "", + "@Component(modules = MapModule.class)", + "interface TestComponent {", + " Map<Class<?>, Integer> classKey();", + " Provider<Map<Class<?>, Integer>> classKeyProvider();", + "", + " Map<MapKeys.ComplexKey, Integer> complexKey();", + " Provider<Map<MapKeys.ComplexKey, Integer>> complexKeyProvider();", + "}"); + Compilation compilation = + Compilers.compilerWithOptions(compilerMode.javacopts()) + .compile(mapKeys, moduleFile, componentFile); + assertThat(compilation).succeeded(); + assertThat(compilation) + .generatedSourceFile("test.DaggerTestComponent") + .hasSourceEquivalentTo(goldenFileRule.goldenFile("test.DaggerTestComponent")); + assertThat(compilation) + .generatedSourceFile( + "mapkeys.MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey") + .hasSourceEquivalentTo( + goldenFileRule.goldenFile( + "mapkeys.MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey")); + assertThat(compilation) + .generatedSourceFile("mapkeys.MapModule_ClassKeyMapKey") + .hasSourceEquivalentTo(goldenFileRule.goldenFile("mapkeys.MapModule_ClassKeyMapKey")); + } + + @Test + public void lazyClassKeySimilarQualifiedName_doesNotConflict() throws Exception { + Source fooBar = + CompilerTests.javaSource("test.Foo_Bar", "package test;", "", "interface Foo_Bar {}"); + Source fooBar2 = + CompilerTests.javaSource( + "test.Foo", "package test;", "", "interface Foo { interface Bar {} }"); + Source mapKeyBindingsModule = + CompilerTests.javaSource( + "test.MapKeyBindingsModule", + "package test;", + "", + "import dagger.Module;", + "import dagger.Provides;", + "import dagger.multibindings.LazyClassKey;", + "import dagger.multibindings.IntoMap;", + "", + "@Module", + "public interface MapKeyBindingsModule {", + " @Provides @IntoMap @LazyClassKey(test.Foo_Bar.class)", + " static int classKey() { return 1; }", + "", + " @Provides @IntoMap @LazyClassKey(test.Foo.Bar.class)", + " static int classKey2() { return 1; }", + "}"); + + Source componentFile = + CompilerTests.javaSource( + "test.TestComponent", + "package test;", + "", + "import dagger.Component;", + "import java.util.Map;", + "", + "@Component(modules = MapKeyBindingsModule.class)", + "interface TestComponent {", + " Map<Class<?>, Integer> classKey();", + "}"); + CompilerTests.daggerCompiler(fooBar, fooBar2, mapKeyBindingsModule, componentFile) + .withProcessingOptions(compilerMode.processorOptions()) + .compile(subject -> subject.hasErrorCount(0)); + } +} diff --git a/javatests/dagger/internal/codegen/MembersInjectionTest.java b/javatests/dagger/internal/codegen/MembersInjectionTest.java index 8d2ff0b9f..4748853fb 100644 --- a/javatests/dagger/internal/codegen/MembersInjectionTest.java +++ b/javatests/dagger/internal/codegen/MembersInjectionTest.java @@ -46,6 +46,88 @@ public class MembersInjectionTest { } @Test + public void injectKotlinProtectField_fails() { + Source injectFieldSrc = + CompilerTests.kotlinSource( + "MyClass.kt", + "package test", + "", + "import javax.inject.Inject", + "", + "class MyClass @Inject constructor() {", + " @Inject protected lateinit var protectedField: String", + "}"); + Source moduleSrc = + CompilerTests.kotlinSource( + "MyModule.kt", + "package test", + "", + "import dagger.Module", + "import dagger.Provides", + "", + "@Module", + "object MyModule {", + " @Provides", + " fun providesString() = \"hello\"", + "}"); + Source componentSrc = + CompilerTests.kotlinSource( + "MyComponent.kt", + "package test", + "", + "import dagger.Component", + "@Component(modules = [MyModule::class])", + "interface MyComponent {}"); + CompilerTests.daggerCompiler(injectFieldSrc, moduleSrc, componentSrc) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining( + "Dagger injector does not have access to kotlin protected fields"); + }); + } + + @Test + public void injectJavaProtectField_succeeds() { + Source injectFieldSrc = + CompilerTests.javaSource( + "test.MyClass", + "package test;", + "", + "import javax.inject.Inject;", + "", + "public final class MyClass {", + " @Inject MyClass() {}", + " @Inject protected String protectedField;", + "}"); + Source moduleSrc = + CompilerTests.kotlinSource( + "MyModule.kt", + "package test", + "", + "import dagger.Module", + "import dagger.Provides", + "", + "@Module", + "object MyModule {", + " @Provides", + " fun providesString() = \"hello\"", + "}"); + Source componentSrc = + CompilerTests.kotlinSource( + "MyComponent.kt", + "package test", + "", + "import dagger.Component", + "@Component(modules = [MyModule::class])", + "interface MyComponent {}"); + CompilerTests.daggerCompiler(injectFieldSrc, moduleSrc, componentSrc) + .withProcessingOptions(compilerMode.processorOptions()) + .compile(subject -> subject.hasErrorCount(0)); + } + + @Test public void parentClass_noInjectedMembers() throws Exception { Source childFile = CompilerTests.javaSource( @@ -159,7 +241,8 @@ public class MembersInjectionTest { .compile( subject -> { subject.hasErrorCount(0); - subject.generatedSource(goldenFileRule.goldenSource("test/GenericClass_MembersInjector")); + subject.generatedSource( + goldenFileRule.goldenSource("test/GenericClass_MembersInjector")); }); } diff --git a/javatests/dagger/internal/codegen/MissingBindingSuggestionsTest.java b/javatests/dagger/internal/codegen/MissingBindingSuggestionsTest.java deleted file mode 100644 index 5e64c12a7..000000000 --- a/javatests/dagger/internal/codegen/MissingBindingSuggestionsTest.java +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright (C) 2015 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.internal.codegen; - -import androidx.room.compiler.processing.util.Source; -import com.google.common.collect.ImmutableList; -import dagger.testing.compile.CompilerTests; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; - -@RunWith(Parameterized.class) -public class MissingBindingSuggestionsTest { - @Parameters(name = "{0}") - public static ImmutableList<Object[]> parameters() { - return CompilerMode.TEST_PARAMETERS; - } - - private final CompilerMode compilerMode; - - public MissingBindingSuggestionsTest(CompilerMode compilerMode) { - this.compilerMode = compilerMode; - } - - private static Source injectable(String className, String constructorParams) { - return CompilerTests.javaSource( - "test." + className, - "package test;", - "", - "import javax.inject.Inject;", - "", - "class " + className + " {", - " @Inject " + className + "(" + constructorParams + ") {}", - "}"); - } - - private static Source emptyInterface(String interfaceName) { - return CompilerTests.javaSource( - "test." + interfaceName, - "package test;", - "", - "import javax.inject.Inject;", - "", - "interface " + interfaceName + " {}"); - } - - @Test public void suggestsBindingInSeparateComponent() { - Source fooComponent = - CompilerTests.javaSource( - "test.FooComponent", - "package test;", - "", - "import dagger.Subcomponent;", - "", - "@Subcomponent", - "interface FooComponent {", - " Foo getFoo();", - "}"); - Source barModule = - CompilerTests.javaSource( - "test.BarModule", - "package test;", - "", - "import dagger.Provides;", - "import javax.inject.Inject;", - "", - "@dagger.Module", - "final class BarModule {", - " @Provides Bar provideBar() {return null;}", - "}"); - Source barComponent = - CompilerTests.javaSource( - "test.BarComponent", - "package test;", - "", - "import dagger.Subcomponent;", - "", - "@Subcomponent(modules = {BarModule.class})", - "interface BarComponent {", - " Bar getBar();", - "}"); - Source foo = injectable("Foo", "Bar bar"); - Source bar = emptyInterface("Bar"); - - Source topComponent = - CompilerTests.javaSource( - "test.TopComponent", - "package test;", - "", - "import dagger.Component;", - "", - "@Component", - "interface TopComponent {", - " FooComponent getFoo();", - " BarComponent getBar(BarModule barModule);", - "}"); - - CompilerTests.daggerCompiler(fooComponent, barComponent, topComponent, foo, bar, barModule) - .withProcessingOptions(compilerMode.processorOptions()) - .compile( - subject -> { - subject.hasErrorCount(1); - subject.hasErrorContaining("A binding for Bar exists in BarComponent:"); - }); - } - - @Test public void suggestsBindingInNestedSubcomponent() { - Source fooComponent = - CompilerTests.javaSource( - "test.FooComponent", - "package test;", - "", - "import dagger.Subcomponent;", - "", - "@Subcomponent", - "interface FooComponent {", - " Foo getFoo();", - "}"); - Source barComponent = - CompilerTests.javaSource( - "test.BarComponent", - "package test;", - "", - "import dagger.Subcomponent;", - "", - "@Subcomponent()", - "interface BarComponent {", - " BazComponent getBaz();", - "}"); - Source bazModule = - CompilerTests.javaSource( - "test.BazModule", - "package test;", - "", - "import dagger.Provides;", - "import javax.inject.Inject;", - "", - "@dagger.Module", - "final class BazModule {", - " @Provides Baz provideBaz() {return null;}", - "}"); - Source bazComponent = - CompilerTests.javaSource( - "test.BazComponent", - "package test;", - "", - "import dagger.Subcomponent;", - "", - "@Subcomponent(modules = {BazModule.class})", - "interface BazComponent {", - " Baz getBaz();", - "}"); - Source foo = injectable("Foo", "Baz baz"); - Source baz = emptyInterface("Baz"); - - Source topComponent = - CompilerTests.javaSource( - "test.TopComponent", - "package test;", - "", - "import dagger.Component;", - "", - "@Component", - "interface TopComponent {", - " FooComponent getFoo();", - " BarComponent getBar();", - "}"); - - CompilerTests.daggerCompiler( - fooComponent, barComponent, bazComponent, topComponent, foo, baz, bazModule) - .withProcessingOptions(compilerMode.processorOptions()) - .compile( - subject -> { - subject.hasErrorCount(1); - subject.hasErrorContaining("A binding for Baz exists in BazComponent:"); - }); - } - - @Test - public void missingBindingInParentComponent() { - Source parent = - CompilerTests.javaSource( - "Parent", - "import dagger.Component;", - "", - "@Component", - "interface Parent {", - " Foo foo();", - " Bar bar();", - " Child child();", - "}"); - Source child = - CompilerTests.javaSource( - "Child", - "import dagger.Subcomponent;", - "", - "@Subcomponent(modules=BazModule.class)", - "interface Child {", - " Foo foo();", - " Baz baz();", - "}"); - Source foo = - CompilerTests.javaSource( - "Foo", - "import javax.inject.Inject;", - "", - "class Foo {", - " @Inject Foo(Bar bar) {}", - "}"); - Source bar = - CompilerTests.javaSource( - "Bar", - "import javax.inject.Inject;", - "", - "class Bar {", - " @Inject Bar(Baz baz) {}", - "}"); - Source baz = CompilerTests.javaSource("Baz", "class Baz {}"); - Source bazModule = - CompilerTests.javaSource( - "BazModule", - "import dagger.Module;", - "import dagger.Provides;", - "import javax.inject.Inject;", - "", - "@Module", - "final class BazModule {", - " @Provides Baz provideBaz() {return new Baz();}", - "}"); - - CompilerTests.daggerCompiler(parent, child, foo, bar, baz, bazModule) - .withProcessingOptions(compilerMode.processorOptions()) - .compile( - subject -> { - subject.hasErrorCount(1); - subject.hasErrorContaining( - "\033[1;31m[Dagger/MissingBinding]\033[0m Baz cannot be provided without an " - + "@Inject constructor or an @Provides-annotated method."); - subject.hasErrorContaining("A binding for Baz exists in Child:"); - subject.hasErrorContaining(" Baz is injected at"); - subject.hasErrorContaining(" [Parent] Bar(baz)"); - subject.hasErrorContaining(" Bar is requested at"); - subject.hasErrorContaining(" [Parent] Parent.bar()"); - subject.hasErrorContaining("The following other entry points also depend on it:"); - subject.hasErrorContaining(" Parent.foo()"); - subject.hasErrorContaining(" Child.foo() [Parent → Child]") - .onSource(parent) - .onLineContaining("interface Parent"); - }); - } - - @Test - public void missingBindingInSiblingComponent() { - Source parent = - CompilerTests.javaSource( - "Parent", - "import dagger.Component;", - "", - "@Component", - "interface Parent {", - " Foo foo();", - " Bar bar();", - " Child1 child1();", - " Child2 child2();", - "}"); - Source child1 = - CompilerTests.javaSource( - "Child1", - "import dagger.Subcomponent;", - "", - "@Subcomponent", - "interface Child1 {", - " Foo foo();", - " Baz baz();", - "}"); - Source child2 = - CompilerTests.javaSource( - "Child2", - "import dagger.Subcomponent;", - "", - "@Subcomponent(modules = BazModule.class)", - "interface Child2 {", - " Foo foo();", - " Baz baz();", - "}"); - Source foo = - CompilerTests.javaSource( - "Foo", - "import javax.inject.Inject;", - "", - "class Foo {", - " @Inject Foo(Bar bar) {}", - "}"); - Source bar = - CompilerTests.javaSource( - "Bar", - "import javax.inject.Inject;", - "", - "class Bar {", - " @Inject Bar(Baz baz) {}", - "}"); - Source baz = CompilerTests.javaSource("Baz", "class Baz {}"); - Source bazModule = - CompilerTests.javaSource( - "BazModule", - "import dagger.Module;", - "import dagger.Provides;", - "import javax.inject.Inject;", - "", - "@Module", - "final class BazModule {", - " @Provides Baz provideBaz() {return new Baz();}", - "}"); - - CompilerTests.daggerCompiler(parent, child1, child2, foo, bar, baz, bazModule) - .withProcessingOptions(compilerMode.processorOptions()) - .compile( - subject -> { - subject.hasErrorCount(1); - subject.hasErrorContaining( - "\033[1;31m[Dagger/MissingBinding]\033[0m Baz cannot be provided without an " - + "@Inject constructor or an @Provides-annotated method."); - subject.hasErrorContaining("A binding for Baz exists in Child2:"); - subject.hasErrorContaining(" Baz is injected at"); - subject.hasErrorContaining(" [Parent] Bar(baz)"); - subject.hasErrorContaining(" Bar is requested at"); - subject.hasErrorContaining(" [Parent] Parent.bar()"); - subject.hasErrorContaining("The following other entry points also depend on it:"); - subject.hasErrorContaining(" Parent.foo()"); - subject.hasErrorContaining(" Child1.foo() [Parent → Child1]"); - subject.hasErrorContaining(" Child2.foo() [Parent → Child2]"); - subject.hasErrorContaining(" Child1.baz() [Parent → Child1]") - .onSource(parent) - .onLineContaining("interface Parent"); - }); - } -} diff --git a/javatests/dagger/internal/codegen/MissingBindingValidationTest.java b/javatests/dagger/internal/codegen/MissingBindingValidationTest.java index 919700ee5..8250861d8 100644 --- a/javatests/dagger/internal/codegen/MissingBindingValidationTest.java +++ b/javatests/dagger/internal/codegen/MissingBindingValidationTest.java @@ -18,6 +18,7 @@ package dagger.internal.codegen; import static com.google.common.truth.Truth.assertThat; +import androidx.room.compiler.processing.XProcessingEnv; import androidx.room.compiler.processing.util.DiagnosticMessage; import androidx.room.compiler.processing.util.Source; import com.google.common.collect.ImmutableList; @@ -348,18 +349,21 @@ public class MissingBindingValidationTest { subject -> { subject.hasErrorCount(1); subject.hasErrorContaining( - "TestClass.A cannot be provided without an @Provides-annotated method."); - subject.hasErrorContaining(" TestClass.A is injected at"); - subject.hasErrorContaining(" TestClass.B(a)"); - subject.hasErrorContaining(" TestClass.B is injected at"); - subject.hasErrorContaining(" TestClass.C.b"); - subject.hasErrorContaining(" TestClass.C is injected at"); - subject.hasErrorContaining(" TestClass.AComponent.injectC(TestClass.C)"); - subject.hasErrorContaining("The following other entry points also depend on it:"); - subject.hasErrorContaining(" TestClass.AComponent.getFoo()"); - subject.hasErrorContaining(" TestClass.AComponent.cProvider()"); - subject.hasErrorContaining(" TestClass.AComponent.lazyC()"); - subject.hasErrorContaining(" TestClass.AComponent.lazyCProvider()") + String.join( + "\n", + "TestClass.A cannot be provided without an @Provides-annotated method.", + "", + " TestClass.A is injected at", + " [TestClass.AComponent] TestClass.B(a)", + " TestClass.B is injected at", + " [TestClass.AComponent] TestClass.C.b", + " TestClass.C is injected at", + " [TestClass.AComponent] TestClass.AComponent.injectC(TestClass.C)", + "The following other entry points also depend on it:", + " TestClass.AComponent.getFoo()", + " TestClass.AComponent.cProvider()", + " TestClass.AComponent.lazyC()", + " TestClass.AComponent.lazyCProvider()")) .onSource(component) .onLineContaining("interface AComponent"); }); @@ -403,14 +407,17 @@ public class MissingBindingValidationTest { subject -> { subject.hasErrorCount(1); subject.hasErrorContaining( - "String cannot be provided without an @Inject constructor or an " - + "@Provides-annotated method."); - subject.hasErrorContaining(" String is injected at"); - subject.hasErrorContaining(" TestImplementation(missingBinding)"); - subject.hasErrorContaining(" TestImplementation is injected at"); - subject.hasErrorContaining(" TestModule.bindTestInterface(implementation)"); - subject.hasErrorContaining(" TestInterface is requested at"); - subject.hasErrorContaining(" TestComponent.testInterface()") + String.join( + "\n", + "String cannot be provided without an @Inject constructor or an " + + "@Provides-annotated method.", + "", + " String is injected at", + " [TestComponent] TestImplementation(missingBinding)", + " TestImplementation is injected at", + " [TestComponent] TestModule.bindTestInterface(implementation)", + " TestInterface is requested at", + " [TestComponent] TestComponent.testInterface()")) .onSource(component) .onLineContaining("interface TestComponent"); }); @@ -463,15 +470,18 @@ public class MissingBindingValidationTest { subject -> { subject.hasErrorCount(1); subject.hasErrorContaining( - "List cannot be provided without an @Provides-annotated method."); - subject.hasErrorContaining(" List is injected at"); - subject.hasErrorContaining(" TestClass(list)"); - subject.hasErrorContaining(" TestClass is injected at"); - subject.hasErrorContaining(" Generic(t)"); - subject.hasErrorContaining(" Generic<TestClass> is injected at"); - subject.hasErrorContaining(" UsesTest(genericTestClass)"); - subject.hasErrorContaining(" UsesTest is requested at"); - subject.hasErrorContaining(" TestComponent.usesTest()"); + String.join( + "\n", + "List cannot be provided without an @Provides-annotated method.", + "", + " List is injected at", + " [TestComponent] TestClass(list)", + " TestClass is injected at", + " [TestComponent] Generic(t)", + " Generic<TestClass> is injected at", + " [TestComponent] UsesTest(genericTestClass)", + " UsesTest is requested at", + " [TestComponent] TestComponent.usesTest()")); }); } @@ -527,15 +537,18 @@ public class MissingBindingValidationTest { subject -> { subject.hasErrorCount(1); subject.hasErrorContaining( - "List cannot be provided without an @Provides-annotated method."); - subject.hasErrorContaining(" List is injected at"); - subject.hasErrorContaining(" TestClass(list)"); - subject.hasErrorContaining(" TestClass is injected at"); - subject.hasErrorContaining(" Generic.t"); - subject.hasErrorContaining(" Generic<TestClass> is injected at"); - subject.hasErrorContaining(" UsesTest(genericTestClass)"); - subject.hasErrorContaining(" UsesTest is requested at"); - subject.hasErrorContaining(" TestComponent.usesTest()"); + String.join( + "\n", + "List cannot be provided without an @Provides-annotated method.", + "", + " List is injected at", + " [TestComponent] TestClass(list)", + " TestClass is injected at", + " [TestComponent] Generic.t", + " Generic<TestClass> is injected at", + " [TestComponent] UsesTest(genericTestClass)", + " UsesTest is requested at", + " [TestComponent] TestComponent.usesTest()")); }); } @@ -669,16 +682,19 @@ public class MissingBindingValidationTest { subject.hasErrorCount(1); // TODO(b/243720787): Replace with CompilationResultSubject#hasErrorContainingMatch() subject.hasErrorContaining( - "Double cannot be provided without an @Inject constructor or an " - + "@Provides-annotated method."); - subject.hasErrorContaining("Double is injected at"); - subject.hasErrorContaining(" ParentModule.missingDependency(dub)"); - subject.hasErrorContaining("Integer is injected at"); - subject.hasErrorContaining(" ChildModule.contributesToSet(i)"); - subject.hasErrorContaining("Set<String> is injected at"); - subject.hasErrorContaining(" ParentModule.dependsOnSet(strings)"); - subject.hasErrorContaining("Object is requested at"); - subject.hasErrorContaining(" Grandchild.object() [Parent → Child → Grandchild]") + String.join( + "\n", + "Double cannot be provided without an @Inject constructor or an " + + "@Provides-annotated method.", + "", + " Double is injected at", + " [Parent] ParentModule.missingDependency(dub)", + " Integer is injected at", + " [Child] ChildModule.contributesToSet(i)", + " Set<String> is injected at", + " [Child] ParentModule.dependsOnSet(strings)", + " Object is requested at", + " [Grandchild] Grandchild.object() [Parent → Child → Grandchild]")) .onSource(parent) .onLineContaining("interface Parent"); }); @@ -727,16 +743,18 @@ public class MissingBindingValidationTest { subject -> { subject.hasErrorCount(1); subject.hasErrorContaining( - "\033[1;31m[Dagger/MissingBinding]\033[0m " - + "NotBound cannot be provided without an @Provides-annotated method."); - subject.hasErrorContaining(" NotBound is injected at"); - subject.hasErrorContaining(" TestModule.object(notBound)"); - subject.hasErrorContaining(" Object is requested at"); - subject.hasErrorContaining(" TestComponent.object()"); - subject.hasErrorContaining("It is also requested at:"); - subject.hasErrorContaining(" TestModule.string(notBound, …)"); - subject.hasErrorContaining("The following other entry points also depend on it:"); - subject.hasErrorContaining(" TestComponent.string()") + String.join( + "\n", + "NotBound cannot be provided without an @Provides-annotated method.", + "", + " NotBound is injected at", + " [TestComponent] TestModule.object(notBound)", + " Object is requested at", + " [TestComponent] TestComponent.object()", + "It is also requested at:", + " TestModule.string(notBound, …)", + "The following other entry points also depend on it:", + " TestComponent.string()")) .onSource(component) .onLineContaining("interface TestComponent"); }); @@ -787,22 +805,27 @@ public class MissingBindingValidationTest { subject -> { subject.hasErrorCount(1); subject.hasErrorContaining( - "\033[1;31m[Dagger/MissingBinding]\033[0m String cannot be provided without an " - + "@Inject constructor or an @Provides-annotated method."); - subject.hasErrorContaining(" String is requested at"); - subject.hasErrorContaining(" TestComponent.string()"); - subject.hasErrorContaining("It is also requested at:"); - subject.hasErrorContaining(" Foo(one, …)"); - subject.hasErrorContaining(" Foo(…, two, …)"); - subject.hasErrorContaining(" Foo(…, three, …)"); - subject.hasErrorContaining(" Foo(…, four, …)"); - subject.hasErrorContaining(" Foo(…, five, …)"); - subject.hasErrorContaining(" Foo(…, six, …)"); - subject.hasErrorContaining(" Foo(…, seven, …)"); - subject.hasErrorContaining(" Foo(…, eight, …)"); - subject.hasErrorContaining(" Foo(…, nine, …)"); - subject.hasErrorContaining(" Foo(…, ten, …)"); - subject.hasErrorContaining(" and 3 others") + String.join( + "\n", + "String cannot be provided without an @Inject constructor or an " + + "@Provides-annotated method.", + "", + " String is requested at", + " [TestComponent] TestComponent.string()", + "It is also requested at:", + " Foo(one, …)", + " Foo(…, two, …)", + " Foo(…, three, …)", + " Foo(…, four, …)", + " Foo(…, five, …)", + " Foo(…, six, …)", + " Foo(…, seven, …)", + " Foo(…, eight, …)", + " Foo(…, nine, …)", + " Foo(…, ten, …)", + " and 3 others", + "The following other entry points also depend on it:", + " TestComponent.foo()")) .onSource(component) .onLineContaining("interface TestComponent"); }); @@ -839,22 +862,25 @@ public class MissingBindingValidationTest { subject -> { subject.hasErrorCount(1); subject.hasErrorContaining( - "\033[1;31m[Dagger/MissingBinding]\033[0m String cannot be provided without an " - + "@Inject constructor or an @Provides-annotated method."); - subject.hasErrorContaining(" String is requested at"); - subject.hasErrorContaining(" TestComponent.string1()"); - subject.hasErrorContaining("The following other entry points also depend on it:"); - subject.hasErrorContaining(" TestComponent.string2()"); - subject.hasErrorContaining(" TestComponent.string3()"); - subject.hasErrorContaining(" TestComponent.string4()"); - subject.hasErrorContaining(" TestComponent.string5()"); - subject.hasErrorContaining(" TestComponent.string6()"); - subject.hasErrorContaining(" TestComponent.string7()"); - subject.hasErrorContaining(" TestComponent.string8()"); - subject.hasErrorContaining(" TestComponent.string9()"); - subject.hasErrorContaining(" TestComponent.string10()"); - subject.hasErrorContaining(" TestComponent.string11()"); - subject.hasErrorContaining(" and 1 other") + String.join( + "\n", + "String cannot be provided without an @Inject constructor or an " + + "@Provides-annotated method.", + "", + " String is requested at", + " [TestComponent] TestComponent.string1()", + "The following other entry points also depend on it:", + " TestComponent.string2()", + " TestComponent.string3()", + " TestComponent.string4()", + " TestComponent.string5()", + " TestComponent.string6()", + " TestComponent.string7()", + " TestComponent.string8()", + " TestComponent.string9()", + " TestComponent.string10()", + " TestComponent.string11()", + " and 1 other")) .onSource(component) .onLineContaining("interface TestComponent"); }); @@ -908,16 +934,19 @@ public class MissingBindingValidationTest { subject -> { subject.hasErrorCount(1); subject.hasErrorContaining( - "\033[1;31m[Dagger/MissingBinding]\033[0m Baz cannot be provided without an " - + "@Inject constructor or an @Provides-annotated method."); - subject.hasErrorContaining(" Baz is injected at"); - subject.hasErrorContaining(" Bar(baz)"); - subject.hasErrorContaining(" Bar is requested at"); - subject.hasErrorContaining(" Parent.bar()"); - subject.hasErrorContaining("The following other entry points also depend on it:"); - subject.hasErrorContaining(" Parent.foo()"); - subject.hasErrorContaining(" Child.foo() [Parent → Child]"); - subject.hasErrorContaining(" Child.baz() [Parent → Child]") + String.join( + "\n", + "Baz cannot be provided without an @Inject constructor or an " + + "@Provides-annotated method.", + "", + " Baz is injected at", + " [Parent] Bar(baz)", + " Bar is requested at", + " [Parent] Parent.bar()", + "The following other entry points also depend on it:", + " Parent.foo()", + " Child.foo() [Parent → Child]", + " Child.baz() [Parent → Child]")) .onSource(parent) .onLineContaining("interface Parent"); }); @@ -1061,9 +1090,14 @@ public class MissingBindingValidationTest { subject.hasErrorContaining( String.join( "\n", - "A binding for Object exists in Child2:", - "Object is requested at", - "[Child1] Child1.getObject() [Parent → Child1]")); + "Object cannot be provided without an @Inject constructor or an " + + "@Provides-annotated method.", + "", + " Object is requested at", + " [Child1] Child1.getObject() [Parent → Child1]", + "", + "Note: Object is provided in the following other components:", + " [Child2] Child2Module.provideObject()")); }); } @@ -1174,10 +1208,17 @@ public class MissingBindingValidationTest { subject -> { subject.hasErrorCount(1); subject.hasErrorContaining( - "A binding for Object exists in [Parent → Child2 → RepeatedSub]:"); - subject.hasErrorContaining( - "[Parent → Child1 → RepeatedSub] RepeatedSub.getObject() [Parent → Child1 →" - + " RepeatedSub]"); + String.join( + "\n", + "Object cannot be provided without an @Inject constructor or an " + + "@Provides-annotated method.", + "", + " Object is requested at", + " [RepeatedSub] RepeatedSub.getObject() " + + "[Parent → Child1 → RepeatedSub]", + "", + "Note: Object is provided in the following other components:", + " [Child2] Child2Module.provideObject(…)")); }); } @@ -1298,9 +1339,17 @@ public class MissingBindingValidationTest { .compile( subject -> { subject.hasErrorCount(1); - subject.hasErrorContaining("A binding for Object exists in bar.Sub:"); subject.hasErrorContaining( - "[foo.Sub] foo.Sub.getObject() [Parent → Child1 → foo.Sub]"); + String.join( + "\n", + "Object cannot be provided without an @Inject constructor or an " + + "@Provides-annotated method.", + "", + " Object is requested at", + " [Sub] Sub.getObject() [Parent → Child1 → Sub]", + "", + "Note: Object is provided in the following other components:", + " [Child2] Child2Module.provideObject(…)")); }); } @@ -1384,11 +1433,25 @@ public class MissingBindingValidationTest { subject -> { subject.hasErrorCount(1); subject - .hasErrorContaining("Found similar bindings:") + .hasErrorContaining( + String.join( + "\n", + "Set<? extends Bar> cannot be provided without an @Provides-annotated " + + "method.", + "", + " Set<? extends Bar> is injected at", + " [MyComponent] Foo(bar)", + " Foo is requested at", + " [MyComponent] MyComponent.getFoo()", + "", + "Note: Set<? extends Bar> is provided in the following other components:", + " [Child] ChildModule.provideBar()", + "", + "Note: A similar binding is provided in the following other components:", + " Set<Bar> is provided at:", + " [MyComponent] Dagger-generated binding for Set<Bar>")) .onSource(component) .onLineContaining("interface MyComponent"); - subject.hasErrorContaining("Set<Bar> in [MyComponent"); - subject.hasErrorContaining("Set<? extends Bar> in [MyComponent → Child]"); }); } @@ -1443,7 +1506,20 @@ public class MissingBindingValidationTest { subject -> { subject.hasErrorCount(1); subject - .hasErrorContaining("Set<Bar> in [MyComponent]") + .hasErrorContaining( + String.join( + "\n", + "Set<? extends Bar> cannot be provided without an @Provides-annotated " + + "method.", + "", + " Set<? extends Bar> is injected at", + " [MyComponent] Foo(bar)", + " Foo is requested at", + " [MyComponent] MyComponent.getFoo()", + "", + "Note: A similar binding is provided in the following other components:", + " Set<Bar> is provided at:", + " [MyComponent] Dagger-generated binding for Set<Bar>")) .onSource(component) .onLineContaining("interface MyComponent"); }); @@ -1503,10 +1579,22 @@ public class MissingBindingValidationTest { subject -> { subject.hasErrorCount(1); subject - .hasErrorContaining("Found similar bindings:") + .hasErrorContaining( + String.join( + "\n", + "Set<? extends Bar> cannot be provided without an @Provides-annotated " + + "method.", + "", + " Set<? extends Bar> is injected at", + " [MyComponent] Foo.bar", + " Foo is requested at", + " [MyComponent] MyComponent.getFoo()", + "", + "Note: A similar binding is provided in the following other components:", + " Set<Bar> is provided at:", + " [MyComponent] Dagger-generated binding for Set<Bar>")) .onSource(component) .onLineContaining("interface MyComponent"); - subject.hasErrorContaining("Set<Bar> in [MyComponent]"); }); } @@ -1554,10 +1642,21 @@ public class MissingBindingValidationTest { subject -> { subject.hasErrorCount(1); subject - .hasErrorContaining("Found similar bindings:") + .hasErrorContaining( + String.join( + "\n", + "List<Bar> cannot be provided without an @Provides-annotated method.", + "", + " List<Bar> is injected at", + " [MyComponent] Foo(bar)", + " Foo is requested at", + " [MyComponent] MyComponent.getFoo()", + "", + "Note: A similar binding is provided in the following other components:", + " List<? extends Bar> is provided at:", + " [MyComponent] TestModule.provideBars()")) .onSource(component) .onLineContaining("interface MyComponent"); - subject.hasErrorContaining("List<? extends Bar> in [MyComponent]"); }); } @@ -1613,7 +1712,24 @@ public class MissingBindingValidationTest { subject -> { subject.hasErrorCount(1); subject - .hasErrorContaining("Bar<Baz,Baz,Set<Baz>> in [MyComponent]") + .hasErrorContaining( + String.join( + "\n", + // TODO(b/324325095): Align KSP and KAPT error message. + CompilerTests.backend(subject) == XProcessingEnv.Backend.KSP + ? "Bar<? extends Baz,Baz,Set<Baz>> cannot be provided without an " + + "@Inject constructor or an @Provides-annotated method." + : "Bar<? extends Baz,Baz,Set<Baz>> cannot be provided without an " + + "@Provides-annotated method.", + "", + " Bar<? extends Baz,Baz,Set<Baz>> is injected at", + " [MyComponent] Foo(bar)", + " Foo is requested at", + " [MyComponent] MyComponent.getFoo()", + "", + "Note: A similar binding is provided in the following other components:", + " Bar<Baz,Baz,Set<Baz>> is provided at:", + " [MyComponent] TestModule.provideBar()")) .onSource(component) .onLineContaining("interface MyComponent"); }); @@ -1733,8 +1849,23 @@ public class MissingBindingValidationTest { .compile( subject -> { subject.hasErrorCount(1); - subject.hasErrorContaining("Found similar bindings:"); - subject.hasErrorContaining("Bar in [MyComponent]"); + subject.hasErrorContaining( + String.join( + "\n", + // TODO(b/324325095): Align KSP and KAPT error message. + CompilerTests.backend(subject) == XProcessingEnv.Backend.KSP + ? "Bar<?> cannot be provided without an @Inject constructor or an " + + "@Provides-annotated method." + : "Bar<?> cannot be provided without an @Provides-annotated method.", + "", + " Bar<?> is injected at", + " [MyComponent] Foo(bar)", + " Foo is requested at", + " [MyComponent] MyComponent.getFoo()", + "", + "Note: A similar binding is provided in the following other components:", + " Bar is provided at:", + " [MyComponent] TestModule.provideBar()")); }); } diff --git a/javatests/dagger/internal/codegen/ProductionComponentProcessorTest.java b/javatests/dagger/internal/codegen/ProductionComponentProcessorTest.java index b9758c121..39e63c99e 100644 --- a/javatests/dagger/internal/codegen/ProductionComponentProcessorTest.java +++ b/javatests/dagger/internal/codegen/ProductionComponentProcessorTest.java @@ -202,6 +202,51 @@ public class ProductionComponentProcessorTest { } @Test + public void dependsOnProductionSubcomponentWithPluginsVisitFullBindingGraphs() throws Exception { + Source myComponent = + CompilerTests.javaSource( + "test.MyComponent", + "package test;", + "", + "import dagger.Component;", + "", + "@Component(modules = MyModule.class)", + "interface MyComponent {}"); + Source myModule = + CompilerTests.javaSource( + "test.MyModule", + "package test;", + "", + "import dagger.Component;", + "import dagger.Module;", + "", + "@Module(subcomponents = MyProductionSubcomponent.class)", + "interface MyModule {}"); + Source myProductionSubcomponent = + CompilerTests.javaSource( + "test.MyProductionSubcomponent", + "package test;", + "", + "import dagger.producers.ProductionSubcomponent;", + "", + "@ProductionSubcomponent", + "interface MyProductionSubcomponent {", + " @ProductionSubcomponent.Builder", + " interface Builder {", + " MyProductionSubcomponent build();", + " }", + "}"); + + CompilerTests.daggerCompiler(myComponent, myModule, myProductionSubcomponent) + .withProcessingOptions( + ImmutableMap.<String, String>builder() + .putAll(compilerMode.processorOptions()) + .put("dagger.pluginsVisitFullBindingGraphs", "ENABLED") + .buildOrThrow()) + .compile(subject -> subject.hasErrorCount(0)); + } + + @Test public void simpleComponent() throws Exception { Source component = CompilerTests.javaSource( diff --git a/javatests/dagger/internal/codegen/ProductionGraphValidationTest.java b/javatests/dagger/internal/codegen/ProductionGraphValidationTest.java index 1b0b85bbd..cfcf8ee88 100644 --- a/javatests/dagger/internal/codegen/ProductionGraphValidationTest.java +++ b/javatests/dagger/internal/codegen/ProductionGraphValidationTest.java @@ -195,14 +195,11 @@ public class ProductionGraphValidationTest { .buildOrThrow()) .compile( subject -> { - subject.hasErrorCount(2); + subject.hasErrorCount(1); subject.hasErrorContaining( "TestClass.A is a provision, which cannot depend on a production.") .onSource(component) .onLineContaining("class AModule"); - subject.hasErrorContaining("test.TestClass.AModule has errors") - .onSource(component) - .onLineContaining("@ProductionComponent"); }); } diff --git a/javatests/dagger/internal/codegen/bindinggraphvalidation/NullableBindingValidationKotlinTest.java b/javatests/dagger/internal/codegen/bindinggraphvalidation/NullableBindingValidationKotlinTest.java index 6b63b7c9b..4b49e1660 100644 --- a/javatests/dagger/internal/codegen/bindinggraphvalidation/NullableBindingValidationKotlinTest.java +++ b/javatests/dagger/internal/codegen/bindinggraphvalidation/NullableBindingValidationKotlinTest.java @@ -18,7 +18,6 @@ package dagger.internal.codegen.bindinggraphvalidation; import static dagger.internal.codegen.bindinggraphvalidation.NullableBindingValidator.nullableToNonNullable; -import androidx.room.compiler.processing.XProcessingEnv; import androidx.room.compiler.processing.util.Source; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -83,12 +82,7 @@ public class NullableBindingValidationKotlinTest { subject.hasErrorContaining( nullableToNonNullable( "String", - CompilerTests.backend(subject) == XProcessingEnv.Backend.JAVAC - ? "@Nullable @Provides String TestModule.provideString()" - // TODO(b/268550160): For KSP, we should be including the kotlin typename - // in the error message, e.g. "String?" otherwise the message doesn't make - // a lot of sense. - : "@Provides String TestModule.provideString()")); + "@Provides @Nullable String TestModule.provideString()")); }); // but if we disable the validation, then it compiles fine. @@ -144,12 +138,7 @@ public class NullableBindingValidationKotlinTest { subject.hasErrorContaining( nullableToNonNullable( "String", - CompilerTests.backend(subject) == XProcessingEnv.Backend.JAVAC - ? "@Nullable @Provides String TestModule.provideString()" - // TODO(b/268550160): For KSP, we should be including the kotlin typename - // in the error message, e.g. "String?" otherwise the message doesn't make - // a lot of sense. - : "@Provides String TestModule.provideString()")); + "@Provides @Nullable String TestModule.provideString()")); }); // but if we disable the validation, then it compiles fine. @@ -205,12 +194,7 @@ public class NullableBindingValidationKotlinTest { subject.hasErrorContaining( nullableToNonNullable( "String", - CompilerTests.backend(subject) == XProcessingEnv.Backend.JAVAC - ? "@Nullable @Provides String TestModule.provideString()" - // TODO(b/268550160): For KSP, we should be including the kotlin typename - // in the error message, e.g. "String?" otherwise the message doesn't make - // a lot of sense. - : "@Provides String TestModule.provideString()")); + "@Provides @Nullable String TestModule.provideString()")); }); // but if we disable the validation, then it compiles fine. @@ -255,12 +239,7 @@ public class NullableBindingValidationKotlinTest { subject.hasErrorContaining( nullableToNonNullable( "String", - CompilerTests.backend(subject) == XProcessingEnv.Backend.JAVAC - ? "@Nullable @Provides String TestModule.provideString()" - // TODO(b/268550160): For KSP, we should be including the kotlin typename - // in the error message, e.g. "String?" otherwise the message doesn't make - // a lot of sense. - : "@Provides String TestModule.provideString()")); + "@Provides @Nullable String TestModule.provideString()")); }); // but if we disable the validation, then it compiles fine. @@ -320,12 +299,7 @@ public class NullableBindingValidationKotlinTest { subject.hasErrorContaining( nullableToNonNullable( "String", - CompilerTests.backend(subject) == XProcessingEnv.Backend.JAVAC - ? "@Nullable @Provides String TestModule.Companion.provideString()" - // TODO(b/268550160): For KSP, we should be including the kotlin typename - // in the error message, e.g. "String?" otherwise the message doesn't make - // a lot of sense. - : "@Provides String TestModule.Companion.provideString()")); + "@Provides @Nullable String TestModule.Companion.provideString()")); }); } @@ -496,12 +470,7 @@ public class NullableBindingValidationKotlinTest { subject.hasErrorContaining( nullableToNonNullable( "String", - CompilerTests.backend(subject) == XProcessingEnv.Backend.JAVAC - ? "@Nullable @Provides String TestModule.Companion.nullableString()" - // TODO(b/268550160): For KSP, we should be including the kotlin typename - // in the error message, e.g. "String?" otherwise the message doesn't make - // a lot of sense. - : "@Provides String TestModule.Companion.nullableString()")); + "@Provides @Nullable String TestModule.Companion.nullableString()")); }); } } diff --git a/javatests/dagger/internal/codegen/bindinggraphvalidation/SetMultibindingValidationTest.java b/javatests/dagger/internal/codegen/bindinggraphvalidation/SetMultibindingValidationTest.java index 8eaccaede..e68099ae4 100644 --- a/javatests/dagger/internal/codegen/bindinggraphvalidation/SetMultibindingValidationTest.java +++ b/javatests/dagger/internal/codegen/bindinggraphvalidation/SetMultibindingValidationTest.java @@ -95,6 +95,85 @@ public class SetMultibindingValidationTest { }); } + // Regression test for b/316582741 to ensure the duplicate binding gets reported rather than + // causing a crash. + @Test public void testSetBindingsToDuplicateBinding() { + Source module = + CompilerTests.javaSource( + "test.TestModule", + "package test;", + "", + "import dagger.Binds;", + "import dagger.Module;", + "import dagger.Provides;", + "import dagger.multibindings.IntoSet;", + "", + "@Module", + "interface TestModule {", + " @Binds @IntoSet Foo bindFoo(FooImpl impl);", + "", + " @Provides static FooImpl provideFooImpl() { return null; }", + "", + " @Provides static FooImpl provideFooImplAgain() { return null; }", + "}"); + Source component = + CompilerTests.javaSource( + "test.TestComponent", + "package test;", + "", + "import dagger.Component;", + "import java.util.Set;", + "", + "@Component(modules = TestModule.class)", + "interface TestComponent {", + " Set<Foo> setOfFoo();", + "}"); + CompilerTests.daggerCompiler(FOO, FOO_IMPL, module, component) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining("FooImpl is bound multiple times"); + }); + } + + @Test public void testSetBindingsToMissingBinding() { + Source module = + CompilerTests.javaSource( + "test.TestModule", + "package test;", + "", + "import dagger.Binds;", + "import dagger.Module;", + "import dagger.multibindings.IntoSet;", + "", + "@Module", + "interface TestModule {", + " @Binds @IntoSet Foo bindFoo(MissingFooImpl impl);", + "", + " static class MissingFooImpl implements Foo {}", + "}"); + Source component = + CompilerTests.javaSource( + "test.TestComponent", + "package test;", + "", + "import dagger.Component;", + "import java.util.Set;", + "", + "@Component(modules = TestModule.class)", + "interface TestComponent {", + " Set<Foo> setOfFoo();", + "}"); + CompilerTests.daggerCompiler(FOO, module, component) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining("MissingFooImpl cannot be provided"); + }); + } + @Test public void testMultipleSetBindingsToSameFooThroughMultipleBinds() { Source module = CompilerTests.javaSource( diff --git a/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_assistedParamConflictsWithComponentFieldName_successfulyDeduped_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_assistedParamConflictsWithComponentFieldName_successfulyDeduped_DEFAULT_MODE_test.DaggerTestComponent index 20f38ddd0..ebea812d2 100644 --- a/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_assistedParamConflictsWithComponentFieldName_successfulyDeduped_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_assistedParamConflictsWithComponentFieldName_successfulyDeduped_DEFAULT_MODE_test.DaggerTestComponent @@ -1,8 +1,8 @@ package test; import dagger.internal.DaggerGenerated; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -13,7 +13,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -52,7 +53,7 @@ final class DaggerTestComponent { @SuppressWarnings("unchecked") private void initialize() { this.fooProvider = Foo_Factory.create(Bar_Factory.create()); - this.fooFactoryProvider = FooFactory_Impl.create(fooProvider); + this.fooFactoryProvider = FooFactory_Impl.createFactoryProvider(fooProvider); } @Override diff --git a/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_assistedParamConflictsWithComponentFieldName_successfulyDeduped_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_assistedParamConflictsWithComponentFieldName_successfulyDeduped_FAST_INIT_MODE_test.DaggerTestComponent index c76a5fbdd..f522a426d 100644 --- a/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_assistedParamConflictsWithComponentFieldName_successfulyDeduped_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_assistedParamConflictsWithComponentFieldName_successfulyDeduped_FAST_INIT_MODE_test.DaggerTestComponent @@ -1,9 +1,9 @@ package test; import dagger.internal.DaggerGenerated; +import dagger.internal.Provider; import dagger.internal.SingleCheck; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -14,7 +14,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testAssistedFactoryCycle_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testAssistedFactoryCycle_DEFAULT_MODE_test.DaggerTestComponent index 7b22b0018..bdd35a5fc 100644 --- a/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testAssistedFactoryCycle_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testAssistedFactoryCycle_DEFAULT_MODE_test.DaggerTestComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DelegateFactory; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -14,7 +14,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -57,7 +58,7 @@ final class DaggerTestComponent { this.fooFactoryProvider = new DelegateFactory<>(); this.barProvider = Bar_Factory.create(fooFactoryProvider); this.fooProvider = Foo_Factory.create(barProvider); - DelegateFactory.setDelegate(fooFactoryProvider, FooFactory_Impl.create(fooProvider)); + DelegateFactory.setDelegate(fooFactoryProvider, FooFactory_Impl.createFactoryProvider(fooProvider)); } @Override diff --git a/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testAssistedFactoryCycle_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testAssistedFactoryCycle_FAST_INIT_MODE_test.DaggerTestComponent index 48f517401..2d5efe691 100644 --- a/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testAssistedFactoryCycle_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testAssistedFactoryCycle_FAST_INIT_MODE_test.DaggerTestComponent @@ -2,9 +2,9 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DelegateFactory; +import dagger.internal.Provider; import dagger.internal.SingleCheck; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -15,7 +15,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testAssistedFactory_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testAssistedFactory_DEFAULT_MODE_test.DaggerTestComponent index 20f38ddd0..ebea812d2 100644 --- a/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testAssistedFactory_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testAssistedFactory_DEFAULT_MODE_test.DaggerTestComponent @@ -1,8 +1,8 @@ package test; import dagger.internal.DaggerGenerated; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -13,7 +13,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -52,7 +53,7 @@ final class DaggerTestComponent { @SuppressWarnings("unchecked") private void initialize() { this.fooProvider = Foo_Factory.create(Bar_Factory.create()); - this.fooFactoryProvider = FooFactory_Impl.create(fooProvider); + this.fooFactoryProvider = FooFactory_Impl.createFactoryProvider(fooProvider); } @Override diff --git a/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testAssistedFactory_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testAssistedFactory_FAST_INIT_MODE_test.DaggerTestComponent index 72f16729c..db44f08dd 100644 --- a/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testAssistedFactory_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testAssistedFactory_FAST_INIT_MODE_test.DaggerTestComponent @@ -1,9 +1,9 @@ package test; import dagger.internal.DaggerGenerated; +import dagger.internal.Provider; import dagger.internal.SingleCheck; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -14,7 +14,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testFactoryGeneratorDuplicatedParamNames_DEFAULT_MODE_test.Foo_Factory b/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testFactoryGeneratorDuplicatedParamNames_DEFAULT_MODE_test.Foo_Factory index ed8f09856..0ae501c07 100644 --- a/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testFactoryGeneratorDuplicatedParamNames_DEFAULT_MODE_test.Foo_Factory +++ b/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testFactoryGeneratorDuplicatedParamNames_DEFAULT_MODE_test.Foo_Factory @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class Foo_Factory { private final Provider<Bar> argProvider; diff --git a/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testFactoryGeneratorDuplicatedParamNames_FAST_INIT_MODE_test.Foo_Factory b/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testFactoryGeneratorDuplicatedParamNames_FAST_INIT_MODE_test.Foo_Factory index ed8f09856..0ae501c07 100644 --- a/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testFactoryGeneratorDuplicatedParamNames_FAST_INIT_MODE_test.Foo_Factory +++ b/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testFactoryGeneratorDuplicatedParamNames_FAST_INIT_MODE_test.Foo_Factory @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class Foo_Factory { private final Provider<Bar> argProvider; diff --git a/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testMultipleAssistedFactoryInDifferentComponents_DEFAULT_MODE_test.DaggerMyComponent b/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testMultipleAssistedFactoryInDifferentComponents_DEFAULT_MODE_test.DaggerMyComponent new file mode 100644 index 000000000..b3fc31665 --- /dev/null +++ b/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testMultipleAssistedFactoryInDifferentComponents_DEFAULT_MODE_test.DaggerMyComponent @@ -0,0 +1,98 @@ +package test; + +import dagger.internal.DaggerGenerated; +import dagger.internal.Provider; +import javax.annotation.processing.Generated; + +@DaggerGenerated +@Generated( + value = "dagger.internal.codegen.ComponentProcessor", + comments = "https://dagger.dev" +) +@SuppressWarnings({ + "unchecked", + "rawtypes", + "KotlinInternal", + "KotlinInternalInJava", + "cast" +}) +final class DaggerMyComponent { + private DaggerMyComponent() { + } + + public static Builder builder() { + return new Builder(); + } + + public static MyComponent create() { + return new Builder().build(); + } + + static final class Builder { + private Builder() { + } + + public MyComponent build() { + return new MyComponentImpl(); + } + } + + private static final class MySubcomponentImpl implements MySubcomponent { + private final MyComponentImpl myComponentImpl; + + private final MySubcomponentImpl mySubcomponentImpl = this; + + private MyAssistedClass_Factory myAssistedClassProvider; + + private Provider<MySubcomponentAssistedFactory> mySubcomponentAssistedFactoryProvider; + + private MySubcomponentImpl(MyComponentImpl myComponentImpl) { + this.myComponentImpl = myComponentImpl; + + initialize(); + + } + + @SuppressWarnings("unchecked") + private void initialize() { + this.myAssistedClassProvider = MyAssistedClass_Factory.create(Baz_Factory.create()); + this.mySubcomponentAssistedFactoryProvider = MySubcomponentAssistedFactory_Impl.createFactoryProvider(myAssistedClassProvider); + } + + @Override + public MySubcomponentAssistedFactory mySubcomponentAssistedFactory() { + return mySubcomponentAssistedFactoryProvider.get(); + } + } + + private static final class MyComponentImpl implements MyComponent { + private final MyComponentImpl myComponentImpl = this; + + private MyAssistedClass_Factory myAssistedClassProvider; + + private Provider<MyComponentAssistedFactory> myComponentAssistedFactoryProvider; + + private MyComponentImpl() { + + initialize(); + + } + + @SuppressWarnings("unchecked") + private void initialize() { + this.myAssistedClassProvider = MyAssistedClass_Factory.create(Baz_Factory.create()); + this.myComponentAssistedFactoryProvider = MyComponentAssistedFactory_Impl.createFactoryProvider(myAssistedClassProvider); + } + + @Override + public MyComponentAssistedFactory myComponentAssistedFactory() { + return myComponentAssistedFactoryProvider.get(); + } + + @Override + public MySubcomponent mySubcomponent() { + return new MySubcomponentImpl(myComponentImpl); + } + } +} + diff --git a/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testMultipleAssistedFactoryInDifferentComponents_FAST_INIT_MODE_test.DaggerMyComponent b/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testMultipleAssistedFactoryInDifferentComponents_FAST_INIT_MODE_test.DaggerMyComponent new file mode 100644 index 000000000..68c5a77d0 --- /dev/null +++ b/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testMultipleAssistedFactoryInDifferentComponents_FAST_INIT_MODE_test.DaggerMyComponent @@ -0,0 +1,151 @@ +package test; + +import dagger.internal.DaggerGenerated; +import dagger.internal.Provider; +import dagger.internal.SingleCheck; +import javax.annotation.processing.Generated; + +@DaggerGenerated +@Generated( + value = "dagger.internal.codegen.ComponentProcessor", + comments = "https://dagger.dev" +) +@SuppressWarnings({ + "unchecked", + "rawtypes", + "KotlinInternal", + "KotlinInternalInJava", + "cast" +}) +final class DaggerMyComponent { + private DaggerMyComponent() { + } + + public static Builder builder() { + return new Builder(); + } + + public static MyComponent create() { + return new Builder().build(); + } + + static final class Builder { + private Builder() { + } + + public MyComponent build() { + return new MyComponentImpl(); + } + } + + private static final class MySubcomponentImpl implements MySubcomponent { + private final MyComponentImpl myComponentImpl; + + private final MySubcomponentImpl mySubcomponentImpl = this; + + private Provider<MySubcomponentAssistedFactory> mySubcomponentAssistedFactoryProvider; + + private MySubcomponentImpl(MyComponentImpl myComponentImpl) { + this.myComponentImpl = myComponentImpl; + + initialize(); + + } + + @SuppressWarnings("unchecked") + private void initialize() { + this.mySubcomponentAssistedFactoryProvider = SingleCheck.provider(new SwitchingProvider<MySubcomponentAssistedFactory>(myComponentImpl, mySubcomponentImpl, 0)); + } + + @Override + public MySubcomponentAssistedFactory mySubcomponentAssistedFactory() { + return mySubcomponentAssistedFactoryProvider.get(); + } + + private static final class SwitchingProvider<T> implements Provider<T> { + private final MyComponentImpl myComponentImpl; + + private final MySubcomponentImpl mySubcomponentImpl; + + private final int id; + + SwitchingProvider(MyComponentImpl myComponentImpl, MySubcomponentImpl mySubcomponentImpl, + int id) { + this.myComponentImpl = myComponentImpl; + this.mySubcomponentImpl = mySubcomponentImpl; + this.id = id; + } + + @SuppressWarnings("unchecked") + @Override + public T get() { + switch (id) { + case 0: // test.MySubcomponentAssistedFactory + return (T) new MySubcomponentAssistedFactory() { + @Override + public MyAssistedClass create(Bar bar, Foo foo) { + return new MyAssistedClass(foo, new Baz(), bar); + } + }; + + default: throw new AssertionError(id); + } + } + } + } + + private static final class MyComponentImpl implements MyComponent { + private final MyComponentImpl myComponentImpl = this; + + private Provider<MyComponentAssistedFactory> myComponentAssistedFactoryProvider; + + private MyComponentImpl() { + + initialize(); + + } + + @SuppressWarnings("unchecked") + private void initialize() { + this.myComponentAssistedFactoryProvider = SingleCheck.provider(new SwitchingProvider<MyComponentAssistedFactory>(myComponentImpl, 0)); + } + + @Override + public MyComponentAssistedFactory myComponentAssistedFactory() { + return myComponentAssistedFactoryProvider.get(); + } + + @Override + public MySubcomponent mySubcomponent() { + return new MySubcomponentImpl(myComponentImpl); + } + + private static final class SwitchingProvider<T> implements Provider<T> { + private final MyComponentImpl myComponentImpl; + + private final int id; + + SwitchingProvider(MyComponentImpl myComponentImpl, int id) { + this.myComponentImpl = myComponentImpl; + this.id = id; + } + + @SuppressWarnings("unchecked") + @Override + public T get() { + switch (id) { + case 0: // test.MyComponentAssistedFactory + return (T) new MyComponentAssistedFactory() { + @Override + public MyAssistedClass create(Bar bar, Foo foo) { + return new MyAssistedClass(foo, new Baz(), bar); + } + }; + + default: throw new AssertionError(id); + } + } + } + } +} + diff --git a/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testParameterizedAssistParam_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testParameterizedAssistParam_DEFAULT_MODE_test.DaggerTestComponent index da1f53e75..f94d608f7 100644 --- a/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testParameterizedAssistParam_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testParameterizedAssistParam_DEFAULT_MODE_test.DaggerTestComponent @@ -1,8 +1,8 @@ package test; import dagger.internal.DaggerGenerated; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -13,7 +13,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -52,7 +53,7 @@ final class DaggerTestComponent { @SuppressWarnings("unchecked") private void initialize() { this.fooProvider = Foo_Factory.create(); - this.fooFactoryProvider = FooFactory_Impl.create(fooProvider); + this.fooFactoryProvider = FooFactory_Impl.createFactoryProvider(fooProvider); } @Override diff --git a/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testParameterizedAssistParam_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testParameterizedAssistParam_FAST_INIT_MODE_test.DaggerTestComponent index a56b3e084..0726e0fe2 100644 --- a/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testParameterizedAssistParam_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testParameterizedAssistParam_FAST_INIT_MODE_test.DaggerTestComponent @@ -1,9 +1,9 @@ package test; import dagger.internal.DaggerGenerated; +import dagger.internal.Provider; import dagger.internal.SingleCheck; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -14,7 +14,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentBuilderTest_testUsesBuildAndSetterNames_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentBuilderTest_testUsesBuildAndSetterNames_DEFAULT_MODE_test.DaggerTestComponent index f5524ec83..7aed6ce53 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentBuilderTest_testUsesBuildAndSetterNames_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentBuilderTest_testUsesBuildAndSetterNames_DEFAULT_MODE_test.DaggerTestComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentBuilderTest_testUsesBuildAndSetterNames_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentBuilderTest_testUsesBuildAndSetterNames_FAST_INIT_MODE_test.DaggerTestComponent index f5524ec83..7aed6ce53 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentBuilderTest_testUsesBuildAndSetterNames_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentBuilderTest_testUsesBuildAndSetterNames_FAST_INIT_MODE_test.DaggerTestComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCanInstantiateModulesUserCannotSet_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Builder_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCanInstantiateModulesUserCannotSet_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Builder_test.DaggerTestComponent index fd3b2dde2..384875abb 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCanInstantiateModulesUserCannotSet_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Builder_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCanInstantiateModulesUserCannotSet_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Builder_test.DaggerTestComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCanInstantiateModulesUserCannotSet_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Factory_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCanInstantiateModulesUserCannotSet_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Factory_test.DaggerTestComponent index e2e2d9383..b4fa61912 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCanInstantiateModulesUserCannotSet_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Factory_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCanInstantiateModulesUserCannotSet_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Factory_test.DaggerTestComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCanInstantiateModulesUserCannotSet_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Builder_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCanInstantiateModulesUserCannotSet_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Builder_test.DaggerTestComponent index fd3b2dde2..384875abb 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCanInstantiateModulesUserCannotSet_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Builder_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCanInstantiateModulesUserCannotSet_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Builder_test.DaggerTestComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCanInstantiateModulesUserCannotSet_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Factory_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCanInstantiateModulesUserCannotSet_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Factory_test.DaggerTestComponent index e2e2d9383..b4fa61912 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCanInstantiateModulesUserCannotSet_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Factory_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCanInstantiateModulesUserCannotSet_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Factory_test.DaggerTestComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithBindsInstanceNoStaticCreateGenerated_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Builder_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithBindsInstanceNoStaticCreateGenerated_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Builder_test.DaggerSimpleComponent index dd9662b7c..510db53fb 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithBindsInstanceNoStaticCreateGenerated_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Builder_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithBindsInstanceNoStaticCreateGenerated_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Builder_test.DaggerSimpleComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithBindsInstanceNoStaticCreateGenerated_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Factory_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithBindsInstanceNoStaticCreateGenerated_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Factory_test.DaggerSimpleComponent index 05ac4a822..c31b4abaf 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithBindsInstanceNoStaticCreateGenerated_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Factory_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithBindsInstanceNoStaticCreateGenerated_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Factory_test.DaggerSimpleComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithBindsInstanceNoStaticCreateGenerated_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Builder_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithBindsInstanceNoStaticCreateGenerated_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Builder_test.DaggerSimpleComponent index dd9662b7c..510db53fb 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithBindsInstanceNoStaticCreateGenerated_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Builder_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithBindsInstanceNoStaticCreateGenerated_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Builder_test.DaggerSimpleComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithBindsInstanceNoStaticCreateGenerated_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Factory_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithBindsInstanceNoStaticCreateGenerated_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Factory_test.DaggerSimpleComponent index 05ac4a822..c31b4abaf 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithBindsInstanceNoStaticCreateGenerated_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Factory_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithBindsInstanceNoStaticCreateGenerated_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Factory_test.DaggerSimpleComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithPrimitiveBindsInstance_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Builder_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithPrimitiveBindsInstance_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Builder_test.DaggerSimpleComponent index bbfedd0e1..77058c340 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithPrimitiveBindsInstance_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Builder_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithPrimitiveBindsInstance_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Builder_test.DaggerSimpleComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithPrimitiveBindsInstance_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Factory_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithPrimitiveBindsInstance_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Factory_test.DaggerSimpleComponent index fb85bebc1..6583a231d 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithPrimitiveBindsInstance_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Factory_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithPrimitiveBindsInstance_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Factory_test.DaggerSimpleComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithPrimitiveBindsInstance_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Builder_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithPrimitiveBindsInstance_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Builder_test.DaggerSimpleComponent index bbfedd0e1..77058c340 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithPrimitiveBindsInstance_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Builder_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithPrimitiveBindsInstance_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Builder_test.DaggerSimpleComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithPrimitiveBindsInstance_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Factory_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithPrimitiveBindsInstance_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Factory_test.DaggerSimpleComponent index fb85bebc1..6583a231d 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithPrimitiveBindsInstance_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Factory_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testCreatorWithPrimitiveBindsInstance_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Factory_test.DaggerSimpleComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testEmptyCreator_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Builder_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testEmptyCreator_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Builder_test.DaggerSimpleComponent index b117ad872..5040a7824 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testEmptyCreator_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Builder_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testEmptyCreator_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Builder_test.DaggerSimpleComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testEmptyCreator_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Factory_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testEmptyCreator_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Factory_test.DaggerSimpleComponent index 3e078be16..10bc3656c 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testEmptyCreator_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Factory_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testEmptyCreator_compilerMode=DEFAULT_MODE, creatorKind=dagger.Component.Factory_test.DaggerSimpleComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testEmptyCreator_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Builder_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testEmptyCreator_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Builder_test.DaggerSimpleComponent index b117ad872..5040a7824 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testEmptyCreator_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Builder_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testEmptyCreator_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Builder_test.DaggerSimpleComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testEmptyCreator_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Factory_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testEmptyCreator_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Factory_test.DaggerSimpleComponent index 3e078be16..10bc3656c 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testEmptyCreator_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Factory_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentCreatorTest_testEmptyCreator_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Component.Factory_test.DaggerSimpleComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentFactoryTest_testUsesParameterNames_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentFactoryTest_testUsesParameterNames_DEFAULT_MODE_test.DaggerTestComponent index d91808344..ac6ba38c2 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentFactoryTest_testUsesParameterNames_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentFactoryTest_testUsesParameterNames_DEFAULT_MODE_test.DaggerTestComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentFactoryTest_testUsesParameterNames_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentFactoryTest_testUsesParameterNames_FAST_INIT_MODE_test.DaggerTestComponent index d91808344..ac6ba38c2 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentFactoryTest_testUsesParameterNames_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentFactoryTest_testUsesParameterNames_FAST_INIT_MODE_test.DaggerTestComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_arrayComponentDependency_DEFAULT_MODE_test.DaggerBComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_arrayComponentDependency_DEFAULT_MODE_test.DaggerBComponent index a3127fbf0..dc3a6e78e 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_arrayComponentDependency_DEFAULT_MODE_test.DaggerBComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_arrayComponentDependency_DEFAULT_MODE_test.DaggerBComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.Preconditions; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -14,7 +14,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerBComponent { private DaggerBComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_arrayComponentDependency_FAST_INIT_MODE_test.DaggerBComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_arrayComponentDependency_FAST_INIT_MODE_test.DaggerBComponent index bb09e8b6e..87aba7d21 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_arrayComponentDependency_FAST_INIT_MODE_test.DaggerBComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_arrayComponentDependency_FAST_INIT_MODE_test.DaggerBComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.Preconditions; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -14,7 +14,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerBComponent { private DaggerBComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentDependency_DEFAULT_MODE_test.DaggerBComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentDependency_DEFAULT_MODE_test.DaggerBComponent index eb9476a7b..0626b32cd 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentDependency_DEFAULT_MODE_test.DaggerBComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentDependency_DEFAULT_MODE_test.DaggerBComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.Preconditions; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -14,7 +14,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerBComponent { private DaggerBComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentDependency_FAST_INIT_MODE_test.DaggerBComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentDependency_FAST_INIT_MODE_test.DaggerBComponent index 7a97ba515..26b5f28dc 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentDependency_FAST_INIT_MODE_test.DaggerBComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentDependency_FAST_INIT_MODE_test.DaggerBComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.Preconditions; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -14,7 +14,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerBComponent { private DaggerBComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentInjection_DEFAULT_MODE_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentInjection_DEFAULT_MODE_test.DaggerSimpleComponent index e32f689d6..66af8f585 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentInjection_DEFAULT_MODE_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentInjection_DEFAULT_MODE_test.DaggerSimpleComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.InstanceFactory; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -14,7 +14,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { @@ -59,7 +60,7 @@ final class DaggerSimpleComponent { } @Override - public Provider<SimpleComponent> selfProvider() { + public javax.inject.Provider<SimpleComponent> selfProvider() { return simpleComponentProvider; } } diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentInjection_FAST_INIT_MODE_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentInjection_FAST_INIT_MODE_test.DaggerSimpleComponent index 4f9289e45..4ce6af3aa 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentInjection_FAST_INIT_MODE_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentInjection_FAST_INIT_MODE_test.DaggerSimpleComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.InstanceFactory; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -14,7 +14,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { @@ -59,7 +60,7 @@ final class DaggerSimpleComponent { } @Override - public Provider<SimpleComponent> selfProvider() { + public javax.inject.Provider<SimpleComponent> selfProvider() { return simpleComponentProvider; } } diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentMethodInChildCallsComponentMethodInParent_DEFAULT_MODE_test.DaggerParent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentMethodInChildCallsComponentMethodInParent_DEFAULT_MODE_test.DaggerParent index 1d5bc09cb..2f1124bd2 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentMethodInChildCallsComponentMethodInParent_DEFAULT_MODE_test.DaggerParent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentMethodInChildCallsComponentMethodInParent_DEFAULT_MODE_test.DaggerParent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -14,7 +14,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParent { private DaggerParent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentMethodInChildCallsComponentMethodInParent_FAST_INIT_MODE_test.DaggerParent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentMethodInChildCallsComponentMethodInParent_FAST_INIT_MODE_test.DaggerParent index af0cdb92e..7d9a5d3c9 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentMethodInChildCallsComponentMethodInParent_FAST_INIT_MODE_test.DaggerParent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentMethodInChildCallsComponentMethodInParent_FAST_INIT_MODE_test.DaggerParent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -14,7 +14,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParent { private DaggerParent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentWithAbstractModule_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentWithAbstractModule_DEFAULT_MODE_test.DaggerTestComponent index 8726e7218..03fcd70cf 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentWithAbstractModule_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentWithAbstractModule_DEFAULT_MODE_test.DaggerTestComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentWithAbstractModule_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentWithAbstractModule_FAST_INIT_MODE_test.DaggerTestComponent index 8726e7218..03fcd70cf 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentWithAbstractModule_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentWithAbstractModule_FAST_INIT_MODE_test.DaggerTestComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentWithModule_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentWithModule_DEFAULT_MODE_test.DaggerTestComponent index fddeb7c1c..8d8ddad62 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentWithModule_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentWithModule_DEFAULT_MODE_test.DaggerTestComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentWithModule_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentWithModule_FAST_INIT_MODE_test.DaggerTestComponent index fddeb7c1c..8d8ddad62 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentWithModule_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentWithModule_FAST_INIT_MODE_test.DaggerTestComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentWithScope_DEFAULT_MODE_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentWithScope_DEFAULT_MODE_test.DaggerSimpleComponent index 76f413869..b79b07de8 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentWithScope_DEFAULT_MODE_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentWithScope_DEFAULT_MODE_test.DaggerSimpleComponent @@ -3,8 +3,8 @@ package test; import dagger.Lazy; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -15,7 +15,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { @@ -65,7 +66,7 @@ final class DaggerSimpleComponent { } @Override - public Provider<SomeInjectableType> someInjectableTypeProvider() { + public javax.inject.Provider<SomeInjectableType> someInjectableTypeProvider() { return someInjectableTypeProvider; } } diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentWithScope_FAST_INIT_MODE_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentWithScope_FAST_INIT_MODE_test.DaggerSimpleComponent index 20d695da5..e89783cc9 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentWithScope_FAST_INIT_MODE_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_componentWithScope_FAST_INIT_MODE_test.DaggerSimpleComponent @@ -3,8 +3,8 @@ package test; import dagger.Lazy; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -15,7 +15,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { @@ -65,7 +66,7 @@ final class DaggerSimpleComponent { } @Override - public Provider<SomeInjectableType> someInjectableTypeProvider() { + public javax.inject.Provider<SomeInjectableType> someInjectableTypeProvider() { return someInjectableTypeProvider; } diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_dependencyNameCollision_DEFAULT_MODE_test.DaggerBComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_dependencyNameCollision_DEFAULT_MODE_test.DaggerBComponent index b8284979d..a2d1d8595 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_dependencyNameCollision_DEFAULT_MODE_test.DaggerBComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_dependencyNameCollision_DEFAULT_MODE_test.DaggerBComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.Preconditions; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; import pkg1.A; import pkg1.AComponent; @@ -16,7 +16,8 @@ import pkg1.AComponent; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerBComponent { private DaggerBComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_dependencyNameCollision_FAST_INIT_MODE_test.DaggerBComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_dependencyNameCollision_FAST_INIT_MODE_test.DaggerBComponent index 99a7e4271..42a0386cb 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_dependencyNameCollision_FAST_INIT_MODE_test.DaggerBComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_dependencyNameCollision_FAST_INIT_MODE_test.DaggerBComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.Preconditions; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; import pkg1.A; import pkg1.AComponent; @@ -16,7 +16,8 @@ import pkg1.AComponent; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerBComponent { private DaggerBComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_ignoresDependencyMethodsFromObject_DEFAULT_MODE_test.DaggerBComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_ignoresDependencyMethodsFromObject_DEFAULT_MODE_test.DaggerBComponent index 0373c5369..b284dbdbf 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_ignoresDependencyMethodsFromObject_DEFAULT_MODE_test.DaggerBComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_ignoresDependencyMethodsFromObject_DEFAULT_MODE_test.DaggerBComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerBComponent { private DaggerBComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_ignoresDependencyMethodsFromObject_FAST_INIT_MODE_test.DaggerBComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_ignoresDependencyMethodsFromObject_FAST_INIT_MODE_test.DaggerBComponent index 0373c5369..b284dbdbf 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_ignoresDependencyMethodsFromObject_FAST_INIT_MODE_test.DaggerBComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_ignoresDependencyMethodsFromObject_FAST_INIT_MODE_test.DaggerBComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerBComponent { private DaggerBComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_justInTimeAtInjectConstructor_hasGeneratedQualifier_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_justInTimeAtInjectConstructor_hasGeneratedQualifier_DEFAULT_MODE_test.DaggerTestComponent index 264aeb32e..898e8772a 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_justInTimeAtInjectConstructor_hasGeneratedQualifier_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_justInTimeAtInjectConstructor_hasGeneratedQualifier_DEFAULT_MODE_test.DaggerTestComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_justInTimeAtInjectConstructor_hasGeneratedQualifier_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_justInTimeAtInjectConstructor_hasGeneratedQualifier_FAST_INIT_MODE_test.DaggerTestComponent index 264aeb32e..898e8772a 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_justInTimeAtInjectConstructor_hasGeneratedQualifier_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_justInTimeAtInjectConstructor_hasGeneratedQualifier_FAST_INIT_MODE_test.DaggerTestComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_membersInjection_DEFAULT_MODE_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_membersInjection_DEFAULT_MODE_test.DaggerSimpleComponent index e4330ef54..d991e42c0 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_membersInjection_DEFAULT_MODE_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_membersInjection_DEFAULT_MODE_test.DaggerSimpleComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_membersInjection_FAST_INIT_MODE_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_membersInjection_FAST_INIT_MODE_test.DaggerSimpleComponent index e4330ef54..d991e42c0 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_membersInjection_FAST_INIT_MODE_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_membersInjection_FAST_INIT_MODE_test.DaggerSimpleComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_moduleHasGeneratedQualifier_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_moduleHasGeneratedQualifier_DEFAULT_MODE_test.DaggerTestComponent index f7515ed3a..dd932010a 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_moduleHasGeneratedQualifier_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_moduleHasGeneratedQualifier_DEFAULT_MODE_test.DaggerTestComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_moduleHasGeneratedQualifier_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_moduleHasGeneratedQualifier_FAST_INIT_MODE_test.DaggerTestComponent index f7515ed3a..dd932010a 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_moduleHasGeneratedQualifier_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_moduleHasGeneratedQualifier_FAST_INIT_MODE_test.DaggerTestComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_moduleNameCollision_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_moduleNameCollision_DEFAULT_MODE_test.DaggerTestComponent index 137e599c5..872646f4a 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_moduleNameCollision_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_moduleNameCollision_DEFAULT_MODE_test.DaggerTestComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_moduleNameCollision_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_moduleNameCollision_FAST_INIT_MODE_test.DaggerTestComponent index 137e599c5..872646f4a 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_moduleNameCollision_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_moduleNameCollision_FAST_INIT_MODE_test.DaggerTestComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullCheckingIgnoredWhenProviderReturnsPrimitive_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullCheckingIgnoredWhenProviderReturnsPrimitive_DEFAULT_MODE_test.DaggerTestComponent index 0aaa8d869..b9a27ebd0 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullCheckingIgnoredWhenProviderReturnsPrimitive_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullCheckingIgnoredWhenProviderReturnsPrimitive_DEFAULT_MODE_test.DaggerTestComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullCheckingIgnoredWhenProviderReturnsPrimitive_DEFAULT_MODE_test.TestModule_PrimitiveIntegerFactory b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullCheckingIgnoredWhenProviderReturnsPrimitive_DEFAULT_MODE_test.TestModule_PrimitiveIntegerFactory index 4b0e55769..4caa6e1ac 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullCheckingIgnoredWhenProviderReturnsPrimitive_DEFAULT_MODE_test.TestModule_PrimitiveIntegerFactory +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullCheckingIgnoredWhenProviderReturnsPrimitive_DEFAULT_MODE_test.TestModule_PrimitiveIntegerFactory @@ -17,7 +17,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class TestModule_PrimitiveIntegerFactory implements Factory<Integer> { @Override diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullCheckingIgnoredWhenProviderReturnsPrimitive_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullCheckingIgnoredWhenProviderReturnsPrimitive_FAST_INIT_MODE_test.DaggerTestComponent index 0aaa8d869..b9a27ebd0 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullCheckingIgnoredWhenProviderReturnsPrimitive_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullCheckingIgnoredWhenProviderReturnsPrimitive_FAST_INIT_MODE_test.DaggerTestComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullCheckingIgnoredWhenProviderReturnsPrimitive_FAST_INIT_MODE_test.TestModule_PrimitiveIntegerFactory b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullCheckingIgnoredWhenProviderReturnsPrimitive_FAST_INIT_MODE_test.TestModule_PrimitiveIntegerFactory index 4b0e55769..4caa6e1ac 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullCheckingIgnoredWhenProviderReturnsPrimitive_FAST_INIT_MODE_test.TestModule_PrimitiveIntegerFactory +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullCheckingIgnoredWhenProviderReturnsPrimitive_FAST_INIT_MODE_test.TestModule_PrimitiveIntegerFactory @@ -17,7 +17,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class TestModule_PrimitiveIntegerFactory implements Factory<Integer> { @Override diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullIncorrectlyReturnedFromNonNullableInlinedProvider_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullIncorrectlyReturnedFromNonNullableInlinedProvider_DEFAULT_MODE_test.DaggerTestComponent index 17727c090..54425a70b 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullIncorrectlyReturnedFromNonNullableInlinedProvider_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullIncorrectlyReturnedFromNonNullableInlinedProvider_DEFAULT_MODE_test.DaggerTestComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullIncorrectlyReturnedFromNonNullableInlinedProvider_DEFAULT_MODE_test.TestModule_NonNullableStringFactory b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullIncorrectlyReturnedFromNonNullableInlinedProvider_DEFAULT_MODE_test.TestModule_NonNullableStringFactory index a19af9696..96e870822 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullIncorrectlyReturnedFromNonNullableInlinedProvider_DEFAULT_MODE_test.TestModule_NonNullableStringFactory +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullIncorrectlyReturnedFromNonNullableInlinedProvider_DEFAULT_MODE_test.TestModule_NonNullableStringFactory @@ -18,7 +18,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class TestModule_NonNullableStringFactory implements Factory<String> { @Override diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullIncorrectlyReturnedFromNonNullableInlinedProvider_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullIncorrectlyReturnedFromNonNullableInlinedProvider_FAST_INIT_MODE_test.DaggerTestComponent index 17727c090..54425a70b 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullIncorrectlyReturnedFromNonNullableInlinedProvider_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullIncorrectlyReturnedFromNonNullableInlinedProvider_FAST_INIT_MODE_test.DaggerTestComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullIncorrectlyReturnedFromNonNullableInlinedProvider_FAST_INIT_MODE_test.TestModule_NonNullableStringFactory b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullIncorrectlyReturnedFromNonNullableInlinedProvider_FAST_INIT_MODE_test.TestModule_NonNullableStringFactory index a19af9696..96e870822 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullIncorrectlyReturnedFromNonNullableInlinedProvider_FAST_INIT_MODE_test.TestModule_NonNullableStringFactory +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_nullIncorrectlyReturnedFromNonNullableInlinedProvider_FAST_INIT_MODE_test.TestModule_NonNullableStringFactory @@ -18,7 +18,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class TestModule_NonNullableStringFactory implements Factory<String> { @Override diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_primitiveComponentDependency_DEFAULT_MODE_test.DaggerBComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_primitiveComponentDependency_DEFAULT_MODE_test.DaggerBComponent index 755b402f9..c1a2108c7 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_primitiveComponentDependency_DEFAULT_MODE_test.DaggerBComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_primitiveComponentDependency_DEFAULT_MODE_test.DaggerBComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.Preconditions; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -14,7 +14,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerBComponent { private DaggerBComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_primitiveComponentDependency_FAST_INIT_MODE_test.DaggerBComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_primitiveComponentDependency_FAST_INIT_MODE_test.DaggerBComponent index 6ce1e2451..d88c74ec3 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_primitiveComponentDependency_FAST_INIT_MODE_test.DaggerBComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_primitiveComponentDependency_FAST_INIT_MODE_test.DaggerBComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.Preconditions; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -14,7 +14,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerBComponent { private DaggerBComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_privateMethodUsedOnlyInChildDoesNotUseQualifiedThis_DEFAULT_MODE_test.DaggerParent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_privateMethodUsedOnlyInChildDoesNotUseQualifiedThis_DEFAULT_MODE_test.DaggerParent index f26d8a5bb..73f067ba2 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_privateMethodUsedOnlyInChildDoesNotUseQualifiedThis_DEFAULT_MODE_test.DaggerParent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_privateMethodUsedOnlyInChildDoesNotUseQualifiedThis_DEFAULT_MODE_test.DaggerParent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -14,7 +14,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParent { private DaggerParent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_privateMethodUsedOnlyInChildDoesNotUseQualifiedThis_FAST_INIT_MODE_test.DaggerParent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_privateMethodUsedOnlyInChildDoesNotUseQualifiedThis_FAST_INIT_MODE_test.DaggerParent index 5edc873ff..c20b8f062 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_privateMethodUsedOnlyInChildDoesNotUseQualifiedThis_FAST_INIT_MODE_test.DaggerParent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_privateMethodUsedOnlyInChildDoesNotUseQualifiedThis_FAST_INIT_MODE_test.DaggerParent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -14,7 +14,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParent { private DaggerParent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_providerComponentType_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_providerComponentType_DEFAULT_MODE_test.DaggerTestComponent index 19c4c90bf..5558c81a8 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_providerComponentType_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_providerComponentType_DEFAULT_MODE_test.DaggerTestComponent @@ -1,8 +1,8 @@ package test; import dagger.internal.DaggerGenerated; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -13,7 +13,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_providerComponentType_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_providerComponentType_FAST_INIT_MODE_test.DaggerTestComponent index 0af158555..e19505d67 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_providerComponentType_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_providerComponentType_FAST_INIT_MODE_test.DaggerTestComponent @@ -1,8 +1,8 @@ package test; import dagger.internal.DaggerGenerated; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -13,7 +13,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_publicComponentType_DEFAULT_MODE_test.DaggerPublicComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_publicComponentType_DEFAULT_MODE_test.DaggerPublicComponent index 71341f026..48c0f34a9 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_publicComponentType_DEFAULT_MODE_test.DaggerPublicComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_publicComponentType_DEFAULT_MODE_test.DaggerPublicComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class DaggerPublicComponent { private DaggerPublicComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_publicComponentType_FAST_INIT_MODE_test.DaggerPublicComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_publicComponentType_FAST_INIT_MODE_test.DaggerPublicComponent index 71341f026..48c0f34a9 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_publicComponentType_FAST_INIT_MODE_test.DaggerPublicComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_publicComponentType_FAST_INIT_MODE_test.DaggerPublicComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class DaggerPublicComponent { private DaggerPublicComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_resolutionOrder_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_resolutionOrder_DEFAULT_MODE_test.DaggerTestComponent index 6841e9363..22771bbf0 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_resolutionOrder_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_resolutionOrder_DEFAULT_MODE_test.DaggerTestComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_resolutionOrder_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_resolutionOrder_FAST_INIT_MODE_test.DaggerTestComponent index 6841e9363..22771bbf0 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_resolutionOrder_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_resolutionOrder_FAST_INIT_MODE_test.DaggerTestComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponentWithNesting_DEFAULT_MODE_test.DaggerOuterType_SimpleComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponentWithNesting_DEFAULT_MODE_test.DaggerOuterType_SimpleComponent index 37ea93066..1a79810f8 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponentWithNesting_DEFAULT_MODE_test.DaggerOuterType_SimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponentWithNesting_DEFAULT_MODE_test.DaggerOuterType_SimpleComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerOuterType_SimpleComponent { private DaggerOuterType_SimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponentWithNesting_FAST_INIT_MODE_test.DaggerOuterType_SimpleComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponentWithNesting_FAST_INIT_MODE_test.DaggerOuterType_SimpleComponent index 37ea93066..1a79810f8 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponentWithNesting_FAST_INIT_MODE_test.DaggerOuterType_SimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponentWithNesting_FAST_INIT_MODE_test.DaggerOuterType_SimpleComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerOuterType_SimpleComponent { private DaggerOuterType_SimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponent_DEFAULT_MODE_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponent_DEFAULT_MODE_test.DaggerSimpleComponent index 9e46639a8..e1e3f6442 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponent_DEFAULT_MODE_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponent_DEFAULT_MODE_test.DaggerSimpleComponent @@ -15,7 +15,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponent_FAST_INIT_MODE_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponent_FAST_INIT_MODE_test.DaggerSimpleComponent index d92a70e85..094c1ff24 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponent_FAST_INIT_MODE_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponent_FAST_INIT_MODE_test.DaggerSimpleComponent @@ -3,8 +3,8 @@ package test; import dagger.Lazy; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -15,7 +15,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { @@ -65,7 +66,7 @@ final class DaggerSimpleComponent { } @Override - public Provider<SomeInjectableType> someInjectableTypeProvider() { + public javax.inject.Provider<SomeInjectableType> someInjectableTypeProvider() { return someInjectableTypeProvider; } diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponent_inheritedComponentMethodDep_DEFAULT_MODE_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponent_inheritedComponentMethodDep_DEFAULT_MODE_test.DaggerSimpleComponent index 630073e96..108b13d68 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponent_inheritedComponentMethodDep_DEFAULT_MODE_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponent_inheritedComponentMethodDep_DEFAULT_MODE_test.DaggerSimpleComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponent_inheritedComponentMethodDep_FAST_INIT_MODE_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponent_inheritedComponentMethodDep_FAST_INIT_MODE_test.DaggerSimpleComponent index 630073e96..108b13d68 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponent_inheritedComponentMethodDep_FAST_INIT_MODE_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponent_inheritedComponentMethodDep_FAST_INIT_MODE_test.DaggerSimpleComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponent_redundantComponentMethod_DEFAULT_MODE_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponent_redundantComponentMethod_DEFAULT_MODE_test.DaggerSimpleComponent index 630073e96..108b13d68 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponent_redundantComponentMethod_DEFAULT_MODE_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponent_redundantComponentMethod_DEFAULT_MODE_test.DaggerSimpleComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponent_redundantComponentMethod_FAST_INIT_MODE_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponent_redundantComponentMethod_FAST_INIT_MODE_test.DaggerSimpleComponent index 630073e96..108b13d68 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponent_redundantComponentMethod_FAST_INIT_MODE_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_simpleComponent_redundantComponentMethod_FAST_INIT_MODE_test.DaggerSimpleComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_subcomponentNotGeneratedIfNotUsedInGraph_DEFAULT_MODE_test.DaggerParent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_subcomponentNotGeneratedIfNotUsedInGraph_DEFAULT_MODE_test.DaggerParent index 9447a4730..c630533eb 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_subcomponentNotGeneratedIfNotUsedInGraph_DEFAULT_MODE_test.DaggerParent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_subcomponentNotGeneratedIfNotUsedInGraph_DEFAULT_MODE_test.DaggerParent @@ -1,7 +1,6 @@ package test; import dagger.internal.DaggerGenerated; -import dagger.internal.Preconditions; import javax.annotation.processing.Generated; @DaggerGenerated @@ -13,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParent { private DaggerParent() { @@ -31,15 +31,6 @@ final class DaggerParent { private Builder() { } - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder parentModule(ParentModule parentModule) { - Preconditions.checkNotNull(parentModule); - return this; - } - public Parent build() { return new ParentImpl(); } diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_subcomponentNotGeneratedIfNotUsedInGraph_FAST_INIT_MODE_test.DaggerParent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_subcomponentNotGeneratedIfNotUsedInGraph_FAST_INIT_MODE_test.DaggerParent index 9447a4730..c630533eb 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_subcomponentNotGeneratedIfNotUsedInGraph_FAST_INIT_MODE_test.DaggerParent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_subcomponentNotGeneratedIfNotUsedInGraph_FAST_INIT_MODE_test.DaggerParent @@ -1,7 +1,6 @@ package test; import dagger.internal.DaggerGenerated; -import dagger.internal.Preconditions; import javax.annotation.processing.Generated; @DaggerGenerated @@ -13,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParent { private DaggerParent() { @@ -31,15 +31,6 @@ final class DaggerParent { private Builder() { } - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder parentModule(ParentModule parentModule) { - Preconditions.checkNotNull(parentModule); - return this; - } - public Parent build() { return new ParentImpl(); } diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_transitiveModuleDeps_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_transitiveModuleDeps_DEFAULT_MODE_test.DaggerTestComponent index ec93b6ca0..7b077e72b 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_transitiveModuleDeps_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_transitiveModuleDeps_DEFAULT_MODE_test.DaggerTestComponent @@ -1,7 +1,6 @@ package test; import dagger.internal.DaggerGenerated; -import dagger.internal.Preconditions; import javax.annotation.processing.Generated; @DaggerGenerated @@ -13,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -31,60 +31,6 @@ final class DaggerTestComponent { private Builder() { } - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder testModule(TestModule testModule) { - Preconditions.checkNotNull(testModule); - return this; - } - - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder parentTestIncluded(ParentTestIncluded parentTestIncluded) { - Preconditions.checkNotNull(parentTestIncluded); - return this; - } - - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder alwaysIncluded(AlwaysIncluded alwaysIncluded) { - Preconditions.checkNotNull(alwaysIncluded); - return this; - } - - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder depModule(DepModule depModule) { - Preconditions.checkNotNull(depModule); - return this; - } - - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder parentDepIncluded(ParentDepIncluded parentDepIncluded) { - Preconditions.checkNotNull(parentDepIncluded); - return this; - } - - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder refByDep(RefByDep refByDep) { - Preconditions.checkNotNull(refByDep); - return this; - } - public TestComponent build() { return new TestComponentImpl(); } diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_transitiveModuleDeps_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_transitiveModuleDeps_FAST_INIT_MODE_test.DaggerTestComponent index ec93b6ca0..7b077e72b 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_transitiveModuleDeps_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_transitiveModuleDeps_FAST_INIT_MODE_test.DaggerTestComponent @@ -1,7 +1,6 @@ package test; import dagger.internal.DaggerGenerated; -import dagger.internal.Preconditions; import javax.annotation.processing.Generated; @DaggerGenerated @@ -13,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -31,60 +31,6 @@ final class DaggerTestComponent { private Builder() { } - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder testModule(TestModule testModule) { - Preconditions.checkNotNull(testModule); - return this; - } - - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder parentTestIncluded(ParentTestIncluded parentTestIncluded) { - Preconditions.checkNotNull(parentTestIncluded); - return this; - } - - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder alwaysIncluded(AlwaysIncluded alwaysIncluded) { - Preconditions.checkNotNull(alwaysIncluded); - return this; - } - - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder depModule(DepModule depModule) { - Preconditions.checkNotNull(depModule); - return this; - } - - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder parentDepIncluded(ParentDepIncluded parentDepIncluded) { - Preconditions.checkNotNull(parentDepIncluded); - return this; - } - - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder refByDep(RefByDep refByDep) { - Preconditions.checkNotNull(refByDep); - return this; - } - public TestComponent build() { return new TestComponentImpl(); } diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_unusedSubcomponents_dontResolveExtraBindingsInParentComponents_DEFAULT_MODE_test.DaggerParent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_unusedSubcomponents_dontResolveExtraBindingsInParentComponents_DEFAULT_MODE_test.DaggerParent index 89764b99a..9fcf3dcaf 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_unusedSubcomponents_dontResolveExtraBindingsInParentComponents_DEFAULT_MODE_test.DaggerParent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_unusedSubcomponents_dontResolveExtraBindingsInParentComponents_DEFAULT_MODE_test.DaggerParent @@ -1,7 +1,6 @@ package test; import dagger.internal.DaggerGenerated; -import dagger.internal.Preconditions; import javax.annotation.processing.Generated; @DaggerGenerated @@ -13,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParent { private DaggerParent() { @@ -31,15 +31,6 @@ final class DaggerParent { private Builder() { } - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder testModule(TestModule testModule) { - Preconditions.checkNotNull(testModule); - return this; - } - public Parent build() { return new ParentImpl(); } diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_unusedSubcomponents_dontResolveExtraBindingsInParentComponents_FAST_INIT_MODE_test.DaggerParent b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_unusedSubcomponents_dontResolveExtraBindingsInParentComponents_FAST_INIT_MODE_test.DaggerParent index 89764b99a..9fcf3dcaf 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_unusedSubcomponents_dontResolveExtraBindingsInParentComponents_FAST_INIT_MODE_test.DaggerParent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProcessorTest_unusedSubcomponents_dontResolveExtraBindingsInParentComponents_FAST_INIT_MODE_test.DaggerParent @@ -1,7 +1,6 @@ package test; import dagger.internal.DaggerGenerated; -import dagger.internal.Preconditions; import javax.annotation.processing.Generated; @DaggerGenerated @@ -13,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParent { private DaggerParent() { @@ -31,15 +31,6 @@ final class DaggerParent { private Builder() { } - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder testModule(TestModule testModule) { - Preconditions.checkNotNull(testModule); - return this; - } - public Parent build() { return new ParentImpl(); } diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProtectedTypeTest_componentAccessesProtectedType_succeeds_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentProtectedTypeTest_componentAccessesProtectedType_succeeds_DEFAULT_MODE_test.DaggerTestComponent index 98c9ea783..a03654654 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProtectedTypeTest_componentAccessesProtectedType_succeeds_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProtectedTypeTest_componentAccessesProtectedType_succeeds_DEFAULT_MODE_test.DaggerTestComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; import test.sub.TestComponentBase_Dep_Factory; import test.sub.TestComponentBase_ProtectedType_Factory; @@ -16,7 +16,8 @@ import test.sub.TestComponentBase_ProtectedType_Factory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentProtectedTypeTest_componentAccessesProtectedType_succeeds_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentProtectedTypeTest_componentAccessesProtectedType_succeeds_FAST_INIT_MODE_test.DaggerTestComponent index 441b713d4..7defcfc8a 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentProtectedTypeTest_componentAccessesProtectedType_succeeds_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentProtectedTypeTest_componentAccessesProtectedType_succeeds_FAST_INIT_MODE_test.DaggerTestComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; import test.sub.TestComponentBase_Dep_Factory; import test.sub.TestComponentBase_ProtectedType_Factory; @@ -16,7 +16,8 @@ import test.sub.TestComponentBase_ProtectedType_Factory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_bindsInstance_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_bindsInstance_DEFAULT_MODE_test.DaggerTestComponent index 0999a8b5e..bbe89b976 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_bindsInstance_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_bindsInstance_DEFAULT_MODE_test.DaggerTestComponent @@ -14,7 +14,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_bindsInstance_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_bindsInstance_FAST_INIT_MODE_test.DaggerTestComponent index 0999a8b5e..bbe89b976 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_bindsInstance_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_bindsInstance_FAST_INIT_MODE_test.DaggerTestComponent @@ -14,7 +14,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_componentInstances_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_componentInstances_DEFAULT_MODE_test.DaggerTestComponent index 7f50d88a8..98ba4b605 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_componentInstances_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_componentInstances_DEFAULT_MODE_test.DaggerTestComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_componentInstances_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_componentInstances_FAST_INIT_MODE_test.DaggerTestComponent index 7f50d88a8..98ba4b605 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_componentInstances_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_componentInstances_FAST_INIT_MODE_test.DaggerTestComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_componentRequirementNeededInFactoryCreationOfSubcomponent_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_componentRequirementNeededInFactoryCreationOfSubcomponent_DEFAULT_MODE_test.DaggerTestComponent index 78ff25e66..9b3981664 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_componentRequirementNeededInFactoryCreationOfSubcomponent_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_componentRequirementNeededInFactoryCreationOfSubcomponent_DEFAULT_MODE_test.DaggerTestComponent @@ -2,10 +2,10 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.Preconditions; +import dagger.internal.Provider; import dagger.internal.SetFactory; import java.util.Set; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -16,7 +16,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -72,7 +73,7 @@ final class DaggerTestComponent { } @Override - public Provider<Object> dependsOnMultibinding() { + public javax.inject.Provider<Object> dependsOnMultibinding() { return reliesOnMultibindingProvider; } } @@ -99,7 +100,7 @@ final class DaggerTestComponent { } @Override - public Provider<Object> dependsOnMultibinding() { + public javax.inject.Provider<Object> dependsOnMultibinding() { return reliesOnMultibindingProvider; } diff --git a/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_componentRequirementNeededInFactoryCreationOfSubcomponent_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_componentRequirementNeededInFactoryCreationOfSubcomponent_FAST_INIT_MODE_test.DaggerTestComponent index 5eb16adf8..94ebb33ce 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_componentRequirementNeededInFactoryCreationOfSubcomponent_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_componentRequirementNeededInFactoryCreationOfSubcomponent_FAST_INIT_MODE_test.DaggerTestComponent @@ -3,9 +3,9 @@ package test; import com.google.common.collect.ImmutableSet; import dagger.internal.DaggerGenerated; import dagger.internal.Preconditions; +import dagger.internal.Provider; import java.util.Set; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -16,7 +16,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -73,7 +74,7 @@ final class DaggerTestComponent { } @Override - public Provider<Object> dependsOnMultibinding() { + public javax.inject.Provider<Object> dependsOnMultibinding() { return reliesOnMultibindingProvider; } @@ -127,7 +128,7 @@ final class DaggerTestComponent { } @Override - public Provider<Object> dependsOnMultibinding() { + public javax.inject.Provider<Object> dependsOnMultibinding() { return reliesOnMultibindingProvider; } diff --git a/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_instanceModuleMethod_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_instanceModuleMethod_DEFAULT_MODE_test.DaggerTestComponent index 36c3a11f2..99caa0746 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_instanceModuleMethod_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_instanceModuleMethod_DEFAULT_MODE_test.DaggerTestComponent @@ -15,7 +15,8 @@ import other.OtherPackageModule_LFactory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_instanceModuleMethod_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_instanceModuleMethod_FAST_INIT_MODE_test.DaggerTestComponent index 36c3a11f2..99caa0746 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_instanceModuleMethod_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_instanceModuleMethod_FAST_INIT_MODE_test.DaggerTestComponent @@ -15,7 +15,8 @@ import other.OtherPackageModule_LFactory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ComponentShardTest_testNewShardCreatedWithDependencies_DEFAULT_MODE_dagger.internal.codegen.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentShardTest_testNewShardCreatedWithDependencies_DEFAULT_MODE_dagger.internal.codegen.DaggerTestComponent index d5a2af096..a2c9032bc 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentShardTest_testNewShardCreatedWithDependencies_DEFAULT_MODE_dagger.internal.codegen.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentShardTest_testNewShardCreatedWithDependencies_DEFAULT_MODE_dagger.internal.codegen.DaggerTestComponent @@ -3,8 +3,8 @@ package dagger.internal.codegen; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; import dagger.internal.Preconditions; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -15,7 +15,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -81,17 +82,17 @@ final class DaggerTestComponent { } @Override - public Provider<Binding1> providerBinding1() { + public javax.inject.Provider<Binding1> providerBinding1() { return binding1Provider; } @Override - public Provider<Binding2> providerBinding2() { + public javax.inject.Provider<Binding2> providerBinding2() { return binding2Provider; } @Override - public Provider<Binding3> providerBinding3() { + public javax.inject.Provider<Binding3> providerBinding3() { return testComponentImpl.testComponentImplShard.binding3Provider; } diff --git a/javatests/dagger/internal/codegen/goldens/ComponentShardTest_testNewShardCreatedWithDependencies_FAST_INIT_MODE_dagger.internal.codegen.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentShardTest_testNewShardCreatedWithDependencies_FAST_INIT_MODE_dagger.internal.codegen.DaggerTestComponent index e09bb44be..5d58c6e6c 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentShardTest_testNewShardCreatedWithDependencies_FAST_INIT_MODE_dagger.internal.codegen.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentShardTest_testNewShardCreatedWithDependencies_FAST_INIT_MODE_dagger.internal.codegen.DaggerTestComponent @@ -3,8 +3,8 @@ package dagger.internal.codegen; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; import dagger.internal.Preconditions; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -15,7 +15,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -81,17 +82,17 @@ final class DaggerTestComponent { } @Override - public Provider<Binding1> providerBinding1() { + public javax.inject.Provider<Binding1> providerBinding1() { return binding1Provider; } @Override - public Provider<Binding2> providerBinding2() { + public javax.inject.Provider<Binding2> providerBinding2() { return binding2Provider; } @Override - public Provider<Binding3> providerBinding3() { + public javax.inject.Provider<Binding3> providerBinding3() { return testComponentImpl.testComponentImplShard.binding3Provider; } diff --git a/javatests/dagger/internal/codegen/goldens/ComponentShardTest_testNewShardCreated_DEFAULT_MODE_dagger.internal.codegen.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentShardTest_testNewShardCreated_DEFAULT_MODE_dagger.internal.codegen.DaggerTestComponent index de033d5dc..59a7cae85 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentShardTest_testNewShardCreated_DEFAULT_MODE_dagger.internal.codegen.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentShardTest_testNewShardCreated_DEFAULT_MODE_dagger.internal.codegen.DaggerTestComponent @@ -3,8 +3,8 @@ package dagger.internal.codegen; import dagger.internal.DaggerGenerated; import dagger.internal.DelegateFactory; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -15,7 +15,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -98,37 +99,37 @@ final class DaggerTestComponent { } @Override - public Provider<Binding1> providerBinding1() { + public javax.inject.Provider<Binding1> providerBinding1() { return testComponentImpl.testComponentImplShard2.binding1Provider; } @Override - public Provider<Binding2> providerBinding2() { + public javax.inject.Provider<Binding2> providerBinding2() { return testComponentImpl.testComponentImplShard.binding2Provider; } @Override - public Provider<Binding3> providerBinding3() { + public javax.inject.Provider<Binding3> providerBinding3() { return testComponentImpl.testComponentImplShard.binding3Provider; } @Override - public Provider<Binding4> providerBinding4() { + public javax.inject.Provider<Binding4> providerBinding4() { return testComponentImpl.testComponentImplShard.binding4Provider; } @Override - public Provider<Binding5> providerBinding5() { + public javax.inject.Provider<Binding5> providerBinding5() { return testComponentImpl.testComponentImplShard.binding5Provider; } @Override - public Provider<Binding6> providerBinding6() { + public javax.inject.Provider<Binding6> providerBinding6() { return binding6Provider; } @Override - public Provider<Binding7> providerBinding7() { + public javax.inject.Provider<Binding7> providerBinding7() { return binding7Provider; } } diff --git a/javatests/dagger/internal/codegen/goldens/ComponentShardTest_testNewShardCreated_FAST_INIT_MODE_dagger.internal.codegen.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentShardTest_testNewShardCreated_FAST_INIT_MODE_dagger.internal.codegen.DaggerTestComponent index 81056e24f..9a84c8545 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentShardTest_testNewShardCreated_FAST_INIT_MODE_dagger.internal.codegen.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentShardTest_testNewShardCreated_FAST_INIT_MODE_dagger.internal.codegen.DaggerTestComponent @@ -3,8 +3,8 @@ package dagger.internal.codegen; import dagger.internal.DaggerGenerated; import dagger.internal.DelegateFactory; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -15,7 +15,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -98,37 +99,37 @@ final class DaggerTestComponent { } @Override - public Provider<Binding1> providerBinding1() { + public javax.inject.Provider<Binding1> providerBinding1() { return testComponentImpl.testComponentImplShard2.binding1Provider; } @Override - public Provider<Binding2> providerBinding2() { + public javax.inject.Provider<Binding2> providerBinding2() { return testComponentImpl.testComponentImplShard.binding2Provider; } @Override - public Provider<Binding3> providerBinding3() { + public javax.inject.Provider<Binding3> providerBinding3() { return testComponentImpl.testComponentImplShard.binding3Provider; } @Override - public Provider<Binding4> providerBinding4() { + public javax.inject.Provider<Binding4> providerBinding4() { return testComponentImpl.testComponentImplShard.binding4Provider; } @Override - public Provider<Binding5> providerBinding5() { + public javax.inject.Provider<Binding5> providerBinding5() { return testComponentImpl.testComponentImplShard.binding5Provider; } @Override - public Provider<Binding6> providerBinding6() { + public javax.inject.Provider<Binding6> providerBinding6() { return binding6Provider; } @Override - public Provider<Binding7> providerBinding7() { + public javax.inject.Provider<Binding7> providerBinding7() { return binding7Provider; } diff --git a/javatests/dagger/internal/codegen/goldens/ComponentShardTest_testNewShardSubcomponentCreated_DEFAULT_MODE_dagger.internal.codegen.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentShardTest_testNewShardSubcomponentCreated_DEFAULT_MODE_dagger.internal.codegen.DaggerTestComponent index 86b5db46d..13f15e0b8 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentShardTest_testNewShardSubcomponentCreated_DEFAULT_MODE_dagger.internal.codegen.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentShardTest_testNewShardSubcomponentCreated_DEFAULT_MODE_dagger.internal.codegen.DaggerTestComponent @@ -2,8 +2,8 @@ package dagger.internal.codegen; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -14,7 +14,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -77,17 +78,17 @@ final class DaggerTestComponent { } @Override - public Provider<Binding1> providerBinding1() { + public javax.inject.Provider<Binding1> providerBinding1() { return binding1Provider; } @Override - public Provider<Binding2> providerBinding2() { + public javax.inject.Provider<Binding2> providerBinding2() { return binding2Provider; } @Override - public Provider<Binding3> providerBinding3() { + public javax.inject.Provider<Binding3> providerBinding3() { return testSubcomponentImpl.testSubcomponentImplShard.binding3Provider; } } diff --git a/javatests/dagger/internal/codegen/goldens/ComponentShardTest_testNewShardSubcomponentCreated_FAST_INIT_MODE_dagger.internal.codegen.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentShardTest_testNewShardSubcomponentCreated_FAST_INIT_MODE_dagger.internal.codegen.DaggerTestComponent index 5a675bae8..f2a4aa6ac 100644 --- a/javatests/dagger/internal/codegen/goldens/ComponentShardTest_testNewShardSubcomponentCreated_FAST_INIT_MODE_dagger.internal.codegen.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/ComponentShardTest_testNewShardSubcomponentCreated_FAST_INIT_MODE_dagger.internal.codegen.DaggerTestComponent @@ -2,8 +2,8 @@ package dagger.internal.codegen; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -14,7 +14,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -77,17 +78,17 @@ final class DaggerTestComponent { } @Override - public Provider<Binding1> providerBinding1() { + public javax.inject.Provider<Binding1> providerBinding1() { return binding1Provider; } @Override - public Provider<Binding2> providerBinding2() { + public javax.inject.Provider<Binding2> providerBinding2() { return binding2Provider; } @Override - public Provider<Binding3> providerBinding3() { + public javax.inject.Provider<Binding3> providerBinding3() { return testSubcomponentImpl.testSubcomponentImplShard.binding3Provider; } diff --git a/javatests/dagger/internal/codegen/goldens/DaggerProcessingOptionsTest_testCmdLineOptionEnabledPrecedesAnnotationDisabled_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/DaggerProcessingOptionsTest_testCmdLineOptionEnabledPrecedesAnnotationDisabled_test.DaggerSimpleComponent index d92a70e85..094c1ff24 100644 --- a/javatests/dagger/internal/codegen/goldens/DaggerProcessingOptionsTest_testCmdLineOptionEnabledPrecedesAnnotationDisabled_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/DaggerProcessingOptionsTest_testCmdLineOptionEnabledPrecedesAnnotationDisabled_test.DaggerSimpleComponent @@ -3,8 +3,8 @@ package test; import dagger.Lazy; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -15,7 +15,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { @@ -65,7 +66,7 @@ final class DaggerSimpleComponent { } @Override - public Provider<SomeInjectableType> someInjectableTypeProvider() { + public javax.inject.Provider<SomeInjectableType> someInjectableTypeProvider() { return someInjectableTypeProvider; } diff --git a/javatests/dagger/internal/codegen/goldens/DaggerProcessingOptionsTest_testFastInitEnabledFromAnnotationSucceeded_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/DaggerProcessingOptionsTest_testFastInitEnabledFromAnnotationSucceeded_test.DaggerSimpleComponent index d92a70e85..094c1ff24 100644 --- a/javatests/dagger/internal/codegen/goldens/DaggerProcessingOptionsTest_testFastInitEnabledFromAnnotationSucceeded_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/DaggerProcessingOptionsTest_testFastInitEnabledFromAnnotationSucceeded_test.DaggerSimpleComponent @@ -3,8 +3,8 @@ package test; import dagger.Lazy; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -15,7 +15,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { @@ -65,7 +66,7 @@ final class DaggerSimpleComponent { } @Override - public Provider<SomeInjectableType> someInjectableTypeProvider() { + public javax.inject.Provider<SomeInjectableType> someInjectableTypeProvider() { return someInjectableTypeProvider; } diff --git a/javatests/dagger/internal/codegen/goldens/DaggerProcessingOptionsTest_testFastInitaDisabledFromAnnotationSucceeded_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/DaggerProcessingOptionsTest_testFastInitaDisabledFromAnnotationSucceeded_test.DaggerSimpleComponent index 9e46639a8..e1e3f6442 100644 --- a/javatests/dagger/internal/codegen/goldens/DaggerProcessingOptionsTest_testFastInitaDisabledFromAnnotationSucceeded_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/DaggerProcessingOptionsTest_testFastInitaDisabledFromAnnotationSucceeded_test.DaggerSimpleComponent @@ -15,7 +15,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_castNeeded_rawTypes_Provider_get_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_castNeeded_rawTypes_Provider_get_DEFAULT_MODE_test.DaggerTestComponent index 87f55ab41..0cf470e1b 100644 --- a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_castNeeded_rawTypes_Provider_get_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_castNeeded_rawTypes_Provider_get_DEFAULT_MODE_test.DaggerTestComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; import other.Subtype_Factory; import other.Supertype; @@ -16,7 +16,8 @@ import other.Supertype; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_castNeeded_rawTypes_Provider_get_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_castNeeded_rawTypes_Provider_get_FAST_INIT_MODE_test.DaggerTestComponent index 06e4298ff..f7bd4485a 100644 --- a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_castNeeded_rawTypes_Provider_get_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_castNeeded_rawTypes_Provider_get_FAST_INIT_MODE_test.DaggerTestComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; import other.Subtype_Factory; import other.Supertype; @@ -16,7 +16,8 @@ import other.Supertype; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_castedToRawType_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_castedToRawType_DEFAULT_MODE_test.DaggerTestComponent index 6bdd833da..d5ebea6d6 100644 --- a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_castedToRawType_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_castedToRawType_DEFAULT_MODE_test.DaggerTestComponent @@ -13,7 +13,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -46,7 +47,7 @@ final class DaggerTestComponent { @Override public Provider<CharSequence> charSequence() { - return ((Provider) TestModule_ProvideStringFactory.create()); + return ((dagger.internal.Provider) TestModule_ProvideStringFactory.create()); } @Override diff --git a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_castedToRawType_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_castedToRawType_FAST_INIT_MODE_test.DaggerTestComponent index f186b844c..dda883661 100644 --- a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_castedToRawType_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_castedToRawType_FAST_INIT_MODE_test.DaggerTestComponent @@ -1,8 +1,8 @@ package test; import dagger.internal.DaggerGenerated; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -13,7 +13,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -53,7 +54,7 @@ final class DaggerTestComponent { } @Override - public Provider<CharSequence> charSequence() { + public javax.inject.Provider<CharSequence> charSequence() { return ((Provider) provideStringProvider); } @@ -63,7 +64,7 @@ final class DaggerTestComponent { } @Override - public Provider<String> namedString() { + public javax.inject.Provider<String> namedString() { return provideStringProvider; } diff --git a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_doubleBinds_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_doubleBinds_DEFAULT_MODE_test.DaggerTestComponent index 578eaf46f..8a2c7de07 100644 --- a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_doubleBinds_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_doubleBinds_DEFAULT_MODE_test.DaggerTestComponent @@ -13,7 +13,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -46,12 +47,12 @@ final class DaggerTestComponent { @Override public Provider<CharSequence> charSequence() { - return ((Provider) TestModule_ProvideStringFactory.create()); + return ((dagger.internal.Provider) TestModule_ProvideStringFactory.create()); } @Override public Provider<Object> object() { - return ((Provider) TestModule_ProvideStringFactory.create()); + return ((dagger.internal.Provider) TestModule_ProvideStringFactory.create()); } } } diff --git a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_doubleBinds_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_doubleBinds_FAST_INIT_MODE_test.DaggerTestComponent index 310f8a1d8..5c9ce8ab8 100644 --- a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_doubleBinds_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_doubleBinds_FAST_INIT_MODE_test.DaggerTestComponent @@ -1,8 +1,8 @@ package test; import dagger.internal.DaggerGenerated; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -13,7 +13,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -53,12 +54,12 @@ final class DaggerTestComponent { } @Override - public Provider<CharSequence> charSequence() { + public javax.inject.Provider<CharSequence> charSequence() { return ((Provider) provideStringProvider); } @Override - public Provider<Object> object() { + public javax.inject.Provider<Object> object() { return ((Provider) provideStringProvider); } diff --git a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_inlineFactoryOfInacessibleType_DEFAULT_MODE_test.DaggerRequestsSubtypeAsProvider b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_inlineFactoryOfInacessibleType_DEFAULT_MODE_test.DaggerRequestsSubtypeAsProvider index 193724a41..a8ad72f6b 100644 --- a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_inlineFactoryOfInacessibleType_DEFAULT_MODE_test.DaggerRequestsSubtypeAsProvider +++ b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_inlineFactoryOfInacessibleType_DEFAULT_MODE_test.DaggerRequestsSubtypeAsProvider @@ -15,7 +15,8 @@ import other.Supertype; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerRequestsSubtypeAsProvider { private DaggerRequestsSubtypeAsProvider() { @@ -48,7 +49,7 @@ final class DaggerRequestsSubtypeAsProvider { @Override public Provider<Supertype> supertypeProvider() { - return ((Provider) Subtype_Factory.create()); + return ((dagger.internal.Provider) Subtype_Factory.create()); } } } diff --git a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_inlineFactoryOfInacessibleType_FAST_INIT_MODE_test.DaggerRequestsSubtypeAsProvider b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_inlineFactoryOfInacessibleType_FAST_INIT_MODE_test.DaggerRequestsSubtypeAsProvider index 0d3233a98..6f6e32c93 100644 --- a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_inlineFactoryOfInacessibleType_FAST_INIT_MODE_test.DaggerRequestsSubtypeAsProvider +++ b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_inlineFactoryOfInacessibleType_FAST_INIT_MODE_test.DaggerRequestsSubtypeAsProvider @@ -1,8 +1,8 @@ package test; import dagger.internal.DaggerGenerated; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; import other.Subtype_Factory; import other.Supertype; @@ -15,7 +15,8 @@ import other.Supertype; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerRequestsSubtypeAsProvider { private DaggerRequestsSubtypeAsProvider() { @@ -56,7 +57,7 @@ final class DaggerRequestsSubtypeAsProvider { } @Override - public Provider<Supertype> supertypeProvider() { + public javax.inject.Provider<Supertype> supertypeProvider() { return subtypeProvider; } diff --git a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_noCast_rawTypes_Provider_get_toInaccessibleType_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_noCast_rawTypes_Provider_get_toInaccessibleType_DEFAULT_MODE_test.DaggerTestComponent index b1c1c2c87..9e96fba0b 100644 --- a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_noCast_rawTypes_Provider_get_toInaccessibleType_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_noCast_rawTypes_Provider_get_toInaccessibleType_DEFAULT_MODE_test.DaggerTestComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; import other.Subtype_Factory; import other.UsesSupertype; import other.UsesSupertype_Factory; @@ -17,7 +17,8 @@ import other.UsesSupertype_Factory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_noCast_rawTypes_Provider_get_toInaccessibleType_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_noCast_rawTypes_Provider_get_toInaccessibleType_FAST_INIT_MODE_test.DaggerTestComponent index e076a1dc6..059eaab2b 100644 --- a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_noCast_rawTypes_Provider_get_toInaccessibleType_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_noCast_rawTypes_Provider_get_toInaccessibleType_FAST_INIT_MODE_test.DaggerTestComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; import other.Subtype_Factory; import other.UsesSupertype; import other.UsesSupertype_Factory; @@ -17,7 +17,8 @@ import other.UsesSupertype_Factory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_providerWhenBindsScopeGreaterThanDependencyScope_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_providerWhenBindsScopeGreaterThanDependencyScope_DEFAULT_MODE_test.DaggerTestComponent index 149a5fe68..a8a4aad74 100644 --- a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_providerWhenBindsScopeGreaterThanDependencyScope_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_providerWhenBindsScopeGreaterThanDependencyScope_DEFAULT_MODE_test.DaggerTestComponent @@ -2,9 +2,9 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import dagger.internal.SingleCheck; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -15,7 +15,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -58,7 +59,7 @@ final class DaggerTestComponent { } @Override - public Provider<Object> object() { + public javax.inject.Provider<Object> object() { return bindStringProvider; } } diff --git a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_providerWhenBindsScopeGreaterThanDependencyScope_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_providerWhenBindsScopeGreaterThanDependencyScope_FAST_INIT_MODE_test.DaggerTestComponent index 09600ed69..40dcf73e4 100644 --- a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_providerWhenBindsScopeGreaterThanDependencyScope_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_providerWhenBindsScopeGreaterThanDependencyScope_FAST_INIT_MODE_test.DaggerTestComponent @@ -2,9 +2,9 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import dagger.internal.SingleCheck; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -15,7 +15,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -58,7 +59,7 @@ final class DaggerTestComponent { } @Override - public Provider<Object> object() { + public javax.inject.Provider<Object> object() { return bindStringProvider; } diff --git a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_toDoubleCheck_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_toDoubleCheck_DEFAULT_MODE_test.DaggerTestComponent index 61f28ddf7..4877c334f 100644 --- a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_toDoubleCheck_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_toDoubleCheck_DEFAULT_MODE_test.DaggerTestComponent @@ -2,9 +2,9 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import dagger.internal.SingleCheck; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -15,7 +15,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_toDoubleCheck_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_toDoubleCheck_FAST_INIT_MODE_test.DaggerTestComponent index 323f241f2..08c584464 100644 --- a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_toDoubleCheck_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_toDoubleCheck_FAST_INIT_MODE_test.DaggerTestComponent @@ -2,9 +2,9 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import dagger.internal.SingleCheck; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -15,7 +15,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_toSingleCheck_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_toSingleCheck_DEFAULT_MODE_test.DaggerTestComponent index ccbf8fc06..e04aae669 100644 --- a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_toSingleCheck_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_toSingleCheck_DEFAULT_MODE_test.DaggerTestComponent @@ -2,9 +2,9 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import dagger.internal.SingleCheck; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -15,7 +15,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_toSingleCheck_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_toSingleCheck_FAST_INIT_MODE_test.DaggerTestComponent index 1b7c50552..2ca627d02 100644 --- a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_toSingleCheck_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_toSingleCheck_FAST_INIT_MODE_test.DaggerTestComponent @@ -2,9 +2,9 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import dagger.internal.SingleCheck; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -15,7 +15,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_toUnscoped_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_toUnscoped_DEFAULT_MODE_test.DaggerTestComponent index 227bed0a8..e3d5bf697 100644 --- a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_toUnscoped_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_toUnscoped_DEFAULT_MODE_test.DaggerTestComponent @@ -2,9 +2,9 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import dagger.internal.SingleCheck; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -15,7 +15,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_toUnscoped_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_toUnscoped_FAST_INIT_MODE_test.DaggerTestComponent index dea546e94..93973b689 100644 --- a/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_toUnscoped_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/DelegateRequestRepresentationTest_toUnscoped_FAST_INIT_MODE_test.DaggerTestComponent @@ -2,9 +2,9 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import dagger.internal.SingleCheck; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -15,7 +15,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ElidedFactoriesTest_scopedBinding_onlyUsedInSubcomponent_DEFAULT_MODE_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ElidedFactoriesTest_scopedBinding_onlyUsedInSubcomponent_DEFAULT_MODE_test.DaggerSimpleComponent index cb7a35d2c..416d9c23a 100644 --- a/javatests/dagger/internal/codegen/goldens/ElidedFactoriesTest_scopedBinding_onlyUsedInSubcomponent_DEFAULT_MODE_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ElidedFactoriesTest_scopedBinding_onlyUsedInSubcomponent_DEFAULT_MODE_test.DaggerSimpleComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -14,7 +14,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ElidedFactoriesTest_scopedBinding_onlyUsedInSubcomponent_FAST_INIT_MODE_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ElidedFactoriesTest_scopedBinding_onlyUsedInSubcomponent_FAST_INIT_MODE_test.DaggerSimpleComponent index 94c174c71..64762bdcf 100644 --- a/javatests/dagger/internal/codegen/goldens/ElidedFactoriesTest_scopedBinding_onlyUsedInSubcomponent_FAST_INIT_MODE_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ElidedFactoriesTest_scopedBinding_onlyUsedInSubcomponent_FAST_INIT_MODE_test.DaggerSimpleComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -14,7 +14,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ElidedFactoriesTest_simpleComponent_DEFAULT_MODE_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ElidedFactoriesTest_simpleComponent_DEFAULT_MODE_test.DaggerSimpleComponent index a5f9992c9..39dc9c5a4 100644 --- a/javatests/dagger/internal/codegen/goldens/ElidedFactoriesTest_simpleComponent_DEFAULT_MODE_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ElidedFactoriesTest_simpleComponent_DEFAULT_MODE_test.DaggerSimpleComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ElidedFactoriesTest_simpleComponent_FAST_INIT_MODE_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ElidedFactoriesTest_simpleComponent_FAST_INIT_MODE_test.DaggerSimpleComponent index a5f9992c9..39dc9c5a4 100644 --- a/javatests/dagger/internal/codegen/goldens/ElidedFactoriesTest_simpleComponent_FAST_INIT_MODE_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ElidedFactoriesTest_simpleComponent_FAST_INIT_MODE_test.DaggerSimpleComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ElidedFactoriesTest_simpleComponent_injectsProviderOf_dependsOnScoped_DEFAULT_MODE_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ElidedFactoriesTest_simpleComponent_injectsProviderOf_dependsOnScoped_DEFAULT_MODE_test.DaggerSimpleComponent index 32382c8cf..d11d1ab9c 100644 --- a/javatests/dagger/internal/codegen/goldens/ElidedFactoriesTest_simpleComponent_injectsProviderOf_dependsOnScoped_DEFAULT_MODE_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ElidedFactoriesTest_simpleComponent_injectsProviderOf_dependsOnScoped_DEFAULT_MODE_test.DaggerSimpleComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -14,7 +14,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ElidedFactoriesTest_simpleComponent_injectsProviderOf_dependsOnScoped_FAST_INIT_MODE_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/ElidedFactoriesTest_simpleComponent_injectsProviderOf_dependsOnScoped_FAST_INIT_MODE_test.DaggerSimpleComponent index 381eeebf9..acf83f2df 100644 --- a/javatests/dagger/internal/codegen/goldens/ElidedFactoriesTest_simpleComponent_injectsProviderOf_dependsOnScoped_FAST_INIT_MODE_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ElidedFactoriesTest_simpleComponent_injectsProviderOf_dependsOnScoped_FAST_INIT_MODE_test.DaggerSimpleComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -14,7 +14,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoopScoped_DEFAULT_JAVA7_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoopScoped_DEFAULT_JAVA7_MODE_test.DaggerTestComponent index 9e10117e4..e752840df 100644 --- a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoopScoped_DEFAULT_JAVA7_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoopScoped_DEFAULT_JAVA7_MODE_test.DaggerTestComponent @@ -3,8 +3,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DelegateFactory; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.Generated; -import javax.inject.Provider; import other.FooImpl_Factory; import other.OtherEntryPoint; import other.OtherEntryPoint_Factory; @@ -18,7 +18,8 @@ import other.OtherEntryPoint_Factory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -71,4 +72,4 @@ final class DaggerTestComponent { return OtherEntryPoint_Factory.newInstance(fooImpl()); } } -}
\ No newline at end of file +} diff --git a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoopScoped_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoopScoped_DEFAULT_MODE_test.DaggerTestComponent index 9c2506681..799007973 100644 --- a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoopScoped_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoopScoped_DEFAULT_MODE_test.DaggerTestComponent @@ -3,8 +3,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DelegateFactory; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; import other.FooImpl_Factory; import other.OtherEntryPoint; import other.OtherEntryPoint_Factory; @@ -18,7 +18,8 @@ import other.OtherEntryPoint_Factory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoopScoped_FAST_INIT_JAVA7_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoopScoped_FAST_INIT_JAVA7_MODE_test.DaggerTestComponent index 9642f3381..bf80e634f 100644 --- a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoopScoped_FAST_INIT_JAVA7_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoopScoped_FAST_INIT_JAVA7_MODE_test.DaggerTestComponent @@ -3,8 +3,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DelegateFactory; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.Generated; -import javax.inject.Provider; import other.FooImpl_Factory; import other.OtherEntryPoint; import other.OtherEntryPoint_Factory; @@ -18,7 +18,8 @@ import other.OtherEntryPoint_Factory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -93,4 +94,4 @@ final class DaggerTestComponent { } } } -}
\ No newline at end of file +} diff --git a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoopScoped_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoopScoped_FAST_INIT_MODE_test.DaggerTestComponent index a18b8a4c4..f92f5585d 100644 --- a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoopScoped_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoopScoped_FAST_INIT_MODE_test.DaggerTestComponent @@ -3,8 +3,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DelegateFactory; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; import other.FooImpl_Factory; import other.OtherEntryPoint; import other.OtherEntryPoint_Factory; @@ -18,7 +18,8 @@ import other.OtherEntryPoint_Factory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoop_DEFAULT_JAVA7_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoop_DEFAULT_JAVA7_MODE_test.DaggerTestComponent index e377365d4..f13d94ad1 100644 --- a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoop_DEFAULT_JAVA7_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoop_DEFAULT_JAVA7_MODE_test.DaggerTestComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DelegateFactory; +import dagger.internal.Provider; import javax.annotation.Generated; -import javax.inject.Provider; import other.FooImpl_Factory; import other.OtherEntryPoint; import other.OtherEntryPoint_Factory; @@ -17,7 +17,8 @@ import other.OtherEntryPoint_Factory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -67,4 +68,4 @@ final class DaggerTestComponent { return OtherEntryPoint_Factory.newInstance(fooImpl()); } } -}
\ No newline at end of file +} diff --git a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoop_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoop_DEFAULT_MODE_test.DaggerTestComponent index c1345ad1c..30be4f105 100644 --- a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoop_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoop_DEFAULT_MODE_test.DaggerTestComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DelegateFactory; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; import other.FooImpl_Factory; import other.OtherEntryPoint; import other.OtherEntryPoint_Factory; @@ -17,7 +17,8 @@ import other.OtherEntryPoint_Factory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoop_FAST_INIT_JAVA7_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoop_FAST_INIT_JAVA7_MODE_test.DaggerTestComponent index c6db8da9b..27a30fb98 100644 --- a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoop_FAST_INIT_JAVA7_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoop_FAST_INIT_JAVA7_MODE_test.DaggerTestComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DelegateFactory; +import dagger.internal.Provider; import javax.annotation.Generated; -import javax.inject.Provider; import other.FooImpl_Factory; import other.OtherEntryPoint; import other.OtherEntryPoint_Factory; @@ -17,7 +17,8 @@ import other.OtherEntryPoint_Factory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -89,4 +90,4 @@ final class DaggerTestComponent { } } } -}
\ No newline at end of file +} diff --git a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoop_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoop_FAST_INIT_MODE_test.DaggerTestComponent index 8e2e95981..7146c06e3 100644 --- a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoop_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoop_FAST_INIT_MODE_test.DaggerTestComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DelegateFactory; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; import other.FooImpl_Factory; import other.OtherEntryPoint; import other.OtherEntryPoint_Factory; @@ -17,7 +17,8 @@ import other.OtherEntryPoint_Factory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_scopedInaccessibleTypeBound_DEFAULT_JAVA7_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_scopedInaccessibleTypeBound_DEFAULT_JAVA7_MODE_test.DaggerTestComponent index d39656c9b..01ffe8668 100644 --- a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_scopedInaccessibleTypeBound_DEFAULT_JAVA7_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_scopedInaccessibleTypeBound_DEFAULT_JAVA7_MODE_test.DaggerTestComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.Generated; -import javax.inject.Provider; import other.FooImpl_Factory; @DaggerGenerated @@ -15,7 +15,8 @@ import other.FooImpl_Factory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -59,4 +60,4 @@ final class DaggerTestComponent { return bindProvider.get(); } } -}
\ No newline at end of file +} diff --git a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_scopedInaccessibleTypeBound_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_scopedInaccessibleTypeBound_DEFAULT_MODE_test.DaggerTestComponent index 73dda53a9..ca51d3f3e 100644 --- a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_scopedInaccessibleTypeBound_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_scopedInaccessibleTypeBound_DEFAULT_MODE_test.DaggerTestComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; import other.FooImpl_Factory; @DaggerGenerated @@ -15,7 +15,8 @@ import other.FooImpl_Factory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_scopedInaccessibleTypeBound_FAST_INIT_JAVA7_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_scopedInaccessibleTypeBound_FAST_INIT_JAVA7_MODE_test.DaggerTestComponent index 7c0c68df2..ce6bcdff6 100644 --- a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_scopedInaccessibleTypeBound_FAST_INIT_JAVA7_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_scopedInaccessibleTypeBound_FAST_INIT_JAVA7_MODE_test.DaggerTestComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.Generated; -import javax.inject.Provider; import other.FooImpl_Factory; @DaggerGenerated @@ -15,7 +15,8 @@ import other.FooImpl_Factory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -85,4 +86,4 @@ final class DaggerTestComponent { } } } -}
\ No newline at end of file +} diff --git a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_scopedInaccessibleTypeBound_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_scopedInaccessibleTypeBound_FAST_INIT_MODE_test.DaggerTestComponent index 84ae12fed..c39381bc4 100644 --- a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_scopedInaccessibleTypeBound_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_scopedInaccessibleTypeBound_FAST_INIT_MODE_test.DaggerTestComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; import other.FooImpl_Factory; @DaggerGenerated @@ -15,7 +15,8 @@ import other.FooImpl_Factory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_basicNameCollision_test.InjectConstructor_Factory b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_basicNameCollision_test.InjectConstructor_Factory index 00ee9afe8..8488abaa4 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_basicNameCollision_test.InjectConstructor_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_basicNameCollision_test.InjectConstructor_Factory @@ -18,7 +18,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class InjectConstructor_Factory implements Factory<InjectConstructor> { private final Provider<other.pkg.Factory> factoryProvider; diff --git a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_boundedGenerics_test.GenericClass_Factory b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_boundedGenerics_test.GenericClass_Factory index 012d3d040..143d1ed7c 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_boundedGenerics_test.GenericClass_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_boundedGenerics_test.GenericClass_Factory @@ -19,7 +19,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class GenericClass_Factory<A extends Number & Comparable<A>, B extends List<? extends String>, C extends List<? super String>> implements Factory<GenericClass<A, B, C>> { private final Provider<A> aProvider; diff --git a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_fieldAndMethodGenerics_test.GenericClass_Factory b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_fieldAndMethodGenerics_test.GenericClass_Factory index a3d5bf2ac..ab6d9aef3 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_fieldAndMethodGenerics_test.GenericClass_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_fieldAndMethodGenerics_test.GenericClass_Factory @@ -18,7 +18,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class GenericClass_Factory<A, B> implements Factory<GenericClass<A, B>> { private final Provider<A> aProvider; diff --git a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_genericClassWithNoDependencies_test.GenericClass_Factory b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_genericClassWithNoDependencies_test.GenericClass_Factory index d43e19f10..95e00381d 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_genericClassWithNoDependencies_test.GenericClass_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_genericClassWithNoDependencies_test.GenericClass_Factory @@ -17,7 +17,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class GenericClass_Factory<T> implements Factory<GenericClass<T>> { @Override diff --git a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_injectConstructorAndMembersInjection_test.AllInjections_Factory b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_injectConstructorAndMembersInjection_test.AllInjections_Factory index 71d791bc1..0c2475c7a 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_injectConstructorAndMembersInjection_test.AllInjections_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_injectConstructorAndMembersInjection_test.AllInjections_Factory @@ -18,7 +18,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class AllInjections_Factory implements Factory<AllInjections> { private final Provider<String> sProvider; diff --git a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_injectConstructorOnGenericClass_test.GenericClass_Factory b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_injectConstructorOnGenericClass_test.GenericClass_Factory index 67d5808a5..6ac47e92e 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_injectConstructorOnGenericClass_test.GenericClass_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_injectConstructorOnGenericClass_test.GenericClass_Factory @@ -18,7 +18,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class GenericClass_Factory<T> implements Factory<GenericClass<T>> { private final Provider<T> tProvider; diff --git a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_injectConstructor_test.InjectConstructor_Factory b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_injectConstructor_test.InjectConstructor_Factory index bf20ec4ef..638815ea9 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_injectConstructor_test.InjectConstructor_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_injectConstructor_test.InjectConstructor_Factory @@ -18,7 +18,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class InjectConstructor_Factory implements Factory<InjectConstructor> { private final Provider<String> sProvider; diff --git a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_multipleSameTypesWithGenericsAndQualifiersAndLazies_test.GenericClass_Factory b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_multipleSameTypesWithGenericsAndQualifiersAndLazies_test.GenericClass_Factory index bfc28d062..a5b93b8e8 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_multipleSameTypesWithGenericsAndQualifiersAndLazies_test.GenericClass_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_multipleSameTypesWithGenericsAndQualifiersAndLazies_test.GenericClass_Factory @@ -20,7 +20,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class GenericClass_Factory<A, B> implements Factory<GenericClass<A, B>> { private final Provider<A> aProvider; diff --git a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_nestedNameCollision_test.InjectConstructor_Factory b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_nestedNameCollision_test.InjectConstructor_Factory index aba20cef2..f3337a1c8 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_nestedNameCollision_test.InjectConstructor_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_nestedNameCollision_test.InjectConstructor_Factory @@ -19,7 +19,8 @@ import other.pkg.Outer; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class InjectConstructor_Factory implements Factory<InjectConstructor> { private final Provider<Outer.Factory> factoryProvider; diff --git a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_noDeps_test.SimpleType_Factory b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_noDeps_test.SimpleType_Factory index 67f856c2c..41c6c72a4 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_noDeps_test.SimpleType_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_noDeps_test.SimpleType_Factory @@ -17,7 +17,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class SimpleType_Factory implements Factory<SimpleType> { @Override diff --git a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_samePackageNameCollision_test.InjectConstructor_Factory b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_samePackageNameCollision_test.InjectConstructor_Factory index 0e22f2d66..f65c9c550 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_samePackageNameCollision_test.InjectConstructor_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_samePackageNameCollision_test.InjectConstructor_Factory @@ -18,7 +18,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class InjectConstructor_Factory implements Factory<InjectConstructor> { private final Provider<other.pkg.CommonName> otherPackageProvider; diff --git a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_simpleComponentWithNesting_test.OuterType_A_Factory b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_simpleComponentWithNesting_test.OuterType_A_Factory index 371c71688..424c614d9 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_simpleComponentWithNesting_test.OuterType_A_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_simpleComponentWithNesting_test.OuterType_A_Factory @@ -17,7 +17,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class OuterType_A_Factory implements Factory<OuterType.A> { @Override diff --git a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testBaseClassQualifierMetadata_test.FooBase_Factory b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testBaseClassQualifierMetadata_test.FooBase_Factory index e2b44b501..1f00f95b6 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testBaseClassQualifierMetadata_test.FooBase_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testBaseClassQualifierMetadata_test.FooBase_Factory @@ -18,7 +18,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class FooBase_Factory implements Factory<FooBase> { private final Provider<Integer> iProvider; diff --git a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testBaseClassQualifierMetadata_test.FooBase_MembersInjector b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testBaseClassQualifierMetadata_test.FooBase_MembersInjector index e93005b17..5e865ffab 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testBaseClassQualifierMetadata_test.FooBase_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testBaseClassQualifierMetadata_test.FooBase_MembersInjector @@ -20,7 +20,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class FooBase_MembersInjector implements MembersInjector<FooBase> { private final Provider<String> injectFieldProvider; diff --git a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testBaseClassQualifierMetadata_test.Foo_Factory b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testBaseClassQualifierMetadata_test.Foo_Factory index 69bc96234..48d9102ec 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testBaseClassQualifierMetadata_test.Foo_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testBaseClassQualifierMetadata_test.Foo_Factory @@ -18,7 +18,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class Foo_Factory implements Factory<Foo> { private final Provider<Integer> iProvider; diff --git a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testBaseClassQualifierMetadata_test.Foo_MembersInjector b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testBaseClassQualifierMetadata_test.Foo_MembersInjector index 36d5b1da1..748583647 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testBaseClassQualifierMetadata_test.Foo_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testBaseClassQualifierMetadata_test.Foo_MembersInjector @@ -20,7 +20,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class Foo_MembersInjector implements MembersInjector<Foo> { private final Provider<String> injectFieldProvider; diff --git a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testComplexQualifierMetadata_test.SomeBinding_Factory b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testComplexQualifierMetadata_test.SomeBinding_Factory index 9a4b6e67a..2d100f6ff 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testComplexQualifierMetadata_test.SomeBinding_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testComplexQualifierMetadata_test.SomeBinding_Factory @@ -21,7 +21,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class SomeBinding_Factory implements Factory<SomeBinding> { private final Provider<String> str1Provider; diff --git a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testComplexQualifierMetadata_test.SomeBinding_MembersInjector b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testComplexQualifierMetadata_test.SomeBinding_MembersInjector index a30a9dfb0..a5707af6e 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testComplexQualifierMetadata_test.SomeBinding_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testComplexQualifierMetadata_test.SomeBinding_MembersInjector @@ -20,7 +20,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class SomeBinding_MembersInjector implements MembersInjector<SomeBinding> { private final Provider<String> injectFieldProvider; diff --git a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testQualifierMetadata_test.SomeBinding_Factory b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testQualifierMetadata_test.SomeBinding_Factory index f8308661e..40690b35a 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testQualifierMetadata_test.SomeBinding_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testQualifierMetadata_test.SomeBinding_Factory @@ -18,7 +18,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class SomeBinding_Factory implements Factory<SomeBinding> { private final Provider<Double> dProvider; diff --git a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testQualifierMetadata_test.SomeBinding_MembersInjector b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testQualifierMetadata_test.SomeBinding_MembersInjector index f17203dd2..a8ca78019 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testQualifierMetadata_test.SomeBinding_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testQualifierMetadata_test.SomeBinding_MembersInjector @@ -20,7 +20,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class SomeBinding_MembersInjector implements MembersInjector<SomeBinding> { private final Provider<String> injectFieldProvider; diff --git a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testScopedMetadataWithCustomScope_test.ScopedBinding_Factory b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testScopedMetadataWithCustomScope_test.ScopedBinding_Factory index 8220ee617..d949bdd26 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testScopedMetadataWithCustomScope_test.ScopedBinding_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testScopedMetadataWithCustomScope_test.ScopedBinding_Factory @@ -17,7 +17,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class ScopedBinding_Factory implements Factory<ScopedBinding> { @Override diff --git a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testScopedMetadata_test.ScopedBinding_Factory b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testScopedMetadata_test.ScopedBinding_Factory index 871fe75c3..5682bb07b 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testScopedMetadata_test.ScopedBinding_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testScopedMetadata_test.ScopedBinding_Factory @@ -17,7 +17,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class ScopedBinding_Factory implements Factory<ScopedBinding> { @Override diff --git a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_twoGenericTypes_test.GenericClass_Factory b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_twoGenericTypes_test.GenericClass_Factory index 39e73daff..116df17b3 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_twoGenericTypes_test.GenericClass_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_twoGenericTypes_test.GenericClass_Factory @@ -18,7 +18,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class GenericClass_Factory<A, B> implements Factory<GenericClass<A, B>> { private final Provider<A> aProvider; diff --git a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_wildcardDependency_test.InjectConstructor_Factory b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_wildcardDependency_test.InjectConstructor_Factory index d5758e71d..681a4b6d9 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_wildcardDependency_test.InjectConstructor_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_wildcardDependency_test.InjectConstructor_Factory @@ -19,7 +19,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class InjectConstructor_Factory implements Factory<InjectConstructor> { private final Provider<List<?>> objectsProvider; diff --git a/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_DEFAULT_MODE_mapkeys.MapModule_ClassKeyMapKey b/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_DEFAULT_MODE_mapkeys.MapModule_ClassKeyMapKey new file mode 100644 index 000000000..63a07ab64 --- /dev/null +++ b/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_DEFAULT_MODE_mapkeys.MapModule_ClassKeyMapKey @@ -0,0 +1,30 @@ +package mapkeys; + +import dagger.internal.DaggerGenerated; +import dagger.internal.KeepFieldType; +import javax.annotation.processing.Generated; + +@DaggerGenerated +@Generated( + value = "dagger.internal.codegen.ComponentProcessor", + comments = "https://dagger.dev" +) +@SuppressWarnings({ + "unchecked", + "rawtypes", + "KotlinInternal", + "KotlinInternalInJava", + "cast" +}) +public final class MapModule_ClassKeyMapKey { + @KeepFieldType + MapKeys.Inaccessible className; + + private MapModule_ClassKeyMapKey() { + } + + public static Class<?> create() { + return MapKeys.Inaccessible.class; + } +} + diff --git a/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_DEFAULT_MODE_mapkeys.MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey b/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_DEFAULT_MODE_mapkeys.MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey new file mode 100644 index 000000000..3e00ffd48 --- /dev/null +++ b/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_DEFAULT_MODE_mapkeys.MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey @@ -0,0 +1,26 @@ +package mapkeys; + +import dagger.internal.DaggerGenerated; +import javax.annotation.processing.Generated; + +@DaggerGenerated +@Generated( + value = "dagger.internal.codegen.ComponentProcessor", + comments = "https://dagger.dev" +) +@SuppressWarnings({ + "unchecked", + "rawtypes", + "KotlinInternal", + "KotlinInternalInJava", + "cast" +}) +public final class MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey { + private MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey() { + } + + public static MapKeys.ComplexKey create() { + return MapKeys_ComplexKeyCreator.createComplexKey(new Class[] {String.class}, String.class, MapKeys_ComplexKeyCreator.createLazyClassKey(MapKeys.Inaccessible.class)); + } +} + diff --git a/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_DEFAULT_MODE_test.DaggerTestComponent new file mode 100644 index 000000000..eff6a40b8 --- /dev/null +++ b/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_DEFAULT_MODE_test.DaggerTestComponent @@ -0,0 +1,99 @@ +package test; + +import com.google.common.collect.ImmutableMap; +import dagger.internal.DaggerGenerated; +import dagger.internal.IdentifierNameString; +import dagger.internal.LazyClassKeyMap; +import dagger.internal.MapFactory; +import dagger.internal.Provider; +import java.util.Map; +import javax.annotation.processing.Generated; +import mapkeys.MapKeys; +import mapkeys.MapModule; +import mapkeys.MapModule_ClassKeyFactory; +import mapkeys.MapModule_ComplexKeyWithInaccessibleAnnotationValueFactory; +import mapkeys.MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey; +import mapkeys.MapModule_ComplexKeyWithInaccessibleArrayValueFactory; +import mapkeys.MapModule_ComplexKeyWithInaccessibleArrayValueMapKey; +import mapkeys.MapModule_ComplexKeyWithInaccessibleValueFactory; +import mapkeys.MapModule_ComplexKeyWithInaccessibleValueMapKey; + +@DaggerGenerated +@Generated( + value = "dagger.internal.codegen.ComponentProcessor", + comments = "https://dagger.dev" +) +@SuppressWarnings({ + "unchecked", + "rawtypes", + "KotlinInternal", + "KotlinInternalInJava", + "cast" +}) +final class DaggerTestComponent { + private DaggerTestComponent() { + } + + public static Builder builder() { + return new Builder(); + } + + public static TestComponent create() { + return new Builder().build(); + } + + static final class Builder { + private Builder() { + } + + public TestComponent build() { + return new TestComponentImpl(); + } + } + + private static final class TestComponentImpl implements TestComponent { + private final TestComponentImpl testComponentImpl = this; + + private Provider<Map<Class<?>, Integer>> mapOfClassOfAndIntegerProvider; + + private Provider<Map<MapKeys.ComplexKey, Integer>> mapOfComplexKeyAndIntegerProvider; + + private TestComponentImpl() { + + initialize(); + + } + + @SuppressWarnings("unchecked") + private void initialize() { + this.mapOfClassOfAndIntegerProvider = LazyClassKeyMap.Factory.<Integer>of(MapFactory.<String, Integer>builder(1).put(LazyClassKeyProvider.mapkeys_MapKeys_Inaccessible, MapModule_ClassKeyFactory.create()).build()); + this.mapOfComplexKeyAndIntegerProvider = MapFactory.<MapKeys.ComplexKey, Integer>builder(3).put(MapModule_ComplexKeyWithInaccessibleValueMapKey.create(), MapModule_ComplexKeyWithInaccessibleValueFactory.create()).put(MapModule_ComplexKeyWithInaccessibleArrayValueMapKey.create(), MapModule_ComplexKeyWithInaccessibleArrayValueFactory.create()).put(MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey.create(), MapModule_ComplexKeyWithInaccessibleAnnotationValueFactory.create()).build(); + } + + @Override + public Map<Class<?>, Integer> classKey() { + return LazyClassKeyMap.<Integer>of(ImmutableMap.<String, Integer>of(LazyClassKeyProvider.mapkeys_MapKeys_Inaccessible, MapModule.classKey())); + } + + @Override + public javax.inject.Provider<Map<Class<?>, Integer>> classKeyProvider() { + return mapOfClassOfAndIntegerProvider; + } + + @Override + public Map<MapKeys.ComplexKey, Integer> complexKey() { + return ImmutableMap.<MapKeys.ComplexKey, Integer>of(MapModule_ComplexKeyWithInaccessibleValueMapKey.create(), MapModule.complexKeyWithInaccessibleValue(), MapModule_ComplexKeyWithInaccessibleArrayValueMapKey.create(), MapModule.complexKeyWithInaccessibleArrayValue(), MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey.create(), MapModule.complexKeyWithInaccessibleAnnotationValue()); + } + + @Override + public javax.inject.Provider<Map<MapKeys.ComplexKey, Integer>> complexKeyProvider() { + return mapOfComplexKeyAndIntegerProvider; + } + + @IdentifierNameString + private static final class LazyClassKeyProvider { + static String mapkeys_MapKeys_Inaccessible = "mapkeys.MapKeys$Inaccessible"; + } + } +} + diff --git a/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_FAST_INIT_MODE_mapkeys.MapModule_ClassKeyMapKey b/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_FAST_INIT_MODE_mapkeys.MapModule_ClassKeyMapKey new file mode 100644 index 000000000..63a07ab64 --- /dev/null +++ b/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_FAST_INIT_MODE_mapkeys.MapModule_ClassKeyMapKey @@ -0,0 +1,30 @@ +package mapkeys; + +import dagger.internal.DaggerGenerated; +import dagger.internal.KeepFieldType; +import javax.annotation.processing.Generated; + +@DaggerGenerated +@Generated( + value = "dagger.internal.codegen.ComponentProcessor", + comments = "https://dagger.dev" +) +@SuppressWarnings({ + "unchecked", + "rawtypes", + "KotlinInternal", + "KotlinInternalInJava", + "cast" +}) +public final class MapModule_ClassKeyMapKey { + @KeepFieldType + MapKeys.Inaccessible className; + + private MapModule_ClassKeyMapKey() { + } + + public static Class<?> create() { + return MapKeys.Inaccessible.class; + } +} + diff --git a/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_FAST_INIT_MODE_mapkeys.MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey b/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_FAST_INIT_MODE_mapkeys.MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey new file mode 100644 index 000000000..3e00ffd48 --- /dev/null +++ b/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_FAST_INIT_MODE_mapkeys.MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey @@ -0,0 +1,26 @@ +package mapkeys; + +import dagger.internal.DaggerGenerated; +import javax.annotation.processing.Generated; + +@DaggerGenerated +@Generated( + value = "dagger.internal.codegen.ComponentProcessor", + comments = "https://dagger.dev" +) +@SuppressWarnings({ + "unchecked", + "rawtypes", + "KotlinInternal", + "KotlinInternalInJava", + "cast" +}) +public final class MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey { + private MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey() { + } + + public static MapKeys.ComplexKey create() { + return MapKeys_ComplexKeyCreator.createComplexKey(new Class[] {String.class}, String.class, MapKeys_ComplexKeyCreator.createLazyClassKey(MapKeys.Inaccessible.class)); + } +} + diff --git a/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_FAST_INIT_MODE_test.DaggerTestComponent new file mode 100644 index 000000000..478b0101d --- /dev/null +++ b/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_FAST_INIT_MODE_test.DaggerTestComponent @@ -0,0 +1,119 @@ +package test; + +import com.google.common.collect.ImmutableMap; +import dagger.internal.DaggerGenerated; +import dagger.internal.IdentifierNameString; +import dagger.internal.LazyClassKeyMap; +import dagger.internal.Provider; +import java.util.Map; +import javax.annotation.processing.Generated; +import mapkeys.MapKeys; +import mapkeys.MapModule; +import mapkeys.MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey; +import mapkeys.MapModule_ComplexKeyWithInaccessibleArrayValueMapKey; +import mapkeys.MapModule_ComplexKeyWithInaccessibleValueMapKey; + +@DaggerGenerated +@Generated( + value = "dagger.internal.codegen.ComponentProcessor", + comments = "https://dagger.dev" +) +@SuppressWarnings({ + "unchecked", + "rawtypes", + "KotlinInternal", + "KotlinInternalInJava", + "cast" +}) +final class DaggerTestComponent { + private DaggerTestComponent() { + } + + public static Builder builder() { + return new Builder(); + } + + public static TestComponent create() { + return new Builder().build(); + } + + static final class Builder { + private Builder() { + } + + public TestComponent build() { + return new TestComponentImpl(); + } + } + + private static final class TestComponentImpl implements TestComponent { + private final TestComponentImpl testComponentImpl = this; + + private Provider<Map<Class<?>, Integer>> mapOfClassOfAndIntegerProvider; + + private Provider<Map<MapKeys.ComplexKey, Integer>> mapOfComplexKeyAndIntegerProvider; + + private TestComponentImpl() { + + initialize(); + + } + + @SuppressWarnings("unchecked") + private void initialize() { + this.mapOfClassOfAndIntegerProvider = new SwitchingProvider<>(testComponentImpl, 0); + this.mapOfComplexKeyAndIntegerProvider = new SwitchingProvider<>(testComponentImpl, 1); + } + + @Override + public Map<Class<?>, Integer> classKey() { + return mapOfClassOfAndIntegerProvider.get(); + } + + @Override + public javax.inject.Provider<Map<Class<?>, Integer>> classKeyProvider() { + return mapOfClassOfAndIntegerProvider; + } + + @Override + public Map<MapKeys.ComplexKey, Integer> complexKey() { + return mapOfComplexKeyAndIntegerProvider.get(); + } + + @Override + public javax.inject.Provider<Map<MapKeys.ComplexKey, Integer>> complexKeyProvider() { + return mapOfComplexKeyAndIntegerProvider; + } + + private static final class SwitchingProvider<T> implements Provider<T> { + private final TestComponentImpl testComponentImpl; + + private final int id; + + SwitchingProvider(TestComponentImpl testComponentImpl, int id) { + this.testComponentImpl = testComponentImpl; + this.id = id; + } + + @SuppressWarnings("unchecked") + @Override + public T get() { + switch (id) { + case 0: // java.util.Map<java.lang.Class<?>,java.lang.Integer> + return (T) LazyClassKeyMap.<Integer>of(ImmutableMap.<String, Integer>of(LazyClassKeyProvider.mapkeys_MapKeys_Inaccessible, MapModule.classKey())); + + case 1: // java.util.Map<mapkeys.MapKeys.ComplexKey,java.lang.Integer> + return (T) ImmutableMap.<MapKeys.ComplexKey, Integer>of(MapModule_ComplexKeyWithInaccessibleValueMapKey.create(), MapModule.complexKeyWithInaccessibleValue(), MapModule_ComplexKeyWithInaccessibleArrayValueMapKey.create(), MapModule.complexKeyWithInaccessibleArrayValue(), MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey.create(), MapModule.complexKeyWithInaccessibleAnnotationValue()); + + default: throw new AssertionError(id); + } + } + } + + @IdentifierNameString + private static final class LazyClassKeyProvider { + static String mapkeys_MapKeys_Inaccessible = "mapkeys.MapKeys$Inaccessible"; + } + } +} + diff --git a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_injectMapWithoutMapBinding_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_injectMapWithoutMapBinding_DEFAULT_MODE_test.DaggerTestComponent index 227404c19..b348b61de 100644 --- a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_injectMapWithoutMapBinding_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_injectMapWithoutMapBinding_DEFAULT_MODE_test.DaggerTestComponent @@ -14,7 +14,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_injectMapWithoutMapBinding_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_injectMapWithoutMapBinding_FAST_INIT_MODE_test.DaggerTestComponent index 227404c19..b348b61de 100644 --- a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_injectMapWithoutMapBinding_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_injectMapWithoutMapBinding_FAST_INIT_MODE_test.DaggerTestComponent @@ -14,7 +14,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithEnumKey_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithEnumKey_DEFAULT_MODE_test.DaggerTestComponent index 88153bcb5..dbffeddd7 100644 --- a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithEnumKey_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithEnumKey_DEFAULT_MODE_test.DaggerTestComponent @@ -3,9 +3,9 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.MapProviderFactory; import dagger.internal.Preconditions; +import dagger.internal.Provider; import java.util.Map; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -16,7 +16,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -66,7 +67,7 @@ final class DaggerTestComponent { private Provider<Handler> provideLoginHandlerProvider; - private Provider<Map<PathEnum, Provider<Handler>>> mapOfPathEnumAndProviderOfHandlerProvider; + private Provider mapOfPathEnumAndProviderOfHandlerProvider; private TestComponentImpl(MapModuleOne mapModuleOneParam, MapModuleTwo mapModuleTwoParam) { @@ -83,7 +84,7 @@ final class DaggerTestComponent { } @Override - public Provider<Map<PathEnum, Provider<Handler>>> dispatcher() { + public javax.inject.Provider<Map<PathEnum, javax.inject.Provider<Handler>>> dispatcher() { return mapOfPathEnumAndProviderOfHandlerProvider; } } diff --git a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithEnumKey_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithEnumKey_FAST_INIT_MODE_test.DaggerTestComponent index ac0e74e19..54f6250f7 100644 --- a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithEnumKey_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithEnumKey_FAST_INIT_MODE_test.DaggerTestComponent @@ -3,9 +3,9 @@ package test; import com.google.common.collect.ImmutableMap; import dagger.internal.DaggerGenerated; import dagger.internal.Preconditions; +import dagger.internal.Provider; import java.util.Map; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -16,7 +16,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -70,7 +71,7 @@ final class DaggerTestComponent { private Provider<Handler> provideLoginHandlerProvider; - private Provider<Map<PathEnum, Provider<Handler>>> mapOfPathEnumAndProviderOfHandlerProvider; + private Provider mapOfPathEnumAndProviderOfHandlerProvider; private TestComponentImpl(MapModuleOne mapModuleOneParam, MapModuleTwo mapModuleTwoParam) { this.mapModuleOne = mapModuleOneParam; @@ -88,7 +89,7 @@ final class DaggerTestComponent { } @Override - public Provider<Map<PathEnum, Provider<Handler>>> dispatcher() { + public javax.inject.Provider<Map<PathEnum, javax.inject.Provider<Handler>>> dispatcher() { return mapOfPathEnumAndProviderOfHandlerProvider; } @@ -107,7 +108,7 @@ final class DaggerTestComponent { public T get() { switch (id) { case 0: // java.util.Map<test.PathEnum,javax.inject.Provider<test.Handler>> - return (T) ImmutableMap.<PathEnum, Provider<Handler>>of(PathEnum.ADMIN, testComponentImpl.provideAdminHandlerProvider, PathEnum.LOGIN, testComponentImpl.provideLoginHandlerProvider); + return (T) ImmutableMap.<PathEnum, javax.inject.Provider<Handler>>of(PathEnum.ADMIN, testComponentImpl.provideAdminHandlerProvider, PathEnum.LOGIN, testComponentImpl.provideLoginHandlerProvider); case 1: // java.util.Map<test.PathEnum,javax.inject.Provider<test.Handler>> test.MapModuleOne#provideAdminHandler return (T) MapModuleOne_ProvideAdminHandlerFactory.provideAdminHandler(testComponentImpl.mapModuleOne); diff --git a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_DEFAULT_MODE_mapkeys.MapModule_ClassKeyMapKey b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_DEFAULT_MODE_mapkeys.MapModule_ClassKeyMapKey index 252d0073f..209220e95 100644 --- a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_DEFAULT_MODE_mapkeys.MapModule_ClassKeyMapKey +++ b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_DEFAULT_MODE_mapkeys.MapModule_ClassKeyMapKey @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class MapModule_ClassKeyMapKey { private MapModule_ClassKeyMapKey() { diff --git a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_DEFAULT_MODE_mapkeys.MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_DEFAULT_MODE_mapkeys.MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey index 34cbcbad0..f65280bb3 100644 --- a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_DEFAULT_MODE_mapkeys.MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey +++ b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_DEFAULT_MODE_mapkeys.MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey { private MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey() { diff --git a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_DEFAULT_MODE_test.DaggerTestComponent index 1d9618dd2..2b35d4612 100644 --- a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_DEFAULT_MODE_test.DaggerTestComponent @@ -3,9 +3,9 @@ package test; import com.google.common.collect.ImmutableMap; import dagger.internal.DaggerGenerated; import dagger.internal.MapFactory; +import dagger.internal.Provider; import java.util.Map; import javax.annotation.processing.Generated; -import javax.inject.Provider; import mapkeys.MapKeys; import mapkeys.MapModule; import mapkeys.MapModule_ClassKeyFactory; @@ -28,7 +28,8 @@ import mapkeys.MapModule_EnumKeyMapKey; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -84,7 +85,7 @@ final class DaggerTestComponent { } @Override - public Provider<Map<Class<?>, Integer>> classKeyProvider() { + public javax.inject.Provider<Map<Class<?>, Integer>> classKeyProvider() { return mapOfClassOfAndIntegerProvider; } @@ -94,7 +95,7 @@ final class DaggerTestComponent { } @Override - public Provider<Object> inaccessibleEnumProvider() { + public javax.inject.Provider<Object> inaccessibleEnumProvider() { return mapOfPackagePrivateEnumAndIntegerProvider; } @@ -104,7 +105,7 @@ final class DaggerTestComponent { } @Override - public Provider<Map<MapKeys.ComplexKey, Integer>> complexKeyProvider() { + public javax.inject.Provider<Map<MapKeys.ComplexKey, Integer>> complexKeyProvider() { return mapOfComplexKeyAndIntegerProvider; } } diff --git a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_FAST_INIT_MODE_mapkeys.MapModule_ClassKeyMapKey b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_FAST_INIT_MODE_mapkeys.MapModule_ClassKeyMapKey index 252d0073f..209220e95 100644 --- a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_FAST_INIT_MODE_mapkeys.MapModule_ClassKeyMapKey +++ b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_FAST_INIT_MODE_mapkeys.MapModule_ClassKeyMapKey @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class MapModule_ClassKeyMapKey { private MapModule_ClassKeyMapKey() { diff --git a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_FAST_INIT_MODE_mapkeys.MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_FAST_INIT_MODE_mapkeys.MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey index 34cbcbad0..f65280bb3 100644 --- a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_FAST_INIT_MODE_mapkeys.MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey +++ b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_FAST_INIT_MODE_mapkeys.MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey { private MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey() { diff --git a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_FAST_INIT_MODE_test.DaggerTestComponent index 1d9618dd2..2b35d4612 100644 --- a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_FAST_INIT_MODE_test.DaggerTestComponent @@ -3,9 +3,9 @@ package test; import com.google.common.collect.ImmutableMap; import dagger.internal.DaggerGenerated; import dagger.internal.MapFactory; +import dagger.internal.Provider; import java.util.Map; import javax.annotation.processing.Generated; -import javax.inject.Provider; import mapkeys.MapKeys; import mapkeys.MapModule; import mapkeys.MapModule_ClassKeyFactory; @@ -28,7 +28,8 @@ import mapkeys.MapModule_EnumKeyMapKey; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -84,7 +85,7 @@ final class DaggerTestComponent { } @Override - public Provider<Map<Class<?>, Integer>> classKeyProvider() { + public javax.inject.Provider<Map<Class<?>, Integer>> classKeyProvider() { return mapOfClassOfAndIntegerProvider; } @@ -94,7 +95,7 @@ final class DaggerTestComponent { } @Override - public Provider<Object> inaccessibleEnumProvider() { + public javax.inject.Provider<Object> inaccessibleEnumProvider() { return mapOfPackagePrivateEnumAndIntegerProvider; } @@ -104,7 +105,7 @@ final class DaggerTestComponent { } @Override - public Provider<Map<MapKeys.ComplexKey, Integer>> complexKeyProvider() { + public javax.inject.Provider<Map<MapKeys.ComplexKey, Integer>> complexKeyProvider() { return mapOfComplexKeyAndIntegerProvider; } } diff --git a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithNonProviderValue_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithNonProviderValue_DEFAULT_MODE_test.DaggerTestComponent index b2e7cf5fd..e2d93ecd6 100644 --- a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithNonProviderValue_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithNonProviderValue_DEFAULT_MODE_test.DaggerTestComponent @@ -3,9 +3,9 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.MapFactory; import dagger.internal.Preconditions; +import dagger.internal.Provider; import java.util.Map; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -16,7 +16,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -83,7 +84,7 @@ final class DaggerTestComponent { } @Override - public Provider<Map<PathEnum, Handler>> dispatcher() { + public javax.inject.Provider<Map<PathEnum, Handler>> dispatcher() { return mapOfPathEnumAndHandlerProvider; } } diff --git a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithNonProviderValue_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithNonProviderValue_FAST_INIT_MODE_test.DaggerTestComponent index 4e898edfa..c3f057811 100644 --- a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithNonProviderValue_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithNonProviderValue_FAST_INIT_MODE_test.DaggerTestComponent @@ -3,9 +3,9 @@ package test; import com.google.common.collect.ImmutableMap; import dagger.internal.DaggerGenerated; import dagger.internal.Preconditions; +import dagger.internal.Provider; import java.util.Map; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -16,7 +16,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -82,7 +83,7 @@ final class DaggerTestComponent { } @Override - public Provider<Map<PathEnum, Handler>> dispatcher() { + public javax.inject.Provider<Map<PathEnum, Handler>> dispatcher() { return mapOfPathEnumAndHandlerProvider; } diff --git a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithStringKey_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithStringKey_DEFAULT_MODE_test.DaggerTestComponent index 0b463f566..cd24892bd 100644 --- a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithStringKey_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithStringKey_DEFAULT_MODE_test.DaggerTestComponent @@ -3,9 +3,9 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.MapProviderFactory; import dagger.internal.Preconditions; +import dagger.internal.Provider; import java.util.Map; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -16,7 +16,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -66,7 +67,7 @@ final class DaggerTestComponent { private Provider<Handler> provideLoginHandlerProvider; - private Provider<Map<String, Provider<Handler>>> mapOfStringAndProviderOfHandlerProvider; + private Provider mapOfStringAndProviderOfHandlerProvider; private TestComponentImpl(MapModuleOne mapModuleOneParam, MapModuleTwo mapModuleTwoParam) { @@ -83,7 +84,7 @@ final class DaggerTestComponent { } @Override - public Provider<Map<String, Provider<Handler>>> dispatcher() { + public javax.inject.Provider<Map<String, javax.inject.Provider<Handler>>> dispatcher() { return mapOfStringAndProviderOfHandlerProvider; } } diff --git a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithStringKey_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithStringKey_FAST_INIT_MODE_test.DaggerTestComponent index 65513bb7e..47a7d8baa 100644 --- a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithStringKey_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithStringKey_FAST_INIT_MODE_test.DaggerTestComponent @@ -3,9 +3,9 @@ package test; import com.google.common.collect.ImmutableMap; import dagger.internal.DaggerGenerated; import dagger.internal.Preconditions; +import dagger.internal.Provider; import java.util.Map; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -16,7 +16,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -70,7 +71,7 @@ final class DaggerTestComponent { private Provider<Handler> provideLoginHandlerProvider; - private Provider<Map<String, Provider<Handler>>> mapOfStringAndProviderOfHandlerProvider; + private Provider mapOfStringAndProviderOfHandlerProvider; private TestComponentImpl(MapModuleOne mapModuleOneParam, MapModuleTwo mapModuleTwoParam) { this.mapModuleOne = mapModuleOneParam; @@ -88,7 +89,7 @@ final class DaggerTestComponent { } @Override - public Provider<Map<String, Provider<Handler>>> dispatcher() { + public javax.inject.Provider<Map<String, javax.inject.Provider<Handler>>> dispatcher() { return mapOfStringAndProviderOfHandlerProvider; } @@ -107,7 +108,7 @@ final class DaggerTestComponent { public T get() { switch (id) { case 0: // java.util.Map<java.lang.String,javax.inject.Provider<test.Handler>> - return (T) ImmutableMap.<String, Provider<Handler>>of("Admin", testComponentImpl.provideAdminHandlerProvider, "Login", testComponentImpl.provideLoginHandlerProvider); + return (T) ImmutableMap.<String, javax.inject.Provider<Handler>>of("Admin", testComponentImpl.provideAdminHandlerProvider, "Login", testComponentImpl.provideLoginHandlerProvider); case 1: // java.util.Map<java.lang.String,javax.inject.Provider<test.Handler>> test.MapModuleOne#provideAdminHandler return (T) MapModuleOne_ProvideAdminHandlerFactory.provideAdminHandler(testComponentImpl.mapModuleOne); diff --git a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithWrappedKey_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithWrappedKey_DEFAULT_MODE_test.DaggerTestComponent index 47847a7dc..bbba316c9 100644 --- a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithWrappedKey_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithWrappedKey_DEFAULT_MODE_test.DaggerTestComponent @@ -3,9 +3,9 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.MapProviderFactory; import dagger.internal.Preconditions; +import dagger.internal.Provider; import java.util.Map; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -16,7 +16,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -66,7 +67,7 @@ final class DaggerTestComponent { private Provider<Handler> provideLoginHandlerProvider; - private Provider<Map<WrappedClassKey, Provider<Handler>>> mapOfWrappedClassKeyAndProviderOfHandlerProvider; + private Provider mapOfWrappedClassKeyAndProviderOfHandlerProvider; private TestComponentImpl(MapModuleOne mapModuleOneParam, MapModuleTwo mapModuleTwoParam) { @@ -83,7 +84,8 @@ final class DaggerTestComponent { } @Override - public Provider<Map<WrappedClassKey, Provider<Handler>>> dispatcher() { + public javax.inject.Provider<Map<WrappedClassKey, javax.inject.Provider<Handler>>> dispatcher( + ) { return mapOfWrappedClassKeyAndProviderOfHandlerProvider; } } diff --git a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithWrappedKey_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithWrappedKey_FAST_INIT_MODE_test.DaggerTestComponent index 3180571c2..d057b50ae 100644 --- a/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithWrappedKey_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MapBindingComponentProcessorTest_mapBindingsWithWrappedKey_FAST_INIT_MODE_test.DaggerTestComponent @@ -3,9 +3,9 @@ package test; import com.google.common.collect.ImmutableMap; import dagger.internal.DaggerGenerated; import dagger.internal.Preconditions; +import dagger.internal.Provider; import java.util.Map; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -16,7 +16,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -70,7 +71,7 @@ final class DaggerTestComponent { private Provider<Handler> provideLoginHandlerProvider; - private Provider<Map<WrappedClassKey, Provider<Handler>>> mapOfWrappedClassKeyAndProviderOfHandlerProvider; + private Provider mapOfWrappedClassKeyAndProviderOfHandlerProvider; private TestComponentImpl(MapModuleOne mapModuleOneParam, MapModuleTwo mapModuleTwoParam) { this.mapModuleOne = mapModuleOneParam; @@ -88,7 +89,8 @@ final class DaggerTestComponent { } @Override - public Provider<Map<WrappedClassKey, Provider<Handler>>> dispatcher() { + public javax.inject.Provider<Map<WrappedClassKey, javax.inject.Provider<Handler>>> dispatcher( + ) { return mapOfWrappedClassKeyAndProviderOfHandlerProvider; } @@ -107,7 +109,7 @@ final class DaggerTestComponent { public T get() { switch (id) { case 0: // java.util.Map<test.WrappedClassKey,javax.inject.Provider<test.Handler>> - return (T) ImmutableMap.<WrappedClassKey, Provider<Handler>>of(WrappedClassKeyCreator.createWrappedClassKey(Integer.class), testComponentImpl.provideAdminHandlerProvider, WrappedClassKeyCreator.createWrappedClassKey(Long.class), testComponentImpl.provideLoginHandlerProvider); + return (T) ImmutableMap.<WrappedClassKey, javax.inject.Provider<Handler>>of(WrappedClassKeyCreator.createWrappedClassKey(Integer.class), testComponentImpl.provideAdminHandlerProvider, WrappedClassKeyCreator.createWrappedClassKey(Long.class), testComponentImpl.provideLoginHandlerProvider); case 1: // java.util.Map<test.WrappedClassKey,javax.inject.Provider<test.Handler>> test.MapModuleOne#provideAdminHandler return (T) MapModuleOne_ProvideAdminHandlerFactory.provideAdminHandler(testComponentImpl.mapModuleOne); diff --git a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_inaccessible_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_inaccessible_DEFAULT_MODE_test.DaggerTestComponent index 390f13a8c..37bbf7913 100644 --- a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_inaccessible_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_inaccessible_DEFAULT_MODE_test.DaggerTestComponent @@ -16,7 +16,8 @@ import other.UsesInaccessible_Factory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_inaccessible_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_inaccessible_FAST_INIT_MODE_test.DaggerTestComponent index 390f13a8c..37bbf7913 100644 --- a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_inaccessible_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_inaccessible_FAST_INIT_MODE_test.DaggerTestComponent @@ -16,7 +16,8 @@ import other.UsesInaccessible_Factory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_mapBindings_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_mapBindings_DEFAULT_MODE_test.DaggerTestComponent index 79ac59f39..f47f08125 100644 --- a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_mapBindings_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_mapBindings_DEFAULT_MODE_test.DaggerTestComponent @@ -16,7 +16,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_mapBindings_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_mapBindings_FAST_INIT_MODE_test.DaggerTestComponent index 0010e588c..0acd7f17a 100644 --- a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_mapBindings_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_mapBindings_FAST_INIT_MODE_test.DaggerTestComponent @@ -2,10 +2,10 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.MapBuilder; +import dagger.internal.Provider; import java.util.Collections; import java.util.Map; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -16,7 +16,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -70,8 +71,8 @@ final class DaggerTestComponent { } @Override - public Map<String, Provider<String>> providerStrings() { - return Collections.<String, Provider<String>>emptyMap(); + public Map<String, javax.inject.Provider<String>> providerStrings() { + return Collections.<String, javax.inject.Provider<String>>emptyMap(); } @Override @@ -80,8 +81,8 @@ final class DaggerTestComponent { } @Override - public Map<Integer, Provider<Integer>> providerInts() { - return Collections.<Integer, Provider<Integer>>singletonMap(0, provideIntProvider); + public Map<Integer, javax.inject.Provider<Integer>> providerInts() { + return Collections.<Integer, javax.inject.Provider<Integer>>singletonMap(0, provideIntProvider); } @Override @@ -90,8 +91,8 @@ final class DaggerTestComponent { } @Override - public Map<Long, Provider<Long>> providerLongs() { - return MapBuilder.<Long, Provider<Long>>newMapBuilder(3).put(0L, provideLong0Provider).put(1L, provideLong1Provider).put(2L, provideLong2Provider).build(); + public Map<Long, javax.inject.Provider<Long>> providerLongs() { + return MapBuilder.<Long, javax.inject.Provider<Long>>newMapBuilder(3).put(0L, provideLong0Provider).put(1L, provideLong1Provider).put(2L, provideLong2Provider).build(); } private static final class SwitchingProvider<T> implements Provider<T> { diff --git a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_productionComponents_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_productionComponents_DEFAULT_MODE_test.DaggerTestComponent index 635667fe1..8ae5d82d6 100644 --- a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_productionComponents_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_productionComponents_DEFAULT_MODE_test.DaggerTestComponent @@ -17,7 +17,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_productionComponents_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_productionComponents_FAST_INIT_MODE_test.DaggerTestComponent index 635667fe1..8ae5d82d6 100644 --- a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_productionComponents_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_productionComponents_FAST_INIT_MODE_test.DaggerTestComponent @@ -17,7 +17,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_subcomponentOmitsInheritedBindings_DEFAULT_MODE_test.DaggerParent b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_subcomponentOmitsInheritedBindings_DEFAULT_MODE_test.DaggerParent index e9f21dd47..f4f656470 100644 --- a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_subcomponentOmitsInheritedBindings_DEFAULT_MODE_test.DaggerParent +++ b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_subcomponentOmitsInheritedBindings_DEFAULT_MODE_test.DaggerParent @@ -15,7 +15,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParent { private DaggerParent() { diff --git a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_subcomponentOmitsInheritedBindings_FAST_INIT_MODE_test.DaggerParent b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_subcomponentOmitsInheritedBindings_FAST_INIT_MODE_test.DaggerParent index e9f21dd47..f4f656470 100644 --- a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_subcomponentOmitsInheritedBindings_FAST_INIT_MODE_test.DaggerParent +++ b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationTest_subcomponentOmitsInheritedBindings_FAST_INIT_MODE_test.DaggerParent @@ -15,7 +15,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParent { private DaggerParent() { diff --git a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_inaccessible_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_inaccessible_DEFAULT_MODE_test.DaggerTestComponent index 1f1d76a1e..24c561912 100644 --- a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_inaccessible_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_inaccessible_DEFAULT_MODE_test.DaggerTestComponent @@ -16,7 +16,8 @@ import other.UsesInaccessible_Factory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_inaccessible_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_inaccessible_FAST_INIT_MODE_test.DaggerTestComponent index 1f1d76a1e..24c561912 100644 --- a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_inaccessible_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_inaccessible_FAST_INIT_MODE_test.DaggerTestComponent @@ -16,7 +16,8 @@ import other.UsesInaccessible_Factory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_mapBindings_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_mapBindings_DEFAULT_MODE_test.DaggerTestComponent index e6f96d5f7..55202813e 100644 --- a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_mapBindings_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_mapBindings_DEFAULT_MODE_test.DaggerTestComponent @@ -15,7 +15,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_mapBindings_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_mapBindings_FAST_INIT_MODE_test.DaggerTestComponent index e99a9639e..12346c8b3 100644 --- a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_mapBindings_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_mapBindings_FAST_INIT_MODE_test.DaggerTestComponent @@ -2,9 +2,9 @@ package test; import com.google.common.collect.ImmutableMap; import dagger.internal.DaggerGenerated; +import dagger.internal.Provider; import java.util.Map; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -15,7 +15,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -69,8 +70,8 @@ final class DaggerTestComponent { } @Override - public Map<Long, Provider<Long>> providerLongs() { - return ImmutableMap.<Long, Provider<Long>>builderWithExpectedSize(6).put(0L, testComponentImpl.provideLong0Provider).put(1L, testComponentImpl.provideLong1Provider).put(2L, testComponentImpl.provideLong2Provider).put(3L, provideLong3Provider).put(4L, provideLong4Provider).put(5L, provideLong5Provider).build(); + public Map<Long, javax.inject.Provider<Long>> providerLongs() { + return ImmutableMap.<Long, javax.inject.Provider<Long>>builderWithExpectedSize(6).put(0L, testComponentImpl.provideLong0Provider).put(1L, testComponentImpl.provideLong1Provider).put(2L, testComponentImpl.provideLong2Provider).put(3L, provideLong3Provider).put(4L, provideLong4Provider).put(5L, provideLong5Provider).build(); } private static final class SwitchingProvider<T> implements Provider<T> { @@ -136,8 +137,8 @@ final class DaggerTestComponent { } @Override - public Map<String, Provider<String>> providerStrings() { - return ImmutableMap.<String, Provider<String>>of(); + public Map<String, javax.inject.Provider<String>> providerStrings() { + return ImmutableMap.<String, javax.inject.Provider<String>>of(); } @Override @@ -146,8 +147,8 @@ final class DaggerTestComponent { } @Override - public Map<Integer, Provider<Integer>> providerInts() { - return ImmutableMap.<Integer, Provider<Integer>>of(0, provideIntProvider); + public Map<Integer, javax.inject.Provider<Integer>> providerInts() { + return ImmutableMap.<Integer, javax.inject.Provider<Integer>>of(0, provideIntProvider); } @Override @@ -156,8 +157,8 @@ final class DaggerTestComponent { } @Override - public Map<Long, Provider<Long>> providerLongs() { - return ImmutableMap.<Long, Provider<Long>>of(0L, provideLong0Provider, 1L, provideLong1Provider, 2L, provideLong2Provider); + public Map<Long, javax.inject.Provider<Long>> providerLongs() { + return ImmutableMap.<Long, javax.inject.Provider<Long>>of(0L, provideLong0Provider, 1L, provideLong1Provider, 2L, provideLong2Provider); } @Override diff --git a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_productionComponents_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_productionComponents_DEFAULT_MODE_test.DaggerTestComponent index 26b3dfd76..dc297087b 100644 --- a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_productionComponents_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_productionComponents_DEFAULT_MODE_test.DaggerTestComponent @@ -17,7 +17,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_productionComponents_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_productionComponents_FAST_INIT_MODE_test.DaggerTestComponent index 26b3dfd76..dc297087b 100644 --- a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_productionComponents_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_productionComponents_FAST_INIT_MODE_test.DaggerTestComponent @@ -17,7 +17,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_subcomponentOmitsInheritedBindings_DEFAULT_MODE_test.DaggerParent b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_subcomponentOmitsInheritedBindings_DEFAULT_MODE_test.DaggerParent index eb764709a..0ac6e9f88 100644 --- a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_subcomponentOmitsInheritedBindings_DEFAULT_MODE_test.DaggerParent +++ b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_subcomponentOmitsInheritedBindings_DEFAULT_MODE_test.DaggerParent @@ -15,7 +15,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParent { private DaggerParent() { diff --git a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_subcomponentOmitsInheritedBindings_FAST_INIT_MODE_test.DaggerParent b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_subcomponentOmitsInheritedBindings_FAST_INIT_MODE_test.DaggerParent index eb764709a..0ac6e9f88 100644 --- a/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_subcomponentOmitsInheritedBindings_FAST_INIT_MODE_test.DaggerParent +++ b/javatests/dagger/internal/codegen/goldens/MapRequestRepresentationWithGuavaTest_subcomponentOmitsInheritedBindings_FAST_INIT_MODE_test.DaggerParent @@ -15,7 +15,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParent { private DaggerParent() { diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_accessibility_DEFAULT_MODE_other.Inaccessible_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_accessibility_DEFAULT_MODE_other.Inaccessible_MembersInjector index 0bf65b2b0..cc45f79ed 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_accessibility_DEFAULT_MODE_other.Inaccessible_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_accessibility_DEFAULT_MODE_other.Inaccessible_MembersInjector @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class Inaccessible_MembersInjector implements MembersInjector<Inaccessible> { private final Provider<Foo> fooProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_accessibility_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_accessibility_DEFAULT_MODE_test.DaggerTestComponent index 4ecf3f572..5f232b192 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_accessibility_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_accessibility_DEFAULT_MODE_test.DaggerTestComponent @@ -18,7 +18,8 @@ import other.UsesInaccessible_Factory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_accessibility_FAST_INIT_MODE_other.Inaccessible_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_accessibility_FAST_INIT_MODE_other.Inaccessible_MembersInjector index 0bf65b2b0..cc45f79ed 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_accessibility_FAST_INIT_MODE_other.Inaccessible_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_accessibility_FAST_INIT_MODE_other.Inaccessible_MembersInjector @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class Inaccessible_MembersInjector implements MembersInjector<Inaccessible> { private final Provider<Foo> fooProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_accessibility_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_accessibility_FAST_INIT_MODE_test.DaggerTestComponent index 4ecf3f572..5f232b192 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_accessibility_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_accessibility_FAST_INIT_MODE_test.DaggerTestComponent @@ -18,7 +18,8 @@ import other.UsesInaccessible_Factory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_accessibleRawType_ofInaccessibleType_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_accessibleRawType_ofInaccessibleType_DEFAULT_MODE_test.DaggerTestComponent index 5cb03e884..c17dea0d5 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_accessibleRawType_ofInaccessibleType_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_accessibleRawType_ofInaccessibleType_DEFAULT_MODE_test.DaggerTestComponent @@ -3,11 +3,9 @@ package test; import com.google.errorprone.annotations.CanIgnoreReturnValue; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; -import dagger.internal.Preconditions; +import dagger.internal.Provider; import java.util.List; import javax.annotation.processing.Generated; -import javax.inject.Provider; -import other.InaccessiblesModule; import other.InaccessiblesModule_InaccessiblesFactory; import other.UsesInaccessibles; import other.UsesInaccessibles_Factory; @@ -22,7 +20,8 @@ import other.UsesInaccessibles_MembersInjector; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -40,15 +39,6 @@ final class DaggerTestComponent { private Builder() { } - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder inaccessiblesModule(InaccessiblesModule inaccessiblesModule) { - Preconditions.checkNotNull(inaccessiblesModule); - return this; - } - public TestComponent build() { return new TestComponentImpl(); } diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_accessibleRawType_ofInaccessibleType_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_accessibleRawType_ofInaccessibleType_FAST_INIT_MODE_test.DaggerTestComponent index 02230a628..854a42927 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_accessibleRawType_ofInaccessibleType_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_accessibleRawType_ofInaccessibleType_FAST_INIT_MODE_test.DaggerTestComponent @@ -3,11 +3,9 @@ package test; import com.google.errorprone.annotations.CanIgnoreReturnValue; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; -import dagger.internal.Preconditions; +import dagger.internal.Provider; import java.util.List; import javax.annotation.processing.Generated; -import javax.inject.Provider; -import other.InaccessiblesModule; import other.InaccessiblesModule_InaccessiblesFactory; import other.UsesInaccessibles; import other.UsesInaccessibles_Factory; @@ -22,7 +20,8 @@ import other.UsesInaccessibles_MembersInjector; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -40,15 +39,6 @@ final class DaggerTestComponent { private Builder() { } - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder inaccessiblesModule(InaccessiblesModule inaccessiblesModule) { - Preconditions.checkNotNull(inaccessiblesModule); - return this; - } - public TestComponent build() { return new TestComponentImpl(); } diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_componentWithNestingAndGeneratedType_DEFAULT_MODE_test.OuterType_B_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_componentWithNestingAndGeneratedType_DEFAULT_MODE_test.OuterType_B_MembersInjector index 72b876ef0..5b4932f1c 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_componentWithNestingAndGeneratedType_DEFAULT_MODE_test.OuterType_B_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_componentWithNestingAndGeneratedType_DEFAULT_MODE_test.OuterType_B_MembersInjector @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class OuterType_B_MembersInjector implements MembersInjector<OuterType.B> { private final Provider<OuterType.A> aProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_componentWithNestingAndGeneratedType_FAST_INIT_MODE_test.OuterType_B_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_componentWithNestingAndGeneratedType_FAST_INIT_MODE_test.OuterType_B_MembersInjector index 72b876ef0..5b4932f1c 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_componentWithNestingAndGeneratedType_FAST_INIT_MODE_test.OuterType_B_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_componentWithNestingAndGeneratedType_FAST_INIT_MODE_test.OuterType_B_MembersInjector @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class OuterType_B_MembersInjector implements MembersInjector<OuterType.B> { private final Provider<OuterType.A> aProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldAndMethodGenerics_DEFAULT_MODE_test.GenericClass_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldAndMethodGenerics_DEFAULT_MODE_test.GenericClass_MembersInjector index e3a70356d..70415a8fd 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldAndMethodGenerics_DEFAULT_MODE_test.GenericClass_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldAndMethodGenerics_DEFAULT_MODE_test.GenericClass_MembersInjector @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class GenericClass_MembersInjector<A, B> implements MembersInjector<GenericClass<A, B>> { private final Provider<A> aProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldAndMethodGenerics_FAST_INIT_MODE_test.GenericClass_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldAndMethodGenerics_FAST_INIT_MODE_test.GenericClass_MembersInjector index e3a70356d..70415a8fd 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldAndMethodGenerics_FAST_INIT_MODE_test.GenericClass_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldAndMethodGenerics_FAST_INIT_MODE_test.GenericClass_MembersInjector @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class GenericClass_MembersInjector<A, B> implements MembersInjector<GenericClass<A, B>> { private final Provider<A> aProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldInjectionForShadowedMember_DEFAULT_MODE_test.Child_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldInjectionForShadowedMember_DEFAULT_MODE_test.Child_MembersInjector index 36f5651a8..2f69706c0 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldInjectionForShadowedMember_DEFAULT_MODE_test.Child_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldInjectionForShadowedMember_DEFAULT_MODE_test.Child_MembersInjector @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class Child_MembersInjector implements MembersInjector<Child> { private final Provider<Foo> objectProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldInjectionForShadowedMember_FAST_INIT_MODE_test.Child_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldInjectionForShadowedMember_FAST_INIT_MODE_test.Child_MembersInjector index 36f5651a8..2f69706c0 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldInjectionForShadowedMember_FAST_INIT_MODE_test.Child_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldInjectionForShadowedMember_FAST_INIT_MODE_test.Child_MembersInjector @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class Child_MembersInjector implements MembersInjector<Child> { private final Provider<Foo> objectProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldInjectionWithQualifier_DEFAULT_MODE_test.FieldInjectionWithQualifier_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldInjectionWithQualifier_DEFAULT_MODE_test.FieldInjectionWithQualifier_MembersInjector index 7d5b2776e..46faeb8fd 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldInjectionWithQualifier_DEFAULT_MODE_test.FieldInjectionWithQualifier_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldInjectionWithQualifier_DEFAULT_MODE_test.FieldInjectionWithQualifier_MembersInjector @@ -18,7 +18,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class FieldInjectionWithQualifier_MembersInjector implements MembersInjector<FieldInjectionWithQualifier> { private final Provider<String> aProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldInjectionWithQualifier_FAST_INIT_MODE_test.FieldInjectionWithQualifier_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldInjectionWithQualifier_FAST_INIT_MODE_test.FieldInjectionWithQualifier_MembersInjector index 7d5b2776e..46faeb8fd 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldInjectionWithQualifier_FAST_INIT_MODE_test.FieldInjectionWithQualifier_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldInjectionWithQualifier_FAST_INIT_MODE_test.FieldInjectionWithQualifier_MembersInjector @@ -18,7 +18,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class FieldInjectionWithQualifier_MembersInjector implements MembersInjector<FieldInjectionWithQualifier> { private final Provider<String> aProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldInjection_DEFAULT_MODE_test.FieldInjection_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldInjection_DEFAULT_MODE_test.FieldInjection_MembersInjector index 7c3425a73..b0af86500 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldInjection_DEFAULT_MODE_test.FieldInjection_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldInjection_DEFAULT_MODE_test.FieldInjection_MembersInjector @@ -19,7 +19,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class FieldInjection_MembersInjector implements MembersInjector<FieldInjection> { private final Provider<String> stringProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldInjection_FAST_INIT_MODE_test.FieldInjection_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldInjection_FAST_INIT_MODE_test.FieldInjection_MembersInjector index 7c3425a73..b0af86500 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldInjection_FAST_INIT_MODE_test.FieldInjection_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_fieldInjection_FAST_INIT_MODE_test.FieldInjection_MembersInjector @@ -19,7 +19,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class FieldInjection_MembersInjector implements MembersInjector<FieldInjection> { private final Provider<String> stringProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_injectConstructorAndMembersInjection_DEFAULT_MODE_test.AllInjections_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_injectConstructorAndMembersInjection_DEFAULT_MODE_test.AllInjections_MembersInjector index 479cf0702..0c67f5925 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_injectConstructorAndMembersInjection_DEFAULT_MODE_test.AllInjections_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_injectConstructorAndMembersInjection_DEFAULT_MODE_test.AllInjections_MembersInjector @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class AllInjections_MembersInjector implements MembersInjector<AllInjections> { private final Provider<String> sProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_injectConstructorAndMembersInjection_FAST_INIT_MODE_test.AllInjections_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_injectConstructorAndMembersInjection_FAST_INIT_MODE_test.AllInjections_MembersInjector index 479cf0702..0c67f5925 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_injectConstructorAndMembersInjection_FAST_INIT_MODE_test.AllInjections_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_injectConstructorAndMembersInjection_FAST_INIT_MODE_test.AllInjections_MembersInjector @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class AllInjections_MembersInjector implements MembersInjector<AllInjections> { private final Provider<String> sProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_injectsPrimitive_DEFAULT_MODE_test.InjectedType_Factory b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_injectsPrimitive_DEFAULT_MODE_test.InjectedType_Factory index 8851616a8..b63c40869 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_injectsPrimitive_DEFAULT_MODE_test.InjectedType_Factory +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_injectsPrimitive_DEFAULT_MODE_test.InjectedType_Factory @@ -18,7 +18,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class InjectedType_Factory implements Factory<InjectedType> { private final Provider<Integer> primitiveIntProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_injectsPrimitive_DEFAULT_MODE_test.InjectedType_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_injectsPrimitive_DEFAULT_MODE_test.InjectedType_MembersInjector index 91f6586b4..f28869798 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_injectsPrimitive_DEFAULT_MODE_test.InjectedType_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_injectsPrimitive_DEFAULT_MODE_test.InjectedType_MembersInjector @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class InjectedType_MembersInjector implements MembersInjector<InjectedType> { private final Provider<Integer> primitiveIntProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_injectsPrimitive_FAST_INIT_MODE_test.InjectedType_Factory b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_injectsPrimitive_FAST_INIT_MODE_test.InjectedType_Factory index 8851616a8..b63c40869 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_injectsPrimitive_FAST_INIT_MODE_test.InjectedType_Factory +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_injectsPrimitive_FAST_INIT_MODE_test.InjectedType_Factory @@ -18,7 +18,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class InjectedType_Factory implements Factory<InjectedType> { private final Provider<Integer> primitiveIntProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_injectsPrimitive_FAST_INIT_MODE_test.InjectedType_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_injectsPrimitive_FAST_INIT_MODE_test.InjectedType_MembersInjector index 91f6586b4..f28869798 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_injectsPrimitive_FAST_INIT_MODE_test.InjectedType_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_injectsPrimitive_FAST_INIT_MODE_test.InjectedType_MembersInjector @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class InjectedType_MembersInjector implements MembersInjector<InjectedType> { private final Provider<Integer> primitiveIntProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_methodInjection_DEFAULT_MODE_test.MethodInjection_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_methodInjection_DEFAULT_MODE_test.MethodInjection_MembersInjector index 3fcbb904b..9d11248f0 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_methodInjection_DEFAULT_MODE_test.MethodInjection_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_methodInjection_DEFAULT_MODE_test.MethodInjection_MembersInjector @@ -18,7 +18,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class MethodInjection_MembersInjector implements MembersInjector<MethodInjection> { private final Provider<String> stringProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_methodInjection_FAST_INIT_MODE_test.MethodInjection_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_methodInjection_FAST_INIT_MODE_test.MethodInjection_MembersInjector index 3fcbb904b..9d11248f0 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_methodInjection_FAST_INIT_MODE_test.MethodInjection_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_methodInjection_FAST_INIT_MODE_test.MethodInjection_MembersInjector @@ -18,7 +18,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class MethodInjection_MembersInjector implements MembersInjector<MethodInjection> { private final Provider<String> stringProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_middleClassNoFieldInjection_DEFAULT_MODE_test.A_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_middleClassNoFieldInjection_DEFAULT_MODE_test.A_MembersInjector index f06dabebe..86589c7a2 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_middleClassNoFieldInjection_DEFAULT_MODE_test.A_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_middleClassNoFieldInjection_DEFAULT_MODE_test.A_MembersInjector @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class A_MembersInjector implements MembersInjector<A> { private final Provider<String> valueCProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_middleClassNoFieldInjection_DEFAULT_MODE_test.C_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_middleClassNoFieldInjection_DEFAULT_MODE_test.C_MembersInjector index 1b862a731..9c181789c 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_middleClassNoFieldInjection_DEFAULT_MODE_test.C_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_middleClassNoFieldInjection_DEFAULT_MODE_test.C_MembersInjector @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class C_MembersInjector implements MembersInjector<C> { private final Provider<String> valueCProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_middleClassNoFieldInjection_FAST_INIT_MODE_test.A_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_middleClassNoFieldInjection_FAST_INIT_MODE_test.A_MembersInjector index f06dabebe..86589c7a2 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_middleClassNoFieldInjection_FAST_INIT_MODE_test.A_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_middleClassNoFieldInjection_FAST_INIT_MODE_test.A_MembersInjector @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class A_MembersInjector implements MembersInjector<A> { private final Provider<String> valueCProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_middleClassNoFieldInjection_FAST_INIT_MODE_test.C_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_middleClassNoFieldInjection_FAST_INIT_MODE_test.C_MembersInjector index 1b862a731..9c181789c 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_middleClassNoFieldInjection_FAST_INIT_MODE_test.C_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_middleClassNoFieldInjection_FAST_INIT_MODE_test.C_MembersInjector @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class C_MembersInjector implements MembersInjector<C> { private final Provider<String> valueCProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_mixedMemberInjection_DEFAULT_MODE_test.MixedMemberInjection_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_mixedMemberInjection_DEFAULT_MODE_test.MixedMemberInjection_MembersInjector index e12de5ca8..ba590b851 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_mixedMemberInjection_DEFAULT_MODE_test.MixedMemberInjection_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_mixedMemberInjection_DEFAULT_MODE_test.MixedMemberInjection_MembersInjector @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class MixedMemberInjection_MembersInjector implements MembersInjector<MixedMemberInjection> { private final Provider<String> stringProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_mixedMemberInjection_FAST_INIT_MODE_test.MixedMemberInjection_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_mixedMemberInjection_FAST_INIT_MODE_test.MixedMemberInjection_MembersInjector index e12de5ca8..ba590b851 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_mixedMemberInjection_FAST_INIT_MODE_test.MixedMemberInjection_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_mixedMemberInjection_FAST_INIT_MODE_test.MixedMemberInjection_MembersInjector @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class MixedMemberInjection_MembersInjector implements MembersInjector<MixedMemberInjection> { private final Provider<String> stringProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_parentClass_injectedMembersInSupertype_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_parentClass_injectedMembersInSupertype_DEFAULT_MODE_test.DaggerTestComponent index 2bcafb9b7..88e7fa573 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_parentClass_injectedMembersInSupertype_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_parentClass_injectedMembersInSupertype_DEFAULT_MODE_test.DaggerTestComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_parentClass_injectedMembersInSupertype_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_parentClass_injectedMembersInSupertype_FAST_INIT_MODE_test.DaggerTestComponent index 2bcafb9b7..88e7fa573 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_parentClass_injectedMembersInSupertype_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_parentClass_injectedMembersInSupertype_FAST_INIT_MODE_test.DaggerTestComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_parentClass_noInjectedMembers_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_parentClass_noInjectedMembers_DEFAULT_MODE_test.DaggerTestComponent index 9549f7be5..c4c4b0759 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_parentClass_noInjectedMembers_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_parentClass_noInjectedMembers_DEFAULT_MODE_test.DaggerTestComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_parentClass_noInjectedMembers_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_parentClass_noInjectedMembers_FAST_INIT_MODE_test.DaggerTestComponent index 9549f7be5..c4c4b0759 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_parentClass_noInjectedMembers_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_parentClass_noInjectedMembers_FAST_INIT_MODE_test.DaggerTestComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_publicSupertypeHiddenSubtype_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_publicSupertypeHiddenSubtype_DEFAULT_MODE_test.DaggerTestComponent index 560506bf0..04a41311e 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_publicSupertypeHiddenSubtype_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_publicSupertypeHiddenSubtype_DEFAULT_MODE_test.DaggerTestComponent @@ -19,7 +19,8 @@ import other.Supertype_MembersInjector; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_publicSupertypeHiddenSubtype_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_publicSupertypeHiddenSubtype_FAST_INIT_MODE_test.DaggerTestComponent index 560506bf0..04a41311e 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_publicSupertypeHiddenSubtype_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_publicSupertypeHiddenSubtype_FAST_INIT_MODE_test.DaggerTestComponent @@ -19,7 +19,8 @@ import other.Supertype_MembersInjector; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_simpleComponentWithNesting_DEFAULT_MODE_test.OuterType_B_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_simpleComponentWithNesting_DEFAULT_MODE_test.OuterType_B_MembersInjector index 72b876ef0..5b4932f1c 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_simpleComponentWithNesting_DEFAULT_MODE_test.OuterType_B_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_simpleComponentWithNesting_DEFAULT_MODE_test.OuterType_B_MembersInjector @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class OuterType_B_MembersInjector implements MembersInjector<OuterType.B> { private final Provider<OuterType.A> aProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_simpleComponentWithNesting_FAST_INIT_MODE_test.OuterType_B_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_simpleComponentWithNesting_FAST_INIT_MODE_test.OuterType_B_MembersInjector index 72b876ef0..5b4932f1c 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_simpleComponentWithNesting_FAST_INIT_MODE_test.OuterType_B_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_simpleComponentWithNesting_FAST_INIT_MODE_test.OuterType_B_MembersInjector @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class OuterType_B_MembersInjector implements MembersInjector<OuterType.B> { private final Provider<OuterType.A> aProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_subclassedGenericMembersInjectors_DEFAULT_MODE_test.Child_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_subclassedGenericMembersInjectors_DEFAULT_MODE_test.Child_MembersInjector index 19d0335fd..6040966cf 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_subclassedGenericMembersInjectors_DEFAULT_MODE_test.Child_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_subclassedGenericMembersInjectors_DEFAULT_MODE_test.Child_MembersInjector @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class Child_MembersInjector<T> implements MembersInjector<Child<T>> { private final Provider<T> xProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_subclassedGenericMembersInjectors_FAST_INIT_MODE_test.Child_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_subclassedGenericMembersInjectors_FAST_INIT_MODE_test.Child_MembersInjector index 19d0335fd..6040966cf 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_subclassedGenericMembersInjectors_FAST_INIT_MODE_test.Child_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_subclassedGenericMembersInjectors_FAST_INIT_MODE_test.Child_MembersInjector @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class Child_MembersInjector<T> implements MembersInjector<Child<T>> { private final Provider<T> xProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_supertypeMembersInjection_DEFAULT_MODE_test.B_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_supertypeMembersInjection_DEFAULT_MODE_test.B_MembersInjector index 048997088..01f787bd0 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_supertypeMembersInjection_DEFAULT_MODE_test.B_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_supertypeMembersInjection_DEFAULT_MODE_test.B_MembersInjector @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class B_MembersInjector implements MembersInjector<B> { private final Provider<String> sProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_supertypeMembersInjection_FAST_INIT_MODE_test.B_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_supertypeMembersInjection_FAST_INIT_MODE_test.B_MembersInjector index 048997088..01f787bd0 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_supertypeMembersInjection_FAST_INIT_MODE_test.B_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_supertypeMembersInjection_FAST_INIT_MODE_test.B_MembersInjector @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class B_MembersInjector implements MembersInjector<B> { private final Provider<String> sProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testConstructorInjectedFieldInjection_DEFAULT_MODE_test.A_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testConstructorInjectedFieldInjection_DEFAULT_MODE_test.A_MembersInjector index 5db62ea1f..f12625126 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testConstructorInjectedFieldInjection_DEFAULT_MODE_test.A_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testConstructorInjectedFieldInjection_DEFAULT_MODE_test.A_MembersInjector @@ -16,7 +16,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class A_MembersInjector implements MembersInjector<A> { private final Provider<String> valueBProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testConstructorInjectedFieldInjection_DEFAULT_MODE_test.B_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testConstructorInjectedFieldInjection_DEFAULT_MODE_test.B_MembersInjector index 6a818515c..192947e29 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testConstructorInjectedFieldInjection_DEFAULT_MODE_test.B_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testConstructorInjectedFieldInjection_DEFAULT_MODE_test.B_MembersInjector @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class B_MembersInjector implements MembersInjector<B> { private final Provider<String> valueBProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testConstructorInjectedFieldInjection_FAST_INIT_MODE_test.A_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testConstructorInjectedFieldInjection_FAST_INIT_MODE_test.A_MembersInjector index 5db62ea1f..f12625126 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testConstructorInjectedFieldInjection_FAST_INIT_MODE_test.A_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testConstructorInjectedFieldInjection_FAST_INIT_MODE_test.A_MembersInjector @@ -16,7 +16,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class A_MembersInjector implements MembersInjector<A> { private final Provider<String> valueBProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testConstructorInjectedFieldInjection_FAST_INIT_MODE_test.B_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testConstructorInjectedFieldInjection_FAST_INIT_MODE_test.B_MembersInjector index 6a818515c..192947e29 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testConstructorInjectedFieldInjection_FAST_INIT_MODE_test.B_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testConstructorInjectedFieldInjection_FAST_INIT_MODE_test.B_MembersInjector @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class B_MembersInjector implements MembersInjector<B> { private final Provider<String> valueBProvider; diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testMembersInjectionBindingExistsInParentComponent_DEFAULT_MODE_test.DaggerMyComponent b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testMembersInjectionBindingExistsInParentComponent_DEFAULT_MODE_test.DaggerMyComponent index c20059fe4..c563a1a1b 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testMembersInjectionBindingExistsInParentComponent_DEFAULT_MODE_test.DaggerMyComponent +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testMembersInjectionBindingExistsInParentComponent_DEFAULT_MODE_test.DaggerMyComponent @@ -15,7 +15,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class DaggerMyComponent { private DaggerMyComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testMembersInjectionBindingExistsInParentComponent_FAST_INIT_MODE_test.DaggerMyComponent b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testMembersInjectionBindingExistsInParentComponent_FAST_INIT_MODE_test.DaggerMyComponent index c20059fe4..c563a1a1b 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testMembersInjectionBindingExistsInParentComponent_FAST_INIT_MODE_test.DaggerMyComponent +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testMembersInjectionBindingExistsInParentComponent_FAST_INIT_MODE_test.DaggerMyComponent @@ -15,7 +15,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class DaggerMyComponent { private DaggerMyComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testMembersInjectionBindingSharesInjectMethodsWithProvisionBinding_DEFAULT_MODE_test.DaggerMyComponent b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testMembersInjectionBindingSharesInjectMethodsWithProvisionBinding_DEFAULT_MODE_test.DaggerMyComponent index a352ab616..72140b34b 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testMembersInjectionBindingSharesInjectMethodsWithProvisionBinding_DEFAULT_MODE_test.DaggerMyComponent +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testMembersInjectionBindingSharesInjectMethodsWithProvisionBinding_DEFAULT_MODE_test.DaggerMyComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class DaggerMyComponent { private DaggerMyComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testMembersInjectionBindingSharesInjectMethodsWithProvisionBinding_FAST_INIT_MODE_test.DaggerMyComponent b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testMembersInjectionBindingSharesInjectMethodsWithProvisionBinding_FAST_INIT_MODE_test.DaggerMyComponent index a352ab616..72140b34b 100644 --- a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testMembersInjectionBindingSharesInjectMethodsWithProvisionBinding_FAST_INIT_MODE_test.DaggerMyComponent +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testMembersInjectionBindingSharesInjectMethodsWithProvisionBinding_FAST_INIT_MODE_test.DaggerMyComponent @@ -13,7 +13,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class DaggerMyComponent { private DaggerMyComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ChildIntegerModule_ProvideIntegerFactory b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ChildIntegerModule_ProvideIntegerFactory index 622314a01..8b9a451f2 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ChildIntegerModule_ProvideIntegerFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ChildIntegerModule_ProvideIntegerFactory @@ -18,7 +18,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class ChildIntegerModule_ProvideIntegerFactory implements Factory<Integer> { private final ChildIntegerModule module; diff --git a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ChildNumberModule_ProvideNumberFactory b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ChildNumberModule_ProvideNumberFactory index b9067499f..d662cc604 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ChildNumberModule_ProvideNumberFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ChildNumberModule_ProvideNumberFactory @@ -18,7 +18,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class ChildNumberModule_ProvideNumberFactory implements Factory<Number> { private final ChildNumberModule module; diff --git a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ParentModule_ProvideBElementFactory b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ParentModule_ProvideBElementFactory index 967f5f222..d669e2a92 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ParentModule_ProvideBElementFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ParentModule_ProvideBElementFactory @@ -19,7 +19,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class ParentModule_ProvideBElementFactory<A extends CharSequence, B, C extends Number & Comparable<C>> implements Factory<B> { private final ParentModule<A, B, C> module; diff --git a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ParentModule_ProvideBEntryFactory b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ParentModule_ProvideBEntryFactory index d518c0505..35052f405 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ParentModule_ProvideBEntryFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ParentModule_ProvideBEntryFactory @@ -19,7 +19,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class ParentModule_ProvideBEntryFactory<A extends CharSequence, B, C extends Number & Comparable<C>> implements Factory<B> { private final ParentModule<A, B, C> module; diff --git a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ParentModule_ProvideListBFactory b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ParentModule_ProvideListBFactory index 405bdda7d..a36bf2620 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ParentModule_ProvideListBFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ParentModule_ProvideListBFactory @@ -20,7 +20,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class ParentModule_ProvideListBFactory<A extends CharSequence, B, C extends Number & Comparable<C>> implements Factory<List<B>> { private final ParentModule<A, B, C> module; diff --git a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_multipleProvidesMethods_test.TestModule_ProvideObjectsFactory b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_multipleProvidesMethods_test.TestModule_ProvideObjectsFactory index d0147f70d..63ae5bf3d 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_multipleProvidesMethods_test.TestModule_ProvideObjectsFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_multipleProvidesMethods_test.TestModule_ProvideObjectsFactory @@ -24,7 +24,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class TestModule_ProvideObjectsFactory implements Factory<List<Object>> { private final TestModule module; diff --git a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_nullableProvides_test.TestModule_ProvideStringFactory b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_nullableProvides_test.TestModule_ProvideStringFactory index cbc4dc1f8..8e3b1cd13 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_nullableProvides_test.TestModule_ProvideStringFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_nullableProvides_test.TestModule_ProvideStringFactory @@ -17,7 +17,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class TestModule_ProvideStringFactory implements Factory<String> { private final TestModule module; diff --git a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_parameterizedModuleWithStaticProvidesMethodOfGenericType_test.ParameterizedModule_ProvideMapStringNumberFactory b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_parameterizedModuleWithStaticProvidesMethodOfGenericType_test.ParameterizedModule_ProvideMapStringNumberFactory index 397def820..9185ad3dc 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_parameterizedModuleWithStaticProvidesMethodOfGenericType_test.ParameterizedModule_ProvideMapStringNumberFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_parameterizedModuleWithStaticProvidesMethodOfGenericType_test.ParameterizedModule_ProvideMapStringNumberFactory @@ -19,7 +19,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class ParameterizedModule_ProvideMapStringNumberFactory implements Factory<Map<String, Number>> { @Override diff --git a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_parameterizedModuleWithStaticProvidesMethodOfGenericType_test.ParameterizedModule_ProvideNonGenericTypeFactory b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_parameterizedModuleWithStaticProvidesMethodOfGenericType_test.ParameterizedModule_ProvideNonGenericTypeFactory index c5a0f3092..29bea60b7 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_parameterizedModuleWithStaticProvidesMethodOfGenericType_test.ParameterizedModule_ProvideNonGenericTypeFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_parameterizedModuleWithStaticProvidesMethodOfGenericType_test.ParameterizedModule_ProvideNonGenericTypeFactory @@ -18,7 +18,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class ParameterizedModule_ProvideNonGenericTypeFactory implements Factory<Object> { @Override diff --git a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_parameterizedModuleWithStaticProvidesMethodOfGenericType_test.ParameterizedModule_ProvideNonGenericTypeWithDepsFactory b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_parameterizedModuleWithStaticProvidesMethodOfGenericType_test.ParameterizedModule_ProvideNonGenericTypeWithDepsFactory index 019f5f266..4f9137642 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_parameterizedModuleWithStaticProvidesMethodOfGenericType_test.ParameterizedModule_ProvideNonGenericTypeWithDepsFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_parameterizedModuleWithStaticProvidesMethodOfGenericType_test.ParameterizedModule_ProvideNonGenericTypeWithDepsFactory @@ -19,7 +19,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class ParameterizedModule_ProvideNonGenericTypeWithDepsFactory implements Factory<String> { private final Provider<Object> oProvider; diff --git a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_providesSetElementWildcard_test.TestModule_ProvideWildcardListFactory b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_providesSetElementWildcard_test.TestModule_ProvideWildcardListFactory index bb66ad317..6fabfaa79 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_providesSetElementWildcard_test.TestModule_ProvideWildcardListFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_providesSetElementWildcard_test.TestModule_ProvideWildcardListFactory @@ -19,7 +19,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class TestModule_ProvideWildcardListFactory implements Factory<List<List<?>>> { private final TestModule module; diff --git a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_providesSetElement_test.TestModule_ProvideStringFactory b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_providesSetElement_test.TestModule_ProvideStringFactory index 835bb72f8..6675a4129 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_providesSetElement_test.TestModule_ProvideStringFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_providesSetElement_test.TestModule_ProvideStringFactory @@ -18,7 +18,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class TestModule_ProvideStringFactory implements Factory<String> { private final TestModule module; diff --git a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_providesSetValues_test.TestModule_ProvideStringsFactory b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_providesSetValues_test.TestModule_ProvideStringsFactory index 459a1a8a7..240620f55 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_providesSetValues_test.TestModule_ProvideStringsFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_providesSetValues_test.TestModule_ProvideStringsFactory @@ -19,7 +19,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class TestModule_ProvideStringsFactory implements Factory<Set<String>> { private final TestModule module; diff --git a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_proxyMethodsConflictWithOtherFactoryMethods_test.TestModule_CreateFactory b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_proxyMethodsConflictWithOtherFactoryMethods_test.TestModule_CreateFactory index 061a827ee..9250da8c0 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_proxyMethodsConflictWithOtherFactoryMethods_test.TestModule_CreateFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_proxyMethodsConflictWithOtherFactoryMethods_test.TestModule_CreateFactory @@ -17,7 +17,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class TestModule_CreateFactory implements Factory<Boolean> { @Override diff --git a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_proxyMethodsConflictWithOtherFactoryMethods_test.TestModule_GetFactory b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_proxyMethodsConflictWithOtherFactoryMethods_test.TestModule_GetFactory index 7d9d3c5ca..52eb22859 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_proxyMethodsConflictWithOtherFactoryMethods_test.TestModule_GetFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_proxyMethodsConflictWithOtherFactoryMethods_test.TestModule_GetFactory @@ -17,7 +17,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class TestModule_GetFactory implements Factory<Integer> { @Override diff --git a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_singleProvidesMethodNoArgs_disableNullable_test.TestModule_ProvideStringFactory b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_singleProvidesMethodNoArgs_disableNullable_test.TestModule_ProvideStringFactory index 4515d0aad..975588734 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_singleProvidesMethodNoArgs_disableNullable_test.TestModule_ProvideStringFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_singleProvidesMethodNoArgs_disableNullable_test.TestModule_ProvideStringFactory @@ -17,7 +17,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class TestModule_ProvideStringFactory implements Factory<String> { private final TestModule module; diff --git a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_singleProvidesMethodNoArgs_test.TestModule_ProvideStringFactory b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_singleProvidesMethodNoArgs_test.TestModule_ProvideStringFactory index 835bb72f8..6675a4129 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_singleProvidesMethodNoArgs_test.TestModule_ProvideStringFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_singleProvidesMethodNoArgs_test.TestModule_ProvideStringFactory @@ -18,7 +18,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class TestModule_ProvideStringFactory implements Factory<String> { private final TestModule module; diff --git a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_testQualifierMetadataOnProvides_test.MyModule_ProvideStringFactory b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_testQualifierMetadataOnProvides_test.MyModule_ProvideStringFactory index 64da8b3eb..e62e7b9b0 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_testQualifierMetadataOnProvides_test.MyModule_ProvideStringFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_testQualifierMetadataOnProvides_test.MyModule_ProvideStringFactory @@ -22,7 +22,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class MyModule_ProvideStringFactory implements Factory<String> { private final Provider<Integer> iProvider; diff --git a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_testScopeMetadataWithCustomScope_test.MyModule_ProvideStringFactory b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_testScopeMetadataWithCustomScope_test.MyModule_ProvideStringFactory index d9b71ef85..8ec360d2d 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_testScopeMetadataWithCustomScope_test.MyModule_ProvideStringFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_testScopeMetadataWithCustomScope_test.MyModule_ProvideStringFactory @@ -18,7 +18,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class MyModule_ProvideStringFactory implements Factory<String> { @Override diff --git a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_testScopedMetadataOnNonStaticProvides_test.MyModule_ProvideStringFactory b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_testScopedMetadataOnNonStaticProvides_test.MyModule_ProvideStringFactory index bd6c23753..e5a04c565 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_testScopedMetadataOnNonStaticProvides_test.MyModule_ProvideStringFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_testScopedMetadataOnNonStaticProvides_test.MyModule_ProvideStringFactory @@ -18,7 +18,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class MyModule_ProvideStringFactory implements Factory<String> { private final MyModule module; diff --git a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_testScopedMetadataOnStaticProvides_test.MyModule_ProvideStringFactory b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_testScopedMetadataOnStaticProvides_test.MyModule_ProvideStringFactory index 591f9ac4f..b88b3e345 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_testScopedMetadataOnStaticProvides_test.MyModule_ProvideStringFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_testScopedMetadataOnStaticProvides_test.MyModule_ProvideStringFactory @@ -18,7 +18,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class MyModule_ProvideStringFactory implements Factory<String> { @Override diff --git a/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_inlinedOptionalBindings_DEFAULT_JAVA7_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_inlinedOptionalBindings_DEFAULT_JAVA7_MODE_test.DaggerTestComponent index 3f21b64db..37c1bb80f 100644 --- a/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_inlinedOptionalBindings_DEFAULT_JAVA7_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_inlinedOptionalBindings_DEFAULT_JAVA7_MODE_test.DaggerTestComponent @@ -3,7 +3,6 @@ package test; import com.google.common.base.Optional; import dagger.Lazy; import dagger.internal.DaggerGenerated; -import dagger.internal.Preconditions; import dagger.internal.ProviderOfLazy; import javax.annotation.Generated; import javax.inject.Provider; @@ -20,7 +19,8 @@ import other.Maybe_MaybeModule_ProvideMaybeFactory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -38,15 +38,6 @@ final class DaggerTestComponent { private Builder() { } - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder maybeModule(Maybe.MaybeModule maybeModule) { - Preconditions.checkNotNull(maybeModule); - return this; - } - public TestComponent build() { return new TestComponentImpl(); } @@ -67,7 +58,7 @@ final class DaggerTestComponent { @Override public Optional<Provider<Lazy<Maybe>>> providerOfLazyOfMaybe() { - return Optional.of(ProviderOfLazy.create(Maybe_MaybeModule_ProvideMaybeFactory.create())); + return (Optional) Optional.of(ProviderOfLazy.create(Maybe_MaybeModule_ProvideMaybeFactory.create())); } @Override @@ -77,7 +68,7 @@ final class DaggerTestComponent { @Override public Optional<Provider<Lazy<DefinitelyNot>>> providerOfLazyOfDefinitelyNot() { - return Optional.<Provider<Lazy<DefinitelyNot>>>absent(); + return (Optional) Optional.<Provider<Lazy<DefinitelyNot>>>absent(); } } } diff --git a/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_inlinedOptionalBindings_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_inlinedOptionalBindings_DEFAULT_MODE_test.DaggerTestComponent index 72d51f348..0884286cb 100644 --- a/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_inlinedOptionalBindings_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_inlinedOptionalBindings_DEFAULT_MODE_test.DaggerTestComponent @@ -3,7 +3,6 @@ package test; import com.google.common.base.Optional; import dagger.Lazy; import dagger.internal.DaggerGenerated; -import dagger.internal.Preconditions; import dagger.internal.ProviderOfLazy; import javax.annotation.processing.Generated; import javax.inject.Provider; @@ -20,7 +19,8 @@ import other.Maybe_MaybeModule_ProvideMaybeFactory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -38,15 +38,6 @@ final class DaggerTestComponent { private Builder() { } - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder maybeModule(Maybe.MaybeModule maybeModule) { - Preconditions.checkNotNull(maybeModule); - return this; - } - public TestComponent build() { return new TestComponentImpl(); } diff --git a/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_inlinedOptionalBindings_FAST_INIT_JAVA7_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_inlinedOptionalBindings_FAST_INIT_JAVA7_MODE_test.DaggerTestComponent index f99b125cc..f1ab21401 100644 --- a/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_inlinedOptionalBindings_FAST_INIT_JAVA7_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_inlinedOptionalBindings_FAST_INIT_JAVA7_MODE_test.DaggerTestComponent @@ -3,10 +3,9 @@ package test; import com.google.common.base.Optional; import dagger.Lazy; import dagger.internal.DaggerGenerated; -import dagger.internal.Preconditions; +import dagger.internal.Provider; import dagger.internal.ProviderOfLazy; import javax.annotation.Generated; -import javax.inject.Provider; import other.DefinitelyNot; import other.Maybe; import other.Maybe_MaybeModule_ProvideMaybeFactory; @@ -20,7 +19,8 @@ import other.Maybe_MaybeModule_ProvideMaybeFactory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -38,15 +38,6 @@ final class DaggerTestComponent { private Builder() { } - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder maybeModule(Maybe.MaybeModule maybeModule) { - Preconditions.checkNotNull(maybeModule); - return this; - } - public TestComponent build() { return new TestComponentImpl(); } @@ -74,8 +65,8 @@ final class DaggerTestComponent { } @Override - public Optional<Provider<Lazy<Maybe>>> providerOfLazyOfMaybe() { - return Optional.of(ProviderOfLazy.create(provideMaybeProvider)); + public Optional<javax.inject.Provider<Lazy<Maybe>>> providerOfLazyOfMaybe() { + return (Optional) Optional.of(ProviderOfLazy.create(provideMaybeProvider)); } @Override @@ -84,8 +75,8 @@ final class DaggerTestComponent { } @Override - public Optional<Provider<Lazy<DefinitelyNot>>> providerOfLazyOfDefinitelyNot() { - return Optional.<Provider<Lazy<DefinitelyNot>>>absent(); + public Optional<javax.inject.Provider<Lazy<DefinitelyNot>>> providerOfLazyOfDefinitelyNot() { + return (Optional) Optional.<javax.inject.Provider<Lazy<DefinitelyNot>>>absent(); } private static final class SwitchingProvider<T> implements Provider<T> { diff --git a/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_inlinedOptionalBindings_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_inlinedOptionalBindings_FAST_INIT_MODE_test.DaggerTestComponent index 5d4406344..83b8f8114 100644 --- a/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_inlinedOptionalBindings_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_inlinedOptionalBindings_FAST_INIT_MODE_test.DaggerTestComponent @@ -3,10 +3,9 @@ package test; import com.google.common.base.Optional; import dagger.Lazy; import dagger.internal.DaggerGenerated; -import dagger.internal.Preconditions; +import dagger.internal.Provider; import dagger.internal.ProviderOfLazy; import javax.annotation.processing.Generated; -import javax.inject.Provider; import other.DefinitelyNot; import other.Maybe; import other.Maybe_MaybeModule_ProvideMaybeFactory; @@ -20,7 +19,8 @@ import other.Maybe_MaybeModule_ProvideMaybeFactory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -38,15 +38,6 @@ final class DaggerTestComponent { private Builder() { } - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder maybeModule(Maybe.MaybeModule maybeModule) { - Preconditions.checkNotNull(maybeModule); - return this; - } - public TestComponent build() { return new TestComponentImpl(); } @@ -74,7 +65,7 @@ final class DaggerTestComponent { } @Override - public Optional<Provider<Lazy<Maybe>>> providerOfLazyOfMaybe() { + public Optional<javax.inject.Provider<Lazy<Maybe>>> providerOfLazyOfMaybe() { return Optional.of(ProviderOfLazy.create(provideMaybeProvider)); } @@ -84,7 +75,7 @@ final class DaggerTestComponent { } @Override - public Optional<Provider<Lazy<DefinitelyNot>>> providerOfLazyOfDefinitelyNot() { + public Optional<javax.inject.Provider<Lazy<DefinitelyNot>>> providerOfLazyOfDefinitelyNot() { return Optional.absent(); } diff --git a/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_requestForFuture_DEFAULT_JAVA7_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_requestForFuture_DEFAULT_JAVA7_MODE_test.DaggerTestComponent index 7325da92c..9d278cb34 100644 --- a/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_requestForFuture_DEFAULT_JAVA7_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_requestForFuture_DEFAULT_JAVA7_MODE_test.DaggerTestComponent @@ -4,7 +4,6 @@ import com.google.common.base.Optional; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import dagger.internal.DaggerGenerated; -import dagger.internal.Preconditions; import dagger.producers.internal.CancellationListener; import javax.annotation.Generated; import other.DefinitelyNot; @@ -20,7 +19,8 @@ import other.Maybe_MaybeModule_ProvideMaybeFactory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -38,15 +38,6 @@ final class DaggerTestComponent { private Builder() { } - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder maybeModule(Maybe.MaybeModule maybeModule) { - Preconditions.checkNotNull(maybeModule); - return this; - } - public TestComponent build() { return new TestComponentImpl(); } diff --git a/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_requestForFuture_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_requestForFuture_DEFAULT_MODE_test.DaggerTestComponent index 0e2bb0f67..e6e1d5aab 100644 --- a/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_requestForFuture_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_requestForFuture_DEFAULT_MODE_test.DaggerTestComponent @@ -4,7 +4,6 @@ import com.google.common.base.Optional; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import dagger.internal.DaggerGenerated; -import dagger.internal.Preconditions; import dagger.producers.internal.CancellationListener; import javax.annotation.processing.Generated; import other.DefinitelyNot; @@ -20,7 +19,8 @@ import other.Maybe_MaybeModule_ProvideMaybeFactory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -38,15 +38,6 @@ final class DaggerTestComponent { private Builder() { } - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder maybeModule(Maybe.MaybeModule maybeModule) { - Preconditions.checkNotNull(maybeModule); - return this; - } - public TestComponent build() { return new TestComponentImpl(); } diff --git a/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_requestForFuture_FAST_INIT_JAVA7_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_requestForFuture_FAST_INIT_JAVA7_MODE_test.DaggerTestComponent index 7325da92c..9d278cb34 100644 --- a/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_requestForFuture_FAST_INIT_JAVA7_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_requestForFuture_FAST_INIT_JAVA7_MODE_test.DaggerTestComponent @@ -4,7 +4,6 @@ import com.google.common.base.Optional; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import dagger.internal.DaggerGenerated; -import dagger.internal.Preconditions; import dagger.producers.internal.CancellationListener; import javax.annotation.Generated; import other.DefinitelyNot; @@ -20,7 +19,8 @@ import other.Maybe_MaybeModule_ProvideMaybeFactory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -38,15 +38,6 @@ final class DaggerTestComponent { private Builder() { } - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder maybeModule(Maybe.MaybeModule maybeModule) { - Preconditions.checkNotNull(maybeModule); - return this; - } - public TestComponent build() { return new TestComponentImpl(); } diff --git a/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_requestForFuture_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_requestForFuture_FAST_INIT_MODE_test.DaggerTestComponent index 0e2bb0f67..e6e1d5aab 100644 --- a/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_requestForFuture_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_requestForFuture_FAST_INIT_MODE_test.DaggerTestComponent @@ -4,7 +4,6 @@ import com.google.common.base.Optional; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import dagger.internal.DaggerGenerated; -import dagger.internal.Preconditions; import dagger.producers.internal.CancellationListener; import javax.annotation.processing.Generated; import other.DefinitelyNot; @@ -20,7 +19,8 @@ import other.Maybe_MaybeModule_ProvideMaybeFactory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -38,15 +38,6 @@ final class DaggerTestComponent { private Builder() { } - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder maybeModule(Maybe.MaybeModule maybeModule) { - Preconditions.checkNotNull(maybeModule); - return this; - } - public TestComponent build() { return new TestComponentImpl(); } diff --git a/javatests/dagger/internal/codegen/goldens/ProducerModuleFactoryGeneratorTest_singleProducesMethodNoArgsFutureWithProducerName_test.TestModule_ProduceStringFactory b/javatests/dagger/internal/codegen/goldens/ProducerModuleFactoryGeneratorTest_singleProducesMethodNoArgsFutureWithProducerName_test.TestModule_ProduceStringFactory index bf59a062c..048cdc8c3 100644 --- a/javatests/dagger/internal/codegen/goldens/ProducerModuleFactoryGeneratorTest_singleProducesMethodNoArgsFutureWithProducerName_test.TestModule_ProduceStringFactory +++ b/javatests/dagger/internal/codegen/goldens/ProducerModuleFactoryGeneratorTest_singleProducesMethodNoArgsFutureWithProducerName_test.TestModule_ProduceStringFactory @@ -20,7 +20,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class TestModule_ProduceStringFactory extends AbstractProducesMethodProducer<Void, String> { private final TestModule module; diff --git a/javatests/dagger/internal/codegen/goldens/ProducerModuleFactoryGeneratorTest_singleProducesMethodNoArgsFuture_test.TestModule_ProduceStringFactory b/javatests/dagger/internal/codegen/goldens/ProducerModuleFactoryGeneratorTest_singleProducesMethodNoArgsFuture_test.TestModule_ProduceStringFactory index cf94c2df4..248ceb1d3 100644 --- a/javatests/dagger/internal/codegen/goldens/ProducerModuleFactoryGeneratorTest_singleProducesMethodNoArgsFuture_test.TestModule_ProduceStringFactory +++ b/javatests/dagger/internal/codegen/goldens/ProducerModuleFactoryGeneratorTest_singleProducesMethodNoArgsFuture_test.TestModule_ProduceStringFactory @@ -20,7 +20,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) public final class TestModule_ProduceStringFactory extends AbstractProducesMethodProducer<Void, String> { private final TestModule module; diff --git a/javatests/dagger/internal/codegen/goldens/ProductionComponentProcessorTest_productionScope_injectConstructor_DEFAULT_MODE_test.DaggerParent b/javatests/dagger/internal/codegen/goldens/ProductionComponentProcessorTest_productionScope_injectConstructor_DEFAULT_MODE_test.DaggerParent index 11af50c5f..3b72cd404 100644 --- a/javatests/dagger/internal/codegen/goldens/ProductionComponentProcessorTest_productionScope_injectConstructor_DEFAULT_MODE_test.DaggerParent +++ b/javatests/dagger/internal/codegen/goldens/ProductionComponentProcessorTest_productionScope_injectConstructor_DEFAULT_MODE_test.DaggerParent @@ -2,9 +2,9 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import dagger.producers.internal.CancellationListener; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -15,7 +15,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParent { private DaggerParent() { diff --git a/javatests/dagger/internal/codegen/goldens/ProductionComponentProcessorTest_productionScope_injectConstructor_FAST_INIT_MODE_test.DaggerParent b/javatests/dagger/internal/codegen/goldens/ProductionComponentProcessorTest_productionScope_injectConstructor_FAST_INIT_MODE_test.DaggerParent index 5d0b797d5..ab89babec 100644 --- a/javatests/dagger/internal/codegen/goldens/ProductionComponentProcessorTest_productionScope_injectConstructor_FAST_INIT_MODE_test.DaggerParent +++ b/javatests/dagger/internal/codegen/goldens/ProductionComponentProcessorTest_productionScope_injectConstructor_FAST_INIT_MODE_test.DaggerParent @@ -2,9 +2,9 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import dagger.producers.internal.CancellationListener; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -15,7 +15,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParent { private DaggerParent() { diff --git a/javatests/dagger/internal/codegen/goldens/ProductionComponentProcessorTest_simpleComponent_DEFAULT_MODE_test.DaggerTestClass_SimpleComponent b/javatests/dagger/internal/codegen/goldens/ProductionComponentProcessorTest_simpleComponent_DEFAULT_MODE_test.DaggerTestClass_SimpleComponent index d55cd3735..61460047a 100644 --- a/javatests/dagger/internal/codegen/goldens/ProductionComponentProcessorTest_simpleComponent_DEFAULT_MODE_test.DaggerTestClass_SimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ProductionComponentProcessorTest_simpleComponent_DEFAULT_MODE_test.DaggerTestClass_SimpleComponent @@ -5,6 +5,7 @@ import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; import dagger.internal.InstanceFactory; import dagger.internal.Preconditions; +import dagger.internal.Provider; import dagger.internal.SetFactory; import dagger.producers.Producer; import dagger.producers.internal.CancellationListener; @@ -12,7 +13,6 @@ import dagger.producers.internal.Producers; import dagger.producers.monitoring.ProductionComponentMonitor; import java.util.concurrent.Executor; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -23,7 +23,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestClass_SimpleComponent { private DaggerTestClass_SimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/ProductionComponentProcessorTest_simpleComponent_FAST_INIT_MODE_test.DaggerTestClass_SimpleComponent b/javatests/dagger/internal/codegen/goldens/ProductionComponentProcessorTest_simpleComponent_FAST_INIT_MODE_test.DaggerTestClass_SimpleComponent index 9ad6e6fa2..c5df7dce1 100644 --- a/javatests/dagger/internal/codegen/goldens/ProductionComponentProcessorTest_simpleComponent_FAST_INIT_MODE_test.DaggerTestClass_SimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/ProductionComponentProcessorTest_simpleComponent_FAST_INIT_MODE_test.DaggerTestClass_SimpleComponent @@ -5,6 +5,7 @@ import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; import dagger.internal.InstanceFactory; import dagger.internal.Preconditions; +import dagger.internal.Provider; import dagger.internal.SetFactory; import dagger.producers.Producer; import dagger.producers.internal.CancellationListener; @@ -12,7 +13,6 @@ import dagger.producers.internal.Producers; import dagger.producers.monitoring.ProductionComponentMonitor; import java.util.concurrent.Executor; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -23,7 +23,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestClass_SimpleComponent { private DaggerTestClass_SimpleComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_inaccessible_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_inaccessible_DEFAULT_MODE_test.DaggerTestComponent index 7d8595248..988302c7e 100644 --- a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_inaccessible_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_inaccessible_DEFAULT_MODE_test.DaggerTestComponent @@ -18,7 +18,8 @@ import other.UsesInaccessible_Factory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_inaccessible_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_inaccessible_FAST_INIT_MODE_test.DaggerTestComponent index 7d8595248..988302c7e 100644 --- a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_inaccessible_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_inaccessible_FAST_INIT_MODE_test.DaggerTestComponent @@ -18,7 +18,8 @@ import other.UsesInaccessible_Factory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_productionComponents_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_productionComponents_DEFAULT_MODE_test.DaggerTestComponent index d174c1f9f..f56f0e62c 100644 --- a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_productionComponents_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_productionComponents_DEFAULT_MODE_test.DaggerTestComponent @@ -17,7 +17,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_productionComponents_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_productionComponents_FAST_INIT_MODE_test.DaggerTestComponent index d174c1f9f..f56f0e62c 100644 --- a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_productionComponents_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_productionComponents_FAST_INIT_MODE_test.DaggerTestComponent @@ -17,7 +17,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_setBindings_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_setBindings_DEFAULT_MODE_test.DaggerTestComponent index 829486b19..e69fffee6 100644 --- a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_setBindings_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_setBindings_DEFAULT_MODE_test.DaggerTestComponent @@ -1,7 +1,6 @@ package test; import dagger.internal.DaggerGenerated; -import dagger.internal.Preconditions; import dagger.internal.SetBuilder; import java.util.Collections; import java.util.Set; @@ -16,7 +15,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -34,15 +34,6 @@ final class DaggerTestComponent { private Builder() { } - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder setModule(SetModule setModule) { - Preconditions.checkNotNull(setModule); - return this; - } - public TestComponent build() { return new TestComponentImpl(); } diff --git a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_setBindings_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_setBindings_FAST_INIT_MODE_test.DaggerTestComponent index 829486b19..e69fffee6 100644 --- a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_setBindings_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_setBindings_FAST_INIT_MODE_test.DaggerTestComponent @@ -1,7 +1,6 @@ package test; import dagger.internal.DaggerGenerated; -import dagger.internal.Preconditions; import dagger.internal.SetBuilder; import java.util.Collections; import java.util.Set; @@ -16,7 +15,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -34,15 +34,6 @@ final class DaggerTestComponent { private Builder() { } - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder setModule(SetModule setModule) { - Preconditions.checkNotNull(setModule); - return this; - } - public TestComponent build() { return new TestComponentImpl(); } diff --git a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_subcomponentOmitsInheritedBindings_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_subcomponentOmitsInheritedBindings_DEFAULT_MODE_test.DaggerTestComponent index 24b2d569f..2ffdfd2e7 100644 --- a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_subcomponentOmitsInheritedBindings_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_subcomponentOmitsInheritedBindings_DEFAULT_MODE_test.DaggerTestComponent @@ -1,7 +1,6 @@ package test; import dagger.internal.DaggerGenerated; -import dagger.internal.Preconditions; import java.util.Collections; import java.util.Set; import javax.annotation.processing.Generated; @@ -15,7 +14,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParent { private DaggerParent() { @@ -33,15 +33,6 @@ final class DaggerParent { private Builder() { } - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder parentModule(ParentModule parentModule) { - Preconditions.checkNotNull(parentModule); - return this; - } - public Parent build() { return new ParentImpl(); } diff --git a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_subcomponentOmitsInheritedBindings_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_subcomponentOmitsInheritedBindings_FAST_INIT_MODE_test.DaggerTestComponent index 24b2d569f..2ffdfd2e7 100644 --- a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_subcomponentOmitsInheritedBindings_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentTest_subcomponentOmitsInheritedBindings_FAST_INIT_MODE_test.DaggerTestComponent @@ -1,7 +1,6 @@ package test; import dagger.internal.DaggerGenerated; -import dagger.internal.Preconditions; import java.util.Collections; import java.util.Set; import javax.annotation.processing.Generated; @@ -15,7 +14,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParent { private DaggerParent() { @@ -33,15 +33,6 @@ final class DaggerParent { private Builder() { } - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder parentModule(ParentModule parentModule) { - Preconditions.checkNotNull(parentModule); - return this; - } - public Parent build() { return new ParentImpl(); } diff --git a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_inaccessible_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_inaccessible_DEFAULT_MODE_test.DaggerTestComponent index fb9fffb5d..1d16978ae 100644 --- a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_inaccessible_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_inaccessible_DEFAULT_MODE_test.DaggerTestComponent @@ -17,7 +17,8 @@ import other.UsesInaccessible_Factory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_inaccessible_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_inaccessible_FAST_INIT_MODE_test.DaggerTestComponent index fb9fffb5d..1d16978ae 100644 --- a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_inaccessible_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_inaccessible_FAST_INIT_MODE_test.DaggerTestComponent @@ -17,7 +17,8 @@ import other.UsesInaccessible_Factory; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_productionComponents_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_productionComponents_DEFAULT_MODE_test.DaggerTestComponent index 5df3e4df4..a6836ce31 100644 --- a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_productionComponents_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_productionComponents_DEFAULT_MODE_test.DaggerTestComponent @@ -17,7 +17,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_productionComponents_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_productionComponents_FAST_INIT_MODE_test.DaggerTestComponent index 5df3e4df4..a6836ce31 100644 --- a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_productionComponents_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_productionComponents_FAST_INIT_MODE_test.DaggerTestComponent @@ -17,7 +17,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_setBindings_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_setBindings_DEFAULT_MODE_test.DaggerTestComponent index ef0830982..e2ff2df65 100644 --- a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_setBindings_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_setBindings_DEFAULT_MODE_test.DaggerTestComponent @@ -2,7 +2,6 @@ package test; import com.google.common.collect.ImmutableSet; import dagger.internal.DaggerGenerated; -import dagger.internal.Preconditions; import java.util.Set; import javax.annotation.processing.Generated; @@ -15,7 +14,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -33,15 +33,6 @@ final class DaggerTestComponent { private Builder() { } - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder setModule(SetModule setModule) { - Preconditions.checkNotNull(setModule); - return this; - } - public TestComponent build() { return new TestComponentImpl(); } diff --git a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_setBindings_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_setBindings_FAST_INIT_MODE_test.DaggerTestComponent index ef0830982..e2ff2df65 100644 --- a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_setBindings_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_setBindings_FAST_INIT_MODE_test.DaggerTestComponent @@ -2,7 +2,6 @@ package test; import com.google.common.collect.ImmutableSet; import dagger.internal.DaggerGenerated; -import dagger.internal.Preconditions; import java.util.Set; import javax.annotation.processing.Generated; @@ -15,7 +14,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -33,15 +33,6 @@ final class DaggerTestComponent { private Builder() { } - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder setModule(SetModule setModule) { - Preconditions.checkNotNull(setModule); - return this; - } - public TestComponent build() { return new TestComponentImpl(); } diff --git a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_subcomponentOmitsInheritedBindings_DEFAULT_MODE_test.DaggerParent b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_subcomponentOmitsInheritedBindings_DEFAULT_MODE_test.DaggerParent index 36e87af44..9b03019f2 100644 --- a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_subcomponentOmitsInheritedBindings_DEFAULT_MODE_test.DaggerParent +++ b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_subcomponentOmitsInheritedBindings_DEFAULT_MODE_test.DaggerParent @@ -2,7 +2,6 @@ package test; import com.google.common.collect.ImmutableSet; import dagger.internal.DaggerGenerated; -import dagger.internal.Preconditions; import java.util.Set; import javax.annotation.processing.Generated; @@ -15,7 +14,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParent { private DaggerParent() { @@ -33,15 +33,6 @@ final class DaggerParent { private Builder() { } - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder parentModule(ParentModule parentModule) { - Preconditions.checkNotNull(parentModule); - return this; - } - public Parent build() { return new ParentImpl(); } diff --git a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_subcomponentOmitsInheritedBindings_FAST_INIT_MODE_test.DaggerParent b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_subcomponentOmitsInheritedBindings_FAST_INIT_MODE_test.DaggerParent index 36e87af44..9b03019f2 100644 --- a/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_subcomponentOmitsInheritedBindings_FAST_INIT_MODE_test.DaggerParent +++ b/javatests/dagger/internal/codegen/goldens/SetBindingRequestFulfillmentWithGuavaTest_subcomponentOmitsInheritedBindings_FAST_INIT_MODE_test.DaggerParent @@ -2,7 +2,6 @@ package test; import com.google.common.collect.ImmutableSet; import dagger.internal.DaggerGenerated; -import dagger.internal.Preconditions; import java.util.Set; import javax.annotation.processing.Generated; @@ -15,7 +14,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParent { private DaggerParent() { @@ -33,15 +33,6 @@ final class DaggerParent { private Builder() { } - /** - * @deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://dagger.dev/unused-modules. - */ - @Deprecated - public Builder parentModule(ParentModule parentModule) { - Preconditions.checkNotNull(parentModule); - return this; - } - public Parent build() { return new ParentImpl(); } diff --git a/javatests/dagger/internal/codegen/goldens/SubcomponentCreatorRequestFulfillmentTest_testInlinedSubcomponentCreators_componentMethod_compilerMode=DEFAULT_MODE, creatorKind=dagger.Subcomponent.Builder_test.DaggerC b/javatests/dagger/internal/codegen/goldens/SubcomponentCreatorRequestFulfillmentTest_testInlinedSubcomponentCreators_componentMethod_compilerMode=DEFAULT_MODE, creatorKind=dagger.Subcomponent.Builder_test.DaggerC index cac6863d8..a2352f628 100644 --- a/javatests/dagger/internal/codegen/goldens/SubcomponentCreatorRequestFulfillmentTest_testInlinedSubcomponentCreators_componentMethod_compilerMode=DEFAULT_MODE, creatorKind=dagger.Subcomponent.Builder_test.DaggerC +++ b/javatests/dagger/internal/codegen/goldens/SubcomponentCreatorRequestFulfillmentTest_testInlinedSubcomponentCreators_componentMethod_compilerMode=DEFAULT_MODE, creatorKind=dagger.Subcomponent.Builder_test.DaggerC @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerC { private DaggerC() { diff --git a/javatests/dagger/internal/codegen/goldens/SubcomponentCreatorRequestFulfillmentTest_testInlinedSubcomponentCreators_componentMethod_compilerMode=DEFAULT_MODE, creatorKind=dagger.Subcomponent.Factory_test.DaggerC b/javatests/dagger/internal/codegen/goldens/SubcomponentCreatorRequestFulfillmentTest_testInlinedSubcomponentCreators_componentMethod_compilerMode=DEFAULT_MODE, creatorKind=dagger.Subcomponent.Factory_test.DaggerC index bb85c82cf..a0c70805b 100644 --- a/javatests/dagger/internal/codegen/goldens/SubcomponentCreatorRequestFulfillmentTest_testInlinedSubcomponentCreators_componentMethod_compilerMode=DEFAULT_MODE, creatorKind=dagger.Subcomponent.Factory_test.DaggerC +++ b/javatests/dagger/internal/codegen/goldens/SubcomponentCreatorRequestFulfillmentTest_testInlinedSubcomponentCreators_componentMethod_compilerMode=DEFAULT_MODE, creatorKind=dagger.Subcomponent.Factory_test.DaggerC @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerC { private DaggerC() { diff --git a/javatests/dagger/internal/codegen/goldens/SubcomponentCreatorRequestFulfillmentTest_testInlinedSubcomponentCreators_componentMethod_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Subcomponent.Builder_test.DaggerC b/javatests/dagger/internal/codegen/goldens/SubcomponentCreatorRequestFulfillmentTest_testInlinedSubcomponentCreators_componentMethod_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Subcomponent.Builder_test.DaggerC index cac6863d8..a2352f628 100644 --- a/javatests/dagger/internal/codegen/goldens/SubcomponentCreatorRequestFulfillmentTest_testInlinedSubcomponentCreators_componentMethod_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Subcomponent.Builder_test.DaggerC +++ b/javatests/dagger/internal/codegen/goldens/SubcomponentCreatorRequestFulfillmentTest_testInlinedSubcomponentCreators_componentMethod_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Subcomponent.Builder_test.DaggerC @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerC { private DaggerC() { diff --git a/javatests/dagger/internal/codegen/goldens/SubcomponentCreatorRequestFulfillmentTest_testInlinedSubcomponentCreators_componentMethod_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Subcomponent.Factory_test.DaggerC b/javatests/dagger/internal/codegen/goldens/SubcomponentCreatorRequestFulfillmentTest_testInlinedSubcomponentCreators_componentMethod_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Subcomponent.Factory_test.DaggerC index bb85c82cf..a0c70805b 100644 --- a/javatests/dagger/internal/codegen/goldens/SubcomponentCreatorRequestFulfillmentTest_testInlinedSubcomponentCreators_componentMethod_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Subcomponent.Factory_test.DaggerC +++ b/javatests/dagger/internal/codegen/goldens/SubcomponentCreatorRequestFulfillmentTest_testInlinedSubcomponentCreators_componentMethod_compilerMode=FAST_INIT_MODE, creatorKind=dagger.Subcomponent.Factory_test.DaggerC @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerC { private DaggerC() { diff --git a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_delegateFactoryNotCreatedForSubcomponentWhenProviderExistsInParent_DEFAULT_MODE_test.DaggerParentComponent b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_delegateFactoryNotCreatedForSubcomponentWhenProviderExistsInParent_DEFAULT_MODE_test.DaggerParentComponent index b05b85f06..3a24c10c8 100644 --- a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_delegateFactoryNotCreatedForSubcomponentWhenProviderExistsInParent_DEFAULT_MODE_test.DaggerParentComponent +++ b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_delegateFactoryNotCreatedForSubcomponentWhenProviderExistsInParent_DEFAULT_MODE_test.DaggerParentComponent @@ -3,8 +3,8 @@ package test; import com.google.errorprone.annotations.CanIgnoreReturnValue; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -15,7 +15,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParentComponent { private DaggerParentComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_delegateFactoryNotCreatedForSubcomponentWhenProviderExistsInParent_FAST_INIT_MODE_test.DaggerParentComponent b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_delegateFactoryNotCreatedForSubcomponentWhenProviderExistsInParent_FAST_INIT_MODE_test.DaggerParentComponent index 6311a200c..4cbe54367 100644 --- a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_delegateFactoryNotCreatedForSubcomponentWhenProviderExistsInParent_FAST_INIT_MODE_test.DaggerParentComponent +++ b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_delegateFactoryNotCreatedForSubcomponentWhenProviderExistsInParent_FAST_INIT_MODE_test.DaggerParentComponent @@ -3,8 +3,8 @@ package test; import com.google.errorprone.annotations.CanIgnoreReturnValue; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -15,7 +15,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParentComponent { private DaggerParentComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_multipleSubcomponentsWithSameSimpleNamesCanExistInSameComponent_DEFAULT_MODE_test.DaggerParentComponent b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_multipleSubcomponentsWithSameSimpleNamesCanExistInSameComponent_DEFAULT_MODE_test.DaggerParentComponent index 5e80c3697..245871b86 100644 --- a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_multipleSubcomponentsWithSameSimpleNamesCanExistInSameComponent_DEFAULT_MODE_test.DaggerParentComponent +++ b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_multipleSubcomponentsWithSameSimpleNamesCanExistInSameComponent_DEFAULT_MODE_test.DaggerParentComponent @@ -13,7 +13,8 @@ import test.subpackage.Sub; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParentComponent { private DaggerParentComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_multipleSubcomponentsWithSameSimpleNamesCanExistInSameComponent_FAST_INIT_MODE_test.DaggerParentComponent b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_multipleSubcomponentsWithSameSimpleNamesCanExistInSameComponent_FAST_INIT_MODE_test.DaggerParentComponent index 5e80c3697..245871b86 100644 --- a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_multipleSubcomponentsWithSameSimpleNamesCanExistInSameComponent_FAST_INIT_MODE_test.DaggerParentComponent +++ b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_multipleSubcomponentsWithSameSimpleNamesCanExistInSameComponent_FAST_INIT_MODE_test.DaggerParentComponent @@ -13,7 +13,8 @@ import test.subpackage.Sub; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParentComponent { private DaggerParentComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentBuilderNamesShouldNotConflict_DEFAULT_MODE_test.DaggerC b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentBuilderNamesShouldNotConflict_DEFAULT_MODE_test.DaggerC index ad51478c6..c866218de 100644 --- a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentBuilderNamesShouldNotConflict_DEFAULT_MODE_test.DaggerC +++ b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentBuilderNamesShouldNotConflict_DEFAULT_MODE_test.DaggerC @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerC { private DaggerC() { diff --git a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentBuilderNamesShouldNotConflict_FAST_INIT_MODE_test.DaggerC b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentBuilderNamesShouldNotConflict_FAST_INIT_MODE_test.DaggerC index ad51478c6..c866218de 100644 --- a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentBuilderNamesShouldNotConflict_FAST_INIT_MODE_test.DaggerC +++ b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentBuilderNamesShouldNotConflict_FAST_INIT_MODE_test.DaggerC @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerC { private DaggerC() { diff --git a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentImplNameUsesFullyQualifiedClassNameIfNecessary_DEFAULT_MODE_test.DaggerParentComponent b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentImplNameUsesFullyQualifiedClassNameIfNecessary_DEFAULT_MODE_test.DaggerParentComponent index fc75681bb..a778a058c 100644 --- a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentImplNameUsesFullyQualifiedClassNameIfNecessary_DEFAULT_MODE_test.DaggerParentComponent +++ b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentImplNameUsesFullyQualifiedClassNameIfNecessary_DEFAULT_MODE_test.DaggerParentComponent @@ -13,7 +13,8 @@ import top1.a.b.c.d.E; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParentComponent { private DaggerParentComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentImplNameUsesFullyQualifiedClassNameIfNecessary_FAST_INIT_MODE_test.DaggerParentComponent b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentImplNameUsesFullyQualifiedClassNameIfNecessary_FAST_INIT_MODE_test.DaggerParentComponent index fc75681bb..a778a058c 100644 --- a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentImplNameUsesFullyQualifiedClassNameIfNecessary_FAST_INIT_MODE_test.DaggerParentComponent +++ b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentImplNameUsesFullyQualifiedClassNameIfNecessary_FAST_INIT_MODE_test.DaggerParentComponent @@ -13,7 +13,8 @@ import top1.a.b.c.d.E; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParentComponent { private DaggerParentComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentNamesShouldNotConflictWithParent_DEFAULT_MODE_test.DaggerC b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentNamesShouldNotConflictWithParent_DEFAULT_MODE_test.DaggerC index 69f480fb1..e2c98e3d4 100644 --- a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentNamesShouldNotConflictWithParent_DEFAULT_MODE_test.DaggerC +++ b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentNamesShouldNotConflictWithParent_DEFAULT_MODE_test.DaggerC @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerC { private DaggerC() { diff --git a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentNamesShouldNotConflictWithParent_FAST_INIT_MODE_test.DaggerC b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentNamesShouldNotConflictWithParent_FAST_INIT_MODE_test.DaggerC index 69f480fb1..e2c98e3d4 100644 --- a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentNamesShouldNotConflictWithParent_FAST_INIT_MODE_test.DaggerC +++ b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentNamesShouldNotConflictWithParent_FAST_INIT_MODE_test.DaggerC @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerC { private DaggerC() { diff --git a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentSimpleNamesDisambiguatedInRoot_DEFAULT_MODE_DaggerParentComponent b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentSimpleNamesDisambiguatedInRoot_DEFAULT_MODE_DaggerParentComponent index 33e45bf6b..7b47466d6 100644 --- a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentSimpleNamesDisambiguatedInRoot_DEFAULT_MODE_DaggerParentComponent +++ b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentSimpleNamesDisambiguatedInRoot_DEFAULT_MODE_DaggerParentComponent @@ -10,7 +10,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParentComponent { private DaggerParentComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentSimpleNamesDisambiguatedInRoot_FAST_INIT_MODE_DaggerParentComponent b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentSimpleNamesDisambiguatedInRoot_FAST_INIT_MODE_DaggerParentComponent index 33e45bf6b..7b47466d6 100644 --- a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentSimpleNamesDisambiguatedInRoot_FAST_INIT_MODE_DaggerParentComponent +++ b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentSimpleNamesDisambiguatedInRoot_FAST_INIT_MODE_DaggerParentComponent @@ -10,7 +10,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParentComponent { private DaggerParentComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentSimpleNamesDisambiguated_DEFAULT_MODE_test.DaggerParentComponent b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentSimpleNamesDisambiguated_DEFAULT_MODE_test.DaggerParentComponent index 9f50fa921..6a9942d83 100644 --- a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentSimpleNamesDisambiguated_DEFAULT_MODE_test.DaggerParentComponent +++ b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentSimpleNamesDisambiguated_DEFAULT_MODE_test.DaggerParentComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParentComponent { private DaggerParentComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentSimpleNamesDisambiguated_FAST_INIT_MODE_test.DaggerParentComponent b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentSimpleNamesDisambiguated_FAST_INIT_MODE_test.DaggerParentComponent index 9f50fa921..6a9942d83 100644 --- a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentSimpleNamesDisambiguated_FAST_INIT_MODE_test.DaggerParentComponent +++ b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentSimpleNamesDisambiguated_FAST_INIT_MODE_test.DaggerParentComponent @@ -12,7 +12,8 @@ import javax.annotation.processing.Generated; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerParentComponent { private DaggerParentComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_emptyMultibindings_avoidSwitchProviders_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_emptyMultibindings_avoidSwitchProviders_DEFAULT_MODE_test.DaggerTestComponent index 7b26af182..0ac7a6deb 100644 --- a/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_emptyMultibindings_avoidSwitchProviders_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_emptyMultibindings_avoidSwitchProviders_DEFAULT_MODE_test.DaggerTestComponent @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_emptyMultibindings_avoidSwitchProviders_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_emptyMultibindings_avoidSwitchProviders_FAST_INIT_MODE_test.DaggerTestComponent index 7b26af182..0ac7a6deb 100644 --- a/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_emptyMultibindings_avoidSwitchProviders_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_emptyMultibindings_avoidSwitchProviders_FAST_INIT_MODE_test.DaggerTestComponent @@ -17,7 +17,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_memberInjectors_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_memberInjectors_DEFAULT_MODE_test.DaggerTestComponent index e0230e0c7..db768e1fa 100644 --- a/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_memberInjectors_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_memberInjectors_DEFAULT_MODE_test.DaggerTestComponent @@ -4,8 +4,8 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InstanceFactory; import dagger.internal.MembersInjectors; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -16,7 +16,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -56,7 +57,7 @@ final class DaggerTestComponent { } @Override - public Provider<MembersInjector<Foo>> providerOfMembersInjector() { + public javax.inject.Provider<MembersInjector<Foo>> providerOfMembersInjector() { return fooMembersInjectorProvider; } } diff --git a/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_memberInjectors_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_memberInjectors_FAST_INIT_MODE_test.DaggerTestComponent index e0230e0c7..db768e1fa 100644 --- a/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_memberInjectors_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_memberInjectors_FAST_INIT_MODE_test.DaggerTestComponent @@ -4,8 +4,8 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InstanceFactory; import dagger.internal.MembersInjectors; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -16,7 +16,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -56,7 +57,7 @@ final class DaggerTestComponent { } @Override - public Provider<MembersInjector<Foo>> providerOfMembersInjector() { + public javax.inject.Provider<MembersInjector<Foo>> providerOfMembersInjector() { return fooMembersInjectorProvider; } } diff --git a/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_optionals_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_optionals_DEFAULT_MODE_test.DaggerTestComponent index 904fb4aea..c474dc4f3 100644 --- a/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_optionals_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_optionals_DEFAULT_MODE_test.DaggerTestComponent @@ -3,9 +3,9 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.InstanceFactory; import dagger.internal.Preconditions; +import dagger.internal.Provider; import java.util.Optional; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -16,7 +16,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { /** @@ -94,12 +95,12 @@ final class DaggerTestComponent { } @Override - public Provider<Optional<Present>> providerOfOptionalOfPresent() { + public javax.inject.Provider<Optional<Present>> providerOfOptionalOfPresent() { return optionalOfPresentProvider; } @Override - public Provider<Optional<Absent>> providerOfOptionalOfAbsent() { + public javax.inject.Provider<Optional<Absent>> providerOfOptionalOfAbsent() { return optionalOfAbsentProvider; } } diff --git a/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_optionals_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_optionals_FAST_INIT_MODE_test.DaggerTestComponent index 1e46fdee1..54d032d0f 100644 --- a/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_optionals_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_optionals_FAST_INIT_MODE_test.DaggerTestComponent @@ -2,9 +2,9 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.InstanceFactory; +import dagger.internal.Provider; import java.util.Optional; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -15,7 +15,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { /** @@ -73,12 +74,12 @@ final class DaggerTestComponent { } @Override - public Provider<Optional<Present>> providerOfOptionalOfPresent() { + public javax.inject.Provider<Optional<Present>> providerOfOptionalOfPresent() { return optionalOfPresentProvider; } @Override - public Provider<Optional<Absent>> providerOfOptionalOfAbsent() { + public javax.inject.Provider<Optional<Absent>> providerOfOptionalOfAbsent() { return optionalOfAbsentProvider; } diff --git a/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_scopedBinds_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_scopedBinds_DEFAULT_MODE_test.DaggerTestComponent index d3f68be07..ab66d4e37 100644 --- a/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_scopedBinds_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_scopedBinds_DEFAULT_MODE_test.DaggerTestComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -14,7 +14,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -54,12 +55,12 @@ final class DaggerTestComponent { } @Override - public Provider<Object> objectProvider() { + public javax.inject.Provider<Object> objectProvider() { return ((Provider) cProvider); } @Override - public Provider<CharSequence> charSequenceProvider() { + public javax.inject.Provider<CharSequence> charSequenceProvider() { return cProvider; } } diff --git a/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_scopedBinds_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_scopedBinds_FAST_INIT_MODE_test.DaggerTestComponent index 440def076..0a7cdb22f 100644 --- a/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_scopedBinds_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_scopedBinds_FAST_INIT_MODE_test.DaggerTestComponent @@ -2,8 +2,8 @@ package test; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -14,7 +14,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -57,12 +58,12 @@ final class DaggerTestComponent { } @Override - public Provider<Object> objectProvider() { + public javax.inject.Provider<Object> objectProvider() { return ((Provider) cProvider); } @Override - public Provider<CharSequence> charSequenceProvider() { + public javax.inject.Provider<CharSequence> charSequenceProvider() { return cProvider; } diff --git a/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_switchingProviderTest_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_switchingProviderTest_DEFAULT_MODE_test.DaggerTestComponent index c04beefef..ade9e533f 100644 --- a/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_switchingProviderTest_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_switchingProviderTest_DEFAULT_MODE_test.DaggerTestComponent @@ -13,7 +13,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { diff --git a/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_switchingProviderTest_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_switchingProviderTest_FAST_INIT_MODE_test.DaggerTestComponent index c2bcf9116..e225c47ff 100644 --- a/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_switchingProviderTest_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_switchingProviderTest_FAST_INIT_MODE_test.DaggerTestComponent @@ -1,8 +1,8 @@ package test; import dagger.internal.DaggerGenerated; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -13,7 +13,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -358,507 +359,507 @@ final class DaggerTestComponent { } @Override - public Provider<Binding0> getBinding0Provider() { + public javax.inject.Provider<Binding0> getBinding0Provider() { return binding0Provider; } @Override - public Provider<Binding1> getBinding1Provider() { + public javax.inject.Provider<Binding1> getBinding1Provider() { return binding1Provider; } @Override - public Provider<Binding2> getBinding2Provider() { + public javax.inject.Provider<Binding2> getBinding2Provider() { return binding2Provider; } @Override - public Provider<Binding3> getBinding3Provider() { + public javax.inject.Provider<Binding3> getBinding3Provider() { return binding3Provider; } @Override - public Provider<Binding4> getBinding4Provider() { + public javax.inject.Provider<Binding4> getBinding4Provider() { return binding4Provider; } @Override - public Provider<Binding5> getBinding5Provider() { + public javax.inject.Provider<Binding5> getBinding5Provider() { return binding5Provider; } @Override - public Provider<Binding6> getBinding6Provider() { + public javax.inject.Provider<Binding6> getBinding6Provider() { return binding6Provider; } @Override - public Provider<Binding7> getBinding7Provider() { + public javax.inject.Provider<Binding7> getBinding7Provider() { return binding7Provider; } @Override - public Provider<Binding8> getBinding8Provider() { + public javax.inject.Provider<Binding8> getBinding8Provider() { return binding8Provider; } @Override - public Provider<Binding9> getBinding9Provider() { + public javax.inject.Provider<Binding9> getBinding9Provider() { return binding9Provider; } @Override - public Provider<Binding10> getBinding10Provider() { + public javax.inject.Provider<Binding10> getBinding10Provider() { return binding10Provider; } @Override - public Provider<Binding11> getBinding11Provider() { + public javax.inject.Provider<Binding11> getBinding11Provider() { return binding11Provider; } @Override - public Provider<Binding12> getBinding12Provider() { + public javax.inject.Provider<Binding12> getBinding12Provider() { return binding12Provider; } @Override - public Provider<Binding13> getBinding13Provider() { + public javax.inject.Provider<Binding13> getBinding13Provider() { return binding13Provider; } @Override - public Provider<Binding14> getBinding14Provider() { + public javax.inject.Provider<Binding14> getBinding14Provider() { return binding14Provider; } @Override - public Provider<Binding15> getBinding15Provider() { + public javax.inject.Provider<Binding15> getBinding15Provider() { return binding15Provider; } @Override - public Provider<Binding16> getBinding16Provider() { + public javax.inject.Provider<Binding16> getBinding16Provider() { return binding16Provider; } @Override - public Provider<Binding17> getBinding17Provider() { + public javax.inject.Provider<Binding17> getBinding17Provider() { return binding17Provider; } @Override - public Provider<Binding18> getBinding18Provider() { + public javax.inject.Provider<Binding18> getBinding18Provider() { return binding18Provider; } @Override - public Provider<Binding19> getBinding19Provider() { + public javax.inject.Provider<Binding19> getBinding19Provider() { return binding19Provider; } @Override - public Provider<Binding20> getBinding20Provider() { + public javax.inject.Provider<Binding20> getBinding20Provider() { return binding20Provider; } @Override - public Provider<Binding21> getBinding21Provider() { + public javax.inject.Provider<Binding21> getBinding21Provider() { return binding21Provider; } @Override - public Provider<Binding22> getBinding22Provider() { + public javax.inject.Provider<Binding22> getBinding22Provider() { return binding22Provider; } @Override - public Provider<Binding23> getBinding23Provider() { + public javax.inject.Provider<Binding23> getBinding23Provider() { return binding23Provider; } @Override - public Provider<Binding24> getBinding24Provider() { + public javax.inject.Provider<Binding24> getBinding24Provider() { return binding24Provider; } @Override - public Provider<Binding25> getBinding25Provider() { + public javax.inject.Provider<Binding25> getBinding25Provider() { return binding25Provider; } @Override - public Provider<Binding26> getBinding26Provider() { + public javax.inject.Provider<Binding26> getBinding26Provider() { return binding26Provider; } @Override - public Provider<Binding27> getBinding27Provider() { + public javax.inject.Provider<Binding27> getBinding27Provider() { return binding27Provider; } @Override - public Provider<Binding28> getBinding28Provider() { + public javax.inject.Provider<Binding28> getBinding28Provider() { return binding28Provider; } @Override - public Provider<Binding29> getBinding29Provider() { + public javax.inject.Provider<Binding29> getBinding29Provider() { return binding29Provider; } @Override - public Provider<Binding30> getBinding30Provider() { + public javax.inject.Provider<Binding30> getBinding30Provider() { return binding30Provider; } @Override - public Provider<Binding31> getBinding31Provider() { + public javax.inject.Provider<Binding31> getBinding31Provider() { return binding31Provider; } @Override - public Provider<Binding32> getBinding32Provider() { + public javax.inject.Provider<Binding32> getBinding32Provider() { return binding32Provider; } @Override - public Provider<Binding33> getBinding33Provider() { + public javax.inject.Provider<Binding33> getBinding33Provider() { return binding33Provider; } @Override - public Provider<Binding34> getBinding34Provider() { + public javax.inject.Provider<Binding34> getBinding34Provider() { return binding34Provider; } @Override - public Provider<Binding35> getBinding35Provider() { + public javax.inject.Provider<Binding35> getBinding35Provider() { return binding35Provider; } @Override - public Provider<Binding36> getBinding36Provider() { + public javax.inject.Provider<Binding36> getBinding36Provider() { return binding36Provider; } @Override - public Provider<Binding37> getBinding37Provider() { + public javax.inject.Provider<Binding37> getBinding37Provider() { return binding37Provider; } @Override - public Provider<Binding38> getBinding38Provider() { + public javax.inject.Provider<Binding38> getBinding38Provider() { return binding38Provider; } @Override - public Provider<Binding39> getBinding39Provider() { + public javax.inject.Provider<Binding39> getBinding39Provider() { return binding39Provider; } @Override - public Provider<Binding40> getBinding40Provider() { + public javax.inject.Provider<Binding40> getBinding40Provider() { return binding40Provider; } @Override - public Provider<Binding41> getBinding41Provider() { + public javax.inject.Provider<Binding41> getBinding41Provider() { return binding41Provider; } @Override - public Provider<Binding42> getBinding42Provider() { + public javax.inject.Provider<Binding42> getBinding42Provider() { return binding42Provider; } @Override - public Provider<Binding43> getBinding43Provider() { + public javax.inject.Provider<Binding43> getBinding43Provider() { return binding43Provider; } @Override - public Provider<Binding44> getBinding44Provider() { + public javax.inject.Provider<Binding44> getBinding44Provider() { return binding44Provider; } @Override - public Provider<Binding45> getBinding45Provider() { + public javax.inject.Provider<Binding45> getBinding45Provider() { return binding45Provider; } @Override - public Provider<Binding46> getBinding46Provider() { + public javax.inject.Provider<Binding46> getBinding46Provider() { return binding46Provider; } @Override - public Provider<Binding47> getBinding47Provider() { + public javax.inject.Provider<Binding47> getBinding47Provider() { return binding47Provider; } @Override - public Provider<Binding48> getBinding48Provider() { + public javax.inject.Provider<Binding48> getBinding48Provider() { return binding48Provider; } @Override - public Provider<Binding49> getBinding49Provider() { + public javax.inject.Provider<Binding49> getBinding49Provider() { return binding49Provider; } @Override - public Provider<Binding50> getBinding50Provider() { + public javax.inject.Provider<Binding50> getBinding50Provider() { return binding50Provider; } @Override - public Provider<Binding51> getBinding51Provider() { + public javax.inject.Provider<Binding51> getBinding51Provider() { return binding51Provider; } @Override - public Provider<Binding52> getBinding52Provider() { + public javax.inject.Provider<Binding52> getBinding52Provider() { return binding52Provider; } @Override - public Provider<Binding53> getBinding53Provider() { + public javax.inject.Provider<Binding53> getBinding53Provider() { return binding53Provider; } @Override - public Provider<Binding54> getBinding54Provider() { + public javax.inject.Provider<Binding54> getBinding54Provider() { return binding54Provider; } @Override - public Provider<Binding55> getBinding55Provider() { + public javax.inject.Provider<Binding55> getBinding55Provider() { return binding55Provider; } @Override - public Provider<Binding56> getBinding56Provider() { + public javax.inject.Provider<Binding56> getBinding56Provider() { return binding56Provider; } @Override - public Provider<Binding57> getBinding57Provider() { + public javax.inject.Provider<Binding57> getBinding57Provider() { return binding57Provider; } @Override - public Provider<Binding58> getBinding58Provider() { + public javax.inject.Provider<Binding58> getBinding58Provider() { return binding58Provider; } @Override - public Provider<Binding59> getBinding59Provider() { + public javax.inject.Provider<Binding59> getBinding59Provider() { return binding59Provider; } @Override - public Provider<Binding60> getBinding60Provider() { + public javax.inject.Provider<Binding60> getBinding60Provider() { return binding60Provider; } @Override - public Provider<Binding61> getBinding61Provider() { + public javax.inject.Provider<Binding61> getBinding61Provider() { return binding61Provider; } @Override - public Provider<Binding62> getBinding62Provider() { + public javax.inject.Provider<Binding62> getBinding62Provider() { return binding62Provider; } @Override - public Provider<Binding63> getBinding63Provider() { + public javax.inject.Provider<Binding63> getBinding63Provider() { return binding63Provider; } @Override - public Provider<Binding64> getBinding64Provider() { + public javax.inject.Provider<Binding64> getBinding64Provider() { return binding64Provider; } @Override - public Provider<Binding65> getBinding65Provider() { + public javax.inject.Provider<Binding65> getBinding65Provider() { return binding65Provider; } @Override - public Provider<Binding66> getBinding66Provider() { + public javax.inject.Provider<Binding66> getBinding66Provider() { return binding66Provider; } @Override - public Provider<Binding67> getBinding67Provider() { + public javax.inject.Provider<Binding67> getBinding67Provider() { return binding67Provider; } @Override - public Provider<Binding68> getBinding68Provider() { + public javax.inject.Provider<Binding68> getBinding68Provider() { return binding68Provider; } @Override - public Provider<Binding69> getBinding69Provider() { + public javax.inject.Provider<Binding69> getBinding69Provider() { return binding69Provider; } @Override - public Provider<Binding70> getBinding70Provider() { + public javax.inject.Provider<Binding70> getBinding70Provider() { return binding70Provider; } @Override - public Provider<Binding71> getBinding71Provider() { + public javax.inject.Provider<Binding71> getBinding71Provider() { return binding71Provider; } @Override - public Provider<Binding72> getBinding72Provider() { + public javax.inject.Provider<Binding72> getBinding72Provider() { return binding72Provider; } @Override - public Provider<Binding73> getBinding73Provider() { + public javax.inject.Provider<Binding73> getBinding73Provider() { return binding73Provider; } @Override - public Provider<Binding74> getBinding74Provider() { + public javax.inject.Provider<Binding74> getBinding74Provider() { return binding74Provider; } @Override - public Provider<Binding75> getBinding75Provider() { + public javax.inject.Provider<Binding75> getBinding75Provider() { return binding75Provider; } @Override - public Provider<Binding76> getBinding76Provider() { + public javax.inject.Provider<Binding76> getBinding76Provider() { return binding76Provider; } @Override - public Provider<Binding77> getBinding77Provider() { + public javax.inject.Provider<Binding77> getBinding77Provider() { return binding77Provider; } @Override - public Provider<Binding78> getBinding78Provider() { + public javax.inject.Provider<Binding78> getBinding78Provider() { return binding78Provider; } @Override - public Provider<Binding79> getBinding79Provider() { + public javax.inject.Provider<Binding79> getBinding79Provider() { return binding79Provider; } @Override - public Provider<Binding80> getBinding80Provider() { + public javax.inject.Provider<Binding80> getBinding80Provider() { return binding80Provider; } @Override - public Provider<Binding81> getBinding81Provider() { + public javax.inject.Provider<Binding81> getBinding81Provider() { return binding81Provider; } @Override - public Provider<Binding82> getBinding82Provider() { + public javax.inject.Provider<Binding82> getBinding82Provider() { return binding82Provider; } @Override - public Provider<Binding83> getBinding83Provider() { + public javax.inject.Provider<Binding83> getBinding83Provider() { return binding83Provider; } @Override - public Provider<Binding84> getBinding84Provider() { + public javax.inject.Provider<Binding84> getBinding84Provider() { return binding84Provider; } @Override - public Provider<Binding85> getBinding85Provider() { + public javax.inject.Provider<Binding85> getBinding85Provider() { return binding85Provider; } @Override - public Provider<Binding86> getBinding86Provider() { + public javax.inject.Provider<Binding86> getBinding86Provider() { return binding86Provider; } @Override - public Provider<Binding87> getBinding87Provider() { + public javax.inject.Provider<Binding87> getBinding87Provider() { return binding87Provider; } @Override - public Provider<Binding88> getBinding88Provider() { + public javax.inject.Provider<Binding88> getBinding88Provider() { return binding88Provider; } @Override - public Provider<Binding89> getBinding89Provider() { + public javax.inject.Provider<Binding89> getBinding89Provider() { return binding89Provider; } @Override - public Provider<Binding90> getBinding90Provider() { + public javax.inject.Provider<Binding90> getBinding90Provider() { return binding90Provider; } @Override - public Provider<Binding91> getBinding91Provider() { + public javax.inject.Provider<Binding91> getBinding91Provider() { return binding91Provider; } @Override - public Provider<Binding92> getBinding92Provider() { + public javax.inject.Provider<Binding92> getBinding92Provider() { return binding92Provider; } @Override - public Provider<Binding93> getBinding93Provider() { + public javax.inject.Provider<Binding93> getBinding93Provider() { return binding93Provider; } @Override - public Provider<Binding94> getBinding94Provider() { + public javax.inject.Provider<Binding94> getBinding94Provider() { return binding94Provider; } @Override - public Provider<Binding95> getBinding95Provider() { + public javax.inject.Provider<Binding95> getBinding95Provider() { return binding95Provider; } @Override - public Provider<Binding96> getBinding96Provider() { + public javax.inject.Provider<Binding96> getBinding96Provider() { return binding96Provider; } @Override - public Provider<Binding97> getBinding97Provider() { + public javax.inject.Provider<Binding97> getBinding97Provider() { return binding97Provider; } @Override - public Provider<Binding98> getBinding98Provider() { + public javax.inject.Provider<Binding98> getBinding98Provider() { return binding98Provider; } @Override - public Provider<Binding99> getBinding99Provider() { + public javax.inject.Provider<Binding99> getBinding99Provider() { return binding99Provider; } @Override - public Provider<Binding100> getBinding100Provider() { + public javax.inject.Provider<Binding100> getBinding100Provider() { return binding100Provider; } diff --git a/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_unscopedBinds_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_unscopedBinds_DEFAULT_MODE_test.DaggerTestComponent index 00679b417..b2933ae32 100644 --- a/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_unscopedBinds_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_unscopedBinds_DEFAULT_MODE_test.DaggerTestComponent @@ -13,7 +13,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -46,12 +47,12 @@ final class DaggerTestComponent { @Override public Provider<Object> objectProvider() { - return ((Provider) TestModule_SFactory.create()); + return ((dagger.internal.Provider) TestModule_SFactory.create()); } @Override public Provider<CharSequence> charSequenceProvider() { - return ((Provider) TestModule_SFactory.create()); + return ((dagger.internal.Provider) TestModule_SFactory.create()); } } } diff --git a/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_unscopedBinds_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_unscopedBinds_FAST_INIT_MODE_test.DaggerTestComponent index 2970ba6f6..eef5afc71 100644 --- a/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_unscopedBinds_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/SwitchingProviderTest_unscopedBinds_FAST_INIT_MODE_test.DaggerTestComponent @@ -1,8 +1,8 @@ package test; import dagger.internal.DaggerGenerated; +import dagger.internal.Provider; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -13,7 +13,8 @@ import javax.inject.Provider; "unchecked", "rawtypes", "KotlinInternal", - "KotlinInternalInJava" + "KotlinInternalInJava", + "cast" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -53,12 +54,12 @@ final class DaggerTestComponent { } @Override - public Provider<Object> objectProvider() { + public javax.inject.Provider<Object> objectProvider() { return ((Provider) sProvider); } @Override - public Provider<CharSequence> charSequenceProvider() { + public javax.inject.Provider<CharSequence> charSequenceProvider() { return ((Provider) sProvider); } diff --git a/javatests/dagger/internal/codegen/kotlin/KspComponentProcessorTest.java b/javatests/dagger/internal/codegen/kotlin/KspComponentProcessorTest.java index cc4f5a155..20a57f1a4 100644 --- a/javatests/dagger/internal/codegen/kotlin/KspComponentProcessorTest.java +++ b/javatests/dagger/internal/codegen/kotlin/KspComponentProcessorTest.java @@ -57,7 +57,8 @@ public final class KspComponentProcessorTest { " \"unchecked\",", " \"rawtypes\",", " \"KotlinInternal\",", - " \"KotlinInternalInJava\"", + " \"KotlinInternalInJava\",", + " \"cast\"", "})", "public final class DaggerMyComponent {", " private DaggerMyComponent() {", @@ -160,7 +161,8 @@ public final class KspComponentProcessorTest { " \"unchecked\",", " \"rawtypes\",", " \"KotlinInternal\",", - " \"KotlinInternalInJava\"", + " \"KotlinInternalInJava\",", + " \"cast\"", "})", "public final class DaggerMyComponent {", " private DaggerMyComponent() {", @@ -230,8 +232,8 @@ public final class KspComponentProcessorTest { "package test;", "", "import dagger.internal.DaggerGenerated;", + "import dagger.internal.Provider;", "import javax.annotation.processing.Generated;", - "import javax.inject.Provider;", "", "@DaggerGenerated", "@Generated(", @@ -242,7 +244,8 @@ public final class KspComponentProcessorTest { " \"unchecked\",", " \"rawtypes\",", " \"KotlinInternal\",", - " \"KotlinInternalInJava\"", + " \"KotlinInternalInJava\",", + " \"cast\"", "})", "public final class DaggerMyComponent {", " private DaggerMyComponent() {", @@ -283,7 +286,7 @@ public final class KspComponentProcessorTest { " }", "", " @Override", - " public Provider<Foo> foo() {", + " public javax.inject.Provider<Foo> foo() {", " return fooProvider;", " }", " }", @@ -342,7 +345,8 @@ public final class KspComponentProcessorTest { " \"unchecked\",", " \"rawtypes\",", " \"KotlinInternal\",", - " \"KotlinInternalInJava\"", + " \"KotlinInternalInJava\",", + " \"cast\"", "})", "public final class DaggerMyComponent {", " private DaggerMyComponent() {", @@ -448,7 +452,8 @@ public final class KspComponentProcessorTest { " \"unchecked\",", " \"rawtypes\",", " \"KotlinInternal\",", - " \"KotlinInternalInJava\"", + " \"KotlinInternalInJava\",", + " \"cast\"", "})", "public final class DaggerMyComponent {", " private DaggerMyComponent() {", @@ -560,7 +565,8 @@ public final class KspComponentProcessorTest { " \"unchecked\",", " \"rawtypes\",", " \"KotlinInternal\",", - " \"KotlinInternalInJava\"", + " \"KotlinInternalInJava\",", + " \"cast\"", "})", "public final class DaggerMyComponent {", " private DaggerMyComponent() {", diff --git a/javatests/dagger/producers/BUILD b/javatests/dagger/producers/BUILD index 025379996..6c7685614 100644 --- a/javatests/dagger/producers/BUILD +++ b/javatests/dagger/producers/BUILD @@ -31,6 +31,7 @@ GenJavaTests( functional = 0, javacopts = JAVA_RELEASE_MIN + DOCLINT_REFERENCES + DOCLINT_HTML_AND_SYNTAX, deps = [ + "//java/dagger:core", "//java/dagger/producers", "//third_party/java/guava:testlib", "//third_party/java/guava/collect", diff --git a/javatests/dagger/producers/internal/AbstractProducesMethodProducerTest.java b/javatests/dagger/producers/internal/AbstractProducesMethodProducerTest.java index af1350447..0b32d7170 100644 --- a/javatests/dagger/producers/internal/AbstractProducesMethodProducerTest.java +++ b/javatests/dagger/producers/internal/AbstractProducesMethodProducerTest.java @@ -28,13 +28,13 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.SettableFuture; +import dagger.internal.Provider; import dagger.producers.Producer; import dagger.producers.monitoring.ProducerMonitor; import dagger.producers.monitoring.ProducerToken; import dagger.producers.monitoring.ProductionComponentMonitor; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; -import javax.inject.Provider; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/javatests/dagger/producers/internal/ProducersTest.java b/javatests/dagger/producers/internal/ProducersTest.java index 1cfe12106..5b2d9c103 100644 --- a/javatests/dagger/producers/internal/ProducersTest.java +++ b/javatests/dagger/producers/internal/ProducersTest.java @@ -23,12 +23,12 @@ import com.google.common.collect.ImmutableList; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.SettableFuture; +import dagger.internal.Provider; import dagger.producers.Produced; import dagger.producers.Producer; import java.util.Set; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; -import javax.inject.Provider; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/test_defs.bzl b/test_defs.bzl index 467f4e9b9..3b136261b 100644 --- a/test_defs.bzl +++ b/test_defs.bzl @@ -31,7 +31,6 @@ _FUNCTIONAL_BUILD_VARIANTS = { "Shards": ["-Adagger.keysPerComponentShard=2"], "FastInit": ["-Adagger.fastInit=enabled"], "FastInit_Shards": ["-Adagger.fastInit=enabled", "-Adagger.keysPerComponentShard=2"], - "IgnoreProvisionKeyWildcards": ["-Adagger.ignoreProvisionKeyWildcards=enabled"], } def GenKtLibrary( @@ -51,6 +50,7 @@ def GenKtLibrary( deps = deps, gen_library_deps = gen_library_deps, test_only_deps = None, + shard_count = None, plugins = plugins, javacopts = javacopts, functional = functional, @@ -65,6 +65,7 @@ def GenKtTests( test_only_deps = None, plugins = None, javacopts = None, + shard_count = None, functional = True, require_jdk7_syntax = True): _GenTestsWithVariants( @@ -77,6 +78,7 @@ def GenKtTests( test_only_deps = test_only_deps, plugins = plugins, javacopts = javacopts, + shard_count = shard_count, functional = functional, require_jdk7_syntax = require_jdk7_syntax, ) @@ -102,6 +104,7 @@ def GenJavaLibrary( test_only_deps = None, plugins = plugins, javacopts = javacopts, + shard_count = None, functional = functional, require_jdk7_syntax = require_jdk7_syntax, ) @@ -114,6 +117,7 @@ def GenJavaTests( test_only_deps = None, plugins = None, javacopts = None, + shard_count = None, functional = True, require_jdk7_syntax = True): if any([src for src in srcs if src.endswith(".kt")]): @@ -128,6 +132,7 @@ def GenJavaTests( test_only_deps = test_only_deps, plugins = plugins, javacopts = javacopts, + shard_count = shard_count, functional = functional, require_jdk7_syntax = require_jdk7_syntax, ) @@ -139,6 +144,7 @@ def GenRobolectricTests( test_only_deps = None, plugins = None, javacopts = None, + shard_count = None, functional = True, require_jdk7_syntax = True, manifest_values = None): @@ -153,6 +159,7 @@ def GenRobolectricTests( test_only_deps = test_only_deps, plugins = plugins, javacopts = javacopts, + shard_count = shard_count, functional = functional, require_jdk7_syntax = require_jdk7_syntax, test_kwargs = {"manifest_values": manifest_values}, @@ -168,6 +175,7 @@ def _GenTestsWithVariants( test_only_deps, plugins, javacopts, + shard_count, functional, require_jdk7_syntax, test_kwargs = None): @@ -243,6 +251,7 @@ def _GenTestsWithVariants( deps = test_deps + variant_deps, plugins = plugins, javacopts = javacopts + variant_javacopts, + shard_count = shard_count, jvm_flags = jvm_flags, functional = functional, test_kwargs = test_kwargs, @@ -292,6 +301,7 @@ def _GenTestWithVariant( deps, plugins, javacopts, + shard_count, jvm_flags, functional, test_kwargs): @@ -320,6 +330,7 @@ def _GenTestWithVariant( jvm_flags = jvm_flags, plugins = plugins, tags = tags, + shard_count = shard_count, test_class = test_class, deps = deps, **test_kwargs_with_javacopts diff --git a/third_party/java/jspecify_annotations/BUILD b/third_party/java/jspecify_annotations/BUILD new file mode 100644 index 000000000..cb7208281 --- /dev/null +++ b/third_party/java/jspecify_annotations/BUILD @@ -0,0 +1,22 @@ +# Copyright (C) 2023 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. + +# BUILD rules for https://github.com/square/javapoet + +package(default_visibility = ["//:src"]) + +alias( + name = "jspecify_annotations", + actual = "@maven//:org_jspecify_jspecify", +) diff --git a/tools/bazel.rc b/tools/bazel.rc new file mode 100644 index 000000000..2707c1c3a --- /dev/null +++ b/tools/bazel.rc @@ -0,0 +1,11 @@ +# Global bazelrc file (see https://bazel.build/run/bazelrc#global-bazelrc) + +# Note: This flag is required to prevent actions from clashing with each when +# reading/writing tmp files. Without this flag we get errors like: +# +# Error: Cannot use file /tmp/hsperfdata_runner/12 because it is locked by +# another process +# +# This flag will be enabled by default in Bazel 7.0.0, but for now we enable it +# manually. For more details: https://github.com/bazelbuild/bazel/issues/3236. +build --incompatible_sandbox_hermetic_tmp
\ No newline at end of file diff --git a/tools/maven.bzl b/tools/maven.bzl index bc7638673..4fba1a53c 100644 --- a/tools/maven.bzl +++ b/tools/maven.bzl @@ -15,10 +15,10 @@ """Macros to simplify generating maven files. """ +load("@google_bazel_common//tools/jarjar:jarjar.bzl", "jarjar_library") +load("@google_bazel_common//tools/javadoc:javadoc.bzl", "javadoc_library") load("@google_bazel_common//tools/maven:pom_file.bzl", default_pom_file = "pom_file") load(":maven_info.bzl", "MavenInfo", "collect_maven_info") -load("@google_bazel_common//tools/javadoc:javadoc.bzl", "javadoc_library") -load("@google_bazel_common//tools/jarjar:jarjar.bzl", "jarjar_library") SHADED_MAVEN_DEPS = [ "com.google.auto:auto-common", @@ -66,6 +66,8 @@ def gen_maven_artifact( shaded_deps = None, manifest = None, lint_deps = None, + proguard_and_r8_specs = None, + r8_specs = None, proguard_specs = None): _gen_maven_artifact( name, @@ -85,6 +87,8 @@ def gen_maven_artifact( shaded_deps, manifest, lint_deps, + proguard_and_r8_specs, + r8_specs, proguard_specs ) @@ -106,6 +110,8 @@ def _gen_maven_artifact( shaded_deps, manifest, lint_deps, + proguard_and_r8_specs, + r8_specs, proguard_specs): """Generates the files required for a maven artifact. @@ -140,7 +146,12 @@ def _gen_maven_artifact( shaded_deps: The shaded deps for the jarjar. manifest: The AndroidManifest.xml to bundle in when packaing an 'aar'. lint_deps: The lint targets to be bundled in when packaging an 'aar'. - proguard_specs: The proguard spec files to be bundled in when packaging an 'aar' + proguard_and_r8_specs: The proguard spec files to be bundled in when + packaging an 'aar', which will be applied in + both r8 and proguard. + r8_specs: The proguard spec files to be used only for r8 when packaging an 'jar'. + proguard_specs: The proguard spec files to be used only for proguard not r8 when + packaging an 'jar'. """ _validate_maven_deps( @@ -189,11 +200,11 @@ def _gen_maven_artifact( else: lint_jar_name = None - if proguard_specs: + if proguard_and_r8_specs: # Concatenate all proguard rules since an aar only contains a single proguard.txt native.genrule( name = name + "-proguard", - srcs = proguard_specs, + srcs = proguard_and_r8_specs, outs = [name + "-proguard.txt"], cmd = "cat $(SRCS) > $@", ) @@ -217,12 +228,46 @@ def _gen_maven_artifact( cmd = "cp $< $@", ) else: + # (TODO/322873492) add support for passing in general proguard rule. + if r8_specs: + # Concatenate all r8 rules. + native.genrule( + name = name + "-r8", + srcs = r8_specs, + outs = [name + "-r8.txt"], + cmd = "cat $(SRCS) > $@", + ) + r8_file = name + "-r8.txt" + else: + r8_file = None + + if proguard_specs: + # Concatenate all proguard only rules. + native.genrule( + name = name + "-proguard-only", + srcs = proguard_specs, + outs = [name + "-proguard-only.txt"], + cmd = "cat $(SRCS) > $@", + ) + proguard_only_file = name + "-proguard-only.txt" + else: + proguard_only_file = None + jarjar_library( - name = name, + name = name + "-classes", testonly = testonly, jars = artifact_targets + shaded_deps, merge_meta_inf_files = merge_meta_inf_files, ) + jar_name = name + "-classes.jar" + + # Include r8 and proguard rules to dagger jar if there is one. + _package_r8_and_proguard_rule( + name = name, + artifactJar = jar_name, + r8Spec = r8_file, + proguardSpec = proguard_only_file, + ) jarjar_library( name = name + "-src", @@ -405,3 +450,58 @@ _package_android_library = rule( "aar": "%{name}.aar", }, ) + +def _package_r8_and_proguard_rule_impl(ctx): + inputs = [ctx.file.artifactJar] + if ctx.file.r8Spec: + inputs.append(ctx.file.r8Spec) + if ctx.file.proguardSpec: + inputs.append(ctx.file.proguardSpec) + ctx.actions.run_shell( + inputs = inputs, + outputs = [ctx.outputs.jar], + command = """ + TMPDIR="$(mktemp -d)" + cp {artifactJar} $TMPDIR/artifact.jar + if [[ -a {r8Spec} ]]; then + mkdir -p META-INF/com.android.tools/r8 + cp {r8Spec} META-INF/com.android.tools/r8/r8.pro + jar uf $TMPDIR/artifact.jar META-INF/ + fi + if [[ -a {proguardSpec} ]]; then + mkdir -p META-INF/com.android.tools/proguard + cp {proguardSpec} META-INF/com.android.tools/proguard/proguard.pro + jar uf $TMPDIR/artifact.jar META-INF/ + fi + cp $TMPDIR/artifact.jar {outputFile} + """.format( + artifactJar = ctx.file.artifactJar.path, + r8Spec = ctx.file.r8Spec.path if ctx.file.r8Spec else "none", + proguardSpec = ctx.file.proguardSpec.path if ctx.file.proguardSpec else "none", + outputFile = ctx.outputs.jar.path, + ), + ) + +_package_r8_and_proguard_rule = rule( + implementation = _package_r8_and_proguard_rule_impl, + attrs = { + "artifactJar": attr.label( + doc = "The library artifact jar to be updated.", + allow_single_file = True, + mandatory = True, + ), + "r8Spec": attr.label( + doc = "The r8.txt file to be merged with the artifact jar", + allow_single_file = True, + mandatory = False, + ), + "proguardSpec": attr.label( + doc = "The proguard-only.txt file to be merged with the artifact jar", + allow_single_file = True, + mandatory = False, + ), + }, + outputs = { + "jar": "%{name}.jar", + }, +) diff --git a/util/cleanup-github-caches.py b/util/cleanup-github-caches.py new file mode 100755 index 000000000..41e4ede55 --- /dev/null +++ b/util/cleanup-github-caches.py @@ -0,0 +1,142 @@ +"""Cleans out the GitHub Actions cache by deleting obsolete caches. + + Usage: + python cleanup-github-caches.py +""" + +import collections +import datetime +import json +import os +import re +import subprocess +import sys + + +def main(argv): + if len(argv) > 1: + raise ValueError('Expected no arguments: {}'.format(argv)) + + # Group caches by their Git reference, e.g "refs/pull/3968/merge" + caches_by_ref = collections.defaultdict(list) + for cache in get_caches(): + caches_by_ref[cache['ref']].append(cache) + + # Caclulate caches that should be deleted. + caches_to_delete = [] + for ref, caches in caches_by_ref.items(): + # If the pull request is already "closed", then delete all caches. + if (ref != 'refs/heads/master' and ref != 'master'): + match = re.findall(r'refs/pull/(\d+)/merge', ref) + if match: + pull_request_number = match[0] + pull_request = get_pull_request(pull_request_number) + if pull_request['state'] == 'closed': + caches_to_delete += caches + continue + else: + raise ValueError('Could not find pull request number:', ref) + + # Check for caches with the same key prefix and delete the older caches. + caches_by_key = {} + for cache in caches: + key_prefix = re.findall('(.*)-.*', cache['key'])[0] + if key_prefix in caches_by_key: + prev_cache = caches_by_key[key_prefix] + if (get_created_at(cache) > get_created_at(prev_cache)): + caches_to_delete.append(prev_cache) + caches_by_key[key_prefix] = cache + else: + caches_to_delete.append(cache) + else: + caches_by_key[key_prefix] = cache + + for cache in caches_to_delete: + print('Deleting cache ({}): {}'.format(cache['ref'], cache['key'])) + print(delete_cache(cache)) + + +def get_created_at(cache): + created_at = cache['created_at'].split('.')[0] + # GitHub changed its date format so support both the old and new format for + # now. + for date_format in ('%Y-%m-%dT%H:%M:%SZ', '%Y-%m-%dT%H:%M:%S'): + try: + return datetime.datetime.strptime(created_at, date_format) + except ValueError: + pass + raise ValueError('no valid date format found: "%s"' % created_at) + + +def delete_cache(cache): + # pylint: disable=line-too-long + """Deletes the given cache from GitHub Actions. + + See https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28#delete-a-github-actions-cache-for-a-repository-using-a-cache-id + + Args: + cache: The cache to delete. + + Returns: + The response of the api call. + """ + return call_github_api( + """-X DELETE \ + https://api.github.com/repos/google/dagger/actions/caches/{0} + """.format(cache['id']) + ) + + +def get_caches(): + # pylint: disable=line-too-long + """Gets the list of existing caches from GitHub Actions. + + See https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28#list-github-actions-caches-for-a-repository + + Returns: + The list of existing caches. + """ + result = call_github_api( + 'https://api.github.com/repos/google/dagger/actions/caches' + ) + return json.loads(result)['actions_caches'] + + +def get_pull_request(pr_number): + # pylint: disable=line-too-long + """Gets the pull request with given number from GitHub Actions. + + See https://docs.github.com/en/rest/pulls/pulls?apiVersion=2022-11-28#get-a-pull-request + + Args: + pr_number: The pull request number used to get the pull request. + + Returns: + The pull request. + """ + result = call_github_api( + 'https://api.github.com/repos/google/dagger/pulls/{0}'.format(pr_number) + ) + return json.loads(result) + + +def call_github_api(endpoint): + auth_cmd = '' + if 'GITHUB_TOKEN' in os.environ: + token = os.environ.get('GITHUB_TOKEN') + auth_cmd = '-H "Authorization: Bearer {0}"'.format(token) + cmd = """curl -L \ + {auth_cmd} \ + -H \"Accept: application/vnd.github+json\" \ + -H \"X-GitHub-Api-Version: 2022-11-28\" \ + {endpoint}""".format(auth_cmd=auth_cmd, endpoint=endpoint) + return subprocess.run( + [cmd], + check=True, + shell=True, + capture_output=True + ).stdout.decode('utf-8') + + +if __name__ == '__main__': + main(sys.argv) diff --git a/util/deploy-dagger.sh b/util/deploy-dagger.sh index 9249b916c..b0b68a8eb 100755 --- a/util/deploy-dagger.sh +++ b/util/deploy-dagger.sh @@ -37,10 +37,10 @@ _deploy() { _deploy \ "" \ - java/dagger/libcore.jar \ + java/dagger/artifact.jar \ java/dagger/pom.xml \ - java/dagger/libcore-src.jar \ - java/dagger/core-javadoc.jar \ + java/dagger/artifact-src.jar \ + java/dagger/artifact-javadoc.jar \ "dagger" _deploy \ @@ -52,7 +52,7 @@ _deploy \ "" _deploy \ - "com.google.auto.common,dagger.spi.shaded.auto.common;androidx.room.compiler,dagger.spi.shaded.androidx.room.compiler;kotlinx.metadata,dagger.spi.shaded.kotlinx.metadata;androidx.room,dagger.spi.shaded.androidx.room" \ + "com.google.auto.common,dagger.spi.internal.shaded.auto.common;androidx.room.compiler,dagger.spi.internal.shaded.androidx.room.compiler;kotlinx.metadata,dagger.spi.internal.shaded.kotlinx.metadata;androidx.room,dagger.spi.internal.shaded.androidx.room" \ java/dagger/internal/codegen/artifact.jar \ java/dagger/internal/codegen/pom.xml \ java/dagger/internal/codegen/artifact-src.jar \ @@ -68,7 +68,7 @@ _deploy \ "" _deploy \ - "com.google.auto.common,dagger.spi.shaded.auto.common;androidx.room.compiler,dagger.spi.shaded.androidx.room.compiler;kotlinx.metadata,dagger.spi.shaded.kotlinx.metadata;androidx.room,dagger.spi.shaded.androidx.room" \ + "com.google.auto.common,dagger.spi.internal.shaded.auto.common;androidx.room.compiler,dagger.spi.internal.shaded.androidx.room.compiler;kotlinx.metadata,dagger.spi.internal.shaded.kotlinx.metadata;androidx.room,dagger.spi.internal.shaded.androidx.room" \ java/dagger/spi/artifact.jar \ java/dagger/spi/pom.xml \ java/dagger/spi/artifact-src.jar \ @@ -77,10 +77,10 @@ _deploy \ _deploy \ "" \ - java/dagger/android/android.aar \ + java/dagger/android/artifact.aar \ java/dagger/android/pom.xml \ - java/dagger/android/libandroid-src.jar \ - java/dagger/android/android-javadoc.jar \ + java/dagger/android/artifact-src.jar \ + java/dagger/android/artifact-javadoc.jar \ "" _deploy \ @@ -93,10 +93,10 @@ _deploy \ _deploy \ "" \ - java/dagger/android/support/support.aar \ + java/dagger/android/support/artifact.aar \ java/dagger/android/support/pom.xml \ - java/dagger/android/support/libsupport-src.jar \ - java/dagger/android/support/support-javadoc.jar \ + java/dagger/android/support/artifact-src.jar \ + java/dagger/android/support/artifact-javadoc.jar \ "" _deploy \ @@ -108,11 +108,11 @@ _deploy \ "" _deploy \ - "" \ - shaded_android_processor.jar \ + "com.google.auto.common,dagger.spi.internal.shaded.auto.common;androidx.room.compiler,dagger.spi.internal.shaded.androidx.room.compiler;kotlinx.metadata,dagger.spi.internal.shaded.kotlinx.metadata;androidx.room,dagger.spi.internal.shaded.androidx.room" \ + java/dagger/android/processor/artifact.jar \ java/dagger/android/processor/pom.xml \ - java/dagger/android/processor/libprocessor-src.jar \ - java/dagger/android/processor/processor-javadoc.jar \ + java/dagger/android/processor/artifact-src.jar \ + java/dagger/android/processor/artifact-javadoc.jar \ "" _deploy \ diff --git a/util/deploy-hilt-gradle-plugin.sh b/util/deploy-hilt-gradle-plugin.sh index 72ff939da..698b0c969 100755 --- a/util/deploy-hilt-gradle-plugin.sh +++ b/util/deploy-hilt-gradle-plugin.sh @@ -12,8 +12,8 @@ _deploy_plugin() { local plugindir=java/dagger/hilt/android/plugin ./$plugindir/gradlew -p $plugindir --no-daemon clean \ publishAllPublicationsToMavenRepository -PPublishVersion="$VERSION_NAME" - local outdir=$plugindir/main/build/repo/com/google/dagger/hilt-android-gradle-plugin/$VERSION_NAME - local markerOutDir=$plugindir/main/build/repo/com/google/dagger/hilt/android/com.google.dagger.hilt.android.gradle.plugin/$VERSION_NAME + local outdir=$plugindir/main/buildOut/repo/com/google/dagger/hilt-android-gradle-plugin/$VERSION_NAME + local markerOutDir=$plugindir/main/buildOut/repo/com/google/dagger/hilt/android/com.google.dagger.hilt.android.gradle.plugin/$VERSION_NAME # When building '-SNAPSHOT' versions in gradle, the filenames replaces # '-SNAPSHOT' with timestamps, so we need to disambiguate by finding each file # to deploy. See: https://stackoverflow.com/questions/54182823/ diff --git a/util/deploy-hilt.sh b/util/deploy-hilt.sh index cdf4b6b1a..81b384c30 100755 --- a/util/deploy-hilt.sh +++ b/util/deploy-hilt.sh @@ -52,7 +52,7 @@ _deploy \ "" _deploy \ - "com.google.auto.common,dagger.spi.shaded.auto.common;androidx.room.compiler,dagger.spi.shaded.androidx.room.compiler;kotlinx.metadata,dagger.spi.shaded.kotlinx.metadata;androidx.room,dagger.spi.shaded.androidx.room" \ + "com.google.auto.common,dagger.spi.internal.shaded.auto.common;androidx.room.compiler,dagger.spi.internal.shaded.androidx.room.compiler;kotlinx.metadata,dagger.spi.internal.shaded.kotlinx.metadata;androidx.room,dagger.spi.internal.shaded.androidx.room" \ java/dagger/hilt/processor/artifact.jar \ java/dagger/hilt/processor/pom.xml \ java/dagger/hilt/processor/artifact-src.jar \ @@ -60,7 +60,7 @@ _deploy \ "" _deploy \ - "com.google.auto.common,dagger.spi.shaded.auto.common;androidx.room.compiler,dagger.spi.shaded.androidx.room.compiler;kotlinx.metadata,dagger.spi.shaded.kotlinx.metadata;androidx.room,dagger.spi.shaded.androidx.room" \ + "com.google.auto.common,dagger.spi.internal.shaded.auto.common;androidx.room.compiler,dagger.spi.internal.shaded.androidx.room.compiler;kotlinx.metadata,dagger.spi.internal.shaded.kotlinx.metadata;androidx.room,dagger.spi.internal.shaded.androidx.room" \ java/dagger/hilt/android/processor/artifact.jar \ java/dagger/hilt/android/processor/pom.xml \ java/dagger/hilt/android/processor/artifact-src.jar \ diff --git a/util/run-local-emulator-tests.sh b/util/run-local-emulator-tests.sh index 30b31bedb..733f63744 100755 --- a/util/run-local-emulator-tests.sh +++ b/util/run-local-emulator-tests.sh @@ -8,6 +8,9 @@ adb logcat *:S TestRunner:V & LOGCAT_PID=$! readonly GRADLE_PROJECTS=( "javatests/artifacts/hilt-android/simple" "javatests/artifacts/hilt-android/simpleKotlin" + "javatests/artifacts/hilt-android/viewmodel" + "javatests/artifacts/hilt-android/lazyclasskey" + "javatests/artifacts/dagger/lazyclasskey" ) for project in "${GRADLE_PROJECTS[@]}"; do echo "Running gradle Android emulator tests for $project" diff --git a/util/run-local-gradle-android-tests.sh b/util/run-local-gradle-android-tests.sh index 0b3a5f54b..9ae56f892 100755 --- a/util/run-local-gradle-android-tests.sh +++ b/util/run-local-gradle-android-tests.sh @@ -9,18 +9,33 @@ readonly JAVA_ANDROID_GRADLE_PROJECTS=( "javatests/artifacts/dagger-android/simple" "javatests/artifacts/hilt-android/simple" ) -for project in "${JAVA_ANDROID_GRADLE_PROJECTS[@]}"; do - echo "Running gradle tests for $project with AGP $AGP_VERSION_INPUT" - AGP_VERSION=$AGP_VERSION_INPUT ./$project/gradlew -p $project assembleDebug $COMMON_GRADLE_ARGS - AGP_VERSION=$AGP_VERSION_INPUT ./$project/gradlew -p $project testDebug --continue $COMMON_GRADLE_ARGS -done - readonly KOTLIN_ANDROID_GRADLE_PROJECTS=( "javatests/artifacts/hilt-android/simpleKotlin" ) -for project in "${KOTLIN_ANDROID_GRADLE_PROJECTS[@]}"; do - echo "Running gradle tests for $project with AGP $AGP_VERSION_INPUT" - AGP_VERSION=$AGP_VERSION_INPUT ./$project/gradlew -p $project assembleDebug $COMMON_GRADLE_ARGS - AGP_VERSION=$AGP_VERSION_INPUT ./$project/gradlew -p $project testWithKaptDebugUnitTest --continue $COMMON_GRADLE_ARGS - AGP_VERSION=$AGP_VERSION_INPUT ./$project/gradlew -p $project testWithKspDebugUnitTest --continue $COMMON_GRADLE_ARGS -done +if [[ $AGP_VERSION_INPUT == "7.0.0" || $AGP_VERSION_INPUT == "7.1.2" ]] +then + for project in "${JAVA_ANDROID_GRADLE_PROJECTS[@]}"; do + echo "Running gradle tests for $project with AGP $AGP_VERSION_INPUT" + AGP_VERSION=$AGP_VERSION_INPUT ./$project/gradlew -p $project assembleDebug $COMMON_GRADLE_ARGS + AGP_VERSION=$AGP_VERSION_INPUT ./$project/gradlew -p $project testDebug --continue $COMMON_GRADLE_ARGS + done + + for project in "${KOTLIN_ANDROID_GRADLE_PROJECTS[@]}"; do + echo "Running gradle tests for $project with AGP $AGP_VERSION_INPUT" + AGP_VERSION=$AGP_VERSION_INPUT ./$project/gradlew -p $project assembleDebug $COMMON_GRADLE_ARGS + AGP_VERSION=$AGP_VERSION_INPUT ./$project/gradlew -p $project testWithKaptDebugUnitTest --continue $COMMON_GRADLE_ARGS + AGP_VERSION=$AGP_VERSION_INPUT ./$project/gradlew -p $project testWithKspDebugUnitTest --continue $COMMON_GRADLE_ARGS + done +fi + +readonly JAVA_ANDROID_GRADLE_JDK17_PROJECTS=( + "javatests/artifacts/dagger-android-ksp" +) +if [[ $AGP_VERSION_INPUT == "8.1.0" ]] +then + for project in "${JAVA_ANDROID_GRADLE_JDK17_PROJECTS[@]}"; do + echo "Running gradle tests for $project with AGP $AGP_VERSION_INPUT" + AGP_VERSION=$AGP_VERSION_INPUT ./$project/gradlew -p $project assembleDebug $COMMON_GRADLE_ARGS + AGP_VERSION=$AGP_VERSION_INPUT ./$project/gradlew -p $project testDebug --continue $COMMON_GRADLE_ARGS + done +fi diff --git a/util/run-local-tests.sh b/util/run-local-tests.sh index 4e81e5fe1..2603346dc 100755 --- a/util/run-local-tests.sh +++ b/util/run-local-tests.sh @@ -19,4 +19,4 @@ util/run-local-gradle-tests.sh util/run-local-gradle-android-tests.sh "7.0.0" util/run-local-gradle-android-tests.sh "7.1.2" - +# TODO: this script is not up-to-date with Dagger github actions |